diff --git a/docs/content/docs/2.components/chat-message.md b/docs/content/docs/2.components/chat-message.md index c930cbde41..34c38b35a7 100644 --- a/docs/content/docs/2.components/chat-message.md +++ b/docs/content/docs/2.components/chat-message.md @@ -113,6 +113,29 @@ props: When using the [`ChatMessages`](/docs/components/chat-messages) component, the `variant` prop is set to `naked` for `assistant` messages and `soft` for `user` messages. :: +### Color :badge{label="Soon" class="align-text-top"} + +Use the `color` prop to change the color of the message. + +::component-code +--- +prettier: true +ignore: + - parts + - role + - id +props: + variant: 'soft' + color: 'primary' + parts: + - type: 'text' + id: '1' + text: 'Hello! Tell me more about building AI chatbots with Nuxt UI.' + role: 'user' + id: '1' +--- +:: + ### Icon Use the `icon` prop to display an [Icon](/docs/components/icon) component next to the message. diff --git a/playgrounds/nuxt/app/composables/useNavigation.ts b/playgrounds/nuxt/app/composables/useNavigation.ts index b5e7a27165..dda7b2be63 100644 --- a/playgrounds/nuxt/app/composables/useNavigation.ts +++ b/playgrounds/nuxt/app/composables/useNavigation.ts @@ -13,6 +13,7 @@ const components = [ 'calendar', 'card', 'carousel', + 'chat-message', 'chat-reasoning', 'chat-shimmer', 'chat-tool', diff --git a/playgrounds/nuxt/app/pages/components/chat-message.vue b/playgrounds/nuxt/app/pages/components/chat-message.vue new file mode 100644 index 0000000000..e02015c507 --- /dev/null +++ b/playgrounds/nuxt/app/pages/components/chat-message.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/runtime/components/ChatMessage.vue b/src/runtime/components/ChatMessage.vue index 397d2d6596..20d61cd3aa 100644 --- a/src/runtime/components/ChatMessage.vue +++ b/src/runtime/components/ChatMessage.vue @@ -23,6 +23,10 @@ export interface ChatMessageProps { + header?(props: UIMessage): VNode[] leading?(props: UIMessage & { avatar: ChatMessageProps['avatar'], ui: ChatMessage['ui'] }): VNode[] files?(props: Omit, 'parts'> & { parts: FileUIPart[] }): VNode[] content?(props: UIMessage & { content?: string }): VNode[] @@ -80,11 +85,12 @@ const appConfig = useAppConfig() as ChatMessage['AppConfig'] const fileParts = computed(() => props.parts?.filter((part): part is FileUIPart => part.type === 'file') ?? []) const textParts = computed(() => props.parts?.filter((part): part is TextUIPart => part.type === 'text') ?? []) -const messageProps = computed(() => omit(props, ['as', 'icon', 'avatar', 'variant', 'side', 'actions', 'compact', 'class', 'ui', 'content'])) +const messageProps = computed(() => omit(props, ['as', 'icon', 'avatar', 'variant', 'color', 'side', 'actions', 'compact', 'class', 'ui', 'content'])) // eslint-disable-next-line vue/no-dupe-keys const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.chatMessage || {}) })({ variant: props.variant, + color: props.color, side: props.side, leading: !!props.icon || !!props.avatar || !!slots.leading, actions: !!props.actions || !!slots.actions, @@ -94,8 +100,12 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.chatMessage