@dreamtree-org/twreact-ui 1.3.0 → 1.3.2
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/DESIGN.md +2 -2
- package/README.md +258 -10
- package/ai-skills/dreamtree-ui.md +111 -15
- package/charts/package.json +5 -0
- package/dist/_shared/cn-DPPQUJu1.js +138 -0
- package/dist/ai-schema.json +1252 -179
- package/dist/charts/index.d.ts +9 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +769 -0
- package/dist/components/charts/AreaChart.d.ts +4 -0
- package/dist/components/charts/AreaChart.d.ts.map +1 -0
- package/dist/components/charts/BarChart.d.ts +4 -0
- package/dist/components/charts/BarChart.d.ts.map +1 -0
- package/dist/components/charts/CartesianChart.d.ts +5 -0
- package/dist/components/charts/CartesianChart.d.ts.map +1 -0
- package/dist/components/charts/ChartFrame.d.ts +18 -0
- package/dist/components/charts/ChartFrame.d.ts.map +1 -0
- package/dist/components/charts/DonutChart.d.ts +4 -0
- package/dist/components/charts/DonutChart.d.ts.map +1 -0
- package/dist/components/charts/LineChart.d.ts +4 -0
- package/dist/components/charts/LineChart.d.ts.map +1 -0
- package/dist/components/charts/Sparkline.d.ts +5 -0
- package/dist/components/charts/Sparkline.d.ts.map +1 -0
- package/dist/components/charts/chartTheme.d.ts +26 -0
- package/dist/components/charts/chartTheme.d.ts.map +1 -0
- package/dist/components/core/Accordion.d.ts.map +1 -1
- 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/LocationPicker.d.ts.map +1 -1
- package/dist/components/core/Popover.d.ts +4 -0
- package/dist/components/core/Popover.d.ts.map +1 -0
- package/dist/components/core/PriceRangePicker.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/Select.d.ts.map +1 -1
- package/dist/components/core/Skeleton.d.ts.map +1 -1
- package/dist/components/core/Slider.d.ts +4 -0
- package/dist/components/core/Slider.d.ts.map +1 -0
- package/dist/components/core/SpeechToText.d.ts.map +1 -1
- package/dist/components/core/Switch.d.ts.map +1 -1
- package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
- package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
- package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
- package/dist/components/core/Table/MobileCard.d.ts +2 -2
- package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
- package/dist/components/core/Table/Table.d.ts.map +1 -1
- package/dist/components/core/Table/TableRow.d.ts +4 -2
- package/dist/components/core/Table/TableRow.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/Textarea.d.ts +4 -0
- package/dist/components/core/Textarea.d.ts.map +1 -0
- package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
- package/dist/components/core/Tooltip.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Drawer.d.ts +4 -0
- package/dist/components/feedback/Drawer.d.ts.map +1 -0
- package/dist/components/feedback/Toast.d.ts +14 -5
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/feedback/Tour.d.ts +4 -0
- package/dist/components/feedback/Tour.d.ts.map +1 -0
- package/dist/components/feedback/TourSpotlight.d.ts +9 -0
- package/dist/components/feedback/TourSpotlight.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 +8 -2
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/rich-text/RichTextEditor.d.ts +4 -0
- package/dist/components/rich-text/RichTextEditor.d.ts.map +1 -0
- package/dist/components/rich-text/RichTextToolbar.d.ts +219 -0
- package/dist/components/rich-text/RichTextToolbar.d.ts.map +1 -0
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Sortable.d.ts +4 -0
- package/dist/components/utility/Sortable.d.ts.map +1 -0
- package/dist/esm/_vendor/object-assign/index.js +99 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
- package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
- package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
- package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
- package/dist/esm/_vendor/prop-types/index.js +30 -0
- package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
- package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
- package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
- package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
- package/dist/esm/_virtual/index.js +3 -0
- package/dist/esm/_virtual/index2.js +3 -0
- package/dist/esm/_virtual/react-is.development.js +3 -0
- package/dist/esm/_virtual/react-is.production.min.js +3 -0
- package/dist/esm/charts/index.js +5 -0
- package/dist/esm/components/blocks/AppShell.js +205 -0
- package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
- package/dist/esm/components/blocks/EmptyState.js +44 -0
- package/dist/esm/components/blocks/ErrorState.js +53 -0
- package/dist/esm/components/blocks/LoadingState.js +134 -0
- package/dist/esm/components/blocks/PageHeader.js +51 -0
- package/dist/esm/components/blocks/StatCard.js +79 -0
- package/dist/esm/components/blocks/StatusPill.js +55 -0
- package/dist/esm/components/charts/AreaChart.js +16 -0
- package/dist/esm/components/charts/BarChart.js +16 -0
- package/dist/esm/components/charts/CartesianChart.js +250 -0
- package/dist/esm/components/charts/ChartFrame.js +170 -0
- package/dist/esm/components/charts/DonutChart.js +119 -0
- package/dist/esm/components/charts/LineChart.js +16 -0
- package/dist/esm/components/charts/Sparkline.js +110 -0
- package/dist/esm/components/charts/chartTheme.js +109 -0
- package/dist/esm/components/core/Accordion.js +260 -0
- package/dist/esm/components/core/Button.js +59 -0
- package/dist/esm/components/core/Checkbox.js +188 -0
- package/dist/esm/components/core/ColorPicker.js +348 -0
- package/dist/esm/components/core/DatePicker.js +436 -0
- package/dist/esm/components/core/DateRangePicker.js +494 -0
- package/dist/esm/components/core/Form.js +522 -0
- package/dist/esm/components/core/Input.js +179 -0
- package/dist/esm/components/core/Loader.js +141 -0
- package/dist/esm/components/core/LocationPicker.js +161 -0
- package/dist/esm/components/core/Popover.js +171 -0
- package/dist/esm/components/core/PriceRangePicker.js +376 -0
- package/dist/esm/components/core/ProgressBar.js +152 -0
- package/dist/esm/components/core/Radio.js +156 -0
- package/dist/esm/components/core/Rate.js +197 -0
- package/dist/esm/components/core/RoundedTag.js +118 -0
- package/dist/esm/components/core/Select.js +857 -0
- package/dist/esm/components/core/Skeleton.js +100 -0
- package/dist/esm/components/core/Slider.js +134 -0
- package/dist/esm/components/core/SpeechToText.js +226 -0
- package/dist/esm/components/core/Switch.js +207 -0
- package/dist/esm/components/core/Table/ActionMenu.js +251 -0
- package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
- package/dist/esm/components/core/Table/FieldInput.js +157 -0
- package/dist/esm/components/core/Table/MobileCard.js +187 -0
- package/dist/esm/components/core/Table/MobileFilters.js +72 -0
- package/dist/esm/components/core/Table/Pagination.js +157 -0
- package/dist/esm/components/core/Table/Table.js +1533 -0
- package/dist/esm/components/core/Table/TableRow.js +254 -0
- package/dist/esm/components/core/Table/constants.js +35 -0
- package/dist/esm/components/core/Table/helpers.js +124 -0
- package/dist/esm/components/core/Table/useClickOutside.js +26 -0
- package/dist/esm/components/core/Tabs.js +289 -0
- package/dist/esm/components/core/TextToSpeech.js +52 -0
- package/dist/esm/components/core/Textarea.js +125 -0
- package/dist/esm/components/core/ThreeDotPopover.js +160 -0
- package/dist/esm/components/core/Tooltip.js +372 -0
- package/dist/esm/components/feedback/Alert.js +96 -0
- package/dist/esm/components/feedback/Dialog.js +200 -0
- package/dist/esm/components/feedback/Drawer.js +171 -0
- package/dist/esm/components/feedback/Toast.js +362 -0
- package/dist/esm/components/feedback/Tour.js +214 -0
- package/dist/esm/components/feedback/TourSpotlight.js +71 -0
- package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
- package/dist/esm/components/navigation/Dropdown.js +53 -0
- package/dist/esm/components/navigation/FootNav.js +51 -0
- package/dist/esm/components/navigation/Navbar.js +437 -0
- package/dist/esm/components/navigation/Sidebar.js +567 -0
- package/dist/esm/components/rich-text/RichTextEditor.js +244 -0
- package/dist/esm/components/rich-text/RichTextToolbar.js +397 -0
- package/dist/esm/components/utility/Avatar.js +89 -0
- package/dist/esm/components/utility/Badge.js +47 -0
- package/dist/esm/components/utility/Card.js +85 -0
- package/dist/esm/components/utility/Carousel.js +97 -0
- package/dist/esm/components/utility/Condition.js +9 -0
- package/dist/esm/components/utility/FileUpload.js +177 -0
- package/dist/esm/components/utility/Pagination.js +111 -0
- package/dist/esm/components/utility/Sortable.js +190 -0
- package/dist/esm/components/utility/Stepper.js +101 -0
- package/dist/esm/hooks/useApi.js +169 -0
- package/dist/esm/hooks/useControllableState.js +32 -0
- package/dist/esm/hooks/useFocusTrap.js +85 -0
- package/dist/esm/hooks/useLatestRef.js +20 -0
- package/dist/esm/hooks/useMixins.js +100 -0
- package/dist/esm/hooks/useScrollLock.js +26 -0
- package/dist/esm/hooks/useSliderValues.js +135 -0
- package/dist/esm/hooks/useSortable.js +188 -0
- package/dist/esm/hooks/useTheme.js +53 -0
- package/dist/esm/hooks/useTourTarget.js +92 -0
- package/dist/esm/index.js +65 -0
- package/dist/esm/rich-text/index.js +1 -0
- package/dist/esm/store/index.js +26 -0
- package/dist/esm/store/store.js +107 -0
- package/dist/esm/store/storeSlice.js +45 -0
- package/dist/esm/utils/cn.js +11 -0
- package/dist/esm/utils/emitter.js +169 -0
- package/dist/esm/utils/helpers.js +161 -0
- package/dist/esm/utils/position.js +134 -0
- package/dist/hooks/useApi.d.ts +2 -1
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/dist/hooks/useControllableState.d.ts +11 -0
- package/dist/hooks/useControllableState.d.ts.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts +15 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/hooks/useLatestRef.d.ts +8 -0
- package/dist/hooks/useLatestRef.d.ts.map +1 -0
- package/dist/hooks/useMixins.d.ts.map +1 -1
- package/dist/hooks/useScrollLock.d.ts +2 -0
- package/dist/hooks/useScrollLock.d.ts.map +1 -0
- package/dist/hooks/useSliderValues.d.ts +43 -0
- package/dist/hooks/useSliderValues.d.ts.map +1 -0
- package/dist/hooks/useSortable.d.ts +32 -0
- package/dist/hooks/useSortable.d.ts.map +1 -0
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/hooks/useTourTarget.d.ts +15 -0
- package/dist/hooks/useTourTarget.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +4817 -2216
- package/dist/index.js +4822 -2214
- package/dist/rich-text/index.d.ts +5 -0
- package/dist/rich-text/index.d.ts.map +1 -0
- package/dist/rich-text/index.js +654 -0
- package/dist/tokens/brands/studio.css +14 -0
- package/dist/tokens/brands/studio.json +20 -0
- package/dist/types/charts.d.ts +97 -0
- package/dist/types/charts.d.ts.map +1 -0
- package/dist/types/index.d.ts +193 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/rich-text.d.ts +50 -0
- package/dist/types/rich-text.d.ts.map +1 -0
- package/dist/utils/position.d.ts +30 -0
- package/dist/utils/position.d.ts.map +1 -0
- package/doc/README.md +20 -1
- package/mcp/catalog.snapshot.json +2505 -800
- package/mcp/server-core.mjs +30 -1
- package/package.json +51 -3
- package/rich-text/package.json +5 -0
- package/tokens/brands/studio.json +20 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import { useRef, useState, useLayoutEffect, useEffect } from 'react';
|
|
5
|
+
import { createPortal } from 'react-dom';
|
|
6
|
+
import { cn } from '../../../utils/cn.js';
|
|
7
|
+
import { useLatestRef } from '../../../hooks/useLatestRef.js';
|
|
8
|
+
|
|
9
|
+
var DEFAULT_MENU_BG = "bg-white border border-gray-100 shadow-xl";
|
|
10
|
+
var DEFAULT_MENU_ITEM_HOVER = "opacity-75 hover:opacity-100 hover:bg-gray-100/80 active:bg-gray-200/80";
|
|
11
|
+
function ActionMenu(_ref) {
|
|
12
|
+
var _theme$menuBg, _theme$menuItemHover;
|
|
13
|
+
var _ref$actions = _ref.actions,
|
|
14
|
+
actions = _ref$actions === void 0 ? [] : _ref$actions,
|
|
15
|
+
row = _ref.row,
|
|
16
|
+
onAction = _ref.onAction,
|
|
17
|
+
onClose = _ref.onClose,
|
|
18
|
+
externalMenuRef = _ref.menuRef,
|
|
19
|
+
anchorEl = _ref.anchorEl,
|
|
20
|
+
theme = _ref.theme;
|
|
21
|
+
var internalRef = useRef(null);
|
|
22
|
+
var menuRef = externalMenuRef || internalRef;
|
|
23
|
+
var _useState = useState(-1),
|
|
24
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
25
|
+
focusedIndex = _useState2[0],
|
|
26
|
+
setFocusedIndex = _useState2[1];
|
|
27
|
+
var menuBg = (_theme$menuBg = theme === null || theme === void 0 ? void 0 : theme.menuBg) !== null && _theme$menuBg !== void 0 ? _theme$menuBg : DEFAULT_MENU_BG;
|
|
28
|
+
var menuItemHover = (_theme$menuItemHover = theme === null || theme === void 0 ? void 0 : theme.menuItemHover) !== null && _theme$menuItemHover !== void 0 ? _theme$menuItemHover : DEFAULT_MENU_ITEM_HOVER;
|
|
29
|
+
var _useState3 = useState({
|
|
30
|
+
left: 0,
|
|
31
|
+
top: 0,
|
|
32
|
+
transformOrigin: "top right",
|
|
33
|
+
maxHeight: 300,
|
|
34
|
+
width: 190,
|
|
35
|
+
opacity: 0
|
|
36
|
+
}),
|
|
37
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
38
|
+
style = _useState4[0],
|
|
39
|
+
setStyle = _useState4[1];
|
|
40
|
+
var menuWidth = 190;
|
|
41
|
+
var maxMenuHeight = 320;
|
|
42
|
+
var minMenuHeight = 80;
|
|
43
|
+
var margin = 8;
|
|
44
|
+
var computePosition = function computePosition() {
|
|
45
|
+
if (!anchorEl || typeof window === "undefined") return;
|
|
46
|
+
var rect = anchorEl.getBoundingClientRect();
|
|
47
|
+
var scrollY = window.scrollY || window.pageYOffset || 0;
|
|
48
|
+
var scrollX = window.scrollX || window.pageXOffset || 0;
|
|
49
|
+
var spaceBelow = window.innerHeight - rect.bottom;
|
|
50
|
+
var spaceAbove = rect.top;
|
|
51
|
+
// Estimate or measure menu height
|
|
52
|
+
var menuEl = menuRef === null || menuRef === void 0 ? void 0 : menuRef.current;
|
|
53
|
+
var actionCount = Array.isArray(actions) && actions.length > 0 ? actions.length : 1;
|
|
54
|
+
var estimatedHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, actionCount * 42 + 16));
|
|
55
|
+
var actualContentHeight = estimatedHeight;
|
|
56
|
+
if (menuEl) {
|
|
57
|
+
actualContentHeight = Math.min(maxMenuHeight, menuEl.scrollHeight || menuEl.offsetHeight || estimatedHeight);
|
|
58
|
+
}
|
|
59
|
+
// Determine placement (top vs bottom) based on available viewport space
|
|
60
|
+
var placement = "bottom";
|
|
61
|
+
if (spaceBelow < actualContentHeight + margin && spaceAbove > spaceBelow) {
|
|
62
|
+
placement = "top";
|
|
63
|
+
}
|
|
64
|
+
var availableSpace = placement === "top" ? spaceAbove - margin : spaceBelow - margin;
|
|
65
|
+
var allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, availableSpace));
|
|
66
|
+
var finalMenuHeight = Math.min(actualContentHeight, allowedMaxHeight);
|
|
67
|
+
// Compute top coordinate based on placement
|
|
68
|
+
var top;
|
|
69
|
+
if (placement === "top") {
|
|
70
|
+
top = rect.top + scrollY - finalMenuHeight - margin;
|
|
71
|
+
} else {
|
|
72
|
+
top = rect.bottom + scrollY + margin;
|
|
73
|
+
}
|
|
74
|
+
// Clamp top within viewport scroll bounds
|
|
75
|
+
var minTop = margin + scrollY;
|
|
76
|
+
var maxTop = window.innerHeight + scrollY - finalMenuHeight - margin;
|
|
77
|
+
if (top < minTop) top = minTop;
|
|
78
|
+
if (top > maxTop) top = maxTop;
|
|
79
|
+
// Compute left coordinate (align right edge to anchor right, fallback to left align if overflow)
|
|
80
|
+
var left = rect.right + scrollX - menuWidth;
|
|
81
|
+
if (left < margin) {
|
|
82
|
+
left = rect.left + scrollX;
|
|
83
|
+
}
|
|
84
|
+
if (left + menuWidth > window.innerWidth - margin) {
|
|
85
|
+
left = Math.max(margin, window.innerWidth - menuWidth - margin);
|
|
86
|
+
}
|
|
87
|
+
var transformOrigin = placement === "bottom" ? "top right" : "bottom right";
|
|
88
|
+
setStyle({
|
|
89
|
+
left: left,
|
|
90
|
+
top: top,
|
|
91
|
+
transformOrigin: transformOrigin,
|
|
92
|
+
maxHeight: allowedMaxHeight,
|
|
93
|
+
width: menuWidth,
|
|
94
|
+
opacity: 1
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
// computePosition is rebuilt every render; read it through a ref so the
|
|
98
|
+
// listeners below are only re-bound when the anchor/actions change.
|
|
99
|
+
var computePositionRef = useLatestRef(computePosition);
|
|
100
|
+
useLayoutEffect(function () {
|
|
101
|
+
// Measuring the anchor and positioning the menu before paint is the
|
|
102
|
+
// intended use of a layout effect.
|
|
103
|
+
computePositionRef.current();
|
|
104
|
+
var rafId = window.requestAnimationFrame(function () {
|
|
105
|
+
return computePositionRef.current();
|
|
106
|
+
});
|
|
107
|
+
var handleResize = function handleResize() {
|
|
108
|
+
window.requestAnimationFrame(function () {
|
|
109
|
+
return computePositionRef.current();
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
var handleScroll = function handleScroll(e) {
|
|
113
|
+
// If scroll event originates inside the menu container itself,
|
|
114
|
+
// do NOT close the menu! Let the user scroll through options.
|
|
115
|
+
if (menuRef !== null && menuRef !== void 0 && menuRef.current && e.target && e.target instanceof Node && (menuRef.current === e.target || menuRef.current.contains(e.target))) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
onClose === null || onClose === void 0 || onClose();
|
|
119
|
+
};
|
|
120
|
+
window.addEventListener("resize", handleResize);
|
|
121
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
122
|
+
return function () {
|
|
123
|
+
window.cancelAnimationFrame(rafId);
|
|
124
|
+
window.removeEventListener("resize", handleResize);
|
|
125
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
126
|
+
};
|
|
127
|
+
}, [anchorEl, actions, menuRef, onClose, computePositionRef]);
|
|
128
|
+
// Focus management & Keyboard navigation
|
|
129
|
+
useEffect(function () {
|
|
130
|
+
var handleKeyDown = function handleKeyDown(e) {
|
|
131
|
+
if (!Array.isArray(actions) || actions.length === 0) return;
|
|
132
|
+
if (e.key === "Escape") {
|
|
133
|
+
var _anchorEl$focus;
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
onClose === null || onClose === void 0 || onClose();
|
|
136
|
+
anchorEl === null || anchorEl === void 0 || (_anchorEl$focus = anchorEl.focus) === null || _anchorEl$focus === void 0 || _anchorEl$focus.call(anchorEl);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (e.key === "ArrowDown") {
|
|
140
|
+
e.preventDefault();
|
|
141
|
+
setFocusedIndex(function (prev) {
|
|
142
|
+
var next = prev + 1;
|
|
143
|
+
while (next < actions.length && (_actions$next = actions[next]) !== null && _actions$next !== void 0 && _actions$next.disabled) {
|
|
144
|
+
var _actions$next;
|
|
145
|
+
next++;
|
|
146
|
+
}
|
|
147
|
+
return next < actions.length ? next : prev;
|
|
148
|
+
});
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (e.key === "ArrowUp") {
|
|
152
|
+
e.preventDefault();
|
|
153
|
+
setFocusedIndex(function (prev) {
|
|
154
|
+
var next = prev - 1;
|
|
155
|
+
while (next >= 0 && (_actions$next2 = actions[next]) !== null && _actions$next2 !== void 0 && _actions$next2.disabled) {
|
|
156
|
+
var _actions$next2;
|
|
157
|
+
next--;
|
|
158
|
+
}
|
|
159
|
+
return next >= 0 ? next : prev;
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (e.key === "Home") {
|
|
164
|
+
e.preventDefault();
|
|
165
|
+
var first = actions.findIndex(function (a) {
|
|
166
|
+
return !a.disabled;
|
|
167
|
+
});
|
|
168
|
+
if (first !== -1) setFocusedIndex(first);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (e.key === "End") {
|
|
172
|
+
e.preventDefault();
|
|
173
|
+
var last = _toConsumableArray(actions).reverse().findIndex(function (a) {
|
|
174
|
+
return !a.disabled;
|
|
175
|
+
});
|
|
176
|
+
if (last !== -1) setFocusedIndex(actions.length - 1 - last);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
181
|
+
return function () {
|
|
182
|
+
return window.removeEventListener("keydown", handleKeyDown);
|
|
183
|
+
};
|
|
184
|
+
}, [actions, onClose, anchorEl]);
|
|
185
|
+
// Automatically focus focused item
|
|
186
|
+
useEffect(function () {
|
|
187
|
+
if (focusedIndex >= 0 && menuRef !== null && menuRef !== void 0 && menuRef.current) {
|
|
188
|
+
var buttons = menuRef.current.querySelectorAll("button:not([disabled])");
|
|
189
|
+
if (buttons[focusedIndex]) {
|
|
190
|
+
buttons[focusedIndex].focus();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}, [focusedIndex, menuRef]);
|
|
194
|
+
return /*#__PURE__*/createPortal(jsx("div", {
|
|
195
|
+
ref: menuRef,
|
|
196
|
+
role: "menu",
|
|
197
|
+
"aria-orientation": "vertical",
|
|
198
|
+
style: {
|
|
199
|
+
position: "absolute",
|
|
200
|
+
top: style.top,
|
|
201
|
+
left: style.left,
|
|
202
|
+
width: style.width,
|
|
203
|
+
maxHeight: style.maxHeight,
|
|
204
|
+
transformOrigin: style.transformOrigin,
|
|
205
|
+
opacity: style.opacity
|
|
206
|
+
},
|
|
207
|
+
className: cn("absolute z-50 rounded-xl shadow-xl ring-1 ring-black/10 overflow-y-auto transition-opacity duration-150 ease-out focus:outline-none", menuBg),
|
|
208
|
+
onClick: function onClick(e) {
|
|
209
|
+
return e.stopPropagation();
|
|
210
|
+
},
|
|
211
|
+
children: jsx("div", {
|
|
212
|
+
className: "p-1.5 space-y-0.5",
|
|
213
|
+
children: !Array.isArray(actions) || actions.length === 0 ? jsx("div", {
|
|
214
|
+
className: "px-3 py-2 text-sm text-gray-400 italic",
|
|
215
|
+
children: "No actions"
|
|
216
|
+
}) : actions.map(function (action, idx) {
|
|
217
|
+
var _action$name;
|
|
218
|
+
var isDisabled = !!action.disabled;
|
|
219
|
+
var isFocused = focusedIndex === idx;
|
|
220
|
+
return jsx("div", {
|
|
221
|
+
children: jsx("button", {
|
|
222
|
+
type: "button",
|
|
223
|
+
disabled: isDisabled,
|
|
224
|
+
"aria-disabled": isDisabled || undefined,
|
|
225
|
+
className: cn("w-full text-left px-3 py-2 text-sm flex items-center gap-2.5 rounded-lg transition-colors font-medium", isDisabled ? "opacity-50 cursor-not-allowed text-gray-400" : ["text-gray-700 hover:text-gray-900", menuItemHover, isFocused ? "bg-gray-100 text-gray-900 ring-1 ring-gray-300" : ""]),
|
|
226
|
+
onMouseEnter: function onMouseEnter() {
|
|
227
|
+
return !isDisabled && setFocusedIndex(idx);
|
|
228
|
+
},
|
|
229
|
+
onClick: function onClick(e) {
|
|
230
|
+
e.stopPropagation();
|
|
231
|
+
if (isDisabled) return;
|
|
232
|
+
onAction === null || onAction === void 0 || onAction(action, row);
|
|
233
|
+
onClose === null || onClose === void 0 || onClose();
|
|
234
|
+
},
|
|
235
|
+
children: action.render ? action.render(row) : jsxs(Fragment, {
|
|
236
|
+
children: [action.icon && jsx("span", {
|
|
237
|
+
className: "inline-flex text-gray-500 flex-shrink-0",
|
|
238
|
+
children: action.icon
|
|
239
|
+
}), jsx("span", {
|
|
240
|
+
className: "truncate",
|
|
241
|
+
children: action.label
|
|
242
|
+
})]
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
}, (_action$name = action.name) !== null && _action$name !== void 0 ? _action$name : "action-".concat(idx));
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
}), document.body);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export { ActionMenu as default };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { defineProperty as _defineProperty } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
var DEFAULT_ROW_HOVER = "bg-gray-50";
|
|
8
|
+
/**
|
|
9
|
+
* Column visibility toggle menu
|
|
10
|
+
*/
|
|
11
|
+
function ColumnMenu(_ref) {
|
|
12
|
+
var _theme$rowHover;
|
|
13
|
+
var id = _ref.id,
|
|
14
|
+
columns = _ref.columns,
|
|
15
|
+
onToggle = _ref.onToggle,
|
|
16
|
+
menuRef = _ref.menuRef,
|
|
17
|
+
theme = _ref.theme;
|
|
18
|
+
var rowHover = (_theme$rowHover = theme === null || theme === void 0 ? void 0 : theme.rowHover) !== null && _theme$rowHover !== void 0 ? _theme$rowHover : DEFAULT_ROW_HOVER;
|
|
19
|
+
return jsxs("div", {
|
|
20
|
+
id: id,
|
|
21
|
+
role: "group",
|
|
22
|
+
"aria-label": "Show / hide columns",
|
|
23
|
+
ref: menuRef,
|
|
24
|
+
className: "absolute right-4 mt-2 w-56 z-50 rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 p-3 lg:block sm:block hidden",
|
|
25
|
+
onClick: function onClick(e) {
|
|
26
|
+
return e.stopPropagation();
|
|
27
|
+
},
|
|
28
|
+
children: [jsx("p", {
|
|
29
|
+
className: "text-sm font-medium text-center mb-2",
|
|
30
|
+
children: "Show / hide columns"
|
|
31
|
+
}), jsx("div", {
|
|
32
|
+
className: "max-h-56 overflow-auto",
|
|
33
|
+
children: columns.map(function (col) {
|
|
34
|
+
return jsxs("label", {
|
|
35
|
+
className: cn(_defineProperty({
|
|
36
|
+
"flex cursor-pointer items-center gap-2 px-2 py-1.5 rounded": true
|
|
37
|
+
}, "hover:" + rowHover, true)),
|
|
38
|
+
children: [jsx("input", {
|
|
39
|
+
type: "checkbox",
|
|
40
|
+
checked: col.isVisible !== false,
|
|
41
|
+
onChange: function onChange() {
|
|
42
|
+
return onToggle(col.key);
|
|
43
|
+
},
|
|
44
|
+
className: "rounded"
|
|
45
|
+
}), jsx("span", {
|
|
46
|
+
className: "text-sm font-normal",
|
|
47
|
+
children: col.label
|
|
48
|
+
})]
|
|
49
|
+
}, col.key);
|
|
50
|
+
})
|
|
51
|
+
})]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { ColumnMenu as default };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { typeof as _typeof } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Unified FieldInput component for cell editing and new rows.
|
|
9
|
+
* Reuses existing onRender pattern and supports text, number, select, date, boolean, textarea.
|
|
10
|
+
*/
|
|
11
|
+
function FieldInput(_ref) {
|
|
12
|
+
var column = _ref.column,
|
|
13
|
+
value = _ref.value,
|
|
14
|
+
_onChange = _ref.onChange,
|
|
15
|
+
onKeyDown = _ref.onKeyDown,
|
|
16
|
+
_ref$isEditing = _ref.isEditing,
|
|
17
|
+
isEditing = _ref$isEditing === void 0 ? true : _ref$isEditing,
|
|
18
|
+
_ref$row = _ref.row,
|
|
19
|
+
row = _ref$row === void 0 ? {} : _ref$row,
|
|
20
|
+
_ref$rowIndex = _ref.rowIndex,
|
|
21
|
+
rowIndex = _ref$rowIndex === void 0 ? 0 : _ref$rowIndex,
|
|
22
|
+
_ref$className = _ref.className,
|
|
23
|
+
className = _ref$className === void 0 ? "" : _ref$className,
|
|
24
|
+
_ref$autoFocus = _ref.autoFocus,
|
|
25
|
+
autoFocus = _ref$autoFocus === void 0 ? false : _ref$autoFocus;
|
|
26
|
+
var currentValue = value !== null && value !== void 0 ? value : "";
|
|
27
|
+
var inputType = column.type || column.inputType || "text";
|
|
28
|
+
var stopProp = function stopProp(e) {
|
|
29
|
+
e.stopPropagation();
|
|
30
|
+
};
|
|
31
|
+
// Check if custom onRender renderer is provided on the column definition
|
|
32
|
+
if (typeof column.onRender === "function") {
|
|
33
|
+
return jsx("div", {
|
|
34
|
+
onClick: stopProp,
|
|
35
|
+
onMouseDown: stopProp,
|
|
36
|
+
children: column.onRender(row, rowIndex, column, {
|
|
37
|
+
value: currentValue,
|
|
38
|
+
onChange: function onChange(newVal) {
|
|
39
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(newVal);
|
|
40
|
+
},
|
|
41
|
+
onKeyDown: onKeyDown,
|
|
42
|
+
isEditing: isEditing
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Textarea / Longtext
|
|
47
|
+
if (inputType === "textarea" || inputType === "longtext") {
|
|
48
|
+
return jsx("textarea", {
|
|
49
|
+
autoFocus: autoFocus,
|
|
50
|
+
rows: 2,
|
|
51
|
+
value: currentValue,
|
|
52
|
+
onChange: function onChange(e) {
|
|
53
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(e.target.value);
|
|
54
|
+
},
|
|
55
|
+
onKeyDown: onKeyDown,
|
|
56
|
+
onClick: stopProp,
|
|
57
|
+
onMouseDown: stopProp,
|
|
58
|
+
placeholder: "Enter ".concat(column.label || column.key, "..."),
|
|
59
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none transition-all focus:ring-2 focus:ring-primary-500 bg-white resize-y min-h-[2.5rem]", className)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Select / Dropdown
|
|
63
|
+
if (inputType === "select" || inputType === "dropdown") {
|
|
64
|
+
var options = Array.isArray(column.options) ? column.options.map(function (opt) {
|
|
65
|
+
return _typeof(opt) === "object" ? opt : {
|
|
66
|
+
label: opt,
|
|
67
|
+
value: opt
|
|
68
|
+
};
|
|
69
|
+
}) : [];
|
|
70
|
+
return jsxs("select", {
|
|
71
|
+
autoFocus: autoFocus,
|
|
72
|
+
value: currentValue,
|
|
73
|
+
onChange: function onChange(e) {
|
|
74
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(e.target.value);
|
|
75
|
+
},
|
|
76
|
+
onKeyDown: onKeyDown,
|
|
77
|
+
onClick: stopProp,
|
|
78
|
+
onMouseDown: stopProp,
|
|
79
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-white", className),
|
|
80
|
+
children: [jsxs("option", {
|
|
81
|
+
value: "",
|
|
82
|
+
children: ["Select ", column.label || column.key]
|
|
83
|
+
}), options.map(function (opt) {
|
|
84
|
+
return jsx("option", {
|
|
85
|
+
value: opt.value,
|
|
86
|
+
children: opt.label
|
|
87
|
+
}, String(opt.value));
|
|
88
|
+
})]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Checkbox / Boolean
|
|
92
|
+
if (inputType === "checkbox" || inputType === "boolean") {
|
|
93
|
+
var checked = Boolean(currentValue);
|
|
94
|
+
return jsx("div", {
|
|
95
|
+
className: cn("flex items-center justify-center py-1", className),
|
|
96
|
+
onClick: stopProp,
|
|
97
|
+
onMouseDown: stopProp,
|
|
98
|
+
children: jsx("input", {
|
|
99
|
+
type: "checkbox",
|
|
100
|
+
autoFocus: autoFocus,
|
|
101
|
+
checked: checked,
|
|
102
|
+
onChange: function onChange(e) {
|
|
103
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(e.target.checked);
|
|
104
|
+
},
|
|
105
|
+
onKeyDown: onKeyDown,
|
|
106
|
+
className: "w-4 h-4 text-primary-600 border-gray-300 rounded focus:ring-primary-500 cursor-pointer"
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Date
|
|
111
|
+
if (inputType === "date") {
|
|
112
|
+
return jsx("input", {
|
|
113
|
+
type: "date",
|
|
114
|
+
autoFocus: autoFocus,
|
|
115
|
+
value: currentValue,
|
|
116
|
+
onChange: function onChange(e) {
|
|
117
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(e.target.value);
|
|
118
|
+
},
|
|
119
|
+
onKeyDown: onKeyDown,
|
|
120
|
+
onClick: stopProp,
|
|
121
|
+
onMouseDown: stopProp,
|
|
122
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-white", className)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// Number
|
|
126
|
+
if (inputType === "number") {
|
|
127
|
+
return jsx("input", {
|
|
128
|
+
type: "number",
|
|
129
|
+
autoFocus: autoFocus,
|
|
130
|
+
value: currentValue,
|
|
131
|
+
onChange: function onChange(e) {
|
|
132
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(e.target.value === "" ? "" : Number(e.target.value));
|
|
133
|
+
},
|
|
134
|
+
onKeyDown: onKeyDown,
|
|
135
|
+
onClick: stopProp,
|
|
136
|
+
onMouseDown: stopProp,
|
|
137
|
+
placeholder: "Enter ".concat(column.label || column.key, "..."),
|
|
138
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-white", className)
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// Default: Text
|
|
142
|
+
return jsx("input", {
|
|
143
|
+
type: "text",
|
|
144
|
+
autoFocus: autoFocus,
|
|
145
|
+
value: currentValue,
|
|
146
|
+
onChange: function onChange(e) {
|
|
147
|
+
return _onChange === null || _onChange === void 0 ? void 0 : _onChange(e.target.value);
|
|
148
|
+
},
|
|
149
|
+
onKeyDown: onKeyDown,
|
|
150
|
+
onClick: stopProp,
|
|
151
|
+
onMouseDown: stopProp,
|
|
152
|
+
placeholder: "Enter ".concat(column.label || column.key, "..."),
|
|
153
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-white", className)
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export { FieldInput as default };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { cn } from '../../../utils/cn.js';
|
|
5
|
+
import { MoreVertical } from 'lucide-react';
|
|
6
|
+
import ActionMenu from './ActionMenu.js';
|
|
7
|
+
import { getRowKey, resolveActions, rowHasDetails, getActionLabelText } from './helpers.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Mobile card view for a single table row
|
|
11
|
+
*/
|
|
12
|
+
function MobileCard(_ref) {
|
|
13
|
+
var row = _ref.row,
|
|
14
|
+
rowIndexInPage = _ref.rowIndexInPage,
|
|
15
|
+
startIndex = _ref.startIndex,
|
|
16
|
+
selectedRows = _ref.selectedRows,
|
|
17
|
+
expandedRows = _ref.expandedRows,
|
|
18
|
+
rowClass = _ref.rowClass,
|
|
19
|
+
stripedRows = _ref.stripedRows,
|
|
20
|
+
stripedColors = _ref.stripedColors,
|
|
21
|
+
theme = _ref.theme,
|
|
22
|
+
onRowClick = _ref.onRowClick,
|
|
23
|
+
hasDetails = _ref.hasDetails,
|
|
24
|
+
selectable = _ref.selectable,
|
|
25
|
+
showSerial = _ref.showSerial,
|
|
26
|
+
withAction = _ref.withAction,
|
|
27
|
+
visibleColumns = _ref.visibleColumns,
|
|
28
|
+
cellClass = _ref.cellClass,
|
|
29
|
+
DetailsComponent = _ref.DetailsComponent,
|
|
30
|
+
actionsToUse = _ref.actionsToUse,
|
|
31
|
+
activeActionRowKey = _ref.activeActionRowKey,
|
|
32
|
+
activeAnchorEl = _ref.activeAnchorEl,
|
|
33
|
+
registerActionButton = _ref.registerActionButton,
|
|
34
|
+
actionMenuRef = _ref.actionMenuRef,
|
|
35
|
+
toggleExpandRow = _ref.toggleExpandRow,
|
|
36
|
+
handleSelectRow = _ref.handleSelectRow,
|
|
37
|
+
toggleActions = _ref.toggleActions,
|
|
38
|
+
handleOnAction = _ref.handleOnAction,
|
|
39
|
+
closeActionMenu = _ref.closeActionMenu,
|
|
40
|
+
renderCell = _ref.renderCell;
|
|
41
|
+
var globalIndex = startIndex + rowIndexInPage;
|
|
42
|
+
var key = getRowKey(row, globalIndex);
|
|
43
|
+
var actionCellKey = "actions-".concat(key);
|
|
44
|
+
var isSelected = selectedRows.has(key);
|
|
45
|
+
var isExpanded = expandedRows.has(key);
|
|
46
|
+
var _React$useMemo = React.useMemo(function () {
|
|
47
|
+
return resolveActions(actionsToUse, row, globalIndex);
|
|
48
|
+
}, [actionsToUse, row, globalIndex]),
|
|
49
|
+
inlineActions = _React$useMemo.inlineActions,
|
|
50
|
+
menuActions = _React$useMemo.menuActions;
|
|
51
|
+
// Unlike the desktop row there is no column grid to keep aligned, so a
|
|
52
|
+
// non-qualifying row simply renders no toggle and no placeholder.
|
|
53
|
+
var showDetailsToggle = rowHasDetails(hasDetails, row, globalIndex);
|
|
54
|
+
var extraRowClass = typeof rowClass === "function" ? rowClass({
|
|
55
|
+
row: row,
|
|
56
|
+
rowIndex: globalIndex
|
|
57
|
+
}) : "";
|
|
58
|
+
var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
|
|
59
|
+
// The header strip only renders when it has something to hold; otherwise a
|
|
60
|
+
// card would open with an empty grey band above its first field.
|
|
61
|
+
var hasActions = withAction && (inlineActions.length > 0 || menuActions.length > 0);
|
|
62
|
+
var showHeader = showDetailsToggle || selectable || showSerial || hasActions;
|
|
63
|
+
var stripeBg = stripedRows && !isSelected && Array.isArray(stripedColors) && stripedColors.length > 0 ? stripedColors[globalIndex % stripedColors.length] : undefined;
|
|
64
|
+
return jsxs("div", {
|
|
65
|
+
style: stripeBg ? {
|
|
66
|
+
backgroundColor: stripeBg
|
|
67
|
+
} : undefined,
|
|
68
|
+
className: cn("border rounded-lg mb-3 shadow-sm overflow-hidden transition-all duration-200", {
|
|
69
|
+
"cursor-pointer": !!onRowClick,
|
|
70
|
+
"bg-primary-50 border-primary-200": isSelected,
|
|
71
|
+
"hover:shadow-md": !isSelected
|
|
72
|
+
}, safeExtraRowClass),
|
|
73
|
+
onClick: function onClick() {
|
|
74
|
+
return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
|
|
75
|
+
},
|
|
76
|
+
children: [showHeader && jsxs("div", {
|
|
77
|
+
className: "flex items-center justify-between p-4 border-b bg-gray-50",
|
|
78
|
+
children: [jsxs("div", {
|
|
79
|
+
className: "flex items-center gap-3",
|
|
80
|
+
children: [showDetailsToggle && jsx("button", {
|
|
81
|
+
type: "button",
|
|
82
|
+
onClick: function onClick(e) {
|
|
83
|
+
e.stopPropagation();
|
|
84
|
+
toggleExpandRow(row, rowIndexInPage);
|
|
85
|
+
},
|
|
86
|
+
"aria-expanded": isExpanded,
|
|
87
|
+
"aria-label": isExpanded ? "Collapse row details" : "Expand row details",
|
|
88
|
+
className: "p-1 rounded hover:bg-gray-200",
|
|
89
|
+
children: isExpanded ? "▾" : "▸"
|
|
90
|
+
}), selectable && jsx("input", {
|
|
91
|
+
type: "checkbox",
|
|
92
|
+
className: "rounded border-gray-300 h-4 w-4",
|
|
93
|
+
checked: isSelected,
|
|
94
|
+
onChange: function onChange(e) {
|
|
95
|
+
e.stopPropagation();
|
|
96
|
+
handleSelectRow(row, rowIndexInPage);
|
|
97
|
+
},
|
|
98
|
+
onClick: function onClick(e) {
|
|
99
|
+
return e.stopPropagation();
|
|
100
|
+
}
|
|
101
|
+
}), showSerial && jsxs("span", {
|
|
102
|
+
className: "text-sm font-medium",
|
|
103
|
+
children: ["#", globalIndex + 1]
|
|
104
|
+
})]
|
|
105
|
+
}), hasActions && jsxs("div", {
|
|
106
|
+
className: "flex items-center gap-1",
|
|
107
|
+
children: [inlineActions.map(function (action, idx) {
|
|
108
|
+
var _action$icon, _action$name;
|
|
109
|
+
var actionLabel = getActionLabelText(action);
|
|
110
|
+
return jsx("button", {
|
|
111
|
+
type: "button",
|
|
112
|
+
title: actionLabel,
|
|
113
|
+
"aria-label": actionLabel,
|
|
114
|
+
disabled: action.disabled,
|
|
115
|
+
onClick: function onClick(e) {
|
|
116
|
+
// The card root binds onRowClick and there is no stopping
|
|
117
|
+
// ancestor here, unlike the desktop actions <td>.
|
|
118
|
+
e.stopPropagation();
|
|
119
|
+
if (action.disabled) return;
|
|
120
|
+
handleOnAction(action, row);
|
|
121
|
+
},
|
|
122
|
+
className: cn("p-1.5 rounded", action.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-200"),
|
|
123
|
+
children: action.render ? action.render(row) : (_action$icon = action.icon) !== null && _action$icon !== void 0 ? _action$icon : jsx("span", {
|
|
124
|
+
className: "text-xs",
|
|
125
|
+
children: actionLabel
|
|
126
|
+
})
|
|
127
|
+
}, (_action$name = action.name) !== null && _action$name !== void 0 ? _action$name : "inline-".concat(idx));
|
|
128
|
+
}), menuActions.length > 0 && jsxs("div", {
|
|
129
|
+
className: "relative",
|
|
130
|
+
children: [jsx("button", {
|
|
131
|
+
ref: function ref(el) {
|
|
132
|
+
return registerActionButton === null || registerActionButton === void 0 ? void 0 : registerActionButton(actionCellKey, el);
|
|
133
|
+
},
|
|
134
|
+
onClick: function onClick(e) {
|
|
135
|
+
return toggleActions(e, actionCellKey, row);
|
|
136
|
+
},
|
|
137
|
+
"aria-expanded": activeActionRowKey === actionCellKey,
|
|
138
|
+
className: "p-1.5 rounded hover:bg-gray-200",
|
|
139
|
+
title: "Actions",
|
|
140
|
+
children: jsx(MoreVertical, {
|
|
141
|
+
className: "h-4 w-4"
|
|
142
|
+
})
|
|
143
|
+
}), activeActionRowKey === actionCellKey && jsx(ActionMenu, {
|
|
144
|
+
actions: menuActions,
|
|
145
|
+
row: row,
|
|
146
|
+
onAction: function onAction(action) {
|
|
147
|
+
return handleOnAction(action, row);
|
|
148
|
+
},
|
|
149
|
+
menuRef: actionMenuRef,
|
|
150
|
+
anchorEl: activeAnchorEl,
|
|
151
|
+
onClose: closeActionMenu,
|
|
152
|
+
theme: theme
|
|
153
|
+
})]
|
|
154
|
+
})]
|
|
155
|
+
})]
|
|
156
|
+
}), jsx("div", {
|
|
157
|
+
className: "p-4",
|
|
158
|
+
children: visibleColumns.map(function (column, colIndex) {
|
|
159
|
+
var extraCellClass = typeof cellClass === "function" ? cellClass({
|
|
160
|
+
row: row,
|
|
161
|
+
rowIndex: globalIndex,
|
|
162
|
+
column: column,
|
|
163
|
+
columnIndex: colIndex
|
|
164
|
+
}) : "";
|
|
165
|
+
var safeExtraCellClass = typeof extraCellClass === "string" ? extraCellClass.trim() : "";
|
|
166
|
+
return jsxs("div", {
|
|
167
|
+
className: cn("flex justify-between items-center flex-row py-2 border-b last:border-b-0", safeExtraCellClass),
|
|
168
|
+
children: [jsx("div", {
|
|
169
|
+
className: "text-xs font-medium text-primary-500 uppercase tracking-wide mb-1 sm:mb-0 sm:w-1/3 sm:pr-2",
|
|
170
|
+
children: column.label
|
|
171
|
+
}), jsx("div", {
|
|
172
|
+
className: "text-sm text-primary-900 sm:w-2/3 sm:pl-2 break-words",
|
|
173
|
+
children: renderCell(column, row, globalIndex)
|
|
174
|
+
})]
|
|
175
|
+
}, column.key);
|
|
176
|
+
})
|
|
177
|
+
}), showDetailsToggle && isExpanded && DetailsComponent && jsx("div", {
|
|
178
|
+
className: "border-t bg-gray-50 p-4",
|
|
179
|
+
children: jsx(DetailsComponent, {
|
|
180
|
+
row: row,
|
|
181
|
+
index: globalIndex
|
|
182
|
+
})
|
|
183
|
+
})]
|
|
184
|
+
}, key);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export { MobileCard as default };
|