diff --git a/src/app/demo/document.ts b/src/app/demo/document.ts index 2eec3fed6..15efa0460 100644 --- a/src/app/demo/document.ts +++ b/src/app/demo/document.ts @@ -1,5 +1,6 @@ import { computeAllLayouts } from '@open-pencil/core/layout' +import { DEMO_COLORS, solid } from '@/app/demo/colors' import { createAppPreviewSection } from '@/app/demo/sections/app-preview' import { createComponentsSection } from '@/app/demo/sections/components' import { createDemoVariables } from '@/app/demo/sections/variables' @@ -19,6 +20,25 @@ export function createDemoShapes(store: EditorStore) { graph.bindVariable(app.chartTitle, 'fills/0/color', 'var-text-primary') computeAllLayouts(graph) + + // Apply badge tones after layout so component sync doesn't revert them. + const toneColors = { + success: [DEMO_COLORS.successSoft, DEMO_COLORS.success], + accent: [DEMO_COLORS.accentSoft, DEMO_COLORS.accent], + danger: [DEMO_COLORS.dangerSoft, DEMO_COLORS.danger] + } as const + for (const b of app.statBadges) { + const [soft, strong] = toneColors[b.tone] + const badge = graph.getNode(b.id) + if (!badge) continue + // Record the label fill as an override so component sync preserves it. + graph.updateNode(b.labelId, { fills: [solid(strong)] }) + graph.updateNode(b.id, { + fills: [solid(soft)], + overrides: { ...badge.overrides, [`${b.labelId}:fills`]: [solid(strong)] } + }) + } + store.clearSelection() void store.loadFontsForNodes(graph.getPages().flatMap((page) => page.childIds)).then(() => { store.requestRender() diff --git a/src/app/demo/sections/app-preview.ts b/src/app/demo/sections/app-preview.ts index a0985cca5..387f12f71 100644 --- a/src/app/demo/sections/app-preview.ts +++ b/src/app/demo/sections/app-preview.ts @@ -154,6 +154,7 @@ export function createAppPreviewSection(store: EditorStore, comps: DemoComponent { title: 'Churn', value: '1.9%', trend: '-3%', tone: 'danger' as const } ] + const statBadges: StatBadge[] = [] stats.forEach((s) => { const card = store.createShape('FRAME', 0, 0, 148, 96, statRow) graph.updateNode(card, { @@ -192,13 +193,6 @@ export function createAppPreviewSection(store: EditorStore, comps: DemoComponent }) const badge = graph.createInstance(comps.badgeComp, card) if (badge) { - const bLabel = badge.childIds.map((cid) => graph.getNode(cid)).find((n) => n?.type === 'TEXT') - if (bLabel) { - graph.updateNode(bLabel.id, { text: s.trend }) - graph.updateNode(badge.id, { - overrides: { ...badge.overrides, [`${bLabel.id}:text`]: s.trend } - }) - } const tone = s.tone === 'success' ? DEMO_COLORS.success @@ -211,8 +205,15 @@ export function createAppPreviewSection(store: EditorStore, comps: DemoComponent : s.tone === 'danger' ? DEMO_COLORS.dangerSoft : DEMO_COLORS.accentSoft - graph.updateNode(badge.id, { fills: [solid(toneSoft)] }) - if (bLabel) graph.updateNode(bLabel.id, { fills: [solid(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)] }) + overrides[`${bLabel.id}:text`] = s.trend + overrides[`${bLabel.id}:fills`] = [solid(tone)] + graph.updateNode(badge.id, { fills: [solid(toneSoft)], overrides }) + statBadges.push({ id: badge.id, labelId: bLabel.id, tone: s.tone }) + } } }) @@ -304,5 +305,11 @@ export function createAppPreviewSection(store: EditorStore, comps: DemoComponent fills: [solid(DEMO_COLORS.accentText)] }) - return { sectionId, sidebar, main, headerTitle, chartTitle } + return { sectionId, sidebar, main, headerTitle, chartTitle, statBadges } +} + +interface StatBadge { + id: string + labelId: string + tone: 'success' | 'accent' | 'danger' }