diff --git a/.changeset/four-peaches-sniff.md b/.changeset/four-peaches-sniff.md new file mode 100644 index 000000000..53b1f6d6c --- /dev/null +++ b/.changeset/four-peaches-sniff.md @@ -0,0 +1,5 @@ +--- +"@assistant-ui/react": patch +--- + +feat: UserMessageAttachment UI diff --git a/packages/react/src/styles/tailwindcss/thread.css b/packages/react/src/styles/tailwindcss/thread.css index a966218ba..a05c0b230 100644 --- a/packages/react/src/styles/tailwindcss/thread.css +++ b/packages/react/src/styles/tailwindcss/thread.css @@ -81,12 +81,17 @@ @apply col-start-1 mr-3 mt-2.5; } +:where(.aui-user-message-root) > .aui-user-message-attachments { + @apply col-span-full col-start-1 row-start-1; + @apply justify-end; +} + :where(.aui-user-message-root) > .aui-user-message-content { - @apply col-start-2 row-start-1; + @apply col-start-2 row-start-2; } :where(.aui-user-message-root) > .aui-branch-picker-root { - @apply col-span-full col-start-1 row-start-2; + @apply col-span-full col-start-1 row-start-3; @apply -mr-1 justify-end; } @@ -94,12 +99,22 @@ @apply bg-aui-muted text-aui-foreground max-w-xl break-words rounded-3xl px-5 py-2.5; } -/* thread action bar */ +.aui-user-message-attachments { + @apply flex w-full flex-row gap-3; +} + +.aui-user-message-attachment-root { + @apply bg-aui-muted relative flex size-20 items-center justify-center rounded-lg p-2; +} + +/* user action bar */ .aui-user-action-bar-root { @apply flex flex-col items-end; } +/* edit composer */ + .aui-edit-composer-root { @apply bg-aui-muted my-4 flex w-full max-w-2xl flex-col gap-2 rounded-xl; } diff --git a/packages/react/src/ui/composer.tsx b/packages/react/src/ui/composer.tsx index 3de07c812..ec021f29f 100644 --- a/packages/react/src/ui/composer.tsx +++ b/packages/react/src/ui/composer.tsx @@ -13,6 +13,7 @@ import { CircleStopIcon } from "./base/CircleStopIcon"; import { ComposerPrimitive, ThreadPrimitive } from "../primitives"; import { useThreadContext } from "../context/react/ThreadContext"; import ComposerAttachment from "./composer-attachment"; +import { ComposerPrimitiveAttachmentsProps } from "../primitives/composer/ComposerAttachments"; const useAllowAttachments = (ensureCapability = false) => { const { composer: { allowAttachments = true } = {} } = useThreadConfig(); @@ -69,11 +70,16 @@ const ComposerAttachmentsContainer = withDefaults("div", { className: "aui-composer-attachments", }); -const ComposerAttachments: FC = () => { +type ComposerAttachmentsProps = Partial; + +const ComposerAttachments: FC = ({ components }) => { return ( ); diff --git a/packages/react/src/ui/index.ts b/packages/react/src/ui/index.ts index 7631a285b..94acc8384 100644 --- a/packages/react/src/ui/index.ts +++ b/packages/react/src/ui/index.ts @@ -36,6 +36,8 @@ export { export { default as UserActionBar } from "./user-action-bar"; +export { default as UserMessageAttachment } from "./user-message-attachment"; + export { default as ThreadWelcome, type ThreadWelcomeMessageProps, diff --git a/packages/react/src/ui/user-message-attachment.tsx b/packages/react/src/ui/user-message-attachment.tsx new file mode 100644 index 000000000..4a7aca54c --- /dev/null +++ b/packages/react/src/ui/user-message-attachment.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { type FC } from "react"; + +import { withDefaults } from "./utils/withDefaults"; +import { useAttachmentContext } from "../context/react/AttachmentContext"; + +const UserMessageAttachmentRoot = withDefaults("div", { + className: "aui-user-message-attachment-root", +}); + +UserMessageAttachmentRoot.displayName = "UserMessageAttachmentRoot"; + +const UserMessageAttachment: FC = () => { + const { useAttachment } = useAttachmentContext(); + const attachment = useAttachment((a) => a.attachment); + + return ( + + .{attachment.name.split(".").pop()} + + ); +}; + +UserMessageAttachment.displayName = "UserMessageAttachment"; + +const exports = { + Root: UserMessageAttachmentRoot, +}; + +export default Object.assign( + UserMessageAttachment, + exports, +) as typeof UserMessageAttachment & typeof exports; diff --git a/packages/react/src/ui/user-message.tsx b/packages/react/src/ui/user-message.tsx index 9899f8898..3ad72c7f5 100644 --- a/packages/react/src/ui/user-message.tsx +++ b/packages/react/src/ui/user-message.tsx @@ -7,10 +7,13 @@ import { withDefaults } from "./utils/withDefaults"; import UserActionBar from "./user-action-bar"; import ContentPart from "./content-part"; import { MessagePrimitive, MessagePrimitiveContentProps } from "../primitives"; +import UserMessageAttachment from "./user-message-attachment"; +import { MessagePrimitiveAttachmentsProps } from "../primitives/message/MessageAttachments"; const UserMessage: FC = () => { return ( + @@ -50,9 +53,34 @@ const UserMessageContent = forwardRef( UserMessageContent.displayName = "UserMessageContent"; +const UserMessageAttachmentsContainer = withDefaults("div", { + className: "aui-user-message-attachments", +}); + +export type UserMessageAttachmentsProps = + Partial; + +const UserMessageAttachments: FC = ({ + components, +}) => { + return ( + + + + + + ); +}; + const exports = { Root: UserMessageRoot, Content: UserMessageContent, + Attachments: UserMessageAttachments, }; export default Object.assign(UserMessage, exports) as typeof UserMessage &