> ## Documentation Index
> Fetch the complete documentation index at: https://docs.napps.io/llms.txt
> Use this file to discover all available pages before exploring further.

# UI examples

These examples use `@napps/nodes` and are intended to be copied into a React UI component.

## Settings-driven card

```tsx theme={null}
function ProductBanner({ title, subtitle }: { title: string; subtitle: string }) {
  return (
    <box class="promo-card" style={{ padding: 16, spacing: 8 }}>
      <text style={{ fontSize: 20, fontWeight: 700 }}>{title}</text>
      <text style={{ color: "#6b7280" }}>{subtitle}</text>
    </box>
  );
}
```

## Scrollable row

```tsx theme={null}
<scrollable horizontal style={{ paddingStart: 16, paddingEnd: 16, spacing: 12 }}>
  {items.map((item) => (
    <box key={item.id} style={{ width: 140, height: 96 }}>
      <text>{item.title}</text>
    </box>
  ))}
</scrollable>
```

Use padding on the scroll container so edge spacing remains part of the scroll content.

## Gradient callout

```tsx theme={null}
import { linearGradient } from "@napps/nodes";

<box
  style={{
    padding: 20,
    borderRadius: 16,
    backgroundGradient: linearGradient(90, ["#111827", "#2563eb"]),
    verticalAlignment: "center",
    horizontalAlignment: "center",
  }}
>
  <text style={{ color: "#ffffff", fontWeight: 700, textAlignment: "center" }}>Member offer</text>
</box>
```

## Pan gesture card

```tsx theme={null}
function DraggableCard() {
  const x = sv(0);

  return (
    <gestureDetector
      gesture={{ type: "pan", minDistance: 8 }}
      onUpdate={mapEvent({ translationX: x })}
      onEnd={(event) => {
        x.value = spring(0, { velocity: event.velocityX });
      }}
    >
      <box style={animatedProps({ translationX: x })}>
        <text>Drag me</text>
      </box>
    </gestureDetector>
  );
}
```

## Product card surface

```tsx theme={null}
function ProductCards() {
  const { products, loadingCount, surface } = useProductCards();
  if (surface === null) return null;

  return (
    <>
      {products.map((product) => <Card key={product.id} item={product} />)}
      {Array.from({ length: loadingCount }, (_, index) => (
        <SkeletonCard key={`skeleton-${index}`} />
      ))}
    </>
  );
}
```

Render a flat root list, keep product keys stable, and render loading skeletons after real products.
