@arbor-education/design-system.components 3.1.0 → 3.2.1

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 (104) hide show
  1. package/.gather/skills/write-stories/README.md +8 -4
  2. package/.gather/skills/write-stories/SKILL.md +59 -5
  3. package/.github/pull_request_template.md +4 -3
  4. package/CHANGELOG.md +20 -0
  5. package/CONTRIBUTING.md +1 -0
  6. package/dist/components/breadcrumbs/Breadcrumbs.stories.d.ts +1 -0
  7. package/dist/components/breadcrumbs/Breadcrumbs.stories.d.ts.map +1 -1
  8. package/dist/components/breadcrumbs/Breadcrumbs.stories.js +103 -21
  9. package/dist/components/breadcrumbs/Breadcrumbs.stories.js.map +1 -1
  10. package/dist/components/card/Card.stories.d.ts.map +1 -1
  11. package/dist/components/card/Card.stories.js +46 -41
  12. package/dist/components/card/Card.stories.js.map +1 -1
  13. package/dist/components/editableText/EditableText.stories.d.ts.map +1 -1
  14. package/dist/components/editableText/EditableText.stories.js +19 -6
  15. package/dist/components/editableText/EditableText.stories.js.map +1 -1
  16. package/dist/components/formField/fieldset/Fieldset.stories.d.ts.map +1 -1
  17. package/dist/components/formField/fieldset/Fieldset.stories.js +5 -3
  18. package/dist/components/formField/fieldset/Fieldset.stories.js.map +1 -1
  19. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts +2 -2
  20. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts.map +1 -1
  21. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js +0 -1
  22. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js.map +1 -1
  23. package/dist/components/formField/inputs/time/TimeInput.d.ts +1 -1
  24. package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +1 -1
  25. package/dist/components/icon/Icon.d.ts.map +1 -1
  26. package/dist/components/icon/Icon.js +18 -3
  27. package/dist/components/icon/Icon.js.map +1 -1
  28. package/dist/components/icon/Icon.stories.d.ts +4 -2
  29. package/dist/components/icon/Icon.stories.d.ts.map +1 -1
  30. package/dist/components/icon/Icon.stories.js +150 -102
  31. package/dist/components/icon/Icon.stories.js.map +1 -1
  32. package/dist/components/icon/Icon.test.js +146 -6
  33. package/dist/components/icon/Icon.test.js.map +1 -1
  34. package/dist/components/icon/LucideIcon.d.ts +17 -0
  35. package/dist/components/icon/LucideIcon.d.ts.map +1 -0
  36. package/dist/components/icon/LucideIcon.js +73 -0
  37. package/dist/components/icon/LucideIcon.js.map +1 -0
  38. package/dist/components/icon/allowedIcons.d.ts +44 -108
  39. package/dist/components/icon/allowedIcons.d.ts.map +1 -1
  40. package/dist/components/icon/allowedIcons.js +52 -112
  41. package/dist/components/icon/allowedIcons.js.map +1 -1
  42. package/dist/components/icon/types.d.ts +5 -4
  43. package/dist/components/icon/types.d.ts.map +1 -1
  44. package/dist/components/row/Row.stories.d.ts.map +1 -1
  45. package/dist/components/row/Row.stories.js +22 -13
  46. package/dist/components/row/Row.stories.js.map +1 -1
  47. package/dist/components/sidebar/Sidebar.stories.d.ts.map +1 -1
  48. package/dist/components/sidebar/Sidebar.stories.js +19 -24
  49. package/dist/components/sidebar/Sidebar.stories.js.map +1 -1
  50. package/dist/components/table/Table.stories.d.ts.map +1 -1
  51. package/dist/components/table/Table.stories.js +16 -10
  52. package/dist/components/table/Table.stories.js.map +1 -1
  53. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts.map +1 -1
  54. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js +8 -5
  55. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js.map +1 -1
  56. package/dist/components/table/tableControls/TableControls.stories.d.ts +1 -1
  57. package/dist/components/table/tableControls/TableControls.stories.d.ts.map +1 -1
  58. package/dist/components/table/tableControls/TableControls.stories.js +26 -21
  59. package/dist/components/table/tableControls/TableControls.stories.js.map +1 -1
  60. package/dist/components/tabs/Tabs.d.ts +1 -1
  61. package/dist/components/tabs/Tabs.stories.d.ts +1 -1
  62. package/dist/components/tabs/Tabs.stories.js +1 -1
  63. package/dist/components/tabs/Tabs.stories.js.map +1 -1
  64. package/dist/components/tabs/TabsItem.d.ts +2 -2
  65. package/dist/components/tabs/TabsItem.d.ts.map +1 -1
  66. package/dist/components/tabs/TabsItem.stories.d.ts +5 -5
  67. package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
  68. package/dist/components/tabs/TabsItem.stories.js +7 -4
  69. package/dist/components/tabs/TabsItem.stories.js.map +1 -1
  70. package/dist/components/widget/Widget.stories.d.ts +13 -0
  71. package/dist/components/widget/Widget.stories.d.ts.map +1 -1
  72. package/dist/components/widget/Widget.stories.js +45 -6
  73. package/dist/components/widget/Widget.stories.js.map +1 -1
  74. package/dist/components/widgetCalendar/WidgetCalendar.stories.d.ts +88 -16
  75. package/dist/components/widgetCalendar/WidgetCalendar.stories.d.ts.map +1 -1
  76. package/dist/components/widgetCalendar/WidgetCalendar.stories.js +443 -30
  77. package/dist/components/widgetCalendar/WidgetCalendar.stories.js.map +1 -1
  78. package/dist/index.css +1 -4
  79. package/dist/index.css.map +1 -1
  80. package/package.json +1 -1
  81. package/src/components/breadcrumbs/Breadcrumbs.stories.tsx +112 -21
  82. package/src/components/card/Card.stories.tsx +46 -41
  83. package/src/components/datePicker/datePicker.scss +0 -5
  84. package/src/components/editableText/EditableText.stories.tsx +26 -29
  85. package/src/components/formField/fieldset/Fieldset.stories.tsx +5 -3
  86. package/src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx +2 -2
  87. package/src/components/icon/Icon.stories.tsx +224 -119
  88. package/src/components/icon/Icon.test.tsx +178 -6
  89. package/src/components/icon/Icon.tsx +25 -3
  90. package/src/components/icon/LucideIcon.tsx +94 -0
  91. package/src/components/icon/allowedIcons.tsx +67 -207
  92. package/src/components/icon/lucideDynamic.d.ts +13 -0
  93. package/src/components/icon/types.ts +5 -4
  94. package/src/components/row/Row.stories.tsx +20 -14
  95. package/src/components/sidebar/Sidebar.stories.tsx +61 -112
  96. package/src/components/table/Table.stories.tsx +25 -10
  97. package/src/components/table/cellRenderers/SelectDropdownCellRenderer.stories.tsx +8 -5
  98. package/src/components/table/tableControls/TableControls.stories.tsx +26 -21
  99. package/src/components/tabs/Tabs.stories.tsx +1 -1
  100. package/src/components/tabs/TabsItem.stories.tsx +8 -4
  101. package/src/components/tabs/TabsItem.tsx +2 -2
  102. package/src/components/widget/Widget.stories.tsx +61 -6
  103. package/src/components/widgetCalendar/WidgetCalendar.stories.tsx +547 -74
  104. package/src/tokens.scss +1 -0
@@ -0,0 +1,17 @@
1
+ import type { IconName } from 'lucide-react/dynamic';
2
+ import type { CustomIconProps } from './types.js';
3
+ /** Every icon name published by `lucide-react`, kebab-cased. */
4
+ export type LucideIconName = IconName;
5
+ /** Every `lucide-react` icon name, for building galleries and validating input. */
6
+ export declare const lucideIconNames: readonly LucideIconName[];
7
+ export type LucideIconProps = CustomIconProps & {
8
+ name: LucideIconName;
9
+ fill?: string;
10
+ };
11
+ /**
12
+ * Renders a single `lucide-react` icon, loading it on demand. Until the icon resolves an empty SVG
13
+ * of the same size is rendered in its place, so the surrounding layout does not shift and the
14
+ * element keeps its accessible role throughout.
15
+ */
16
+ export declare const LucideIcon: (props: LucideIconProps) => import("react").JSX.Element;
17
+ //# sourceMappingURL=LucideIcon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LucideIcon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/LucideIcon.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEtC,mFAAmF;AACnF,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAAc,CAAC;AAgEpE,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG;IAC9C,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,eAAe,gCAUhD,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useReducer } from 'react';
3
+ import { dynamicIconImports, iconNames } from 'lucide-react/dynamic.mjs';
4
+ /** Every `lucide-react` icon name, for building galleries and validating input. */
5
+ export const lucideIconNames = iconNames;
6
+ const iconLoaders = dynamicIconImports;
7
+ /**
8
+ * Icons resolve through `lucide-react`'s per-icon dynamic imports so that consumers only ship the
9
+ * icons they actually render, rather than all ~1,900 of them. Both caches are module-scoped: the
10
+ * first render of a given icon anywhere in the app pays the import, and every render after that —
11
+ * including new instances in other trees — resolves synchronously from `loadedIcons`.
12
+ */
13
+ const loadedIcons = new Map();
14
+ const inFlightLoads = new Map();
15
+ const loadIcon = (name) => {
16
+ const inFlight = inFlightLoads.get(name);
17
+ if (inFlight) {
18
+ return inFlight;
19
+ }
20
+ // Annotated rather than inferred: names reaching `Icon` from a backend are not always valid.
21
+ const loader = iconLoaders[name];
22
+ if (!loader) {
23
+ console.error(`[design-system] "${name}" is not a known icon name.`);
24
+ // Cached so an unknown name is only reported once, however many times it is rendered.
25
+ const noSuchIcon = Promise.resolve();
26
+ inFlightLoads.set(name, noSuchIcon);
27
+ return noSuchIcon;
28
+ }
29
+ const load = loader()
30
+ .then((iconModule) => {
31
+ loadedIcons.set(name, iconModule.default);
32
+ })
33
+ .catch((error) => {
34
+ // Drop the rejected promise so a later render can retry (e.g. after a transient chunk 404).
35
+ inFlightLoads.delete(name);
36
+ console.error(`[design-system] Could not load the "${name}" icon.`, error);
37
+ });
38
+ inFlightLoads.set(name, load);
39
+ return load;
40
+ };
41
+ const useLucideIcon = (name) => {
42
+ const [, rerender] = useReducer((renderCount) => renderCount + 1, 0);
43
+ useEffect(() => {
44
+ if (loadedIcons.has(name)) {
45
+ return;
46
+ }
47
+ let isMounted = true;
48
+ void loadIcon(name).then(() => {
49
+ if (isMounted) {
50
+ rerender();
51
+ }
52
+ });
53
+ return () => {
54
+ isMounted = false;
55
+ };
56
+ }, [name]);
57
+ return loadedIcons.get(name);
58
+ };
59
+ /**
60
+ * Renders a single `lucide-react` icon, loading it on demand. Until the icon resolves an empty SVG
61
+ * of the same size is rendered in its place, so the surrounding layout does not shift and the
62
+ * element keeps its accessible role throughout.
63
+ */
64
+ export const LucideIcon = (props) => {
65
+ const { name, ...iconProps } = props;
66
+ const Component = useLucideIcon(name);
67
+ if (!Component) {
68
+ const { size, ...placeholderProps } = iconProps;
69
+ return _jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", ...placeholderProps });
70
+ }
71
+ return _jsx(Component, { ...iconProps });
72
+ };
73
+ //# sourceMappingURL=LucideIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LucideIcon.js","sourceRoot":"","sources":["../../../src/components/icon/LucideIcon.tsx"],"names":[],"mappings":"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"}
@@ -1,115 +1,51 @@
1
- import { type LucideProps } from 'lucide-react';
1
+ import { type LucideIconName } from './LucideIcon.js';
2
2
  import type { CustomIconProps } from './types.js';
3
- export declare const allowedIcons: {
4
- readonly '3-dot': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
5
- readonly archive: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
6
- readonly 'arrow-down': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
7
- readonly 'arrow-left': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
8
- readonly 'arrow-right-from-line': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
9
- readonly 'arrow-right': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
10
- readonly 'arrow-up-right': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
11
- readonly 'arrow-up': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
12
- readonly 'book-open': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
13
- readonly camera: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
14
- readonly 'chart-column-increasing': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
15
- readonly 'chart-spline': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
16
- readonly check: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
17
- readonly 'chevron-down': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
18
- readonly 'chevron-left': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
19
- readonly 'chevron-right': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
20
- readonly 'chevron-up': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
21
- readonly 'chevrons-left': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
22
- readonly 'chevrons-right': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
23
- readonly 'circle-alert': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
24
- readonly 'circle-check-big': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
25
- readonly 'circle-check': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
26
- readonly 'circle-help': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
27
- readonly 'circle-percent': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
28
- readonly 'circle-plus': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
29
- readonly 'circle-x': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
30
- readonly 'clipboard-list': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
31
- readonly clipboard: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
32
- readonly 'clock-3': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
33
- readonly 'cloud-upload': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
34
- readonly copy: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
35
- readonly 'corner-down-left': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
36
- readonly date: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
37
- readonly dot: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
38
- readonly download: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
39
- readonly 'ellipsis-vertical': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
40
- readonly ellipsis: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
41
- readonly expand: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
42
- readonly 'external-link': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
43
- readonly 'eye-off': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
44
- readonly eye: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
45
- readonly 'favourite-outline': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
46
- readonly file: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
47
- readonly files: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
48
- readonly flag: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
49
- readonly funnel: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
50
- readonly grab: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
51
- readonly 'graduation-cap': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
52
- readonly 'grid-3x3': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
53
- readonly group: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
54
- readonly guardians: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
55
- readonly history: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
56
- readonly house: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
57
- readonly info: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
58
- readonly 'iteration-ccw': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
59
- readonly 'layout-list': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
60
- readonly lightbulb: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
61
- readonly link: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
62
- readonly 'list-filter-plus': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
63
- readonly list: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
64
- readonly 'list-tree': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
65
- readonly loader: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
66
- readonly 'lock-open': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
67
- readonly lock: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
68
- readonly 'log-out': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
69
- readonly mail: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
70
- readonly menu: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
71
- readonly 'message-square-more': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
72
- readonly mic: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
73
- readonly minus: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
74
- readonly monitor: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
75
- readonly 'paint-bucket': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
76
- readonly paperclip: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
77
- readonly 'party-popper': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
78
- readonly pencil: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
79
- readonly percent: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
80
- readonly phone: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
81
- readonly pin: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
82
- readonly plus: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
83
- readonly projector: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
84
- readonly redo: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
85
- readonly save: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
86
- readonly search: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
87
- readonly send: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
88
- readonly settings: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
89
- readonly share: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
90
- readonly sheet: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
91
- readonly shrink: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
92
- readonly 'sliders-horizontal': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
93
- readonly smartphone: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
94
- readonly sorting: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
95
- readonly sparkles: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
96
- readonly staff: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
97
- readonly 'switch-camera': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
98
- readonly table: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
99
- readonly trash: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
100
- readonly 'trending-down': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
101
- readonly 'trending-up': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
102
- readonly 'triangle-alert': import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
103
- readonly undo: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
104
- readonly upload: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
105
- readonly user: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
106
- readonly x: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
107
- readonly zap: import("react").ForwardRefExoticComponent<Omit<LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
3
+ /**
4
+ * Arbor names that point at a differently-named Lucide icon. These take precedence over the Lucide
5
+ * name they shadow, so `trash` stays the lidded can (`trash-2`) rather than Lucide's plain `trash`.
6
+ * Seven of these — `grab`, `group`, `loader`, `redo`, `shrink`, `trash` and `undo` — shadow a real
7
+ * Lucide icon with a different glyph, which is deliberate: renaming them would break every existing
8
+ * consumer. Reach for the target name directly if you want Lucide's version.
9
+ *
10
+ * The `satisfies` clause makes every target a compile-time-checked Lucide icon name.
11
+ */
12
+ export declare const iconAliases: {
13
+ readonly '3-dot': "ellipsis-vertical";
14
+ readonly 'circle-help': "circle-question-mark";
15
+ readonly date: "calendar-fold";
16
+ readonly 'favourite-outline': "star";
17
+ readonly grab: "grip-vertical";
18
+ readonly group: "users-round";
19
+ readonly guardians: "users";
20
+ readonly loader: "loader-circle";
21
+ readonly redo: "redo-2";
22
+ readonly shrink: "minimize-2";
23
+ readonly sorting: "arrow-down-up";
24
+ readonly staff: "graduation-cap";
25
+ readonly trash: "trash-2";
26
+ readonly undo: "undo-2";
27
+ };
28
+ /**
29
+ * Icons that are not plain Lucide glyphs: Arbor-specific artwork, and the solid variants built for
30
+ * particular semantic emphasis states.
31
+ */
32
+ export declare const customIcons: {
108
33
  readonly 'ask-arbor': (props: CustomIconProps) => import("react").JSX.Element;
109
34
  readonly google: (props: CustomIconProps) => import("react").JSX.Element;
110
35
  readonly 'check-solid': (props: CustomIconProps) => import("react").JSX.Element;
111
- readonly 'favourite-filled': (props: LucideProps) => import("react").JSX.Element;
36
+ readonly 'favourite-filled': (props: CustomIconProps) => import("react").JSX.Element;
112
37
  readonly 'x-solid': (props: CustomIconProps) => import("react").JSX.Element;
113
38
  };
114
- export type IconName = keyof typeof allowedIcons;
39
+ export type IconName = LucideIconName | keyof typeof iconAliases | keyof typeof customIcons;
40
+ /** Every name `Icon` accepts: the whole Lucide set, plus Arbor's aliases and custom icons. */
41
+ export declare const iconNames: readonly IconName[];
42
+ /**
43
+ * The `Icon` name allow-list, as a plain object so that membership can be tested with
44
+ * `hasOwnProperty`. Prefer {@link isIconName}; the values carry no meaning and exist only to make
45
+ * this a record. Icon components are no longer held here — they are loaded on demand, so nothing
46
+ * outside a render has a component to hand out.
47
+ */
48
+ export declare const allowedIcons: Readonly<Record<IconName, true>>;
49
+ /** Narrows an arbitrary string to an `IconName`, for validating names that come from a backend. */
50
+ export declare const isIconName: (name: string) => name is IconName;
115
51
  //# sourceMappingURL=allowedIcons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"allowedIcons.d.ts","sourceRoot":"","sources":["../../../src/components/icon/allowedIcons.tsx"],"names":[],"mappings":"AAAA,OAAO,EA8DG,KAAK,WAAW,EA8BzB,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA8GA,eAAe;yCACV,WAAW;gCAGpB,eAAe;CAC1B,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,YAAY,CAAC"}
1
+ {"version":3,"file":"allowedIcons.d.ts","sourceRoot":"","sources":["../../../src/components/icon/allowedIcons.tsx"],"names":[],"mappings":"AACA,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;CAeqC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;yCAIM,eAAe;;CAIuC,CAAC;AAErF,MAAM,MAAM,QAAQ,GACd,cAAc,GACd,MAAM,OAAO,WAAW,GACxB,MAAM,OAAO,WAAW,CAAC;AAM/B,8FAA8F;AAC9F,eAAO,MAAM,SAAS,EAAE,SAAS,QAAQ,EAIxC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAEpB,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AAEtC,mGAAmG;AACnG,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,IAAI,IAAI,QACQ,CAAC"}
@@ -1,121 +1,61 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Archive, ArrowDown, ArrowDownUp, ArrowLeft, ArrowRight, ArrowRightFromLine, ArrowUp, ArrowUpRight, BookOpen, CalendarFold, Camera, ChartColumnIncreasing, ChartSpline, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, ChevronUp, CircleAlert, CircleCheck, CircleCheckBig, CirclePercent, CirclePlus, CircleQuestionMark, CircleX, Clipboard, ClipboardList, Clock3, CloudUpload, Copy, CornerDownLeft, Dot, Download, Ellipsis, EllipsisVertical, Expand, ExternalLink, Eye, EyeOff, File, Files, Flag, Funnel, GraduationCap, Grid3x3, GripVertical, History, House, Info, IterationCcw, LayoutList, Lightbulb, Link, List, ListFilterPlus, ListTree, LoaderCircle, Lock, LockOpen, LogOut, Mail, Menu, MessageSquareMore, Mic, Minimize2, Minus, Monitor, PaintBucket, Paperclip, PartyPopper, Pencil, Percent, Phone, Pin, Plus, Projector, Redo2, Save, Search, Send, Settings, Share, Sheet, SlidersHorizontal, Smartphone, Sparkles, Star, SwitchCamera, Table, Trash2, TrendingDown, TrendingUp, TriangleAlert, Undo2, Upload, User, Users, UsersRound, X, Zap, } from 'lucide-react';
2
+ import { LucideIcon, lucideIconNames } from './LucideIcon.js';
3
3
  import { AskArbor } from './customIcons/AskArbor.js';
4
4
  import { CheckSolid } from './customIcons/CheckSolid.js';
5
5
  import { Google } from './customIcons/Google.js';
6
6
  import { XSolid } from './customIcons/XSolid.js';
7
- export const allowedIcons = {
8
- // lucide icons
9
- '3-dot': EllipsisVertical,
10
- 'archive': Archive,
11
- 'arrow-down': ArrowDown,
12
- 'arrow-left': ArrowLeft,
13
- 'arrow-right-from-line': ArrowRightFromLine,
14
- 'arrow-right': ArrowRight,
15
- 'arrow-up-right': ArrowUpRight,
16
- 'arrow-up': ArrowUp,
17
- 'book-open': BookOpen,
18
- 'camera': Camera,
19
- 'chart-column-increasing': ChartColumnIncreasing,
20
- 'chart-spline': ChartSpline,
21
- 'check': Check,
22
- 'chevron-down': ChevronDown,
23
- 'chevron-left': ChevronLeft,
24
- 'chevron-right': ChevronRight,
25
- 'chevron-up': ChevronUp,
26
- 'chevrons-left': ChevronsLeft,
27
- 'chevrons-right': ChevronsRight,
28
- 'circle-alert': CircleAlert,
29
- 'circle-check-big': CircleCheckBig,
30
- 'circle-check': CircleCheck,
31
- 'circle-help': CircleQuestionMark,
32
- 'circle-percent': CirclePercent,
33
- 'circle-plus': CirclePlus,
34
- 'circle-x': CircleX,
35
- 'clipboard-list': ClipboardList,
36
- 'clipboard': Clipboard,
37
- 'clock-3': Clock3,
38
- 'cloud-upload': CloudUpload,
39
- 'copy': Copy,
40
- 'corner-down-left': CornerDownLeft,
41
- 'date': CalendarFold,
42
- 'dot': Dot,
43
- 'download': Download,
44
- 'ellipsis-vertical': EllipsisVertical,
45
- 'ellipsis': Ellipsis,
46
- 'expand': Expand,
47
- 'external-link': ExternalLink,
48
- 'eye-off': EyeOff,
49
- 'eye': Eye,
50
- 'favourite-outline': Star,
51
- 'file': File,
52
- 'files': Files,
53
- 'flag': Flag,
54
- 'funnel': Funnel,
55
- 'grab': GripVertical,
56
- 'graduation-cap': GraduationCap,
57
- 'grid-3x3': Grid3x3,
58
- 'group': UsersRound,
59
- 'guardians': Users,
60
- 'history': History,
61
- 'house': House,
62
- 'info': Info,
63
- 'iteration-ccw': IterationCcw,
64
- 'layout-list': LayoutList,
65
- 'lightbulb': Lightbulb,
66
- 'link': Link,
67
- 'list-filter-plus': ListFilterPlus,
68
- 'list': List,
69
- 'list-tree': ListTree,
70
- 'loader': LoaderCircle,
71
- 'lock-open': LockOpen,
72
- 'lock': Lock,
73
- 'log-out': LogOut,
74
- 'mail': Mail,
75
- 'menu': Menu,
76
- 'message-square-more': MessageSquareMore,
77
- 'mic': Mic,
78
- 'minus': Minus,
79
- 'monitor': Monitor,
80
- 'paint-bucket': PaintBucket,
81
- 'paperclip': Paperclip,
82
- 'party-popper': PartyPopper,
83
- 'pencil': Pencil,
84
- 'percent': Percent,
85
- 'phone': Phone,
86
- 'pin': Pin,
87
- 'plus': Plus,
88
- 'projector': Projector,
89
- 'redo': Redo2,
90
- 'save': Save,
91
- 'search': Search,
92
- 'send': Send,
93
- 'settings': Settings,
94
- 'share': Share,
95
- 'sheet': Sheet,
96
- 'shrink': Minimize2,
97
- 'sliders-horizontal': SlidersHorizontal,
98
- 'smartphone': Smartphone,
99
- 'sorting': ArrowDownUp,
100
- 'sparkles': Sparkles,
101
- 'staff': GraduationCap,
102
- 'switch-camera': SwitchCamera,
103
- 'table': Table,
104
- 'trash': Trash2,
105
- 'trending-down': TrendingDown,
106
- 'trending-up': TrendingUp,
107
- 'triangle-alert': TriangleAlert,
108
- 'undo': Undo2,
109
- 'upload': Upload,
110
- 'user': User,
111
- 'x': X,
112
- 'zap': Zap,
113
- // custom icons
7
+ /**
8
+ * Arbor names that point at a differently-named Lucide icon. These take precedence over the Lucide
9
+ * name they shadow, so `trash` stays the lidded can (`trash-2`) rather than Lucide's plain `trash`.
10
+ * Seven of these — `grab`, `group`, `loader`, `redo`, `shrink`, `trash` and `undo` — shadow a real
11
+ * Lucide icon with a different glyph, which is deliberate: renaming them would break every existing
12
+ * consumer. Reach for the target name directly if you want Lucide's version.
13
+ *
14
+ * The `satisfies` clause makes every target a compile-time-checked Lucide icon name.
15
+ */
16
+ export const iconAliases = {
17
+ '3-dot': 'ellipsis-vertical',
18
+ 'circle-help': 'circle-question-mark',
19
+ 'date': 'calendar-fold',
20
+ 'favourite-outline': 'star',
21
+ 'grab': 'grip-vertical',
22
+ 'group': 'users-round',
23
+ 'guardians': 'users',
24
+ 'loader': 'loader-circle',
25
+ 'redo': 'redo-2',
26
+ 'shrink': 'minimize-2',
27
+ 'sorting': 'arrow-down-up',
28
+ 'staff': 'graduation-cap',
29
+ 'trash': 'trash-2',
30
+ 'undo': 'undo-2',
31
+ };
32
+ /**
33
+ * Icons that are not plain Lucide glyphs: Arbor-specific artwork, and the solid variants built for
34
+ * particular semantic emphasis states.
35
+ */
36
+ export const customIcons = {
114
37
  'ask-arbor': AskArbor,
115
38
  'google': Google,
116
- // solid icons
117
- 'check-solid': (props) => _jsx(CheckSolid, { ...props }),
118
- 'favourite-filled': (props) => (_jsx(Star, { ...props, fill: props.color })),
119
- 'x-solid': (props) => _jsx(XSolid, { ...props }),
39
+ 'check-solid': CheckSolid,
40
+ 'favourite-filled': (props) => (_jsx(LucideIcon, { name: "star", ...props, fill: props.color })),
41
+ 'x-solid': XSolid,
120
42
  };
43
+ // `Object.keys` widens to `string[]`, so the key unions are reasserted here.
44
+ const aliasNames = Object.keys(iconAliases);
45
+ const customIconNames = Object.keys(customIcons);
46
+ /** Every name `Icon` accepts: the whole Lucide set, plus Arbor's aliases and custom icons. */
47
+ export const iconNames = [
48
+ ...lucideIconNames,
49
+ ...aliasNames,
50
+ ...customIconNames,
51
+ ];
52
+ /**
53
+ * The `Icon` name allow-list, as a plain object so that membership can be tested with
54
+ * `hasOwnProperty`. Prefer {@link isIconName}; the values carry no meaning and exist only to make
55
+ * this a record. Icon components are no longer held here — they are loaded on demand, so nothing
56
+ * outside a render has a component to hand out.
57
+ */
58
+ export const allowedIcons = Object.freeze(Object.fromEntries(iconNames.map(name => [name, true])));
59
+ /** Narrows an arbitrary string to an `IconName`, for validating names that come from a backend. */
60
+ export const isIconName = (name) => Object.prototype.hasOwnProperty.call(allowedIcons, name);
121
61
  //# sourceMappingURL=allowedIcons.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"allowedIcons.js","sourceRoot":"","sources":["../../../src/components/icon/allowedIcons.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"allowedIcons.js","sourceRoot":"","sources":["../../../src/components/icon/allowedIcons.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAuB,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,mBAAmB;IAC5B,aAAa,EAAE,sBAAsB;IACrC,MAAM,EAAE,eAAe;IACvB,mBAAmB,EAAE,MAAM;IAC3B,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,aAAa;IACtB,WAAW,EAAE,OAAO;IACpB,QAAQ,EAAE,eAAe;IACzB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,YAAY;IACtB,SAAS,EAAE,eAAe;IAC1B,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;CAC2C,CAAC;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE,MAAM;IAChB,aAAa,EAAE,UAAU;IACzB,kBAAkB,EAAE,CAAC,KAAsB,EAAE,EAAE,CAAC,CAC9C,KAAC,UAAU,IAAC,IAAI,EAAC,MAAM,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,GAAI,CACzD;IACD,SAAS,EAAE,MAAM;CACiE,CAAC;AAOrF,6EAA6E;AAC7E,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAA4C,CAAC;AACvF,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAA4C,CAAC;AAE5F,8FAA8F;AAC9F,MAAM,CAAC,MAAM,SAAS,GAAwB;IAC5C,GAAG,eAAe;IAClB,GAAG,UAAU;IACb,GAAG,eAAe;CACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CACvC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CACpB,CAAC;AAEtC,mGAAmG;AACnG,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAoB,EAAE,CAC3D,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC"}
@@ -1,9 +1,10 @@
1
1
  export declare const iconSizes: readonly [12, 16, 24];
2
2
  export type IconSize = typeof iconSizes[number];
3
3
  export type CustomIconProps = {
4
- size: IconSize;
5
- color?: string;
6
- role?: string;
7
- className?: string;
4
+ 'size': IconSize;
5
+ 'color'?: string;
6
+ 'role'?: string;
7
+ 'className'?: string;
8
+ 'aria-hidden'?: boolean;
8
9
  };
9
10
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/icon/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,uBAAwB,CAAC;AAC/C,MAAM,MAAM,QAAQ,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/icon/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,uBAAwB,CAAC;AAC/C,MAAM,MAAM,QAAQ,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Row.stories.d.ts","sourceRoot":"","sources":["../../../src/components/row/Row.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAa5D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAyI/B,iBAAS,WAAW,gCAmBnB;AAMD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiHkB,CAAC;AAE7B,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;AAyGlC,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAqBvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAqBvB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KA+B7B,CAAC;AAEF,eAAO,MAAM,kCAAkC,EAAE,KAiChD,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAiCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAiCtB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAsB9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAiC5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAmC7B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAiCvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAmC/B,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAuCrC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAiCvB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAiDzB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAqC1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KA+B9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KA+B7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KA+D9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAkChC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KA4CzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAmCjC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAsBtB,CAAC"}
1
+ {"version":3,"file":"Row.stories.d.ts","sourceRoot":"","sources":["../../../src/components/row/Row.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAa5D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAyI/B,iBAAS,WAAW,gCAmBnB;AAMD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiHkB,CAAC;AAE7B,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;AAuGlC,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAqBvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAqBvB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KA+B7B,CAAC;AAEF,eAAO,MAAM,kCAAkC,EAAE,KAiChD,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAiCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAiCtB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAsB9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAiC5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAmC7B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAiCvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAmC/B,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAqCrC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAiCvB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KA+CzB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAqC1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KA+B9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KA+B7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KA+D9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAkChC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAwDzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAmCjC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAsBtB,CAAC"}
@@ -270,7 +270,7 @@ const withDescription = (story, description) => ({
270
270
  // ---------------------------------------------------------------------------
271
271
  // Template components
272
272
  // ---------------------------------------------------------------------------
273
- const MixedClickableAndStaticTemplate = () => (_jsxs(Section, { title: "Pupil details", children: [_jsx(Row, { label: "Name", value: "Amara Osei-Bonsu" }), _jsx(Row, { label: "Year group", value: "Year 10" }), _jsx(Row, { label: "Form", value: "10JH" }), _jsx(Row, { label: "SEN status", value: "SEN Support", note: "Review due May 2026", onClick: () => { } }), _jsx(Row, { label: "Attendance (YTD)", value: "88.3%", note: "Below 90% threshold", onClick: () => { } })] }));
273
+ const MixedClickableAndStaticTemplate = () => (_jsxs(Section, { title: "Pupil details", children: [_jsx(Row, { label: "Name", value: "Amara Osei-Bonsu" }), _jsx(Row, { label: "Year group", value: "Year 10" }), _jsx(Row, { label: "Form", value: "10JH" }), _jsx(Row, { label: "SEN status", value: "SEN Support", onClick: () => { } }), _jsx(Row, { label: "Attendance (YTD)", value: "88.3%", onClick: () => { } })] }));
274
274
  const InSectionTemplate = () => (_jsxs(Section, { title: "Personal details", children: [_jsx(Row, { label: "Pupil", value: "Amara Osei-Bonsu" }), _jsx(Row, { label: "Date of birth", value: "14 March 2010" }), _jsx(Row, { label: "Admission number", value: "001847" }), _jsx(Row, { label: "UPN", value: "A823456789012" }), _jsx(Row, { label: "Email address", value: "a.osei-bonsu@pupil.school.example", href: "mailto:a.osei-bonsu@pupil.school.example" })] }));
275
275
  const AccessibilityNotesTemplate = () => (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--spacing-xsmall)' }, children: [_jsxs("p", { style: { margin: 0, color: 'var(--color-grey-600)', fontSize: 'var(--font-size-3-14)' }, children: ["Static row \u2014", ' ', _jsx("code", { children: "tabIndex=\"-1\"" }), ", no ARIA role, not in tab order"] }), _jsx(Row, { label: "Year group", value: "Year 9" })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--spacing-xsmall)' }, children: [_jsxs("p", { style: { margin: 0, color: 'var(--color-grey-600)', fontSize: 'var(--font-size-3-14)' }, children: ["Clickable row \u2014", ' ', _jsx("code", { children: "tabIndex=\"0\"" }), ", keyboard-activatable, but", ' ', _jsxs("strong", { children: ["no", _jsx("code", { children: "role=\"button\"" })] }), ' ', "\u2014 screen readers may not announce it as interactive"] }), _jsx(Row, { label: "SEN record", value: "SEN Support", onClick: () => { } })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--spacing-xsmall)' }, children: [_jsxs("p", { style: { margin: 0, color: 'var(--color-grey-600)', fontSize: 'var(--font-size-3-14)' }, children: ["href row \u2014 renders a real", ' ', _jsx("code", { children: "<a>" }), ' ', "tag with full native link semantics \u2713"] }), _jsx(Row, { label: "Email address", value: "admin@school.example", href: "mailto:admin@school.example" })] })] }));
276
276
  // ---------------------------------------------------------------------------
@@ -562,13 +562,11 @@ function PupilDetailSection() {
562
562
  <Row
563
563
  label="SEN status"
564
564
  value="SEN Support"
565
- note="Review due May 2026"
566
565
  onClick={() => navigateToSENRecord()}
567
566
  />
568
567
  <Row
569
568
  label="Attendance (YTD)"
570
569
  value="88.3%"
571
- note="Below 90% threshold"
572
570
  onClick={() => navigateToAttendance()}
573
571
  />
574
572
  </Section>
@@ -611,7 +609,7 @@ export default PersonalDetailsSection;
611
609
  },
612
610
  },
613
611
  render: InSectionTemplate,
614
- }, 'The canonical real-world usage: `Row` components as children of a `Section`. The `Section` provides the container heading and background; each `Row` handles the label/value layout. Most product uses of `Row` are inside a `Section`.');
612
+ }, 'The canonical real-world usage: `Row` components as children of a `Section`. The `Section` provides the container heading and background; each `Row` handles the label/value layout. Most product uses of `Row` are inside a `Section` — one row demonstrates a linked value via `href` to show that pattern working inside a realistic panel too.');
615
613
  export const LongContent = withDescription({
616
614
  parameters: {
617
615
  controls: { disable: true },
@@ -633,7 +631,6 @@ function LongContentExample() {
633
631
  label="Pupil premium eligibility reason"
634
632
  value="Free school meals — ever 6"
635
633
  note="Verified by LA"
636
- onClick={() => navigateToEligibilityDetail()}
637
634
  />
638
635
  </div>
639
636
  );
@@ -643,7 +640,7 @@ export default LongContentExample;
643
640
  },
644
641
  },
645
642
  },
646
- render: () => (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--spacing-xsmall)' }, children: [_jsx(Row, { label: "Special educational needs and disabilities coordinator", value: "Mrs Jacqueline Abernathy-Thornton", note: "Updated 3 January 2026" }), _jsx(Row, { label: "Pupil premium eligibility reason", value: "Free school meals \u2014 ever 6", note: "Verified by LA", onClick: fn() })] })),
643
+ render: () => (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--spacing-xsmall)' }, children: [_jsx(Row, { label: "Special educational needs and disabilities coordinator", value: "Mrs Jacqueline Abernathy-Thornton", note: "Updated 3 January 2026" }), _jsx(Row, { label: "Pupil premium eligibility reason", value: "Free school meals \u2014 ever 6", note: "Verified by LA" })] })),
647
644
  }, 'Long label and value strings exercise the flex layout. The label column enforces a 190 px maximum width — long labels wrap rather than compress the value column. Test your specific container widths if you have long copy in narrow panels.');
648
645
  export const MultipleRows = withDescription({
649
646
  parameters: {
@@ -799,16 +796,28 @@ export const WithTooltip = withDescription({
799
796
  code: `
800
797
  import { Row } from '@arbor-education/design-system.components';
801
798
 
802
- function ReadOnlyRow() {
799
+ function ReadOnlyRows() {
803
800
  return (
804
- <Row
805
- label="UPN"
806
- value="A823456789012"
807
- tooltipText="Unique Pupil Number — assigned by the DfE and cannot be changed here"
808
- />
801
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--spacing-small)' }}>
802
+ <Row
803
+ label="UPN"
804
+ value="A823456789012"
805
+ tooltipText="Unique Pupil Number — assigned by the DfE and cannot be changed here"
806
+ />
807
+ <Row
808
+ label="Admission number"
809
+ value="001847"
810
+ tooltipText="Set at admission — contact the office to request a change"
811
+ />
812
+ {/* No tooltipText — hovering this row shows nothing */}
813
+ <Row
814
+ label="Year group"
815
+ value="Year 9"
816
+ />
817
+ </div>
809
818
  );
810
819
  }
811
- export default ReadOnlyRow;
820
+ export default ReadOnlyRows;
812
821
  `.trim(),
813
822
  },
814
823
  },