pixelize-design-library 2.4.2-beta.58 → 2.4.2-beta.60
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/CHANGELOG.md +149 -5
- package/COMPONENT-GOTCHAS.md +205 -18
- package/DESIGN-GUIDE.md +43 -9
- package/dist/Components/AppSwitcher/AppSwitcher.js +5 -1
- package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +2 -0
- package/dist/Components/AppSwitcher/AppSwitcherProps.js +7 -4
- package/dist/Components/AudioRecorder/AudioRecorder.d.ts +8 -0
- package/dist/Components/AudioRecorder/AudioRecorder.js +169 -0
- package/dist/Components/AudioRecorder/AudioRecorderProps.d.ts +20 -0
- package/dist/Components/AudioRecorder/AudioRecorderProps.js +2 -0
- package/dist/Components/Breadcrumbs/Breadcrumbs.d.ts +1 -1
- package/dist/Components/Breadcrumbs/Breadcrumbs.js +33 -10
- package/dist/Components/Breadcrumbs/BreadcrumbsProps.d.ts +16 -2
- package/dist/Components/BulkSelectionBar/BulkSelectionBar.d.ts +3 -0
- package/dist/Components/BulkSelectionBar/BulkSelectionBar.js +43 -0
- package/dist/Components/BulkSelectionBar/BulkSelectionBarProps.d.ts +35 -0
- package/dist/Components/BulkSelectionBar/BulkSelectionBarProps.js +2 -0
- package/dist/Components/BulkSelectionBar/index.d.ts +2 -0
- package/dist/Components/BulkSelectionBar/index.js +8 -0
- package/dist/Components/CalendarGrid/CalendarGrid.d.ts +3 -0
- package/dist/Components/CalendarGrid/CalendarGrid.js +173 -0
- package/dist/Components/CalendarGrid/CalendarGridProps.d.ts +54 -0
- package/dist/Components/CalendarGrid/CalendarGridProps.js +2 -0
- package/dist/Components/CalendarGrid/calendarMath.d.ts +49 -0
- package/dist/Components/CalendarGrid/calendarMath.js +178 -0
- package/dist/Components/Card/Card.d.ts +3 -1
- package/dist/Components/Card/Card.js +12 -2
- package/dist/Components/Card/CardProps.d.ts +5 -1
- package/dist/Components/CircularProgress/CircularProgress.d.ts +4 -0
- package/dist/Components/CircularProgress/CircularProgress.js +39 -0
- package/dist/Components/CircularProgress/CircularProgressProps.d.ts +22 -0
- package/dist/Components/CircularProgress/CircularProgressProps.js +2 -0
- package/dist/Components/CircularProgress/arc.d.ts +12 -0
- package/dist/Components/CircularProgress/arc.js +16 -0
- package/dist/Components/Common/fieldStyles.d.ts +1 -0
- package/dist/Components/Common/fieldStyles.js +2 -1
- package/dist/Components/Drawer/Drawer.d.ts +1 -1
- package/dist/Components/Drawer/Drawer.js +4 -2
- package/dist/Components/Drawer/DrawerProps.d.ts +3 -1
- package/dist/Components/Editor/Editor.js +50 -2
- package/dist/Components/Editor/EditorFieldBar.d.ts +15 -0
- package/dist/Components/Editor/EditorFieldBar.js +19 -0
- package/dist/Components/Editor/EditorProps.d.ts +74 -1
- package/dist/Components/Editor/MakeDynamicDialog.d.ts +12 -0
- package/dist/Components/Editor/MakeDynamicDialog.js +59 -0
- package/dist/Components/Editor/editorLabels.d.ts +4 -0
- package/dist/Components/Editor/editorLabels.js +24 -0
- package/dist/Components/Editor/editorTokenStyles.d.ts +28 -0
- package/dist/Components/Editor/editorTokenStyles.js +30 -0
- package/dist/Components/Editor/editorTokens.d.ts +26 -0
- package/dist/Components/Editor/editorTokens.js +134 -0
- package/dist/Components/Editor/useEditorBridge.d.ts +40 -0
- package/dist/Components/Editor/useEditorBridge.js +141 -0
- package/dist/Components/EmptyState/EmptyState.js +2 -1
- package/dist/Components/EmptyState/EmptyStateProps.d.ts +2 -2
- package/dist/Components/FormDrawer/FormDrawer.d.ts +2 -0
- package/dist/Components/FormDrawer/FormDrawer.js +97 -0
- package/dist/Components/FormDrawer/FormDrawerProps.d.ts +55 -0
- package/dist/Components/FormDrawer/FormDrawerProps.js +2 -0
- package/dist/Components/Kbd/Kbd.d.ts +6 -0
- package/dist/Components/Kbd/Kbd.js +33 -0
- package/dist/Components/Kbd/KbdProps.d.ts +17 -0
- package/dist/Components/Kbd/KbdProps.js +2 -0
- package/dist/Components/LauncherTrigger/LauncherTrigger.d.ts +4 -0
- package/dist/Components/LauncherTrigger/LauncherTrigger.js +48 -0
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.d.ts +18 -0
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.js +2 -0
- package/dist/Components/Modal/Modal.d.ts +1 -1
- package/dist/Components/Modal/Modal.js +4 -2
- package/dist/Components/Modal/ModalProps.d.ts +3 -1
- package/dist/Components/Modal/warnDroppedSlotChildren.d.ts +2 -0
- package/dist/Components/Modal/warnDroppedSlotChildren.js +45 -0
- package/dist/Components/NavLauncher/NavLauncher.d.ts +3 -0
- package/dist/Components/NavLauncher/NavLauncher.js +452 -0
- package/dist/Components/NavLauncher/NavLauncherProps.d.ts +187 -0
- package/dist/Components/NavLauncher/NavLauncherProps.js +2 -0
- package/dist/Components/NavLauncher/NewTabLink.d.ts +3 -0
- package/dist/Components/NavLauncher/NewTabLink.js +14 -0
- package/dist/Components/NavLauncher/PinToggle.d.ts +3 -0
- package/dist/Components/NavLauncher/PinToggle.js +21 -0
- package/dist/Components/NavLauncher/launcherParts.d.ts +152 -0
- package/dist/Components/NavLauncher/launcherParts.js +212 -0
- package/dist/Components/NavLauncher/match.d.ts +53 -0
- package/dist/Components/NavLauncher/match.js +178 -0
- package/dist/Components/NavLauncher/revealStyles.d.ts +4 -0
- package/dist/Components/NavLauncher/revealStyles.js +19 -0
- package/dist/Components/NavigationBar/NavigationBar.d.ts +1 -1
- package/dist/Components/NavigationBar/NavigationBar.js +2 -2
- package/dist/Components/NavigationBar/NavigationBarProps.d.ts +2 -0
- package/dist/Components/PageHeader/PageHeader.d.ts +1 -1
- package/dist/Components/PageHeader/PageHeader.js +9 -2
- package/dist/Components/PageHeader/PageHeaderProps.d.ts +8 -0
- package/dist/Components/PdfViewer/PdfViewer.d.ts +21 -4
- package/dist/Components/PdfViewer/PdfViewer.js +124 -3
- package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +5 -0
- package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewerProps.d.ts +1 -1
- package/dist/Components/QueryState/QueryStateBoundary.d.ts +2 -2
- package/dist/Components/QueryState/QueryStateBoundary.js +9 -3
- package/dist/Components/QueryState/QueryStateProps.d.ts +19 -2
- package/dist/Components/Search/Search.js +2 -1
- package/dist/Components/SectionRail/SectionRail.d.ts +3 -0
- package/dist/Components/SectionRail/SectionRail.js +49 -0
- package/dist/Components/SectionRail/SectionRailProps.d.ts +23 -0
- package/dist/Components/SectionRail/SectionRailProps.js +2 -0
- package/dist/Components/SectionRail/index.d.ts +2 -0
- package/dist/Components/SectionRail/index.js +8 -0
- package/dist/Components/SegmentedControl/SegmentedControl.js +9 -14
- package/dist/Components/SegmentedControl/segmentedInk.d.ts +0 -2
- package/dist/Components/SegmentedControl/segmentedInk.js +1 -5
- package/dist/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/Components/SideBar/SideBar.d.ts +1 -1
- package/dist/Components/SideBar/SideBar.js +30 -9
- package/dist/Components/SideBar/SideBarProps.d.ts +32 -0
- package/dist/Components/SideBar/components/MenuItemBox.d.ts +6 -0
- package/dist/Components/SideBar/components/MenuItemBox.js +8 -4
- package/dist/Components/SideBar/components/MenuPopoverContent.js +3 -2
- package/dist/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/Components/SideBar/components/PinnedSection.d.ts +17 -0
- package/dist/Components/SideBar/components/PinnedSection.js +98 -0
- package/dist/Components/SideBar/sidebarFocus.d.ts +23 -0
- package/dist/Components/SideBar/sidebarFocus.js +20 -0
- package/dist/Components/StageProgress/StageProgress.js +2 -2
- package/dist/Components/StageProgress/StageProgressProps.d.ts +2 -0
- package/dist/Components/StageProgress/StepperStage.js +5 -2
- package/dist/Components/StatCard/StatCard.d.ts +1 -1
- package/dist/Components/StatCard/StatCard.js +6 -2
- package/dist/Components/StatCard/StatCardProps.d.ts +3 -0
- package/dist/Components/StatusTag/StatusTag.d.ts +4 -0
- package/dist/Components/StatusTag/StatusTag.js +24 -0
- package/dist/Components/StatusTag/StatusTagProps.d.ts +20 -0
- package/dist/Components/StatusTag/StatusTagProps.js +2 -0
- package/dist/Components/Table/Table.d.ts +1 -1
- package/dist/Components/Table/Table.js +6 -2
- package/dist/Components/Table/TableProps.d.ts +20 -0
- package/dist/Components/Table/components/TableBody.d.ts +1 -1
- package/dist/Components/Table/components/TableBody.js +43 -18
- package/dist/Components/Table/components/TableHeader.d.ts +1 -1
- package/dist/Components/Table/components/TableHeader.js +7 -5
- package/dist/Components/Table/components/rowDetail.d.ts +32 -0
- package/dist/Components/Table/components/rowDetail.js +20 -0
- package/dist/Components/Table/hooks/useRowExpansion.d.ts +7 -0
- package/dist/Components/Table/hooks/useRowExpansion.js +27 -0
- package/dist/Components/Tabs/Tabs.d.ts +1 -1
- package/dist/Components/Tabs/Tabs.js +15 -2
- package/dist/Components/Tabs/TabsProps.d.ts +6 -2
- package/dist/Components/Tabs/components/Tab.js +4 -33
- package/dist/Components/Tabs/components/TabLinkList.d.ts +7 -0
- package/dist/Components/Tabs/components/TabLinkList.js +34 -0
- package/dist/Components/Tabs/useTabAppearance.d.ts +17 -0
- package/dist/Components/Tabs/useTabAppearance.js +67 -0
- package/dist/Components/Tag/Tag.js +11 -1
- package/dist/Components/Tag/TagProps.d.ts +4 -0
- package/dist/Components/Tag/tagDot.d.ts +3 -0
- package/dist/Components/Tag/tagDot.js +21 -0
- package/dist/Components/WizardDialog/WizardDialog.d.ts +9 -0
- package/dist/Components/WizardDialog/WizardDialog.js +102 -0
- package/dist/Components/WizardDialog/WizardDialogProps.d.ts +48 -0
- package/dist/Components/WizardDialog/WizardDialogProps.js +2 -0
- package/dist/Components/WizardDialog/useWizardFlow.d.ts +22 -0
- package/dist/Components/WizardDialog/useWizardFlow.js +47 -0
- package/dist/Components/WizardDialog/wizardSteps.d.ts +31 -0
- package/dist/Components/WizardDialog/wizardSteps.js +40 -0
- package/dist/esm/Components/AppSwitcher/AppSwitcher.js +2 -1
- package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +5 -3
- package/dist/esm/Components/AudioRecorder/AudioRecorder.js +161 -0
- package/dist/esm/Components/AudioRecorder/AudioRecorderProps.js +1 -0
- package/dist/esm/Components/Breadcrumbs/Breadcrumbs.js +35 -12
- package/dist/esm/Components/BulkSelectionBar/BulkSelectionBar.js +38 -0
- package/dist/esm/Components/BulkSelectionBar/BulkSelectionBarProps.js +1 -0
- package/dist/esm/Components/BulkSelectionBar/index.js +1 -0
- package/dist/esm/Components/CalendarGrid/CalendarGrid.js +168 -0
- package/dist/esm/Components/CalendarGrid/CalendarGridProps.js +1 -0
- package/dist/esm/Components/CalendarGrid/calendarMath.js +155 -0
- package/dist/esm/Components/Card/Card.js +12 -2
- package/dist/esm/Components/CircularProgress/CircularProgress.js +37 -0
- package/dist/esm/Components/CircularProgress/CircularProgressProps.js +1 -0
- package/dist/esm/Components/CircularProgress/arc.js +11 -0
- package/dist/esm/Components/Common/fieldStyles.js +2 -1
- package/dist/esm/Components/Drawer/Drawer.js +4 -2
- package/dist/esm/Components/Editor/Editor.js +48 -3
- package/dist/esm/Components/Editor/EditorFieldBar.js +13 -0
- package/dist/esm/Components/Editor/MakeDynamicDialog.js +20 -0
- package/dist/esm/Components/Editor/editorLabels.js +20 -0
- package/dist/esm/Components/Editor/editorTokenStyles.js +25 -0
- package/dist/esm/Components/Editor/editorTokens.js +121 -0
- package/dist/esm/Components/Editor/useEditorBridge.js +138 -0
- package/dist/esm/Components/EmptyState/EmptyState.js +2 -1
- package/dist/esm/Components/FormDrawer/FormDrawer.js +58 -0
- package/dist/esm/Components/FormDrawer/FormDrawerProps.js +1 -0
- package/dist/esm/Components/Kbd/Kbd.js +28 -0
- package/dist/esm/Components/Kbd/KbdProps.js +1 -0
- package/dist/esm/Components/LauncherTrigger/LauncherTrigger.js +41 -0
- package/dist/esm/Components/LauncherTrigger/LauncherTriggerProps.js +1 -0
- package/dist/esm/Components/Modal/Modal.js +4 -2
- package/dist/esm/Components/Modal/warnDroppedSlotChildren.js +38 -0
- package/dist/esm/Components/NavLauncher/NavLauncher.js +413 -0
- package/dist/esm/Components/NavLauncher/NavLauncherProps.js +1 -0
- package/dist/esm/Components/NavLauncher/NewTabLink.js +11 -0
- package/dist/esm/Components/NavLauncher/PinToggle.js +18 -0
- package/dist/esm/Components/NavLauncher/launcherParts.js +187 -0
- package/dist/esm/Components/NavLauncher/match.js +172 -0
- package/dist/esm/Components/NavLauncher/revealStyles.js +15 -0
- package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
- package/dist/esm/Components/PageHeader/PageHeader.js +9 -2
- package/dist/esm/Components/PdfViewer/PdfViewer.js +123 -2
- package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +5 -0
- package/dist/esm/Components/QueryState/QueryStateBoundary.js +10 -4
- package/dist/esm/Components/Search/Search.js +3 -2
- package/dist/esm/Components/SectionRail/SectionRail.js +44 -0
- package/dist/esm/Components/SectionRail/SectionRailProps.js +1 -0
- package/dist/esm/Components/SectionRail/index.js +1 -0
- package/dist/esm/Components/SegmentedControl/SegmentedControl.js +11 -16
- package/dist/esm/Components/SegmentedControl/segmentedInk.js +0 -3
- package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/esm/Components/SideBar/SideBar.js +31 -10
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +4 -2
- package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +3 -2
- package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/esm/Components/SideBar/components/PinnedSection.js +92 -0
- package/dist/esm/Components/SideBar/sidebarFocus.js +15 -0
- package/dist/esm/Components/StageProgress/StageProgress.js +2 -2
- package/dist/esm/Components/StageProgress/StepperStage.js +5 -2
- package/dist/esm/Components/StatCard/StatCard.js +6 -2
- package/dist/esm/Components/StatusTag/StatusTag.js +19 -0
- package/dist/esm/Components/StatusTag/StatusTagProps.js +1 -0
- package/dist/esm/Components/Table/Table.js +7 -3
- package/dist/esm/Components/Table/components/TableBody.js +43 -18
- package/dist/esm/Components/Table/components/TableHeader.js +7 -5
- package/dist/esm/Components/Table/components/rowDetail.js +14 -0
- package/dist/esm/Components/Table/hooks/useRowExpansion.js +23 -0
- package/dist/esm/Components/Tabs/Tabs.js +15 -2
- package/dist/esm/Components/Tabs/components/Tab.js +4 -33
- package/dist/esm/Components/Tabs/components/TabLinkList.js +29 -0
- package/dist/esm/Components/Tabs/useTabAppearance.js +63 -0
- package/dist/esm/Components/Tag/Tag.js +12 -2
- package/dist/esm/Components/Tag/tagDot.js +17 -0
- package/dist/esm/Components/WizardDialog/WizardDialog.js +58 -0
- package/dist/esm/Components/WizardDialog/WizardDialogProps.js +1 -0
- package/dist/esm/Components/WizardDialog/useWizardFlow.js +44 -0
- package/dist/esm/Components/WizardDialog/wizardSteps.js +35 -0
- package/dist/esm/index.js +14 -0
- package/dist/index.d.ts +35 -6
- package/dist/index.js +38 -4
- package/package.json +1 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useEditorBridge = useEditorBridge;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const editorTokens_1 = require("./editorTokens");
|
|
6
|
+
function useEditorBridge({ value, onChange, onBlur, mergeFields, syntax, chipLabel, apiRef, onReady, onUnknownTokens, }) {
|
|
7
|
+
const enabled = mergeFields !== undefined;
|
|
8
|
+
const fieldsKey = JSON.stringify(mergeFields);
|
|
9
|
+
const ctx = (0, react_1.useMemo)(() => ({ fields: mergeFields !== null && mergeFields !== void 0 ? mergeFields : [], syntax, chipLabel }),
|
|
10
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11
|
+
[fieldsKey, syntax.open, syntax.close, chipLabel]);
|
|
12
|
+
const joditRef = (0, react_1.useRef)(null);
|
|
13
|
+
const rangeRef = (0, react_1.useRef)(null);
|
|
14
|
+
const lastRef = (0, react_1.useRef)(null);
|
|
15
|
+
const appliedFieldsKey = (0, react_1.useRef)(fieldsKey);
|
|
16
|
+
const live = (0, react_1.useRef)({ enabled, ctx, onChange, onBlur, onReady, fieldsKey });
|
|
17
|
+
live.current = { enabled, ctx, onChange, onBlur, onReady, fieldsKey };
|
|
18
|
+
const [instance, setInstance] = (0, react_1.useState)(null);
|
|
19
|
+
const [raw, setRaw] = (0, react_1.useState)(value !== null && value !== void 0 ? value : "");
|
|
20
|
+
(0, react_1.useEffect)(() => {
|
|
21
|
+
if (value !== undefined)
|
|
22
|
+
setRaw(value);
|
|
23
|
+
}, [value]);
|
|
24
|
+
const handleChange = (0, react_1.useCallback)((html) => {
|
|
25
|
+
const { enabled: on, ctx: c, onChange: emit } = live.current;
|
|
26
|
+
const next = on ? (0, editorTokens_1.serializeChips)(html, c.syntax) : html;
|
|
27
|
+
lastRef.current = { raw: next, jodit: html };
|
|
28
|
+
setRaw(next);
|
|
29
|
+
emit === null || emit === void 0 ? void 0 : emit(next);
|
|
30
|
+
}, []);
|
|
31
|
+
const handleBlur = (0, react_1.useCallback)((html, event) => {
|
|
32
|
+
const { enabled: on, ctx: c, onBlur: emit } = live.current;
|
|
33
|
+
emit === null || emit === void 0 ? void 0 : emit(on ? (0, editorTokens_1.serializeChips)(html, c.syntax) : html, event);
|
|
34
|
+
}, []);
|
|
35
|
+
const attachEditor = (0, react_1.useCallback)((jodit) => {
|
|
36
|
+
joditRef.current = jodit;
|
|
37
|
+
rangeRef.current = null;
|
|
38
|
+
appliedFieldsKey.current = live.current.fieldsKey;
|
|
39
|
+
const remember = () => {
|
|
40
|
+
if (jodit.s.isInsideArea)
|
|
41
|
+
rangeRef.current = jodit.s.range.cloneRange();
|
|
42
|
+
};
|
|
43
|
+
jodit.events.on("keyup mouseup touchend", remember);
|
|
44
|
+
jodit.events.on("change", handleChange);
|
|
45
|
+
jodit.events.on("blur", (event) => handleBlur(jodit.value, event));
|
|
46
|
+
const deleteChip = (event) => {
|
|
47
|
+
if (!live.current.enabled)
|
|
48
|
+
return false;
|
|
49
|
+
if (event.key !== "Backspace" && event.key !== "Delete")
|
|
50
|
+
return false;
|
|
51
|
+
const chip = (0, editorTokens_1.adjacentChip)(jodit.s.range, event.key === "Backspace" ? "backward" : "forward");
|
|
52
|
+
if (!chip)
|
|
53
|
+
return false;
|
|
54
|
+
chip.remove();
|
|
55
|
+
jodit.synchronizeValues();
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
jodit.events.on("keydown", ((event) => (deleteChip(event) ? false : undefined)));
|
|
60
|
+
jodit.editor.addEventListener("keydown", (event) => {
|
|
61
|
+
if (deleteChip(event))
|
|
62
|
+
event.stopImmediatePropagation();
|
|
63
|
+
}, true);
|
|
64
|
+
jodit.waitForReady().then(() => {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
if (joditRef.current !== jodit)
|
|
67
|
+
return;
|
|
68
|
+
setInstance(jodit);
|
|
69
|
+
(_b = (_a = live.current).onReady) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
70
|
+
});
|
|
71
|
+
}, [handleChange, handleBlur]);
|
|
72
|
+
(0, react_1.useEffect)(() => {
|
|
73
|
+
if (!instance || !enabled || appliedFieldsKey.current === fieldsKey)
|
|
74
|
+
return;
|
|
75
|
+
appliedFieldsKey.current = fieldsKey;
|
|
76
|
+
const html = (0, editorTokens_1.chipify)((0, editorTokens_1.serializeChips)(instance.value, ctx.syntax), ctx);
|
|
77
|
+
instance.value = html;
|
|
78
|
+
lastRef.current = { raw: (0, editorTokens_1.serializeChips)(html, ctx.syntax), jodit: instance.value };
|
|
79
|
+
}, [instance, enabled, fieldsKey, ctx]);
|
|
80
|
+
const api = (0, react_1.useMemo)(() => {
|
|
81
|
+
const current = () => joditRef.current;
|
|
82
|
+
const currentRaw = (jodit) => live.current.enabled ? (0, editorTokens_1.serializeChips)(jodit.value, live.current.ctx.syntax) : jodit.value;
|
|
83
|
+
const insertHTML = (html) => {
|
|
84
|
+
const jodit = current();
|
|
85
|
+
if (!jodit)
|
|
86
|
+
return;
|
|
87
|
+
if (rangeRef.current)
|
|
88
|
+
jodit.s.selectRange(rangeRef.current, true);
|
|
89
|
+
jodit.s.insertHTML(html);
|
|
90
|
+
rangeRef.current = jodit.s.range.cloneRange();
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
insertHTML,
|
|
94
|
+
insertField: (path) => {
|
|
95
|
+
const { enabled: on, ctx: c } = live.current;
|
|
96
|
+
insertHTML(on ? (0, editorTokens_1.chipHtml)(path, c) : (0, editorTokens_1.fieldToken)(path, c.syntax));
|
|
97
|
+
},
|
|
98
|
+
getSelectionText: () => (rangeRef.current ? rangeRef.current.toString().trim() : ""),
|
|
99
|
+
replaceAll: (text, path) => {
|
|
100
|
+
const jodit = current();
|
|
101
|
+
if (!jodit)
|
|
102
|
+
return 0;
|
|
103
|
+
const { enabled: on, ctx: c, onChange: emit } = live.current;
|
|
104
|
+
const result = (0, editorTokens_1.makeDynamic)(currentRaw(jodit), text, path, c.syntax);
|
|
105
|
+
if (result.count === 0)
|
|
106
|
+
return 0;
|
|
107
|
+
jodit.value = on ? (0, editorTokens_1.chipify)(result.html, c) : result.html;
|
|
108
|
+
lastRef.current = { raw: result.html, jodit: jodit.value };
|
|
109
|
+
rangeRef.current = null;
|
|
110
|
+
setRaw(result.html);
|
|
111
|
+
emit === null || emit === void 0 ? void 0 : emit(result.html);
|
|
112
|
+
return result.count;
|
|
113
|
+
},
|
|
114
|
+
countOccurrences: (text) => {
|
|
115
|
+
const jodit = current();
|
|
116
|
+
return jodit ? (0, editorTokens_1.countOccurrences)(currentRaw(jodit), text, live.current.ctx.syntax) : 0;
|
|
117
|
+
},
|
|
118
|
+
focus: () => {
|
|
119
|
+
var _a;
|
|
120
|
+
(_a = current()) === null || _a === void 0 ? void 0 : _a.s.focus();
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}, []);
|
|
124
|
+
(0, react_1.useImperativeHandle)(apiRef, () => api, [api]);
|
|
125
|
+
const unknown = (0, react_1.useMemo)(() => (enabled ? (0, editorTokens_1.unknownTokens)(raw, ctx.fields, syntax) : []), [enabled, raw, ctx, syntax]);
|
|
126
|
+
const unknownKey = unknown.join("\n");
|
|
127
|
+
const reported = (0, react_1.useRef)("");
|
|
128
|
+
(0, react_1.useEffect)(() => {
|
|
129
|
+
if (!enabled || reported.current === unknownKey)
|
|
130
|
+
return;
|
|
131
|
+
reported.current = unknownKey;
|
|
132
|
+
onUnknownTokens === null || onUnknownTokens === void 0 ? void 0 : onUnknownTokens(unknown);
|
|
133
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
134
|
+
}, [enabled, unknownKey]);
|
|
135
|
+
const last = lastRef.current;
|
|
136
|
+
let joditValue = value;
|
|
137
|
+
if (enabled && value !== undefined) {
|
|
138
|
+
joditValue = last && last.raw === value ? last.jodit : (0, editorTokens_1.chipify)(value, ctx);
|
|
139
|
+
}
|
|
140
|
+
return { joditValue, attachEditor, api, instance, raw, unknown, ctx };
|
|
141
|
+
}
|
|
@@ -26,6 +26,7 @@ const scaleFor = (colors, scheme) => scheme === "primary" || scheme === "seconda
|
|
|
26
26
|
const EmptyState = ({ title = "No data found", titleAs = "h3", description, icon: IconComp = lucide_react_1.Inbox, image, imageAlt = "", size = "md", colorScheme = "primary", variant = "default", action, animate = false, minH = "15rem", sx, }) => {
|
|
27
27
|
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
28
28
|
const s = sizeMap[size];
|
|
29
|
+
const hasDescription = description !== undefined && description !== null && description !== false && description !== "";
|
|
29
30
|
const palette = scaleFor(theme.colors, colorScheme);
|
|
30
31
|
const tone = (0, tone_1.resolveSoftTone)(theme.colors, palette, theme.colors.background[50]);
|
|
31
32
|
const accentSoft = tone.bg;
|
|
@@ -48,6 +49,6 @@ const EmptyState = ({ title = "No data found", titleAs = "h3", description, icon
|
|
|
48
49
|
bg: accentSoft,
|
|
49
50
|
opacity: HALO_OPACITY,
|
|
50
51
|
zIndex: -1,
|
|
51
|
-
}, sx: (0, motion_1.reducedMotionSx)(), children: (0, jsx_runtime_1.jsx)(IconComp, { size: s.icon, strokeWidth: 1.75, "aria-hidden": true }) })), (0, jsx_runtime_1.jsxs)(react_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_1.Text, { as: titleAs, fontSize: s.title, fontWeight: 600, color: theme.colors.header[900], mt: 1, children: title }),
|
|
52
|
+
}, sx: (0, motion_1.reducedMotionSx)(), children: (0, jsx_runtime_1.jsx)(IconComp, { size: s.icon, strokeWidth: 1.75, "aria-hidden": true }) })), (0, jsx_runtime_1.jsxs)(react_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_1.Text, { as: titleAs, fontSize: s.title, fontWeight: 600, color: theme.colors.header[900], mt: 1, children: title }), hasDescription && ((0, jsx_runtime_1.jsx)(react_1.Text, { as: typeof description === "string" ? undefined : "div", fontSize: s.desc, color: theme.colors.textMuted, mt: 1, maxW: "23.75rem", children: description }))] }), action && ((0, jsx_runtime_1.jsx)(react_1.Flex, { gap: 3, mt: 2, wrap: "wrap", justify: "center", children: action }))] }));
|
|
52
53
|
};
|
|
53
54
|
exports.default = EmptyState;
|
|
@@ -10,8 +10,8 @@ export interface EmptyStateProps {
|
|
|
10
10
|
title?: string;
|
|
11
11
|
/** Heading element for the title; defaults to "h3" — pick the level that fits the page outline. */
|
|
12
12
|
titleAs?: "h2" | "h3" | "h4" | "h5" | "h6" | "p";
|
|
13
|
-
/** Supporting
|
|
14
|
-
description?:
|
|
13
|
+
/** Supporting text under the title; a node (bold, link) is wrapped in the same muted block and renders above `action`. */
|
|
14
|
+
description?: ReactNode;
|
|
15
15
|
/** A lucide-react (or any) icon component rendered inside the badge. */
|
|
16
16
|
icon?: ElementType;
|
|
17
17
|
/** Illustration image URL. When provided it replaces the icon badge. */
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { FormDrawerProps } from "./FormDrawerProps";
|
|
2
|
+
export default function FormDrawer({ isOpen, onClose, title, description, sections, errors, isDirty, onSubmit, isSubmitting, submitLabel, cancelLabel, secondaryAction, size, labels, "data-testid": testId, }: FormDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.default = FormDrawer;
|
|
40
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
41
|
+
const react_1 = require("react");
|
|
42
|
+
const react_2 = require("@chakra-ui/react");
|
|
43
|
+
const Drawer_1 = __importStar(require("../Drawer/Drawer"));
|
|
44
|
+
const AlertDialog_1 = __importDefault(require("../AlertDialog/AlertDialog"));
|
|
45
|
+
const Button_1 = __importDefault(require("../Button/Button"));
|
|
46
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
47
|
+
const DEFAULT_LABELS = {
|
|
48
|
+
fixErrors: "Please fix the following before saving",
|
|
49
|
+
discardTitle: "Discard changes?",
|
|
50
|
+
discardBody: "You have unsaved changes. If you close now, they will be lost.",
|
|
51
|
+
discard: "Discard",
|
|
52
|
+
keepEditing: "Keep editing",
|
|
53
|
+
};
|
|
54
|
+
function FormDrawer({ isOpen, onClose, title, description, sections, errors = [], isDirty, onSubmit, isSubmitting = false, submitLabel = "Save", cancelLabel = "Cancel", secondaryAction, size = "md", labels, "data-testid": testId = "form-drawer", }) {
|
|
55
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
56
|
+
const uid = (0, react_1.useId)();
|
|
57
|
+
const formId = `${uid}-form`;
|
|
58
|
+
const titleId = `${uid}-title`;
|
|
59
|
+
const text = { ...DEFAULT_LABELS, ...labels };
|
|
60
|
+
const [confirmDiscard, setConfirmDiscard] = (0, react_1.useState)(false);
|
|
61
|
+
const [attempt, setAttempt] = (0, react_1.useState)(0);
|
|
62
|
+
const keepEditingRef = (0, react_1.useRef)(null);
|
|
63
|
+
const summaryRef = (0, react_1.useRef)(null);
|
|
64
|
+
const focusPending = (0, react_1.useRef)(false);
|
|
65
|
+
(0, react_1.useEffect)(() => {
|
|
66
|
+
if (!isOpen)
|
|
67
|
+
setConfirmDiscard(false);
|
|
68
|
+
}, [isOpen]);
|
|
69
|
+
(0, react_1.useEffect)(() => {
|
|
70
|
+
var _a;
|
|
71
|
+
if (!focusPending.current || isSubmitting)
|
|
72
|
+
return;
|
|
73
|
+
focusPending.current = false;
|
|
74
|
+
if (errors.length)
|
|
75
|
+
(_a = summaryRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
76
|
+
}, [attempt, errors, isSubmitting]);
|
|
77
|
+
const requestClose = () => {
|
|
78
|
+
if (isSubmitting)
|
|
79
|
+
return;
|
|
80
|
+
if (isDirty)
|
|
81
|
+
setConfirmDiscard(true);
|
|
82
|
+
else
|
|
83
|
+
onClose();
|
|
84
|
+
};
|
|
85
|
+
const submit = (event) => {
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
if (isSubmitting)
|
|
88
|
+
return;
|
|
89
|
+
focusPending.current = true;
|
|
90
|
+
setAttempt((n) => n + 1);
|
|
91
|
+
onSubmit();
|
|
92
|
+
};
|
|
93
|
+
return ((0, jsx_runtime_1.jsxs)(Drawer_1.default, { isOpen: isOpen, onClose: requestClose, size: size, closeOnEsc: !isSubmitting, closeOnOverlayClick: !isSubmitting, portalChildren: (0, jsx_runtime_1.jsx)(AlertDialog_1.default, { isOpen: confirmDiscard, onClose: () => setConfirmDiscard(false), leastDestructiveRef: keepEditingRef, isCentered: true, tone: "danger", title: text.discardTitle, content: (0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "sm", color: colors.text[800], children: text.discardBody }), cancelButtonText: text.keepEditing, confirmButtonText: text.discard, onConfirm: () => {
|
|
94
|
+
setConfirmDiscard(false);
|
|
95
|
+
onClose();
|
|
96
|
+
} }), children: [(0, jsx_runtime_1.jsxs)(Drawer_1.DrawerHeader, { children: [(0, jsx_runtime_1.jsx)(react_2.Heading, { id: titleId, as: "h2", fontSize: "md", fontWeight: 600, color: colors.header[900], children: title }), description ? ((0, jsx_runtime_1.jsx)(react_2.Text, { mt: 0.5, fontSize: "sm", fontWeight: 400, color: colors.textMuted, children: description })) : null] }), (0, jsx_runtime_1.jsx)(Drawer_1.DrawerBody, { children: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "form", id: formId, "aria-labelledby": titleId, onSubmit: submit, noValidate: true, "data-testid": testId, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { direction: "column", gap: 5, pt: 2, children: [errors.length ? ((0, jsx_runtime_1.jsxs)(react_2.Alert, { ref: summaryRef, tabIndex: -1, status: "error", variant: "subtle", borderRadius: "md", alignItems: "flex-start", "data-testid": `${testId}-errors`, children: [(0, jsx_runtime_1.jsx)(react_2.AlertIcon, {}), (0, jsx_runtime_1.jsxs)(react_2.Box, { children: [(0, jsx_runtime_1.jsx)(react_2.AlertTitle, { fontSize: "sm", children: text.fixErrors }), (0, jsx_runtime_1.jsx)(react_2.AlertDescription, { fontSize: "sm", children: (0, jsx_runtime_1.jsx)(react_2.UnorderedList, { mt: 1, children: errors.map((message) => ((0, jsx_runtime_1.jsx)(react_2.ListItem, { children: message }, message))) }) })] })] })) : null, sections.map((section, index) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [index > 0 ? (0, jsx_runtime_1.jsx)(react_2.Divider, { borderColor: colors.boxborder[200] }) : null, (0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "section", direction: "column", gap: 4, "aria-label": section.title, children: [section.title ? ((0, jsx_runtime_1.jsxs)(react_2.Box, { children: [(0, jsx_runtime_1.jsx)(react_2.Heading, { as: "h3", fontSize: "sm", fontWeight: 600, color: colors.header[900], children: section.title }), section.description ? ((0, jsx_runtime_1.jsx)(react_2.Text, { mt: 0.5, fontSize: "xs", color: colors.textMuted, children: section.description })) : null] })) : null, section.content] })] }, section.id)))] }) }) }), (0, jsx_runtime_1.jsx)(Drawer_1.DrawerFooter, { children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { gap: 2, w: "100%", justify: "flex-end", wrap: "wrap", children: [secondaryAction, (0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", colorScheme: "gray", onClick: requestClose, isDisabled: isSubmitting, label: cancelLabel }), (0, jsx_runtime_1.jsx)(Button_1.default, { variant: "solid", colorScheme: "primary", type: "submit", form: formId, isLoading: isSubmitting, loadingText: submitLabel, label: submitLabel, "data-testid": `${testId}-submit` })] }) })] }));
|
|
97
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** One block of the form; sections after the first are separated by a divider. */
|
|
3
|
+
export type FormDrawerSection = {
|
|
4
|
+
/** Stable React key. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Renders an h3 above the content; also names the section region. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Muted line under `title`; ignored without a title. */
|
|
9
|
+
description?: string;
|
|
10
|
+
content: ReactNode;
|
|
11
|
+
};
|
|
12
|
+
/** Every user-facing string FormDrawer owns; pass the ones you localise. */
|
|
13
|
+
export type FormDrawerLabels = {
|
|
14
|
+
/** Heading of the error summary. Defaults to "Please fix the following before saving". */
|
|
15
|
+
fixErrors: string;
|
|
16
|
+
/** Defaults to "Discard changes?". */
|
|
17
|
+
discardTitle: string;
|
|
18
|
+
/** Defaults to "You have unsaved changes. If you close now, they will be lost.". */
|
|
19
|
+
discardBody: string;
|
|
20
|
+
/** Confirm button of the discard dialog. Defaults to "Discard". */
|
|
21
|
+
discard: string;
|
|
22
|
+
/** Cancel button of the discard dialog, focused on open. Defaults to "Keep editing". */
|
|
23
|
+
keepEditing: string;
|
|
24
|
+
};
|
|
25
|
+
/** Sectioned create/edit form in a Drawer: error summary, sticky footer, and a discard-changes confirm when closing while dirty. */
|
|
26
|
+
export interface FormDrawerProps {
|
|
27
|
+
isOpen: boolean;
|
|
28
|
+
/** Called once the user has really closed: clean close, or Discard confirmed. Never called while `isSubmitting`. */
|
|
29
|
+
onClose: () => void;
|
|
30
|
+
/** Drawer heading; also the accessible name of the dialog and of the form. */
|
|
31
|
+
title: string;
|
|
32
|
+
/** Muted line under the title. */
|
|
33
|
+
description?: string;
|
|
34
|
+
sections: FormDrawerSection[];
|
|
35
|
+
/** Validation messages shown as a summary above the form; the summary takes focus after a submit that leaves any. */
|
|
36
|
+
errors?: string[];
|
|
37
|
+
/** Closing (X, Esc, overlay, Cancel) asks for confirmation while true. */
|
|
38
|
+
isDirty: boolean;
|
|
39
|
+
/** Fires on submit (button or Enter in a field); the browser's own validation is off, so validate in the handler. */
|
|
40
|
+
onSubmit: () => void;
|
|
41
|
+
/** Spins the submit button, disables Cancel and blocks every close path. Set it synchronously in `onSubmit` so error focus waits for the result. */
|
|
42
|
+
isSubmitting?: boolean;
|
|
43
|
+
/** Defaults to "Save". */
|
|
44
|
+
submitLabel?: string;
|
|
45
|
+
/** Defaults to "Cancel". */
|
|
46
|
+
cancelLabel?: string;
|
|
47
|
+
/** Rendered left of Cancel, e.g. a ghost "Save as draft" Button. */
|
|
48
|
+
secondaryAction?: ReactNode;
|
|
49
|
+
/** Drawer width. Defaults to "md". */
|
|
50
|
+
size?: "sm" | "md" | "lg";
|
|
51
|
+
/** Overrides for the built-in strings. */
|
|
52
|
+
labels?: Partial<FormDrawerLabels>;
|
|
53
|
+
/** Set on the form; the error summary and submit button get `-errors` / `-submit` suffixes. Defaults to "form-drawer". */
|
|
54
|
+
"data-testid"?: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { KbdProps, KbdShortcutProps } from "./KbdProps";
|
|
2
|
+
export declare const detectApple: () => boolean;
|
|
3
|
+
/** One keyboard key cap; decorative hint rows should wrap it in `aria-hidden`. */
|
|
4
|
+
declare const Kbd: ({ children, size, "data-testid": testId }: KbdProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare const KbdShortcut: ({ shortcut, size, isApple, "data-testid": testId }: KbdShortcutProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default Kbd;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KbdShortcut = exports.detectApple = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("@chakra-ui/react");
|
|
6
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
7
|
+
const AppSwitcherProps_1 = require("../AppSwitcher/AppSwitcherProps");
|
|
8
|
+
const HEIGHT = { xs: "1rem", sm: "1.25rem" };
|
|
9
|
+
const SPOKEN = {
|
|
10
|
+
mod: "Command",
|
|
11
|
+
cmd: "Command",
|
|
12
|
+
ctrl: "Control",
|
|
13
|
+
alt: "Option",
|
|
14
|
+
shift: "Shift",
|
|
15
|
+
enter: "Enter",
|
|
16
|
+
esc: "Escape",
|
|
17
|
+
};
|
|
18
|
+
const detectApple = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform);
|
|
19
|
+
exports.detectApple = detectApple;
|
|
20
|
+
/** One keyboard key cap; decorative hint rows should wrap it in `aria-hidden`. */
|
|
21
|
+
const Kbd = ({ children, size = "sm", "data-testid": testId }) => {
|
|
22
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
23
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "kbd", "data-testid": testId, display: "inline-flex", alignItems: "center", justifyContent: "center", minW: HEIGHT[size], h: HEIGHT[size], px: 1.5, fontFamily: "inherit", fontSize: "0.6875rem", fontWeight: 600, lineHeight: 1, whiteSpace: "nowrap", borderWidth: "1px", borderColor: colors.boxborder[200], borderRadius: "base", bg: colors.backgroundColor.subtle, color: colors.textMuted, children: children }));
|
|
24
|
+
};
|
|
25
|
+
const KbdShortcut = ({ shortcut, size, isApple, "data-testid": testId }) => {
|
|
26
|
+
const parts = shortcut.split("+").map((p) => p.trim()).filter(Boolean);
|
|
27
|
+
const apple = isApple !== null && isApple !== void 0 ? isApple : (0, exports.detectApple)();
|
|
28
|
+
const spoken = parts.map((p) => { var _a; return (_a = SPOKEN[p.toLowerCase()]) !== null && _a !== void 0 ? _a : p.toUpperCase(); }).join(" ");
|
|
29
|
+
const keys = (0, AppSwitcherProps_1.shortcutKeys)(shortcut, apple);
|
|
30
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "span", display: "inline-flex", gap: 1, role: "img", "aria-label": spoken, "data-testid": testId, children: keys.map((key, i) => ((0, jsx_runtime_1.jsx)(Kbd, { size: size, children: key }, `${key}-${i}`))) }));
|
|
31
|
+
};
|
|
32
|
+
exports.KbdShortcut = KbdShortcut;
|
|
33
|
+
exports.default = Kbd;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** Props for a single keyboard key cap. */
|
|
3
|
+
export interface KbdProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** `sm` is 20px tall (default); `xs` is 16px. */
|
|
6
|
+
size?: "xs" | "sm";
|
|
7
|
+
"data-testid"?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Props for a key chord such as `mod+k`, rendered as one `Kbd` per key. */
|
|
10
|
+
export interface KbdShortcutProps {
|
|
11
|
+
/** Chord in `AppSwitcher` notation, e.g. `mod+shift+k`. */
|
|
12
|
+
shortcut: string;
|
|
13
|
+
size?: KbdProps["size"];
|
|
14
|
+
/** Forces Apple glyphs (⌘ ⇧) or Ctrl/Shift words; defaults to platform detection. */
|
|
15
|
+
isApple?: boolean;
|
|
16
|
+
"data-testid"?: string;
|
|
17
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LauncherTriggerProps } from "./LauncherTriggerProps";
|
|
2
|
+
export declare const keyShortcutsFor: (shortcut: string) => string;
|
|
3
|
+
declare const LauncherTrigger: ({ onClick, isOpen, label, shortcut, icon: Icon, display, "aria-label": ariaLabel, "data-testid": testId, }: LauncherTriggerProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default LauncherTrigger;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.keyShortcutsFor = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("@chakra-ui/react");
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
11
|
+
const motion_1 = require("../../Theme/chakra/motion");
|
|
12
|
+
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
13
|
+
const motion_2 = require("../../Theme/tokens/primitives/motion");
|
|
14
|
+
const useMatchMedia_1 = require("../../Hooks/useMatchMedia");
|
|
15
|
+
const Kbd_1 = require("../Kbd/Kbd");
|
|
16
|
+
const AppSwitcherProps_1 = require("../AppSwitcher/AppSwitcherProps");
|
|
17
|
+
const ToolTip_1 = __importDefault(require("../ToolTip/ToolTip"));
|
|
18
|
+
const MD_QUERY = "(min-width: 48em)";
|
|
19
|
+
const KEY_NAMES = {
|
|
20
|
+
mod: ["Meta", "Control"],
|
|
21
|
+
cmd: ["Meta"],
|
|
22
|
+
ctrl: ["Control"],
|
|
23
|
+
alt: ["Alt"],
|
|
24
|
+
shift: ["Shift"],
|
|
25
|
+
esc: ["Escape"],
|
|
26
|
+
};
|
|
27
|
+
const keyShortcutsFor = (shortcut) => {
|
|
28
|
+
const options = shortcut
|
|
29
|
+
.split("+")
|
|
30
|
+
.map((p) => p.trim())
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.map((p) => { var _a; return (_a = KEY_NAMES[p.toLowerCase()]) !== null && _a !== void 0 ? _a : [p.length === 1 ? p.toUpperCase() : p]; });
|
|
33
|
+
const variants = Math.max(1, ...options.map((o) => o.length));
|
|
34
|
+
const chords = Array.from({ length: variants }, (_, v) => options.map((o) => o[Math.min(v, o.length - 1)]).join("+"));
|
|
35
|
+
return Array.from(new Set(chords)).join(" ");
|
|
36
|
+
};
|
|
37
|
+
exports.keyShortcutsFor = keyShortcutsFor;
|
|
38
|
+
const LauncherTrigger = ({ onClick, isOpen, label = "Menu", shortcut = "mod+k", icon: Icon = lucide_react_1.Compass, display = "chip", "aria-label": ariaLabel, "data-testid": testId, }) => {
|
|
39
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
40
|
+
const showHint = (0, useMatchMedia_1.useMatchMedia)(MD_QUERY, true);
|
|
41
|
+
const ring = (0, focusRing_styles_1.focusVisibleRing)(colors);
|
|
42
|
+
const hint = shortcut ? (0, AppSwitcherProps_1.formatShortcut)(shortcut, (0, Kbd_1.detectApple)()) : "";
|
|
43
|
+
if (display === "icon") {
|
|
44
|
+
return ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: hint ? `${label} (${hint})` : label, placement: "bottom", children: (0, jsx_runtime_1.jsx)(react_1.Box, { as: "button", type: "button", "data-testid": testId, onClick: onClick, "aria-haspopup": "dialog", "aria-expanded": isOpen, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : label, "aria-keyshortcuts": shortcut ? (0, exports.keyShortcutsFor)(shortcut) : undefined, display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0, w: "36px", h: "36px", borderRadius: "10px", borderWidth: "1px", borderColor: colors.primary[100], bg: colors.primary[50], color: colors.accentText, cursor: "pointer", transition: (0, motion_2.transitionFor)(["background-color", "border-color", "box-shadow"]), _hover: { borderColor: colors.primary[300] }, sx: { _focusVisible: ring, [focusRing_styles_1.FOCUS_VISIBLE_OVER_STATE]: ring, ...(0, motion_1.reducedMotionSx)() }, children: (0, jsx_runtime_1.jsx)(Icon, { size: 17, "aria-hidden": "true" }) }) }));
|
|
45
|
+
}
|
|
46
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Box, { as: "button", type: "button", "data-testid": testId, onClick: onClick, "aria-haspopup": "dialog", "aria-expanded": isOpen, "aria-label": ariaLabel, "aria-keyshortcuts": shortcut ? (0, exports.keyShortcutsFor)(shortcut) : undefined, display: "inline-flex", alignItems: "center", gap: 2, flexShrink: 0, h: "2.25rem", pl: "0.625rem", pr: "0.375rem", borderRadius: "10px", borderWidth: "1px", borderColor: colors.primary[100], bg: colors.primary[50], color: colors.accentText, fontSize: "0.84375rem", fontWeight: 600, lineHeight: 1, cursor: "pointer", transition: (0, motion_2.transitionFor)(["background-color", "border-color", "box-shadow"]), _hover: { borderColor: colors.primary[300] }, sx: { _focusVisible: ring, [focusRing_styles_1.FOCUS_VISIBLE_OVER_STATE]: ring, ...(0, motion_1.reducedMotionSx)() }, children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { as: "span", display: "inline-flex", alignItems: "center", gap: 2, "aria-hidden": ariaLabel ? true : undefined, children: [(0, jsx_runtime_1.jsx)(Icon, { size: 17, "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("span", { children: label })] }), hint && showHint && ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "kbd", "aria-hidden": "true", fontFamily: "inherit", fontSize: "0.6875rem", fontWeight: 600, lineHeight: "normal", px: "6px", py: "2px", borderRadius: "6px", borderWidth: "1px", borderColor: colors.primary[100], bg: colors.surfaceRaised, children: hint }))] }));
|
|
47
|
+
};
|
|
48
|
+
exports.default = LauncherTrigger;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ElementType } from "react";
|
|
2
|
+
/** Props for the chip that opens an app-owned launcher; it renders the trigger only and binds no shortcut. */
|
|
3
|
+
export interface LauncherTriggerProps {
|
|
4
|
+
onClick: () => void;
|
|
5
|
+
/** Whether the launcher is open; drives `aria-expanded`. */
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
/** Visible text. Default "Menu". */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Chord in `AppSwitcher` notation shown as a hint above `md` and exposed as `aria-keyshortcuts`; `null` hides both. Default "mod+k". */
|
|
10
|
+
shortcut?: string | null;
|
|
11
|
+
/** Component rendered at 17px before the label. Default lucide `Compass`. */
|
|
12
|
+
icon?: ElementType;
|
|
13
|
+
/** `"chip"` shows icon, label and chord hint; `"icon"` is a 36px square whose label is the accessible name and tooltip. Default "chip". */
|
|
14
|
+
display?: "chip" | "icon";
|
|
15
|
+
/** Overrides the accessible name; the visible label and hint then become `aria-hidden`. */
|
|
16
|
+
"aria-label"?: string;
|
|
17
|
+
"data-testid"?: string;
|
|
18
|
+
}
|
|
@@ -3,4 +3,4 @@ import { ChakraModelProps, ModalHeaderSlotProps, ModalBodySlotProps, ModalFooter
|
|
|
3
3
|
export declare const ModalHeader: React.FC<ModalHeaderSlotProps>;
|
|
4
4
|
export declare const ModalBody: React.FC<ModalBodySlotProps>;
|
|
5
5
|
export declare const ModalFooter: React.FC<ModalFooterSlotProps>;
|
|
6
|
-
export default function Modal({ size, isOpen, onClose, overlaybg, overlaybackdropFilter, overlaybackdropInvert, overlaybackdropBlur, isCentered, finalFocusRef, blockScrollOnMount, initialFocusRef, closeOnOverlayClick, closeOnEsc, trapFocus, motionPreset, scrollBehavior, children, isLoading, title, subtitle, hideCloseButton, contentProps, }: ChakraModelProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default function Modal({ size, isOpen, onClose, overlaybg, overlaybackdropFilter, overlaybackdropInvert, overlaybackdropBlur, isCentered, finalFocusRef, blockScrollOnMount, initialFocusRef, closeOnOverlayClick, closeOnEsc, trapFocus, motionPreset, scrollBehavior, children, isLoading, title, subtitle, hideCloseButton, contentProps, portalChildren, }: ChakraModelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,6 +9,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
9
9
|
const react_1 = __importDefault(require("react"));
|
|
10
10
|
const react_2 = require("@chakra-ui/react");
|
|
11
11
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
12
|
+
const warnDroppedSlotChildren_1 = require("./warnDroppedSlotChildren");
|
|
12
13
|
const ModalHeader = ({ children }) => {
|
|
13
14
|
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
14
15
|
};
|
|
@@ -37,12 +38,13 @@ const findSlot = (children, slot) => {
|
|
|
37
38
|
}
|
|
38
39
|
return undefined;
|
|
39
40
|
};
|
|
40
|
-
function Modal({ size, isOpen = false, onClose, overlaybg, overlaybackdropFilter, overlaybackdropInvert, overlaybackdropBlur, isCentered, finalFocusRef, blockScrollOnMount = true, initialFocusRef, closeOnOverlayClick = true, closeOnEsc = true, trapFocus = true, motionPreset = "scale", scrollBehavior = "outside", children, isLoading, title, subtitle, hideCloseButton, contentProps, }) {
|
|
41
|
+
function Modal({ size, isOpen = false, onClose, overlaybg, overlaybackdropFilter, overlaybackdropInvert, overlaybackdropBlur, isCentered, finalFocusRef, blockScrollOnMount = true, initialFocusRef, closeOnOverlayClick = true, closeOnEsc = true, trapFocus = true, motionPreset = "scale", scrollBehavior = "outside", children, isLoading, title, subtitle, hideCloseButton, contentProps, portalChildren, }) {
|
|
41
42
|
var _a, _b;
|
|
42
43
|
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
43
44
|
const headerSlot = findSlot(children, exports.ModalHeader);
|
|
44
45
|
const bodySlot = findSlot(children, exports.ModalBody);
|
|
45
46
|
const footerSlot = findSlot(children, exports.ModalFooter);
|
|
47
|
+
(0, warnDroppedSlotChildren_1.warnDroppedSlotChildren)("Modal", children, [exports.ModalHeader, exports.ModalBody, exports.ModalFooter]);
|
|
46
48
|
const headerContent = headerSlot !== null && headerSlot !== void 0 ? headerSlot : title;
|
|
47
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.Modal, { isOpen: isOpen, onClose: onClose, size: size, isCentered: isCentered, finalFocusRef: finalFocusRef, blockScrollOnMount: blockScrollOnMount, initialFocusRef: initialFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, trapFocus: trapFocus, motionPreset: motionPreset, scrollBehavior: scrollBehavior, children: [(0, jsx_runtime_1.jsx)(react_2.ModalOverlay, { bg: overlaybg, backdropFilter: overlaybackdropFilter, backdropInvert: overlaybackdropInvert, backdropBlur: overlaybackdropBlur }), (0, jsx_runtime_1.jsxs)(react_2.ModalContent, { "aria-busy": isLoading || undefined, ...contentProps, children: [(headerContent || subtitle) && ((0, jsx_runtime_1.jsxs)(react_2.ModalHeader, { ...((_a = headerSlot === null || headerSlot === void 0 ? void 0 : headerSlot.props) !== null && _a !== void 0 ? _a : {}), children: [headerContent, subtitle && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "div", mt: 0.5, fontSize: "0.875rem", fontWeight: 400, color: colors.textMuted, children: subtitle }))] })), !hideCloseButton && (0, jsx_runtime_1.jsx)(react_2.ModalCloseButton, {}), isLoading ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { role: "status", "aria-label": "Loading", justify: "center", align: "center", py: 16, children: (0, jsx_runtime_1.jsx)(react_2.Spinner, { thickness: "4px", speed: "0.65s", emptyColor: colors.boxborder[200], color: colors.accentText, size: "xl" }) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.ModalBody, { ...((_b = bodySlot === null || bodySlot === void 0 ? void 0 : bodySlot.props) !== null && _b !== void 0 ? _b : {}), children: bodySlot }), footerSlot && ((0, jsx_runtime_1.jsx)(react_2.ModalFooter, { ...footerSlot.props, children: footerSlot }))] }))] })] }));
|
|
49
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Modal, { isOpen: isOpen, onClose: onClose, size: size, isCentered: isCentered, finalFocusRef: finalFocusRef, blockScrollOnMount: blockScrollOnMount, initialFocusRef: initialFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, trapFocus: trapFocus, motionPreset: motionPreset, scrollBehavior: scrollBehavior, children: [(0, jsx_runtime_1.jsx)(react_2.ModalOverlay, { bg: overlaybg, backdropFilter: overlaybackdropFilter, backdropInvert: overlaybackdropInvert, backdropBlur: overlaybackdropBlur }), (0, jsx_runtime_1.jsxs)(react_2.ModalContent, { "aria-busy": isLoading || undefined, ...contentProps, children: [(headerContent || subtitle) && ((0, jsx_runtime_1.jsxs)(react_2.ModalHeader, { ...((_a = headerSlot === null || headerSlot === void 0 ? void 0 : headerSlot.props) !== null && _a !== void 0 ? _a : {}), children: [headerContent, subtitle && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "div", mt: 0.5, fontSize: "0.875rem", fontWeight: 400, color: colors.textMuted, children: subtitle }))] })), !hideCloseButton && (0, jsx_runtime_1.jsx)(react_2.ModalCloseButton, {}), isLoading ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { role: "status", "aria-label": "Loading", justify: "center", align: "center", py: 16, children: (0, jsx_runtime_1.jsx)(react_2.Spinner, { thickness: "4px", speed: "0.65s", emptyColor: colors.boxborder[200], color: colors.accentText, size: "xl" }) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.ModalBody, { ...((_b = bodySlot === null || bodySlot === void 0 ? void 0 : bodySlot.props) !== null && _b !== void 0 ? _b : {}), children: bodySlot }), footerSlot && ((0, jsx_runtime_1.jsx)(react_2.ModalFooter, { ...footerSlot.props, children: footerSlot }))] })), portalChildren] })] }));
|
|
48
50
|
}
|
|
@@ -7,7 +7,7 @@ export type ChakraModelProps = Pick<ModalProps, "isOpen" | "onClose" | "finalFoc
|
|
|
7
7
|
overlaybackdropInvert?: string;
|
|
8
8
|
overlaybackdropBlur?: string;
|
|
9
9
|
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "full";
|
|
10
|
-
/** Only ModalHeader/ModalBody/ModalFooter render, matched by type one fragment deep; any other
|
|
10
|
+
/** Only ModalHeader/ModalBody/ModalFooter render, matched by type one fragment deep; any other child is dropped (dev console.warn) — use `portalChildren`. */
|
|
11
11
|
children?: React.ReactNode;
|
|
12
12
|
/** Spinner replaces body and footer; header and close button stay. */
|
|
13
13
|
isLoading?: boolean;
|
|
@@ -18,6 +18,8 @@ export type ChakraModelProps = Pick<ModalProps, "isOpen" | "onClose" | "finalFoc
|
|
|
18
18
|
hideCloseButton?: boolean;
|
|
19
19
|
/** Spread onto ModalContent last, so it overrides `aria-busy` and theme styles. */
|
|
20
20
|
contentProps?: ModalContentProps;
|
|
21
|
+
/** Rendered inside the modal's dialog after the slots (so live regions stay announced); nested dialogs portal out and keep focus here. Unmounts with the modal. */
|
|
22
|
+
portalChildren?: React.ReactNode;
|
|
21
23
|
};
|
|
22
24
|
/** Chakra style props (padding, borderBottom, gap, sx, ...) spread onto the rendered ModalHeader; omit to keep theme defaults. */
|
|
23
25
|
export type ModalHeaderSlotProps = ModalHeaderProps;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.warnDroppedSlotChildren = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const warned = new Set();
|
|
9
|
+
const nameOf = (type) => {
|
|
10
|
+
if (typeof type === "string")
|
|
11
|
+
return type;
|
|
12
|
+
const fn = type;
|
|
13
|
+
return (fn === null || fn === void 0 ? void 0 : fn.displayName) || (fn === null || fn === void 0 ? void 0 : fn.name) || "Component";
|
|
14
|
+
};
|
|
15
|
+
const collect = (children, slots, dropped) => {
|
|
16
|
+
for (const child of react_1.default.Children.toArray(children)) {
|
|
17
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
18
|
+
if (String(child).trim())
|
|
19
|
+
dropped.set("#text", "text");
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (!react_1.default.isValidElement(child))
|
|
23
|
+
continue;
|
|
24
|
+
if (slots.includes(child.type))
|
|
25
|
+
continue;
|
|
26
|
+
if (child.type === react_1.default.Fragment) {
|
|
27
|
+
collect(child.props.children, slots, dropped);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
dropped.set(child.type, nameOf(child.type));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const warnDroppedSlotChildren = (owner, children, slots) => {
|
|
34
|
+
if (process.env.NODE_ENV === "production")
|
|
35
|
+
return;
|
|
36
|
+
const dropped = new Map();
|
|
37
|
+
collect(children, slots, dropped);
|
|
38
|
+
dropped.forEach((name, type) => {
|
|
39
|
+
if (warned.has(type))
|
|
40
|
+
return;
|
|
41
|
+
warned.add(type);
|
|
42
|
+
console.warn(`[pixelize-design-library] ${owner}: <${name}> is not a ${owner}Header/${owner}Body/${owner}Footer slot and was dropped. Pass nested dialogs and live regions through the portalChildren prop.`);
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
exports.warnDroppedSlotChildren = warnDroppedSlotChildren;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NavLauncherProps } from "./NavLauncherProps";
|
|
2
|
+
/** Left-drawer navigation launcher: browse every module, pins, Frequent, Recent, search and (compact) the suite's apps. */
|
|
3
|
+
export default function NavLauncher({ isOpen, onClose, sections: rawSections, pinnedIds, frequentIds, recentIds, onTogglePin, onNavigate, linkAs, actions, extraResults, query: controlledQuery, onQueryChange, isSearching, isLoading, keyScreenLimit, frequentLimit, suggestions, searchHint, openShortcutHint, modKeyLabel, maxWidth, labels: labelOverrides, apps, currentAppId, onAppSelect, appsVisibility, "data-testid": testId, }: NavLauncherProps): import("react/jsx-runtime").JSX.Element;
|