@dreamtree-org/twreact-ui 1.3.10 → 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 +70 -6
- package/ai-skills/dreamtree-ui.md +58 -15
- package/codemods/v2.cjs +198 -0
- package/dist/ai-schema.json +745 -53
- package/dist/charts/index.js +195 -66
- 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/charts/CartesianChart.d.ts.map +1 -1
- package/dist/components/charts/ChartFrame.d.ts.map +1 -1
- package/dist/components/charts/useChartLayout.d.ts +25 -0
- package/dist/components/charts/useChartLayout.d.ts.map +1 -0
- package/dist/components/core/Button.d.ts.map +1 -1
- package/dist/components/core/Checkbox.d.ts.map +1 -1
- package/dist/components/core/ColorPicker.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/Loader.d.ts.map +1 -1
- package/dist/components/core/LocationPicker.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/Radio.d.ts.map +1 -1
- package/dist/components/core/Rate.d.ts.map +1 -1
- package/dist/components/core/RoundedTag.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/Skeleton.d.ts.map +1 -1
- package/dist/components/core/Slider.d.ts.map +1 -1
- package/dist/components/core/SpeechToText.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 +5 -8
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/Textarea.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/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/FootNav.d.ts.map +1 -1
- 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/Avatar.d.ts +8 -0
- package/dist/components/utility/Avatar.d.ts.map +1 -1
- package/dist/components/utility/AvatarGroup.d.ts +4 -0
- package/dist/components/utility/AvatarGroup.d.ts.map +1 -0
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/Card.d.ts.map +1 -1
- package/dist/components/utility/Carousel.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Pagination.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/components/utility/Sortable.d.ts.map +1 -1
- package/dist/components/utility/Stepper.d.ts.map +1 -1
- 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/EmptyState.js +1 -1
- package/dist/esm/components/blocks/ErrorState.js +1 -1
- package/dist/esm/components/blocks/LoadingState.js +4 -4
- package/dist/esm/components/blocks/PageHeader.js +16 -3
- package/dist/esm/components/blocks/StatCard.js +6 -6
- package/dist/esm/components/blocks/StatusPill.js +5 -8
- package/dist/esm/components/charts/CartesianChart.js +85 -62
- package/dist/esm/components/charts/ChartFrame.js +12 -5
- package/dist/esm/components/charts/useChartLayout.js +105 -0
- package/dist/esm/components/core/Button.js +49 -25
- package/dist/esm/components/core/Checkbox.js +72 -57
- package/dist/esm/components/core/ColorPicker.js +31 -42
- 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 +100 -38
- package/dist/esm/components/core/Loader.js +30 -44
- package/dist/esm/components/core/LocationPicker.js +82 -16
- package/dist/esm/components/core/Popover.js +59 -48
- package/dist/esm/components/core/ProgressBar.js +40 -72
- package/dist/esm/components/core/Radio.js +10 -12
- package/dist/esm/components/core/Rate.js +77 -14
- package/dist/esm/components/core/RoundedTag.js +5 -5
- 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/Skeleton.js +13 -14
- package/dist/esm/components/core/Slider.js +24 -6
- package/dist/esm/components/core/SpeechToText.js +68 -16
- 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 +98 -28
- 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 +186 -39
- package/dist/esm/components/core/Textarea.js +10 -2
- 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/Breadcrumbs.js +97 -35
- package/dist/esm/components/navigation/Dropdown.js +1 -1
- package/dist/esm/components/navigation/FootNav.js +102 -13
- 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/Avatar.js +14 -12
- package/dist/esm/components/utility/AvatarGroup.js +56 -0
- package/dist/esm/components/utility/Badge.js +43 -23
- package/dist/esm/components/utility/Card.js +32 -8
- package/dist/esm/components/utility/Carousel.js +139 -29
- package/dist/esm/components/utility/FileUpload.js +106 -31
- package/dist/esm/components/utility/Pagination.js +31 -13
- package/dist/esm/components/utility/Portal.js +31 -0
- package/dist/esm/components/utility/PullToRefresh.js +229 -0
- package/dist/esm/components/utility/Sortable.js +6 -2
- package/dist/esm/components/utility/Stepper.js +110 -47
- 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/hooks/useSliderValues.js +8 -2
- package/dist/esm/hooks/useSortable.js +107 -5
- package/dist/esm/index.js +14 -2
- package/dist/esm/utils/position.js +10 -63
- package/dist/esm/utils/touchTarget.js +4 -1
- 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/hooks/useSliderValues.d.ts +6 -2
- package/dist/hooks/useSliderValues.d.ts.map +1 -1
- package/dist/hooks/useSortable.d.ts +11 -1
- package/dist/hooks/useSortable.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +10645 -3842
- package/dist/index.js +10657 -3845
- 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/charts.d.ts +3 -1
- package/dist/types/charts.d.ts.map +1 -1
- package/dist/types/index.d.ts +409 -26
- 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 +16 -0
- package/mcp/catalog.snapshot.json +1540 -407
- 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
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
-
import React, { forwardRef, useState, useRef, useId, useEffect, createContext, useContext } from 'react';
|
|
4
|
+
import React, { forwardRef, useState, useRef, useId, useEffect, createContext, useContext, useLayoutEffect } from 'react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
6
|
|
|
7
|
-
var _excluded = ["children", "defaultIndex", "index", "onChange", "orientation", "size", "variant", "animated", "className"]
|
|
7
|
+
var _excluded = ["children", "defaultIndex", "index", "onChange", "orientation", "size", "variant", "animated", "swipeable", "className"],
|
|
8
|
+
_excluded2 = ["children", "className"];
|
|
9
|
+
// useLayoutEffect warns during SSR; fall back to useEffect on the server.
|
|
10
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
11
|
+
// Minimum horizontal travel (px) for a swipe to change tabs, and how much more
|
|
12
|
+
// horizontal than vertical it must be, so vertical page scrolls never switch tabs.
|
|
13
|
+
var SWIPE_THRESHOLD = 50;
|
|
14
|
+
var SWIPE_DOMINANCE = 1.5;
|
|
15
|
+
// Variants whose active state is drawn by the sliding indicator (horizontal only).
|
|
16
|
+
var INDICATOR_VARIANTS = ["line", "segmented"];
|
|
8
17
|
/*
|
|
9
18
|
Tabs.jsx
|
|
10
19
|
- Default export: Tabs (provider wrapper)
|
|
@@ -14,7 +23,10 @@ var _excluded = ["children", "defaultIndex", "index", "onChange", "orientation",
|
|
|
14
23
|
- Controlled / uncontrolled usage
|
|
15
24
|
- Keyboard navigation (Arrow keys, Home, End)
|
|
16
25
|
- ARIA attributes for accessibility
|
|
17
|
-
- Variants: "line" | "pills" | "unstyled"
|
|
26
|
+
- Variants: "line" | "pills" | "segmented" | "unstyled"
|
|
27
|
+
- Horizontal lists scroll with snap; the active tab is kept in view
|
|
28
|
+
- Animated active indicator for "line" / "segmented" (off under reduced motion)
|
|
29
|
+
- Optional `swipeable` panels (touch / pen pointer swipes)
|
|
18
30
|
- Sizes: "sm" | "md" | "lg"
|
|
19
31
|
- Simple fade animation
|
|
20
32
|
- Tailwind CSS only
|
|
@@ -60,6 +72,8 @@ var Tabs = /*#__PURE__*/forwardRef(function Tabs(_ref, ref) {
|
|
|
60
72
|
variant = _ref$variant === void 0 ? "line" : _ref$variant,
|
|
61
73
|
_ref$animated = _ref.animated,
|
|
62
74
|
animated = _ref$animated === void 0 ? true : _ref$animated,
|
|
75
|
+
_ref$swipeable = _ref.swipeable,
|
|
76
|
+
swipeable = _ref$swipeable === void 0 ? false : _ref$swipeable,
|
|
63
77
|
_ref$className = _ref.className,
|
|
64
78
|
className = _ref$className === void 0 ? "" : _ref$className,
|
|
65
79
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
@@ -71,6 +85,12 @@ var Tabs = /*#__PURE__*/forwardRef(function Tabs(_ref, ref) {
|
|
|
71
85
|
var activeIndex = isControlled ? controlledIndex : internalIndex;
|
|
72
86
|
var tabsRef = useRef([]); // DOM refs for keyboard navigation
|
|
73
87
|
var baseId = useId();
|
|
88
|
+
// Set by TabList once the sliding indicator has been measured; until then
|
|
89
|
+
// (SSR, first paint) tabs draw their own active styling.
|
|
90
|
+
var _useState3 = useState(false),
|
|
91
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
92
|
+
indicatorReady = _useState4[0],
|
|
93
|
+
setIndicatorReady = _useState4[1];
|
|
74
94
|
var changeTab = function changeTab(idx) {
|
|
75
95
|
if (!isControlled) setActiveIndex(idx);
|
|
76
96
|
onChange === null || onChange === void 0 || onChange(idx);
|
|
@@ -87,7 +107,10 @@ var Tabs = /*#__PURE__*/forwardRef(function Tabs(_ref, ref) {
|
|
|
87
107
|
orientation: orientation,
|
|
88
108
|
size: size,
|
|
89
109
|
variant: variant,
|
|
90
|
-
animated: animated
|
|
110
|
+
animated: animated,
|
|
111
|
+
swipeable: swipeable,
|
|
112
|
+
indicatorReady: indicatorReady,
|
|
113
|
+
setIndicatorReady: setIndicatorReady
|
|
91
114
|
};
|
|
92
115
|
return jsx(TabsContext.Provider, {
|
|
93
116
|
value: value,
|
|
@@ -101,33 +124,104 @@ var Tabs = /*#__PURE__*/forwardRef(function Tabs(_ref, ref) {
|
|
|
101
124
|
});
|
|
102
125
|
Tabs.displayName = "Tabs";
|
|
103
126
|
/* ------------------------- TabList ------------------------- */
|
|
104
|
-
function TabList(_ref2) {
|
|
127
|
+
var TabList = /*#__PURE__*/forwardRef(function TabList(_ref2, ref) {
|
|
105
128
|
var children = _ref2.children,
|
|
106
129
|
_ref2$className = _ref2.className,
|
|
107
|
-
className = _ref2$className === void 0 ? "" : _ref2$className
|
|
130
|
+
className = _ref2$className === void 0 ? "" : _ref2$className,
|
|
131
|
+
rest = _objectWithoutProperties(_ref2, _excluded2);
|
|
108
132
|
var _useTabsContext = useTabsContext("Tabs.List"),
|
|
109
|
-
orientation = _useTabsContext.orientation
|
|
110
|
-
|
|
133
|
+
orientation = _useTabsContext.orientation,
|
|
134
|
+
variant = _useTabsContext.variant,
|
|
135
|
+
activeIndex = _useTabsContext.activeIndex,
|
|
136
|
+
tabsRef = _useTabsContext.tabsRef,
|
|
137
|
+
indicatorReady = _useTabsContext.indicatorReady,
|
|
138
|
+
setIndicatorReady = _useTabsContext.setIndicatorReady;
|
|
139
|
+
var listRef = useRef(null);
|
|
140
|
+
var _useState5 = useState(null),
|
|
141
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
142
|
+
indicator = _useState6[0],
|
|
143
|
+
setIndicator = _useState6[1];
|
|
144
|
+
var horizontal = orientation !== "vertical";
|
|
145
|
+
var hasIndicator = horizontal && INDICATOR_VARIANTS.includes(variant);
|
|
146
|
+
var childCount = React.Children.count(children);
|
|
147
|
+
var setRefs = function setRefs(node) {
|
|
148
|
+
listRef.current = node;
|
|
149
|
+
if (typeof ref === "function") ref(node);else if (ref) ref.current = node;
|
|
150
|
+
};
|
|
151
|
+
// Measure the active tab: position the indicator and scroll the tab into view.
|
|
152
|
+
useIsomorphicLayoutEffect(function () {
|
|
153
|
+
var list = listRef.current;
|
|
154
|
+
var tab = tabsRef.current[activeIndex];
|
|
155
|
+
if (!list || !tab) return undefined;
|
|
156
|
+
var measure = function measure() {
|
|
157
|
+
if (horizontal) {
|
|
158
|
+
var left = tab.offsetLeft;
|
|
159
|
+
var right = left + tab.offsetWidth;
|
|
160
|
+
if (left < list.scrollLeft) list.scrollLeft = left;else if (right > list.scrollLeft + list.clientWidth) list.scrollLeft = right - list.clientWidth;
|
|
161
|
+
}
|
|
162
|
+
// jsdom / display:none report 0; keep the tabs' own active styling then.
|
|
163
|
+
if (!hasIndicator || !tab.offsetWidth) return;
|
|
164
|
+
setIndicator({
|
|
165
|
+
left: tab.offsetLeft,
|
|
166
|
+
top: tab.offsetTop,
|
|
167
|
+
width: tab.offsetWidth,
|
|
168
|
+
height: tab.offsetHeight
|
|
169
|
+
});
|
|
170
|
+
setIndicatorReady(true);
|
|
171
|
+
};
|
|
172
|
+
measure();
|
|
173
|
+
if (typeof ResizeObserver === "undefined") return undefined;
|
|
174
|
+
var ro = new ResizeObserver(measure);
|
|
175
|
+
ro.observe(list);
|
|
176
|
+
ro.observe(tab);
|
|
177
|
+
return function () {
|
|
178
|
+
return ro.disconnect();
|
|
179
|
+
};
|
|
180
|
+
}, [activeIndex, hasIndicator, horizontal, childCount]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
181
|
+
// Leaving an indicator variant hands the active styling back to the tabs.
|
|
182
|
+
useEffect(function () {
|
|
183
|
+
if (!hasIndicator && indicatorReady) setIndicatorReady(false);
|
|
184
|
+
}, [hasIndicator, indicatorReady, setIndicatorReady]);
|
|
185
|
+
var showIndicator = hasIndicator && indicatorReady && indicator;
|
|
186
|
+
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
187
|
+
ref: setRefs,
|
|
111
188
|
role: "tablist",
|
|
112
189
|
"aria-orientation": orientation,
|
|
113
|
-
className:
|
|
114
|
-
|
|
190
|
+
className: cn("relative flex gap-1", horizontal ?
|
|
191
|
+
// Scroll with snap, scrollbar hidden; native smooth scrolling unless reduced motion.
|
|
192
|
+
"flex-row overflow-x-auto snap-x snap-mandatory scroll-smooth motion-reduce:scroll-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" : "flex-col", variant === "segmented" && "rounded-lg bg-line p-1", className)
|
|
193
|
+
}, rest), {}, {
|
|
194
|
+
children: [showIndicator && jsx("span", {
|
|
195
|
+
"aria-hidden": "true",
|
|
196
|
+
"data-tabs-indicator": "",
|
|
197
|
+
className: cn("pointer-events-none absolute left-0 top-0", "transition-[transform,width,height] duration-base ease-standard motion-reduce:transition-none", variant === "line" ? "bg-primary-500" : "rounded-md bg-surface shadow-sm"),
|
|
198
|
+
style: variant === "line" ? {
|
|
199
|
+
width: indicator.width,
|
|
200
|
+
height: 2,
|
|
201
|
+
transform: "translate(".concat(indicator.left, "px, ").concat(indicator.top + indicator.height - 2, "px)")
|
|
202
|
+
} : {
|
|
203
|
+
width: indicator.width,
|
|
204
|
+
height: indicator.height,
|
|
205
|
+
transform: "translate(".concat(indicator.left, "px, ").concat(indicator.top, "px)")
|
|
206
|
+
}
|
|
207
|
+
}), React.Children.map(children, function (child, i) {
|
|
115
208
|
var _child$props$index;
|
|
116
209
|
if (! /*#__PURE__*/React.isValidElement(child)) return child;
|
|
117
210
|
return /*#__PURE__*/React.cloneElement(child, {
|
|
118
211
|
index: (_child$props$index = child.props.index) !== null && _child$props$index !== void 0 ? _child$props$index : i
|
|
119
212
|
});
|
|
120
|
-
})
|
|
121
|
-
});
|
|
122
|
-
}
|
|
213
|
+
})]
|
|
214
|
+
}));
|
|
215
|
+
});
|
|
216
|
+
TabList.displayName = "Tabs.List";
|
|
123
217
|
/* ------------------------- Tab ------------------------- */
|
|
124
218
|
function Tab(_ref3) {
|
|
125
219
|
var children = _ref3.children,
|
|
126
220
|
index = _ref3.index,
|
|
127
221
|
_ref3$className = _ref3.className,
|
|
128
222
|
className = _ref3$className === void 0 ? "" : _ref3$className,
|
|
129
|
-
|
|
130
|
-
|
|
223
|
+
leftIcon = _ref3.leftIcon,
|
|
224
|
+
rightIcon = _ref3.rightIcon,
|
|
131
225
|
_ref3$disabled = _ref3.disabled,
|
|
132
226
|
disabled = _ref3$disabled === void 0 ? false : _ref3$disabled,
|
|
133
227
|
_ref3$tabClassName = _ref3.tabClassName,
|
|
@@ -139,32 +233,45 @@ function Tab(_ref3) {
|
|
|
139
233
|
tabsRef = _useTabsContext2.tabsRef,
|
|
140
234
|
baseId = _useTabsContext2.baseId,
|
|
141
235
|
size = _useTabsContext2.size,
|
|
142
|
-
variant = _useTabsContext2.variant
|
|
236
|
+
variant = _useTabsContext2.variant,
|
|
237
|
+
orientation = _useTabsContext2.orientation,
|
|
238
|
+
indicatorReady = _useTabsContext2.indicatorReady;
|
|
143
239
|
var internalRef = useRef(null);
|
|
144
240
|
// If the user didn't provide `index` we derive from DOM position by registering nulls until mount.
|
|
145
241
|
// However it's recommended to always keep Tabs.Tab order consistent with Panels.
|
|
146
|
-
|
|
242
|
+
// Registered from a ref callback (runs at commit, before any layout effect) so
|
|
243
|
+
// Tabs.List can measure the active tab on mount without a flash.
|
|
244
|
+
var setTabRef = function setTabRef(el) {
|
|
245
|
+
internalRef.current = el;
|
|
246
|
+
if (!el) return;
|
|
147
247
|
// find index in tabsRef if index not provided
|
|
148
|
-
var
|
|
149
|
-
return
|
|
248
|
+
var slot = typeof index === "number" ? index : tabsRef.current.findIndex(function (node) {
|
|
249
|
+
return node === el;
|
|
150
250
|
});
|
|
151
|
-
if (
|
|
152
|
-
registerTab(
|
|
153
|
-
|
|
154
|
-
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
251
|
+
if (slot === -1) slot = tabsRef.current.length; // fallback
|
|
252
|
+
registerTab(el, slot);
|
|
253
|
+
};
|
|
155
254
|
// TabList always injects `index`; a Tab rendered outside it is never selected.
|
|
156
255
|
var idx = typeof index === "number" ? index : -1;
|
|
157
256
|
var selected = idx === activeIndex;
|
|
158
257
|
var id = tabId(baseId, idx);
|
|
159
|
-
var
|
|
258
|
+
var horizontal = orientation !== "vertical";
|
|
259
|
+
// Once the sliding indicator is measured it draws the active state; until then
|
|
260
|
+
// (SSR / first paint) the tab draws it itself so nothing flashes.
|
|
261
|
+
var indicatorDraws = indicatorReady && horizontal && INDICATOR_VARIANTS.includes(variant);
|
|
262
|
+
var base = cn("relative inline-flex items-center gap-2 whitespace-nowrap outline-none select-none", "focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-1", "transition-colors duration-fast motion-reduce:transition-none", "disabled:cursor-not-allowed disabled:opacity-50",
|
|
263
|
+
// The scrolling list clips outside rings, so horizontal tabs draw theirs inset.
|
|
264
|
+
horizontal && "shrink-0 snap-start focus-visible:ring-inset focus-visible:ring-offset-0");
|
|
160
265
|
var sizeClasses = {
|
|
161
266
|
sm: "px-2 py-1 text-sm",
|
|
162
267
|
md: "px-3 py-2 text-sm",
|
|
163
268
|
lg: "px-4 py-3 text-base"
|
|
164
269
|
};
|
|
165
270
|
var variantClasses = {
|
|
166
|
-
line: selected ? "border-b-2 border-primary-500" : "border-b-2 border-transparent hover:border-gray-200",
|
|
167
|
-
pills: selected ? "bg-primary-600 text-white rounded-full shadow-sm" : "bg-transparent rounded-full hover:bg-gray-100",
|
|
271
|
+
line: selected ? cn("border-b-2", indicatorDraws ? "border-transparent" : "border-primary-500") : "border-b-2 border-transparent hover:border-gray-200 dark:hover:border-gray-700",
|
|
272
|
+
pills: selected ? "bg-primary-600 text-white rounded-full shadow-sm" : "bg-transparent rounded-full hover:bg-gray-100 dark:hover:bg-gray-800",
|
|
273
|
+
// iOS-style segmented control: equal-width segments on a tinted track.
|
|
274
|
+
segmented: cn("z-10 flex-1 justify-center rounded-md font-medium", selected ? cn("text-foreground", !indicatorDraws && "bg-surface shadow-sm") : "text-muted hover:text-foreground"),
|
|
168
275
|
unstyled: ""
|
|
169
276
|
};
|
|
170
277
|
var computedClass = cn(base, sizeClasses[size] || sizeClasses.md, variantClasses[variant], tabClassName, className);
|
|
@@ -208,7 +315,7 @@ function Tab(_ref3) {
|
|
|
208
315
|
}
|
|
209
316
|
};
|
|
210
317
|
return jsxs("button", {
|
|
211
|
-
ref:
|
|
318
|
+
ref: setTabRef,
|
|
212
319
|
id: id,
|
|
213
320
|
role: "tab",
|
|
214
321
|
"aria-selected": selected,
|
|
@@ -220,14 +327,14 @@ function Tab(_ref3) {
|
|
|
220
327
|
return !disabled && changeTab(idx);
|
|
221
328
|
},
|
|
222
329
|
onKeyDown: onKeyDown,
|
|
223
|
-
children: [
|
|
330
|
+
children: [leftIcon && jsx("span", {
|
|
224
331
|
className: "shrink-0",
|
|
225
|
-
children:
|
|
332
|
+
children: leftIcon
|
|
226
333
|
}), jsx("span", {
|
|
227
334
|
children: children
|
|
228
|
-
}),
|
|
335
|
+
}), rightIcon && jsx("span", {
|
|
229
336
|
className: "shrink-0",
|
|
230
|
-
children:
|
|
337
|
+
children: rightIcon
|
|
231
338
|
})]
|
|
232
339
|
});
|
|
233
340
|
}
|
|
@@ -237,9 +344,49 @@ function Panels(_ref4) {
|
|
|
237
344
|
_ref4$className = _ref4.className,
|
|
238
345
|
className = _ref4$className === void 0 ? "" : _ref4$className;
|
|
239
346
|
var _useTabsContext3 = useTabsContext("Tabs.Panels"),
|
|
240
|
-
animated = _useTabsContext3.animated
|
|
241
|
-
|
|
242
|
-
|
|
347
|
+
animated = _useTabsContext3.animated,
|
|
348
|
+
swipeable = _useTabsContext3.swipeable,
|
|
349
|
+
activeIndex = _useTabsContext3.activeIndex,
|
|
350
|
+
changeTab = _useTabsContext3.changeTab,
|
|
351
|
+
tabsRef = _useTabsContext3.tabsRef;
|
|
352
|
+
var start = useRef(null);
|
|
353
|
+
// Next enabled tab in `dir`, or -1 at either end (no wrap-around on swipe).
|
|
354
|
+
var neighbour = function neighbour(dir) {
|
|
355
|
+
var tabs = tabsRef.current;
|
|
356
|
+
for (var i = activeIndex + dir; i >= 0 && i < tabs.length; i += dir) {
|
|
357
|
+
if (tabs[i] && !tabs[i].disabled) return i;
|
|
358
|
+
}
|
|
359
|
+
return -1;
|
|
360
|
+
};
|
|
361
|
+
var swipeHandlers = swipeable ? {
|
|
362
|
+
onPointerDown: function onPointerDown(e) {
|
|
363
|
+
// Touch and pen only: a mouse drag selects text instead.
|
|
364
|
+
if (e.pointerType === "mouse" || e.isPrimary === false) return;
|
|
365
|
+
start.current = {
|
|
366
|
+
x: e.clientX,
|
|
367
|
+
y: e.clientY
|
|
368
|
+
};
|
|
369
|
+
},
|
|
370
|
+
onPointerUp: function onPointerUp(e) {
|
|
371
|
+
var from = start.current;
|
|
372
|
+
start.current = null;
|
|
373
|
+
if (!from) return;
|
|
374
|
+
var dx = e.clientX - from.x;
|
|
375
|
+
var dy = e.clientY - from.y;
|
|
376
|
+
if (!Number.isFinite(dx) || !Number.isFinite(dy)) return;
|
|
377
|
+
if (Math.abs(dx) < SWIPE_THRESHOLD || Math.abs(dx) < Math.abs(dy) * SWIPE_DOMINANCE) return;
|
|
378
|
+
// Swipe left -> next tab, swipe right -> previous tab.
|
|
379
|
+
var next = neighbour(dx < 0 ? 1 : -1);
|
|
380
|
+
if (next !== -1) changeTab(next);
|
|
381
|
+
},
|
|
382
|
+
onPointerCancel: function onPointerCancel() {
|
|
383
|
+
start.current = null;
|
|
384
|
+
}
|
|
385
|
+
} : {};
|
|
386
|
+
return jsx("div", _objectSpread2(_objectSpread2({
|
|
387
|
+
// touch-pan-y: the browser keeps vertical scrolling; horizontal moves reach us.
|
|
388
|
+
className: cn("relative w-full", swipeable && "touch-pan-y", className)
|
|
389
|
+
}, swipeHandlers), {}, {
|
|
243
390
|
children: React.Children.map(children, function (child, i) {
|
|
244
391
|
var _child$props$index2;
|
|
245
392
|
// inject index if missing
|
|
@@ -249,7 +396,7 @@ function Panels(_ref4) {
|
|
|
249
396
|
animated: animated
|
|
250
397
|
});
|
|
251
398
|
})
|
|
252
|
-
});
|
|
399
|
+
}));
|
|
253
400
|
}
|
|
254
401
|
function Panel(_ref5) {
|
|
255
402
|
var children = _ref5.children,
|
|
@@ -262,10 +409,10 @@ function Panel(_ref5) {
|
|
|
262
409
|
activeIndex = _useTabsContext4.activeIndex,
|
|
263
410
|
baseId = _useTabsContext4.baseId;
|
|
264
411
|
var isActive = index === activeIndex;
|
|
265
|
-
var
|
|
266
|
-
|
|
267
|
-
wasActive =
|
|
268
|
-
setWasActive =
|
|
412
|
+
var _useState7 = useState(isActive),
|
|
413
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
414
|
+
wasActive = _useState8[0],
|
|
415
|
+
setWasActive = _useState8[1];
|
|
269
416
|
// Remember that the panel has been shown once (adjust-during-render pattern).
|
|
270
417
|
if (isActive && !wasActive) setWasActive(true);
|
|
271
418
|
if (!wasActive && !isActive) return null;
|
|
@@ -6,7 +6,7 @@ import { AlertCircle } from 'lucide-react';
|
|
|
6
6
|
import { cn } from '../../utils/cn.js';
|
|
7
7
|
import { setRefs } from '../../utils/position.js';
|
|
8
8
|
|
|
9
|
-
var _excluded = ["id", "className", "label", "error", "helperText", "required", "disabled", "showCount", "maxLength", "autoResize", "rows", "maxRows", "value", "defaultValue", "onChange"];
|
|
9
|
+
var _excluded = ["id", "className", "label", "error", "helperText", "required", "disabled", "showCount", "maxLength", "autoResize", "rows", "maxRows", "value", "defaultValue", "onChange", "size"];
|
|
10
10
|
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
11
11
|
function fitToContent(el, maxRows) {
|
|
12
12
|
if (!el) return;
|
|
@@ -24,6 +24,12 @@ function fitToContent(el, maxRows) {
|
|
|
24
24
|
}
|
|
25
25
|
el.style.height = "".concat(height, "px");
|
|
26
26
|
}
|
|
27
|
+
// Padding / text per size; `md` is the original look. Rows set the height.
|
|
28
|
+
var SIZE_CLASSES = {
|
|
29
|
+
sm: "px-2.5 py-1.5 text-xs",
|
|
30
|
+
md: "px-3 py-2 text-sm",
|
|
31
|
+
lg: "px-4 py-2.5 text-base"
|
|
32
|
+
};
|
|
27
33
|
var Textarea = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
|
|
28
34
|
var id = _ref.id,
|
|
29
35
|
className = _ref.className,
|
|
@@ -45,6 +51,8 @@ var Textarea = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
|
|
|
45
51
|
value = _ref.value,
|
|
46
52
|
defaultValue = _ref.defaultValue,
|
|
47
53
|
onChange = _ref.onChange,
|
|
54
|
+
_ref$size = _ref.size,
|
|
55
|
+
size = _ref$size === void 0 ? "md" : _ref$size,
|
|
48
56
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
49
57
|
var reactId = useId();
|
|
50
58
|
var textareaId = id || "textarea-".concat(reactId);
|
|
@@ -93,7 +101,7 @@ var Textarea = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
|
|
|
93
101
|
onChange: handleChange,
|
|
94
102
|
"aria-invalid": error ? true : undefined,
|
|
95
103
|
"aria-describedby": describedBy,
|
|
96
|
-
className: cn("block w-full rounded-md border bg-
|
|
104
|
+
className: cn("block w-full rounded-md border bg-surface text-foreground placeholder-gray-400", SIZE_CLASSES[size] || SIZE_CLASSES.md, "transition-colors duration-fast ease-standard motion-reduce:transition-none", "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2", "disabled:cursor-not-allowed disabled:opacity-50", "dark:placeholder-gray-500 dark:focus-visible:ring-offset-gray-900", error ? "border-error-500 focus-visible:ring-error-500 dark:border-error-400" : "border-gray-300 focus-visible:ring-primary-500 dark:border-gray-600", autoResize ? "resize-none" : "resize-y", className)
|
|
97
105
|
})), (error || helperText || showCount && maxLength) && jsxs("div", {
|
|
98
106
|
className: "mt-1 flex items-start justify-between gap-3 text-sm",
|
|
99
107
|
children: [jsxs("div", {
|
|
@@ -1,37 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
-
import React, { forwardRef, useRef,
|
|
4
|
+
import React, { forwardRef, useRef, useState, useCallback, useId } from 'react';
|
|
5
5
|
import { MoreVertical } from 'lucide-react';
|
|
6
6
|
import { cn } from '../../utils/cn.js';
|
|
7
|
+
import { TOUCH_TARGET } from '../../utils/touchTarget.js';
|
|
8
|
+
import ActionMenuSurface from './menu/ActionMenuSurface.js';
|
|
9
|
+
import { renderIcon } from './menu/menuItems.js';
|
|
7
10
|
|
|
8
|
-
var _excluded = ["items", "trigger", "className", "menuClass", "menuItemClass", "closeOnSelect", "ariaLabel", "wrapperClassName"];
|
|
11
|
+
var _excluded = ["items", "trigger", "className", "menuClass", "menuItemClass", "closeOnSelect", "ariaLabel", "wrapperClassName", "presentation", "cancelLabel"];
|
|
9
12
|
/**
|
|
10
|
-
* ThreeDotPopover
|
|
13
|
+
* ThreeDotPopover
|
|
11
14
|
*
|
|
12
|
-
* A
|
|
15
|
+
* A kebab (three-dot) button that opens an action menu.
|
|
13
16
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
17
|
+
* - Desktop (`presentation="popover"`): a portaled floating `role="menu"`
|
|
18
|
+
* that flips/shifts to stay on screen, with roving focus (ArrowUp/Down,
|
|
19
|
+
* Home/End, typeahead). Escape closes and returns focus to the trigger.
|
|
20
|
+
* - Phones (`presentation="sheet"`): an iOS-style action sheet with a
|
|
21
|
+
* separate Cancel button.
|
|
22
|
+
* - `presentation="auto"` (default) picks the sheet on small touch screens.
|
|
19
23
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* - trigger: optional React node to use as trigger (falls back to three-dot button)
|
|
23
|
-
* - className: additional class for trigger wrapper
|
|
24
|
-
* - menuClass: additional class for menu container
|
|
25
|
-
* - menuItemClass: additional class for every menu item
|
|
26
|
-
* - closeOnSelect: boolean (default true)
|
|
27
|
-
*
|
|
28
|
-
* Example:
|
|
29
|
-
* const items = [
|
|
30
|
-
* { key: 'edit', label: 'Edit', icon: Edit2, onClick: () => {} },
|
|
31
|
-
* { key: 'view', label: 'View', icon: Eye, onClick: () => {} },
|
|
32
|
-
* { key: 'delete', label: 'Delete', destructive: true, onClick: () => {} },
|
|
33
|
-
* ];
|
|
34
|
-
* <ThreeDotPopoverSimple items={items} />
|
|
24
|
+
* Items: { key, label, icon?, onClick?, disabled?, destructive?, tone? }.
|
|
25
|
+
* `tone: 'destructive'` and `destructive: true` are equivalent.
|
|
35
26
|
*/
|
|
36
27
|
var ThreeDotPopoverSimple = /*#__PURE__*/forwardRef(function ThreeDotPopoverSimple(_ref, ref) {
|
|
37
28
|
var _ref$items = _ref.items,
|
|
@@ -50,108 +41,111 @@ var ThreeDotPopoverSimple = /*#__PURE__*/forwardRef(function ThreeDotPopoverSimp
|
|
|
50
41
|
ariaLabel = _ref$ariaLabel === void 0 ? "More options" : _ref$ariaLabel,
|
|
51
42
|
_ref$wrapperClassName = _ref.wrapperClassName,
|
|
52
43
|
wrapperClassName = _ref$wrapperClassName === void 0 ? "" : _ref$wrapperClassName,
|
|
44
|
+
_ref$presentation = _ref.presentation,
|
|
45
|
+
presentation = _ref$presentation === void 0 ? "auto" : _ref$presentation,
|
|
46
|
+
_ref$cancelLabel = _ref.cancelLabel,
|
|
47
|
+
cancelLabel = _ref$cancelLabel === void 0 ? "Cancel" : _ref$cancelLabel,
|
|
53
48
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
54
49
|
var triggerRef = useRef(null);
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
var _useState = useState(null),
|
|
51
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
52
|
+
anchorEl = _useState2[0],
|
|
53
|
+
setAnchorEl = _useState2[1];
|
|
54
|
+
// Callback ref for the trigger (default or consumer-supplied): handing a
|
|
55
|
+
// function (not the ref object) to cloneElement keeps ref access out of render.
|
|
57
56
|
var setTriggerNode = useCallback(function (node) {
|
|
58
57
|
triggerRef.current = node;
|
|
58
|
+
setAnchorEl(node);
|
|
59
59
|
}, []);
|
|
60
|
-
var
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (menuRef.current && menuRef.current.contains(e.target)) return;
|
|
70
|
-
setOpen(false);
|
|
71
|
-
}
|
|
72
|
-
function onKey(e) {
|
|
73
|
-
if (!open) return;
|
|
74
|
-
if (e.key === "Escape") setOpen(false);
|
|
75
|
-
}
|
|
76
|
-
document.addEventListener("mousedown", onDocClick);
|
|
77
|
-
document.addEventListener("keydown", onKey);
|
|
78
|
-
return function () {
|
|
79
|
-
document.removeEventListener("mousedown", onDocClick);
|
|
80
|
-
document.removeEventListener("keydown", onKey);
|
|
81
|
-
};
|
|
82
|
-
}, [open]);
|
|
60
|
+
var _useState3 = useState(false),
|
|
61
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
62
|
+
open = _useState4[0],
|
|
63
|
+
setOpen = _useState4[1];
|
|
64
|
+
var _useState5 = useState("first"),
|
|
65
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
66
|
+
initialFocus = _useState6[0],
|
|
67
|
+
setInitialFocus = _useState6[1];
|
|
68
|
+
var menuId = "three-dot-menu-".concat(useId());
|
|
83
69
|
function toggleOpen(e) {
|
|
84
70
|
e && e.stopPropagation();
|
|
71
|
+
setInitialFocus("first");
|
|
85
72
|
setOpen(function (v) {
|
|
86
73
|
return !v;
|
|
87
74
|
});
|
|
88
75
|
}
|
|
89
|
-
function
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
triggerRef.current && triggerRef.current.focus();
|
|
76
|
+
function onTriggerKeyDown(e) {
|
|
77
|
+
if (open || e.key !== "ArrowDown" && e.key !== "ArrowUp") return;
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
setInitialFocus(e.key === "ArrowUp" ? "last" : "first");
|
|
80
|
+
setOpen(true);
|
|
95
81
|
}
|
|
96
|
-
var
|
|
97
|
-
|
|
98
|
-
|
|
82
|
+
var menuItems = (Array.isArray(items) ? items : []).map(function (it, i) {
|
|
83
|
+
var _it$key, _renderIcon;
|
|
84
|
+
return {
|
|
85
|
+
key: (_it$key = it.key) !== null && _it$key !== void 0 ? _it$key : i,
|
|
86
|
+
label: it.label,
|
|
87
|
+
icon: (_renderIcon = renderIcon(it.icon, "w-5 h-5")) !== null && _renderIcon !== void 0 ? _renderIcon : jsx("span", {
|
|
88
|
+
className: "w-5 h-5"
|
|
89
|
+
}),
|
|
90
|
+
disabled: Boolean(it.disabled),
|
|
91
|
+
tone: it.tone,
|
|
92
|
+
destructive: it.destructive,
|
|
93
|
+
onSelect: function onSelect() {
|
|
94
|
+
return it.onClick && it.onClick(it);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
var triggerA11y = {
|
|
99
|
+
"aria-haspopup": "menu",
|
|
99
100
|
"aria-expanded": open,
|
|
100
|
-
|
|
101
|
+
"aria-controls": open ? menuId : undefined
|
|
102
|
+
};
|
|
103
|
+
var DefaultTrigger = jsx("button", _objectSpread2(_objectSpread2({
|
|
104
|
+
type: "button",
|
|
105
|
+
"aria-label": ariaLabel
|
|
106
|
+
}, triggerA11y), {}, {
|
|
107
|
+
ref: setTriggerNode,
|
|
101
108
|
onClick: toggleOpen,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
onKeyDown: onTriggerKeyDown,
|
|
110
|
+
className: cn("inline-flex items-center justify-center rounded-md text-muted hover:text-foreground", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2", TOUCH_TARGET, className),
|
|
111
|
+
children: jsx(MoreVertical, {
|
|
112
|
+
"aria-hidden": "true"
|
|
113
|
+
})
|
|
114
|
+
}));
|
|
105
115
|
var triggerNode = trigger ?
|
|
106
116
|
/*#__PURE__*/
|
|
107
117
|
// eslint-disable-next-line react-hooks/refs -- setTriggerNode is a callback ref, run by React at commit
|
|
108
|
-
React.cloneElement(trigger, {
|
|
118
|
+
React.cloneElement(trigger, _objectSpread2({
|
|
109
119
|
ref: setTriggerNode,
|
|
110
120
|
onClick: function onClick(e) {
|
|
111
121
|
trigger.props && trigger.props.onClick && trigger.props.onClick(e);
|
|
112
122
|
toggleOpen(e);
|
|
113
123
|
},
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
onKeyDown: function onKeyDown(e) {
|
|
125
|
+
trigger.props && trigger.props.onKeyDown && trigger.props.onKeyDown(e);
|
|
126
|
+
if (!e.defaultPrevented) onTriggerKeyDown(e);
|
|
127
|
+
}
|
|
128
|
+
}, triggerA11y)) : DefaultTrigger;
|
|
117
129
|
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
118
130
|
ref: ref,
|
|
119
131
|
className: cn("inline-block relative", wrapperClassName)
|
|
120
132
|
}, rest), {}, {
|
|
121
|
-
children: [triggerNode, jsx(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
display: open ? "block" : "none"
|
|
133
|
+
children: [triggerNode, jsx(ActionMenuSurface, {
|
|
134
|
+
open: open,
|
|
135
|
+
onClose: function onClose() {
|
|
136
|
+
return setOpen(false);
|
|
126
137
|
},
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
onClick: function onClick() {
|
|
139
|
-
return handleItemClick(it);
|
|
140
|
-
},
|
|
141
|
-
disabled: it.disabled,
|
|
142
|
-
className: "w-full text-left px-4 py-3 flex items-center gap-3 text-sm leading-5 ".concat(it.destructive ? "text-error-600" : "text-primary-900", " ").concat(it.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-50", " ").concat(menuItemClass),
|
|
143
|
-
children: [Icon ? jsx(Icon, {
|
|
144
|
-
className: "w-5 h-5"
|
|
145
|
-
}) : jsx("span", {
|
|
146
|
-
className: "w-5 h-5"
|
|
147
|
-
}), jsx("span", {
|
|
148
|
-
className: "flex-1",
|
|
149
|
-
children: it.label
|
|
150
|
-
})]
|
|
151
|
-
})
|
|
152
|
-
}, (_it$key = it.key) !== null && _it$key !== void 0 ? _it$key : i);
|
|
153
|
-
})
|
|
154
|
-
})
|
|
138
|
+
anchorEl: anchorEl,
|
|
139
|
+
items: menuItems,
|
|
140
|
+
presentation: presentation,
|
|
141
|
+
placement: "bottom-start",
|
|
142
|
+
initialFocus: initialFocus,
|
|
143
|
+
closeOnSelect: closeOnSelect,
|
|
144
|
+
id: menuId,
|
|
145
|
+
label: typeof ariaLabel === "string" ? ariaLabel : undefined,
|
|
146
|
+
cancelLabel: cancelLabel,
|
|
147
|
+
menuClassName: menuClass,
|
|
148
|
+
itemClassName: menuItemClass
|
|
155
149
|
})]
|
|
156
150
|
}));
|
|
157
151
|
});
|