# UI Setup (https://v2.s3.dimah.dev/docs/react/ui)

[`@dimah-s3/ui`](https://www.npmjs.com/package/@dimah-s3/ui) provides accessible, theme-ready UI controls built on top of [shadcn](https://ui.shadcn.com) design tokens and `@dimah-s3/react` hooks.

## 1. Installation [#1-installation]

<Tabs items={["npm package", "shadcn registry"]}>

<Tab value="npm package">

`@dimah-s3/core`, `@dimah-s3/react`, and `@fuma-translate/react` are peer
dependencies. Install them with the package:

```npm
npm i @dimah-s3/ui@beta @dimah-s3/core@beta @dimah-s3/react@beta @fuma-translate/react shadcn
```

</Tab>

<Tab value="shadcn registry">

```json title="components.json"
{
  "registries": {
    "@dimah-s3": "https://v2.s3.dimah.dev/r/{name}.json" // [!code ++]
  }
}
```

```npm
npx shadcn@latest add @dimah-s3/upload
```

The registry copies the component source into your project and installs the
packages it needs.

</Tab>

</Tabs>

## 2. Import CSS stylesheet [#2-import-css-stylesheet]

Import the UI stylesheet in your global CSS to enable animations and design tokens:

```css title="app/globals.css"
@import "shadcn/tailwind.css";
@import "@dimah-s3/ui/styles.css"; /* [!code ++] */

/* shadcn theme variables (`--primary`, `--muted`, …) */
```

## 3. Mount Toaster [#3-mount-toaster]

Mount one `<Toaster />` next to `<S3Provider>` in your root layout:

```tsx title="app/layout.tsx"
import { Toaster } from "@dimah-s3/ui"; // [!code ++]
import { S3Provider } from "@/lib/s3-client";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <S3Provider>{children}</S3Provider>
        {/* [!code ++] */}
        <Toaster />
      </body>
    </html>
  );
}
```

## 4. Render a component [#4-render-a-component]

Each family has a root that holds one hook, and parts that read it. Toasts
are separate: mount `UploadToasts`, `DownloadToasts`, or `DeleteToasts` once
per hook.

```tsx title="components/avatar-uploader.tsx"
"use client";

import { useUpload } from "@dimah-s3/react";
import {
  Upload,
  UploadToasts,
  UploadTrigger,
  UploadStatus,
} from "@dimah-s3/ui";

export function AvatarUploader() {
  const upload = useUpload({ route: "avatar" });

  return (
    <>
      <Upload upload={upload}>
        <UploadTrigger />
        <UploadStatus />
      </Upload>
      <UploadToasts upload={upload} />
    </>
  );
}
```

Components never toast on their own. A second toast owner for the same hook
renders nothing and warns in development.

---

## Explore UI components [#explore-ui-components]

### Upload [#upload]

<Cards>
  <Card
    title="Upload"
    href="/docs/react/ui/components/upload"
    description="File picker, dropzone with the progress inside, queue status, and toasts for useUpload."
  />
  <Card
    title="Upload Field"
    href="/docs/react/ui/components/upload-field"
    description="Form field whose value is the uploaded object keys."
  />
  <Card
    title="Avatar Upload"
    href="/docs/react/ui/components/avatar-upload"
    description="Image button that shows and replaces a picture, round or square."
  />
</Cards>

### Download and delete [#download-and-delete]

<Cards>
  <Card
    title="Download"
    href="/docs/react/ui/components/download"
    description="Download triggers and fetch progress for one download hook."
  />
  <Card
    title="Delete"
    href="/docs/react/ui/components/delete"
    description="Delete triggers with one confirm dialog per root."
  />
</Cards>

### Files [#files]

<Cards>
  <Card
    title="Object List"
    href="/docs/react/ui/components/object-list"
    description="Composable file browser for useObjectList: list and grid views, search, sort, selection, and folders."
  />
  <Card
    title="Object Card"
    href="/docs/react/ui/components/object-card"
    description="One stored file with download and delete actions."
  />
  <Card
    title="Object Image"
    href="/docs/react/ui/components/object-image"
    description="Image of a private object with a signed, refreshed URL."
  />
  <Card
    title="Attachment"
    href="/docs/react/ui/components/attachment"
    description="File cards, status rows, progress rings, and type glyphs."
  />
</Cards>

### Customization [#customization]

<Cards>
  <Card
    title="Theming"
    href="/docs/react/ui/customization/theming"
    description="Override the --dimah-s3-* tokens on :root or any container."
  />
</Cards>

## Frequently asked questions [#frequently-asked-questions]

<Accordions>

<Accordion title="Can I use the components without installing the @dimah-s3/ui package?">

Yes. Add items from the shadcn registry to copy their source into your
codebase. The items are `upload`, `upload-field`, `avatar-upload`,
`object-image`, `object-card`, `download`, `delete`, `object-list`, and
`file-attachment`:

```npm
npx shadcn@latest add @dimah-s3/upload @dimah-s3/delete
```

</Accordion>

<Accordion title="How do I translate the components?">

The components read their strings through `@fuma-translate/react`. See
[Internationalization](https://v2.s3.dimah.dev/docs/i18n).

</Accordion>

</Accordions>
