@dreamtree-org/twreact-ui 1.3.11 → 2.0.1
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,381 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { useMemo, useState, useRef, useEffect } from 'react';
|
|
5
|
+
import ReactDOM from 'react-dom';
|
|
6
|
+
import { parseISO, startOfDay, isBefore, isAfter, startOfWeek, startOfMonth, endOfWeek, endOfMonth, eachDayOfInterval, format, isSameMonth, isToday, isSameDay, addMonths, subMonths, addDays } from 'date-fns';
|
|
7
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
8
|
+
import { cn } from '../../../utils/cn.js';
|
|
9
|
+
import { TOUCH_TARGET } from '../../../utils/touchTarget.js';
|
|
10
|
+
import Sheet from '../../feedback/Sheet.js';
|
|
11
|
+
|
|
12
|
+
// Internal (not exported). The month calendar shared by DatePicker and
|
|
13
|
+
// DateRangePicker: month header, weekday row and an ARIA grid of days with a
|
|
14
|
+
// roving tabindex, arrow/Home/End/PageUp/PageDown navigation and (in sheet
|
|
15
|
+
// presentation) a horizontal swipe to change month.
|
|
16
|
+
var WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
17
|
+
var SWIPE_THRESHOLD = 50; // px of horizontal travel that changes month
|
|
18
|
+
var SWIPE_RATIO = 1.5; // horizontal travel must beat vertical by this much
|
|
19
|
+
/** Date | ISO string | null → Date | null. */
|
|
20
|
+
function normalizeDate(d) {
|
|
21
|
+
if (!d) return null;
|
|
22
|
+
if (typeof d === "string") {
|
|
23
|
+
var parsed = parseISO(d);
|
|
24
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
25
|
+
}
|
|
26
|
+
return d instanceof Date ? d : null;
|
|
27
|
+
}
|
|
28
|
+
/** Builds an `isDisabled(date)` predicate from optional min / max bounds. */
|
|
29
|
+
function makeIsDisabled(minDate, maxDate) {
|
|
30
|
+
var minD = normalizeDate(minDate);
|
|
31
|
+
var maxD = normalizeDate(maxDate);
|
|
32
|
+
var min = minD ? startOfDay(minD) : null;
|
|
33
|
+
var max = maxD ? startOfDay(maxD) : null;
|
|
34
|
+
return function (date) {
|
|
35
|
+
var d = startOfDay(date);
|
|
36
|
+
if (min && isBefore(d, min)) return true;
|
|
37
|
+
if (max && isAfter(d, max)) return true;
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Is `d` within [a, b] (either order), by calendar day. */
|
|
42
|
+
function isBetween(d, a, b) {
|
|
43
|
+
if (!a || !b) return false;
|
|
44
|
+
var _ref = isBefore(b, a) ? [b, a] : [a, b],
|
|
45
|
+
_ref2 = _slicedToArray(_ref, 2),
|
|
46
|
+
lo = _ref2[0],
|
|
47
|
+
hi = _ref2[1];
|
|
48
|
+
var day = startOfDay(d);
|
|
49
|
+
return !isBefore(day, startOfDay(lo)) && !isAfter(day, startOfDay(hi));
|
|
50
|
+
}
|
|
51
|
+
/** Pointer-event swipe on the grid: left → next month, right → previous. */
|
|
52
|
+
function useMonthSwipe(enabled, onSwipe) {
|
|
53
|
+
var start = useRef(null);
|
|
54
|
+
var swiped = useRef(false);
|
|
55
|
+
if (!enabled) return {};
|
|
56
|
+
return {
|
|
57
|
+
onPointerDown: function onPointerDown(e) {
|
|
58
|
+
swiped.current = false;
|
|
59
|
+
start.current = {
|
|
60
|
+
x: e.clientX,
|
|
61
|
+
y: e.clientY
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
onPointerUp: function onPointerUp(e) {
|
|
65
|
+
var s = start.current;
|
|
66
|
+
start.current = null;
|
|
67
|
+
if (!s) return;
|
|
68
|
+
var dx = e.clientX - s.x;
|
|
69
|
+
var dy = e.clientY - s.y;
|
|
70
|
+
if (Math.abs(dx) < SWIPE_THRESHOLD || Math.abs(dx) < Math.abs(dy) * SWIPE_RATIO) return;
|
|
71
|
+
swiped.current = true;
|
|
72
|
+
onSwipe(dx < 0 ? 1 : -1);
|
|
73
|
+
},
|
|
74
|
+
onPointerCancel: function onPointerCancel() {
|
|
75
|
+
start.current = null;
|
|
76
|
+
},
|
|
77
|
+
// A swipe that ends over a day must not also select it.
|
|
78
|
+
onClickCapture: function onClickCapture(e) {
|
|
79
|
+
if (!swiped.current) return;
|
|
80
|
+
swiped.current = false;
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* @param {object} props
|
|
88
|
+
* @param {Date} props.month - any date in the visible month.
|
|
89
|
+
* @param {(month: Date) => void} props.onMonthChange
|
|
90
|
+
* @param {0|1} [props.weekStartsOn=0]
|
|
91
|
+
* @param {(d: Date) => boolean} props.isDisabled
|
|
92
|
+
* @param {(d: Date) => { selected?: boolean, edge?: boolean, inRange?: boolean }} props.getDayState
|
|
93
|
+
* - `selected` sets aria-selected; `edge` paints the solid (selected / range end) style;
|
|
94
|
+
* `inRange` paints the in-between tint.
|
|
95
|
+
* @param {(d: Date) => void} props.onSelect
|
|
96
|
+
* @param {(d: Date | null) => void} [props.onPreview] - hovered / focused day, null on leave.
|
|
97
|
+
* @param {Date|null} [props.preferredDate] - tabbable day when nothing was focused yet.
|
|
98
|
+
* @param {'popover'|'sheet'} [props.size='popover'] - sheet uses 44px day cells.
|
|
99
|
+
* @param {boolean} [props.fullDateLabels=false] - aria-label each day with its full date.
|
|
100
|
+
* @param {boolean} [props.autoFocus=false] - focus the tabbable day on mount.
|
|
101
|
+
* @param {boolean} [props.swipe=false] - horizontal swipe changes month.
|
|
102
|
+
* @param {boolean} [props.multiSelectable=false]
|
|
103
|
+
* @param {object} [props.locale] - date-fns locale for the day labels.
|
|
104
|
+
* @param {React.Ref} [props.gridRef]
|
|
105
|
+
*/
|
|
106
|
+
function Calendar(_ref3) {
|
|
107
|
+
var month = _ref3.month,
|
|
108
|
+
onMonthChange = _ref3.onMonthChange,
|
|
109
|
+
_ref3$weekStartsOn = _ref3.weekStartsOn,
|
|
110
|
+
weekStartsOn = _ref3$weekStartsOn === void 0 ? 0 : _ref3$weekStartsOn,
|
|
111
|
+
isDisabled = _ref3.isDisabled,
|
|
112
|
+
getDayState = _ref3.getDayState,
|
|
113
|
+
onSelect = _ref3.onSelect,
|
|
114
|
+
onPreview = _ref3.onPreview,
|
|
115
|
+
_ref3$preferredDate = _ref3.preferredDate,
|
|
116
|
+
preferredDate = _ref3$preferredDate === void 0 ? null : _ref3$preferredDate,
|
|
117
|
+
_ref3$size = _ref3.size,
|
|
118
|
+
size = _ref3$size === void 0 ? "popover" : _ref3$size,
|
|
119
|
+
_ref3$fullDateLabels = _ref3.fullDateLabels,
|
|
120
|
+
fullDateLabels = _ref3$fullDateLabels === void 0 ? false : _ref3$fullDateLabels,
|
|
121
|
+
_ref3$autoFocus = _ref3.autoFocus,
|
|
122
|
+
autoFocus = _ref3$autoFocus === void 0 ? false : _ref3$autoFocus,
|
|
123
|
+
_ref3$swipe = _ref3.swipe,
|
|
124
|
+
swipe = _ref3$swipe === void 0 ? false : _ref3$swipe,
|
|
125
|
+
_ref3$multiSelectable = _ref3.multiSelectable,
|
|
126
|
+
multiSelectable = _ref3$multiSelectable === void 0 ? false : _ref3$multiSelectable,
|
|
127
|
+
locale = _ref3.locale,
|
|
128
|
+
gridRef = _ref3.gridRef;
|
|
129
|
+
var _useState = useState(null),
|
|
130
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
131
|
+
focusedDate = _useState2[0],
|
|
132
|
+
setFocusedDate = _useState2[1];
|
|
133
|
+
// Set when a keyboard action / mount should move DOM focus to the active day.
|
|
134
|
+
var pendingFocus = useRef(autoFocus);
|
|
135
|
+
var ownGridRef = useRef(null);
|
|
136
|
+
var grid = gridRef || ownGridRef;
|
|
137
|
+
var sheet = size === "sheet";
|
|
138
|
+
var gridStart = startOfWeek(startOfMonth(month), {
|
|
139
|
+
weekStartsOn: weekStartsOn
|
|
140
|
+
});
|
|
141
|
+
var gridEnd = endOfWeek(endOfMonth(month), {
|
|
142
|
+
weekStartsOn: weekStartsOn
|
|
143
|
+
});
|
|
144
|
+
var days = eachDayOfInterval({
|
|
145
|
+
start: gridStart,
|
|
146
|
+
end: gridEnd
|
|
147
|
+
});
|
|
148
|
+
var weeks = [];
|
|
149
|
+
for (var i = 0; i < days.length; i += 7) weeks.push(days.slice(i, i + 7));
|
|
150
|
+
// Roving tabindex: exactly one enabled day is tabbable. Priority:
|
|
151
|
+
// keyboard-focused ?? preferred (selected) ?? today ?? first enabled day.
|
|
152
|
+
var usable = function usable(d) {
|
|
153
|
+
return d && isSameMonth(d, month) && !isDisabled(d);
|
|
154
|
+
};
|
|
155
|
+
var today = new Date();
|
|
156
|
+
var activeDate = null;
|
|
157
|
+
if (usable(focusedDate)) activeDate = focusedDate;else if (usable(preferredDate)) activeDate = preferredDate;else if (usable(today)) activeDate = today;else activeDate = days.find(function (d) {
|
|
158
|
+
return usable(d);
|
|
159
|
+
}) || days.find(function (d) {
|
|
160
|
+
return !isDisabled(d);
|
|
161
|
+
}) || null;
|
|
162
|
+
useEffect(function () {
|
|
163
|
+
var _grid$current, _grid$current$querySe, _grid$current$querySe2;
|
|
164
|
+
if (!pendingFocus.current) return;
|
|
165
|
+
pendingFocus.current = false;
|
|
166
|
+
(_grid$current = grid.current) === null || _grid$current === void 0 || (_grid$current$querySe = _grid$current.querySelector) === null || _grid$current$querySe === void 0 || (_grid$current$querySe = _grid$current$querySe.call(_grid$current, '[data-active-day="true"]')) === null || _grid$current$querySe === void 0 || (_grid$current$querySe2 = _grid$current$querySe.focus) === null || _grid$current$querySe2 === void 0 || _grid$current$querySe2.call(_grid$current$querySe);
|
|
167
|
+
});
|
|
168
|
+
var moveFocusTo = function moveFocusTo(date) {
|
|
169
|
+
if (!date || isDisabled(date)) return;
|
|
170
|
+
if (!isSameMonth(date, month)) onMonthChange(date);
|
|
171
|
+
setFocusedDate(date);
|
|
172
|
+
onPreview === null || onPreview === void 0 || onPreview(date);
|
|
173
|
+
pendingFocus.current = true;
|
|
174
|
+
};
|
|
175
|
+
var changeMonth = function changeMonth(step) {
|
|
176
|
+
var next = step > 0 ? addMonths(month, 1) : subMonths(month, 1);
|
|
177
|
+
onMonthChange(next);
|
|
178
|
+
};
|
|
179
|
+
var swipeProps = useMonthSwipe(swipe, changeMonth);
|
|
180
|
+
var handleKeyDown = function handleKeyDown(e, day, idx) {
|
|
181
|
+
var keys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", "Enter"];
|
|
182
|
+
if (!keys.includes(e.key)) return;
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
var rowStart = Math.floor(idx / 7) * 7;
|
|
185
|
+
switch (e.key) {
|
|
186
|
+
case "ArrowLeft":
|
|
187
|
+
moveFocusTo(addDays(day, -1));
|
|
188
|
+
break;
|
|
189
|
+
case "ArrowRight":
|
|
190
|
+
moveFocusTo(addDays(day, 1));
|
|
191
|
+
break;
|
|
192
|
+
case "ArrowUp":
|
|
193
|
+
moveFocusTo(addDays(day, -7));
|
|
194
|
+
break;
|
|
195
|
+
case "ArrowDown":
|
|
196
|
+
moveFocusTo(addDays(day, 7));
|
|
197
|
+
break;
|
|
198
|
+
case "PageUp":
|
|
199
|
+
moveFocusTo(subMonths(day, 1));
|
|
200
|
+
break;
|
|
201
|
+
case "PageDown":
|
|
202
|
+
moveFocusTo(addMonths(day, 1));
|
|
203
|
+
break;
|
|
204
|
+
case "Home":
|
|
205
|
+
moveFocusTo(days[rowStart]);
|
|
206
|
+
break;
|
|
207
|
+
case "End":
|
|
208
|
+
moveFocusTo(days[Math.min(days.length - 1, rowStart + 6)]);
|
|
209
|
+
break;
|
|
210
|
+
case "Enter":
|
|
211
|
+
if (!isDisabled(day)) onSelect(day);
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
var navClass = cn("inline-flex items-center justify-center rounded-md p-1 hover:bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500", TOUCH_TARGET);
|
|
216
|
+
return jsxs("div", {
|
|
217
|
+
children: [jsxs("div", {
|
|
218
|
+
className: cn("flex items-center justify-between", sheet ? "mb-3" : "mb-2"),
|
|
219
|
+
children: [jsx("button", {
|
|
220
|
+
type: "button",
|
|
221
|
+
className: navClass,
|
|
222
|
+
onClick: function onClick() {
|
|
223
|
+
return changeMonth(-1);
|
|
224
|
+
},
|
|
225
|
+
"aria-label": "Previous month",
|
|
226
|
+
children: jsx(ChevronLeft, {
|
|
227
|
+
className: "h-4 w-4",
|
|
228
|
+
"aria-hidden": "true"
|
|
229
|
+
})
|
|
230
|
+
}), jsx("h3", {
|
|
231
|
+
className: "text-sm font-medium",
|
|
232
|
+
"aria-live": "polite",
|
|
233
|
+
children: format(month, "MMMM yyyy")
|
|
234
|
+
}), jsx("button", {
|
|
235
|
+
type: "button",
|
|
236
|
+
className: navClass,
|
|
237
|
+
onClick: function onClick() {
|
|
238
|
+
return changeMonth(1);
|
|
239
|
+
},
|
|
240
|
+
"aria-label": "Next month",
|
|
241
|
+
children: jsx(ChevronRight, {
|
|
242
|
+
className: "h-4 w-4",
|
|
243
|
+
"aria-hidden": "true"
|
|
244
|
+
})
|
|
245
|
+
})]
|
|
246
|
+
}), jsx("div", {
|
|
247
|
+
className: "mb-1 grid grid-cols-7 gap-1",
|
|
248
|
+
"aria-hidden": "true",
|
|
249
|
+
children: Array.from({
|
|
250
|
+
length: 7
|
|
251
|
+
}).map(function (_, i) {
|
|
252
|
+
var label = WEEKDAYS[(i + weekStartsOn) % 7];
|
|
253
|
+
return jsx("div", {
|
|
254
|
+
className: "p-2 text-center text-xs font-medium text-primary-500",
|
|
255
|
+
children: label
|
|
256
|
+
}, label);
|
|
257
|
+
})
|
|
258
|
+
}), jsx("div", _objectSpread2(_objectSpread2({
|
|
259
|
+
ref: grid,
|
|
260
|
+
role: "grid",
|
|
261
|
+
"aria-label": format(month, "MMMM yyyy"),
|
|
262
|
+
"aria-multiselectable": multiSelectable || undefined,
|
|
263
|
+
"data-swipe": swipe ? "" : undefined,
|
|
264
|
+
className: cn("grid grid-cols-7", sheet ? "touch-pan-y gap-y-1" : "gap-1"),
|
|
265
|
+
onMouseLeave: onPreview ? function () {
|
|
266
|
+
return onPreview(null);
|
|
267
|
+
} : undefined
|
|
268
|
+
}, swipeProps), {}, {
|
|
269
|
+
children: weeks.map(function (week, w) {
|
|
270
|
+
return jsx("div", {
|
|
271
|
+
role: "row",
|
|
272
|
+
className: "contents",
|
|
273
|
+
children: week.map(function (day, i) {
|
|
274
|
+
var idx = w * 7 + i;
|
|
275
|
+
var state = getDayState(day) || {};
|
|
276
|
+
var disabled = isDisabled(day);
|
|
277
|
+
var currentMonth = isSameMonth(day, month);
|
|
278
|
+
var todayDate = isToday(day);
|
|
279
|
+
var active = activeDate != null && isSameDay(day, activeDate);
|
|
280
|
+
return jsx("button", {
|
|
281
|
+
type: "button",
|
|
282
|
+
role: "gridcell",
|
|
283
|
+
tabIndex: active ? 0 : -1,
|
|
284
|
+
"data-active-day": active ? "true" : undefined,
|
|
285
|
+
"data-in-range": state.inRange ? "" : undefined,
|
|
286
|
+
"aria-selected": Boolean(state.selected),
|
|
287
|
+
"aria-current": todayDate ? "date" : undefined,
|
|
288
|
+
"aria-label": fullDateLabels ? format(day, "EEEE, d MMMM yyyy", {
|
|
289
|
+
locale: locale
|
|
290
|
+
}) : undefined,
|
|
291
|
+
disabled: disabled,
|
|
292
|
+
onKeyDown: function onKeyDown(e) {
|
|
293
|
+
return handleKeyDown(e, day, idx);
|
|
294
|
+
},
|
|
295
|
+
onFocus: function onFocus() {
|
|
296
|
+
if (!focusedDate || !isSameDay(focusedDate, day)) setFocusedDate(day);
|
|
297
|
+
onPreview === null || onPreview === void 0 || onPreview(day);
|
|
298
|
+
},
|
|
299
|
+
onMouseEnter: onPreview ? function () {
|
|
300
|
+
return onPreview(day);
|
|
301
|
+
} : undefined,
|
|
302
|
+
onClick: function onClick() {
|
|
303
|
+
return !disabled && onSelect(day);
|
|
304
|
+
},
|
|
305
|
+
className: cn("mx-auto rounded-md text-sm transition-colors motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-1", sheet ? "h-11 w-full min-w-0 text-base" : "h-9 w-full max-w-9", {
|
|
306
|
+
"text-primary-400": !currentMonth,
|
|
307
|
+
"bg-primary-600 text-primary-50": state.edge,
|
|
308
|
+
"bg-primary-200": state.inRange && !state.edge,
|
|
309
|
+
"bg-primary-100 text-primary-600": todayDate && !state.edge && !state.inRange,
|
|
310
|
+
"hover:bg-background": currentMonth && !state.edge && !state.inRange && !disabled,
|
|
311
|
+
"cursor-not-allowed opacity-50": disabled
|
|
312
|
+
}),
|
|
313
|
+
children: format(day, "d")
|
|
314
|
+
}, day.toISOString());
|
|
315
|
+
})
|
|
316
|
+
}, w);
|
|
317
|
+
})
|
|
318
|
+
}))]
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
/** Popover surface classes: fluid width that never overflows a 320px screen. */
|
|
322
|
+
var POPOVER_CLASSES = "z-popover w-[min(20rem,calc(100vw-2rem))] rounded-md border border-line bg-surface p-4 shadow-lg";
|
|
323
|
+
/**
|
|
324
|
+
* A ref-like object for Sheet's `initialFocus`: the grid's tabbable day.
|
|
325
|
+
* Read lazily (when the sheet opens), never during render.
|
|
326
|
+
*/
|
|
327
|
+
function useActiveDayFocusRef(gridRef) {
|
|
328
|
+
return useMemo(function () {
|
|
329
|
+
return {
|
|
330
|
+
get current() {
|
|
331
|
+
var _gridRef$current$quer, _gridRef$current, _gridRef$current$quer2;
|
|
332
|
+
return (_gridRef$current$quer = (_gridRef$current = gridRef.current) === null || _gridRef$current === void 0 || (_gridRef$current$quer2 = _gridRef$current.querySelector) === null || _gridRef$current$quer2 === void 0 ? void 0 : _gridRef$current$quer2.call(_gridRef$current, '[data-active-day="true"]')) !== null && _gridRef$current$quer !== void 0 ? _gridRef$current$quer : null;
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}, [gridRef]);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Where the calendar lives: a bottom Sheet, or an anchored popover positioned
|
|
339
|
+
* by useFloatingPosition (fixed strategy, `z-popover`, fluid width).
|
|
340
|
+
*/
|
|
341
|
+
function PickerSurface(_ref4) {
|
|
342
|
+
var mode = _ref4.mode,
|
|
343
|
+
open = _ref4.open,
|
|
344
|
+
onClose = _ref4.onClose,
|
|
345
|
+
title = _ref4.title,
|
|
346
|
+
_ref4$portal = _ref4.portal,
|
|
347
|
+
portal = _ref4$portal === void 0 ? false : _ref4$portal,
|
|
348
|
+
floatingRef = _ref4.floatingRef,
|
|
349
|
+
floatingStyles = _ref4.floatingStyles,
|
|
350
|
+
_ref4$isPositioned = _ref4.isPositioned,
|
|
351
|
+
isPositioned = _ref4$isPositioned === void 0 ? true : _ref4$isPositioned,
|
|
352
|
+
initialFocus = _ref4.initialFocus,
|
|
353
|
+
sheetFooter = _ref4.sheetFooter,
|
|
354
|
+
children = _ref4.children;
|
|
355
|
+
if (mode === "sheet") {
|
|
356
|
+
return jsxs(Sheet, {
|
|
357
|
+
open: open,
|
|
358
|
+
onClose: onClose,
|
|
359
|
+
title: title,
|
|
360
|
+
initialFocus: initialFocus,
|
|
361
|
+
children: [jsx(Sheet.Body, {
|
|
362
|
+
children: children
|
|
363
|
+
}), sheetFooter ? jsx(Sheet.Footer, {
|
|
364
|
+
className: "justify-between",
|
|
365
|
+
children: sheetFooter
|
|
366
|
+
}) : null]
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
if (!open) return null;
|
|
370
|
+
var popup = jsx("div", {
|
|
371
|
+
ref: floatingRef,
|
|
372
|
+
className: cn(POPOVER_CLASSES, !isPositioned && "opacity-0"),
|
|
373
|
+
role: "dialog",
|
|
374
|
+
"aria-modal": "false",
|
|
375
|
+
style: floatingStyles,
|
|
376
|
+
children: children
|
|
377
|
+
});
|
|
378
|
+
return portal && typeof document !== "undefined" ? /*#__PURE__*/ReactDOM.createPortal(popup, document.body) : popup;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export { Calendar, POPOVER_CLASSES, PickerSurface, SWIPE_THRESHOLD, isBetween, makeIsDisabled, normalizeDate, useActiveDayFocusRef };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import 'react';
|
|
4
|
+
import { usePresentation } from '../../../hooks/usePresentation.js';
|
|
5
|
+
import MenuPopover from './MenuPopover.js';
|
|
6
|
+
import ActionSheetMenu from './ActionSheetMenu.js';
|
|
7
|
+
|
|
8
|
+
// Internal (not exported). The one action-menu primitive behind
|
|
9
|
+
// ThreeDotPopover and Table's row ActionMenu (DTUI-36). It resolves
|
|
10
|
+
// `presentation` (ADR 0001) and renders either:
|
|
11
|
+
// - popover: a portaled floating role="menu" next to `anchorEl`, or
|
|
12
|
+
// - sheet: an iOS-style action sheet in a bottom Sheet.
|
|
13
|
+
// The caller owns the open state and the trigger.
|
|
14
|
+
var RETURN_FOCUS_REASONS = new Set(["select", "escape", "tab", "cancel"]);
|
|
15
|
+
/**
|
|
16
|
+
* @param {object} props
|
|
17
|
+
* @param {boolean} props.open
|
|
18
|
+
* @param {(reason: string) => void} props.onClose - reason is one of 'select',
|
|
19
|
+
* 'escape', 'outside', 'tab', 'scroll' (popover) or 'cancel', 'backdrop',
|
|
20
|
+
* 'drag' (sheet).
|
|
21
|
+
* @param {HTMLElement|null} props.anchorEl - trigger element; focus returns to
|
|
22
|
+
* it after select / Escape / Tab / Cancel.
|
|
23
|
+
* @param {Array<object>} props.items - normalized items (see menuItems.js).
|
|
24
|
+
* @param {'auto'|'popover'|'sheet'} [props.presentation='auto']
|
|
25
|
+
* @param {string} [props.placement='bottom-start'] - popover placement.
|
|
26
|
+
* @param {'first'|'last'} [props.initialFocus='first'] - popover item focused on open.
|
|
27
|
+
* @param {boolean} [props.closeOnSelect=true]
|
|
28
|
+
* @param {boolean} [props.closeOnScroll=false] - popover only.
|
|
29
|
+
* @param {React.Ref} [props.menuRef] - receives the menu (popover) or sheet panel element.
|
|
30
|
+
* @param {string} [props.menuClassName] - popover menu classes.
|
|
31
|
+
* @param {string} [props.itemClassName] - classes for every item (both modes).
|
|
32
|
+
* @param {string} [props.label] - accessible name of the menu / sheet.
|
|
33
|
+
* @param {React.ReactNode} [props.sheetTitle] - optional heading in the sheet.
|
|
34
|
+
* @param {React.ReactNode} [props.cancelLabel='Cancel'] - sheet Cancel button text.
|
|
35
|
+
* @param {React.ReactNode} [props.emptyLabel='No actions']
|
|
36
|
+
*/
|
|
37
|
+
function ActionMenuSurface(_ref) {
|
|
38
|
+
var open = _ref.open,
|
|
39
|
+
onClose = _ref.onClose,
|
|
40
|
+
anchorEl = _ref.anchorEl,
|
|
41
|
+
_ref$items = _ref.items,
|
|
42
|
+
items = _ref$items === void 0 ? [] : _ref$items,
|
|
43
|
+
_ref$presentation = _ref.presentation,
|
|
44
|
+
presentation = _ref$presentation === void 0 ? "auto" : _ref$presentation,
|
|
45
|
+
_ref$placement = _ref.placement,
|
|
46
|
+
placement = _ref$placement === void 0 ? "bottom-start" : _ref$placement,
|
|
47
|
+
_ref$initialFocus = _ref.initialFocus,
|
|
48
|
+
initialFocus = _ref$initialFocus === void 0 ? "first" : _ref$initialFocus,
|
|
49
|
+
_ref$closeOnSelect = _ref.closeOnSelect,
|
|
50
|
+
closeOnSelect = _ref$closeOnSelect === void 0 ? true : _ref$closeOnSelect,
|
|
51
|
+
_ref$closeOnScroll = _ref.closeOnScroll,
|
|
52
|
+
closeOnScroll = _ref$closeOnScroll === void 0 ? false : _ref$closeOnScroll,
|
|
53
|
+
menuRef = _ref.menuRef,
|
|
54
|
+
id = _ref.id,
|
|
55
|
+
menuClassName = _ref.menuClassName,
|
|
56
|
+
itemClassName = _ref.itemClassName,
|
|
57
|
+
label = _ref.label,
|
|
58
|
+
sheetTitle = _ref.sheetTitle,
|
|
59
|
+
_ref$cancelLabel = _ref.cancelLabel,
|
|
60
|
+
cancelLabel = _ref$cancelLabel === void 0 ? "Cancel" : _ref$cancelLabel,
|
|
61
|
+
_ref$emptyLabel = _ref.emptyLabel,
|
|
62
|
+
emptyLabel = _ref$emptyLabel === void 0 ? "No actions" : _ref$emptyLabel;
|
|
63
|
+
var mode = usePresentation(presentation);
|
|
64
|
+
var list = Array.isArray(items) ? items : [];
|
|
65
|
+
var close = function close(reason) {
|
|
66
|
+
var _anchorEl$focus;
|
|
67
|
+
onClose === null || onClose === void 0 || onClose(reason);
|
|
68
|
+
if (RETURN_FOCUS_REASONS.has(reason)) anchorEl === null || anchorEl === void 0 || (_anchorEl$focus = anchorEl.focus) === null || _anchorEl$focus === void 0 || _anchorEl$focus.call(anchorEl, {
|
|
69
|
+
preventScroll: true
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
var selectItem = function selectItem(item) {
|
|
73
|
+
var _item$onSelect;
|
|
74
|
+
if (item.disabled) return;
|
|
75
|
+
(_item$onSelect = item.onSelect) === null || _item$onSelect === void 0 || _item$onSelect.call(item);
|
|
76
|
+
if (closeOnSelect) close("select");
|
|
77
|
+
};
|
|
78
|
+
if (mode === "sheet") {
|
|
79
|
+
return jsx(ActionSheetMenu, {
|
|
80
|
+
ref: menuRef,
|
|
81
|
+
open: Boolean(open),
|
|
82
|
+
onClose: close,
|
|
83
|
+
groups: [list],
|
|
84
|
+
onSelectItem: selectItem,
|
|
85
|
+
title: sheetTitle,
|
|
86
|
+
label: label || "Actions",
|
|
87
|
+
cancelLabel: cancelLabel,
|
|
88
|
+
emptyLabel: emptyLabel,
|
|
89
|
+
itemClassName: itemClassName
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (!open) return null;
|
|
93
|
+
return jsx(MenuPopover, {
|
|
94
|
+
anchorEl: anchorEl,
|
|
95
|
+
items: list,
|
|
96
|
+
onSelectItem: selectItem,
|
|
97
|
+
onRequestClose: close,
|
|
98
|
+
placement: placement,
|
|
99
|
+
initialFocus: initialFocus,
|
|
100
|
+
closeOnScroll: closeOnScroll,
|
|
101
|
+
menuRef: menuRef,
|
|
102
|
+
id: id,
|
|
103
|
+
label: label,
|
|
104
|
+
className: menuClassName,
|
|
105
|
+
itemClassName: itemClassName,
|
|
106
|
+
emptyLabel: emptyLabel
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export { ActionMenuSurface as default };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import React, { useId } from 'react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
import Sheet from '../../feedback/Sheet.js';
|
|
7
|
+
import { isDestructive } from './menuItems.js';
|
|
8
|
+
|
|
9
|
+
var _excluded = ["open", "onClose", "groups", "onSelectItem", "title", "message", "label", "cancelLabel", "emptyLabel", "itemClassName", "className"];
|
|
10
|
+
// Internal. The one action-sheet implementation: an iOS-style action sheet in
|
|
11
|
+
// a bottom Sheet. Actions sit in rounded cards (one card per group),
|
|
12
|
+
// destructive actions use the error tone, and a separate Cancel button closes
|
|
13
|
+
// the sheet. Rows are at least 48px tall. Shared by the phone presentation of
|
|
14
|
+
// ThreeDotPopover / Table's row menu (via ActionMenuSurface) and the public
|
|
15
|
+
// `ActionSheet` (DTUI-53), so it depends only on Sheet and normalized items.
|
|
16
|
+
var CARD_CLASSES = "overflow-hidden rounded-card bg-surface divide-y divide-line";
|
|
17
|
+
var ROW_CLASSES = "flex min-h-12 w-full items-center justify-center gap-3 px-4 py-2 text-center text-base outline-none transition-colors motion-reduce:transition-none active:bg-line/50 focus-visible:bg-line/50 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary-500";
|
|
18
|
+
function rowToneClass(item) {
|
|
19
|
+
if (item.disabled) return "cursor-not-allowed opacity-50 text-muted";
|
|
20
|
+
if (isDestructive(item)) return "text-error-600 dark:text-error-400";
|
|
21
|
+
return "text-primary-600 dark:text-primary-400";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} props
|
|
25
|
+
* @param {boolean} props.open
|
|
26
|
+
* @param {(reason: string) => void} props.onClose - 'cancel' | 'escape' | 'backdrop' | 'drag'.
|
|
27
|
+
* @param {Array<Array<object>>} props.groups - normalized items, one card per group.
|
|
28
|
+
* @param {(item: object) => void} props.onSelectItem
|
|
29
|
+
* @param {React.ReactNode} [props.title] - small muted heading at the top of the first card.
|
|
30
|
+
* @param {React.ReactNode} [props.message] - muted text under the title (the sheet's description).
|
|
31
|
+
* @param {string} [props.label] - accessible name of the sheet; without it the
|
|
32
|
+
* title names the sheet, and with neither it is "Actions".
|
|
33
|
+
* @param {React.ReactNode} [props.cancelLabel='Cancel']
|
|
34
|
+
* Other props are forwarded to the Sheet panel.
|
|
35
|
+
*/
|
|
36
|
+
var ActionSheetMenu = /*#__PURE__*/React.forwardRef(function ActionSheetMenu(_ref, ref) {
|
|
37
|
+
var open = _ref.open,
|
|
38
|
+
onClose = _ref.onClose,
|
|
39
|
+
groups = _ref.groups,
|
|
40
|
+
onSelectItem = _ref.onSelectItem,
|
|
41
|
+
title = _ref.title,
|
|
42
|
+
message = _ref.message,
|
|
43
|
+
label = _ref.label,
|
|
44
|
+
_ref$cancelLabel = _ref.cancelLabel,
|
|
45
|
+
cancelLabel = _ref$cancelLabel === void 0 ? "Cancel" : _ref$cancelLabel,
|
|
46
|
+
_ref$emptyLabel = _ref.emptyLabel,
|
|
47
|
+
emptyLabel = _ref$emptyLabel === void 0 ? "No actions" : _ref$emptyLabel,
|
|
48
|
+
itemClassName = _ref.itemClassName,
|
|
49
|
+
className = _ref.className,
|
|
50
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
51
|
+
var nonEmpty = (groups || []).filter(function (g) {
|
|
52
|
+
return Array.isArray(g) && g.length > 0;
|
|
53
|
+
});
|
|
54
|
+
var id = useId();
|
|
55
|
+
var titleId = "action-sheet-title-".concat(id);
|
|
56
|
+
var messageId = "action-sheet-message-".concat(id);
|
|
57
|
+
var hasTitle = title != null;
|
|
58
|
+
var hasMessage = message != null;
|
|
59
|
+
var labelledByTitle = label == null && hasTitle;
|
|
60
|
+
var header = hasTitle || hasMessage ? jsxs("div", {
|
|
61
|
+
className: "px-4 py-3 text-center",
|
|
62
|
+
children: [hasTitle && jsx("div", {
|
|
63
|
+
id: titleId,
|
|
64
|
+
className: cn("text-xs text-muted", hasMessage && "font-semibold"),
|
|
65
|
+
children: title
|
|
66
|
+
}), hasMessage && jsx("div", {
|
|
67
|
+
id: messageId,
|
|
68
|
+
className: cn("text-xs text-muted", hasTitle && "mt-1"),
|
|
69
|
+
children: message
|
|
70
|
+
})]
|
|
71
|
+
}) : null;
|
|
72
|
+
return jsx(Sheet, _objectSpread2(_objectSpread2({
|
|
73
|
+
ref: ref,
|
|
74
|
+
open: open,
|
|
75
|
+
onClose: onClose,
|
|
76
|
+
handle: false,
|
|
77
|
+
showCloseButton: false,
|
|
78
|
+
"aria-label": labelledByTitle ? undefined : label !== null && label !== void 0 ? label : "Actions",
|
|
79
|
+
"aria-labelledby": labelledByTitle ? titleId : undefined,
|
|
80
|
+
"aria-describedby": hasMessage ? messageId : undefined,
|
|
81
|
+
"data-presentation": "sheet",
|
|
82
|
+
// The panel is a transparent tray; the cards carry the surface.
|
|
83
|
+
className: cn("border-0 bg-transparent !shadow-none", className)
|
|
84
|
+
}, rest), {}, {
|
|
85
|
+
children: jsxs(Sheet.Body, {
|
|
86
|
+
className: "flex flex-col gap-2 p-2",
|
|
87
|
+
onClick: function onClick(e) {
|
|
88
|
+
return e.stopPropagation();
|
|
89
|
+
},
|
|
90
|
+
children: [nonEmpty.length === 0 ? jsxs("div", {
|
|
91
|
+
className: CARD_CLASSES,
|
|
92
|
+
children: [header, jsx("div", {
|
|
93
|
+
className: "flex min-h-12 items-center justify-center px-4 text-sm italic text-muted",
|
|
94
|
+
children: emptyLabel
|
|
95
|
+
})]
|
|
96
|
+
}) : nonEmpty.map(function (group, g) {
|
|
97
|
+
return jsxs("div", {
|
|
98
|
+
role: "group",
|
|
99
|
+
className: CARD_CLASSES,
|
|
100
|
+
children: [g === 0 && header, group.map(function (item, idx) {
|
|
101
|
+
var _item$content, _item$key;
|
|
102
|
+
return jsx("button", {
|
|
103
|
+
type: "button",
|
|
104
|
+
disabled: item.disabled || undefined,
|
|
105
|
+
"aria-disabled": item.disabled || undefined,
|
|
106
|
+
"data-tone": isDestructive(item) ? "destructive" : undefined,
|
|
107
|
+
className: cn(ROW_CLASSES, rowToneClass(item), itemClassName),
|
|
108
|
+
onClick: function onClick(e) {
|
|
109
|
+
e.stopPropagation();
|
|
110
|
+
if (!item.disabled) onSelectItem(item);
|
|
111
|
+
},
|
|
112
|
+
children: (_item$content = item.content) !== null && _item$content !== void 0 ? _item$content : jsxs(Fragment, {
|
|
113
|
+
children: [item.icon != null && jsx("span", {
|
|
114
|
+
className: "inline-flex shrink-0",
|
|
115
|
+
"aria-hidden": "true",
|
|
116
|
+
children: item.icon
|
|
117
|
+
}), jsx("span", {
|
|
118
|
+
className: "min-w-0 truncate",
|
|
119
|
+
children: item.label
|
|
120
|
+
})]
|
|
121
|
+
})
|
|
122
|
+
}, (_item$key = item.key) !== null && _item$key !== void 0 ? _item$key : "item-".concat(idx));
|
|
123
|
+
})]
|
|
124
|
+
}, "group-".concat(g));
|
|
125
|
+
}), jsx("button", {
|
|
126
|
+
type: "button",
|
|
127
|
+
"data-action-sheet-cancel": "",
|
|
128
|
+
className: cn(CARD_CLASSES, ROW_CLASSES, "font-semibold text-primary-600 dark:text-primary-400"),
|
|
129
|
+
onClick: function onClick(e) {
|
|
130
|
+
e.stopPropagation();
|
|
131
|
+
onClose === null || onClose === void 0 || onClose("cancel");
|
|
132
|
+
},
|
|
133
|
+
children: cancelLabel
|
|
134
|
+
})]
|
|
135
|
+
})
|
|
136
|
+
}));
|
|
137
|
+
});
|
|
138
|
+
ActionSheetMenu.displayName = "ActionSheetMenu";
|
|
139
|
+
|
|
140
|
+
export { ActionSheetMenu as default };
|