@navikt/ds-react 8.4.1 → 8.5.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.
- package/cjs/accordion/Accordion.d.ts +10 -0
- package/cjs/accordion/Accordion.js +2 -2
- package/cjs/accordion/Accordion.js.map +1 -1
- package/cjs/data/table/helpers/table-cell.d.ts +2 -2
- package/cjs/data/table/helpers/table-cell.js +2 -5
- package/cjs/data/table/helpers/table-cell.js.map +1 -1
- package/cjs/data/table/helpers/table-focus.d.ts +26 -2
- package/cjs/data/table/helpers/table-focus.js +60 -9
- package/cjs/data/table/helpers/table-focus.js.map +1 -1
- package/cjs/data/table/helpers/table-grid-nav.d.ts +40 -10
- package/cjs/data/table/helpers/table-grid-nav.js +102 -25
- package/cjs/data/table/helpers/table-grid-nav.js.map +1 -1
- package/cjs/data/table/helpers/table-keyboard.d.ts +24 -3
- package/cjs/data/table/helpers/table-keyboard.js +25 -5
- package/cjs/data/table/helpers/table-keyboard.js.map +1 -1
- package/cjs/data/table/hooks/useGridCache.d.ts +17 -0
- package/cjs/data/table/hooks/useGridCache.js +65 -0
- package/cjs/data/table/hooks/useGridCache.js.map +1 -0
- package/cjs/data/table/root/DataTableRoot.d.ts +14 -4
- package/cjs/data/table/root/DataTableRoot.js +4 -6
- package/cjs/data/table/root/DataTableRoot.js.map +1 -1
- package/cjs/data/table/root/useTableKeyboardNav.d.ts +10 -4
- package/cjs/data/table/root/useTableKeyboardNav.js +70 -99
- package/cjs/data/table/root/useTableKeyboardNav.js.map +1 -1
- package/cjs/data/token-filter/AutoSuggest.d.ts +21 -0
- package/cjs/data/token-filter/AutoSuggest.js +129 -0
- package/cjs/data/token-filter/AutoSuggest.js.map +1 -0
- package/cjs/data/token-filter/TokenFilter.d.ts +11 -0
- package/cjs/data/token-filter/TokenFilter.js +91 -0
- package/cjs/data/token-filter/TokenFilter.js.map +1 -0
- package/cjs/data/token-filter/TokenFilter.types.d.ts +46 -0
- package/cjs/data/token-filter/TokenFilter.types.js +3 -0
- package/cjs/data/token-filter/TokenFilter.types.js.map +1 -0
- package/cjs/data/token-filter/helpers/generate-autocomplete-options.d.ts +70 -0
- package/cjs/data/token-filter/helpers/generate-autocomplete-options.js +171 -0
- package/cjs/data/token-filter/helpers/generate-autocomplete-options.js.map +1 -0
- package/cjs/data/token-filter/helpers/parse-query-text.d.ts +31 -0
- package/cjs/data/token-filter/helpers/parse-query-text.js +91 -0
- package/cjs/data/token-filter/helpers/parse-query-text.js.map +1 -0
- package/cjs/link-card/LinkCard.d.ts +13 -0
- package/cjs/link-card/LinkCard.js +2 -2
- package/cjs/link-card/LinkCard.js.map +1 -1
- package/cjs/process/Process.d.ts +1 -1
- package/cjs/tooltip/Tooltip.js +1 -1
- package/cjs/tooltip/Tooltip.js.map +1 -1
- package/esm/accordion/Accordion.d.ts +10 -0
- package/esm/accordion/Accordion.js +2 -2
- package/esm/accordion/Accordion.js.map +1 -1
- package/esm/data/table/helpers/table-cell.d.ts +2 -2
- package/esm/data/table/helpers/table-cell.js +2 -5
- package/esm/data/table/helpers/table-cell.js.map +1 -1
- package/esm/data/table/helpers/table-focus.d.ts +26 -2
- package/esm/data/table/helpers/table-focus.js +55 -9
- package/esm/data/table/helpers/table-focus.js.map +1 -1
- package/esm/data/table/helpers/table-grid-nav.d.ts +40 -10
- package/esm/data/table/helpers/table-grid-nav.js +96 -24
- package/esm/data/table/helpers/table-grid-nav.js.map +1 -1
- package/esm/data/table/helpers/table-keyboard.d.ts +24 -3
- package/esm/data/table/helpers/table-keyboard.js +24 -4
- package/esm/data/table/helpers/table-keyboard.js.map +1 -1
- package/esm/data/table/hooks/useGridCache.d.ts +17 -0
- package/esm/data/table/hooks/useGridCache.js +63 -0
- package/esm/data/table/hooks/useGridCache.js.map +1 -0
- package/esm/data/table/root/DataTableRoot.d.ts +14 -4
- package/esm/data/table/root/DataTableRoot.js +4 -6
- package/esm/data/table/root/DataTableRoot.js.map +1 -1
- package/esm/data/table/root/useTableKeyboardNav.d.ts +10 -4
- package/esm/data/table/root/useTableKeyboardNav.js +75 -104
- package/esm/data/table/root/useTableKeyboardNav.js.map +1 -1
- package/esm/data/token-filter/AutoSuggest.d.ts +21 -0
- package/esm/data/token-filter/AutoSuggest.js +93 -0
- package/esm/data/token-filter/AutoSuggest.js.map +1 -0
- package/esm/data/token-filter/TokenFilter.d.ts +11 -0
- package/esm/data/token-filter/TokenFilter.js +55 -0
- package/esm/data/token-filter/TokenFilter.js.map +1 -0
- package/esm/data/token-filter/TokenFilter.types.d.ts +46 -0
- package/esm/data/token-filter/TokenFilter.types.js +2 -0
- package/esm/data/token-filter/TokenFilter.types.js.map +1 -0
- package/esm/data/token-filter/helpers/generate-autocomplete-options.d.ts +70 -0
- package/esm/data/token-filter/helpers/generate-autocomplete-options.js +169 -0
- package/esm/data/token-filter/helpers/generate-autocomplete-options.js.map +1 -0
- package/esm/data/token-filter/helpers/parse-query-text.d.ts +31 -0
- package/esm/data/token-filter/helpers/parse-query-text.js +87 -0
- package/esm/data/token-filter/helpers/parse-query-text.js.map +1 -0
- package/esm/link-card/LinkCard.d.ts +13 -0
- package/esm/link-card/LinkCard.js +2 -2
- package/esm/link-card/LinkCard.js.map +1 -1
- package/esm/process/Process.d.ts +1 -1
- package/esm/tooltip/Tooltip.js +2 -2
- package/esm/tooltip/Tooltip.js.map +1 -1
- package/package.json +3 -3
- package/src/accordion/Accordion.tsx +19 -2
- package/src/data/table/helpers/table-cell.ts +2 -7
- package/src/data/table/helpers/table-focus.ts +70 -9
- package/src/data/table/helpers/table-grid-nav.test.ts +659 -0
- package/src/data/table/helpers/table-grid-nav.ts +128 -32
- package/src/data/table/helpers/table-keyboard.test.ts +27 -27
- package/src/data/table/helpers/table-keyboard.ts +34 -4
- package/src/data/table/hooks/useGridCache.ts +73 -0
- package/src/data/table/root/DataTableRoot.tsx +21 -11
- package/src/data/table/root/useTableKeyboardNav.ts +110 -128
- package/src/data/token-filter/AutoSuggest.tsx +179 -0
- package/src/data/token-filter/TokenFilter.tsx +124 -0
- package/src/data/token-filter/TokenFilter.types.ts +79 -0
- package/src/data/token-filter/helpers/generate-autocomplete-options.ts +244 -0
- package/src/data/token-filter/helpers/parse-query-text.test.ts +410 -0
- package/src/data/token-filter/helpers/parse-query-text.ts +148 -0
- package/src/link-card/LinkCard.tsx +15 -1
- package/src/process/Process.tsx +1 -1
- package/src/tooltip/Tooltip.tsx +3 -3
|
@@ -48,6 +48,16 @@ interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
48
48
|
* @see [📝 Documentation](https://aksel.nav.no/grunnleggende/styling/farger-tokens)
|
|
49
49
|
*/
|
|
50
50
|
"data-color"?: Exclude<AkselColor, AkselStatusColorRole>;
|
|
51
|
+
/**
|
|
52
|
+
* Changes the HTML element used for the root element.
|
|
53
|
+
*
|
|
54
|
+
* **When using `section`, provide either `aria-label` or `aria-labelledby` for better accessibility.**
|
|
55
|
+
* `axe-core` might warn about unique landmarks if you have multiple Accordions on page with the same label.
|
|
56
|
+
* In those cases consider updating to unique `aria-label` or `aria-labelledby` props.
|
|
57
|
+
* @see [📝 Landmarks unique](https://dequeuniversity.com/rules/axe/4.6/landmark-unique)
|
|
58
|
+
* @default "div"
|
|
59
|
+
*/
|
|
60
|
+
as?: "div" | "section";
|
|
51
61
|
}
|
|
52
62
|
/**
|
|
53
63
|
* A component that displays collapsible content sections.
|
|
@@ -39,7 +39,7 @@ import AccordionItem from "./AccordionItem.js";
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
export const Accordion = forwardRef((_a, ref) => {
|
|
42
|
-
var { className, variant = "default", size = "medium", indent = true } = _a, rest = __rest(_a, ["className", "variant", "size", "indent"]);
|
|
42
|
+
var { className, variant = "default", size = "medium", indent = true, as: Component = "div" } = _a, rest = __rest(_a, ["className", "variant", "size", "indent", "as"]);
|
|
43
43
|
const localRef = useRef(null);
|
|
44
44
|
const mergedRef = useMergeRefs(localRef, ref);
|
|
45
45
|
useEffect(() => {
|
|
@@ -59,7 +59,7 @@ export const Accordion = forwardRef((_a, ref) => {
|
|
|
59
59
|
mounted: true,
|
|
60
60
|
variant,
|
|
61
61
|
} },
|
|
62
|
-
React.createElement(
|
|
62
|
+
React.createElement(Component, Object.assign({}, omit(rest, ["headingSize"]), { className: cl("aksel-accordion", className, `aksel-accordion--${size}`, { "aksel-accordion--indent": indent }), ref: mergedRef }))));
|
|
63
63
|
});
|
|
64
64
|
Accordion.Header = AccordionHeader;
|
|
65
65
|
Accordion.Content = AccordionContent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.js","sourceRoot":"","sources":["../../src/accordion/Accordion.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAG7D,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,gBAA2C,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,eAAyC,MAAM,mBAAmB,CAAC;AAC1E,OAAO,aAAqC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Accordion.js","sourceRoot":"","sources":["../../src/accordion/Accordion.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAG7D,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,gBAA2C,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,eAAyC,MAAM,mBAAmB,CAAC;AAC1E,OAAO,aAAqC,MAAM,iBAAiB,CAAC;AA6DpE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CACjC,CACE,EAOC,EACD,GAAG,EACH,EAAE;QATF,EACE,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,QAAQ,EACf,MAAM,GAAG,IAAI,EACb,EAAE,EAAE,SAAS,GAAG,KAAK,OAEtB,EADI,IAAI,cANT,gDAOC,CADQ;IAIT,MAAM,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;;QACb,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC/D,OAAO;QACT,CAAC;QACD,IACE,MAAA,QAAQ,CAAC,OAAO,CAAC,kBAAkB,0CAAE,SAAS,CAAC,QAAQ,CACrD,iBAAiB,CAClB,EACD,CAAC;YACD,cAAc,CACZ,uHAAuH,EACvH,QAAQ,CAAC,OAAO,CACjB,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,cAAc,CACZ,mFAAmF,EACnF,QAAQ,CAAC,OAAO,CACjB,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,oBAAC,gBAAgB,CAAC,QAAQ,IACxB,KAAK,EAAE;YACL,IAAI;YACJ,OAAO,EAAE,IAAI;YACb,OAAO;SACR;QAED,oBAAC,SAAS,oBACJ,IAAI,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,IAC/B,SAAS,EAAE,EAAE,CACX,iBAAiB,EACjB,SAAS,EACT,oBAAoB,IAAI,EAAE,EAC1B,EAAE,yBAAyB,EAAE,MAAM,EAAE,CACtC,EACD,GAAG,EAAE,SAAS,IACd,CACwB,CAC7B,CAAC;AACJ,CAAC,CACoB,CAAC;AAExB,SAAS,CAAC,MAAM,GAAG,eAAe,CAAC;AACnC,SAAS,CAAC,OAAO,GAAG,gBAAgB,CAAC;AACrC,SAAS,CAAC,IAAI,GAAG,aAAa,CAAC;AAE/B,eAAe,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
declare function getFirstCell(tableRef: HTMLTableElement): Element | null;
|
|
2
|
-
declare function
|
|
3
|
-
export {
|
|
2
|
+
declare function focusInitialTableTarget(tableRef: HTMLTableElement | null): Element | null;
|
|
3
|
+
export { getFirstCell, focusInitialTableTarget };
|
|
@@ -2,15 +2,12 @@ import { focusCell } from "./table-focus.js";
|
|
|
2
2
|
function getFirstCell(tableRef) {
|
|
3
3
|
return tableRef.querySelector("td, th");
|
|
4
4
|
}
|
|
5
|
-
function
|
|
5
|
+
function focusInitialTableTarget(tableRef) {
|
|
6
6
|
if (!tableRef) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
|
-
if (activeCell) {
|
|
10
|
-
return activeCell;
|
|
11
|
-
}
|
|
12
9
|
const firstCell = getFirstCell(tableRef);
|
|
13
10
|
return firstCell ? focusCell(firstCell) : null;
|
|
14
11
|
}
|
|
15
|
-
export {
|
|
12
|
+
export { getFirstCell, focusInitialTableTarget };
|
|
16
13
|
//# sourceMappingURL=table-cell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-cell.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-cell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,SAAS,YAAY,CAAC,QAA0B;IAC9C,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,
|
|
1
|
+
{"version":3,"file":"table-cell.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-cell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,SAAS,YAAY,CAAC,QAA0B;IAC9C,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,uBAAuB,CAC9B,QAAiC;IAEjC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Restores the original tabIndex for a cell.
|
|
3
|
+
*/
|
|
4
|
+
declare function restoreTabIndex(cell: Element): void;
|
|
1
5
|
/**
|
|
2
6
|
* Makes sure only focusable and non-disabled elements are targeted when navigating through the table using keyboard interactions.
|
|
3
7
|
* Tries to find the most logical focus target inside a cell, by looking for commonly used interactive elements,
|
|
@@ -6,9 +10,29 @@
|
|
|
6
10
|
* If the assumed focus target is not the cell itself, we check if that element is hidden or disabled, and fall back to the cell if so,
|
|
7
11
|
* since we want to avoid/can't focus hidden/disabled elements.
|
|
8
12
|
*/
|
|
9
|
-
declare function
|
|
13
|
+
declare function findFocusableElementInCell(cell: Element): HTMLElement | null;
|
|
14
|
+
/**
|
|
15
|
+
* Checks if an element is visually hidden (but not SR-only).
|
|
16
|
+
*/
|
|
17
|
+
declare function isHiddenElement(el: HTMLElement): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Checks if an element is disabled (via aria-disabled, fieldset, or native disabled property).
|
|
20
|
+
*/
|
|
21
|
+
declare function isDisabledElement(el: HTMLElement): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Determines the focus target and updates tabIndex if the cell itself should be focused.
|
|
24
|
+
* Returns null if no focusable target found.
|
|
25
|
+
*/
|
|
26
|
+
declare function prepareCellFocus(cell: Element): HTMLElement | null;
|
|
27
|
+
/**
|
|
28
|
+
* Applies focus and scroll to an element.
|
|
29
|
+
*/
|
|
30
|
+
declare function applyFocusAndScroll(element: HTMLElement): void;
|
|
31
|
+
/**
|
|
32
|
+
* Focuses a cell by finding its focusable target and applying focus with scroll.
|
|
33
|
+
*/
|
|
10
34
|
declare function focusCell(cell: Element): Element | null;
|
|
11
35
|
declare function focusCellAndUpdateTabIndex(nextCell: Element, previousCell?: Element | null, { shouldFocus }?: {
|
|
12
36
|
shouldFocus?: boolean;
|
|
13
37
|
}): Element | null;
|
|
14
|
-
export { focusCell, focusCellAndUpdateTabIndex,
|
|
38
|
+
export { applyFocusAndScroll, focusCell, focusCellAndUpdateTabIndex, findFocusableElementInCell, isDisabledElement, isHiddenElement, prepareCellFocus, restoreTabIndex, };
|
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeakMap to store original tabIndex values for cells.
|
|
3
|
+
* Used to restore tabIndex when navigation moves away from a cell.
|
|
4
|
+
*/
|
|
5
|
+
const originalTabIndexMap = new WeakMap();
|
|
6
|
+
/**
|
|
7
|
+
* Stores the original tabIndex of a cell if not already stored, and returns it.
|
|
8
|
+
*/
|
|
9
|
+
function syncOriginalTabIndex(cell) {
|
|
10
|
+
if (!originalTabIndexMap.has(cell)) {
|
|
11
|
+
const current = cell.tabIndex;
|
|
12
|
+
originalTabIndexMap.set(cell, current);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Restores the original tabIndex for a cell.
|
|
17
|
+
*/
|
|
18
|
+
function restoreTabIndex(cell) {
|
|
19
|
+
const original = originalTabIndexMap.get(cell);
|
|
20
|
+
if (original !== undefined) {
|
|
21
|
+
cell.tabIndex = original;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
1
24
|
/**
|
|
2
25
|
* Makes sure only focusable and non-disabled elements are targeted when navigating through the table using keyboard interactions.
|
|
3
26
|
* Tries to find the most logical focus target inside a cell, by looking for commonly used interactive elements,
|
|
@@ -6,7 +29,7 @@
|
|
|
6
29
|
* If the assumed focus target is not the cell itself, we check if that element is hidden or disabled, and fall back to the cell if so,
|
|
7
30
|
* since we want to avoid/can't focus hidden/disabled elements.
|
|
8
31
|
*/
|
|
9
|
-
function
|
|
32
|
+
function findFocusableElementInCell(cell) {
|
|
10
33
|
const el = cell;
|
|
11
34
|
if (!el || isHiddenElement(el)) {
|
|
12
35
|
return null;
|
|
@@ -24,8 +47,7 @@ function getFocusableTarget(cell) {
|
|
|
24
47
|
return el;
|
|
25
48
|
}
|
|
26
49
|
/**
|
|
27
|
-
*
|
|
28
|
-
* - validate this implementation against SR-only elements
|
|
50
|
+
* Checks if an element is visually hidden (but not SR-only).
|
|
29
51
|
*/
|
|
30
52
|
function isHiddenElement(el) {
|
|
31
53
|
if (el.hidden) {
|
|
@@ -34,6 +56,9 @@ function isHiddenElement(el) {
|
|
|
34
56
|
const style = window.getComputedStyle(el);
|
|
35
57
|
return style.display === "none" || style.visibility === "hidden";
|
|
36
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Checks if an element is disabled (via aria-disabled, fieldset, or native disabled property).
|
|
61
|
+
*/
|
|
37
62
|
function isDisabledElement(el) {
|
|
38
63
|
if (el.getAttribute("aria-disabled") === "true") {
|
|
39
64
|
return true;
|
|
@@ -49,32 +74,53 @@ function isDisabledElement(el) {
|
|
|
49
74
|
}
|
|
50
75
|
return false;
|
|
51
76
|
}
|
|
52
|
-
|
|
53
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Determines the focus target and updates tabIndex if the cell itself should be focused.
|
|
79
|
+
* Returns null if no focusable target found.
|
|
80
|
+
*/
|
|
81
|
+
function prepareCellFocus(cell) {
|
|
82
|
+
const focusTarget = findFocusableElementInCell(cell);
|
|
54
83
|
if (!focusTarget) {
|
|
55
84
|
return null;
|
|
56
85
|
}
|
|
57
86
|
if (focusTarget === cell) {
|
|
58
87
|
cell.tabIndex = 0;
|
|
59
88
|
}
|
|
60
|
-
focusTarget
|
|
89
|
+
return focusTarget;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Applies focus and scroll to an element.
|
|
93
|
+
*/
|
|
94
|
+
function applyFocusAndScroll(element) {
|
|
95
|
+
element.focus({
|
|
61
96
|
preventScroll: true,
|
|
62
97
|
});
|
|
63
|
-
|
|
98
|
+
element.scrollIntoView({
|
|
64
99
|
behavior: "smooth",
|
|
65
100
|
block: "nearest",
|
|
66
101
|
inline: "nearest",
|
|
67
102
|
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Focuses a cell by finding its focusable target and applying focus with scroll.
|
|
106
|
+
*/
|
|
107
|
+
function focusCell(cell) {
|
|
108
|
+
const focusTarget = prepareCellFocus(cell);
|
|
109
|
+
if (!focusTarget) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
applyFocusAndScroll(focusTarget);
|
|
68
113
|
return cell;
|
|
69
114
|
}
|
|
70
115
|
function focusCellAndUpdateTabIndex(nextCell, previousCell, { shouldFocus = true } = {}) {
|
|
71
116
|
if (previousCell && previousCell !== nextCell) {
|
|
72
|
-
previousCell
|
|
117
|
+
syncOriginalTabIndex(previousCell);
|
|
118
|
+
restoreTabIndex(previousCell);
|
|
73
119
|
}
|
|
74
120
|
if (!shouldFocus) {
|
|
75
121
|
return nextCell;
|
|
76
122
|
}
|
|
77
123
|
return focusCell(nextCell);
|
|
78
124
|
}
|
|
79
|
-
export { focusCell, focusCellAndUpdateTabIndex,
|
|
125
|
+
export { applyFocusAndScroll, focusCell, focusCellAndUpdateTabIndex, findFocusableElementInCell, isDisabledElement, isHiddenElement, prepareCellFocus, restoreTabIndex, };
|
|
80
126
|
//# sourceMappingURL=table-focus.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-focus.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-focus.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,SAAS,
|
|
1
|
+
{"version":3,"file":"table-focus.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-focus.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,33 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builds a utility grid allowing for easier keyboard-navigation between cells on columns and rows
|
|
3
3
|
*/
|
|
4
|
-
declare function
|
|
4
|
+
declare function buildTableGridMap(tableRef: HTMLTableElement): {
|
|
5
5
|
grid: (Element | undefined)[][];
|
|
6
6
|
positions: Map<Element, {
|
|
7
7
|
x: number;
|
|
8
8
|
y: number;
|
|
9
9
|
}>;
|
|
10
|
-
maxCols: number;
|
|
11
10
|
};
|
|
12
|
-
type TableGrid = ReturnType<typeof buildTableGrid>;
|
|
13
11
|
type GridCache = {
|
|
14
|
-
grid:
|
|
12
|
+
grid: ReturnType<typeof buildTableGridMap> | null;
|
|
15
13
|
dirty: boolean;
|
|
16
14
|
};
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
16
|
+
* Pure function that calculates the next grid position given a current position and delta.
|
|
17
|
+
* Returns the position if valid, or null if out of bounds.
|
|
19
18
|
*/
|
|
20
|
-
declare function
|
|
19
|
+
declare function getNextGridPosition(grid: (Element | undefined)[][], currentPos: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
}, delta: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
}): {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
} | null;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if a cell is focusable (contains focusable elements).
|
|
31
|
+
* Type guard that narrows Element | undefined to Element.
|
|
32
|
+
*/
|
|
33
|
+
declare function isCellFocusable(cell: Element | undefined): cell is Element;
|
|
21
34
|
/**
|
|
22
35
|
* Finds the next cell in the given direction, starting from the current position.
|
|
23
|
-
* Skips over cells that are not focusable
|
|
36
|
+
* Skips over cells that are not focusable.
|
|
24
37
|
* Returns null if no next cell is found in the given direction.
|
|
25
38
|
*/
|
|
26
|
-
declare function
|
|
39
|
+
declare function findNextFocusableCell(grid: (Element | undefined)[][], currentPos: {
|
|
27
40
|
x: number;
|
|
28
41
|
y: number;
|
|
29
42
|
}, delta: {
|
|
30
43
|
x: number;
|
|
31
44
|
y: number;
|
|
32
|
-
}, currentCell: Element
|
|
33
|
-
|
|
45
|
+
}, currentCell: Element): Element | null;
|
|
46
|
+
/**
|
|
47
|
+
* Finds the first focusable cell in the given row.
|
|
48
|
+
*/
|
|
49
|
+
declare function findFirstCellInRow(grid: (Element | undefined)[][], rowIndex: number): Element | null;
|
|
50
|
+
/**
|
|
51
|
+
* Finds the last focusable cell in the given row.
|
|
52
|
+
*/
|
|
53
|
+
declare function findLastCellInRow(grid: (Element | undefined)[][], rowIndex: number): Element | null;
|
|
54
|
+
/**
|
|
55
|
+
* Finds the first focusable cell in the entire table.
|
|
56
|
+
*/
|
|
57
|
+
declare function findFirstCell(grid: (Element | undefined)[][]): Element | null;
|
|
58
|
+
/**
|
|
59
|
+
* Finds the last focusable cell in the entire table.
|
|
60
|
+
*/
|
|
61
|
+
declare function findLastCell(grid: (Element | undefined)[][]): Element | null;
|
|
62
|
+
export { buildTableGridMap, findFirstCell, findFirstCellInRow, findLastCell, findLastCellInRow, findNextFocusableCell, getNextGridPosition, isCellFocusable, };
|
|
63
|
+
export type { GridCache };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { findFocusableElementInCell } from "./table-focus.js";
|
|
2
2
|
/**
|
|
3
3
|
* Builds a utility grid allowing for easier keyboard-navigation between cells on columns and rows
|
|
4
4
|
*/
|
|
5
|
-
function
|
|
5
|
+
function buildTableGridMap(tableRef) {
|
|
6
6
|
const rows = tableRef.rows;
|
|
7
7
|
const grid = [];
|
|
8
8
|
const positions = new Map();
|
|
9
|
-
let maxCols = 0;
|
|
10
9
|
/* Walk trough each row in order */
|
|
11
10
|
for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
|
|
12
11
|
const row = rows[rowIndex];
|
|
@@ -38,43 +37,116 @@ function buildTableGrid(tableRef) {
|
|
|
38
37
|
positions.set(cell, { x: colIndex, y: rowIndex });
|
|
39
38
|
}
|
|
40
39
|
colIndex += colSpan;
|
|
41
|
-
if (colIndex > maxCols) {
|
|
42
|
-
maxCols = colIndex;
|
|
43
|
-
}
|
|
44
40
|
}
|
|
45
41
|
}
|
|
46
|
-
return { grid, positions
|
|
42
|
+
return { grid, positions };
|
|
47
43
|
}
|
|
48
44
|
/**
|
|
49
|
-
*
|
|
45
|
+
* Pure function that calculates the next grid position given a current position and delta.
|
|
46
|
+
* Returns the position if valid, or null if out of bounds.
|
|
50
47
|
*/
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
function getNextGridPosition(grid, currentPos, delta) {
|
|
49
|
+
var _a;
|
|
50
|
+
const x = currentPos.x + delta.x;
|
|
51
|
+
const y = currentPos.y + delta.y;
|
|
52
|
+
if (y < 0 || y >= grid.length) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const row = (_a = grid[y]) !== null && _a !== void 0 ? _a : [];
|
|
56
|
+
if (x < 0 || x >= row.length) {
|
|
57
|
+
return null;
|
|
55
58
|
}
|
|
56
|
-
return
|
|
59
|
+
return { x, y };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Checks if a cell is focusable (contains focusable elements).
|
|
63
|
+
* Type guard that narrows Element | undefined to Element.
|
|
64
|
+
*/
|
|
65
|
+
function isCellFocusable(cell) {
|
|
66
|
+
if (!cell) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return !!findFocusableElementInCell(cell);
|
|
57
70
|
}
|
|
58
71
|
/**
|
|
59
72
|
* Finds the next cell in the given direction, starting from the current position.
|
|
60
|
-
* Skips over cells that are not focusable
|
|
73
|
+
* Skips over cells that are not focusable.
|
|
61
74
|
* Returns null if no next cell is found in the given direction.
|
|
62
75
|
*/
|
|
63
|
-
function
|
|
76
|
+
function findNextFocusableCell(grid, currentPos, delta, currentCell) {
|
|
77
|
+
let position = currentPos;
|
|
78
|
+
while (true) {
|
|
79
|
+
const nextPos = getNextGridPosition(grid, position, delta);
|
|
80
|
+
if (!nextPos) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const cell = grid[nextPos.y][nextPos.x];
|
|
84
|
+
/* We check against current cell to avoid returning the same cell in cases of rowspan/colspan. */
|
|
85
|
+
if (cell !== currentCell && isCellFocusable(cell)) {
|
|
86
|
+
return cell;
|
|
87
|
+
}
|
|
88
|
+
position = nextPos;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Finds the first focusable cell in the given row.
|
|
93
|
+
*/
|
|
94
|
+
function findFirstCellInRow(grid, rowIndex) {
|
|
64
95
|
var _a;
|
|
65
|
-
|
|
66
|
-
let
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
96
|
+
const row = (_a = grid[rowIndex]) !== null && _a !== void 0 ? _a : [];
|
|
97
|
+
for (let x = 0; x < row.length; x += 1) {
|
|
98
|
+
const cell = row[x];
|
|
99
|
+
if (isCellFocusable(cell)) {
|
|
100
|
+
return cell;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Finds the last focusable cell in the given row.
|
|
107
|
+
*/
|
|
108
|
+
function findLastCellInRow(grid, rowIndex) {
|
|
109
|
+
var _a;
|
|
110
|
+
const row = (_a = grid[rowIndex]) !== null && _a !== void 0 ? _a : [];
|
|
111
|
+
for (let x = row.length - 1; x >= 0; x -= 1) {
|
|
70
112
|
const cell = row[x];
|
|
71
|
-
if (
|
|
113
|
+
if (isCellFocusable(cell)) {
|
|
72
114
|
return cell;
|
|
73
115
|
}
|
|
74
|
-
x += delta.x;
|
|
75
|
-
y += delta.y;
|
|
76
116
|
}
|
|
77
117
|
return null;
|
|
78
118
|
}
|
|
79
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Finds the first focusable cell in the entire table.
|
|
121
|
+
*/
|
|
122
|
+
function findFirstCell(grid) {
|
|
123
|
+
var _a;
|
|
124
|
+
for (let y = 0; y < grid.length; y += 1) {
|
|
125
|
+
const row = (_a = grid[y]) !== null && _a !== void 0 ? _a : [];
|
|
126
|
+
for (let x = 0; x < row.length; x += 1) {
|
|
127
|
+
const cell = row[x];
|
|
128
|
+
if (isCellFocusable(cell)) {
|
|
129
|
+
return cell;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Finds the last focusable cell in the entire table.
|
|
137
|
+
*/
|
|
138
|
+
function findLastCell(grid) {
|
|
139
|
+
var _a;
|
|
140
|
+
for (let y = grid.length - 1; y >= 0; y -= 1) {
|
|
141
|
+
const row = (_a = grid[y]) !== null && _a !== void 0 ? _a : [];
|
|
142
|
+
for (let x = row.length - 1; x >= 0; x -= 1) {
|
|
143
|
+
const cell = row[x];
|
|
144
|
+
if (isCellFocusable(cell)) {
|
|
145
|
+
return cell;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
export { buildTableGridMap, findFirstCell, findFirstCellInRow, findLastCell, findLastCellInRow, findNextFocusableCell, getNextGridPosition, isCellFocusable, };
|
|
80
152
|
//# sourceMappingURL=table-grid-nav.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-grid-nav.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-grid-nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"table-grid-nav.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-grid-nav.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,28 @@ type Delta = {
|
|
|
2
2
|
x: number;
|
|
3
3
|
y: number;
|
|
4
4
|
};
|
|
5
|
-
|
|
5
|
+
type NavigationAction = {
|
|
6
|
+
type: "delta";
|
|
7
|
+
delta: Delta;
|
|
8
|
+
} | {
|
|
9
|
+
type: "home";
|
|
10
|
+
} | {
|
|
11
|
+
type: "end";
|
|
12
|
+
} | {
|
|
13
|
+
type: "tableStart";
|
|
14
|
+
} | {
|
|
15
|
+
type: "tableEnd";
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Maps keyboard events to navigation actions.
|
|
19
|
+
* Supports arrow keys, Home/End (row navigation), Ctrl/Cmd+Home/End (table navigation),
|
|
20
|
+
* and PageUp/PageDown (multi-row navigation).
|
|
21
|
+
*/
|
|
22
|
+
declare function getNavigationAction(event: KeyboardEvent): NavigationAction | null;
|
|
6
23
|
/**
|
|
24
|
+
* Determines if keyboard navigation should be blocked based on the current focus context.
|
|
25
|
+
* Allows for custom blocking logic via an optional callback.
|
|
26
|
+
*
|
|
7
27
|
* Tries to make assumptions of what the user is currently doing inside a table cell
|
|
8
28
|
* Should block navigation if:
|
|
9
29
|
* - Input has selection, caret is not at start/end
|
|
@@ -11,5 +31,6 @@ declare function getDeltaFromKey(key: string): Delta | null;
|
|
|
11
31
|
* - User is navigating inside multiline textarea
|
|
12
32
|
* - contenteditable attrb is in use
|
|
13
33
|
*/
|
|
14
|
-
declare function
|
|
15
|
-
export {
|
|
34
|
+
declare function shouldBlockNavigation(event: KeyboardEvent): boolean;
|
|
35
|
+
export { getNavigationAction, shouldBlockNavigation };
|
|
36
|
+
export type { Delta, NavigationAction };
|
|
@@ -4,13 +4,33 @@ const keyToCoord = {
|
|
|
4
4
|
ArrowLeft: { x: -1, y: 0 },
|
|
5
5
|
ArrowRight: { x: 1, y: 0 },
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Maps keyboard events to navigation actions.
|
|
9
|
+
* Supports arrow keys, Home/End (row navigation), Ctrl/Cmd+Home/End (table navigation),
|
|
10
|
+
* and PageUp/PageDown (multi-row navigation).
|
|
11
|
+
*/
|
|
12
|
+
function getNavigationAction(event) {
|
|
13
|
+
const key = event.key;
|
|
14
|
+
/* Arrow keys -> directional navigation */
|
|
8
15
|
if (key in keyToCoord) {
|
|
9
|
-
return keyToCoord[key];
|
|
16
|
+
return { type: "delta", delta: keyToCoord[key] };
|
|
17
|
+
}
|
|
18
|
+
if (key === "Home") {
|
|
19
|
+
return event.ctrlKey || event.metaKey
|
|
20
|
+
? { type: "tableStart" }
|
|
21
|
+
: { type: "home" };
|
|
22
|
+
}
|
|
23
|
+
if (key === "End") {
|
|
24
|
+
return event.ctrlKey || event.metaKey
|
|
25
|
+
? { type: "tableEnd" }
|
|
26
|
+
: { type: "end" };
|
|
10
27
|
}
|
|
11
28
|
return null;
|
|
12
29
|
}
|
|
13
30
|
/**
|
|
31
|
+
* Determines if keyboard navigation should be blocked based on the current focus context.
|
|
32
|
+
* Allows for custom blocking logic via an optional callback.
|
|
33
|
+
*
|
|
14
34
|
* Tries to make assumptions of what the user is currently doing inside a table cell
|
|
15
35
|
* Should block navigation if:
|
|
16
36
|
* - Input has selection, caret is not at start/end
|
|
@@ -18,7 +38,7 @@ function getDeltaFromKey(key) {
|
|
|
18
38
|
* - User is navigating inside multiline textarea
|
|
19
39
|
* - contenteditable attrb is in use
|
|
20
40
|
*/
|
|
21
|
-
function
|
|
41
|
+
function shouldBlockNavigation(event) {
|
|
22
42
|
const key = event.key;
|
|
23
43
|
if (!(key in keyToCoord)) {
|
|
24
44
|
return false;
|
|
@@ -91,5 +111,5 @@ function isTextInputType(type) {
|
|
|
91
111
|
return false;
|
|
92
112
|
}
|
|
93
113
|
}
|
|
94
|
-
export {
|
|
114
|
+
export { getNavigationAction, shouldBlockNavigation };
|
|
95
115
|
//# sourceMappingURL=table-keyboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-keyboard.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-keyboard.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG;IACjB,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACxB,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IACzB,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IAC1B,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"table-keyboard.js","sourceRoot":"","sources":["../../../../src/data/table/helpers/table-keyboard.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG;IACjB,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACxB,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IACzB,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IAC1B,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;CAClB,CAAC;AAWX;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAoB;IAC/C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAEtB,0CAA0C;IAC1C,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,GAAkB,CAAC,EAAE,CAAC;IAClE,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;YACnC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE;YACxB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;YACnC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE;YACtB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,qBAAqB,CAAC,KAAoB;IACjD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC,MAA4B,CAAC;IAC9C,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CACzB,mDAAmD,CACpD,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,QAAQ,YAAY,gBAAgB,EAAE,CAAC;QACzC,OAAO,qBAAqB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,QAAQ,YAAY,mBAAmB,EAAE,CAAC;QAC5C,OAAO,wBAAwB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,QAAQ,YAAY,iBAAiB,EAAE,CAAC;QAC1C,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,QAAQ,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAuB,EAAE,GAAW;IACjE,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC;IACnC,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC;IAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,sBAAsB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,wBAAwB,CAC/B,QAA6B,EAC7B,GAAW;IAEX,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC;IAClC,OAAO,sBAAsB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,sBAAsB,CAC7B,GAAW,EACX,KAAa,EACb,GAAW,EACX,WAAmB;IAEnB,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7C,OAAO,KAAK,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;QAChD,OAAO,GAAG,GAAG,WAAW,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,KAAK,CAAC;QACX,KAAK,KAAK,CAAC;QACX,KAAK,UAAU,CAAC;QAChB,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC;QACd;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages the table grid cache and observes DOM changes that require grid rebuilding.
|
|
3
|
+
* Watches for structural changes (rows/cells added/removed) and attribute changes
|
|
4
|
+
* (colspan, rowspan, hidden, style) that affect grid layout and focusability.
|
|
5
|
+
*/
|
|
6
|
+
declare function useGridCache(tableRef: HTMLTableElement | null, enabled: boolean): {
|
|
7
|
+
getTableGrid: (_tableRef: HTMLTableElement) => {
|
|
8
|
+
grid: (Element | undefined)[][];
|
|
9
|
+
positions: Map<Element, {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
activeCell: Element | null;
|
|
15
|
+
setActiveCell: import("react").Dispatch<import("react").SetStateAction<Element | null>>;
|
|
16
|
+
};
|
|
17
|
+
export { useGridCache };
|