@lilydesignsystem/svelte-headless 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/components/CandlestickChart/CandlestickChart.svelte +63 -0
  3. package/dist/components/CandlestickChart/CandlestickChart.svelte.d.ts +13 -0
  4. package/dist/components/ChatComposer/ChatComposer.svelte +110 -0
  5. package/dist/components/ChatComposer/ChatComposer.svelte.d.ts +25 -0
  6. package/dist/components/ChoroplethChart/ChoroplethChart.svelte +63 -0
  7. package/dist/components/ChoroplethChart/ChoroplethChart.svelte.d.ts +13 -0
  8. package/dist/components/ComposedChart/ComposedChart.svelte +63 -0
  9. package/dist/components/ComposedChart/ComposedChart.svelte.d.ts +13 -0
  10. package/dist/components/FunnelChart/FunnelChart.svelte +63 -0
  11. package/dist/components/FunnelChart/FunnelChart.svelte.d.ts +13 -0
  12. package/dist/components/Mark/Mark.svelte +27 -0
  13. package/dist/components/Mark/Mark.svelte.d.ts +9 -0
  14. package/dist/components/PieChart/PieChart.svelte +63 -0
  15. package/dist/components/PieChart/PieChart.svelte.d.ts +13 -0
  16. package/dist/components/RingChart/RingChart.svelte +63 -0
  17. package/dist/components/RingChart/RingChart.svelte.d.ts +13 -0
  18. package/dist/components/StreamingText/StreamingText.svelte +48 -0
  19. package/dist/components/StreamingText/StreamingText.svelte.d.ts +13 -0
  20. package/dist/components/SunburstChart/SunburstChart.svelte +63 -0
  21. package/dist/components/SunburstChart/SunburstChart.svelte.d.ts +13 -0
  22. package/dist/components/ToolCall/ToolCall.svelte +54 -0
  23. package/dist/components/ToolCall/ToolCall.svelte.d.ts +15 -0
  24. package/dist/components/ToolCallError/ToolCallError.svelte +27 -0
  25. package/dist/components/ToolCallError/ToolCallError.svelte.d.ts +9 -0
  26. package/dist/components/ToolCallInput/ToolCallInput.svelte +30 -0
  27. package/dist/components/ToolCallInput/ToolCallInput.svelte.d.ts +11 -0
  28. package/dist/components/ToolCallName/ToolCallName.svelte +27 -0
  29. package/dist/components/ToolCallName/ToolCallName.svelte.d.ts +9 -0
  30. package/dist/components/ToolCallOutput/ToolCallOutput.svelte +30 -0
  31. package/dist/components/ToolCallOutput/ToolCallOutput.svelte.d.ts +11 -0
  32. package/dist/components/ToolCallStatus/ToolCallStatus.svelte +29 -0
  33. package/dist/components/ToolCallStatus/ToolCallStatus.svelte.d.ts +11 -0
  34. package/dist/index.d.ts +16 -0
  35. package/dist/index.js +16 -0
  36. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  The format is loosely based on [Keep a Changelog](https://keepachangelog.com/)
4
4
  and the package follows [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## 0.4.0 — 2026-10-06
7
+
8
+ **16 new components (catalog 555 → 571); no breaking changes.**
9
+ Seven charts built with the graphic + optional data-table structure
10
+ introduced in the previous release: `pie-chart`, `ring-chart`,
11
+ `funnel-chart`, `candlestick-chart`, `composed-chart`, `choropleth-chart`,
12
+ `sunburst-chart`. `streaming-text` (a polite, atomic status region that goes
13
+ busy while text arrives, then announces the finished text once). `tool-call`
14
+ (a native `<details>` with `status`) and its inner parts `tool-call-name`,
15
+ `tool-call-status`, `tool-call-input`, `tool-call-output`, `tool-call-error`.
16
+ `mark` (the native `<mark>` highlight). `chat-composer` (a chat input form:
17
+ growing textarea, Enter sends, Shift+Enter inserts a line break, IME-safe, one
18
+ button that is send or stop). See the monorepo CHANGELOG for the full record
19
+ and the per-library deviations (Blazor: no plain-Enter send; Nunjucks and
20
+ HTML: markup-only `chat-composer`).
21
+
6
22
  ## 0.3.0 — 2026-10-05
7
23
 
8
24
  **16 new components (catalog 539 → 555) and a breaking chart change.**
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // CandlestickChart component
3
+ //
4
+ // A headless chart container for a financial chart showing open, high, low and close values for each period as candles. The consumer supplies the inline
5
+ // svg as `children`; the component draws nothing. The graphic is a
6
+ // role="img" wrapper named by `label`. The optional `dataTable` snippet
7
+ // renders the accessible table alternative as a SIBLING of that image
8
+ // wrapper, never inside it: a role="img" element makes its descendants
9
+ // presentational, so a table placed inside would be invisible to
10
+ // assistive technology.
11
+ //
12
+ // Props:
13
+ // class — string, optional. Consumer class appended after the base class.
14
+ // label — string, optional. Accessible name of the chart image.
15
+ // children — Snippet. The consumer-supplied inline svg.
16
+ // dataTable — Snippet, optional. The accessible table alternative.
17
+ // ...restProps — spread onto the root <figure>.
18
+ //
19
+ // Markup:
20
+ // <figure class="candlestick-chart">
21
+ // <div class="candlestick-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="candlestick-chart-data-table">…table…</div> (only when provided)
23
+ // </figure>
24
+ //
25
+ // Keyboard: none on the graphic; the data table follows native table behaviour.
26
+ //
27
+ // Claude rules:
28
+ // - Headless: no CSS, no inline styles; no drawing.
29
+ // - No hardcoded user-facing strings.
30
+
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label = undefined,
36
+ children,
37
+ dataTable,
38
+ ...restProps
39
+ }: {
40
+ /** Accessible name for the chart. */
41
+ label?: string;
42
+ /** The consumer-supplied inline svg. */
43
+ children: Snippet;
44
+ /** Optional accessible data table alternative. */
45
+ dataTable?: Snippet;
46
+ [key: string]: unknown;
47
+ } = $props();
48
+ </script>
49
+
50
+ <!-- CandlestickChart.svelte -->
51
+ <figure
52
+ class={`candlestick-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="candlestick-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="candlestick-chart-data-table">
60
+ {@render dataTable()}
61
+ </div>
62
+ {/if}
63
+ </figure>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name for the chart. */
4
+ label?: string;
5
+ /** The consumer-supplied inline svg. */
6
+ children: Snippet;
7
+ /** Optional accessible data table alternative. */
8
+ dataTable?: Snippet;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const CandlestickChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type CandlestickChart = ReturnType<typeof CandlestickChart>;
13
+ export default CandlestickChart;
@@ -0,0 +1,110 @@
1
+ <script lang="ts">
2
+ // ChatComposer component
3
+ //
4
+ // A headless chat input form: a <textarea> that grows with its content (rows from the number of lines, clamped between minRows and maxRows) and ONE button that is "send" normally and turns into "stop" while `busy`. Enter sends; Shift+Enter inserts a line break; Enter while an IME composition is in progress does nothing. The send button is disabled, never hidden, when the text is empty or the form is disabled. The component never clears the text (the consumer does, in its send handler), never animates, and carries no strings: the textarea name, the send word and the stop word are required props. Models, attachments and menus are consumer composition (put them in the default slot, rendered before the textarea).
5
+ //
6
+ // Props:
7
+ // class — string, optional. CSS class name.
8
+ // label — string, required. Accessible name of the textarea.
9
+ // sendLabel — string, required. Visible/accessible word for the send button.
10
+ // stopLabel — string, required. Visible/accessible word for the stop button.
11
+ // value — string, default "". Bindable.
12
+ // placeholder, name — optional, passed to the textarea.
13
+ // minRows — number, default 1. maxRows — number, default 8.
14
+ // busy — boolean, default false. A reply is in progress: the button becomes "stop".
15
+ // disabled — boolean, default false.
16
+ // onSend(value) — called on Enter or submit when there is text and not busy/disabled.
17
+ // onStop() — called when the stop button is pressed.
18
+ // children — Snippet, optional. Rendered inside the form, before the textarea.
19
+ // ...restProps — additional HTML attributes spread onto the root <form>.
20
+ //
21
+ // Keyboard: Enter sends; Shift+Enter inserts a line break; Enter during IME composition is ignored.
22
+ //
23
+ // Claude rules:
24
+ // - Headless: no CSS, no inline styles, no animation, no hardcoded strings
25
+ import type { Snippet } from "svelte";
26
+
27
+ let {
28
+ class: className = "",
29
+ label,
30
+ sendLabel,
31
+ stopLabel,
32
+ value = $bindable(""),
33
+ placeholder = undefined,
34
+ name = undefined,
35
+ minRows = 1,
36
+ maxRows = 8,
37
+ busy = false,
38
+ disabled = false,
39
+ onSend,
40
+ onStop,
41
+ children,
42
+ ...restProps
43
+ }: {
44
+ /** Accessible name of the textarea. */
45
+ label: string;
46
+ /** Word for the send button. */
47
+ sendLabel: string;
48
+ /** Word for the stop button. */
49
+ stopLabel: string;
50
+ /** The text. Bindable. */
51
+ value?: string;
52
+ placeholder?: string;
53
+ name?: string;
54
+ minRows?: number;
55
+ maxRows?: number;
56
+ /** A reply is in progress. */
57
+ busy?: boolean;
58
+ disabled?: boolean;
59
+ onSend?: (value: string) => void;
60
+ onStop?: () => void;
61
+ children?: Snippet;
62
+ [key: string]: unknown;
63
+ } = $props();
64
+
65
+ const empty = $derived(value.trim() === "");
66
+ const rows = $derived(Math.min(maxRows, Math.max(minRows, value.split("\n").length)));
67
+
68
+ function trySend(): void {
69
+ if (disabled || busy || empty) return;
70
+ onSend?.(value);
71
+ }
72
+
73
+ function onKeydown(event: KeyboardEvent): void {
74
+ if (event.key !== "Enter") return;
75
+ if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) return;
76
+ // IME: Enter that confirms a composition must not send.
77
+ if (event.isComposing || event.keyCode === 229) return;
78
+ event.preventDefault();
79
+ trySend();
80
+ }
81
+
82
+ function onSubmit(event: SubmitEvent): void {
83
+ event.preventDefault();
84
+ trySend();
85
+ }
86
+ </script>
87
+
88
+ <!-- ChatComposer.svelte -->
89
+ <form class={`chat-composer ${className}`} onsubmit={onSubmit} {...restProps}>
90
+ {@render children?.()}
91
+ <textarea
92
+ class="chat-composer-input"
93
+ aria-label={label}
94
+ bind:value
95
+ {rows}
96
+ {placeholder}
97
+ {name}
98
+ {disabled}
99
+ onkeydown={onKeydown}
100
+ ></textarea>
101
+ <button
102
+ class="chat-composer-button"
103
+ type={busy ? "button" : "submit"}
104
+ data-state={busy ? "stop" : "send"}
105
+ disabled={disabled || (!busy && empty)}
106
+ onclick={busy ? () => onStop?.() : undefined}
107
+ >
108
+ <span class="chat-composer-button-label">{busy ? stopLabel : sendLabel}</span>
109
+ </button>
110
+ </form>
@@ -0,0 +1,25 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name of the textarea. */
4
+ label: string;
5
+ /** Word for the send button. */
6
+ sendLabel: string;
7
+ /** Word for the stop button. */
8
+ stopLabel: string;
9
+ /** The text. Bindable. */
10
+ value?: string;
11
+ placeholder?: string;
12
+ name?: string;
13
+ minRows?: number;
14
+ maxRows?: number;
15
+ /** A reply is in progress. */
16
+ busy?: boolean;
17
+ disabled?: boolean;
18
+ onSend?: (value: string) => void;
19
+ onStop?: () => void;
20
+ children?: Snippet;
21
+ [key: string]: unknown;
22
+ };
23
+ declare const ChatComposer: import("svelte").Component<$$ComponentProps, {}, "value">;
24
+ type ChatComposer = ReturnType<typeof ChatComposer>;
25
+ export default ChatComposer;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // ChoroplethChart component
3
+ //
4
+ // A headless chart container for a map chart that shades regions by the value of a measure. The consumer supplies the inline
5
+ // svg as `children`; the component draws nothing. The graphic is a
6
+ // role="img" wrapper named by `label`. The optional `dataTable` snippet
7
+ // renders the accessible table alternative as a SIBLING of that image
8
+ // wrapper, never inside it: a role="img" element makes its descendants
9
+ // presentational, so a table placed inside would be invisible to
10
+ // assistive technology.
11
+ //
12
+ // Props:
13
+ // class — string, optional. Consumer class appended after the base class.
14
+ // label — string, optional. Accessible name of the chart image.
15
+ // children — Snippet. The consumer-supplied inline svg.
16
+ // dataTable — Snippet, optional. The accessible table alternative.
17
+ // ...restProps — spread onto the root <figure>.
18
+ //
19
+ // Markup:
20
+ // <figure class="choropleth-chart">
21
+ // <div class="choropleth-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="choropleth-chart-data-table">…table…</div> (only when provided)
23
+ // </figure>
24
+ //
25
+ // Keyboard: none on the graphic; the data table follows native table behaviour.
26
+ //
27
+ // Claude rules:
28
+ // - Headless: no CSS, no inline styles; no drawing.
29
+ // - No hardcoded user-facing strings.
30
+
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label = undefined,
36
+ children,
37
+ dataTable,
38
+ ...restProps
39
+ }: {
40
+ /** Accessible name for the chart. */
41
+ label?: string;
42
+ /** The consumer-supplied inline svg. */
43
+ children: Snippet;
44
+ /** Optional accessible data table alternative. */
45
+ dataTable?: Snippet;
46
+ [key: string]: unknown;
47
+ } = $props();
48
+ </script>
49
+
50
+ <!-- ChoroplethChart.svelte -->
51
+ <figure
52
+ class={`choropleth-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="choropleth-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="choropleth-chart-data-table">
60
+ {@render dataTable()}
61
+ </div>
62
+ {/if}
63
+ </figure>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name for the chart. */
4
+ label?: string;
5
+ /** The consumer-supplied inline svg. */
6
+ children: Snippet;
7
+ /** Optional accessible data table alternative. */
8
+ dataTable?: Snippet;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const ChoroplethChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type ChoroplethChart = ReturnType<typeof ChoroplethChart>;
13
+ export default ChoroplethChart;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // ComposedChart component
3
+ //
4
+ // A headless chart container for a chart that combines several chart types, such as bars and a line, on shared axes. The consumer supplies the inline
5
+ // svg as `children`; the component draws nothing. The graphic is a
6
+ // role="img" wrapper named by `label`. The optional `dataTable` snippet
7
+ // renders the accessible table alternative as a SIBLING of that image
8
+ // wrapper, never inside it: a role="img" element makes its descendants
9
+ // presentational, so a table placed inside would be invisible to
10
+ // assistive technology.
11
+ //
12
+ // Props:
13
+ // class — string, optional. Consumer class appended after the base class.
14
+ // label — string, optional. Accessible name of the chart image.
15
+ // children — Snippet. The consumer-supplied inline svg.
16
+ // dataTable — Snippet, optional. The accessible table alternative.
17
+ // ...restProps — spread onto the root <figure>.
18
+ //
19
+ // Markup:
20
+ // <figure class="composed-chart">
21
+ // <div class="composed-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="composed-chart-data-table">…table…</div> (only when provided)
23
+ // </figure>
24
+ //
25
+ // Keyboard: none on the graphic; the data table follows native table behaviour.
26
+ //
27
+ // Claude rules:
28
+ // - Headless: no CSS, no inline styles; no drawing.
29
+ // - No hardcoded user-facing strings.
30
+
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label = undefined,
36
+ children,
37
+ dataTable,
38
+ ...restProps
39
+ }: {
40
+ /** Accessible name for the chart. */
41
+ label?: string;
42
+ /** The consumer-supplied inline svg. */
43
+ children: Snippet;
44
+ /** Optional accessible data table alternative. */
45
+ dataTable?: Snippet;
46
+ [key: string]: unknown;
47
+ } = $props();
48
+ </script>
49
+
50
+ <!-- ComposedChart.svelte -->
51
+ <figure
52
+ class={`composed-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="composed-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="composed-chart-data-table">
60
+ {@render dataTable()}
61
+ </div>
62
+ {/if}
63
+ </figure>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name for the chart. */
4
+ label?: string;
5
+ /** The consumer-supplied inline svg. */
6
+ children: Snippet;
7
+ /** Optional accessible data table alternative. */
8
+ dataTable?: Snippet;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const ComposedChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type ComposedChart = ReturnType<typeof ComposedChart>;
13
+ export default ComposedChart;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // FunnelChart component
3
+ //
4
+ // A headless chart container for a chart of stages narrowing from top to bottom, showing how a quantity drops at each step. The consumer supplies the inline
5
+ // svg as `children`; the component draws nothing. The graphic is a
6
+ // role="img" wrapper named by `label`. The optional `dataTable` snippet
7
+ // renders the accessible table alternative as a SIBLING of that image
8
+ // wrapper, never inside it: a role="img" element makes its descendants
9
+ // presentational, so a table placed inside would be invisible to
10
+ // assistive technology.
11
+ //
12
+ // Props:
13
+ // class — string, optional. Consumer class appended after the base class.
14
+ // label — string, optional. Accessible name of the chart image.
15
+ // children — Snippet. The consumer-supplied inline svg.
16
+ // dataTable — Snippet, optional. The accessible table alternative.
17
+ // ...restProps — spread onto the root <figure>.
18
+ //
19
+ // Markup:
20
+ // <figure class="funnel-chart">
21
+ // <div class="funnel-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="funnel-chart-data-table">…table…</div> (only when provided)
23
+ // </figure>
24
+ //
25
+ // Keyboard: none on the graphic; the data table follows native table behaviour.
26
+ //
27
+ // Claude rules:
28
+ // - Headless: no CSS, no inline styles; no drawing.
29
+ // - No hardcoded user-facing strings.
30
+
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label = undefined,
36
+ children,
37
+ dataTable,
38
+ ...restProps
39
+ }: {
40
+ /** Accessible name for the chart. */
41
+ label?: string;
42
+ /** The consumer-supplied inline svg. */
43
+ children: Snippet;
44
+ /** Optional accessible data table alternative. */
45
+ dataTable?: Snippet;
46
+ [key: string]: unknown;
47
+ } = $props();
48
+ </script>
49
+
50
+ <!-- FunnelChart.svelte -->
51
+ <figure
52
+ class={`funnel-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="funnel-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="funnel-chart-data-table">
60
+ {@render dataTable()}
61
+ </div>
62
+ {/if}
63
+ </figure>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name for the chart. */
4
+ label?: string;
5
+ /** The consumer-supplied inline svg. */
6
+ children: Snippet;
7
+ /** Optional accessible data table alternative. */
8
+ dataTable?: Snippet;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const FunnelChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type FunnelChart = ReturnType<typeof FunnelChart>;
13
+ export default FunnelChart;
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ // Mark component
3
+ //
4
+ // A headless inline wrapper: an inline highlight marking text as relevant or referenced, such as a search match, using the native mark element. Contract: a plain wrapper with the base class and children.
5
+ // Draws nothing and carries no strings of its own; the consumer supplies the text.
6
+ import type { Snippet } from "svelte";
7
+
8
+ let {
9
+ class: className = "",
10
+ children,
11
+ ...restProps
12
+ }: {
13
+
14
+ /** The content. */
15
+ children?: Snippet;
16
+ [key: string]: unknown;
17
+ } = $props();
18
+ </script>
19
+
20
+ <!-- Mark.svelte -->
21
+ <mark
22
+ class={`mark ${className}`}
23
+
24
+ {...restProps}
25
+ >
26
+ {@render children?.()}
27
+ </mark>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** The content. */
4
+ children?: Snippet;
5
+ [key: string]: unknown;
6
+ };
7
+ declare const Mark: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type Mark = ReturnType<typeof Mark>;
9
+ export default Mark;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // PieChart component
3
+ //
4
+ // A headless chart container for a circular chart divided into slices that show each part of a whole. The consumer supplies the inline
5
+ // svg as `children`; the component draws nothing. The graphic is a
6
+ // role="img" wrapper named by `label`. The optional `dataTable` snippet
7
+ // renders the accessible table alternative as a SIBLING of that image
8
+ // wrapper, never inside it: a role="img" element makes its descendants
9
+ // presentational, so a table placed inside would be invisible to
10
+ // assistive technology.
11
+ //
12
+ // Props:
13
+ // class — string, optional. Consumer class appended after the base class.
14
+ // label — string, optional. Accessible name of the chart image.
15
+ // children — Snippet. The consumer-supplied inline svg.
16
+ // dataTable — Snippet, optional. The accessible table alternative.
17
+ // ...restProps — spread onto the root <figure>.
18
+ //
19
+ // Markup:
20
+ // <figure class="pie-chart">
21
+ // <div class="pie-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="pie-chart-data-table">…table…</div> (only when provided)
23
+ // </figure>
24
+ //
25
+ // Keyboard: none on the graphic; the data table follows native table behaviour.
26
+ //
27
+ // Claude rules:
28
+ // - Headless: no CSS, no inline styles; no drawing.
29
+ // - No hardcoded user-facing strings.
30
+
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label = undefined,
36
+ children,
37
+ dataTable,
38
+ ...restProps
39
+ }: {
40
+ /** Accessible name for the chart. */
41
+ label?: string;
42
+ /** The consumer-supplied inline svg. */
43
+ children: Snippet;
44
+ /** Optional accessible data table alternative. */
45
+ dataTable?: Snippet;
46
+ [key: string]: unknown;
47
+ } = $props();
48
+ </script>
49
+
50
+ <!-- PieChart.svelte -->
51
+ <figure
52
+ class={`pie-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="pie-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="pie-chart-data-table">
60
+ {@render dataTable()}
61
+ </div>
62
+ {/if}
63
+ </figure>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name for the chart. */
4
+ label?: string;
5
+ /** The consumer-supplied inline svg. */
6
+ children: Snippet;
7
+ /** Optional accessible data table alternative. */
8
+ dataTable?: Snippet;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const PieChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type PieChart = ReturnType<typeof PieChart>;
13
+ export default PieChart;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // RingChart component
3
+ //
4
+ // A headless chart container for a pie chart with a hollow centre, often used to show progress or a share of a total. The consumer supplies the inline
5
+ // svg as `children`; the component draws nothing. The graphic is a
6
+ // role="img" wrapper named by `label`. The optional `dataTable` snippet
7
+ // renders the accessible table alternative as a SIBLING of that image
8
+ // wrapper, never inside it: a role="img" element makes its descendants
9
+ // presentational, so a table placed inside would be invisible to
10
+ // assistive technology.
11
+ //
12
+ // Props:
13
+ // class — string, optional. Consumer class appended after the base class.
14
+ // label — string, optional. Accessible name of the chart image.
15
+ // children — Snippet. The consumer-supplied inline svg.
16
+ // dataTable — Snippet, optional. The accessible table alternative.
17
+ // ...restProps — spread onto the root <figure>.
18
+ //
19
+ // Markup:
20
+ // <figure class="ring-chart">
21
+ // <div class="ring-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="ring-chart-data-table">…table…</div> (only when provided)
23
+ // </figure>
24
+ //
25
+ // Keyboard: none on the graphic; the data table follows native table behaviour.
26
+ //
27
+ // Claude rules:
28
+ // - Headless: no CSS, no inline styles; no drawing.
29
+ // - No hardcoded user-facing strings.
30
+
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label = undefined,
36
+ children,
37
+ dataTable,
38
+ ...restProps
39
+ }: {
40
+ /** Accessible name for the chart. */
41
+ label?: string;
42
+ /** The consumer-supplied inline svg. */
43
+ children: Snippet;
44
+ /** Optional accessible data table alternative. */
45
+ dataTable?: Snippet;
46
+ [key: string]: unknown;
47
+ } = $props();
48
+ </script>
49
+
50
+ <!-- RingChart.svelte -->
51
+ <figure
52
+ class={`ring-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="ring-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="ring-chart-data-table">
60
+ {@render dataTable()}
61
+ </div>
62
+ {/if}
63
+ </figure>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible name for the chart. */
4
+ label?: string;
5
+ /** The consumer-supplied inline svg. */
6
+ children: Snippet;
7
+ /** Optional accessible data table alternative. */
8
+ dataTable?: Snippet;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const RingChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type RingChart = ReturnType<typeof RingChart>;
13
+ export default RingChart;