@dreamtree-org/twreact-ui 1.3.11 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -6
- package/ai-skills/dreamtree-ui.md +47 -9
- package/codemods/v2.cjs +198 -0
- package/dist/ai-schema.json +609 -33
- package/dist/components/blocks/AppShell.d.ts.map +1 -1
- package/dist/components/blocks/BottomActionBar.d.ts +6 -0
- package/dist/components/blocks/BottomActionBar.d.ts.map +1 -0
- package/dist/components/blocks/ConfirmDialog.d.ts.map +1 -1
- package/dist/components/blocks/PageHeader.d.ts.map +1 -1
- package/dist/components/core/Checkbox.d.ts.map +1 -1
- package/dist/components/core/DatePicker.d.ts.map +1 -1
- package/dist/components/core/DateRangePicker.d.ts.map +1 -1
- package/dist/components/core/Form.d.ts.map +1 -1
- package/dist/components/core/Input.d.ts.map +1 -1
- package/dist/components/core/Popover.d.ts.map +1 -1
- package/dist/components/core/ProgressBar.d.ts.map +1 -1
- package/dist/components/core/Rate.d.ts.map +1 -1
- package/dist/components/core/SearchField.d.ts +9 -0
- package/dist/components/core/SearchField.d.ts.map +1 -0
- package/dist/components/core/SegmentedControl.d.ts +8 -0
- package/dist/components/core/SegmentedControl.d.ts.map +1 -0
- package/dist/components/core/Select.d.ts.map +1 -1
- package/dist/components/core/SwipeableListItem.d.ts +4 -0
- package/dist/components/core/SwipeableListItem.d.ts.map +1 -0
- package/dist/components/core/SwipeableListItemGesture.d.ts +58 -0
- package/dist/components/core/SwipeableListItemGesture.d.ts.map +1 -0
- package/dist/components/core/Switch.d.ts.map +1 -1
- package/dist/components/core/Table/ActionMenu.d.ts +10 -3
- package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
- package/dist/components/core/Table/MobileCard.d.ts +10 -1
- package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
- package/dist/components/core/Table/MobileFilters.d.ts +8 -2
- package/dist/components/core/Table/MobileFilters.d.ts.map +1 -1
- package/dist/components/core/Table/Table.d.ts.map +1 -1
- package/dist/components/core/Table/TableRow.d.ts +2 -1
- package/dist/components/core/Table/TableRow.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts +3 -3
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/ThreeDotPopover.d.ts +10 -22
- package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
- package/dist/components/core/Tooltip.d.ts +2 -1
- package/dist/components/core/Tooltip.d.ts.map +1 -1
- package/dist/components/core/internal/Calendar.d.ts +77 -0
- package/dist/components/core/internal/Calendar.d.ts.map +1 -0
- package/dist/components/core/menu/ActionMenuSurface.d.ts +42 -0
- package/dist/components/core/menu/ActionMenuSurface.d.ts.map +1 -0
- package/dist/components/core/menu/ActionSheetMenu.d.ts +17 -0
- package/dist/components/core/menu/ActionSheetMenu.d.ts.map +1 -0
- package/dist/components/core/menu/MenuPopover.d.ts +21 -0
- package/dist/components/core/menu/MenuPopover.d.ts.map +1 -0
- package/dist/components/core/menu/menuItems.d.ts +21 -0
- package/dist/components/core/menu/menuItems.d.ts.map +1 -0
- package/dist/components/core/menu/menuKeyboard.d.ts +16 -0
- package/dist/components/core/menu/menuKeyboard.d.ts.map +1 -0
- package/dist/components/feedback/ActionSheet.d.ts +4 -0
- package/dist/components/feedback/ActionSheet.d.ts.map +1 -0
- package/dist/components/feedback/Alert.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Drawer.d.ts.map +1 -1
- package/dist/components/feedback/Sheet.d.ts +4 -0
- package/dist/components/feedback/Sheet.d.ts.map +1 -0
- package/dist/components/feedback/Toast.d.ts +4 -3
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/feedback/ToastItem.d.ts +47 -0
- package/dist/components/feedback/ToastItem.d.ts.map +1 -0
- package/dist/components/feedback/ToastStack.d.ts +20 -0
- package/dist/components/feedback/ToastStack.d.ts.map +1 -0
- package/dist/components/feedback/ToastSwipe.d.ts +22 -0
- package/dist/components/feedback/ToastSwipe.d.ts.map +1 -0
- package/dist/components/feedback/Tour.d.ts.map +1 -1
- package/dist/components/feedback/sheetCore.d.ts +30 -0
- package/dist/components/feedback/sheetCore.d.ts.map +1 -0
- package/dist/components/navigation/Navbar.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts +6 -0
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/rich-text/RichTextEditor.d.ts.map +1 -1
- package/dist/components/rich-text/RichTextToolbar.d.ts +6 -2
- package/dist/components/rich-text/RichTextToolbar.d.ts.map +1 -1
- package/dist/components/utility/PullToRefresh.d.ts +5 -0
- package/dist/components/utility/PullToRefresh.d.ts.map +1 -0
- package/dist/esm/components/blocks/AppShell.js +97 -90
- package/dist/esm/components/blocks/BottomActionBar.js +132 -0
- package/dist/esm/components/blocks/ConfirmDialog.js +40 -4
- package/dist/esm/components/blocks/PageHeader.js +16 -3
- package/dist/esm/components/core/Checkbox.js +13 -24
- package/dist/esm/components/core/DatePicker.js +117 -304
- package/dist/esm/components/core/DateRangePicker.js +260 -308
- package/dist/esm/components/core/Form.js +11 -2
- package/dist/esm/components/core/Input.js +13 -18
- package/dist/esm/components/core/Popover.js +59 -48
- package/dist/esm/components/core/ProgressBar.js +36 -64
- package/dist/esm/components/core/Rate.js +5 -10
- package/dist/esm/components/core/SearchField.js +311 -0
- package/dist/esm/components/core/SegmentedControl.js +189 -0
- package/dist/esm/components/core/Select.js +185 -190
- package/dist/esm/components/core/SwipeableListItem.js +286 -0
- package/dist/esm/components/core/SwipeableListItemGesture.js +219 -0
- package/dist/esm/components/core/Switch.js +11 -13
- package/dist/esm/components/core/Table/ActionMenu.js +45 -231
- package/dist/esm/components/core/Table/ColumnMenu.js +1 -1
- package/dist/esm/components/core/Table/MobileCard.js +66 -16
- package/dist/esm/components/core/Table/MobileFilters.js +181 -10
- package/dist/esm/components/core/Table/Table.js +149 -102
- package/dist/esm/components/core/Table/TableRow.js +10 -2
- package/dist/esm/components/core/Tabs.js +7 -7
- package/dist/esm/components/core/ThreeDotPopover.js +93 -99
- package/dist/esm/components/core/Tooltip.js +138 -145
- package/dist/esm/components/core/internal/Calendar.js +381 -0
- package/dist/esm/components/core/menu/ActionMenuSurface.js +110 -0
- package/dist/esm/components/core/menu/ActionSheetMenu.js +140 -0
- package/dist/esm/components/core/menu/MenuPopover.js +177 -0
- package/dist/esm/components/core/menu/menuItems.js +61 -0
- package/dist/esm/components/core/menu/menuKeyboard.js +54 -0
- package/dist/esm/components/feedback/ActionSheet.js +55 -0
- package/dist/esm/components/feedback/Alert.js +63 -53
- package/dist/esm/components/feedback/Dialog.js +141 -53
- package/dist/esm/components/feedback/Drawer.js +130 -132
- package/dist/esm/components/feedback/Sheet.js +125 -0
- package/dist/esm/components/feedback/Toast.js +21 -291
- package/dist/esm/components/feedback/ToastItem.js +348 -0
- package/dist/esm/components/feedback/ToastStack.js +130 -0
- package/dist/esm/components/feedback/ToastSwipe.js +52 -0
- package/dist/esm/components/feedback/Tour.js +107 -30
- package/dist/esm/components/feedback/sheetCore.js +494 -0
- package/dist/esm/components/navigation/Dropdown.js +1 -1
- package/dist/esm/components/navigation/Navbar.js +172 -37
- package/dist/esm/components/navigation/Sidebar.js +263 -111
- package/dist/esm/components/rich-text/RichTextEditor.js +9 -3
- package/dist/esm/components/rich-text/RichTextToolbar.js +29 -9
- package/dist/esm/components/utility/Portal.js +31 -0
- package/dist/esm/components/utility/PullToRefresh.js +229 -0
- package/dist/esm/hooks/useFloatingPosition.js +82 -0
- package/dist/esm/hooks/useHaptics.js +65 -0
- package/dist/esm/hooks/usePresence.js +58 -0
- package/dist/esm/hooks/usePresentation.js +21 -0
- package/dist/esm/hooks/useSheetDrag.js +220 -0
- package/dist/esm/index.js +13 -2
- package/dist/esm/utils/position.js +10 -63
- package/dist/hooks/useFloatingPosition.d.ts +8 -4
- package/dist/hooks/useFloatingPosition.d.ts.map +1 -1
- package/dist/hooks/useHaptics.d.ts +19 -0
- package/dist/hooks/useHaptics.d.ts.map +1 -0
- package/dist/hooks/useSheetDrag.d.ts +31 -0
- package/dist/hooks/useSheetDrag.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +8851 -3198
- package/dist/index.js +8856 -3195
- package/dist/rich-text/index.js +41 -11
- package/dist/types/blocks.d.ts +32 -2
- package/dist/types/blocks.d.ts.map +1 -1
- package/dist/types/index.d.ts +353 -19
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/rich-text.d.ts +5 -0
- package/dist/types/rich-text.d.ts.map +1 -1
- package/dist/utils/position.d.ts +0 -15
- package/dist/utils/position.d.ts.map +1 -1
- package/doc/README.md +15 -0
- package/mcp/catalog.snapshot.json +1398 -464
- package/package.json +7 -2
- package/dist/esm/hooks/useSwipeToClose.js +0 -66
- package/dist/hooks/useSwipeToClose.d.ts +0 -24
- package/dist/hooks/useSwipeToClose.d.ts.map +0 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import React, { useContext } from 'react';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
import { useHaptics } from '../../hooks/useHaptics.js';
|
|
7
|
+
import { setRefs } from '../../utils/position.js';
|
|
8
|
+
import { SheetCore, SheetContext, mergeHandlers, SheetCloseButton, SHEET_PLACEMENTS } from './sheetCore.js';
|
|
9
|
+
|
|
10
|
+
var _excluded = ["open", "isOpen", "placement", "title", "description", "showCloseButton", "haptics", "onSnapChange"],
|
|
11
|
+
_excluded2 = ["className"],
|
|
12
|
+
_excluded3 = ["className"],
|
|
13
|
+
_excluded4 = ["className"];
|
|
14
|
+
// Phone-native sheet (ADR 0001). Bottom by default; snap points, drag to
|
|
15
|
+
// dismiss, keyboard-aware via visualViewport. The behaviour lives in the
|
|
16
|
+
// internal sheet core (./sheetCore.jsx), shared with Drawer (DTUI-33).
|
|
17
|
+
var PANEL_CLASSES = {
|
|
18
|
+
bottom: "inset-x-0 bottom-0 w-full rounded-t-sheet border-t pb-safe px-safe max-h-[calc(100dvh-env(safe-area-inset-top)-1rem)]",
|
|
19
|
+
top: "inset-x-0 top-0 w-full rounded-b-sheet border-b pt-safe px-safe max-h-[calc(100dvh-env(safe-area-inset-top)-1rem)]",
|
|
20
|
+
right: "inset-y-0 right-0 h-dvh w-[min(88vw,24rem)] border-l py-safe pr-safe",
|
|
21
|
+
left: "inset-y-0 left-0 h-dvh w-[min(88vw,24rem)] border-r py-safe pl-safe"
|
|
22
|
+
};
|
|
23
|
+
var Sheet = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
24
|
+
var open = _ref.open,
|
|
25
|
+
isOpen = _ref.isOpen,
|
|
26
|
+
_ref$placement = _ref.placement,
|
|
27
|
+
placement = _ref$placement === void 0 ? "bottom" : _ref$placement,
|
|
28
|
+
title = _ref.title,
|
|
29
|
+
description = _ref.description,
|
|
30
|
+
_ref$showCloseButton = _ref.showCloseButton,
|
|
31
|
+
showCloseButton = _ref$showCloseButton === void 0 ? true : _ref$showCloseButton,
|
|
32
|
+
_ref$haptics = _ref.haptics,
|
|
33
|
+
haptics = _ref$haptics === void 0 ? false : _ref$haptics,
|
|
34
|
+
onSnapChange = _ref.onSnapChange,
|
|
35
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
36
|
+
// Opt-in: a selection tick when a drag or arrow key settles on a new snap point.
|
|
37
|
+
var _useHaptics = useHaptics({
|
|
38
|
+
enabled: haptics
|
|
39
|
+
}),
|
|
40
|
+
haptic = _useHaptics.trigger;
|
|
41
|
+
var handleSnapChange = function handleSnapChange(index) {
|
|
42
|
+
haptic("selection");
|
|
43
|
+
onSnapChange === null || onSnapChange === void 0 || onSnapChange(index);
|
|
44
|
+
};
|
|
45
|
+
var side = SHEET_PLACEMENTS.includes(placement) ? placement : "bottom";
|
|
46
|
+
var hasHeader = title != null || description != null;
|
|
47
|
+
var renderHeader = function renderHeader(_ref2) {
|
|
48
|
+
var titleId = _ref2.titleId,
|
|
49
|
+
descriptionId = _ref2.descriptionId,
|
|
50
|
+
requestClose = _ref2.requestClose,
|
|
51
|
+
showHandle = _ref2.showHandle;
|
|
52
|
+
return hasHeader ? jsxs(SheetHeader, {
|
|
53
|
+
className: cn("flex items-start justify-between gap-4", showHandle && side === "bottom" && "pt-1"),
|
|
54
|
+
children: [jsxs("div", {
|
|
55
|
+
className: "min-w-0",
|
|
56
|
+
children: [title != null && jsx("h2", {
|
|
57
|
+
id: titleId,
|
|
58
|
+
className: "text-lg font-semibold",
|
|
59
|
+
children: title
|
|
60
|
+
}), description != null && jsx("p", {
|
|
61
|
+
id: descriptionId,
|
|
62
|
+
className: "mt-1 text-sm text-muted",
|
|
63
|
+
children: description
|
|
64
|
+
})]
|
|
65
|
+
}), showCloseButton && jsx(SheetCloseButton, {
|
|
66
|
+
label: "Close sheet",
|
|
67
|
+
onClick: function onClick() {
|
|
68
|
+
return requestClose("close-button");
|
|
69
|
+
}
|
|
70
|
+
})]
|
|
71
|
+
}) : null;
|
|
72
|
+
};
|
|
73
|
+
return jsx(SheetCore, _objectSpread2({
|
|
74
|
+
ref: ref,
|
|
75
|
+
open: Boolean(open !== null && open !== void 0 ? open : isOpen),
|
|
76
|
+
placement: side,
|
|
77
|
+
hasTitle: title != null,
|
|
78
|
+
hasDescription: description != null,
|
|
79
|
+
panelClassName: cn("border-line bg-surface text-foreground", PANEL_CLASSES[side]),
|
|
80
|
+
renderHeader: renderHeader,
|
|
81
|
+
onSnapChange: handleSnapChange
|
|
82
|
+
}, props));
|
|
83
|
+
});
|
|
84
|
+
Sheet.displayName = "Sheet";
|
|
85
|
+
var SheetHeader = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
86
|
+
var className = _ref3.className,
|
|
87
|
+
props = _objectWithoutProperties(_ref3, _excluded2);
|
|
88
|
+
var ctx = useContext(SheetContext);
|
|
89
|
+
var dragProps = ctx ? mergeHandlers(ctx.headerDragProps, props) : {};
|
|
90
|
+
return jsx("div", _objectSpread2(_objectSpread2(_objectSpread2({
|
|
91
|
+
ref: ref
|
|
92
|
+
}, props), dragProps), {}, {
|
|
93
|
+
className: cn("shrink-0 border-b border-line px-4 py-3", ctx === null || ctx === void 0 ? void 0 : ctx.grabClass, className)
|
|
94
|
+
}));
|
|
95
|
+
});
|
|
96
|
+
var SheetBody = /*#__PURE__*/React.forwardRef(function (_ref4, _ref5) {
|
|
97
|
+
var className = _ref4.className,
|
|
98
|
+
props = _objectWithoutProperties(_ref4, _excluded3);
|
|
99
|
+
var ctx = useContext(SheetContext);
|
|
100
|
+
var dragProps = ctx ? mergeHandlers(ctx.bodyDragProps, props) : {};
|
|
101
|
+
return jsx("div", _objectSpread2(_objectSpread2(_objectSpread2({
|
|
102
|
+
ref: function ref(node) {
|
|
103
|
+
return setRefs(node, _ref5, ctx === null || ctx === void 0 ? void 0 : ctx.setBodyEl);
|
|
104
|
+
},
|
|
105
|
+
"data-sheet-body": ""
|
|
106
|
+
}, props), dragProps), {}, {
|
|
107
|
+
className: cn("min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4", className)
|
|
108
|
+
}));
|
|
109
|
+
});
|
|
110
|
+
var SheetFooter = /*#__PURE__*/React.forwardRef(function (_ref6, ref) {
|
|
111
|
+
var className = _ref6.className,
|
|
112
|
+
props = _objectWithoutProperties(_ref6, _excluded4);
|
|
113
|
+
return jsx("div", _objectSpread2({
|
|
114
|
+
ref: ref,
|
|
115
|
+
className: cn("sticky bottom-0 flex shrink-0 items-center justify-end gap-3 border-t border-line bg-surface px-4 py-3", className)
|
|
116
|
+
}, props));
|
|
117
|
+
});
|
|
118
|
+
SheetHeader.displayName = "Sheet.Header";
|
|
119
|
+
SheetBody.displayName = "Sheet.Body";
|
|
120
|
+
SheetFooter.displayName = "Sheet.Footer";
|
|
121
|
+
Sheet.Header = SheetHeader;
|
|
122
|
+
Sheet.Body = SheetBody;
|
|
123
|
+
Sheet.Footer = SheetFooter;
|
|
124
|
+
|
|
125
|
+
export { Sheet as default };
|
|
@@ -1,287 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { Bell, Info, AlertTriangle, XCircle, CheckCircle2, X } from 'lucide-react';
|
|
8
|
-
import { TOUCH_TARGET } from '../../utils/touchTarget.js';
|
|
2
|
+
import { objectSpread2 as _objectSpread2, objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import { useContext, createContext, useState, useCallback, useMemo } from 'react';
|
|
5
|
+
import Toast from './ToastItem.js';
|
|
6
|
+
import ToastStack from './ToastStack.js';
|
|
9
7
|
|
|
10
|
-
var _excluded = ["
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// their own role / aria-live, which win because ...props spreads last.
|
|
14
|
-
var liveRegionProps = function liveRegionProps(type) {
|
|
15
|
-
return type === 'error' ? {
|
|
16
|
-
role: 'alert',
|
|
17
|
-
'aria-live': 'assertive',
|
|
18
|
-
'aria-atomic': 'true'
|
|
19
|
-
} : {
|
|
20
|
-
role: 'status',
|
|
21
|
-
'aria-live': 'polite',
|
|
22
|
-
'aria-atomic': 'true'
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
var STATUS_CONFIG = {
|
|
26
|
-
success: {
|
|
27
|
-
icon: CheckCircle2,
|
|
28
|
-
iconClass: 'text-emerald-500 dark:text-emerald-400',
|
|
29
|
-
progressClass: 'bg-emerald-500 dark:bg-emerald-400'
|
|
30
|
-
},
|
|
31
|
-
error: {
|
|
32
|
-
icon: XCircle,
|
|
33
|
-
iconClass: 'text-rose-500 dark:text-rose-400',
|
|
34
|
-
progressClass: 'bg-rose-500 dark:bg-rose-400'
|
|
35
|
-
},
|
|
36
|
-
warning: {
|
|
37
|
-
icon: AlertTriangle,
|
|
38
|
-
iconClass: 'text-amber-500 dark:text-amber-400',
|
|
39
|
-
progressClass: 'bg-amber-500 dark:bg-amber-400'
|
|
40
|
-
},
|
|
41
|
-
info: {
|
|
42
|
-
icon: Info,
|
|
43
|
-
iconClass: 'text-sky-500 dark:text-sky-400',
|
|
44
|
-
progressClass: 'bg-sky-500 dark:bg-sky-400'
|
|
45
|
-
},
|
|
46
|
-
"default": {
|
|
47
|
-
icon: Bell,
|
|
48
|
-
iconClass: 'text-primary-500 dark:text-primary-400',
|
|
49
|
-
progressClass: 'bg-primary-500 dark:bg-primary-400'
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
var POSITION_CLASSES = {
|
|
53
|
-
'top-right': 'top-4 right-4 items-end',
|
|
54
|
-
'top-left': 'top-4 left-4 items-start',
|
|
55
|
-
'bottom-right': 'bottom-4 right-4 items-end',
|
|
56
|
-
'bottom-left': 'bottom-4 left-4 items-start',
|
|
57
|
-
'top-center': 'top-4 left-1/2 transform -translate-x-1/2 items-center',
|
|
58
|
-
'bottom-center': 'bottom-4 left-1/2 transform -translate-x-1/2 items-center'
|
|
59
|
-
};
|
|
60
|
-
var STANDALONE_POSITION_CLASSES = {
|
|
61
|
-
'top-right': 'top-4 right-4',
|
|
62
|
-
'top-left': 'top-4 left-4',
|
|
63
|
-
'bottom-right': 'bottom-4 right-4',
|
|
64
|
-
'bottom-left': 'bottom-4 left-4',
|
|
65
|
-
'top-center': 'top-4 left-1/2 transform -translate-x-1/2',
|
|
66
|
-
'bottom-center': 'bottom-4 left-1/2 transform -translate-x-1/2'
|
|
67
|
-
};
|
|
68
|
-
var Toast = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
69
|
-
var id = _ref.id,
|
|
70
|
-
title = _ref.title,
|
|
71
|
-
message = _ref.message,
|
|
72
|
-
description = _ref.description,
|
|
73
|
-
_ref$type = _ref.type,
|
|
74
|
-
type = _ref$type === void 0 ? 'info' : _ref$type,
|
|
75
|
-
_ref$duration = _ref.duration,
|
|
76
|
-
duration = _ref$duration === void 0 ? 5000 : _ref$duration,
|
|
77
|
-
onClose = _ref.onClose,
|
|
78
|
-
_ref$position = _ref.position,
|
|
79
|
-
position = _ref$position === void 0 ? 'top-right' : _ref$position,
|
|
80
|
-
statusIcon = _ref.statusIcon,
|
|
81
|
-
_ref$actions = _ref.actions,
|
|
82
|
-
actions = _ref$actions === void 0 ? [] : _ref$actions,
|
|
83
|
-
color = _ref.color,
|
|
84
|
-
footerNote = _ref.footerNote,
|
|
85
|
-
_ref$showFooterNote = _ref.showFooterNote,
|
|
86
|
-
showFooterNote = _ref$showFooterNote === void 0 ? false : _ref$showFooterNote,
|
|
87
|
-
_ref$portal = _ref.portal,
|
|
88
|
-
portal = _ref$portal === void 0 ? true : _ref$portal,
|
|
89
|
-
_ref$className = _ref.className,
|
|
90
|
-
className = _ref$className === void 0 ? '' : _ref$className,
|
|
91
|
-
props = _objectWithoutProperties(_ref, _excluded);
|
|
92
|
-
var _useState = useState(true),
|
|
93
|
-
_useState2 = _slicedToArray(_useState, 2),
|
|
94
|
-
isVisible = _useState2[0],
|
|
95
|
-
setIsVisible = _useState2[1];
|
|
96
|
-
var _useState3 = useState(false),
|
|
97
|
-
_useState4 = _slicedToArray(_useState3, 2),
|
|
98
|
-
isLeaving = _useState4[0],
|
|
99
|
-
setIsLeaving = _useState4[1];
|
|
100
|
-
var _useState5 = useState(false),
|
|
101
|
-
_useState6 = _slicedToArray(_useState5, 2),
|
|
102
|
-
isPaused = _useState6[0],
|
|
103
|
-
setIsPaused = _useState6[1];
|
|
104
|
-
var progressBarRef = useRef(null);
|
|
105
|
-
var timerTextRef = useRef(null);
|
|
106
|
-
var startTimeRef = useRef(null);
|
|
107
|
-
var remainingRef = useRef(duration);
|
|
108
|
-
var timerRef = useRef(null);
|
|
109
|
-
var animFrameRef = useRef(null);
|
|
110
|
-
var handleClose = useCallback(function () {
|
|
111
|
-
if (isLeaving) return;
|
|
112
|
-
setIsLeaving(true);
|
|
113
|
-
setTimeout(function () {
|
|
114
|
-
setIsVisible(false);
|
|
115
|
-
onClose === null || onClose === void 0 || onClose(id);
|
|
116
|
-
}, 300);
|
|
117
|
-
}, [id, onClose, isLeaving]);
|
|
118
|
-
var handleStopTimer = useCallback(function (e) {
|
|
119
|
-
e === null || e === void 0 || e.stopPropagation();
|
|
120
|
-
setIsPaused(true);
|
|
121
|
-
if (timerRef.current) clearTimeout(timerRef.current);
|
|
122
|
-
if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
|
|
123
|
-
}, []);
|
|
124
|
-
// Direct DOM-based progress updates to prevent 60 FPS React re-renders and glitches
|
|
125
|
-
useEffect(function () {
|
|
126
|
-
if (duration <= 0) return;
|
|
127
|
-
if (isPaused) {
|
|
128
|
-
if (timerRef.current) clearTimeout(timerRef.current);
|
|
129
|
-
if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
startTimeRef.current = Date.now();
|
|
133
|
-
timerRef.current = setTimeout(function () {
|
|
134
|
-
handleClose();
|
|
135
|
-
}, remainingRef.current);
|
|
136
|
-
var _updateProgress = function updateProgress() {
|
|
137
|
-
var elapsed = startTimeRef.current ? Date.now() - startTimeRef.current : 0;
|
|
138
|
-
var currentRemaining = Math.max(0, remainingRef.current - elapsed);
|
|
139
|
-
var pct = currentRemaining / duration * 100;
|
|
140
|
-
if (progressBarRef.current) {
|
|
141
|
-
progressBarRef.current.style.width = "".concat(pct, "%");
|
|
142
|
-
}
|
|
143
|
-
if (timerTextRef.current) {
|
|
144
|
-
var secs = Math.ceil(currentRemaining / 1000);
|
|
145
|
-
timerTextRef.current.textContent = "This message will close in ".concat(secs, " seconds. ");
|
|
146
|
-
}
|
|
147
|
-
if (currentRemaining > 0 && !isPaused) {
|
|
148
|
-
animFrameRef.current = requestAnimationFrame(_updateProgress);
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
animFrameRef.current = requestAnimationFrame(_updateProgress);
|
|
152
|
-
return function () {
|
|
153
|
-
if (timerRef.current) clearTimeout(timerRef.current);
|
|
154
|
-
if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
|
|
155
|
-
if (!isPaused && startTimeRef.current) {
|
|
156
|
-
var elapsed = Date.now() - startTimeRef.current;
|
|
157
|
-
remainingRef.current = Math.max(0, remainingRef.current - elapsed);
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
}, [duration, isPaused, handleClose]);
|
|
161
|
-
if (!isVisible) return null;
|
|
162
|
-
var statusStyle = STATUS_CONFIG[type] || STATUS_CONFIG.info || STATUS_CONFIG["default"];
|
|
163
|
-
var StatusIconComponent = statusStyle.icon;
|
|
164
|
-
var bodyText = description || message;
|
|
165
|
-
var toastContent = jsxs("div", _objectSpread2(_objectSpread2(_objectSpread2({
|
|
166
|
-
ref: ref,
|
|
167
|
-
onMouseEnter: function onMouseEnter() {
|
|
168
|
-
return setIsPaused(true);
|
|
169
|
-
},
|
|
170
|
-
onMouseLeave: function onMouseLeave() {
|
|
171
|
-
return setIsPaused(false);
|
|
172
|
-
},
|
|
173
|
-
className: cn('relative overflow-hidden rounded-xl border border-slate-200/90 bg-white/95 shadow-xl backdrop-blur-md transition-all duration-300', 'dark:border-slate-800/80 dark:bg-[#18181b] dark:text-slate-100 dark:shadow-2xl', 'max-w-md w-full motion-reduce:transition-none', isLeaving ? 'opacity-0 scale-95 translate-y-1' : 'animate-slide-up motion-reduce:animate-none opacity-100 scale-100', portal ? ['fixed z-50', STANDALONE_POSITION_CLASSES[position] || STANDALONE_POSITION_CLASSES['top-right']] : '', className)
|
|
174
|
-
}, liveRegionProps(type)), props), {}, {
|
|
175
|
-
children: [jsx("div", {
|
|
176
|
-
className: "p-4",
|
|
177
|
-
children: jsxs("div", {
|
|
178
|
-
className: "flex items-start gap-3 justify-between",
|
|
179
|
-
children: [jsx("span", {
|
|
180
|
-
className: "flex-shrink-0 mt-0.5",
|
|
181
|
-
"aria-hidden": "true",
|
|
182
|
-
children: statusIcon ? statusIcon : jsx(StatusIconComponent, {
|
|
183
|
-
className: cn('h-5 w-5', statusStyle.iconClass)
|
|
184
|
-
})
|
|
185
|
-
}), jsxs("div", {
|
|
186
|
-
className: "flex-1 min-w-0 pr-2",
|
|
187
|
-
children: [title && jsx("h4", {
|
|
188
|
-
className: "text-sm font-semibold text-slate-900 dark:text-slate-100 leading-snug",
|
|
189
|
-
children: title
|
|
190
|
-
}), bodyText && jsx("p", {
|
|
191
|
-
className: "mt-1 text-xs text-slate-600 dark:text-slate-400 leading-relaxed whitespace-pre-line",
|
|
192
|
-
children: bodyText
|
|
193
|
-
}), actions && actions.length > 0 && jsx("div", {
|
|
194
|
-
className: "mt-3 flex items-center gap-2 flex-wrap",
|
|
195
|
-
children: actions.map(function (actItem, idx) {
|
|
196
|
-
return jsx("button", {
|
|
197
|
-
type: "button",
|
|
198
|
-
onClick: function onClick(e) {
|
|
199
|
-
var _actItem$onClick;
|
|
200
|
-
(_actItem$onClick = actItem.onClick) === null || _actItem$onClick === void 0 || _actItem$onClick.call(actItem, e);
|
|
201
|
-
if (actItem.dismiss !== false) {
|
|
202
|
-
handleClose();
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
className: cn('px-3 py-1.5 text-xs font-medium rounded-lg transition-colors border shadow-xs', actItem.variant === 'primary' ? 'bg-primary-600 hover:bg-primary-700 text-white border-primary-600' : 'bg-slate-100 dark:bg-zinc-800/80 text-slate-700 dark:text-zinc-200 border-slate-200 dark:border-zinc-700 hover:bg-slate-200 dark:hover:bg-zinc-700', actItem.className),
|
|
206
|
-
children: actItem.label
|
|
207
|
-
}, actItem.id || actItem.label || "act-".concat(idx));
|
|
208
|
-
})
|
|
209
|
-
})]
|
|
210
|
-
}), jsx("button", {
|
|
211
|
-
type: "button",
|
|
212
|
-
"aria-label": "Close notification",
|
|
213
|
-
className: cn('inline-flex flex-shrink-0 items-center justify-center rounded-lg p-1 text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-zinc-800/70 transition-colors motion-reduce:transition-none outline-none focus-visible:ring-2 focus-visible:ring-primary-500', TOUCH_TARGET),
|
|
214
|
-
onClick: handleClose,
|
|
215
|
-
children: jsx(X, {
|
|
216
|
-
className: "h-4 w-4",
|
|
217
|
-
"aria-hidden": "true"
|
|
218
|
-
})
|
|
219
|
-
})]
|
|
220
|
-
})
|
|
221
|
-
}), (showFooterNote || footerNote) && duration > 0 && jsx("div", {
|
|
222
|
-
className: "px-4 py-2 bg-slate-50 dark:bg-zinc-950/40 border-t border-slate-100 dark:border-zinc-800/50 text-[11px] text-slate-500 dark:text-zinc-400 flex items-center justify-between",
|
|
223
|
-
children: jsx("span", {
|
|
224
|
-
children: footerNote ? footerNote : jsxs(Fragment, {
|
|
225
|
-
children: [jsxs("span", {
|
|
226
|
-
ref: timerTextRef,
|
|
227
|
-
children: ["This message will close in ", Math.ceil(duration / 1000), " seconds.", ' ']
|
|
228
|
-
}), jsx("button", {
|
|
229
|
-
type: "button",
|
|
230
|
-
onClick: handleStopTimer,
|
|
231
|
-
className: "font-medium text-slate-700 dark:text-zinc-200 hover:underline inline",
|
|
232
|
-
children: "Click to stop."
|
|
233
|
-
})]
|
|
234
|
-
})
|
|
235
|
-
})
|
|
236
|
-
}), duration > 0 && jsx("div", {
|
|
237
|
-
className: "absolute bottom-0 left-0 right-0 h-0.5 bg-slate-100 dark:bg-zinc-800/80 overflow-hidden rounded-b-xl",
|
|
238
|
-
children: jsx("div", {
|
|
239
|
-
ref: progressBarRef,
|
|
240
|
-
className: cn('h-full transition-all ease-linear', color ? '' : statusStyle.progressClass),
|
|
241
|
-
style: {
|
|
242
|
-
width: '100%',
|
|
243
|
-
backgroundColor: color || undefined
|
|
244
|
-
}
|
|
245
|
-
})
|
|
246
|
-
})]
|
|
247
|
-
}));
|
|
248
|
-
if (portal) {
|
|
249
|
-
return /*#__PURE__*/createPortal(toastContent, document.body);
|
|
250
|
-
}
|
|
251
|
-
return toastContent;
|
|
252
|
-
});
|
|
253
|
-
Toast.displayName = 'Toast';
|
|
8
|
+
var _excluded = ["children", "position", "className"];
|
|
9
|
+
// The toast family: the card (./ToastItem.jsx), the stack (./ToastStack.jsx),
|
|
10
|
+
// and the queue shared by <ToastProvider> / useToast().
|
|
254
11
|
// Shared queue for <ToastProvider>. `null` outside a provider, where useToast
|
|
255
12
|
// falls back to its own component-local queue (the pre-provider behavior).
|
|
256
13
|
var ToastContext = /*#__PURE__*/createContext(null);
|
|
257
|
-
var ToastStack = function ToastStack(_ref2) {
|
|
258
|
-
var _ref2$toasts = _ref2.toasts,
|
|
259
|
-
toasts = _ref2$toasts === void 0 ? [] : _ref2$toasts,
|
|
260
|
-
_ref2$position = _ref2.position,
|
|
261
|
-
position = _ref2$position === void 0 ? 'top-right' : _ref2$position,
|
|
262
|
-
onRemove = _ref2.onRemove,
|
|
263
|
-
_ref2$className = _ref2.className,
|
|
264
|
-
className = _ref2$className === void 0 ? '' : _ref2$className;
|
|
265
|
-
if (!toasts || toasts.length === 0) {
|
|
266
|
-
return null;
|
|
267
|
-
}
|
|
268
|
-
var posClass = POSITION_CLASSES[position] || POSITION_CLASSES['top-right'];
|
|
269
|
-
return /*#__PURE__*/createPortal(jsx("div", {
|
|
270
|
-
role: "region",
|
|
271
|
-
"aria-label": "Notifications",
|
|
272
|
-
className: cn('fixed z-50 flex flex-col gap-3 max-h-[calc(100vh-2rem)] overflow-y-auto overflow-x-hidden p-2 pointer-events-none', '[scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden', posClass, className),
|
|
273
|
-
children: toasts.map(function (t) {
|
|
274
|
-
return jsx("div", {
|
|
275
|
-
className: "pointer-events-auto w-full max-w-md",
|
|
276
|
-
children: jsx(Toast, _objectSpread2(_objectSpread2({}, t), {}, {
|
|
277
|
-
portal: false,
|
|
278
|
-
position: position,
|
|
279
|
-
onClose: onRemove
|
|
280
|
-
}))
|
|
281
|
-
}, t.id);
|
|
282
|
-
})
|
|
283
|
-
}), document.body);
|
|
284
|
-
};
|
|
285
14
|
// Toast Container Component for vertical stacking & scrollable overflow without visible scrollbars
|
|
286
15
|
var ToastContainer = function ToastContainer(props) {
|
|
287
16
|
var shared = useContext(ToastContext);
|
|
@@ -292,10 +21,10 @@ var ToastContainer = function ToastContainer(props) {
|
|
|
292
21
|
return jsx(ToastStack, _objectSpread2({}, props));
|
|
293
22
|
};
|
|
294
23
|
var useToastQueue = function useToastQueue() {
|
|
295
|
-
var
|
|
296
|
-
|
|
297
|
-
toasts =
|
|
298
|
-
setToasts =
|
|
24
|
+
var _useState = useState([]),
|
|
25
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
26
|
+
toasts = _useState2[0],
|
|
27
|
+
setToasts = _useState2[1];
|
|
299
28
|
var addToast = useCallback(function (toastOptions) {
|
|
300
29
|
var id = toastOptions.id || "".concat(Date.now(), "-").concat(Math.random().toString(36).slice(2, 7));
|
|
301
30
|
var newToast = _objectSpread2(_objectSpread2({}, toastOptions), {}, {
|
|
@@ -352,21 +81,22 @@ var useToastQueue = function useToastQueue() {
|
|
|
352
81
|
};
|
|
353
82
|
// App-level provider: every useToast() below it shares ONE queue, rendered by
|
|
354
83
|
// the provider's own container — no per-screen <ToastContainer> needed.
|
|
355
|
-
var ToastProvider = function ToastProvider(
|
|
356
|
-
var children =
|
|
357
|
-
|
|
358
|
-
position =
|
|
359
|
-
|
|
360
|
-
className =
|
|
84
|
+
var ToastProvider = function ToastProvider(_ref) {
|
|
85
|
+
var children = _ref.children,
|
|
86
|
+
_ref$position = _ref.position,
|
|
87
|
+
position = _ref$position === void 0 ? 'top-right' : _ref$position,
|
|
88
|
+
_ref$className = _ref.className,
|
|
89
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
90
|
+
stackProps = _objectWithoutProperties(_ref, _excluded);
|
|
361
91
|
var queue = useToastQueue();
|
|
362
92
|
return jsxs(ToastContext.Provider, {
|
|
363
93
|
value: queue,
|
|
364
|
-
children: [children, jsx(ToastStack, {
|
|
94
|
+
children: [children, jsx(ToastStack, _objectSpread2({
|
|
365
95
|
toasts: queue.toasts,
|
|
366
96
|
position: position,
|
|
367
97
|
onRemove: queue.removeToast,
|
|
368
98
|
className: className
|
|
369
|
-
})]
|
|
99
|
+
}, stackProps))]
|
|
370
100
|
});
|
|
371
101
|
};
|
|
372
102
|
ToastProvider.displayName = 'ToastProvider';
|