@olundot/ui 0.21.2 → 0.22.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/index.js CHANGED
@@ -829,10 +829,14 @@ var FileUploadZone = React5.forwardRef(
829
829
  onKeyDown,
830
830
  size = "default",
831
831
  surface = "surface",
832
+ "aria-describedby": ariaDescribedBy,
832
833
  ...props
833
834
  }, ref) => {
835
+ const field = useFormFieldControl();
834
836
  const generatedId = React5.useId();
835
- const inputId = id ?? generatedId;
837
+ const inputId = id ?? field?.controlId ?? generatedId;
838
+ const errorId = field && error ? `${generatedId}-error` : void 0;
839
+ const fieldDescribedBy = field ? joinIds(ariaDescribedBy, errorId, field.describedBy) : void 0;
836
840
  const inputRef = React5.useRef(null);
837
841
  const [isDragging, setIsDragging] = React5.useState(false);
838
842
  const [selectedFiles, setSelectedFiles] = React5.useState("");
@@ -919,6 +923,7 @@ var FileUploadZone = React5.forwardRef(
919
923
  "aria-disabled": disabled || void 0,
920
924
  tabIndex: disabled ? -1 : 0,
921
925
  htmlFor: inputId,
926
+ "aria-describedby": field ? fieldDescribedBy : ariaDescribedBy,
922
927
  className: cn(fileUploadZoneVariants({ size, surface, className })),
923
928
  onDragEnter: handleDragEnter,
924
929
  onDragLeave: handleDragLeave,
@@ -932,6 +937,8 @@ var FileUploadZone = React5.forwardRef(
932
937
  {
933
938
  ref: inputRef,
934
939
  id: inputId,
940
+ "aria-describedby": fieldDescribedBy,
941
+ "aria-invalid": errorId ? true : void 0,
935
942
  "data-slot": "file-upload-zone-input",
936
943
  className: "sr-only",
937
944
  type: "file",
@@ -983,6 +990,7 @@ var FileUploadZone = React5.forwardRef(
983
990
  error ? /* @__PURE__ */ jsx4(
984
991
  "span",
985
992
  {
993
+ id: errorId,
986
994
  role: "alert",
987
995
  "data-slot": "file-upload-zone-error",
988
996
  className: "mt-[var(--space-1)] text-xs leading-normal text-[var(--error)]",
@@ -3794,7 +3802,7 @@ var FormLayout = React21.forwardRef(
3794
3802
  FormLayout.displayName = "FormLayout";
3795
3803
 
3796
3804
  // src/components/ui/dialog.tsx
3797
- import * as React28 from "react";
3805
+ import * as React29 from "react";
3798
3806
  import { Dialog as DialogPrimitive3 } from "radix-ui";
3799
3807
 
3800
3808
  // src/lib/use-overlay-action.ts
@@ -3877,7 +3885,7 @@ function useReturnFocus() {
3877
3885
  }
3878
3886
 
3879
3887
  // src/components/ui/overlay-anatomy.tsx
3880
- import * as React26 from "react";
3888
+ import * as React27 from "react";
3881
3889
  import { AlertDialog as AlertDialogPrimitive, Dialog as DialogPrimitive2 } from "radix-ui";
3882
3890
 
3883
3891
  // src/components/ui/overlay-bottom-sheet.tsx
@@ -4062,9 +4070,33 @@ import { X as X2 } from "lucide-react";
4062
4070
  import { Dialog as DialogPrimitive } from "radix-ui";
4063
4071
 
4064
4072
  // src/components/ui/icon-button.tsx
4065
- import * as React25 from "react";
4073
+ import * as React26 from "react";
4066
4074
  import { cva as cva10 } from "class-variance-authority";
4067
4075
  import { Check as Check3, ChevronDown as ChevronDown4, Loader2 as Loader23 } from "lucide-react";
4076
+
4077
+ // src/lib/compose-refs.ts
4078
+ import * as React25 from "react";
4079
+ function setRef(ref, value) {
4080
+ if (typeof ref === "function") return ref(value);
4081
+ if (ref) ref.current = value;
4082
+ }
4083
+ function composeRefs(...refs) {
4084
+ return (node) => {
4085
+ const cleanups = refs.map((ref) => setRef(ref, node));
4086
+ if (!cleanups.some((cleanup) => typeof cleanup === "function")) return;
4087
+ return () => {
4088
+ cleanups.forEach((cleanup, index) => {
4089
+ if (typeof cleanup === "function") cleanup();
4090
+ else setRef(refs[index], null);
4091
+ });
4092
+ };
4093
+ };
4094
+ }
4095
+ function useComposedRefs(...refs) {
4096
+ return React25.useCallback(composeRefs(...refs), refs);
4097
+ }
4098
+
4099
+ // src/components/ui/icon-button.tsx
4068
4100
  import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
4069
4101
  var pressedNeutralClassName = "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground";
4070
4102
  var doneClassName = "cursor-default text-[var(--success)]";
@@ -4072,7 +4104,7 @@ var doneRestPaint = (classes) => classes.split(" ").filter(
4072
4104
  (name) => !name.startsWith("hover:") && (!name.startsWith("aria-disabled:") || name.startsWith("aria-disabled:active:"))
4073
4105
  ).join(" ");
4074
4106
  var tabbing = false;
4075
- var tabListeners = 0;
4107
+ var tabListeners = /* @__PURE__ */ new WeakMap();
4076
4108
  var markTab = (event) => {
4077
4109
  if (event.key !== "Tab") return;
4078
4110
  tabbing = true;
@@ -4080,14 +4112,46 @@ var markTab = (event) => {
4080
4112
  tabbing = false;
4081
4113
  }, 0);
4082
4114
  };
4083
- function useTabMark(enabled) {
4084
- React25.useEffect(() => {
4085
- if (!enabled) return;
4086
- if (tabListeners++ === 0) document.addEventListener("keydown", markTab, true);
4087
- return () => {
4088
- if (--tabListeners === 0) document.removeEventListener("keydown", markTab, true);
4115
+ function tabDocuments(ownerDocument) {
4116
+ const documents = [];
4117
+ for (let current = ownerDocument; current; ) {
4118
+ documents.push(current);
4119
+ current = current.defaultView?.frameElement?.ownerDocument;
4120
+ }
4121
+ return documents;
4122
+ }
4123
+ function useTabMark(nodeRef, enabled) {
4124
+ React26.useEffect(() => {
4125
+ const ownerDocument = nodeRef.current?.ownerDocument;
4126
+ if (!enabled || !ownerDocument) return;
4127
+ const documents = tabDocuments(ownerDocument);
4128
+ for (const target of documents) {
4129
+ const count = tabListeners.get(target) ?? 0;
4130
+ if (count === 0) target.addEventListener("keydown", markTab, true);
4131
+ tabListeners.set(target, count + 1);
4132
+ }
4133
+ const view = ownerDocument.defaultView;
4134
+ let released = false;
4135
+ const onPageHide = (event) => {
4136
+ if (!event.persisted) release();
4089
4137
  };
4090
- }, [enabled]);
4138
+ const release = () => {
4139
+ if (released) return;
4140
+ released = true;
4141
+ view?.removeEventListener("pagehide", onPageHide);
4142
+ for (const target of documents) {
4143
+ const remaining = (tabListeners.get(target) ?? 1) - 1;
4144
+ if (remaining > 0) {
4145
+ tabListeners.set(target, remaining);
4146
+ continue;
4147
+ }
4148
+ tabListeners.delete(target);
4149
+ target.removeEventListener("keydown", markTab, true);
4150
+ }
4151
+ };
4152
+ view?.addEventListener("pagehide", onPageHide);
4153
+ return release;
4154
+ }, [nodeRef, enabled]);
4091
4155
  }
4092
4156
  var iconButtonCva = cva10(
4093
4157
  [
@@ -4165,7 +4229,7 @@ var iconButtonBadgeVariants = cva10(
4165
4229
  }
4166
4230
  }
4167
4231
  );
4168
- var IconButton = React25.forwardRef(
4232
+ var IconButton = React26.forwardRef(
4169
4233
  ({
4170
4234
  className,
4171
4235
  appearance,
@@ -4203,9 +4267,11 @@ var IconButton = React25.forwardRef(
4203
4267
  const hasText = text !== void 0 && text !== null && text !== false;
4204
4268
  const resolvedBadge = badge === void 0 && isDone ? /* @__PURE__ */ jsx22(Check3, { strokeWidth: 3 }) : badge;
4205
4269
  const resolvedBadgeTone = badge === void 0 && isDone ? "success" : badgeTone;
4206
- const [tooltipOpen, setTooltipOpen] = React25.useState(false);
4207
- useTabMark(tooltip !== void 0);
4208
- React25.useEffect(() => {
4270
+ const [tooltipOpen, setTooltipOpen] = React26.useState(false);
4271
+ const buttonRef = React26.useRef(null);
4272
+ const setButtonRefs = useComposedRefs(buttonRef, ref);
4273
+ useTabMark(buttonRef, tooltip !== void 0);
4274
+ React26.useEffect(() => {
4209
4275
  if (isDisabled) setTooltipOpen(false);
4210
4276
  }, [isDisabled]);
4211
4277
  const style = resolveActionStyle(appearance, tone, "ghost");
@@ -4237,7 +4303,7 @@ var IconButton = React25.forwardRef(
4237
4303
  const button = /* @__PURE__ */ jsxs20(
4238
4304
  "button",
4239
4305
  {
4240
- ref,
4306
+ ref: setButtonRefs,
4241
4307
  ...props,
4242
4308
  "data-slot": "icon-button",
4243
4309
  "data-appearance": style.appearance,
@@ -4419,7 +4485,7 @@ var scrimMotionOf = {
4419
4485
  sheet: scrimMotion.responsive,
4420
4486
  menu: scrimMotion.sheet
4421
4487
  };
4422
- var OverlayScrimLayer = React26.forwardRef(
4488
+ var OverlayScrimLayer = React27.forwardRef(
4423
4489
  ({ scrim, kind, still, className, ...props }, ref) => {
4424
4490
  const Overlay = kind === "alert" ? AlertDialogPrimitive.Overlay : DialogPrimitive2.Overlay;
4425
4491
  return /* @__PURE__ */ jsx24(
@@ -4617,9 +4683,9 @@ var listBoxClassName = {
4617
4683
  };
4618
4684
  var listFloorClassName = "h-[calc(112px+var(--space-3))]";
4619
4685
  function OverlayList({ height = "md", fit = "max", label, children }) {
4620
- const ref = React26.useRef(null);
4621
- const [hasFocusable, setHasFocusable] = React26.useState(true);
4622
- React26.useLayoutEffect(() => {
4686
+ const ref = React27.useRef(null);
4687
+ const [hasFocusable, setHasFocusable] = React27.useState(true);
4688
+ React27.useLayoutEffect(() => {
4623
4689
  const node = ref.current;
4624
4690
  if (!node) return;
4625
4691
  const check = () => setHasFocusable(firstTabbable(node, TABBABLE_CANDIDATE) != null);
@@ -4696,7 +4762,7 @@ var bottomSheet = {
4696
4762
  };
4697
4763
 
4698
4764
  // src/components/ui/sheet.tsx
4699
- import * as React27 from "react";
4765
+ import * as React28 from "react";
4700
4766
  import { Dialog as SheetPrimitive } from "radix-ui";
4701
4767
  import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
4702
4768
  var defaultSheetMotionConfig = {
@@ -4766,7 +4832,7 @@ function StructuredSheet({
4766
4832
  }) {
4767
4833
  const policy = OVERLAY_POLICY.sheet;
4768
4834
  const motionConfig = resolveSheetMotionConfig(motion);
4769
- const surfaceRef = React27.useRef(null);
4835
+ const surfaceRef = React28.useRef(null);
4770
4836
  const swipe = useSwipeDismiss({ enabled: policy.swipe, onDismiss: () => onOpenChange(false), surfaceRef });
4771
4837
  const returnFocus = useReturnFocus();
4772
4838
  return /* @__PURE__ */ jsx25(SheetPrimitive.Root, { open, onOpenChange, children: /* @__PURE__ */ jsx25(FormFieldBoundary, { children: /* @__PURE__ */ jsxs22(SheetPrimitive.Portal, { children: [
@@ -4999,7 +5065,7 @@ import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-
4999
5065
  function dialogMobileSheetStyle(style) {
5000
5066
  return getDefaultSheetMotionStyle(style);
5001
5067
  }
5002
- var DialogModalContext = React28.createContext(true);
5068
+ var DialogModalContext = React29.createContext(true);
5003
5069
  function Dialog(props) {
5004
5070
  if (props.title !== void 0) return /* @__PURE__ */ jsx26(StructuredDialog, { ...props });
5005
5071
  return /* @__PURE__ */ jsx26(DialogRoot, { ...props });
@@ -5037,7 +5103,7 @@ function StructuredDialog({
5037
5103
  onError
5038
5104
  });
5039
5105
  const returnFocus = useReturnFocus();
5040
- const surfaceRef = React28.useRef(null);
5106
+ const surfaceRef = React29.useRef(null);
5041
5107
  const swipe = useSwipeDismiss({ enabled: policy.swipe, onDismiss: () => guardOpenChange(false), surfaceRef });
5042
5108
  const body = list != null ? (
5043
5109
  // Scrolls only on a screen too low for the body's 16 and the list floor; the footer stays.
@@ -5119,7 +5185,7 @@ function DialogPortal(props) {
5119
5185
  return /* @__PURE__ */ jsx26(FormFieldBoundary, { children: /* @__PURE__ */ jsx26(DialogPrimitive3.Portal, { ...props }) });
5120
5186
  }
5121
5187
  var DialogClose = DialogPrimitive3.Close;
5122
- var DialogOverlay = React28.forwardRef(({ className, ...props }, ref) => (
5188
+ var DialogOverlay = React29.forwardRef(({ className, ...props }, ref) => (
5123
5189
  // Position and scrim color come from the shared scrim (overlay-anatomy).
5124
5190
  /* @__PURE__ */ jsx26(
5125
5191
  OverlayScrimLayer,
@@ -5136,7 +5202,7 @@ var DialogOverlay = React28.forwardRef(({ className, ...props }, ref) => (
5136
5202
  )
5137
5203
  ));
5138
5204
  DialogOverlay.displayName = DialogPrimitive3.Overlay.displayName;
5139
- var DialogContent = React28.forwardRef(
5205
+ var DialogContent = React29.forwardRef(
5140
5206
  ({
5141
5207
  className,
5142
5208
  children,
@@ -5147,7 +5213,7 @@ var DialogContent = React28.forwardRef(
5147
5213
  onCloseAutoFocus,
5148
5214
  ...props
5149
5215
  }, ref) => {
5150
- const modal = React28.useContext(DialogModalContext);
5216
+ const modal = React29.useContext(DialogModalContext);
5151
5217
  const returnFocus = useReturnFocus();
5152
5218
  const handleOpenAutoFocus = (event) => {
5153
5219
  if (modal) returnFocus.onOpenAutoFocus(event);
@@ -5232,7 +5298,7 @@ var DialogFooter = ({
5232
5298
  }
5233
5299
  );
5234
5300
  DialogFooter.displayName = "DialogFooter";
5235
- var DialogTitle = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
5301
+ var DialogTitle = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
5236
5302
  DialogPrimitive3.Title,
5237
5303
  {
5238
5304
  ref,
@@ -5244,7 +5310,7 @@ var DialogTitle = React28.forwardRef(({ className, ...props }, ref) => /* @__PUR
5244
5310
  }
5245
5311
  ));
5246
5312
  DialogTitle.displayName = DialogPrimitive3.Title.displayName;
5247
- var DialogDescription = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
5313
+ var DialogDescription = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
5248
5314
  DialogPrimitive3.Description,
5249
5315
  {
5250
5316
  ref,
@@ -5253,7 +5319,7 @@ var DialogDescription = React28.forwardRef(({ className, ...props }, ref) => /*
5253
5319
  }
5254
5320
  ));
5255
5321
  DialogDescription.displayName = DialogPrimitive3.Description.displayName;
5256
- var DialogEyebrow = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
5322
+ var DialogEyebrow = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
5257
5323
  "p",
5258
5324
  {
5259
5325
  ref,
@@ -5265,7 +5331,7 @@ var DialogEyebrow = React28.forwardRef(({ className, ...props }, ref) => /* @__P
5265
5331
  }
5266
5332
  ));
5267
5333
  DialogEyebrow.displayName = "DialogEyebrow";
5268
- var DialogRawContent = React28.forwardRef((props, ref) => /* @__PURE__ */ jsx26(FormFieldBoundary, { children: /* @__PURE__ */ jsx26(DialogPrimitive3.Content, { ref, ...props }) }));
5334
+ var DialogRawContent = React29.forwardRef((props, ref) => /* @__PURE__ */ jsx26(FormFieldBoundary, { children: /* @__PURE__ */ jsx26(DialogPrimitive3.Content, { ref, ...props }) }));
5269
5335
  DialogRawContent.displayName = DialogPrimitive3.Content.displayName;
5270
5336
 
5271
5337
  // src/components/ui/form-modal.tsx
@@ -5442,11 +5508,11 @@ function InfoModal({
5442
5508
  }
5443
5509
 
5444
5510
  // src/components/ui/filter-toolbar.tsx
5445
- import * as React31 from "react";
5511
+ import * as React32 from "react";
5446
5512
  import { SlidersHorizontal } from "lucide-react";
5447
5513
 
5448
5514
  // src/components/ui/chip.tsx
5449
- import * as React29 from "react";
5515
+ import * as React30 from "react";
5450
5516
  import { cva as cva11 } from "class-variance-authority";
5451
5517
  import { X as X3 } from "lucide-react";
5452
5518
  import { Slot as Slot2 } from "radix-ui";
@@ -5566,7 +5632,7 @@ function ChipCount({
5566
5632
  ] })
5567
5633
  ] });
5568
5634
  }
5569
- var Chip = React29.forwardRef(
5635
+ var Chip = React30.forwardRef(
5570
5636
  ({
5571
5637
  className,
5572
5638
  variant = "filter",
@@ -5671,7 +5737,7 @@ var Chip = React29.forwardRef(
5671
5737
  Chip.displayName = "Chip";
5672
5738
 
5673
5739
  // src/components/ui/popover.tsx
5674
- import * as React30 from "react";
5740
+ import * as React31 from "react";
5675
5741
  import { Popover as PopoverPrimitive } from "radix-ui";
5676
5742
  import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
5677
5743
  function Popover({ modal = false, ...props }) {
@@ -5681,7 +5747,7 @@ var popoverArrowClassName = "fill-[var(--bg-surface)] stroke-[var(--border)] [&>
5681
5747
  var PopoverTrigger = PopoverPrimitive.Trigger;
5682
5748
  var PopoverAnchor = PopoverPrimitive.Anchor;
5683
5749
  var PopoverClose = PopoverPrimitive.Close;
5684
- var PopoverContent = React30.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx31(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs27(
5750
+ var PopoverContent = React31.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx31(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs27(
5685
5751
  PopoverPrimitive.Content,
5686
5752
  {
5687
5753
  ref,
@@ -5718,7 +5784,7 @@ var PopoverContent = React30.forwardRef(({ className, align = "center", sideOffs
5718
5784
  }
5719
5785
  ) }));
5720
5786
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
5721
- var PopoverArrow = React30.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx31(
5787
+ var PopoverArrow = React31.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx31(
5722
5788
  PopoverPrimitive.Arrow,
5723
5789
  {
5724
5790
  ref,
@@ -5769,9 +5835,9 @@ function canTakeFocus(element) {
5769
5835
  return Boolean(element && element.getClientRects().length > 0 && !element.matches(":disabled"));
5770
5836
  }
5771
5837
  function filterCells(node, prefix = "") {
5772
- return React31.Children.toArray(node).flatMap((child, index) => {
5773
- const key = `${prefix}${React31.isValidElement(child) ? child.key : index}`;
5774
- return React31.isValidElement(child) && child.type === React31.Fragment ? filterCells(child.props.children, `${key}/`) : [{ key, cell: child }];
5838
+ return React32.Children.toArray(node).flatMap((child, index) => {
5839
+ const key = `${prefix}${React32.isValidElement(child) ? child.key : index}`;
5840
+ return React32.isValidElement(child) && child.type === React32.Fragment ? filterCells(child.props.children, `${key}/`) : [{ key, cell: child }];
5775
5841
  });
5776
5842
  }
5777
5843
  function contentWidth(element) {
@@ -5784,7 +5850,7 @@ function warnGridFilters(count) {
5784
5850
  `FilterToolbar: layout="grid" fits ${MAX_GRID_FILTERS} filters on the line, got ${count}. Move the rest to \`collapsible\`.`
5785
5851
  );
5786
5852
  }
5787
- var FilterToolbar = React31.forwardRef(
5853
+ var FilterToolbar = React32.forwardRef(
5788
5854
  ({
5789
5855
  className,
5790
5856
  search,
@@ -5803,20 +5869,20 @@ var FilterToolbar = React31.forwardRef(
5803
5869
  appliedFilters,
5804
5870
  ...props
5805
5871
  }, ref) => {
5806
- const [rootElement, setRootElement] = React31.useState(
5872
+ const [rootElement, setRootElement] = React32.useState(
5807
5873
  null
5808
5874
  );
5809
- const [containerWidth, setContainerWidth] = React31.useState(
5875
+ const [containerWidth, setContainerWidth] = React32.useState(
5810
5876
  null
5811
5877
  );
5812
- const [overlayOpen, setOverlayOpen] = React31.useState(false);
5813
- const rootRef = React31.useRef(null);
5814
- const triggerRef = React31.useRef(null);
5815
- const rowRef = React31.useRef(null);
5816
- const chipsRef = React31.useRef(null);
5817
- const chipRemoveRefs = React31.useRef(/* @__PURE__ */ new Map());
5818
- const pendingFocusRef = React31.useRef(null);
5819
- const setRootRefs = React31.useCallback(
5878
+ const [overlayOpen, setOverlayOpen] = React32.useState(false);
5879
+ const rootRef = React32.useRef(null);
5880
+ const triggerRef = React32.useRef(null);
5881
+ const rowRef = React32.useRef(null);
5882
+ const chipsRef = React32.useRef(null);
5883
+ const chipRemoveRefs = React32.useRef(/* @__PURE__ */ new Map());
5884
+ const pendingFocusRef = React32.useRef(null);
5885
+ const setRootRefs = React32.useCallback(
5820
5886
  (element) => {
5821
5887
  rootRef.current = element;
5822
5888
  setRootElement(element);
@@ -5826,7 +5892,7 @@ var FilterToolbar = React31.forwardRef(
5826
5892
  [ref]
5827
5893
  );
5828
5894
  const isGrid = layout === "grid";
5829
- React31.useEffect(() => {
5895
+ React32.useEffect(() => {
5830
5896
  if (!rootElement) return;
5831
5897
  const updateWidth = (entry) => {
5832
5898
  setContainerWidth(
@@ -5839,16 +5905,16 @@ var FilterToolbar = React31.forwardRef(
5839
5905
  observer.observe(rootElement);
5840
5906
  return () => observer.disconnect();
5841
5907
  }, [rootElement, isGrid]);
5842
- const handleOverlayOpenChange = React31.useCallback((open) => {
5908
+ const handleOverlayOpenChange = React32.useCallback((open) => {
5843
5909
  setOverlayOpen(open);
5844
5910
  if (!open) queueMicrotask(() => triggerRef.current?.focus());
5845
5911
  }, []);
5846
5912
  const gridCells = isGrid ? filterCells(filters) : [];
5847
5913
  const filterCellCount = gridCells.length;
5848
- React31.useEffect(() => {
5914
+ React32.useEffect(() => {
5849
5915
  if (filterCellCount > MAX_GRID_FILTERS) warnGridFilters(filterCellCount);
5850
5916
  }, [filterCellCount]);
5851
- React31.useEffect(() => {
5917
+ React32.useEffect(() => {
5852
5918
  const ownerDocument = rootElement?.ownerDocument;
5853
5919
  if (!ownerDocument) return;
5854
5920
  const dropOutside = (event) => {
@@ -5861,7 +5927,7 @@ var FilterToolbar = React31.forwardRef(
5861
5927
  ownerDocument.removeEventListener("pointerdown", dropOutside, true);
5862
5928
  };
5863
5929
  }, [rootElement]);
5864
- React31.useEffect(() => {
5930
+ React32.useEffect(() => {
5865
5931
  const request = pendingFocusRef.current;
5866
5932
  if (!request) return;
5867
5933
  const present = new Set(appliedFilters?.map((filter) => filter.key));
@@ -5890,7 +5956,7 @@ var FilterToolbar = React31.forwardRef(
5890
5956
  const narrowFilterCount = activeFilterCount + lineFilterCount;
5891
5957
  const hasCollapsed = Boolean(collapsible) || gridSheet;
5892
5958
  const outgrownSheet = isGrid && !collapsible && containerWidth !== null && containerWidth >= 640 && overlayOpen;
5893
- React31.useEffect(() => {
5959
+ React32.useEffect(() => {
5894
5960
  if (!outgrownSheet) return;
5895
5961
  setOverlayOpen(false);
5896
5962
  const ownerDocument = rootElement?.ownerDocument;
@@ -6188,12 +6254,12 @@ var FilterToolbar = React31.forwardRef(
6188
6254
  FilterToolbar.displayName = "FilterToolbar";
6189
6255
 
6190
6256
  // src/components/ui/data-table.tsx
6191
- import * as React35 from "react";
6257
+ import * as React36 from "react";
6192
6258
  import { ChevronDown as ChevronDown5, ChevronRight as ChevronRight3, ChevronUp as ChevronUp2, ChevronsUpDown, EllipsisVertical } from "lucide-react";
6193
6259
  import { cva as cva13 } from "class-variance-authority";
6194
6260
 
6195
6261
  // src/components/ui/action-menu.tsx
6196
- import * as React32 from "react";
6262
+ import * as React33 from "react";
6197
6263
  import { Dialog as DialogPrimitive4, Slot as Slot3 } from "radix-ui";
6198
6264
 
6199
6265
  // src/components/ui/dropdown-menu.tsx
@@ -6472,9 +6538,9 @@ function ActionMenuSheet({
6472
6538
  onOpenAutoFocus,
6473
6539
  onCloseAutoFocus
6474
6540
  }) {
6475
- const pendingRef = React32.useRef(null);
6476
- const surfaceRef = React32.useRef(null);
6477
- const labelId = React32.useId();
6541
+ const pendingRef = React33.useRef(null);
6542
+ const surfaceRef = React33.useRef(null);
6543
+ const labelId = React33.useId();
6478
6544
  const handleOpenChange = (nextOpen) => {
6479
6545
  pendingRef.current = null;
6480
6546
  onOpenChange(nextOpen);
@@ -6525,7 +6591,7 @@ function ActionMenuSheet({
6525
6591
  dragHandleProps: swipe.handleProps
6526
6592
  }
6527
6593
  ),
6528
- /* @__PURE__ */ jsx34(OverlayBody, { kind: "menu", children: groups.map((group, index) => /* @__PURE__ */ jsxs30(React32.Fragment, { children: [
6594
+ /* @__PURE__ */ jsx34(OverlayBody, { kind: "menu", children: groups.map((group, index) => /* @__PURE__ */ jsxs30(React33.Fragment, { children: [
6529
6595
  index > 0 ? /* @__PURE__ */ jsx34("div", { role: "separator", className: sheetGroupSeparatorClassName }) : null,
6530
6596
  /* @__PURE__ */ jsxs30("div", { role: "group", "aria-labelledby": group.label ? `${labelId}-${index}` : void 0, children: [
6531
6597
  group.label ? /* @__PURE__ */ jsx34("div", { id: `${labelId}-${index}`, className: sheetGroupLabelClassName, children: group.label }) : null,
@@ -6573,7 +6639,7 @@ function ActionMenuDropdownItem({
6573
6639
  item,
6574
6640
  onPick
6575
6641
  }) {
6576
- const id = React32.useId();
6642
+ const id = React33.useId();
6577
6643
  const labelId = `${id}-label`;
6578
6644
  const reasonId = `${id}-reason`;
6579
6645
  const Icon = item.icon;
@@ -6584,6 +6650,7 @@ function ActionMenuDropdownItem({
6584
6650
  {
6585
6651
  variant: item.destructive ? "destructive" : "default",
6586
6652
  disabled: item.disabled,
6653
+ title: item.title,
6587
6654
  onSelect: () => onPick(item),
6588
6655
  children: [
6589
6656
  Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
@@ -6613,7 +6680,7 @@ function ActionMenuDropdownItem({
6613
6680
  }
6614
6681
  var readPresentation = () => window.matchMedia?.(OVERLAY_DESKTOP_QUERY).matches ?? true ? "dropdown" : "sheet";
6615
6682
  var subscribeNothing = () => () => void 0;
6616
- var useHydrated = () => React32.useSyncExternalStore(
6683
+ var useHydrated = () => React33.useSyncExternalStore(
6617
6684
  subscribeNothing,
6618
6685
  () => true,
6619
6686
  () => false
@@ -6628,10 +6695,10 @@ function ActionMenu({
6628
6695
  items,
6629
6696
  groups
6630
6697
  }) {
6631
- const [uncontrolledOpen, setUncontrolledOpen] = React32.useState(false);
6698
+ const [uncontrolledOpen, setUncontrolledOpen] = React33.useState(false);
6632
6699
  const hydrated = useHydrated();
6633
6700
  const open = (openProp ?? uncontrolledOpen) && hydrated;
6634
- const [shown, setShown] = React32.useState({
6701
+ const [shown, setShown] = React33.useState({
6635
6702
  open: false,
6636
6703
  presentation: "dropdown"
6637
6704
  });
@@ -6640,8 +6707,8 @@ function ActionMenu({
6640
6707
  if (open) presentation = readPresentation();
6641
6708
  setShown({ open, presentation });
6642
6709
  }
6643
- const triggerRef = React32.useRef(null);
6644
- const pendingRef = React32.useRef(null);
6710
+ const triggerRef = React33.useRef(null);
6711
+ const pendingRef = React33.useRef(null);
6645
6712
  const setOpen = (nextOpen) => {
6646
6713
  if (nextOpen) pendingRef.current = null;
6647
6714
  if (openProp === void 0) setUncontrolledOpen(nextOpen);
@@ -6664,7 +6731,7 @@ function ActionMenu({
6664
6731
  return /* @__PURE__ */ jsxs30(Fragment16, { children: [
6665
6732
  /* @__PURE__ */ jsxs30(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
6666
6733
  /* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx34(Slot3.Root, { ref: triggerRef, children: trigger }) }),
6667
- /* @__PURE__ */ jsx34(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs30(React32.Fragment, { children: [
6734
+ /* @__PURE__ */ jsx34(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs30(React33.Fragment, { children: [
6668
6735
  index > 0 ? /* @__PURE__ */ jsx34(DropdownMenuSeparator, {}) : null,
6669
6736
  /* @__PURE__ */ jsxs30(DropdownMenuGroup, { children: [
6670
6737
  group.label ? /* @__PURE__ */ jsx34(DropdownMenuLabel, { children: group.label }) : null,
@@ -6697,7 +6764,7 @@ function ActionMenu({
6697
6764
  }
6698
6765
 
6699
6766
  // src/components/ui/checkbox.tsx
6700
- import * as React33 from "react";
6767
+ import * as React34 from "react";
6701
6768
  import { cva as cva12 } from "class-variance-authority";
6702
6769
  import { Check as Check4, Minus } from "lucide-react";
6703
6770
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
@@ -6804,11 +6871,11 @@ var checkboxGroupBoxVariants = cva12(
6804
6871
  }
6805
6872
  }
6806
6873
  );
6807
- var CheckboxGroupContext = React33.createContext(null);
6874
+ var CheckboxGroupContext = React34.createContext(null);
6808
6875
  function getLabel(children, label) {
6809
6876
  return children ?? label;
6810
6877
  }
6811
- var Checkbox = React33.forwardRef(
6878
+ var Checkbox = React34.forwardRef(
6812
6879
  ({
6813
6880
  className,
6814
6881
  size = "md",
@@ -6827,9 +6894,9 @@ var Checkbox = React33.forwardRef(
6827
6894
  "aria-describedby": ariaDescribedBy,
6828
6895
  ...props
6829
6896
  }, ref) => {
6830
- const group = React33.useContext(CheckboxGroupContext);
6897
+ const group = React34.useContext(CheckboxGroupContext);
6831
6898
  const field = useFormFieldControl();
6832
- const generatedId = React33.useId();
6899
+ const generatedId = React34.useId();
6833
6900
  const labelContent = getLabel(children, label);
6834
6901
  const isGrouped = Boolean(group && value != null);
6835
6902
  const valueString = value == null ? void 0 : String(value);
@@ -7071,11 +7138,11 @@ function ContextMenu({
7071
7138
  }
7072
7139
 
7073
7140
  // src/components/ui/list-card.tsx
7074
- import * as React34 from "react";
7141
+ import * as React35 from "react";
7075
7142
  import { ChevronRight as ChevronRight2, MoreVertical } from "lucide-react";
7076
7143
  import { Fragment as Fragment17, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
7077
7144
  function lineTokens(value) {
7078
- return React34.Children.toArray(value).filter((token) => token !== "");
7145
+ return React35.Children.toArray(value).filter((token) => token !== "");
7079
7146
  }
7080
7147
  function MetaLine({
7081
7148
  tokens,
@@ -7157,7 +7224,7 @@ function ListCard({
7157
7224
  "data-slot": `${slot}-title`,
7158
7225
  className: titleClassName,
7159
7226
  title: typeof title === "string" || typeof title === "number" ? String(title) : void 0,
7160
- children: overlay && href != null ? React34.createElement(linkComponent ?? "a", { ...linkProps, href, className: overlayClassName }, title) : title
7227
+ children: overlay && href != null ? React35.createElement(linkComponent ?? "a", { ...linkProps, href, className: overlayClassName }, title) : title
7161
7228
  }
7162
7229
  );
7163
7230
  const content = /* @__PURE__ */ jsxs33(Fragment17, { children: [
@@ -7354,18 +7421,18 @@ function RowContextMenu({
7354
7421
  cards,
7355
7422
  onClose
7356
7423
  }) {
7357
- const [open, setOpen] = React35.useState(true);
7358
- const closeRef = React35.useRef(null);
7359
- const pressedOutside = React35.useRef(false);
7424
+ const [open, setOpen] = React36.useState(true);
7425
+ const closeRef = React36.useRef(null);
7426
+ const pressedOutside = React36.useRef(false);
7360
7427
  const close = (reason) => {
7361
7428
  closeRef.current ??= reason;
7362
7429
  setOpen(false);
7363
7430
  };
7364
- const shownGroups = React35.useRef([]);
7431
+ const shownGroups = React36.useRef([]);
7365
7432
  if (groups) shownGroups.current = groups;
7366
7433
  const gone = groups === null;
7367
- const contentRef = React35.useRef(null);
7368
- const focusInsideRef = React35.useRef(false);
7434
+ const contentRef = React36.useRef(null);
7435
+ const focusInsideRef = React36.useRef(false);
7369
7436
  useIsomorphicLayoutEffect(() => {
7370
7437
  const content = contentRef.current;
7371
7438
  if (!open || !focusInsideRef.current || !content?.isConnected) return;
@@ -7374,7 +7441,7 @@ function RowContextMenu({
7374
7441
  const next = content.querySelector('[role="menuitem"]:not([data-disabled])') ?? content;
7375
7442
  next.focus();
7376
7443
  });
7377
- React35.useEffect(() => {
7444
+ React36.useEffect(() => {
7378
7445
  if (gone) close({ by: "dismiss", outside: false });
7379
7446
  }, [gone]);
7380
7447
  useIsomorphicLayoutEffect(() => {
@@ -7413,7 +7480,7 @@ function RowContextMenu({
7413
7480
  onClose(menuKey, reason);
7414
7481
  }
7415
7482
  },
7416
- children: shownGroups.current.map((group, index) => /* @__PURE__ */ jsxs34(React35.Fragment, { children: [
7483
+ children: shownGroups.current.map((group, index) => /* @__PURE__ */ jsxs34(React36.Fragment, { children: [
7417
7484
  index > 0 ? /* @__PURE__ */ jsx38(DropdownMenuSeparator, {}) : null,
7418
7485
  /* @__PURE__ */ jsxs34(DropdownMenuGroup, { children: [
7419
7486
  group.label ? /* @__PURE__ */ jsx38(DropdownMenuLabel, { children: group.label }) : null,
@@ -7440,7 +7507,7 @@ function getRenderedCell(row, column) {
7440
7507
  if (value === null || value === void 0) {
7441
7508
  return null;
7442
7509
  }
7443
- if (React35.isValidElement(value)) {
7510
+ if (React36.isValidElement(value)) {
7444
7511
  return value;
7445
7512
  }
7446
7513
  return String(value);
@@ -7669,7 +7736,7 @@ var expandedPanelClass = cn(
7669
7736
  );
7670
7737
  var expandChevronClass = "motion-safe:transition-transform motion-safe:duration-[var(--dur-base)] motion-safe:ease-[var(--ease-standard)]";
7671
7738
  function useOpenedOnce(expanded) {
7672
- const [opened, setOpened] = React35.useState(expanded);
7739
+ const [opened, setOpened] = React36.useState(expanded);
7673
7740
  if (expanded && !opened) {
7674
7741
  setOpened(true);
7675
7742
  }
@@ -7926,9 +7993,9 @@ function DataTableMobileCardView({
7926
7993
  }
7927
7994
  );
7928
7995
  }
7929
- var MemoDataTableRow = React35.memo(DataTableRowView);
7930
- var MemoDataTableMobileCard = React35.memo(DataTableMobileCardView);
7931
- var useIsomorphicLayoutEffect = typeof window === "undefined" ? React35.useEffect : React35.useLayoutEffect;
7996
+ var MemoDataTableRow = React36.memo(DataTableRowView);
7997
+ var MemoDataTableMobileCard = React36.memo(DataTableMobileCardView);
7998
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? React36.useEffect : React36.useLayoutEffect;
7932
7999
  var VIRTUAL_DEFAULT_OVERSCAN = 8;
7933
8000
  var VIRTUAL_INITIAL_ROWS = 24;
7934
8001
  var VIRTUAL_FALLBACK_SIZE = { desktop: 48, mobile: 120 };
@@ -8008,7 +8075,7 @@ function useVirtualWindow({
8008
8075
  mobileListRef
8009
8076
  }) {
8010
8077
  const count = rowIds.length;
8011
- const [win, setWin] = React35.useState({
8078
+ const [win, setWin] = React36.useState({
8012
8079
  layout: null,
8013
8080
  start: 0,
8014
8081
  end: VIRTUAL_INITIAL_ROWS,
@@ -8016,12 +8083,12 @@ function useVirtualWindow({
8016
8083
  padTop: 0,
8017
8084
  padBottom: 0
8018
8085
  });
8019
- const desktopSize = React35.useRef(0);
8020
- const cardHeights = React35.useRef(null);
8086
+ const desktopSize = React36.useRef(0);
8087
+ const cardHeights = React36.useRef(null);
8021
8088
  cardHeights.current ??= new CardHeights();
8022
- const update = React35.useRef(() => void 0);
8023
- const reported = React35.useRef("");
8024
- const latest = React35.useRef({
8089
+ const update = React36.useRef(() => void 0);
8090
+ const reported = React36.useRef("");
8091
+ const latest = React36.useRef({
8025
8092
  count,
8026
8093
  layout: "desktop",
8027
8094
  extent: uniformExtent(VIRTUAL_FALLBACK_SIZE.desktop)
@@ -8084,7 +8151,7 @@ function useVirtualWindow({
8084
8151
  useIsomorphicLayoutEffect(() => {
8085
8152
  update.current();
8086
8153
  });
8087
- React35.useEffect(() => {
8154
+ React36.useEffect(() => {
8088
8155
  if (!enabled) {
8089
8156
  return;
8090
8157
  }
@@ -8106,7 +8173,7 @@ function useVirtualWindow({
8106
8173
  window.cancelAnimationFrame(frame);
8107
8174
  };
8108
8175
  }, [enabled]);
8109
- const scrollToIndex = React35.useCallback(
8176
+ const scrollToIndex = React36.useCallback(
8110
8177
  (index) => {
8111
8178
  const { count: rowCount, layout, extent } = latest.current;
8112
8179
  const list = (layout === "desktop" ? desktopListRef : mobileListRef).current;
@@ -8139,7 +8206,7 @@ function useVisibleLayout({
8139
8206
  desktopRef,
8140
8207
  mobileRef
8141
8208
  }) {
8142
- const [layout, setLayout] = React35.useState(null);
8209
+ const [layout, setLayout] = React36.useState(null);
8143
8210
  useIsomorphicLayoutEffect(() => {
8144
8211
  if (!enabled) {
8145
8212
  return;
@@ -8176,9 +8243,9 @@ function useLayoutFocusHandoff({
8176
8243
  layout,
8177
8244
  containers
8178
8245
  }) {
8179
- const lastFocus = React35.useRef(null);
8180
- const previousLayout = React35.useRef(layout);
8181
- React35.useEffect(() => {
8246
+ const lastFocus = React36.useRef(null);
8247
+ const previousLayout = React36.useRef(layout);
8248
+ React36.useEffect(() => {
8182
8249
  const root = rootRef.current;
8183
8250
  if (!root) {
8184
8251
  return;
@@ -8281,13 +8348,13 @@ function DataTableInner({
8281
8348
  if (isVirtual && columns.some((column) => column.wrap)) {
8282
8349
  warnWrapVirtualOnce();
8283
8350
  }
8284
- const rootRef = React35.useRef(null);
8285
- const desktopRef = React35.useRef(null);
8286
- const headerRef = React35.useRef(null);
8287
- const desktopListRef = React35.useRef(null);
8288
- const mobileRef = React35.useRef(null);
8289
- const mobileListRef = React35.useRef(null);
8290
- const setRootRef = React35.useCallback(
8351
+ const rootRef = React36.useRef(null);
8352
+ const desktopRef = React36.useRef(null);
8353
+ const headerRef = React36.useRef(null);
8354
+ const desktopListRef = React36.useRef(null);
8355
+ const mobileRef = React36.useRef(null);
8356
+ const mobileListRef = React36.useRef(null);
8357
+ const setRootRef = React36.useCallback(
8291
8358
  (node) => {
8292
8359
  rootRef.current = node;
8293
8360
  if (typeof ref === "function") ref(node);
@@ -8306,7 +8373,7 @@ function DataTableInner({
8306
8373
  desktopListRef,
8307
8374
  mobileListRef
8308
8375
  });
8309
- React35.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
8376
+ React36.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
8310
8377
  const visibleLayout = useVisibleLayout({ enabled: !isVirtual, desktopRef, mobileRef });
8311
8378
  const activeLayout = isVirtual ? virtualWindow.layout : visibleLayout;
8312
8379
  useLayoutFocusHandoff({
@@ -8330,8 +8397,8 @@ function DataTableInner({
8330
8397
  const expandable = renderExpanded != null;
8331
8398
  const hasRowActions = rowActions != null;
8332
8399
  const gridTemplateColumns = getGridTemplate(columns, selectable, expandable, hasRowActions);
8333
- const panelIdBase = React35.useId();
8334
- const [ownExpandedIds, setOwnExpandedIds] = React35.useState(() => /* @__PURE__ */ new Set());
8400
+ const panelIdBase = React36.useId();
8401
+ const [ownExpandedIds, setOwnExpandedIds] = React36.useState(() => /* @__PURE__ */ new Set());
8335
8402
  const resolvedExpandedIds = expandedIds ?? ownExpandedIds;
8336
8403
  const toggleExpanded = (id) => {
8337
8404
  const nextIds = new Set(resolvedExpandedIds);
@@ -8377,8 +8444,8 @@ function DataTableInner({
8377
8444
  window.location.assign(href);
8378
8445
  }
8379
8446
  };
8380
- const [contextMenu, setContextMenu] = React35.useState(null);
8381
- const contextMenuKey = React35.useRef(0);
8447
+ const [contextMenu, setContextMenu] = React36.useState(null);
8448
+ const contextMenuKey = React36.useRef(0);
8382
8449
  const contextRow = contextMenu ? data.find((item) => getRowId(item, keyField) === contextMenu.rowId) : void 0;
8383
8450
  const contextActions = contextRow && rowActions ? rowActions(contextRow) : [];
8384
8451
  const contextGroups = countActions(contextActions) > 0 ? toActionGroups(contextActions) : null;
@@ -8419,23 +8486,23 @@ function DataTableInner({
8419
8486
  if (close.by === "item") close.item.onSelect();
8420
8487
  };
8421
8488
  const handleRowContextMenu = rowActions ? openRowContextMenu : onRowContextMenu;
8422
- const latestHandlers = React35.useRef({ toggleRow, activateRow, onRowContextMenu, handleRowContextMenu });
8489
+ const latestHandlers = React36.useRef({ toggleRow, activateRow, onRowContextMenu, handleRowContextMenu });
8423
8490
  useIsomorphicLayoutEffect(() => {
8424
8491
  latestHandlers.current = { toggleRow, activateRow, onRowContextMenu, handleRowContextMenu };
8425
8492
  });
8426
- const stableToggleRow = React35.useCallback(
8493
+ const stableToggleRow = React36.useCallback(
8427
8494
  (id, checked) => latestHandlers.current.toggleRow(id, checked),
8428
8495
  []
8429
8496
  );
8430
- const stableActivateRow = React35.useCallback(
8497
+ const stableActivateRow = React36.useCallback(
8431
8498
  (row, href, event) => latestHandlers.current.activateRow(row, href, event),
8432
8499
  []
8433
8500
  );
8434
- const stableRowContextMenu = React35.useCallback(
8501
+ const stableRowContextMenu = React36.useCallback(
8435
8502
  (rowId, event) => latestHandlers.current.onRowContextMenu?.(rowId, event),
8436
8503
  []
8437
8504
  );
8438
- const stableHandleRowContextMenu = React35.useCallback(
8505
+ const stableHandleRowContextMenu = React36.useCallback(
8439
8506
  (rowId, event) => latestHandlers.current.handleRowContextMenu?.(rowId, event),
8440
8507
  []
8441
8508
  );
@@ -8681,14 +8748,21 @@ function DataTableInner({
8681
8748
  }
8682
8749
  );
8683
8750
  }
8684
- var DataTable = React35.forwardRef(DataTableInner);
8751
+ var DataTable = React36.forwardRef(DataTableInner);
8685
8752
  DataTable.displayName = "DataTable";
8686
8753
 
8687
8754
  // src/components/ui/bulk-action-bar.tsx
8688
- import * as React36 from "react";
8689
- import { X as X4 } from "lucide-react";
8755
+ import * as React37 from "react";
8756
+ import { Ellipsis, X as X4 } from "lucide-react";
8690
8757
  import { jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
8691
- function CardActionButton({ action }) {
8758
+ var foldedStyle = {
8759
+ position: "absolute",
8760
+ top: 0,
8761
+ left: 0,
8762
+ visibility: "hidden",
8763
+ pointerEvents: "none"
8764
+ };
8765
+ function CardActionButton({ action, folded }) {
8692
8766
  const Icon = action.icon;
8693
8767
  return /* @__PURE__ */ jsxs35(
8694
8768
  Button,
@@ -8696,9 +8770,13 @@ function CardActionButton({ action }) {
8696
8770
  appearance: "outline",
8697
8771
  tone: action.variant === "destructive" ? "danger" : "neutral",
8698
8772
  size: "sm",
8699
- className: "before:-inset-y-[5px]",
8773
+ className: "shrink-0 before:-inset-y-[5px]",
8700
8774
  "data-slot": "bulk-action-bar-action",
8701
8775
  "data-variant": action.variant ?? "default",
8776
+ "data-folded": folded ? "" : void 0,
8777
+ "aria-hidden": folded || void 0,
8778
+ tabIndex: folded ? -1 : void 0,
8779
+ style: folded ? foldedStyle : void 0,
8702
8780
  disabled: action.disabled,
8703
8781
  title: action.title,
8704
8782
  onClick: action.onClick,
@@ -8717,6 +8795,191 @@ function CardActionButton({ action }) {
8717
8795
  }
8718
8796
  );
8719
8797
  }
8798
+ var BAR_LABEL = "\uC120\uD0DD \uD56D\uBAA9 \uC77C\uAD04 \uC791\uC5C5";
8799
+ var TO_LIST_LABEL = "\uBAA9\uB85D\uC73C\uB85C";
8800
+ var MORE_LABEL = "\uB354\uBCF4\uAE30";
8801
+ var BAR_SELECTOR = '[data-slot="bulk-action-bar"]';
8802
+ var ROW_SELECTOR = "[data-row-id]";
8803
+ var LIST_SELECTOR = '[role="rowgroup"],[role="list"],[role="listbox"],[role="grid"],[role="treegrid"],[role="tree"],[role="table"],table,tbody,ul,ol';
8804
+ var TEXT_ENTRY_SELECTOR = 'textarea,select,[contenteditable]:not([contenteditable="false"]),[role="textbox"],[role="combobox"],[role="searchbox"]';
8805
+ var NON_TEXT_INPUTS = /* @__PURE__ */ new Set(["checkbox", "radio", "button", "submit", "reset", "image", "file", "range", "color"]);
8806
+ function isShortcut(event) {
8807
+ return event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey && event.code === "Period";
8808
+ }
8809
+ function isTextEntry(target) {
8810
+ if (!(target instanceof Element)) return false;
8811
+ if (target instanceof HTMLInputElement) return !NON_TEXT_INPUTS.has(target.type);
8812
+ return target.isContentEditable === true || target.closest(TEXT_ENTRY_SELECTOR) !== null;
8813
+ }
8814
+ function isShown(node) {
8815
+ return typeof node.checkVisibility === "function" ? node.checkVisibility() : true;
8816
+ }
8817
+ function rowsIn(container) {
8818
+ const seen = /* @__PURE__ */ new Set();
8819
+ const rows = [];
8820
+ for (const node of container.querySelectorAll(ROW_SELECTOR)) {
8821
+ const id = node.getAttribute("data-row-id") ?? "";
8822
+ if (seen.has(id) || node.closest(BAR_SELECTOR) || !isShown(node)) continue;
8823
+ seen.add(id);
8824
+ rows.push(node);
8825
+ }
8826
+ return rows;
8827
+ }
8828
+ var listOf = (row) => row.parentElement?.closest(LIST_SELECTOR) ?? row.parentElement;
8829
+ var rowPosition = (row) => row?.getAttribute("aria-rowindex") ?? row?.getAttribute("aria-posinset") ?? null;
8830
+ function markOf(target) {
8831
+ const row = target.closest(ROW_SELECTOR);
8832
+ if (!row || row.closest(BAR_SELECTOR)) return null;
8833
+ const id = row.getAttribute("data-row-id") ?? "";
8834
+ const list = listOf(row);
8835
+ const rows = list ? rowsIn(list) : [];
8836
+ const index = rows.findIndex((node) => node.getAttribute("data-row-id") === id);
8837
+ return {
8838
+ id,
8839
+ checkbox: target.matches('[role="checkbox"],input[type="checkbox"]'),
8840
+ position: rowPosition(rows[index]),
8841
+ index,
8842
+ list
8843
+ };
8844
+ }
8845
+ function listIn(scope) {
8846
+ const row = rowsIn(scope)[0];
8847
+ if (row) return listOf(row);
8848
+ return Array.from(scope.querySelectorAll(LIST_SELECTOR)).find(
8849
+ (node) => !node.closest(BAR_SELECTOR) && isShown(node)
8850
+ ) ?? null;
8851
+ }
8852
+ function returnTarget(scope, mark) {
8853
+ const list = mark?.list && mark.list.isConnected && scope.contains(mark.list) && isShown(mark.list) ? mark.list : listIn(scope);
8854
+ if (mark && list) {
8855
+ const rows = rowsIn(list);
8856
+ const row = rows.find((node) => node.getAttribute("data-row-id") === mark.id) ?? (mark.position !== null ? rows.find((node) => rowPosition(node) === mark.position) : mark.index >= 0 ? rows[mark.index] : void 0);
8857
+ if (row) {
8858
+ return (mark.checkbox ? row.querySelector('[role="checkbox"],input[type="checkbox"]') : row.hasAttribute("tabindex") ? row : row.querySelector('[data-slot="data-table-row-link"],[data-slot="data-table-expand-cell"] button')) ?? row;
8859
+ }
8860
+ }
8861
+ return list ?? scope;
8862
+ }
8863
+ function focusTarget(target) {
8864
+ if (!target.hasAttribute("tabindex") && !target.matches("a[href],button,input,select,textarea")) {
8865
+ target.tabIndex = -1;
8866
+ }
8867
+ target.focus();
8868
+ }
8869
+ var shortcutBars = /* @__PURE__ */ new Set();
8870
+ function scopeOf(card, scopeProp) {
8871
+ return scopeProp?.current ?? card.closest('[data-slot="data-layout-region"]') ?? card.parentElement;
8872
+ }
8873
+ function depth(node) {
8874
+ let n = 0;
8875
+ for (let at = node; at; at = at.parentNode) n += 1;
8876
+ return n;
8877
+ }
8878
+ function ownerOf(target) {
8879
+ let owner = null;
8880
+ let ownerDepth = -1;
8881
+ for (const bar of shortcutBars) {
8882
+ if (bar.card.contains(target)) return bar;
8883
+ const scope = bar.scope();
8884
+ if (scope?.contains(target) && depth(scope) > ownerDepth) {
8885
+ owner = bar;
8886
+ ownerDepth = depth(scope);
8887
+ }
8888
+ }
8889
+ return owner;
8890
+ }
8891
+ var MODAL_SELECTOR = '[role="dialog"],[role="alertdialog"]';
8892
+ function isFocusVisible(node) {
8893
+ try {
8894
+ return node.matches(":focus-visible");
8895
+ } catch {
8896
+ return false;
8897
+ }
8898
+ }
8899
+ var isMac = () => {
8900
+ const nav = navigator;
8901
+ return /mac|iphone|ipad|ipod/i.test(nav.userAgentData?.platform || nav.platform || "");
8902
+ };
8903
+ var keyCapStyle = {
8904
+ display: "inline-flex",
8905
+ boxSizing: "border-box",
8906
+ height: 20,
8907
+ minWidth: 20,
8908
+ alignItems: "center",
8909
+ justifyContent: "center",
8910
+ padding: "0 var(--space-1)",
8911
+ borderRadius: "var(--radius-sm)",
8912
+ background: "var(--semantic-neutral-bg)",
8913
+ fontFamily: "var(--font-sans)",
8914
+ fontSize: 12,
8915
+ fontWeight: 500,
8916
+ lineHeight: 1,
8917
+ color: "var(--text-tertiary)"
8918
+ };
8919
+ var visuallyHiddenStyle = {
8920
+ position: "absolute",
8921
+ width: 1,
8922
+ height: 1,
8923
+ margin: -1,
8924
+ padding: 0,
8925
+ overflow: "hidden",
8926
+ clip: "rect(0 0 0 0)",
8927
+ whiteSpace: "nowrap",
8928
+ border: 0
8929
+ };
8930
+ function MoveButton({
8931
+ mac,
8932
+ shown,
8933
+ onMove
8934
+ }) {
8935
+ return /* @__PURE__ */ jsxs35(
8936
+ Button,
8937
+ {
8938
+ appearance: "outline",
8939
+ size: "sm",
8940
+ className: "mr-auto shrink-0 pr-[var(--space-2)] before:-inset-y-[5px] [@media(hover:none)_and_(pointer:coarse)]:hidden",
8941
+ style: shown ? void 0 : visuallyHiddenStyle,
8942
+ "data-slot": "bulk-action-bar-move",
8943
+ "data-hidden": shown ? void 0 : "",
8944
+ "aria-keyshortcuts": "Control+.",
8945
+ onMouseDown: (event) => event.preventDefault(),
8946
+ onClick: onMove,
8947
+ children: [
8948
+ /* @__PURE__ */ jsx39("span", { "data-slot": "bulk-action-bar-move-label", children: TO_LIST_LABEL }),
8949
+ /* @__PURE__ */ jsxs35("span", { "aria-hidden": "true", "data-slot": "bulk-action-bar-keys", style: { display: "inline-flex", gap: "var(--space-1)" }, children: [
8950
+ /* @__PURE__ */ jsx39("kbd", { style: keyCapStyle, children: mac ? "\u2303" : "Ctrl" }),
8951
+ /* @__PURE__ */ jsx39("kbd", { style: keyCapStyle, children: "." })
8952
+ ] })
8953
+ ]
8954
+ }
8955
+ );
8956
+ }
8957
+ var sameFold = (a, b) => a !== null && a.folded === b.folded && a.texts.join("\n") === b.texts.join("\n");
8958
+ var ROW_GAP = 8;
8959
+ var MORE_WIDTH = 30;
8960
+ var MOVE_EDGES = 2 + 12 + 6 + 8;
8961
+ function measureFold(row, actionCount) {
8962
+ const buttons = Array.from(row.querySelectorAll('[data-slot="bulk-action-bar-action"]'));
8963
+ const texts = buttons.map((node) => node.textContent ?? "");
8964
+ const available = row.clientWidth;
8965
+ if (available === 0) return { folded: 0, texts };
8966
+ const scale = row.getBoundingClientRect().width / available || 1;
8967
+ const width = (node) => (node?.getBoundingClientRect().width ?? 0) / scale;
8968
+ const move = row.querySelector('[data-slot="bulk-action-bar-move"]');
8969
+ const hasMove = move !== null && !move.hasAttribute("data-hidden") && isShown(move);
8970
+ const label = hasMove ? width(row.querySelector('[data-slot="bulk-action-bar-move-label"]')) : 0;
8971
+ const keys = hasMove ? width(row.querySelector('[data-slot="bulk-action-bar-keys"]')) : 0;
8972
+ const actions = buttons.map(width);
8973
+ const need = (folded2) => {
8974
+ const items = actions.slice(0, actionCount - folded2);
8975
+ if (hasMove) items.unshift(keys + label + MOVE_EDGES);
8976
+ if (folded2 > 0) items.push(MORE_WIDTH);
8977
+ return items.reduce((sum, item) => sum + item, 0) + ROW_GAP * Math.max(0, items.length - 1);
8978
+ };
8979
+ let folded = 0;
8980
+ while (folded < actionCount - 1 && need(folded) > available + 0.5) folded += 1;
8981
+ return { folded, texts };
8982
+ }
8720
8983
  var CLEAR_CLEARANCE = 32;
8721
8984
  var IDLE_HEIGHT = 40;
8722
8985
  var FLOATING_BOTTOM = "calc(var(--space-4) + env(safe-area-inset-bottom))";
@@ -8770,10 +9033,10 @@ function reportOffset(key, card) {
8770
9033
  else cardOffsets.delete(key);
8771
9034
  writeOffset();
8772
9035
  }
8773
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React36.useEffect : React36.useLayoutEffect;
9036
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React37.useEffect : React37.useLayoutEffect;
8774
9037
  function useBottomOffset(card) {
8775
- const [key] = React36.useState(() => ({}));
8776
- React36.useEffect(() => {
9038
+ const [key] = React37.useState(() => ({}));
9039
+ React37.useEffect(() => {
8777
9040
  if (!card) return;
8778
9041
  let frame = 0;
8779
9042
  let stopped = false;
@@ -8863,12 +9126,239 @@ function BulkActionBar({
8863
9126
  unit = "\uAC1C",
8864
9127
  summary,
8865
9128
  idleContent,
9129
+ shortcut = true,
9130
+ shortcutScope,
8866
9131
  className,
8867
9132
  style,
9133
+ "aria-label": ariaLabelProp,
8868
9134
  ...props
8869
9135
  }) {
8870
- const [card, setCard] = React36.useState(null);
9136
+ const ariaLabel = ariaLabelProp ?? BAR_LABEL;
9137
+ const [card, setCard] = React37.useState(null);
8871
9138
  useBottomOffset(card);
9139
+ const active = shortcut && count > 0;
9140
+ const cardRef = React37.useRef(null);
9141
+ const activeRef = React37.useRef(false);
9142
+ const scopePropRef = React37.useRef(shortcutScope);
9143
+ const markRef = React37.useRef(null);
9144
+ const moreRef = React37.useRef(null);
9145
+ const foldedFocusRef = React37.useRef(null);
9146
+ const focusedActionRef = React37.useRef(null);
9147
+ const moreLostFocusRef = React37.useRef(false);
9148
+ const [menuOpen, setMenuOpen] = React37.useState(false);
9149
+ const menuOpenRef = React37.useRef(false);
9150
+ const menuKeysRef = React37.useRef([]);
9151
+ const clearRef = React37.useRef(null);
9152
+ const [mac, setMac] = React37.useState(false);
9153
+ const [row, setRow] = React37.useState(null);
9154
+ const [fold, setFold] = React37.useState(null);
9155
+ React37.useEffect(() => setMac(isMac()), []);
9156
+ useIsomorphicLayoutEffect2(() => {
9157
+ activeRef.current = active;
9158
+ scopePropRef.current = shortcutScope;
9159
+ menuOpenRef.current = menuOpen;
9160
+ menuKeysRef.current = actions.slice(actions.length - Math.min(fold?.folded ?? 0, Math.max(0, actions.length - 1))).map((action) => action.key);
9161
+ });
9162
+ const toBar = React37.useCallback(() => {
9163
+ const node = cardRef.current;
9164
+ if (!node) return;
9165
+ const actionButtons = Array.from(node.querySelectorAll('[data-slot="bulk-action-bar-action"]'));
9166
+ const move = node.querySelector('[data-slot="bulk-action-bar-move"]');
9167
+ const target = actionButtons.find((button) => !button.disabled && !button.hasAttribute("data-folded")) ?? (actionButtons.some((button) => !button.disabled) ? moreRef.current : null) ?? (move && isShown(move) ? move : null) ?? clearRef.current;
9168
+ target?.focus();
9169
+ }, []);
9170
+ const toList = React37.useCallback(() => {
9171
+ const scope = cardRef.current && scopeOf(cardRef.current, scopePropRef.current);
9172
+ if (scope) focusTarget(returnTarget(scope, markRef.current));
9173
+ }, []);
9174
+ React37.useEffect(() => {
9175
+ if (!active || !card) return;
9176
+ const resolveScope = () => scopeOf(card, scopePropRef.current);
9177
+ const bar = { card, scope: resolveScope };
9178
+ const note = (target) => {
9179
+ const scope = resolveScope();
9180
+ if (!(target instanceof Element) || !scope?.contains(target) || card.contains(target)) return;
9181
+ const mark = markOf(target);
9182
+ if (mark) markRef.current = mark;
9183
+ };
9184
+ markRef.current = null;
9185
+ note(document.activeElement);
9186
+ const onFocusIn = (event) => note(event.target);
9187
+ const onKeyDown = (event) => {
9188
+ if (!isShortcut(event) || event.isComposing || event.defaultPrevented || isTextEntry(event.target)) return;
9189
+ if (!(event.target instanceof Node) || ownerOf(event.target) !== bar) return;
9190
+ event.preventDefault();
9191
+ if (card.contains(event.target)) toList();
9192
+ else toBar();
9193
+ };
9194
+ shortcutBars.add(bar);
9195
+ window.addEventListener("focusin", onFocusIn);
9196
+ window.addEventListener("keydown", onKeyDown);
9197
+ return () => {
9198
+ shortcutBars.delete(bar);
9199
+ window.removeEventListener("focusin", onFocusIn);
9200
+ window.removeEventListener("keydown", onKeyDown);
9201
+ };
9202
+ }, [active, card, toBar, toList]);
9203
+ const [keyboardIn, setKeyboardIn] = React37.useState(false);
9204
+ React37.useEffect(() => {
9205
+ if (!active || !card) return;
9206
+ let timer = 0;
9207
+ let holder = null;
9208
+ let holderGiveUp = 0;
9209
+ let pressed = false;
9210
+ const read = () => {
9211
+ timer = 0;
9212
+ if (pressed) return;
9213
+ const focused = document.activeElement;
9214
+ if (menuOpenRef.current) return;
9215
+ if (holder) {
9216
+ if (focused && focused !== document.body && holder.contains(focused)) {
9217
+ window.clearTimeout(holderGiveUp);
9218
+ holderGiveUp = 0;
9219
+ return;
9220
+ }
9221
+ if (!focused || focused === document.body) {
9222
+ if (!holderGiveUp) {
9223
+ holderGiveUp = window.setTimeout(() => {
9224
+ holder = null;
9225
+ schedule();
9226
+ }, 1e3);
9227
+ }
9228
+ return;
9229
+ }
9230
+ holder = null;
9231
+ }
9232
+ window.clearTimeout(holderGiveUp);
9233
+ holderGiveUp = 0;
9234
+ setKeyboardIn(focused instanceof Element && card.contains(focused) && (focused.matches('[data-slot="bulk-action-bar-move"]') || isFocusVisible(focused)));
9235
+ };
9236
+ const schedule = () => {
9237
+ if (!timer) timer = window.setTimeout(read, 0);
9238
+ };
9239
+ const onFocusIn = (event) => {
9240
+ const target = event.target instanceof Element ? event.target : null;
9241
+ const content = target?.closest('[role="menu"],[data-slot="action-menu-sheet"]');
9242
+ const id = moreRef.current?.getAttribute("aria-controls");
9243
+ const dialog = target?.closest(MODAL_SELECTOR);
9244
+ if (content && menuOpenRef.current && (!id || content.id === id || content.matches('[data-slot="action-menu-sheet"]'))) holder = content;
9245
+ else if (dialog && !card.contains(dialog) && !dialog.contains(card)) holder = dialog;
9246
+ schedule();
9247
+ };
9248
+ const onPointerDown = () => {
9249
+ pressed = true;
9250
+ };
9251
+ const onPointerUp = () => {
9252
+ pressed = false;
9253
+ schedule();
9254
+ };
9255
+ const onVisibility = () => {
9256
+ if (document.visibilityState === "hidden") onPointerUp();
9257
+ };
9258
+ read();
9259
+ window.addEventListener("focusout", schedule, true);
9260
+ window.addEventListener("focusin", onFocusIn, true);
9261
+ window.addEventListener("pointerdown", onPointerDown, true);
9262
+ for (const type of ["pointerup", "pointercancel", "keydown"]) window.addEventListener(type, onPointerUp, true);
9263
+ window.addEventListener("blur", onPointerUp);
9264
+ document.addEventListener("visibilitychange", onVisibility);
9265
+ return () => {
9266
+ window.clearTimeout(timer);
9267
+ window.clearTimeout(holderGiveUp);
9268
+ window.removeEventListener("focusout", schedule, true);
9269
+ window.removeEventListener("focusin", onFocusIn, true);
9270
+ window.removeEventListener("pointerdown", onPointerDown, true);
9271
+ for (const type of ["pointerup", "pointercancel", "keydown"]) window.removeEventListener(type, onPointerUp, true);
9272
+ window.removeEventListener("blur", onPointerUp);
9273
+ document.removeEventListener("visibilitychange", onVisibility);
9274
+ };
9275
+ }, [active, card]);
9276
+ React37.useEffect(() => {
9277
+ if (!card) return;
9278
+ const onFocusIn = (event) => {
9279
+ const target = event.target instanceof HTMLElement ? event.target : null;
9280
+ focusedActionRef.current = target?.matches('[data-slot="bulk-action-bar-action"]') ? target : null;
9281
+ };
9282
+ const onFocusOut = (event) => {
9283
+ const folding = event.relatedTarget === null && event.target instanceof Element && event.target.hasAttribute("data-folded");
9284
+ if (!folding) focusedActionRef.current = null;
9285
+ };
9286
+ card.addEventListener("focusin", onFocusIn);
9287
+ card.addEventListener("focusout", onFocusOut);
9288
+ return () => {
9289
+ card.removeEventListener("focusin", onFocusIn);
9290
+ card.removeEventListener("focusout", onFocusOut);
9291
+ };
9292
+ }, [card]);
9293
+ const handleCard = React37.useCallback((node) => {
9294
+ const previous = cardRef.current;
9295
+ cardRef.current = node;
9296
+ setCard(node);
9297
+ if (node || !previous || !activeRef.current || !previous.contains(document.activeElement)) return;
9298
+ const scope = scopeOf(previous, scopePropRef.current);
9299
+ const mark = markRef.current;
9300
+ queueMicrotask(() => {
9301
+ const now = document.activeElement;
9302
+ if (now && now !== document.body && now.isConnected) return;
9303
+ if (scope?.isConnected) focusTarget(returnTarget(scope, mark));
9304
+ });
9305
+ }, []);
9306
+ const handleMore = React37.useCallback((node) => {
9307
+ const focused = document.activeElement;
9308
+ if (!node && moreRef.current && focused === moreRef.current) moreLostFocusRef.current = true;
9309
+ const menu = !node && menuOpenRef.current ? focused?.closest('[role="menu"],[data-slot="action-menu-sheet"]') : null;
9310
+ if (menu) {
9311
+ const items = Array.from(menu.querySelectorAll('[role="menuitem"],[data-slot="action-menu-item"]'));
9312
+ foldedFocusRef.current = menuKeysRef.current[items.indexOf(focused)] ?? null;
9313
+ moreLostFocusRef.current = true;
9314
+ }
9315
+ moreRef.current = node;
9316
+ }, []);
9317
+ const actionCount = actions.length;
9318
+ useIsomorphicLayoutEffect2(() => {
9319
+ if (!row) return;
9320
+ const buttons = Array.from(row.querySelectorAll('[data-slot="bulk-action-bar-action"]'));
9321
+ const focused = document.activeElement;
9322
+ const lost = focusedActionRef.current;
9323
+ const index = lost ? buttons.findIndex((button) => button === lost) : -1;
9324
+ const blurred = !focused || focused === document.body || focused === lost;
9325
+ if (index >= 0 && buttons[index].hasAttribute("data-folded") && blurred && moreRef.current) {
9326
+ focusedActionRef.current = null;
9327
+ foldedFocusRef.current = actions[index]?.key ?? null;
9328
+ moreRef.current.focus();
9329
+ } else if (moreLostFocusRef.current) {
9330
+ moreLostFocusRef.current = false;
9331
+ if (!focused || focused === document.body) {
9332
+ const shown = (button) => !button.disabled && !button.hasAttribute("data-folded");
9333
+ const back = buttons.find((button, i) => actions[i]?.key === foldedFocusRef.current && shown(button)) ?? buttons.find(shown);
9334
+ back?.focus();
9335
+ }
9336
+ foldedFocusRef.current = null;
9337
+ }
9338
+ if (!moreRef.current) setMenuOpen(false);
9339
+ const next = measureFold(row, actionCount);
9340
+ setFold((current) => sameFold(current, next) ? current : next);
9341
+ });
9342
+ React37.useEffect(() => {
9343
+ if (!row || typeof ResizeObserver === "undefined") return;
9344
+ const update = () => {
9345
+ const next = measureFold(row, actionCount);
9346
+ setFold((current) => sameFold(current, next) ? current : next);
9347
+ };
9348
+ const observer = new ResizeObserver(update);
9349
+ observer.observe(row);
9350
+ for (const node of row.querySelectorAll(
9351
+ '[data-slot="bulk-action-bar-action"],[data-slot="bulk-action-bar-move-label"],[data-slot="bulk-action-bar-keys"]'
9352
+ )) {
9353
+ observer.observe(node);
9354
+ }
9355
+ const texts = new MutationObserver(update);
9356
+ texts.observe(row, { characterData: true, childList: true, subtree: true });
9357
+ return () => {
9358
+ observer.disconnect();
9359
+ texts.disconnect();
9360
+ };
9361
+ }, [row, actionCount, active]);
8872
9362
  if (count === 0 && idleContent !== void 0) {
8873
9363
  return /* @__PURE__ */ jsx39(
8874
9364
  "div",
@@ -8880,6 +9370,7 @@ function BulkActionBar({
8880
9370
  className,
8881
9371
  style: { ...idleLineStyle, ...style },
8882
9372
  ...props,
9373
+ "aria-label": ariaLabelProp,
8883
9374
  children: idleContent
8884
9375
  }
8885
9376
  );
@@ -8928,11 +9419,27 @@ function BulkActionBar({
8928
9419
  children: summary
8929
9420
  }
8930
9421
  ) : null;
8931
- return /* @__PURE__ */ jsxs35(
8932
- "div",
9422
+ const showMove = active;
9423
+ const folded = Math.min(fold?.folded ?? 0, Math.max(0, actions.length - 1));
9424
+ const shownCount = actions.length - folded;
9425
+ const menuItems = actions.slice(shownCount).map((action, i) => ({
9426
+ id: action.key,
9427
+ // The menu takes text (also its typeahead text): a node label goes in as its rendered text.
9428
+ label: typeof action.label === "string" ? action.label : fold?.texts[shownCount + i] || action.key,
9429
+ icon: action.icon,
9430
+ destructive: action.variant === "destructive",
9431
+ disabled: action.disabled,
9432
+ // `title` of an action that cannot run is its reason, under the label; of one that can, the
9433
+ // dropdown item's tooltip and the menu sheet's line under the label.
9434
+ disabledReason: action.disabled ? action.title : void 0,
9435
+ description: action.disabled ? void 0 : action.title,
9436
+ title: action.disabled ? void 0 : action.title,
9437
+ onSelect: action.onClick
9438
+ }));
9439
+ return /* @__PURE__ */ jsx39(
9440
+ "section",
8933
9441
  {
8934
- role: "toolbar",
8935
- "aria-label": "\uC120\uD0DD \uD56D\uBAA9 \uC77C\uAD04 \uC791\uC5C5",
9442
+ "aria-label": ariaLabel,
8936
9443
  "data-slot": "bulk-action-bar",
8937
9444
  className: cn(
8938
9445
  // Subtle entrance when the bar appears (count>0). CSS animation runs once
@@ -8940,51 +9447,90 @@ function BulkActionBar({
8940
9447
  "animate-[olun-bulk-action-bar-in_var(--dur-fast)_var(--ease-out)_both] motion-reduce:animate-none",
8941
9448
  className
8942
9449
  ),
8943
- ref: setCard,
9450
+ ref: handleCard,
8944
9451
  style: { ...floatingStyle, ...style },
8945
9452
  ...props,
8946
- children: [
8947
- /* @__PURE__ */ jsxs35(
8948
- "div",
8949
- {
8950
- role: "status",
8951
- "data-slot": "bulk-action-bar-state",
8952
- style: {
8953
- display: "flex",
8954
- minWidth: 0,
8955
- flexDirection: "column",
8956
- rowGap: "var(--space-2)"
8957
- },
8958
- children: [
8959
- countLabel,
8960
- summarySlot
8961
- ]
8962
- }
8963
- ),
8964
- actions.length > 0 ? /* @__PURE__ */ jsx39(
8965
- "div",
8966
- {
8967
- "data-slot": "bulk-action-bar-actions",
8968
- style: {
8969
- display: "flex",
8970
- flexWrap: "wrap",
8971
- justifyContent: "flex-end",
8972
- gap: "var(--space-2)",
8973
- marginTop: "var(--space-3)"
8974
- },
8975
- children: actions.map((action) => /* @__PURE__ */ jsx39(CardActionButton, { action }, action.key))
8976
- }
8977
- ) : null,
8978
- /* @__PURE__ */ jsx39(
8979
- IconButton,
8980
- {
8981
- icon: X4,
8982
- "aria-label": "\uC120\uD0DD \uD574\uC81C",
8983
- onClick: onClear,
8984
- style: { position: "absolute", top: "var(--space-2)", right: "var(--space-2)" }
8985
- }
8986
- )
8987
- ]
9453
+ children: /* @__PURE__ */ jsxs35(
9454
+ "div",
9455
+ {
9456
+ role: "toolbar",
9457
+ "aria-label": ariaLabel,
9458
+ "data-slot": "bulk-action-bar-toolbar",
9459
+ style: { display: "flex", minWidth: 0, flexDirection: "column" },
9460
+ children: [
9461
+ /* @__PURE__ */ jsxs35(
9462
+ "div",
9463
+ {
9464
+ role: "status",
9465
+ "data-slot": "bulk-action-bar-state",
9466
+ style: {
9467
+ display: "flex",
9468
+ minWidth: 0,
9469
+ flexDirection: "column",
9470
+ rowGap: "var(--space-2)"
9471
+ },
9472
+ children: [
9473
+ countLabel,
9474
+ summarySlot
9475
+ ]
9476
+ }
9477
+ ),
9478
+ actions.length > 0 || showMove ? (
9479
+ // One line: move button at the left, actions at the right, then ⋯ for folded ones.
9480
+ /* @__PURE__ */ jsxs35(
9481
+ "div",
9482
+ {
9483
+ ref: setRow,
9484
+ "data-slot": "bulk-action-bar-actions",
9485
+ style: {
9486
+ position: "relative",
9487
+ display: "flex",
9488
+ minWidth: 0,
9489
+ flexWrap: fold ? "nowrap" : "wrap",
9490
+ alignItems: "center",
9491
+ justifyContent: "flex-end",
9492
+ gap: "var(--space-2)",
9493
+ marginTop: "var(--space-3)"
9494
+ },
9495
+ children: [
9496
+ showMove ? /* @__PURE__ */ jsx39(MoveButton, { mac, shown: keyboardIn, onMove: toList }) : null,
9497
+ actions.map((action, index) => /* @__PURE__ */ jsx39(CardActionButton, { action, folded: index >= shownCount }, action.key)),
9498
+ folded > 0 ? /* @__PURE__ */ jsx39(
9499
+ ActionMenu,
9500
+ {
9501
+ open: menuOpen,
9502
+ onOpenChange: setMenuOpen,
9503
+ items: menuItems,
9504
+ trigger: /* @__PURE__ */ jsx39(
9505
+ IconButton,
9506
+ {
9507
+ ref: handleMore,
9508
+ icon: Ellipsis,
9509
+ "aria-label": MORE_LABEL,
9510
+ appearance: "outline",
9511
+ size: "sm",
9512
+ className: "shrink-0"
9513
+ }
9514
+ )
9515
+ }
9516
+ ) : null
9517
+ ]
9518
+ }
9519
+ )
9520
+ ) : null,
9521
+ /* @__PURE__ */ jsx39(
9522
+ IconButton,
9523
+ {
9524
+ ref: clearRef,
9525
+ icon: X4,
9526
+ "aria-label": "\uC120\uD0DD \uD574\uC81C",
9527
+ onClick: onClear,
9528
+ style: { position: "absolute", top: "var(--space-2)", right: "var(--space-2)" }
9529
+ }
9530
+ )
9531
+ ]
9532
+ }
9533
+ )
8988
9534
  }
8989
9535
  );
8990
9536
  }
@@ -9233,7 +9779,7 @@ function ActionSheet({
9233
9779
  }
9234
9780
 
9235
9781
  // src/components/ui/badge.tsx
9236
- import * as React37 from "react";
9782
+ import * as React38 from "react";
9237
9783
  import { jsx as jsx45 } from "react/jsx-runtime";
9238
9784
  var TONE = {
9239
9785
  neutral: "bg-[var(--fill-on-bg,var(--semantic-neutral-bg))] text-[var(--semantic-neutral-fg)]",
@@ -9243,7 +9789,7 @@ var TONE = {
9243
9789
  error: "bg-[var(--semantic-error-bg)] text-[var(--semantic-error-fg)]",
9244
9790
  brand: "bg-[var(--accent-bg-strong)] text-[var(--accent)]"
9245
9791
  };
9246
- var Badge = React37.forwardRef(
9792
+ var Badge = React38.forwardRef(
9247
9793
  ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsx45(
9248
9794
  "span",
9249
9795
  {
@@ -9264,7 +9810,7 @@ var Badge = React37.forwardRef(
9264
9810
  Badge.displayName = "Badge";
9265
9811
 
9266
9812
  // src/components/ui/two-tier-badge.tsx
9267
- import * as React38 from "react";
9813
+ import * as React39 from "react";
9268
9814
  import { jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
9269
9815
  var FG = {
9270
9816
  neutral: "var(--text-secondary)",
@@ -9287,7 +9833,7 @@ var SEGMENT = {
9287
9833
  md: "gap-[7px] py-[var(--space-1)] px-[var(--space-3)] text-[14px]"
9288
9834
  };
9289
9835
  var DOT = { xs: 5, sm: 6, md: 7 };
9290
- var TwoTierBadge = React38.forwardRef(
9836
+ var TwoTierBadge = React39.forwardRef(
9291
9837
  ({ primary, secondary, tone = "neutral", emphasis = "subtle", size = "sm", showDot = false, className, style, ...props }, ref) => {
9292
9838
  const strong = emphasis === "strong";
9293
9839
  const fg = FG[tone];
@@ -9357,7 +9903,7 @@ var TwoTierBadge = React38.forwardRef(
9357
9903
  TwoTierBadge.displayName = "TwoTierBadge";
9358
9904
 
9359
9905
  // src/components/ui/status-badge.tsx
9360
- import * as React39 from "react";
9906
+ import * as React40 from "react";
9361
9907
  import { jsx as jsx47 } from "react/jsx-runtime";
9362
9908
  var ROLE = {
9363
9909
  error: "error",
@@ -9368,13 +9914,13 @@ var ROLE = {
9368
9914
  success: "success",
9369
9915
  archived: "neutral"
9370
9916
  };
9371
- var StatusBadge = React39.forwardRef(
9917
+ var StatusBadge = React40.forwardRef(
9372
9918
  ({ status = "active", emphasis: _emphasis, size: _size, showDot: _showDot, pulse: _pulse, ...props }, ref) => /* @__PURE__ */ jsx47(Badge, { ref, tone: ROLE[status], ...props })
9373
9919
  );
9374
9920
  StatusBadge.displayName = "StatusBadge";
9375
9921
 
9376
9922
  // src/components/ui/status-dot.tsx
9377
- import * as React40 from "react";
9923
+ import * as React41 from "react";
9378
9924
  import { jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
9379
9925
  var DOT2 = {
9380
9926
  neutral: "bg-[var(--semantic-neutral-fg)]",
@@ -9383,7 +9929,7 @@ var DOT2 = {
9383
9929
  warning: "bg-[var(--semantic-warning-fg)]",
9384
9930
  error: "bg-[var(--semantic-error-fg)]"
9385
9931
  };
9386
- var StatusDot = React40.forwardRef(
9932
+ var StatusDot = React41.forwardRef(
9387
9933
  ({ tone, label, pulse = false, className, ...props }, ref) => /* @__PURE__ */ jsxs38(
9388
9934
  "span",
9389
9935
  {
@@ -9417,7 +9963,7 @@ var StatusDot = React40.forwardRef(
9417
9963
  StatusDot.displayName = "StatusDot";
9418
9964
 
9419
9965
  // src/components/ui/notification-badge.tsx
9420
- import * as React41 from "react";
9966
+ import * as React42 from "react";
9421
9967
  import { cva as cva14 } from "class-variance-authority";
9422
9968
  import { jsx as jsx49, jsxs as jsxs39 } from "react/jsx-runtime";
9423
9969
  var notificationBadgeVariants = cva14(
@@ -9450,7 +9996,7 @@ function formatNotificationCount(count, max) {
9450
9996
  }
9451
9997
  return String(count);
9452
9998
  }
9453
- var NotificationBadge = React41.forwardRef(
9999
+ var NotificationBadge = React42.forwardRef(
9454
10000
  ({
9455
10001
  className,
9456
10002
  count,
@@ -9485,7 +10031,7 @@ var NotificationBadge = React41.forwardRef(
9485
10031
  NotificationBadge.displayName = "NotificationBadge";
9486
10032
 
9487
10033
  // src/components/ui/empty-state.tsx
9488
- import * as React42 from "react";
10034
+ import * as React43 from "react";
9489
10035
  import { cva as cva15 } from "class-variance-authority";
9490
10036
  import { jsx as jsx50, jsxs as jsxs40 } from "react/jsx-runtime";
9491
10037
  var emptyStateBaseVariants = cva15(
@@ -9513,7 +10059,7 @@ var emptyStateBaseVariants = cva15(
9513
10059
  }
9514
10060
  );
9515
10061
  var PAGE_FILL_QUERY = "(min-width: 768px)";
9516
- var useIsomorphicLayoutEffect3 = typeof window === "undefined" ? React42.useEffect : React42.useLayoutEffect;
10062
+ var useIsomorphicLayoutEffect3 = typeof window === "undefined" ? React43.useEffect : React43.useLayoutEffect;
9517
10063
  function findScrollParent(node) {
9518
10064
  for (let el = node.parentElement; el && el !== document.body && el !== document.documentElement; el = el.parentElement) {
9519
10065
  const { overflowY } = getComputedStyle(el);
@@ -9625,7 +10171,7 @@ var iconSize2 = {
9625
10171
  md: 20,
9626
10172
  lg: 24
9627
10173
  };
9628
- var EmptyState = React42.forwardRef(
10174
+ var EmptyState = React43.forwardRef(
9629
10175
  ({
9630
10176
  className,
9631
10177
  size = "md",
@@ -9641,7 +10187,7 @@ var EmptyState = React42.forwardRef(
9641
10187
  ...props
9642
10188
  }, ref) => {
9643
10189
  const resolvedSize = size ?? "md";
9644
- const pageRef = React42.useRef(null);
10190
+ const pageRef = React43.useRef(null);
9645
10191
  usePageFill(pageRef, layout === "page");
9646
10192
  const box = /* @__PURE__ */ jsxs40(
9647
10193
  "div",
@@ -9707,7 +10253,7 @@ var EmptyState = React42.forwardRef(
9707
10253
  EmptyState.displayName = "EmptyState";
9708
10254
 
9709
10255
  // src/components/ui/error-state.tsx
9710
- import * as React43 from "react";
10256
+ import * as React44 from "react";
9711
10257
  import { AlertTriangle } from "lucide-react";
9712
10258
  import { cva as cva16 } from "class-variance-authority";
9713
10259
  import { jsx as jsx51, jsxs as jsxs41 } from "react/jsx-runtime";
@@ -9732,7 +10278,7 @@ var errorStateVariants = cva16(
9732
10278
  }
9733
10279
  }
9734
10280
  );
9735
- var ErrorState = React43.forwardRef(
10281
+ var ErrorState = React44.forwardRef(
9736
10282
  ({
9737
10283
  className,
9738
10284
  size = "md",
@@ -9770,14 +10316,14 @@ var ErrorState = React43.forwardRef(
9770
10316
  children: title
9771
10317
  }
9772
10318
  ),
9773
- /* @__PURE__ */ jsx51(
10319
+ message || message === 0 ? /* @__PURE__ */ jsx51(
9774
10320
  "p",
9775
10321
  {
9776
10322
  "data-slot": "error-state-message",
9777
10323
  className: "break-keep text-sm leading-normal text-text-tertiary",
9778
10324
  children: message
9779
10325
  }
9780
- ),
10326
+ ) : null,
9781
10327
  errorCode ? /* @__PURE__ */ jsx51(
9782
10328
  "p",
9783
10329
  {
@@ -9795,7 +10341,7 @@ var ErrorState = React43.forwardRef(
9795
10341
  ErrorState.displayName = "ErrorState";
9796
10342
 
9797
10343
  // src/components/ui/skeleton.tsx
9798
- import * as React44 from "react";
10344
+ import * as React45 from "react";
9799
10345
  import { cva as cva17 } from "class-variance-authority";
9800
10346
  import { jsx as jsx52 } from "react/jsx-runtime";
9801
10347
  var skeletonVariants = cva17(
@@ -9841,7 +10387,7 @@ var spinnerVariants = cva17(
9841
10387
  }
9842
10388
  }
9843
10389
  );
9844
- var Skeleton = React44.forwardRef(
10390
+ var Skeleton = React45.forwardRef(
9845
10391
  ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx52(
9846
10392
  "div",
9847
10393
  {
@@ -9855,7 +10401,7 @@ var Skeleton = React44.forwardRef(
9855
10401
  );
9856
10402
  Skeleton.displayName = "Skeleton";
9857
10403
  var defaultTextWidths = ["92%", "84%", "68%", "76%"];
9858
- var SkeletonText = React44.forwardRef(
10404
+ var SkeletonText = React45.forwardRef(
9859
10405
  ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx52(
9860
10406
  "div",
9861
10407
  {
@@ -9875,7 +10421,7 @@ var SkeletonText = React44.forwardRef(
9875
10421
  )
9876
10422
  );
9877
10423
  SkeletonText.displayName = "SkeletonText";
9878
- var SkeletonRow = React44.forwardRef(
10424
+ var SkeletonRow = React45.forwardRef(
9879
10425
  ({
9880
10426
  className,
9881
10427
  columns,
@@ -9932,7 +10478,7 @@ var SkeletonRow = React44.forwardRef(
9932
10478
  }
9933
10479
  );
9934
10480
  SkeletonRow.displayName = "SkeletonRow";
9935
- var Spinner = React44.forwardRef(
10481
+ var Spinner = React45.forwardRef(
9936
10482
  ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx52(
9937
10483
  "span",
9938
10484
  {
@@ -9948,7 +10494,7 @@ var Spinner = React44.forwardRef(
9948
10494
  Spinner.displayName = "Spinner";
9949
10495
 
9950
10496
  // src/components/ui/pagination.tsx
9951
- import * as React45 from "react";
10497
+ import * as React46 from "react";
9952
10498
  import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight4, ChevronsRight } from "lucide-react";
9953
10499
  import { cva as cva18 } from "class-variance-authority";
9954
10500
 
@@ -10089,7 +10635,7 @@ function NavigationButton({
10089
10635
  }
10090
10636
  );
10091
10637
  }
10092
- var Pagination = React45.forwardRef(
10638
+ var Pagination = React46.forwardRef(
10093
10639
  ({
10094
10640
  className,
10095
10641
  size = "standard",
@@ -10405,7 +10951,7 @@ function ModeToggle({
10405
10951
  }
10406
10952
 
10407
10953
  // src/components/ui/action-footer.tsx
10408
- import * as React46 from "react";
10954
+ import * as React47 from "react";
10409
10955
  import { cva as cva20 } from "class-variance-authority";
10410
10956
  import { jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
10411
10957
  var actionFooterVariants = cva20(
@@ -10506,7 +11052,7 @@ function renderAction(action, className) {
10506
11052
  }
10507
11053
  return /* @__PURE__ */ jsx57(Button, { ...common, ...style, size: "lg", loading: action.loading, children: action.label }, key);
10508
11054
  }
10509
- var ActionFooter = React46.forwardRef(
11055
+ var ActionFooter = React47.forwardRef(
10510
11056
  ({
10511
11057
  className,
10512
11058
  status,
@@ -10576,7 +11122,7 @@ var ActionFooter = React46.forwardRef(
10576
11122
  ActionFooter.displayName = "ActionFooter";
10577
11123
 
10578
11124
  // src/components/ui/toast.tsx
10579
- import * as React47 from "react";
11125
+ import * as React48 from "react";
10580
11126
  import { cva as cva21 } from "class-variance-authority";
10581
11127
  import { jsx as jsx58, jsxs as jsxs47 } from "react/jsx-runtime";
10582
11128
  var DOT3 = {
@@ -10697,7 +11243,7 @@ var toast = {
10697
11243
  }
10698
11244
  };
10699
11245
  var Toast = toast;
10700
- var ToastRoot = React47.forwardRef(
11246
+ var ToastRoot = React48.forwardRef(
10701
11247
  ({
10702
11248
  className,
10703
11249
  id,
@@ -10714,10 +11260,10 @@ var ToastRoot = React47.forwardRef(
10714
11260
  ...props
10715
11261
  }, ref) => {
10716
11262
  const durationMs = getToastDuration({ message, variant, duration });
10717
- const onCloseRef = React47.useRef(onClose);
11263
+ const onCloseRef = React48.useRef(onClose);
10718
11264
  onCloseRef.current = onClose;
10719
- const timerRef = React47.useRef(null);
10720
- React47.useEffect(() => {
11265
+ const timerRef = React48.useRef(null);
11266
+ React48.useEffect(() => {
10721
11267
  if (!onCloseRef.current) return void 0;
10722
11268
  const timer = createToastTimer(durationMs, () => onCloseRef.current?.());
10723
11269
  timerRef.current = timer;
@@ -10815,7 +11361,7 @@ var ToastRoot = React47.forwardRef(
10815
11361
  }
10816
11362
  );
10817
11363
  ToastRoot.displayName = "ToastRoot";
10818
- var ToastViewport = React47.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx58(
11364
+ var ToastViewport = React48.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx58(
10819
11365
  "ol",
10820
11366
  {
10821
11367
  ref,
@@ -10826,8 +11372,8 @@ var ToastViewport = React47.forwardRef(({ className, ...props }, ref) => /* @__P
10826
11372
  ));
10827
11373
  ToastViewport.displayName = "ToastViewport";
10828
11374
  function ToastProvider({ children, maxToasts = 3, className, ...props }) {
10829
- const [items, setItems] = React47.useState([]);
10830
- React47.useEffect(
11375
+ const [items, setItems] = React48.useState([]);
11376
+ React48.useEffect(
10831
11377
  () => toast.subscribe((nextItems) => {
10832
11378
  setItems(limitToasts(nextItems, maxToasts));
10833
11379
  }),
@@ -10840,7 +11386,7 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
10840
11386
  }
10841
11387
 
10842
11388
  // src/components/ui/otp-field.tsx
10843
- import * as React48 from "react";
11389
+ import * as React49 from "react";
10844
11390
  import { cva as cva22 } from "class-variance-authority";
10845
11391
  import { AlertCircle as AlertCircle4 } from "lucide-react";
10846
11392
  import { Fragment as Fragment21, jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
@@ -10970,7 +11516,7 @@ function fillDigitsFromIndex(slots, index, inserted, length) {
10970
11516
  focusIndex: Math.min(cursor, length - 1)
10971
11517
  };
10972
11518
  }
10973
- var OTPField = React48.forwardRef(
11519
+ var OTPField = React49.forwardRef(
10974
11520
  ({
10975
11521
  className,
10976
11522
  defaultValue,
@@ -10994,7 +11540,7 @@ var OTPField = React48.forwardRef(
10994
11540
  ...props
10995
11541
  }, ref) => {
10996
11542
  const formField = useFormFieldControl();
10997
- const generatedId = React48.useId();
11543
+ const generatedId = React49.useId();
10998
11544
  const fieldId = id ?? generatedId;
10999
11545
  const slotId = formField ? generatedId : fieldId;
11000
11546
  const labelId = `${slotId}-label`;
@@ -11002,22 +11548,22 @@ var OTPField = React48.forwardRef(
11002
11548
  const errorId = errorText ? `${slotId}-error` : void 0;
11003
11549
  const resolvedState = invalid || errorText ? "error" : "default";
11004
11550
  const isControlled = value !== void 0;
11005
- const [uncontrolledSlots, setUncontrolledSlots] = React48.useState(
11551
+ const [uncontrolledSlots, setUncontrolledSlots] = React49.useState(
11006
11552
  () => toDigitsArray(onlyDigits(defaultValue, length), length)
11007
11553
  );
11008
- const resolvedSlots = React48.useMemo(
11554
+ const resolvedSlots = React49.useMemo(
11009
11555
  () => isControlled ? toDigitsArray(onlyDigits(value, length), length) : uncontrolledSlots,
11010
11556
  [isControlled, length, uncontrolledSlots, value]
11011
11557
  );
11012
11558
  const resolvedValue = joinDigits(resolvedSlots).slice(0, length);
11013
- const cellsRef = React48.useRef([]);
11559
+ const cellsRef = React49.useRef([]);
11014
11560
  const groupDescribedBy = joinIds(
11015
11561
  ariaDescribedBy,
11016
11562
  helperId,
11017
11563
  errorId,
11018
11564
  formField?.describedBy
11019
11565
  );
11020
- const setResolvedValue = React48.useCallback(
11566
+ const setResolvedValue = React49.useCallback(
11021
11567
  (nextSlots, focusIndex) => {
11022
11568
  const normalizedSlots = nextSlots.slice(0, length);
11023
11569
  const normalizedValue = joinDigits(normalizedSlots).slice(0, length);
@@ -11207,7 +11753,7 @@ var OTPField = React48.forwardRef(
11207
11753
  OTPField.displayName = "OTPField";
11208
11754
 
11209
11755
  // src/components/ui/search-field.tsx
11210
- import * as React49 from "react";
11756
+ import * as React50 from "react";
11211
11757
  import { Search, X as X5 } from "lucide-react";
11212
11758
  import { cva as cva23 } from "class-variance-authority";
11213
11759
  import { jsx as jsx60, jsxs as jsxs49 } from "react/jsx-runtime";
@@ -11275,7 +11821,7 @@ var iconSize3 = {
11275
11821
  function hasVisibleValue(value) {
11276
11822
  return typeof value === "string" ? value.length > 0 : value !== void 0;
11277
11823
  }
11278
- var SearchField = React49.forwardRef(
11824
+ var SearchField = React50.forwardRef(
11279
11825
  ({
11280
11826
  className,
11281
11827
  inputMode = "search",
@@ -11292,14 +11838,20 @@ var SearchField = React49.forwardRef(
11292
11838
  "aria-describedby": ariaDescribedBy,
11293
11839
  ...props
11294
11840
  }, ref) => {
11841
+ const {
11842
+ description: _description,
11843
+ message: _message,
11844
+ state: _state,
11845
+ ...inputProps
11846
+ } = props;
11295
11847
  const field = useFormFieldControl();
11296
11848
  const resolvedSize = size ?? "md";
11297
- const inputRef = React49.useRef(null);
11298
- const [hasText, setHasText] = React49.useState(
11849
+ const inputRef = React50.useRef(null);
11850
+ const [hasText, setHasText] = React50.useState(
11299
11851
  () => hasVisibleValue(value ?? defaultValue)
11300
11852
  );
11301
- React49.useImperativeHandle(ref, () => inputRef.current);
11302
- React49.useEffect(() => {
11853
+ React50.useImperativeHandle(ref, () => inputRef.current);
11854
+ React50.useEffect(() => {
11303
11855
  if (value !== void 0) {
11304
11856
  setHasText(hasVisibleValue(value));
11305
11857
  }
@@ -11349,7 +11901,7 @@ var SearchField = React49.forwardRef(
11349
11901
  className: cn(
11350
11902
  searchFieldInputVariants({ size, hasClear: showClear, surface })
11351
11903
  ),
11352
- ...props
11904
+ ...inputProps
11353
11905
  }
11354
11906
  ),
11355
11907
  showClear ? /* @__PURE__ */ jsx60(
@@ -11371,7 +11923,7 @@ var SearchField = React49.forwardRef(
11371
11923
  SearchField.displayName = "SearchField";
11372
11924
 
11373
11925
  // src/components/ui/checkbox-group.tsx
11374
- import * as React50 from "react";
11926
+ import * as React51 from "react";
11375
11927
  import { cva as cva24 } from "class-variance-authority";
11376
11928
  import { jsx as jsx61 } from "react/jsx-runtime";
11377
11929
  var checkboxGroupVariants = cva24("gap-[var(--space-2)]", {
@@ -11399,7 +11951,7 @@ var checkboxGroupVariants = cva24("gap-[var(--space-2)]", {
11399
11951
  function toSelectionSet(value) {
11400
11952
  return new Set(value ?? []);
11401
11953
  }
11402
- var CheckboxGroup = React50.forwardRef(
11954
+ var CheckboxGroup = React51.forwardRef(
11403
11955
  ({
11404
11956
  className,
11405
11957
  children,
@@ -11418,14 +11970,14 @@ var CheckboxGroup = React50.forwardRef(
11418
11970
  }, ref) => {
11419
11971
  const field = useFormFieldControl();
11420
11972
  const isControlled = value != null;
11421
- const [uncontrolledValue, setUncontrolledValue] = React50.useState(
11973
+ const [uncontrolledValue, setUncontrolledValue] = React51.useState(
11422
11974
  () => toSelectionSet(defaultValue)
11423
11975
  );
11424
- const selectedValues = React50.useMemo(
11976
+ const selectedValues = React51.useMemo(
11425
11977
  () => isControlled ? toSelectionSet(value) : uncontrolledValue,
11426
11978
  [isControlled, uncontrolledValue, value]
11427
11979
  );
11428
- const toggleValue = React50.useCallback(
11980
+ const toggleValue = React51.useCallback(
11429
11981
  (itemValue, checked) => {
11430
11982
  const nextValues = new Set(selectedValues);
11431
11983
  if (checked) {
@@ -11441,7 +11993,7 @@ var CheckboxGroup = React50.forwardRef(
11441
11993
  },
11442
11994
  [isControlled, onValueChange, selectedValues]
11443
11995
  );
11444
- const contextValue = React50.useMemo(
11996
+ const contextValue = React51.useMemo(
11445
11997
  () => ({
11446
11998
  appearance,
11447
11999
  density,
@@ -11479,7 +12031,7 @@ var CheckboxGroup = React50.forwardRef(
11479
12031
  CheckboxGroup.displayName = "CheckboxGroup";
11480
12032
 
11481
12033
  // src/components/ui/radio-group.tsx
11482
- import * as React51 from "react";
12034
+ import * as React52 from "react";
11483
12035
  import { cva as cva25 } from "class-variance-authority";
11484
12036
  import { Circle } from "lucide-react";
11485
12037
  import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
@@ -11572,12 +12124,12 @@ var radioControlVariants = cva25(
11572
12124
  }
11573
12125
  }
11574
12126
  );
11575
- var RadioGroupContext = React51.createContext({
12127
+ var RadioGroupContext = React52.createContext({
11576
12128
  appearance: "plain",
11577
12129
  density: "comfortable",
11578
12130
  orientation: "vertical"
11579
12131
  });
11580
- var RadioGroup = React51.forwardRef(
12132
+ var RadioGroup = React52.forwardRef(
11581
12133
  ({
11582
12134
  className,
11583
12135
  children,
@@ -11591,7 +12143,7 @@ var RadioGroup = React51.forwardRef(
11591
12143
  ...props
11592
12144
  }, ref) => {
11593
12145
  const field = useFormFieldControl();
11594
- const contextValue = React51.useMemo(
12146
+ const contextValue = React52.useMemo(
11595
12147
  () => ({ appearance, density, orientation }),
11596
12148
  [appearance, density, orientation]
11597
12149
  );
@@ -11620,9 +12172,9 @@ var RadioGroup = React51.forwardRef(
11620
12172
  }
11621
12173
  );
11622
12174
  RadioGroup.displayName = "RadioGroup";
11623
- var Radio = React51.forwardRef(({ className, children, description, id, ...props }, ref) => {
11624
- const { appearance, density, orientation } = React51.useContext(RadioGroupContext);
11625
- const generatedId = React51.useId();
12175
+ var Radio = React52.forwardRef(({ className, children, description, id, ...props }, ref) => {
12176
+ const { appearance, density, orientation } = React52.useContext(RadioGroupContext);
12177
+ const generatedId = React52.useId();
11626
12178
  const radioId = id ?? generatedId;
11627
12179
  const labelId = `${radioId}-label`;
11628
12180
  const descriptionId = description ? `${radioId}-description` : void 0;
@@ -11795,7 +12347,7 @@ function Progress({
11795
12347
  }
11796
12348
 
11797
12349
  // src/components/ui/tree-view.tsx
11798
- import * as React52 from "react";
12350
+ import * as React53 from "react";
11799
12351
  import { ChevronRight as ChevronRight6 } from "lucide-react";
11800
12352
  import { cva as cva26 } from "class-variance-authority";
11801
12353
  import { jsx as jsx65, jsxs as jsxs52 } from "react/jsx-runtime";
@@ -11829,14 +12381,14 @@ var treeItemRowVariants = cva26(
11829
12381
  function defaultGetChildren(node) {
11830
12382
  return node.children;
11831
12383
  }
11832
- function flattenVisibleNodes(nodes, getChildren, expandedSet, depth = 1, parentId = null, acc = []) {
12384
+ function flattenVisibleNodes(nodes, getChildren, expandedSet, depth2 = 1, parentId = null, acc = []) {
11833
12385
  for (const node of nodes) {
11834
12386
  const children = getChildren(node);
11835
12387
  const hasChildren = Array.isArray(children) && children.length > 0;
11836
12388
  const expanded = hasChildren && expandedSet.has(node.id);
11837
- acc.push({ node, id: node.id, depth, hasChildren, expanded, parentId });
12389
+ acc.push({ node, id: node.id, depth: depth2, hasChildren, expanded, parentId });
11838
12390
  if (expanded && children) {
11839
- flattenVisibleNodes(children, getChildren, expandedSet, depth + 1, node.id, acc);
12391
+ flattenVisibleNodes(children, getChildren, expandedSet, depth2 + 1, node.id, acc);
11840
12392
  }
11841
12393
  }
11842
12394
  return acc;
@@ -11901,27 +12453,27 @@ function TreeView({
11901
12453
  ...rest
11902
12454
  }) {
11903
12455
  const isExpandedControlled = expandedIds !== void 0;
11904
- const [internalExpanded, setInternalExpanded] = React52.useState(
12456
+ const [internalExpanded, setInternalExpanded] = React53.useState(
11905
12457
  () => defaultExpandedIds ?? []
11906
12458
  );
11907
12459
  const expandedList = isExpandedControlled ? expandedIds : internalExpanded;
11908
- const expandedSet = React52.useMemo(() => new Set(expandedList), [expandedList]);
11909
- const items = React52.useMemo(
12460
+ const expandedSet = React53.useMemo(() => new Set(expandedList), [expandedList]);
12461
+ const items = React53.useMemo(
11910
12462
  () => flattenVisibleNodes(nodes, getChildren, expandedSet),
11911
12463
  [nodes, getChildren, expandedSet]
11912
12464
  );
11913
- const [focusedId, setFocusedId] = React52.useState(null);
12465
+ const [focusedId, setFocusedId] = React53.useState(null);
11914
12466
  const visibleIds = items.map((item) => item.id);
11915
12467
  const activeId = focusedId && visibleIds.includes(focusedId) ? focusedId : selectedId && visibleIds.includes(selectedId) ? selectedId : visibleIds[0] ?? null;
11916
- const itemRefs = React52.useRef(/* @__PURE__ */ new Map());
11917
- const commitExpanded = React52.useCallback(
12468
+ const itemRefs = React53.useRef(/* @__PURE__ */ new Map());
12469
+ const commitExpanded = React53.useCallback(
11918
12470
  (next) => {
11919
12471
  if (!isExpandedControlled) setInternalExpanded(next);
11920
12472
  onExpandedChange?.(next);
11921
12473
  },
11922
12474
  [isExpandedControlled, onExpandedChange]
11923
12475
  );
11924
- const setExpanded = React52.useCallback(
12476
+ const setExpanded = React53.useCallback(
11925
12477
  (id, expand) => {
11926
12478
  const has = expandedSet.has(id);
11927
12479
  if (expand && !has) {
@@ -11932,7 +12484,7 @@ function TreeView({
11932
12484
  },
11933
12485
  [commitExpanded, expandedList, expandedSet]
11934
12486
  );
11935
- const focusItem = React52.useCallback((id) => {
12487
+ const focusItem = React53.useCallback((id) => {
11936
12488
  setFocusedId(id);
11937
12489
  itemRefs.current.get(id)?.focus();
11938
12490
  }, []);
@@ -11960,14 +12512,14 @@ function TreeView({
11960
12512
  }
11961
12513
  }
11962
12514
  };
11963
- function renderLevel(levelNodes, depth) {
12515
+ function renderLevel(levelNodes, depth2) {
11964
12516
  return levelNodes.map((node) => {
11965
12517
  const children = getChildren(node);
11966
12518
  const hasChildren = Array.isArray(children) && children.length > 0;
11967
12519
  const expanded = hasChildren && expandedSet.has(node.id);
11968
12520
  const selected = node.id === selectedId;
11969
12521
  const isActive = node.id === activeId;
11970
- const itemState = { expanded, selected, depth, hasChildren };
12522
+ const itemState = { expanded, selected, depth: depth2, hasChildren };
11971
12523
  return /* @__PURE__ */ jsxs52(
11972
12524
  "li",
11973
12525
  {
@@ -11978,7 +12530,7 @@ function TreeView({
11978
12530
  role: "treeitem",
11979
12531
  "data-slot": "treeitem",
11980
12532
  "data-id": node.id,
11981
- "aria-level": depth,
12533
+ "aria-level": depth2,
11982
12534
  "aria-expanded": hasChildren ? expanded : void 0,
11983
12535
  "aria-selected": selected ? true : void 0,
11984
12536
  "aria-current": selected && selectionAriaCurrent ? selectionAriaCurrent : void 0,
@@ -11998,7 +12550,7 @@ function TreeView({
11998
12550
  {
11999
12551
  "data-slot": "treeitem-row",
12000
12552
  style: {
12001
- paddingInlineStart: `calc(var(--space-2) + var(--space-4) * ${depth - 1})`
12553
+ paddingInlineStart: `calc(var(--space-2) + var(--space-4) * ${depth2 - 1})`
12002
12554
  },
12003
12555
  className: treeItemRowVariants({ selected }),
12004
12556
  children: [
@@ -12037,7 +12589,7 @@ function TreeView({
12037
12589
  ]
12038
12590
  }
12039
12591
  ),
12040
- hasChildren && expanded && children ? /* @__PURE__ */ jsx65("ul", { role: "group", "data-slot": "tree-group", className: "m-0 list-none p-0", children: renderLevel(children, depth + 1) }) : null
12592
+ hasChildren && expanded && children ? /* @__PURE__ */ jsx65("ul", { role: "group", "data-slot": "tree-group", className: "m-0 list-none p-0", children: renderLevel(children, depth2 + 1) }) : null
12041
12593
  ]
12042
12594
  },
12043
12595
  node.id