From 51b97246a8a3255a308c361221d9404a82f5700b Mon Sep 17 00:00:00 2001 From: vince Date: Thu, 18 Jun 2026 20:07:03 +0200 Subject: [PATCH] feat(ui): add decorative style primitives --- .../ui/components/CornerBracketFrame.svelte | 97 +++++++++++++++ .../ui/components/DiagonalStripeField.svelte | 77 ++++++++++++ src/lib/ui/components/ScanlineField.svelte | 66 +++++++++++ src/lib/ui/components/SignalTrace.svelte | 112 ++++++++++++++++++ src/lib/ui/index.ts | 4 + .../stories/CornerBracketFrame.stories.svelte | 22 ++++ .../DiagonalStripeField.stories.svelte | 23 ++++ .../ui/stories/ScanlineField.stories.svelte | 20 ++++ src/lib/ui/stories/SignalTrace.stories.svelte | 21 ++++ src/lib/ui/storybook.test.ts | 34 ++++++ 10 files changed, 476 insertions(+) create mode 100644 src/lib/ui/components/CornerBracketFrame.svelte create mode 100644 src/lib/ui/components/DiagonalStripeField.svelte create mode 100644 src/lib/ui/components/ScanlineField.svelte create mode 100644 src/lib/ui/components/SignalTrace.svelte create mode 100644 src/lib/ui/stories/CornerBracketFrame.stories.svelte create mode 100644 src/lib/ui/stories/DiagonalStripeField.stories.svelte create mode 100644 src/lib/ui/stories/ScanlineField.stories.svelte create mode 100644 src/lib/ui/stories/SignalTrace.stories.svelte diff --git a/src/lib/ui/components/CornerBracketFrame.svelte b/src/lib/ui/components/CornerBracketFrame.svelte new file mode 100644 index 0000000..ffda881 --- /dev/null +++ b/src/lib/ui/components/CornerBracketFrame.svelte @@ -0,0 +1,97 @@ + + + + + diff --git a/src/lib/ui/components/DiagonalStripeField.svelte b/src/lib/ui/components/DiagonalStripeField.svelte new file mode 100644 index 0000000..0af4b99 --- /dev/null +++ b/src/lib/ui/components/DiagonalStripeField.svelte @@ -0,0 +1,77 @@ + + + + + diff --git a/src/lib/ui/components/ScanlineField.svelte b/src/lib/ui/components/ScanlineField.svelte new file mode 100644 index 0000000..4514830 --- /dev/null +++ b/src/lib/ui/components/ScanlineField.svelte @@ -0,0 +1,66 @@ + + + + + diff --git a/src/lib/ui/components/SignalTrace.svelte b/src/lib/ui/components/SignalTrace.svelte new file mode 100644 index 0000000..6826336 --- /dev/null +++ b/src/lib/ui/components/SignalTrace.svelte @@ -0,0 +1,112 @@ + + + + + diff --git a/src/lib/ui/index.ts b/src/lib/ui/index.ts index 8c312fc..398bcbe 100644 --- a/src/lib/ui/index.ts +++ b/src/lib/ui/index.ts @@ -1,7 +1,9 @@ export { default as Badge } from "./components/Badge.svelte"; export { default as Button } from "./components/Button.svelte"; +export { default as CornerBracketFrame } from "./components/CornerBracketFrame.svelte"; export { default as DashboardHeader } from "./components/DashboardHeader.svelte"; export { default as DashboardFrame } from "./components/DashboardFrame.svelte"; +export { default as DiagonalStripeField } from "./components/DiagonalStripeField.svelte"; export { default as FooterCell } from "./components/FooterCell.svelte"; export { default as FooterStatusCell } from "./components/FooterStatusCell.svelte"; export { default as GridFrame } from "./components/GridFrame.svelte"; @@ -14,6 +16,8 @@ export { default as Separator } from "./components/Separator.svelte"; export { default as ServiceGroupPanel } from "./components/ServiceGroupPanel.svelte"; export { default as ServicePanel } from "./components/ServicePanel.svelte"; export { default as ServiceRow } from "./components/ServiceRow.svelte"; +export { default as ScanlineField } from "./components/ScanlineField.svelte"; +export { default as SignalTrace } from "./components/SignalTrace.svelte"; export { default as Sparkline } from "./components/Sparkline.svelte"; export { default as StatusBadge } from "./components/StatusBadge.svelte"; export { default as StatusStrip } from "./components/StatusStrip.svelte"; diff --git a/src/lib/ui/stories/CornerBracketFrame.stories.svelte b/src/lib/ui/stories/CornerBracketFrame.stories.svelte new file mode 100644 index 0000000..70b8b2a --- /dev/null +++ b/src/lib/ui/stories/CornerBracketFrame.stories.svelte @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/src/lib/ui/stories/DiagonalStripeField.stories.svelte b/src/lib/ui/stories/DiagonalStripeField.stories.svelte new file mode 100644 index 0000000..f1dcb77 --- /dev/null +++ b/src/lib/ui/stories/DiagonalStripeField.stories.svelte @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/src/lib/ui/stories/ScanlineField.stories.svelte b/src/lib/ui/stories/ScanlineField.stories.svelte new file mode 100644 index 0000000..cc993f7 --- /dev/null +++ b/src/lib/ui/stories/ScanlineField.stories.svelte @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/src/lib/ui/stories/SignalTrace.stories.svelte b/src/lib/ui/stories/SignalTrace.stories.svelte new file mode 100644 index 0000000..0130817 --- /dev/null +++ b/src/lib/ui/stories/SignalTrace.stories.svelte @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/lib/ui/storybook.test.ts b/src/lib/ui/storybook.test.ts index 226eea8..172526e 100644 --- a/src/lib/ui/storybook.test.ts +++ b/src/lib/ui/storybook.test.ts @@ -12,6 +12,8 @@ const requiredStoryFiles = [ "DashboardFrame.stories.svelte", "DashboardHeader.stories.svelte", "DashboardOnePager.stories.svelte", + "CornerBracketFrame.stories.svelte", + "DiagonalStripeField.stories.svelte", "FooterCell.stories.svelte", "FooterStatusCell.stories.svelte", "GridFrame.stories.svelte", @@ -24,10 +26,12 @@ const requiredStoryFiles = [ "ServiceGroupPanel.stories.svelte", "ServicePanel.stories.svelte", "ServiceRow.stories.svelte", + "SignalTrace.stories.svelte", "Sparkline.stories.svelte", "StatusBadge.stories.svelte", "StatusStrip.stories.svelte", "SystemState.stories.svelte", + "ScanlineField.stories.svelte", "TelemetryCard.stories.svelte", "TelemetryGrid.stories.svelte", "TelemetryStrip.stories.svelte", @@ -79,6 +83,36 @@ describe("Storybook inventory", () => { } }); + test("includes style-only decorative primitives in the reusable UI inventory", () => { + for (const component of [ + "CornerBracketFrame", + "DiagonalStripeField", + "ScanlineField", + "SignalTrace", + ]) { + expect(existsSync(join(componentsDir, `${component}.svelte`)), `${component} is missing`).toBe( + true, + ); + expect( + existsSync(join(storiesDir, `${component}.stories.svelte`)), + `${component}.stories.svelte is missing`, + ).toBe(true); + } + }); + + test("keeps decorative primitives hidden from assistive technology", () => { + for (const component of [ + "CornerBracketFrame", + "DiagonalStripeField", + "ScanlineField", + "SignalTrace", + ]) { + const source = readFileSync(join(componentsDir, `${component}.svelte`), "utf8"); + + expect(source).toContain('aria-hidden="true"'); + } + }); + test("does not add deferred form/navigation primitives", () => { for (const component of ["Input", "ToggleGroup", "ScrollArea"]) { expect(existsSync(join(root, `src/lib/ui/components/${component}.svelte`))).toBe(false); -- 2.49.1