@arbor-education/design-system.components 3.4.5 → 4.0.0-react19-alpha.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 (82) hide show
  1. package/.changeset/empty-clocks-jog.md +5 -0
  2. package/dist/components/combobox/ComboboxButtonTrigger.d.ts +1 -1
  3. package/dist/components/combobox/ComboboxButtonTrigger.d.ts.map +1 -1
  4. package/dist/components/combobox/ComboboxListbox.d.ts +2 -2
  5. package/dist/components/combobox/ComboboxListbox.d.ts.map +1 -1
  6. package/dist/components/combobox/ComboboxTrigger.d.ts +2 -2
  7. package/dist/components/combobox/ComboboxTrigger.d.ts.map +1 -1
  8. package/dist/components/combobox/useComboboxListboxDom.d.ts +1 -1
  9. package/dist/components/combobox/useComboboxListboxDom.d.ts.map +1 -1
  10. package/dist/components/combobox/useElementWidth.d.ts +2 -0
  11. package/dist/components/combobox/useElementWidth.d.ts.map +1 -0
  12. package/dist/components/combobox/useElementWidth.js +31 -0
  13. package/dist/components/combobox/useElementWidth.js.map +1 -0
  14. package/dist/components/combobox/useVisibleChips.d.ts +21 -0
  15. package/dist/components/combobox/useVisibleChips.d.ts.map +1 -0
  16. package/dist/components/combobox/useVisibleChips.js +59 -0
  17. package/dist/components/combobox/useVisibleChips.js.map +1 -0
  18. package/dist/components/combobox/useVisibleChips.test.d.ts +2 -0
  19. package/dist/components/combobox/useVisibleChips.test.d.ts.map +1 -0
  20. package/dist/components/combobox/useVisibleChips.test.js +81 -0
  21. package/dist/components/combobox/useVisibleChips.test.js.map +1 -0
  22. package/dist/components/heading/Heading.d.ts +28 -14
  23. package/dist/components/heading/Heading.d.ts.map +1 -1
  24. package/dist/components/heading/Heading.stories.d.ts +28 -14
  25. package/dist/components/heading/Heading.stories.d.ts.map +1 -1
  26. package/dist/components/icoText/IcoText.d.ts +37 -0
  27. package/dist/components/icoText/IcoText.d.ts.map +1 -0
  28. package/dist/components/icoText/IcoText.js +29 -0
  29. package/dist/components/icoText/IcoText.js.map +1 -0
  30. package/dist/components/icoText/IcoText.stories.d.ts +60 -0
  31. package/dist/components/icoText/IcoText.stories.d.ts.map +1 -0
  32. package/dist/components/icoText/IcoText.stories.js +319 -0
  33. package/dist/components/icoText/IcoText.stories.js.map +1 -0
  34. package/dist/components/icoText/IcoText.test.d.ts +2 -0
  35. package/dist/components/icoText/IcoText.test.d.ts.map +1 -0
  36. package/dist/components/icoText/IcoText.test.js +27 -0
  37. package/dist/components/icoText/IcoText.test.js.map +1 -0
  38. package/dist/components/table/Table.test.js +18 -14
  39. package/dist/components/table/Table.test.js.map +1 -1
  40. package/dist/components/tabs/TabsItem.stories.d.ts +50 -22
  41. package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
  42. package/dist/components/tagList/useTagListCollapsedLayout.d.ts +3 -3
  43. package/dist/components/tagList/useTagListCollapsedLayout.d.ts.map +1 -1
  44. package/dist/components/tree-row/TreeRow.d.ts +32 -0
  45. package/dist/components/tree-row/TreeRow.d.ts.map +1 -0
  46. package/dist/components/tree-row/TreeRow.js +19 -0
  47. package/dist/components/tree-row/TreeRow.js.map +1 -0
  48. package/dist/components/tree-row/TreeRow.stories.d.ts +13 -0
  49. package/dist/components/tree-row/TreeRow.stories.d.ts.map +1 -0
  50. package/dist/components/tree-row/TreeRow.stories.js +774 -0
  51. package/dist/components/tree-row/TreeRow.stories.js.map +1 -0
  52. package/dist/components/tree-row/TreeRow.test.d.ts +2 -0
  53. package/dist/components/tree-row/TreeRow.test.d.ts.map +1 -0
  54. package/dist/components/tree-row/TreeRow.test.js +262 -0
  55. package/dist/components/tree-row/TreeRow.test.js.map +1 -0
  56. package/dist/components/tree-row/TreeRowSection.d.ts +12 -0
  57. package/dist/components/tree-row/TreeRowSection.d.ts.map +1 -0
  58. package/dist/components/tree-row/TreeRowSection.js +20 -0
  59. package/dist/components/tree-row/TreeRowSection.js.map +1 -0
  60. package/dist/utils/PopupParentContext.d.ts +3 -0
  61. package/dist/utils/PopupParentContext.d.ts.map +1 -0
  62. package/dist/utils/PopupParentContext.js +6 -0
  63. package/dist/utils/PopupParentContext.js.map +1 -0
  64. package/dist/utils/PopupParentContext.stories.d.ts +17 -0
  65. package/dist/utils/PopupParentContext.stories.d.ts.map +1 -0
  66. package/dist/utils/PopupParentContext.stories.js +266 -0
  67. package/dist/utils/PopupParentContext.stories.js.map +1 -0
  68. package/dist/utils/getDefaultPopupParent.d.ts +2 -0
  69. package/dist/utils/getDefaultPopupParent.d.ts.map +1 -0
  70. package/dist/utils/getDefaultPopupParent.js +19 -0
  71. package/dist/utils/getDefaultPopupParent.js.map +1 -0
  72. package/dist/utils/hooks/useIsMounted.d.ts +1 -1
  73. package/dist/utils/hooks/useIsMounted.d.ts.map +1 -1
  74. package/package.json +19 -5
  75. package/src/components/arborLogo/__snapshots__/ArborLogo.test.tsx.snap +18 -18
  76. package/src/components/combobox/ComboboxButtonTrigger.tsx +1 -1
  77. package/src/components/combobox/ComboboxListbox.tsx +2 -2
  78. package/src/components/combobox/ComboboxTrigger.tsx +2 -2
  79. package/src/components/combobox/useComboboxListboxDom.ts +1 -1
  80. package/src/components/table/Table.test.tsx +18 -14
  81. package/src/components/tagList/useTagListCollapsedLayout.ts +3 -3
  82. package/src/docs/UsingComponents.mdx +6 -0
@@ -0,0 +1,266 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useRef } from 'react';
3
+ import { Heading as DocHeading, Markdown, Stories, Subtitle, Title, } from '@storybook/addon-docs/blocks';
4
+ import { PopupParentContext } from './PopupParentContext.js';
5
+ import { Button } from '../components/button/Button.js';
6
+ import { Dropdown } from '../components/dropdown/Dropdown.js';
7
+ // ---------------------------------------------------------------------------
8
+ // Docs page content
9
+ // ---------------------------------------------------------------------------
10
+ const DESCRIPTION_INTRO = [
11
+ '`PopupParentContext` is a React context that controls where portalled floating elements',
12
+ '— dropdowns, tooltips, date pickers, comboboxes — are rendered in the DOM.',
13
+ 'In most applications you do **not** need to configure this: the default behaviour portals all floating',
14
+ 'content to a shared `<div id="ds-popup-parent">` appended to `document.body`.',
15
+ ].join(' ');
16
+ const USAGE_GUIDANCE = [
17
+ '### When you need PopupParentContext',
18
+ '',
19
+ '- **Custom virtualised panels** — when your layout clips content with `overflow: hidden` AND you need',
20
+ ' popups to appear inside that container (not body), provide a ref to a container element inside the',
21
+ ' clip boundary',
22
+ '- **Non-Arbor modals and drawers** — if you wrap Arbor components inside a third-party modal, floating',
23
+ ' elements may render beneath the modal overlay due to z-index stacking. Provide a container inside the',
24
+ ' modal to keep popups on top',
25
+ '- **Custom stacking contexts** — when `transform`, `isolation`, or `will-change` creates a stacking',
26
+ ' context above `z-index: 1` (the default popup parent z-index), popups may appear beneath fixed UI',
27
+ ' chrome. Move the container inside the stacking context',
28
+ '',
29
+ '---',
30
+ '',
31
+ '### When you do NOT need PopupParentContext',
32
+ '',
33
+ '| Situation | Why you are safe |',
34
+ '|---|---|',
35
+ '| `Dropdown`, `Tooltip`, `Combobox` in a standard page layout | Default context portals to `document.body` — no clipping |',
36
+ '| Floating elements inside Arbor `Modal` | Modal provides its overlay as the popup parent automatically |',
37
+ '| `Table` column filters | `BooleanFilter` and `TimeFilter` wrap their children in a provider automatically |',
38
+ ].join('\n');
39
+ const DEVELOPER_NOTES = [
40
+ '### Components that consume PopupParentContext',
41
+ '',
42
+ '| Component | What gets portalled |',
43
+ '|---|---|',
44
+ '| `Dropdown` | `Dropdown.Content` panel |',
45
+ '| `Tooltip` | Tooltip bubble |',
46
+ '| `Combobox` | Options listbox |',
47
+ '| `DatePicker` | Calendar popup |',
48
+ '| `DateTimePicker` | Calendar + time popup |',
49
+ '| `Modal` | Modal overlay (also provides itself as parent for any floating elements inside) |',
50
+ '| `SlideoverManager` | Slideover panel |',
51
+ '| `Table` column filters | `BooleanFilter`, `TimeFilter` (wraps automatically) |',
52
+ '',
53
+ '---',
54
+ '',
55
+ '### Usage',
56
+ '',
57
+ '```tsx',
58
+ 'import { useRef } from \'react\';',
59
+ 'import { PopupParentContext, Dropdown } from \'@arbor-education/design-system.components\';',
60
+ '',
61
+ 'function ClippedPanel() {',
62
+ ' // ref points to the container that should receive portalled content',
63
+ ' const popupContainerRef = useRef<HTMLDivElement>(null);',
64
+ '',
65
+ ' return (',
66
+ ' <div style={{ position: \'relative\', overflow: \'hidden\', maxHeight: 300 }}>',
67
+ ' {/*',
68
+ ' This div sits OUTSIDE the overflow:hidden clip boundary.',
69
+ ' Floating elements portal here instead of document.body.',
70
+ ' */}',
71
+ ' <div ref={popupContainerRef} style={{ position: \'fixed\', zIndex: 100 }} />',
72
+ '',
73
+ ' <PopupParentContext.Provider value={popupContainerRef}>',
74
+ ' <Dropdown>',
75
+ ' <Dropdown.Trigger>',
76
+ ' <Button variant="dropdown">Actions</Button>',
77
+ ' </Dropdown.Trigger>',
78
+ ' <Dropdown.Content>',
79
+ ' <Dropdown.Item>Edit record</Dropdown.Item>',
80
+ ' <Dropdown.Item>Delete record</Dropdown.Item>',
81
+ ' </Dropdown.Content>',
82
+ ' </Dropdown>',
83
+ ' </PopupParentContext.Provider>',
84
+ ' </div>',
85
+ ' );',
86
+ '}',
87
+ '```',
88
+ '',
89
+ '---',
90
+ '',
91
+ '### Default behaviour',
92
+ '',
93
+ 'When no provider wraps your component tree, `PopupParentContext` falls back to a ref pointing to',
94
+ '`div#ds-popup-parent`. This element is created once and appended to `document.body` with',
95
+ '`position: fixed; z-index: 1`. All floating elements on the page share it.',
96
+ '',
97
+ 'You can pre-create this element for SSR environments:',
98
+ '```html',
99
+ '<div id="ds-popup-parent" style="position: fixed; z-index: 1;"></div>',
100
+ '```',
101
+ '',
102
+ '---',
103
+ '',
104
+ '### Accessibility',
105
+ '',
106
+ '- Portalling to `document.body` or a fixed container does not break focus management — Radix UI',
107
+ ' and the DS components handle focus trapping and restoration internally',
108
+ '- Ensure the portal container has no `aria-hidden` ancestor — this would hide portalled content from',
109
+ ' assistive technology even if it is visible on screen',
110
+ ].join('\n');
111
+ const RELATED_COMPONENTS = [
112
+ '## Related components',
113
+ '',
114
+ '[Dropdown](?path=/docs/components-dropdown--docs) · [Tooltip](?path=/docs/components-tooltip--docs) · [Combobox](?path=/docs/components-combobox--docs) · [DatePicker](?path=/docs/components-datepicker--docs) · [Modal](?path=/docs/components-modal--docs)',
115
+ ].join('\n');
116
+ // ---------------------------------------------------------------------------
117
+ // Docs page
118
+ // ---------------------------------------------------------------------------
119
+ function PopupParentContextDocsPage() {
120
+ return (_jsxs(_Fragment, { children: [_jsx(Title, {}), _jsx(Subtitle, {}), _jsx(Markdown, { children: DESCRIPTION_INTRO }), _jsx(DocHeading, { children: "Usage guidance" }), _jsx(Markdown, { children: USAGE_GUIDANCE }), _jsx(DocHeading, { children: "Developer notes" }), _jsx(Markdown, { children: DEVELOPER_NOTES }), _jsx(DocHeading, { children: "Examples" }), _jsx(Stories, { title: "" }), _jsx(Markdown, { children: RELATED_COMPONENTS })] }));
121
+ }
122
+ // ---------------------------------------------------------------------------
123
+ // Meta
124
+ // ---------------------------------------------------------------------------
125
+ const meta = {
126
+ title: 'Utils/PopupParentContext',
127
+ parameters: {
128
+ layout: 'padded',
129
+ docs: {
130
+ page: PopupParentContextDocsPage,
131
+ },
132
+ },
133
+ tags: ['autodocs'],
134
+ };
135
+ export default meta;
136
+ // ---------------------------------------------------------------------------
137
+ // Helper
138
+ // ---------------------------------------------------------------------------
139
+ const withDescription = (story, description) => ({
140
+ ...story,
141
+ parameters: {
142
+ ...story.parameters,
143
+ docs: {
144
+ ...story.parameters?.docs,
145
+ description: {
146
+ story: description,
147
+ },
148
+ },
149
+ },
150
+ });
151
+ // ---------------------------------------------------------------------------
152
+ // Templates
153
+ // ---------------------------------------------------------------------------
154
+ const DefaultTemplate = () => (_jsxs("div", { style: {
155
+ border: 'var(--border-weight) solid var(--color-grey-200)',
156
+ borderRadius: 'var(--border-radius-small)',
157
+ padding: 'var(--spacing-medium)',
158
+ overflow: 'hidden',
159
+ maxHeight: '120px',
160
+ display: 'flex',
161
+ flexDirection: 'column',
162
+ gap: 'var(--spacing-small)',
163
+ }, children: [_jsxs("p", { style: { margin: 0, fontSize: 'var(--font-size-2-13)', color: 'var(--color-grey-700)' }, children: ["This panel has", ' ', _jsx("code", { children: "overflow: hidden" }), ' ', "\u2014 yet the dropdown opens correctly."] }), _jsxs(Dropdown, { children: [_jsx(Dropdown.Trigger, { children: _jsx(Button, { variant: "dropdown", children: "Actions" }) }), _jsxs(Dropdown.Content, { children: [_jsx(Dropdown.Item, { children: "View pupil profile" }), _jsx(Dropdown.Item, { children: "Edit enrolment" }), _jsx(Dropdown.Separator, {}), _jsx(Dropdown.Item, { children: "Remove from group" })] })] })] }));
164
+ const WithCustomContainerTemplate = () => {
165
+ const popupContainerRef = useRef(null);
166
+ return (_jsxs("div", { style: { position: 'relative', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-small)' }, children: [_jsxs("p", { style: { margin: 0, fontSize: 'var(--font-size-2-13)', color: 'var(--color-grey-700)' }, children: ["The dropdown portals into", ' ', _jsx("code", { children: "popupContainerRef" }), ' ', "(the pink border below) instead of", ' ', _jsx("code", { children: "document.body" }), "."] }), _jsx("div", { ref: popupContainerRef, style: {
167
+ position: 'relative',
168
+ zIndex: 10,
169
+ border: '2px dashed var(--color-semantic-destructive-300)',
170
+ borderRadius: 'var(--border-radius-small)',
171
+ padding: 'var(--spacing-xsmall)',
172
+ minHeight: '2rem',
173
+ }, "aria-label": "Custom popup container" }), _jsx(PopupParentContext.Provider, { value: popupContainerRef, children: _jsxs(Dropdown, { children: [_jsx(Dropdown.Trigger, { children: _jsx(Button, { variant: "dropdown", children: "Actions" }) }), _jsxs(Dropdown.Content, { children: [_jsx(Dropdown.Item, { children: "View pupil profile" }), _jsx(Dropdown.Item, { children: "Edit enrolment" }), _jsx(Dropdown.Separator, {}), _jsx(Dropdown.Item, { children: "Remove from group" })] })] }) })] }));
174
+ };
175
+ // ---------------------------------------------------------------------------
176
+ // Stories
177
+ // ---------------------------------------------------------------------------
178
+ export const Default = withDescription({
179
+ render: DefaultTemplate,
180
+ parameters: {
181
+ controls: { disable: true },
182
+ docs: {
183
+ source: {
184
+ language: 'tsx',
185
+ code: `
186
+ import { Dropdown, Button } from '@arbor-education/design-system.components';
187
+
188
+ // No PopupParentContext setup needed — the dropdown portals to document.body automatically.
189
+ function PupilActionsDropdown() {
190
+ return (
191
+ <Dropdown>
192
+ <Dropdown.Trigger>
193
+ <Button variant="dropdown">Actions</Button>
194
+ </Dropdown.Trigger>
195
+ <Dropdown.Content>
196
+ <Dropdown.Item>View pupil profile</Dropdown.Item>
197
+ <Dropdown.Item>Edit enrolment</Dropdown.Item>
198
+ <Dropdown.Separator />
199
+ <Dropdown.Item>Remove from group</Dropdown.Item>
200
+ </Dropdown.Content>
201
+ </Dropdown>
202
+ );
203
+ }
204
+ export default PupilActionsDropdown;
205
+ `.trim(),
206
+ },
207
+ },
208
+ },
209
+ }, [
210
+ 'The default behaviour — no `PopupParentContext` setup required.',
211
+ 'The dropdown portals its content to `div#ds-popup-parent` in `document.body` via the context default.',
212
+ 'Even inside an `overflow: hidden` container, the popup appears correctly because it exits the clip',
213
+ 'boundary by rendering in the body.',
214
+ ].join(' '));
215
+ export const WithCustomContainer = withDescription({
216
+ render: WithCustomContainerTemplate,
217
+ parameters: {
218
+ controls: { disable: true },
219
+ docs: {
220
+ source: {
221
+ language: 'tsx',
222
+ code: `
223
+ import { useRef } from 'react';
224
+ import { PopupParentContext, Dropdown, Button } from '@arbor-education/design-system.components';
225
+
226
+ function ClippedPanel() {
227
+ const popupContainerRef = useRef<HTMLDivElement>(null);
228
+
229
+ return (
230
+ <div style={{ position: 'relative' }}>
231
+ {/*
232
+ This container receives portalled popups.
233
+ Place it outside any overflow:hidden ancestor,
234
+ with a z-index high enough to appear above surrounding content.
235
+ */}
236
+ <div ref={popupContainerRef} style={{ position: 'fixed', zIndex: 100 }} />
237
+
238
+ <PopupParentContext.Provider value={popupContainerRef}>
239
+ <Dropdown>
240
+ <Dropdown.Trigger>
241
+ <Button variant="dropdown">Actions</Button>
242
+ </Dropdown.Trigger>
243
+ <Dropdown.Content>
244
+ <Dropdown.Item>View pupil profile</Dropdown.Item>
245
+ <Dropdown.Item>Edit enrolment</Dropdown.Item>
246
+ <Dropdown.Separator />
247
+ <Dropdown.Item>Remove from group</Dropdown.Item>
248
+ </Dropdown.Content>
249
+ </Dropdown>
250
+ </PopupParentContext.Provider>
251
+ </div>
252
+ );
253
+ }
254
+ export default ClippedPanel;
255
+ `.trim(),
256
+ },
257
+ },
258
+ },
259
+ }, [
260
+ 'Override the popup container with `PopupParentContext.Provider`. The `value` prop accepts a',
261
+ '`RefObject<HTMLElement | null>` pointing to the element that should receive portalled content.',
262
+ 'Open the dropdown to see it appear inside the dashed container (highlighted in pink) instead of',
263
+ '`document.body`. In production you would omit the visual indicator and size/position the container',
264
+ 'as needed for your layout.',
265
+ ].join(' '));
266
+ //# sourceMappingURL=PopupParentContext.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PopupParentContext.stories.js","sourceRoot":"","sources":["../../src/utils/PopupParentContext.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const getDefaultPopupParent: () => HTMLElement;
2
+ //# sourceMappingURL=getDefaultPopupParent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDefaultPopupParent.d.ts","sourceRoot":"","sources":["../../src/utils/getDefaultPopupParent.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,mBAmBjC,CAAC"}
@@ -0,0 +1,19 @@
1
+ export const getDefaultPopupParent = () => {
2
+ const element = document.getElementById('ds-popup-parent');
3
+ if (element) {
4
+ return element;
5
+ }
6
+ const newContainer = document.createElement('div');
7
+ newContainer.id = 'ds-popup-parent';
8
+ newContainer.style.zIndex = '1';
9
+ newContainer.style.position = 'fixed';
10
+ // ag grid has clamping behaviour for floating elements - it clamps the area
11
+ // to whichever has the largest boundingRect between its own main container
12
+ // and whatever is passed to the popupParent prop. without this inset here
13
+ // the container ends up with a height and width of zero so they get clamped
14
+ // to the ag container instead of the viewport (most heinous).
15
+ newContainer.style.inset = '0';
16
+ document.body.appendChild(newContainer);
17
+ return newContainer;
18
+ };
19
+ //# sourceMappingURL=getDefaultPopupParent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDefaultPopupParent.js","sourceRoot":"","sources":["../../src/utils/getDefaultPopupParent.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC3D,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,GAAG,iBAAiB,CAAC;IACpC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;IAChC,YAAY,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;IACtC,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,4EAA4E;IAC5E,8DAA8D;IAC9D,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAExC,OAAO,YAA2B,CAAC;AACrC,CAAC,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const useIsMounted: () => import("react").MutableRefObject<boolean>;
1
+ export declare const useIsMounted: () => import("react").RefObject<boolean>;
2
2
  //# sourceMappingURL=useIsMounted.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useIsMounted.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useIsMounted.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,iDAQxB,CAAC"}
1
+ {"version":3,"file":"useIsMounted.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useIsMounted.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,0CAQxB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbor-education/design-system.components",
3
- "version": "3.4.5",
3
+ "version": "4.0.0-react19-alpha.0",
4
4
  "description": "The component library for the design system (the baby)",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -12,8 +12,6 @@
12
12
  "license": "MIT",
13
13
  "dependencies": {
14
14
  "@react-hook/resize-observer": "^2.0.2",
15
- "@types/react": "^18.2.0",
16
- "@types/react-dom": "^18.2.0",
17
15
  "@uiw/react-color": "2.8.0",
18
16
  "ag-grid-community": "^34.3.1",
19
17
  "ag-grid-enterprise": "^34.3.1",
@@ -24,12 +22,24 @@
24
22
  "decimal.js": "^10.6.0",
25
23
  "lucide-react": "^0.544.0",
26
24
  "radix-ui": "1.4.3",
27
- "react": "^18.2.0",
28
25
  "react-day-picker": "^9.14.0",
29
- "react-dom": "^18.2.0",
30
26
  "react-dropzone": "^15.0.0",
31
27
  "typescript": "^5.9.2"
32
28
  },
29
+ "peerDependencies": {
30
+ "@types/react": "*",
31
+ "@types/react-dom": "*",
32
+ "react": "^18.0.0 || ^19.0.0",
33
+ "react-dom": "^18.0.0 || ^19.0.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "@types/react": {
37
+ "optional": true
38
+ },
39
+ "@types/react-dom": {
40
+ "optional": true
41
+ }
42
+ },
33
43
  "devDependencies": {
34
44
  "@changesets/changelog-github": "^0.5.2",
35
45
  "@changesets/cli": "^2.29.8",
@@ -45,6 +55,8 @@
45
55
  "@testing-library/react": "^16.3.0",
46
56
  "@testing-library/user-event": "^14.6.1",
47
57
  "@types/node": "^24.7.0",
58
+ "@types/react": "^19.0.0",
59
+ "@types/react-dom": "^19.0.0",
48
60
  "@vitejs/plugin-react": "^5.0.1",
49
61
  "@vitest/browser": "3.2.4",
50
62
  "@vitest/coverage-v8": "3.2.4",
@@ -60,6 +72,8 @@
60
72
  "jsdom": "^26.1.0",
61
73
  "lint-staged": "^16.2.3",
62
74
  "playwright": "^1.55.0",
75
+ "react": "^19.0.0",
76
+ "react-dom": "^19.0.0",
63
77
  "sass": "^1.104.1",
64
78
  "storybook": "^10.4.6",
65
79
  "storybook-addon-deep-controls": "^0.10.0",
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`ArborLogo > renders the icon-only variant 1`] = `
4
4
  <svg
5
- aria-labelledby=":r1:"
5
+ aria-labelledby="_r_1_"
6
6
  fill="none"
7
7
  height="25"
8
8
  role="img"
@@ -11,12 +11,12 @@ exports[`ArborLogo > renders the icon-only variant 1`] = `
11
11
  xmlns="http://www.w3.org/2000/svg"
12
12
  >
13
13
  <title
14
- id=":r1:"
14
+ id="_r_1_"
15
15
  >
16
16
  Arbor
17
17
  </title>
18
18
  <g
19
- clip-path="url(#:r0:)"
19
+ clip-path="url(#_r_0_)"
20
20
  >
21
21
  <path
22
22
  d="M12.6821 12.448C12.6821 9.06699 15.4229 6.32623 18.8039 6.32623C18.8039 2.94571 16.0631 0.205391 12.6817 0.205391C9.30163 0.205391 6.56086 2.94571 6.56042 6.32623C9.94138 6.32623 12.6817 9.06699 12.6821 12.448Z"
@@ -53,7 +53,7 @@ exports[`ArborLogo > renders the icon-only variant 1`] = `
53
53
  </g>
54
54
  <defs>
55
55
  <clippath
56
- id=":r0:"
56
+ id="_r_0_"
57
57
  >
58
58
  <rect
59
59
  fill="white"
@@ -67,7 +67,7 @@ exports[`ArborLogo > renders the icon-only variant 1`] = `
67
67
 
68
68
  exports[`ArborLogo > renders the icon-only variant with a custom aria-label 1`] = `
69
69
  <svg
70
- aria-labelledby=":r5:"
70
+ aria-labelledby="_r_5_"
71
71
  fill="none"
72
72
  height="25"
73
73
  role="img"
@@ -76,12 +76,12 @@ exports[`ArborLogo > renders the icon-only variant with a custom aria-label 1`]
76
76
  xmlns="http://www.w3.org/2000/svg"
77
77
  >
78
78
  <title
79
- id=":r5:"
79
+ id="_r_5_"
80
80
  >
81
81
  Arbor Education logo
82
82
  </title>
83
83
  <g
84
- clip-path="url(#:r4:)"
84
+ clip-path="url(#_r_4_)"
85
85
  >
86
86
  <path
87
87
  d="M12.6821 12.448C12.6821 9.06699 15.4229 6.32623 18.8039 6.32623C18.8039 2.94571 16.0631 0.205391 12.6817 0.205391C9.30163 0.205391 6.56086 2.94571 6.56042 6.32623C9.94138 6.32623 12.6817 9.06699 12.6821 12.448Z"
@@ -118,7 +118,7 @@ exports[`ArborLogo > renders the icon-only variant with a custom aria-label 1`]
118
118
  </g>
119
119
  <defs>
120
120
  <clippath
121
- id=":r4:"
121
+ id="_r_4_"
122
122
  >
123
123
  <rect
124
124
  fill="white"
@@ -140,7 +140,7 @@ exports[`ArborLogo > renders the icon-only variant with aria-hidden 1`] = `
140
140
  xmlns="http://www.w3.org/2000/svg"
141
141
  >
142
142
  <g
143
- clip-path="url(#:r2:)"
143
+ clip-path="url(#_r_2_)"
144
144
  >
145
145
  <path
146
146
  d="M12.6821 12.448C12.6821 9.06699 15.4229 6.32623 18.8039 6.32623C18.8039 2.94571 16.0631 0.205391 12.6817 0.205391C9.30163 0.205391 6.56086 2.94571 6.56042 6.32623C9.94138 6.32623 12.6817 9.06699 12.6821 12.448Z"
@@ -177,7 +177,7 @@ exports[`ArborLogo > renders the icon-only variant with aria-hidden 1`] = `
177
177
  </g>
178
178
  <defs>
179
179
  <clippath
180
- id=":r2:"
180
+ id="_r_2_"
181
181
  >
182
182
  <rect
183
183
  fill="white"
@@ -199,7 +199,7 @@ exports[`ArborLogo > renders the text variant with aria-hidden 1`] = `
199
199
  xmlns="http://www.w3.org/2000/svg"
200
200
  >
201
201
  <g
202
- clip-path="url(#:ra:)"
202
+ clip-path="url(#_r_a_)"
203
203
  >
204
204
  <path
205
205
  d="M12.6822 12.4479C12.6822 9.06698 15.423 6.32622 18.8039 6.32622C18.8039 2.9457 16.0632 0.205383 12.6818 0.205383C9.30169 0.205383 6.56093 2.9457 6.56049 6.32622C9.94145 6.32622 12.6818 9.06698 12.6822 12.4479Z"
@@ -256,7 +256,7 @@ exports[`ArborLogo > renders the text variant with aria-hidden 1`] = `
256
256
  </g>
257
257
  <defs>
258
258
  <clippath
259
- id=":ra:"
259
+ id="_r_a_"
260
260
  >
261
261
  <rect
262
262
  fill="white"
@@ -270,7 +270,7 @@ exports[`ArborLogo > renders the text variant with aria-hidden 1`] = `
270
270
 
271
271
  exports[`ArborLogo > renders the text variant with black text 1`] = `
272
272
  <svg
273
- aria-labelledby=":r7:"
273
+ aria-labelledby="_r_7_"
274
274
  fill="none"
275
275
  height="26"
276
276
  role="img"
@@ -279,12 +279,12 @@ exports[`ArborLogo > renders the text variant with black text 1`] = `
279
279
  xmlns="http://www.w3.org/2000/svg"
280
280
  >
281
281
  <title
282
- id=":r7:"
282
+ id="_r_7_"
283
283
  >
284
284
  Arbor
285
285
  </title>
286
286
  <g
287
- clip-path="url(#:r6:)"
287
+ clip-path="url(#_r_6_)"
288
288
  >
289
289
  <path
290
290
  d="M12.6822 12.4479C12.6822 9.06698 15.423 6.32622 18.8039 6.32622C18.8039 2.9457 16.0632 0.205383 12.6818 0.205383C9.30169 0.205383 6.56093 2.9457 6.56049 6.32622C9.94145 6.32622 12.6818 9.06698 12.6822 12.4479Z"
@@ -341,7 +341,7 @@ exports[`ArborLogo > renders the text variant with black text 1`] = `
341
341
  </g>
342
342
  <defs>
343
343
  <clippath
344
- id=":r6:"
344
+ id="_r_6_"
345
345
  >
346
346
  <rect
347
347
  fill="white"
@@ -355,7 +355,7 @@ exports[`ArborLogo > renders the text variant with black text 1`] = `
355
355
 
356
356
  exports[`ArborLogo > renders the text variant with white text 1`] = `
357
357
  <svg
358
- aria-labelledby=":r9:"
358
+ aria-labelledby="_r_9_"
359
359
  fill="none"
360
360
  height="26"
361
361
  role="img"
@@ -364,7 +364,7 @@ exports[`ArborLogo > renders the text variant with white text 1`] = `
364
364
  xmlns="http://www.w3.org/2000/svg"
365
365
  >
366
366
  <title
367
- id=":r9:"
367
+ id="_r_9_"
368
368
  >
369
369
  Arbor
370
370
  </title>
@@ -11,7 +11,7 @@ import type { ComboboxAriaInvalid, ComboboxOption, ComboboxSelectedValueDisplay
11
11
  import { useVisibleTriggerTags } from './useVisibleTriggerTags.js';
12
12
 
13
13
  export type ComboboxButtonTriggerProps = {
14
- triggerRef: React.RefObject<HTMLDivElement>;
14
+ triggerRef: React.RefObject<HTMLDivElement | null>;
15
15
  listboxId: string;
16
16
  isOpen: boolean;
17
17
  hasError: boolean;
@@ -4,7 +4,7 @@ import { ComboboxOptionRow } from './ComboboxOptionRow.js';
4
4
  import type { ComboboxAriaInvalid, ComboboxOption, ComboboxSearchType } from './types.js';
5
5
 
6
6
  export type ComboboxListboxProps = {
7
- listboxRef: React.RefObject<HTMLUListElement>;
7
+ listboxRef: React.RefObject<HTMLUListElement | null>;
8
8
  listboxId: string;
9
9
  multiple: boolean;
10
10
  ariaLabel: string | undefined;
@@ -27,7 +27,7 @@ export type ComboboxListboxProps = {
27
27
  filteredOptionsLength: number;
28
28
  preventMouseDefault: (e: React.MouseEvent) => void;
29
29
  renderSearchInputInListbox: boolean;
30
- inputRef: React.RefObject<HTMLInputElement>;
30
+ inputRef: React.RefObject<HTMLInputElement | null>;
31
31
  comboboxId: string;
32
32
  shouldShowPopover: boolean;
33
33
  activeDescendant: string | undefined;
@@ -5,8 +5,8 @@ import { Popover } from 'radix-ui';
5
5
  import type { ComboboxAriaInvalid, ComboboxOption, ComboboxSelectedValueDisplay } from './types.js';
6
6
 
7
7
  export type ComboboxTriggerProps = {
8
- 'inputRef': React.RefObject<HTMLInputElement>;
9
- 'triggerRef': React.RefObject<HTMLDivElement>;
8
+ 'inputRef': React.RefObject<HTMLInputElement | null>;
9
+ 'triggerRef': React.RefObject<HTMLDivElement | null>;
10
10
  'comboboxId': string;
11
11
  'listboxId': string;
12
12
  'isOpen': boolean;
@@ -6,7 +6,7 @@ type UseComboboxListboxDomParams = {
6
6
  };
7
7
 
8
8
  export type UseComboboxListboxDomReturn = {
9
- listboxRef: React.RefObject<HTMLUListElement>;
9
+ listboxRef: React.RefObject<HTMLUListElement | null>;
10
10
  getOptionId: (index: number) => string;
11
11
  scrollHighlightedIntoView: (index: number) => void;
12
12
  };