@lilydesignsystem/svelte-headless 0.2.0 → 0.3.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 (153) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/components/AotearoaNationalHealthIndexInput/AotearoaNationalHealthIndexInput.svelte +55 -0
  3. package/dist/components/AotearoaNationalHealthIndexInput/AotearoaNationalHealthIndexInput.svelte.d.ts +10 -0
  4. package/dist/components/AotearoaNationalHealthIndexView/AotearoaNationalHealthIndexView.svelte +40 -0
  5. package/dist/components/AotearoaNationalHealthIndexView/AotearoaNationalHealthIndexView.svelte.d.ts +8 -0
  6. package/dist/components/AreaChart/AreaChart.svelte +42 -3
  7. package/dist/components/AreaChart/AreaChart.svelte.d.ts +4 -0
  8. package/dist/components/ArgentinaCodigoUnicoDeIdentificacionLaboralInput/ArgentinaCodigoUnicoDeIdentificacionLaboralInput.svelte +55 -0
  9. package/dist/components/ArgentinaCodigoUnicoDeIdentificacionLaboralInput/ArgentinaCodigoUnicoDeIdentificacionLaboralInput.svelte.d.ts +10 -0
  10. package/dist/components/ArgentinaCodigoUnicoDeIdentificacionLaboralView/ArgentinaCodigoUnicoDeIdentificacionLaboralView.svelte +40 -0
  11. package/dist/components/ArgentinaCodigoUnicoDeIdentificacionLaboralView/ArgentinaCodigoUnicoDeIdentificacionLaboralView.svelte.d.ts +8 -0
  12. package/dist/components/BarChart/BarChart.svelte +42 -3
  13. package/dist/components/BarChart/BarChart.svelte.d.ts +4 -0
  14. package/dist/components/BharatAadhaarInput/BharatAadhaarInput.svelte +55 -0
  15. package/dist/components/BharatAadhaarInput/BharatAadhaarInput.svelte.d.ts +10 -0
  16. package/dist/components/BharatAadhaarView/BharatAadhaarView.svelte +40 -0
  17. package/dist/components/BharatAadhaarView/BharatAadhaarView.svelte.d.ts +8 -0
  18. package/dist/components/BrasilCartaoNacionalDeSaudeInput/BrasilCartaoNacionalDeSaudeInput.svelte +55 -0
  19. package/dist/components/BrasilCartaoNacionalDeSaudeInput/BrasilCartaoNacionalDeSaudeInput.svelte.d.ts +10 -0
  20. package/dist/components/BrasilCartaoNacionalDeSaudeView/BrasilCartaoNacionalDeSaudeView.svelte +40 -0
  21. package/dist/components/BrasilCartaoNacionalDeSaudeView/BrasilCartaoNacionalDeSaudeView.svelte.d.ts +8 -0
  22. package/dist/components/CalendarDayTable/CalendarDayTable.svelte +71 -0
  23. package/dist/components/CalendarDayTable/CalendarDayTable.svelte.d.ts +13 -0
  24. package/dist/components/CalendarMonthTable/CalendarMonthTable.svelte +71 -0
  25. package/dist/components/CalendarMonthTable/CalendarMonthTable.svelte.d.ts +13 -0
  26. package/dist/components/CalendarWeekTable/CalendarWeekTable.svelte +71 -0
  27. package/dist/components/CalendarWeekTable/CalendarWeekTable.svelte.d.ts +13 -0
  28. package/dist/components/CalendarYearTable/CalendarYearTable.svelte +71 -0
  29. package/dist/components/CalendarYearTable/CalendarYearTable.svelte.d.ts +13 -0
  30. package/dist/components/CanadaSocialInsuranceNumberInput/CanadaSocialInsuranceNumberInput.svelte +55 -0
  31. package/dist/components/CanadaSocialInsuranceNumberInput/CanadaSocialInsuranceNumberInput.svelte.d.ts +10 -0
  32. package/dist/components/CanadaSocialInsuranceNumberView/CanadaSocialInsuranceNumberView.svelte +40 -0
  33. package/dist/components/CanadaSocialInsuranceNumberView/CanadaSocialInsuranceNumberView.svelte.d.ts +8 -0
  34. package/dist/components/ChileRolUnicoNacionalInput/ChileRolUnicoNacionalInput.svelte +55 -0
  35. package/dist/components/ChileRolUnicoNacionalInput/ChileRolUnicoNacionalInput.svelte.d.ts +10 -0
  36. package/dist/components/ChileRolUnicoNacionalView/ChileRolUnicoNacionalView.svelte +40 -0
  37. package/dist/components/ChileRolUnicoNacionalView/ChileRolUnicoNacionalView.svelte.d.ts +8 -0
  38. package/dist/components/ColumnChart/ColumnChart.svelte +42 -3
  39. package/dist/components/ColumnChart/ColumnChart.svelte.d.ts +4 -0
  40. package/dist/components/EmptyState/EmptyState.svelte +47 -0
  41. package/dist/components/EmptyState/EmptyState.svelte.d.ts +11 -0
  42. package/dist/components/FileTree/FileTree.svelte +210 -0
  43. package/dist/components/FileTree/FileTree.svelte.d.ts +11 -0
  44. package/dist/components/GanttTable/GanttTable.svelte +5 -5
  45. package/dist/components/GanttTableTD/GanttTableTD.svelte +2 -2
  46. package/dist/components/GanttTableTH/GanttTableTH.svelte +3 -3
  47. package/dist/components/GanttTableTbody/GanttTableTbody.svelte +5 -5
  48. package/dist/components/GanttTableTbody/GanttTableTbody.svelte.d.ts +1 -1
  49. package/dist/components/GanttTableTfoot/GanttTableTfoot.svelte +5 -5
  50. package/dist/components/GanttTableTfoot/GanttTableTfoot.svelte.d.ts +1 -1
  51. package/dist/components/GanttTableThead/GanttTableThead.svelte +4 -4
  52. package/dist/components/GanttTableThead/GanttTableThead.svelte.d.ts +1 -1
  53. package/dist/components/GanttTableTr/GanttTableTr.svelte +8 -8
  54. package/dist/components/GaugeChart/GaugeChart.svelte +63 -0
  55. package/dist/components/GaugeChart/GaugeChart.svelte.d.ts +13 -0
  56. package/dist/components/HangukJuminDeungnokBeonhoInput/HangukJuminDeungnokBeonhoInput.svelte +55 -0
  57. package/dist/components/HangukJuminDeungnokBeonhoInput/HangukJuminDeungnokBeonhoInput.svelte.d.ts +10 -0
  58. package/dist/components/HangukJuminDeungnokBeonhoView/HangukJuminDeungnokBeonhoView.svelte +40 -0
  59. package/dist/components/HangukJuminDeungnokBeonhoView/HangukJuminDeungnokBeonhoView.svelte.d.ts +8 -0
  60. package/dist/components/HeatmapChart/HeatmapChart.svelte +63 -0
  61. package/dist/components/HeatmapChart/HeatmapChart.svelte.d.ts +13 -0
  62. package/dist/components/IndonesiaNomorIndukKependudukanInput/IndonesiaNomorIndukKependudukanInput.svelte +55 -0
  63. package/dist/components/IndonesiaNomorIndukKependudukanInput/IndonesiaNomorIndukKependudukanInput.svelte.d.ts +10 -0
  64. package/dist/components/IndonesiaNomorIndukKependudukanView/IndonesiaNomorIndukKependudukanView.svelte +40 -0
  65. package/dist/components/IndonesiaNomorIndukKependudukanView/IndonesiaNomorIndukKependudukanView.svelte.d.ts +8 -0
  66. package/dist/components/KbdShortcut/KbdShortcut.svelte +49 -0
  67. package/dist/components/KbdShortcut/KbdShortcut.svelte.d.ts +12 -0
  68. package/dist/components/LineChart/LineChart.svelte +42 -3
  69. package/dist/components/LineChart/LineChart.svelte.d.ts +4 -0
  70. package/dist/components/LuxembourgMatriculeInput/LuxembourgMatriculeInput.svelte +55 -0
  71. package/dist/components/LuxembourgMatriculeInput/LuxembourgMatriculeInput.svelte.d.ts +10 -0
  72. package/dist/components/LuxembourgMatriculeView/LuxembourgMatriculeView.svelte +40 -0
  73. package/dist/components/LuxembourgMatriculeView/LuxembourgMatriculeView.svelte.d.ts +8 -0
  74. package/dist/components/MagyarorszagTajSzamInput/MagyarorszagTajSzamInput.svelte +55 -0
  75. package/dist/components/MagyarorszagTajSzamInput/MagyarorszagTajSzamInput.svelte.d.ts +10 -0
  76. package/dist/components/MagyarorszagTajSzamView/MagyarorszagTajSzamView.svelte +40 -0
  77. package/dist/components/MagyarorszagTajSzamView/MagyarorszagTajSzamView.svelte.d.ts +8 -0
  78. package/dist/components/MexicoClaveUnicaDeRegistroDePoblacionInput/MexicoClaveUnicaDeRegistroDePoblacionInput.svelte +55 -0
  79. package/dist/components/MexicoClaveUnicaDeRegistroDePoblacionInput/MexicoClaveUnicaDeRegistroDePoblacionInput.svelte.d.ts +10 -0
  80. package/dist/components/MexicoClaveUnicaDeRegistroDePoblacionView/MexicoClaveUnicaDeRegistroDePoblacionView.svelte +40 -0
  81. package/dist/components/MexicoClaveUnicaDeRegistroDePoblacionView/MexicoClaveUnicaDeRegistroDePoblacionView.svelte.d.ts +8 -0
  82. package/dist/components/MisrAlRaqmAlQawmiInput/MisrAlRaqmAlQawmiInput.svelte +55 -0
  83. package/dist/components/MisrAlRaqmAlQawmiInput/MisrAlRaqmAlQawmiInput.svelte.d.ts +10 -0
  84. package/dist/components/MisrAlRaqmAlQawmiView/MisrAlRaqmAlQawmiView.svelte +40 -0
  85. package/dist/components/MisrAlRaqmAlQawmiView/MisrAlRaqmAlQawmiView.svelte.d.ts +8 -0
  86. package/dist/components/MultiSelect/MultiSelect.svelte +70 -0
  87. package/dist/components/MultiSelect/MultiSelect.svelte.d.ts +19 -0
  88. package/dist/components/MultiSelectWithExtras/MultiSelectWithExtras.svelte +80 -0
  89. package/dist/components/MultiSelectWithExtras/MultiSelectWithExtras.svelte.d.ts +23 -0
  90. package/dist/components/NihonKojinBangoInput/NihonKojinBangoInput.svelte +55 -0
  91. package/dist/components/NihonKojinBangoInput/NihonKojinBangoInput.svelte.d.ts +10 -0
  92. package/dist/components/NihonKojinBangoView/NihonKojinBangoView.svelte +40 -0
  93. package/dist/components/NihonKojinBangoView/NihonKojinBangoView.svelte.d.ts +8 -0
  94. package/dist/components/OneTimePasswordInput/OneTimePasswordInput.svelte +85 -0
  95. package/dist/components/OneTimePasswordInput/OneTimePasswordInput.svelte.d.ts +22 -0
  96. package/dist/components/OsterreichSozialversicherungsnummerInput/OsterreichSozialversicherungsnummerInput.svelte +55 -0
  97. package/dist/components/OsterreichSozialversicherungsnummerInput/OsterreichSozialversicherungsnummerInput.svelte.d.ts +10 -0
  98. package/dist/components/OsterreichSozialversicherungsnummerView/OsterreichSozialversicherungsnummerView.svelte +40 -0
  99. package/dist/components/OsterreichSozialversicherungsnummerView/OsterreichSozialversicherungsnummerView.svelte.d.ts +8 -0
  100. package/dist/components/PilipinasPhilhealthIdentificationNumberInput/PilipinasPhilhealthIdentificationNumberInput.svelte +55 -0
  101. package/dist/components/PilipinasPhilhealthIdentificationNumberInput/PilipinasPhilhealthIdentificationNumberInput.svelte.d.ts +10 -0
  102. package/dist/components/PilipinasPhilhealthIdentificationNumberView/PilipinasPhilhealthIdentificationNumberView.svelte +40 -0
  103. package/dist/components/PilipinasPhilhealthIdentificationNumberView/PilipinasPhilhealthIdentificationNumberView.svelte.d.ts +8 -0
  104. package/dist/components/PrathetThaiLekPrajamTuaPrachachonInput/PrathetThaiLekPrajamTuaPrachachonInput.svelte +55 -0
  105. package/dist/components/PrathetThaiLekPrajamTuaPrachachonInput/PrathetThaiLekPrajamTuaPrachachonInput.svelte.d.ts +10 -0
  106. package/dist/components/PrathetThaiLekPrajamTuaPrachachonView/PrathetThaiLekPrajamTuaPrachachonView.svelte +40 -0
  107. package/dist/components/PrathetThaiLekPrajamTuaPrachachonView/PrathetThaiLekPrajamTuaPrachachonView.svelte.d.ts +8 -0
  108. package/dist/components/RadarChart/RadarChart.svelte +63 -0
  109. package/dist/components/RadarChart/RadarChart.svelte.d.ts +13 -0
  110. package/dist/components/RossiyaSnilsInput/RossiyaSnilsInput.svelte +55 -0
  111. package/dist/components/RossiyaSnilsInput/RossiyaSnilsInput.svelte.d.ts +10 -0
  112. package/dist/components/RossiyaSnilsView/RossiyaSnilsView.svelte +40 -0
  113. package/dist/components/RossiyaSnilsView/RossiyaSnilsView.svelte.d.ts +8 -0
  114. package/dist/components/SankeyChart/SankeyChart.svelte +63 -0
  115. package/dist/components/SankeyChart/SankeyChart.svelte.d.ts +13 -0
  116. package/dist/components/ScatterChart/ScatterChart.svelte +42 -3
  117. package/dist/components/ScatterChart/ScatterChart.svelte.d.ts +4 -0
  118. package/dist/components/SchweizAhvNummerInput/SchweizAhvNummerInput.svelte +55 -0
  119. package/dist/components/SchweizAhvNummerInput/SchweizAhvNummerInput.svelte.d.ts +10 -0
  120. package/dist/components/SchweizAhvNummerView/SchweizAhvNummerView.svelte +40 -0
  121. package/dist/components/SchweizAhvNummerView/SchweizAhvNummerView.svelte.d.ts +8 -0
  122. package/dist/components/ShowMore/ShowMore.svelte +64 -0
  123. package/dist/components/ShowMore/ShowMore.svelte.d.ts +15 -0
  124. package/dist/components/SingaporeNationalRegistrationIdentityCardInput/SingaporeNationalRegistrationIdentityCardInput.svelte +55 -0
  125. package/dist/components/SingaporeNationalRegistrationIdentityCardInput/SingaporeNationalRegistrationIdentityCardInput.svelte.d.ts +10 -0
  126. package/dist/components/SingaporeNationalRegistrationIdentityCardView/SingaporeNationalRegistrationIdentityCardView.svelte +40 -0
  127. package/dist/components/SingaporeNationalRegistrationIdentityCardView/SingaporeNationalRegistrationIdentityCardView.svelte.d.ts +8 -0
  128. package/dist/components/SouthAfricaIdentityNumberInput/SouthAfricaIdentityNumberInput.svelte +55 -0
  129. package/dist/components/SouthAfricaIdentityNumberInput/SouthAfricaIdentityNumberInput.svelte.d.ts +10 -0
  130. package/dist/components/SouthAfricaIdentityNumberView/SouthAfricaIdentityNumberView.svelte +40 -0
  131. package/dist/components/SouthAfricaIdentityNumberView/SouthAfricaIdentityNumberView.svelte.d.ts +8 -0
  132. package/dist/components/Thinking/Thinking.svelte +58 -0
  133. package/dist/components/Thinking/Thinking.svelte.d.ts +15 -0
  134. package/dist/components/TurkiyeTcKimlikNumarasiInput/TurkiyeTcKimlikNumarasiInput.svelte +55 -0
  135. package/dist/components/TurkiyeTcKimlikNumarasiInput/TurkiyeTcKimlikNumarasiInput.svelte.d.ts +10 -0
  136. package/dist/components/TurkiyeTcKimlikNumarasiView/TurkiyeTcKimlikNumarasiView.svelte +40 -0
  137. package/dist/components/TurkiyeTcKimlikNumarasiView/TurkiyeTcKimlikNumarasiView.svelte.d.ts +8 -0
  138. package/dist/components/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivInput/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivInput.svelte +55 -0
  139. package/dist/components/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivInput/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivInput.svelte.d.ts +10 -0
  140. package/dist/components/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivView/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivView.svelte +40 -0
  141. package/dist/components/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivView/UkrayinaReyestratsiyniyNomerOblikovoyiKartkyPlatnykaPodatkivView.svelte.d.ts +8 -0
  142. package/dist/components/YisraelTeudatZehutInput/YisraelTeudatZehutInput.svelte +55 -0
  143. package/dist/components/YisraelTeudatZehutInput/YisraelTeudatZehutInput.svelte.d.ts +10 -0
  144. package/dist/components/YisraelTeudatZehutView/YisraelTeudatZehutView.svelte +40 -0
  145. package/dist/components/YisraelTeudatZehutView/YisraelTeudatZehutView.svelte.d.ts +8 -0
  146. package/dist/components/ZhongguoJuminShenfenzhengHaomaInput/ZhongguoJuminShenfenzhengHaomaInput.svelte +55 -0
  147. package/dist/components/ZhongguoJuminShenfenzhengHaomaInput/ZhongguoJuminShenfenzhengHaomaInput.svelte.d.ts +10 -0
  148. package/dist/components/ZhongguoJuminShenfenzhengHaomaView/ZhongguoJuminShenfenzhengHaomaView.svelte +40 -0
  149. package/dist/components/ZhongguoJuminShenfenzhengHaomaView/ZhongguoJuminShenfenzhengHaomaView.svelte.d.ts +8 -0
  150. package/dist/index.d.ts +64 -0
  151. package/dist/index.js +64 -0
  152. package/index.md +1 -1
  153. package/package.json +9 -9
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ // EmptyState component
3
+ //
4
+ // A headless container for the "nothing here yet" state of a list, table,
5
+ // search or inbox. The consumer supplies the heading, explanation and action
6
+ // as children; there is no icon and no default text.
7
+ //
8
+ // Props:
9
+ // className — string, optional. CSS class name.
10
+ // label — string, optional. When given, the root becomes role="group" with this aria-label.
11
+ // children — Snippet. Heading, text, action.
12
+ // ...restProps — additional HTML attributes spread onto the root <div>.
13
+ //
14
+ // Keyboard:
15
+ // - None; any action inside is a native control
16
+ //
17
+ // Accessibility:
18
+ // - role="group" + aria-label only when label is supplied; otherwise a plain <div>
19
+ // - Not a live region: use InfoState (role="status") for announced states
20
+ //
21
+ // Claude rules:
22
+ // - Headless: no CSS, no icon, no hardcoded strings
23
+ import type { Snippet } from "svelte";
24
+
25
+ let {
26
+ class: className = "",
27
+ label = undefined,
28
+ children,
29
+ ...restProps
30
+ }: {
31
+ /** Optional accessible name; adds role="group". */
32
+ label?: string;
33
+ /** Heading, text and action supplied by the consumer. */
34
+ children?: Snippet;
35
+ [key: string]: unknown;
36
+ } = $props();
37
+ </script>
38
+
39
+ <!-- EmptyState.svelte -->
40
+ <div
41
+ class={`empty-state ${className}`}
42
+ role={label ? "group" : undefined}
43
+ aria-label={label}
44
+ {...restProps}
45
+ >
46
+ {@render children?.()}
47
+ </div>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Optional accessible name; adds role="group". */
4
+ label?: string;
5
+ /** Heading, text and action supplied by the consumer. */
6
+ children?: Snippet;
7
+ [key: string]: unknown;
8
+ };
9
+ declare const EmptyState: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type EmptyState = ReturnType<typeof EmptyState>;
11
+ export default EmptyState;
@@ -0,0 +1,210 @@
1
+ <script lang="ts">
2
+ // FileTree component
3
+ //
4
+ // A headless hierarchical tree (folders and files) following the WAI-ARIA APG
5
+ // tree pattern. The consumer supplies <li role="treeitem"> descendants, with a
6
+ // nested <ul role="group"> inside each folder item and aria-expanded on folders.
7
+ // The root owns the keyboard and a ROVING TABINDEX: exactly one visible item has
8
+ // tabindex="0", all others -1. Opening/closing is done by toggling aria-expanded;
9
+ // hiding a closed folder's group is consumer CSS.
10
+ //
11
+ // Props:
12
+ // className — string, optional. CSS class name.
13
+ // label — string, required. Accessible name via aria-label.
14
+ // children — Snippet. The tree items.
15
+ // ...restProps — additional HTML attributes spread onto the root <ul>.
16
+ //
17
+ // Keyboard (focus on a treeitem):
18
+ // - ArrowDown / ArrowUp: next / previous visible item (clamped, no wrap)
19
+ // - ArrowRight: closed folder opens; open folder moves to first child
20
+ // - ArrowLeft: open folder closes; otherwise moves to the parent folder
21
+ // - Home / End: first / last visible item
22
+ // - * : expand all sibling folders at the focused level
23
+ // - Printable characters: typeahead on the item's own text
24
+ // - Enter / Space: activate (clicks the item)
25
+ //
26
+ // Accessibility:
27
+ // - role="tree" on the root; consumer supplies treeitem/group roles and aria-selected
28
+ //
29
+ // Claude rules:
30
+ // - Headless: no CSS; state is aria-expanded only; no events beyond native click
31
+ import type { Snippet } from "svelte";
32
+
33
+ let {
34
+ class: className = "",
35
+ label,
36
+ children,
37
+ ...restProps
38
+ }: {
39
+ /** Accessible label. */
40
+ label: string;
41
+ /** Tree item elements. */
42
+ children?: Snippet;
43
+ [key: string]: unknown;
44
+ } = $props();
45
+
46
+ let treeRef: HTMLElement | undefined = $state(undefined);
47
+ let buffer = "";
48
+ let bufferTimer: ReturnType<typeof setTimeout> | undefined;
49
+
50
+ function allItems(): HTMLElement[] {
51
+ return treeRef ? Array.from(treeRef.querySelectorAll<HTMLElement>("[role='treeitem']")) : [];
52
+ }
53
+
54
+ function parentItem(item: HTMLElement): HTMLElement | null {
55
+ return item.parentElement?.closest<HTMLElement>("[role='treeitem']") ?? null;
56
+ }
57
+
58
+ function isVisible(item: HTMLElement): boolean {
59
+ let p = parentItem(item);
60
+ while (p) {
61
+ if (p.getAttribute("aria-expanded") === "false") return false;
62
+ p = parentItem(p);
63
+ }
64
+ return true;
65
+ }
66
+
67
+ function visibleItems(): HTMLElement[] {
68
+ return allItems().filter(isVisible);
69
+ }
70
+
71
+ // The item's own text, excluding any nested group.
72
+ function ownText(item: HTMLElement): string {
73
+ let text = "";
74
+ item.childNodes.forEach((n) => {
75
+ if (n.nodeType === Node.ELEMENT_NODE && (n as HTMLElement).getAttribute("role") === "group") return;
76
+ text += n.textContent ?? "";
77
+ });
78
+ return text.trim().toLowerCase();
79
+ }
80
+
81
+ function setStop(target: HTMLElement | undefined) {
82
+ for (const item of allItems()) {
83
+ item.setAttribute("tabindex", item === target ? "0" : "-1");
84
+ }
85
+ }
86
+
87
+ // Keep exactly one tab stop, on a visible item.
88
+ function normalise() {
89
+ const visible = visibleItems();
90
+ if (visible.length === 0) return;
91
+ const stops = allItems().filter((i) => i.getAttribute("tabindex") === "0");
92
+ if (stops.length === 1 && isVisible(stops[0])) return;
93
+ const keep =
94
+ stops.find(isVisible) ??
95
+ visible.find((i) => i.getAttribute("aria-selected") === "true") ??
96
+ visible[0];
97
+ setStop(keep);
98
+ }
99
+
100
+ $effect(() => {
101
+ if (!treeRef) return;
102
+ normalise();
103
+ const observer = new MutationObserver(normalise);
104
+ observer.observe(treeRef, {
105
+ subtree: true,
106
+ childList: true,
107
+ attributes: true,
108
+ attributeFilter: ["aria-expanded"],
109
+ });
110
+ return () => observer.disconnect();
111
+ });
112
+
113
+ function onfocusin(event: FocusEvent) {
114
+ const item = (event.target as HTMLElement).closest<HTMLElement>("[role='treeitem']");
115
+ if (item && treeRef?.contains(item)) setStop(item);
116
+ }
117
+
118
+ function focusItem(item: HTMLElement | undefined) {
119
+ if (!item) return;
120
+ setStop(item);
121
+ item.focus();
122
+ }
123
+
124
+ function onkeydown(event: KeyboardEvent) {
125
+ const target = event.target as HTMLElement;
126
+ const item = target.closest<HTMLElement>("[role='treeitem']");
127
+ if (!item || !treeRef?.contains(item)) return;
128
+ if (event.ctrlKey || event.metaKey || event.altKey) return;
129
+
130
+ const visible = visibleItems();
131
+ const index = visible.indexOf(item);
132
+ const expanded = item.getAttribute("aria-expanded");
133
+
134
+ switch (event.key) {
135
+ case "ArrowDown":
136
+ event.preventDefault();
137
+ focusItem(visible[Math.min(index + 1, visible.length - 1)]);
138
+ return;
139
+ case "ArrowUp":
140
+ event.preventDefault();
141
+ focusItem(visible[Math.max(index - 1, 0)]);
142
+ return;
143
+ case "Home":
144
+ event.preventDefault();
145
+ focusItem(visible[0]);
146
+ return;
147
+ case "End":
148
+ event.preventDefault();
149
+ focusItem(visible[visible.length - 1]);
150
+ return;
151
+ case "ArrowRight":
152
+ if (target !== item) return;
153
+ event.preventDefault();
154
+ if (expanded === "false") {
155
+ item.setAttribute("aria-expanded", "true");
156
+ } else if (expanded === "true") {
157
+ focusItem(item.querySelector<HTMLElement>("[role='group'] [role='treeitem']") ?? undefined);
158
+ }
159
+ return;
160
+ case "ArrowLeft":
161
+ if (target !== item) return;
162
+ event.preventDefault();
163
+ if (expanded === "true") {
164
+ item.setAttribute("aria-expanded", "false");
165
+ } else {
166
+ focusItem(parentItem(item) ?? undefined);
167
+ }
168
+ return;
169
+ case "Enter":
170
+ case " ":
171
+ if (target !== item) return;
172
+ event.preventDefault();
173
+ item.click();
174
+ return;
175
+ case "*":
176
+ event.preventDefault();
177
+ for (const sibling of Array.from(item.parentElement?.children ?? [])) {
178
+ if (sibling.getAttribute("role") === "treeitem" && sibling.getAttribute("aria-expanded") === "false") {
179
+ sibling.setAttribute("aria-expanded", "true");
180
+ }
181
+ }
182
+ return;
183
+ }
184
+
185
+ // Typeahead
186
+ if (event.key.length === 1) {
187
+ event.preventDefault();
188
+ buffer += event.key.toLowerCase();
189
+ clearTimeout(bufferTimer);
190
+ bufferTimer = setTimeout(() => (buffer = ""), 500);
191
+ const cycle = buffer.length === 1 || [...buffer].every((c) => c === buffer[0]);
192
+ const needle = cycle ? buffer[0] : buffer;
193
+ const ordered = [...visible.slice(index + (cycle ? 1 : 0)), ...visible.slice(0, index + (cycle ? 1 : 0))];
194
+ focusItem(ordered.find((i) => ownText(i).startsWith(needle)));
195
+ }
196
+ }
197
+ </script>
198
+
199
+ <!-- FileTree.svelte -->
200
+ <ul
201
+ class={`file-tree ${className}`}
202
+ role="tree"
203
+ aria-label={label}
204
+ bind:this={treeRef}
205
+ {onkeydown}
206
+ {onfocusin}
207
+ {...restProps}
208
+ >
209
+ {@render children?.()}
210
+ </ul>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** Accessible label. */
4
+ label: string;
5
+ /** Tree item elements. */
6
+ children?: Snippet;
7
+ [key: string]: unknown;
8
+ };
9
+ declare const FileTree: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type FileTree = ReturnType<typeof FileTree>;
11
+ export default FileTree;
@@ -16,17 +16,17 @@
16
16
  // Syntax:
17
17
  // <GanttTable label="Project timeline">
18
18
  // <GanttTableHead>
19
- // <GanttTableTR>
19
+ // <GanttTableTr>
20
20
  // <th>Task</th><th>Week 1</th><th>Week 2</th><th>Week 3</th>
21
- // </GanttTableTR>
21
+ // </GanttTableTr>
22
22
  // </GanttTableHead>
23
23
  // <GanttTableBody>
24
- // <GanttTableTR>
24
+ // <GanttTableTr>
25
25
  // <th>Design</th>
26
26
  // <GanttTableTD active>---</GanttTableTD>
27
27
  // <GanttTableTD />
28
28
  // <GanttTableTD />
29
- // </GanttTableTR>
29
+ // </GanttTableTr>
30
30
  // </GanttTableBody>
31
31
  // </GanttTable>
32
32
  //
@@ -46,7 +46,7 @@
46
46
  // Claude rules:
47
47
  // - Headless: no CSS, no styles — consumer provides all styling
48
48
  // - Compound component: use with GanttTableHead, GanttTableBody, GanttTableTfoot,
49
- // GanttTableTR, GanttTableTD, and GanttTableTH
49
+ // GanttTableTr, GanttTableTD, and GanttTableTH
50
50
  //
51
51
  // References:
52
52
  // - WAI-ARIA Grid Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/grid/
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  // GanttTableTD component
3
3
  //
4
- // A single cell within a GanttTableTR representing a time period in the
4
+ // A single cell within a GanttTableTr representing a time period in the
5
5
  // Gantt table grid. Renders as a <td> with role="gridcell". Supports an
6
6
  // active state to indicate the task spans this time period, communicated
7
7
  // via aria-selected for screen readers.
@@ -39,7 +39,7 @@
39
39
  //
40
40
  // Claude rules:
41
41
  // - Headless: no CSS, no styles — consumer provides all styling
42
- // - Must be used inside a GanttTableTR (which provides the <tr>)
42
+ // - Must be used inside a GanttTableTr (which provides the <tr>)
43
43
  // - Children are optional — empty cells represent inactive time periods
44
44
  //
45
45
  // References:
@@ -2,7 +2,7 @@
2
2
  // GanttTableTH component
3
3
  //
4
4
  // A column header cell within a GanttTable, rendered as a <th> element.
5
- // Used inside a <GanttTableTR> within <GanttTableHead> to label the time
5
+ // Used inside a <GanttTableTr> within <GanttTableHead> to label the time
6
6
  // period columns of the Gantt grid (days, weeks, milestones, etc.).
7
7
  //
8
8
  // Props:
@@ -15,10 +15,10 @@
15
15
  //
16
16
  // Syntax:
17
17
  // <GanttTableHead>
18
- // <GanttTableTR>
18
+ // <GanttTableTr>
19
19
  // <GanttTableTH>Week 1</GanttTableTH>
20
20
  // <GanttTableTH>Week 2</GanttTableTH>
21
- // </GanttTableTR>
21
+ // </GanttTableTr>
22
22
  // </GanttTableHead>
23
23
  //
24
24
  // Keyboard:
@@ -2,19 +2,19 @@
2
2
  // GanttTableBody component
3
3
  //
4
4
  // The body section of a GanttTable, rendered as a <tbody> element.
5
- // Contains GanttTableTR elements with task data cells.
5
+ // Contains GanttTableTr elements with task data cells.
6
6
  //
7
7
  // Props:
8
8
  // className — string, optional. CSS class name.
9
- // children — Snippet, required. GanttTableTR elements with data cells.
9
+ // children — Snippet, required. GanttTableTr elements with data cells.
10
10
  // ...restProps — additional HTML attributes spread onto the <tbody>.
11
11
  //
12
12
  // Syntax:
13
13
  // <GanttTableBody>
14
- // <GanttTableTR>
14
+ // <GanttTableTr>
15
15
  // <GanttTableTD>Design</GanttTableTD>
16
16
  // <GanttTableTD>Jan 1</GanttTableTD>
17
- // </GanttTableTR>
17
+ // </GanttTableTr>
18
18
  // </GanttTableBody>
19
19
  //
20
20
  // Keyboard:
@@ -38,7 +38,7 @@
38
38
  children,
39
39
  ...restProps
40
40
  }: {
41
- /** GanttTableTR elements with task data cells. */
41
+ /** GanttTableTr elements with task data cells. */
42
42
  children: Snippet;
43
43
  [key: string]: unknown;
44
44
  } = $props();
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
2
  type $$ComponentProps = {
3
- /** GanttTableTR elements with task data cells. */
3
+ /** GanttTableTr elements with task data cells. */
4
4
  children: Snippet;
5
5
  [key: string]: unknown;
6
6
  };
@@ -2,18 +2,18 @@
2
2
  // GanttTableTfoot component
3
3
  //
4
4
  // The footer section of a GanttTable, rendered as a <tfoot> element.
5
- // Contains GanttTableTR elements with summary or aggregate data cells.
5
+ // Contains GanttTableTr elements with summary or aggregate data cells.
6
6
  //
7
7
  // Props:
8
8
  // className — string, optional. CSS class name.
9
- // children — Snippet, required. GanttTableTR elements with footer cells.
9
+ // children — Snippet, required. GanttTableTr elements with footer cells.
10
10
  // ...restProps — additional HTML attributes spread onto the <tfoot>.
11
11
  //
12
12
  // Syntax:
13
13
  // <GanttTableTfoot>
14
- // <GanttTableTR>
14
+ // <GanttTableTr>
15
15
  // <GanttTableTD>Total: 12 tasks</GanttTableTD>
16
- // </GanttTableTR>
16
+ // </GanttTableTr>
17
17
  // </GanttTableTfoot>
18
18
  //
19
19
  // Keyboard:
@@ -37,7 +37,7 @@
37
37
  children,
38
38
  ...restProps
39
39
  }: {
40
- /** GanttTableTR elements with footer cells. */
40
+ /** GanttTableTr elements with footer cells. */
41
41
  children: Snippet;
42
42
  [key: string]: unknown;
43
43
  } = $props();
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
2
  type $$ComponentProps = {
3
- /** GanttTableTR elements with footer cells. */
3
+ /** GanttTableTr elements with footer cells. */
4
4
  children: Snippet;
5
5
  [key: string]: unknown;
6
6
  };
@@ -2,17 +2,17 @@
2
2
  // GanttTableHead component
3
3
  //
4
4
  // The header section of a GanttTable, rendered as a <thead> element.
5
- // Contains GanttTableTR elements with column headers for task names,
5
+ // Contains GanttTableTr elements with column headers for task names,
6
6
  // dates, durations, or other Gantt chart metadata.
7
7
  //
8
8
  // Props:
9
9
  // className — string, optional. CSS class name.
10
- // children — Snippet, required. GanttTableTR elements with header cells.
10
+ // children — Snippet, required. GanttTableTr elements with header cells.
11
11
  // ...restProps — additional HTML attributes spread onto the <thead>.
12
12
  //
13
13
  // Syntax:
14
14
  // <GanttTableHead>
15
- // <GanttTableTR><th>Task</th><th>Start</th><th>End</th></GanttTableTR>
15
+ // <GanttTableTr><th>Task</th><th>Start</th><th>End</th></GanttTableTr>
16
16
  // </GanttTableHead>
17
17
  //
18
18
  // Keyboard:
@@ -36,7 +36,7 @@
36
36
  children,
37
37
  ...restProps
38
38
  }: {
39
- /** GanttTableTR elements with header cells. */
39
+ /** GanttTableTr elements with header cells. */
40
40
  children: Snippet;
41
41
  [key: string]: unknown;
42
42
  } = $props();
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
2
  type $$ComponentProps = {
3
- /** GanttTableTR elements with header cells. */
3
+ /** GanttTableTr elements with header cells. */
4
4
  children: Snippet;
5
5
  [key: string]: unknown;
6
6
  };
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- // GanttTableTR component
2
+ // GanttTableTr component
3
3
  //
4
4
  // A single row within a GanttTable grid. Renders as a <tr> containing
5
5
  // GanttTableTD cells for each time period and task header cells.
@@ -11,25 +11,25 @@
11
11
  // ...restProps — additional HTML attributes spread onto the <tr>.
12
12
  //
13
13
  // Syntax:
14
- // <GanttTableTR>
14
+ // <GanttTableTr>
15
15
  // <th>Design</th>
16
16
  // <GanttTableTD active>---</GanttTableTD>
17
17
  // <GanttTableTD />
18
- // </GanttTableTR>
18
+ // </GanttTableTr>
19
19
  //
20
20
  // Examples:
21
21
  // <!-- Task row with active time periods -->
22
- // <GanttTableTR>
22
+ // <GanttTableTr>
23
23
  // <th>Development</th>
24
24
  // <GanttTableTD />
25
25
  // <GanttTableTD active>---</GanttTableTD>
26
26
  // <GanttTableTD active>---</GanttTableTD>
27
- // </GanttTableTR>
27
+ // </GanttTableTr>
28
28
  //
29
29
  // <!-- Header row with time period labels -->
30
- // <GanttTableTR>
30
+ // <GanttTableTr>
31
31
  // <th>Task</th><th>Week 1</th><th>Week 2</th><th>Week 3</th>
32
- // </GanttTableTR>
32
+ // </GanttTableTr>
33
33
  //
34
34
  // Keyboard:
35
35
  // None built-in — keyboard navigation is handled at the GanttTable grid level.
@@ -61,7 +61,7 @@
61
61
  } = $props();
62
62
  </script>
63
63
 
64
- <!-- GanttTableTR.svelte -->
64
+ <!-- GanttTableTr.svelte -->
65
65
  <tr
66
66
  class={`gantt-table-tr ${className}`}
67
67
  {...restProps}
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ // GaugeChart component
3
+ //
4
+ // A headless chart container. The consumer supplies the inline svg as
5
+ // `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, required. 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="gauge-chart">
21
+ // <div class="gauge-chart-graphic" role="img" aria-label>…svg…</div>
22
+ // <div class="gauge-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,
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
+ <!-- GaugeChart.svelte -->
51
+ <figure
52
+ class={`gauge-chart ${className}`}
53
+ {...restProps}
54
+ >
55
+ <div class="gauge-chart-graphic" role="img" aria-label={label}>
56
+ {@render children?.()}
57
+ </div>
58
+ {#if dataTable}
59
+ <div class="gauge-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 GaugeChart: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type GaugeChart = ReturnType<typeof GaugeChart>;
13
+ export default GaugeChart;
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ // HangukJuminDeungnokBeonhoInput component
3
+ //
4
+ // A headless input for entering South Korea's Resident Registration Number (주민등록번호).
5
+ // Format: Thirteen digits, displayed as NNNNNN-NNNNNNN. The first six digits encode date of birth (YYMMDD); the seventh digit encodes sex and birth century; digits eight through eleven encode place of registration; the twelfth is a sequence number; the thirteenth is a Modulus-11 check digit over the preceding twelve.
6
+ //
7
+ // Props:
8
+ // className — string, optional. CSS class name.
9
+ // label — string, required. Accessible label for screen readers via aria-label.
10
+ // value — string, default "". Bindable input value; supports bind:value.
11
+ // required — boolean, default false. Whether the input is required for form submission.
12
+ // disabled — boolean, default false. Whether the input is disabled.
13
+ // ...restProps — additional HTML attributes spread onto the <input>.
14
+ //
15
+ // Syntax:
16
+ // <HangukJuminDeungnokBeonhoInput label="Resident Registration Number (주민등록번호)" bind:value />
17
+ //
18
+ // Accessibility:
19
+ // - aria-label provides the accessible name for screen readers
20
+ // - autocomplete="off" protects sensitive identifiers
21
+ // - required and disabled states are conveyed to assistive technology
22
+ //
23
+ // Internationalization:
24
+ // - The label prop externalizes user-facing text for translation
25
+ //
26
+ // References:
27
+ // - https://en.wikipedia.org/wiki/Resident_registration_number
28
+
29
+ let {
30
+ class: className = "",
31
+ label,
32
+ value = $bindable(""),
33
+ required = false,
34
+ disabled = false,
35
+ ...restProps
36
+ }: {
37
+ label: string;
38
+ value?: string;
39
+ required?: boolean;
40
+ disabled?: boolean;
41
+ [key: string]: unknown;
42
+ } = $props();
43
+ </script>
44
+
45
+ <!-- HangukJuminDeungnokBeonhoInput.svelte -->
46
+ <input
47
+ class={`hanguk-jumin-deungnok-beonho-input ${className}`}
48
+ type="text"
49
+ aria-label={label}
50
+ autocomplete="off"
51
+ bind:value
52
+ {required}
53
+ {disabled}
54
+ {...restProps}
55
+ />