From c7d4fb9e1eeb4050bd1bc73f73263c97af5dc08a Mon Sep 17 00:00:00 2001 From: Den Date: Thu, 14 May 2026 15:21:09 +0200 Subject: [PATCH 1/2] Align ColorToken & TypographyStyle with new design system tokens --- .../src/protocol/v1/customRenderer.ts | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/host-api/src/protocol/v1/customRenderer.ts b/packages/host-api/src/protocol/v1/customRenderer.ts index 9369d15a..80a57080 100644 --- a/packages/host-api/src/protocol/v1/customRenderer.ts +++ b/packages/host-api/src/protocol/v1/customRenderer.ts @@ -5,20 +5,26 @@ import { Option, Struct, Tuple, Vector, _void, bool, compact, str } from 'scale- export const Size = compact; export const Dimensions = Tuple(Size, Size, Option(Size), Option(Size)); -export const TypographyStyle = Status('titleXL', 'headline', 'bodyM', 'bodyS', 'caption'); +export const TypographyStyle = Status( + 'headline.large', + 'title.medium.regular', + 'body.large.regular', + 'body.medium.regular', + 'body.small.regular', +); export const ButtonVariant = Status('primary', 'secondary', 'text'); export const ColorToken = Status( - 'textPrimary', - 'textSecondary', - 'textTertiary', - 'backgroundPrimary', - 'backgroundSecondary', - 'backgroundTertiary', - 'success', - 'error', - 'warning', + 'fg.primary', + 'fg.secondary', + 'fg.tertiary', + 'bg.surface.main', + 'bg.surface.container', + 'bg.surface.nested', + 'fg.success', + 'fg.error', + 'fg.warning', ); export const ContentAlignment = Status( From 95e9b4651ee7248af698c95019dc549e35954a47 Mon Sep 17 00:00:00 2001 From: Den Date: Mon, 18 May 2026 14:54:31 +0200 Subject: [PATCH 2/2] fixed tests and readme --- __tests__/hostApi/chatReactRenderer.spec.tsx | 50 ++++++++--------- packages/product-react-renderer/README.md | 56 +++++++++---------- .../src/components.spec.tsx | 6 +- .../src/renderer.spec.tsx | 8 +-- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/__tests__/hostApi/chatReactRenderer.spec.tsx b/__tests__/hostApi/chatReactRenderer.spec.tsx index 2dac4f41..3588992f 100644 --- a/__tests__/hostApi/chatReactRenderer.spec.tsx +++ b/__tests__/hostApi/chatReactRenderer.spec.tsx @@ -111,18 +111,18 @@ describe('registerChatMessageRenderer + createProductChatManager integration', ( {/* Box A: contentAlignment, background+Rounded shape, border, fillMaxWidth */} - + Title {/* Box B: background as plain ColorToken, width/height/minWidth/minHeight */} {/* Inner Box: Circle shape, fillMaxWidth + fillMaxHeight */} {/* Row: verticalAlignment, horizontalArrangement, margin; covers bodyM/bodyS/caption + success/warning/error */} - + Item A - + Item B - + Item C - + Balance: 100 DOT {/* Spacer with fillMaxHeight */} @@ -221,26 +221,26 @@ describe('registerChatMessageRenderer + createProductChatManager integration', ( const boxAMods = boxA.value.modifiers as RendererModifier[]; expect(boxAMods).toContainEqual({ tag: 'background', - value: { color: 'backgroundSecondary', shape: { tag: 'Rounded', value: 8 } }, + value: { color: 'bg.surface.container', shape: { tag: 'Rounded', value: 8 } }, }); expect(boxAMods).toContainEqual({ tag: 'border', - value: { width: 1, color: 'textTertiary', shape: undefined }, + value: { width: 1, color: 'fg.tertiary', shape: undefined }, }); expect(boxAMods).toContainEqual({ tag: 'fillWidth', value: true }); - // Box A > Text: titleXL + textSecondary + // Box A > Text: title.medium.regular + fg.secondary const boxAText = boxA.value.children[0]; expect(boxAText.tag).toBe('Text'); - expect(boxAText.value.props.style).toBe('titleXL'); - expect(boxAText.value.props.color).toBe('textSecondary'); + expect(boxAText.value.props.style).toBe('title.medium.regular'); + expect(boxAText.value.props.color).toBe('fg.secondary'); expect(boxAText.value.children[0]).toEqual({ tag: 'String', value: 'Title' }); // Box B: contentAlignment, background as plain color token, width/height/minWidth/minHeight expect(boxB.tag).toBe('Box'); expect(boxB.value.props.contentAlignment).toBe('center'); const boxBMods = boxB.value.modifiers as RendererModifier[]; - expect(boxBMods).toContainEqual({ tag: 'background', value: { color: 'backgroundPrimary', shape: undefined } }); + expect(boxBMods).toContainEqual({ tag: 'background', value: { color: 'bg.surface.main', shape: undefined } }); expect(boxBMods).toContainEqual({ tag: 'width', value: 40 }); expect(boxBMods).toContainEqual({ tag: 'height', value: 40 }); expect(boxBMods).toContainEqual({ tag: 'minWidth', value: 20 }); @@ -252,7 +252,7 @@ describe('registerChatMessageRenderer + createProductChatManager integration', ( const innerBoxMods = innerBox.value.modifiers as RendererModifier[]; expect(innerBoxMods).toContainEqual({ tag: 'background', - value: { color: 'backgroundTertiary', shape: { tag: 'Circle', value: undefined } }, + value: { color: 'bg.surface.nested', shape: { tag: 'Circle', value: undefined } }, }); expect(innerBoxMods).toContainEqual({ tag: 'fillWidth', value: true }); expect(innerBoxMods).toContainEqual({ tag: 'fillHeight', value: true }); @@ -267,8 +267,8 @@ describe('registerChatMessageRenderer + createProductChatManager integration', ( // Row > Text: bodyM + success const rowTextA = rowNode.value.children[0]; expect(rowTextA.tag).toBe('Text'); - expect(rowTextA.value.props.style).toBe('bodyM'); - expect(rowTextA.value.props.color).toBe('success'); + expect(rowTextA.value.props.style).toBe('body.medium.regular'); + expect(rowTextA.value.props.color).toBe('fg.success'); expect(rowTextA.value.children[0]).toEqual({ tag: 'String', value: 'Item A' }); // Row > Spacer: width + height modifiers @@ -281,21 +281,21 @@ describe('registerChatMessageRenderer + createProductChatManager integration', ( // Row > Text: bodyS + warning const rowTextB = rowNode.value.children[2]; expect(rowTextB.tag).toBe('Text'); - expect(rowTextB.value.props.style).toBe('bodyS'); - expect(rowTextB.value.props.color).toBe('warning'); + expect(rowTextB.value.props.style).toBe('body.small.regular'); + expect(rowTextB.value.props.color).toBe('fg.warning'); expect(rowTextB.value.children[0]).toEqual({ tag: 'String', value: 'Item B' }); // Row > Text: caption + error const rowTextC = rowNode.value.children[3]; expect(rowTextC.tag).toBe('Text'); - expect(rowTextC.value.props.style).toBe('caption'); - expect(rowTextC.value.props.color).toBe('error'); + expect(rowTextC.value.props.style).toBe('body.small.regular'); + expect(rowTextC.value.props.color).toBe('fg.error'); expect(rowTextC.value.children[0]).toEqual({ tag: 'String', value: 'Item C' }); - // Text: headline + textPrimary + // Text: headline.large + fg.primary expect(headlineText.tag).toBe('Text'); - expect(headlineText.value.props.style).toBe('headline'); - expect(headlineText.value.props.color).toBe('textPrimary'); + expect(headlineText.value.props.style).toBe('headline.large'); + expect(headlineText.value.props.color).toBe('fg.primary'); expect(headlineText.value.children[0]).toEqual({ tag: 'String', value: 'Balance: 100 DOT' }); // Spacer: fillMaxHeight diff --git a/packages/product-react-renderer/README.md b/packages/product-react-renderer/README.md index 7eab5874..1028f9b1 100644 --- a/packages/product-react-renderer/README.md +++ b/packages/product-react-renderer/README.md @@ -46,7 +46,7 @@ import { registerChatMessageRenderer, Text } from '@novasamatech/product-react-r chat.onCustomMessageRenderingRequest( registerChatMessageRenderer( () => undefined, - () => Hello from the product!, + () => Hello from the product!, ), ); ``` @@ -65,8 +65,8 @@ chat.onCustomMessageRenderingRequest( raw => JSON.parse(new TextDecoder().decode(raw)) as BalancePayload, ({ payload }) => ( - {payload.amount} - {payload.token} + {payload.amount} + {payload.token} ), ), @@ -85,7 +85,7 @@ function VoteWidget() { const [votes, setVotes] = useState(0); return ( - Votes: {votes} + Votes: {votes}