shadcn-ui-react 0.7.10 → 0.7.12

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.cjs CHANGED
@@ -251,12 +251,10 @@ __export(index_exports, {
251
251
  SelectGroup: () => SelectGroup,
252
252
  SelectItem: () => SelectItem,
253
253
  SelectLabel: () => SelectLabel,
254
- SelectScrollDownButton: () => SelectScrollDownButton,
255
- SelectScrollUpButton: () => SelectScrollUpButton,
256
254
  SelectSeparator: () => SelectSeparator,
257
255
  SelectTrigger: () => SelectTrigger,
258
256
  SelectValue: () => SelectValue,
259
- Separator: () => Separator6,
257
+ Separator: () => Separator5,
260
258
  Sheet: () => Sheet,
261
259
  SheetClose: () => SheetClose,
262
260
  SheetContent: () => SheetContent,
@@ -307,9 +305,18 @@ __export(index_exports, {
307
305
  badgeVariants: () => badgeVariants,
308
306
  buttonVariants: () => buttonVariants,
309
307
  cn: () => cn,
308
+ formCompositeControlBase: () => formCompositeControlBase,
309
+ formCompositeControlErrorClass: () => formCompositeControlErrorClass,
310
+ formCompositeVariants: () => formCompositeVariants,
311
+ formControlBase: () => formControlBase,
312
+ formControlErrorClass: () => formControlErrorClass,
313
+ formInputVariants: () => formInputVariants,
314
+ formSizeVariants: () => formSizeVariants,
310
315
  getDefaultOptionLabel: () => getDefaultOptionLabel,
311
316
  getDefaultOptionValue: () => getDefaultOptionValue,
312
317
  getErrorMessage: () => getErrorMessage,
318
+ getFormControlSizeClass: () => getFormControlSizeClass,
319
+ getFormSizeClasses: () => getFormSizeClasses,
313
320
  getNextEnabledIndex: () => getNextEnabledIndex,
314
321
  iconButtonVariants: () => iconButtonVariants,
315
322
  navigationMenuTriggerStyle: () => navigationMenuTriggerStyle,
@@ -319,7 +326,8 @@ __export(index_exports, {
319
326
  toggleVariants: () => toggleVariants,
320
327
  useFormField: () => useFormField,
321
328
  useSidebar: () => useSidebar,
322
- useToast: () => useToast
329
+ useToast: () => useToast,
330
+ variants: () => variants
323
331
  });
324
332
  module.exports = __toCommonJS(index_exports);
325
333
 
@@ -6550,7 +6558,7 @@ var import_class_variance_authority5 = require("class-variance-authority");
6550
6558
  var React42 = __toESM(require("react"), 1);
6551
6559
  var import_jsx_runtime18 = require("react/jsx-runtime");
6552
6560
  var labelVariants = (0, import_class_variance_authority5.cva)(
6553
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-label"
6561
+ "text-sm font-medium leading-none text-label peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
6554
6562
  );
6555
6563
  var Label3 = React42.forwardRef((_a, ref) => {
6556
6564
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
@@ -6865,7 +6873,7 @@ var import_react_hook_form4 = require("react-hook-form");
6865
6873
  // src/components/input.tsx
6866
6874
  var React45 = __toESM(require("react"), 1);
6867
6875
 
6868
- // src/components/Form/utils/form-utils.ts
6876
+ // src/utils/form-utils.ts
6869
6877
  var formInputVariants = {
6870
6878
  outline: "rounded-md border border-input bg-input backdrop-blur-sm shadow-sm hover:border-primary/60 focus:border-primary focus:ring-2 focus:ring-primary/20",
6871
6879
  soft: "rounded-md border border-transparent bg-muted/60 shadow-sm hover:bg-muted focus:bg-input/80 focus:ring-2 focus:ring-primary/20",
@@ -6875,6 +6883,15 @@ var formInputVariants = {
6875
6883
  unstyled: "border-0 shadow-none focus:ring-0",
6876
6884
  link: "h-auto border-0 bg-transparent p-0 text-primary shadow-none underline-offset-4 focus:underline focus:ring-0"
6877
6885
  };
6886
+ var formCompositeVariants = {
6887
+ outline: "rounded-md border border-input bg-input backdrop-blur-sm shadow-sm hover:border-primary/60 focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/20",
6888
+ soft: "rounded-md border border-transparent bg-muted/60 shadow-sm hover:bg-muted focus-within:bg-input/80 focus-within:ring-2 focus-within:ring-primary/20",
6889
+ ghost: "rounded-md border border-transparent bg-transparent hover:bg-muted/50 focus-within:ring-2 focus-within:ring-ring",
6890
+ filled: "rounded-md border border-input bg-muted/70 shadow-inner hover:bg-muted focus-within:bg-input/70 focus-within:ring-2 focus-within:ring-primary/20",
6891
+ flushed: "rounded-none border-0 border-b border-input px-0 shadow-none focus-within:border-b-2 focus-within:border-primary focus-within:ring-0",
6892
+ unstyled: "border-0 shadow-none focus-within:ring-0",
6893
+ link: "h-auto border-0 bg-transparent p-0 text-primary shadow-none underline-offset-4 focus-within:underline focus-within:ring-0"
6894
+ };
6878
6895
  var variants = formInputVariants;
6879
6896
  var formSizeVariants = {
6880
6897
  "2xs": {
@@ -6955,9 +6972,18 @@ var formSizeVariants = {
6955
6972
  message: "text-base"
6956
6973
  }
6957
6974
  };
6975
+ var formControlBase = "relative inline-flex w-full items-center justify-between gap-2 text-foreground outline-none transition data-[placeholder]:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50";
6976
+ var formCompositeControlBase = "relative flex w-full items-center gap-2 text-foreground outline-none transition";
6977
+ var formControlErrorClass = "border-destructive focus:border-destructive focus:ring-destructive/20";
6978
+ var formCompositeControlErrorClass = "border-destructive focus-within:border-destructive focus-within:ring-destructive/20";
6958
6979
  function getFormSizeClasses(size = "md", customSize) {
6959
6980
  return __spreadValues(__spreadValues({}, formSizeVariants[size]), customSize);
6960
6981
  }
6982
+ function getFormControlSizeClass(variant, sizeClasses) {
6983
+ if (variant === "flushed") return sizeClasses.flushedControl;
6984
+ if (variant === "link") return sizeClasses.linkControl;
6985
+ return sizeClasses.control;
6986
+ }
6961
6987
 
6962
6988
  // src/components/input.tsx
6963
6989
  var import_jsx_runtime22 = require("react/jsx-runtime");
@@ -7167,207 +7193,851 @@ var import_react_hook_form5 = require("react-hook-form");
7167
7193
 
7168
7194
  // src/components/select.tsx
7169
7195
  var import_react_icons9 = require("@radix-ui/react-icons");
7170
- var SelectPrimitive = __toESM(require("@radix-ui/react-select"), 1);
7171
7196
  var React46 = __toESM(require("react"), 1);
7197
+ var import_react_dom = require("react-dom");
7172
7198
  var import_jsx_runtime24 = require("react/jsx-runtime");
7173
- var Select2 = SelectPrimitive.Root;
7174
- var SelectGroup = SelectPrimitive.Group;
7175
- var SelectValue = SelectPrimitive.Value;
7176
- var BODY_UNLOCK_ATTR = "data-select-scroll-unlocked";
7177
- var BODY_UNLOCK_STYLE_ID = "radix-select-scroll-unlock-style";
7178
- var useSafeLayoutEffect = typeof window !== "undefined" ? React46.useLayoutEffect : React46.useEffect;
7179
- function SelectBodyScrollUnlock() {
7180
- useSafeLayoutEffect(() => {
7181
- var _a;
7182
- if (typeof document === "undefined") return;
7183
- if (!document.getElementById(BODY_UNLOCK_STYLE_ID)) {
7184
- const style = document.createElement("style");
7185
- style.id = BODY_UNLOCK_STYLE_ID;
7186
- style.textContent = `
7187
- body[${BODY_UNLOCK_ATTR}][data-scroll-locked] {
7188
- overflow: auto !important;
7189
- margin-right: 0 !important;
7190
- padding-right: 0 !important;
7191
- }
7192
- `;
7193
- document.head.appendChild(style);
7194
- }
7195
- const body = document.body;
7196
- const currentCount = Number((_a = body.getAttribute(BODY_UNLOCK_ATTR)) != null ? _a : "0");
7197
- body.setAttribute(BODY_UNLOCK_ATTR, String(currentCount + 1));
7198
- return () => {
7199
- var _a2;
7200
- const nextCount = Number((_a2 = body.getAttribute(BODY_UNLOCK_ATTR)) != null ? _a2 : "1") - 1;
7201
- if (nextCount <= 0) {
7202
- body.removeAttribute(BODY_UNLOCK_ATTR);
7203
- } else {
7204
- body.setAttribute(BODY_UNLOCK_ATTR, String(nextCount));
7199
+ var SelectContext = React46.createContext(null);
7200
+ function useSelectContext(componentName) {
7201
+ const context = React46.useContext(SelectContext);
7202
+ if (!context) {
7203
+ throw new Error(
7204
+ `${componentName} must be used within <Select />. Aseg\xFArate de importar Select, SelectTrigger, SelectContent, SelectValue y SelectItem desde el mismo archivo "../select", sin mezclar Radix ni otra versi\xF3n del componente.`
7205
+ );
7206
+ }
7207
+ return context;
7208
+ }
7209
+ function useControllableState({
7210
+ value,
7211
+ defaultValue,
7212
+ onChange
7213
+ }) {
7214
+ const [internalValue, setInternalValue] = React46.useState(defaultValue);
7215
+ const isControlled = value !== void 0;
7216
+ const currentValue = isControlled ? value : internalValue;
7217
+ const setValue = React46.useCallback(
7218
+ (nextValue) => {
7219
+ if (!isControlled) {
7220
+ setInternalValue(
7221
+ (previousValue) => Object.is(previousValue, nextValue) ? previousValue : nextValue
7222
+ );
7205
7223
  }
7206
- };
7207
- }, []);
7208
- return null;
7224
+ if (!Object.is(currentValue, nextValue)) {
7225
+ onChange == null ? void 0 : onChange(nextValue);
7226
+ }
7227
+ },
7228
+ [currentValue, isControlled, onChange]
7229
+ );
7230
+ return [currentValue, setValue];
7209
7231
  }
7210
- var SelectTrigger = React46.forwardRef((_a, ref) => {
7211
- var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
7212
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7213
- SelectPrimitive.Trigger,
7214
- __spreadProps(__spreadValues({
7215
- ref,
7216
- className: cn(
7217
- "flex h-9 w-full items-center justify-between gap-2 whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background transition-colors placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
7218
- className
7219
- )
7220
- }, props), {
7221
- children: [
7222
- children,
7223
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_icons9.CaretSortIcon, { className: "h-4 w-4 shrink-0 opacity-50" }) })
7224
- ]
7225
- })
7232
+ function composeRefs(...refs) {
7233
+ return (node) => {
7234
+ refs.forEach((ref) => {
7235
+ if (!ref) return;
7236
+ if (typeof ref === "function") {
7237
+ ref(node);
7238
+ return;
7239
+ }
7240
+ ref.current = node;
7241
+ });
7242
+ };
7243
+ }
7244
+ function getNodeText(node) {
7245
+ if (node === null || node === void 0 || typeof node === "boolean") {
7246
+ return "";
7247
+ }
7248
+ if (typeof node === "string" || typeof node === "number") {
7249
+ return String(node);
7250
+ }
7251
+ if (Array.isArray(node)) {
7252
+ return node.map(getNodeText).join("");
7253
+ }
7254
+ if (React46.isValidElement(node)) {
7255
+ return getNodeText(node.props.children);
7256
+ }
7257
+ return "";
7258
+ }
7259
+ function getEnabledItems(items) {
7260
+ return items.filter((item) => !item.disabled);
7261
+ }
7262
+ function getNextItemValue(items, currentValue, direction) {
7263
+ var _a, _b, _c;
7264
+ const enabledItems = getEnabledItems(items);
7265
+ if (!enabledItems.length) return void 0;
7266
+ const currentIndex = enabledItems.findIndex(
7267
+ (item) => item.value === currentValue
7268
+ );
7269
+ if (currentIndex === -1) {
7270
+ return direction === "next" ? (_a = enabledItems[0]) == null ? void 0 : _a.value : (_b = enabledItems[enabledItems.length - 1]) == null ? void 0 : _b.value;
7271
+ }
7272
+ const nextIndex = direction === "next" ? (currentIndex + 1) % enabledItems.length : (currentIndex - 1 + enabledItems.length) % enabledItems.length;
7273
+ return (_c = enabledItems[nextIndex]) == null ? void 0 : _c.value;
7274
+ }
7275
+ function areRegisteredItemsEqual(previous, next) {
7276
+ return Boolean(
7277
+ previous && previous.id === next.id && previous.value === next.value && previous.textValue === next.textValue && previous.disabled === next.disabled && previous.label === next.label
7278
+ );
7279
+ }
7280
+ function areStylesEqual(previous, next) {
7281
+ if (!previous) return false;
7282
+ return previous.position === next.position && previous.zIndex === next.zIndex && previous.width === next.width && previous.minWidth === next.minWidth && previous.maxWidth === next.maxWidth && previous.maxHeight === next.maxHeight && previous.left === next.left && previous.right === next.right && previous.top === next.top && previous.bottom === next.bottom && previous.transform === next.transform;
7283
+ }
7284
+ function scrollItemIntoView(container, item) {
7285
+ if (!container || !item) return;
7286
+ const containerRect = container.getBoundingClientRect();
7287
+ const itemRect = item.getBoundingClientRect();
7288
+ const itemTop = itemRect.top - containerRect.top + container.scrollTop;
7289
+ const itemBottom = itemTop + itemRect.height;
7290
+ const visibleTop = container.scrollTop;
7291
+ const visibleBottom = visibleTop + container.clientHeight;
7292
+ if (itemTop < visibleTop) {
7293
+ container.scrollTop = itemTop;
7294
+ return;
7295
+ }
7296
+ if (itemBottom > visibleBottom) {
7297
+ container.scrollTop = itemBottom - container.clientHeight;
7298
+ }
7299
+ }
7300
+ function Select2({
7301
+ value,
7302
+ defaultValue = "",
7303
+ onValueChange,
7304
+ open,
7305
+ defaultOpen = false,
7306
+ onOpenChange,
7307
+ disabled = false,
7308
+ name,
7309
+ required,
7310
+ variant = "outline",
7311
+ size = "sm",
7312
+ customSize,
7313
+ invalid = false,
7314
+ children
7315
+ }) {
7316
+ const triggerRef = React46.useRef(null);
7317
+ const contentRef = React46.useRef(null);
7318
+ const [currentValue, setCurrentValue] = useControllableState({
7319
+ value,
7320
+ defaultValue,
7321
+ onChange: onValueChange
7322
+ });
7323
+ const [isOpen, setIsOpen] = useControllableState({
7324
+ value: open,
7325
+ defaultValue: defaultOpen,
7326
+ onChange: onOpenChange
7327
+ });
7328
+ const itemsRef = React46.useRef(/* @__PURE__ */ new Map());
7329
+ const [itemsVersion, forceItemsUpdate] = React46.useReducer(
7330
+ (version) => version + 1,
7331
+ 0
7332
+ );
7333
+ const [activeValue, setActiveValue] = React46.useState();
7334
+ const items = React46.useMemo(
7335
+ () => Array.from(itemsRef.current.values()),
7336
+ [itemsVersion]
7337
+ );
7338
+ const selectedItem = React46.useMemo(
7339
+ () => items.find((item) => item.value === currentValue),
7340
+ [currentValue, items]
7341
+ );
7342
+ const registerItem = React46.useCallback((item) => {
7343
+ const previousItem = itemsRef.current.get(item.value);
7344
+ if (previousItem && previousItem.id === item.id) {
7345
+ previousItem.label = item.label;
7346
+ previousItem.textValue = item.textValue;
7347
+ previousItem.disabled = item.disabled;
7348
+ if (!areRegisteredItemsEqual(previousItem, item)) {
7349
+ forceItemsUpdate();
7350
+ }
7351
+ return;
7352
+ }
7353
+ itemsRef.current.set(item.value, item);
7354
+ forceItemsUpdate();
7355
+ }, []);
7356
+ const unregisterItem = React46.useCallback((value2, id) => {
7357
+ const currentItem = itemsRef.current.get(value2);
7358
+ if (!currentItem || currentItem.id !== id) return;
7359
+ itemsRef.current.delete(value2);
7360
+ forceItemsUpdate();
7361
+ }, []);
7362
+ const updateItemRef = React46.useCallback(
7363
+ (value2, id, node) => {
7364
+ const currentItem = itemsRef.current.get(value2);
7365
+ if (!currentItem || currentItem.id !== id) return;
7366
+ if (currentItem.ref === node) return;
7367
+ currentItem.ref = node;
7368
+ },
7369
+ []
7226
7370
  );
7227
- });
7228
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
7229
- var SelectScrollUpButton = React46.forwardRef((_a, ref) => {
7230
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
7231
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7232
- SelectPrimitive.ScrollUpButton,
7233
- __spreadProps(__spreadValues({
7234
- ref,
7235
- className: cn(
7236
- "flex cursor-default items-center justify-center py-1",
7237
- className
7238
- )
7239
- }, props), {
7240
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_icons9.ChevronUpIcon, { className: "h-4 w-4" })
7241
- })
7371
+ const handleOpenChange = React46.useCallback(
7372
+ (nextOpen) => {
7373
+ if (disabled) return;
7374
+ setIsOpen(nextOpen);
7375
+ },
7376
+ [disabled, setIsOpen]
7242
7377
  );
7243
- });
7244
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
7245
- var SelectScrollDownButton = React46.forwardRef((_a, ref) => {
7246
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
7247
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7248
- SelectPrimitive.ScrollDownButton,
7249
- __spreadProps(__spreadValues({
7250
- ref,
7251
- className: cn(
7252
- "flex cursor-default items-center justify-center py-1",
7253
- className
7254
- )
7255
- }, props), {
7256
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_icons9.ChevronDownIcon, { className: "h-4 w-4" })
7257
- })
7378
+ const handleValueChange = React46.useCallback(
7379
+ (nextValue) => {
7380
+ if (disabled) return;
7381
+ setCurrentValue(nextValue);
7382
+ setIsOpen(false);
7383
+ requestAnimationFrame(() => {
7384
+ var _a;
7385
+ (_a = triggerRef.current) == null ? void 0 : _a.focus({ preventScroll: true });
7386
+ });
7387
+ },
7388
+ [disabled, setCurrentValue, setIsOpen]
7258
7389
  );
7259
- });
7260
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
7390
+ React46.useEffect(() => {
7391
+ var _a;
7392
+ if (!isOpen) return;
7393
+ const selectedEnabledItem = items.find(
7394
+ (item) => item.value === currentValue && !item.disabled
7395
+ );
7396
+ const firstEnabledItem = getEnabledItems(items)[0];
7397
+ const nextActiveValue = (_a = selectedEnabledItem == null ? void 0 : selectedEnabledItem.value) != null ? _a : firstEnabledItem == null ? void 0 : firstEnabledItem.value;
7398
+ setActiveValue(
7399
+ (previousValue) => previousValue === nextActiveValue ? previousValue : nextActiveValue
7400
+ );
7401
+ }, [currentValue, isOpen, items]);
7402
+ React46.useEffect(() => {
7403
+ if (!isOpen) return;
7404
+ const handlePointerDown = (event) => {
7405
+ var _a, _b;
7406
+ const target = event.target;
7407
+ if (target && (((_a = triggerRef.current) == null ? void 0 : _a.contains(target)) || ((_b = contentRef.current) == null ? void 0 : _b.contains(target)))) {
7408
+ return;
7409
+ }
7410
+ setIsOpen(false);
7411
+ };
7412
+ document.addEventListener("pointerdown", handlePointerDown, true);
7413
+ return () => {
7414
+ document.removeEventListener("pointerdown", handlePointerDown, true);
7415
+ };
7416
+ }, [isOpen, setIsOpen]);
7417
+ const contextValue = React46.useMemo(
7418
+ () => ({
7419
+ value: currentValue,
7420
+ open: isOpen,
7421
+ disabled,
7422
+ invalid,
7423
+ variant,
7424
+ size,
7425
+ customSize,
7426
+ selectedItem,
7427
+ activeValue,
7428
+ items,
7429
+ triggerRef,
7430
+ contentRef,
7431
+ setOpen: handleOpenChange,
7432
+ setValue: handleValueChange,
7433
+ setActiveValue,
7434
+ registerItem,
7435
+ unregisterItem,
7436
+ updateItemRef
7437
+ }),
7438
+ [
7439
+ currentValue,
7440
+ isOpen,
7441
+ disabled,
7442
+ invalid,
7443
+ variant,
7444
+ size,
7445
+ customSize,
7446
+ selectedItem,
7447
+ activeValue,
7448
+ items,
7449
+ handleOpenChange,
7450
+ handleValueChange,
7451
+ registerItem,
7452
+ unregisterItem,
7453
+ updateItemRef
7454
+ ]
7455
+ );
7456
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(SelectContext.Provider, { value: contextValue, children: [
7457
+ children,
7458
+ name ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7459
+ "input",
7460
+ {
7461
+ type: "hidden",
7462
+ name,
7463
+ value: currentValue,
7464
+ required,
7465
+ disabled
7466
+ }
7467
+ ) : null
7468
+ ] });
7469
+ }
7470
+ var SelectTrigger = React46.forwardRef(
7471
+ (_a, ref) => {
7472
+ var _b = _a, {
7473
+ className,
7474
+ children,
7475
+ variant,
7476
+ size,
7477
+ customSize,
7478
+ invalid,
7479
+ disabled,
7480
+ onClick,
7481
+ onKeyDown,
7482
+ onPointerDown
7483
+ } = _b, props = __objRest(_b, [
7484
+ "className",
7485
+ "children",
7486
+ "variant",
7487
+ "size",
7488
+ "customSize",
7489
+ "invalid",
7490
+ "disabled",
7491
+ "onClick",
7492
+ "onKeyDown",
7493
+ "onPointerDown"
7494
+ ]);
7495
+ const context = useSelectContext("SelectTrigger");
7496
+ const resolvedVariant = variant != null ? variant : context.variant;
7497
+ const resolvedSize = size != null ? size : context.size;
7498
+ const resolvedCustomSize = customSize != null ? customSize : context.customSize;
7499
+ const resolvedInvalid = invalid != null ? invalid : context.invalid;
7500
+ const resolvedDisabled = disabled != null ? disabled : context.disabled;
7501
+ const sizeClasses = getFormSizeClasses(resolvedSize, resolvedCustomSize);
7502
+ const controlSizeClass = getFormControlSizeClass(
7503
+ resolvedVariant,
7504
+ sizeClasses
7505
+ );
7506
+ const typeaheadRef = React46.useRef("");
7507
+ const typeaheadTimeoutRef = React46.useRef(null);
7508
+ const moveActiveItem = React46.useCallback(
7509
+ (direction) => {
7510
+ var _a2;
7511
+ const nextValue = getNextItemValue(
7512
+ context.items,
7513
+ (_a2 = context.activeValue) != null ? _a2 : context.value,
7514
+ direction
7515
+ );
7516
+ if (nextValue) {
7517
+ context.setActiveValue(nextValue);
7518
+ }
7519
+ },
7520
+ [context]
7521
+ );
7522
+ const handleTypeahead = React46.useCallback(
7523
+ (key) => {
7524
+ typeaheadRef.current += key.toLowerCase();
7525
+ if (typeaheadTimeoutRef.current) {
7526
+ window.clearTimeout(typeaheadTimeoutRef.current);
7527
+ }
7528
+ typeaheadTimeoutRef.current = window.setTimeout(() => {
7529
+ typeaheadRef.current = "";
7530
+ }, 500);
7531
+ const enabledItems = getEnabledItems(context.items);
7532
+ const match2 = enabledItems.find(
7533
+ (item) => item.textValue.toLowerCase().startsWith(typeaheadRef.current)
7534
+ );
7535
+ if (!match2) return;
7536
+ if (!context.open) {
7537
+ context.setOpen(true);
7538
+ }
7539
+ context.setActiveValue(match2.value);
7540
+ },
7541
+ [context]
7542
+ );
7543
+ React46.useEffect(() => {
7544
+ return () => {
7545
+ if (typeaheadTimeoutRef.current) {
7546
+ window.clearTimeout(typeaheadTimeoutRef.current);
7547
+ }
7548
+ };
7549
+ }, []);
7550
+ const handleKeyDown = (event) => {
7551
+ onKeyDown == null ? void 0 : onKeyDown(event);
7552
+ if (event.defaultPrevented || resolvedDisabled) return;
7553
+ if (event.key === "ArrowDown") {
7554
+ event.preventDefault();
7555
+ if (!context.open) {
7556
+ context.setOpen(true);
7557
+ return;
7558
+ }
7559
+ moveActiveItem("next");
7560
+ return;
7561
+ }
7562
+ if (event.key === "ArrowUp") {
7563
+ event.preventDefault();
7564
+ if (!context.open) {
7565
+ context.setOpen(true);
7566
+ return;
7567
+ }
7568
+ moveActiveItem("previous");
7569
+ return;
7570
+ }
7571
+ if (event.key === "Enter" || event.key === " ") {
7572
+ event.preventDefault();
7573
+ if (!context.open) {
7574
+ context.setOpen(true);
7575
+ return;
7576
+ }
7577
+ if (context.activeValue) {
7578
+ context.setValue(context.activeValue);
7579
+ }
7580
+ return;
7581
+ }
7582
+ if (event.key === "Escape") {
7583
+ event.preventDefault();
7584
+ context.setOpen(false);
7585
+ return;
7586
+ }
7587
+ if (event.key === "Home") {
7588
+ event.preventDefault();
7589
+ const firstEnabledItem = getEnabledItems(context.items)[0];
7590
+ if (firstEnabledItem) {
7591
+ context.setActiveValue(firstEnabledItem.value);
7592
+ }
7593
+ return;
7594
+ }
7595
+ if (event.key === "End") {
7596
+ event.preventDefault();
7597
+ const enabledItems = getEnabledItems(context.items);
7598
+ const lastEnabledItem = enabledItems[enabledItems.length - 1];
7599
+ if (lastEnabledItem) {
7600
+ context.setActiveValue(lastEnabledItem.value);
7601
+ }
7602
+ return;
7603
+ }
7604
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
7605
+ handleTypeahead(event.key);
7606
+ }
7607
+ };
7608
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7609
+ "button",
7610
+ __spreadProps(__spreadValues({
7611
+ ref: composeRefs(ref, context.triggerRef),
7612
+ type: "button",
7613
+ "aria-haspopup": "listbox",
7614
+ "aria-expanded": context.open,
7615
+ "data-placeholder": !context.value ? "" : void 0,
7616
+ disabled: resolvedDisabled,
7617
+ className: cn(
7618
+ formControlBase,
7619
+ "relative flex w-full items-center justify-between gap-2 overflow-hidden whitespace-nowrap ring-offset-background",
7620
+ formInputVariants[resolvedVariant],
7621
+ controlSizeClass,
7622
+ resolvedInvalid && formControlErrorClass,
7623
+ className
7624
+ ),
7625
+ onPointerDown: (event) => {
7626
+ onPointerDown == null ? void 0 : onPointerDown(event);
7627
+ if (event.defaultPrevented || resolvedDisabled || event.button !== 0 || event.ctrlKey) {
7628
+ return;
7629
+ }
7630
+ event.preventDefault();
7631
+ },
7632
+ onClick: (event) => {
7633
+ onClick == null ? void 0 : onClick(event);
7634
+ if (!event.defaultPrevented && !resolvedDisabled) {
7635
+ context.setOpen(!context.open);
7636
+ requestAnimationFrame(() => {
7637
+ var _a2;
7638
+ (_a2 = context.triggerRef.current) == null ? void 0 : _a2.focus({ preventScroll: true });
7639
+ });
7640
+ }
7641
+ },
7642
+ onKeyDown: handleKeyDown
7643
+ }, props), {
7644
+ children: [
7645
+ children,
7646
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_icons9.CaretSortIcon, { className: "h-4 w-4 shrink-0 opacity-50" })
7647
+ ]
7648
+ })
7649
+ );
7650
+ }
7651
+ );
7652
+ SelectTrigger.displayName = "SelectTrigger";
7653
+ var SelectValue = React46.forwardRef(
7654
+ (_a, ref) => {
7655
+ var _b = _a, { className, placeholder = "Select an option", children } = _b, props = __objRest(_b, ["className", "placeholder", "children"]);
7656
+ var _a2;
7657
+ const context = useSelectContext("SelectValue");
7658
+ const hasValue = Boolean(context.selectedItem) || children !== void 0;
7659
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7660
+ "span",
7661
+ __spreadProps(__spreadValues({
7662
+ ref,
7663
+ className: cn(
7664
+ "min-w-0 flex-1 truncate text-left",
7665
+ !hasValue && "text-muted-foreground",
7666
+ className
7667
+ )
7668
+ }, props), {
7669
+ children: hasValue ? children != null ? children : (_a2 = context.selectedItem) == null ? void 0 : _a2.label : placeholder
7670
+ })
7671
+ );
7672
+ }
7673
+ );
7261
7674
  var SelectContent = React46.forwardRef(
7262
7675
  (_a, ref) => {
7263
7676
  var _b = _a, {
7264
7677
  className,
7265
7678
  children,
7266
- position = "popper",
7267
7679
  sideOffset = 4,
7268
- align = "start"
7680
+ align = "start",
7681
+ position: _position,
7682
+ style
7269
7683
  } = _b, props = __objRest(_b, [
7270
7684
  "className",
7271
7685
  "children",
7272
- "position",
7273
7686
  "sideOffset",
7274
- "align"
7687
+ "align",
7688
+ "position",
7689
+ "style"
7275
7690
  ]);
7276
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
7277
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectBodyScrollUnlock, {}),
7278
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7279
- SelectPrimitive.Content,
7280
- __spreadProps(__spreadValues({
7281
- ref,
7282
- position,
7283
- sideOffset,
7284
- align,
7691
+ const context = useSelectContext("SelectContent");
7692
+ const scrollRef = React46.useRef(null);
7693
+ const rafRef = React46.useRef(null);
7694
+ const lockedSideRef = React46.useRef(null);
7695
+ const [mounted, setMounted] = React46.useState(false);
7696
+ const [side, setSide] = React46.useState("bottom");
7697
+ const [contentStyle, setContentStyle] = React46.useState();
7698
+ React46.useLayoutEffect(() => {
7699
+ setMounted(true);
7700
+ }, []);
7701
+ React46.useLayoutEffect(() => {
7702
+ if (!context.open) {
7703
+ lockedSideRef.current = null;
7704
+ setContentStyle(void 0);
7705
+ }
7706
+ }, [context.open]);
7707
+ const updatePosition = React46.useCallback(() => {
7708
+ const trigger = context.triggerRef.current;
7709
+ if (!trigger) return;
7710
+ const rect = trigger.getBoundingClientRect();
7711
+ const viewportPadding = 8;
7712
+ const preferredMaxHeight = 288;
7713
+ const minUsefulHeight = 140;
7714
+ const availableBelow = window.innerHeight - rect.bottom - viewportPadding - sideOffset;
7715
+ const availableAbove = rect.top - viewportPadding - sideOffset;
7716
+ const calculatedSide = availableBelow >= Math.min(preferredMaxHeight, minUsefulHeight) || availableBelow >= availableAbove ? "bottom" : "top";
7717
+ if (!lockedSideRef.current) {
7718
+ lockedSideRef.current = calculatedSide;
7719
+ }
7720
+ const nextSide = lockedSideRef.current;
7721
+ const availableHeight = nextSide === "bottom" ? availableBelow : availableAbove;
7722
+ const contentMaxHeight = Math.max(
7723
+ 80,
7724
+ Math.min(preferredMaxHeight, availableHeight)
7725
+ );
7726
+ const baseStyle = {
7727
+ position: "fixed",
7728
+ zIndex: 9999,
7729
+ width: rect.width,
7730
+ minWidth: rect.width,
7731
+ maxWidth: "calc(100vw - 16px)",
7732
+ maxHeight: contentMaxHeight
7733
+ };
7734
+ if (align === "start") {
7735
+ baseStyle.left = rect.left;
7736
+ baseStyle.right = void 0;
7737
+ baseStyle.transform = void 0;
7738
+ }
7739
+ if (align === "center") {
7740
+ baseStyle.left = rect.left + rect.width / 2;
7741
+ baseStyle.right = void 0;
7742
+ baseStyle.transform = "translateX(-50%)";
7743
+ }
7744
+ if (align === "end") {
7745
+ baseStyle.left = rect.right;
7746
+ baseStyle.right = void 0;
7747
+ baseStyle.transform = "translateX(-100%)";
7748
+ }
7749
+ if (nextSide === "bottom") {
7750
+ baseStyle.top = rect.bottom + sideOffset;
7751
+ baseStyle.bottom = void 0;
7752
+ } else {
7753
+ baseStyle.bottom = window.innerHeight - rect.top + sideOffset;
7754
+ baseStyle.top = void 0;
7755
+ }
7756
+ setSide(
7757
+ (previousSide) => previousSide === nextSide ? previousSide : nextSide
7758
+ );
7759
+ setContentStyle(
7760
+ (previousStyle) => areStylesEqual(previousStyle, baseStyle) ? previousStyle : baseStyle
7761
+ );
7762
+ }, [align, context.triggerRef, sideOffset]);
7763
+ const scheduleUpdatePosition = React46.useCallback(() => {
7764
+ if (rafRef.current) {
7765
+ cancelAnimationFrame(rafRef.current);
7766
+ }
7767
+ rafRef.current = requestAnimationFrame(() => {
7768
+ rafRef.current = null;
7769
+ updatePosition();
7770
+ });
7771
+ }, [updatePosition]);
7772
+ React46.useLayoutEffect(() => {
7773
+ var _a2, _b2;
7774
+ if (!context.open) return;
7775
+ updatePosition();
7776
+ scheduleUpdatePosition();
7777
+ const handleResize = () => {
7778
+ scheduleUpdatePosition();
7779
+ };
7780
+ const handlePageScroll = (event) => {
7781
+ var _a3;
7782
+ const target = event.target;
7783
+ if (target && ((_a3 = scrollRef.current) == null ? void 0 : _a3.contains(target))) {
7784
+ return;
7785
+ }
7786
+ scheduleUpdatePosition();
7787
+ };
7788
+ window.addEventListener("resize", handleResize);
7789
+ window.addEventListener("scroll", handlePageScroll, true);
7790
+ (_a2 = window.visualViewport) == null ? void 0 : _a2.addEventListener("resize", handleResize);
7791
+ (_b2 = window.visualViewport) == null ? void 0 : _b2.addEventListener("scroll", handleResize);
7792
+ return () => {
7793
+ var _a3, _b3;
7794
+ window.removeEventListener("resize", handleResize);
7795
+ window.removeEventListener("scroll", handlePageScroll, true);
7796
+ (_a3 = window.visualViewport) == null ? void 0 : _a3.removeEventListener("resize", handleResize);
7797
+ (_b3 = window.visualViewport) == null ? void 0 : _b3.removeEventListener("scroll", handleResize);
7798
+ if (rafRef.current) {
7799
+ cancelAnimationFrame(rafRef.current);
7800
+ rafRef.current = null;
7801
+ }
7802
+ };
7803
+ }, [context.open, scheduleUpdatePosition, updatePosition]);
7804
+ React46.useLayoutEffect(() => {
7805
+ if (!context.open) return;
7806
+ const frame = requestAnimationFrame(() => {
7807
+ const activeItem = context.items.find(
7808
+ (item) => item.value === context.activeValue
7809
+ );
7810
+ scrollItemIntoView(scrollRef.current, activeItem == null ? void 0 : activeItem.ref);
7811
+ });
7812
+ return () => {
7813
+ cancelAnimationFrame(frame);
7814
+ };
7815
+ }, [context.activeValue, context.items, context.open]);
7816
+ if (!context.open) {
7817
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { hidden: true, "aria-hidden": "true", style: { display: "none" }, children });
7818
+ }
7819
+ if (!mounted || !contentStyle) return null;
7820
+ return (0, import_react_dom.createPortal)(
7821
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7822
+ "div",
7823
+ __spreadProps(__spreadValues({}, props), {
7824
+ ref: composeRefs(ref, context.contentRef),
7825
+ role: "listbox",
7826
+ "data-side": side,
7285
7827
  className: cn(
7286
- "relative z-50 min-w-32 overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
7287
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
7288
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
7289
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
7290
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
7291
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
7292
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
7828
+ "min-w-32 overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
7293
7829
  className
7830
+ ),
7831
+ style: __spreadValues(__spreadValues({}, contentStyle), style),
7832
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7833
+ "div",
7834
+ {
7835
+ ref: scrollRef,
7836
+ "data-select-scroll-content": true,
7837
+ className: cn(
7838
+ "max-h-full overflow-x-hidden overflow-y-auto overscroll-contain px-1 py-1",
7839
+ "scrollbar-gutter-stable"
7840
+ ),
7841
+ style: {
7842
+ maxHeight: contentStyle.maxHeight,
7843
+ overflowX: "hidden",
7844
+ overflowY: "auto",
7845
+ overscrollBehavior: "contain",
7846
+ scrollbarGutter: "stable",
7847
+ WebkitOverflowScrolling: "touch"
7848
+ },
7849
+ onWheel: (event) => {
7850
+ event.stopPropagation();
7851
+ },
7852
+ onTouchMove: (event) => {
7853
+ event.stopPropagation();
7854
+ },
7855
+ children
7856
+ }
7294
7857
  )
7295
- }, props), {
7296
- children: [
7297
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectScrollUpButton, {}),
7298
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7299
- SelectPrimitive.Viewport,
7300
- {
7301
- className: cn(
7302
- "max-h-[min(20rem,var(--radix-select-content-available-height))] overflow-y-auto p-1",
7303
- position === "popper" && "w-full min-w-(--radix-select-trigger-width)"
7304
- ),
7305
- children
7306
- }
7307
- ),
7308
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectScrollDownButton, {})
7309
- ]
7310
7858
  })
7311
- ) })
7312
- ] });
7859
+ ),
7860
+ document.body
7861
+ );
7313
7862
  }
7314
7863
  );
7315
- SelectContent.displayName = SelectPrimitive.Content.displayName;
7316
- var SelectLabel = React46.forwardRef((_a, ref) => {
7317
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
7318
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7319
- SelectPrimitive.Label,
7320
- __spreadValues({
7321
- ref,
7322
- className: cn("px-2 py-1.5 text-sm font-semibold", className)
7323
- }, props)
7324
- );
7325
- });
7326
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
7327
- var SelectItem = React46.forwardRef((_a, ref) => {
7328
- var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
7329
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7330
- SelectPrimitive.Item,
7331
- __spreadProps(__spreadValues({
7332
- ref,
7333
- className: cn(
7334
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none transition-colors",
7335
- "focus:bg-accent focus:text-accent-foreground",
7336
- "data-disabled:pointer-events-none data-disabled:opacity-50",
7337
- className
7338
- )
7339
- }, props), {
7340
- children: [
7341
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_icons9.CheckIcon, { className: "h-4 w-4" }) }) }),
7342
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SelectPrimitive.ItemText, { children })
7343
- ]
7344
- })
7345
- );
7346
- });
7347
- SelectItem.displayName = SelectPrimitive.Item.displayName;
7348
- var SelectSeparator = React46.forwardRef((_a, ref) => {
7349
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
7350
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7351
- SelectPrimitive.Separator,
7352
- __spreadValues({
7353
- ref,
7354
- className: cn("-mx-1 my-1 h-px bg-muted", className)
7355
- }, props)
7356
- );
7357
- });
7358
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
7864
+ SelectContent.displayName = "SelectContent";
7865
+ var SelectGroup = React46.forwardRef(
7866
+ (_a, ref) => {
7867
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
7868
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", __spreadValues({ ref, role: "group", className }, props));
7869
+ }
7870
+ );
7871
+ SelectGroup.displayName = "SelectGroup";
7872
+ var SelectLabel = React46.forwardRef(
7873
+ (_a, ref) => {
7874
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
7875
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7876
+ "div",
7877
+ __spreadValues({
7878
+ ref,
7879
+ className: cn("px-2 py-1.5 text-sm font-semibold", className)
7880
+ }, props)
7881
+ );
7882
+ }
7883
+ );
7884
+ SelectLabel.displayName = "SelectLabel";
7885
+ var SelectItem = React46.forwardRef(
7886
+ (_a, ref) => {
7887
+ var _b = _a, {
7888
+ className,
7889
+ children,
7890
+ value,
7891
+ disabled = false,
7892
+ textValue,
7893
+ size,
7894
+ customSize,
7895
+ onClick,
7896
+ onMouseMove,
7897
+ onMouseDown
7898
+ } = _b, props = __objRest(_b, [
7899
+ "className",
7900
+ "children",
7901
+ "value",
7902
+ "disabled",
7903
+ "textValue",
7904
+ "size",
7905
+ "customSize",
7906
+ "onClick",
7907
+ "onMouseMove",
7908
+ "onMouseDown"
7909
+ ]);
7910
+ const context = useSelectContext("SelectItem");
7911
+ const {
7912
+ registerItem,
7913
+ unregisterItem,
7914
+ updateItemRef,
7915
+ setActiveValue,
7916
+ setValue,
7917
+ value: selectedValue,
7918
+ activeValue,
7919
+ size: contextSize,
7920
+ customSize: contextCustomSize
7921
+ } = context;
7922
+ const itemId = React46.useId();
7923
+ const localRef = React46.useRef(null);
7924
+ const resolvedSize = size != null ? size : contextSize;
7925
+ const resolvedCustomSize = customSize != null ? customSize : contextCustomSize;
7926
+ const sizeClasses = getFormSizeClasses(resolvedSize, resolvedCustomSize);
7927
+ const labelText = textValue != null ? textValue : getNodeText(children);
7928
+ const isSelected = selectedValue === value;
7929
+ const isActive = activeValue === value;
7930
+ React46.useLayoutEffect(() => {
7931
+ registerItem({
7932
+ id: itemId,
7933
+ value,
7934
+ label: children,
7935
+ textValue: labelText,
7936
+ disabled,
7937
+ ref: localRef.current
7938
+ });
7939
+ return () => {
7940
+ unregisterItem(value, itemId);
7941
+ };
7942
+ }, [
7943
+ registerItem,
7944
+ unregisterItem,
7945
+ itemId,
7946
+ value,
7947
+ labelText,
7948
+ disabled,
7949
+ children
7950
+ ]);
7951
+ const handleItemRef = React46.useCallback(
7952
+ (node) => {
7953
+ localRef.current = node;
7954
+ updateItemRef(value, itemId, node);
7955
+ },
7956
+ [updateItemRef, value, itemId]
7957
+ );
7958
+ const setRefs = React46.useMemo(
7959
+ () => composeRefs(ref, handleItemRef),
7960
+ [ref, handleItemRef]
7961
+ );
7962
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7963
+ "div",
7964
+ __spreadProps(__spreadValues({
7965
+ ref: setRefs,
7966
+ id: itemId,
7967
+ role: "option",
7968
+ "aria-selected": isSelected,
7969
+ "aria-disabled": disabled,
7970
+ "data-highlighted": isActive ? "" : void 0,
7971
+ "data-disabled": disabled ? "" : void 0,
7972
+ className: cn(
7973
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 outline-none transition-colors",
7974
+ sizeClasses.selectItem,
7975
+ !disabled && "data-highlighted:bg-accent data-highlighted:text-accent-foreground",
7976
+ disabled && "pointer-events-none opacity-50",
7977
+ className
7978
+ ),
7979
+ onMouseDown: (event) => {
7980
+ event.preventDefault();
7981
+ onMouseDown == null ? void 0 : onMouseDown(event);
7982
+ },
7983
+ onMouseMove: (event) => {
7984
+ onMouseMove == null ? void 0 : onMouseMove(event);
7985
+ if (!disabled) {
7986
+ setActiveValue(value);
7987
+ }
7988
+ },
7989
+ onClick: (event) => {
7990
+ onClick == null ? void 0 : onClick(event);
7991
+ if (!event.defaultPrevented && !disabled) {
7992
+ setValue(value);
7993
+ }
7994
+ }
7995
+ }, props), {
7996
+ children: [
7997
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_icons9.CheckIcon, { className: "h-4 w-4" }) : null }),
7998
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "truncate", children })
7999
+ ]
8000
+ })
8001
+ );
8002
+ }
8003
+ );
8004
+ SelectItem.displayName = "SelectItem";
8005
+ var SelectSeparator = React46.forwardRef(
8006
+ (_a, ref) => {
8007
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
8008
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8009
+ "div",
8010
+ __spreadValues({
8011
+ ref,
8012
+ role: "separator",
8013
+ className: cn("-mx-1 my-1 h-px bg-muted", className)
8014
+ }, props)
8015
+ );
8016
+ }
8017
+ );
8018
+ SelectSeparator.displayName = "SelectSeparator";
7359
8019
 
7360
8020
  // src/components/searchable-select.tsx
7361
8021
  var React47 = __toESM(require("react"), 1);
8022
+ var import_react_dom2 = require("react-dom");
7362
8023
  var import_react_icons10 = require("@radix-ui/react-icons");
7363
8024
  var import_jsx_runtime25 = require("react/jsx-runtime");
7364
8025
  function normalizeText(value) {
7365
8026
  return String(value != null ? value : "").normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().trim();
7366
8027
  }
7367
8028
  function getLabelText(value) {
8029
+ if (value === null || value === void 0 || typeof value === "boolean") {
8030
+ return "";
8031
+ }
7368
8032
  if (typeof value === "string" || typeof value === "number") {
7369
8033
  return String(value);
7370
8034
  }
8035
+ if (Array.isArray(value)) {
8036
+ return value.map(getLabelText).join("");
8037
+ }
8038
+ if (React47.isValidElement(value)) {
8039
+ return getLabelText(value.props.children);
8040
+ }
7371
8041
  return "";
7372
8042
  }
7373
8043
  function getOptionText(item) {
@@ -7386,6 +8056,10 @@ function getNextEnabledIndex2(items, currentIndex, direction) {
7386
8056
  }
7387
8057
  return -1;
7388
8058
  }
8059
+ function areStylesEqual2(previous, next) {
8060
+ if (!previous) return false;
8061
+ return previous.position === next.position && previous.zIndex === next.zIndex && previous.width === next.width && previous.minWidth === next.minWidth && previous.maxWidth === next.maxWidth && previous.maxHeight === next.maxHeight && previous.left === next.left && previous.right === next.right && previous.top === next.top && previous.bottom === next.bottom && previous.transform === next.transform;
8062
+ }
7389
8063
  function SearchableSelectBase({
7390
8064
  items,
7391
8065
  value,
@@ -7397,6 +8071,11 @@ function SearchableSelectBase({
7397
8071
  disabled,
7398
8072
  name,
7399
8073
  required,
8074
+ invalid = false,
8075
+ size = "md",
8076
+ customSize,
8077
+ variant = "outline",
8078
+ classNameDefault = true,
7400
8079
  triggerClassName,
7401
8080
  contentClassName,
7402
8081
  itemClassName,
@@ -7404,7 +8083,11 @@ function SearchableSelectBase({
7404
8083
  }) {
7405
8084
  const rootRef = React47.useRef(null);
7406
8085
  const inputRef = React47.useRef(null);
8086
+ const contentRef = React47.useRef(null);
8087
+ const rafRef = React47.useRef(null);
7407
8088
  const listboxId = React47.useId();
8089
+ const sizeClasses = getFormSizeClasses(size, customSize);
8090
+ const triggerSizeClass = getFormControlSizeClass(variant, sizeClasses);
7408
8091
  const isControlled = value !== void 0;
7409
8092
  const [internalValue, setInternalValue] = React47.useState(defaultValue != null ? defaultValue : "");
7410
8093
  const currentValue = isControlled ? value != null ? value : "" : internalValue;
@@ -7414,9 +8097,14 @@ function SearchableSelectBase({
7414
8097
  const selectedText = React47.useMemo(() => {
7415
8098
  return getOptionText(selectedItem);
7416
8099
  }, [selectedItem]);
8100
+ const [mounted, setMounted] = React47.useState(false);
7417
8101
  const [open, setOpen] = React47.useState(false);
7418
8102
  const [inputValue, setInputValue] = React47.useState(selectedText);
7419
8103
  const [activeIndex, setActiveIndex] = React47.useState(-1);
8104
+ const [contentStyle, setContentStyle] = React47.useState();
8105
+ React47.useLayoutEffect(() => {
8106
+ setMounted(true);
8107
+ }, []);
7420
8108
  React47.useEffect(() => {
7421
8109
  if (!open) {
7422
8110
  setInputValue(selectedText);
@@ -7433,17 +8121,110 @@ function SearchableSelectBase({
7433
8121
  return haystack.includes(query);
7434
8122
  });
7435
8123
  }, [inputValue, items]);
8124
+ const updatePosition = React47.useCallback(() => {
8125
+ const root = rootRef.current;
8126
+ if (!root) return;
8127
+ const rect = root.getBoundingClientRect();
8128
+ const viewportPadding = 8;
8129
+ const sideOffset = 6;
8130
+ const preferredMaxHeight = 288;
8131
+ const minUsefulHeight = 140;
8132
+ const availableBelow = window.innerHeight - rect.bottom - viewportPadding - sideOffset;
8133
+ const availableAbove = rect.top - viewportPadding - sideOffset;
8134
+ const shouldOpenBelow = availableBelow >= Math.min(preferredMaxHeight, minUsefulHeight) || availableBelow >= availableAbove;
8135
+ const availableHeight = shouldOpenBelow ? availableBelow : availableAbove;
8136
+ const contentMaxHeight = Math.max(
8137
+ 96,
8138
+ Math.min(preferredMaxHeight, availableHeight)
8139
+ );
8140
+ const nextStyle = {
8141
+ position: "fixed",
8142
+ zIndex: 9999,
8143
+ left: Math.max(viewportPadding, rect.left),
8144
+ width: rect.width,
8145
+ minWidth: rect.width,
8146
+ maxWidth: `calc(100vw - ${viewportPadding * 2}px)`,
8147
+ maxHeight: contentMaxHeight
8148
+ };
8149
+ if (shouldOpenBelow) {
8150
+ nextStyle.top = rect.bottom + sideOffset;
8151
+ nextStyle.bottom = void 0;
8152
+ } else {
8153
+ nextStyle.bottom = window.innerHeight - rect.top + sideOffset;
8154
+ nextStyle.top = void 0;
8155
+ }
8156
+ setContentStyle(
8157
+ (previousStyle) => areStylesEqual2(previousStyle, nextStyle) ? previousStyle : nextStyle
8158
+ );
8159
+ }, []);
8160
+ const scheduleUpdatePosition = React47.useCallback(() => {
8161
+ if (rafRef.current) {
8162
+ cancelAnimationFrame(rafRef.current);
8163
+ }
8164
+ rafRef.current = requestAnimationFrame(() => {
8165
+ rafRef.current = null;
8166
+ updatePosition();
8167
+ });
8168
+ }, [updatePosition]);
8169
+ const openDropdown = React47.useCallback(() => {
8170
+ if (disabled) return;
8171
+ if (!open) {
8172
+ setInputValue("");
8173
+ setOpen(true);
8174
+ }
8175
+ requestAnimationFrame(() => {
8176
+ var _a;
8177
+ (_a = inputRef.current) == null ? void 0 : _a.focus({ preventScroll: true });
8178
+ });
8179
+ }, [disabled, open]);
8180
+ React47.useLayoutEffect(() => {
8181
+ if (!open) {
8182
+ setContentStyle(void 0);
8183
+ }
8184
+ }, [open]);
8185
+ React47.useLayoutEffect(() => {
8186
+ var _a, _b;
8187
+ if (!open) return;
8188
+ updatePosition();
8189
+ scheduleUpdatePosition();
8190
+ const handleResizeOrScroll = () => {
8191
+ scheduleUpdatePosition();
8192
+ };
8193
+ window.addEventListener("resize", handleResizeOrScroll);
8194
+ window.addEventListener("scroll", handleResizeOrScroll, true);
8195
+ (_a = window.visualViewport) == null ? void 0 : _a.addEventListener("resize", handleResizeOrScroll);
8196
+ (_b = window.visualViewport) == null ? void 0 : _b.addEventListener("scroll", handleResizeOrScroll);
8197
+ return () => {
8198
+ var _a2, _b2;
8199
+ window.removeEventListener("resize", handleResizeOrScroll);
8200
+ window.removeEventListener("scroll", handleResizeOrScroll, true);
8201
+ (_a2 = window.visualViewport) == null ? void 0 : _a2.removeEventListener(
8202
+ "resize",
8203
+ handleResizeOrScroll
8204
+ );
8205
+ (_b2 = window.visualViewport) == null ? void 0 : _b2.removeEventListener(
8206
+ "scroll",
8207
+ handleResizeOrScroll
8208
+ );
8209
+ if (rafRef.current) {
8210
+ cancelAnimationFrame(rafRef.current);
8211
+ rafRef.current = null;
8212
+ }
8213
+ };
8214
+ }, [open, scheduleUpdatePosition, updatePosition]);
7436
8215
  React47.useEffect(() => {
7437
8216
  if (!open) return;
7438
8217
  const firstEnabledIndex = filteredItems.findIndex((item) => !item.disabled);
7439
- setActiveIndex(firstEnabledIndex);
8218
+ setActiveIndex(
8219
+ (previousIndex) => previousIndex === firstEnabledIndex ? previousIndex : firstEnabledIndex
8220
+ );
7440
8221
  }, [filteredItems, open]);
7441
8222
  React47.useEffect(() => {
7442
8223
  if (!open) return;
7443
8224
  const handlePointerDown = (event) => {
7444
- var _a;
8225
+ var _a, _b;
7445
8226
  const target = event.target;
7446
- if (target && ((_a = rootRef.current) == null ? void 0 : _a.contains(target))) {
8227
+ if (target && (((_a = rootRef.current) == null ? void 0 : _a.contains(target)) || ((_b = contentRef.current) == null ? void 0 : _b.contains(target)))) {
7447
8228
  return;
7448
8229
  }
7449
8230
  setOpen(false);
@@ -7469,6 +8250,99 @@ function SearchableSelectBase({
7469
8250
  },
7470
8251
  [isControlled, onValueChange]
7471
8252
  );
8253
+ const dropdown = open && mounted && contentStyle ? (0, import_react_dom2.createPortal)(
8254
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8255
+ "div",
8256
+ {
8257
+ ref: contentRef,
8258
+ className: cn(
8259
+ "overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-xl",
8260
+ contentClassName
8261
+ ),
8262
+ style: __spreadProps(__spreadValues({}, contentStyle), {
8263
+ maxHeight: contentStyle.maxHeight
8264
+ }),
8265
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8266
+ "div",
8267
+ {
8268
+ id: listboxId,
8269
+ role: "listbox",
8270
+ className: "max-h-full overflow-x-hidden overflow-y-auto overscroll-contain p-1 scrollbar-gutter-stable",
8271
+ style: {
8272
+ maxHeight: contentStyle.maxHeight,
8273
+ overflowX: "hidden",
8274
+ overflowY: "auto",
8275
+ overscrollBehavior: "contain",
8276
+ scrollbarGutter: "stable",
8277
+ WebkitOverflowScrolling: "touch"
8278
+ },
8279
+ onWheel: (event) => {
8280
+ event.stopPropagation();
8281
+ },
8282
+ onTouchMove: (event) => {
8283
+ event.stopPropagation();
8284
+ },
8285
+ children: filteredItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8286
+ "div",
8287
+ {
8288
+ className: cn(
8289
+ "px-3 py-6 text-center text-muted-foreground",
8290
+ sizeClasses.message
8291
+ ),
8292
+ children: emptyText
8293
+ }
8294
+ ) : filteredItems.map((item, index) => {
8295
+ const isSelected = item.value === currentValue;
8296
+ const isActive = index === activeIndex;
8297
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
8298
+ "div",
8299
+ {
8300
+ id: `${listboxId}-option-${index}`,
8301
+ role: "option",
8302
+ "aria-selected": isSelected,
8303
+ "aria-disabled": item.disabled,
8304
+ tabIndex: -1,
8305
+ onMouseMove: () => {
8306
+ if (!item.disabled) {
8307
+ setActiveIndex(index);
8308
+ }
8309
+ },
8310
+ onPointerDown: (event) => {
8311
+ event.preventDefault();
8312
+ event.stopPropagation();
8313
+ if (!item.disabled) {
8314
+ selectItem(item);
8315
+ }
8316
+ },
8317
+ className: cn(
8318
+ "relative flex w-full select-none items-center gap-2 rounded-lg px-3 text-left outline-none transition",
8319
+ sizeClasses.selectItem,
8320
+ item.disabled ? "pointer-events-none opacity-50" : "cursor-pointer",
8321
+ isActive && !item.disabled && "bg-accent text-accent-foreground",
8322
+ !isActive && !item.disabled && "hover:bg-accent/70 hover:text-accent-foreground",
8323
+ isSelected && "font-medium",
8324
+ itemClassName
8325
+ ),
8326
+ children: [
8327
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label }),
8328
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8329
+ import_react_icons10.CheckIcon,
8330
+ {
8331
+ "aria-hidden": "true",
8332
+ className: "h-4 w-4 shrink-0 text-primary"
8333
+ }
8334
+ ) : null
8335
+ ]
8336
+ },
8337
+ item.value
8338
+ );
8339
+ })
8340
+ }
8341
+ )
8342
+ }
8343
+ ),
8344
+ document.body
8345
+ ) : null;
7472
8346
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
7473
8347
  name ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
7474
8348
  "input",
@@ -7483,19 +8357,18 @@ function SearchableSelectBase({
7483
8357
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
7484
8358
  "div",
7485
8359
  {
7486
- className: cn(
7487
- "relative flex h-9 w-full items-center gap-2 rounded-md border border-input bg-background px-3 text-sm shadow-sm transition",
7488
- "focus-within:border-primary/60 focus-within:ring-2 focus-within:ring-primary/20",
8360
+ className: classNameDefault ? cn(
8361
+ formCompositeControlBase,
8362
+ formCompositeVariants[variant],
8363
+ triggerSizeClass,
8364
+ invalid && formCompositeControlErrorClass,
7489
8365
  disabled && "cursor-not-allowed opacity-50",
7490
8366
  triggerClassName
7491
- ),
7492
- onPointerDown: () => {
7493
- if (disabled) return;
7494
- setOpen(true);
7495
- requestAnimationFrame(() => {
7496
- var _a;
7497
- (_a = inputRef.current) == null ? void 0 : _a.focus({ preventScroll: true });
7498
- });
8367
+ ) : triggerClassName,
8368
+ onPointerDown: (event) => {
8369
+ if (disabled || event.button !== 0 || event.ctrlKey) return;
8370
+ event.preventDefault();
8371
+ openDropdown();
7499
8372
  },
7500
8373
  children: [
7501
8374
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
@@ -7507,17 +8380,14 @@ function SearchableSelectBase({
7507
8380
  "aria-autocomplete": "list",
7508
8381
  "aria-expanded": open,
7509
8382
  "aria-controls": listboxId,
8383
+ "aria-invalid": invalid || void 0,
7510
8384
  "aria-activedescendant": activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : void 0,
7511
8385
  placeholder: open ? searchPlaceholder : placeholder,
7512
8386
  autoComplete: "off",
7513
8387
  spellCheck: false,
7514
8388
  disabled,
7515
8389
  onFocus: () => {
7516
- setOpen(true);
7517
- requestAnimationFrame(() => {
7518
- var _a;
7519
- (_a = inputRef.current) == null ? void 0 : _a.select();
7520
- });
8390
+ openDropdown();
7521
8391
  },
7522
8392
  onChange: (event) => {
7523
8393
  setInputValue(event.target.value);
@@ -7558,7 +8428,7 @@ function SearchableSelectBase({
7558
8428
  }
7559
8429
  },
7560
8430
  className: cn(
7561
- "h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-sm outline-none",
8431
+ "h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none",
7562
8432
  "placeholder:text-muted-foreground disabled:cursor-not-allowed",
7563
8433
  searchInputClassName
7564
8434
  )
@@ -7600,76 +8470,7 @@ function SearchableSelectBase({
7600
8470
  ]
7601
8471
  }
7602
8472
  ),
7603
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
7604
- "div",
7605
- {
7606
- className: cn(
7607
- "absolute left-0 top-full z-50 mt-1 w-full overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-xl transition",
7608
- !open && "pointer-events-none invisible opacity-0",
7609
- open && "visible opacity-100",
7610
- contentClassName
7611
- ),
7612
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
7613
- "div",
7614
- {
7615
- id: listboxId,
7616
- role: "listbox",
7617
- className: "max-h-72 overflow-y-auto overscroll-contain p-1 [scrollbar-gutter:stable]",
7618
- onWheelCapture: (event) => {
7619
- event.stopPropagation();
7620
- },
7621
- onTouchMoveCapture: (event) => {
7622
- event.stopPropagation();
7623
- },
7624
- children: filteredItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyText }) : filteredItems.map((item, index) => {
7625
- const isSelected = item.value === currentValue;
7626
- const isActive = index === activeIndex;
7627
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
7628
- "div",
7629
- {
7630
- id: `${listboxId}-option-${index}`,
7631
- role: "option",
7632
- "aria-selected": isSelected,
7633
- "aria-disabled": item.disabled,
7634
- tabIndex: -1,
7635
- onMouseMove: () => {
7636
- if (!item.disabled) {
7637
- setActiveIndex(index);
7638
- }
7639
- },
7640
- onPointerDown: (event) => {
7641
- event.preventDefault();
7642
- event.stopPropagation();
7643
- if (!item.disabled) {
7644
- selectItem(item);
7645
- }
7646
- },
7647
- className: cn(
7648
- "relative flex w-full select-none items-center gap-2 rounded-lg px-3 py-2 text-left text-sm outline-none transition",
7649
- item.disabled ? "pointer-events-none opacity-50" : "cursor-pointer",
7650
- isActive && !item.disabled && "bg-accent text-accent-foreground",
7651
- !isActive && !item.disabled && "hover:bg-accent/70 hover:text-accent-foreground",
7652
- isSelected && "font-medium",
7653
- itemClassName
7654
- ),
7655
- children: [
7656
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label }),
7657
- isSelected ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
7658
- import_react_icons10.CheckIcon,
7659
- {
7660
- "aria-hidden": "true",
7661
- className: "h-4 w-4 shrink-0 text-primary"
7662
- }
7663
- ) : null
7664
- ]
7665
- },
7666
- item.value
7667
- );
7668
- })
7669
- }
7670
- )
7671
- }
7672
- )
8473
+ dropdown
7673
8474
  ] });
7674
8475
  }
7675
8476
  var SearchableSelect = React47.memo(
@@ -7684,7 +8485,7 @@ var FormSelect = ({
7684
8485
  rules,
7685
8486
  shouldUnregister,
7686
8487
  defaultValue,
7687
- placeholder = "Seleccionar opci\xF3n",
8488
+ placeholder = "Select an option",
7688
8489
  label,
7689
8490
  requiredLabel,
7690
8491
  className,
@@ -7700,7 +8501,6 @@ var FormSelect = ({
7700
8501
  getOptionLabel = getDefaultOptionLabel,
7701
8502
  getOptionDisabled,
7702
8503
  getOptionData,
7703
- children,
7704
8504
  onChange,
7705
8505
  onChangeItem,
7706
8506
  disabled,
@@ -7709,17 +8509,14 @@ var FormSelect = ({
7709
8509
  variant = "outline",
7710
8510
  invalid,
7711
8511
  searchable = false,
7712
- searchPlaceholder = "Buscar\u2026",
7713
- emptyText = "No hay resultados",
7714
- position = "popper"
8512
+ searchPlaceholder = "Search\u2026",
8513
+ emptyText = "No results",
8514
+ classNameDefault = true
7715
8515
  }) => {
7716
8516
  const form = (0, import_react_hook_form5.useFormContext)();
7717
8517
  const controllerControl = control != null ? control : form == null ? void 0 : form.control;
7718
8518
  const sizeClasses = getFormSizeClasses(size, customSize);
7719
- const triggerBase = "relative inline-flex w-full items-center justify-between gap-2 text-foreground outline-none ring-offset-background transition placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50";
7720
- const triggerSizeClass = variant === "flushed" ? sizeClasses.flushedControl : variant === "link" ? sizeClasses.linkControl : sizeClasses.control;
7721
- const contentBase = "z-50 rounded-xl border border-border bg-popover text-popover-foreground shadow-xl outline-none";
7722
- const contentViewport = "[&_[data-radix-select-viewport]]:max-h-72 [&_[data-radix-select-viewport]]:overflow-y-auto [&_[data-radix-select-viewport]]:overscroll-contain [&_[data-radix-select-viewport]]:[scrollbar-gutter:stable]";
8519
+ const triggerSizeClass = getFormControlSizeClass(variant, sizeClasses);
7723
8520
  const normalizedOptions = React48.useMemo(() => {
7724
8521
  if (options) return options;
7725
8522
  return (items != null ? items : []).map((item) => {
@@ -7760,15 +8557,11 @@ var FormSelect = ({
7760
8557
  onChange == null ? void 0 : onChange(value);
7761
8558
  onChangeItem == null ? void 0 : onChangeItem((_a2 = nextOption == null ? void 0 : nextOption.data) != null ? _a2 : null);
7762
8559
  };
7763
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(FormItem, { children: [
8560
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(FormItem, { className: itemClassName, children: [
7764
8561
  label ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
7765
8562
  FormLabel,
7766
8563
  {
7767
- className: cn(
7768
- "flex items-center gap-0.5",
7769
- sizeClasses.label,
7770
- labelClassName
7771
- ),
8564
+ className: cn("flex items-center gap-0.5", labelClassName),
7772
8565
  children: [
7773
8566
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: label }),
7774
8567
  requiredLabel ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
@@ -7784,7 +8577,7 @@ var FormSelect = ({
7784
8577
  ]
7785
8578
  }
7786
8579
  ) : null,
7787
- searchable ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
8580
+ searchable ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7788
8581
  SearchableSelect,
7789
8582
  {
7790
8583
  items: normalizedOptions,
@@ -7794,93 +8587,47 @@ var FormSelect = ({
7794
8587
  searchPlaceholder,
7795
8588
  emptyText,
7796
8589
  disabled,
7797
- triggerClassName: cn(
7798
- "min-h-10 w-full rounded-xl border border-input bg-input px-3 text-sm shadow-sm",
7799
- "focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/20",
7800
- hasError && "border-destructive ring-destructive/20",
7801
- className
7802
- ),
7803
- contentClassName: cn(
7804
- "z-50 mt-1 max-h-72 w-full overflow-hidden rounded-xl border border-border bg-popover shadow-xl",
7805
- contentClassName
7806
- ),
7807
- itemClassName: cn(sizeClasses.selectItem, itemClassName),
7808
- searchInputClassName: cn(
7809
- "h-full w-full min-w-0 bg-transparent outline-none placeholder:text-muted-foreground",
7810
- searchInputClassName
7811
- ),
8590
+ invalid: hasError,
8591
+ size,
8592
+ customSize,
8593
+ variant,
8594
+ classNameDefault,
8595
+ triggerClassName: className,
8596
+ contentClassName,
8597
+ itemClassName,
8598
+ searchInputClassName,
7812
8599
  onValueChange: (value, option) => {
7813
8600
  var _a2;
7814
8601
  field.onChange(value);
7815
8602
  onChange == null ? void 0 : onChange(value);
7816
- onChangeItem == null ? void 0 : onChangeItem((_a2 = option == null ? void 0 : option.data) != null ? _a2 : null);
8603
+ onChangeItem == null ? void 0 : onChangeItem(
8604
+ (_a2 = option == null ? void 0 : option.data) != null ? _a2 : null
8605
+ );
7817
8606
  field.onBlur();
7818
8607
  }
7819
8608
  }
7820
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
8609
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7821
8610
  Select2,
7822
8611
  {
7823
8612
  value: (_b = field.value) != null ? _b : "",
7824
8613
  onValueChange: handleValueChange,
7825
8614
  onOpenChange: (nextOpen) => {
7826
- if (!nextOpen) {
7827
- field.onBlur();
7828
- }
8615
+ if (!nextOpen) field.onBlur();
7829
8616
  },
7830
8617
  disabled,
7831
- children: [
7832
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7833
- SelectTrigger,
7834
- {
7835
- className: cn(
7836
- triggerBase,
7837
- variants[variant],
7838
- triggerSizeClass,
7839
- hasError && "border-destructive ring-destructive focus:ring-destructive/40",
7840
- className
7841
- ),
7842
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SelectValue, { placeholder })
7843
- }
7844
- ) }),
7845
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7846
- SelectContent,
7847
- {
7848
- position,
7849
- sideOffset: 6,
7850
- className: cn(
7851
- contentBase,
7852
- contentViewport,
7853
- "w-(--radix-select-trigger-width) min-w-(--radix-select-trigger-width) overflow-hidden!",
7854
- contentClassName
7855
- ),
7856
- onWheelCapture: (event) => {
7857
- event.stopPropagation();
7858
- },
7859
- onTouchMoveCapture: (event) => {
7860
- event.stopPropagation();
7861
- },
7862
- children: children ? children : normalizedOptions.length > 0 ? normalizedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7863
- SelectItem,
7864
- {
7865
- value: option.value,
7866
- disabled: option.disabled,
7867
- className: cn(sizeClasses.selectItem, itemClassName),
7868
- children: option.label
7869
- },
7870
- option.value
7871
- )) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7872
- "div",
7873
- {
7874
- className: cn(
7875
- "px-3 py-2 text-muted-foreground",
7876
- sizeClasses.message
7877
- ),
7878
- children: emptyText
7879
- }
7880
- )
7881
- }
7882
- )
7883
- ]
8618
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
8619
+ SelectTrigger,
8620
+ {
8621
+ className: classNameDefault ? cn(
8622
+ formControlBase,
8623
+ formInputVariants[variant],
8624
+ triggerSizeClass,
8625
+ hasError && formControlErrorClass,
8626
+ className
8627
+ ) : className,
8628
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SelectValue, { placeholder })
8629
+ }
8630
+ ) })
7884
8631
  }
7885
8632
  ),
7886
8633
  fieldError ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
@@ -8790,7 +9537,7 @@ SearchInput.displayName = "SearchInput";
8790
9537
  var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"), 1);
8791
9538
  var React59 = __toESM(require("react"), 1);
8792
9539
  var import_jsx_runtime39 = require("react/jsx-runtime");
8793
- var Separator6 = React59.forwardRef(
9540
+ var Separator5 = React59.forwardRef(
8794
9541
  (_a, ref) => {
8795
9542
  var _b = _a, { className, orientation = "horizontal", decorative = true } = _b, props = __objRest(_b, ["className", "orientation", "decorative"]);
8796
9543
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
@@ -8808,7 +9555,7 @@ var Separator6 = React59.forwardRef(
8808
9555
  );
8809
9556
  }
8810
9557
  );
8811
- Separator6.displayName = SeparatorPrimitive.Root.displayName;
9558
+ Separator5.displayName = SeparatorPrimitive.Root.displayName;
8812
9559
 
8813
9560
  // src/components/sheet.tsx
8814
9561
  var SheetPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
@@ -9609,24 +10356,10 @@ UiInput.displayName = "UiInput";
9609
10356
  // src/components/ui/select.tsx
9610
10357
  var React72 = __toESM(require("react"), 1);
9611
10358
  var import_lucide_react9 = require("lucide-react");
9612
-
9613
- // src/types/select.ts
9614
- var selectVariants = {
9615
- outline: "rounded-md border border-input bg-input backdrop-blur-sm shadow-sm hover:border-primary/60 focus:border-primary focus:ring-2 focus:ring-primary/20",
9616
- soft: "rounded-md border border-transparent bg-muted/60 shadow-sm hover:bg-muted focus:bg-input/80 focus:ring-2 focus:ring-primary/20",
9617
- ghost: "rounded-md border border-transparent bg-transparent hover:bg-muted/50 focus:ring-2 focus:ring-ring",
9618
- filled: "rounded-md border border-input bg-muted/70 shadow-inner hover:bg-muted focus:bg-input/70 focus:ring-2 focus:ring-primary/20",
9619
- flushed: "rounded-none border-0 border-b border-input px-0 shadow-none focus:border-b-2 focus:border-primary focus:ring-0",
9620
- unstyled: "border-0 shadow-none focus:ring-0",
9621
- link: "h-auto border-0 bg-transparent p-0 text-primary shadow-none underline-offset-4 focus:underline focus:ring-0"
9622
- };
9623
- var variants2 = selectVariants;
9624
-
9625
- // src/components/ui/select.tsx
9626
10359
  var import_jsx_runtime54 = require("react/jsx-runtime");
9627
10360
  function UiSelect({
9628
10361
  label,
9629
- placeholder,
10362
+ placeholder = "Select an option",
9630
10363
  value,
9631
10364
  defaultValue,
9632
10365
  onChange,
@@ -9642,37 +10375,27 @@ function UiSelect({
9642
10375
  messageClassName,
9643
10376
  requiredLabelClassName,
9644
10377
  size = "md",
10378
+ customSize,
9645
10379
  variant = "outline",
9646
10380
  errorMessage,
9647
- htmlFormItemId
10381
+ htmlFormItemId,
10382
+ position
9648
10383
  }) {
9649
10384
  const generatedId = React72.useId();
9650
10385
  const triggerId = htmlFormItemId != null ? htmlFormItemId : generatedId;
9651
10386
  const messageId = `${triggerId}-message`;
9652
10387
  const hasError = Boolean(errorMessage);
9653
- const triggerBase = "relative inline-flex w-full items-center justify-between text-foreground outline-none ring-offset-background transition placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50";
9654
- const sizeTrigger = {
9655
- sm: "h-9 px-3 text-sm",
9656
- md: "h-10 px-3.5 text-sm",
9657
- lg: "h-11 px-4 text-base"
9658
- };
9659
- const itemSize = {
9660
- sm: "h-8 text-sm",
9661
- md: "h-9 text-sm",
9662
- lg: "h-10 text-base"
9663
- };
9664
- const specialFlushed = variant === "flushed" ? size === "sm" ? "h-9 text-sm" : size === "lg" ? "h-11 text-base" : "h-10 text-sm" : "";
9665
- const specialLink = variant === "link" ? "text-sm" : "";
9666
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: cn("w-full space-y-1.5", selectClassName), children: [
10388
+ const sizeClasses = getFormSizeClasses(size, customSize);
10389
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: cn("w-full space-y-0.5", selectClassName), children: [
9667
10390
  label ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
9668
10391
  Label3,
9669
10392
  {
10393
+ htmlFor: triggerId,
9670
10394
  className: cn(
9671
- "inline-flex items-start gap-0.5 text-sm font-medium",
10395
+ "flex items-center gap-0.5 text-sm font-medium -mt-0.75 -pt-1.5",
9672
10396
  hasError && "text-destructive",
9673
10397
  labelClassName
9674
10398
  ),
9675
- htmlFor: triggerId,
9676
10399
  children: [
9677
10400
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: label }),
9678
10401
  requiredLabel ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
@@ -9680,7 +10403,7 @@ function UiSelect({
9680
10403
  {
9681
10404
  "aria-hidden": "true",
9682
10405
  className: cn(
9683
- "mt-0.5 h-3 w-3 shrink-0 text-red-500",
10406
+ "h-3 w-3 shrink-0 text-red-500",
9684
10407
  requiredLabelClassName
9685
10408
  )
9686
10409
  }
@@ -9695,6 +10418,10 @@ function UiSelect({
9695
10418
  defaultValue,
9696
10419
  onValueChange: onChange,
9697
10420
  disabled,
10421
+ size,
10422
+ customSize,
10423
+ variant,
10424
+ invalid: hasError,
9698
10425
  children: [
9699
10426
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
9700
10427
  SelectTrigger,
@@ -9702,26 +10429,33 @@ function UiSelect({
9702
10429
  id: triggerId,
9703
10430
  "aria-invalid": hasError || void 0,
9704
10431
  "aria-describedby": errorMessage ? messageId : void 0,
9705
- className: cn(
9706
- triggerBase,
9707
- variants2[variant],
9708
- variant === "flushed" ? specialFlushed : variant === "link" ? specialLink : sizeTrigger[size],
9709
- hasError && "border-destructive ring-destructive focus:ring-destructive/40",
9710
- className
9711
- ),
10432
+ className,
9712
10433
  children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(SelectValue, { placeholder })
9713
10434
  }
9714
10435
  ),
9715
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(SelectContent, { className: contentClassName, children: children != null ? children : items == null ? void 0 : items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
9716
- SelectItem,
10436
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
10437
+ SelectContent,
9717
10438
  {
9718
- value: item.value,
9719
- disabled: item.disabled,
9720
- className: cn(itemSize[size], itemClassName),
9721
- children: item.label
9722
- },
9723
- item.value
9724
- )) })
10439
+ position,
10440
+ sideOffset: 6,
10441
+ className: cn(
10442
+ "z-50 overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-xl outline-none",
10443
+ contentClassName
10444
+ ),
10445
+ onWheelCapture: (event) => event.stopPropagation(),
10446
+ onTouchMoveCapture: (event) => event.stopPropagation(),
10447
+ children: children != null ? children : items == null ? void 0 : items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
10448
+ SelectItem,
10449
+ {
10450
+ value: item.value,
10451
+ disabled: item.disabled,
10452
+ className: cn(sizeClasses.selectItem, itemClassName),
10453
+ children: item.label
10454
+ },
10455
+ item.value
10456
+ ))
10457
+ }
10458
+ )
9725
10459
  ]
9726
10460
  }
9727
10461
  ),
@@ -9729,7 +10463,11 @@ function UiSelect({
9729
10463
  "p",
9730
10464
  {
9731
10465
  id: messageId,
9732
- className: cn("text-sm font-medium text-destructive", messageClassName),
10466
+ className: cn(
10467
+ "font-medium text-destructive",
10468
+ sizeClasses.message,
10469
+ messageClassName
10470
+ ),
9733
10471
  children: errorMessage
9734
10472
  }
9735
10473
  ) : null
@@ -10330,7 +11068,7 @@ function DataTable({
10330
11068
  children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SelectValue, { placeholder: `${pageSize}` })
10331
11069
  }
10332
11070
  ),
10333
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SelectContent, { side: "top", children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SelectItem, { value: `${size}`, children: size }, size)) })
11071
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SelectContent, { children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SelectItem, { value: `${size}`, children: size }, size)) })
10334
11072
  ]
10335
11073
  }
10336
11074
  )
@@ -10855,8 +11593,6 @@ function PaginationSection({
10855
11593
  SelectGroup,
10856
11594
  SelectItem,
10857
11595
  SelectLabel,
10858
- SelectScrollDownButton,
10859
- SelectScrollUpButton,
10860
11596
  SelectSeparator,
10861
11597
  SelectTrigger,
10862
11598
  SelectValue,
@@ -10911,9 +11647,18 @@ function PaginationSection({
10911
11647
  badgeVariants,
10912
11648
  buttonVariants,
10913
11649
  cn,
11650
+ formCompositeControlBase,
11651
+ formCompositeControlErrorClass,
11652
+ formCompositeVariants,
11653
+ formControlBase,
11654
+ formControlErrorClass,
11655
+ formInputVariants,
11656
+ formSizeVariants,
10914
11657
  getDefaultOptionLabel,
10915
11658
  getDefaultOptionValue,
10916
11659
  getErrorMessage,
11660
+ getFormControlSizeClass,
11661
+ getFormSizeClasses,
10917
11662
  getNextEnabledIndex,
10918
11663
  iconButtonVariants,
10919
11664
  navigationMenuTriggerStyle,
@@ -10923,5 +11668,6 @@ function PaginationSection({
10923
11668
  toggleVariants,
10924
11669
  useFormField,
10925
11670
  useSidebar,
10926
- useToast
11671
+ useToast,
11672
+ variants
10927
11673
  });