@flikk/ui 1.0.0-beta.23 → 1.0.0-beta.25
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/dist/components/charts/AreaChart/AreaChart.types.d.ts +2 -2
- package/dist/components/charts/BarChart/BarChart.types.d.ts +2 -2
- package/dist/components/charts/ComboChart/ComboChart.types.d.ts +2 -2
- package/dist/components/charts/LineChart/LineChart.types.d.ts +2 -2
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +2 -2
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +2 -2
- package/dist/components/core/Accordion/Accordion.theme.js +2 -2
- package/dist/components/core/Accordion/AccordionTrigger.js +28 -1
- package/dist/components/core/Alert/Alert.js +2 -1
- package/dist/components/core/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/core/Badge/Badge.js +6 -17
- package/dist/components/core/Breadcrumbs/Breadcrumbs.js +17 -28
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +2 -2
- package/dist/components/core/Calendar/Calendar.js +1 -1
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +4 -2
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.theme.js +1 -1
- package/dist/components/core/Carousel/CarouselBody.js +6 -1
- package/dist/components/core/ContextMenu/ContextMenuBody.js +6 -3
- package/dist/components/core/ContextMenu/ContextMenuSubBody.js +6 -3
- package/dist/components/core/DragDrop/DragDrop.js +170 -17
- package/dist/components/core/DragDrop/DragDrop.types.d.ts +6 -0
- package/dist/components/core/Drawer/Drawer.d.ts +1 -1
- package/dist/components/core/Drawer/Drawer.js +2 -0
- package/dist/components/core/Drawer/Drawer.types.d.ts +2 -0
- package/dist/components/core/Drawer/DrawerTitle.d.ts +1 -1
- package/dist/components/core/Drawer/DrawerTitle.js +2 -2
- package/dist/components/core/Dropdown/DropdownMenu.js +2 -30
- package/dist/components/core/Empty/Empty.theme.js +1 -1
- package/dist/components/core/Link/Link.js +1 -1
- package/dist/components/core/Masonry/Masonry.js +7 -2
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +3 -3
- package/dist/components/core/Modal/Modal.types.d.ts +2 -0
- package/dist/components/core/Modal/ModalTitle.d.ts +1 -1
- package/dist/components/core/Modal/ModalTitle.js +2 -2
- package/dist/components/core/NavItem/NavItem.js +13 -8
- package/dist/components/core/Pagination/Pagination.js +1 -1
- package/dist/components/core/Popover/PopoverBody.js +3 -27
- package/dist/components/core/Popover/PopoverTrigger.js +1 -1
- package/dist/components/core/Progress/Progress.js +4 -4
- package/dist/components/core/Rating/Rating.js +1 -1
- package/dist/components/core/ScrollArea/ScrollArea.js +3 -2
- package/dist/components/core/Segmented/Segmented.js +6 -6
- package/dist/components/core/Segmented/SegmentedItem.js +28 -2
- package/dist/components/core/Skeleton/Skeleton.js +2 -2
- package/dist/components/core/Sortable/Sortable.d.ts +1 -1
- package/dist/components/core/Sortable/Sortable.js +20 -4
- package/dist/components/core/Sortable/Sortable.types.d.ts +2 -0
- package/dist/components/core/Tabs/Tabs.js +6 -4
- package/dist/components/core/Tabs/Tabs.types.d.ts +2 -0
- package/dist/components/core/Tabs/TabsBody.js +3 -3
- package/dist/components/core/Tabs/TabsList.js +19 -21
- package/dist/components/core/Tabs/TabsTrigger.js +47 -28
- package/dist/components/core/Toast/Toast.js +1 -1
- package/dist/components/core/Toast/ToastProvider.js +3 -2
- package/dist/components/core/Tooltip/Tooltip.js +25 -34
- package/dist/components/core/Tree/Tree.js +178 -8
- package/dist/components/data-display/GanttChart/GanttSplitter.js +15 -1
- package/dist/components/data-display/Table/Table.js +2 -2
- package/dist/components/data-display/Table/Table.types.d.ts +2 -0
- package/dist/components/data-display/Table/TableFilter.js +21 -18
- package/dist/components/data-display/Timeline/Timeline.animations.d.ts +0 -7
- package/dist/components/data-display/Timeline/Timeline.animations.js +1 -27
- package/dist/components/data-display/Timeline/Timeline.js +3 -4
- package/dist/components/data-display/Timeline/Timeline.types.d.ts +0 -13
- package/dist/components/data-display/Timeline/TimelineContent.js +3 -7
- package/dist/components/data-display/Timeline/TimelineItem.js +4 -17
- package/dist/components/data-display/Timeline/index.d.ts +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.js +3 -7
- package/dist/components/effects/Overlay/Overlay.js +4 -9
- package/dist/components/effects/PageTransition/PageTransition.js +17 -6
- package/dist/components/effects/SpotlightBorder/SpotlightBorder.js +3 -4
- package/dist/components/effects/index.d.ts +7 -0
- package/dist/components/effects/index.js +3 -0
- package/dist/components/forms/Checkbox/Checkbox.js +11 -1
- package/dist/components/forms/Checkbox/Checkbox.theme.js +4 -1
- package/dist/components/forms/Checkbox/Checkbox.types.d.ts +7 -5
- package/dist/components/forms/Checkbox/CheckboxGroup.js +9 -4
- package/dist/components/forms/ColorPicker/ColorPicker.js +7 -4
- package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerBody.js +5 -3
- package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +3 -3
- package/dist/components/forms/ColorPicker/ColorPickerGradient.js +8 -8
- package/dist/components/forms/ColorPicker/ColorPickerInput.js +1 -1
- package/dist/components/forms/ColorPicker/index.d.ts +1 -1
- package/dist/components/forms/Combobox/Combobox.js +20 -45
- package/dist/components/forms/Combobox/Combobox.types.d.ts +4 -2
- package/dist/components/forms/CronInput/CronInput.js +10 -4
- package/dist/components/forms/CronInput/CronInput.types.d.ts +12 -1
- package/dist/components/forms/DatePicker/DatePicker.js +2 -2
- package/dist/components/forms/DatePicker/DatePicker.types.d.ts +4 -2
- package/dist/components/forms/DatePicker/DatePickerBody.js +1 -29
- package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePicker.js +3 -3
- package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +4 -2
- package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -28
- package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
- package/dist/components/forms/FileUpload/FileUpload.js +14 -10
- package/dist/components/forms/FileUpload/FileUpload.types.d.ts +15 -0
- package/dist/components/forms/FormLabel/FormLabel.js +2 -2
- package/dist/components/forms/Input/Input.js +5 -3
- package/dist/components/forms/Input/Input.types.d.ts +2 -0
- package/dist/components/forms/InputAddress/InputAddress.d.ts +1 -1
- package/dist/components/forms/InputAddress/InputAddress.js +8 -9
- package/dist/components/forms/InputCounter/InputCounter.js +25 -18
- package/dist/components/forms/InputCounter/InputCounter.types.d.ts +8 -1
- package/dist/components/forms/InputCreditCard/InputCreditCard.d.ts +1 -1
- package/dist/components/forms/InputCreditCard/InputCreditCard.js +27 -9
- package/dist/components/forms/InputCreditCard/InputCreditCard.types.d.ts +5 -0
- package/dist/components/forms/InputOTP/InputOTP.js +26 -17
- package/dist/components/forms/InputOTP/InputOTP.types.d.ts +21 -4
- package/dist/components/forms/InputTag/InputTag.js +12 -39
- package/dist/components/forms/InputTag/InputTag.types.d.ts +2 -2
- package/dist/components/forms/Mention/Mention.js +13 -6
- package/dist/components/forms/Mention/Mention.types.d.ts +9 -0
- package/dist/components/forms/Radio/Radio.js +12 -2
- package/dist/components/forms/Radio/Radio.theme.js +5 -1
- package/dist/components/forms/Radio/Radio.types.d.ts +7 -5
- package/dist/components/forms/Radio/RadioGroup.js +8 -3
- package/dist/components/forms/RichTextEditor/RichTextEditor.js +21 -21
- package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +2 -2
- package/dist/components/forms/Select/Select.d.ts +2 -0
- package/dist/components/forms/Select/Select.js +27 -57
- package/dist/components/forms/Select/Select.types.d.ts +14 -0
- package/dist/components/forms/Signature/Signature.js +1 -1
- package/dist/components/forms/Signature/Signature.types.d.ts +3 -3
- package/dist/components/forms/Slider/Slider.js +18 -4
- package/dist/components/forms/Slider/Slider.types.d.ts +2 -2
- package/dist/components/forms/Switch/Switch.js +12 -19
- package/dist/components/forms/Switch/Switch.theme.js +12 -2
- package/dist/components/forms/Switch/Switch.types.d.ts +20 -2
- package/dist/components/forms/Textarea/Textarea.js +8 -3
- package/dist/components/forms/Textarea/Textarea.types.d.ts +2 -0
- package/dist/components/forms/TimePicker/TimePicker.js +1 -1
- package/dist/components/forms/TimePicker/TimePicker.types.d.ts +6 -2
- package/dist/components/forms/TimePicker/TimePickerContent.js +2 -29
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +2 -2
- package/dist/components/forms/index.js +1 -1
- package/dist/components/layout/index.js +4 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useClickOutside.d.ts +10 -4
- package/dist/hooks/useClickOutside.js +44 -24
- package/dist/hooks/useDarkMode.d.ts +1 -0
- package/dist/hooks/useDarkMode.js +42 -0
- package/dist/hooks/useFormStateMachine.d.ts +1 -1
- package/dist/hooks/useNetworkStatus.js +1 -1
- package/dist/hooks/useOverlay.js +4 -0
- package/dist/hooks/useScaleBackground.js +5 -2
- package/dist/hooks/useSelectPortal.js +14 -5
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1 -57
- package/dist/shadcn-compat.css +80 -0
- package/dist/styles.css +1 -1
- package/dist/utils/stateMachine.d.ts +4 -4
- package/package.json +11 -10
- package/tailwind.preset.cjs +32 -3
- /package/{src/theme-plugin.css → dist/theme.css} +0 -0
|
@@ -19,7 +19,7 @@ export declare const AREA_CHART_DEFAULTS: {
|
|
|
19
19
|
readonly radius: 4;
|
|
20
20
|
readonly strokeWidth: 2;
|
|
21
21
|
readonly curved: true;
|
|
22
|
-
readonly curveType: import("
|
|
22
|
+
readonly curveType: import("..").CurveType;
|
|
23
23
|
readonly showDots: true;
|
|
24
24
|
readonly fillOpacity: 0.3;
|
|
25
25
|
readonly showStroke: true;
|
|
@@ -32,7 +32,7 @@ export declare const AREA_CHART_DEFAULTS: {
|
|
|
32
32
|
readonly gap: 4;
|
|
33
33
|
readonly categoryGap: 16;
|
|
34
34
|
readonly orientation: "vertical" | "horizontal";
|
|
35
|
-
readonly variant: import("
|
|
35
|
+
readonly variant: import("..").ChartVariant;
|
|
36
36
|
readonly enableKeyboardNavigation: true;
|
|
37
37
|
};
|
|
38
38
|
export type AreaChartData = BaseChartProps['data'][0];
|
|
@@ -38,12 +38,12 @@ export declare const BAR_CHART_DEFAULTS: {
|
|
|
38
38
|
readonly cellRadius: 4;
|
|
39
39
|
readonly strokeWidth: 2;
|
|
40
40
|
readonly curved: true;
|
|
41
|
-
readonly curveType: import("
|
|
41
|
+
readonly curveType: import("..").CurveType;
|
|
42
42
|
readonly fillOpacity: 0.3;
|
|
43
43
|
readonly showStroke: true;
|
|
44
44
|
readonly showDots: true;
|
|
45
45
|
readonly stacked: false;
|
|
46
|
-
readonly variant: import("
|
|
46
|
+
readonly variant: import("..").ChartVariant;
|
|
47
47
|
readonly enableKeyboardNavigation: true;
|
|
48
48
|
};
|
|
49
49
|
export type BarChartData = BaseChartProps["data"][0];
|
|
@@ -32,7 +32,7 @@ export declare const COMBO_CHART_DEFAULTS: {
|
|
|
32
32
|
readonly dotRadius: 4;
|
|
33
33
|
readonly categoryGap: 16;
|
|
34
34
|
readonly curved: true;
|
|
35
|
-
readonly curveType: import("
|
|
35
|
+
readonly curveType: import("..").CurveType;
|
|
36
36
|
readonly showDots: true;
|
|
37
37
|
readonly showDualAxis: false;
|
|
38
38
|
readonly showGrid: true;
|
|
@@ -46,6 +46,6 @@ export declare const COMBO_CHART_DEFAULTS: {
|
|
|
46
46
|
readonly showStroke: true;
|
|
47
47
|
readonly orientation: "vertical" | "horizontal";
|
|
48
48
|
readonly stacked: false;
|
|
49
|
-
readonly variant: import("
|
|
49
|
+
readonly variant: import("..").ChartVariant;
|
|
50
50
|
readonly enableKeyboardNavigation: true;
|
|
51
51
|
};
|
|
@@ -15,7 +15,7 @@ export declare const LINE_CHART_DEFAULTS: {
|
|
|
15
15
|
readonly radius: 4;
|
|
16
16
|
readonly strokeWidth: 2;
|
|
17
17
|
readonly curved: true;
|
|
18
|
-
readonly curveType: import("
|
|
18
|
+
readonly curveType: import("..").CurveType;
|
|
19
19
|
readonly showDots: true;
|
|
20
20
|
readonly showGrid: true;
|
|
21
21
|
readonly showXAxis: true;
|
|
@@ -28,6 +28,6 @@ export declare const LINE_CHART_DEFAULTS: {
|
|
|
28
28
|
readonly showStroke: true;
|
|
29
29
|
readonly orientation: "vertical" | "horizontal";
|
|
30
30
|
readonly stacked: false;
|
|
31
|
-
readonly variant: import("
|
|
31
|
+
readonly variant: import("..").ChartVariant;
|
|
32
32
|
readonly enableKeyboardNavigation: true;
|
|
33
33
|
};
|
|
@@ -60,12 +60,12 @@ export declare const SCATTER_PLOT_DEFAULTS: {
|
|
|
60
60
|
readonly gap: 4;
|
|
61
61
|
readonly categoryGap: 16;
|
|
62
62
|
readonly curved: true;
|
|
63
|
-
readonly curveType: import("
|
|
63
|
+
readonly curveType: import("..").CurveType;
|
|
64
64
|
readonly fillOpacity: 0.3;
|
|
65
65
|
readonly showStroke: true;
|
|
66
66
|
readonly showDots: true;
|
|
67
67
|
readonly orientation: "vertical" | "horizontal";
|
|
68
68
|
readonly stacked: false;
|
|
69
|
-
readonly variant: import("
|
|
69
|
+
readonly variant: import("..").ChartVariant;
|
|
70
70
|
readonly enableKeyboardNavigation: true;
|
|
71
71
|
};
|
|
@@ -23,12 +23,12 @@ export declare const STACKED_BAR_CHART_DEFAULTS: {
|
|
|
23
23
|
readonly radius: 20;
|
|
24
24
|
readonly strokeWidth: 2;
|
|
25
25
|
readonly curved: true;
|
|
26
|
-
readonly curveType: import("
|
|
26
|
+
readonly curveType: import("..").CurveType;
|
|
27
27
|
readonly fillOpacity: 0.3;
|
|
28
28
|
readonly showStroke: true;
|
|
29
29
|
readonly showDots: true;
|
|
30
30
|
readonly stacked: false;
|
|
31
|
-
readonly variant: import("
|
|
31
|
+
readonly variant: import("..").ChartVariant;
|
|
32
32
|
readonly enableKeyboardNavigation: true;
|
|
33
33
|
};
|
|
34
34
|
export type StackedBarChartData = BaseChartProps["data"][0];
|
|
@@ -8,9 +8,9 @@ const accordionTheme = {
|
|
|
8
8
|
// Item styles for stacked variant (shared borders, no spacing)
|
|
9
9
|
itemStyleStacked: "bg-white border-t border-[var(--color-border)] first-of-type:border-t-0",
|
|
10
10
|
// Trigger styles (shared across variants)
|
|
11
|
-
triggerStyle: "flex w-full gap-3 items-center px-4 py-2.5 text-left font-medium transition-all duration-200 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-[var(--color-text-primary)]",
|
|
11
|
+
triggerStyle: "flex w-full gap-3 items-center px-4 py-2.5 text-left font-medium transition-all duration-200 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-[var(--color-text-primary)] text-sm",
|
|
12
12
|
// Body styles (shared across variants)
|
|
13
|
-
bodyStyle: "data-[state=closed]:max-h-0 data-[state=open]:max-h-[320px] accordion-content overflow-hidden",
|
|
13
|
+
bodyStyle: "data-[state=closed]:max-h-0 data-[state=open]:max-h-[320px] accordion-content overflow-hidden text-sm",
|
|
14
14
|
// Body inner wrapper styles
|
|
15
15
|
bodyInnerStyle: "p-4 pb-2.5 pt-0",
|
|
16
16
|
};
|
|
@@ -24,7 +24,34 @@ const AccordionTrigger = React__default.forwardRef(({ children, className, chevr
|
|
|
24
24
|
// When chevronPosition="left", render the default animated chevron before children
|
|
25
25
|
const useDefaultOnLeft = chevron !== null && chevronPosition === "left" && chevron === undefined;
|
|
26
26
|
const animatedChevron = (rotation, extraClass) => (jsx(motion.div, { initial: false, animate: isOpen ? "open" : "closed", variants: createTriggerIconVariants(rotation), className: cn("flex items-center justify-center shrink-0", extraClass), children: defaultChevronIcon }));
|
|
27
|
-
|
|
27
|
+
const handleKeyDown = (event) => {
|
|
28
|
+
const currentButton = event.currentTarget;
|
|
29
|
+
// Find the accordion container (closest ancestor with role="region" or the first
|
|
30
|
+
// common ancestor that holds all triggers). Walk up until we find a container
|
|
31
|
+
// that owns multiple [data-accordion-trigger] buttons.
|
|
32
|
+
let container = currentButton.parentElement;
|
|
33
|
+
while (container) {
|
|
34
|
+
const triggers = container.querySelectorAll('[data-accordion-trigger]');
|
|
35
|
+
if (triggers.length > 1)
|
|
36
|
+
break;
|
|
37
|
+
container = container.parentElement;
|
|
38
|
+
}
|
|
39
|
+
if (!container)
|
|
40
|
+
return;
|
|
41
|
+
const triggers = Array.from(container.querySelectorAll('[data-accordion-trigger]'));
|
|
42
|
+
const currentIndex = triggers.indexOf(currentButton);
|
|
43
|
+
if (event.key === 'ArrowDown') {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
const next = triggers[(currentIndex + 1) % triggers.length];
|
|
46
|
+
next === null || next === void 0 ? void 0 : next.focus();
|
|
47
|
+
}
|
|
48
|
+
else if (event.key === 'ArrowUp') {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
const prev = triggers[(currentIndex - 1 + triggers.length) % triggers.length];
|
|
51
|
+
prev === null || prev === void 0 ? void 0 : prev.focus();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
return (jsxs("button", { ref: ref, type: "button", id: triggerId, className: cn(theme === null || theme === void 0 ? void 0 : theme.triggerStyle, className), "aria-expanded": isOpen, "aria-controls": contentId, "data-state": isOpen ? "open" : "closed", "data-accordion-trigger": true, onClick: toggle, onKeyDown: handleKeyDown, ...props, children: [useDefaultOnLeft && animatedChevron(resolvedChevronRotation), children, resolvedChevron && (jsx(motion.div, { initial: false, animate: isOpen ? "open" : "closed", variants: createTriggerIconVariants(resolvedChevronRotation), className: "flex items-center justify-center shrink-0 ml-auto", children: resolvedChevron }))] }));
|
|
28
55
|
});
|
|
29
56
|
AccordionTrigger.displayName = "Accordion.Trigger";
|
|
30
57
|
|
|
@@ -41,7 +41,8 @@ const Alert = React__default.forwardRef(({ variant = "default", color = "primary
|
|
|
41
41
|
const IconComponent = defaultIcons[color];
|
|
42
42
|
return (jsx("div", { className: "flex-shrink-0 w-6 h-6 mt-1", "aria-hidden": "true", children: jsx(IconComponent, { className: cn("w-6 h-6", iconColor) }) }));
|
|
43
43
|
};
|
|
44
|
-
const
|
|
44
|
+
const isUrgent = color === 'danger' || color === 'warning';
|
|
45
|
+
const alertContent = (jsxs("div", { ref: ref, className: cn(alertTheme.baseStyle, alertTheme.variants[variant], className), role: isUrgent ? 'alert' : 'status', "aria-live": isUrgent ? undefined : 'polite', ...props, children: [renderIconOrAvatar(), jsxs("div", { className: `flex-1 min-w-0 ${showDismiss ? "mr-5" : ""}`, children: [title && (typeof title === 'string'
|
|
45
46
|
? jsx("div", { className: cn("font-semibold text-[var(--color-text-primary)]"), children: title })
|
|
46
47
|
: title), subtitle && (typeof subtitle === 'string'
|
|
47
48
|
? jsx("div", { className: "text-[var(--color-text-secondary)]/90 mt-1", children: subtitle })
|
|
@@ -10,7 +10,7 @@ const AlertDialog = ({ trigger, icon, title, subtitle, footer, className, }) =>
|
|
|
10
10
|
const triggerElement = isValidElement(trigger)
|
|
11
11
|
? cloneElement(trigger, { onClick: handleOpen })
|
|
12
12
|
: null;
|
|
13
|
-
return (jsxs(Fragment, { children: [triggerElement, jsxs(Modal, { isOpen: isOpen, onClose: handleClose, size: "sm", closeOnOverlayClick: false, closeOnEsc:
|
|
13
|
+
return (jsxs(Fragment, { children: [triggerElement, jsxs(Modal, { isOpen: isOpen, onClose: handleClose, size: "sm", closeOnOverlayClick: false, closeOnEsc: !footer, showCloseButton: false, role: "alertdialog", className: cn("!overflow-visible", className), children: [jsxs(Modal.Header, { children: [icon && (jsx("div", { className: "text-2xl rounded-full p-3 mb-3 w-fit glass-effect shadow-xl shadow-black/5", "aria-hidden": "true", children: icon })), jsx(Modal.Title, { children: title })] }), jsx(Modal.Body, { className: "pt-2", children: jsx("div", { className: "text-[var(--color-text-secondary)] text-base", children: subtitle }) }), footer && (jsx(Modal.Footer, { className: "pb-6", children: footer(handleClose) }))] })] }));
|
|
14
14
|
};
|
|
15
15
|
AlertDialog.displayName = "AlertDialog";
|
|
16
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import React__default, { useState,
|
|
3
|
-
import { AnimatePresence, motion } from 'motion/react';
|
|
2
|
+
import React__default, { useState, useCallback } from 'react';
|
|
3
|
+
import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
|
|
4
4
|
import { XMarkIcon } from '@heroicons/react/24/outline';
|
|
5
5
|
import { UserIcon } from '@heroicons/react/16/solid';
|
|
6
6
|
import { cn } from '../../../utils/cn.js';
|
|
@@ -8,19 +8,6 @@ import { Avatar } from '../Avatar/Avatar.js';
|
|
|
8
8
|
import { animationTiming, dismissVariants, badgeVariants, dismissButtonVariants, dotVariants } from './Badge.animations.js';
|
|
9
9
|
import { badgeTheme } from './Badge.theme.js';
|
|
10
10
|
|
|
11
|
-
// Helper to determine whether we should animate (Storybook can disable animations globally)
|
|
12
|
-
const getShouldAnimate = () => {
|
|
13
|
-
if (typeof window === "undefined")
|
|
14
|
-
return true;
|
|
15
|
-
if (window.__STORYBOOK_DISABLE_ANIMATIONS__)
|
|
16
|
-
return false;
|
|
17
|
-
try {
|
|
18
|
-
return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
19
|
-
}
|
|
20
|
-
catch (_a) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
11
|
/**
|
|
25
12
|
* Badge component for displaying status, labels, or counters.
|
|
26
13
|
*
|
|
@@ -36,7 +23,9 @@ const Badge = React__default.memo(React__default.forwardRef(({ children, variant
|
|
|
36
23
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
37
24
|
// State management
|
|
38
25
|
const [isVisible, setIsVisible] = useState(true);
|
|
39
|
-
|
|
26
|
+
// useReducedMotion is SSR-safe (returns null on server, actual value after hydration)
|
|
27
|
+
const prefersReducedMotion = useReducedMotion();
|
|
28
|
+
const shouldAnimate = !prefersReducedMotion;
|
|
40
29
|
// Development-only warnings
|
|
41
30
|
if (process.env.NODE_ENV !== "production") {
|
|
42
31
|
if (dismissible && !onDismiss) {
|
|
@@ -155,7 +144,7 @@ const Badge = React__default.memo(React__default.forwardRef(({ children, variant
|
|
|
155
144
|
if (!shouldAnimate) {
|
|
156
145
|
// Spread props directly — Badge only receives HTMLSpanElement attributes
|
|
157
146
|
const restHtmlProps = props;
|
|
158
|
-
// Non-animated render for
|
|
147
|
+
// Non-animated render for reduced-motion environments
|
|
159
148
|
return isVisible ? (jsxs("span", { ref: ref, className: baseStyles, onClick: handleClick, "aria-disabled": disabled || undefined, ...dataAttributes, ...restHtmlProps, children: [renderLeftContent(), jsx("span", { className: cn("badge-content", maxWidth && "truncate"), style: maxWidth
|
|
160
149
|
? {
|
|
161
150
|
maxWidth: typeof maxWidth === "number"
|
|
@@ -39,20 +39,17 @@ const Breadcrumbs = ({ items, separator, maxItems = 4, variant = "default", clas
|
|
|
39
39
|
return { visibleItems, hiddenItems };
|
|
40
40
|
};
|
|
41
41
|
const { visibleItems, hiddenItems } = getVisibleItems();
|
|
42
|
-
// Render
|
|
42
|
+
// Render the inner content of a breadcrumb item (icon + label)
|
|
43
|
+
const renderItemContent = (item) => (jsxs(Fragment, { children: [showIcons && item.iconStart && (jsx("span", { className: "mr-1.5 flex-shrink-0", children: item.iconStart })), typeof item.label === 'string'
|
|
44
|
+
? jsx("span", { children: item.label })
|
|
45
|
+
: item.label] }));
|
|
46
|
+
// Render individual breadcrumb item wrapped in its own <li>
|
|
43
47
|
const renderItem = (item, index, isLast) => {
|
|
44
48
|
const isCurrentPage = isLast || !item.href;
|
|
45
|
-
|
|
46
|
-
? jsx("span", { children: item.label })
|
|
47
|
-
: item.label] }));
|
|
48
|
-
return (jsx("span", { className: "flex items-center text-base", children: isCurrentPage ? (jsx("span", { className: cn("flex items-center", theme.current), "aria-current": "page", children: itemContent })) : (jsx("a", { href: item.href, className: cn("flex items-center", theme.link), "aria-label": typeof item.label === 'string' ? `Navigate to ${item.label}` : undefined, children: itemContent })) }, `breadcrumb-${index}`));
|
|
49
|
+
return (jsxs("li", { className: "flex items-center", children: [isCurrentPage ? (jsx("span", { className: cn("flex items-center text-sm", theme.current), "aria-current": "page", children: renderItemContent(item) })) : (jsx("a", { href: item.href, className: cn("flex items-center text-sm", theme.link), "aria-label": typeof item.label === 'string' ? `Navigate to ${item.label}` : undefined, children: renderItemContent(item) })), !isLast && (jsx("span", { className: cn("flex items-center ml-1", theme.separator), "aria-hidden": "true", children: SeparatorComponent }))] }, `breadcrumb-${index}`));
|
|
49
50
|
};
|
|
50
|
-
// Render
|
|
51
|
-
const
|
|
52
|
-
return (jsx("span", { className: cn("flex items-center", theme.separator), "aria-hidden": "true", children: SeparatorComponent }, `separator-${index}`));
|
|
53
|
-
};
|
|
54
|
-
// Render ellipsis with dropdown
|
|
55
|
-
const renderEllipsis = () => {
|
|
51
|
+
// Render ellipsis with dropdown wrapped in its own <li>
|
|
52
|
+
const renderEllipsis = (separatorIndex) => {
|
|
56
53
|
if (hiddenItems.length === 0)
|
|
57
54
|
return null;
|
|
58
55
|
const handleEllipsisAction = (itemKey) => {
|
|
@@ -62,29 +59,24 @@ const Breadcrumbs = ({ items, separator, maxItems = 4, variant = "default", clas
|
|
|
62
59
|
window.location.href = selectedItem.href;
|
|
63
60
|
}
|
|
64
61
|
};
|
|
65
|
-
return (jsxs(Dropdown, { isOpen: isEllipsisOpen, onOpenChange: setIsEllipsisOpen, onAction: handleEllipsisAction, placement: "bottom-start", offset: 8, children: [jsx(Dropdown.Trigger, { children: jsx("button", { type: "button", className: cn(theme.ellipsis), "aria-label": `Navigate to one of ${hiddenItems.length} hidden breadcrumbs`, children: "..." }) }), jsx(Dropdown.Menu, { "aria-label": "Hidden breadcrumb items", children: hiddenItems.map((item, index) => (jsx(Dropdown.Item, { itemKey: `hidden-${index}`, startContent: showIcons && item.iconStart, children: typeof item.label === 'string'
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
return (jsxs("li", { className: "flex items-center", children: [jsxs(Dropdown, { isOpen: isEllipsisOpen, onOpenChange: setIsEllipsisOpen, onAction: handleEllipsisAction, placement: "bottom-start", offset: 8, children: [jsx(Dropdown.Trigger, { children: jsx("button", { type: "button", className: cn(theme.ellipsis), "aria-label": `Navigate to one of ${hiddenItems.length} hidden breadcrumbs`, children: "..." }) }), jsx(Dropdown.Menu, { "aria-label": "Hidden breadcrumb items", children: hiddenItems.map((item, index) => (jsx(Dropdown.Item, { itemKey: `hidden-${index}`, startContent: showIcons && item.iconStart, children: typeof item.label === 'string'
|
|
63
|
+
? jsx("span", { children: item.label })
|
|
64
|
+
: item.label }, `hidden-${index}`))) })] }), jsx("span", { className: cn("flex items-center ml-1", theme.separator), "aria-hidden": "true", children: SeparatorComponent }, `separator-${separatorIndex}`)] }, "ellipsis"));
|
|
68
65
|
};
|
|
69
|
-
// Build the breadcrumb elements
|
|
66
|
+
// Build the breadcrumb <li> elements
|
|
70
67
|
const breadcrumbElements = [];
|
|
71
68
|
let separatorIndex = 0; // Unique separator counter
|
|
72
69
|
if (shouldCollapse) {
|
|
73
|
-
// Add first item
|
|
70
|
+
// Add first item (not last, so it will include a separator)
|
|
74
71
|
breadcrumbElements.push(renderItem(visibleItems[0], 0, false));
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
breadcrumbElements.push(renderEllipsis());
|
|
78
|
-
breadcrumbElements.push(renderSeparator(separatorIndex++));
|
|
72
|
+
// Add ellipsis (includes its own trailing separator)
|
|
73
|
+
breadcrumbElements.push(renderEllipsis(separatorIndex++));
|
|
79
74
|
// Add last two items
|
|
80
75
|
const lastTwoItems = visibleItems.slice(1);
|
|
81
76
|
lastTwoItems.forEach((item, index) => {
|
|
82
77
|
const actualIndex = index + 1;
|
|
83
|
-
const isLast =
|
|
78
|
+
const isLast = index === lastTwoItems.length - 1;
|
|
84
79
|
breadcrumbElements.push(renderItem(item, actualIndex, isLast));
|
|
85
|
-
if (!isLast) {
|
|
86
|
-
breadcrumbElements.push(renderSeparator(separatorIndex++));
|
|
87
|
-
}
|
|
88
80
|
});
|
|
89
81
|
}
|
|
90
82
|
else {
|
|
@@ -92,12 +84,9 @@ const Breadcrumbs = ({ items, separator, maxItems = 4, variant = "default", clas
|
|
|
92
84
|
visibleItems.forEach((item, index) => {
|
|
93
85
|
const isLast = index === visibleItems.length - 1;
|
|
94
86
|
breadcrumbElements.push(renderItem(item, index, isLast));
|
|
95
|
-
if (!isLast) {
|
|
96
|
-
breadcrumbElements.push(renderSeparator(separatorIndex++));
|
|
97
|
-
}
|
|
98
87
|
});
|
|
99
88
|
}
|
|
100
|
-
return (jsx("nav", { "aria-label": "Breadcrumb", className: cn("flex items-center", className), ...props, children: jsx("ol", { className: "flex items-center gap-1
|
|
89
|
+
return (jsx("nav", { "aria-label": "Breadcrumb", className: cn("flex items-center", className), ...props, children: jsx("ol", { className: "flex items-center gap-1 flex-wrap", children: breadcrumbElements }) }));
|
|
101
90
|
};
|
|
102
91
|
Breadcrumbs.displayName = "Breadcrumbs";
|
|
103
92
|
|
|
@@ -10,7 +10,7 @@ const breadcrumbsTheme = {
|
|
|
10
10
|
link: "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-150 font-medium",
|
|
11
11
|
current: "text-[var(--color-text-primary)] font-medium",
|
|
12
12
|
separator: "text-[var(--color-text-muted)] select-none",
|
|
13
|
-
ellipsis: "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-150 cursor-pointer p-1 rounded hover:bg-[var(--color-background-tertiary)]",
|
|
13
|
+
ellipsis: "text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-150 cursor-pointer p-1 rounded hover:bg-[var(--color-background-tertiary)]",
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* Variant styles for different breadcrumb appearances
|
|
@@ -21,7 +21,7 @@ const breadcrumbsVariants = {
|
|
|
21
21
|
link: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-150 font-normal",
|
|
22
22
|
current: "text-[var(--color-text-secondary)] font-normal",
|
|
23
23
|
separator: "text-[var(--color-border)]",
|
|
24
|
-
ellipsis: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-150 cursor-pointer p-1 rounded hover:bg-[var(--color-background-secondary)]",
|
|
24
|
+
ellipsis: "text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-150 cursor-pointer p-1 rounded hover:bg-[var(--color-background-secondary)]",
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
27
|
/**
|
|
@@ -371,7 +371,7 @@ const Calendar = React__default.forwardRef(({ mode = 'single', value, defaultVal
|
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
}, [minDate, maxDate, customIsDateDisabled, currentMonth, currentYear, onViewDateChange, mode, value, onChange, selectedValue, rangeSelectionState]);
|
|
374
|
-
return (jsxs("div", { ref: ref, className: cn(calendarTheme.baseStyle, className), ...props, children: [jsxs("div", { className: calendarTheme.headerStyle, children: [onNavigatePrev !== null && (jsx(Button, { onClick: navigateToPreviousMonth, "aria-label": "Previous month", disabled: !canNavigateToPrev, iconOnly: true, variant: "link", color: "neutral", size: "sm", children: jsx(ChevronLeftIcon, { className: "size-4", strokeWidth: 2 }) })), onNavigatePrev === null && jsx("div", { className: "w-8" }), resolvedHeaderMode === 'static' ? (jsxs("h2", { className: calendarTheme.titleStyle, children: [getMonthName(viewDate, months), " ", currentYear] })) : (jsxs("div", { className: calendarTheme.headerDropdownsStyle, children: [(resolvedHeaderMode === 'dropdown' || (resolvedHeaderMode === 'mixed' && enableMonthDropdown)) && (jsx(Select, { value: currentMonth.toString(), onChange: handleMonthChange, options: monthOptions, displayValue: currentAbbreviatedMonth, size: "sm", className: "
|
|
374
|
+
return (jsxs("div", { ref: ref, className: cn(calendarTheme.baseStyle, className), ...props, children: [jsxs("div", { className: calendarTheme.headerStyle, children: [onNavigatePrev !== null && (jsx(Button, { onClick: navigateToPreviousMonth, "aria-label": "Previous month", disabled: !canNavigateToPrev, iconOnly: true, variant: "link", color: "neutral", size: "sm", children: jsx(ChevronLeftIcon, { className: "size-4", strokeWidth: 2 }) })), onNavigatePrev === null && jsx("div", { className: "w-8" }), resolvedHeaderMode === 'static' ? (jsxs("h2", { className: calendarTheme.titleStyle, children: [getMonthName(viewDate, months), " ", currentYear] })) : (jsxs("div", { className: calendarTheme.headerDropdownsStyle, children: [(resolvedHeaderMode === 'dropdown' || (resolvedHeaderMode === 'mixed' && enableMonthDropdown)) && (jsx(Select, { value: currentMonth.toString(), onChange: handleMonthChange, options: monthOptions, displayValue: currentAbbreviatedMonth, size: "sm", className: "font-medium" })), (resolvedHeaderMode === 'dropdown' || (resolvedHeaderMode === 'mixed' && enableYearDropdown)) && (jsx(Select, { value: currentYear.toString(), onChange: handleYearChange, options: yearOptions, size: "sm", className: "font-medium" }))] })), onNavigateNext !== null && (jsx(Button, { onClick: navigateToNextMonth, "aria-label": "Next month", disabled: !canNavigateToNext, iconOnly: true, variant: "link", color: "neutral", size: "sm", children: jsx(ChevronRightIcon, { className: "size-4", strokeWidth: 2 }) })), onNavigateNext === null && jsx("div", { className: "w-8" })] }), jsx("div", { className: calendarTheme.weekdaysStyle, children: weekdays.map((day) => (jsx("div", { className: calendarTheme.weekdayStyle, children: day }, day))) }), jsx("div", { className: calendarTheme.daysGridStyle, children: calendarDays.map((day, index) => {
|
|
375
375
|
var _a;
|
|
376
376
|
const dayNumber = day.date.getDate();
|
|
377
377
|
const isInStrip = day.isRangeStart || day.isRangeEnd || day.isInRange;
|
|
@@ -182,7 +182,9 @@ const CalendarMini = React__default.forwardRef(({ selectedDate, currentMonth, on
|
|
|
182
182
|
}, [activeMonth]);
|
|
183
183
|
// Check if date is selected
|
|
184
184
|
const isDateSelected = useCallback((date) => {
|
|
185
|
-
return defaultSelectedDate
|
|
185
|
+
return defaultSelectedDate
|
|
186
|
+
? isSameDay(date, defaultSelectedDate)
|
|
187
|
+
: false;
|
|
186
188
|
}, [defaultSelectedDate]);
|
|
187
189
|
// Check if date is today
|
|
188
190
|
const isDateToday = useCallback((date) => {
|
|
@@ -242,7 +244,7 @@ const CalendarMini = React__default.forwardRef(({ selectedDate, currentMonth, on
|
|
|
242
244
|
day: "numeric",
|
|
243
245
|
}), "aria-selected": isSelected, "aria-current": isToday ? "date" : undefined, "aria-disabled": disabled, type: "button", ...(enableAnimations && {
|
|
244
246
|
whileTap: !disabled ? { scale: 0.95 } : undefined,
|
|
245
|
-
}), children: [jsx("div", { className: "text-
|
|
247
|
+
}), children: [jsx("div", { className: "text-sm font-medium opacity-60", children: formatDayName(date) }), jsx("time", { dateTime: date.toISOString(), className: cn("font-semibold"), children: formatDateNumber(date) })] }, date.toISOString()));
|
|
246
248
|
}) }, `${startDate.getTime()}-dates`) }) }) })] }), jsx(Button, { iconOnly: true, color: "neutral", variant: "soft", className: "!flex-shrink !flex-grow-0 !w-fit self-stretch !h-auto !min-h-0 px-0.5", onClick: handleNextMonth, "aria-label": "Next month", children: jsx(ChevronRightIcon, { className: "size-5 text-[var(--color-text-primary)]" }) })] }));
|
|
247
249
|
});
|
|
248
250
|
CalendarMini.displayName = "CalendarMini";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const calendarMiniTheme = {
|
|
2
|
-
baseStyle: "flex items-center justify-center gap-1 transition-all duration-300",
|
|
2
|
+
baseStyle: "flex items-center justify-center gap-1 transition-all duration-300 text-sm",
|
|
3
3
|
monthRowStyle: "flex flex-1 gap-4 overflow-x-auto scrollbar-hide scroll-smooth snap-x snap-mandatory px-4 ml-3",
|
|
4
4
|
monthItemStyle: "font-semibold text-[var(--color-text-secondary)] cursor-pointer transition-colors hover:text-[var(--color-text-primary)] flex-shrink-0 snap-center data-[state=active]:text-[var(--color-text-primary)] data-[state=active]:opacity-100",
|
|
5
5
|
dateRowStyle: "relative overflow-hidden px-4 py-0.5",
|
|
@@ -41,8 +41,13 @@ const CarouselBody = React__default.forwardRef(({ className, children, ...props
|
|
|
41
41
|
: { type: 'spring', stiffness: 180, damping: 25, mass: 0.7 }, children: React__default.Children.map(children, (child, index) => {
|
|
42
42
|
if (!React__default.isValidElement(child))
|
|
43
43
|
return child;
|
|
44
|
+
const isActive = index === currentIndex;
|
|
44
45
|
return React__default.cloneElement(child, {
|
|
45
|
-
'aria-hidden':
|
|
46
|
+
'aria-hidden': !isActive,
|
|
47
|
+
// inert removes all focusable descendants from tab order and hides
|
|
48
|
+
// them from assistive technologies when the slide is not active.
|
|
49
|
+
// The empty string is the correct value for boolean HTML attributes in React.
|
|
50
|
+
inert: !isActive ? "" : undefined,
|
|
46
51
|
});
|
|
47
52
|
}) }) }));
|
|
48
53
|
});
|
|
@@ -100,6 +100,8 @@ const ContextMenuBody = React__default.forwardRef(({ children, className, animat
|
|
|
100
100
|
// Update position when menu opens
|
|
101
101
|
useEffect(() => {
|
|
102
102
|
if (isOpen && cursorPosition) {
|
|
103
|
+
if (typeof window === "undefined")
|
|
104
|
+
return;
|
|
103
105
|
// Get cursor position from trigger
|
|
104
106
|
const { x, y } = cursorPosition;
|
|
105
107
|
// Adjust position to keep menu in viewport
|
|
@@ -135,6 +137,8 @@ const ContextMenuBody = React__default.forwardRef(({ children, className, animat
|
|
|
135
137
|
useEffect(() => {
|
|
136
138
|
if (!isOpen)
|
|
137
139
|
return;
|
|
140
|
+
if (typeof window === "undefined")
|
|
141
|
+
return;
|
|
138
142
|
const handleScroll = () => {
|
|
139
143
|
onOpenChange(false);
|
|
140
144
|
};
|
|
@@ -188,9 +192,8 @@ const ContextMenuBody = React__default.forwardRef(({ children, className, animat
|
|
|
188
192
|
damping: 30,
|
|
189
193
|
}, "data-state": isOpen ? "open" : "closed", ...domProps, children: children })) }));
|
|
190
194
|
// Always use portal for context menus
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
: null;
|
|
195
|
+
const portalTarget = isClient ? document.body : null;
|
|
196
|
+
return portalTarget ? createPortal(menuContent, portalTarget) : null;
|
|
194
197
|
});
|
|
195
198
|
ContextMenuBody.displayName = "ContextMenu.Body";
|
|
196
199
|
|
|
@@ -19,6 +19,8 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
|
|
|
19
19
|
// Update position when submenu opens
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
if (isOpen && triggerRef.current) {
|
|
22
|
+
if (typeof window === "undefined")
|
|
23
|
+
return;
|
|
22
24
|
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
23
25
|
// Position to the right of the trigger
|
|
24
26
|
let x = triggerRect.right + 4; // 4px offset
|
|
@@ -44,6 +46,8 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
|
|
|
44
46
|
useEffect(() => {
|
|
45
47
|
if (!isOpen)
|
|
46
48
|
return;
|
|
49
|
+
if (typeof window === "undefined")
|
|
50
|
+
return;
|
|
47
51
|
const handleScroll = () => {
|
|
48
52
|
onOpenChange(false);
|
|
49
53
|
};
|
|
@@ -97,9 +101,8 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
|
|
|
97
101
|
damping: 30,
|
|
98
102
|
}, "data-state": isOpen ? "open" : "closed", ...domProps, children: children })) }));
|
|
99
103
|
// Always use portal for submenus
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
: null;
|
|
104
|
+
const portalTarget = isClient ? document.body : null;
|
|
105
|
+
return portalTarget ? createPortal(submenuContent, portalTarget) : null;
|
|
103
106
|
});
|
|
104
107
|
ContextMenuSubBody.displayName = "ContextMenu.SubBody";
|
|
105
108
|
|