@arbor-education/design-system.components 0.3.0 → 0.3.2

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 (98) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.d.ts +1 -0
  3. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.d.ts.map +1 -1
  4. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.js +19 -12
  5. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.js.map +1 -1
  6. package/dist/components/table/DSDefaultColDef.d.ts +5 -0
  7. package/dist/components/table/DSDefaultColDef.d.ts.map +1 -0
  8. package/dist/components/table/DSDefaultColDef.js +32 -0
  9. package/dist/components/table/DSDefaultColDef.js.map +1 -0
  10. package/dist/components/table/Table.d.ts +6 -6
  11. package/dist/components/table/Table.d.ts.map +1 -1
  12. package/dist/components/table/Table.js +43 -22
  13. package/dist/components/table/Table.js.map +1 -1
  14. package/dist/components/table/Table.stories.d.ts +3 -0
  15. package/dist/components/table/Table.stories.d.ts.map +1 -1
  16. package/dist/components/table/Table.stories.js +265 -24
  17. package/dist/components/table/Table.stories.js.map +1 -1
  18. package/dist/components/table/Table.test.js +362 -7
  19. package/dist/components/table/Table.test.js.map +1 -1
  20. package/dist/components/table/cellColorStyles.d.ts +34 -0
  21. package/dist/components/table/cellColorStyles.d.ts.map +1 -0
  22. package/dist/components/table/cellColorStyles.js +52 -0
  23. package/dist/components/table/cellColorStyles.js.map +1 -0
  24. package/dist/components/table/cellRenderers/ButtonCellRenderer.d.ts.map +1 -1
  25. package/dist/components/table/cellRenderers/ButtonCellRenderer.js +15 -2
  26. package/dist/components/table/cellRenderers/ButtonCellRenderer.js.map +1 -1
  27. package/dist/components/table/cellRenderers/DefaultCellRenderer.d.ts +3 -0
  28. package/dist/components/table/cellRenderers/DefaultCellRenderer.d.ts.map +1 -0
  29. package/dist/components/table/cellRenderers/DefaultCellRenderer.js +11 -0
  30. package/dist/components/table/cellRenderers/DefaultCellRenderer.js.map +1 -0
  31. package/dist/components/table/cellRenderers/InlineTextCellRenderer.d.ts +7 -0
  32. package/dist/components/table/cellRenderers/InlineTextCellRenderer.d.ts.map +1 -0
  33. package/dist/components/table/cellRenderers/InlineTextCellRenderer.js +7 -0
  34. package/dist/components/table/cellRenderers/InlineTextCellRenderer.js.map +1 -0
  35. package/dist/components/table/cellRenderers/SelectDropdownCellEditor.d.ts +8 -0
  36. package/dist/components/table/cellRenderers/SelectDropdownCellEditor.d.ts.map +1 -0
  37. package/dist/components/table/cellRenderers/SelectDropdownCellEditor.js +19 -0
  38. package/dist/components/table/cellRenderers/SelectDropdownCellEditor.js.map +1 -0
  39. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.d.ts +8 -0
  40. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.d.ts.map +1 -0
  41. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.js +18 -0
  42. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.js.map +1 -0
  43. package/dist/components/table/pagination/TableSettingsDropdown.js +4 -5
  44. package/dist/components/table/pagination/TableSettingsDropdown.js.map +1 -1
  45. package/dist/components/table/theme/baseThemeParams.d.ts +14 -0
  46. package/dist/components/table/theme/baseThemeParams.d.ts.map +1 -0
  47. package/dist/components/table/{tableTheme.js → theme/baseThemeParams.js} +3 -7
  48. package/dist/components/table/theme/baseThemeParams.js.map +1 -0
  49. package/dist/components/table/theme/defaultTheme.d.ts +2 -0
  50. package/dist/components/table/theme/defaultTheme.d.ts.map +1 -0
  51. package/dist/components/table/theme/defaultTheme.js +9 -0
  52. package/dist/components/table/theme/defaultTheme.js.map +1 -0
  53. package/dist/components/table/theme/tidyTheme.d.ts +2 -0
  54. package/dist/components/table/theme/tidyTheme.d.ts.map +1 -0
  55. package/dist/components/table/theme/tidyTheme.js +10 -0
  56. package/dist/components/table/theme/tidyTheme.js.map +1 -0
  57. package/dist/components/table/useTableSettings.d.ts +5 -2
  58. package/dist/components/table/useTableSettings.d.ts.map +1 -1
  59. package/dist/components/table/useTableSettings.js +11 -3
  60. package/dist/components/table/useTableSettings.js.map +1 -1
  61. package/dist/index.css +14 -0
  62. package/dist/index.css.map +1 -1
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +2 -0
  66. package/dist/index.js.map +1 -1
  67. package/dist/utils/focusFirstFocusableElement.d.ts +2 -0
  68. package/dist/utils/focusFirstFocusableElement.d.ts.map +1 -0
  69. package/dist/utils/focusFirstFocusableElement.js +12 -0
  70. package/dist/utils/focusFirstFocusableElement.js.map +1 -0
  71. package/dist/utils/focusFirstFocusableElement.test.d.ts +2 -0
  72. package/dist/utils/focusFirstFocusableElement.test.d.ts.map +1 -0
  73. package/dist/utils/focusFirstFocusableElement.test.js +109 -0
  74. package/dist/utils/focusFirstFocusableElement.test.js.map +1 -0
  75. package/package.json +1 -1
  76. package/src/components/formField/inputs/selectDropdown/SelectDropdown.tsx +20 -14
  77. package/src/components/table/DSDefaultColDef.ts +37 -0
  78. package/src/components/table/Table.stories.tsx +284 -28
  79. package/src/components/table/Table.test.tsx +543 -7
  80. package/src/components/table/Table.tsx +55 -23
  81. package/src/components/table/cellColorStyles.ts +70 -0
  82. package/src/components/table/cellRenderers/ButtonCellRenderer.tsx +16 -2
  83. package/src/components/table/cellRenderers/DefaultCellRenderer.tsx +23 -0
  84. package/src/components/table/cellRenderers/InlineTextCellRenderer.tsx +10 -0
  85. package/src/components/table/cellRenderers/SelectDropdownCellEditor.tsx +43 -0
  86. package/src/components/table/cellRenderers/SelectDropdownCellRenderer.tsx +37 -0
  87. package/src/components/table/pagination/TableSettingsDropdown.tsx +5 -5
  88. package/src/components/table/table.scss +16 -0
  89. package/src/components/table/{tableTheme.ts → theme/baseThemeParams.ts} +2 -7
  90. package/src/components/table/theme/defaultTheme.ts +9 -0
  91. package/src/components/table/theme/tidyTheme.ts +10 -0
  92. package/src/components/table/useTableSettings.ts +15 -3
  93. package/src/index.ts +2 -0
  94. package/src/utils/focusFirstFocusableElement.test.ts +150 -0
  95. package/src/utils/focusFirstFocusableElement.ts +21 -0
  96. package/dist/components/table/tableTheme.d.ts +0 -2
  97. package/dist/components/table/tableTheme.d.ts.map +0 -1
  98. package/dist/components/table/tableTheme.js.map +0 -1
@@ -0,0 +1,12 @@
1
+ const focusableElementsQuery = 'button:enabled, [href], input:not(input[type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])';
2
+ export const focusFirstFocusableElement = (containerElement) => {
3
+ if (containerElement
4
+ && typeof containerElement.querySelector === 'function') {
5
+ const firstFocusableElement = containerElement.querySelector(focusableElementsQuery);
6
+ if (firstFocusableElement
7
+ && typeof firstFocusableElement.focus === 'function') {
8
+ firstFocusableElement.focus();
9
+ }
10
+ }
11
+ };
12
+ //# sourceMappingURL=focusFirstFocusableElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusFirstFocusableElement.js","sourceRoot":"","sources":["../../src/utils/focusFirstFocusableElement.ts"],"names":[],"mappings":"AAAA,MAAM,sBAAsB,GAAG,4GAA4G,CAAC;AAE5I,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,gBAAoC,EACpC,EAAE;IACF,IACE,gBAAgB;WACb,OAAO,gBAAgB,CAAC,aAAa,KAAK,UAAU,EACvD,CAAC;QACD,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,aAAa,CAC1D,sBAAsB,CACR,CAAC;QAEjB,IACE,qBAAqB;eAClB,OAAO,qBAAqB,CAAC,KAAK,KAAK,UAAU,EACpD,CAAC;YACD,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=focusFirstFocusableElement.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusFirstFocusableElement.test.d.ts","sourceRoot":"","sources":["../../src/utils/focusFirstFocusableElement.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest';
2
+ import { focusFirstFocusableElement } from './focusFirstFocusableElement';
3
+ describe('focusFirstFocusableElement', () => {
4
+ let container;
5
+ beforeEach(() => {
6
+ container = document.createElement('div');
7
+ document.body.appendChild(container);
8
+ });
9
+ afterEach(() => {
10
+ document.body.removeChild(container);
11
+ vi.clearAllMocks();
12
+ });
13
+ test('does nothing when containerElementRef is null', () => {
14
+ const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus');
15
+ focusFirstFocusableElement(null);
16
+ expect(focusSpy).not.toHaveBeenCalled();
17
+ });
18
+ test('does nothing when container has no focusable elements', () => {
19
+ container.innerHTML = '<div>No focusable elements</div>';
20
+ const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus');
21
+ focusFirstFocusableElement(container);
22
+ expect(focusSpy).not.toHaveBeenCalled();
23
+ });
24
+ test('focuses the first button element', () => {
25
+ container.innerHTML = '<button>First Button</button><button>Second Button</button>';
26
+ const firstButton = container.querySelector('button');
27
+ const focusSpy = vi.spyOn(firstButton, 'focus');
28
+ focusFirstFocusableElement(container);
29
+ expect(focusSpy).toHaveBeenCalledTimes(1);
30
+ });
31
+ test('focuses the first input element', () => {
32
+ container.innerHTML = '<input type="text" /><input type="text" />';
33
+ const firstInput = container.querySelector('input');
34
+ const focusSpy = vi.spyOn(firstInput, 'focus');
35
+ focusFirstFocusableElement(container);
36
+ expect(focusSpy).toHaveBeenCalledTimes(1);
37
+ });
38
+ test('focuses the first link element', () => {
39
+ container.innerHTML = '<a href="#">First Link</a><a href="#">Second Link</a>';
40
+ const firstLink = container.querySelector('a');
41
+ const focusSpy = vi.spyOn(firstLink, 'focus');
42
+ focusFirstFocusableElement(container);
43
+ expect(focusSpy).toHaveBeenCalledTimes(1);
44
+ });
45
+ test('focuses the first select element', () => {
46
+ container.innerHTML = '<select><option>Option 1</option></select><select><option>Option 2</option></select>';
47
+ const firstSelect = container.querySelector('select');
48
+ const focusSpy = vi.spyOn(firstSelect, 'focus');
49
+ focusFirstFocusableElement(container);
50
+ expect(focusSpy).toHaveBeenCalledTimes(1);
51
+ });
52
+ test('focuses the first textarea element', () => {
53
+ container.innerHTML = '<textarea></textarea><textarea></textarea>';
54
+ const firstTextarea = container.querySelector('textarea');
55
+ const focusSpy = vi.spyOn(firstTextarea, 'focus');
56
+ focusFirstFocusableElement(container);
57
+ expect(focusSpy).toHaveBeenCalledTimes(1);
58
+ });
59
+ test('focuses element with tabindex attribute', () => {
60
+ container.innerHTML = '<div tabindex="0">Focusable div</div><div tabindex="1">Another focusable div</div>';
61
+ const firstDiv = container.querySelector('[tabindex]');
62
+ const focusSpy = vi.spyOn(firstDiv, 'focus');
63
+ focusFirstFocusableElement(container);
64
+ expect(focusSpy).toHaveBeenCalledTimes(1);
65
+ });
66
+ test('ignores disabled buttons', () => {
67
+ container.innerHTML = '<button disabled>Disabled</button><button>Enabled</button>';
68
+ const enabledButton = container.querySelector('button:not([disabled])');
69
+ const focusSpy = vi.spyOn(enabledButton, 'focus');
70
+ focusFirstFocusableElement(container);
71
+ expect(focusSpy).toHaveBeenCalledTimes(1);
72
+ });
73
+ test('ignores hidden inputs', () => {
74
+ container.innerHTML = '<input type="hidden" /><input type="text" />';
75
+ const textInput = container.querySelector('input[type="text"]');
76
+ const focusSpy = vi.spyOn(textInput, 'focus');
77
+ focusFirstFocusableElement(container);
78
+ expect(focusSpy).toHaveBeenCalledTimes(1);
79
+ });
80
+ test('ignores elements with tabindex="-1"', () => {
81
+ container.innerHTML = '<div tabindex="-1">Not focusable</div><div tabindex="0">Focusable</div>';
82
+ const focusableDiv = container.querySelector('[tabindex="0"]');
83
+ const focusSpy = vi.spyOn(focusableDiv, 'focus');
84
+ focusFirstFocusableElement(container);
85
+ expect(focusSpy).toHaveBeenCalledTimes(1);
86
+ });
87
+ test('focuses the first focusable element when multiple types exist', () => {
88
+ container.innerHTML = '<button>Button</button><input type="text" /><a href="#">Link</a>';
89
+ const firstButton = container.querySelector('button');
90
+ const focusSpy = vi.spyOn(firstButton, 'focus');
91
+ focusFirstFocusableElement(container);
92
+ expect(focusSpy).toHaveBeenCalledTimes(1);
93
+ });
94
+ test('focuses the first focusable element in nested structure', () => {
95
+ container.innerHTML = `
96
+ <div>
97
+ <div>Non-focusable</div>
98
+ <button>Nested Button</button>
99
+ </div>
100
+ <button>Outer Button</button>
101
+ `;
102
+ const nestedButton = container.querySelector('button');
103
+ const focusSpy = vi.spyOn(nestedButton, 'focus');
104
+ focusFirstFocusableElement(container);
105
+ expect(focusSpy).toHaveBeenCalledTimes(1);
106
+ expect(nestedButton.textContent).toBe('Nested Button');
107
+ });
108
+ });
109
+ //# sourceMappingURL=focusFirstFocusableElement.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusFirstFocusableElement.test.js","sourceRoot":"","sources":["../../src/utils/focusFirstFocusableElement.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbor-education/design-system.components",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "The component library for the design system (the baby)",
5
5
  "main": "dist/index.js",
6
6
  "repository": {
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useRef, useState } from 'react';
2
2
 
3
3
  import { SelectDropdownItem, type SelectDropdownItemProps } from './items/item/SelectDropdownItem';
4
4
  import { Dropdown } from 'Components/dropdown/Dropdown';
@@ -15,17 +15,16 @@ export type SelectDropdownInputProps = {
15
15
  'onSelectionChange'?: (value: string[]) => void;
16
16
  'id'?: string;
17
17
  'alwaysShowPlaceholder'?: boolean;
18
+ 'initialSelectedValues'?: string[];
18
19
  };
19
20
 
20
21
  export const SelectDropdown = (props: SelectDropdownInputProps) => {
21
- const { options, disabled, multiple, placeholder, hasError, onSelectionChange, id, 'aria-describedBy': ariaDescribedBy, 'aria-invalid': ariaInvalid, alwaysShowPlaceholder = false } = props;
22
+ const { options, disabled, multiple, placeholder, hasError, onSelectionChange, id, 'aria-describedBy': ariaDescribedBy, 'aria-invalid': ariaInvalid, alwaysShowPlaceholder = false, initialSelectedValues } = props;
22
23
 
23
- const [selectedValues, setSelectedValues] = useState<string[]>([]);
24
+ const [selectedValues, setSelectedValues] = useState<string[]>(initialSelectedValues ?? []);
24
25
  const [renderedSelectContent, setRenderedSelectContent] = useState('');
25
-
26
- useEffect(() => {
27
- onSelectionChange?.(selectedValues);
28
- }, [selectedValues]);
26
+ const selectedValuesRef = useRef(selectedValues);
27
+ selectedValuesRef.current = selectedValues;
29
28
 
30
29
  useEffect(() => {
31
30
  if (alwaysShowPlaceholder) {
@@ -36,13 +35,15 @@ export const SelectDropdown = (props: SelectDropdownInputProps) => {
36
35
  setRenderedSelectContent(placeholder ?? 'Select');
37
36
  }
38
37
  else if (selectedValues.length === 1) {
39
- const selectedLabel = options.find(option => option.value === selectedValues[0])?.label;
40
- if (selectedLabel) setRenderedSelectContent(selectedLabel);
38
+ const selectedValue = selectedValues[0];
39
+ const option = options.find(opt => opt.value === selectedValue);
40
+ const displayText = option?.label ?? option?.value ?? String(selectedValue);
41
+ setRenderedSelectContent(displayText || (placeholder ?? 'Select'));
41
42
  }
42
43
  else {
43
44
  setRenderedSelectContent(placeholder ?? `Select (${selectedValues.length})`);
44
45
  }
45
- }, [selectedValues, placeholder]);
46
+ }, [selectedValues, placeholder, options]);
46
47
 
47
48
  // Flatten grouped options into a single array with headers
48
49
  const UNGROUPED_KEY = 'Ungrouped';
@@ -62,14 +63,19 @@ export const SelectDropdown = (props: SelectDropdownInputProps) => {
62
63
  });
63
64
 
64
65
  const handleItemClick = (value: string) => {
66
+ const prev = selectedValuesRef.current;
67
+ let nextValues: string[];
65
68
  if (!multiple) {
66
- setSelectedValues([value]);
69
+ nextValues = [value];
70
+ }
71
+ else if (prev.includes(value)) {
72
+ nextValues = prev.filter(sel => sel !== value);
67
73
  }
68
74
  else {
69
- setSelectedValues(prev =>
70
- prev.includes(value) ? prev.filter(sel => sel !== value) : [...prev, value],
71
- );
75
+ nextValues = [...prev, value];
72
76
  }
77
+ setSelectedValues(nextValues);
78
+ onSelectionChange?.(nextValues);
73
79
  };
74
80
 
75
81
  return (
@@ -0,0 +1,37 @@
1
+ import type { CellClassParams, CellFocusedParams, ColDef, SuppressMouseEventHandlingParams, ValueFormatterFunc } from 'ag-grid-community';
2
+ import { cellColorStyles } from './cellColorStyles';
3
+
4
+ export const defaultValueFormatter: ValueFormatterFunc = (params) => {
5
+ const { value } = params;
6
+ if (value != null && typeof value === 'object' && 'value' in value) {
7
+ return value.value;
8
+ }
9
+
10
+ return value;
11
+ };
12
+
13
+ export const shouldSuppressFocus = (params: SuppressMouseEventHandlingParams | CellClassParams | CellFocusedParams) => typeof params.column === 'object' && params.column?.getColDef().cellRendererParams.supressCellFocusAndFocusFirstElement;
14
+
15
+ export const DSDefaultColDef: ColDef = {
16
+ cellStyle: cellColorStyles,
17
+ valueGetter: (params) => {
18
+ const { data, colDef: { field } } = params;
19
+
20
+ return data[field!];
21
+ },
22
+ valueFormatter: defaultValueFormatter,
23
+ cellEditorParams: {
24
+ useFormatter: true,
25
+ },
26
+ cellClassRules: {
27
+ 'ds-table__cell--supress-focus': shouldSuppressFocus,
28
+ },
29
+ cellRendererParams: {
30
+ suppressMouseEventHandling: (params: SuppressMouseEventHandlingParams) => {
31
+ if (shouldSuppressFocus(params)) {
32
+ return true;
33
+ }
34
+ return false;
35
+ },
36
+ },
37
+ };