feat: improve event presentation with separate icons and add aria labels to buttons

This commit is contained in:
weishu
2025-12-18 08:56:52 +08:00
parent 279c0c2dd8
commit 35d959dba4
4 changed files with 37 additions and 13 deletions
@@ -86,6 +86,8 @@ export function ComposerButtons(props: {
{props.showSettingsButton ? (
<button
type="button"
aria-label="Settings"
title="Settings"
className="settings-button flex h-8 w-8 items-center justify-center rounded-full text-[var(--app-fg)]/60 transition-colors hover:bg-[var(--app-bg)] hover:text-[var(--app-fg)]"
onClick={props.onSettingsToggle}
disabled={props.controlsDisabled}
@@ -97,6 +99,8 @@ export function ComposerButtons(props: {
{props.showAbortButton ? (
<button
type="button"
aria-label="Abort"
title="Abort"
disabled={props.abortDisabled}
className="flex h-8 w-8 items-center justify-center rounded-full text-[var(--app-fg)]/60 transition-colors hover:bg-[var(--app-bg)] hover:text-red-500 disabled:cursor-not-allowed disabled:opacity-50"
onClick={props.onAbort}
@@ -108,6 +112,8 @@ export function ComposerButtons(props: {
<ComposerPrimitive.Send
disabled={props.controlsDisabled || !props.canSend}
aria-label="Send"
title="Send"
className={`flex h-8 w-8 items-center justify-center rounded-full transition-colors ${
props.canSend && !props.controlsDisabled
? 'bg-black text-white'
@@ -119,4 +125,3 @@ export function ComposerButtons(props: {
</div>
)
}
@@ -1,17 +1,24 @@
import { MessagePrimitive, useAssistantState } from '@assistant-ui/react'
import { getEventPresentation } from '@/chat/presentation'
import type { HappyChatMessageMetadata } from '@/lib/assistant-runtime'
export function HappySystemMessage() {
const message = useAssistantState(({ message }) => message)
if (message.role !== 'system') return null
const text = message.content[0]?.type === 'text' ? message.content[0].text : ''
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
const event = custom?.kind === 'event' ? custom.event : undefined
const icon = event ? getEventPresentation(event).icon : null
return (
<MessagePrimitive.Root className="py-1">
<div className="mx-auto w-fit max-w-[92%] px-2 text-center text-xs text-[var(--app-hint)] opacity-80">
{text}
<span className="inline-flex items-center gap-1">
{icon ? <span aria-hidden="true">{icon}</span> : null}
<span>{text}</span>
</span>
</div>
</MessagePrimitive.Root>
)
}
@@ -1,7 +1,7 @@
import type { ToolCallMessagePartProps } from '@assistant-ui/react'
import type { ChatBlock } from '@/chat/types'
import type { ToolCallBlock } from '@/chat/types'
import { renderEventLabel } from '@/chat/presentation'
import { getEventPresentation } from '@/chat/presentation'
import { CodeBlock } from '@/components/CodeBlock'
import { MarkdownRenderer } from '@/components/MarkdownRenderer'
import { LazyRainbowText } from '@/components/LazyRainbowText'
@@ -77,10 +77,14 @@ function HappyNestedBlockList(props: {
}
if (block.kind === 'agent-event') {
const presentation = getEventPresentation(block.event)
return (
<div key={`event:${block.id}`} className="py-1">
<div className="mx-auto w-fit max-w-[92%] px-2 text-center text-xs text-[var(--app-hint)] opacity-80">
{renderEventLabel(block.event)}
<span className="inline-flex items-center gap-1">
{presentation.icon ? <span aria-hidden="true">{presentation.icon}</span> : null}
<span>{presentation.text}</span>
</span>
</div>
</div>
)