From 8561d73eafc6f492eef7671d74ba26f074f7b0a5 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Tue, 21 Jul 2026 02:32:03 +0300 Subject: [PATCH] fix(demo): restore showcase validation - Replace nested tone branches with a typed color map - Cover the rebuilt component library and analytics demo --- src/app/demo/sections/app-preview.ts | 31 ++++++++++++------------- tests/engine/app/demo.test.ts | 34 ++++++++-------------------- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/src/app/demo/sections/app-preview.ts b/src/app/demo/sections/app-preview.ts index 387f12f71..fef05b555 100644 --- a/src/app/demo/sections/app-preview.ts +++ b/src/app/demo/sections/app-preview.ts @@ -1,3 +1,5 @@ +import type { Color } from '@open-pencil/scene-graph' + import { DEMO_COLORS, gradient, solid, thinStroke } from '@/app/demo/colors' import type { EditorStore } from '@/app/editor/session' @@ -10,6 +12,14 @@ interface DemoComponents { toggleComp: string } +type StatTone = 'success' | 'accent' | 'danger' + +const STAT_TONE_COLORS: Record = { + success: { foreground: DEMO_COLORS.success, background: DEMO_COLORS.successSoft }, + accent: { foreground: DEMO_COLORS.accent, background: DEMO_COLORS.accentSoft }, + danger: { foreground: DEMO_COLORS.danger, background: DEMO_COLORS.dangerSoft } +} + /** * One cohesive product screen assembled from INSTANCEs of the component * library, laid out with real auto-layout, and themed via bound variables. @@ -193,25 +203,14 @@ export function createAppPreviewSection(store: EditorStore, comps: DemoComponent }) const badge = graph.createInstance(comps.badgeComp, card) if (badge) { - const tone = - s.tone === 'success' - ? DEMO_COLORS.success - : s.tone === 'danger' - ? DEMO_COLORS.danger - : DEMO_COLORS.accent - const toneSoft = - s.tone === 'success' - ? DEMO_COLORS.successSoft - : s.tone === 'danger' - ? DEMO_COLORS.dangerSoft - : DEMO_COLORS.accentSoft + const tone = STAT_TONE_COLORS[s.tone] const bLabel = badge.childIds.map((cid) => graph.getNode(cid)).find((n) => n?.type === 'TEXT') if (bLabel) { const overrides: Record = { ...badge.overrides } - graph.updateNode(bLabel.id, { text: s.trend, fills: [solid(tone)] }) + graph.updateNode(bLabel.id, { text: s.trend, fills: [solid(tone.foreground)] }) overrides[`${bLabel.id}:text`] = s.trend - overrides[`${bLabel.id}:fills`] = [solid(tone)] - graph.updateNode(badge.id, { fills: [solid(toneSoft)], overrides }) + overrides[`${bLabel.id}:fills`] = [solid(tone.foreground)] + graph.updateNode(badge.id, { fills: [solid(tone.background)], overrides }) statBadges.push({ id: badge.id, labelId: bLabel.id, tone: s.tone }) } } @@ -311,5 +310,5 @@ export function createAppPreviewSection(store: EditorStore, comps: DemoComponent interface StatBadge { id: string labelId: string - tone: 'success' | 'accent' | 'danger' + tone: StatTone } diff --git a/tests/engine/app/demo.test.ts b/tests/engine/app/demo.test.ts index c4d4e1478..2fd59c72c 100644 --- a/tests/engine/app/demo.test.ts +++ b/tests/engine/app/demo.test.ts @@ -1,36 +1,20 @@ import { describe, expect, test } from 'bun:test' -import { createStandaloneShapes } from '@/app/demo/sections/standalone' +import { createDemoShapes } from '@/app/demo/document' import { createEditorStore } from '@/app/editor/session' describe('demo document', () => { - test('showcases imported OpenType and text decoration features', () => { + test('builds the component library and analytics showcase', () => { const store = createEditorStore() - createStandaloneShapes(store) + createDemoShapes(store) const nodes = [...store.graph.getAllNodes()] - const ligatures = nodes.find((node) => node.name === 'Ligatures') - const rawTags = nodes.find((node) => node.name === 'Raw') - const wavy = nodes.find((node) => node.name === 'Wavy') - const dotted = nodes.find((node) => node.name === 'Dotted') - - expect(ligatures?.fontFeatures).toEqual([{ tag: 'LIGA', enabled: false }]) - expect(rawTags?.fontFeatures).toEqual([ - { tag: 'DLIG', enabled: true }, - { tag: 'KERN', enabled: false } - ]) - expect(wavy).toMatchObject({ - textDecoration: 'UNDERLINE', - textDecorationStyle: 'WAVY', - textDecorationThickness: 1.6 - }) - expect(wavy?.textDecorationFills[0]?.type).toBe('SOLID') - expect(dotted).toMatchObject({ - textDecoration: 'UNDERLINE', - textDecorationStyle: 'DOTTED', - textDecorationThickness: 2 - }) - expect(dotted?.textDecorationFills[0]?.type).toBe('SOLID') + expect(nodes.some((node) => node.name === 'Component Library')).toBe(true) + expect(nodes.some((node) => node.name === 'App — Analytics')).toBe(true) + expect(nodes.some((node) => node.name === 'Chart')).toBe(true) + expect(nodes.filter((node) => node.type === 'COMPONENT').length).toBeGreaterThanOrEqual(6) + expect(nodes.filter((node) => node.type === 'INSTANCE').length).toBeGreaterThan(6) + expect(store.graph.variables.size).toBeGreaterThan(0) }) })