@dreamtree-org/twreact-ui 2.0.3 → 2.0.5
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 +17 -6
- package/ai-skills/dreamtree-ui.md +12 -5
- package/dist/ai-schema.json +150 -1
- package/dist/charts/index.d.ts +2 -1
- package/dist/charts/index.js +297 -12
- package/dist/components/charts/ChartFrame.d.ts +1 -0
- package/dist/components/charts/ChartFrame.d.ts.map +1 -1
- package/dist/components/charts/ScatterChart.d.ts +4 -0
- package/dist/components/charts/ScatterChart.d.ts.map +1 -0
- package/dist/components/charts/ScatterTooltip.d.ts +14 -0
- package/dist/components/charts/ScatterTooltip.d.ts.map +1 -0
- package/dist/components/charts/scatterData.d.ts +17 -0
- package/dist/components/charts/scatterData.d.ts.map +1 -0
- package/dist/components/core/DatePicker.d.ts.map +1 -1
- package/dist/components/core/DateRangePicker.d.ts.map +1 -1
- package/dist/components/core/Select.d.ts.map +1 -1
- package/dist/components/navigation/Navbar.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts +2 -0
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/utility/Sortable.d.ts.map +1 -1
- package/dist/components/utility/SortableGroup.d.ts +15 -0
- package/dist/components/utility/SortableGroup.d.ts.map +1 -0
- package/dist/esm/charts/index.js +1 -0
- package/dist/esm/components/charts/ChartFrame.js +5 -5
- package/dist/esm/components/charts/ScatterChart.js +204 -0
- package/dist/esm/components/charts/ScatterTooltip.js +61 -0
- package/dist/esm/components/charts/scatterData.js +43 -0
- package/dist/esm/components/core/DatePicker.js +4 -1
- package/dist/esm/components/core/DateRangePicker.js +6 -2
- package/dist/esm/components/core/Select.js +6 -2
- package/dist/esm/components/navigation/Navbar.js +23 -6
- package/dist/esm/components/navigation/Sidebar.js +9 -2
- package/dist/esm/components/utility/Sortable.js +70 -48
- package/dist/esm/components/utility/SortableGroup.js +48 -0
- package/dist/esm/hooks/useFocusTrap.js +21 -9
- package/dist/esm/hooks/useSortable.js +96 -30
- package/dist/esm/hooks/useSortableGroup.js +268 -0
- package/dist/esm/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useSortable.d.ts +12 -3
- package/dist/hooks/useSortable.d.ts.map +1 -1
- package/dist/hooks/useSortableGroup.d.ts +43 -0
- package/dist/hooks/useSortableGroup.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +936 -498
- package/dist/index.js +936 -497
- package/dist/types/charts.d.ts +28 -0
- package/dist/types/charts.d.ts.map +1 -1
- package/dist/types/index.d.ts +40 -1
- package/dist/types/index.d.ts.map +1 -1
- package/doc/README.md +2 -0
- package/mcp/catalog.snapshot.json +252 -14
- package/package.json +1 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2, toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { ResponsiveContainer, ScatterChart as ScatterChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Scatter } from 'recharts';
|
|
6
|
+
import { ChartFrame } from './ChartFrame.js';
|
|
7
|
+
import ScatterTooltipContent from './ScatterTooltip.js';
|
|
8
|
+
import { useChartTheme, useChartId, defaultValueFormatter } from './chartTheme.js';
|
|
9
|
+
import { useElementWidth, tickGapFor, yAxisWidthFor } from './useChartLayout.js';
|
|
10
|
+
import { groupScatter, scatterDomain, textOf } from './scatterData.js';
|
|
11
|
+
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
|
|
12
|
+
|
|
13
|
+
var _excluded = ["data", "x", "y", "index", "category", "colors", "valueFormatter", "xAxisFormatter", "xAxisLabel", "yAxisLabel", "height", "aspectRatio", "showLegend", "showTooltip", "showXAxis", "showYAxis", "showGrid", "yAxisWidth", "animate", "title", "description", "emptyState", "accessibleTable", "className"];
|
|
14
|
+
var ScatterChart = /*#__PURE__*/React.forwardRef(function ScatterChart(_ref, ref) {
|
|
15
|
+
var data = _ref.data,
|
|
16
|
+
x = _ref.x,
|
|
17
|
+
y = _ref.y,
|
|
18
|
+
index = _ref.index,
|
|
19
|
+
category = _ref.category,
|
|
20
|
+
colors = _ref.colors,
|
|
21
|
+
_ref$valueFormatter = _ref.valueFormatter,
|
|
22
|
+
valueFormatter = _ref$valueFormatter === void 0 ? defaultValueFormatter : _ref$valueFormatter,
|
|
23
|
+
_ref$xAxisFormatter = _ref.xAxisFormatter,
|
|
24
|
+
xAxisFormatter = _ref$xAxisFormatter === void 0 ? defaultValueFormatter : _ref$xAxisFormatter,
|
|
25
|
+
xAxisLabel = _ref.xAxisLabel,
|
|
26
|
+
yAxisLabel = _ref.yAxisLabel,
|
|
27
|
+
_ref$height = _ref.height,
|
|
28
|
+
height = _ref$height === void 0 ? 300 : _ref$height,
|
|
29
|
+
aspectRatio = _ref.aspectRatio,
|
|
30
|
+
_ref$showLegend = _ref.showLegend,
|
|
31
|
+
showLegend = _ref$showLegend === void 0 ? true : _ref$showLegend,
|
|
32
|
+
_ref$showTooltip = _ref.showTooltip,
|
|
33
|
+
showTooltip = _ref$showTooltip === void 0 ? true : _ref$showTooltip,
|
|
34
|
+
_ref$showXAxis = _ref.showXAxis,
|
|
35
|
+
showXAxis = _ref$showXAxis === void 0 ? true : _ref$showXAxis,
|
|
36
|
+
_ref$showYAxis = _ref.showYAxis,
|
|
37
|
+
showYAxis = _ref$showYAxis === void 0 ? true : _ref$showYAxis,
|
|
38
|
+
_ref$showGrid = _ref.showGrid,
|
|
39
|
+
showGrid = _ref$showGrid === void 0 ? true : _ref$showGrid,
|
|
40
|
+
yAxisWidth = _ref.yAxisWidth,
|
|
41
|
+
_ref$animate = _ref.animate,
|
|
42
|
+
animate = _ref$animate === void 0 ? true : _ref$animate,
|
|
43
|
+
title = _ref.title,
|
|
44
|
+
description = _ref.description,
|
|
45
|
+
emptyState = _ref.emptyState,
|
|
46
|
+
_ref$accessibleTable = _ref.accessibleTable,
|
|
47
|
+
accessibleTable = _ref$accessibleTable === void 0 ? true : _ref$accessibleTable,
|
|
48
|
+
className = _ref.className,
|
|
49
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
50
|
+
var _groupScatter = groupScatter(data, {
|
|
51
|
+
x: x,
|
|
52
|
+
y: y,
|
|
53
|
+
category: category
|
|
54
|
+
}),
|
|
55
|
+
rows = _groupScatter.rows,
|
|
56
|
+
names = _groupScatter.names,
|
|
57
|
+
groups = _groupScatter.groups;
|
|
58
|
+
var _useChartTheme = useChartTheme(names, colors),
|
|
59
|
+
chrome = _useChartTheme.chrome,
|
|
60
|
+
series = _useChartTheme.series;
|
|
61
|
+
var reducedMotion = useReducedMotion();
|
|
62
|
+
var chartId = useChartId();
|
|
63
|
+
var _useElementWidth = useElementWidth(),
|
|
64
|
+
_useElementWidth2 = _slicedToArray(_useElementWidth, 2),
|
|
65
|
+
measureRef = _useElementWidth2[0],
|
|
66
|
+
width = _useElementWidth2[1];
|
|
67
|
+
var tick = {
|
|
68
|
+
fill: chrome.axis,
|
|
69
|
+
fontSize: 12
|
|
70
|
+
};
|
|
71
|
+
var axisTitle = function axisTitle(value, angle) {
|
|
72
|
+
return value ? {
|
|
73
|
+
value: value,
|
|
74
|
+
angle: angle,
|
|
75
|
+
position: angle ? "insideLeft" : "insideBottom",
|
|
76
|
+
offset: angle ? 10 : -4,
|
|
77
|
+
fill: chrome.axis,
|
|
78
|
+
fontSize: 12
|
|
79
|
+
} : undefined;
|
|
80
|
+
};
|
|
81
|
+
var xLabel = xAxisLabel || x;
|
|
82
|
+
var yLabel = yAxisLabel || y;
|
|
83
|
+
return jsx(ChartFrame, _objectSpread2(_objectSpread2({
|
|
84
|
+
ref: ref,
|
|
85
|
+
className: className,
|
|
86
|
+
title: title,
|
|
87
|
+
description: description,
|
|
88
|
+
defaultTitle: "Scatter chart",
|
|
89
|
+
data: rows,
|
|
90
|
+
height: height,
|
|
91
|
+
aspectRatio: aspectRatio,
|
|
92
|
+
emptyState: emptyState,
|
|
93
|
+
accessibleTable: accessibleTable,
|
|
94
|
+
legend: showLegend && category ? names.map(function (name, i) {
|
|
95
|
+
return {
|
|
96
|
+
name: name,
|
|
97
|
+
color: series[i]
|
|
98
|
+
};
|
|
99
|
+
}) : null,
|
|
100
|
+
tableColumns: [].concat(_toConsumableArray(index ? [{
|
|
101
|
+
key: index,
|
|
102
|
+
label: index,
|
|
103
|
+
format: textOf
|
|
104
|
+
}] : []), _toConsumableArray(category && category !== index ? [{
|
|
105
|
+
key: category,
|
|
106
|
+
label: category,
|
|
107
|
+
format: textOf
|
|
108
|
+
}] : []), [{
|
|
109
|
+
key: x,
|
|
110
|
+
label: xLabel,
|
|
111
|
+
format: xAxisFormatter
|
|
112
|
+
}, {
|
|
113
|
+
key: y,
|
|
114
|
+
label: yLabel,
|
|
115
|
+
format: valueFormatter
|
|
116
|
+
}])
|
|
117
|
+
}, rest), {}, {
|
|
118
|
+
children: jsx("div", {
|
|
119
|
+
className: "h-full w-full",
|
|
120
|
+
ref: measureRef,
|
|
121
|
+
children: jsx(ResponsiveContainer, {
|
|
122
|
+
width: "100%",
|
|
123
|
+
height: "100%",
|
|
124
|
+
minWidth: 0,
|
|
125
|
+
children: jsxs(ScatterChart$1, {
|
|
126
|
+
id: chartId,
|
|
127
|
+
margin: {
|
|
128
|
+
top: 8,
|
|
129
|
+
right: 8,
|
|
130
|
+
bottom: xAxisLabel ? 16 : 0,
|
|
131
|
+
left: 0
|
|
132
|
+
},
|
|
133
|
+
accessibilityLayer: false,
|
|
134
|
+
children: [showGrid && jsx(CartesianGrid, {
|
|
135
|
+
stroke: chrome.grid,
|
|
136
|
+
strokeDasharray: "3 3"
|
|
137
|
+
}), jsx(XAxis, {
|
|
138
|
+
type: "number",
|
|
139
|
+
dataKey: x,
|
|
140
|
+
name: xLabel,
|
|
141
|
+
domain: scatterDomain(rows.map(function (row) {
|
|
142
|
+
return row[x];
|
|
143
|
+
})),
|
|
144
|
+
tick: tick,
|
|
145
|
+
tickLine: false,
|
|
146
|
+
axisLine: false,
|
|
147
|
+
tickFormatter: xAxisFormatter,
|
|
148
|
+
minTickGap: tickGapFor(width),
|
|
149
|
+
hide: !showXAxis,
|
|
150
|
+
label: axisTitle(xAxisLabel, 0)
|
|
151
|
+
}), jsx(YAxis, {
|
|
152
|
+
type: "number",
|
|
153
|
+
dataKey: y,
|
|
154
|
+
name: yLabel,
|
|
155
|
+
domain: scatterDomain(rows.map(function (row) {
|
|
156
|
+
return row[y];
|
|
157
|
+
})),
|
|
158
|
+
tick: tick,
|
|
159
|
+
tickLine: false,
|
|
160
|
+
axisLine: false,
|
|
161
|
+
tickFormatter: valueFormatter,
|
|
162
|
+
width: yAxisWidth !== null && yAxisWidth !== void 0 ? yAxisWidth : yAxisWidthFor(width),
|
|
163
|
+
hide: !showYAxis,
|
|
164
|
+
label: axisTitle(yAxisLabel, -90)
|
|
165
|
+
}), showTooltip && jsx(Tooltip, {
|
|
166
|
+
cursor: {
|
|
167
|
+
stroke: chrome.grid,
|
|
168
|
+
strokeDasharray: "3 3"
|
|
169
|
+
},
|
|
170
|
+
isAnimationActive: false,
|
|
171
|
+
content: jsx(ScatterTooltipContent, {
|
|
172
|
+
index: index,
|
|
173
|
+
category: category,
|
|
174
|
+
colorFor: Object.fromEntries(names.map(function (name, i) {
|
|
175
|
+
return [name, series[i]];
|
|
176
|
+
})),
|
|
177
|
+
x: {
|
|
178
|
+
key: x,
|
|
179
|
+
label: xLabel,
|
|
180
|
+
format: xAxisFormatter
|
|
181
|
+
},
|
|
182
|
+
y: {
|
|
183
|
+
key: y,
|
|
184
|
+
label: yLabel,
|
|
185
|
+
format: valueFormatter
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
}), names.map(function (name, i) {
|
|
189
|
+
return jsx(Scatter, {
|
|
190
|
+
id: "".concat(chartId, "-").concat(i),
|
|
191
|
+
name: name,
|
|
192
|
+
data: groups.get(name),
|
|
193
|
+
fill: series[i],
|
|
194
|
+
isAnimationActive: animate && !reducedMotion
|
|
195
|
+
}, name);
|
|
196
|
+
})]
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
}));
|
|
201
|
+
});
|
|
202
|
+
ScatterChart.displayName = "ScatterChart";
|
|
203
|
+
|
|
204
|
+
export { ScatterChart as default };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { toConsumableArray as _toConsumableArray, slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import { swatch } from './ChartFrame.js';
|
|
6
|
+
import { textOf } from './scatterData.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Tooltip for one ScatterChart point: the entity (`index`) or series name as the
|
|
10
|
+
* heading, then the series (when both are set) and the formatted x and y values.
|
|
11
|
+
*/
|
|
12
|
+
function ScatterTooltipContent(_ref) {
|
|
13
|
+
var active = _ref.active,
|
|
14
|
+
payload = _ref.payload,
|
|
15
|
+
index = _ref.index,
|
|
16
|
+
category = _ref.category,
|
|
17
|
+
_ref$colorFor = _ref.colorFor,
|
|
18
|
+
colorFor = _ref$colorFor === void 0 ? {} : _ref$colorFor,
|
|
19
|
+
x = _ref.x,
|
|
20
|
+
y = _ref.y;
|
|
21
|
+
var row = active && payload && payload.length ? payload[0].payload : null;
|
|
22
|
+
if (!row) return null;
|
|
23
|
+
var seriesName = category ? textOf(row[category]) : null;
|
|
24
|
+
var heading = index ? textOf(row[index]) : seriesName;
|
|
25
|
+
var lines = [].concat(_toConsumableArray(index && seriesName ? [[category, seriesName]] : []), [[x.label, x.format(row[x.key])], [y.label, y.format(row[y.key])]]);
|
|
26
|
+
return jsxs("div", {
|
|
27
|
+
className: "rounded-md border border-line bg-surface px-3 py-2 text-xs text-foreground shadow-md",
|
|
28
|
+
"data-chart-tooltip": "",
|
|
29
|
+
children: [heading && jsxs("p", {
|
|
30
|
+
className: "mb-1 flex items-center gap-2 font-medium",
|
|
31
|
+
children: [seriesName && jsx("span", {
|
|
32
|
+
className: swatch("h-2 w-2"),
|
|
33
|
+
style: {
|
|
34
|
+
"--dt-chart-color": colorFor[seriesName]
|
|
35
|
+
},
|
|
36
|
+
"aria-hidden": "true"
|
|
37
|
+
}), jsx("span", {
|
|
38
|
+
children: heading
|
|
39
|
+
})]
|
|
40
|
+
}), jsx("ul", {
|
|
41
|
+
className: "space-y-0.5",
|
|
42
|
+
children: lines.map(function (_ref2) {
|
|
43
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
44
|
+
name = _ref3[0],
|
|
45
|
+
value = _ref3[1];
|
|
46
|
+
return jsxs("li", {
|
|
47
|
+
className: "flex items-center gap-2",
|
|
48
|
+
children: [jsx("span", {
|
|
49
|
+
className: "text-muted",
|
|
50
|
+
children: name
|
|
51
|
+
}), jsx("span", {
|
|
52
|
+
className: "ml-auto pl-3 font-medium tabular-nums",
|
|
53
|
+
children: value
|
|
54
|
+
})]
|
|
55
|
+
}, name);
|
|
56
|
+
})
|
|
57
|
+
})]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { ScatterTooltipContent as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
|
|
3
|
+
// Internal to the charts entry point: data shaping for ScatterChart.
|
|
4
|
+
var isFiniteNumber = function isFiniteNumber(v) {
|
|
5
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
6
|
+
};
|
|
7
|
+
var textOf = function textOf(v) {
|
|
8
|
+
return v == null ? "" : String(v);
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Axis domain. recharts draws a zero-width scale for a single distinct value, so
|
|
12
|
+
* pad around it; otherwise let recharts pick nice bounds.
|
|
13
|
+
*/
|
|
14
|
+
function scatterDomain(values) {
|
|
15
|
+
if (!values.length) return ["auto", "auto"];
|
|
16
|
+
var min = Math.min.apply(Math, _toConsumableArray(values));
|
|
17
|
+
var max = Math.max.apply(Math, _toConsumableArray(values));
|
|
18
|
+
if (min !== max) return ["auto", "auto"];
|
|
19
|
+
var pad = Math.abs(min) / 2 || 1;
|
|
20
|
+
return [min - pad, max + pad];
|
|
21
|
+
}
|
|
22
|
+
/** Rows with a numeric x and y, split into series by the `category` key (first-seen order). */
|
|
23
|
+
function groupScatter(data, _ref) {
|
|
24
|
+
var x = _ref.x,
|
|
25
|
+
y = _ref.y,
|
|
26
|
+
category = _ref.category;
|
|
27
|
+
var rows = (Array.isArray(data) ? data : []).filter(function (row) {
|
|
28
|
+
return isFiniteNumber(row === null || row === void 0 ? void 0 : row[x]) && isFiniteNumber(row === null || row === void 0 ? void 0 : row[y]);
|
|
29
|
+
});
|
|
30
|
+
var groups = new Map();
|
|
31
|
+
rows.forEach(function (row) {
|
|
32
|
+
var name = category ? textOf(row[category]) : y;
|
|
33
|
+
if (!groups.has(name)) groups.set(name, []);
|
|
34
|
+
groups.get(name).push(row);
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
rows: rows,
|
|
38
|
+
names: _toConsumableArray(groups.keys()),
|
|
39
|
+
groups: groups
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { groupScatter, scatterDomain, textOf };
|
|
@@ -210,10 +210,13 @@ var DatePicker = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
|
|
|
210
210
|
"aria-invalid": error ? true : undefined,
|
|
211
211
|
className: cn("flex w-full items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50", {
|
|
212
212
|
"border-error-500 focus:ring-error-500": error,
|
|
213
|
-
|
|
213
|
+
// Empty: the placeholder reads muted, like Input's
|
|
214
|
+
// ::placeholder (#159). `className` still merges last.
|
|
215
|
+
"text-muted": !selected,
|
|
214
216
|
// leave room for the sibling clear button overlaid on the field
|
|
215
217
|
"pr-16": showClear && selected
|
|
216
218
|
}, className),
|
|
219
|
+
"data-empty": selected ? undefined : "",
|
|
217
220
|
onClick: function onClick() {
|
|
218
221
|
return setIsOpen(function (open) {
|
|
219
222
|
return !open;
|
|
@@ -279,7 +279,8 @@ var DateRangePicker = /*#__PURE__*/forwardRef(function DateRangePicker(_ref, ref
|
|
|
279
279
|
}));
|
|
280
280
|
};
|
|
281
281
|
// Display placeholder until both start and end are committed (mandatory range).
|
|
282
|
-
var
|
|
282
|
+
var isEmpty = !committed.start || !committed.end;
|
|
283
|
+
var triggerText = isEmpty ? placeholder : formatRange(committed.start, committed.end);
|
|
283
284
|
var draftText = localStart && localEnd ? formatRange(localStart, localEnd) : placeholder;
|
|
284
285
|
var presetList = Array.isArray(presets) && presets.length > 0 ? presets : null;
|
|
285
286
|
var presetChips = presetList ? jsx("div", {
|
|
@@ -359,9 +360,12 @@ var DateRangePicker = /*#__PURE__*/forwardRef(function DateRangePicker(_ref, ref
|
|
|
359
360
|
"aria-invalid": error ? true : undefined,
|
|
360
361
|
className: cn("flex w-full items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50", {
|
|
361
362
|
"border-error-500 focus:ring-error-500": error,
|
|
362
|
-
|
|
363
|
+
// Empty: the placeholder reads muted, like Input's
|
|
364
|
+
// ::placeholder (#159). `className` still merges last.
|
|
365
|
+
"text-muted": isEmpty,
|
|
363
366
|
"pr-16": showClearButton
|
|
364
367
|
}, className),
|
|
368
|
+
"data-empty": isEmpty ? "" : undefined,
|
|
365
369
|
onClick: function onClick() {
|
|
366
370
|
// The trigger always toggles, even mid-pick (DTUI-35): closing
|
|
367
371
|
// drops the uncommitted start, reopening starts from the last
|
|
@@ -495,7 +495,8 @@ var Select = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
|
|
|
495
495
|
return document.removeEventListener("mousedown", handleClickOutside);
|
|
496
496
|
};
|
|
497
497
|
}, []);
|
|
498
|
-
var
|
|
498
|
+
var isEmpty = selectedOptions.length === 0;
|
|
499
|
+
var showClearButton = allowClear && !disabled && !isEmpty;
|
|
499
500
|
var displayValue = function displayValue() {
|
|
500
501
|
var _selectedOptions$;
|
|
501
502
|
if (multiSelect) {
|
|
@@ -753,9 +754,12 @@ var Select = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
|
|
|
753
754
|
"aria-invalid": error ? true : undefined,
|
|
754
755
|
className: cn("flex w-full items-center justify-between rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50", SIZE_CLASSES[size] || SIZE_CLASSES.md, {
|
|
755
756
|
"border-error-500 focus:ring-error-500": error,
|
|
756
|
-
|
|
757
|
+
// Empty: the placeholder reads muted, like Input's
|
|
758
|
+
// ::placeholder (#159). `className` still merges last.
|
|
759
|
+
"text-muted": isEmpty,
|
|
757
760
|
"pr-14": showClearButton
|
|
758
761
|
}, className),
|
|
762
|
+
"data-empty": isEmpty ? "" : undefined,
|
|
759
763
|
onClick: function onClick() {
|
|
760
764
|
if (!disabled) {
|
|
761
765
|
setIsOpen(function (prev) {
|
|
@@ -12,7 +12,8 @@ import { TOUCH_TARGET } from '../../utils/touchTarget.js';
|
|
|
12
12
|
import PropTypes from '../../_vendor/prop-types/index.js';
|
|
13
13
|
|
|
14
14
|
var _excluded = ["emitter", "content", "notifications"],
|
|
15
|
-
_excluded2 = ["emitter", "logo", "center", "items", "user", "notifications", "searchable", "onSearch", "leftIcon", "rightMenuContent", "onLeftIconClick", "onLoginClick", "onLogoutClick", "className", "onFetch", "isMobileOpen", "setIsMobileOpen", "sticky", "largeTitle"]
|
|
15
|
+
_excluded2 = ["emitter", "logo", "center", "items", "user", "notifications", "searchable", "onSearch", "leftIcon", "rightMenuContent", "onLeftIconClick", "leftIconLabel", "leftIconProps", "onLoginClick", "onLogoutClick", "className", "onFetch", "isMobileOpen", "setIsMobileOpen", "sticky", "largeTitle"],
|
|
16
|
+
_excluded3 = ["className", "onClick"];
|
|
16
17
|
var NO_NOTIFICATIONS = [];
|
|
17
18
|
// Icon-only bar buttons: 36px on desktop, the 44px touch target on coarse pointers.
|
|
18
19
|
var ICON_BUTTON = cn("inline-flex items-center justify-center rounded-md p-2 text-primary-400 hover:text-primary-500 hover:bg-gray-100 dark:hover:bg-gray-800", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500", TOUCH_TARGET);
|
|
@@ -241,6 +242,9 @@ var Navbar = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
|
241
242
|
leftIcon = _ref3$leftIcon === void 0 ? jsx(ChevronLeft, {}) : _ref3$leftIcon,
|
|
242
243
|
RightMenuContentProp = _ref3.rightMenuContent,
|
|
243
244
|
onLeftIconClick = _ref3.onLeftIconClick,
|
|
245
|
+
_ref3$leftIconLabel = _ref3.leftIconLabel,
|
|
246
|
+
leftIconLabel = _ref3$leftIconLabel === void 0 ? "Go back" : _ref3$leftIconLabel,
|
|
247
|
+
leftIconProps = _ref3.leftIconProps,
|
|
244
248
|
_ref3$onLoginClick = _ref3.onLoginClick,
|
|
245
249
|
onLoginClick = _ref3$onLoginClick === void 0 ? function () {
|
|
246
250
|
return console.log("invoked onLoginClick");
|
|
@@ -287,6 +291,18 @@ var Navbar = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
|
287
291
|
window.removeEventListener("resize", handleResize);
|
|
288
292
|
};
|
|
289
293
|
}, [handleResize]);
|
|
294
|
+
// Left button: `leftIconLabel` names it ("Go back" by default; e.g. "Open
|
|
295
|
+
// menu" when it opens a Sidebar drawer). `leftIconProps` lands on the
|
|
296
|
+
// <button> (aria-expanded, aria-controls, data-*, …); its className merges
|
|
297
|
+
// last and its onClick runs after `onLeftIconClick`.
|
|
298
|
+
var _ref4 = leftIconProps || {},
|
|
299
|
+
leftIconClassName = _ref4.className,
|
|
300
|
+
leftIconOnClick = _ref4.onClick,
|
|
301
|
+
leftIconRest = _objectWithoutProperties(_ref4, _excluded3);
|
|
302
|
+
var handleLeftIconClick = function handleLeftIconClick(e) {
|
|
303
|
+
onLeftIconClick === null || onLeftIconClick === void 0 || onLeftIconClick(e);
|
|
304
|
+
leftIconOnClick === null || leftIconOnClick === void 0 || leftIconOnClick(e);
|
|
305
|
+
};
|
|
290
306
|
// Handle search submit
|
|
291
307
|
var handleSearch = function handleSearch(e) {
|
|
292
308
|
e.preventDefault();
|
|
@@ -356,13 +372,14 @@ var Navbar = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
|
356
372
|
"aria-hidden": true
|
|
357
373
|
}), jsxs("div", {
|
|
358
374
|
className: "flex min-w-0 items-center",
|
|
359
|
-
children: [leftIcon !== false && jsx("button", {
|
|
360
|
-
onClick: onLeftIconClick,
|
|
375
|
+
children: [leftIcon !== false && jsx("button", _objectSpread2(_objectSpread2({
|
|
361
376
|
type: "button",
|
|
362
|
-
|
|
363
|
-
|
|
377
|
+
"aria-label": leftIconLabel
|
|
378
|
+
}, leftIconRest), {}, {
|
|
379
|
+
onClick: handleLeftIconClick,
|
|
380
|
+
className: cn(ICON_BUTTON, "shrink-0 md:hidden", leftIconClassName),
|
|
364
381
|
children: leftIcon
|
|
365
|
-
}), logo && jsx("div", {
|
|
382
|
+
})), logo && jsx("div", {
|
|
366
383
|
className: "ml-2 min-w-0 truncate sm:ml-4 md:ml-0",
|
|
367
384
|
children: logo
|
|
368
385
|
})]
|
|
@@ -11,7 +11,7 @@ import { useScrollLock } from '../../hooks/useScrollLock.js';
|
|
|
11
11
|
import { useMediaQuery } from '../../hooks/useMediaQuery.js';
|
|
12
12
|
import { useSheetDrag, FLICK_VELOCITY } from '../../hooks/useSheetDrag.js';
|
|
13
13
|
|
|
14
|
-
var _excluded = ["items", "collapsed", "onToggle", "className", "containerClassName", "stickyOffset", "logo", "footer", "user", "onUserClick", "drawerPosition", "isMobileOpen", "setIsMobileOpen", "showCollapsedTooltips", "tooltipOptions", "linkAs", "expandedIds", "defaultExpandedIds", "onExpandedChange", "swipeable"];
|
|
14
|
+
var _excluded = ["items", "collapsed", "collapsible", "onToggle", "className", "containerClassName", "stickyOffset", "logo", "footer", "user", "onUserClick", "drawerPosition", "isMobileOpen", "setIsMobileOpen", "showCollapsedTooltips", "tooltipOptions", "linkAs", "expandedIds", "defaultExpandedIds", "onExpandedChange", "swipeable"];
|
|
15
15
|
// From `md` up the sidebar is an in-flow sticky column; below it, the same
|
|
16
16
|
// tree becomes an off-canvas drawer (modal dialog while open).
|
|
17
17
|
var SIDEBAR_DESKTOP_QUERY = "(min-width: 768px)";
|
|
@@ -178,6 +178,8 @@ var hasBadge = function hasBadge(item) {
|
|
|
178
178
|
* - linkAs: element type used for items with `href` (default "a"; pass Next.js Link etc.)
|
|
179
179
|
* - collapsed: boolean (desktop collapsed)
|
|
180
180
|
* - onToggle: function to toggle collapse
|
|
181
|
+
* - collapsible: boolean (default true) — false hides the md+ collapse/expand
|
|
182
|
+
* toggle (the drawer keeps its "Close navigation" button)
|
|
181
183
|
* - expandedIds / defaultExpandedIds / onExpandedChange: open groups (ids)
|
|
182
184
|
* - className, containerClassName, stickyOffset, logo, footer, user, onUserClick
|
|
183
185
|
* - drawerPosition: 'left' | 'right'
|
|
@@ -194,6 +196,8 @@ var Sidebar = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
194
196
|
items = _ref2$items === void 0 ? [] : _ref2$items,
|
|
195
197
|
_ref2$collapsed = _ref2.collapsed,
|
|
196
198
|
collapsed = _ref2$collapsed === void 0 ? false : _ref2$collapsed,
|
|
199
|
+
_ref2$collapsible = _ref2.collapsible,
|
|
200
|
+
collapsible = _ref2$collapsible === void 0 ? true : _ref2$collapsible,
|
|
197
201
|
onToggle = _ref2.onToggle,
|
|
198
202
|
className = _ref2.className,
|
|
199
203
|
containerClassName = _ref2.containerClassName,
|
|
@@ -525,6 +529,9 @@ var Sidebar = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
525
529
|
if (drawerMode && mobileOpen && setIsMobileOpen) setIsMobileOpen(false);else onToggle === null || onToggle === void 0 || onToggle();
|
|
526
530
|
};
|
|
527
531
|
var toggleLabel = drawerMode ? "Close navigation" : effectiveCollapsed ? "Expand sidebar" : "Collapse sidebar";
|
|
532
|
+
// `collapsible={false}`: no collapse/expand toggle on md+. The drawer keeps
|
|
533
|
+
// its close button (44px touch target, the drawer's only visible close).
|
|
534
|
+
var showToggle = drawerMode || collapsible;
|
|
528
535
|
var CloseChevron = isRight ? ChevronRight : ChevronLeft;
|
|
529
536
|
var toggleIcon = drawerMode ? jsx(CloseChevron, {
|
|
530
537
|
className: "h-5 w-5",
|
|
@@ -591,7 +598,7 @@ var Sidebar = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
591
598
|
children: [!effectiveCollapsed && logo && jsx("div", {
|
|
592
599
|
className: "flex min-w-0 items-center",
|
|
593
600
|
children: logo
|
|
594
|
-
}), jsx("button", {
|
|
601
|
+
}), showToggle && jsx("button", {
|
|
595
602
|
type: "button",
|
|
596
603
|
onClick: handleToggleClick,
|
|
597
604
|
className: cn("inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-md", "hover:bg-gray-100 dark:hover:bg-gray-800", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500"),
|