@navikt/ds-react 7.2.0 → 7.3.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/accordion/AccordionHeader.js +1 -1
- package/cjs/accordion/AccordionHeader.js.map +1 -1
- package/cjs/alert/Alert.d.ts +0 -3
- package/cjs/alert/Alert.js +11 -17
- package/cjs/alert/Alert.js.map +1 -1
- package/cjs/chips/Removable.d.ts +5 -5
- package/cjs/chips/Removable.js +4 -2
- package/cjs/chips/Removable.js.map +1 -1
- package/cjs/collapsible/Collapsible.context.d.ts +1 -1
- package/cjs/date/datepicker/DatePicker.d.ts +2 -2
- package/cjs/date/monthpicker/MonthPicker.d.ts +2 -2
- package/cjs/dropdown/Menu/index.js +1 -1
- package/cjs/dropdown/Menu/index.js.map +1 -1
- package/cjs/form/checkbox/useCheckbox.js +3 -2
- package/cjs/form/checkbox/useCheckbox.js.map +1 -1
- package/cjs/form/combobox/ComboboxProvider.js +4 -1
- package/cjs/form/combobox/ComboboxProvider.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js +1 -1
- package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/useVirtualFocus.d.ts +3 -0
- package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js +33 -10
- package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
- package/cjs/form/combobox/Input/Input.js +23 -10
- package/cjs/form/combobox/Input/Input.js.map +1 -1
- package/cjs/form/file-upload/FileUpload.context.d.ts +1 -1
- package/cjs/form/radio/useRadio.js +3 -2
- package/cjs/form/radio/useRadio.js.map +1 -1
- package/cjs/form/search/Search.js +1 -1
- package/cjs/form/search/Search.js.map +1 -1
- package/cjs/form/switch/Switch.js +2 -1
- package/cjs/form/switch/Switch.js.map +1 -1
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +4 -2
- package/cjs/index.js.map +1 -1
- package/cjs/layout/base/BasePrimitive.d.ts +3 -0
- package/cjs/layout/base/BasePrimitive.js.map +1 -1
- package/cjs/layout/box/Box.d.ts +2 -2
- package/cjs/layout/box/Box.js.map +1 -1
- package/cjs/layout/grid/HGrid.d.ts +2 -2
- package/cjs/layout/grid/HGrid.js.map +1 -1
- package/cjs/layout/stack/Stack.d.ts +2 -2
- package/cjs/layout/stack/Stack.js.map +1 -1
- package/cjs/modal/ModalHeader.js +6 -1
- package/cjs/modal/ModalHeader.js.map +1 -1
- package/cjs/modal/dialog-polyfill.js +2 -2
- package/cjs/modal/dialog-polyfill.js.map +1 -1
- package/cjs/overlays/action-menu/ActionMenu.d.ts +310 -0
- package/cjs/overlays/action-menu/ActionMenu.js +227 -0
- package/cjs/overlays/action-menu/ActionMenu.js.map +1 -0
- package/cjs/overlays/action-menu/index.d.ts +1 -0
- package/cjs/overlays/action-menu/index.js +19 -0
- package/cjs/overlays/action-menu/index.js.map +1 -0
- package/cjs/overlays/floating/Floating.js +9 -10
- package/cjs/overlays/floating/Floating.js.map +1 -1
- package/cjs/overlays/floating/Floating.utils.d.ts +3 -5
- package/cjs/overlays/floating/Floating.utils.js +0 -2
- package/cjs/overlays/floating/Floating.utils.js.map +1 -1
- package/cjs/overlays/floating-menu/Menu.d.ts +15 -21
- package/cjs/overlays/floating-menu/Menu.js +119 -230
- package/cjs/overlays/floating-menu/Menu.js.map +1 -1
- package/cjs/overlays/floating-menu/parts/RovingFocus.d.ts +1 -1
- package/cjs/overlays/floating-menu/parts/RovingFocus.js +4 -4
- package/cjs/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
- package/cjs/pagination/Pagination.d.ts +1 -6
- package/cjs/pagination/Pagination.js.map +1 -1
- package/cjs/provider/i18n/LanguageProvider.d.ts +3 -3
- package/cjs/stepper/context.d.ts +1 -1
- package/cjs/table/Body.d.ts +2 -4
- package/cjs/table/Body.js.map +1 -1
- package/cjs/table/ColumnHeader.d.ts +1 -2
- package/cjs/table/ColumnHeader.js.map +1 -1
- package/cjs/table/ExpandableRow.d.ts +1 -2
- package/cjs/table/ExpandableRow.js.map +1 -1
- package/cjs/table/Header.d.ts +2 -4
- package/cjs/table/Header.js.map +1 -1
- package/cjs/table/HeaderCell.d.ts +1 -2
- package/cjs/table/HeaderCell.js.map +1 -1
- package/cjs/table/Row.d.ts +1 -2
- package/cjs/table/Row.js.map +1 -1
- package/cjs/tabs/Tabs.context.d.ts +1 -1
- package/cjs/tabs/parts/tablist/useScrollButtons.js +1 -1
- package/cjs/tabs/parts/tablist/useScrollButtons.js.map +1 -1
- package/cjs/tabs/parts/tablist/useTabList.js +4 -4
- package/cjs/tabs/parts/tablist/useTabList.js.map +1 -1
- package/cjs/timeline/TimelineRow.js +9 -10
- package/cjs/timeline/TimelineRow.js.map +1 -1
- package/cjs/toggle-group/ToggleGroup.context.d.ts +1 -1
- package/cjs/toggle-group/parts/useToggleItem.js +4 -4
- package/cjs/toggle-group/parts/useToggleItem.js.map +1 -1
- package/cjs/util/TextareaAutoSize.js +2 -2
- package/cjs/util/TextareaAutoSize.js.map +1 -1
- package/cjs/util/hooks/descendants/descendant.js +1 -1
- package/cjs/util/hooks/descendants/descendant.js.map +1 -1
- package/cjs/util/hooks/descendants/useDescendant.js +1 -1
- package/cjs/util/hooks/descendants/useDescendant.js.map +1 -1
- package/cjs/util/i18n/get.d.ts +2 -2
- package/cjs/util/i18n/get.js.map +1 -1
- package/cjs/util/i18n/i18n.context.d.ts +2 -3
- package/cjs/util/i18n/i18n.context.js.map +1 -1
- package/cjs/util/i18n/i18n.types.d.ts +5 -9
- package/cjs/util/i18n/locales/en.d.ts +39 -0
- package/cjs/util/i18n/locales/en.js +41 -0
- package/cjs/util/i18n/locales/en.js.map +1 -0
- package/cjs/util/i18n/locales/nb.d.ts +14 -0
- package/cjs/util/i18n/locales/nb.js +14 -0
- package/cjs/util/i18n/locales/nb.js.map +1 -1
- package/cjs/util/i18n/locales/nn.d.ts +39 -0
- package/cjs/util/i18n/locales/nn.js +41 -0
- package/cjs/util/i18n/locales/nn.js.map +1 -0
- package/cjs/util/requireReactElement.d.ts +2 -0
- package/cjs/util/requireReactElement.js +22 -0
- package/cjs/util/requireReactElement.js.map +1 -0
- package/cjs/util/virtualfocus/Context.d.ts +1 -1
- package/cjs/util/virtualfocus/parts/VirtualFocusContent.d.ts +1 -2
- package/cjs/util/virtualfocus/parts/VirtualFocusContent.js.map +1 -1
- package/esm/accordion/AccordionHeader.js +1 -1
- package/esm/accordion/AccordionHeader.js.map +1 -1
- package/esm/alert/Alert.d.ts +0 -3
- package/esm/alert/Alert.js +11 -17
- package/esm/alert/Alert.js.map +1 -1
- package/esm/chips/Removable.d.ts +5 -5
- package/esm/chips/Removable.js +4 -2
- package/esm/chips/Removable.js.map +1 -1
- package/esm/collapsible/Collapsible.context.d.ts +1 -1
- package/esm/date/datepicker/DatePicker.d.ts +2 -2
- package/esm/date/monthpicker/MonthPicker.d.ts +2 -2
- package/esm/dropdown/Menu/index.js +1 -1
- package/esm/dropdown/Menu/index.js.map +1 -1
- package/esm/form/checkbox/useCheckbox.js +3 -2
- package/esm/form/checkbox/useCheckbox.js.map +1 -1
- package/esm/form/combobox/ComboboxProvider.js +4 -1
- package/esm/form/combobox/ComboboxProvider.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js +1 -1
- package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/useVirtualFocus.d.ts +3 -0
- package/esm/form/combobox/FilteredOptions/useVirtualFocus.js +34 -11
- package/esm/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
- package/esm/form/combobox/Input/Input.js +23 -10
- package/esm/form/combobox/Input/Input.js.map +1 -1
- package/esm/form/file-upload/FileUpload.context.d.ts +1 -1
- package/esm/form/radio/useRadio.js +3 -2
- package/esm/form/radio/useRadio.js.map +1 -1
- package/esm/form/search/Search.js +1 -1
- package/esm/form/search/Search.js.map +1 -1
- package/esm/form/switch/Switch.js +2 -1
- package/esm/form/switch/Switch.js.map +1 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/layout/base/BasePrimitive.d.ts +3 -0
- package/esm/layout/base/BasePrimitive.js.map +1 -1
- package/esm/layout/box/Box.d.ts +2 -2
- package/esm/layout/box/Box.js.map +1 -1
- package/esm/layout/grid/HGrid.d.ts +2 -2
- package/esm/layout/grid/HGrid.js.map +1 -1
- package/esm/layout/stack/Stack.d.ts +2 -2
- package/esm/layout/stack/Stack.js.map +1 -1
- package/esm/modal/ModalHeader.js +6 -1
- package/esm/modal/ModalHeader.js.map +1 -1
- package/esm/modal/dialog-polyfill.js +2 -2
- package/esm/modal/dialog-polyfill.js.map +1 -1
- package/esm/overlays/action-menu/ActionMenu.d.ts +310 -0
- package/esm/overlays/action-menu/ActionMenu.js +197 -0
- package/esm/overlays/action-menu/ActionMenu.js.map +1 -0
- package/esm/overlays/action-menu/index.d.ts +1 -0
- package/esm/overlays/action-menu/index.js +3 -0
- package/esm/overlays/action-menu/index.js.map +1 -0
- package/esm/overlays/floating/Floating.js +9 -10
- package/esm/overlays/floating/Floating.js.map +1 -1
- package/esm/overlays/floating/Floating.utils.d.ts +3 -5
- package/esm/overlays/floating/Floating.utils.js +0 -2
- package/esm/overlays/floating/Floating.utils.js.map +1 -1
- package/esm/overlays/floating-menu/Menu.d.ts +15 -21
- package/esm/overlays/floating-menu/Menu.js +119 -230
- package/esm/overlays/floating-menu/Menu.js.map +1 -1
- package/esm/overlays/floating-menu/parts/RovingFocus.d.ts +1 -1
- package/esm/overlays/floating-menu/parts/RovingFocus.js +4 -4
- package/esm/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
- package/esm/pagination/Pagination.d.ts +1 -6
- package/esm/pagination/Pagination.js.map +1 -1
- package/esm/provider/i18n/LanguageProvider.d.ts +3 -3
- package/esm/stepper/context.d.ts +1 -1
- package/esm/table/Body.d.ts +2 -4
- package/esm/table/Body.js.map +1 -1
- package/esm/table/ColumnHeader.d.ts +1 -2
- package/esm/table/ColumnHeader.js.map +1 -1
- package/esm/table/ExpandableRow.d.ts +1 -2
- package/esm/table/ExpandableRow.js.map +1 -1
- package/esm/table/Header.d.ts +2 -4
- package/esm/table/Header.js.map +1 -1
- package/esm/table/HeaderCell.d.ts +1 -2
- package/esm/table/HeaderCell.js.map +1 -1
- package/esm/table/Row.d.ts +1 -2
- package/esm/table/Row.js.map +1 -1
- package/esm/tabs/Tabs.context.d.ts +1 -1
- package/esm/tabs/parts/tablist/useScrollButtons.js +1 -1
- package/esm/tabs/parts/tablist/useScrollButtons.js.map +1 -1
- package/esm/tabs/parts/tablist/useTabList.js +4 -4
- package/esm/tabs/parts/tablist/useTabList.js.map +1 -1
- package/esm/timeline/TimelineRow.js +9 -10
- package/esm/timeline/TimelineRow.js.map +1 -1
- package/esm/toggle-group/ToggleGroup.context.d.ts +1 -1
- package/esm/toggle-group/parts/useToggleItem.js +4 -4
- package/esm/toggle-group/parts/useToggleItem.js.map +1 -1
- package/esm/util/TextareaAutoSize.js +2 -2
- package/esm/util/TextareaAutoSize.js.map +1 -1
- package/esm/util/hooks/descendants/descendant.js +1 -1
- package/esm/util/hooks/descendants/descendant.js.map +1 -1
- package/esm/util/hooks/descendants/useDescendant.js +1 -1
- package/esm/util/hooks/descendants/useDescendant.js.map +1 -1
- package/esm/util/i18n/get.d.ts +2 -2
- package/esm/util/i18n/get.js.map +1 -1
- package/esm/util/i18n/i18n.context.d.ts +2 -3
- package/esm/util/i18n/i18n.context.js.map +1 -1
- package/esm/util/i18n/i18n.types.d.ts +5 -9
- package/esm/util/i18n/locales/en.d.ts +39 -0
- package/esm/util/i18n/locales/en.js +39 -0
- package/esm/util/i18n/locales/en.js.map +1 -0
- package/esm/util/i18n/locales/nb.d.ts +14 -0
- package/esm/util/i18n/locales/nb.js +14 -0
- package/esm/util/i18n/locales/nb.js.map +1 -1
- package/esm/util/i18n/locales/nn.d.ts +39 -0
- package/esm/util/i18n/locales/nn.js +39 -0
- package/esm/util/i18n/locales/nn.js.map +1 -0
- package/esm/util/requireReactElement.d.ts +2 -0
- package/esm/util/requireReactElement.js +15 -0
- package/esm/util/requireReactElement.js.map +1 -0
- package/esm/util/virtualfocus/Context.d.ts +1 -1
- package/esm/util/virtualfocus/parts/VirtualFocusContent.d.ts +1 -2
- package/esm/util/virtualfocus/parts/VirtualFocusContent.js.map +1 -1
- package/package.json +15 -7
- package/src/accordion/AccordionHeader.tsx +0 -1
- package/src/alert/Alert.tsx +11 -20
- package/src/chips/Removable.tsx +13 -9
- package/src/date/datepicker/DatePicker.tsx +2 -2
- package/src/date/monthpicker/MonthPicker.tsx +2 -2
- package/src/dropdown/Menu/index.tsx +1 -1
- package/src/form/checkbox/Checkbox.test.tsx +2 -3
- package/src/form/checkbox/useCheckbox.ts +2 -2
- package/src/form/combobox/ComboboxProvider.tsx +9 -1
- package/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +1 -1
- package/src/form/combobox/FilteredOptions/useVirtualFocus.ts +42 -11
- package/src/form/combobox/Input/Input.tsx +19 -10
- package/src/form/combobox/__tests__/combobox.test.tsx +36 -0
- package/src/form/confirmation-panel/ConfirmationPanel.test.tsx +1 -2
- package/src/form/radio/Radio.test.tsx +4 -5
- package/src/form/radio/useRadio.ts +2 -2
- package/src/form/search/Search.tsx +1 -1
- package/src/form/switch/Switch.tsx +1 -1
- package/src/index.ts +1 -0
- package/src/layout/base/BasePrimitive.tsx +3 -0
- package/src/layout/box/Box.tsx +35 -36
- package/src/layout/grid/HGrid.tsx +26 -27
- package/src/layout/stack/Stack.tsx +53 -54
- package/src/modal/ModalHeader.tsx +6 -0
- package/src/modal/dialog-polyfill.ts +2 -2
- package/src/overlays/action-menu/ActionMenu.tsx +971 -0
- package/src/overlays/action-menu/index.ts +29 -0
- package/src/overlays/floating/Floating.tsx +6 -12
- package/src/overlays/floating/Floating.utils.ts +2 -5
- package/src/overlays/floating-menu/Menu.tsx +183 -332
- package/src/overlays/floating-menu/parts/RovingFocus.tsx +7 -7
- package/src/pagination/Pagination.tsx +4 -1
- package/src/pagination/steps.test.ts +15 -16
- package/src/provider/i18n/LanguageProvider.tsx +3 -3
- package/src/table/Body.tsx +4 -6
- package/src/table/ColumnHeader.tsx +3 -4
- package/src/table/ExpandableRow.tsx +3 -4
- package/src/table/Header.tsx +4 -6
- package/src/table/HeaderCell.tsx +3 -4
- package/src/table/Row.tsx +3 -4
- package/src/tabs/parts/tablist/useScrollButtons.ts +1 -1
- package/src/tabs/parts/tablist/useTabList.ts +4 -4
- package/src/timeline/TimelineRow.tsx +20 -21
- package/src/toggle-group/parts/useToggleItem.ts +4 -4
- package/src/util/TextareaAutoSize.tsx +2 -2
- package/src/util/hooks/descendants/descendant.ts +1 -1
- package/src/util/hooks/descendants/useDescendant.tsx +1 -1
- package/src/util/i18n/get.ts +3 -3
- package/src/util/i18n/i18n.context.ts +2 -3
- package/src/util/i18n/i18n.types.ts +7 -11
- package/src/util/i18n/locales/en.ts +40 -0
- package/src/util/i18n/locales/nb.ts +23 -1
- package/src/util/i18n/locales/nn.ts +40 -0
- package/src/util/i18n/locales.test.tsx +23 -0
- package/src/util/requireReactElement.ts +25 -0
- package/src/util/virtualfocus/parts/VirtualFocusContent.tsx +4 -2
- package/cjs/util/i18n/merge.d.ts +0 -2
- package/cjs/util/i18n/merge.js +0 -28
- package/cjs/util/i18n/merge.js.map +0 -1
- package/esm/util/i18n/merge.d.ts +0 -2
- package/esm/util/i18n/merge.js +0 -25
- package/esm/util/i18n/merge.js.map +0 -1
- package/src/util/i18n/merge.ts +0 -35
|
@@ -7,7 +7,7 @@ import { DescendantsManager } from "../../../util/hooks/descendants/descendant";
|
|
|
7
7
|
interface RovingFocusProps
|
|
8
8
|
extends Omit<React.HTMLAttributes<HTMLDivElement>, "tabIndex"> {
|
|
9
9
|
asChild?: boolean;
|
|
10
|
-
descendants: DescendantsManager<HTMLDivElement,
|
|
10
|
+
descendants: DescendantsManager<HTMLDivElement, any>;
|
|
11
11
|
onEntryFocus?: (event: Event) => void;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -25,8 +25,8 @@ const RovingFocus = forwardRef<HTMLDivElement, RovingFocusProps>(
|
|
|
25
25
|
onMouseDown,
|
|
26
26
|
onFocus,
|
|
27
27
|
...rest
|
|
28
|
-
}
|
|
29
|
-
ref
|
|
28
|
+
},
|
|
29
|
+
ref: React.Ref<HTMLDivElement>,
|
|
30
30
|
) => {
|
|
31
31
|
const _ref = React.useRef<HTMLDivElement>(null);
|
|
32
32
|
const composedRefs = useMergeRefs(ref, _ref);
|
|
@@ -55,19 +55,19 @@ const RovingFocus = forwardRef<HTMLDivElement, RovingFocusProps>(
|
|
|
55
55
|
|
|
56
56
|
const nextItem = () => {
|
|
57
57
|
const next = descendants.nextEnabled(idx, loop);
|
|
58
|
-
next
|
|
58
|
+
next?.node?.focus();
|
|
59
59
|
};
|
|
60
60
|
const prevItem = () => {
|
|
61
61
|
const prev = descendants.prevEnabled(idx, loop);
|
|
62
|
-
prev
|
|
62
|
+
prev?.node?.focus();
|
|
63
63
|
};
|
|
64
64
|
const firstItem = () => {
|
|
65
65
|
const first = descendants.firstEnabled();
|
|
66
|
-
first
|
|
66
|
+
first?.node?.focus();
|
|
67
67
|
};
|
|
68
68
|
const lastItem = () => {
|
|
69
69
|
const last = descendants.lastEnabled();
|
|
70
|
-
last
|
|
70
|
+
last?.node?.focus();
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
const keyMap: Record<string, React.KeyboardEventHandler> = {
|
|
@@ -69,7 +69,10 @@ export const getSteps = ({
|
|
|
69
69
|
count,
|
|
70
70
|
boundaryCount = 1,
|
|
71
71
|
siblingCount = 1,
|
|
72
|
-
}
|
|
72
|
+
}: Pick<
|
|
73
|
+
PaginationProps,
|
|
74
|
+
"page" | "count" | "boundaryCount" | "siblingCount"
|
|
75
|
+
>) => {
|
|
73
76
|
const range = (start: number, end: number) =>
|
|
74
77
|
Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
75
78
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import faker from "faker";
|
|
2
1
|
import { describe, expect, test } from "vitest";
|
|
3
2
|
import { getSteps } from "./Pagination";
|
|
4
3
|
|
|
5
4
|
describe("getSteps", () => {
|
|
6
5
|
test("lists all pages when count is <= 7", () => {
|
|
7
|
-
const count =
|
|
6
|
+
const count = 5;
|
|
8
7
|
expect(getSteps({ page: 1, count })).toEqual(
|
|
9
8
|
Array.from({ length: count }, (_, i) => i + 1),
|
|
10
9
|
);
|
|
11
10
|
});
|
|
12
11
|
|
|
13
12
|
test("has an end ellipsis when count >= 8", () => {
|
|
14
|
-
const count =
|
|
15
|
-
const page =
|
|
13
|
+
const count = 8;
|
|
14
|
+
const page = 3;
|
|
16
15
|
expect(
|
|
17
16
|
getSteps({
|
|
18
17
|
page,
|
|
@@ -22,8 +21,8 @@ describe("getSteps", () => {
|
|
|
22
21
|
});
|
|
23
22
|
|
|
24
23
|
test("has a start ellipsis when count - page >= 3", () => {
|
|
25
|
-
const count =
|
|
26
|
-
const page =
|
|
24
|
+
const count = 8;
|
|
25
|
+
const page = 5;
|
|
27
26
|
expect(
|
|
28
27
|
getSteps({
|
|
29
28
|
page,
|
|
@@ -41,8 +40,8 @@ describe("getSteps", () => {
|
|
|
41
40
|
});
|
|
42
41
|
|
|
43
42
|
test("has start & end ellipsis when count is high", () => {
|
|
44
|
-
const count =
|
|
45
|
-
const page =
|
|
43
|
+
const count = 9;
|
|
44
|
+
const page = 5;
|
|
46
45
|
expect(
|
|
47
46
|
getSteps({
|
|
48
47
|
page,
|
|
@@ -52,8 +51,8 @@ describe("getSteps", () => {
|
|
|
52
51
|
});
|
|
53
52
|
|
|
54
53
|
test("can have a reduced siblingCount", () => {
|
|
55
|
-
const count =
|
|
56
|
-
const page =
|
|
54
|
+
const count = 7;
|
|
55
|
+
const page = 4;
|
|
57
56
|
expect(
|
|
58
57
|
getSteps({
|
|
59
58
|
page,
|
|
@@ -64,8 +63,8 @@ describe("getSteps", () => {
|
|
|
64
63
|
});
|
|
65
64
|
|
|
66
65
|
test("can have an increased siblingCount", () => {
|
|
67
|
-
const count =
|
|
68
|
-
const page =
|
|
66
|
+
const count = 11;
|
|
67
|
+
const page = 6;
|
|
69
68
|
expect(
|
|
70
69
|
getSteps({
|
|
71
70
|
page,
|
|
@@ -86,8 +85,8 @@ describe("getSteps", () => {
|
|
|
86
85
|
});
|
|
87
86
|
|
|
88
87
|
test("can have an reduced boundaryCount", () => {
|
|
89
|
-
const count =
|
|
90
|
-
const page =
|
|
88
|
+
const count = 7;
|
|
89
|
+
const page = 4;
|
|
91
90
|
expect(
|
|
92
91
|
getSteps({
|
|
93
92
|
page,
|
|
@@ -98,8 +97,8 @@ describe("getSteps", () => {
|
|
|
98
97
|
});
|
|
99
98
|
|
|
100
99
|
test("can have an increased boundaryCount", () => {
|
|
101
|
-
const count =
|
|
102
|
-
const page =
|
|
100
|
+
const count = 11;
|
|
101
|
+
const page = 6;
|
|
103
102
|
expect(
|
|
104
103
|
getSteps({
|
|
105
104
|
page,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { createContext, useContext } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { PartialTranslations } from "../../util/i18n/i18n.types";
|
|
3
3
|
import nb from "../../util/i18n/locales/nb";
|
|
4
4
|
|
|
5
5
|
export interface LanguageProviderContextType {
|
|
6
6
|
/**
|
|
7
7
|
* Merged with the default language translations object (officially provided translations).
|
|
8
8
|
*/
|
|
9
|
-
translations:
|
|
9
|
+
translations: PartialTranslations | PartialTranslations[];
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const LanguageProviderContext =
|
|
@@ -16,7 +16,7 @@ export const LanguageProviderContext =
|
|
|
16
16
|
|
|
17
17
|
export interface LanguageProviderProps {
|
|
18
18
|
children?: React.ReactNode;
|
|
19
|
-
translations?:
|
|
19
|
+
translations?: PartialTranslations | PartialTranslations[];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const useProvider = () => useContext(LanguageProviderContext);
|
package/src/table/Body.tsx
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import cl from "clsx";
|
|
2
2
|
import React, { forwardRef } from "react";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
extends React.HTMLAttributes<HTMLTableSectionElement> {}
|
|
4
|
+
export type BodyProps = React.HTMLAttributes<HTMLTableSectionElement>;
|
|
6
5
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
> {}
|
|
6
|
+
export type BodyType = React.ForwardRefExoticComponent<
|
|
7
|
+
BodyProps & React.RefAttributes<HTMLTableSectionElement>
|
|
8
|
+
>;
|
|
11
9
|
|
|
12
10
|
export const Body: BodyType = forwardRef(({ className, ...rest }, ref) => (
|
|
13
11
|
<tbody {...rest} ref={ref} className={cl("navds-table__body", className)} />
|
|
@@ -19,10 +19,9 @@ export interface ColumnHeaderProps extends HeaderCellProps {
|
|
|
19
19
|
sortable?: boolean;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
> {}
|
|
22
|
+
export type ColumnHeaderType = React.ForwardRefExoticComponent<
|
|
23
|
+
ColumnHeaderProps & React.RefAttributes<HTMLTableCellElement>
|
|
24
|
+
>;
|
|
26
25
|
|
|
27
26
|
export const ColumnHeader: ColumnHeaderType = forwardRef(
|
|
28
27
|
({ className, children, sortable = false, sortKey, ...rest }, ref) => {
|
|
@@ -49,10 +49,9 @@ export interface ExpandableRowProps extends Omit<RowProps, "content"> {
|
|
|
49
49
|
colSpan?: number;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
> {}
|
|
52
|
+
export type ExpandableRowType = React.ForwardRefExoticComponent<
|
|
53
|
+
ExpandableRowProps & React.RefAttributes<HTMLTableRowElement>
|
|
54
|
+
>;
|
|
56
55
|
|
|
57
56
|
export const ExpandableRow: ExpandableRowType = forwardRef(
|
|
58
57
|
(
|
package/src/table/Header.tsx
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import cl from "clsx";
|
|
2
2
|
import React, { forwardRef } from "react";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
extends React.HTMLAttributes<HTMLTableSectionElement> {}
|
|
4
|
+
export type HeaderProps = React.HTMLAttributes<HTMLTableSectionElement>;
|
|
6
5
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
> {}
|
|
6
|
+
export type HeaderType = React.ForwardRefExoticComponent<
|
|
7
|
+
HeaderProps & React.RefAttributes<HTMLTableSectionElement>
|
|
8
|
+
>;
|
|
11
9
|
|
|
12
10
|
export const Header: HeaderType = forwardRef(({ className, ...rest }, ref) => (
|
|
13
11
|
<thead {...rest} ref={ref} className={cl("navds-table__header", className)} />
|
package/src/table/HeaderCell.tsx
CHANGED
|
@@ -15,10 +15,9 @@ export interface HeaderCellProps
|
|
|
15
15
|
textSize?: "medium" | "small";
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
> {}
|
|
18
|
+
export type HeaderCellType = React.ForwardRefExoticComponent<
|
|
19
|
+
HeaderCellProps & React.RefAttributes<HTMLTableCellElement>
|
|
20
|
+
>;
|
|
22
21
|
|
|
23
22
|
export const HeaderCell: HeaderCellType = forwardRef(
|
|
24
23
|
({ className, children, align, textSize, ...rest }, ref) => {
|
package/src/table/Row.tsx
CHANGED
|
@@ -14,10 +14,9 @@ export interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
|
|
14
14
|
shadeOnHover?: boolean;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
> {}
|
|
17
|
+
export type RowType = React.ForwardRefExoticComponent<
|
|
18
|
+
RowProps & React.RefAttributes<HTMLTableRowElement>
|
|
19
|
+
>;
|
|
21
20
|
|
|
22
21
|
export const Row: RowType = forwardRef(
|
|
23
22
|
({ className, selected = false, shadeOnHover = true, ...rest }, ref) => (
|
|
@@ -41,7 +41,7 @@ export function useScrollButtons(listRef: React.RefObject<HTMLDivElement>) {
|
|
|
41
41
|
|
|
42
42
|
return () => {
|
|
43
43
|
win.removeEventListener("resize", handleResize);
|
|
44
|
-
resizeObserver
|
|
44
|
+
resizeObserver?.disconnect();
|
|
45
45
|
updateScrollButtonState.clear();
|
|
46
46
|
};
|
|
47
47
|
}, [listRef, updateScrollButtonState]);
|
|
@@ -26,19 +26,19 @@ export function useTabList() {
|
|
|
26
26
|
|
|
27
27
|
const nextTab = () => {
|
|
28
28
|
const next = descendants.nextEnabled(idx, loop);
|
|
29
|
-
next
|
|
29
|
+
next?.node?.focus();
|
|
30
30
|
};
|
|
31
31
|
const prevTab = () => {
|
|
32
32
|
const prev = descendants.prevEnabled(idx, loop);
|
|
33
|
-
prev
|
|
33
|
+
prev?.node?.focus();
|
|
34
34
|
};
|
|
35
35
|
const firstTab = () => {
|
|
36
36
|
const first = descendants.firstEnabled();
|
|
37
|
-
first
|
|
37
|
+
first?.node?.focus();
|
|
38
38
|
};
|
|
39
39
|
const lastTab = () => {
|
|
40
40
|
const last = descendants.lastEnabled();
|
|
41
|
-
last
|
|
41
|
+
last?.node?.focus();
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
const keyMap: Record<string, React.KeyboardEventHandler> = {
|
|
@@ -91,27 +91,26 @@ export const TimelineRow = forwardRef<HTMLOListElement, TimelineRowProps>(
|
|
|
91
91
|
}
|
|
92
92
|
}}
|
|
93
93
|
>
|
|
94
|
-
{periods
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
})}
|
|
94
|
+
{periods?.map((period) => {
|
|
95
|
+
return (
|
|
96
|
+
<li key={`period-${period.id}`}>
|
|
97
|
+
<PeriodContext.Provider
|
|
98
|
+
value={{
|
|
99
|
+
periodId: period.id,
|
|
100
|
+
firstFocus: firstFocusable?.id === period.id,
|
|
101
|
+
restProps: period?.restProps,
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
<Period
|
|
105
|
+
start={period.start}
|
|
106
|
+
end={period.endInclusive}
|
|
107
|
+
icon={period.icon}
|
|
108
|
+
ref={period?.ref}
|
|
109
|
+
/>
|
|
110
|
+
</PeriodContext.Provider>
|
|
111
|
+
</li>
|
|
112
|
+
);
|
|
113
|
+
})}
|
|
115
114
|
</ol>
|
|
116
115
|
</div>
|
|
117
116
|
</>
|
|
@@ -55,19 +55,19 @@ export function useToggleItem<P extends UseToggleItemProps>(
|
|
|
55
55
|
|
|
56
56
|
const nextTab = () => {
|
|
57
57
|
const next = descendants.nextEnabled(idx, false);
|
|
58
|
-
next
|
|
58
|
+
next?.node?.focus();
|
|
59
59
|
};
|
|
60
60
|
const prevTab = () => {
|
|
61
61
|
const prev = descendants.prevEnabled(idx, false);
|
|
62
|
-
prev
|
|
62
|
+
prev?.node?.focus();
|
|
63
63
|
};
|
|
64
64
|
const firstTab = () => {
|
|
65
65
|
const first = descendants.firstEnabled();
|
|
66
|
-
first
|
|
66
|
+
first?.node?.focus();
|
|
67
67
|
};
|
|
68
68
|
const lastTab = () => {
|
|
69
69
|
const last = descendants.lastEnabled();
|
|
70
|
-
last
|
|
70
|
+
last?.node?.focus();
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
const keyMap: Record<string, React.KeyboardEventHandler> = {
|
|
@@ -40,7 +40,7 @@ const checkState = (
|
|
|
40
40
|
* https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerWindow/ownerWindow.ts
|
|
41
41
|
*/
|
|
42
42
|
const ownerWindow = (node: Node | undefined): Window => {
|
|
43
|
-
const doc =
|
|
43
|
+
const doc = node?.ownerDocument || document;
|
|
44
44
|
return doc.defaultView || window;
|
|
45
45
|
};
|
|
46
46
|
|
|
@@ -223,7 +223,7 @@ const TextareaAutosize = forwardRef<HTMLTextAreaElement, TextareaAutosizeProps>(
|
|
|
223
223
|
};
|
|
224
224
|
|
|
225
225
|
const mainStyle: React.CSSProperties = {
|
|
226
|
-
|
|
226
|
+
"--__ac-textarea-height": state.outerHeightStyle + "px",
|
|
227
227
|
// Need a large enough difference to allow scrolling.
|
|
228
228
|
// This prevents infinite rendering loop.
|
|
229
229
|
overflow:
|
|
@@ -60,7 +60,7 @@ export class DescendantsManager<
|
|
|
60
60
|
this.descendants.forEach((descendant) => {
|
|
61
61
|
const index = descendants.indexOf(descendant.node);
|
|
62
62
|
descendant.index = index;
|
|
63
|
-
descendant.node.dataset
|
|
63
|
+
descendant.node.dataset.index = descendant.index.toString();
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
66
|
|
|
@@ -52,7 +52,7 @@ export function createDescendantContext<
|
|
|
52
52
|
|
|
53
53
|
useClientLayoutEffect(() => {
|
|
54
54
|
if (!ref.current) return;
|
|
55
|
-
const dataIndex = Number(ref.current.dataset
|
|
55
|
+
const dataIndex = Number(ref.current.dataset.index);
|
|
56
56
|
if (index !== dataIndex && !Number.isNaN(dataIndex)) {
|
|
57
57
|
setIndex(dataIndex);
|
|
58
58
|
}
|
package/src/util/i18n/get.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PartialTranslations } from "./i18n.types";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* https://github.com/Shopify/polaris/blob/main/polaris-react/src/utilities/get.ts#L3
|
|
@@ -7,7 +7,7 @@ const OBJECT_NOTATION_MATCHER = /(\w+)/g;
|
|
|
7
7
|
|
|
8
8
|
export function get(
|
|
9
9
|
keypath: string | string[],
|
|
10
|
-
...objs: (
|
|
10
|
+
...objs: (PartialTranslations | undefined)[]
|
|
11
11
|
) {
|
|
12
12
|
const keys = Array.isArray(keypath) ? keypath : getKeypath(keypath);
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ export function get(
|
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
let acc: string |
|
|
19
|
+
let acc: string | PartialTranslations = obj;
|
|
20
20
|
|
|
21
21
|
for (let i = 0; i < keys.length; i++) {
|
|
22
22
|
const val = acc[keys[i]];
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
2
|
import { LanguageProviderContext } from "../../provider/i18n/LanguageProvider";
|
|
3
3
|
import { get } from "./get";
|
|
4
|
-
import { Component, ComponentTranslation } from "./i18n.types";
|
|
5
|
-
import nb from "./locales/nb";
|
|
4
|
+
import { Component, ComponentTranslation, Translations } from "./i18n.types";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* https://regex101.com/r/LYKWi3/1
|
|
@@ -27,7 +26,7 @@ export function useI18n<T extends Component>(
|
|
|
27
26
|
* https://github.com/Shopify/polaris/blob/2115f9ba2f5bcbf2ad15745233501bff2db81ecf/polaris-react/src/utilities/i18n/I18n.ts#L24
|
|
28
27
|
*/
|
|
29
28
|
const translate = (
|
|
30
|
-
keypath: NestedKeyOf<
|
|
29
|
+
keypath: NestedKeyOf<Translations[T]>,
|
|
31
30
|
options?: { replacements: Record<string, string | number> },
|
|
32
31
|
) => {
|
|
33
32
|
const text = get(
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import nb from "./locales/nb";
|
|
2
|
-
|
|
3
|
-
export interface TranslationObject {
|
|
4
|
-
[key: string]: string | TranslationObject | undefined;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface TranslationDictionary {
|
|
8
|
-
[key: string]: TranslationObject | undefined;
|
|
9
|
-
}
|
|
1
|
+
import type nb from "./locales/nb";
|
|
10
2
|
|
|
11
3
|
/* https://stackoverflow.com/questions/47914536/use-partial-in-nested-property-with-typescripts */
|
|
12
4
|
type RecursivePartial<T> = {
|
|
13
5
|
[P in keyof T]?: RecursivePartial<T[P]>;
|
|
14
6
|
};
|
|
15
7
|
|
|
16
|
-
export type
|
|
8
|
+
export type Translations = typeof nb;
|
|
9
|
+
|
|
10
|
+
export type PartialTranslations = RecursivePartial<Translations>;
|
|
11
|
+
|
|
12
|
+
export type Component = keyof Translations;
|
|
17
13
|
|
|
18
14
|
export type ComponentTranslation<T extends Component> = RecursivePartial<
|
|
19
|
-
|
|
15
|
+
Translations[T]
|
|
20
16
|
>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Translations } from "../i18n.types";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
FileUpload: {
|
|
5
|
+
dropzone: {
|
|
6
|
+
button: "Choose file",
|
|
7
|
+
buttonMultiple: "Choose files",
|
|
8
|
+
dragAndDrop: "Drag and drop file here",
|
|
9
|
+
dragAndDropMultiple: "Drag and drop files here",
|
|
10
|
+
drop: "Drop",
|
|
11
|
+
or: "or",
|
|
12
|
+
disabled: "File upload disabled",
|
|
13
|
+
disabledFilelimit: "You cannot upload more files",
|
|
14
|
+
},
|
|
15
|
+
item: {
|
|
16
|
+
retryButtonTitle: "Try uploading the file again",
|
|
17
|
+
deleteButtonTitle: "Delete file",
|
|
18
|
+
uploading: "Uploading…",
|
|
19
|
+
downloading: "Downloading…",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
FormProgress: {
|
|
23
|
+
step: "Step {activeStep} of {totalSteps}",
|
|
24
|
+
showAllSteps: "Show all steps",
|
|
25
|
+
hideAllSteps: "Hide all steps",
|
|
26
|
+
},
|
|
27
|
+
Alert: {
|
|
28
|
+
closeAlert: "Close alert",
|
|
29
|
+
closeMessage: "Close message",
|
|
30
|
+
error: "Error",
|
|
31
|
+
info: "Information",
|
|
32
|
+
success: "Success",
|
|
33
|
+
warning: "Warning",
|
|
34
|
+
},
|
|
35
|
+
Chips: {
|
|
36
|
+
Removable: {
|
|
37
|
+
labelSuffix: "delete",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
} satisfies Translations;
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
interface TranslationMap {
|
|
2
|
+
[component: string]:
|
|
3
|
+
| Record<string, string>
|
|
4
|
+
| {
|
|
5
|
+
[subComponent: string]: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
|
|
1
9
|
export default {
|
|
2
10
|
FileUpload: {
|
|
3
11
|
dropzone: {
|
|
@@ -22,4 +30,18 @@ export default {
|
|
|
22
30
|
showAllSteps: "Vis alle steg",
|
|
23
31
|
hideAllSteps: "Skjul alle steg",
|
|
24
32
|
},
|
|
25
|
-
|
|
33
|
+
Alert: {
|
|
34
|
+
closeAlert: "Lukk varsel",
|
|
35
|
+
closeMessage: "Lukk melding",
|
|
36
|
+
error: "Feil",
|
|
37
|
+
info: "Informasjon",
|
|
38
|
+
success: "Suksess",
|
|
39
|
+
warning: "Advarsel",
|
|
40
|
+
},
|
|
41
|
+
Chips: {
|
|
42
|
+
Removable: {
|
|
43
|
+
/** Will be appended to the accessible name for the button. */
|
|
44
|
+
labelSuffix: "slett",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
} satisfies TranslationMap;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Translations } from "../i18n.types";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
FileUpload: {
|
|
5
|
+
dropzone: {
|
|
6
|
+
button: "Vel fil",
|
|
7
|
+
buttonMultiple: "Vel filer",
|
|
8
|
+
dragAndDrop: "Dra og slepp fila her",
|
|
9
|
+
dragAndDropMultiple: "Dra og slepp filer her",
|
|
10
|
+
drop: "Slepp",
|
|
11
|
+
or: "eller",
|
|
12
|
+
disabled: "Filopplasting er deaktivert",
|
|
13
|
+
disabledFilelimit: "Du kan ikkje laste opp fleire filer",
|
|
14
|
+
},
|
|
15
|
+
item: {
|
|
16
|
+
retryButtonTitle: "Prøv å laste opp fila på nytt",
|
|
17
|
+
deleteButtonTitle: "Slett fila",
|
|
18
|
+
uploading: "Lastar opp…",
|
|
19
|
+
downloading: "Lastar ned…",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
FormProgress: {
|
|
23
|
+
step: "Steg {activeStep} av {totalSteps}",
|
|
24
|
+
showAllSteps: "Vis alle steg",
|
|
25
|
+
hideAllSteps: "Skjul alle steg",
|
|
26
|
+
},
|
|
27
|
+
Alert: {
|
|
28
|
+
closeAlert: "Lukk varsel",
|
|
29
|
+
closeMessage: "Lukk melding",
|
|
30
|
+
error: "Feil",
|
|
31
|
+
info: "Informasjon",
|
|
32
|
+
success: "Suksess",
|
|
33
|
+
warning: "Åtvaring",
|
|
34
|
+
},
|
|
35
|
+
Chips: {
|
|
36
|
+
Removable: {
|
|
37
|
+
labelSuffix: "slett",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
} satisfies Translations;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable @vitest/expect-expect */
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { Translations } from "./i18n.types";
|
|
4
|
+
import en from "./locales/en";
|
|
5
|
+
import nb from "./locales/nb";
|
|
6
|
+
import nn from "./locales/nn";
|
|
7
|
+
|
|
8
|
+
function checkValues(obj: Translations | Record<string, string>) {
|
|
9
|
+
Object.values(obj).forEach((value) => {
|
|
10
|
+
if (typeof value === "object") {
|
|
11
|
+
checkValues(value);
|
|
12
|
+
} else {
|
|
13
|
+
expect(value).toBeTypeOf("string");
|
|
14
|
+
expect(value).not.toBe("");
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("Locale", () => {
|
|
20
|
+
test("NB should have no empty strings", () => checkValues(nb));
|
|
21
|
+
test("NN should have no empty strings", () => checkValues(nn));
|
|
22
|
+
test("EN should have no empty strings", () => checkValues(en));
|
|
23
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export const requireReactElement = <T extends React.ReactNode>(
|
|
4
|
+
children: T,
|
|
5
|
+
): T => {
|
|
6
|
+
const isReactElement = React.isValidElement(children);
|
|
7
|
+
|
|
8
|
+
if (!isReactElement) {
|
|
9
|
+
throw Error(
|
|
10
|
+
`Expected a single React Element child, but got: ${React.Children.toArray(
|
|
11
|
+
children,
|
|
12
|
+
)
|
|
13
|
+
.map((child) =>
|
|
14
|
+
typeof child === "object" &&
|
|
15
|
+
"type" in child &&
|
|
16
|
+
typeof child.type === "string"
|
|
17
|
+
? child.type
|
|
18
|
+
: typeof child,
|
|
19
|
+
)
|
|
20
|
+
.join(", ")}`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return children;
|
|
25
|
+
};
|