Skip to content

Commit

Permalink
feat: user-message-attachment UI (#790)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yonom authored Sep 9, 2024
1 parent af764b3 commit b48fbcc
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-peaches-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@assistant-ui/react": patch
---

feat: UserMessageAttachment UI
21 changes: 18 additions & 3 deletions packages/react/src/styles/tailwindcss/thread.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,40 @@
@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;
}

.aui-user-message-content {
@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;
}
Expand Down
10 changes: 8 additions & 2 deletions packages/react/src/ui/composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -69,11 +70,16 @@ const ComposerAttachmentsContainer = withDefaults("div", {
className: "aui-composer-attachments",
});

const ComposerAttachments: FC = () => {
type ComposerAttachmentsProps = Partial<ComposerPrimitiveAttachmentsProps>;

const ComposerAttachments: FC<ComposerAttachmentsProps> = ({ components }) => {
return (
<ComposerAttachmentsContainer>
<ComposerPrimitive.Attachments
components={{ Attachment: ComposerAttachment }}
components={{
...components,
Attachment: components?.Attachment ?? ComposerAttachment,
}}
/>
</ComposerAttachmentsContainer>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
34 changes: 34 additions & 0 deletions packages/react/src/ui/user-message-attachment.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<UserMessageAttachmentRoot>
.{attachment.name.split(".").pop()}
</UserMessageAttachmentRoot>
);
};

UserMessageAttachment.displayName = "UserMessageAttachment";

const exports = {
Root: UserMessageAttachmentRoot,
};

export default Object.assign(
UserMessageAttachment,
exports,
) as typeof UserMessageAttachment & typeof exports;
28 changes: 28 additions & 0 deletions packages/react/src/ui/user-message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<UserMessageRoot>
<UserMessageAttachments />
<UserActionBar />
<UserMessageContent />
<BranchPicker />
Expand Down Expand Up @@ -50,9 +53,34 @@ const UserMessageContent = forwardRef<HTMLDivElement, UserMessageContentProps>(

UserMessageContent.displayName = "UserMessageContent";

const UserMessageAttachmentsContainer = withDefaults("div", {
className: "aui-user-message-attachments",
});

export type UserMessageAttachmentsProps =
Partial<MessagePrimitiveAttachmentsProps>;

const UserMessageAttachments: FC<UserMessageAttachmentsProps> = ({
components,
}) => {
return (
<MessagePrimitive.If hasAttachments>
<UserMessageAttachmentsContainer>
<MessagePrimitive.Attachments
components={{
...components,
Attachment: components?.Attachment ?? UserMessageAttachment,
}}
/>
</UserMessageAttachmentsContainer>
</MessagePrimitive.If>
);
};

const exports = {
Root: UserMessageRoot,
Content: UserMessageContent,
Attachments: UserMessageAttachments,
};

export default Object.assign(UserMessage, exports) as typeof UserMessage &
Expand Down

0 comments on commit b48fbcc

Please sign in to comment.