# Custom UI (https://v1.s3.dimah.dev/docs/react/ui/customization/custom-ui)

Combine `@dimah-s3/react` hooks with your own components or custom shadcn primitives.

## Preview [#preview]

<DemoPreview name="custom-upload-demo.tsx">
  <CustomUploadDemo />
</DemoPreview>

## Example: Headless File Uploader [#example-headless-file-uploader]

```tsx
"use client";

import { useUpload } from "@dimah-s3/react";
import { Button } from "@/components/ui/button";

export function CustomFilePicker() {
  const upload = useUpload({
    route: "avatar",
    noDrag: true, // [!code ++]
    noClick: true, // [!code ++]
  });

  return (
    <div className="flex items-center gap-4">
      <input {...upload.getInputProps()} />
      <Button type="button" onClick={() => upload.open()}>
        {" "}
        {/* [!code ++] */}
        {upload.isUploading
          ? `Uploading ${upload.progress.percent}%`
          : "Choose file"}
      </Button>
    </div>
  );
}
```

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

<Accordions>

<Accordion title="How do I access low-level transfer metrics?">

Read `upload.progress` for loaded bytes, total bytes, percentage, and transfer
speed:

```tsx
const { progress } = useUpload({ route: "avatar" });

console.log(progress.loaded, progress.total, progress.percent);
```

</Accordion>

</Accordions>
