@navikt/ds-react 8.6.0 → 8.7.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.
- package/cjs/data/drag-and-drop/item/DataDragAndDropItem.d.ts +27 -0
- package/cjs/data/drag-and-drop/item/DataDragAndDropItem.js +91 -0
- package/cjs/data/drag-and-drop/item/DataDragAndDropItem.js.map +1 -0
- package/cjs/data/drag-and-drop/root/DataDragAndDrop.context.d.ts +5 -0
- package/cjs/data/drag-and-drop/root/DataDragAndDrop.context.js +6 -0
- package/cjs/data/drag-and-drop/root/DataDragAndDrop.context.js.map +1 -0
- package/cjs/data/drag-and-drop/root/DataDragAndDropRoot.d.ts +24 -0
- package/cjs/data/drag-and-drop/root/DataDragAndDropRoot.js +111 -0
- package/cjs/data/drag-and-drop/root/DataDragAndDropRoot.js.map +1 -0
- package/cjs/data/table/helpers/table-keyboard.d.ts +1 -0
- package/cjs/data/table/helpers/table-keyboard.js +5 -3
- package/cjs/data/table/helpers/table-keyboard.js.map +1 -1
- package/cjs/data/table/root/DataTableRoot.context.d.ts +8 -0
- package/cjs/data/table/root/DataTableRoot.context.js +11 -0
- package/cjs/data/table/root/DataTableRoot.context.js.map +1 -0
- package/cjs/data/table/root/DataTableRoot.js +5 -3
- package/cjs/data/table/root/DataTableRoot.js.map +1 -1
- package/cjs/data/table/th/DataTableTh.d.ts +18 -2
- package/cjs/data/table/th/DataTableTh.js +45 -20
- package/cjs/data/table/th/DataTableTh.js.map +1 -1
- package/cjs/data/table/tr/DataTableTr.js +9 -2
- package/cjs/data/table/tr/DataTableTr.js.map +1 -1
- package/cjs/data/token-filter/AutoSuggest.d.ts +6 -2
- package/cjs/data/token-filter/AutoSuggest.js +46 -11
- package/cjs/data/token-filter/AutoSuggest.js.map +1 -1
- package/cjs/data/token-filter/TokenFilter.d.ts +5 -5
- package/cjs/data/token-filter/TokenFilter.js +105 -42
- package/cjs/data/token-filter/TokenFilter.js.map +1 -1
- package/cjs/data/token-filter/TokenFilter.types.d.ts +51 -33
- package/cjs/data/token-filter/helpers/generate-autocomplete-options.d.ts +2 -3
- package/cjs/data/token-filter/helpers/generate-autocomplete-options.js +11 -15
- package/cjs/data/token-filter/helpers/generate-autocomplete-options.js.map +1 -1
- package/cjs/data/token-filter/helpers/operators.d.ts +6 -6
- package/cjs/data/token-filter/helpers/operators.js +3 -4
- package/cjs/data/token-filter/helpers/operators.js.map +1 -1
- package/cjs/data/token-filter/helpers/parse-query-text.d.ts +2 -20
- package/cjs/data/token-filter/helpers/parse-query-text.js +1 -1
- package/cjs/data/token-filter/helpers/parse-query-text.js.map +1 -1
- package/cjs/data/token-filter/helpers/query-builder.d.ts +2 -2
- package/cjs/data/token-filter/helpers/query-builder.js.map +1 -1
- package/cjs/date/Date.Dialog.d.ts +5 -1
- package/cjs/date/Date.Dialog.js +6 -2
- package/cjs/date/Date.Dialog.js.map +1 -1
- package/cjs/date/datepicker/DatePicker.js +3 -2
- package/cjs/date/datepicker/DatePicker.js.map +1 -1
- package/cjs/date/datepicker/hooks/useDatepicker.js +5 -2
- package/cjs/date/datepicker/hooks/useDatepicker.js.map +1 -1
- package/cjs/date/datepicker/hooks/useRangeDatepicker.js +3 -1
- package/cjs/date/datepicker/hooks/useRangeDatepicker.js.map +1 -1
- package/cjs/date/datepicker/parts/DatePicker.Months.d.ts +2 -1
- package/cjs/date/datepicker/parts/DatePicker.Months.js +3 -3
- package/cjs/date/datepicker/parts/DatePicker.Months.js.map +1 -1
- package/cjs/date/datepicker/parts/DatePicker.RDP.d.ts +5 -1
- package/cjs/date/datepicker/parts/DatePicker.RDP.js +2 -2
- package/cjs/date/datepicker/parts/DatePicker.RDP.js.map +1 -1
- package/cjs/date/monthpicker/MonthPicker.js +3 -2
- package/cjs/date/monthpicker/MonthPicker.js.map +1 -1
- package/cjs/date/monthpicker/hooks/useMonthPicker.js +3 -1
- package/cjs/date/monthpicker/hooks/useMonthPicker.js.map +1 -1
- package/cjs/date/monthpicker/parts/MonthPicker.Caption.d.ts +4 -1
- package/cjs/date/monthpicker/parts/MonthPicker.Caption.js +3 -2
- package/cjs/date/monthpicker/parts/MonthPicker.Caption.js.map +1 -1
- package/cjs/dropdown/Toggle.js +5 -12
- package/cjs/dropdown/Toggle.js.map +1 -1
- package/cjs/form/combobox/Input/Input.js +1 -1
- package/cjs/form/combobox/Input/Input.js.map +1 -1
- package/cjs/inline-message/root/InlineMessage.js +2 -2
- package/cjs/inline-message/root/InlineMessage.js.map +1 -1
- package/cjs/provider/Provider.d.ts +2 -2
- package/cjs/tooltip/Tooltip.js +1 -3
- package/cjs/tooltip/Tooltip.js.map +1 -1
- package/cjs/utils/components/HighlightText/HighlightText.d.ts +8 -0
- package/cjs/utils/components/HighlightText/HighlightText.js +27 -0
- package/cjs/utils/components/HighlightText/HighlightText.js.map +1 -0
- package/cjs/utils/components/Listbox/group/ListboxGroup.d.ts +7 -0
- package/cjs/utils/components/Listbox/group/ListboxGroup.js +15 -0
- package/cjs/utils/components/Listbox/group/ListboxGroup.js.map +1 -0
- package/cjs/utils/components/Listbox/input-slot/ListboxInputSlot.d.ts +7 -0
- package/cjs/utils/components/Listbox/input-slot/ListboxInputSlot.js +15 -0
- package/cjs/utils/components/Listbox/input-slot/ListboxInputSlot.js.map +1 -0
- package/cjs/utils/components/Listbox/item/ListboxItem.d.ts +24 -0
- package/cjs/utils/components/Listbox/item/ListboxItem.js +33 -0
- package/cjs/utils/components/Listbox/item/ListboxItem.js.map +1 -0
- package/cjs/utils/components/Listbox/list/ListboxList.d.ts +8 -0
- package/cjs/utils/components/Listbox/list/ListboxList.js +32 -0
- package/cjs/utils/components/Listbox/list/ListboxList.js.map +1 -0
- package/cjs/utils/components/Listbox/root/ListboxRoot.d.ts +20 -0
- package/cjs/utils/components/Listbox/root/ListboxRoot.js +84 -0
- package/cjs/utils/components/Listbox/root/ListboxRoot.js.map +1 -0
- package/cjs/utils/components/Listbox/root/domHelpers.d.ts +3 -0
- package/cjs/utils/components/Listbox/root/domHelpers.js +53 -0
- package/cjs/utils/components/Listbox/root/domHelpers.js.map +1 -0
- package/cjs/utils/components/focus-boundary/FocusBoundary.js +9 -64
- package/cjs/utils/components/focus-boundary/FocusBoundary.js.map +1 -1
- package/cjs/utils/helpers/focus.d.ts +14 -0
- package/cjs/utils/helpers/focus.js +63 -0
- package/cjs/utils/helpers/focus.js.map +1 -0
- package/cjs/utils/hooks/useDeferredValue.d.ts +1 -0
- package/cjs/utils/hooks/useDeferredValue.js +14 -0
- package/cjs/utils/hooks/useDeferredValue.js.map +1 -0
- package/esm/data/drag-and-drop/item/DataDragAndDropItem.d.ts +27 -0
- package/esm/data/drag-and-drop/item/DataDragAndDropItem.js +55 -0
- package/esm/data/drag-and-drop/item/DataDragAndDropItem.js.map +1 -0
- package/esm/data/drag-and-drop/root/DataDragAndDrop.context.d.ts +5 -0
- package/esm/data/drag-and-drop/root/DataDragAndDrop.context.js +3 -0
- package/esm/data/drag-and-drop/root/DataDragAndDrop.context.js.map +1 -0
- package/esm/data/drag-and-drop/root/DataDragAndDropRoot.d.ts +24 -0
- package/esm/data/drag-and-drop/root/DataDragAndDropRoot.js +71 -0
- package/esm/data/drag-and-drop/root/DataDragAndDropRoot.js.map +1 -0
- package/esm/data/table/helpers/table-keyboard.d.ts +1 -0
- package/esm/data/table/helpers/table-keyboard.js +5 -3
- package/esm/data/table/helpers/table-keyboard.js.map +1 -1
- package/esm/data/table/root/DataTableRoot.context.d.ts +8 -0
- package/esm/data/table/root/DataTableRoot.context.js +7 -0
- package/esm/data/table/root/DataTableRoot.context.js.map +1 -0
- package/esm/data/table/root/DataTableRoot.js +5 -3
- package/esm/data/table/root/DataTableRoot.js.map +1 -1
- package/esm/data/table/th/DataTableTh.d.ts +18 -2
- package/esm/data/table/th/DataTableTh.js +46 -21
- package/esm/data/table/th/DataTableTh.js.map +1 -1
- package/esm/data/table/tr/DataTableTr.js +9 -2
- package/esm/data/table/tr/DataTableTr.js.map +1 -1
- package/esm/data/token-filter/AutoSuggest.d.ts +6 -2
- package/esm/data/token-filter/AutoSuggest.js +45 -13
- package/esm/data/token-filter/AutoSuggest.js.map +1 -1
- package/esm/data/token-filter/TokenFilter.d.ts +5 -5
- package/esm/data/token-filter/TokenFilter.js +105 -42
- package/esm/data/token-filter/TokenFilter.js.map +1 -1
- package/esm/data/token-filter/TokenFilter.types.d.ts +51 -33
- package/esm/data/token-filter/helpers/generate-autocomplete-options.d.ts +2 -3
- package/esm/data/token-filter/helpers/generate-autocomplete-options.js +11 -15
- package/esm/data/token-filter/helpers/generate-autocomplete-options.js.map +1 -1
- package/esm/data/token-filter/helpers/operators.d.ts +6 -6
- package/esm/data/token-filter/helpers/operators.js +3 -4
- package/esm/data/token-filter/helpers/operators.js.map +1 -1
- package/esm/data/token-filter/helpers/parse-query-text.d.ts +2 -20
- package/esm/data/token-filter/helpers/parse-query-text.js +1 -1
- package/esm/data/token-filter/helpers/parse-query-text.js.map +1 -1
- package/esm/data/token-filter/helpers/query-builder.d.ts +2 -2
- package/esm/data/token-filter/helpers/query-builder.js.map +1 -1
- package/esm/date/Date.Dialog.d.ts +5 -1
- package/esm/date/Date.Dialog.js +6 -2
- package/esm/date/Date.Dialog.js.map +1 -1
- package/esm/date/datepicker/DatePicker.js +3 -2
- package/esm/date/datepicker/DatePicker.js.map +1 -1
- package/esm/date/datepicker/hooks/useDatepicker.js +5 -2
- package/esm/date/datepicker/hooks/useDatepicker.js.map +1 -1
- package/esm/date/datepicker/hooks/useRangeDatepicker.js +3 -1
- package/esm/date/datepicker/hooks/useRangeDatepicker.js.map +1 -1
- package/esm/date/datepicker/parts/DatePicker.Months.d.ts +2 -1
- package/esm/date/datepicker/parts/DatePicker.Months.js +3 -3
- package/esm/date/datepicker/parts/DatePicker.Months.js.map +1 -1
- package/esm/date/datepicker/parts/DatePicker.RDP.d.ts +5 -1
- package/esm/date/datepicker/parts/DatePicker.RDP.js +2 -2
- package/esm/date/datepicker/parts/DatePicker.RDP.js.map +1 -1
- package/esm/date/monthpicker/MonthPicker.js +3 -2
- package/esm/date/monthpicker/MonthPicker.js.map +1 -1
- package/esm/date/monthpicker/hooks/useMonthPicker.js +3 -1
- package/esm/date/monthpicker/hooks/useMonthPicker.js.map +1 -1
- package/esm/date/monthpicker/parts/MonthPicker.Caption.d.ts +4 -1
- package/esm/date/monthpicker/parts/MonthPicker.Caption.js +3 -2
- package/esm/date/monthpicker/parts/MonthPicker.Caption.js.map +1 -1
- package/esm/dropdown/Toggle.js +5 -12
- package/esm/dropdown/Toggle.js.map +1 -1
- package/esm/form/combobox/Input/Input.js +1 -1
- package/esm/form/combobox/Input/Input.js.map +1 -1
- package/esm/inline-message/root/InlineMessage.js +3 -3
- package/esm/inline-message/root/InlineMessage.js.map +1 -1
- package/esm/provider/Provider.d.ts +2 -2
- package/esm/tooltip/Tooltip.js +1 -3
- package/esm/tooltip/Tooltip.js.map +1 -1
- package/esm/utils/components/HighlightText/HighlightText.d.ts +8 -0
- package/esm/utils/components/HighlightText/HighlightText.js +21 -0
- package/esm/utils/components/HighlightText/HighlightText.js.map +1 -0
- package/esm/utils/components/Listbox/group/ListboxGroup.d.ts +7 -0
- package/esm/utils/components/Listbox/group/ListboxGroup.js +10 -0
- package/esm/utils/components/Listbox/group/ListboxGroup.js.map +1 -0
- package/esm/utils/components/Listbox/input-slot/ListboxInputSlot.d.ts +7 -0
- package/esm/utils/components/Listbox/input-slot/ListboxInputSlot.js +9 -0
- package/esm/utils/components/Listbox/input-slot/ListboxInputSlot.js.map +1 -0
- package/esm/utils/components/Listbox/item/ListboxItem.d.ts +24 -0
- package/esm/utils/components/Listbox/item/ListboxItem.js +27 -0
- package/esm/utils/components/Listbox/item/ListboxItem.js.map +1 -0
- package/esm/utils/components/Listbox/list/ListboxList.d.ts +8 -0
- package/esm/utils/components/Listbox/list/ListboxList.js +27 -0
- package/esm/utils/components/Listbox/list/ListboxList.js.map +1 -0
- package/esm/utils/components/Listbox/root/ListboxRoot.d.ts +20 -0
- package/esm/utils/components/Listbox/root/ListboxRoot.js +79 -0
- package/esm/utils/components/Listbox/root/ListboxRoot.js.map +1 -0
- package/esm/utils/components/Listbox/root/domHelpers.d.ts +3 -0
- package/esm/utils/components/Listbox/root/domHelpers.js +50 -0
- package/esm/utils/components/Listbox/root/domHelpers.js.map +1 -0
- package/esm/utils/components/focus-boundary/FocusBoundary.js +8 -63
- package/esm/utils/components/focus-boundary/FocusBoundary.js.map +1 -1
- package/esm/utils/helpers/focus.d.ts +14 -0
- package/esm/utils/helpers/focus.js +60 -0
- package/esm/utils/helpers/focus.js.map +1 -0
- package/esm/utils/hooks/useDeferredValue.d.ts +1 -0
- package/esm/utils/hooks/useDeferredValue.js +7 -0
- package/esm/utils/hooks/useDeferredValue.js.map +1 -0
- package/package.json +7 -7
- package/src/data/drag-and-drop/item/DataDragAndDropItem.tsx +101 -0
- package/src/data/drag-and-drop/root/DataDragAndDrop.context.tsx +9 -0
- package/src/data/drag-and-drop/root/DataDragAndDropRoot.tsx +98 -0
- package/src/data/table/helpers/table-keyboard.ts +7 -3
- package/src/data/table/root/DataTableRoot.context.ts +13 -0
- package/src/data/table/root/DataTableRoot.tsx +16 -13
- package/src/data/table/th/DataTableTh.tsx +110 -54
- package/src/data/table/tr/DataTableTr.tsx +13 -2
- package/src/data/token-filter/AutoSuggest.tsx +142 -29
- package/src/data/token-filter/TokenFilter.tsx +174 -79
- package/src/data/token-filter/TokenFilter.types.ts +70 -42
- package/src/data/token-filter/helpers/generate-autocomplete-options.test.ts +97 -97
- package/src/data/token-filter/helpers/generate-autocomplete-options.ts +31 -38
- package/src/data/token-filter/helpers/operators.test.ts +29 -29
- package/src/data/token-filter/helpers/operators.ts +16 -16
- package/src/data/token-filter/helpers/parse-query-text.test.ts +37 -35
- package/src/data/token-filter/helpers/parse-query-text.ts +7 -26
- package/src/data/token-filter/helpers/query-builder.ts +2 -2
- package/src/date/Date.Dialog.tsx +15 -0
- package/src/date/datepicker/DatePicker.tsx +3 -0
- package/src/date/datepicker/hooks/useDatepicker.tsx +7 -2
- package/src/date/datepicker/hooks/useRangeDatepicker.tsx +5 -1
- package/src/date/datepicker/parts/DatePicker.Months.tsx +9 -1
- package/src/date/datepicker/parts/DatePicker.RDP.tsx +7 -1
- package/src/date/monthpicker/MonthPicker.tsx +3 -1
- package/src/date/monthpicker/hooks/useMonthPicker.tsx +5 -1
- package/src/date/monthpicker/parts/MonthPicker.Caption.tsx +20 -2
- package/src/dropdown/Toggle.tsx +6 -12
- package/src/form/combobox/Input/Input.tsx +2 -2
- package/src/inline-message/root/InlineMessage.tsx +5 -5
- package/src/provider/Provider.tsx +2 -2
- package/src/tooltip/Tooltip.tsx +1 -3
- package/src/utils/components/HighlightText/HighlightText.tsx +34 -0
- package/src/utils/components/Listbox/group/ListboxGroup.tsx +26 -0
- package/src/utils/components/Listbox/input-slot/ListboxInputSlot.tsx +22 -0
- package/src/utils/components/Listbox/item/ListboxItem.tsx +57 -0
- package/src/utils/components/Listbox/list/ListboxList.tsx +38 -0
- package/src/utils/components/Listbox/root/ListboxRoot.tsx +104 -0
- package/src/utils/components/Listbox/root/domHelpers.ts +59 -0
- package/src/utils/components/focus-boundary/FocusBoundary.tsx +8 -78
- package/src/utils/helpers/focus.ts +75 -0
- package/src/utils/hooks/useDeferredValue.ts +12 -0
- package/cjs/data/table/th/DataTableThSortHandle.d.ts +0 -6
- package/cjs/data/table/th/DataTableThSortHandle.js +0 -82
- package/cjs/data/table/th/DataTableThSortHandle.js.map +0 -1
- package/esm/data/table/th/DataTableThSortHandle.d.ts +0 -6
- package/esm/data/table/th/DataTableThSortHandle.js +0 -47
- package/esm/data/table/th/DataTableThSortHandle.js.map +0 -1
- package/src/data/table/th/DataTableThSortHandle.tsx +0 -67
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
2
|
+
/** biome-ignore-all lint/a11y/noStaticElementInteractions: We know what we are doing */
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { ListboxGroup } from "../group/ListboxGroup";
|
|
5
|
+
import { ListboxInputSlot } from "../input-slot/ListboxInputSlot";
|
|
6
|
+
import { ListboxItem } from "../item/ListboxItem";
|
|
7
|
+
import { ListboxList } from "../list/ListboxList";
|
|
8
|
+
import { findNextItem, findPrevItem } from "./domHelpers";
|
|
9
|
+
|
|
10
|
+
export interface ListboxProps {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
setVirtuallyFocusedItemId: (value: string) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Low level component for displaying a list of selectable items with optional grouping.
|
|
17
|
+
* Keyboard navigation is implemented with virtual focus so that real focus can remain on an input field.
|
|
18
|
+
*/
|
|
19
|
+
function Listbox({ children, setVirtuallyFocusedItemId }: ListboxProps) {
|
|
20
|
+
const virtuallyFocusItem = (element: HTMLElement | null) => {
|
|
21
|
+
setVirtuallyFocusedItemId(element?.dataset.id || "");
|
|
22
|
+
element?.scrollIntoView({ block: "nearest" });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
onKeyDown={(event) => {
|
|
28
|
+
const listbox =
|
|
29
|
+
event.currentTarget.querySelector<HTMLElement>('[role="listbox"]');
|
|
30
|
+
if (!listbox) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Helper functions
|
|
35
|
+
const getFirstItem = (suffix: string = "") =>
|
|
36
|
+
listbox.querySelector<HTMLElement>(`[role="option"]${suffix}`);
|
|
37
|
+
const getLastItem = () => {
|
|
38
|
+
const allItems =
|
|
39
|
+
listbox.querySelectorAll<HTMLElement>('[role="option"]');
|
|
40
|
+
return allItems[allItems.length - 1];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const focusedItemElm = getFirstItem('[data-virtual-focus="true"]');
|
|
44
|
+
|
|
45
|
+
// Doesn't make sense to have real focus on one item and virtual focus on another at the same time.
|
|
46
|
+
// Not sure if it matters, though 🤔
|
|
47
|
+
const itemElmWithRealFocus = getFirstItem(":focus");
|
|
48
|
+
if (itemElmWithRealFocus) {
|
|
49
|
+
listbox.focus();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const virtuallyFocusWithFallback = (
|
|
53
|
+
getNextElement: (currentItem: HTMLElement) => HTMLElement | null,
|
|
54
|
+
getFallback: () => HTMLElement | null,
|
|
55
|
+
) => {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
if (!focusedItemElm) {
|
|
58
|
+
virtuallyFocusItem(getFallback());
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const nextItem = getNextElement(focusedItemElm);
|
|
62
|
+
if (!nextItem) {
|
|
63
|
+
virtuallyFocusItem(getFallback());
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
virtuallyFocusItem(nextItem);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
switch (event.key) {
|
|
70
|
+
case "ArrowDown":
|
|
71
|
+
virtuallyFocusWithFallback(findNextItem, getFirstItem);
|
|
72
|
+
break;
|
|
73
|
+
case "ArrowUp":
|
|
74
|
+
virtuallyFocusWithFallback(findPrevItem, getLastItem);
|
|
75
|
+
break;
|
|
76
|
+
case "Home":
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
virtuallyFocusItem(getFirstItem());
|
|
79
|
+
break;
|
|
80
|
+
case "End":
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
virtuallyFocusItem(getLastItem());
|
|
83
|
+
break;
|
|
84
|
+
case "Enter":
|
|
85
|
+
case "Accept":
|
|
86
|
+
if (focusedItemElm) {
|
|
87
|
+
focusedItemElm.click();
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
// TODO: Consider implementing PageUp/PageDown too
|
|
91
|
+
}
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
{children}
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Listbox.InputSlot = ListboxInputSlot;
|
|
100
|
+
Listbox.List = ListboxList;
|
|
101
|
+
Listbox.Item = ListboxItem;
|
|
102
|
+
Listbox.Group = ListboxGroup;
|
|
103
|
+
|
|
104
|
+
export default Listbox;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function findNextItem(currentItem: HTMLElement) {
|
|
2
|
+
const nextElement = currentItem.nextElementSibling as HTMLElement | null;
|
|
3
|
+
if (nextElement) {
|
|
4
|
+
if (nextElement.role === "group") {
|
|
5
|
+
return nextElement.querySelector<HTMLElement>('[role="option"]');
|
|
6
|
+
}
|
|
7
|
+
if (nextElement.role === "option") {
|
|
8
|
+
return nextElement;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// No next element: Current element might be inside a group.
|
|
13
|
+
// Check if the parent has a next sibling
|
|
14
|
+
const parentNextElement = currentItem.parentElement
|
|
15
|
+
?.nextElementSibling as HTMLElement | null;
|
|
16
|
+
if (parentNextElement) {
|
|
17
|
+
if (parentNextElement.role === "group") {
|
|
18
|
+
return parentNextElement.querySelector<HTMLElement>('[role="option"]');
|
|
19
|
+
}
|
|
20
|
+
if (parentNextElement.role === "option") {
|
|
21
|
+
return parentNextElement;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function findPrevItem(currentItem: HTMLElement) {
|
|
29
|
+
const prevElement = currentItem.previousElementSibling as HTMLElement | null;
|
|
30
|
+
if (prevElement) {
|
|
31
|
+
if (prevElement.role === "group") {
|
|
32
|
+
return prevElement.querySelector<HTMLElement>(
|
|
33
|
+
'[role="option"]:last-of-type',
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (prevElement.role === "option") {
|
|
37
|
+
return prevElement;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// No previous element: Current element might be inside a group.
|
|
42
|
+
// Check if the parent has a previous sibling.
|
|
43
|
+
const parentPrevElement = currentItem.parentElement
|
|
44
|
+
?.previousElementSibling as HTMLElement | null;
|
|
45
|
+
if (parentPrevElement) {
|
|
46
|
+
if (parentPrevElement.role === "group") {
|
|
47
|
+
return parentPrevElement.querySelector<HTMLElement>(
|
|
48
|
+
'[role="option"]:last-of-type',
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (parentPrevElement.role === "option") {
|
|
52
|
+
return parentPrevElement;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { findNextItem, findPrevItem };
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
ownerDocument,
|
|
12
12
|
resolveRef,
|
|
13
13
|
} from "../../helpers";
|
|
14
|
+
import { focusElement, getTabbableCandidates } from "../../helpers/focus";
|
|
14
15
|
import { useMergeRefs } from "../../hooks";
|
|
15
16
|
import { useValueAsRef } from "../../hooks/useValueAsRef";
|
|
16
17
|
import { Slot } from "../slot/Slot";
|
|
@@ -118,7 +119,7 @@ const FocusBoundary = forwardRef<HTMLDivElement, FocusBoundaryProps>(
|
|
|
118
119
|
if (container.contains(target)) {
|
|
119
120
|
lastFocusedElementRef.current = target;
|
|
120
121
|
} else {
|
|
121
|
-
|
|
122
|
+
focusElement(lastFocusedElementRef.current, { select: true });
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
@@ -150,7 +151,7 @@ const FocusBoundary = forwardRef<HTMLDivElement, FocusBoundaryProps>(
|
|
|
150
151
|
* when they are not supposed to (like when clicking on elements outside the container
|
|
151
152
|
*/
|
|
152
153
|
if (!container.contains(relatedTarget)) {
|
|
153
|
-
|
|
154
|
+
focusElement(lastFocusedElementRef.current, { select: true });
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
|
|
@@ -165,7 +166,7 @@ const FocusBoundary = forwardRef<HTMLDivElement, FocusBoundaryProps>(
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
if (mutations.some((mutation) => mutation.removedNodes.length > 0)) {
|
|
168
|
-
|
|
169
|
+
focusElement(container);
|
|
169
170
|
}
|
|
170
171
|
};
|
|
171
172
|
|
|
@@ -230,7 +231,7 @@ const FocusBoundary = forwardRef<HTMLDivElement, FocusBoundaryProps>(
|
|
|
230
231
|
const previouslyFocusedElement = ownerDoc.activeElement;
|
|
231
232
|
|
|
232
233
|
queueMicrotask(() => {
|
|
233
|
-
const focusableElements =
|
|
234
|
+
const focusableElements = getTabbableCandidates(container);
|
|
234
235
|
const initialFocusValueOrFn = initialFocusRef.current;
|
|
235
236
|
const resolvedInitialFocus =
|
|
236
237
|
typeof initialFocusValueOrFn === "function"
|
|
@@ -262,7 +263,7 @@ const FocusBoundary = forwardRef<HTMLDivElement, FocusBoundaryProps>(
|
|
|
262
263
|
return;
|
|
263
264
|
}
|
|
264
265
|
|
|
265
|
-
|
|
266
|
+
focusElement(elToFocus, {
|
|
266
267
|
preventScroll: elToFocus === container,
|
|
267
268
|
sync: false,
|
|
268
269
|
});
|
|
@@ -361,12 +362,12 @@ const FocusBoundary = forwardRef<HTMLDivElement, FocusBoundaryProps>(
|
|
|
361
362
|
if (!event.shiftKey && focusedElement === last) {
|
|
362
363
|
event.preventDefault();
|
|
363
364
|
if (loop) {
|
|
364
|
-
|
|
365
|
+
focusElement(first, { select: true });
|
|
365
366
|
}
|
|
366
367
|
} else if (event.shiftKey && focusedElement === first) {
|
|
367
368
|
event.preventDefault();
|
|
368
369
|
if (loop) {
|
|
369
|
-
|
|
370
|
+
focusElement(last, { select: true });
|
|
370
371
|
}
|
|
371
372
|
}
|
|
372
373
|
}
|
|
@@ -398,40 +399,6 @@ function getTabbableEdges(container: HTMLElement) {
|
|
|
398
399
|
] as const;
|
|
399
400
|
}
|
|
400
401
|
|
|
401
|
-
/**
|
|
402
|
-
* Returns a list of potential tabbable candidates.
|
|
403
|
-
* We do not take into account tabindex values.
|
|
404
|
-
*
|
|
405
|
-
* See: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
|
|
406
|
-
* Credit: https://github.com/discord/focus-layers/blob/master/src/util/wrapFocus.tsx#L1
|
|
407
|
-
*/
|
|
408
|
-
function getTabbableCandidates(container: HTMLElement) {
|
|
409
|
-
const nodes: HTMLElement[] = [];
|
|
410
|
-
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
411
|
-
acceptNode: (node: any) => {
|
|
412
|
-
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
|
413
|
-
if (node.disabled || node.hidden || isHiddenInput) {
|
|
414
|
-
return NodeFilter.FILTER_SKIP;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* `.tabIndex` is not the same as the `tabindex` attribute. It works on the
|
|
419
|
-
* runtime's understanding of tabbability, so this automatically accounts
|
|
420
|
-
* for any kind of element that could be tabbed to.
|
|
421
|
-
*/
|
|
422
|
-
return node.tabIndex >= 0
|
|
423
|
-
? NodeFilter.FILTER_ACCEPT
|
|
424
|
-
: NodeFilter.FILTER_SKIP;
|
|
425
|
-
},
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
while (walker.nextNode()) {
|
|
429
|
-
nodes.push(walker.currentNode as HTMLElement);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
return nodes;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
402
|
/**
|
|
436
403
|
* Returns the first visible element in a list.
|
|
437
404
|
* NOTE: Only checks visibility up to the `container`.
|
|
@@ -462,39 +429,6 @@ function isHidden(node: HTMLElement, { upTo }: { upTo?: HTMLElement }) {
|
|
|
462
429
|
return false;
|
|
463
430
|
}
|
|
464
431
|
|
|
465
|
-
let rafId = 0;
|
|
466
|
-
function focus(
|
|
467
|
-
element?: HTMLElement | null,
|
|
468
|
-
{ select = false, preventScroll = true, sync = true } = {},
|
|
469
|
-
) {
|
|
470
|
-
if (!element?.focus) {
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
const previouslyFocusedElement = document.activeElement;
|
|
475
|
-
|
|
476
|
-
cancelAnimationFrame(rafId);
|
|
477
|
-
const exec = () => element.focus({ preventScroll });
|
|
478
|
-
|
|
479
|
-
if (sync) {
|
|
480
|
-
exec();
|
|
481
|
-
} else {
|
|
482
|
-
rafId = requestAnimationFrame(exec);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
if (!select) {
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/* By default, inputs that gets focus should select its contents */
|
|
490
|
-
if (
|
|
491
|
-
element !== previouslyFocusedElement &&
|
|
492
|
-
element instanceof HTMLInputElement &&
|
|
493
|
-
"select" in element
|
|
494
|
-
)
|
|
495
|
-
element.select();
|
|
496
|
-
}
|
|
497
|
-
|
|
498
432
|
/* ---------------------------- FocusBoundary stack ---------------------------- */
|
|
499
433
|
type FocusBoundaryAPI = { paused: boolean; pause(): void; resume(): void };
|
|
500
434
|
const focusBoundarysStack = createFocusBoundarysStack();
|
|
@@ -531,10 +465,6 @@ function arrayRemove<T>(array: T[], item: T) {
|
|
|
531
465
|
return updatedArray;
|
|
532
466
|
}
|
|
533
467
|
|
|
534
|
-
function removeLinks(items: HTMLElement[]) {
|
|
535
|
-
return items.filter((item) => item.tagName !== "A");
|
|
536
|
-
}
|
|
537
|
-
|
|
538
468
|
const LIST_LIMIT = 10;
|
|
539
469
|
let previouslyFocusedElements: Element[] = [];
|
|
540
470
|
const focusedElementsByContainer = new WeakMap<Element, Element[]>();
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a list of potential tabbable candidates.
|
|
3
|
+
* We do not take into account tabindex values.
|
|
4
|
+
*
|
|
5
|
+
* See: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
|
|
6
|
+
* Credit: https://github.com/discord/focus-layers/blob/master/src/util/wrapFocus.tsx#L1
|
|
7
|
+
*/
|
|
8
|
+
function getTabbableCandidates(container: HTMLElement) {
|
|
9
|
+
const nodes: HTMLElement[] = [];
|
|
10
|
+
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
11
|
+
acceptNode: (node: any) => {
|
|
12
|
+
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
|
13
|
+
if (node.disabled || node.hidden || isHiddenInput) {
|
|
14
|
+
return NodeFilter.FILTER_SKIP;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* `.tabIndex` is not the same as the `tabindex` attribute. It works on the
|
|
19
|
+
* runtime's understanding of tabbability, so this automatically accounts
|
|
20
|
+
* for any kind of element that could be tabbed to.
|
|
21
|
+
*/
|
|
22
|
+
return node.tabIndex >= 0
|
|
23
|
+
? NodeFilter.FILTER_ACCEPT
|
|
24
|
+
: NodeFilter.FILTER_SKIP;
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
while (walker.nextNode()) {
|
|
29
|
+
nodes.push(walker.currentNode as HTMLElement);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return removeLinks(nodes);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function removeLinks(items: HTMLElement[]) {
|
|
36
|
+
return items.filter((item) => item.tagName !== "A");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let rafId = 0;
|
|
40
|
+
|
|
41
|
+
function focusElement(
|
|
42
|
+
element?: HTMLElement | null,
|
|
43
|
+
{ select = false, preventScroll = true, sync = true } = {},
|
|
44
|
+
) {
|
|
45
|
+
if (!element?.focus) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const previouslyFocusedElement = document.activeElement;
|
|
50
|
+
|
|
51
|
+
cancelAnimationFrame(rafId);
|
|
52
|
+
const exec = () => {
|
|
53
|
+
element.focus({ preventScroll });
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (sync) {
|
|
57
|
+
exec();
|
|
58
|
+
} else {
|
|
59
|
+
rafId = requestAnimationFrame(exec);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!select) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* By default, inputs that gets focus should select its contents */
|
|
67
|
+
if (
|
|
68
|
+
element !== previouslyFocusedElement &&
|
|
69
|
+
element instanceof HTMLInputElement &&
|
|
70
|
+
"select" in element
|
|
71
|
+
)
|
|
72
|
+
element.select();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { getTabbableCandidates, focusElement };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
const maybeReactUseDeferredValue: undefined | ((string: string) => string) = (
|
|
4
|
+
React as any
|
|
5
|
+
)[
|
|
6
|
+
"useDeferredValue" + "" // Workaround for https://github.com/webpack/webpack/issues/14814
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export const useDeferredValue = (value: string): string =>
|
|
10
|
+
maybeReactUseDeferredValue !== undefined
|
|
11
|
+
? maybeReactUseDeferredValue(value)
|
|
12
|
+
: value;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
declare function DataTableThSortHandle({ sortDirection, onSortChange, }: {
|
|
3
|
-
sortDirection?: "asc" | "desc" | "none" | false;
|
|
4
|
-
onSortChange?: (direction: "asc" | "desc" | "none", event: Event) => void;
|
|
5
|
-
}): React.JSX.Element | null;
|
|
6
|
-
export { DataTableThSortHandle };
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.DataTableThSortHandle = DataTableThSortHandle;
|
|
37
|
-
const react_1 = __importStar(require("react"));
|
|
38
|
-
const aksel_icons_1 = require("@navikt/aksel-icons");
|
|
39
|
-
const button_1 = require("../../../button");
|
|
40
|
-
const ICON_CONFIG = {
|
|
41
|
-
desc: {
|
|
42
|
-
icon: aksel_icons_1.SortDownIcon,
|
|
43
|
-
title: "Sorter stigende",
|
|
44
|
-
},
|
|
45
|
-
asc: {
|
|
46
|
-
icon: aksel_icons_1.SortUpIcon,
|
|
47
|
-
title: "Ingen sortering",
|
|
48
|
-
},
|
|
49
|
-
none: {
|
|
50
|
-
icon: aksel_icons_1.ArrowsUpDownIcon,
|
|
51
|
-
title: "Sorter synkende",
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
function DataTableThSortHandle({ sortDirection = false, onSortChange, }) {
|
|
55
|
-
const IconConfig = (0, react_1.useMemo)(() => {
|
|
56
|
-
if (!sortDirection) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
return ICON_CONFIG[sortDirection];
|
|
60
|
-
}, [sortDirection]);
|
|
61
|
-
if (!sortDirection || !IconConfig) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
return (react_1.default.createElement(button_1.Button, { "data-color": "neutral", variant: "tertiary", size: "small", icon: react_1.default.createElement(IconConfig.icon, { title: IconConfig.title }), onClick: (event) => {
|
|
65
|
-
if (!onSortChange)
|
|
66
|
-
return;
|
|
67
|
-
/* TODO: This configuration is not a given */
|
|
68
|
-
let newDirection;
|
|
69
|
-
if (sortDirection === "none") {
|
|
70
|
-
newDirection = "asc";
|
|
71
|
-
}
|
|
72
|
-
else if (sortDirection === "asc") {
|
|
73
|
-
newDirection = "desc";
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
newDirection = "none";
|
|
77
|
-
}
|
|
78
|
-
/* TODO: Handle types better */
|
|
79
|
-
onSortChange(newDirection, event);
|
|
80
|
-
} }));
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=DataTableThSortHandle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DataTableThSortHandle.js","sourceRoot":"","sources":["../../../../src/data/table/th/DataTableThSortHandle.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkES,sDAAqB;AAlE9B,+CAAuC;AACvC,qDAI6B;AAC7B,4CAAyC;AAEzC,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE;QACJ,IAAI,EAAE,0BAAY;QAClB,KAAK,EAAE,iBAAiB;KACzB;IACD,GAAG,EAAE;QACH,IAAI,EAAE,wBAAU;QAChB,KAAK,EAAE,iBAAiB;KACzB;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,8BAAgB;QACtB,KAAK,EAAE,iBAAiB;KACzB;CACF,CAAC;AAEF,SAAS,qBAAqB,CAAC,EAC7B,aAAa,GAAG,KAAK,EACrB,YAAY,GAIb;IACC,MAAM,UAAU,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,WAAW,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,8BAAC,eAAM,kBACM,SAAS,EACpB,OAAO,EAAC,UAAU,EAClB,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,8BAAC,UAAU,CAAC,IAAI,IAAC,KAAK,EAAE,UAAU,CAAC,KAAK,GAAI,EAClD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,CAAC,YAAY;gBAAE,OAAO;YAE1B,6CAA6C;YAC7C,IAAI,YAAqC,CAAC;YAC1C,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;gBAC7B,YAAY,GAAG,KAAK,CAAC;YACvB,CAAC;iBAAM,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;gBACnC,YAAY,GAAG,MAAM,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,MAAM,CAAC;YACxB,CAAC;YACD,+BAA+B;YAC/B,YAAY,CAAC,YAAY,EAAE,KAAyB,CAAC,CAAC;QACxD,CAAC,GACD,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
declare function DataTableThSortHandle({ sortDirection, onSortChange, }: {
|
|
3
|
-
sortDirection?: "asc" | "desc" | "none" | false;
|
|
4
|
-
onSortChange?: (direction: "asc" | "desc" | "none", event: Event) => void;
|
|
5
|
-
}): React.JSX.Element | null;
|
|
6
|
-
export { DataTableThSortHandle };
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import { ArrowsUpDownIcon, SortDownIcon, SortUpIcon, } from "@navikt/aksel-icons";
|
|
3
|
-
import { Button } from "../../../button/index.js";
|
|
4
|
-
const ICON_CONFIG = {
|
|
5
|
-
desc: {
|
|
6
|
-
icon: SortDownIcon,
|
|
7
|
-
title: "Sorter stigende",
|
|
8
|
-
},
|
|
9
|
-
asc: {
|
|
10
|
-
icon: SortUpIcon,
|
|
11
|
-
title: "Ingen sortering",
|
|
12
|
-
},
|
|
13
|
-
none: {
|
|
14
|
-
icon: ArrowsUpDownIcon,
|
|
15
|
-
title: "Sorter synkende",
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
function DataTableThSortHandle({ sortDirection = false, onSortChange, }) {
|
|
19
|
-
const IconConfig = useMemo(() => {
|
|
20
|
-
if (!sortDirection) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
return ICON_CONFIG[sortDirection];
|
|
24
|
-
}, [sortDirection]);
|
|
25
|
-
if (!sortDirection || !IconConfig) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
return (React.createElement(Button, { "data-color": "neutral", variant: "tertiary", size: "small", icon: React.createElement(IconConfig.icon, { title: IconConfig.title }), onClick: (event) => {
|
|
29
|
-
if (!onSortChange)
|
|
30
|
-
return;
|
|
31
|
-
/* TODO: This configuration is not a given */
|
|
32
|
-
let newDirection;
|
|
33
|
-
if (sortDirection === "none") {
|
|
34
|
-
newDirection = "asc";
|
|
35
|
-
}
|
|
36
|
-
else if (sortDirection === "asc") {
|
|
37
|
-
newDirection = "desc";
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
newDirection = "none";
|
|
41
|
-
}
|
|
42
|
-
/* TODO: Handle types better */
|
|
43
|
-
onSortChange(newDirection, event);
|
|
44
|
-
} }));
|
|
45
|
-
}
|
|
46
|
-
export { DataTableThSortHandle };
|
|
47
|
-
//# sourceMappingURL=DataTableThSortHandle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DataTableThSortHandle.js","sourceRoot":"","sources":["../../../../src/data/table/th/DataTableThSortHandle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,UAAU,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,iBAAiB;KACzB;IACD,GAAG,EAAE;QACH,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,iBAAiB;KACzB;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,iBAAiB;KACzB;CACF,CAAC;AAEF,SAAS,qBAAqB,CAAC,EAC7B,aAAa,GAAG,KAAK,EACrB,YAAY,GAIb;IACC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE;QAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,WAAW,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,oBAAC,MAAM,kBACM,SAAS,EACpB,OAAO,EAAC,UAAU,EAClB,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,oBAAC,UAAU,CAAC,IAAI,IAAC,KAAK,EAAE,UAAU,CAAC,KAAK,GAAI,EAClD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,CAAC,YAAY;gBAAE,OAAO;YAE1B,6CAA6C;YAC7C,IAAI,YAAqC,CAAC;YAC1C,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;gBAC7B,YAAY,GAAG,KAAK,CAAC;YACvB,CAAC;iBAAM,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;gBACnC,YAAY,GAAG,MAAM,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,MAAM,CAAC;YACxB,CAAC;YACD,+BAA+B;YAC/B,YAAY,CAAC,YAAY,EAAE,KAAyB,CAAC,CAAC;QACxD,CAAC,GACD,CACH,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import {
|
|
3
|
-
ArrowsUpDownIcon,
|
|
4
|
-
SortDownIcon,
|
|
5
|
-
SortUpIcon,
|
|
6
|
-
} from "@navikt/aksel-icons";
|
|
7
|
-
import { Button } from "../../../button";
|
|
8
|
-
|
|
9
|
-
const ICON_CONFIG = {
|
|
10
|
-
desc: {
|
|
11
|
-
icon: SortDownIcon,
|
|
12
|
-
title: "Sorter stigende",
|
|
13
|
-
},
|
|
14
|
-
asc: {
|
|
15
|
-
icon: SortUpIcon,
|
|
16
|
-
title: "Ingen sortering",
|
|
17
|
-
},
|
|
18
|
-
none: {
|
|
19
|
-
icon: ArrowsUpDownIcon,
|
|
20
|
-
title: "Sorter synkende",
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function DataTableThSortHandle({
|
|
25
|
-
sortDirection = false,
|
|
26
|
-
onSortChange,
|
|
27
|
-
}: {
|
|
28
|
-
sortDirection?: "asc" | "desc" | "none" | false;
|
|
29
|
-
onSortChange?: (direction: "asc" | "desc" | "none", event: Event) => void;
|
|
30
|
-
}) {
|
|
31
|
-
const IconConfig = useMemo(() => {
|
|
32
|
-
if (!sortDirection) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
return ICON_CONFIG[sortDirection];
|
|
36
|
-
}, [sortDirection]);
|
|
37
|
-
|
|
38
|
-
if (!sortDirection || !IconConfig) {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<Button
|
|
44
|
-
data-color="neutral"
|
|
45
|
-
variant="tertiary"
|
|
46
|
-
size="small"
|
|
47
|
-
icon={<IconConfig.icon title={IconConfig.title} />}
|
|
48
|
-
onClick={(event) => {
|
|
49
|
-
if (!onSortChange) return;
|
|
50
|
-
|
|
51
|
-
/* TODO: This configuration is not a given */
|
|
52
|
-
let newDirection: "asc" | "desc" | "none";
|
|
53
|
-
if (sortDirection === "none") {
|
|
54
|
-
newDirection = "asc";
|
|
55
|
-
} else if (sortDirection === "asc") {
|
|
56
|
-
newDirection = "desc";
|
|
57
|
-
} else {
|
|
58
|
-
newDirection = "none";
|
|
59
|
-
}
|
|
60
|
-
/* TODO: Handle types better */
|
|
61
|
-
onSortChange(newDirection, event as unknown as Event);
|
|
62
|
-
}}
|
|
63
|
-
/>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export { DataTableThSortHandle };
|