@dreamtree-org/twreact-ui 1.3.2 → 1.3.4
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 +14 -6
- package/ai-skills/dreamtree-ui.md +3 -1
- package/bin/cli.mjs +72 -4
- package/dist/ai-schema.json +3 -2
- package/dist/charts/index.js +75 -47
- package/dist/components/charts/CartesianChart.d.ts.map +1 -1
- package/dist/components/charts/DonutChart.d.ts.map +1 -1
- package/dist/components/charts/Sparkline.d.ts.map +1 -1
- package/dist/components/charts/chartTheme.d.ts +13 -3
- package/dist/components/charts/chartTheme.d.ts.map +1 -1
- package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/components/core/Table/helpers.d.ts +12 -0
- package/dist/components/core/Table/helpers.d.ts.map +1 -1
- package/dist/components/utility/Stepper.d.ts.map +1 -1
- package/dist/esm/components/blocks/StatCard.js +1 -1
- package/dist/esm/components/charts/CartesianChart.js +7 -2
- package/dist/esm/components/charts/DonutChart.js +4 -1
- package/dist/esm/components/charts/Sparkline.js +4 -1
- package/dist/esm/components/charts/chartTheme.js +65 -48
- package/dist/esm/components/core/Select.js +2 -2
- package/dist/esm/components/core/Table/ActionMenu.js +5 -5
- package/dist/esm/components/core/Table/ColumnMenu.js +1 -1
- package/dist/esm/components/core/Table/FieldInput.js +5 -5
- package/dist/esm/components/core/Table/MobileCard.js +14 -12
- package/dist/esm/components/core/Table/MobileFilters.js +11 -4
- package/dist/esm/components/core/Table/Pagination.js +1 -1
- package/dist/esm/components/core/Table/Table.js +22 -19
- package/dist/esm/components/core/Table/TableRow.js +10 -11
- package/dist/esm/components/core/Table/helpers.js +16 -1
- package/dist/esm/components/navigation/Dropdown.js +1 -1
- package/dist/esm/components/navigation/Navbar.js +21 -21
- package/dist/esm/components/navigation/Sidebar.js +12 -12
- package/dist/esm/components/utility/Card.js +5 -5
- package/dist/esm/components/utility/Stepper.js +6 -4
- package/dist/index.css +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +129 -101
- package/dist/index.js +129 -101
- package/dist/tokens/brands/practicepro.json +1 -0
- package/dist/tokens/brands/studio.json +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/mcp/catalog.snapshot.json +21 -21
- package/package.json +2 -1
- package/tokens/brand.schema.json +612 -0
- package/tokens/brands/practicepro.json +1 -0
- package/tokens/brands/studio.json +1 -0
- package/tokens/lib.cjs +131 -7
|
@@ -4,7 +4,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { ResponsiveContainer, PieChart, Tooltip, Pie } from 'recharts';
|
|
6
6
|
import { ChartFrame, ChartTooltipContent } from './ChartFrame.js';
|
|
7
|
-
import { useChartTheme, useReducedMotion, defaultValueFormatter } from './chartTheme.js';
|
|
7
|
+
import { useChartTheme, useReducedMotion, useChartId, defaultValueFormatter } from './chartTheme.js';
|
|
8
8
|
|
|
9
9
|
var _excluded = ["data", "index", "category", "colors", "valueFormatter", "variant", "innerRadius", "outerRadius", "centerLabel", "height", "showLegend", "showTooltip", "animate", "title", "description", "emptyState", "accessibleTable", "className"];
|
|
10
10
|
var DonutChart = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
@@ -46,6 +46,7 @@ var DonutChart = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
46
46
|
chrome = _useChartTheme.chrome,
|
|
47
47
|
series = _useChartTheme.series;
|
|
48
48
|
var reducedMotion = useReducedMotion();
|
|
49
|
+
var chartId = useChartId();
|
|
49
50
|
var slices = rows.map(function (row, i) {
|
|
50
51
|
return _objectSpread2(_objectSpread2({}, row), {}, {
|
|
51
52
|
fill: series[i]
|
|
@@ -87,6 +88,7 @@ var DonutChart = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
87
88
|
height: "100%",
|
|
88
89
|
minWidth: 0,
|
|
89
90
|
children: jsxs(PieChart, {
|
|
91
|
+
id: chartId,
|
|
90
92
|
accessibilityLayer: false,
|
|
91
93
|
children: [showTooltip && jsx(Tooltip, {
|
|
92
94
|
isAnimationActive: false,
|
|
@@ -95,6 +97,7 @@ var DonutChart = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
95
97
|
hideLabel: true
|
|
96
98
|
})
|
|
97
99
|
}), jsx(Pie, {
|
|
100
|
+
id: "".concat(chartId, "-0"),
|
|
98
101
|
data: slices,
|
|
99
102
|
dataKey: category,
|
|
100
103
|
nameKey: index,
|
|
@@ -4,7 +4,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { ResponsiveContainer, AreaChart, LineChart, YAxis, Tooltip, Area, Line } from 'recharts';
|
|
6
6
|
import { ChartFrame, ChartTooltipContent } from './ChartFrame.js';
|
|
7
|
-
import { useChartTheme, useReducedMotion, defaultValueFormatter } from './chartTheme.js';
|
|
7
|
+
import { useChartTheme, useReducedMotion, useChartId, defaultValueFormatter } from './chartTheme.js';
|
|
8
8
|
|
|
9
9
|
var _excluded = ["data", "category", "index", "color", "type", "valueFormatter", "height", "showTooltip", "animate", "title", "description", "emptyState", "accessibleTable", "className"];
|
|
10
10
|
/** A word-sized trend line: no axes, grid or legend — just the shape of the data. */
|
|
@@ -36,9 +36,11 @@ var Sparkline = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
36
36
|
var _useChartTheme = useChartTheme([category], [color]),
|
|
37
37
|
series = _useChartTheme.series;
|
|
38
38
|
var reducedMotion = useReducedMotion();
|
|
39
|
+
var chartId = useChartId();
|
|
39
40
|
var stroke = series[0];
|
|
40
41
|
var Root = type === "area" ? AreaChart : LineChart;
|
|
41
42
|
var common = {
|
|
43
|
+
id: "".concat(chartId, "-0"),
|
|
42
44
|
dataKey: category,
|
|
43
45
|
name: category,
|
|
44
46
|
type: "monotone",
|
|
@@ -79,6 +81,7 @@ var Sparkline = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
79
81
|
height: "100%",
|
|
80
82
|
minWidth: 0,
|
|
81
83
|
children: jsxs(Root, {
|
|
84
|
+
id: chartId,
|
|
82
85
|
data: data,
|
|
83
86
|
margin: {
|
|
84
87
|
top: 2,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
-
import {
|
|
3
|
+
import { useSyncExternalStore, useId } from 'react';
|
|
4
4
|
import { prefersReducedMotion } from '../../utils/position.js';
|
|
5
5
|
|
|
6
6
|
var CHART_PALETTES = ["primary", "secondary", "success", "warning", "error", "info", "gray"];
|
|
@@ -23,9 +23,11 @@ function readVar(name) {
|
|
|
23
23
|
}
|
|
24
24
|
// SVG presentation attributes do not resolve var() in every engine, so a token is
|
|
25
25
|
// turned into a concrete rgb() string when the browser can tell us its value. The
|
|
26
|
-
// var() form is the SSR / jsdom fallback
|
|
26
|
+
// var() form is the SSR / jsdom fallback, and what the first (hydrating) client
|
|
27
|
+
// render uses so it matches the server's HTML (`live` = false).
|
|
27
28
|
function resolveVar(name) {
|
|
28
|
-
var
|
|
29
|
+
var live = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
30
|
+
var value = live ? readVar(name) : "";
|
|
29
31
|
return value ? "rgb(".concat(value.split(/[\s,]+/).join(" "), ")") : "rgb(var(".concat(name, "))");
|
|
30
32
|
}
|
|
31
33
|
/**
|
|
@@ -34,76 +36,91 @@ function resolveVar(name) {
|
|
|
34
36
|
* by the consumer (e.g. a colour stored with the data).
|
|
35
37
|
*/
|
|
36
38
|
function resolveColor(color) {
|
|
39
|
+
var live = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
37
40
|
var name = tokenVar(color);
|
|
38
|
-
return name ? resolveVar(name) : color;
|
|
41
|
+
return name ? resolveVar(name, live) : color;
|
|
39
42
|
}
|
|
40
43
|
function seriesColors(categories, colors) {
|
|
44
|
+
var live = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
41
45
|
var palette = colors && colors.length ? colors : DEFAULT_CHART_COLORS;
|
|
42
46
|
return categories.map(function (_, i) {
|
|
43
|
-
return resolveColor(palette[i % palette.length]);
|
|
47
|
+
return resolveColor(palette[i % palette.length], live);
|
|
44
48
|
});
|
|
45
49
|
}
|
|
46
|
-
function readChrome() {
|
|
50
|
+
function readChrome(live) {
|
|
47
51
|
return Object.fromEntries(Object.entries(CHROME_VARS).map(function (_ref) {
|
|
48
52
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
49
53
|
k = _ref2[0],
|
|
50
54
|
v = _ref2[1];
|
|
51
|
-
return [k, resolveVar(v)];
|
|
55
|
+
return [k, resolveVar(v, live)];
|
|
52
56
|
}));
|
|
53
57
|
}
|
|
58
|
+
// The theme is an external store: the attributes on <html> that flip it. The
|
|
59
|
+
// server snapshot is null, so a hydrating render keeps the var() fallback the
|
|
60
|
+
// server rendered and React re-renders with live colours right after (#130).
|
|
61
|
+
function subscribeTheme(onChange) {
|
|
62
|
+
if (typeof document === "undefined" || typeof MutationObserver !== "function") return function () {};
|
|
63
|
+
var observer = new MutationObserver(onChange);
|
|
64
|
+
observer.observe(document.documentElement, {
|
|
65
|
+
attributes: true,
|
|
66
|
+
attributeFilter: ["class", "data-theme", "style"]
|
|
67
|
+
});
|
|
68
|
+
return function () {
|
|
69
|
+
return observer.disconnect();
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function themeSnapshot() {
|
|
73
|
+
if (typeof document === "undefined") return null;
|
|
74
|
+
var el = document.documentElement;
|
|
75
|
+
return "".concat(el.className, "|").concat(el.getAttribute("data-theme") || "", "|").concat(el.getAttribute("style") || "");
|
|
76
|
+
}
|
|
77
|
+
var serverThemeSnapshot = function serverThemeSnapshot() {
|
|
78
|
+
return null;
|
|
79
|
+
};
|
|
54
80
|
/**
|
|
55
81
|
* Chart chrome + series colours, re-read whenever the theme flips (the `dark`
|
|
56
82
|
* class or `data-theme` on <html>) so axes and series follow dark mode without
|
|
57
83
|
* a remount.
|
|
58
84
|
*/
|
|
59
85
|
function useChartTheme(categories, colors) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
_useState2[0];
|
|
63
|
-
var setVersion = _useState2[1];
|
|
64
|
-
useEffect(function () {
|
|
65
|
-
if (typeof MutationObserver !== "function") return undefined;
|
|
66
|
-
var observer = new MutationObserver(function () {
|
|
67
|
-
return setVersion(function (v) {
|
|
68
|
-
return v + 1;
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
observer.observe(document.documentElement, {
|
|
72
|
-
attributes: true,
|
|
73
|
-
attributeFilter: ["class", "data-theme", "style"]
|
|
74
|
-
});
|
|
75
|
-
return function () {
|
|
76
|
-
return observer.disconnect();
|
|
77
|
-
};
|
|
78
|
-
}, []);
|
|
86
|
+
// The snapshot only signals a change; the values come from the live document.
|
|
87
|
+
var live = useSyncExternalStore(subscribeTheme, themeSnapshot, serverThemeSnapshot) !== null;
|
|
79
88
|
return {
|
|
80
|
-
chrome: readChrome(),
|
|
81
|
-
series: seriesColors(categories, colors)
|
|
89
|
+
chrome: readChrome(live),
|
|
90
|
+
series: seriesColors(categories, colors, live)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function subscribeReducedMotion(onChange) {
|
|
94
|
+
var _query$addEventListen;
|
|
95
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return function () {};
|
|
96
|
+
var query = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
97
|
+
(_query$addEventListen = query.addEventListener) === null || _query$addEventListen === void 0 || _query$addEventListen.call(query, "change", onChange);
|
|
98
|
+
return function () {
|
|
99
|
+
var _query$removeEventLis;
|
|
100
|
+
return (_query$removeEventLis = query.removeEventListener) === null || _query$removeEventLis === void 0 ? void 0 : _query$removeEventLis.call(query, "change", onChange);
|
|
82
101
|
};
|
|
83
102
|
}
|
|
84
|
-
|
|
103
|
+
var serverReducedMotion = function serverReducedMotion() {
|
|
104
|
+
return false;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* `true` while the user asks the OS for reduced motion; follows changes live.
|
|
108
|
+
* `false` on the server and while hydrating, so the first render matches.
|
|
109
|
+
*/
|
|
85
110
|
function useReducedMotion() {
|
|
86
|
-
|
|
87
|
-
_useState4 = _slicedToArray(_useState3, 2),
|
|
88
|
-
reduced = _useState4[0],
|
|
89
|
-
setReduced = _useState4[1];
|
|
90
|
-
useEffect(function () {
|
|
91
|
-
var _query$addEventListen;
|
|
92
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return undefined;
|
|
93
|
-
var query = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
94
|
-
var update = function update() {
|
|
95
|
-
return setReduced(query.matches);
|
|
96
|
-
};
|
|
97
|
-
(_query$addEventListen = query.addEventListener) === null || _query$addEventListen === void 0 || _query$addEventListen.call(query, "change", update);
|
|
98
|
-
return function () {
|
|
99
|
-
var _query$removeEventLis;
|
|
100
|
-
return (_query$removeEventLis = query.removeEventListener) === null || _query$removeEventLis === void 0 ? void 0 : _query$removeEventLis.call(query, "change", update);
|
|
101
|
-
};
|
|
102
|
-
}, []);
|
|
103
|
-
return reduced;
|
|
111
|
+
return useSyncExternalStore(subscribeReducedMotion, prefersReducedMotion, serverReducedMotion);
|
|
104
112
|
}
|
|
105
113
|
var defaultValueFormatter = function defaultValueFormatter(value) {
|
|
106
114
|
return typeof value === "number" ? value.toLocaleString() : value == null ? "" : String(value);
|
|
107
115
|
};
|
|
116
|
+
/**
|
|
117
|
+
* A per-instance id for the SVG defs recharts draws (clip paths). recharts 2
|
|
118
|
+
* falls back to a module-level counter, which differs between the server and the
|
|
119
|
+
* client; an id from React.useId() is the same on both. Only [A-Za-z0-9_-] so it
|
|
120
|
+
* is safe inside `url(#…)`.
|
|
121
|
+
*/
|
|
122
|
+
function useChartId() {
|
|
123
|
+
return "dt-chart-".concat(useId().replace(/[^A-Za-z0-9_-]/g, ""));
|
|
124
|
+
}
|
|
108
125
|
|
|
109
|
-
export { CHART_PALETTES, DEFAULT_CHART_COLORS, defaultValueFormatter, resolveColor, seriesColors, tokenVar, useChartTheme, useReducedMotion };
|
|
126
|
+
export { CHART_PALETTES, DEFAULT_CHART_COLORS, defaultValueFormatter, resolveColor, seriesColors, tokenVar, useChartId, useChartTheme, useReducedMotion };
|
|
@@ -127,7 +127,7 @@ var Select = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
|
|
|
127
127
|
onMenuItemRender = _ref.onMenuItemRender,
|
|
128
128
|
className = _ref.className,
|
|
129
129
|
_ref$allowClear = _ref.allowClear,
|
|
130
|
-
allowClear = _ref$allowClear === void 0 ?
|
|
130
|
+
allowClear = _ref$allowClear === void 0 ? false : _ref$allowClear,
|
|
131
131
|
_ref$creatable = _ref.creatable,
|
|
132
132
|
creatable = _ref$creatable === void 0 ? false : _ref$creatable,
|
|
133
133
|
onCreateOption = _ref.onCreateOption,
|
|
@@ -564,7 +564,7 @@ var Select = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
|
|
|
564
564
|
}, opt.value);
|
|
565
565
|
})
|
|
566
566
|
}), jsxs("div", {
|
|
567
|
-
className: "text-xs text-primary-
|
|
567
|
+
className: "text-xs text-primary-700",
|
|
568
568
|
children: ["+", rest]
|
|
569
569
|
})]
|
|
570
570
|
});
|
|
@@ -6,8 +6,8 @@ import { createPortal } from 'react-dom';
|
|
|
6
6
|
import { cn } from '../../../utils/cn.js';
|
|
7
7
|
import { useLatestRef } from '../../../hooks/useLatestRef.js';
|
|
8
8
|
|
|
9
|
-
var DEFAULT_MENU_BG = "bg-
|
|
10
|
-
var DEFAULT_MENU_ITEM_HOVER = "opacity-75 hover:opacity-100 hover:bg-gray-100/80 active:bg-gray-200/80";
|
|
9
|
+
var DEFAULT_MENU_BG = "bg-surface border border-line shadow-xl";
|
|
10
|
+
var DEFAULT_MENU_ITEM_HOVER = "opacity-75 hover:opacity-100 hover:bg-gray-100/80 active:bg-gray-200/80 dark:hover:bg-gray-800 dark:active:bg-gray-700";
|
|
11
11
|
function ActionMenu(_ref) {
|
|
12
12
|
var _theme$menuBg, _theme$menuItemHover;
|
|
13
13
|
var _ref$actions = _ref.actions,
|
|
@@ -211,7 +211,7 @@ function ActionMenu(_ref) {
|
|
|
211
211
|
children: jsx("div", {
|
|
212
212
|
className: "p-1.5 space-y-0.5",
|
|
213
213
|
children: !Array.isArray(actions) || actions.length === 0 ? jsx("div", {
|
|
214
|
-
className: "px-3 py-2 text-sm text-
|
|
214
|
+
className: "px-3 py-2 text-sm text-muted italic",
|
|
215
215
|
children: "No actions"
|
|
216
216
|
}) : actions.map(function (action, idx) {
|
|
217
217
|
var _action$name;
|
|
@@ -222,7 +222,7 @@ function ActionMenu(_ref) {
|
|
|
222
222
|
type: "button",
|
|
223
223
|
disabled: isDisabled,
|
|
224
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-
|
|
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-muted" : ["text-foreground", menuItemHover, isFocused ? "bg-gray-100 text-gray-900 ring-1 ring-gray-300 dark:bg-gray-800 dark:text-foreground dark:ring-gray-600" : ""]),
|
|
226
226
|
onMouseEnter: function onMouseEnter() {
|
|
227
227
|
return !isDisabled && setFocusedIndex(idx);
|
|
228
228
|
},
|
|
@@ -234,7 +234,7 @@ function ActionMenu(_ref) {
|
|
|
234
234
|
},
|
|
235
235
|
children: action.render ? action.render(row) : jsxs(Fragment, {
|
|
236
236
|
children: [action.icon && jsx("span", {
|
|
237
|
-
className: "inline-flex text-
|
|
237
|
+
className: "inline-flex text-muted flex-shrink-0",
|
|
238
238
|
children: action.icon
|
|
239
239
|
}), jsx("span", {
|
|
240
240
|
className: "truncate",
|
|
@@ -56,7 +56,7 @@ function FieldInput(_ref) {
|
|
|
56
56
|
onClick: stopProp,
|
|
57
57
|
onMouseDown: stopProp,
|
|
58
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-
|
|
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-surface text-foreground resize-y min-h-[2.5rem]", className)
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
// Select / Dropdown
|
|
@@ -76,7 +76,7 @@ function FieldInput(_ref) {
|
|
|
76
76
|
onKeyDown: onKeyDown,
|
|
77
77
|
onClick: stopProp,
|
|
78
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-
|
|
79
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-surface text-foreground", className),
|
|
80
80
|
children: [jsxs("option", {
|
|
81
81
|
value: "",
|
|
82
82
|
children: ["Select ", column.label || column.key]
|
|
@@ -119,7 +119,7 @@ function FieldInput(_ref) {
|
|
|
119
119
|
onKeyDown: onKeyDown,
|
|
120
120
|
onClick: stopProp,
|
|
121
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-
|
|
122
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-surface text-foreground", className)
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
// Number
|
|
@@ -135,7 +135,7 @@ function FieldInput(_ref) {
|
|
|
135
135
|
onClick: stopProp,
|
|
136
136
|
onMouseDown: stopProp,
|
|
137
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-
|
|
138
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-surface text-foreground", className)
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
141
|
// Default: Text
|
|
@@ -150,7 +150,7 @@ function FieldInput(_ref) {
|
|
|
150
150
|
onClick: stopProp,
|
|
151
151
|
onMouseDown: stopProp,
|
|
152
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-
|
|
153
|
+
className: cn("w-full px-2 py-1 text-sm border rounded outline-none focus:ring-2 focus:ring-primary-500 bg-surface text-foreground", className)
|
|
154
154
|
});
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -4,7 +4,7 @@ import React from 'react';
|
|
|
4
4
|
import { cn } from '../../../utils/cn.js';
|
|
5
5
|
import { MoreVertical } from 'lucide-react';
|
|
6
6
|
import ActionMenu from './ActionMenu.js';
|
|
7
|
-
import { getRowKey, resolveActions, rowHasDetails, getActionLabelText } from './helpers.js';
|
|
7
|
+
import { getRowKey, resolveActions, rowHasDetails, getActionLabelText, getStripeProps } from './helpers.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Mobile card view for a single table row
|
|
@@ -61,11 +61,10 @@ function MobileCard(_ref) {
|
|
|
61
61
|
var hasActions = withAction && (inlineActions.length > 0 || menuActions.length > 0);
|
|
62
62
|
var showHeader = showDetailsToggle || selectable || showSerial || hasActions;
|
|
63
63
|
var stripeBg = stripedRows && !isSelected && Array.isArray(stripedColors) && stripedColors.length > 0 ? stripedColors[globalIndex % stripedColors.length] : undefined;
|
|
64
|
+
var stripeProps = getStripeProps(stripeBg);
|
|
64
65
|
return jsxs("div", {
|
|
65
|
-
style:
|
|
66
|
-
|
|
67
|
-
} : undefined,
|
|
68
|
-
className: cn("border rounded-lg mb-3 shadow-sm overflow-hidden transition-all duration-200", {
|
|
66
|
+
style: stripeProps.style,
|
|
67
|
+
className: cn(stripeProps.className, "border border-line rounded-lg mb-3 shadow-sm overflow-hidden transition-all duration-200", {
|
|
69
68
|
"cursor-pointer": !!onRowClick,
|
|
70
69
|
"bg-primary-50 border-primary-200": isSelected,
|
|
71
70
|
"hover:shadow-md": !isSelected
|
|
@@ -74,7 +73,7 @@ function MobileCard(_ref) {
|
|
|
74
73
|
return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
|
|
75
74
|
},
|
|
76
75
|
children: [showHeader && jsxs("div", {
|
|
77
|
-
className: "flex items-center justify-between p-4 border-b bg-
|
|
76
|
+
className: "flex items-center justify-between p-4 border-b border-line bg-background",
|
|
78
77
|
children: [jsxs("div", {
|
|
79
78
|
className: "flex items-center gap-3",
|
|
80
79
|
children: [showDetailsToggle && jsx("button", {
|
|
@@ -85,7 +84,7 @@ function MobileCard(_ref) {
|
|
|
85
84
|
},
|
|
86
85
|
"aria-expanded": isExpanded,
|
|
87
86
|
"aria-label": isExpanded ? "Collapse row details" : "Expand row details",
|
|
88
|
-
className: "p-1 rounded hover:bg-gray-200",
|
|
87
|
+
className: "p-1 rounded hover:bg-gray-200 dark:hover:bg-gray-700",
|
|
89
88
|
children: isExpanded ? "▾" : "▸"
|
|
90
89
|
}), selectable && jsx("input", {
|
|
91
90
|
type: "checkbox",
|
|
@@ -119,7 +118,7 @@ function MobileCard(_ref) {
|
|
|
119
118
|
if (action.disabled) return;
|
|
120
119
|
handleOnAction(action, row);
|
|
121
120
|
},
|
|
122
|
-
className: cn("p-1.5 rounded", action.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-200"),
|
|
121
|
+
className: cn("p-1.5 rounded", action.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-200 dark:hover:bg-gray-700"),
|
|
123
122
|
children: action.render ? action.render(row) : (_action$icon = action.icon) !== null && _action$icon !== void 0 ? _action$icon : jsx("span", {
|
|
124
123
|
className: "text-xs",
|
|
125
124
|
children: actionLabel
|
|
@@ -128,6 +127,7 @@ function MobileCard(_ref) {
|
|
|
128
127
|
}), menuActions.length > 0 && jsxs("div", {
|
|
129
128
|
className: "relative",
|
|
130
129
|
children: [jsx("button", {
|
|
130
|
+
type: "button",
|
|
131
131
|
ref: function ref(el) {
|
|
132
132
|
return registerActionButton === null || registerActionButton === void 0 ? void 0 : registerActionButton(actionCellKey, el);
|
|
133
133
|
},
|
|
@@ -135,10 +135,12 @@ function MobileCard(_ref) {
|
|
|
135
135
|
return toggleActions(e, actionCellKey, row);
|
|
136
136
|
},
|
|
137
137
|
"aria-expanded": activeActionRowKey === actionCellKey,
|
|
138
|
-
className: "p-1.5 rounded hover:bg-gray-200",
|
|
138
|
+
className: "p-1.5 rounded hover:bg-gray-200 dark:hover:bg-gray-700",
|
|
139
139
|
title: "Actions",
|
|
140
|
+
"aria-label": "Actions",
|
|
140
141
|
children: jsx(MoreVertical, {
|
|
141
|
-
className: "h-4 w-4"
|
|
142
|
+
className: "h-4 w-4",
|
|
143
|
+
"aria-hidden": "true"
|
|
142
144
|
})
|
|
143
145
|
}), activeActionRowKey === actionCellKey && jsx(ActionMenu, {
|
|
144
146
|
actions: menuActions,
|
|
@@ -166,7 +168,7 @@ function MobileCard(_ref) {
|
|
|
166
168
|
return jsxs("div", {
|
|
167
169
|
className: cn("flex justify-between items-center flex-row py-2 border-b last:border-b-0", safeExtraCellClass),
|
|
168
170
|
children: [jsx("div", {
|
|
169
|
-
className: "text-xs font-medium text-primary-
|
|
171
|
+
className: "text-xs font-medium text-primary-700 uppercase tracking-wide mb-1 sm:mb-0 sm:w-1/3 sm:pr-2",
|
|
170
172
|
children: column.label
|
|
171
173
|
}), jsx("div", {
|
|
172
174
|
className: "text-sm text-primary-900 sm:w-2/3 sm:pl-2 break-words",
|
|
@@ -175,7 +177,7 @@ function MobileCard(_ref) {
|
|
|
175
177
|
}, column.key);
|
|
176
178
|
})
|
|
177
179
|
}), showDetailsToggle && isExpanded && DetailsComponent && jsx("div", {
|
|
178
|
-
className: "border-t bg-
|
|
180
|
+
className: "border-t border-line bg-background p-4",
|
|
179
181
|
children: jsx(DetailsComponent, {
|
|
180
182
|
row: row,
|
|
181
183
|
index: globalIndex
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import 'react';
|
|
3
|
+
import React from 'react';
|
|
4
4
|
import { Search } from 'lucide-react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -17,20 +17,23 @@ function MobileFilters(_ref) {
|
|
|
17
17
|
visibleColumns = _ref.visibleColumns,
|
|
18
18
|
filters = _ref.filters,
|
|
19
19
|
handleFilter = _ref.handleFilter;
|
|
20
|
+
var idPrefix = React.useId();
|
|
20
21
|
return jsxs("div", {
|
|
21
|
-
className: "mb-4 p-3 bg-
|
|
22
|
+
className: "mb-4 p-3 bg-background rounded-lg",
|
|
22
23
|
children: [jsxs("div", {
|
|
23
24
|
className: "flex items-center justify-between mb-3",
|
|
24
25
|
children: [jsx("h3", {
|
|
25
26
|
className: "text-sm font-medium",
|
|
26
27
|
children: "Filters"
|
|
27
28
|
}), jsx("button", {
|
|
29
|
+
type: "button",
|
|
28
30
|
onClick: function onClick() {
|
|
29
31
|
return setShowMobileFilters(function (s) {
|
|
30
32
|
return !s;
|
|
31
33
|
});
|
|
32
34
|
},
|
|
33
|
-
|
|
35
|
+
"aria-expanded": !!showMobileFilters,
|
|
36
|
+
className: "text-xs font-medium text-primary-700",
|
|
34
37
|
children: showMobileFilters ? "Hide" : "Show"
|
|
35
38
|
})]
|
|
36
39
|
}), showMobileFilters && jsxs("div", {
|
|
@@ -40,6 +43,7 @@ function MobileFilters(_ref) {
|
|
|
40
43
|
children: [jsx("input", {
|
|
41
44
|
type: "text",
|
|
42
45
|
placeholder: "Search...",
|
|
46
|
+
"aria-label": "Search",
|
|
43
47
|
className: "w-full rounded-md border border-gray-300 px-4 py-2 text-sm",
|
|
44
48
|
value: searchInput,
|
|
45
49
|
onChange: function onChange(e) {
|
|
@@ -47,14 +51,17 @@ function MobileFilters(_ref) {
|
|
|
47
51
|
},
|
|
48
52
|
onKeyDown: onGlobalKeyDown
|
|
49
53
|
}), jsx(Search, {
|
|
50
|
-
className: "absolute right-3 top-2.5 h-4 w-4 text-primary-400"
|
|
54
|
+
className: "absolute right-3 top-2.5 h-4 w-4 text-primary-400",
|
|
55
|
+
"aria-hidden": "true"
|
|
51
56
|
})]
|
|
52
57
|
}), filterable && visibleColumns.map(function (column) {
|
|
53
58
|
return jsxs("div", {
|
|
54
59
|
children: [jsx("label", {
|
|
60
|
+
htmlFor: "".concat(idPrefix, "-filter-").concat(column.key),
|
|
55
61
|
className: "block text-xs font-medium mb-1",
|
|
56
62
|
children: column.label
|
|
57
63
|
}), jsx("input", {
|
|
64
|
+
id: "".concat(idPrefix, "-filter-").concat(column.key),
|
|
58
65
|
type: "text",
|
|
59
66
|
placeholder: "Filter ".concat(column.label),
|
|
60
67
|
className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm",
|
|
@@ -9,7 +9,7 @@ import { ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight } from 'lucide-r
|
|
|
9
9
|
* Pagination controls component for the table
|
|
10
10
|
* Supports both header (icon-only) and footer (with page numbers) variants
|
|
11
11
|
*/
|
|
12
|
-
var DEFAULT_ROW_HOVER = "bg-
|
|
12
|
+
var DEFAULT_ROW_HOVER = "bg-background";
|
|
13
13
|
// Header pagination (compact, icon-based)
|
|
14
14
|
function PaginationHeader(_ref) {
|
|
15
15
|
var _theme$rowHover;
|
|
@@ -21,11 +21,11 @@ var _excluded = ["data", "columns", "sortable", "filterable", "selectable", "pag
|
|
|
21
21
|
var DEFAULT_DATA = [];
|
|
22
22
|
var DEFAULT_COLUMNS = [];
|
|
23
23
|
var DEFAULT_THEME = {
|
|
24
|
-
stripedColors: ["bg-
|
|
25
|
-
rowHover: "bg-
|
|
26
|
-
accentColor: "bg-
|
|
27
|
-
menuBg: "bg-
|
|
28
|
-
menuItemHover: "hover:bg-
|
|
24
|
+
stripedColors: ["bg-surface", "bg-background"],
|
|
25
|
+
rowHover: "bg-background",
|
|
26
|
+
accentColor: "bg-background",
|
|
27
|
+
menuBg: "bg-surface",
|
|
28
|
+
menuItemHover: "hover:bg-background"
|
|
29
29
|
};
|
|
30
30
|
var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
31
31
|
var _validationErrors$;
|
|
@@ -1179,10 +1179,13 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1179
1179
|
children: [showReloadButton && jsx(Fragment, {
|
|
1180
1180
|
children: renderReloadButton ? typeof renderReloadButton === "function" ? renderReloadButton() : renderReloadButton : jsxs("button", {
|
|
1181
1181
|
type: "button",
|
|
1182
|
+
"aria-label": "Reload",
|
|
1183
|
+
title: "Reload",
|
|
1182
1184
|
className: "px-4 py-2 bg-primary-100 flex items-center gap-2 rounded-lg md:rounded text-primary-700 hover:bg-primary-200 transition-colors",
|
|
1183
1185
|
onClick: onReload,
|
|
1184
1186
|
children: [jsx(RefreshCcw, {
|
|
1185
|
-
className: "size-4"
|
|
1187
|
+
className: "size-4",
|
|
1188
|
+
"aria-hidden": "true"
|
|
1186
1189
|
}), jsx("span", {
|
|
1187
1190
|
className: "hidden sm:inline",
|
|
1188
1191
|
children: "Reload"
|
|
@@ -1236,7 +1239,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1236
1239
|
onClick: handleClearChanges,
|
|
1237
1240
|
disabled: isSaving,
|
|
1238
1241
|
title: "Discard all pending modifications",
|
|
1239
|
-
className: "px-4 py-2 font-medium rounded-lg text-sm flex items-center gap-2 transition-all border border-primary-300 text-primary-700 bg-
|
|
1242
|
+
className: "px-4 py-2 font-medium rounded-lg text-sm flex items-center gap-2 transition-all border border-primary-300 text-primary-700 bg-surface hover:bg-primary-50 dark:text-primary-300 dark:border-primary-700 dark:hover:bg-primary-900/40 active:bg-primary-100 cursor-pointer shadow-sm disabled:opacity-50",
|
|
1240
1243
|
children: [jsx(X, {
|
|
1241
1244
|
className: "w-4 h-4 text-primary-600"
|
|
1242
1245
|
}), jsx("span", {
|
|
@@ -1280,7 +1283,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1280
1283
|
onKeyDown: onGlobalKeyDown
|
|
1281
1284
|
}), jsx("button", {
|
|
1282
1285
|
onClick: applyGlobalSearch,
|
|
1283
|
-
className: "absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-lg hover:bg-gray-100",
|
|
1286
|
+
className: "absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800",
|
|
1284
1287
|
title: "Search",
|
|
1285
1288
|
children: jsx(Search, {
|
|
1286
1289
|
className: "h-4 w-4 text-primary-400"
|
|
@@ -1291,7 +1294,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1291
1294
|
setSearchInput("");
|
|
1292
1295
|
handleFilter("global", "");
|
|
1293
1296
|
},
|
|
1294
|
-
className: "whitespace-nowrap rounded-lg md:rounded-md border border-gray-300 px-4 py-3 md:py-2 text-sm hover:bg-gray-100 w-full sm:w-auto",
|
|
1297
|
+
className: "whitespace-nowrap rounded-lg md:rounded-md border border-gray-300 px-4 py-3 md:py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-800 w-full sm:w-auto",
|
|
1295
1298
|
children: "Clear"
|
|
1296
1299
|
})]
|
|
1297
1300
|
})
|
|
@@ -1315,7 +1318,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1315
1318
|
}), !isMobileView && jsx("div", {
|
|
1316
1319
|
className: "overflow-x-auto overflow-y-visible",
|
|
1317
1320
|
children: jsxs("table", _objectSpread2(_objectSpread2({
|
|
1318
|
-
className: cn("min-w-full divide-y divide-
|
|
1321
|
+
className: cn("min-w-full divide-y divide-line", className)
|
|
1319
1322
|
}, props), {}, {
|
|
1320
1323
|
children: [jsxs("thead", {
|
|
1321
1324
|
className: safeTheme.accentColor,
|
|
@@ -1323,7 +1326,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1323
1326
|
children: [hasDetailsColumn && jsx("th", {
|
|
1324
1327
|
className: "w-8 px-4 py-3"
|
|
1325
1328
|
}), showSerial && jsx("th", {
|
|
1326
|
-
className: "w-8 px-4 py-3 text-left text-xs font-medium text-primary-
|
|
1329
|
+
className: "w-8 px-4 py-3 text-left text-xs font-medium text-primary-700 uppercase tracking-wider",
|
|
1327
1330
|
children: "#"
|
|
1328
1331
|
}), selectable && jsx("th", {
|
|
1329
1332
|
className: "w-12 px-6 py-3",
|
|
@@ -1336,8 +1339,8 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1336
1339
|
}), visibleColumns.map(function (column) {
|
|
1337
1340
|
var _column$rules;
|
|
1338
1341
|
return jsx("th", {
|
|
1339
|
-
className: cn("px-6 py-3 text-left text-xs font-medium text-primary-
|
|
1340
|
-
"cursor-pointer hover:bg-gray-100": sortable && column.sortable !== false
|
|
1342
|
+
className: cn("px-6 py-3 text-left text-xs font-medium text-primary-700 uppercase tracking-wider", {
|
|
1343
|
+
"cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800": sortable && column.sortable !== false
|
|
1341
1344
|
}),
|
|
1342
1345
|
onClick: function onClick() {
|
|
1343
1346
|
return column.sortable !== false && handleSort(column.key);
|
|
@@ -1381,7 +1384,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1381
1384
|
return !s;
|
|
1382
1385
|
});
|
|
1383
1386
|
},
|
|
1384
|
-
className: "p-1 rounded hover:bg-gray-100",
|
|
1387
|
+
className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800",
|
|
1385
1388
|
children: jsx(MoreVertical, {
|
|
1386
1389
|
className: "h-4 w-4"
|
|
1387
1390
|
})
|
|
@@ -1417,7 +1420,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1417
1420
|
})]
|
|
1418
1421
|
})]
|
|
1419
1422
|
}), jsx("tbody", {
|
|
1420
|
-
className: "divide-y divide-
|
|
1423
|
+
className: "divide-y divide-line",
|
|
1421
1424
|
children: loading ? jsx("tr", {
|
|
1422
1425
|
children: jsx("td", {
|
|
1423
1426
|
colSpan: visibleCount,
|
|
@@ -1427,7 +1430,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1427
1430
|
children: [jsx("div", {
|
|
1428
1431
|
className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
|
|
1429
1432
|
}), jsx("span", {
|
|
1430
|
-
className: "text-sm text-
|
|
1433
|
+
className: "text-sm text-muted",
|
|
1431
1434
|
children: "Loading..."
|
|
1432
1435
|
})]
|
|
1433
1436
|
})
|
|
@@ -1445,7 +1448,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1445
1448
|
className: "h-8 w-8"
|
|
1446
1449
|
})
|
|
1447
1450
|
}), jsx("span", {
|
|
1448
|
-
className: "text-sm text-
|
|
1451
|
+
className: "text-sm text-muted",
|
|
1449
1452
|
children: "No results found."
|
|
1450
1453
|
})]
|
|
1451
1454
|
})
|
|
@@ -1490,7 +1493,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1490
1493
|
children: [jsx("div", {
|
|
1491
1494
|
className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
|
|
1492
1495
|
}), jsx("span", {
|
|
1493
|
-
className: "text-sm text-
|
|
1496
|
+
className: "text-sm text-muted",
|
|
1494
1497
|
children: "Loading..."
|
|
1495
1498
|
})]
|
|
1496
1499
|
})
|
|
@@ -1504,7 +1507,7 @@ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
|
|
|
1504
1507
|
className: "h-8 w-8"
|
|
1505
1508
|
})
|
|
1506
1509
|
}), jsx("span", {
|
|
1507
|
-
className: "text-sm text-
|
|
1510
|
+
className: "text-sm text-muted",
|
|
1508
1511
|
children: "No results found."
|
|
1509
1512
|
})]
|
|
1510
1513
|
})
|