Skip to content

Commit

Permalink
feat: ComposerPrimitive.AddAttachment (#768)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yonom authored Sep 7, 2024
1 parent 3ba193e commit a81b18f
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-students-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@assistant-ui/react": patch
---

feat: ComposerPrimitive.AddAttachment
60 changes: 60 additions & 0 deletions apps/docs/content/docs/ui/primitives/Composer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { ComposerPrimitive } from "@assistant-ui/react";
// creating a new message
const Composer = () => (
<ComposerPrimitive.Root>
<ComposerPrimitive.Attachments />
<ComposerPrimitive.AddAttachment />
<ComposerPrimitive.Input />
<ComposerPrimitive.Send />
</ComposerPrimitive.Root>
Expand Down Expand Up @@ -152,6 +154,64 @@ const Cancel = () => {
};
```

### Attachments

Renders attachments. This primitive renders a separate component for each attachment.

<ParametersTable
type="ComposerPrimitiveAttachmentsProps"
parameters={[
{
name: "components",
type: "ComposerAttachmentsComponents",
description: "The component to render for each attachment.",
children: [
{
type: "ComposerPrimitiveAttachmentsProps['components']",
parameters: [
{
name: "Image",
type: "ComponentType",
description: "The component to render for each image attachment.",
},
{
name: "Document",
type: "ComponentType",
description:
"The component to render for each document attachment.",
},
{
name: "File",
type: "ComponentType",
description: "The component to render for each file attachment.",
},
{
name: "Fallback",
type: "ComponentType",
description: "The component to render for each attachment type.",
},
],
},
],
},
]}
/>

### AddAttachment

Renders a button to add an attachment.

This primitive renders a `<button>` element unless `asChild` is set.

<ParametersTable
type="ComposerPrimitiveAddAttachmentProps"
parameters={[
{
name: "asChild",
},
]}
/>

### If

Renders children if a condition is met.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useCallback } from "react";
import { useThreadContext } from "../../context";
import { generateId } from "../../internal";

export const useComposerAddAttachment = () => {
const { useComposer } = useThreadContext();

const disabled = useComposer((c) => !c.isEditing);

const callback = useCallback(() => {
const { addAttachment } = useComposer.getState();

const input = document.createElement("input");
input.type = "file";

input.onchange = (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
addAttachment({
id: generateId(),
file,
});
};

input.click();
}, [useComposer]);

if (disabled) return null;
return callback;
};
16 changes: 16 additions & 0 deletions packages/react/src/primitives/composer/ComposerAddAttachment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import {
ActionButtonProps,
createActionButton,
} from "../../utils/createActionButton";
import { useComposerAddAttachment } from "../../primitive-hooks/composer";

export type ComposerPrimitiveAddAttachmentProps = ActionButtonProps<
typeof useComposerAddAttachment
>;

export const ComposerPrimitiveAddAttachment = createActionButton(
"ComposerPrimitive.AddAttachment",
useComposerAddAttachment,
);
1 change: 1 addition & 0 deletions packages/react/src/primitives/composer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export { ComposerPrimitiveRoot as Root } from "./ComposerRoot";
export { ComposerPrimitiveInput as Input } from "./ComposerInput";
export { ComposerPrimitiveSend as Send } from "./ComposerSend";
export { ComposerPrimitiveCancel as Cancel } from "./ComposerCancel";
export { ComposerPrimitiveAddAttachment as AddAttachment } from "./ComposerAddAttachment";
export { ComposerPrimitiveAttachments as Attachments } from "./ComposerAttachments";
export { ComposerPrimitiveIf as If } from "./ComposerIf";

0 comments on commit a81b18f

Please sign in to comment.