Messages: {messages.length}
@@ -243,26 +242,26 @@ All components are headless and use data attributes for styling:
```css
/* Message styling */
-[data-message-role="user"] {
+[data-message-role='user'] {
background: #e3f2fd;
text-align: right;
}
-[data-message-role="assistant"] {
+[data-message-role='assistant'] {
background: #f5f5f5;
}
/* Part type styling */
-[data-part-type="text"] {
+[data-part-type='text'] {
padding: 1rem;
}
-[data-part-type="thinking"] {
+[data-part-type='thinking'] {
opacity: 0.8;
font-style: italic;
}
-[data-part-type="tool-call"] {
+[data-part-type='tool-call'] {
border-left: 3px solid #2196f3;
padding-left: 1rem;
}
diff --git a/packages/typescript/ai-preact-ui/src/chat-input.tsx b/packages/typescript/ai-preact-ui/src/chat-input.tsx
index b4014fb6..be3b9dcc 100644
--- a/packages/typescript/ai-preact-ui/src/chat-input.tsx
+++ b/packages/typescript/ai-preact-ui/src/chat-input.tsx
@@ -127,14 +127,11 @@ export function ChatInput({
transition: 'all 0.2s',
}}
onFocus={(e) => {
- e.currentTarget.style.borderColor =
- 'rgba(249, 115, 22, 0.4)'
- e.currentTarget.style.boxShadow =
- '0 0 0 2px rgba(249, 115, 22, 0.2)'
+ e.currentTarget.style.borderColor = 'rgba(249, 115, 22, 0.4)'
+ e.currentTarget.style.boxShadow = '0 0 0 2px rgba(249, 115, 22, 0.2)'
}}
onBlur={(e) => {
- e.currentTarget.style.borderColor =
- 'rgba(255, 255, 255, 0.1)'
+ e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.1)'
e.currentTarget.style.boxShadow = 'none'
}}
/>
@@ -159,14 +156,12 @@ export function ChatInput({
}}
onMouseEnter={(e) => {
if (!disabled && value.trim()) {
- e.currentTarget.style.backgroundColor =
- 'rgb(234, 88, 12)'
+ e.currentTarget.style.backgroundColor = 'rgb(234, 88, 12)'
}
}}
onMouseLeave={(e) => {
if (!disabled && value.trim()) {
- e.currentTarget.style.backgroundColor =
- 'rgb(249, 115, 22)'
+ e.currentTarget.style.backgroundColor = 'rgb(249, 115, 22)'
}
}}
>
diff --git a/packages/typescript/ai-preact-ui/src/chat-message.tsx b/packages/typescript/ai-preact-ui/src/chat-message.tsx
index 62543ab9..bf17b4c9 100644
--- a/packages/typescript/ai-preact-ui/src/chat-message.tsx
+++ b/packages/typescript/ai-preact-ui/src/chat-message.tsx
@@ -28,7 +28,10 @@ export interface ChatMessageProps {
isComplete?: boolean
}) => ComponentChildren
/** Named tool renderers - use the tool name as the key */
- toolsRenderer?: Record
ComponentChildren>
+ toolsRenderer?: Record<
+ string,
+ (props: ToolCallRenderProps) => ComponentChildren
+ >
/** Default tool renderer when tool name not found in toolsRenderer */
defaultToolRenderer?: (props: ToolCallRenderProps) => ComponentChildren
/** Custom renderer for tool result parts */
diff --git a/packages/typescript/ai-preact-ui/src/chat-messages.tsx b/packages/typescript/ai-preact-ui/src/chat-messages.tsx
index 3f1dd84a..30b62c6b 100644
--- a/packages/typescript/ai-preact-ui/src/chat-messages.tsx
+++ b/packages/typescript/ai-preact-ui/src/chat-messages.tsx
@@ -14,7 +14,10 @@ export interface ChatMessagesProps {
/** Element to show while loading the first message */
loadingState?: ComponentChildren
/** Custom error renderer */
- errorState?: (props: { error: Error; reload: () => void }) => ComponentChildren
+ errorState?: (props: {
+ error: Error
+ reload: () => void
+ }) => ComponentChildren
/** Auto-scroll to bottom on new messages */
autoScroll?: boolean
}
From 06f6f70cccfc003eed4eb854f2dc678687e76131 Mon Sep 17 00:00:00 2001
From: Jovi De Croock
Date: Wed, 14 Jan 2026 18:03:02 +0100
Subject: [PATCH 4/5] Bump preact-md
---
packages/typescript/ai-preact-ui/package.json | 2 +-
packages/typescript/ai-preact-ui/src/text-part.tsx | 1 -
pnpm-lock.yaml | 10 +++++-----
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/packages/typescript/ai-preact-ui/package.json b/packages/typescript/ai-preact-ui/package.json
index 53a99170..e9d5233c 100644
--- a/packages/typescript/ai-preact-ui/package.json
+++ b/packages/typescript/ai-preact-ui/package.json
@@ -36,7 +36,7 @@
],
"dependencies": {
"@tanstack/ai-preact": "workspace:*",
- "preact-md": "^0.2.0",
+ "preact-md": "^0.2.1",
"rehype-highlight": "^7.0.2",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.1"
diff --git a/packages/typescript/ai-preact-ui/src/text-part.tsx b/packages/typescript/ai-preact-ui/src/text-part.tsx
index 0a368319..6f61a3d7 100644
--- a/packages/typescript/ai-preact-ui/src/text-part.tsx
+++ b/packages/typescript/ai-preact-ui/src/text-part.tsx
@@ -73,7 +73,6 @@ export function TextPart({
return (
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 27b3f32f..4d05d95f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -783,8 +783,8 @@ importers:
specifier: '>=10.11.0'
version: 10.28.0
preact-md:
- specifier: ^0.2.0
- version: 0.2.0(preact@10.28.0)
+ specifier: ^0.2.1
+ version: 0.2.1(preact@10.28.0)
rehype-highlight:
specifier: ^7.0.2
version: 7.0.2
@@ -6589,8 +6589,8 @@ packages:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
- preact-md@0.2.0:
- resolution: {integrity: sha512-82C8cD5Ss60u30z6DxsyLdrI2yQZ7KGUdJ/QnA2N5lU0rUv+s3ZX0U3wiDTeoxu/E0Ck5QIFuRYkMeHZgeG5hw==}
+ preact-md@0.2.1:
+ resolution: {integrity: sha512-IvZDZGix3v22iSqY0Bypt879WAh2uui6lyBCl4q3kafG2N/DwRpWUasFfg+ohXIa9xp6E+cyWc1H+6k7fYge0A==}
peerDependencies:
preact: ^10.0.0
@@ -14384,7 +14384,7 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
- preact-md@0.2.0(preact@10.28.0):
+ preact-md@0.2.1(preact@10.28.0):
dependencies:
hast-util-sanitize: 5.0.2
marked: 17.0.1
From ef0d14f50eca63c685a3e6b2440eccb0c0d6e58a Mon Sep 17 00:00:00 2001
From: Jovi De Croock
Date: Wed, 14 Jan 2026 18:03:02 +0100
Subject: [PATCH 5/5] Bump preact-md
---
packages/typescript/ai-preact-ui/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/typescript/ai-preact-ui/README.md b/packages/typescript/ai-preact-ui/README.md
index deae147c..fb17ea36 100644
--- a/packages/typescript/ai-preact-ui/README.md
+++ b/packages/typescript/ai-preact-ui/README.md
@@ -5,14 +5,14 @@