@ceebee/ui 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +603 -10
- package/dist/client.js +2352 -148
- package/dist/index.d.ts +325 -4
- package/dist/index.js +596 -21
- package/dist/styles.css +2281 -116
- package/package.json +13 -10
package/dist/client.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, forwardRef, useContext, useMemo, useState, useRef, useEffect, useCallback,
|
|
3
|
-
import { jsxs, jsx, Fragment
|
|
2
|
+
import { createContext, forwardRef, useContext, useMemo, useId, useState, useRef, useEffect, useCallback, Children, isValidElement, Fragment as Fragment$1, cloneElement, useReducer } from 'react';
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { motion } from 'motion/react';
|
|
5
5
|
import { Select as Select$1 } from '@base-ui/react/select';
|
|
6
|
-
import {
|
|
6
|
+
import { ChevronsUpDown, ChevronDown, ChevronRight, AlertTriangle, ChevronLeft, ZoomOut, RotateCcw, ZoomIn, X, XCircle, CheckCircle2, Info, Check, Minus, CalendarDays, Clock, Upload as Upload$1, Plus, Search, Star, PanelLeftOpen, PanelLeftClose, ArrowUp, ArrowDown } from 'lucide-react';
|
|
7
7
|
import { Checkbox as Checkbox$1 } from '@base-ui/react/checkbox';
|
|
8
8
|
import { Radio } from '@base-ui/react/radio';
|
|
9
9
|
import { RadioGroup as RadioGroup$1 } from '@base-ui/react/radio-group';
|
|
10
10
|
import { Switch as Switch$1 } from '@base-ui/react/switch';
|
|
11
11
|
import { Combobox } from '@base-ui/react/combobox';
|
|
12
12
|
import { Popover as Popover$1 } from '@base-ui/react/popover';
|
|
13
|
+
import { Slider as Slider$1 } from '@base-ui/react/slider';
|
|
13
14
|
import { Dialog } from '@base-ui/react/dialog';
|
|
14
15
|
import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
|
|
15
16
|
import { Toast } from '@base-ui/react/toast';
|
|
16
17
|
import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
|
|
17
|
-
import { Menu } from '@base-ui/react/menu';
|
|
18
|
+
import { Menu as Menu$1 } from '@base-ui/react/menu';
|
|
19
|
+
import { Accordion } from '@base-ui/react/accordion';
|
|
18
20
|
import useEmblaCarousel from 'embla-carousel-react';
|
|
19
21
|
|
|
20
22
|
var DEFAULT_LABELS = {
|
|
@@ -184,6 +186,48 @@ var Button = forwardRef(function Button2({
|
|
|
184
186
|
}
|
|
185
187
|
);
|
|
186
188
|
});
|
|
189
|
+
var FloatButton = forwardRef(function FloatButton2({
|
|
190
|
+
label,
|
|
191
|
+
visibleLabel = false,
|
|
192
|
+
icon,
|
|
193
|
+
tone = "brand",
|
|
194
|
+
size = "md",
|
|
195
|
+
placement = "bottom-end",
|
|
196
|
+
type = "button",
|
|
197
|
+
"aria-label": _ariaLabel,
|
|
198
|
+
"aria-labelledby": _ariaLabelledBy,
|
|
199
|
+
style: _style,
|
|
200
|
+
...rest
|
|
201
|
+
}, ref) {
|
|
202
|
+
const {
|
|
203
|
+
className: _className,
|
|
204
|
+
role: _role,
|
|
205
|
+
color: _color,
|
|
206
|
+
children: _children,
|
|
207
|
+
"data-tone": _dataTone,
|
|
208
|
+
...safeRest
|
|
209
|
+
} = rest;
|
|
210
|
+
return /* @__PURE__ */ jsxs(
|
|
211
|
+
"button",
|
|
212
|
+
{
|
|
213
|
+
ref,
|
|
214
|
+
type,
|
|
215
|
+
...safeRest,
|
|
216
|
+
className: cn(
|
|
217
|
+
"cb-float-button",
|
|
218
|
+
`cb-float-button--${size}`,
|
|
219
|
+
`cb-float-button--${placement}`,
|
|
220
|
+
visibleLabel && "cb-float-button--label-visible"
|
|
221
|
+
),
|
|
222
|
+
"data-tone": tone,
|
|
223
|
+
"aria-label": label,
|
|
224
|
+
children: [
|
|
225
|
+
icon ? /* @__PURE__ */ jsx("span", { className: "cb-float-button__icon", "aria-hidden": "true", children: icon }) : null,
|
|
226
|
+
visibleLabel ? /* @__PURE__ */ jsx("span", { className: "cb-float-button__label", children: label }) : null
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
});
|
|
187
231
|
var FieldContext = createContext(null);
|
|
188
232
|
function useFieldWiring() {
|
|
189
233
|
return useContext(FieldContext);
|
|
@@ -456,6 +500,7 @@ function AutoComplete({
|
|
|
456
500
|
const [loading, setLoading] = useState(false);
|
|
457
501
|
const [failed, setFailed] = useState(false);
|
|
458
502
|
const [chosen, setChosen] = useState(null);
|
|
503
|
+
const [open, setOpen] = useState(false);
|
|
459
504
|
const available = async ? loaded : items ?? [];
|
|
460
505
|
const optionFor = (candidate) => {
|
|
461
506
|
if (candidate == null) return null;
|
|
@@ -497,6 +542,17 @@ function AutoComplete({
|
|
|
497
542
|
asked.current += 1;
|
|
498
543
|
inFlight.current?.abort();
|
|
499
544
|
}, []);
|
|
545
|
+
useEffect(() => {
|
|
546
|
+
if (!open) return void 0;
|
|
547
|
+
const onScroll = (event) => {
|
|
548
|
+
const target = event.target;
|
|
549
|
+
if (target === document || target === document.documentElement || target === document.body) {
|
|
550
|
+
setOpen(false);
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
window.addEventListener("scroll", onScroll, { capture: true, passive: true });
|
|
554
|
+
return () => window.removeEventListener("scroll", onScroll, { capture: true });
|
|
555
|
+
}, [open]);
|
|
500
556
|
return /* @__PURE__ */ jsxs(
|
|
501
557
|
Combobox.Root,
|
|
502
558
|
{
|
|
@@ -510,6 +566,9 @@ function AutoComplete({
|
|
|
510
566
|
setChosen(option);
|
|
511
567
|
onValueChange?.(option?.value ?? null);
|
|
512
568
|
},
|
|
569
|
+
modal: true,
|
|
570
|
+
open,
|
|
571
|
+
onOpenChange: setOpen,
|
|
513
572
|
isItemEqualToValue: (a, b) => a?.value === b?.value,
|
|
514
573
|
itemToStringLabel: (item) => typeof item === "string" ? item : item.label,
|
|
515
574
|
disabled,
|
|
@@ -696,32 +755,32 @@ function DatePicker({
|
|
|
696
755
|
side: "bottom",
|
|
697
756
|
align: "start",
|
|
698
757
|
sideOffset: 6,
|
|
699
|
-
className: "cb-calendar__positioner",
|
|
700
|
-
children: /* @__PURE__ */ jsxs(Popover$1.Popup, { className: "cb-calendar", children: [
|
|
701
|
-
/* @__PURE__ */ jsxs("div", { className: "cb-calendar__head", children: [
|
|
758
|
+
className: "cb-date-picker-calendar__positioner",
|
|
759
|
+
children: /* @__PURE__ */ jsxs(Popover$1.Popup, { className: "cb-date-picker-calendar", children: [
|
|
760
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-date-picker-calendar__head", children: [
|
|
702
761
|
/* @__PURE__ */ jsx(
|
|
703
762
|
"button",
|
|
704
763
|
{
|
|
705
764
|
type: "button",
|
|
706
|
-
className: "cb-calendar__nav",
|
|
765
|
+
className: "cb-date-picker-calendar__nav",
|
|
707
766
|
"aria-label": labels.previousMonth,
|
|
708
767
|
onClick: () => setCursor(new Date(cursor.getFullYear(), cursor.getMonth() - 1, 1)),
|
|
709
768
|
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 16 })
|
|
710
769
|
}
|
|
711
770
|
),
|
|
712
|
-
/* @__PURE__ */ jsx("p", { className: "cb-calendar__month", "aria-live": "polite", children: cursor.toLocaleDateString(void 0, { month: "long", year: "numeric" }) }),
|
|
771
|
+
/* @__PURE__ */ jsx("p", { className: "cb-date-picker-calendar__month", "aria-live": "polite", children: cursor.toLocaleDateString(void 0, { month: "long", year: "numeric" }) }),
|
|
713
772
|
/* @__PURE__ */ jsx(
|
|
714
773
|
"button",
|
|
715
774
|
{
|
|
716
775
|
type: "button",
|
|
717
|
-
className: "cb-calendar__nav",
|
|
776
|
+
className: "cb-date-picker-calendar__nav",
|
|
718
777
|
"aria-label": labels.nextMonth,
|
|
719
778
|
onClick: () => setCursor(new Date(cursor.getFullYear(), cursor.getMonth() + 1, 1)),
|
|
720
779
|
children: /* @__PURE__ */ jsx(ChevronRight, { size: 16 })
|
|
721
780
|
}
|
|
722
781
|
)
|
|
723
782
|
] }),
|
|
724
|
-
/* @__PURE__ */ jsxs("table", { className: "cb-calendar__grid", children: [
|
|
783
|
+
/* @__PURE__ */ jsxs("table", { className: "cb-date-picker-calendar__grid", children: [
|
|
725
784
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: weekdays.map((day) => /* @__PURE__ */ jsx("th", { scope: "col", abbr: day, children: day }, day)) }) }),
|
|
726
785
|
/* @__PURE__ */ jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsx("tr", { children: week.map((cell) => {
|
|
727
786
|
const selected = isSameDay(cell.date, current);
|
|
@@ -730,7 +789,7 @@ function DatePicker({
|
|
|
730
789
|
"button",
|
|
731
790
|
{
|
|
732
791
|
type: "button",
|
|
733
|
-
className: "cb-calendar__day",
|
|
792
|
+
className: "cb-date-picker-calendar__day",
|
|
734
793
|
"data-outside": !cell.inMonth || void 0,
|
|
735
794
|
"data-selected": selected || void 0,
|
|
736
795
|
"data-today": isSameDay(cell.date, /* @__PURE__ */ new Date()) || void 0,
|
|
@@ -1146,125 +1205,1280 @@ function InputNumber({
|
|
|
1146
1205
|
function formatValue(value) {
|
|
1147
1206
|
return value === null ? "" : String(value);
|
|
1148
1207
|
}
|
|
1149
|
-
function
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
size
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1208
|
+
function box({ width = "100%", height = "1rem", radius = "md", className }) {
|
|
1209
|
+
const style = { "--cb-skeleton-w": width, "--cb-skeleton-h": height };
|
|
1210
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("cb-skeleton", `cb-radius--${radius}`, className), style });
|
|
1211
|
+
}
|
|
1212
|
+
function text({ lines = 3, lastLineWidth = "62%", className }) {
|
|
1213
|
+
return /* @__PURE__ */ jsx("span", { className: cn("cb-skeleton-text", className), children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx(SkeletonBox, { height: "0.75rem", width: i === lines - 1 ? lastLineWidth : "100%" }, i)) });
|
|
1214
|
+
}
|
|
1215
|
+
function circle({ size = "2.5rem", className }) {
|
|
1216
|
+
return /* @__PURE__ */ jsx(SkeletonBox, { width: size, height: size, radius: "full", className });
|
|
1217
|
+
}
|
|
1218
|
+
var SkeletonBox = box;
|
|
1219
|
+
var Skeleton = Object.assign(box, {
|
|
1220
|
+
Text: text,
|
|
1221
|
+
Circle: circle,
|
|
1222
|
+
Rect: box
|
|
1223
|
+
});
|
|
1224
|
+
function SliderSkeleton({ orientation = "horizontal", range = false, size = "md" }) {
|
|
1225
|
+
return /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: cn("cb-slider", "cb-slider--skeleton", `cb-slider--${size}`, `cb-slider--${orientation}`, range && "cb-slider--range"), children: /* @__PURE__ */ jsxs("div", { className: "cb-slider__control", children: [
|
|
1226
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "cb-slider__track", radius: "full" }),
|
|
1227
|
+
/* @__PURE__ */ jsx(Skeleton.Circle, { className: "cb-slider__thumb", size: "var(--cb-slider-thumb-size)" }),
|
|
1228
|
+
range ? /* @__PURE__ */ jsx(Skeleton.Circle, { className: "cb-slider__thumb", size: "var(--cb-slider-thumb-size)" }) : null
|
|
1229
|
+
] }) });
|
|
1230
|
+
}
|
|
1231
|
+
function SliderComponent(props) {
|
|
1232
|
+
const {
|
|
1233
|
+
label,
|
|
1234
|
+
min = 0,
|
|
1235
|
+
max = 100,
|
|
1236
|
+
step = 1,
|
|
1237
|
+
largeStep,
|
|
1238
|
+
minStepsBetweenValues = 0,
|
|
1239
|
+
motion: motion3 = true,
|
|
1240
|
+
disabled = false,
|
|
1241
|
+
orientation = "horizontal",
|
|
1242
|
+
tone = "brand",
|
|
1243
|
+
size = "md",
|
|
1244
|
+
name,
|
|
1245
|
+
getAriaValueText
|
|
1246
|
+
} = props;
|
|
1247
|
+
const field = useFieldWiring();
|
|
1248
|
+
const range = props.range === true;
|
|
1249
|
+
const value = props.value;
|
|
1250
|
+
const defaultValue = props.defaultValue;
|
|
1251
|
+
validateSlider({ min, max, step, largeStep, minStepsBetweenValues, value, defaultValue, range });
|
|
1252
|
+
const ariaLabel = (index) => {
|
|
1253
|
+
if (!range) return label;
|
|
1254
|
+
return index === 0 ? `Minimum ${label}` : `Maximum ${label}`;
|
|
1255
|
+
};
|
|
1256
|
+
const ariaValueText = getAriaValueText ? (_formattedValue, currentValue, index) => getAriaValueText(currentValue, index) : void 0;
|
|
1257
|
+
const rootClassName = cn(
|
|
1258
|
+
"cb-slider",
|
|
1259
|
+
`cb-slider--${size}`,
|
|
1260
|
+
`cb-slider--${orientation}`,
|
|
1261
|
+
range && "cb-slider--range",
|
|
1262
|
+
!motion3 && "cb-slider--motionless"
|
|
1263
|
+
);
|
|
1264
|
+
const shared = {
|
|
1265
|
+
min,
|
|
1266
|
+
max,
|
|
1267
|
+
step,
|
|
1268
|
+
largeStep,
|
|
1269
|
+
minStepsBetweenValues,
|
|
1270
|
+
disabled,
|
|
1271
|
+
orientation,
|
|
1272
|
+
name,
|
|
1273
|
+
className: rootClassName,
|
|
1274
|
+
"data-tone": tone,
|
|
1275
|
+
"data-invalid": field?.invalid || void 0
|
|
1276
|
+
};
|
|
1277
|
+
const thumbWiring = {
|
|
1278
|
+
"aria-describedby": field?.describedBy,
|
|
1279
|
+
"aria-invalid": field?.invalid || void 0
|
|
1280
|
+
};
|
|
1281
|
+
const thumbInputRef = (first) => (input) => {
|
|
1282
|
+
if (!input) return;
|
|
1283
|
+
if (first && field) input.id = field.controlId;
|
|
1284
|
+
if (field?.describedBy) input.setAttribute("aria-describedby", field.describedBy);
|
|
1285
|
+
else input.removeAttribute("aria-describedby");
|
|
1286
|
+
if (field?.invalid) input.setAttribute("aria-invalid", "true");
|
|
1287
|
+
else input.removeAttribute("aria-invalid");
|
|
1288
|
+
};
|
|
1289
|
+
if (range) {
|
|
1290
|
+
const rangeDefaultValue = defaultValue ?? [min, max];
|
|
1291
|
+
return /* @__PURE__ */ jsxs(
|
|
1292
|
+
Slider$1.Root,
|
|
1293
|
+
{
|
|
1294
|
+
...shared,
|
|
1295
|
+
value,
|
|
1296
|
+
defaultValue: rangeDefaultValue,
|
|
1297
|
+
onValueChange: (next) => props.onValueChange?.(next),
|
|
1298
|
+
onValueCommitted: (next) => props.onValueCommitted?.(next),
|
|
1299
|
+
children: [
|
|
1300
|
+
/* @__PURE__ */ jsx(SliderTrack, {}),
|
|
1301
|
+
/* @__PURE__ */ jsx(Slider$1.Thumb, { index: 0, className: "cb-slider__thumb", inputRef: thumbInputRef(true), getAriaLabel: ariaLabel, getAriaValueText: ariaValueText, ...thumbWiring }),
|
|
1302
|
+
/* @__PURE__ */ jsx(Slider$1.Thumb, { index: 1, className: "cb-slider__thumb", inputRef: thumbInputRef(false), getAriaLabel: ariaLabel, getAriaValueText: ariaValueText, ...thumbWiring })
|
|
1303
|
+
]
|
|
1304
|
+
},
|
|
1305
|
+
"range"
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1308
|
+
return /* @__PURE__ */ jsxs(
|
|
1309
|
+
Slider$1.Root,
|
|
1310
|
+
{
|
|
1311
|
+
...shared,
|
|
1312
|
+
value,
|
|
1313
|
+
defaultValue,
|
|
1314
|
+
onValueChange: (next) => props.onValueChange?.(next),
|
|
1315
|
+
onValueCommitted: (next) => props.onValueCommitted?.(next),
|
|
1316
|
+
children: [
|
|
1317
|
+
/* @__PURE__ */ jsx(SliderTrack, {}),
|
|
1318
|
+
/* @__PURE__ */ jsx(Slider$1.Thumb, { className: "cb-slider__thumb", inputRef: thumbInputRef(true), getAriaLabel: ariaLabel, getAriaValueText: ariaValueText, ...thumbWiring })
|
|
1319
|
+
]
|
|
1320
|
+
},
|
|
1321
|
+
"single"
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1324
|
+
function SliderTrack() {
|
|
1325
|
+
return /* @__PURE__ */ jsx(Slider$1.Control, { className: "cb-slider__control", children: /* @__PURE__ */ jsx(Slider$1.Track, { className: "cb-slider__track", children: /* @__PURE__ */ jsx(Slider$1.Indicator, { className: "cb-slider__indicator" }) }) });
|
|
1326
|
+
}
|
|
1327
|
+
function validateSlider({
|
|
1328
|
+
min,
|
|
1329
|
+
max,
|
|
1330
|
+
step,
|
|
1331
|
+
largeStep,
|
|
1332
|
+
minStepsBetweenValues,
|
|
1333
|
+
value,
|
|
1334
|
+
defaultValue,
|
|
1335
|
+
range
|
|
1161
1336
|
}) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1337
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || min >= max) {
|
|
1338
|
+
throw new RangeError("Slider requires finite min and max values where min is less than max.");
|
|
1339
|
+
}
|
|
1340
|
+
if (!Number.isFinite(step) || step <= 0) {
|
|
1341
|
+
throw new RangeError("Slider step must be a finite number greater than zero.");
|
|
1342
|
+
}
|
|
1343
|
+
if (largeStep !== void 0 && (!Number.isFinite(largeStep) || largeStep <= 0)) {
|
|
1344
|
+
throw new RangeError("Slider largeStep must be a finite number greater than zero.");
|
|
1345
|
+
}
|
|
1346
|
+
if (!Number.isInteger(minStepsBetweenValues) || minStepsBetweenValues < 0) {
|
|
1347
|
+
throw new RangeError("Slider minStepsBetweenValues must be a non-negative integer.");
|
|
1348
|
+
}
|
|
1349
|
+
if (range && step * minStepsBetweenValues > max - min) {
|
|
1350
|
+
throw new RangeError("Slider minStepsBetweenValues cannot fit within min and max.");
|
|
1351
|
+
}
|
|
1352
|
+
const candidate = value ?? defaultValue;
|
|
1353
|
+
if (candidate === void 0) return;
|
|
1354
|
+
if (range) {
|
|
1355
|
+
if (!Array.isArray(candidate) || candidate.length !== 2) {
|
|
1356
|
+
throw new RangeError("A range Slider requires exactly two values.");
|
|
1357
|
+
}
|
|
1358
|
+
validateValue(candidate[0], min, max, step);
|
|
1359
|
+
validateValue(candidate[1], min, max, step);
|
|
1360
|
+
if (candidate[0] > candidate[1]) {
|
|
1361
|
+
throw new RangeError("A range Slider requires values in ascending order.");
|
|
1362
|
+
}
|
|
1363
|
+
if (candidate[1] - candidate[0] < step * minStepsBetweenValues) {
|
|
1364
|
+
throw new RangeError("Range Slider values do not satisfy minStepsBetweenValues.");
|
|
1365
|
+
}
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
if (typeof candidate !== "number") {
|
|
1369
|
+
throw new RangeError("A single-value Slider requires one number.");
|
|
1370
|
+
}
|
|
1371
|
+
validateValue(candidate, min, max, step);
|
|
1372
|
+
}
|
|
1373
|
+
function validateValue(value, min, max, step) {
|
|
1374
|
+
if (!Number.isFinite(value) || value < min || value > max) {
|
|
1375
|
+
throw new RangeError("Slider values must be finite and within min and max.");
|
|
1376
|
+
}
|
|
1377
|
+
if (!isStepAligned(value, min, step)) {
|
|
1378
|
+
throw new RangeError("Slider values must align to step increments from min.");
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
function isStepAligned(value, min, step) {
|
|
1382
|
+
const steps = (value - min) / step;
|
|
1383
|
+
return Math.abs(steps - Math.round(steps)) <= Number.EPSILON * Math.max(1, Math.abs(steps)) * 32;
|
|
1384
|
+
}
|
|
1385
|
+
var Slider = Object.assign(SliderComponent, { Skeleton: SliderSkeleton });
|
|
1386
|
+
function MentionsSkeleton({ rows = 3 }) {
|
|
1387
|
+
return /* @__PURE__ */ jsx("div", { className: "cb-mentions cb-mentions--skeleton", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Skeleton.Text, { lines: rows }) });
|
|
1388
|
+
}
|
|
1389
|
+
function queryAtCaret(value, caret, trigger) {
|
|
1390
|
+
const prefix = value.slice(0, caret);
|
|
1391
|
+
const triggerIndex = prefix.lastIndexOf(trigger);
|
|
1392
|
+
if (triggerIndex < 0) return null;
|
|
1393
|
+
const beforeTrigger = prefix.slice(0, triggerIndex);
|
|
1394
|
+
const text2 = prefix.slice(triggerIndex + trigger.length);
|
|
1395
|
+
if (beforeTrigger && !/\s$/.test(beforeTrigger) || /\s/.test(text2)) return null;
|
|
1396
|
+
return { start: triggerIndex, end: caret, text: text2 };
|
|
1397
|
+
}
|
|
1398
|
+
function normalizeTrigger(trigger) {
|
|
1399
|
+
if (Array.from(trigger).length !== 1) {
|
|
1400
|
+
throw new RangeError("Mentions trigger must be exactly one character.");
|
|
1401
|
+
}
|
|
1402
|
+
return trigger;
|
|
1403
|
+
}
|
|
1404
|
+
function validateOptions(options) {
|
|
1405
|
+
const values = /* @__PURE__ */ new Set();
|
|
1406
|
+
for (const option of options) {
|
|
1407
|
+
if (values.has(option.value)) throw new RangeError("Mentions options require unique values.");
|
|
1408
|
+
values.add(option.value);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
function matchingOptions(options, query) {
|
|
1412
|
+
if (!query) return [];
|
|
1413
|
+
const needle = query.text.toLocaleLowerCase();
|
|
1414
|
+
return options.filter((option) => (option.searchText ?? option.value).toLocaleLowerCase().includes(needle));
|
|
1415
|
+
}
|
|
1416
|
+
function MentionsRoot({
|
|
1417
|
+
options,
|
|
1418
|
+
value,
|
|
1419
|
+
defaultValue = "",
|
|
1420
|
+
onValueChange,
|
|
1421
|
+
trigger = "@",
|
|
1422
|
+
separator = " ",
|
|
1423
|
+
placeholder,
|
|
1424
|
+
rows = 3,
|
|
1425
|
+
name,
|
|
1426
|
+
disabled = false,
|
|
1427
|
+
motion: motion3 = true
|
|
1428
|
+
}) {
|
|
1429
|
+
const field = useFieldWiring();
|
|
1430
|
+
const listboxId = useId();
|
|
1431
|
+
const normalizedTrigger = normalizeTrigger(trigger);
|
|
1432
|
+
validateOptions(options);
|
|
1433
|
+
const controlled = value !== void 0;
|
|
1434
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
1435
|
+
const text2 = controlled ? value : internalValue;
|
|
1436
|
+
const textareaRef = useRef(null);
|
|
1437
|
+
const anchorRef = useRef(null);
|
|
1438
|
+
const [query, setQuery] = useState(null);
|
|
1439
|
+
const [open, setOpen] = useState(false);
|
|
1440
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
1441
|
+
const isComposingRef = useRef(false);
|
|
1442
|
+
const matches = useMemo(() => matchingOptions(options, query), [options, query]);
|
|
1443
|
+
const enabledMatches = useMemo(() => matches.filter((option) => !option.disabled), [matches]);
|
|
1444
|
+
useEffect(() => {
|
|
1445
|
+
setActiveIndex(0);
|
|
1446
|
+
}, [query?.start, query?.text, matches.length]);
|
|
1447
|
+
useEffect(() => {
|
|
1448
|
+
if (!disabled) return;
|
|
1449
|
+
setOpen(false);
|
|
1450
|
+
setQuery(null);
|
|
1451
|
+
}, [disabled]);
|
|
1452
|
+
const updateText = (next) => {
|
|
1453
|
+
if (!controlled) setInternalValue(next);
|
|
1454
|
+
onValueChange?.(next);
|
|
1455
|
+
};
|
|
1456
|
+
const updateQuery = (nextText = text2, caret = textareaRef.current?.selectionStart ?? nextText.length) => {
|
|
1457
|
+
if (disabled || isComposingRef.current) {
|
|
1458
|
+
setQuery(null);
|
|
1459
|
+
setOpen(false);
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
const nextQuery = queryAtCaret(nextText, caret, normalizedTrigger);
|
|
1463
|
+
setQuery(nextQuery);
|
|
1464
|
+
setOpen(Boolean(matchingOptions(options, nextQuery).some((option) => !option.disabled)));
|
|
1465
|
+
};
|
|
1466
|
+
const selectOption = (option) => {
|
|
1467
|
+
if (disabled || !query || option.disabled) return;
|
|
1468
|
+
const inserted = `${normalizedTrigger}${option.value}${separator}`;
|
|
1469
|
+
const next = `${text2.slice(0, query.start)}${inserted}${text2.slice(query.end)}`;
|
|
1470
|
+
const caret = query.start + inserted.length;
|
|
1471
|
+
updateText(next);
|
|
1472
|
+
setQuery(null);
|
|
1473
|
+
setOpen(false);
|
|
1474
|
+
requestAnimationFrame(() => {
|
|
1475
|
+
textareaRef.current?.focus();
|
|
1476
|
+
textareaRef.current?.setSelectionRange(caret, caret);
|
|
1477
|
+
});
|
|
1478
|
+
};
|
|
1479
|
+
const moveActive = (amount) => {
|
|
1480
|
+
if (enabledMatches.length === 0) return;
|
|
1481
|
+
setActiveIndex((current) => (current + amount + enabledMatches.length) % enabledMatches.length);
|
|
1482
|
+
};
|
|
1483
|
+
const handleChange = (event) => {
|
|
1484
|
+
const next = event.target.value;
|
|
1485
|
+
updateText(next);
|
|
1486
|
+
if (disabled || isComposingRef.current) return;
|
|
1487
|
+
const nextQuery = queryAtCaret(next, event.target.selectionStart, normalizedTrigger);
|
|
1488
|
+
setQuery(nextQuery);
|
|
1489
|
+
setOpen(Boolean(nextQuery && options.some((option) => !option.disabled && (option.searchText ?? option.value).toLocaleLowerCase().includes(nextQuery.text.toLocaleLowerCase()))));
|
|
1490
|
+
};
|
|
1491
|
+
const handleKeyDown = (event) => {
|
|
1492
|
+
if (isComposingRef.current || event.nativeEvent.isComposing) return;
|
|
1493
|
+
if (!open) return;
|
|
1494
|
+
if (event.key === "Tab") {
|
|
1495
|
+
setOpen(false);
|
|
1496
|
+
} else if (event.key === "ArrowDown") {
|
|
1497
|
+
event.preventDefault();
|
|
1498
|
+
moveActive(1);
|
|
1499
|
+
} else if (event.key === "ArrowUp") {
|
|
1500
|
+
event.preventDefault();
|
|
1501
|
+
moveActive(-1);
|
|
1502
|
+
} else if (event.key === "Enter") {
|
|
1503
|
+
const active = enabledMatches[activeIndex];
|
|
1504
|
+
if (active) {
|
|
1505
|
+
event.preventDefault();
|
|
1506
|
+
selectOption(active);
|
|
1507
|
+
}
|
|
1508
|
+
} else if (event.key === "Escape") {
|
|
1509
|
+
event.preventDefault();
|
|
1510
|
+
setOpen(false);
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
const activeOption = enabledMatches[activeIndex];
|
|
1514
|
+
return /* @__PURE__ */ jsxs(Popover$1.Root, { open, onOpenChange: setOpen, children: [
|
|
1515
|
+
/* @__PURE__ */ jsx("div", { ref: anchorRef, className: `cb-mentions${!motion3 ? " cb-mentions--motionless" : ""}`, "data-disabled": disabled || void 0, children: /* @__PURE__ */ jsx(
|
|
1516
|
+
"textarea",
|
|
1517
|
+
{
|
|
1518
|
+
ref: textareaRef,
|
|
1519
|
+
className: "cb-mentions__textarea",
|
|
1520
|
+
id: field?.controlId,
|
|
1521
|
+
name,
|
|
1522
|
+
value: text2,
|
|
1523
|
+
placeholder,
|
|
1524
|
+
rows,
|
|
1525
|
+
disabled,
|
|
1526
|
+
required: field?.required,
|
|
1527
|
+
"aria-describedby": field?.describedBy,
|
|
1528
|
+
"aria-invalid": field?.invalid || void 0,
|
|
1529
|
+
"aria-autocomplete": "list",
|
|
1530
|
+
"aria-controls": open ? listboxId : void 0,
|
|
1531
|
+
"aria-activedescendant": open && activeOption ? `${listboxId}-option-${matches.indexOf(activeOption)}` : void 0,
|
|
1532
|
+
onChange: handleChange,
|
|
1533
|
+
onSelect: () => updateQuery(),
|
|
1534
|
+
onFocus: () => updateQuery(),
|
|
1535
|
+
onCompositionStart: () => {
|
|
1536
|
+
isComposingRef.current = true;
|
|
1537
|
+
setQuery(null);
|
|
1538
|
+
setOpen(false);
|
|
1539
|
+
},
|
|
1540
|
+
onCompositionEnd: (event) => {
|
|
1541
|
+
isComposingRef.current = false;
|
|
1542
|
+
updateQuery(event.currentTarget.value, event.currentTarget.selectionStart);
|
|
1543
|
+
},
|
|
1544
|
+
onKeyDown: handleKeyDown
|
|
1545
|
+
}
|
|
1546
|
+
) }),
|
|
1547
|
+
/* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, { anchor: anchorRef, side: "bottom", align: "start", className: "cb-mentions__positioner", children: /* @__PURE__ */ jsx(Popover$1.Popup, { className: `cb-mentions__popup${!motion3 ? " cb-mentions__popup--motionless" : ""}`, initialFocus: false, finalFocus: false, children: /* @__PURE__ */ jsx("div", { className: "cb-mentions__list", id: listboxId, role: "listbox", "aria-label": "Mention suggestions", children: matches.map((option, matchIndex) => {
|
|
1548
|
+
const index = enabledMatches.indexOf(option);
|
|
1549
|
+
const active = index === activeIndex;
|
|
1550
|
+
return /* @__PURE__ */ jsx(
|
|
1551
|
+
"button",
|
|
1168
1552
|
{
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1553
|
+
type: "button",
|
|
1554
|
+
role: "option",
|
|
1555
|
+
id: `${listboxId}-option-${matchIndex}`,
|
|
1556
|
+
className: "cb-mentions__option",
|
|
1557
|
+
disabled: option.disabled,
|
|
1558
|
+
tabIndex: -1,
|
|
1559
|
+
"aria-selected": active,
|
|
1560
|
+
"data-active": active || void 0,
|
|
1561
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
1562
|
+
onClick: () => selectOption(option),
|
|
1563
|
+
children: option.label
|
|
1564
|
+
},
|
|
1565
|
+
`${option.value}-${matchIndex}`
|
|
1566
|
+
);
|
|
1567
|
+
}) }) }) }) })
|
|
1179
1568
|
] });
|
|
1180
1569
|
}
|
|
1181
|
-
var
|
|
1182
|
-
function
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
trigger,
|
|
1191
|
-
className
|
|
1192
|
-
}) {
|
|
1193
|
-
return /* @__PURE__ */ jsxs(Dialog.Root, { open, defaultOpen, onOpenChange, children: [
|
|
1194
|
-
trigger ? /* @__PURE__ */ jsx(Dialog.Trigger, { render: trigger }) : null,
|
|
1195
|
-
/* @__PURE__ */ jsxs(Dialog.Portal, { children: [
|
|
1196
|
-
/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-drawer__backdrop" }),
|
|
1197
|
-
/* @__PURE__ */ jsxs(Dialog.Popup, { className: cn("cb-drawer", className), children: [
|
|
1198
|
-
/* @__PURE__ */ jsx(Dialog.Title, { className: "cb-drawer__title", children: title }),
|
|
1199
|
-
description ? /* @__PURE__ */ jsx(Dialog.Description, { className: "cb-drawer__description", children: description }) : null,
|
|
1200
|
-
children ? /* @__PURE__ */ jsx("div", { className: "cb-drawer__body", children }) : null,
|
|
1201
|
-
footer ? /* @__PURE__ */ jsx("div", { className: "cb-drawer__footer", children: footer }) : null
|
|
1202
|
-
] })
|
|
1203
|
-
] })
|
|
1570
|
+
var Mentions = Object.assign(MentionsRoot, { Skeleton: MentionsSkeleton });
|
|
1571
|
+
function TransferSkeleton({ items = 4 }) {
|
|
1572
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-transfer cb-transfer--skeleton", "aria-hidden": "true", children: [
|
|
1573
|
+
/* @__PURE__ */ jsx(TransferSkeletonList, { items }),
|
|
1574
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-transfer__actions", children: [
|
|
1575
|
+
/* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-transfer__skeleton-action" }),
|
|
1576
|
+
/* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-transfer__skeleton-action" })
|
|
1577
|
+
] }),
|
|
1578
|
+
/* @__PURE__ */ jsx(TransferSkeletonList, { items })
|
|
1204
1579
|
] });
|
|
1205
1580
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
if (label.startsWith(needle)) return 80;
|
|
1215
|
-
if (label.split(/\s+/).some((word) => word.startsWith(needle))) return 60;
|
|
1216
|
-
if (label.includes(needle)) return 40;
|
|
1217
|
-
if (command.keywords?.some((keyword) => keyword.toLowerCase().includes(needle))) return 20;
|
|
1218
|
-
return 0;
|
|
1581
|
+
function TransferSkeletonList({ items }) {
|
|
1582
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-transfer__list", children: [
|
|
1583
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "cb-transfer__skeleton-title" }),
|
|
1584
|
+
/* @__PURE__ */ jsx("ul", { className: "cb-transfer__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs("li", { className: "cb-transfer__item", children: [
|
|
1585
|
+
/* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-transfer__skeleton-checkbox" }),
|
|
1586
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "cb-transfer__skeleton-label" })
|
|
1587
|
+
] }, index)) })
|
|
1588
|
+
] });
|
|
1219
1589
|
}
|
|
1220
|
-
function
|
|
1221
|
-
|
|
1590
|
+
function normalizeTargetKeys(items, keys) {
|
|
1591
|
+
const itemKeys = new Set(items.map((item) => item.key));
|
|
1592
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1593
|
+
return keys.filter((key) => itemKeys.has(key) && !seen.has(key) && (seen.add(key), true));
|
|
1222
1594
|
}
|
|
1223
|
-
function
|
|
1224
|
-
const
|
|
1225
|
-
for (const
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
else groups.push({ group: command.group, items: [command] });
|
|
1595
|
+
function validateItemKeys(items) {
|
|
1596
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1597
|
+
for (const item of items) {
|
|
1598
|
+
if (seen.has(item.key)) throw new RangeError(`Transfer item keys must be unique: ${item.key}`);
|
|
1599
|
+
seen.add(item.key);
|
|
1229
1600
|
}
|
|
1230
|
-
return groups;
|
|
1231
1601
|
}
|
|
1232
|
-
function
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1602
|
+
function TransferRoot({
|
|
1603
|
+
items,
|
|
1604
|
+
targetKeys,
|
|
1605
|
+
defaultTargetKeys = [],
|
|
1606
|
+
onTargetKeysChange,
|
|
1607
|
+
sourceTitle = "Available",
|
|
1608
|
+
targetTitle = "Selected",
|
|
1609
|
+
disabled = false,
|
|
1610
|
+
"aria-label": ariaLabel = "Transfer items"
|
|
1239
1611
|
}) {
|
|
1240
|
-
|
|
1241
|
-
const
|
|
1242
|
-
const
|
|
1243
|
-
const
|
|
1612
|
+
validateItemKeys(items);
|
|
1613
|
+
const generatedId = useId();
|
|
1614
|
+
const controlled = targetKeys !== void 0;
|
|
1615
|
+
const [internalTargetKeys, setInternalTargetKeys] = useState(() => normalizeTargetKeys(items, defaultTargetKeys));
|
|
1616
|
+
const [sourceSelection, setSourceSelection] = useState(() => /* @__PURE__ */ new Set());
|
|
1617
|
+
const [targetSelection, setTargetSelection] = useState(() => /* @__PURE__ */ new Set());
|
|
1618
|
+
const assignedKeys = normalizeTargetKeys(items, controlled ? targetKeys ?? [] : internalTargetKeys);
|
|
1619
|
+
const assigned = useMemo(() => new Set(assignedKeys), [assignedKeys]);
|
|
1620
|
+
const sourceItems = items.filter((item) => !assigned.has(item.key));
|
|
1621
|
+
const targetItems = items.filter((item) => assigned.has(item.key));
|
|
1244
1622
|
useEffect(() => {
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
}, [
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
command.onRun();
|
|
1623
|
+
const sourceKeys = new Set(sourceItems.map((item) => item.key));
|
|
1624
|
+
const targetKeys2 = new Set(targetItems.map((item) => item.key));
|
|
1625
|
+
setSourceSelection((previous) => intersection(previous, sourceKeys));
|
|
1626
|
+
setTargetSelection((previous) => intersection(previous, targetKeys2));
|
|
1627
|
+
}, [sourceItems, targetItems]);
|
|
1628
|
+
const updateAssignment = (next) => {
|
|
1629
|
+
if (!controlled) setInternalTargetKeys(next);
|
|
1630
|
+
onTargetKeysChange?.(next);
|
|
1254
1631
|
};
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1632
|
+
const toggle = (key, side, checked) => {
|
|
1633
|
+
const setSelection = side === "source" ? setSourceSelection : setTargetSelection;
|
|
1634
|
+
setSelection((previous) => {
|
|
1635
|
+
const next = new Set(previous);
|
|
1636
|
+
if (checked) next.add(key);
|
|
1637
|
+
else next.delete(key);
|
|
1638
|
+
return next;
|
|
1639
|
+
});
|
|
1640
|
+
};
|
|
1641
|
+
const movable = (list, selected) => list.filter((item) => selected.has(item.key) && !item.disabled).map((item) => item.key);
|
|
1642
|
+
const moveToTarget = () => {
|
|
1643
|
+
if (disabled) return;
|
|
1644
|
+
const moving = movable(sourceItems, sourceSelection);
|
|
1645
|
+
if (moving.length === 0) return;
|
|
1646
|
+
updateAssignment([...assignedKeys, ...moving]);
|
|
1647
|
+
if (!controlled) setSourceSelection((previous) => without(previous, moving));
|
|
1648
|
+
};
|
|
1649
|
+
const moveToSource = () => {
|
|
1650
|
+
if (disabled) return;
|
|
1651
|
+
const moving = movable(targetItems, targetSelection);
|
|
1652
|
+
if (moving.length === 0) return;
|
|
1653
|
+
const movingSet = new Set(moving);
|
|
1654
|
+
updateAssignment(assignedKeys.filter((key) => !movingSet.has(key)));
|
|
1655
|
+
if (!controlled) setTargetSelection((previous) => without(previous, moving));
|
|
1656
|
+
};
|
|
1657
|
+
const movableSource = movable(sourceItems, sourceSelection);
|
|
1658
|
+
const movableTarget = movable(targetItems, targetSelection);
|
|
1659
|
+
return /* @__PURE__ */ jsxs("section", { className: "cb-transfer", "aria-label": ariaLabel, "data-disabled": disabled || void 0, children: [
|
|
1660
|
+
/* @__PURE__ */ jsx(
|
|
1661
|
+
TransferList,
|
|
1662
|
+
{
|
|
1663
|
+
id: `${generatedId}-source`,
|
|
1664
|
+
title: sourceTitle,
|
|
1665
|
+
items: sourceItems,
|
|
1666
|
+
selection: sourceSelection,
|
|
1667
|
+
disabled,
|
|
1668
|
+
onToggle: (key, checked) => toggle(key, "source", checked)
|
|
1669
|
+
}
|
|
1670
|
+
),
|
|
1671
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-transfer__actions", "aria-label": "Transfer actions", children: [
|
|
1672
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "cb-transfer__action", onClick: moveToTarget, disabled: disabled || movableSource.length === 0, "aria-label": "Move selected to target", children: "\u2192" }),
|
|
1673
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "cb-transfer__action", onClick: moveToSource, disabled: disabled || movableTarget.length === 0, "aria-label": "Move selected to source", children: "\u2190" })
|
|
1674
|
+
] }),
|
|
1675
|
+
/* @__PURE__ */ jsx(
|
|
1676
|
+
TransferList,
|
|
1677
|
+
{
|
|
1678
|
+
id: `${generatedId}-target`,
|
|
1679
|
+
title: targetTitle,
|
|
1680
|
+
items: targetItems,
|
|
1681
|
+
selection: targetSelection,
|
|
1682
|
+
disabled,
|
|
1683
|
+
onToggle: (key, checked) => toggle(key, "target", checked)
|
|
1684
|
+
}
|
|
1685
|
+
)
|
|
1686
|
+
] });
|
|
1687
|
+
}
|
|
1688
|
+
function without(previous, keys) {
|
|
1689
|
+
const next = new Set(previous);
|
|
1690
|
+
keys.forEach((key) => next.delete(key));
|
|
1691
|
+
return next;
|
|
1692
|
+
}
|
|
1693
|
+
function intersection(previous, valid) {
|
|
1694
|
+
const next = new Set([...previous].filter((key) => valid.has(key)));
|
|
1695
|
+
return next.size === previous.size ? previous : next;
|
|
1696
|
+
}
|
|
1697
|
+
function TransferList({
|
|
1698
|
+
id,
|
|
1699
|
+
title,
|
|
1700
|
+
items,
|
|
1701
|
+
selection,
|
|
1702
|
+
disabled,
|
|
1703
|
+
onToggle
|
|
1704
|
+
}) {
|
|
1705
|
+
return /* @__PURE__ */ jsxs("fieldset", { className: "cb-transfer__list", disabled, children: [
|
|
1706
|
+
/* @__PURE__ */ jsx("legend", { className: "cb-transfer__title", children: title }),
|
|
1707
|
+
/* @__PURE__ */ jsx("span", { className: "cb-transfer__count", "aria-live": "polite", children: items.length }),
|
|
1708
|
+
/* @__PURE__ */ jsx("ul", { className: "cb-transfer__items", children: items.map((item) => {
|
|
1709
|
+
const itemId = `${id}-${encodeURIComponent(item.key)}`;
|
|
1710
|
+
const descriptionId = item.description ? `${itemId}-description` : void 0;
|
|
1711
|
+
return /* @__PURE__ */ jsxs("li", { className: "cb-transfer__item", "data-disabled": item.disabled || void 0, children: [
|
|
1260
1712
|
/* @__PURE__ */ jsx(
|
|
1261
1713
|
"input",
|
|
1262
1714
|
{
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1715
|
+
id: itemId,
|
|
1716
|
+
className: "cb-transfer__checkbox",
|
|
1717
|
+
type: "checkbox",
|
|
1718
|
+
checked: selection.has(item.key),
|
|
1719
|
+
disabled: item.disabled,
|
|
1720
|
+
"aria-describedby": descriptionId,
|
|
1721
|
+
onChange: (event) => onToggle(item.key, event.target.checked)
|
|
1722
|
+
}
|
|
1723
|
+
),
|
|
1724
|
+
/* @__PURE__ */ jsxs("span", { className: "cb-transfer__content", children: [
|
|
1725
|
+
/* @__PURE__ */ jsx("label", { className: "cb-transfer__label", htmlFor: itemId, children: /* @__PURE__ */ jsx("span", { children: item.label }) }),
|
|
1726
|
+
item.description ? /* @__PURE__ */ jsx("span", { className: "cb-transfer__description", id: descriptionId, children: item.description }) : null
|
|
1727
|
+
] })
|
|
1728
|
+
] }, item.key);
|
|
1729
|
+
}) })
|
|
1730
|
+
] });
|
|
1731
|
+
}
|
|
1732
|
+
var Transfer = Object.assign(TransferRoot, { Skeleton: TransferSkeleton });
|
|
1733
|
+
function TreeSkeleton({ items = 5, size = "md", tone = "brand", "aria-label": ariaLabel = "Loading tree" }) {
|
|
1734
|
+
return /* @__PURE__ */ jsx("div", { role: "tree", "aria-label": ariaLabel, "aria-hidden": "true", className: cn("cb-tree", `cb-tree--${size}`, `cb-tree--${tone}`, "cb-tree--skeleton"), children: /* @__PURE__ */ jsx("div", { role: "group", className: "cb-tree__group", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsx("div", { className: "cb-tree__node", children: /* @__PURE__ */ jsx(Skeleton, { className: cn("cb-tree__skeleton-line", index % 3 === 0 && "cb-tree__skeleton-line--long") }) }, index)) }) });
|
|
1735
|
+
}
|
|
1736
|
+
function TreeRoot({
|
|
1737
|
+
nodes,
|
|
1738
|
+
expandedPaths,
|
|
1739
|
+
defaultExpandedPaths = [],
|
|
1740
|
+
onExpandedPathsChange,
|
|
1741
|
+
selectedPath,
|
|
1742
|
+
defaultSelectedPath,
|
|
1743
|
+
onSelectedPathChange,
|
|
1744
|
+
size = "md",
|
|
1745
|
+
tone = "brand",
|
|
1746
|
+
motion: motion3 = true,
|
|
1747
|
+
"aria-label": ariaLabel = "Tree"
|
|
1748
|
+
}) {
|
|
1749
|
+
validateTreeNodes(nodes);
|
|
1750
|
+
const [uncontrolledExpandedPaths, setUncontrolledExpandedPaths] = useState(defaultExpandedPaths);
|
|
1751
|
+
const [uncontrolledSelectedPath, setUncontrolledSelectedPath] = useState(defaultSelectedPath);
|
|
1752
|
+
const currentExpandedPaths = expandedPaths ?? uncontrolledExpandedPaths;
|
|
1753
|
+
const currentSelectedPath = selectedPath ?? uncontrolledSelectedPath;
|
|
1754
|
+
const visibleNodes = useMemo(() => flattenVisible(nodes, currentExpandedPaths), [nodes, currentExpandedPaths]);
|
|
1755
|
+
const firstEnabledPath = visibleNodes.find(({ node }) => !node.disabled)?.path;
|
|
1756
|
+
const [activePath, setActivePath] = useState(() => selectedPath ?? defaultSelectedPath ?? firstEnabledPath);
|
|
1757
|
+
const currentActivePath = visibleNodes.some(({ path, node }) => path === activePath && !node.disabled) ? activePath : firstEnabledPath;
|
|
1758
|
+
useEffect(() => {
|
|
1759
|
+
if (selectedPath && visibleNodes.some(({ path, node }) => path === selectedPath && !node.disabled)) {
|
|
1760
|
+
setActivePath(selectedPath);
|
|
1761
|
+
}
|
|
1762
|
+
}, [selectedPath]);
|
|
1763
|
+
const itemRefs = useRef(/* @__PURE__ */ new Map());
|
|
1764
|
+
const setExpanded = (next) => {
|
|
1765
|
+
if (expandedPaths === void 0) setUncontrolledExpandedPaths(next);
|
|
1766
|
+
onExpandedPathsChange?.(next);
|
|
1767
|
+
};
|
|
1768
|
+
const expand = (path) => {
|
|
1769
|
+
if (!currentExpandedPaths.includes(path)) setExpanded([...currentExpandedPaths, path]);
|
|
1770
|
+
};
|
|
1771
|
+
const collapse = (path) => {
|
|
1772
|
+
if (currentExpandedPaths.includes(path)) setExpanded(currentExpandedPaths.filter((item) => item !== path));
|
|
1773
|
+
};
|
|
1774
|
+
const select = (path) => {
|
|
1775
|
+
if (selectedPath === void 0) setUncontrolledSelectedPath(path);
|
|
1776
|
+
onSelectedPathChange?.(path);
|
|
1777
|
+
};
|
|
1778
|
+
const focusPath = (path) => {
|
|
1779
|
+
setActivePath(path);
|
|
1780
|
+
itemRefs.current.get(path)?.focus();
|
|
1781
|
+
};
|
|
1782
|
+
const onKeyDown = (event, current) => {
|
|
1783
|
+
const enabled = visibleNodes.filter(({ node }) => !node.disabled);
|
|
1784
|
+
const currentIndex = enabled.findIndex(({ path }) => path === current.path);
|
|
1785
|
+
const currentExpanded = currentExpandedPaths.includes(current.path);
|
|
1786
|
+
const child = enabled.find(({ parentPath }) => parentPath === current.path);
|
|
1787
|
+
if (event.key === "ArrowDown" && currentIndex < enabled.length - 1) {
|
|
1788
|
+
event.preventDefault();
|
|
1789
|
+
focusPath(enabled[currentIndex + 1].path);
|
|
1790
|
+
} else if (event.key === "ArrowUp" && currentIndex > 0) {
|
|
1791
|
+
event.preventDefault();
|
|
1792
|
+
focusPath(enabled[currentIndex - 1].path);
|
|
1793
|
+
} else if (event.key === "Home" && enabled[0]) {
|
|
1794
|
+
event.preventDefault();
|
|
1795
|
+
focusPath(enabled[0].path);
|
|
1796
|
+
} else if (event.key === "End" && enabled.at(-1)) {
|
|
1797
|
+
event.preventDefault();
|
|
1798
|
+
focusPath(enabled.at(-1).path);
|
|
1799
|
+
} else if (event.key === "ArrowRight" && current.hasChildren) {
|
|
1800
|
+
event.preventDefault();
|
|
1801
|
+
if (!currentExpanded) expand(current.path);
|
|
1802
|
+
else if (child) focusPath(child.path);
|
|
1803
|
+
} else if (event.key === "ArrowLeft") {
|
|
1804
|
+
if (current.hasChildren && currentExpanded) {
|
|
1805
|
+
event.preventDefault();
|
|
1806
|
+
collapse(current.path);
|
|
1807
|
+
} else if (current.parentPath) {
|
|
1808
|
+
event.preventDefault();
|
|
1809
|
+
const parent = nearestEnabledParent(current.parentPath, visibleNodes);
|
|
1810
|
+
if (parent) focusPath(parent);
|
|
1811
|
+
}
|
|
1812
|
+
} else if (event.key === "Enter" || event.key === " ") {
|
|
1813
|
+
event.preventDefault();
|
|
1814
|
+
select(current.path);
|
|
1815
|
+
}
|
|
1816
|
+
};
|
|
1817
|
+
return /* @__PURE__ */ jsx(
|
|
1818
|
+
"div",
|
|
1819
|
+
{
|
|
1820
|
+
role: "tree",
|
|
1821
|
+
"aria-label": ariaLabel,
|
|
1822
|
+
className: cn("cb-tree", `cb-tree--${size}`, `cb-tree--${tone}`, !motion3 && "cb-tree--motion-off"),
|
|
1823
|
+
children: /* @__PURE__ */ jsx(
|
|
1824
|
+
TreeGroup,
|
|
1825
|
+
{
|
|
1826
|
+
nodes,
|
|
1827
|
+
pathParts: [],
|
|
1828
|
+
root: true,
|
|
1829
|
+
level: 1,
|
|
1830
|
+
parentPath: void 0,
|
|
1831
|
+
expandedPaths: currentExpandedPaths,
|
|
1832
|
+
selectedPath: currentSelectedPath,
|
|
1833
|
+
activePath: currentActivePath,
|
|
1834
|
+
refs: itemRefs,
|
|
1835
|
+
onFocusPath: focusPath,
|
|
1836
|
+
onSelect: select,
|
|
1837
|
+
onKeyDown
|
|
1838
|
+
}
|
|
1839
|
+
)
|
|
1840
|
+
}
|
|
1841
|
+
);
|
|
1842
|
+
}
|
|
1843
|
+
function TreeGroup({ nodes, pathParts, root = false, level, parentPath, expandedPaths, selectedPath, activePath, refs, onFocusPath, onSelect, onKeyDown }) {
|
|
1844
|
+
return /* @__PURE__ */ jsx("div", { role: root ? void 0 : "group", className: "cb-tree__group", children: nodes.map((node) => {
|
|
1845
|
+
const parts = [...pathParts, node.key];
|
|
1846
|
+
const path = toPath(parts);
|
|
1847
|
+
const hasChildren = Boolean(node.children?.length);
|
|
1848
|
+
const expanded = expandedPaths.includes(path);
|
|
1849
|
+
const current = { node, path, parentPath, level, hasChildren };
|
|
1850
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-tree__node", children: [
|
|
1851
|
+
/* @__PURE__ */ jsxs(
|
|
1852
|
+
"div",
|
|
1853
|
+
{
|
|
1854
|
+
ref: (element) => {
|
|
1855
|
+
if (element) refs.current.set(path, element);
|
|
1856
|
+
else refs.current.delete(path);
|
|
1857
|
+
},
|
|
1858
|
+
role: "treeitem",
|
|
1859
|
+
"aria-level": level,
|
|
1860
|
+
"aria-expanded": hasChildren ? expanded : void 0,
|
|
1861
|
+
"aria-selected": selectedPath === path || void 0,
|
|
1862
|
+
"aria-disabled": node.disabled || void 0,
|
|
1863
|
+
tabIndex: !node.disabled && activePath === path ? 0 : -1,
|
|
1864
|
+
className: "cb-tree__item",
|
|
1865
|
+
"data-selected": selectedPath === path || void 0,
|
|
1866
|
+
"data-disabled": node.disabled || void 0,
|
|
1867
|
+
onFocus: () => onFocusPath(path),
|
|
1868
|
+
onClick: () => {
|
|
1869
|
+
if (!node.disabled) onSelect(path);
|
|
1870
|
+
},
|
|
1871
|
+
onKeyDown: (event) => onKeyDown(event, current),
|
|
1872
|
+
children: [
|
|
1873
|
+
hasChildren ? /* @__PURE__ */ jsx(TreeChevron, { expanded }) : /* @__PURE__ */ jsx("span", { className: "cb-tree__indent", "aria-hidden": "true" }),
|
|
1874
|
+
/* @__PURE__ */ jsx("span", { className: "cb-tree__label", children: node.label }),
|
|
1875
|
+
node.content ? /* @__PURE__ */ jsx("span", { className: "cb-tree__content", children: node.content }) : null
|
|
1876
|
+
]
|
|
1877
|
+
}
|
|
1878
|
+
),
|
|
1879
|
+
hasChildren && expanded ? /* @__PURE__ */ jsx(
|
|
1880
|
+
TreeGroup,
|
|
1881
|
+
{
|
|
1882
|
+
nodes: node.children,
|
|
1883
|
+
pathParts: parts,
|
|
1884
|
+
level: level + 1,
|
|
1885
|
+
parentPath: path,
|
|
1886
|
+
expandedPaths,
|
|
1887
|
+
selectedPath,
|
|
1888
|
+
activePath,
|
|
1889
|
+
refs,
|
|
1890
|
+
onFocusPath,
|
|
1891
|
+
onSelect,
|
|
1892
|
+
onKeyDown
|
|
1893
|
+
}
|
|
1894
|
+
) : null
|
|
1895
|
+
] }, path);
|
|
1896
|
+
}) });
|
|
1897
|
+
}
|
|
1898
|
+
function TreeChevron({ expanded }) {
|
|
1899
|
+
return /* @__PURE__ */ jsxs("span", { className: "cb-tree__chevrons", "aria-hidden": "true", "data-expanded": expanded || void 0, children: [
|
|
1900
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "cb-tree__chevron cb-tree__chevron--collapsed" }),
|
|
1901
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "cb-tree__chevron cb-tree__chevron--expanded" })
|
|
1902
|
+
] });
|
|
1903
|
+
}
|
|
1904
|
+
function flattenVisible(nodes, expandedPaths, pathParts = [], level = 1, parentPath) {
|
|
1905
|
+
return nodes.flatMap((node) => {
|
|
1906
|
+
const parts = [...pathParts, node.key];
|
|
1907
|
+
const path = toPath(parts);
|
|
1908
|
+
const hasChildren = Boolean(node.children?.length);
|
|
1909
|
+
const current = { node, path, parentPath, level, hasChildren };
|
|
1910
|
+
const children = hasChildren && expandedPaths.includes(path) ? flattenVisible(node.children, expandedPaths, parts, level + 1, path) : [];
|
|
1911
|
+
return [current, ...children];
|
|
1912
|
+
});
|
|
1913
|
+
}
|
|
1914
|
+
function toPath(parts) {
|
|
1915
|
+
return parts.map(encodeURIComponent).join("/");
|
|
1916
|
+
}
|
|
1917
|
+
function nearestEnabledParent(path, visibleNodes) {
|
|
1918
|
+
let candidate = visibleNodes.find((node) => node.path === path);
|
|
1919
|
+
while (candidate && candidate.node.disabled) {
|
|
1920
|
+
candidate = candidate.parentPath ? visibleNodes.find((node) => node.path === candidate.parentPath) : void 0;
|
|
1921
|
+
}
|
|
1922
|
+
return candidate?.path;
|
|
1923
|
+
}
|
|
1924
|
+
function validateTreeNodes(nodes, path = []) {
|
|
1925
|
+
const siblingKeys = /* @__PURE__ */ new Set();
|
|
1926
|
+
for (const node of nodes) {
|
|
1927
|
+
if (siblingKeys.has(node.key)) {
|
|
1928
|
+
const location = [...path, node.key].join(" / ") || node.key;
|
|
1929
|
+
throw new Error(`Tree requires unique sibling keys; duplicate key at ${location}.`);
|
|
1930
|
+
}
|
|
1931
|
+
siblingKeys.add(node.key);
|
|
1932
|
+
if (node.children?.length) validateTreeNodes(node.children, [...path, node.key]);
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
var Tree = Object.assign(TreeRoot, { Skeleton: TreeSkeleton });
|
|
1936
|
+
function TreeSelectSkeleton({ size = "md" }) {
|
|
1937
|
+
return /* @__PURE__ */ jsx(Skeleton, { className: `cb-tree-select cb-tree-select--${size} cb-tree-select--skeleton` });
|
|
1938
|
+
}
|
|
1939
|
+
function TreeSelectRoot({ nodes, value, defaultValue = null, onValueChange, open, defaultOpen = false, onOpenChange, label, placeholder = "Select\u2026", name, disabled = false, motion: motion3 = true }) {
|
|
1940
|
+
const field = useFieldWiring();
|
|
1941
|
+
const generatedId = useId();
|
|
1942
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
1943
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen);
|
|
1944
|
+
const currentValue = value !== void 0 ? value : internalValue;
|
|
1945
|
+
const currentOpen = open ?? internalOpen;
|
|
1946
|
+
const effectiveOpen = disabled ? false : currentOpen;
|
|
1947
|
+
const selectedLabel = currentValue ? labelForPath(nodes, currentValue) : void 0;
|
|
1948
|
+
const setOpen = (next) => {
|
|
1949
|
+
if (open === void 0) setInternalOpen(next);
|
|
1950
|
+
onOpenChange?.(next);
|
|
1951
|
+
};
|
|
1952
|
+
const select = (path) => {
|
|
1953
|
+
if (value === void 0) setInternalValue(path);
|
|
1954
|
+
onValueChange?.(path);
|
|
1955
|
+
setOpen(false);
|
|
1956
|
+
};
|
|
1957
|
+
useEffect(() => {
|
|
1958
|
+
if (disabled && currentOpen) setOpen(false);
|
|
1959
|
+
}, [disabled, currentOpen]);
|
|
1960
|
+
return /* @__PURE__ */ jsxs(Popover$1.Root, { open: effectiveOpen, onOpenChange: setOpen, children: [
|
|
1961
|
+
/* @__PURE__ */ jsx(
|
|
1962
|
+
Popover$1.Trigger,
|
|
1963
|
+
{
|
|
1964
|
+
disabled,
|
|
1965
|
+
render: /* @__PURE__ */ jsxs("button", { type: "button", id: field?.controlId ?? generatedId, className: cn("cb-tree-select", !motion3 && "cb-tree-select--motionless"), "aria-label": label, "aria-describedby": field?.describedBy, "aria-invalid": field?.invalid || void 0, "aria-required": field?.required || void 0, children: [
|
|
1966
|
+
/* @__PURE__ */ jsx("span", { className: cn("cb-tree-select__value", !selectedLabel && "cb-tree-select__placeholder"), children: selectedLabel ?? placeholder }),
|
|
1967
|
+
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "cb-tree-select__icon", "aria-hidden": "true" })
|
|
1968
|
+
] })
|
|
1969
|
+
}
|
|
1970
|
+
),
|
|
1971
|
+
name && currentValue ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: currentValue }) : null,
|
|
1972
|
+
/* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, { side: "bottom", align: "start", className: "cb-tree-select__positioner", children: /* @__PURE__ */ jsx(Popover$1.Popup, { className: cn("cb-tree-select__popup", !motion3 && "cb-tree-select__popup--motionless"), children: /* @__PURE__ */ jsx(Tree, { nodes, selectedPath: currentValue ?? void 0, onSelectedPathChange: select, motion: motion3, "aria-label": `${label} options` }) }) }) })
|
|
1973
|
+
] });
|
|
1974
|
+
}
|
|
1975
|
+
function labelForPath(nodes, path, parts = []) {
|
|
1976
|
+
for (const node of nodes) {
|
|
1977
|
+
const next = [...parts, node.key];
|
|
1978
|
+
const nodePath = next.map(encodeURIComponent).join("/");
|
|
1979
|
+
if (nodePath === path) return node.label;
|
|
1980
|
+
const found = node.children ? labelForPath(node.children, path, next) : void 0;
|
|
1981
|
+
if (found) return found;
|
|
1982
|
+
}
|
|
1983
|
+
return void 0;
|
|
1984
|
+
}
|
|
1985
|
+
var TreeSelect = Object.assign(TreeSelectRoot, { Skeleton: TreeSelectSkeleton });
|
|
1986
|
+
function CascaderSkeleton({ rows = 3 }) {
|
|
1987
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-cascader cb-cascader--skeleton", "aria-hidden": "true", children: [
|
|
1988
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "cb-cascader__skeleton-label" }),
|
|
1989
|
+
/* @__PURE__ */ jsx(ChevronPlaceholder, {}),
|
|
1990
|
+
/* @__PURE__ */ jsx("div", { className: "cb-cascader__skeleton-menu", children: Array.from({ length: rows }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { height: "var(--cb-control-height-sm)" }, index)) })
|
|
1991
|
+
] });
|
|
1992
|
+
}
|
|
1993
|
+
function ChevronPlaceholder() {
|
|
1994
|
+
return /* @__PURE__ */ jsx(Skeleton.Circle, { size: "var(--cb-space-4)" });
|
|
1995
|
+
}
|
|
1996
|
+
function firstEnabledKey(options) {
|
|
1997
|
+
return options.find((option) => !option.disabled)?.key;
|
|
1998
|
+
}
|
|
1999
|
+
function findOption(options, key) {
|
|
2000
|
+
return options.find((option) => option.key === key);
|
|
2001
|
+
}
|
|
2002
|
+
function isLeafPath(options, path) {
|
|
2003
|
+
let current = options;
|
|
2004
|
+
for (const key of path) {
|
|
2005
|
+
const option = findOption(current, key);
|
|
2006
|
+
if (!option || option.disabled) return false;
|
|
2007
|
+
current = option.children ?? [];
|
|
2008
|
+
}
|
|
2009
|
+
return path.length > 0 && current.length === 0;
|
|
2010
|
+
}
|
|
2011
|
+
function labelsForPath(options, path) {
|
|
2012
|
+
const labels = [];
|
|
2013
|
+
let current = options;
|
|
2014
|
+
for (const key of path) {
|
|
2015
|
+
const option = findOption(current, key);
|
|
2016
|
+
if (!option) return [];
|
|
2017
|
+
labels.push(option.label);
|
|
2018
|
+
current = option.children ?? [];
|
|
2019
|
+
}
|
|
2020
|
+
return labels;
|
|
2021
|
+
}
|
|
2022
|
+
function validateOptions2(options, ancestors = []) {
|
|
2023
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2024
|
+
for (const option of options) {
|
|
2025
|
+
if (keys.has(option.key)) throw new Error(`Cascader requires unique sibling keys; duplicate key at ${[...ancestors, option.key].join(" / ")}.`);
|
|
2026
|
+
keys.add(option.key);
|
|
2027
|
+
if (option.children?.length) validateOptions2(option.children, [...ancestors, option.key]);
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
function columnsForPath(options, path) {
|
|
2031
|
+
const columns = [];
|
|
2032
|
+
let current = options;
|
|
2033
|
+
for (let index = 0; current.length > 0; index += 1) {
|
|
2034
|
+
const activeKey = findOption(current, path[index]) && !findOption(current, path[index]).disabled ? path[index] : firstEnabledKey(current);
|
|
2035
|
+
if (!activeKey) break;
|
|
2036
|
+
columns.push({ options: current, activeKey });
|
|
2037
|
+
if (index >= path.length - 1) break;
|
|
2038
|
+
const active = findOption(current, activeKey);
|
|
2039
|
+
current = active?.children ?? [];
|
|
2040
|
+
}
|
|
2041
|
+
return columns;
|
|
2042
|
+
}
|
|
2043
|
+
function optionId(popupId, path) {
|
|
2044
|
+
const encodedPath = path.map((key) => encodeURIComponent(key)).join("--");
|
|
2045
|
+
return `${popupId}-option-${encodedPath}`;
|
|
2046
|
+
}
|
|
2047
|
+
function CascaderRoot({
|
|
2048
|
+
options,
|
|
2049
|
+
label,
|
|
2050
|
+
value,
|
|
2051
|
+
defaultValue = [],
|
|
2052
|
+
onValueChange,
|
|
2053
|
+
placeholder = "Select\u2026",
|
|
2054
|
+
disabled = false,
|
|
2055
|
+
motion: motion3 = true
|
|
2056
|
+
}) {
|
|
2057
|
+
validateOptions2(options);
|
|
2058
|
+
if (label.trim().length === 0) throw new Error("Cascader label must not be empty.");
|
|
2059
|
+
const field = useFieldWiring();
|
|
2060
|
+
const popupId = useId();
|
|
2061
|
+
const triggerRef = useRef(null);
|
|
2062
|
+
const controlled = value !== void 0;
|
|
2063
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
2064
|
+
const selectedPath = controlled ? value : internalValue;
|
|
2065
|
+
const [open, setOpen] = useState(false);
|
|
2066
|
+
const [activePath, setActivePath] = useState([]);
|
|
2067
|
+
const [activeColumn, setActiveColumn] = useState(0);
|
|
2068
|
+
const columns = useMemo(() => columnsForPath(options, activePath), [options, activePath]);
|
|
2069
|
+
const selectedLabels = labelsForPath(options, selectedPath);
|
|
2070
|
+
useEffect(() => {
|
|
2071
|
+
if (disabled) setOpen(false);
|
|
2072
|
+
}, [disabled]);
|
|
2073
|
+
const initialize = () => {
|
|
2074
|
+
const initialPath = isLeafPath(options, selectedPath) ? selectedPath : [firstEnabledKey(options)].filter((key) => Boolean(key));
|
|
2075
|
+
setActivePath(initialPath);
|
|
2076
|
+
setActiveColumn(Math.max(0, initialPath.length - 1));
|
|
2077
|
+
};
|
|
2078
|
+
const openPopup = () => {
|
|
2079
|
+
if (disabled) return;
|
|
2080
|
+
initialize();
|
|
2081
|
+
setOpen(true);
|
|
2082
|
+
};
|
|
2083
|
+
const updatePathAtColumn = (columnIndex, key) => {
|
|
2084
|
+
setActivePath((current) => [...current.slice(0, columnIndex), key]);
|
|
2085
|
+
setActiveColumn(columnIndex);
|
|
2086
|
+
};
|
|
2087
|
+
const choose = (path) => {
|
|
2088
|
+
if (disabled || !isLeafPath(options, path)) return;
|
|
2089
|
+
if (!controlled) setInternalValue(path);
|
|
2090
|
+
onValueChange?.(path);
|
|
2091
|
+
setOpen(false);
|
|
2092
|
+
requestAnimationFrame(() => triggerRef.current?.focus());
|
|
2093
|
+
};
|
|
2094
|
+
const currentColumn = columns[activeColumn];
|
|
2095
|
+
const currentOption = currentColumn ? findOption(currentColumn.options, currentColumn.activeKey) : void 0;
|
|
2096
|
+
const activeOptionId = open && currentColumn ? optionId(popupId, [...activePath.slice(0, activeColumn), currentColumn.activeKey]) : void 0;
|
|
2097
|
+
const handleKeyDown = (event) => {
|
|
2098
|
+
if (disabled) return;
|
|
2099
|
+
if (!open && (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ")) {
|
|
2100
|
+
event.preventDefault();
|
|
2101
|
+
openPopup();
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
if (!open) return;
|
|
2105
|
+
if (event.key === "Escape") {
|
|
2106
|
+
event.preventDefault();
|
|
2107
|
+
setOpen(false);
|
|
2108
|
+
} else if ((event.key === "ArrowDown" || event.key === "ArrowUp") && currentColumn) {
|
|
2109
|
+
event.preventDefault();
|
|
2110
|
+
const enabled = currentColumn.options.filter((option) => !option.disabled);
|
|
2111
|
+
const index = enabled.findIndex((option) => option.key === currentColumn.activeKey);
|
|
2112
|
+
if (enabled.length > 0) updatePathAtColumn(activeColumn, enabled[(index + (event.key === "ArrowDown" ? 1 : -1) + enabled.length) % enabled.length].key);
|
|
2113
|
+
} else if (event.key === "ArrowRight" && currentOption?.children?.length) {
|
|
2114
|
+
event.preventDefault();
|
|
2115
|
+
const childKey = firstEnabledKey(currentOption.children);
|
|
2116
|
+
if (childKey) {
|
|
2117
|
+
setActivePath((current) => [...current.slice(0, activeColumn + 1), childKey]);
|
|
2118
|
+
setActiveColumn(activeColumn + 1);
|
|
2119
|
+
}
|
|
2120
|
+
} else if (event.key === "ArrowLeft" && activeColumn > 0) {
|
|
2121
|
+
event.preventDefault();
|
|
2122
|
+
setActivePath((current) => current.slice(0, activeColumn));
|
|
2123
|
+
setActiveColumn(activeColumn - 1);
|
|
2124
|
+
} else if (event.key === "Enter" && currentOption && !currentOption.children?.length) {
|
|
2125
|
+
event.preventDefault();
|
|
2126
|
+
choose(activePath.slice(0, activeColumn + 1));
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2129
|
+
return /* @__PURE__ */ jsxs(Popover$1.Root, { open, onOpenChange: setOpen, children: [
|
|
2130
|
+
/* @__PURE__ */ jsxs(
|
|
2131
|
+
"button",
|
|
2132
|
+
{
|
|
2133
|
+
ref: triggerRef,
|
|
2134
|
+
type: "button",
|
|
2135
|
+
role: "combobox",
|
|
2136
|
+
className: `cb-cascader${!motion3 ? " cb-cascader--motionless" : ""}`,
|
|
2137
|
+
id: field?.controlId,
|
|
2138
|
+
disabled,
|
|
2139
|
+
"aria-describedby": field?.describedBy,
|
|
2140
|
+
"aria-label": label,
|
|
2141
|
+
"aria-invalid": field?.invalid || void 0,
|
|
2142
|
+
"aria-required": field?.required || void 0,
|
|
2143
|
+
"aria-haspopup": "dialog",
|
|
2144
|
+
"aria-expanded": open,
|
|
2145
|
+
"aria-controls": open ? popupId : void 0,
|
|
2146
|
+
"aria-activedescendant": activeOptionId,
|
|
2147
|
+
onClick: openPopup,
|
|
2148
|
+
onKeyDown: handleKeyDown,
|
|
2149
|
+
children: [
|
|
2150
|
+
/* @__PURE__ */ jsx("span", { className: "cb-cascader__value", children: selectedLabels.length ? selectedLabels.map((label2, index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
2151
|
+
index ? " / " : null,
|
|
2152
|
+
label2
|
|
2153
|
+
] }, index)) : placeholder }),
|
|
2154
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "cb-cascader__icon", "aria-hidden": "true" })
|
|
2155
|
+
]
|
|
2156
|
+
}
|
|
2157
|
+
),
|
|
2158
|
+
/* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, { anchor: triggerRef, side: "bottom", align: "start", className: "cb-cascader__positioner", children: /* @__PURE__ */ jsx(Popover$1.Popup, { id: popupId, "aria-label": "Cascader options", className: `cb-cascader__popup${!motion3 ? " cb-cascader__popup--motionless" : ""}`, initialFocus: false, finalFocus: false, children: /* @__PURE__ */ jsx("div", { className: "cb-cascader__columns", "aria-label": "Cascader options", children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx("div", { className: "cb-cascader__column", role: "listbox", "aria-label": `Level ${columnIndex + 1}`, children: column.options.map((option) => {
|
|
2159
|
+
const active = option.key === column.activeKey;
|
|
2160
|
+
const hasChildren = Boolean(option.children?.length);
|
|
2161
|
+
const path = [...activePath.slice(0, columnIndex), option.key];
|
|
2162
|
+
return /* @__PURE__ */ jsxs(
|
|
2163
|
+
"button",
|
|
2164
|
+
{
|
|
2165
|
+
type: "button",
|
|
2166
|
+
role: "option",
|
|
2167
|
+
id: optionId(popupId, path),
|
|
2168
|
+
tabIndex: -1,
|
|
2169
|
+
className: "cb-cascader__option",
|
|
2170
|
+
disabled: option.disabled,
|
|
2171
|
+
"aria-selected": active,
|
|
2172
|
+
"data-active": active || void 0,
|
|
2173
|
+
"data-branch": hasChildren || void 0,
|
|
2174
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
2175
|
+
onClick: () => {
|
|
2176
|
+
if (option.disabled) return;
|
|
2177
|
+
if (hasChildren) {
|
|
2178
|
+
const child = firstEnabledKey(option.children);
|
|
2179
|
+
if (child) {
|
|
2180
|
+
setActivePath([...path, child]);
|
|
2181
|
+
setActiveColumn(columnIndex + 1);
|
|
2182
|
+
}
|
|
2183
|
+
} else choose(path);
|
|
2184
|
+
},
|
|
2185
|
+
children: [
|
|
2186
|
+
/* @__PURE__ */ jsx("span", { className: "cb-cascader__option-label", children: option.label }),
|
|
2187
|
+
hasChildren ? /* @__PURE__ */ jsx(ChevronRight, { className: "cb-cascader__option-icon", "aria-hidden": "true" }) : null
|
|
2188
|
+
]
|
|
2189
|
+
},
|
|
2190
|
+
option.key
|
|
2191
|
+
);
|
|
2192
|
+
}) }, columnIndex)) }) }) }) })
|
|
2193
|
+
] });
|
|
2194
|
+
}
|
|
2195
|
+
var Cascader = Object.assign(CascaderRoot, { Skeleton: CascaderSkeleton });
|
|
2196
|
+
function ColorPickerSkeleton() {
|
|
2197
|
+
return /* @__PURE__ */ jsx("div", { className: "cb-color-picker cb-color-picker--skeleton", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Skeleton, { className: "cb-color-picker__skeleton" }) });
|
|
2198
|
+
}
|
|
2199
|
+
var CORE_OPTIONS = [
|
|
2200
|
+
{ tone: "neutral", label: "Neutral" },
|
|
2201
|
+
{ tone: "brand", label: "Brand" },
|
|
2202
|
+
{ tone: "success", label: "Success" },
|
|
2203
|
+
{ tone: "warning", label: "Warning" },
|
|
2204
|
+
{ tone: "danger", label: "Danger" },
|
|
2205
|
+
{ tone: "info", label: "Info" }
|
|
2206
|
+
];
|
|
2207
|
+
function validateOptions3(options) {
|
|
2208
|
+
if (options.length === 0) throw new RangeError("ColorPicker options must not be empty.");
|
|
2209
|
+
const tones = /* @__PURE__ */ new Set();
|
|
2210
|
+
options.forEach((option) => {
|
|
2211
|
+
if (tones.has(option.tone)) throw new RangeError(`ColorPicker option tones must be unique: ${option.tone}`);
|
|
2212
|
+
tones.add(option.tone);
|
|
2213
|
+
});
|
|
2214
|
+
if (!options.some((option) => !option.disabled)) throw new RangeError("ColorPicker options must include an enabled tone.");
|
|
2215
|
+
}
|
|
2216
|
+
function ColorPickerRoot({ label, value, defaultValue = "brand", onValueChange, open, defaultOpen, onOpenChange, options = CORE_OPTIONS, name, disabled = false, motion: motion3 = true }) {
|
|
2217
|
+
validateOptions3(options);
|
|
2218
|
+
if (label.trim().length === 0) throw new RangeError("ColorPicker label must not be empty.");
|
|
2219
|
+
const field = useFieldWiring();
|
|
2220
|
+
const controlledValue = value !== void 0;
|
|
2221
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
2222
|
+
const selected = controlledValue ? value : internalValue;
|
|
2223
|
+
if (!options.some((option) => option.tone === selected && !option.disabled)) throw new RangeError(`ColorPicker value must match an enabled option: ${selected}`);
|
|
2224
|
+
const controlledOpen = open !== void 0;
|
|
2225
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);
|
|
2226
|
+
const expanded = controlledOpen ? open : internalOpen;
|
|
2227
|
+
const effectiveExpanded = disabled ? false : expanded;
|
|
2228
|
+
const [activeIndex, setActiveIndex] = useState(() => Math.max(0, options.findIndex((option) => option.tone === selected && !option.disabled)));
|
|
2229
|
+
const optionRefs = useRef([]);
|
|
2230
|
+
const enabled = useMemo(() => options.map((option, index) => ({ option, index })).filter(({ option }) => !option.disabled), [options]);
|
|
2231
|
+
useEffect(() => {
|
|
2232
|
+
const selectedIndex = options.findIndex((option) => option.tone === selected && !option.disabled);
|
|
2233
|
+
if (selectedIndex >= 0) setActiveIndex(selectedIndex);
|
|
2234
|
+
}, [options, selected]);
|
|
2235
|
+
useEffect(() => {
|
|
2236
|
+
if (disabled && expanded) {
|
|
2237
|
+
if (!controlledOpen) setInternalOpen(false);
|
|
2238
|
+
onOpenChange?.(false);
|
|
2239
|
+
}
|
|
2240
|
+
}, [controlledOpen, disabled, expanded, onOpenChange]);
|
|
2241
|
+
const changeOpen = (next) => {
|
|
2242
|
+
if (!controlledOpen) setInternalOpen(next);
|
|
2243
|
+
onOpenChange?.(next);
|
|
2244
|
+
};
|
|
2245
|
+
const select = (tone) => {
|
|
2246
|
+
if (disabled) return;
|
|
2247
|
+
if (!controlledValue) setInternalValue(tone);
|
|
2248
|
+
onValueChange?.(tone);
|
|
2249
|
+
changeOpen(false);
|
|
2250
|
+
};
|
|
2251
|
+
const move = (amount) => {
|
|
2252
|
+
if (enabled.length === 0) return;
|
|
2253
|
+
const current = enabled.findIndex(({ index }) => index === activeIndex);
|
|
2254
|
+
const next = enabled[(Math.max(0, current) + amount + enabled.length) % enabled.length].index;
|
|
2255
|
+
setActiveIndex(next);
|
|
2256
|
+
optionRefs.current[next]?.focus();
|
|
2257
|
+
};
|
|
2258
|
+
const handleGridKey = (event) => {
|
|
2259
|
+
if (event.key === "ArrowRight") {
|
|
2260
|
+
event.preventDefault();
|
|
2261
|
+
move(1);
|
|
2262
|
+
} else if (event.key === "ArrowLeft") {
|
|
2263
|
+
event.preventDefault();
|
|
2264
|
+
move(-1);
|
|
2265
|
+
} else if (event.key === "ArrowDown") {
|
|
2266
|
+
event.preventDefault();
|
|
2267
|
+
move(3);
|
|
2268
|
+
} else if (event.key === "ArrowUp") {
|
|
2269
|
+
event.preventDefault();
|
|
2270
|
+
move(-3);
|
|
2271
|
+
} else if (event.key === "Escape") {
|
|
2272
|
+
event.preventDefault();
|
|
2273
|
+
changeOpen(false);
|
|
2274
|
+
}
|
|
2275
|
+
};
|
|
2276
|
+
return /* @__PURE__ */ jsxs(Popover$1.Root, { open: effectiveExpanded, onOpenChange: changeOpen, children: [
|
|
2277
|
+
/* @__PURE__ */ jsxs("span", { className: "cb-color-picker", "data-motion": motion3 ? void 0 : "off", "data-disabled": disabled || void 0, children: [
|
|
2278
|
+
name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selected }) : null,
|
|
2279
|
+
/* @__PURE__ */ jsxs(Popover$1.Trigger, { render: /* @__PURE__ */ jsx("button", { type: "button" }), id: field?.controlId, className: "cb-color-picker__trigger", "aria-label": label, "aria-describedby": field?.describedBy, "aria-invalid": field?.invalid || void 0, "aria-required": field?.required || void 0, disabled, children: [
|
|
2280
|
+
/* @__PURE__ */ jsx("span", { className: "cb-color-picker__swatch", "data-tone": selected, "aria-hidden": "true" }),
|
|
2281
|
+
/* @__PURE__ */ jsx("span", { children: options.find((option) => option.tone === selected)?.label ?? selected })
|
|
2282
|
+
] })
|
|
2283
|
+
] }),
|
|
2284
|
+
/* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, { side: "bottom", align: "start", className: "cb-color-picker__positioner", children: /* @__PURE__ */ jsx(Popover$1.Popup, { className: "cb-color-picker__popup", "data-motion": motion3 ? void 0 : "off", initialFocus: () => optionRefs.current[activeIndex] ?? false, children: /* @__PURE__ */ jsx("div", { className: "cb-color-picker__grid", role: "grid", "aria-label": `${label} options`, onKeyDown: handleGridKey, children: Array.from({ length: Math.ceil(options.length / 3) }, (_, rowIndex) => /* @__PURE__ */ jsx("div", { role: "row", className: "cb-color-picker__row", children: options.slice(rowIndex * 3, rowIndex * 3 + 3).map((option, offset) => {
|
|
2285
|
+
const index = rowIndex * 3 + offset;
|
|
2286
|
+
return /* @__PURE__ */ jsx("button", { ref: (node) => {
|
|
2287
|
+
optionRefs.current[index] = node;
|
|
2288
|
+
}, type: "button", role: "gridcell", className: "cb-color-picker__option", "data-tone": option.tone, "data-selected": selected === option.tone || void 0, tabIndex: index === activeIndex ? 0 : -1, disabled: option.disabled, "aria-label": option.label, "aria-selected": selected === option.tone, onClick: () => select(option.tone), onKeyDown: (event) => {
|
|
2289
|
+
if ((event.key === "Enter" || event.key === " ") && !option.disabled) {
|
|
2290
|
+
event.preventDefault();
|
|
2291
|
+
select(option.tone);
|
|
2292
|
+
}
|
|
2293
|
+
}, children: /* @__PURE__ */ jsx("span", { className: "cb-color-picker__swatch", "data-tone": option.tone, "aria-hidden": "true" }) }, option.tone);
|
|
2294
|
+
}) }, rowIndex)) }) }) }) })
|
|
2295
|
+
] });
|
|
2296
|
+
}
|
|
2297
|
+
var ColorPicker = Object.assign(ColorPickerRoot, { Skeleton: ColorPickerSkeleton });
|
|
2298
|
+
function ModalSkeleton({
|
|
2299
|
+
size = "md",
|
|
2300
|
+
lines = 3,
|
|
2301
|
+
withActions = true,
|
|
2302
|
+
className
|
|
2303
|
+
}) {
|
|
2304
|
+
return /* @__PURE__ */ jsxs(
|
|
2305
|
+
"div",
|
|
2306
|
+
{
|
|
2307
|
+
className: cn("cb-modal-skeleton", `cb-modal--${size}`, className),
|
|
2308
|
+
"aria-hidden": "true",
|
|
2309
|
+
children: [
|
|
2310
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "48%", height: "1.125rem" }),
|
|
2311
|
+
/* @__PURE__ */ jsx("div", { className: "cb-modal-skeleton__body", children: /* @__PURE__ */ jsx(Skeleton.Text, { lines }) }),
|
|
2312
|
+
withActions ? /* @__PURE__ */ jsxs("div", { className: "cb-modal__footer", children: [
|
|
2313
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "5rem", height: "2.5rem" }),
|
|
2314
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "5rem", height: "2.5rem" })
|
|
2315
|
+
] }) : null
|
|
2316
|
+
]
|
|
2317
|
+
}
|
|
2318
|
+
);
|
|
2319
|
+
}
|
|
2320
|
+
var CONFIRM_ICONS = {
|
|
2321
|
+
neutral: /* @__PURE__ */ jsx(Info, { size: 20 }),
|
|
2322
|
+
brand: /* @__PURE__ */ jsx(Info, { size: 20 }),
|
|
2323
|
+
info: /* @__PURE__ */ jsx(Info, { size: 20 }),
|
|
2324
|
+
success: /* @__PURE__ */ jsx(CheckCircle2, { size: 20 }),
|
|
2325
|
+
warning: /* @__PURE__ */ jsx(AlertTriangle, { size: 20 }),
|
|
2326
|
+
danger: /* @__PURE__ */ jsx(XCircle, { size: 20 })
|
|
2327
|
+
};
|
|
2328
|
+
function ModalRoot({
|
|
2329
|
+
open,
|
|
2330
|
+
defaultOpen,
|
|
2331
|
+
onOpenChange,
|
|
2332
|
+
title,
|
|
2333
|
+
description,
|
|
2334
|
+
children,
|
|
2335
|
+
footer,
|
|
2336
|
+
size = "md",
|
|
2337
|
+
placement = "center",
|
|
2338
|
+
trigger,
|
|
2339
|
+
className
|
|
2340
|
+
}) {
|
|
2341
|
+
return /* @__PURE__ */ jsxs(Dialog.Root, { open, defaultOpen, onOpenChange, children: [
|
|
2342
|
+
trigger ? /* @__PURE__ */ jsx(Dialog.Trigger, { render: trigger }) : null,
|
|
2343
|
+
/* @__PURE__ */ jsxs(Dialog.Portal, { children: [
|
|
2344
|
+
/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-modal__backdrop" }),
|
|
2345
|
+
/* @__PURE__ */ jsxs(
|
|
2346
|
+
Dialog.Popup,
|
|
2347
|
+
{
|
|
2348
|
+
className: cn("cb-modal", `cb-modal--${size}`, `cb-modal--${placement}`, className),
|
|
2349
|
+
children: [
|
|
2350
|
+
/* @__PURE__ */ jsx(Dialog.Title, { className: "cb-modal__title", children: title }),
|
|
2351
|
+
description ? /* @__PURE__ */ jsx(Dialog.Description, { className: "cb-modal__description", children: description }) : null,
|
|
2352
|
+
children ? /* @__PURE__ */ jsx("div", { className: "cb-modal__body", children }) : null,
|
|
2353
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "cb-modal__footer", children: footer }) : null
|
|
2354
|
+
]
|
|
2355
|
+
}
|
|
2356
|
+
)
|
|
2357
|
+
] })
|
|
2358
|
+
] });
|
|
2359
|
+
}
|
|
2360
|
+
function ModalConfirm({
|
|
2361
|
+
title,
|
|
2362
|
+
description,
|
|
2363
|
+
children,
|
|
2364
|
+
cancelAction,
|
|
2365
|
+
confirmAction,
|
|
2366
|
+
tone = "warning",
|
|
2367
|
+
icon,
|
|
2368
|
+
className,
|
|
2369
|
+
...rootProps
|
|
2370
|
+
}) {
|
|
2371
|
+
return /* @__PURE__ */ jsx(
|
|
2372
|
+
ModalRoot,
|
|
2373
|
+
{
|
|
2374
|
+
...rootProps,
|
|
2375
|
+
title: /* @__PURE__ */ jsxs("span", { className: "cb-modal-confirm__heading", children: [
|
|
2376
|
+
icon === null ? null : /* @__PURE__ */ jsx("span", { className: "cb-modal-confirm__icon", "data-tone": tone, "aria-hidden": "true", children: icon ?? CONFIRM_ICONS[tone] }),
|
|
2377
|
+
/* @__PURE__ */ jsx("span", { children: title })
|
|
2378
|
+
] }),
|
|
2379
|
+
description,
|
|
2380
|
+
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2381
|
+
cancelAction,
|
|
2382
|
+
confirmAction
|
|
2383
|
+
] }),
|
|
2384
|
+
size: "sm",
|
|
2385
|
+
placement: "center",
|
|
2386
|
+
className: cn("cb-modal-confirm", className),
|
|
2387
|
+
children
|
|
2388
|
+
}
|
|
2389
|
+
);
|
|
2390
|
+
}
|
|
2391
|
+
var Modal = Object.assign(ModalRoot, {
|
|
2392
|
+
Confirm: ModalConfirm,
|
|
2393
|
+
Skeleton: ModalSkeleton
|
|
2394
|
+
});
|
|
2395
|
+
var DialogClose = Dialog.Close;
|
|
2396
|
+
function Drawer({
|
|
2397
|
+
open,
|
|
2398
|
+
defaultOpen,
|
|
2399
|
+
onOpenChange,
|
|
2400
|
+
title,
|
|
2401
|
+
description,
|
|
2402
|
+
children,
|
|
2403
|
+
footer,
|
|
2404
|
+
trigger,
|
|
2405
|
+
className
|
|
2406
|
+
}) {
|
|
2407
|
+
return /* @__PURE__ */ jsxs(Dialog.Root, { open, defaultOpen, onOpenChange, children: [
|
|
2408
|
+
trigger ? /* @__PURE__ */ jsx(Dialog.Trigger, { render: trigger }) : null,
|
|
2409
|
+
/* @__PURE__ */ jsxs(Dialog.Portal, { children: [
|
|
2410
|
+
/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-drawer__backdrop" }),
|
|
2411
|
+
/* @__PURE__ */ jsxs(Dialog.Popup, { className: cn("cb-drawer", className), children: [
|
|
2412
|
+
/* @__PURE__ */ jsx(Dialog.Title, { className: "cb-drawer__title", children: title }),
|
|
2413
|
+
description ? /* @__PURE__ */ jsx(Dialog.Description, { className: "cb-drawer__description", children: description }) : null,
|
|
2414
|
+
children ? /* @__PURE__ */ jsx("div", { className: "cb-drawer__body", children }) : null,
|
|
2415
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "cb-drawer__footer", children: footer }) : null
|
|
2416
|
+
] })
|
|
2417
|
+
] })
|
|
2418
|
+
] });
|
|
2419
|
+
}
|
|
2420
|
+
var DrawerClose = Dialog.Close;
|
|
2421
|
+
|
|
2422
|
+
// src/overlay/command.util.ts
|
|
2423
|
+
function rankCommand(command, query) {
|
|
2424
|
+
const needle = query.trim().toLowerCase();
|
|
2425
|
+
if (!needle) return 1;
|
|
2426
|
+
const label = command.label.toLowerCase();
|
|
2427
|
+
if (label === needle) return 100;
|
|
2428
|
+
if (label.startsWith(needle)) return 80;
|
|
2429
|
+
if (label.split(/\s+/).some((word) => word.startsWith(needle))) return 60;
|
|
2430
|
+
if (label.includes(needle)) return 40;
|
|
2431
|
+
if (command.keywords?.some((keyword) => keyword.toLowerCase().includes(needle))) return 20;
|
|
2432
|
+
return 0;
|
|
2433
|
+
}
|
|
2434
|
+
function filterCommands(commands, query) {
|
|
2435
|
+
return commands.map((command, index) => ({ command, score: rankCommand(command, query), index })).filter((entry) => entry.score > 0).sort((a, b) => b.score === a.score ? a.index - b.index : b.score - a.score).map((entry) => entry.command);
|
|
2436
|
+
}
|
|
2437
|
+
function groupCommands(commands) {
|
|
2438
|
+
const groups = [];
|
|
2439
|
+
for (const command of commands) {
|
|
2440
|
+
const existing = groups.find((entry) => entry.group === command.group);
|
|
2441
|
+
if (existing) existing.items.push(command);
|
|
2442
|
+
else groups.push({ group: command.group, items: [command] });
|
|
2443
|
+
}
|
|
2444
|
+
return groups;
|
|
2445
|
+
}
|
|
2446
|
+
function CommandPalette({
|
|
2447
|
+
open,
|
|
2448
|
+
onOpenChange,
|
|
2449
|
+
commands,
|
|
2450
|
+
placeholder = "Type a command\u2026",
|
|
2451
|
+
emptyMessage = "No matching command",
|
|
2452
|
+
className
|
|
2453
|
+
}) {
|
|
2454
|
+
const [query, setQuery] = useState("");
|
|
2455
|
+
const [active, setActive] = useState(0);
|
|
2456
|
+
const results = useMemo(() => filterCommands(commands, query), [commands, query]);
|
|
2457
|
+
const groups = useMemo(() => groupCommands(results), [results]);
|
|
2458
|
+
useEffect(() => {
|
|
2459
|
+
if (!open) {
|
|
2460
|
+
setQuery("");
|
|
2461
|
+
setActive(0);
|
|
2462
|
+
}
|
|
2463
|
+
}, [open]);
|
|
2464
|
+
useEffect(() => setActive(0), [query]);
|
|
2465
|
+
const run = (command) => {
|
|
2466
|
+
onOpenChange(false);
|
|
2467
|
+
command.onRun();
|
|
2468
|
+
};
|
|
2469
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
|
|
2470
|
+
/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-palette__backdrop" }),
|
|
2471
|
+
/* @__PURE__ */ jsxs(Dialog.Popup, { className: cn("cb-palette", className), "aria-label": "Command palette", children: [
|
|
2472
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-palette__search", children: [
|
|
2473
|
+
/* @__PURE__ */ jsx(Search, { size: 16, className: "cb-palette__search-icon" }),
|
|
2474
|
+
/* @__PURE__ */ jsx(
|
|
2475
|
+
"input",
|
|
2476
|
+
{
|
|
2477
|
+
className: "cb-palette__input",
|
|
2478
|
+
value: query,
|
|
2479
|
+
placeholder,
|
|
2480
|
+
autoFocus: true,
|
|
2481
|
+
role: "combobox",
|
|
1268
2482
|
"aria-expanded": true,
|
|
1269
2483
|
"aria-controls": "cb-palette-list",
|
|
1270
2484
|
"aria-activedescendant": results[active] ? `cb-palette-${results[active].id}` : void 0,
|
|
@@ -1449,6 +2663,82 @@ function ArrowShape() {
|
|
|
1449
2663
|
}
|
|
1450
2664
|
);
|
|
1451
2665
|
}
|
|
2666
|
+
function PopconfirmSkeleton({
|
|
2667
|
+
withDescription = true,
|
|
2668
|
+
withCancel = true
|
|
2669
|
+
}) {
|
|
2670
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-popconfirm cb-popconfirm--skeleton", "aria-hidden": "true", children: [
|
|
2671
|
+
/* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-popconfirm__skeleton-icon" }),
|
|
2672
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-popconfirm__content", children: [
|
|
2673
|
+
/* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-popconfirm__skeleton-title" }),
|
|
2674
|
+
withDescription ? /* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-popconfirm__skeleton-description" }) : null,
|
|
2675
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-popconfirm__actions", children: [
|
|
2676
|
+
withCancel ? /* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-popconfirm__skeleton-action" }) : null,
|
|
2677
|
+
/* @__PURE__ */ jsx("span", { className: "cb-skeleton cb-popconfirm__skeleton-action" })
|
|
2678
|
+
] })
|
|
2679
|
+
] })
|
|
2680
|
+
] });
|
|
2681
|
+
}
|
|
2682
|
+
function PopconfirmRoot({
|
|
2683
|
+
trigger,
|
|
2684
|
+
title,
|
|
2685
|
+
description,
|
|
2686
|
+
cancelAction,
|
|
2687
|
+
confirmAction,
|
|
2688
|
+
tone = "warning",
|
|
2689
|
+
icon,
|
|
2690
|
+
side = "top",
|
|
2691
|
+
align = "center",
|
|
2692
|
+
open,
|
|
2693
|
+
defaultOpen,
|
|
2694
|
+
onOpenChange,
|
|
2695
|
+
motion: motion3 = true
|
|
2696
|
+
}) {
|
|
2697
|
+
const hasIcon = icon !== null;
|
|
2698
|
+
return /* @__PURE__ */ jsxs(
|
|
2699
|
+
Popover$1.Root,
|
|
2700
|
+
{
|
|
2701
|
+
open,
|
|
2702
|
+
defaultOpen,
|
|
2703
|
+
onOpenChange,
|
|
2704
|
+
children: [
|
|
2705
|
+
/* @__PURE__ */ jsx(Popover$1.Trigger, { render: trigger }),
|
|
2706
|
+
/* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
2707
|
+
Popover$1.Positioner,
|
|
2708
|
+
{
|
|
2709
|
+
side,
|
|
2710
|
+
align,
|
|
2711
|
+
className: "cb-popconfirm__positioner",
|
|
2712
|
+
children: /* @__PURE__ */ jsxs(
|
|
2713
|
+
Popover$1.Popup,
|
|
2714
|
+
{
|
|
2715
|
+
className: "cb-popconfirm",
|
|
2716
|
+
"data-tone": tone,
|
|
2717
|
+
"data-motion": motion3 ? void 0 : "off",
|
|
2718
|
+
"data-icon": hasIcon ? void 0 : "none",
|
|
2719
|
+
children: [
|
|
2720
|
+
/* @__PURE__ */ jsx(Popover$1.Arrow, { className: "cb-popconfirm__arrow", children: /* @__PURE__ */ jsx(ArrowShape, {}) }),
|
|
2721
|
+
hasIcon ? /* @__PURE__ */ jsx("span", { className: "cb-popconfirm__icon", "aria-hidden": "true", children: icon ?? /* @__PURE__ */ jsx(AlertTriangle, { size: 18 }) }) : null,
|
|
2722
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-popconfirm__content", children: [
|
|
2723
|
+
/* @__PURE__ */ jsx(Popover$1.Title, { className: "cb-popconfirm__title", children: title }),
|
|
2724
|
+
description ? /* @__PURE__ */ jsx(Popover$1.Description, { className: "cb-popconfirm__description", children: description }) : null,
|
|
2725
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-popconfirm__actions", children: [
|
|
2726
|
+
cancelAction ? /* @__PURE__ */ jsx(Popover$1.Close, { render: cancelAction }) : null,
|
|
2727
|
+
/* @__PURE__ */ jsx(Popover$1.Close, { render: confirmAction })
|
|
2728
|
+
] })
|
|
2729
|
+
] })
|
|
2730
|
+
]
|
|
2731
|
+
}
|
|
2732
|
+
)
|
|
2733
|
+
}
|
|
2734
|
+
) })
|
|
2735
|
+
]
|
|
2736
|
+
}
|
|
2737
|
+
);
|
|
2738
|
+
}
|
|
2739
|
+
var Popconfirm = Object.assign(PopconfirmRoot, {
|
|
2740
|
+
Skeleton: PopconfirmSkeleton
|
|
2741
|
+
});
|
|
1452
2742
|
function Tag({
|
|
1453
2743
|
children,
|
|
1454
2744
|
tone = "neutral",
|
|
@@ -1463,7 +2753,7 @@ function Tag({
|
|
|
1463
2753
|
}) {
|
|
1464
2754
|
const labels = useLabels();
|
|
1465
2755
|
const classes = cn("cb-badge", "cb-tag", `cb-badge--${variant}`, `cb-badge--${size}`, className);
|
|
1466
|
-
const body = /* @__PURE__ */ jsxs(Fragment
|
|
2756
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1467
2757
|
icon,
|
|
1468
2758
|
children
|
|
1469
2759
|
] });
|
|
@@ -1618,6 +2908,78 @@ function useToast() {
|
|
|
1618
2908
|
promise: manager.promise
|
|
1619
2909
|
};
|
|
1620
2910
|
}
|
|
2911
|
+
function WatermarkSkeleton({
|
|
2912
|
+
content = "Loading",
|
|
2913
|
+
tone = "neutral",
|
|
2914
|
+
density = "md",
|
|
2915
|
+
direction = "horizontal",
|
|
2916
|
+
lines = 3
|
|
2917
|
+
}) {
|
|
2918
|
+
return /* @__PURE__ */ jsxs(
|
|
2919
|
+
"div",
|
|
2920
|
+
{
|
|
2921
|
+
className: cn(
|
|
2922
|
+
"cb-watermark",
|
|
2923
|
+
"cb-watermark--skeleton",
|
|
2924
|
+
`cb-watermark--${density}`,
|
|
2925
|
+
`cb-watermark--${direction}`
|
|
2926
|
+
),
|
|
2927
|
+
"data-tone": tone,
|
|
2928
|
+
"aria-hidden": "true",
|
|
2929
|
+
children: [
|
|
2930
|
+
/* @__PURE__ */ jsx("div", { className: "cb-watermark__content", children: /* @__PURE__ */ jsx(Skeleton.Text, { lines }) }),
|
|
2931
|
+
/* @__PURE__ */ jsx(WatermarkMarks, { content, density, direction })
|
|
2932
|
+
]
|
|
2933
|
+
}
|
|
2934
|
+
);
|
|
2935
|
+
}
|
|
2936
|
+
function normalizeContent(content) {
|
|
2937
|
+
return Array.isArray(content) ? content.filter(Boolean) : [content];
|
|
2938
|
+
}
|
|
2939
|
+
function WatermarkMarks({
|
|
2940
|
+
content,
|
|
2941
|
+
density = "md",
|
|
2942
|
+
direction = "horizontal"
|
|
2943
|
+
}) {
|
|
2944
|
+
const marks = normalizeContent(content);
|
|
2945
|
+
const values = marks.length > 0 ? marks : [""];
|
|
2946
|
+
const id = `cb-watermark-pattern-${useId().replaceAll(":", "")}`;
|
|
2947
|
+
const vertical = direction === "vertical";
|
|
2948
|
+
return /* @__PURE__ */ jsxs("svg", { className: "cb-watermark__marks", "aria-hidden": "true", focusable: "false", children: [
|
|
2949
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
2950
|
+
"pattern",
|
|
2951
|
+
{
|
|
2952
|
+
className: "cb-watermark__pattern",
|
|
2953
|
+
id,
|
|
2954
|
+
patternUnits: "userSpaceOnUse",
|
|
2955
|
+
width: vertical ? "0.5em" : "1em",
|
|
2956
|
+
height: vertical ? "1em" : "0.5em",
|
|
2957
|
+
children: /* @__PURE__ */ jsx("text", { className: "cb-watermark__mark", x: "0", y: "0", dy: "1em", children: values.join(" \xB7 ") })
|
|
2958
|
+
}
|
|
2959
|
+
) }),
|
|
2960
|
+
/* @__PURE__ */ jsx("rect", { className: "cb-watermark__fill", width: "100%", height: "100%", fill: `url(#${id})` })
|
|
2961
|
+
] });
|
|
2962
|
+
}
|
|
2963
|
+
function WatermarkRoot({
|
|
2964
|
+
content,
|
|
2965
|
+
children,
|
|
2966
|
+
tone = "neutral",
|
|
2967
|
+
density = "md",
|
|
2968
|
+
direction = "horizontal"
|
|
2969
|
+
}) {
|
|
2970
|
+
return /* @__PURE__ */ jsxs(
|
|
2971
|
+
"div",
|
|
2972
|
+
{
|
|
2973
|
+
className: cn("cb-watermark", `cb-watermark--${density}`, `cb-watermark--${direction}`),
|
|
2974
|
+
"data-tone": tone,
|
|
2975
|
+
children: [
|
|
2976
|
+
/* @__PURE__ */ jsx("div", { className: "cb-watermark__content", children }),
|
|
2977
|
+
/* @__PURE__ */ jsx(WatermarkMarks, { content, density, direction })
|
|
2978
|
+
]
|
|
2979
|
+
}
|
|
2980
|
+
);
|
|
2981
|
+
}
|
|
2982
|
+
var Watermark = Object.assign(WatermarkRoot, { Skeleton: WatermarkSkeleton });
|
|
1621
2983
|
function Tabs({ items, value, defaultValue, onValueChange, variant = "underline", className }) {
|
|
1622
2984
|
return /* @__PURE__ */ jsxs(
|
|
1623
2985
|
Tabs$1.Root,
|
|
@@ -1641,22 +3003,22 @@ function Tabs({ items, value, defaultValue, onValueChange, variant = "underline"
|
|
|
1641
3003
|
}
|
|
1642
3004
|
function Dropdown({ trigger, items, sections, align = "end", side = "bottom", className }) {
|
|
1643
3005
|
const groups = sections ?? [{ items }];
|
|
1644
|
-
return /* @__PURE__ */ jsxs(Menu.Root, { children: [
|
|
1645
|
-
/* @__PURE__ */ jsx(Menu.Trigger, { render: trigger }),
|
|
1646
|
-
/* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(
|
|
1647
|
-
Menu.Positioner,
|
|
3006
|
+
return /* @__PURE__ */ jsxs(Menu$1.Root, { children: [
|
|
3007
|
+
/* @__PURE__ */ jsx(Menu$1.Trigger, { render: trigger }),
|
|
3008
|
+
/* @__PURE__ */ jsx(Menu$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
3009
|
+
Menu$1.Positioner,
|
|
1648
3010
|
{
|
|
1649
3011
|
side,
|
|
1650
3012
|
align,
|
|
1651
3013
|
sideOffset: 6,
|
|
1652
3014
|
className: "cb-menu-positioner",
|
|
1653
|
-
children: /* @__PURE__ */ jsx(Menu.Popup, { className: cn("cb-menu", className), children: groups.map((section, sectionIndex) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1654
|
-
sectionIndex > 0 ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }) : null,
|
|
1655
|
-
/* @__PURE__ */ jsxs(Menu.Group, { className: "cb-menu__group", children: [
|
|
1656
|
-
section.label ? /* @__PURE__ */ jsx(Menu.GroupLabel, { className: "cb-menu__group-label", children: section.label }) : null,
|
|
3015
|
+
children: /* @__PURE__ */ jsx(Menu$1.Popup, { className: cn("cb-menu", className), children: groups.map((section, sectionIndex) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3016
|
+
sectionIndex > 0 ? /* @__PURE__ */ jsx(Menu$1.Separator, { className: "cb-menu__separator" }) : null,
|
|
3017
|
+
/* @__PURE__ */ jsxs(Menu$1.Group, { className: "cb-menu__group", children: [
|
|
3018
|
+
section.label ? /* @__PURE__ */ jsx(Menu$1.GroupLabel, { className: "cb-menu__group-label", children: section.label }) : null,
|
|
1657
3019
|
section.items.map(
|
|
1658
|
-
(item, itemIndex) => item.separator ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }, `separator-${itemIndex}`) : /* @__PURE__ */ jsxs(
|
|
1659
|
-
Menu.Item,
|
|
3020
|
+
(item, itemIndex) => item.separator ? /* @__PURE__ */ jsx(Menu$1.Separator, { className: "cb-menu__separator" }, `separator-${itemIndex}`) : /* @__PURE__ */ jsxs(
|
|
3021
|
+
Menu$1.Item,
|
|
1660
3022
|
{
|
|
1661
3023
|
className: "cb-menu__item",
|
|
1662
3024
|
"data-tone": item.tone,
|
|
@@ -1677,6 +3039,156 @@ function Dropdown({ trigger, items, sections, align = "end", side = "bottom", cl
|
|
|
1677
3039
|
) })
|
|
1678
3040
|
] });
|
|
1679
3041
|
}
|
|
3042
|
+
function MenuSkeleton({
|
|
3043
|
+
items = 4,
|
|
3044
|
+
size = "md",
|
|
3045
|
+
tone = "brand",
|
|
3046
|
+
"aria-label": ariaLabel = "Loading navigation"
|
|
3047
|
+
}) {
|
|
3048
|
+
return /* @__PURE__ */ jsx(
|
|
3049
|
+
"nav",
|
|
3050
|
+
{
|
|
3051
|
+
"aria-label": ariaLabel,
|
|
3052
|
+
"aria-hidden": "true",
|
|
3053
|
+
className: cn("cb-persistent-menu", `cb-persistent-menu--${size}`, `cb-persistent-menu--${tone}`, "cb-persistent-menu--skeleton"),
|
|
3054
|
+
children: /* @__PURE__ */ jsx("ul", { className: "cb-persistent-menu__list", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsx("li", { className: "cb-persistent-menu__item", children: /* @__PURE__ */ jsx(Skeleton, { className: cn("cb-persistent-menu__skeleton-line", index % 3 === 0 && "cb-persistent-menu__skeleton-line--long") }) }, index)) })
|
|
3055
|
+
}
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
function MenuRoot({
|
|
3059
|
+
items,
|
|
3060
|
+
selectedPath,
|
|
3061
|
+
defaultSelectedPath,
|
|
3062
|
+
onSelectedPathChange,
|
|
3063
|
+
openKeys,
|
|
3064
|
+
defaultOpenKeys = [],
|
|
3065
|
+
onOpenKeysChange,
|
|
3066
|
+
size = "md",
|
|
3067
|
+
tone = "brand",
|
|
3068
|
+
motion: motion3 = true,
|
|
3069
|
+
"aria-label": ariaLabel = "Navigation"
|
|
3070
|
+
}) {
|
|
3071
|
+
const [uncontrolledSelectedPath, setUncontrolledSelectedPath] = useState(defaultSelectedPath);
|
|
3072
|
+
const [uncontrolledOpenKeys, setUncontrolledOpenKeys] = useState(defaultOpenKeys);
|
|
3073
|
+
const currentSelectedPath = selectedPath ?? uncontrolledSelectedPath;
|
|
3074
|
+
const currentOpenKeys = openKeys ?? uncontrolledOpenKeys;
|
|
3075
|
+
const menuId = useId();
|
|
3076
|
+
const select = (path) => {
|
|
3077
|
+
if (selectedPath === void 0) setUncontrolledSelectedPath(path);
|
|
3078
|
+
onSelectedPathChange?.(path);
|
|
3079
|
+
};
|
|
3080
|
+
const toggle = (key) => {
|
|
3081
|
+
const next = currentOpenKeys.includes(key) ? currentOpenKeys.filter((openKey) => openKey !== key) : [...currentOpenKeys, key];
|
|
3082
|
+
if (openKeys === void 0) setUncontrolledOpenKeys(next);
|
|
3083
|
+
onOpenKeysChange?.(next);
|
|
3084
|
+
};
|
|
3085
|
+
return /* @__PURE__ */ jsx(
|
|
3086
|
+
"nav",
|
|
3087
|
+
{
|
|
3088
|
+
"aria-label": ariaLabel,
|
|
3089
|
+
className: cn("cb-persistent-menu", `cb-persistent-menu--${size}`, `cb-persistent-menu--${tone}`, !motion3 && "cb-persistent-menu--motion-off"),
|
|
3090
|
+
children: /* @__PURE__ */ jsx(
|
|
3091
|
+
MenuList,
|
|
3092
|
+
{
|
|
3093
|
+
items,
|
|
3094
|
+
selectedPath: currentSelectedPath,
|
|
3095
|
+
openKeys: currentOpenKeys,
|
|
3096
|
+
path: [],
|
|
3097
|
+
menuId,
|
|
3098
|
+
onSelect: select,
|
|
3099
|
+
onToggle: toggle
|
|
3100
|
+
}
|
|
3101
|
+
)
|
|
3102
|
+
}
|
|
3103
|
+
);
|
|
3104
|
+
}
|
|
3105
|
+
function MenuList({ items, selectedPath, openKeys, path, menuId, nested = false, onSelect, onToggle }) {
|
|
3106
|
+
return /* @__PURE__ */ jsx("ul", { className: cn("cb-persistent-menu__list", nested && "cb-persistent-menu__list--nested"), children: items.map((item) => {
|
|
3107
|
+
const itemPath = [...path, item.key];
|
|
3108
|
+
const pathKey = pathIdentity(itemPath);
|
|
3109
|
+
const isBranch = "children" in item;
|
|
3110
|
+
const open = openKeys.includes(pathKey);
|
|
3111
|
+
const current = selectedPath === pathKey;
|
|
3112
|
+
const branchId = `${menuId}-${pathKey}`;
|
|
3113
|
+
return /* @__PURE__ */ jsxs("li", { className: "cb-persistent-menu__item", children: [
|
|
3114
|
+
/* @__PURE__ */ jsx("div", { className: "cb-persistent-menu__row", children: isBranch ? /* @__PURE__ */ jsx(MenuBranch, { item, open, branchId, onToggle: () => onToggle(pathKey) }) : /* @__PURE__ */ jsx(MenuEntry, { item, path: pathKey, current, onSelect }) }),
|
|
3115
|
+
isBranch && open ? /* @__PURE__ */ jsx("div", { id: branchId, className: "cb-persistent-menu__branch", children: /* @__PURE__ */ jsx(
|
|
3116
|
+
MenuList,
|
|
3117
|
+
{
|
|
3118
|
+
items: item.children,
|
|
3119
|
+
selectedPath,
|
|
3120
|
+
openKeys,
|
|
3121
|
+
path: itemPath,
|
|
3122
|
+
menuId,
|
|
3123
|
+
nested: true,
|
|
3124
|
+
onSelect,
|
|
3125
|
+
onToggle
|
|
3126
|
+
}
|
|
3127
|
+
) }) : null
|
|
3128
|
+
] }, item.key);
|
|
3129
|
+
}) });
|
|
3130
|
+
}
|
|
3131
|
+
function MenuEntry({
|
|
3132
|
+
item,
|
|
3133
|
+
path,
|
|
3134
|
+
current,
|
|
3135
|
+
onSelect
|
|
3136
|
+
}) {
|
|
3137
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3138
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: "cb-persistent-menu__icon", "aria-hidden": "true", children: item.icon }) : null,
|
|
3139
|
+
/* @__PURE__ */ jsx("span", { className: "cb-persistent-menu__label", children: item.label })
|
|
3140
|
+
] });
|
|
3141
|
+
const props = {
|
|
3142
|
+
className: "cb-persistent-menu__entry",
|
|
3143
|
+
"aria-current": current ? "page" : void 0,
|
|
3144
|
+
"aria-disabled": item.disabled || void 0,
|
|
3145
|
+
"data-current": current || void 0,
|
|
3146
|
+
"data-disabled": item.disabled || void 0
|
|
3147
|
+
};
|
|
3148
|
+
if (item.disabled) {
|
|
3149
|
+
return /* @__PURE__ */ jsx("span", { ...props, children: content });
|
|
3150
|
+
}
|
|
3151
|
+
return /* @__PURE__ */ jsx(
|
|
3152
|
+
"a",
|
|
3153
|
+
{
|
|
3154
|
+
href: item.href,
|
|
3155
|
+
...props,
|
|
3156
|
+
onClick: () => onSelect(path),
|
|
3157
|
+
children: content
|
|
3158
|
+
}
|
|
3159
|
+
);
|
|
3160
|
+
}
|
|
3161
|
+
function MenuBranch({
|
|
3162
|
+
item,
|
|
3163
|
+
open,
|
|
3164
|
+
branchId,
|
|
3165
|
+
onToggle
|
|
3166
|
+
}) {
|
|
3167
|
+
return /* @__PURE__ */ jsxs(
|
|
3168
|
+
"button",
|
|
3169
|
+
{
|
|
3170
|
+
type: "button",
|
|
3171
|
+
className: "cb-persistent-menu__branch-trigger",
|
|
3172
|
+
"aria-label": item.ariaLabel,
|
|
3173
|
+
"aria-expanded": open,
|
|
3174
|
+
"aria-controls": branchId,
|
|
3175
|
+
disabled: item.disabled,
|
|
3176
|
+
"data-open": open || void 0,
|
|
3177
|
+
"data-disabled": item.disabled || void 0,
|
|
3178
|
+
onClick: onToggle,
|
|
3179
|
+
children: [
|
|
3180
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: "cb-persistent-menu__icon", "aria-hidden": "true", children: item.icon }) : null,
|
|
3181
|
+
/* @__PURE__ */ jsx("span", { className: "cb-persistent-menu__label", children: item.label }),
|
|
3182
|
+
/* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true", className: "cb-persistent-menu__chevron cb-persistent-menu__chevron--collapsed" }),
|
|
3183
|
+
/* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true", className: "cb-persistent-menu__chevron cb-persistent-menu__chevron--expanded" })
|
|
3184
|
+
]
|
|
3185
|
+
}
|
|
3186
|
+
);
|
|
3187
|
+
}
|
|
3188
|
+
function pathIdentity(path) {
|
|
3189
|
+
return path.map(encodeURIComponent).join("/");
|
|
3190
|
+
}
|
|
3191
|
+
var Menu = Object.assign(MenuRoot, { Skeleton: MenuSkeleton });
|
|
1680
3192
|
var hasActiveChild = (item) => Boolean(item.items?.some((child) => child.active));
|
|
1681
3193
|
function Sidebar({ sections, header, footer, collapsed = false, onCollapsedChange, className }) {
|
|
1682
3194
|
const labels = useLabels();
|
|
@@ -1718,7 +3230,7 @@ function SidebarEntry({ item, collapsed }) {
|
|
|
1718
3230
|
if (collapsed) {
|
|
1719
3231
|
return /* @__PURE__ */ jsx(Flyout, { label: item.label, items: children, children: /* @__PURE__ */ jsx(SidebarRow, { item: { ...item, active: item.active || hasActiveChild(item) }, collapsed: true }) });
|
|
1720
3232
|
}
|
|
1721
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
3233
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1722
3234
|
/* @__PURE__ */ jsxs(
|
|
1723
3235
|
"button",
|
|
1724
3236
|
{
|
|
@@ -1739,7 +3251,7 @@ function SidebarEntry({ item, collapsed }) {
|
|
|
1739
3251
|
] });
|
|
1740
3252
|
}
|
|
1741
3253
|
function SidebarRow({ item, collapsed, nested }) {
|
|
1742
|
-
const content = /* @__PURE__ */ jsxs(Fragment
|
|
3254
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1743
3255
|
item.icon ? /* @__PURE__ */ jsx("span", { className: "cb-sidebar__icon", children: item.icon }) : null,
|
|
1744
3256
|
/* @__PURE__ */ jsx("span", { className: "cb-sidebar__label", children: item.label }),
|
|
1745
3257
|
item.adornment && !collapsed ? /* @__PURE__ */ jsx("span", { className: "cb-sidebar__adornment", children: item.adornment }) : null
|
|
@@ -1778,22 +3290,6 @@ function TopBar({ title, subtitle, center, actions, sticky = true, className })
|
|
|
1778
3290
|
actions ? /* @__PURE__ */ jsx("div", { className: "cb-topbar__actions", children: actions }) : null
|
|
1779
3291
|
] });
|
|
1780
3292
|
}
|
|
1781
|
-
function box({ width = "100%", height = "1rem", radius = "md", className }) {
|
|
1782
|
-
const style = { "--cb-skeleton-w": width, "--cb-skeleton-h": height };
|
|
1783
|
-
return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("cb-skeleton", `cb-radius--${radius}`, className), style });
|
|
1784
|
-
}
|
|
1785
|
-
function text({ lines = 3, lastLineWidth = "62%", className }) {
|
|
1786
|
-
return /* @__PURE__ */ jsx("span", { className: cn("cb-skeleton-text", className), children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx(SkeletonBox, { height: "0.75rem", width: i === lines - 1 ? lastLineWidth : "100%" }, i)) });
|
|
1787
|
-
}
|
|
1788
|
-
function circle({ size = "2.5rem", className }) {
|
|
1789
|
-
return /* @__PURE__ */ jsx(SkeletonBox, { width: size, height: size, radius: "full", className });
|
|
1790
|
-
}
|
|
1791
|
-
var SkeletonBox = box;
|
|
1792
|
-
var Skeleton = Object.assign(box, {
|
|
1793
|
-
Text: text,
|
|
1794
|
-
Circle: circle,
|
|
1795
|
-
Rect: box
|
|
1796
|
-
});
|
|
1797
3293
|
|
|
1798
3294
|
// src/data/table-sort.ts
|
|
1799
3295
|
function nextSort(current, column) {
|
|
@@ -1949,7 +3445,349 @@ function Pagination({
|
|
|
1949
3445
|
] })
|
|
1950
3446
|
] });
|
|
1951
3447
|
}
|
|
1952
|
-
function
|
|
3448
|
+
function CollapseSkeleton({
|
|
3449
|
+
items = 3,
|
|
3450
|
+
openItems = [0],
|
|
3451
|
+
lines = 2,
|
|
3452
|
+
size = "md",
|
|
3453
|
+
bordered = true,
|
|
3454
|
+
expandIconPosition = "start",
|
|
3455
|
+
className
|
|
3456
|
+
}) {
|
|
3457
|
+
const openSet = new Set(openItems);
|
|
3458
|
+
return /* @__PURE__ */ jsx(
|
|
3459
|
+
"div",
|
|
3460
|
+
{
|
|
3461
|
+
"aria-hidden": "true",
|
|
3462
|
+
className: cn(
|
|
3463
|
+
"cb-collapse",
|
|
3464
|
+
`cb-collapse--${size}`,
|
|
3465
|
+
"cb-collapse--skeleton",
|
|
3466
|
+
bordered && "cb-collapse--bordered",
|
|
3467
|
+
expandIconPosition === "end" && "cb-collapse--icon-end",
|
|
3468
|
+
className
|
|
3469
|
+
),
|
|
3470
|
+
children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs("div", { className: "cb-collapse__item", children: [
|
|
3471
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-collapse__trigger", children: [
|
|
3472
|
+
/* @__PURE__ */ jsx(Skeleton.Circle, { size: "1rem", className: "cb-collapse__icon" }),
|
|
3473
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "42%", height: "0.875rem", className: "cb-collapse__label" })
|
|
3474
|
+
] }),
|
|
3475
|
+
openSet.has(index) ? /* @__PURE__ */ jsx("div", { className: "cb-collapse__content", children: /* @__PURE__ */ jsx(Skeleton.Text, { lines }) }) : null
|
|
3476
|
+
] }, index))
|
|
3477
|
+
}
|
|
3478
|
+
);
|
|
3479
|
+
}
|
|
3480
|
+
function normalizeValue(value, multiple) {
|
|
3481
|
+
if (value == null) return void 0;
|
|
3482
|
+
if (Array.isArray(value)) return multiple ? value : value.slice(0, 1);
|
|
3483
|
+
return [value];
|
|
3484
|
+
}
|
|
3485
|
+
function CollapseRoot({
|
|
3486
|
+
items,
|
|
3487
|
+
value,
|
|
3488
|
+
defaultValue,
|
|
3489
|
+
onValueChange,
|
|
3490
|
+
multiple = false,
|
|
3491
|
+
size = "md",
|
|
3492
|
+
bordered = true,
|
|
3493
|
+
expandIconPosition = "start",
|
|
3494
|
+
headingLevel = 3,
|
|
3495
|
+
disabled = false,
|
|
3496
|
+
keepMounted = false,
|
|
3497
|
+
hiddenUntilFound = false,
|
|
3498
|
+
motion: motion3 = true,
|
|
3499
|
+
className
|
|
3500
|
+
}) {
|
|
3501
|
+
const Heading = `h${headingLevel}`;
|
|
3502
|
+
return /* @__PURE__ */ jsx(
|
|
3503
|
+
Accordion.Root,
|
|
3504
|
+
{
|
|
3505
|
+
value: normalizeValue(value, multiple),
|
|
3506
|
+
defaultValue: normalizeValue(defaultValue, multiple),
|
|
3507
|
+
onValueChange: (next) => onValueChange?.(multiple ? next.map(String) : next[0] == null ? void 0 : String(next[0])),
|
|
3508
|
+
multiple,
|
|
3509
|
+
disabled,
|
|
3510
|
+
keepMounted: hiddenUntilFound ? void 0 : keepMounted,
|
|
3511
|
+
hiddenUntilFound,
|
|
3512
|
+
className: cn(
|
|
3513
|
+
"cb-collapse",
|
|
3514
|
+
`cb-collapse--${size}`,
|
|
3515
|
+
bordered && "cb-collapse--bordered",
|
|
3516
|
+
expandIconPosition === "end" && "cb-collapse--icon-end",
|
|
3517
|
+
!motion3 && "cb-collapse--motionless",
|
|
3518
|
+
className
|
|
3519
|
+
),
|
|
3520
|
+
children: items.map((item) => /* @__PURE__ */ jsxs(
|
|
3521
|
+
Accordion.Item,
|
|
3522
|
+
{
|
|
3523
|
+
value: item.key,
|
|
3524
|
+
disabled: item.disabled,
|
|
3525
|
+
className: "cb-collapse__item",
|
|
3526
|
+
children: [
|
|
3527
|
+
/* @__PURE__ */ jsx(Accordion.Header, { render: /* @__PURE__ */ jsx(Heading, { className: "cb-collapse__heading" }), children: /* @__PURE__ */ jsxs(Accordion.Trigger, { className: "cb-collapse__trigger", children: [
|
|
3528
|
+
/* @__PURE__ */ jsx("span", { className: "cb-collapse__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronDown, {}) }),
|
|
3529
|
+
/* @__PURE__ */ jsx("span", { className: "cb-collapse__label", children: item.label })
|
|
3530
|
+
] }) }),
|
|
3531
|
+
/* @__PURE__ */ jsx(Accordion.Panel, { className: "cb-collapse__panel", children: /* @__PURE__ */ jsx("div", { className: "cb-collapse__content", children: item.children }) })
|
|
3532
|
+
]
|
|
3533
|
+
},
|
|
3534
|
+
item.key
|
|
3535
|
+
))
|
|
3536
|
+
}
|
|
3537
|
+
);
|
|
3538
|
+
}
|
|
3539
|
+
var Collapse = Object.assign(CollapseRoot, {
|
|
3540
|
+
Skeleton: CollapseSkeleton
|
|
3541
|
+
});
|
|
3542
|
+
function CalendarSkeleton({ weekStartsOn = 1 }) {
|
|
3543
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-calendar cb-calendar--skeleton", "aria-hidden": "true", "data-week-starts-on": weekStartsOn, children: [
|
|
3544
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-calendar__header", children: [
|
|
3545
|
+
/* @__PURE__ */ jsx(Skeleton.Circle, { size: "var(--cb-control-height-sm)" }),
|
|
3546
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "42%", height: "var(--cb-text-sm)" }),
|
|
3547
|
+
/* @__PURE__ */ jsx(Skeleton.Circle, { size: "var(--cb-control-height-sm)" })
|
|
3548
|
+
] }),
|
|
3549
|
+
/* @__PURE__ */ jsx("div", { className: "cb-calendar__weekdays", children: Array.from({ length: 7 }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { width: "60%", height: "var(--cb-text-xs)" }, index)) }),
|
|
3550
|
+
/* @__PURE__ */ jsx("div", { className: "cb-calendar__grid", children: Array.from({ length: 42 }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { className: "cb-calendar__skeleton-day" }, index)) })
|
|
3551
|
+
] });
|
|
3552
|
+
}
|
|
3553
|
+
function isUsableDate(value) {
|
|
3554
|
+
return value instanceof Date && Number.isFinite(value.getTime());
|
|
3555
|
+
}
|
|
3556
|
+
function calendarDay(value) {
|
|
3557
|
+
return new Date(value.getFullYear(), value.getMonth(), value.getDate());
|
|
3558
|
+
}
|
|
3559
|
+
function sameDay(left, right) {
|
|
3560
|
+
return Boolean(left && right && left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate());
|
|
3561
|
+
}
|
|
3562
|
+
function sameMonth(left, right) {
|
|
3563
|
+
return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth();
|
|
3564
|
+
}
|
|
3565
|
+
function dateKey(date) {
|
|
3566
|
+
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
3567
|
+
}
|
|
3568
|
+
function addDays(date, amount) {
|
|
3569
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount);
|
|
3570
|
+
}
|
|
3571
|
+
function addMonths(date, amount) {
|
|
3572
|
+
const targetYear = date.getFullYear();
|
|
3573
|
+
const targetMonth = date.getMonth() + amount;
|
|
3574
|
+
const lastDay = new Date(targetYear, targetMonth + 1, 0).getDate();
|
|
3575
|
+
return new Date(targetYear, targetMonth, Math.min(date.getDate(), lastDay));
|
|
3576
|
+
}
|
|
3577
|
+
function isDisabled(date, minDate, maxDate, disabledDate) {
|
|
3578
|
+
const day = calendarDay(date);
|
|
3579
|
+
return isUsableDate(minDate) && day < calendarDay(minDate) || isUsableDate(maxDate) && day > calendarDay(maxDate) || disabledDate?.(day) === true;
|
|
3580
|
+
}
|
|
3581
|
+
function monthCells(month, weekStartsOn) {
|
|
3582
|
+
const first = new Date(month.getFullYear(), month.getMonth(), 1);
|
|
3583
|
+
const leadingDays = (first.getDay() - weekStartsOn + 7) % 7;
|
|
3584
|
+
const start = addDays(first, -leadingDays);
|
|
3585
|
+
return Array.from({ length: 42 }, (_, index) => addDays(start, index));
|
|
3586
|
+
}
|
|
3587
|
+
function firstEnabledDate(month, weekStartsOn, minDate, maxDate, disabledDate) {
|
|
3588
|
+
const cells = monthCells(month, weekStartsOn);
|
|
3589
|
+
return cells.find((date) => sameMonth(date, month) && !isDisabled(date, minDate, maxDate, disabledDate)) ?? cells.find((date) => !isDisabled(date, minDate, maxDate, disabledDate));
|
|
3590
|
+
}
|
|
3591
|
+
function CalendarRoot({
|
|
3592
|
+
value,
|
|
3593
|
+
defaultValue = null,
|
|
3594
|
+
onValueChange,
|
|
3595
|
+
month,
|
|
3596
|
+
defaultMonth,
|
|
3597
|
+
onMonthChange,
|
|
3598
|
+
minDate,
|
|
3599
|
+
maxDate,
|
|
3600
|
+
disabledDate,
|
|
3601
|
+
renderDay,
|
|
3602
|
+
locale,
|
|
3603
|
+
weekStartsOn = 1,
|
|
3604
|
+
disabled = false
|
|
3605
|
+
}) {
|
|
3606
|
+
const labels = useLabels();
|
|
3607
|
+
const headingId = useId();
|
|
3608
|
+
const rootRef = useRef(null);
|
|
3609
|
+
const focusKeyRef = useRef(void 0);
|
|
3610
|
+
const today = useMemo(() => calendarDay(/* @__PURE__ */ new Date()), []);
|
|
3611
|
+
const controlledValue = value !== void 0;
|
|
3612
|
+
const [internalValue, setInternalValue] = useState(() => isUsableDate(defaultValue) && !isDisabled(defaultValue, minDate, maxDate, disabledDate) ? calendarDay(defaultValue) : null);
|
|
3613
|
+
const requestedValue = controlledValue ? value : internalValue;
|
|
3614
|
+
const selected = isUsableDate(requestedValue) && !isDisabled(requestedValue, minDate, maxDate, disabledDate) ? calendarDay(requestedValue) : null;
|
|
3615
|
+
const controlledMonth = month !== void 0;
|
|
3616
|
+
const [internalMonth, setInternalMonth] = useState(() => {
|
|
3617
|
+
const initial = isUsableDate(defaultMonth) ? defaultMonth : selected ?? today;
|
|
3618
|
+
return new Date(initial.getFullYear(), initial.getMonth(), 1);
|
|
3619
|
+
});
|
|
3620
|
+
const displayedMonth = controlledMonth && isUsableDate(month) ? new Date(month.getFullYear(), month.getMonth(), 1) : internalMonth;
|
|
3621
|
+
const [activeDate, setActiveDate] = useState(() => selected && sameMonth(selected, displayedMonth) ? selected : firstEnabledDate(displayedMonth, weekStartsOn, minDate, maxDate, disabledDate) ?? displayedMonth);
|
|
3622
|
+
const cells = useMemo(() => monthCells(displayedMonth, weekStartsOn), [displayedMonth, weekStartsOn]);
|
|
3623
|
+
const rovingDate = cells.some((date) => sameDay(date, activeDate) && !isDisabled(date, minDate, maxDate, disabledDate)) ? activeDate : firstEnabledDate(displayedMonth, weekStartsOn, minDate, maxDate, disabledDate);
|
|
3624
|
+
const weekdayFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: "short" }), [locale]);
|
|
3625
|
+
const fullDateFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { dateStyle: "full" }), [locale]);
|
|
3626
|
+
const monthFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }), [locale]);
|
|
3627
|
+
const weekdayDates = useMemo(() => Array.from({ length: 7 }, (_, index) => new Date(2023, 0, 1 + (weekStartsOn + index) % 7)), [weekStartsOn]);
|
|
3628
|
+
const controlledMonthKey = controlledMonth ? dateKey(displayedMonth) : void 0;
|
|
3629
|
+
const controlledValueKey = controlledValue && selected ? dateKey(selected) : void 0;
|
|
3630
|
+
const previousControlledMonthKey = useRef(controlledMonthKey);
|
|
3631
|
+
const previousControlledValueKey = useRef(controlledValueKey);
|
|
3632
|
+
useEffect(() => {
|
|
3633
|
+
const monthChanged = controlledMonth && previousControlledMonthKey.current !== controlledMonthKey;
|
|
3634
|
+
const valueChanged = controlledValue && previousControlledValueKey.current !== controlledValueKey;
|
|
3635
|
+
previousControlledMonthKey.current = controlledMonthKey;
|
|
3636
|
+
previousControlledValueKey.current = controlledValueKey;
|
|
3637
|
+
if (!monthChanged && !valueChanged) return;
|
|
3638
|
+
const next = selected && sameMonth(selected, displayedMonth) ? selected : firstEnabledDate(displayedMonth, weekStartsOn, minDate, maxDate, disabledDate);
|
|
3639
|
+
if (next) setActiveDate(next);
|
|
3640
|
+
}, [controlledMonth, controlledMonthKey, controlledValue, controlledValueKey, disabledDate, displayedMonth, maxDate, minDate, selected, weekStartsOn]);
|
|
3641
|
+
useEffect(() => {
|
|
3642
|
+
const key = focusKeyRef.current;
|
|
3643
|
+
if (!key) return;
|
|
3644
|
+
const target = rootRef.current?.querySelector(`[data-date-key="${key}"]`);
|
|
3645
|
+
if (target) target.focus();
|
|
3646
|
+
focusKeyRef.current = void 0;
|
|
3647
|
+
}, [displayedMonth, activeDate]);
|
|
3648
|
+
const changeMonth = (next) => {
|
|
3649
|
+
const normalized = new Date(next.getFullYear(), next.getMonth(), 1);
|
|
3650
|
+
if (!controlledMonth) setInternalMonth(normalized);
|
|
3651
|
+
onMonthChange?.(normalized);
|
|
3652
|
+
};
|
|
3653
|
+
const setActive = (next, shouldFocus = false) => {
|
|
3654
|
+
const normalized = calendarDay(next);
|
|
3655
|
+
const enabled = isDisabled(normalized, minDate, maxDate, disabledDate) ? firstEnabledDate(normalized, weekStartsOn, minDate, maxDate, disabledDate) : normalized;
|
|
3656
|
+
if (!enabled) return;
|
|
3657
|
+
setActiveDate(enabled);
|
|
3658
|
+
if (!sameMonth(enabled, displayedMonth)) changeMonth(enabled);
|
|
3659
|
+
if (shouldFocus) focusKeyRef.current = dateKey(enabled);
|
|
3660
|
+
};
|
|
3661
|
+
const select = (next) => {
|
|
3662
|
+
if (disabled || isDisabled(next, minDate, maxDate, disabledDate)) return;
|
|
3663
|
+
const normalized = calendarDay(next);
|
|
3664
|
+
if (!controlledValue) setInternalValue(normalized);
|
|
3665
|
+
onValueChange?.(normalized);
|
|
3666
|
+
setActive(normalized);
|
|
3667
|
+
};
|
|
3668
|
+
const handleKeyDown = (event, current) => {
|
|
3669
|
+
if (disabled) return;
|
|
3670
|
+
const moveFromCurrent = (amount) => {
|
|
3671
|
+
const direction = Math.sign(amount);
|
|
3672
|
+
let candidate = addDays(current, amount);
|
|
3673
|
+
for (let attempts = 0; attempts < 366 && isDisabled(candidate, minDate, maxDate, disabledDate); attempts += 1) {
|
|
3674
|
+
candidate = addDays(candidate, direction || 1);
|
|
3675
|
+
}
|
|
3676
|
+
if (!isDisabled(candidate, minDate, maxDate, disabledDate)) setActive(candidate, true);
|
|
3677
|
+
};
|
|
3678
|
+
if (event.key === "ArrowLeft") {
|
|
3679
|
+
event.preventDefault();
|
|
3680
|
+
moveFromCurrent(-1);
|
|
3681
|
+
} else if (event.key === "ArrowRight") {
|
|
3682
|
+
event.preventDefault();
|
|
3683
|
+
moveFromCurrent(1);
|
|
3684
|
+
} else if (event.key === "ArrowUp") {
|
|
3685
|
+
event.preventDefault();
|
|
3686
|
+
moveFromCurrent(-7);
|
|
3687
|
+
} else if (event.key === "ArrowDown") {
|
|
3688
|
+
event.preventDefault();
|
|
3689
|
+
moveFromCurrent(7);
|
|
3690
|
+
} else if (event.key === "Home") {
|
|
3691
|
+
event.preventDefault();
|
|
3692
|
+
moveFromCurrent(-((current.getDay() - weekStartsOn + 7) % 7));
|
|
3693
|
+
} else if (event.key === "End") {
|
|
3694
|
+
event.preventDefault();
|
|
3695
|
+
moveFromCurrent(6 - (current.getDay() - weekStartsOn + 7) % 7);
|
|
3696
|
+
} else if (event.key === "PageUp") {
|
|
3697
|
+
event.preventDefault();
|
|
3698
|
+
setActive(addMonths(current, event.shiftKey ? -12 : -1), true);
|
|
3699
|
+
} else if (event.key === "PageDown") {
|
|
3700
|
+
event.preventDefault();
|
|
3701
|
+
setActive(addMonths(current, event.shiftKey ? 12 : 1), true);
|
|
3702
|
+
} else if (event.key === "Enter" || event.key === " ") {
|
|
3703
|
+
event.preventDefault();
|
|
3704
|
+
select(current);
|
|
3705
|
+
}
|
|
3706
|
+
};
|
|
3707
|
+
return /* @__PURE__ */ jsxs("section", { ref: rootRef, className: "cb-calendar", "aria-label": monthFormatter.format(displayedMonth), "data-disabled": disabled || void 0, children: [
|
|
3708
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-calendar__header", children: [
|
|
3709
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "cb-calendar__nav", onClick: () => changeMonth(addMonths(displayedMonth, -1)), disabled, "aria-label": labels.previousMonth, children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" }) }),
|
|
3710
|
+
/* @__PURE__ */ jsx("h2", { className: "cb-calendar__month", id: headingId, "aria-live": "polite", children: monthFormatter.format(displayedMonth) }),
|
|
3711
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "cb-calendar__nav", onClick: () => changeMonth(addMonths(displayedMonth, 1)), disabled, "aria-label": labels.nextMonth, children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" }) })
|
|
3712
|
+
] }),
|
|
3713
|
+
/* @__PURE__ */ jsx("div", { className: "cb-calendar__weekdays", "aria-hidden": "true", children: weekdayDates.map((date) => /* @__PURE__ */ jsx("span", { children: weekdayFormatter.format(date) }, date.getDay())) }),
|
|
3714
|
+
/* @__PURE__ */ jsx("div", { className: "cb-calendar__grid", role: "grid", "aria-labelledby": headingId, children: Array.from({ length: 6 }, (_, weekIndex) => /* @__PURE__ */ jsx("div", { className: "cb-calendar__week", role: "row", children: cells.slice(weekIndex * 7, weekIndex * 7 + 7).map((date) => {
|
|
3715
|
+
const unavailable = disabled || isDisabled(date, minDate, maxDate, disabledDate);
|
|
3716
|
+
const day = { date, inMonth: sameMonth(date, displayedMonth), selected: sameDay(date, selected), today: sameDay(date, today), disabled: unavailable };
|
|
3717
|
+
const active = sameDay(date, rovingDate) && !unavailable;
|
|
3718
|
+
return /* @__PURE__ */ jsx("div", { role: "gridcell", className: "cb-calendar__cell", "aria-selected": day.selected || void 0, children: /* @__PURE__ */ jsx(
|
|
3719
|
+
"button",
|
|
3720
|
+
{
|
|
3721
|
+
type: "button",
|
|
3722
|
+
className: "cb-calendar__day",
|
|
3723
|
+
"data-date-key": dateKey(date),
|
|
3724
|
+
"data-outside": !day.inMonth || void 0,
|
|
3725
|
+
"data-selected": day.selected || void 0,
|
|
3726
|
+
"data-today": day.today || void 0,
|
|
3727
|
+
disabled: unavailable,
|
|
3728
|
+
tabIndex: active ? 0 : -1,
|
|
3729
|
+
"aria-label": fullDateFormatter.format(date),
|
|
3730
|
+
"aria-pressed": day.selected,
|
|
3731
|
+
onFocus: () => setActiveDate(date),
|
|
3732
|
+
onClick: () => select(date),
|
|
3733
|
+
onKeyDown: (event) => handleKeyDown(event, date),
|
|
3734
|
+
children: renderDay ? renderDay(day) : date.getDate()
|
|
3735
|
+
}
|
|
3736
|
+
) }, dateKey(date));
|
|
3737
|
+
}) }, weekIndex)) })
|
|
3738
|
+
] });
|
|
3739
|
+
}
|
|
3740
|
+
var Calendar = Object.assign(CalendarRoot, { Skeleton: CalendarSkeleton });
|
|
3741
|
+
function ImageSkeleton({
|
|
3742
|
+
aspectRatio,
|
|
3743
|
+
radius = "md",
|
|
3744
|
+
className
|
|
3745
|
+
}) {
|
|
3746
|
+
return /* @__PURE__ */ jsx(
|
|
3747
|
+
"span",
|
|
3748
|
+
{
|
|
3749
|
+
className: cn(
|
|
3750
|
+
"cb-image cb-image--skeleton",
|
|
3751
|
+
`cb-radius--${radius}`,
|
|
3752
|
+
className
|
|
3753
|
+
),
|
|
3754
|
+
style: aspectRatio ? { aspectRatio: String(aspectRatio) } : void 0,
|
|
3755
|
+
"aria-hidden": "true",
|
|
3756
|
+
children: /* @__PURE__ */ jsx(
|
|
3757
|
+
Skeleton,
|
|
3758
|
+
{
|
|
3759
|
+
className: "cb-image__skeleton-shape",
|
|
3760
|
+
width: "100%",
|
|
3761
|
+
height: "100%",
|
|
3762
|
+
radius: "md"
|
|
3763
|
+
}
|
|
3764
|
+
)
|
|
3765
|
+
}
|
|
3766
|
+
);
|
|
3767
|
+
}
|
|
3768
|
+
function ImagePreviewGroupSkeleton({
|
|
3769
|
+
items = 3,
|
|
3770
|
+
aspectRatio,
|
|
3771
|
+
radius = "md",
|
|
3772
|
+
className
|
|
3773
|
+
}) {
|
|
3774
|
+
return /* @__PURE__ */ jsx(
|
|
3775
|
+
"div",
|
|
3776
|
+
{
|
|
3777
|
+
className: cn("cb-image-preview-group cb-image-preview-group--skeleton", className),
|
|
3778
|
+
"aria-hidden": "true",
|
|
3779
|
+
children: Array.from({ length: Math.max(0, items) }, (_, itemIndex) => /* @__PURE__ */ jsx(
|
|
3780
|
+
ImageSkeleton,
|
|
3781
|
+
{
|
|
3782
|
+
aspectRatio,
|
|
3783
|
+
radius
|
|
3784
|
+
},
|
|
3785
|
+
itemIndex
|
|
3786
|
+
))
|
|
3787
|
+
}
|
|
3788
|
+
);
|
|
3789
|
+
}
|
|
3790
|
+
function ImageRoot({
|
|
1953
3791
|
src,
|
|
1954
3792
|
alt,
|
|
1955
3793
|
aspectRatio,
|
|
@@ -1958,6 +3796,7 @@ function Image({
|
|
|
1958
3796
|
fit = "cover",
|
|
1959
3797
|
radius = "md",
|
|
1960
3798
|
loading = "lazy",
|
|
3799
|
+
motion: motion3 = true,
|
|
1961
3800
|
className
|
|
1962
3801
|
}) {
|
|
1963
3802
|
const [loaded, setLoaded] = useState(false);
|
|
@@ -1972,6 +3811,7 @@ function Image({
|
|
|
1972
3811
|
className: cn("cb-image", `cb-radius--${radius}`, className),
|
|
1973
3812
|
"data-loaded": loaded || void 0,
|
|
1974
3813
|
"data-blurred": blurDataUrl ? "" : void 0,
|
|
3814
|
+
"data-motion": motion3 ? void 0 : "off",
|
|
1975
3815
|
style,
|
|
1976
3816
|
children: /* @__PURE__ */ jsx(
|
|
1977
3817
|
"img",
|
|
@@ -1991,6 +3831,208 @@ function Image({
|
|
|
1991
3831
|
}
|
|
1992
3832
|
);
|
|
1993
3833
|
}
|
|
3834
|
+
var DEFAULT_PREVIEW_LABELS = {
|
|
3835
|
+
close: "Close preview",
|
|
3836
|
+
previous: "Previous image",
|
|
3837
|
+
next: "Next image",
|
|
3838
|
+
zoomIn: "Zoom in",
|
|
3839
|
+
zoomOut: "Zoom out",
|
|
3840
|
+
resetZoom: "Reset zoom",
|
|
3841
|
+
open: (item) => `Preview ${item.alt || "image"}`,
|
|
3842
|
+
position: (current, total) => `Image ${current} of ${total}`
|
|
3843
|
+
};
|
|
3844
|
+
function clampIndex(index, length) {
|
|
3845
|
+
return Math.max(0, Math.min(index, Math.max(length - 1, 0)));
|
|
3846
|
+
}
|
|
3847
|
+
function ImagePreviewGroupRoot({
|
|
3848
|
+
items,
|
|
3849
|
+
label,
|
|
3850
|
+
open,
|
|
3851
|
+
defaultOpen = false,
|
|
3852
|
+
onOpenChange,
|
|
3853
|
+
index,
|
|
3854
|
+
defaultIndex = 0,
|
|
3855
|
+
onIndexChange,
|
|
3856
|
+
loop = false,
|
|
3857
|
+
labels: labelOverrides,
|
|
3858
|
+
motion: motion3 = true,
|
|
3859
|
+
className
|
|
3860
|
+
}) {
|
|
3861
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen);
|
|
3862
|
+
const [internalIndex, setInternalIndex] = useState(
|
|
3863
|
+
() => clampIndex(defaultIndex, items.length)
|
|
3864
|
+
);
|
|
3865
|
+
const [scale, setScale] = useState(1);
|
|
3866
|
+
const isOpen = open ?? internalOpen;
|
|
3867
|
+
const selectedIndex = clampIndex(index ?? internalIndex, items.length);
|
|
3868
|
+
const selectedItem = items[selectedIndex];
|
|
3869
|
+
const labels = useMemo(
|
|
3870
|
+
() => ({ ...DEFAULT_PREVIEW_LABELS, ...labelOverrides }),
|
|
3871
|
+
[labelOverrides]
|
|
3872
|
+
);
|
|
3873
|
+
const changeOpen = (nextOpen) => {
|
|
3874
|
+
if (open === void 0) setInternalOpen(nextOpen);
|
|
3875
|
+
if (!nextOpen) setScale(1);
|
|
3876
|
+
onOpenChange?.(nextOpen);
|
|
3877
|
+
};
|
|
3878
|
+
const changeIndex = (nextIndex) => {
|
|
3879
|
+
if (items.length === 0) return;
|
|
3880
|
+
const next = loop ? (nextIndex + items.length) % items.length : clampIndex(nextIndex, items.length);
|
|
3881
|
+
if (index === void 0) setInternalIndex(next);
|
|
3882
|
+
setScale(1);
|
|
3883
|
+
onIndexChange?.(next);
|
|
3884
|
+
};
|
|
3885
|
+
useEffect(() => {
|
|
3886
|
+
if (selectedIndex !== (index ?? internalIndex) && index === void 0) {
|
|
3887
|
+
setInternalIndex(selectedIndex);
|
|
3888
|
+
}
|
|
3889
|
+
}, [index, internalIndex, selectedIndex]);
|
|
3890
|
+
const canGoPrevious = loop && items.length > 1 || selectedIndex > 0;
|
|
3891
|
+
const canGoNext = loop && items.length > 1 || selectedIndex < items.length - 1;
|
|
3892
|
+
const zoomIn = () => setScale((current) => Math.min(3, current + 0.5));
|
|
3893
|
+
const zoomOut = () => setScale((current) => Math.max(1, current - 0.5));
|
|
3894
|
+
const onPreviewKeyDown = (event) => {
|
|
3895
|
+
if (event.key === "ArrowLeft" && canGoPrevious)
|
|
3896
|
+
changeIndex(selectedIndex - 1);
|
|
3897
|
+
else if (event.key === "ArrowRight" && canGoNext)
|
|
3898
|
+
changeIndex(selectedIndex + 1);
|
|
3899
|
+
else if (event.key === "+" || event.key === "=") zoomIn();
|
|
3900
|
+
else if (event.key === "-") zoomOut();
|
|
3901
|
+
else if (event.key === "0") setScale(1);
|
|
3902
|
+
else if (event.key === "Home") changeIndex(0);
|
|
3903
|
+
else if (event.key === "End") changeIndex(items.length - 1);
|
|
3904
|
+
else return;
|
|
3905
|
+
event.preventDefault();
|
|
3906
|
+
};
|
|
3907
|
+
return /* @__PURE__ */ jsxs(Dialog.Root, { open: isOpen, onOpenChange: changeOpen, children: [
|
|
3908
|
+
/* @__PURE__ */ jsx(
|
|
3909
|
+
"div",
|
|
3910
|
+
{
|
|
3911
|
+
className: cn("cb-image-preview-group", className),
|
|
3912
|
+
role: "group",
|
|
3913
|
+
"aria-label": label,
|
|
3914
|
+
children: items.map((item, itemIndex) => {
|
|
3915
|
+
const {
|
|
3916
|
+
id,
|
|
3917
|
+
previewSrc: _previewSrc,
|
|
3918
|
+
caption: _caption,
|
|
3919
|
+
...imageProps
|
|
3920
|
+
} = item;
|
|
3921
|
+
return /* @__PURE__ */ jsx(
|
|
3922
|
+
Dialog.Trigger,
|
|
3923
|
+
{
|
|
3924
|
+
className: "cb-image-preview-group__trigger",
|
|
3925
|
+
"aria-label": labels.open(item, itemIndex),
|
|
3926
|
+
onClick: () => changeIndex(itemIndex),
|
|
3927
|
+
children: /* @__PURE__ */ jsx(ImageRoot, { ...imageProps })
|
|
3928
|
+
},
|
|
3929
|
+
id
|
|
3930
|
+
);
|
|
3931
|
+
})
|
|
3932
|
+
}
|
|
3933
|
+
),
|
|
3934
|
+
/* @__PURE__ */ jsx(Dialog.Portal, { children: selectedItem ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3935
|
+
/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-image-preview__backdrop" }),
|
|
3936
|
+
/* @__PURE__ */ jsxs(
|
|
3937
|
+
Dialog.Popup,
|
|
3938
|
+
{
|
|
3939
|
+
className: "cb-image-preview",
|
|
3940
|
+
"data-motion": motion3 ? void 0 : "off",
|
|
3941
|
+
onKeyDown: onPreviewKeyDown,
|
|
3942
|
+
children: [
|
|
3943
|
+
/* @__PURE__ */ jsx(Dialog.Title, { className: "cb-image-preview__sr-title", children: labels.position(selectedIndex + 1, items.length) }),
|
|
3944
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-image-preview__toolbar", children: [
|
|
3945
|
+
/* @__PURE__ */ jsx("span", { className: "cb-image-preview__position", "aria-live": "polite", children: labels.position(selectedIndex + 1, items.length) }),
|
|
3946
|
+
/* @__PURE__ */ jsx(
|
|
3947
|
+
"button",
|
|
3948
|
+
{
|
|
3949
|
+
type: "button",
|
|
3950
|
+
className: "cb-image-preview__control",
|
|
3951
|
+
"aria-label": labels.zoomOut,
|
|
3952
|
+
disabled: scale === 1,
|
|
3953
|
+
onClick: zoomOut,
|
|
3954
|
+
children: /* @__PURE__ */ jsx(ZoomOut, { "aria-hidden": "true" })
|
|
3955
|
+
}
|
|
3956
|
+
),
|
|
3957
|
+
/* @__PURE__ */ jsx(
|
|
3958
|
+
"button",
|
|
3959
|
+
{
|
|
3960
|
+
type: "button",
|
|
3961
|
+
className: "cb-image-preview__control",
|
|
3962
|
+
"aria-label": labels.resetZoom,
|
|
3963
|
+
disabled: scale === 1,
|
|
3964
|
+
onClick: () => setScale(1),
|
|
3965
|
+
children: /* @__PURE__ */ jsx(RotateCcw, { "aria-hidden": "true" })
|
|
3966
|
+
}
|
|
3967
|
+
),
|
|
3968
|
+
/* @__PURE__ */ jsx(
|
|
3969
|
+
"button",
|
|
3970
|
+
{
|
|
3971
|
+
type: "button",
|
|
3972
|
+
className: "cb-image-preview__control",
|
|
3973
|
+
"aria-label": labels.zoomIn,
|
|
3974
|
+
disabled: scale === 3,
|
|
3975
|
+
onClick: zoomIn,
|
|
3976
|
+
children: /* @__PURE__ */ jsx(ZoomIn, { "aria-hidden": "true" })
|
|
3977
|
+
}
|
|
3978
|
+
),
|
|
3979
|
+
/* @__PURE__ */ jsx(
|
|
3980
|
+
Dialog.Close,
|
|
3981
|
+
{
|
|
3982
|
+
className: "cb-image-preview__control",
|
|
3983
|
+
"aria-label": labels.close,
|
|
3984
|
+
children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
|
|
3985
|
+
}
|
|
3986
|
+
)
|
|
3987
|
+
] }),
|
|
3988
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-image-preview__stage", children: [
|
|
3989
|
+
/* @__PURE__ */ jsx(
|
|
3990
|
+
"button",
|
|
3991
|
+
{
|
|
3992
|
+
type: "button",
|
|
3993
|
+
className: "cb-image-preview__navigation cb-image-preview__navigation--previous",
|
|
3994
|
+
"aria-label": labels.previous,
|
|
3995
|
+
disabled: !canGoPrevious,
|
|
3996
|
+
onClick: () => changeIndex(selectedIndex - 1),
|
|
3997
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
|
|
3998
|
+
}
|
|
3999
|
+
),
|
|
4000
|
+
/* @__PURE__ */ jsx(
|
|
4001
|
+
"img",
|
|
4002
|
+
{
|
|
4003
|
+
className: "cb-image-preview__image",
|
|
4004
|
+
src: selectedItem.previewSrc ?? selectedItem.src,
|
|
4005
|
+
alt: selectedItem.alt,
|
|
4006
|
+
style: { "--cb-image-preview-scale": scale },
|
|
4007
|
+
onDoubleClick: () => setScale((current) => current === 1 ? 2 : 1)
|
|
4008
|
+
},
|
|
4009
|
+
selectedItem.id
|
|
4010
|
+
),
|
|
4011
|
+
/* @__PURE__ */ jsx(
|
|
4012
|
+
"button",
|
|
4013
|
+
{
|
|
4014
|
+
type: "button",
|
|
4015
|
+
className: "cb-image-preview__navigation cb-image-preview__navigation--next",
|
|
4016
|
+
"aria-label": labels.next,
|
|
4017
|
+
disabled: !canGoNext,
|
|
4018
|
+
onClick: () => changeIndex(selectedIndex + 1),
|
|
4019
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
|
|
4020
|
+
}
|
|
4021
|
+
)
|
|
4022
|
+
] }),
|
|
4023
|
+
selectedItem.caption ? /* @__PURE__ */ jsx("div", { className: "cb-image-preview__caption", children: selectedItem.caption }) : null
|
|
4024
|
+
]
|
|
4025
|
+
}
|
|
4026
|
+
)
|
|
4027
|
+
] }) : null })
|
|
4028
|
+
] });
|
|
4029
|
+
}
|
|
4030
|
+
var Image = Object.assign(ImageRoot, {
|
|
4031
|
+
PreviewGroup: Object.assign(ImagePreviewGroupRoot, {
|
|
4032
|
+
Skeleton: ImagePreviewGroupSkeleton
|
|
4033
|
+
}),
|
|
4034
|
+
Skeleton: ImageSkeleton
|
|
4035
|
+
});
|
|
1994
4036
|
|
|
1995
4037
|
// src/media/autoplay.ts
|
|
1996
4038
|
function shouldAutoplay(conditions) {
|
|
@@ -2167,7 +4209,7 @@ function Coachmark({
|
|
|
2167
4209
|
const labels = useLabels();
|
|
2168
4210
|
const rect = useAnchorRect(anchor, open && spotlight !== false);
|
|
2169
4211
|
const padding = typeof spotlight === "number" ? spotlight : 8;
|
|
2170
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
4212
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2171
4213
|
rect ? /* @__PURE__ */ jsx(
|
|
2172
4214
|
"div",
|
|
2173
4215
|
{
|
|
@@ -2342,7 +4384,7 @@ function Tour({ id, steps, open = false, onOpenChange, seenStore, onFinish, onSk
|
|
|
2342
4384
|
spotlight: step.spotlight,
|
|
2343
4385
|
progress: { current: state.index + 1, total: steps.length },
|
|
2344
4386
|
onDismiss: skip,
|
|
2345
|
-
actions: /* @__PURE__ */ jsxs(Fragment
|
|
4387
|
+
actions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2346
4388
|
state.index > 0 ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", tone: "neutral", onClick: () => rawDispatch({ type: "prev" }), children: text2.back }) : /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", tone: "neutral", onClick: skip, children: text2.skip }),
|
|
2347
4389
|
/* @__PURE__ */ jsx(Button, { size: "sm", onClick: () => rawDispatch({ type: "next" }), children: isLast ? text2.done : text2.next })
|
|
2348
4390
|
] }),
|
|
@@ -2384,5 +4426,167 @@ function Reveal({
|
|
|
2384
4426
|
function Stagger({ children, step = 0.06, from = "below", onView = false, className }) {
|
|
2385
4427
|
return /* @__PURE__ */ jsx("div", { className, children: Children.map(children, (child, index) => /* @__PURE__ */ jsx(Reveal, { from, delay: index * step, onView, children: child })) });
|
|
2386
4428
|
}
|
|
4429
|
+
function BorderBeam({ children, tone = "brand", size = "md", motion: motion3 = true }) {
|
|
4430
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("cb-border-beam", `cb-border-beam--${size}`), "data-tone": tone, "data-motion": motion3 ? "on" : "off", children: [
|
|
4431
|
+
/* @__PURE__ */ jsx("span", { className: "cb-border-beam__overlay", "aria-hidden": "true" }),
|
|
4432
|
+
/* @__PURE__ */ jsx("div", { className: "cb-border-beam__content", children })
|
|
4433
|
+
] });
|
|
4434
|
+
}
|
|
4435
|
+
function SplitterSkeleton({
|
|
4436
|
+
orientation = "horizontal",
|
|
4437
|
+
size = 50,
|
|
4438
|
+
handleSize = "md"
|
|
4439
|
+
}) {
|
|
4440
|
+
const safeSize = Number.isFinite(size) ? size : 50;
|
|
4441
|
+
const boundedSize = Math.min(100, Math.max(0, Math.round(safeSize)));
|
|
4442
|
+
const style = {
|
|
4443
|
+
"--cb-splitter-first-grow": String(boundedSize),
|
|
4444
|
+
"--cb-splitter-second-grow": String(100 - boundedSize)
|
|
4445
|
+
};
|
|
4446
|
+
return /* @__PURE__ */ jsxs(
|
|
4447
|
+
"div",
|
|
4448
|
+
{
|
|
4449
|
+
className: `cb-splitter cb-splitter--skeleton cb-splitter--${orientation} cb-splitter--handle-${handleSize}`,
|
|
4450
|
+
style,
|
|
4451
|
+
"aria-hidden": "true",
|
|
4452
|
+
children: [
|
|
4453
|
+
/* @__PURE__ */ jsx("div", { className: "cb-splitter__pane cb-splitter__pane--first", children: /* @__PURE__ */ jsx(Skeleton, { className: "cb-splitter__skeleton-pane" }) }),
|
|
4454
|
+
/* @__PURE__ */ jsx("div", { className: "cb-splitter__handle" }),
|
|
4455
|
+
/* @__PURE__ */ jsx("div", { className: "cb-splitter__pane cb-splitter__pane--second", children: /* @__PURE__ */ jsx(Skeleton, { className: "cb-splitter__skeleton-pane" }) })
|
|
4456
|
+
]
|
|
4457
|
+
}
|
|
4458
|
+
);
|
|
4459
|
+
}
|
|
4460
|
+
function clampSize(value, minSize, maxSize) {
|
|
4461
|
+
return Math.min(maxSize, Math.max(minSize, Math.round(value)));
|
|
4462
|
+
}
|
|
4463
|
+
function finiteValue(value, fallback) {
|
|
4464
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
4465
|
+
}
|
|
4466
|
+
function normalizedBounds(minSize, maxSize) {
|
|
4467
|
+
const min = Math.min(100, Math.max(0, Math.round(finiteValue(minSize, 0))));
|
|
4468
|
+
const max = Math.min(100, Math.max(min, Math.round(finiteValue(maxSize, 100))));
|
|
4469
|
+
return { min, max };
|
|
4470
|
+
}
|
|
4471
|
+
function paneChildren(children) {
|
|
4472
|
+
return Children.toArray(children).flatMap(
|
|
4473
|
+
(child) => isValidElement(child) && child.type === Fragment$1 ? paneChildren(child.props.children) : [child]
|
|
4474
|
+
);
|
|
4475
|
+
}
|
|
4476
|
+
function SplitterRoot({
|
|
4477
|
+
size,
|
|
4478
|
+
defaultSize = 50,
|
|
4479
|
+
minSize = 0,
|
|
4480
|
+
maxSize = 100,
|
|
4481
|
+
onSizeChange,
|
|
4482
|
+
orientation = "horizontal",
|
|
4483
|
+
handleSize = "md",
|
|
4484
|
+
disabled = false,
|
|
4485
|
+
handleLabel = "Resize panes",
|
|
4486
|
+
children
|
|
4487
|
+
}) {
|
|
4488
|
+
const panes = paneChildren(children);
|
|
4489
|
+
if (panes.length !== 2) {
|
|
4490
|
+
throw new Error("Splitter requires exactly two pane children.");
|
|
4491
|
+
}
|
|
4492
|
+
const rootRef = useRef(null);
|
|
4493
|
+
const grabOffsetRef = useRef(0);
|
|
4494
|
+
const [uncontrolledSize, setUncontrolledSize] = useState(() => finiteValue(defaultSize, 50));
|
|
4495
|
+
const { min, max } = normalizedBounds(minSize, maxSize);
|
|
4496
|
+
const currentSize = clampSize(size === void 0 ? uncontrolledSize : finiteValue(size, 50), min, max);
|
|
4497
|
+
const setSize = (nextSize) => {
|
|
4498
|
+
if (disabled) return;
|
|
4499
|
+
const next = clampSize(nextSize, min, max);
|
|
4500
|
+
if (size === void 0) setUncontrolledSize(next);
|
|
4501
|
+
onSizeChange?.(next);
|
|
4502
|
+
};
|
|
4503
|
+
const sizeFromPointer = (event) => {
|
|
4504
|
+
const rootRect = rootRef.current?.getBoundingClientRect();
|
|
4505
|
+
const handleRect = event.currentTarget.getBoundingClientRect();
|
|
4506
|
+
if (!rootRect) return;
|
|
4507
|
+
const rootLength = orientation === "horizontal" ? rootRect.width : rootRect.height;
|
|
4508
|
+
const handleLength = orientation === "horizontal" ? handleRect.width : handleRect.height;
|
|
4509
|
+
const availableLength = rootLength - handleLength;
|
|
4510
|
+
if (availableLength <= 0) return;
|
|
4511
|
+
const rootStart = orientation === "horizontal" ? rootRect.left : rootRect.top;
|
|
4512
|
+
const pointerPosition = orientation === "horizontal" ? event.clientX : event.clientY;
|
|
4513
|
+
setSize((pointerPosition - rootStart - grabOffsetRef.current) / availableLength * 100);
|
|
4514
|
+
};
|
|
4515
|
+
const handlePointerDown = (event) => {
|
|
4516
|
+
if (disabled) return;
|
|
4517
|
+
const handleRect = event.currentTarget.getBoundingClientRect();
|
|
4518
|
+
const handleStart = orientation === "horizontal" ? handleRect.left : handleRect.top;
|
|
4519
|
+
const pointerPosition = orientation === "horizontal" ? event.clientX : event.clientY;
|
|
4520
|
+
grabOffsetRef.current = pointerPosition - handleStart;
|
|
4521
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
4522
|
+
sizeFromPointer(event);
|
|
4523
|
+
};
|
|
4524
|
+
const handlePointerMove = (event) => {
|
|
4525
|
+
if (!disabled && event.currentTarget.hasPointerCapture(event.pointerId)) sizeFromPointer(event);
|
|
4526
|
+
};
|
|
4527
|
+
const handlePointerUp = (event) => {
|
|
4528
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
4529
|
+
sizeFromPointer(event);
|
|
4530
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
4531
|
+
}
|
|
4532
|
+
};
|
|
4533
|
+
const handlePointerCancel = (event) => {
|
|
4534
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
4535
|
+
};
|
|
4536
|
+
const handleKeyDown = (event) => {
|
|
4537
|
+
if (disabled) return;
|
|
4538
|
+
const decrease = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
|
|
4539
|
+
const increase = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
|
|
4540
|
+
if (event.key === decrease) {
|
|
4541
|
+
event.preventDefault();
|
|
4542
|
+
setSize(currentSize - 1);
|
|
4543
|
+
} else if (event.key === increase) {
|
|
4544
|
+
event.preventDefault();
|
|
4545
|
+
setSize(currentSize + 1);
|
|
4546
|
+
} else if (event.key === "Home") {
|
|
4547
|
+
event.preventDefault();
|
|
4548
|
+
setSize(min);
|
|
4549
|
+
} else if (event.key === "End") {
|
|
4550
|
+
event.preventDefault();
|
|
4551
|
+
setSize(max);
|
|
4552
|
+
}
|
|
4553
|
+
};
|
|
4554
|
+
const style = {
|
|
4555
|
+
"--cb-splitter-first-grow": String(currentSize),
|
|
4556
|
+
"--cb-splitter-second-grow": String(100 - currentSize)
|
|
4557
|
+
};
|
|
4558
|
+
return /* @__PURE__ */ jsxs(
|
|
4559
|
+
"div",
|
|
4560
|
+
{
|
|
4561
|
+
ref: rootRef,
|
|
4562
|
+
className: `cb-splitter cb-splitter--${orientation} cb-splitter--handle-${handleSize}${disabled ? " cb-splitter--disabled" : ""}`,
|
|
4563
|
+
style,
|
|
4564
|
+
children: [
|
|
4565
|
+
/* @__PURE__ */ jsx("div", { className: "cb-splitter__pane cb-splitter__pane--first", children: panes[0] }),
|
|
4566
|
+
/* @__PURE__ */ jsx(
|
|
4567
|
+
"div",
|
|
4568
|
+
{
|
|
4569
|
+
className: "cb-splitter__handle",
|
|
4570
|
+
role: "separator",
|
|
4571
|
+
"aria-orientation": orientation === "horizontal" ? "vertical" : "horizontal",
|
|
4572
|
+
"aria-valuenow": currentSize,
|
|
4573
|
+
"aria-valuemin": min,
|
|
4574
|
+
"aria-valuemax": max,
|
|
4575
|
+
"aria-label": handleLabel,
|
|
4576
|
+
"aria-disabled": disabled || void 0,
|
|
4577
|
+
tabIndex: disabled ? -1 : 0,
|
|
4578
|
+
onKeyDown: handleKeyDown,
|
|
4579
|
+
onPointerDown: handlePointerDown,
|
|
4580
|
+
onPointerMove: handlePointerMove,
|
|
4581
|
+
onPointerUp: handlePointerUp,
|
|
4582
|
+
onPointerCancel: handlePointerCancel
|
|
4583
|
+
}
|
|
4584
|
+
),
|
|
4585
|
+
/* @__PURE__ */ jsx("div", { className: "cb-splitter__pane cb-splitter__pane--second", children: panes[1] })
|
|
4586
|
+
]
|
|
4587
|
+
}
|
|
4588
|
+
);
|
|
4589
|
+
}
|
|
4590
|
+
var Splitter = Object.assign(SplitterRoot, { Skeleton: SplitterSkeleton });
|
|
2387
4591
|
|
|
2388
|
-
export { Alert, AutoComplete, Button, Carousel, Checkbox, Checklist, Coachmark, CommandPalette, DEFAULT_LABELS, DatePicker, DialogClose, Drawer, DrawerClose, Dropdown, Field, Image, Input, InputNumber, LabelsProvider, Modal, MotionProvider, Pagination, Popover, RadioGroup, Rate, Reveal, Select, Sidebar, Stagger, Switch, Table, Tabs, Tag, Textarea, ThemeProvider, TimePicker, ToastProvider, Tooltip, TopBar, Tour, Upload, ariaSortFor, canStep, clamp, decimalPlaces, describeAccept, filterCommands, formatISO, formatTime, groupCommands, hasEnded, initialTourState, isOutOfRange, isSameDay, isTimeOutOfRange, matchesAccept, monthMatrix, nextSort, pageRange, parseDateInput, parseNumber, parseTime, partitionFiles, rankCommand, resolveTarget, shouldAutoplay, startOfDay, stepBy, timeOptions, timeToMinutes, tourReducer, useFieldWiring, useLabels, useMotionSettings, useTheme, useToast };
|
|
4592
|
+
export { Alert, AutoComplete, BorderBeam, Button, Calendar, CalendarSkeleton, Carousel, Cascader, CascaderSkeleton, Checkbox, Checklist, Coachmark, Collapse, CollapseSkeleton, ColorPicker, ColorPickerSkeleton, CommandPalette, DEFAULT_LABELS, DatePicker, DialogClose, Drawer, DrawerClose, Dropdown, Field, FloatButton, Image, Input, InputNumber, LabelsProvider, Mentions, MentionsSkeleton, Menu, MenuSkeleton, Modal, MotionProvider, Pagination, Popconfirm, PopconfirmSkeleton, Popover, RadioGroup, Rate, Reveal, Select, Sidebar, Slider, SliderSkeleton, Splitter, SplitterSkeleton, Stagger, Switch, Table, Tabs, Tag, Textarea, ThemeProvider, TimePicker, ToastProvider, Tooltip, TopBar, Tour, Transfer, TransferSkeleton, Tree, TreeSelect, TreeSelectSkeleton, TreeSkeleton, Upload, Watermark, WatermarkSkeleton, ariaSortFor, canStep, clamp, decimalPlaces, describeAccept, filterCommands, formatISO, formatTime, groupCommands, hasEnded, initialTourState, isOutOfRange, isSameDay, isTimeOutOfRange, matchesAccept, monthMatrix, nextSort, pageRange, parseDateInput, parseNumber, parseTime, partitionFiles, rankCommand, resolveTarget, shouldAutoplay, startOfDay, stepBy, timeOptions, timeToMinutes, tourReducer, useFieldWiring, useLabels, useMotionSettings, useTheme, useToast };
|