@simplysm/solid 13.0.72 → 13.0.74
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/README.md +209 -202
- package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
- package/dist/components/data/calendar/Calendar.js +3 -11
- package/dist/components/data/calendar/Calendar.js.map +2 -2
- package/dist/components/data/sheet/DataSheet.js +10 -10
- package/dist/components/data/sheet/DataSheet.js.map +2 -2
- package/dist/components/data/sheet/DataSheetConfigDialog.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheetConfigDialog.js +27 -9
- package/dist/components/data/sheet/DataSheetConfigDialog.js.map +2 -2
- package/dist/components/disclosure/Dialog.d.ts +1 -1
- package/dist/components/disclosure/Dialog.d.ts.map +1 -1
- package/dist/components/disclosure/Dialog.js +5 -5
- package/dist/components/disclosure/Dialog.js.map +2 -2
- package/dist/components/disclosure/dialogZIndex.d.ts +1 -1
- package/dist/components/features/crud-detail/CrudDetail.js +23 -23
- package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
- package/dist/components/features/crud-sheet/CrudSheet.js +49 -49
- package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
- package/dist/components/features/crud-sheet/types.d.ts +4 -4
- package/dist/components/features/crud-sheet/types.d.ts.map +1 -1
- package/dist/components/features/data-select-button/DataSelectButton.d.ts +25 -7
- package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
- package/dist/components/features/data-select-button/DataSelectButton.js +27 -12
- package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
- package/dist/components/features/permission-table/PermissionTable.js +4 -4
- package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelect.d.ts +22 -10
- package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelect.js +113 -29
- package/dist/components/features/shared-data/SharedDataSelect.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +3 -3
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectButton.js.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectList.js +5 -4
- package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
- package/dist/components/feedback/notification/NotificationBanner.js +3 -3
- package/dist/components/feedback/notification/NotificationBanner.js.map +2 -2
- package/dist/components/feedback/notification/NotificationBell.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationBell.js +12 -5
- package/dist/components/feedback/notification/NotificationBell.js.map +2 -2
- package/dist/components/feedback/notification/NotificationProvider.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationProvider.js +3 -1
- package/dist/components/feedback/notification/NotificationProvider.js.map +2 -2
- package/dist/components/form-control/ThemeToggle.d.ts.map +1 -1
- package/dist/components/form-control/ThemeToggle.js +9 -6
- package/dist/components/form-control/ThemeToggle.js.map +2 -2
- package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Checkbox.js +3 -1
- package/dist/components/form-control/checkbox/Checkbox.js.map +2 -2
- package/dist/components/form-control/checkbox/CheckboxGroup.js +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.js.map +2 -2
- package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Radio.js +3 -1
- package/dist/components/form-control/checkbox/Radio.js.map +2 -2
- package/dist/components/form-control/checkbox/RadioGroup.js +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.js.map +2 -2
- package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
- package/dist/components/form-control/color-picker/ColorPicker.js +3 -1
- package/dist/components/form-control/color-picker/ColorPicker.js.map +2 -2
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/Combobox.js +9 -5
- package/dist/components/form-control/combobox/Combobox.js.map +2 -2
- package/dist/components/form-control/date-range-picker/DateRangePicker.js +9 -9
- package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
- package/dist/components/form-control/editor/EditorToolbar.js +3 -3
- package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
- package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DatePicker.js +9 -3
- package/dist/components/form-control/field/DatePicker.js.map +2 -2
- package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.js +9 -3
- package/dist/components/form-control/field/DateTimePicker.js.map +2 -2
- package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.js +9 -3
- package/dist/components/form-control/field/NumberInput.js.map +2 -2
- package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
- package/dist/components/form-control/field/TextInput.js +10 -4
- package/dist/components/form-control/field/TextInput.js.map +2 -2
- package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
- package/dist/components/form-control/field/Textarea.js +9 -3
- package/dist/components/form-control/field/Textarea.js.map +2 -2
- package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/TimePicker.js +9 -3
- package/dist/components/form-control/field/TimePicker.js.map +2 -2
- package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
- package/dist/components/form-control/numpad/Numpad.js +5 -1
- package/dist/components/form-control/numpad/Numpad.js.map +2 -2
- package/dist/components/form-control/select/Select.js +7 -7
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
- package/dist/components/form-control/state-preset/StatePreset.js +42 -20
- package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
- package/dist/components/layout/sidebar/SidebarContainer.js +3 -3
- package/dist/components/layout/sidebar/SidebarContainer.js.map +2 -2
- package/dist/components/layout/sidebar/SidebarMenu.d.ts.map +1 -1
- package/dist/components/layout/sidebar/SidebarMenu.js +5 -2
- package/dist/components/layout/sidebar/SidebarMenu.js.map +2 -2
- package/dist/components/layout/topbar/Topbar.js +3 -4
- package/dist/components/layout/topbar/Topbar.js.map +2 -2
- package/dist/components/layout/topbar/TopbarMenu.js +3 -3
- package/dist/components/layout/topbar/TopbarMenu.js.map +2 -2
- package/dist/hooks/createSelectionGroup.d.ts +2 -2
- package/dist/hooks/createSelectionGroup.d.ts.map +1 -1
- package/dist/hooks/createSelectionGroup.js +5 -2
- package/dist/hooks/createSelectionGroup.js.map +2 -2
- package/dist/providers/i18n/I18nContext.d.ts +0 -4
- package/dist/providers/i18n/I18nContext.d.ts.map +1 -1
- package/dist/providers/i18n/I18nContext.js +1 -5
- package/dist/providers/i18n/I18nContext.js.map +2 -2
- package/dist/providers/i18n/locales/en.d.ts +38 -0
- package/dist/providers/i18n/locales/en.d.ts.map +1 -1
- package/dist/providers/i18n/locales/en.js +39 -1
- package/dist/providers/i18n/locales/en.js.map +1 -1
- package/dist/providers/i18n/locales/ko.d.ts +38 -0
- package/dist/providers/i18n/locales/ko.d.ts.map +1 -1
- package/dist/providers/i18n/locales/ko.js +39 -1
- package/dist/providers/i18n/locales/ko.js.map +1 -1
- package/package.json +6 -6
- package/src/components/data/calendar/Calendar.tsx +3 -4
- package/src/components/data/sheet/DataSheet.tsx +11 -11
- package/src/components/data/sheet/DataSheetConfigDialog.tsx +12 -10
- package/src/components/data/sheet/types.ts +1 -1
- package/src/components/disclosure/Dialog.tsx +10 -10
- package/src/components/disclosure/dialogZIndex.ts +1 -1
- package/src/components/features/crud-detail/CrudDetail.tsx +25 -25
- package/src/components/features/crud-sheet/CrudSheet.tsx +53 -53
- package/src/components/features/crud-sheet/types.ts +4 -4
- package/src/components/features/data-select-button/DataSelectButton.tsx +51 -21
- package/src/components/features/permission-table/PermissionTable.tsx +3 -3
- package/src/components/features/shared-data/SharedDataSelect.tsx +172 -33
- package/src/components/features/shared-data/SharedDataSelectButton.tsx +3 -2
- package/src/components/features/shared-data/SharedDataSelectList.tsx +4 -4
- package/src/components/feedback/notification/NotificationBanner.tsx +3 -3
- package/src/components/feedback/notification/NotificationBell.tsx +6 -4
- package/src/components/feedback/notification/NotificationProvider.tsx +3 -1
- package/src/components/form-control/ThemeToggle.tsx +10 -6
- package/src/components/form-control/checkbox/Checkbox.tsx +4 -1
- package/src/components/form-control/checkbox/CheckboxGroup.tsx +1 -1
- package/src/components/form-control/checkbox/Radio.tsx +4 -1
- package/src/components/form-control/checkbox/RadioGroup.tsx +1 -1
- package/src/components/form-control/color-picker/ColorPicker.tsx +4 -1
- package/src/components/form-control/combobox/Combobox.tsx +6 -3
- package/src/components/form-control/date-range-picker/DateRangePicker.tsx +8 -8
- package/src/components/form-control/editor/EditorToolbar.tsx +23 -23
- package/src/components/form-control/field/DatePicker.tsx +6 -3
- package/src/components/form-control/field/DateTimePicker.tsx +6 -3
- package/src/components/form-control/field/NumberInput.tsx +6 -3
- package/src/components/form-control/field/TextInput.tsx +7 -4
- package/src/components/form-control/field/Textarea.tsx +6 -3
- package/src/components/form-control/field/TimePicker.tsx +6 -3
- package/src/components/form-control/numpad/Numpad.tsx +3 -1
- package/src/components/form-control/select/Select.tsx +7 -7
- package/src/components/form-control/state-preset/StatePreset.tsx +14 -12
- package/src/components/layout/sidebar/SidebarContainer.tsx +3 -3
- package/src/components/layout/sidebar/SidebarMenu.tsx +3 -1
- package/src/components/layout/topbar/Topbar.tsx +3 -3
- package/src/components/layout/topbar/TopbarMenu.tsx +3 -3
- package/src/hooks/createSelectionGroup.tsx +8 -4
- package/src/providers/i18n/I18nContext.tsx +0 -7
- package/src/providers/i18n/locales/en.ts +38 -0
- package/src/providers/i18n/locales/ko.ts +38 -0
- package/tailwind.config.ts +2 -2
- package/tests/components/data/kanban/Kanban.selection.spec.tsx +34 -24
- package/tests/components/disclosure/Dialog.spec.tsx +28 -28
- package/tests/components/disclosure/DialogProvider.spec.tsx +51 -25
- package/tests/components/features/address/AddressSearch.spec.tsx +12 -4
- package/tests/components/features/crud-detail/CrudDetail.spec.tsx +1 -0
- package/tests/components/features/crud-sheet/CrudSheet.spec.tsx +30 -6
- package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +77 -56
- package/tests/components/features/permission-table/PermissionTable.spec.tsx +12 -8
- package/tests/components/features/shared-data/SharedDataSelect.spec.tsx +172 -0
- package/tests/components/features/shared-data/SharedDataSelectList.spec.tsx +14 -2
- package/tests/components/feedback/notification/LiveRegion.spec.tsx +20 -9
- package/tests/components/feedback/notification/NotificationBanner.spec.tsx +64 -46
- package/tests/components/feedback/notification/NotificationBell.spec.tsx +70 -51
- package/tests/components/feedback/notification/NotificationContext.spec.tsx +105 -78
- package/tests/components/form-control/checkbox/Checkbox.spec.tsx +25 -20
- package/tests/components/form-control/checkbox/CheckboxGroup.spec.tsx +53 -30
- package/tests/components/form-control/checkbox/Radio.spec.tsx +25 -20
- package/tests/components/form-control/checkbox/RadioGroup.spec.tsx +53 -30
- package/tests/components/form-control/color-picker/ColorPicker.spec.tsx +24 -15
- package/tests/components/form-control/combobox/Combobox.spec.tsx +92 -59
- package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +2 -2
- package/tests/components/form-control/field/DatePicker.spec.tsx +50 -44
- package/tests/components/form-control/field/DateTimePicker.spec.tsx +51 -45
- package/tests/components/form-control/field/NumberInput.spec.tsx +53 -47
- package/tests/components/form-control/field/TextInput.spec.tsx +50 -44
- package/tests/components/form-control/field/Textarea.spec.tsx +35 -29
- package/tests/components/form-control/field/TimePicker.spec.tsx +43 -37
- package/tests/components/form-control/numpad/Numpad.spec.tsx +175 -25
- package/tests/components/form-control/select/Select.spec.tsx +5 -0
- package/tests/components/form-control/select/SelectItem.spec.tsx +1 -0
- package/tests/components/layout/sidebar/Sidebar.spec.tsx +79 -35
- package/tests/components/layout/sidebar/SidebarContainer.spec.tsx +1 -0
- package/tests/components/layout/sidebar/SidebarMenu.spec.tsx +28 -17
- package/tests/components/layout/topbar/TopbarActions.spec.tsx +41 -23
- package/tests/components/layout/topbar/createTopbarActions.spec.tsx +1 -0
- package/tests/hooks/usePrint.spec.tsx +1 -1
- package/tests/hooks/useRouterLink.spec.tsx +2 -0
- package/tests/hooks/useSyncConfig.spec.tsx +1 -0
- package/tests/providers/ErrorLoggerProvider.spec.tsx +1 -0
- package/tests/providers/PwaUpdateProvider.spec.tsx +16 -6
- package/tests/providers/ServiceClientContext.spec.tsx +40 -25
- package/tests/providers/i18n/I18nContext.spec.tsx +3 -4
- package/tests/providers/shared-data/SharedDataProvider.spec.tsx +2 -0
- package/dist/hooks/usePrint.d.ts +0 -3
- package/dist/hooks/usePrint.d.ts.map +0 -1
- package/dist/hooks/usePrint.js +0 -5
- package/dist/hooks/usePrint.js.map +0 -6
- package/src/hooks/usePrint.ts +0 -2
|
@@ -1,20 +1,79 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
children as resolveChildren,
|
|
3
|
+
type Component,
|
|
4
|
+
createMemo,
|
|
5
|
+
For,
|
|
6
|
+
type JSX,
|
|
7
|
+
mergeProps,
|
|
8
|
+
splitProps,
|
|
9
|
+
} from "solid-js";
|
|
10
|
+
import { IconSearch } from "@tabler/icons-solidjs";
|
|
3
11
|
import { type SharedDataAccessor } from "../../../providers/shared-data/SharedDataContext";
|
|
4
12
|
import { Select, type SelectProps } from "../../form-control/select/Select";
|
|
5
13
|
import { Icon } from "../../display/Icon";
|
|
6
14
|
import { useDialog } from "../../disclosure/DialogContext";
|
|
7
|
-
import {
|
|
15
|
+
import { useDialogInstance } from "../../disclosure/DialogInstanceContext";
|
|
16
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
8
17
|
import { type ComponentSize } from "../../../styles/tokens.styles";
|
|
18
|
+
import {
|
|
19
|
+
type DataSelectDialogResult,
|
|
20
|
+
type DialogConfig,
|
|
21
|
+
} from "../data-select-button/DataSelectButton";
|
|
22
|
+
|
|
23
|
+
// -- Slot detection --
|
|
24
|
+
const ITEM_TEMPLATE_BRAND = Symbol("SharedDataSelect.ItemTemplate");
|
|
25
|
+
const ACTION_BRAND = Symbol("SharedDataSelect.Action");
|
|
26
|
+
|
|
27
|
+
interface ItemTemplateDef {
|
|
28
|
+
__brand: typeof ITEM_TEMPLATE_BRAND;
|
|
29
|
+
children: (item: any, index: number, depth: number) => JSX.Element;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface ActionDef {
|
|
33
|
+
__brand: typeof ACTION_BRAND;
|
|
34
|
+
children: JSX.Element;
|
|
35
|
+
onClick?: (e: MouseEvent) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isItemTemplateDef(v: unknown): v is ItemTemplateDef {
|
|
39
|
+
return v != null && typeof v === "object" && "__brand" in v && (v as any).__brand === ITEM_TEMPLATE_BRAND;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isActionDef(v: unknown): v is ActionDef {
|
|
43
|
+
return v != null && typeof v === "object" && "__brand" in v && (v as any).__brand === ACTION_BRAND;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// -- Compound components --
|
|
47
|
+
const ItemTemplate: Component<{
|
|
48
|
+
children: (item: any, index: number, depth: number) => JSX.Element;
|
|
49
|
+
}> = (props) => {
|
|
50
|
+
// eslint-disable-next-line solid/reactivity -- factory function, not reactive JSX
|
|
51
|
+
return (() => ({
|
|
52
|
+
__brand: ITEM_TEMPLATE_BRAND,
|
|
53
|
+
children: props.children,
|
|
54
|
+
})) as unknown as JSX.Element;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const Action: Component<{
|
|
58
|
+
children?: JSX.Element;
|
|
59
|
+
onClick?: (e: MouseEvent) => void;
|
|
60
|
+
}> = (props) => {
|
|
61
|
+
// eslint-disable-next-line solid/reactivity -- factory function, not reactive JSX
|
|
62
|
+
return (() => ({
|
|
63
|
+
__brand: ACTION_BRAND,
|
|
64
|
+
children: props.children,
|
|
65
|
+
onClick: props.onClick,
|
|
66
|
+
})) as unknown as JSX.Element;
|
|
67
|
+
};
|
|
9
68
|
|
|
10
69
|
/** SharedDataSelect Props */
|
|
11
70
|
export interface SharedDataSelectProps<TItem> {
|
|
12
71
|
/** Shared data accessor */
|
|
13
72
|
data: SharedDataAccessor<TItem>;
|
|
14
73
|
|
|
15
|
-
/** Currently selected value */
|
|
74
|
+
/** Currently selected key value (translated to item internally) */
|
|
16
75
|
value?: unknown;
|
|
17
|
-
/** Value change callback */
|
|
76
|
+
/** Value change callback (receives key, not item) */
|
|
18
77
|
onValueChange?: (value: unknown) => void;
|
|
19
78
|
/** Multiple selection mode */
|
|
20
79
|
multiple?: boolean;
|
|
@@ -29,21 +88,37 @@ export interface SharedDataSelectProps<TItem> {
|
|
|
29
88
|
|
|
30
89
|
/** Item filter function */
|
|
31
90
|
filterFn?: (item: TItem, index: number) => boolean;
|
|
32
|
-
/** Selection
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
91
|
+
/** Selection dialog configuration */
|
|
92
|
+
dialog?: DialogConfig;
|
|
93
|
+
|
|
94
|
+
/** Compound children: ItemTemplate, Action */
|
|
95
|
+
children: JSX.Element;
|
|
96
|
+
}
|
|
36
97
|
|
|
37
|
-
|
|
38
|
-
|
|
98
|
+
interface SharedDataSelectComponent {
|
|
99
|
+
<TItem>(props: SharedDataSelectProps<TItem>): JSX.Element;
|
|
100
|
+
ItemTemplate: typeof ItemTemplate;
|
|
101
|
+
Action: typeof Action;
|
|
39
102
|
}
|
|
40
103
|
|
|
41
|
-
|
|
42
|
-
const [local, rest] = splitProps(props, [
|
|
104
|
+
const SharedDataSelectBase = <TItem,>(props: SharedDataSelectProps<TItem>): JSX.Element => {
|
|
105
|
+
const [local, rest] = splitProps(props, [
|
|
106
|
+
"data", "filterFn", "dialog", "children",
|
|
107
|
+
]);
|
|
43
108
|
|
|
44
|
-
const i18n =
|
|
109
|
+
const i18n = useI18n();
|
|
45
110
|
const dialog = useDialog();
|
|
46
111
|
|
|
112
|
+
// Resolve compound children
|
|
113
|
+
const resolved = resolveChildren(() => local.children);
|
|
114
|
+
const defs = createMemo(() => {
|
|
115
|
+
const arr = resolved.toArray();
|
|
116
|
+
return {
|
|
117
|
+
itemTemplate: arr.find(isItemTemplateDef) as unknown as ItemTemplateDef | undefined,
|
|
118
|
+
actions: arr.filter(isActionDef) as unknown as ActionDef[],
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
|
|
47
122
|
// Items with filterFn applied
|
|
48
123
|
const items = createMemo(() => {
|
|
49
124
|
const allItems = local.data.items();
|
|
@@ -51,21 +126,77 @@ export function SharedDataSelect<TItem>(props: SharedDataSelectProps<TItem>): JS
|
|
|
51
126
|
return allItems.filter(local.filterFn);
|
|
52
127
|
});
|
|
53
128
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
|
|
129
|
+
// Normalize value to keys array
|
|
130
|
+
const normalizeKeys = (value: unknown): (string | number)[] => {
|
|
131
|
+
if (value === undefined || value === null) return [];
|
|
132
|
+
if (Array.isArray(value)) return value;
|
|
133
|
+
return [value as string | number];
|
|
58
134
|
};
|
|
59
135
|
|
|
60
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
136
|
+
// Translate key(s) to item(s) for Select's value prop
|
|
137
|
+
const keyToItem = (key: string | number): TItem | undefined => {
|
|
138
|
+
return local.data.get(key);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const valueAsItem = createMemo((): TItem | TItem[] | undefined => {
|
|
142
|
+
const key = rest.value;
|
|
143
|
+
if (key === undefined || key === null) return undefined;
|
|
144
|
+
if (Array.isArray(key)) {
|
|
145
|
+
return key.map((k) => keyToItem(k as string | number)).filter((v): v is TItem => v !== undefined);
|
|
146
|
+
}
|
|
147
|
+
return keyToItem(key as string | number);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Translate item back to key for onValueChange callback
|
|
151
|
+
const itemToKey = (item: TItem | TItem[] | undefined): unknown => {
|
|
152
|
+
if (item === undefined || item === null) return undefined;
|
|
153
|
+
if (Array.isArray(item)) return item.map((i) => local.data.getKey(i));
|
|
154
|
+
return local.data.getKey(item);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Open dialog and handle selection result
|
|
158
|
+
const handleOpenDialog = async () => {
|
|
159
|
+
if (!local.dialog) return;
|
|
160
|
+
|
|
161
|
+
const dialogConfig = local.dialog;
|
|
162
|
+
const result = await dialog.show<DataSelectDialogResult<string | number>>(
|
|
163
|
+
() => {
|
|
164
|
+
const instance = useDialogInstance<DataSelectDialogResult<string | number>>();
|
|
165
|
+
return (
|
|
166
|
+
<dialogConfig.component
|
|
167
|
+
{...(dialogConfig.props ?? {})}
|
|
168
|
+
selectMode={rest.multiple ? "multiple" : "single"}
|
|
169
|
+
selectedKeys={normalizeKeys(rest.value)}
|
|
170
|
+
onSelect={(r: { keys: (string | number)[] }) =>
|
|
171
|
+
instance?.close({ selectedKeys: r.keys })
|
|
172
|
+
}
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
dialogConfig.option ?? {},
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
if (result) {
|
|
180
|
+
const newKeys = result.selectedKeys;
|
|
181
|
+
if (rest.multiple) {
|
|
182
|
+
rest.onValueChange?.(newKeys);
|
|
183
|
+
} else {
|
|
184
|
+
rest.onValueChange?.(newKeys.length > 0 ? newKeys[0] : undefined);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
64
187
|
};
|
|
65
188
|
|
|
66
|
-
// Use mergeProps + as for Select's discriminated union (multiple: true | false?) and TItem → unknown conversion
|
|
67
|
-
// Wrap with getter to satisfy SolidJS reactivity lint rules
|
|
68
189
|
const selectProps = mergeProps(rest, {
|
|
190
|
+
get value() {
|
|
191
|
+
return valueAsItem();
|
|
192
|
+
},
|
|
193
|
+
get onValueChange() {
|
|
194
|
+
if (!rest.onValueChange) return undefined;
|
|
195
|
+
// eslint-disable-next-line solid/reactivity -- inside getter, tracked scope
|
|
196
|
+
return (item: TItem | TItem[] | undefined) => {
|
|
197
|
+
rest.onValueChange!(itemToKey(item));
|
|
198
|
+
};
|
|
199
|
+
},
|
|
69
200
|
get items() {
|
|
70
201
|
return items();
|
|
71
202
|
},
|
|
@@ -87,17 +218,25 @@ export function SharedDataSelect<TItem>(props: SharedDataSelectProps<TItem>): JS
|
|
|
87
218
|
|
|
88
219
|
return (
|
|
89
220
|
<Select {...selectProps}>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<Select.Action onClick={() => void handleOpenModal()} aria-label={i18n?.t("sharedDataSelect.search") ?? "Search"}>
|
|
93
|
-
<Icon icon={IconSearch} />
|
|
94
|
-
</Select.Action>
|
|
221
|
+
{defs().itemTemplate && (
|
|
222
|
+
<Select.ItemTemplate>{defs().itemTemplate!.children}</Select.ItemTemplate>
|
|
95
223
|
)}
|
|
96
|
-
{local.
|
|
97
|
-
<Select.Action onClick={() => void
|
|
98
|
-
<Icon icon={
|
|
224
|
+
{local.dialog && (
|
|
225
|
+
<Select.Action onClick={() => void handleOpenDialog()} aria-label={i18n.t("sharedDataSelect.search")}>
|
|
226
|
+
<Icon icon={IconSearch} />
|
|
99
227
|
</Select.Action>
|
|
100
228
|
)}
|
|
229
|
+
<For each={defs().actions}>
|
|
230
|
+
{(action) => (
|
|
231
|
+
<Select.Action onClick={action.onClick}>
|
|
232
|
+
{action.children}
|
|
233
|
+
</Select.Action>
|
|
234
|
+
)}
|
|
235
|
+
</For>
|
|
101
236
|
</Select>
|
|
102
237
|
);
|
|
103
|
-
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export const SharedDataSelect: SharedDataSelectComponent = SharedDataSelectBase as any;
|
|
241
|
+
SharedDataSelect.ItemTemplate = ItemTemplate;
|
|
242
|
+
SharedDataSelect.Action = Action;
|
|
@@ -3,6 +3,7 @@ import { type SharedDataAccessor } from "../../../providers/shared-data/SharedDa
|
|
|
3
3
|
import {
|
|
4
4
|
DataSelectButton,
|
|
5
5
|
type DataSelectButtonProps,
|
|
6
|
+
type DialogConfig,
|
|
6
7
|
} from "../data-select-button/DataSelectButton";
|
|
7
8
|
import { type ComponentSize } from "../../../styles/tokens.styles";
|
|
8
9
|
|
|
@@ -26,8 +27,8 @@ export interface SharedDataSelectButtonProps<TItem> {
|
|
|
26
27
|
/** Borderless style */
|
|
27
28
|
inset?: boolean;
|
|
28
29
|
|
|
29
|
-
/** Selection
|
|
30
|
-
|
|
30
|
+
/** Selection dialog configuration */
|
|
31
|
+
dialog: DialogConfig;
|
|
31
32
|
/** Item rendering function */
|
|
32
33
|
children: (item: TItem) => JSX.Element;
|
|
33
34
|
}
|
|
@@ -5,7 +5,7 @@ import { type SharedDataAccessor } from "../../../providers/shared-data/SharedDa
|
|
|
5
5
|
import { List } from "../../data/list/List";
|
|
6
6
|
import { Pagination } from "../../data/Pagination";
|
|
7
7
|
import { TextInput } from "../../form-control/field/TextInput";
|
|
8
|
-
import {
|
|
8
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
9
9
|
import { textMuted } from "../../../styles/tokens.styles";
|
|
10
10
|
import { createSlotSignal } from "../../../hooks/createSlotSignal";
|
|
11
11
|
import {
|
|
@@ -77,7 +77,7 @@ export const SharedDataSelectList: SharedDataSelectListComponent = (<TItem,>(
|
|
|
77
77
|
"header",
|
|
78
78
|
]);
|
|
79
79
|
|
|
80
|
-
const i18n =
|
|
80
|
+
const i18n = useI18n();
|
|
81
81
|
|
|
82
82
|
// ─── Slot signals ──────────────────────────────────────
|
|
83
83
|
|
|
@@ -203,7 +203,7 @@ export const SharedDataSelectList: SharedDataSelectListComponent = (<TItem,>(
|
|
|
203
203
|
<TextInput
|
|
204
204
|
value={searchText()}
|
|
205
205
|
onValueChange={setSearchText}
|
|
206
|
-
placeholder={i18n
|
|
206
|
+
placeholder={i18n.t("sharedDataSelectList.searchPlaceholder")}
|
|
207
207
|
class={"w-full"}
|
|
208
208
|
/>
|
|
209
209
|
</div>
|
|
@@ -231,7 +231,7 @@ export const SharedDataSelectList: SharedDataSelectListComponent = (<TItem,>(
|
|
|
231
231
|
disabled={local.disabled}
|
|
232
232
|
onClick={() => handleSelect(undefined)}
|
|
233
233
|
>
|
|
234
|
-
<span class={textMuted}>
|
|
234
|
+
<span class={textMuted}>{i18n.t("sharedDataSelectList.unspecified")}</span>
|
|
235
235
|
</List.Item>
|
|
236
236
|
</Show>
|
|
237
237
|
|
|
@@ -3,7 +3,7 @@ import { Portal } from "solid-js/web";
|
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import { IconX } from "@tabler/icons-solidjs";
|
|
5
5
|
import { useNotification } from "./NotificationContext";
|
|
6
|
-
import {
|
|
6
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
7
7
|
import { Icon } from "../../display/Icon";
|
|
8
8
|
import { themeTokens } from "../../../styles/tokens.styles";
|
|
9
9
|
|
|
@@ -39,7 +39,7 @@ const dismissButtonClass = clsx("rounded", "p-1", "hover:bg-white/20");
|
|
|
39
39
|
|
|
40
40
|
export const NotificationBanner: Component = () => {
|
|
41
41
|
const notification = useNotification();
|
|
42
|
-
const i18n =
|
|
42
|
+
const i18n = useI18n();
|
|
43
43
|
|
|
44
44
|
const handleDismiss = () => {
|
|
45
45
|
notification.dismissBanner();
|
|
@@ -74,7 +74,7 @@ export const NotificationBanner: Component = () => {
|
|
|
74
74
|
</Show>
|
|
75
75
|
<button
|
|
76
76
|
type="button"
|
|
77
|
-
aria-label={i18n
|
|
77
|
+
aria-label={i18n.t("notification.close")}
|
|
78
78
|
class={dismissButtonClass}
|
|
79
79
|
onClick={handleDismiss}
|
|
80
80
|
>
|
|
@@ -7,6 +7,7 @@ import { Dropdown } from "../../disclosure/Dropdown";
|
|
|
7
7
|
import { Icon } from "../../display/Icon";
|
|
8
8
|
import { NotificationBanner } from "./NotificationBanner";
|
|
9
9
|
import { iconButtonBase } from "../../../styles/patterns.styles";
|
|
10
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
10
11
|
|
|
11
12
|
export interface NotificationBellProps {
|
|
12
13
|
showBanner?: boolean;
|
|
@@ -52,6 +53,7 @@ const itemTimeClass = clsx("mt-1 text-xs", "text-base-400");
|
|
|
52
53
|
|
|
53
54
|
export const NotificationBell: Component<NotificationBellProps> = (props) => {
|
|
54
55
|
const notification = useNotification();
|
|
56
|
+
const i18n = useI18n();
|
|
55
57
|
const [open, setOpen] = createSignal(false);
|
|
56
58
|
|
|
57
59
|
const handleClear = () => {
|
|
@@ -78,7 +80,7 @@ export const NotificationBell: Component<NotificationBellProps> = (props) => {
|
|
|
78
80
|
type="button"
|
|
79
81
|
data-notification-bell
|
|
80
82
|
class={buttonClass}
|
|
81
|
-
aria-label={
|
|
83
|
+
aria-label={i18n.t("notificationBell.unreadCount", { count: String(notification.unreadCount()) })}
|
|
82
84
|
aria-haspopup="true"
|
|
83
85
|
aria-expanded={open()}
|
|
84
86
|
>
|
|
@@ -93,7 +95,7 @@ export const NotificationBell: Component<NotificationBellProps> = (props) => {
|
|
|
93
95
|
<Dropdown.Content>
|
|
94
96
|
<div class="w-80 p-2">
|
|
95
97
|
<div class={dropdownHeaderClass}>
|
|
96
|
-
<span class="font-bold">
|
|
98
|
+
<span class="font-bold">{i18n.t("notificationBell.notifications")}</span>
|
|
97
99
|
<Show when={notification.items().length > 0}>
|
|
98
100
|
<button
|
|
99
101
|
type="button"
|
|
@@ -101,14 +103,14 @@ export const NotificationBell: Component<NotificationBellProps> = (props) => {
|
|
|
101
103
|
class={clearButtonClass}
|
|
102
104
|
onClick={handleClear}
|
|
103
105
|
>
|
|
104
|
-
|
|
106
|
+
{i18n.t("notificationBell.clearAll")}
|
|
105
107
|
</button>
|
|
106
108
|
</Show>
|
|
107
109
|
</div>
|
|
108
110
|
|
|
109
111
|
<Show
|
|
110
112
|
when={notification.items().length > 0}
|
|
111
|
-
fallback={<div class={emptyClass}>
|
|
113
|
+
fallback={<div class={emptyClass}>{i18n.t("notificationBell.noNotifications")}</div>}
|
|
112
114
|
>
|
|
113
115
|
<div class={listClass}>
|
|
114
116
|
<For each={[...notification.items()].reverse()}>
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type NotificationUpdateOptions,
|
|
9
9
|
} from "./NotificationContext";
|
|
10
10
|
import { useLogger } from "../../../hooks/useLogger";
|
|
11
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
11
12
|
|
|
12
13
|
const MAX_ITEMS = 50;
|
|
13
14
|
|
|
@@ -22,6 +23,7 @@ const MAX_ITEMS = 50;
|
|
|
22
23
|
*/
|
|
23
24
|
export const NotificationProvider: ParentComponent = (props) => {
|
|
24
25
|
const logger = useLogger();
|
|
26
|
+
const i18n = useI18n();
|
|
25
27
|
const [items, setItems] = createSignal<NotificationItem[]>([]);
|
|
26
28
|
const [dismissedBannerId, setDismissedBannerId] = createSignal<string | null>(null);
|
|
27
29
|
|
|
@@ -158,7 +160,7 @@ export const NotificationProvider: ParentComponent = (props) => {
|
|
|
158
160
|
{/* Screen reader Live Region */}
|
|
159
161
|
<div role="status" aria-live="polite" aria-atomic="true" class="sr-only">
|
|
160
162
|
<Show when={latestUnread()}>
|
|
161
|
-
{(item) =>
|
|
163
|
+
{(item) => `${i18n.t("notificationProvider.prefix")} ${item().title} ${item().message ?? ""}`}
|
|
162
164
|
</Show>
|
|
163
165
|
</div>
|
|
164
166
|
{props.children}
|
|
@@ -5,6 +5,7 @@ import { useTheme, type ThemeMode } from "../../providers/ThemeContext";
|
|
|
5
5
|
import { Icon } from "../display/Icon";
|
|
6
6
|
import { ripple } from "../../directives/ripple";
|
|
7
7
|
import { iconButtonBase } from "../../styles/patterns.styles";
|
|
8
|
+
import { useI18n } from "../../providers/i18n/I18nContext";
|
|
8
9
|
|
|
9
10
|
void ripple;
|
|
10
11
|
|
|
@@ -18,10 +19,10 @@ const iconSizes: Record<"sm" | "lg", string> = {
|
|
|
18
19
|
lg: "1.5em",
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
const
|
|
22
|
-
light: "
|
|
23
|
-
system: "
|
|
24
|
-
dark: "
|
|
22
|
+
const modeLabelKeys: Record<ThemeMode, string> = {
|
|
23
|
+
light: "themeToggle.light",
|
|
24
|
+
system: "themeToggle.system",
|
|
25
|
+
dark: "themeToggle.dark",
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
export interface ThemeToggleProps extends Omit<
|
|
@@ -54,6 +55,9 @@ export const ThemeToggle: Component<ThemeToggleProps> = (props) => {
|
|
|
54
55
|
const [local, rest] = splitProps(props, ["class", "size"]);
|
|
55
56
|
|
|
56
57
|
const { mode, cycleMode } = useTheme();
|
|
58
|
+
const i18n = useI18n();
|
|
59
|
+
|
|
60
|
+
const modeLabel = () => i18n.t(modeLabelKeys[mode()]);
|
|
57
61
|
|
|
58
62
|
const getClassName = () =>
|
|
59
63
|
twMerge(iconButtonBase, "p-1.5", local.size && sizeClasses[local.size], local.class);
|
|
@@ -68,8 +72,8 @@ export const ThemeToggle: Component<ThemeToggleProps> = (props) => {
|
|
|
68
72
|
type="button"
|
|
69
73
|
class={getClassName()}
|
|
70
74
|
onClick={cycleMode}
|
|
71
|
-
title={
|
|
72
|
-
aria-label={
|
|
75
|
+
title={modeLabel()}
|
|
76
|
+
aria-label={modeLabel()}
|
|
73
77
|
>
|
|
74
78
|
<Switch>
|
|
75
79
|
<Match when={mode() === "light"}>
|
|
@@ -4,6 +4,7 @@ import { IconCheck } from "@tabler/icons-solidjs";
|
|
|
4
4
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
5
5
|
import { ripple } from "../../../directives/ripple";
|
|
6
6
|
import { Icon } from "../../display/Icon";
|
|
7
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
7
8
|
import {
|
|
8
9
|
type CheckboxSize,
|
|
9
10
|
checkboxBaseClass,
|
|
@@ -51,6 +52,8 @@ export const Checkbox: ParentComponent<CheckboxProps> = (props) => {
|
|
|
51
52
|
"children",
|
|
52
53
|
]);
|
|
53
54
|
|
|
55
|
+
const i18n = useI18n();
|
|
56
|
+
|
|
54
57
|
const [value, setValue] = createControllableSignal({
|
|
55
58
|
value: () => local.value ?? false,
|
|
56
59
|
onChange: () => local.onValueChange,
|
|
@@ -84,7 +87,7 @@ export const Checkbox: ParentComponent<CheckboxProps> = (props) => {
|
|
|
84
87
|
|
|
85
88
|
const errorMsg = createMemo(() => {
|
|
86
89
|
const v = local.value ?? false;
|
|
87
|
-
if (local.required && !v) return "
|
|
90
|
+
if (local.required && !v) return i18n.t("validation.requiredSelection");
|
|
88
91
|
return local.validate?.(v);
|
|
89
92
|
});
|
|
90
93
|
|
|
@@ -31,7 +31,7 @@ const { Group } = createSelectionGroup({
|
|
|
31
31
|
mode: "multiple",
|
|
32
32
|
contextName: "CheckboxGroup",
|
|
33
33
|
ItemComponent: Checkbox,
|
|
34
|
-
|
|
34
|
+
emptyErrorMsgKey: "validation.selectItem",
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
export const CheckboxGroup = Group as unknown as CheckboxGroupComponent;
|
|
@@ -3,6 +3,7 @@ import { twMerge } from "tailwind-merge";
|
|
|
3
3
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
4
4
|
import { ripple } from "../../../directives/ripple";
|
|
5
5
|
import clsx from "clsx";
|
|
6
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
6
7
|
import {
|
|
7
8
|
type CheckboxSize,
|
|
8
9
|
checkboxBaseClass,
|
|
@@ -52,6 +53,8 @@ export const Radio: ParentComponent<RadioProps> = (props) => {
|
|
|
52
53
|
"children",
|
|
53
54
|
]);
|
|
54
55
|
|
|
56
|
+
const i18n = useI18n();
|
|
57
|
+
|
|
55
58
|
const [value, setValue] = createControllableSignal({
|
|
56
59
|
value: () => local.value ?? false,
|
|
57
60
|
onChange: () => local.onValueChange,
|
|
@@ -85,7 +88,7 @@ export const Radio: ParentComponent<RadioProps> = (props) => {
|
|
|
85
88
|
|
|
86
89
|
const errorMsg = createMemo(() => {
|
|
87
90
|
const v = local.value ?? false;
|
|
88
|
-
if (local.required && !v) return "
|
|
91
|
+
if (local.required && !v) return i18n.t("validation.requiredSelection");
|
|
89
92
|
return local.validate?.(v);
|
|
90
93
|
});
|
|
91
94
|
|
|
@@ -31,7 +31,7 @@ const { Group } = createSelectionGroup({
|
|
|
31
31
|
mode: "single",
|
|
32
32
|
contextName: "RadioGroup",
|
|
33
33
|
ItemComponent: Radio,
|
|
34
|
-
|
|
34
|
+
emptyErrorMsgKey: "validation.selectItem",
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
export const RadioGroup = Group as unknown as RadioGroupComponent;
|
|
@@ -4,6 +4,7 @@ import { twMerge } from "tailwind-merge";
|
|
|
4
4
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
5
5
|
import { Invalid } from "../Invalid";
|
|
6
6
|
import { type ComponentSize } from "../../../styles/tokens.styles";
|
|
7
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
7
8
|
|
|
8
9
|
// Base style
|
|
9
10
|
const baseClass = clsx(
|
|
@@ -94,6 +95,8 @@ export const ColorPicker: Component<ColorPickerProps> = (props) => {
|
|
|
94
95
|
"style",
|
|
95
96
|
]);
|
|
96
97
|
|
|
98
|
+
const i18n = useI18n();
|
|
99
|
+
|
|
97
100
|
const [value, setValue] = createControllableSignal({
|
|
98
101
|
value: () => local.value,
|
|
99
102
|
onChange: () => local.onValueChange,
|
|
@@ -113,7 +116,7 @@ export const ColorPicker: Component<ColorPickerProps> = (props) => {
|
|
|
113
116
|
|
|
114
117
|
const errorMsg = createMemo(() => {
|
|
115
118
|
const v = value();
|
|
116
|
-
if (local.required && (v === undefined || v === "")) return "
|
|
119
|
+
if (local.required && (v === undefined || v === "")) return i18n.t("validation.required");
|
|
117
120
|
return local.validate?.(v);
|
|
118
121
|
});
|
|
119
122
|
|
|
@@ -12,6 +12,7 @@ import { createControllableSignal } from "../../../hooks/createControllableSigna
|
|
|
12
12
|
import { type ComponentSize, textMuted } from "../../../styles/tokens.styles";
|
|
13
13
|
import { chevronWrapperClass, getTriggerClass } from "../DropdownTrigger.styles";
|
|
14
14
|
import { Invalid } from "../Invalid";
|
|
15
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
15
16
|
|
|
16
17
|
void ripple;
|
|
17
18
|
|
|
@@ -149,6 +150,8 @@ export const Combobox: ComboboxComponent = <T,>(props: ComboboxProps<T>) => {
|
|
|
149
150
|
"touchMode",
|
|
150
151
|
]);
|
|
151
152
|
|
|
153
|
+
const i18n = useI18n();
|
|
154
|
+
|
|
152
155
|
// State
|
|
153
156
|
const [open, setOpen] = createSignal(false);
|
|
154
157
|
const [query, setQuery] = createSignal("");
|
|
@@ -259,7 +262,7 @@ export const Combobox: ComboboxComponent = <T,>(props: ComboboxProps<T>) => {
|
|
|
259
262
|
const errorMsg = createMemo(() => {
|
|
260
263
|
const v = getValue();
|
|
261
264
|
if (local.required && (v === undefined || v === null || v === ""))
|
|
262
|
-
return "
|
|
265
|
+
return i18n.t("validation.required");
|
|
263
266
|
return local.validate?.(v);
|
|
264
267
|
});
|
|
265
268
|
|
|
@@ -310,12 +313,12 @@ export const Combobox: ComboboxComponent = <T,>(props: ComboboxProps<T>) => {
|
|
|
310
313
|
|
|
311
314
|
// Loading
|
|
312
315
|
if (busyCount() > 0) {
|
|
313
|
-
return <div class={noResultsClass}>
|
|
316
|
+
return <div class={noResultsClass}>{i18n.t("combobox.searching")}</div>;
|
|
314
317
|
}
|
|
315
318
|
|
|
316
319
|
// Items empty
|
|
317
320
|
if (items().length === 0) {
|
|
318
|
-
return <div class={noResultsClass}>
|
|
321
|
+
return <div class={noResultsClass}>{i18n.t("combobox.noResults")}</div>;
|
|
319
322
|
}
|
|
320
323
|
|
|
321
324
|
// ItemTemplate approach
|
|
@@ -6,7 +6,7 @@ import { createControllableSignal } from "../../../hooks/createControllableSigna
|
|
|
6
6
|
import { type FieldSize } from "../field/Field.styles";
|
|
7
7
|
import { DatePicker } from "../field/DatePicker";
|
|
8
8
|
import { Select } from "../select/Select";
|
|
9
|
-
import {
|
|
9
|
+
import { useI18n } from "../../../providers/i18n/I18nContext";
|
|
10
10
|
|
|
11
11
|
export type DateRangePeriodType = "day" | "month" | "range";
|
|
12
12
|
|
|
@@ -78,7 +78,7 @@ function getLastDayOfMonth(date: DateOnly): DateOnly {
|
|
|
78
78
|
* ```
|
|
79
79
|
*/
|
|
80
80
|
export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
81
|
-
const i18n =
|
|
81
|
+
const i18n = useI18n();
|
|
82
82
|
|
|
83
83
|
const [local, rest] = splitProps(props, [
|
|
84
84
|
"periodType",
|
|
@@ -163,9 +163,9 @@ export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
|
163
163
|
onValueChange={handlePeriodTypeChange}
|
|
164
164
|
renderValue={(v: DateRangePeriodType) => {
|
|
165
165
|
const labels = {
|
|
166
|
-
day: i18n
|
|
167
|
-
month: i18n
|
|
168
|
-
range: i18n
|
|
166
|
+
day: i18n.t("dateRangePicker.day"),
|
|
167
|
+
month: i18n.t("dateRangePicker.month"),
|
|
168
|
+
range: i18n.t("dateRangePicker.range"),
|
|
169
169
|
};
|
|
170
170
|
return <>{labels[v]}</>;
|
|
171
171
|
}}
|
|
@@ -175,13 +175,13 @@ export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
|
175
175
|
inset
|
|
176
176
|
>
|
|
177
177
|
<Select.Item value={"day" as DateRangePeriodType}>
|
|
178
|
-
{i18n
|
|
178
|
+
{i18n.t("dateRangePicker.day")}
|
|
179
179
|
</Select.Item>
|
|
180
180
|
<Select.Item value={"month" as DateRangePeriodType}>
|
|
181
|
-
{i18n
|
|
181
|
+
{i18n.t("dateRangePicker.month")}
|
|
182
182
|
</Select.Item>
|
|
183
183
|
<Select.Item value={"range" as DateRangePeriodType}>
|
|
184
|
-
{i18n
|
|
184
|
+
{i18n.t("dateRangePicker.range")}
|
|
185
185
|
</Select.Item>
|
|
186
186
|
</Select>
|
|
187
187
|
|