pixelize-design-library 2.4.2-beta.59 → 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 +78 -9
- package/COMPONENT-GOTCHAS.md +118 -17
- package/DESIGN-GUIDE.md +17 -6
- 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/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/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/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/LauncherTrigger/LauncherTrigger.d.ts +1 -1
- package/dist/Components/LauncherTrigger/LauncherTrigger.js +8 -1
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.d.ts +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.js +83 -26
- package/dist/Components/NavLauncher/NavLauncherProps.d.ts +6 -6
- package/dist/Components/NavLauncher/launcherParts.d.ts +60 -1
- package/dist/Components/NavLauncher/launcherParts.js +93 -11
- 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/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/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/esm/Components/AudioRecorder/AudioRecorder.js +161 -0
- package/dist/esm/Components/AudioRecorder/AudioRecorderProps.js +1 -0
- 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/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/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/LauncherTrigger/LauncherTrigger.js +5 -1
- 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 +85 -28
- package/dist/esm/Components/NavLauncher/launcherParts.js +88 -11
- package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +5 -0
- package/dist/esm/Components/QueryState/QueryStateBoundary.js +10 -4
- 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/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/index.js +7 -0
- package/dist/index.d.ts +16 -2
- package/dist/index.js +18 -4
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CircularProgressSize } from "./CircularProgressProps";
|
|
2
|
+
export declare const SIZE_PX: Record<CircularProgressSize, number>;
|
|
3
|
+
export declare const THICKNESS_PX: Record<CircularProgressSize, number>;
|
|
4
|
+
export declare const clampValue: (value: number, max: number) => number;
|
|
5
|
+
export declare const arcGeometry: (diameter: number, thickness: number, value: number, max: number) => {
|
|
6
|
+
radius: number;
|
|
7
|
+
circumference: number;
|
|
8
|
+
fraction: number;
|
|
9
|
+
clamped: number;
|
|
10
|
+
safeMax: number;
|
|
11
|
+
dashOffset: number;
|
|
12
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.arcGeometry = exports.clampValue = exports.THICKNESS_PX = exports.SIZE_PX = void 0;
|
|
4
|
+
exports.SIZE_PX = { sm: 32, md: 48, lg: 72 };
|
|
5
|
+
exports.THICKNESS_PX = { sm: 4, md: 5, lg: 7 };
|
|
6
|
+
const clampValue = (value, max) => Number.isFinite(value) ? Math.min(Math.max(value, 0), max) : 0;
|
|
7
|
+
exports.clampValue = clampValue;
|
|
8
|
+
const arcGeometry = (diameter, thickness, value, max) => {
|
|
9
|
+
const safeMax = max > 0 ? max : 100;
|
|
10
|
+
const clamped = (0, exports.clampValue)(value, safeMax);
|
|
11
|
+
const radius = Math.max((diameter - thickness) / 2, 0);
|
|
12
|
+
const circumference = 2 * Math.PI * radius;
|
|
13
|
+
const fraction = clamped / safeMax;
|
|
14
|
+
return { radius, circumference, fraction, clamped, safeMax, dashOffset: circumference * (1 - fraction) };
|
|
15
|
+
};
|
|
16
|
+
exports.arcGeometry = arcGeometry;
|
|
@@ -4,6 +4,7 @@ import type { PaletteProps } from "../../Theme/tokens/types";
|
|
|
4
4
|
import { type ControlSize } from "../../Theme/tokens/primitives/controlSizes";
|
|
5
5
|
export declare const FIELD_RADIUS = "lg";
|
|
6
6
|
export declare const FIELD_BORDER_WIDTH = "1px";
|
|
7
|
+
/** No box-shadow: the focus ring must be present the frame focus lands, not fade in. */
|
|
7
8
|
export declare const FIELD_TRANSITION: string;
|
|
8
9
|
/** Chakra `h`/`fontSize`/`px` for a field or select of this size. */
|
|
9
10
|
export declare const controlSizeStyles: (size: ControlSize) => {
|
|
@@ -8,7 +8,8 @@ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
|
|
|
8
8
|
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
9
9
|
exports.FIELD_RADIUS = "lg";
|
|
10
10
|
exports.FIELD_BORDER_WIDTH = "1px";
|
|
11
|
-
|
|
11
|
+
/** No box-shadow: the focus ring must be present the frame focus lands, not fade in. */
|
|
12
|
+
exports.FIELD_TRANSITION = (0, motion_1.transitionFor)(["border-color", "background-color"]);
|
|
12
13
|
/** Chakra `h`/`fontSize`/`px` for a field or select of this size. */
|
|
13
14
|
const controlSizeStyles = (size) => {
|
|
14
15
|
const spec = controlSizes_1.CONTROL_SIZES[size];
|
|
@@ -3,4 +3,4 @@ import { DrawerProps, DrawerHeaderSlotProps, DrawerBodySlotProps, DrawerFooterSl
|
|
|
3
3
|
export declare const DrawerHeader: React.FC<DrawerHeaderSlotProps>;
|
|
4
4
|
export declare const DrawerBody: React.FC<DrawerBodySlotProps>;
|
|
5
5
|
export declare const DrawerFooter: React.FC<DrawerFooterSlotProps>;
|
|
6
|
-
export default function Drawer({ isOpen, onClose, placement, size, id, variant, vaiant, initialFocusRef, finalFocusRef, closeOnOverlayClick, closeOnEsc, contentProps, hideCloseButton, children, }: DrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default function Drawer({ isOpen, onClose, placement, size, id, variant, vaiant, initialFocusRef, finalFocusRef, closeOnOverlayClick, closeOnEsc, contentProps, hideCloseButton, portalChildren, children, }: DrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -8,6 +8,7 @@ exports.default = Drawer;
|
|
|
8
8
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
9
|
const react_1 = __importDefault(require("react"));
|
|
10
10
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
11
|
+
const warnDroppedSlotChildren_1 = require("../Modal/warnDroppedSlotChildren");
|
|
11
12
|
const react_2 = require("@chakra-ui/react");
|
|
12
13
|
const DrawerHeader = ({ children }) => {
|
|
13
14
|
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
@@ -37,11 +38,12 @@ const findSlot = (children, slot) => {
|
|
|
37
38
|
}
|
|
38
39
|
return undefined;
|
|
39
40
|
};
|
|
40
|
-
function Drawer({ isOpen, onClose, placement = "right", size = "xl", id, variant, vaiant, initialFocusRef, finalFocusRef, closeOnOverlayClick, closeOnEsc, contentProps, hideCloseButton, children, }) {
|
|
41
|
+
function Drawer({ isOpen, onClose, placement = "right", size = "xl", id, variant, vaiant, initialFocusRef, finalFocusRef, closeOnOverlayClick, closeOnEsc, contentProps, hideCloseButton, portalChildren, children, }) {
|
|
41
42
|
var _a, _b;
|
|
42
43
|
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
43
44
|
const headerSlot = findSlot(children, exports.DrawerHeader);
|
|
44
45
|
const bodySlot = findSlot(children, exports.DrawerBody);
|
|
45
46
|
const footerSlot = findSlot(children, exports.DrawerFooter);
|
|
46
|
-
|
|
47
|
+
(0, warnDroppedSlotChildren_1.warnDroppedSlotChildren)("Drawer", children, [exports.DrawerHeader, exports.DrawerBody, exports.DrawerFooter]);
|
|
48
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Drawer, { isOpen: isOpen, placement: placement, onClose: onClose, size: size, variant: (_a = variant !== null && variant !== void 0 ? variant : vaiant) !== null && _a !== void 0 ? _a : "solid", id: id, initialFocusRef: initialFocusRef, finalFocusRef: finalFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, children: [(0, jsx_runtime_1.jsx)(react_2.DrawerOverlay, {}), (0, jsx_runtime_1.jsxs)(react_2.DrawerContent, { ...contentProps, children: [!hideCloseButton && (0, jsx_runtime_1.jsx)(react_2.DrawerCloseButton, {}), headerSlot && ((0, jsx_runtime_1.jsx)(react_2.DrawerHeader, { borderBottomWidth: "1px", borderColor: colors.boxborder[200], ...headerSlot.props, children: headerSlot })), (0, jsx_runtime_1.jsx)(react_2.DrawerBody, { ...((_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.DrawerFooter, { borderTopWidth: "1px", borderColor: colors.boxborder[200], ...footerSlot.props, children: footerSlot })), portalChildren] })] }));
|
|
47
49
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DrawerProps as ChakraDrawerProps, DrawerContentProps, ModalHeaderProps, ModalBodyProps, ModalFooterProps } from "@chakra-ui/react";
|
|
2
|
-
/** Only DrawerHeader/Body/Footer children render, matched by type one fragment deep; any other
|
|
2
|
+
/** Only DrawerHeader/Body/Footer children render, matched by type one fragment deep; any other child is dropped (dev console.warn) — use `portalChildren`. */
|
|
3
3
|
export type DrawerProps = Pick<ChakraDrawerProps, "isOpen" | "onClose" | "placement" | "size" | "id" | "variant" | "initialFocusRef" | "finalFocusRef" | "closeOnOverlayClick" | "closeOnEsc"> & {
|
|
4
4
|
/** Defaults to "xl". */
|
|
5
5
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "full";
|
|
@@ -12,6 +12,8 @@ export type DrawerProps = Pick<ChakraDrawerProps, "isOpen" | "onClose" | "placem
|
|
|
12
12
|
contentProps?: DrawerContentProps;
|
|
13
13
|
/** Drops the built-in close button, for a drawer dismissed only by its own footer action. */
|
|
14
14
|
hideCloseButton?: boolean;
|
|
15
|
+
/** Rendered inside the drawer's dialog after the slots (so live regions stay announced); nested dialogs portal out and keep focus here. Unmounts with the drawer. */
|
|
16
|
+
portalChildren?: React.ReactNode;
|
|
15
17
|
};
|
|
16
18
|
/** Chakra style props (padding, borderBottom, gap, sx, ...) spread onto the rendered DrawerHeader; omit to keep theme defaults. Chakra's Drawer reuses Modal's header part internally. */
|
|
17
19
|
export type DrawerHeaderSlotProps = ModalHeaderProps;
|
|
@@ -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
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LauncherTriggerProps } from "./LauncherTriggerProps";
|
|
2
2
|
export declare const keyShortcutsFor: (shortcut: string) => string;
|
|
3
|
-
declare const LauncherTrigger: ({ onClick, isOpen, label, shortcut, icon: Icon, "aria-label": ariaLabel, "data-testid": testId, }: LauncherTriggerProps) => import("react/jsx-runtime").JSX.Element;
|
|
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
4
|
export default LauncherTrigger;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.keyShortcutsFor = void 0;
|
|
4
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
@@ -11,6 +14,7 @@ const motion_2 = require("../../Theme/tokens/primitives/motion");
|
|
|
11
14
|
const useMatchMedia_1 = require("../../Hooks/useMatchMedia");
|
|
12
15
|
const Kbd_1 = require("../Kbd/Kbd");
|
|
13
16
|
const AppSwitcherProps_1 = require("../AppSwitcher/AppSwitcherProps");
|
|
17
|
+
const ToolTip_1 = __importDefault(require("../ToolTip/ToolTip"));
|
|
14
18
|
const MD_QUERY = "(min-width: 48em)";
|
|
15
19
|
const KEY_NAMES = {
|
|
16
20
|
mod: ["Meta", "Control"],
|
|
@@ -31,11 +35,14 @@ const keyShortcutsFor = (shortcut) => {
|
|
|
31
35
|
return Array.from(new Set(chords)).join(" ");
|
|
32
36
|
};
|
|
33
37
|
exports.keyShortcutsFor = keyShortcutsFor;
|
|
34
|
-
const LauncherTrigger = ({ onClick, isOpen, label = "Menu", shortcut = "mod+k", icon: Icon = lucide_react_1.Compass, "aria-label": ariaLabel, "data-testid": testId, }) => {
|
|
38
|
+
const LauncherTrigger = ({ onClick, isOpen, label = "Menu", shortcut = "mod+k", icon: Icon = lucide_react_1.Compass, display = "chip", "aria-label": ariaLabel, "data-testid": testId, }) => {
|
|
35
39
|
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
36
40
|
const showHint = (0, useMatchMedia_1.useMatchMedia)(MD_QUERY, true);
|
|
37
41
|
const ring = (0, focusRing_styles_1.focusVisibleRing)(colors);
|
|
38
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
|
+
}
|
|
39
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 }))] }));
|
|
40
47
|
};
|
|
41
48
|
exports.default = LauncherTrigger;
|
|
@@ -10,6 +10,8 @@ export interface LauncherTriggerProps {
|
|
|
10
10
|
shortcut?: string | null;
|
|
11
11
|
/** Component rendered at 17px before the label. Default lucide `Compass`. */
|
|
12
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";
|
|
13
15
|
/** Overrides the accessible name; the visible label and hint then become `aria-hidden`. */
|
|
14
16
|
"aria-label"?: string;
|
|
15
17
|
"data-testid"?: string;
|
|
@@ -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;
|