@ceebee/ui 0.5.2 → 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.js CHANGED
@@ -1,20 +1,22 @@
1
1
  "use client";
2
- import { createContext, forwardRef, useContext, useMemo, useState, useRef, useEffect, useCallback, useId, isValidElement, cloneElement, Fragment, useReducer, Children } from 'react';
3
- import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
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 { ChevronLeft, ChevronRight, ChevronsUpDown, Check, Minus, X, CalendarDays, Clock, Upload as Upload$1, Plus, Search, Star, PanelLeftOpen, PanelLeftClose, ArrowUp, ArrowDown, XCircle, AlertTriangle, CheckCircle2, Info } from 'lucide-react';
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);
@@ -711,32 +755,32 @@ function DatePicker({
711
755
  side: "bottom",
712
756
  align: "start",
713
757
  sideOffset: 6,
714
- className: "cb-calendar__positioner",
715
- children: /* @__PURE__ */ jsxs(Popover$1.Popup, { className: "cb-calendar", children: [
716
- /* @__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: [
717
761
  /* @__PURE__ */ jsx(
718
762
  "button",
719
763
  {
720
764
  type: "button",
721
- className: "cb-calendar__nav",
765
+ className: "cb-date-picker-calendar__nav",
722
766
  "aria-label": labels.previousMonth,
723
767
  onClick: () => setCursor(new Date(cursor.getFullYear(), cursor.getMonth() - 1, 1)),
724
768
  children: /* @__PURE__ */ jsx(ChevronLeft, { size: 16 })
725
769
  }
726
770
  ),
727
- /* @__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" }) }),
728
772
  /* @__PURE__ */ jsx(
729
773
  "button",
730
774
  {
731
775
  type: "button",
732
- className: "cb-calendar__nav",
776
+ className: "cb-date-picker-calendar__nav",
733
777
  "aria-label": labels.nextMonth,
734
778
  onClick: () => setCursor(new Date(cursor.getFullYear(), cursor.getMonth() + 1, 1)),
735
779
  children: /* @__PURE__ */ jsx(ChevronRight, { size: 16 })
736
780
  }
737
781
  )
738
782
  ] }),
739
- /* @__PURE__ */ jsxs("table", { className: "cb-calendar__grid", children: [
783
+ /* @__PURE__ */ jsxs("table", { className: "cb-date-picker-calendar__grid", children: [
740
784
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: weekdays.map((day) => /* @__PURE__ */ jsx("th", { scope: "col", abbr: day, children: day }, day)) }) }),
741
785
  /* @__PURE__ */ jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsx("tr", { children: week.map((cell) => {
742
786
  const selected = isSameDay(cell.date, current);
@@ -745,7 +789,7 @@ function DatePicker({
745
789
  "button",
746
790
  {
747
791
  type: "button",
748
- className: "cb-calendar__day",
792
+ className: "cb-date-picker-calendar__day",
749
793
  "data-outside": !cell.inMonth || void 0,
750
794
  "data-selected": selected || void 0,
751
795
  "data-today": isSameDay(cell.date, /* @__PURE__ */ new Date()) || void 0,
@@ -1161,130 +1205,1285 @@ function InputNumber({
1161
1205
  function formatValue(value) {
1162
1206
  return value === null ? "" : String(value);
1163
1207
  }
1164
- function Modal({
1165
- open,
1166
- defaultOpen,
1167
- onOpenChange,
1168
- title,
1169
- description,
1170
- children,
1171
- footer,
1172
- size = "md",
1173
- placement = "center",
1174
- trigger,
1175
- className
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
1176
1336
  }) {
1177
- return /* @__PURE__ */ jsxs(Dialog.Root, { open, defaultOpen, onOpenChange, children: [
1178
- trigger ? /* @__PURE__ */ jsx(Dialog.Trigger, { render: trigger }) : null,
1179
- /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
1180
- /* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-modal__backdrop" }),
1181
- /* @__PURE__ */ jsxs(
1182
- Dialog.Popup,
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",
1183
1552
  {
1184
- className: cn("cb-modal", `cb-modal--${size}`, `cb-modal--${placement}`, className),
1185
- children: [
1186
- /* @__PURE__ */ jsx(Dialog.Title, { className: "cb-modal__title", children: title }),
1187
- description ? /* @__PURE__ */ jsx(Dialog.Description, { className: "cb-modal__description", children: description }) : null,
1188
- children ? /* @__PURE__ */ jsx("div", { className: "cb-modal__body", children }) : null,
1189
- footer ? /* @__PURE__ */ jsx("div", { className: "cb-modal__footer", children: footer }) : null
1190
- ]
1191
- }
1192
- )
1193
- ] })
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
+ }) }) }) }) })
1194
1568
  ] });
1195
1569
  }
1196
- var DialogClose = Dialog.Close;
1197
- function Drawer({
1198
- open,
1199
- defaultOpen,
1200
- onOpenChange,
1201
- title,
1202
- description,
1203
- children,
1204
- footer,
1205
- trigger,
1206
- className
1207
- }) {
1208
- return /* @__PURE__ */ jsxs(Dialog.Root, { open, defaultOpen, onOpenChange, children: [
1209
- trigger ? /* @__PURE__ */ jsx(Dialog.Trigger, { render: trigger }) : null,
1210
- /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
1211
- /* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-drawer__backdrop" }),
1212
- /* @__PURE__ */ jsxs(Dialog.Popup, { className: cn("cb-drawer", className), children: [
1213
- /* @__PURE__ */ jsx(Dialog.Title, { className: "cb-drawer__title", children: title }),
1214
- description ? /* @__PURE__ */ jsx(Dialog.Description, { className: "cb-drawer__description", children: description }) : null,
1215
- children ? /* @__PURE__ */ jsx("div", { className: "cb-drawer__body", children }) : null,
1216
- footer ? /* @__PURE__ */ jsx("div", { className: "cb-drawer__footer", children: footer }) : null
1217
- ] })
1218
- ] })
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 })
1219
1579
  ] });
1220
1580
  }
1221
- var DrawerClose = Dialog.Close;
1222
-
1223
- // src/overlay/command.util.ts
1224
- function rankCommand(command, query) {
1225
- const needle = query.trim().toLowerCase();
1226
- if (!needle) return 1;
1227
- const label = command.label.toLowerCase();
1228
- if (label === needle) return 100;
1229
- if (label.startsWith(needle)) return 80;
1230
- if (label.split(/\s+/).some((word) => word.startsWith(needle))) return 60;
1231
- if (label.includes(needle)) return 40;
1232
- if (command.keywords?.some((keyword) => keyword.toLowerCase().includes(needle))) return 20;
1233
- 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
+ ] });
1234
1589
  }
1235
- function filterCommands(commands, query) {
1236
- 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);
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));
1237
1594
  }
1238
- function groupCommands(commands) {
1239
- const groups = [];
1240
- for (const command of commands) {
1241
- const existing = groups.find((entry) => entry.group === command.group);
1242
- if (existing) existing.items.push(command);
1243
- 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);
1244
1600
  }
1245
- return groups;
1246
1601
  }
1247
- function CommandPalette({
1248
- open,
1249
- onOpenChange,
1250
- commands,
1251
- placeholder = "Type a command\u2026",
1252
- emptyMessage = "No matching command",
1253
- className
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"
1254
1611
  }) {
1255
- const [query, setQuery] = useState("");
1256
- const [active, setActive] = useState(0);
1257
- const results = useMemo(() => filterCommands(commands, query), [commands, query]);
1258
- const groups = useMemo(() => groupCommands(results), [results]);
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));
1259
1622
  useEffect(() => {
1260
- if (!open) {
1261
- setQuery("");
1262
- setActive(0);
1263
- }
1264
- }, [open]);
1265
- useEffect(() => setActive(0), [query]);
1266
- const run = (command) => {
1267
- onOpenChange(false);
1268
- 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);
1269
1631
  };
1270
- return /* @__PURE__ */ jsx(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
1271
- /* @__PURE__ */ jsx(Dialog.Backdrop, { className: "cb-palette__backdrop" }),
1272
- /* @__PURE__ */ jsxs(Dialog.Popup, { className: cn("cb-palette", className), "aria-label": "Command palette", children: [
1273
- /* @__PURE__ */ jsxs("div", { className: "cb-palette__search", children: [
1274
- /* @__PURE__ */ jsx(Search, { size: 16, className: "cb-palette__search-icon" }),
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: [
1275
1712
  /* @__PURE__ */ jsx(
1276
1713
  "input",
1277
1714
  {
1278
- className: "cb-palette__input",
1279
- value: query,
1280
- placeholder,
1281
- autoFocus: true,
1282
- role: "combobox",
1283
- "aria-expanded": true,
1284
- "aria-controls": "cb-palette-list",
1285
- "aria-activedescendant": results[active] ? `cb-palette-${results[active].id}` : void 0,
1286
- onChange: (event) => setQuery(event.target.value),
1287
- onKeyDown: (event) => {
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",
2482
+ "aria-expanded": true,
2483
+ "aria-controls": "cb-palette-list",
2484
+ "aria-activedescendant": results[active] ? `cb-palette-${results[active].id}` : void 0,
2485
+ onChange: (event) => setQuery(event.target.value),
2486
+ onKeyDown: (event) => {
1288
2487
  if (event.key === "ArrowDown") {
1289
2488
  setActive((index) => Math.min(index + 1, results.length - 1));
1290
2489
  event.preventDefault();
@@ -1464,6 +2663,82 @@ function ArrowShape() {
1464
2663
  }
1465
2664
  );
1466
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
+ });
1467
2742
  function Tag({
1468
2743
  children,
1469
2744
  tone = "neutral",
@@ -1478,7 +2753,7 @@ function Tag({
1478
2753
  }) {
1479
2754
  const labels = useLabels();
1480
2755
  const classes = cn("cb-badge", "cb-tag", `cb-badge--${variant}`, `cb-badge--${size}`, className);
1481
- const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
2756
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
1482
2757
  icon,
1483
2758
  children
1484
2759
  ] });
@@ -1633,6 +2908,78 @@ function useToast() {
1633
2908
  promise: manager.promise
1634
2909
  };
1635
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 });
1636
2983
  function Tabs({ items, value, defaultValue, onValueChange, variant = "underline", className }) {
1637
2984
  return /* @__PURE__ */ jsxs(
1638
2985
  Tabs$1.Root,
@@ -1656,22 +3003,22 @@ function Tabs({ items, value, defaultValue, onValueChange, variant = "underline"
1656
3003
  }
1657
3004
  function Dropdown({ trigger, items, sections, align = "end", side = "bottom", className }) {
1658
3005
  const groups = sections ?? [{ items }];
1659
- return /* @__PURE__ */ jsxs(Menu.Root, { children: [
1660
- /* @__PURE__ */ jsx(Menu.Trigger, { render: trigger }),
1661
- /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(
1662
- 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,
1663
3010
  {
1664
3011
  side,
1665
3012
  align,
1666
3013
  sideOffset: 6,
1667
3014
  className: "cb-menu-positioner",
1668
- children: /* @__PURE__ */ jsx(Menu.Popup, { className: cn("cb-menu", className), children: groups.map((section, sectionIndex) => /* @__PURE__ */ jsxs(Fragment, { children: [
1669
- sectionIndex > 0 ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }) : null,
1670
- /* @__PURE__ */ jsxs(Menu.Group, { className: "cb-menu__group", children: [
1671
- 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,
1672
3019
  section.items.map(
1673
- (item, itemIndex) => item.separator ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }, `separator-${itemIndex}`) : /* @__PURE__ */ jsxs(
1674
- Menu.Item,
3020
+ (item, itemIndex) => item.separator ? /* @__PURE__ */ jsx(Menu$1.Separator, { className: "cb-menu__separator" }, `separator-${itemIndex}`) : /* @__PURE__ */ jsxs(
3021
+ Menu$1.Item,
1675
3022
  {
1676
3023
  className: "cb-menu__item",
1677
3024
  "data-tone": item.tone,
@@ -1692,6 +3039,156 @@ function Dropdown({ trigger, items, sections, align = "end", side = "bottom", cl
1692
3039
  ) })
1693
3040
  ] });
1694
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 });
1695
3192
  var hasActiveChild = (item) => Boolean(item.items?.some((child) => child.active));
1696
3193
  function Sidebar({ sections, header, footer, collapsed = false, onCollapsedChange, className }) {
1697
3194
  const labels = useLabels();
@@ -1733,7 +3230,7 @@ function SidebarEntry({ item, collapsed }) {
1733
3230
  if (collapsed) {
1734
3231
  return /* @__PURE__ */ jsx(Flyout, { label: item.label, items: children, children: /* @__PURE__ */ jsx(SidebarRow, { item: { ...item, active: item.active || hasActiveChild(item) }, collapsed: true }) });
1735
3232
  }
1736
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
3233
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1737
3234
  /* @__PURE__ */ jsxs(
1738
3235
  "button",
1739
3236
  {
@@ -1754,7 +3251,7 @@ function SidebarEntry({ item, collapsed }) {
1754
3251
  ] });
1755
3252
  }
1756
3253
  function SidebarRow({ item, collapsed, nested }) {
1757
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
3254
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
1758
3255
  item.icon ? /* @__PURE__ */ jsx("span", { className: "cb-sidebar__icon", children: item.icon }) : null,
1759
3256
  /* @__PURE__ */ jsx("span", { className: "cb-sidebar__label", children: item.label }),
1760
3257
  item.adornment && !collapsed ? /* @__PURE__ */ jsx("span", { className: "cb-sidebar__adornment", children: item.adornment }) : null
@@ -1793,22 +3290,6 @@ function TopBar({ title, subtitle, center, actions, sticky = true, className })
1793
3290
  actions ? /* @__PURE__ */ jsx("div", { className: "cb-topbar__actions", children: actions }) : null
1794
3291
  ] });
1795
3292
  }
1796
- function box({ width = "100%", height = "1rem", radius = "md", className }) {
1797
- const style = { "--cb-skeleton-w": width, "--cb-skeleton-h": height };
1798
- return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("cb-skeleton", `cb-radius--${radius}`, className), style });
1799
- }
1800
- function text({ lines = 3, lastLineWidth = "62%", className }) {
1801
- 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)) });
1802
- }
1803
- function circle({ size = "2.5rem", className }) {
1804
- return /* @__PURE__ */ jsx(SkeletonBox, { width: size, height: size, radius: "full", className });
1805
- }
1806
- var SkeletonBox = box;
1807
- var Skeleton = Object.assign(box, {
1808
- Text: text,
1809
- Circle: circle,
1810
- Rect: box
1811
- });
1812
3293
 
1813
3294
  // src/data/table-sort.ts
1814
3295
  function nextSort(current, column) {
@@ -1964,7 +3445,349 @@ function Pagination({
1964
3445
  ] })
1965
3446
  ] });
1966
3447
  }
1967
- function Image({
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({
1968
3791
  src,
1969
3792
  alt,
1970
3793
  aspectRatio,
@@ -1973,6 +3796,7 @@ function Image({
1973
3796
  fit = "cover",
1974
3797
  radius = "md",
1975
3798
  loading = "lazy",
3799
+ motion: motion3 = true,
1976
3800
  className
1977
3801
  }) {
1978
3802
  const [loaded, setLoaded] = useState(false);
@@ -1987,6 +3811,7 @@ function Image({
1987
3811
  className: cn("cb-image", `cb-radius--${radius}`, className),
1988
3812
  "data-loaded": loaded || void 0,
1989
3813
  "data-blurred": blurDataUrl ? "" : void 0,
3814
+ "data-motion": motion3 ? void 0 : "off",
1990
3815
  style,
1991
3816
  children: /* @__PURE__ */ jsx(
1992
3817
  "img",
@@ -2006,6 +3831,208 @@ function Image({
2006
3831
  }
2007
3832
  );
2008
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
+ });
2009
4036
 
2010
4037
  // src/media/autoplay.ts
2011
4038
  function shouldAutoplay(conditions) {
@@ -2182,7 +4209,7 @@ function Coachmark({
2182
4209
  const labels = useLabels();
2183
4210
  const rect = useAnchorRect(anchor, open && spotlight !== false);
2184
4211
  const padding = typeof spotlight === "number" ? spotlight : 8;
2185
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
4212
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2186
4213
  rect ? /* @__PURE__ */ jsx(
2187
4214
  "div",
2188
4215
  {
@@ -2357,7 +4384,7 @@ function Tour({ id, steps, open = false, onOpenChange, seenStore, onFinish, onSk
2357
4384
  spotlight: step.spotlight,
2358
4385
  progress: { current: state.index + 1, total: steps.length },
2359
4386
  onDismiss: skip,
2360
- actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [
4387
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [
2361
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 }),
2362
4389
  /* @__PURE__ */ jsx(Button, { size: "sm", onClick: () => rawDispatch({ type: "next" }), children: isLast ? text2.done : text2.next })
2363
4390
  ] }),
@@ -2399,5 +4426,167 @@ function Reveal({
2399
4426
  function Stagger({ children, step = 0.06, from = "below", onView = false, className }) {
2400
4427
  return /* @__PURE__ */ jsx("div", { className, children: Children.map(children, (child, index) => /* @__PURE__ */ jsx(Reveal, { from, delay: index * step, onView, children: child })) });
2401
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 });
2402
4591
 
2403
- 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 };