@chekinapp/ui 0.0.67 → 0.0.68

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
@@ -4537,8 +4537,9 @@ var iconButtonVariants = cva10(
4537
4537
  variants: {
4538
4538
  size: {
4539
4539
  s: "w-8 h-8",
4540
- m: "w-10 h-10",
4541
- l: "w-[43px] h-[43px]"
4540
+ m: "w-8 h-8",
4541
+ l: "w-[43px] h-[43px]",
4542
+ default: "w-8 h-8"
4542
4543
  },
4543
4544
  shape: {
4544
4545
  rounded: "rounded-[var(--chekin-radius-input)]",
@@ -7052,13 +7053,13 @@ function SearchButton({ onClick, className, icon, ariaLabel }) {
7052
7053
  {
7053
7054
  onClick,
7054
7055
  className: cn(
7055
- "p-1.5 text-[var(--chekin-color-gray-1)] hover:text-[var(--chekin-color-brand-blue)]",
7056
+ "p-1.5 text-[#9696b9] hover:text-[var(--chekin-color-brand-blue)]",
7056
7057
  className
7057
7058
  ),
7058
7059
  "data-testid": "search-button",
7059
7060
  "aria-label": ariaLabel,
7060
7061
  type: "button",
7061
- children: icon || /* @__PURE__ */ jsx91(Search, { size: 14, strokeWidth: 4 })
7062
+ children: icon || /* @__PURE__ */ jsx91(Search, { size: 12, strokeWidth: 4 })
7062
7063
  }
7063
7064
  );
7064
7065
  }
@@ -9399,11 +9400,23 @@ import {
9399
9400
  } from "react";
9400
9401
  import { jsx as jsx125, jsxs as jsxs74 } from "react/jsx-runtime";
9401
9402
  var getValueArray = (value) => {
9402
- if (value) {
9403
+ if (value !== void 0 && value !== null) {
9403
9404
  return Array.isArray(value) ? value : [value];
9404
9405
  }
9405
9406
  return [];
9406
9407
  };
9408
+ var convertStringToValue = (stringValue, option) => {
9409
+ if (option) {
9410
+ return option.value;
9411
+ }
9412
+ if (stringValue === "true") return true;
9413
+ if (stringValue === "false") return false;
9414
+ const numValue = Number(stringValue);
9415
+ if (!isNaN(numValue) && stringValue !== "") {
9416
+ return numValue;
9417
+ }
9418
+ return stringValue;
9419
+ };
9407
9420
  function getToggleContent(label, disabled, readOnly, active) {
9408
9421
  if (isValidElement2(label)) {
9409
9422
  return cloneElement2(label, {
@@ -9440,7 +9453,7 @@ function TogglesInternal({
9440
9453
  const newValueArray = Array.isArray(newValue) ? newValue : [newValue];
9441
9454
  const typedValues = newValueArray.map((item) => {
9442
9455
  const option2 = options.find((opt) => String(opt.value) === item);
9443
- return option2 ? option2.value : item;
9456
+ return convertStringToValue(item, option2);
9444
9457
  });
9445
9458
  onChange?.(
9446
9459
  typedValues,
@@ -9450,7 +9463,7 @@ function TogglesInternal({
9450
9463
  }
9451
9464
  const singleValue = Array.isArray(newValue) ? newValue[0] : newValue;
9452
9465
  const option = options.find((opt) => String(opt.value) === singleValue);
9453
- const typedValue = option ? option.value : singleValue;
9466
+ const typedValue = convertStringToValue(singleValue, option);
9454
9467
  onChange?.(
9455
9468
  typedValue,
9456
9469
  {}
@@ -13305,275 +13318,1849 @@ var AirbnbSearchInput = React52.forwardRef(({ onReset, placeholder, wrapperClass
13305
13318
  });
13306
13319
  AirbnbSearchInput.displayName = "SearchInput";
13307
13320
 
13308
- // src/searchable-select/SearchableSelect.tsx
13321
+ // src/dashboard/input/Input.tsx
13309
13322
  import * as React53 from "react";
13310
- import { ChevronDown as ChevronDown4, Search as Search4 } from "lucide-react";
13311
- import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
13312
- import { useCallback as useCallback33 } from "react";
13313
- import { jsx as jsx152, jsxs as jsxs96 } from "react/jsx-runtime";
13314
- var ROW_HEIGHT = 48;
13315
- var DESKTOP_LIST_HEIGHT = 280;
13316
- var MOBILE_LIST_HEIGHT = 420;
13317
- var LOAD_MORE_THRESHOLD = 6;
13318
- function defaultFilter(option, searchValue) {
13319
- return String(option.label).toLowerCase().includes(searchValue.trim().toLowerCase());
13320
- }
13321
- var SearchableSelectInternal = ({
13322
- options,
13323
- value,
13324
- onChange,
13325
- onBlur,
13326
- onOpenChange,
13327
- searchValue,
13328
- onSearchChange,
13329
- filterOption = defaultFilter,
13330
- loading,
13331
- hasNextPage,
13332
- onLoadMore,
13333
- variant = "default",
13334
- label,
13335
- topLabel,
13336
- placeholder,
13337
- searchPlaceholder = "Search...",
13338
- mobileTitle,
13339
- getValueLabel,
13340
- disabled,
13341
- error,
13323
+ import { Eye, Minus as Minus3, Plus as Plus2, X as X10 } from "lucide-react";
13324
+
13325
+ // src/dashboard/_fieldset/Fieldset.tsx
13326
+ import { Fragment as Fragment14, jsx as jsx152, jsxs as jsxs96 } from "react/jsx-runtime";
13327
+ function Fieldset({
13328
+ isActivated,
13329
+ isFocused,
13330
+ isEmpty,
13342
13331
  invalid,
13343
- optional,
13332
+ label,
13344
13333
  tooltip,
13345
- hideErrorMessage,
13346
- name,
13334
+ legend,
13335
+ onClick,
13336
+ htmlFor,
13337
+ labelId,
13338
+ readOnly,
13339
+ loading,
13340
+ disabled,
13347
13341
  className,
13348
- dropdownClassName,
13349
- menuClassName,
13350
- noOptionsMessage,
13351
- loadingMessage
13352
- }, ref) => {
13353
- const { isMatch: isMobile2 } = useScreenResize(DEVICE.mobileXL);
13354
- const reactId = React53.useId();
13355
- const [open, setOpen] = React53.useState(false);
13356
- const [internalSearchValue, setInternalSearchValue] = React53.useState("");
13357
- const [highlightedIndex, setHighlightedIndex] = React53.useState(-1);
13358
- const containerRef = React53.useRef(null);
13359
- const triggerRef = React53.useRef(null);
13360
- const inputRef = React53.useRef(null);
13361
- const listboxId = `${reactId}-listbox`;
13362
- const labelId = `${reactId}-label`;
13363
- const valueId = `${reactId}-value`;
13364
- const helperTextId = `${reactId}-helper`;
13365
- const errorId = `${reactId}-error`;
13366
- const searchInputId = `${reactId}-search`;
13367
- const effectiveSearchValue = searchValue ?? internalSearchValue;
13368
- const shouldFilterLocally = !onSearchChange && filterOption !== null;
13369
- const visibleOptions = React53.useMemo(() => {
13370
- if (!shouldFilterLocally || !effectiveSearchValue) {
13371
- return options;
13372
- }
13373
- return options.filter((option) => filterOption(option, effectiveSearchValue));
13374
- }, [effectiveSearchValue, filterOption, options, shouldFilterLocally]);
13375
- const selectedIndex = React53.useMemo(
13376
- () => visibleOptions.findIndex((option) => option.value === value?.value),
13377
- [value?.value, visibleOptions]
13378
- );
13379
- const helperText = placeholder ?? label;
13380
- const valueLabel = value ? getValueLabel?.(value) ?? String(value.label) : void 0;
13381
- const isBlocked = Boolean(disabled) || Boolean(loading);
13382
- const triggerError = error ?? invalid;
13383
- const describedBy = error && !hideErrorMessage ? errorId : void 0;
13384
- const activeOptionId = highlightedIndex >= 0 ? getOptionId(reactId, highlightedIndex) : void 0;
13385
- useOutsideClick({
13386
- elementRef: containerRef,
13387
- onOutsideClick: () => closeSelect(),
13388
- isDisabled: !open || isMobile2
13389
- });
13390
- const handleOnOpenChange = useEvent(onOpenChange);
13391
- const setSelectOpen = useCallback33(
13392
- (nextOpen, options2) => {
13393
- setOpen(nextOpen);
13394
- handleOnOpenChange?.(nextOpen);
13395
- if (!nextOpen && options2?.restoreFocus) {
13396
- triggerRef.current?.focus();
13397
- }
13398
- },
13399
- [handleOnOpenChange]
13400
- );
13401
- React53.useEffect(() => {
13402
- if (isBlocked) {
13403
- setSelectOpen(false);
13404
- return;
13405
- }
13406
- if (!open) return;
13407
- const frameId = window.requestAnimationFrame(() => {
13408
- inputRef.current?.focus();
13409
- });
13410
- return () => {
13411
- window.cancelAnimationFrame(frameId);
13412
- };
13413
- }, [isBlocked, open, setSelectOpen]);
13414
- React53.useEffect(() => {
13415
- if (!open) {
13416
- setHighlightedIndex(-1);
13417
- return;
13418
- }
13419
- setHighlightedIndex((currentIndex) => {
13420
- if (currentIndex >= 0 && currentIndex < visibleOptions.length && !visibleOptions[currentIndex]?.isDisabled) {
13421
- return currentIndex;
13422
- }
13423
- return selectedIndex >= 0 ? selectedIndex : getFirstEnabledIndex(visibleOptions);
13424
- });
13425
- }, [open, selectedIndex, visibleOptions]);
13426
- function openSelect() {
13427
- if (isBlocked) return;
13428
- setSelectOpen(true);
13429
- }
13430
- function closeSelect() {
13431
- setSelectOpen(false, { restoreFocus: true });
13432
- }
13433
- function handleSearchChange(nextValue) {
13434
- if (!onSearchChange) {
13435
- setInternalSearchValue(nextValue);
13436
- }
13437
- onSearchChange?.(nextValue);
13438
- }
13439
- function handleSelect(option) {
13440
- if (isBlocked || option.isDisabled) return;
13441
- onChange(option);
13442
- setSelectOpen(false, { restoreFocus: true });
13443
- }
13444
- function moveHighlight(step) {
13445
- const startIndex = highlightedIndex >= 0 ? highlightedIndex + step : step === 1 ? 0 : visibleOptions.length - 1;
13446
- const nextIndex = getNextEnabledIndex(visibleOptions, startIndex, step);
13447
- if (nextIndex >= 0) {
13448
- setHighlightedIndex(nextIndex);
13449
- }
13450
- }
13451
- function handleTriggerKeyDown(event) {
13452
- if (isBlocked) return;
13453
- if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown" || event.key === "ArrowUp") {
13454
- event.preventDefault();
13455
- openSelect();
13456
- }
13457
- }
13458
- function handleSearchKeyDown(event) {
13459
- if (event.key === "Escape") {
13460
- event.preventDefault();
13461
- closeSelect();
13462
- return;
13463
- }
13464
- if (event.key === "ArrowDown") {
13465
- event.preventDefault();
13466
- moveHighlight(1);
13467
- return;
13468
- }
13469
- if (event.key === "ArrowUp") {
13470
- event.preventDefault();
13471
- moveHighlight(-1);
13472
- return;
13473
- }
13474
- if (event.key === "Enter") {
13475
- event.preventDefault();
13476
- const option = visibleOptions[highlightedIndex];
13477
- if (option) {
13478
- handleSelect(option);
13342
+ labelClassName
13343
+ }) {
13344
+ const showLegendText = Boolean(legend || typeof label === "string");
13345
+ const raised = !isEmpty || isFocused;
13346
+ return /* @__PURE__ */ jsxs96(Fragment14, { children: [
13347
+ /* @__PURE__ */ jsxs96(
13348
+ "div",
13349
+ {
13350
+ onClick,
13351
+ className: cn(
13352
+ "absolute box-border inline-flex max-w-full cursor-text items-center pl-[3px] pr-5 transition-all duration-100 ease-in",
13353
+ "left-[13px] text-[var(--chekin-color-gray-1)]",
13354
+ isEmpty && !isFocused ? "top-[14px]" : "top-[-8px] !pl-1 !pr-[22px]",
13355
+ isFocused && "text-[var(--chekin-color-brand-blue)]",
13356
+ raised && invalid && "text-[var(--error-message-color)]",
13357
+ readOnly && "cursor-default",
13358
+ disabled && "pointer-events-none cursor-not-allowed",
13359
+ loading && "cursor-progress",
13360
+ labelClassName
13361
+ ),
13362
+ children: [
13363
+ /* @__PURE__ */ jsx152(
13364
+ "label",
13365
+ {
13366
+ id: labelId,
13367
+ htmlFor,
13368
+ className: cn(
13369
+ "block cursor-[inherit] truncate font-medium transition-all duration-100 ease-in",
13370
+ raised ? "text-[14px]" : "text-[16px]"
13371
+ ),
13372
+ children: label
13373
+ }
13374
+ ),
13375
+ tooltip && /* @__PURE__ */ jsx152("span", { className: "ml-1 inline-flex", children: /* @__PURE__ */ jsx152(
13376
+ HelpTooltip,
13377
+ {
13378
+ content: tooltip,
13379
+ size: 16,
13380
+ className: cn(isFocused && "text-[var(--chekin-color-brand-blue)]")
13381
+ }
13382
+ ) })
13383
+ ]
13479
13384
  }
13480
- }
13481
- }
13482
- const content = /* @__PURE__ */ jsx152(
13483
- SearchableSelectContent,
13484
- {
13485
- inputId: searchInputId,
13486
- listboxId,
13487
- labelId,
13488
- activeOptionId,
13489
- inputRef,
13490
- options: visibleOptions,
13491
- value,
13492
- searchValue: effectiveSearchValue,
13493
- searchPlaceholder,
13494
- highlightedIndex,
13495
- loading,
13496
- hasNextPage,
13497
- onLoadMore,
13498
- menuClassName,
13499
- noOptionsMessage,
13500
- loadingMessage,
13501
- height: isMobile2 ? MOBILE_LIST_HEIGHT : DESKTOP_LIST_HEIGHT,
13502
- idPrefix: reactId,
13503
- onSearchChange: handleSearchChange,
13504
- onSearchKeyDown: handleSearchKeyDown,
13505
- onOptionClick: handleSelect,
13506
- onOptionHover: setHighlightedIndex
13507
- }
13508
- );
13509
- React53.useImperativeHandle(ref, () => triggerRef.current, []);
13510
- return /* @__PURE__ */ jsxs96("div", { ref: containerRef, className: cn("relative w-full max-w-[425px]", className), children: [
13511
- name && /* @__PURE__ */ jsx152("input", { type: "hidden", name, value: value ? String(value.value) : "" }),
13385
+ ),
13512
13386
  /* @__PURE__ */ jsx152(
13513
- FieldTrigger,
13387
+ "fieldset",
13514
13388
  {
13515
- id: `${reactId}-trigger`,
13516
- ref: triggerRef,
13517
- variant,
13518
- "aria-haspopup": "listbox",
13519
- "aria-expanded": open,
13520
- "aria-controls": listboxId,
13521
- label,
13522
- topLabel,
13523
- labelId,
13524
- valueId,
13525
- helperTextId,
13526
- errorId: error ? errorId : void 0,
13527
- labelText: topLabel ? helperText : void 0,
13528
- valueText: valueLabel,
13529
- placeholder: helperText,
13530
- describedBy,
13531
- error: triggerError,
13532
- loading,
13533
- optional,
13534
- tooltip,
13535
- forceLabelText: Boolean(optional) || Boolean(tooltip),
13536
- hideErrorMessage,
13537
- disabled,
13538
- onClick: () => {
13539
- if (open) {
13540
- closeSelect();
13541
- return;
13542
- }
13543
- openSelect();
13544
- },
13545
- onKeyDown: handleTriggerKeyDown,
13546
- onBlur,
13547
- trailingAdornment: /* @__PURE__ */ jsx152(
13548
- ChevronDown4,
13389
+ "aria-hidden": "true",
13390
+ className: cn(
13391
+ "pointer-events-none absolute -top-[5px] bottom-0 left-0 right-0 m-0 min-w-0 rounded-[6px] border px-[13px] transition-colors duration-75",
13392
+ "border-[var(--chekin-color-gray-3)]",
13393
+ isActivated && "border-[var(--chekin-color-gray-2)]",
13394
+ isFocused && "border-[var(--chekin-color-brand-blue)]",
13395
+ invalid && "border-[var(--error-message-color)]",
13396
+ className
13397
+ ),
13398
+ children: /* @__PURE__ */ jsxs96(
13399
+ "legend",
13549
13400
  {
13550
13401
  className: cn(
13551
- "h-6 w-6 text-[#1F1F1B] transition-transform",
13552
- open && "rotate-180"
13553
- )
13402
+ "invisible float-none block h-[11px] max-w-[0.01px] whitespace-nowrap p-0 text-[0.75em]",
13403
+ "transition-[max-width] duration-[50ms] ease-out",
13404
+ raised && "max-w-full !duration-100 !delay-[50ms]",
13405
+ !label && "w-0"
13406
+ ),
13407
+ children: [
13408
+ showLegendText && /* @__PURE__ */ jsx152("span", { className: "visible inline-block pr-[6px] text-[14px] font-medium opacity-0", children: legend || label }),
13409
+ tooltip && /* @__PURE__ */ jsx152("span", { className: "visible inline-block w-[20px] opacity-0", children: /* @__PURE__ */ jsx152("span", { className: "inline-block h-4 w-4" }) })
13410
+ ]
13554
13411
  }
13555
13412
  )
13556
13413
  }
13557
- ),
13558
- isMobile2 ? /* @__PURE__ */ jsx152(
13559
- Drawer,
13560
- {
13561
- open,
13562
- onOpenChange: (nextOpen) => {
13563
- if (isBlocked && nextOpen) return;
13414
+ )
13415
+ ] });
13416
+ }
13417
+
13418
+ // src/dashboard/input/Input.tsx
13419
+ import { jsx as jsx153, jsxs as jsxs97 } from "react/jsx-runtime";
13420
+ var checkIfEmpty = ({
13421
+ empty,
13422
+ defaultValue,
13423
+ value
13424
+ }) => {
13425
+ if (typeof empty !== "undefined") return empty;
13426
+ if (value === 0 || defaultValue === 0) return false;
13427
+ return !value && !defaultValue;
13428
+ };
13429
+ var DashboardInput = React53.forwardRef(
13430
+ ({
13431
+ value,
13432
+ defaultValue,
13433
+ className,
13434
+ wrapperClassName,
13435
+ fieldClassName,
13436
+ contentClassName,
13437
+ inputClassName,
13438
+ label,
13439
+ topLabel,
13440
+ tooltip,
13441
+ disabled,
13442
+ loading,
13443
+ readOnly,
13444
+ name,
13445
+ id,
13446
+ type,
13447
+ error,
13448
+ optional = false,
13449
+ invalid,
13450
+ empty,
13451
+ showNumberButtons,
13452
+ onIncrement,
13453
+ onDecrement,
13454
+ sign,
13455
+ footer,
13456
+ width,
13457
+ onReset,
13458
+ onChange,
13459
+ onFocus,
13460
+ onBlur,
13461
+ helperText,
13462
+ placeholder,
13463
+ leftIcon,
13464
+ trailingAdornment,
13465
+ renderErrorMessage = true,
13466
+ ...props
13467
+ }, ref) => {
13468
+ const generatedId = React53.useId();
13469
+ const inputId = id ?? name ?? generatedId;
13470
+ const errorId = `${inputId}-error`;
13471
+ const isEmpty = checkIfEmpty({ empty, value, defaultValue });
13472
+ const [inputType, setInputType] = React53.useState(type);
13473
+ const [isPasswordRevealed, setIsPasswordRevealed] = React53.useState(false);
13474
+ const [isFocused, setIsFocused] = React53.useState(false);
13475
+ const prevInputType = usePrevious(inputType);
13476
+ const isPasswordReveal = (prevInputType === "password" || type === "password") && !isEmpty;
13477
+ const hasInvalidState = Boolean(invalid) || Boolean(error) && error !== "NONE";
13478
+ const errorMessage = typeof error === "string" && error !== "NONE" ? error : void 0;
13479
+ const wrapperWidth = toCssSize(width);
13480
+ const togglePasswordReveal = () => {
13481
+ if (isPasswordRevealed) {
13482
+ setInputType("password");
13483
+ setIsPasswordRevealed(false);
13484
+ } else {
13485
+ setInputType("text");
13486
+ setIsPasswordRevealed(true);
13487
+ }
13488
+ };
13489
+ React53.useEffect(() => {
13490
+ setInputType(type);
13491
+ }, [type]);
13492
+ const handleChange = (event) => {
13493
+ if (readOnly || disabled || !onChange) return;
13494
+ onChange(event);
13495
+ };
13496
+ const handleLabelClick = () => {
13497
+ if (readOnly || disabled) return;
13498
+ setIsFocused(true);
13499
+ };
13500
+ const handleFocus = (event) => {
13501
+ if (readOnly || disabled) return;
13502
+ onFocus?.(event);
13503
+ setIsFocused(true);
13504
+ };
13505
+ const handleBlur = (event) => {
13506
+ onBlur?.(event);
13507
+ setIsFocused(false);
13508
+ };
13509
+ const showRightPaddingForReset = Boolean(onReset);
13510
+ const showRightPaddingForReveal = isPasswordReveal;
13511
+ return /* @__PURE__ */ jsxs97(
13512
+ "div",
13513
+ {
13514
+ className: cn(
13515
+ "relative block min-h-[68px]",
13516
+ disabled && "cursor-not-allowed opacity-50",
13517
+ loading && "cursor-progress",
13518
+ wrapperClassName,
13519
+ className
13520
+ ),
13521
+ style: wrapperWidth ? { width: wrapperWidth } : void 0,
13522
+ children: [
13523
+ topLabel && /* @__PURE__ */ jsx153(
13524
+ "label",
13525
+ {
13526
+ htmlFor: inputId,
13527
+ className: "mb-2 block text-[14px] font-medium text-[var(--chekin-color-brand-navy)]",
13528
+ children: topLabel
13529
+ }
13530
+ ),
13531
+ /* @__PURE__ */ jsxs97(
13532
+ "div",
13533
+ {
13534
+ className: cn(
13535
+ "relative block w-full",
13536
+ readOnly && "bg-[var(--chekin-color-surface-input-empty)]",
13537
+ fieldClassName
13538
+ ),
13539
+ children: [
13540
+ /* @__PURE__ */ jsxs97("div", { className: cn("relative w-full cursor-text", contentClassName), children: [
13541
+ /* @__PURE__ */ jsx153(
13542
+ Fieldset,
13543
+ {
13544
+ isFocused: isFocused && !readOnly,
13545
+ invalid: hasInvalidState,
13546
+ isEmpty,
13547
+ onClick: handleLabelClick,
13548
+ isActivated: !isEmpty || isFocused,
13549
+ readOnly,
13550
+ loading,
13551
+ disabled,
13552
+ htmlFor: inputId,
13553
+ labelId: `${inputId}-label`,
13554
+ legend: typeof label === "string" ? label : void 0,
13555
+ label,
13556
+ tooltip
13557
+ }
13558
+ ),
13559
+ leftIcon && /* @__PURE__ */ jsx153("span", { className: "pointer-events-none absolute left-0 top-0 flex h-full max-w-10 items-center justify-center text-[var(--chekin-color-gray-2)]", children: /* @__PURE__ */ jsx153("span", { className: "flex h-full w-10 items-center justify-center", children: leftIcon }) }),
13560
+ /* @__PURE__ */ jsx153(
13561
+ "input",
13562
+ {
13563
+ ...props,
13564
+ ref,
13565
+ id: inputId,
13566
+ name,
13567
+ type: inputType,
13568
+ "data-testid": "input",
13569
+ value,
13570
+ defaultValue,
13571
+ disabled: disabled || loading,
13572
+ readOnly,
13573
+ required: !optional,
13574
+ "aria-label": typeof label === "string" ? label : void 0,
13575
+ "aria-invalid": hasInvalidState,
13576
+ "aria-busy": loading,
13577
+ "aria-describedby": errorMessage && renderErrorMessage ? errorId : void 0,
13578
+ placeholder: isFocused || !label ? placeholder : void 0,
13579
+ onChange: handleChange,
13580
+ onFocus: handleFocus,
13581
+ onBlur: handleBlur,
13582
+ className: cn(
13583
+ "m-0 box-border h-12 w-full rounded-[6px] border-0 px-4 text-[16px] font-medium leading-5 text-[var(--chekin-color-brand-navy)] outline-none transition-colors duration-200 [text-overflow:ellipsis] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
13584
+ "placeholder:font-medium placeholder:text-[var(--chekin-color-gray-1)] placeholder:opacity-100",
13585
+ isEmpty && !isFocused ? "bg-[var(--chekin-color-surface-input-empty)]" : "bg-transparent",
13586
+ isEmpty && "text-[var(--chekin-color-gray-1)]",
13587
+ inputType === "password" && "[&:not(:placeholder-shown)]:font-bold [&:not(:placeholder-shown)]:tracking-[2px]",
13588
+ (disabled || readOnly) && "cursor-not-allowed",
13589
+ loading && "cursor-progress",
13590
+ leftIcon && "pl-10",
13591
+ (showRightPaddingForReset || showRightPaddingForReveal) && "pr-10",
13592
+ sign && "pr-10",
13593
+ inputClassName
13594
+ )
13595
+ }
13596
+ ),
13597
+ sign && /* @__PURE__ */ jsx153("span", { className: "pointer-events-none absolute right-[14px] top-0 flex h-full items-center text-[18px] font-medium leading-6 text-[var(--chekin-color-brand-navy)]", children: sign }),
13598
+ trailingAdornment && /* @__PURE__ */ jsx153("span", { className: "pointer-events-none absolute right-[14px] top-0 flex h-full items-center", children: trailingAdornment }),
13599
+ onReset && /* @__PURE__ */ jsx153(
13600
+ "button",
13601
+ {
13602
+ type: "button",
13603
+ onClick: onReset,
13604
+ disabled,
13605
+ className: "absolute right-0 top-0 flex h-full w-10 items-center justify-center border-0 bg-transparent p-0 text-[#9696b9] hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50",
13606
+ "aria-label": "Reset",
13607
+ children: /* @__PURE__ */ jsx153(X10, { size: 14 })
13608
+ }
13609
+ ),
13610
+ isPasswordReveal && /* @__PURE__ */ jsx153(
13611
+ "button",
13612
+ {
13613
+ type: "button",
13614
+ onClick: togglePasswordReveal,
13615
+ className: "absolute right-[14px] top-[13px] flex h-[13px] w-[21px] cursor-pointer items-center justify-center border-0 bg-transparent p-0 hover:opacity-85",
13616
+ "aria-label": isPasswordRevealed ? "Hide password" : "Show password",
13617
+ children: /* @__PURE__ */ jsx153(
13618
+ Eye,
13619
+ {
13620
+ className: cn(
13621
+ "h-[13px] w-[21px]",
13622
+ isPasswordRevealed ? "text-[#fc98dd]" : "text-[var(--chekin-color-gray-2)]"
13623
+ )
13624
+ }
13625
+ )
13626
+ }
13627
+ )
13628
+ ] }),
13629
+ type === "number" && showNumberButtons && /* @__PURE__ */ jsxs97("div", { className: "absolute right-[18px] top-[10px] inline-flex items-center text-right", children: [
13630
+ /* @__PURE__ */ jsx153(
13631
+ "button",
13632
+ {
13633
+ type: "button",
13634
+ onClick: onDecrement,
13635
+ className: "mr-2 inline-flex h-[23px] w-8 cursor-pointer items-center justify-center rounded-[3px] border-0 bg-[var(--chekin-color-brand-blue)] p-0 text-[20px] font-bold text-white outline-none hover:opacity-90 active:opacity-100",
13636
+ "aria-label": "Decrement",
13637
+ children: /* @__PURE__ */ jsx153(Minus3, { size: 16, strokeWidth: 3, "aria-hidden": true })
13638
+ }
13639
+ ),
13640
+ /* @__PURE__ */ jsx153(
13641
+ "button",
13642
+ {
13643
+ type: "button",
13644
+ onClick: onIncrement,
13645
+ className: "inline-flex h-[23px] w-8 cursor-pointer items-center justify-center rounded-[3px] border-0 bg-[var(--chekin-color-brand-blue)] p-0 text-[20px] font-bold text-white outline-none hover:opacity-90 active:opacity-100",
13646
+ "aria-label": "Increment",
13647
+ children: /* @__PURE__ */ jsx153(Plus2, { size: 16, strokeWidth: 3, "aria-hidden": true })
13648
+ }
13649
+ )
13650
+ ] })
13651
+ ]
13652
+ }
13653
+ ),
13654
+ !errorMessage && optional && /* @__PURE__ */ jsx153(
13655
+ "span",
13656
+ {
13657
+ "data-testid": `${name}-optional`,
13658
+ className: "mt-[1px] block text-left text-[14px] font-medium text-[var(--chekin-color-gray-1)]",
13659
+ children: typeof optional === "string" ? optional : "optional"
13660
+ }
13661
+ ),
13662
+ !errorMessage && helperText && /* @__PURE__ */ jsx153("span", { className: "mt-[1px] block text-[12px] font-normal text-[var(--chekin-color-gray-1)]", children: helperText }),
13663
+ errorMessage && renderErrorMessage && /* @__PURE__ */ jsx153(
13664
+ FieldErrorMessage,
13665
+ {
13666
+ id: errorId,
13667
+ message: errorMessage,
13668
+ "data-testid": name ? `${name}-error` : void 0,
13669
+ className: "mt-[1px] text-[14px]"
13670
+ }
13671
+ ),
13672
+ footer
13673
+ ]
13674
+ }
13675
+ );
13676
+ }
13677
+ );
13678
+ DashboardInput.displayName = "DashboardInput";
13679
+
13680
+ // src/dashboard/select/Select.tsx
13681
+ import * as React55 from "react";
13682
+ import { ChevronDown as ChevronDown4 } from "lucide-react";
13683
+
13684
+ // src/dashboard/_select-internals/utils.ts
13685
+ function getOptionIndex2(options, option) {
13686
+ if (!option) return -1;
13687
+ return options.findIndex((item) => item.value === option.value);
13688
+ }
13689
+ function getFirstEnabledOptionIndex2(options) {
13690
+ return options.findIndex((option) => !option.isDisabled);
13691
+ }
13692
+ function getNextEnabledOptionIndex2(options, startIndex, step) {
13693
+ let nextIndex = startIndex;
13694
+ while (nextIndex >= 0 && nextIndex < options.length) {
13695
+ if (!options[nextIndex]?.isDisabled) return nextIndex;
13696
+ nextIndex += step;
13697
+ }
13698
+ return -1;
13699
+ }
13700
+ function defaultFilterOption(option, input) {
13701
+ if (!input) return true;
13702
+ const text = typeof option.label === "string" ? option.label : String(option.value);
13703
+ return text.toLowerCase().includes(input.toLowerCase());
13704
+ }
13705
+ function isOptionSelected(option, selectedValue, selectedValues) {
13706
+ if (selectedValues?.length) {
13707
+ return selectedValues.some((item) => item.value === option.value);
13708
+ }
13709
+ return selectedValue?.value === option.value;
13710
+ }
13711
+
13712
+ // src/dashboard/_select-internals/SelectMenu.tsx
13713
+ import { jsx as jsx154, jsxs as jsxs98 } from "react/jsx-runtime";
13714
+ function SelectMenu({
13715
+ id,
13716
+ options,
13717
+ labelledBy,
13718
+ describedBy,
13719
+ selectedValue,
13720
+ selectedValues,
13721
+ highlightedIndex,
13722
+ onOptionClick,
13723
+ onOptionHover,
13724
+ onKeyDown,
13725
+ disabled,
13726
+ menuClassName,
13727
+ listRef,
13728
+ selectedOptionRef,
13729
+ getOptionId: getOptionId2,
13730
+ noOptionsMessage,
13731
+ isMulti,
13732
+ emptyContent,
13733
+ footer
13734
+ }) {
13735
+ const emptyMessage = noOptionsMessage?.();
13736
+ const hasOptions = options.length > 0;
13737
+ return /* @__PURE__ */ jsxs98(
13738
+ "div",
13739
+ {
13740
+ id,
13741
+ ref: listRef,
13742
+ role: "listbox",
13743
+ tabIndex: -1,
13744
+ "aria-labelledby": labelledBy,
13745
+ "aria-describedby": describedBy,
13746
+ "aria-multiselectable": isMulti,
13747
+ "aria-activedescendant": highlightedIndex !== void 0 && highlightedIndex >= 0 ? getOptionId2(highlightedIndex) : void 0,
13748
+ onKeyDown,
13749
+ className: cn(
13750
+ "h-auto max-h-[322px] min-h-[75px] overflow-y-auto px-4 pb-[19px] pt-[17px] outline-none",
13751
+ menuClassName
13752
+ ),
13753
+ children: [
13754
+ !hasOptions && emptyMessage && /* @__PURE__ */ jsx154("div", { className: "mt-[10px] text-left text-[16px] text-[var(--chekin-color-brand-navy)]", children: emptyMessage }),
13755
+ !hasOptions && !emptyMessage && emptyContent,
13756
+ options.map((option, index) => {
13757
+ const isSelected = isOptionSelected(option, selectedValue, selectedValues);
13758
+ const isHighlighted = index === highlightedIndex;
13759
+ const optionKey = `${String(option.value)}-${index}`;
13760
+ const isOptionDisabled = Boolean(disabled || option.isDisabled);
13761
+ return /* @__PURE__ */ jsxs98(
13762
+ "button",
13763
+ {
13764
+ id: getOptionId2(index),
13765
+ ref: (node) => {
13766
+ selectedOptionRef?.(index, node);
13767
+ },
13768
+ type: "button",
13769
+ role: "option",
13770
+ "aria-selected": isSelected,
13771
+ "aria-disabled": isOptionDisabled,
13772
+ tabIndex: -1,
13773
+ disabled: isOptionDisabled,
13774
+ onClick: () => onOptionClick(option),
13775
+ onMouseMove: () => onOptionHover?.(index),
13776
+ className: cn(
13777
+ "flex w-full items-start justify-between border-0 border-b border-[#f2f4f8] bg-white px-4 py-[20px] text-left text-[16px] font-medium leading-5 text-[var(--chekin-color-brand-navy)] outline-none transition-colors",
13778
+ "last:border-b-transparent",
13779
+ isHighlighted && !isSelected && "cursor-pointer text-[var(--chekin-color-brand-blue)]",
13780
+ isSelected && "cursor-default font-bold text-[var(--chekin-color-brand-navy)]",
13781
+ isOptionDisabled && "cursor-default opacity-30"
13782
+ ),
13783
+ children: [
13784
+ /* @__PURE__ */ jsx154("span", { className: "block break-words", children: option.label }),
13785
+ option.description && /* @__PURE__ */ jsx154("span", { className: "ml-2 mt-[3px] shrink-0 text-[12px] font-bold italic text-[#777e91]", children: option.description })
13786
+ ]
13787
+ },
13788
+ optionKey
13789
+ );
13790
+ }),
13791
+ footer
13792
+ ]
13793
+ }
13794
+ );
13795
+ }
13796
+
13797
+ // src/dashboard/_select-internals/useSelectIds.ts
13798
+ import * as React54 from "react";
13799
+ function useSelectIds2({
13800
+ name,
13801
+ hasValue,
13802
+ error,
13803
+ hideErrorMessage
13804
+ }) {
13805
+ const reactId = React54.useId().replace(/:/g, "");
13806
+ const baseId = name ? `dash-select-${name}` : `dash-select-${reactId}`;
13807
+ const triggerId = `${baseId}-trigger`;
13808
+ const labelId = `${baseId}-label`;
13809
+ const valueId = `${baseId}-value`;
13810
+ const helperTextId = `${baseId}-helper`;
13811
+ const errorId = `${baseId}-error`;
13812
+ const listboxId = `${baseId}-listbox`;
13813
+ const describedErrorId = error && !hideErrorMessage ? errorId : void 0;
13814
+ const describedBy = [!hasValue ? helperTextId : null, describedErrorId].filter(Boolean).join(" ") || void 0;
13815
+ const getOptionId2 = React54.useCallback(
13816
+ (index) => `${baseId}-option-${index}`,
13817
+ [baseId]
13818
+ );
13819
+ return {
13820
+ triggerId,
13821
+ labelId,
13822
+ valueId,
13823
+ helperTextId,
13824
+ errorId,
13825
+ describedErrorId,
13826
+ listboxId,
13827
+ describedBy,
13828
+ getOptionId: getOptionId2
13829
+ };
13830
+ }
13831
+
13832
+ // src/dashboard/select/Select.tsx
13833
+ import { jsx as jsx155, jsxs as jsxs99 } from "react/jsx-runtime";
13834
+ function DashboardSelectInternal({
13835
+ options = [],
13836
+ value,
13837
+ onChange,
13838
+ onBlur,
13839
+ label,
13840
+ topLabel,
13841
+ placeholder,
13842
+ getValueLabel,
13843
+ disabled,
13844
+ loading,
13845
+ optional,
13846
+ tooltip,
13847
+ error,
13848
+ invalid,
13849
+ hideErrorMessage,
13850
+ className,
13851
+ menuClassName,
13852
+ dropdownClassName,
13853
+ name,
13854
+ width,
13855
+ noOptionsMessage,
13856
+ searchable = true,
13857
+ searchPlaceholder,
13858
+ filterOption = defaultFilterOption,
13859
+ helperText
13860
+ }, ref) {
13861
+ const containerRef = React55.useRef(null);
13862
+ const triggerRef = React55.useRef(null);
13863
+ const searchInputRef = React55.useRef(null);
13864
+ const listRef = React55.useRef(null);
13865
+ const optionRefs = React55.useRef([]);
13866
+ const [isOpen, setIsOpen] = React55.useState(false);
13867
+ const [searchValue, setSearchValue] = React55.useState("");
13868
+ const [highlightedIndex, setHighlightedIndex] = React55.useState(-1);
13869
+ const hasValue = Boolean(value);
13870
+ const isEmpty = !hasValue;
13871
+ const isBlocked = Boolean(disabled) || Boolean(loading);
13872
+ const triggerError = error ?? invalid;
13873
+ const hasInvalidState = Boolean(triggerError);
13874
+ const errorMessage = typeof error === "string" ? error : void 0;
13875
+ const wrapperWidth = toCssSize(width);
13876
+ const valueLabel = value ? getValueLabel?.(value) ?? String(value.label) : void 0;
13877
+ const { triggerId, labelId, valueId, listboxId, describedErrorId, errorId, getOptionId: getOptionId2 } = useSelectIds2({ name, hasValue, error, hideErrorMessage });
13878
+ const filteredOptions = React55.useMemo(() => {
13879
+ if (!searchable || !searchValue) return options;
13880
+ return options.filter((option) => filterOption(option, searchValue));
13881
+ }, [options, searchable, searchValue, filterOption]);
13882
+ React55.useImperativeHandle(ref, () => triggerRef.current, []);
13883
+ useOutsideClick({
13884
+ elementRef: containerRef,
13885
+ onOutsideClick: () => setIsOpen(false),
13886
+ isDisabled: !isOpen
13887
+ });
13888
+ React55.useEffect(() => {
13889
+ if (isBlocked) setIsOpen(false);
13890
+ }, [isBlocked]);
13891
+ React55.useEffect(() => {
13892
+ if (!isOpen) {
13893
+ setSearchValue("");
13894
+ setHighlightedIndex(-1);
13895
+ return;
13896
+ }
13897
+ const selectedIndex = getOptionIndex2(filteredOptions, value);
13898
+ setHighlightedIndex(
13899
+ selectedIndex >= 0 ? selectedIndex : getFirstEnabledOptionIndex2(filteredOptions)
13900
+ );
13901
+ if (searchable) {
13902
+ const frame = window.requestAnimationFrame(() => searchInputRef.current?.focus());
13903
+ return () => window.cancelAnimationFrame(frame);
13904
+ }
13905
+ }, [isOpen, filteredOptions, searchable, value]);
13906
+ React55.useEffect(() => {
13907
+ if (!isOpen || highlightedIndex < 0) return;
13908
+ optionRefs.current[highlightedIndex]?.scrollIntoView({ block: "nearest" });
13909
+ }, [highlightedIndex, isOpen]);
13910
+ React55.useEffect(
13911
+ function setCorrectOptionIfThereIsOnlyValue() {
13912
+ if (value?.value === void 0 || value.value === null || value.label !== "")
13913
+ return;
13914
+ const validOption = options.find((option) => option.value === value.value);
13915
+ if (validOption) onChange(validOption);
13916
+ },
13917
+ [onChange, options, value]
13918
+ );
13919
+ const toggleMenu = () => {
13920
+ if (isBlocked) return;
13921
+ setIsOpen((prev) => !prev);
13922
+ };
13923
+ const handleSelect = (option) => {
13924
+ if (option.isDisabled) return;
13925
+ onChange(option);
13926
+ setIsOpen(false);
13927
+ triggerRef.current?.focus();
13928
+ };
13929
+ const handleTriggerKeyDown = (event) => {
13930
+ if (isBlocked) return;
13931
+ if (event.key === "ArrowDown" || event.key === "ArrowUp" || event.key === "Enter" || event.key === " ") {
13932
+ event.preventDefault();
13933
+ setIsOpen(true);
13934
+ }
13935
+ };
13936
+ const handleSearchKeyDown = (event) => {
13937
+ if (event.key === "ArrowDown") {
13938
+ event.preventDefault();
13939
+ const next = getNextEnabledOptionIndex2(filteredOptions, highlightedIndex + 1, 1);
13940
+ if (next >= 0) setHighlightedIndex(next);
13941
+ return;
13942
+ }
13943
+ if (event.key === "ArrowUp") {
13944
+ event.preventDefault();
13945
+ const next = getNextEnabledOptionIndex2(filteredOptions, highlightedIndex - 1, -1);
13946
+ if (next >= 0) setHighlightedIndex(next);
13947
+ return;
13948
+ }
13949
+ if (event.key === "Enter") {
13950
+ event.preventDefault();
13951
+ const option = filteredOptions[highlightedIndex];
13952
+ if (option && !option.isDisabled) handleSelect(option);
13953
+ return;
13954
+ }
13955
+ if (event.key === "Escape") {
13956
+ event.preventDefault();
13957
+ setIsOpen(false);
13958
+ triggerRef.current?.focus();
13959
+ return;
13960
+ }
13961
+ if (event.key === "Tab") {
13962
+ setIsOpen(false);
13963
+ }
13964
+ };
13965
+ return /* @__PURE__ */ jsxs99(
13966
+ "div",
13967
+ {
13968
+ ref: containerRef,
13969
+ className: cn(
13970
+ "relative w-full max-w-[var(--max-field-width)]",
13971
+ disabled && "cursor-not-allowed opacity-50",
13972
+ loading && "cursor-progress",
13973
+ className
13974
+ ),
13975
+ style: wrapperWidth ? { width: wrapperWidth } : void 0,
13976
+ children: [
13977
+ name && /* @__PURE__ */ jsx155("input", { type: "hidden", name, value: value ? String(value.value) : "" }),
13978
+ /* @__PURE__ */ jsxs99("div", { className: "relative w-full min-h-[68px]", children: [
13979
+ topLabel && /* @__PURE__ */ jsx155(
13980
+ "label",
13981
+ {
13982
+ htmlFor: triggerId,
13983
+ className: "mb-2 block text-[14px] font-medium text-[var(--chekin-color-brand-navy)]",
13984
+ children: topLabel
13985
+ }
13986
+ ),
13987
+ /* @__PURE__ */ jsxs99("div", { className: "relative w-full", children: [
13988
+ /* @__PURE__ */ jsxs99(
13989
+ "button",
13990
+ {
13991
+ id: triggerId,
13992
+ ref: triggerRef,
13993
+ type: "button",
13994
+ "aria-haspopup": "listbox",
13995
+ "aria-expanded": isOpen,
13996
+ "aria-controls": listboxId,
13997
+ "aria-labelledby": hasValue && valueId ? `${labelId} ${valueId}` : labelId,
13998
+ "aria-describedby": describedErrorId,
13999
+ "aria-invalid": hasInvalidState,
14000
+ "aria-busy": loading,
14001
+ disabled: isBlocked,
14002
+ onClick: toggleMenu,
14003
+ onKeyDown: handleTriggerKeyDown,
14004
+ onBlur,
14005
+ className: cn(
14006
+ "relative m-0 box-border flex h-12 w-full cursor-pointer items-center justify-between gap-2 rounded-[6px] border-0 px-4 text-left text-[16px] font-medium leading-5 outline-none transition-colors duration-200",
14007
+ isEmpty ? "bg-[var(--chekin-color-surface-input-empty)] text-[var(--chekin-color-gray-1)]" : "bg-transparent text-[var(--chekin-color-brand-navy)]",
14008
+ disabled && "cursor-not-allowed opacity-50",
14009
+ loading && "cursor-progress"
14010
+ ),
14011
+ children: [
14012
+ /* @__PURE__ */ jsx155("span", { id: valueId, className: "block min-w-0 flex-1 truncate text-left", children: valueLabel ?? placeholder ?? label }),
14013
+ /* @__PURE__ */ jsxs99("span", { className: "pointer-events-none flex items-center gap-2 text-[var(--chekin-color-gray-2)]", children: [
14014
+ loading && /* @__PURE__ */ jsx155(ThreeDotsLoader, { height: 18, width: 18 }),
14015
+ /* @__PURE__ */ jsx155(
14016
+ ChevronDown4,
14017
+ {
14018
+ size: 16,
14019
+ className: cn(
14020
+ "transition-transform duration-200",
14021
+ isOpen && "rotate-180 text-[var(--chekin-color-brand-blue)]"
14022
+ )
14023
+ }
14024
+ )
14025
+ ] })
14026
+ ]
14027
+ }
14028
+ ),
14029
+ /* @__PURE__ */ jsx155(
14030
+ Fieldset,
14031
+ {
14032
+ isFocused: isOpen,
14033
+ invalid: hasInvalidState,
14034
+ isEmpty,
14035
+ isActivated: !isEmpty || isOpen,
14036
+ disabled,
14037
+ loading,
14038
+ htmlFor: triggerId,
14039
+ labelId,
14040
+ legend: typeof label === "string" ? label : void 0,
14041
+ label,
14042
+ tooltip,
14043
+ onClick: !isBlocked ? toggleMenu : void 0
14044
+ }
14045
+ ),
14046
+ isOpen && /* @__PURE__ */ jsxs99(
14047
+ "div",
14048
+ {
14049
+ className: cn(
14050
+ "absolute left-0 right-0 top-full z-20 overflow-hidden rounded-b-lg bg-white shadow-[0_30px_30px_0_rgba(33,72,255,0.2)]",
14051
+ dropdownClassName
14052
+ ),
14053
+ children: [
14054
+ searchable && /* @__PURE__ */ jsx155("div", { className: "border-b border-[#f2f4f8] px-4 pb-2 pt-3", children: /* @__PURE__ */ jsx155(
14055
+ "input",
14056
+ {
14057
+ ref: searchInputRef,
14058
+ type: "text",
14059
+ value: searchValue,
14060
+ placeholder: searchPlaceholder,
14061
+ onChange: (event) => setSearchValue(event.target.value),
14062
+ onKeyDown: handleSearchKeyDown,
14063
+ autoComplete: "off",
14064
+ "aria-controls": listboxId,
14065
+ "aria-activedescendant": highlightedIndex >= 0 ? getOptionId2(highlightedIndex) : void 0,
14066
+ className: "m-0 box-border h-9 w-full rounded-md border border-[var(--chekin-color-gray-3)] bg-white px-3 text-[16px] font-medium text-[var(--chekin-color-brand-navy)] outline-none transition-colors placeholder:text-[var(--chekin-color-gray-1)] focus:border-[var(--chekin-color-brand-blue)]"
14067
+ }
14068
+ ) }),
14069
+ /* @__PURE__ */ jsx155(
14070
+ SelectMenu,
14071
+ {
14072
+ id: listboxId,
14073
+ options: filteredOptions,
14074
+ labelledBy: labelId,
14075
+ describedBy: describedErrorId,
14076
+ selectedValue: value,
14077
+ highlightedIndex,
14078
+ onOptionClick: handleSelect,
14079
+ onOptionHover: setHighlightedIndex,
14080
+ disabled: isBlocked,
14081
+ menuClassName,
14082
+ listRef,
14083
+ selectedOptionRef: (index, node) => {
14084
+ optionRefs.current[index] = node;
14085
+ },
14086
+ getOptionId: getOptionId2,
14087
+ noOptionsMessage
14088
+ }
14089
+ )
14090
+ ]
14091
+ }
14092
+ )
14093
+ ] }),
14094
+ !errorMessage && optional && /* @__PURE__ */ jsx155("span", { className: "mt-[1px] block text-left text-[14px] font-medium text-[var(--chekin-color-gray-1)]", children: typeof optional === "string" ? optional : "optional" }),
14095
+ !errorMessage && helperText && /* @__PURE__ */ jsx155("span", { className: "mt-[1px] block text-[12px] font-normal text-[var(--chekin-color-gray-1)]", children: helperText }),
14096
+ errorMessage && !hideErrorMessage && /* @__PURE__ */ jsx155(
14097
+ FieldErrorMessage,
14098
+ {
14099
+ id: errorId,
14100
+ message: errorMessage,
14101
+ className: "mt-[1px] text-[14px]"
14102
+ }
14103
+ )
14104
+ ] })
14105
+ ]
14106
+ }
14107
+ );
14108
+ }
14109
+ var DashboardSelect = React55.forwardRef(
14110
+ DashboardSelectInternal
14111
+ );
14112
+
14113
+ // src/dashboard/multi-select/MultiSelect.tsx
14114
+ import * as React56 from "react";
14115
+ import { SquareX as SquareX2 } from "lucide-react";
14116
+ import { jsx as jsx156, jsxs as jsxs100 } from "react/jsx-runtime";
14117
+ var isValueSelected = (selected, option) => selected.some((item) => item.value === option.value);
14118
+ function DashboardMultiSelectInternal({
14119
+ options = [],
14120
+ value,
14121
+ onChange,
14122
+ onBlur,
14123
+ label,
14124
+ topLabel,
14125
+ placeholder,
14126
+ disabled,
14127
+ readOnly,
14128
+ loading,
14129
+ optional,
14130
+ tooltip,
14131
+ error,
14132
+ invalid,
14133
+ hideErrorMessage,
14134
+ className,
14135
+ menuClassName,
14136
+ dropdownClassName,
14137
+ name,
14138
+ width,
14139
+ noOptionsMessage,
14140
+ filterOption = defaultFilterOption,
14141
+ closeMenuOnSelect = false,
14142
+ renderChip,
14143
+ helperText,
14144
+ isCreatable = false,
14145
+ onCreateOption,
14146
+ formatCreateLabel = (input) => `Create "${input}"`,
14147
+ isValidNewOption
14148
+ }, ref) {
14149
+ const containerRef = React56.useRef(null);
14150
+ const inputRef = React56.useRef(null);
14151
+ const listRef = React56.useRef(null);
14152
+ const optionRefs = React56.useRef([]);
14153
+ const [isOpen, setIsOpen] = React56.useState(false);
14154
+ const [searchValue, setSearchValue] = React56.useState("");
14155
+ const [isFocused, setIsFocused] = React56.useState(false);
14156
+ const [highlightedIndex, setHighlightedIndex] = React56.useState(-1);
14157
+ const selectedValues = React56.useMemo(() => value ?? [], [value]);
14158
+ const hasValue = selectedValues.length > 0;
14159
+ const isEmpty = !hasValue;
14160
+ const isBlocked = Boolean(disabled) || Boolean(loading) || Boolean(readOnly);
14161
+ const triggerError = error ?? invalid;
14162
+ const hasInvalidState = Boolean(triggerError);
14163
+ const errorMessage = typeof error === "string" ? error : void 0;
14164
+ const wrapperWidth = toCssSize(width);
14165
+ const { triggerId, labelId, valueId, listboxId, describedErrorId, errorId, getOptionId: getOptionId2 } = useSelectIds2({ name, hasValue, error, hideErrorMessage });
14166
+ const filteredOptions = React56.useMemo(
14167
+ () => options.filter((option) => filterOption(option, searchValue)),
14168
+ [options, searchValue, filterOption]
14169
+ );
14170
+ const trimmedSearch = searchValue.trim();
14171
+ const canCreateNewOption = React56.useMemo(() => {
14172
+ if (!isCreatable || !trimmedSearch) return false;
14173
+ if (isValidNewOption) return isValidNewOption(trimmedSearch, selectedValues, options);
14174
+ const lower = trimmedSearch.toLowerCase();
14175
+ const existsInOptions = options.some(
14176
+ (option) => typeof option.label === "string" && option.label.toLowerCase() === lower
14177
+ );
14178
+ const existsInSelected = selectedValues.some(
14179
+ (option) => typeof option.label === "string" && option.label.toLowerCase() === lower
14180
+ );
14181
+ return !existsInOptions && !existsInSelected;
14182
+ }, [isCreatable, trimmedSearch, isValidNewOption, options, selectedValues]);
14183
+ React56.useImperativeHandle(
14184
+ ref,
14185
+ () => containerRef.current
14186
+ );
14187
+ useOutsideClick({
14188
+ elementRef: containerRef,
14189
+ onOutsideClick: () => {
14190
+ setIsOpen(false);
14191
+ setIsFocused(false);
14192
+ },
14193
+ isDisabled: !isOpen
14194
+ });
14195
+ React56.useEffect(() => {
14196
+ if (isBlocked) setIsOpen(false);
14197
+ }, [isBlocked]);
14198
+ React56.useEffect(() => {
14199
+ if (!isOpen) {
14200
+ setSearchValue("");
14201
+ setHighlightedIndex(-1);
14202
+ }
14203
+ }, [isOpen]);
14204
+ React56.useEffect(() => {
14205
+ if (!isOpen || filteredOptions.length === 0) {
14206
+ setHighlightedIndex(-1);
14207
+ return;
14208
+ }
14209
+ setHighlightedIndex((current) => {
14210
+ if (current >= 0 && current < filteredOptions.length) return current;
14211
+ return getFirstEnabledOptionIndex2(filteredOptions);
14212
+ });
14213
+ }, [isOpen, filteredOptions]);
14214
+ const openMenu = () => {
14215
+ if (isBlocked) return;
14216
+ setIsOpen(true);
14217
+ setIsFocused(true);
14218
+ };
14219
+ const toggleOption = (option) => {
14220
+ if (option.isDisabled) return;
14221
+ const exists = isValueSelected(selectedValues, option);
14222
+ const next = exists ? selectedValues.filter((item) => item.value !== option.value) : [...selectedValues, option];
14223
+ onChange(next);
14224
+ setSearchValue("");
14225
+ if (closeMenuOnSelect) {
14226
+ setIsOpen(false);
14227
+ } else {
14228
+ inputRef.current?.focus();
14229
+ }
14230
+ };
14231
+ const removeOption = (option) => {
14232
+ if (isBlocked) return;
14233
+ onChange(selectedValues.filter((item) => item.value !== option.value));
14234
+ inputRef.current?.focus();
14235
+ };
14236
+ const clearAll = () => {
14237
+ if (isBlocked) return;
14238
+ onChange([]);
14239
+ inputRef.current?.focus();
14240
+ };
14241
+ const createOption = React56.useCallback(() => {
14242
+ if (!canCreateNewOption) return;
14243
+ const newOption = onCreateOption?.(trimmedSearch) ?? { value: trimmedSearch, label: trimmedSearch };
14244
+ onChange([...selectedValues, newOption]);
14245
+ setSearchValue("");
14246
+ inputRef.current?.focus();
14247
+ if (closeMenuOnSelect) setIsOpen(false);
14248
+ }, [
14249
+ canCreateNewOption,
14250
+ closeMenuOnSelect,
14251
+ onChange,
14252
+ onCreateOption,
14253
+ selectedValues,
14254
+ trimmedSearch
14255
+ ]);
14256
+ const handleInputKeyDown = (event) => {
14257
+ if (event.key === "Backspace" && !searchValue && selectedValues.length > 0) {
14258
+ event.preventDefault();
14259
+ onChange(selectedValues.slice(0, -1));
14260
+ return;
14261
+ }
14262
+ if (event.key === "ArrowDown") {
14263
+ event.preventDefault();
14264
+ if (!isOpen) {
14265
+ openMenu();
14266
+ return;
14267
+ }
14268
+ const next = getNextEnabledOptionIndex2(filteredOptions, highlightedIndex + 1, 1);
14269
+ if (next >= 0) setHighlightedIndex(next);
14270
+ return;
14271
+ }
14272
+ if (event.key === "ArrowUp") {
14273
+ event.preventDefault();
14274
+ if (!isOpen) {
14275
+ openMenu();
14276
+ return;
14277
+ }
14278
+ const next = getNextEnabledOptionIndex2(filteredOptions, highlightedIndex - 1, -1);
14279
+ if (next >= 0) setHighlightedIndex(next);
14280
+ return;
14281
+ }
14282
+ if (event.key === "Enter") {
14283
+ if (!isOpen) return;
14284
+ event.preventDefault();
14285
+ const option = filteredOptions[highlightedIndex];
14286
+ if (option && !option.isDisabled) {
14287
+ toggleOption(option);
14288
+ } else if (canCreateNewOption) {
14289
+ createOption();
14290
+ }
14291
+ return;
14292
+ }
14293
+ if (event.key === "Escape") {
14294
+ event.preventDefault();
14295
+ setIsOpen(false);
14296
+ }
14297
+ };
14298
+ const handleContainerClick = () => {
14299
+ if (isBlocked) return;
14300
+ inputRef.current?.focus();
14301
+ setIsOpen(true);
14302
+ };
14303
+ const handleInputBlur = (event) => {
14304
+ if (containerRef.current?.contains(event.relatedTarget)) return;
14305
+ setIsFocused(false);
14306
+ onBlur?.(event);
14307
+ };
14308
+ return /* @__PURE__ */ jsxs100(
14309
+ "div",
14310
+ {
14311
+ ref: containerRef,
14312
+ onBlur: handleInputBlur,
14313
+ className: cn(
14314
+ "relative min-h-[68px] w-full max-w-[var(--max-field-width)]",
14315
+ disabled && "cursor-not-allowed opacity-50",
14316
+ loading && "cursor-progress",
14317
+ className
14318
+ ),
14319
+ style: wrapperWidth ? { width: wrapperWidth } : void 0,
14320
+ children: [
14321
+ topLabel && /* @__PURE__ */ jsx156(
14322
+ "label",
14323
+ {
14324
+ htmlFor: triggerId,
14325
+ className: "mb-2 block text-[14px] font-medium text-[var(--chekin-color-brand-navy)]",
14326
+ children: topLabel
14327
+ }
14328
+ ),
14329
+ name && /* @__PURE__ */ jsx156(
14330
+ "input",
14331
+ {
14332
+ type: "hidden",
14333
+ name,
14334
+ value: selectedValues.map((item) => String(item.value)).join(",")
14335
+ }
14336
+ ),
14337
+ /* @__PURE__ */ jsxs100("div", { className: "relative w-full", children: [
14338
+ /* @__PURE__ */ jsxs100(
14339
+ "div",
14340
+ {
14341
+ id: triggerId,
14342
+ role: "combobox",
14343
+ "aria-haspopup": "listbox",
14344
+ "aria-expanded": isOpen,
14345
+ "aria-controls": listboxId,
14346
+ "aria-labelledby": hasValue && valueId ? `${labelId} ${valueId}` : labelId,
14347
+ "aria-describedby": describedErrorId,
14348
+ "aria-invalid": hasInvalidState,
14349
+ "aria-busy": loading,
14350
+ "aria-disabled": isBlocked,
14351
+ onClick: handleContainerClick,
14352
+ className: cn(
14353
+ "relative box-border flex w-full cursor-text flex-wrap items-center gap-2 rounded-[6px] border-0 px-4 py-[10px] text-left text-[16px] font-medium leading-5 outline-none transition-colors duration-200",
14354
+ "min-h-12",
14355
+ isEmpty && !isFocused ? "bg-[var(--chekin-color-surface-input-empty)]" : "bg-transparent",
14356
+ disabled && "cursor-not-allowed",
14357
+ loading && "cursor-progress"
14358
+ ),
14359
+ children: [
14360
+ selectedValues.map(
14361
+ (option) => renderChip ? /* @__PURE__ */ jsx156(React56.Fragment, { children: renderChip(option, () => removeOption(option)) }, String(option.value)) : /* @__PURE__ */ jsxs100(
14362
+ "span",
14363
+ {
14364
+ className: "inline-flex items-center gap-2 rounded-[4px] border border-[#acacd5] bg-[#f0f0f8] py-[2px] pl-[10px] pr-1 text-[12px] font-medium text-[var(--chekin-color-brand-navy)]",
14365
+ children: [
14366
+ /* @__PURE__ */ jsx156("span", { className: "whitespace-nowrap", children: option.label }),
14367
+ !readOnly && /* @__PURE__ */ jsx156(
14368
+ "button",
14369
+ {
14370
+ type: "button",
14371
+ onClick: (event) => {
14372
+ event.stopPropagation();
14373
+ removeOption(option);
14374
+ },
14375
+ className: "flex h-[15px] w-[15px] items-center justify-center rounded-[3px] border-0 bg-transparent p-0 text-[#9696b9] hover:shadow-[0_3px_3px_#0f477734]",
14376
+ "aria-label": `Remove ${typeof option.label === "string" ? option.label : String(option.value)}`,
14377
+ children: /* @__PURE__ */ jsx156(SquareX2, { size: 15, fill: "#9696b9", color: "#f8f8f8", strokeWidth: 1.8 })
14378
+ }
14379
+ )
14380
+ ]
14381
+ },
14382
+ String(option.value)
14383
+ )
14384
+ ),
14385
+ /* @__PURE__ */ jsx156(
14386
+ "input",
14387
+ {
14388
+ ref: inputRef,
14389
+ type: "text",
14390
+ id: `${triggerId}-input`,
14391
+ value: searchValue,
14392
+ onChange: (event) => {
14393
+ setSearchValue(event.target.value);
14394
+ if (!isOpen) setIsOpen(true);
14395
+ },
14396
+ onFocus: () => {
14397
+ setIsFocused(true);
14398
+ if (!isBlocked) setIsOpen(true);
14399
+ },
14400
+ onKeyDown: handleInputKeyDown,
14401
+ disabled: isBlocked,
14402
+ readOnly,
14403
+ placeholder: hasValue ? "" : placeholder ?? "",
14404
+ autoComplete: "off",
14405
+ className: cn(
14406
+ "m-0 box-border min-w-[40px] flex-1 border-0 bg-transparent p-0 text-[16px] font-medium leading-5 text-[var(--chekin-color-brand-navy)] outline-none placeholder:text-[var(--chekin-color-gray-1)]",
14407
+ isBlocked && "cursor-not-allowed"
14408
+ ),
14409
+ "aria-autocomplete": "list",
14410
+ "aria-controls": listboxId,
14411
+ "aria-activedescendant": isOpen && highlightedIndex >= 0 ? getOptionId2(highlightedIndex) : void 0
14412
+ }
14413
+ ),
14414
+ /* @__PURE__ */ jsxs100("span", { className: "ml-auto flex items-center gap-2 pl-2 text-[var(--chekin-color-gray-2)]", children: [
14415
+ loading && /* @__PURE__ */ jsx156(ThreeDotsLoader, { height: 18, width: 18 }),
14416
+ hasValue && !readOnly && /* @__PURE__ */ jsx156(
14417
+ "button",
14418
+ {
14419
+ type: "button",
14420
+ onClick: (event) => {
14421
+ event.stopPropagation();
14422
+ clearAll();
14423
+ },
14424
+ className: "flex h-5 w-5 items-center justify-center rounded-[3px] border-0 bg-transparent p-0 text-[#9696b9] hover:shadow-[0_3px_3px_#0f477734]",
14425
+ "aria-label": "Clear all",
14426
+ children: /* @__PURE__ */ jsx156(SquareX2, { size: 15, fill: "#9696b9", color: "#f8f8f8", strokeWidth: 1.8 })
14427
+ }
14428
+ ),
14429
+ /* @__PURE__ */ jsx156(
14430
+ RotateArrow,
14431
+ {
14432
+ shouldRotate: isOpen,
14433
+ className: cn(
14434
+ isFocused || isOpen ? "text-[var(--chekin-color-brand-blue)]" : "text-[var(--chekin-color-gray-2)]"
14435
+ )
14436
+ }
14437
+ )
14438
+ ] })
14439
+ ]
14440
+ }
14441
+ ),
14442
+ /* @__PURE__ */ jsx156(
14443
+ Fieldset,
14444
+ {
14445
+ isFocused: isFocused || isOpen,
14446
+ invalid: hasInvalidState,
14447
+ isEmpty: isEmpty && !searchValue,
14448
+ isActivated: !isEmpty || isFocused || isOpen || Boolean(searchValue),
14449
+ disabled,
14450
+ loading,
14451
+ readOnly,
14452
+ htmlFor: `${triggerId}-input`,
14453
+ labelId,
14454
+ legend: typeof label === "string" ? label : void 0,
14455
+ label,
14456
+ tooltip,
14457
+ onClick: handleContainerClick
14458
+ }
14459
+ ),
14460
+ isOpen && /* @__PURE__ */ jsxs100(
14461
+ "div",
14462
+ {
14463
+ className: cn(
14464
+ "absolute left-0 right-0 top-full z-20 overflow-hidden rounded-b-lg bg-white shadow-[0_30px_30px_0_rgba(33,72,255,0.2)]",
14465
+ dropdownClassName
14466
+ ),
14467
+ children: [
14468
+ /* @__PURE__ */ jsx156(
14469
+ SelectMenu,
14470
+ {
14471
+ id: listboxId,
14472
+ options: filteredOptions,
14473
+ labelledBy: labelId,
14474
+ describedBy: describedErrorId,
14475
+ selectedValues,
14476
+ highlightedIndex,
14477
+ onOptionClick: toggleOption,
14478
+ onOptionHover: setHighlightedIndex,
14479
+ disabled: isBlocked,
14480
+ menuClassName,
14481
+ listRef,
14482
+ selectedOptionRef: (index, node) => {
14483
+ optionRefs.current[index] = node;
14484
+ },
14485
+ getOptionId: getOptionId2,
14486
+ noOptionsMessage,
14487
+ isMulti: true
14488
+ }
14489
+ ),
14490
+ canCreateNewOption && /* @__PURE__ */ jsx156(
14491
+ "button",
14492
+ {
14493
+ type: "button",
14494
+ onClick: createOption,
14495
+ className: "flex w-full items-center justify-start border-0 border-t border-[#f2f4f8] bg-white px-4 py-[16px] text-left text-[16px] font-medium leading-5 text-[var(--chekin-color-brand-blue)] outline-none hover:bg-[var(--chekin-color-surface-pressed)]",
14496
+ children: formatCreateLabel(trimmedSearch)
14497
+ }
14498
+ )
14499
+ ]
14500
+ }
14501
+ )
14502
+ ] }),
14503
+ !errorMessage && optional && /* @__PURE__ */ jsx156("span", { className: "mt-[1px] block text-left text-[14px] font-medium text-[var(--chekin-color-gray-1)]", children: typeof optional === "string" ? optional : "optional" }),
14504
+ !errorMessage && helperText && /* @__PURE__ */ jsx156("span", { className: "mt-[1px] block text-[12px] font-normal text-[var(--chekin-color-gray-1)]", children: helperText }),
14505
+ errorMessage && !hideErrorMessage && /* @__PURE__ */ jsx156(
14506
+ FieldErrorMessage,
14507
+ {
14508
+ id: errorId,
14509
+ message: errorMessage,
14510
+ className: "mt-[1px] text-[14px]"
14511
+ }
14512
+ )
14513
+ ]
14514
+ }
14515
+ );
14516
+ }
14517
+ var DashboardMultiSelect = React56.forwardRef(
14518
+ DashboardMultiSelectInternal
14519
+ );
14520
+
14521
+ // src/dashboard/creatable-multi-select/CreatableMultiSelect.tsx
14522
+ import * as React57 from "react";
14523
+ import { jsx as jsx157 } from "react/jsx-runtime";
14524
+ var DashboardCreatableMultiSelect = React57.forwardRef(
14525
+ function DashboardCreatableMultiSelect2(props, ref) {
14526
+ return /* @__PURE__ */ jsx157(DashboardMultiSelect, { ref, ...props, isCreatable: true });
14527
+ }
14528
+ );
14529
+
14530
+ // src/dashboard/infinite-scroll-select/InfiniteScrollSelect.tsx
14531
+ import * as React58 from "react";
14532
+ import { ChevronDown as ChevronDown5 } from "lucide-react";
14533
+ import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
14534
+ import { jsx as jsx158, jsxs as jsxs101 } from "react/jsx-runtime";
14535
+ var DEFAULT_ITEM_HEIGHT = 60;
14536
+ var DEFAULT_LIST_HEIGHT = 322;
14537
+ var DEFAULT_OVERSCAN = 5;
14538
+ var DEFAULT_LOAD_MORE_THRESHOLD = 5;
14539
+ function DashboardInfiniteScrollSelectInternal({
14540
+ options = [],
14541
+ value,
14542
+ onChange,
14543
+ onBlur,
14544
+ label,
14545
+ topLabel,
14546
+ placeholder,
14547
+ getValueLabel,
14548
+ disabled,
14549
+ loading,
14550
+ optional,
14551
+ tooltip,
14552
+ error,
14553
+ invalid,
14554
+ hideErrorMessage,
14555
+ className,
14556
+ menuClassName,
14557
+ dropdownClassName,
14558
+ name,
14559
+ width,
14560
+ noOptionsMessage,
14561
+ searchable = true,
14562
+ searchPlaceholder,
14563
+ filterOption = defaultFilterOption,
14564
+ helperText,
14565
+ canLoadMore,
14566
+ isLoadingMore,
14567
+ loadMoreItems,
14568
+ loadingMoreText = "Loading\u2026",
14569
+ onSearchChange,
14570
+ itemHeight = DEFAULT_ITEM_HEIGHT,
14571
+ listHeight = DEFAULT_LIST_HEIGHT,
14572
+ overscan = DEFAULT_OVERSCAN,
14573
+ loadMoreThreshold = DEFAULT_LOAD_MORE_THRESHOLD
14574
+ }, ref) {
14575
+ const containerRef = React58.useRef(null);
14576
+ const triggerRef = React58.useRef(null);
14577
+ const searchInputRef = React58.useRef(null);
14578
+ const scrollRef = React58.useRef(null);
14579
+ const [isOpen, setIsOpen] = React58.useState(false);
14580
+ const [searchValue, setSearchValue] = React58.useState("");
14581
+ const [highlightedIndex, setHighlightedIndex] = React58.useState(-1);
14582
+ const hasValue = Boolean(value);
14583
+ const isEmpty = !hasValue;
14584
+ const isBlocked = Boolean(disabled) || Boolean(loading);
14585
+ const triggerError = error ?? invalid;
14586
+ const hasInvalidState = Boolean(triggerError);
14587
+ const errorMessage = typeof error === "string" ? error : void 0;
14588
+ const wrapperWidth = toCssSize(width);
14589
+ const valueLabel = value ? getValueLabel?.(value) ?? String(value.label) : void 0;
14590
+ const { triggerId, labelId, valueId, listboxId, describedErrorId, errorId, getOptionId: getOptionId2 } = useSelectIds2({ name, hasValue, error, hideErrorMessage });
14591
+ const filteredOptions = React58.useMemo(() => {
14592
+ if (!searchable || !searchValue) return options;
14593
+ return options.filter((option) => filterOption(option, searchValue));
14594
+ }, [options, searchable, searchValue, filterOption]);
14595
+ const itemCount = filteredOptions.length + (canLoadMore || isLoadingMore ? 1 : 0);
14596
+ const virtualizer = useVirtualizer2({
14597
+ count: itemCount,
14598
+ getScrollElement: () => scrollRef.current,
14599
+ estimateSize: () => itemHeight,
14600
+ overscan
14601
+ });
14602
+ React58.useImperativeHandle(ref, () => triggerRef.current, []);
14603
+ useOutsideClick({
14604
+ elementRef: containerRef,
14605
+ onOutsideClick: () => setIsOpen(false),
14606
+ isDisabled: !isOpen
14607
+ });
14608
+ React58.useEffect(() => {
14609
+ if (isBlocked) setIsOpen(false);
14610
+ }, [isBlocked]);
14611
+ React58.useEffect(() => {
14612
+ if (!isOpen) {
14613
+ setSearchValue("");
14614
+ setHighlightedIndex(-1);
14615
+ return;
14616
+ }
14617
+ const selectedIndex = getOptionIndex2(filteredOptions, value);
14618
+ setHighlightedIndex(
14619
+ selectedIndex >= 0 ? selectedIndex : getFirstEnabledOptionIndex2(filteredOptions)
14620
+ );
14621
+ if (searchable) {
14622
+ const frame = window.requestAnimationFrame(() => searchInputRef.current?.focus());
14623
+ return () => window.cancelAnimationFrame(frame);
14624
+ }
14625
+ }, [isOpen, filteredOptions, searchable, value]);
14626
+ const virtualItems = virtualizer.getVirtualItems();
14627
+ React58.useEffect(() => {
14628
+ if (!isOpen || !canLoadMore || isLoadingMore || !loadMoreItems) return;
14629
+ if (virtualItems.length === 0) return;
14630
+ const lastItem = virtualItems[virtualItems.length - 1];
14631
+ if (lastItem && lastItem.index >= filteredOptions.length - loadMoreThreshold) {
14632
+ loadMoreItems();
14633
+ }
14634
+ }, [
14635
+ canLoadMore,
14636
+ filteredOptions.length,
14637
+ isLoadingMore,
14638
+ isOpen,
14639
+ loadMoreItems,
14640
+ loadMoreThreshold,
14641
+ virtualItems
14642
+ ]);
14643
+ React58.useEffect(() => {
14644
+ if (!isOpen || highlightedIndex < 0) return;
14645
+ virtualizer.scrollToIndex(highlightedIndex, { align: "auto" });
14646
+ }, [highlightedIndex, isOpen, virtualizer]);
14647
+ const toggleMenu = () => {
14648
+ if (isBlocked) return;
14649
+ setIsOpen((prev) => !prev);
14650
+ };
14651
+ const handleSelect = (option) => {
14652
+ if (option.isDisabled) return;
14653
+ onChange(option);
14654
+ setIsOpen(false);
14655
+ triggerRef.current?.focus();
14656
+ };
14657
+ const handleTriggerKeyDown = (event) => {
14658
+ if (isBlocked) return;
14659
+ if (event.key === "ArrowDown" || event.key === "ArrowUp" || event.key === "Enter" || event.key === " ") {
14660
+ event.preventDefault();
14661
+ setIsOpen(true);
14662
+ }
14663
+ };
14664
+ const handleSearchKeyDown = (event) => {
14665
+ if (event.key === "ArrowDown") {
14666
+ event.preventDefault();
14667
+ const next = getNextEnabledOptionIndex2(filteredOptions, highlightedIndex + 1, 1);
14668
+ if (next >= 0) setHighlightedIndex(next);
14669
+ return;
14670
+ }
14671
+ if (event.key === "ArrowUp") {
14672
+ event.preventDefault();
14673
+ const next = getNextEnabledOptionIndex2(filteredOptions, highlightedIndex - 1, -1);
14674
+ if (next >= 0) setHighlightedIndex(next);
14675
+ return;
14676
+ }
14677
+ if (event.key === "Enter") {
14678
+ event.preventDefault();
14679
+ const option = filteredOptions[highlightedIndex];
14680
+ if (option && !option.isDisabled) handleSelect(option);
14681
+ return;
14682
+ }
14683
+ if (event.key === "Escape") {
14684
+ event.preventDefault();
14685
+ setIsOpen(false);
14686
+ triggerRef.current?.focus();
14687
+ return;
14688
+ }
14689
+ if (event.key === "Tab") {
14690
+ setIsOpen(false);
14691
+ }
14692
+ };
14693
+ const handleSearchChange = (event) => {
14694
+ const next = event.target.value;
14695
+ setSearchValue(next);
14696
+ onSearchChange?.(next);
14697
+ };
14698
+ const emptyMessage = noOptionsMessage?.();
14699
+ const totalSize = virtualizer.getTotalSize();
14700
+ const measuredListHeight = Math.min(listHeight, Math.max(totalSize, itemHeight));
14701
+ return /* @__PURE__ */ jsxs101(
14702
+ "div",
14703
+ {
14704
+ ref: containerRef,
14705
+ className: cn(
14706
+ "relative w-full max-w-[var(--max-field-width)]",
14707
+ disabled && "cursor-not-allowed opacity-50",
14708
+ loading && "cursor-progress",
14709
+ className
14710
+ ),
14711
+ style: wrapperWidth ? { width: wrapperWidth } : void 0,
14712
+ children: [
14713
+ name && /* @__PURE__ */ jsx158("input", { type: "hidden", name, value: value ? String(value.value) : "" }),
14714
+ /* @__PURE__ */ jsxs101("div", { className: "relative min-h-[68px] w-full", children: [
14715
+ topLabel && /* @__PURE__ */ jsx158(
14716
+ "label",
14717
+ {
14718
+ htmlFor: triggerId,
14719
+ className: "mb-2 block text-[14px] font-medium text-[var(--chekin-color-brand-navy)]",
14720
+ children: topLabel
14721
+ }
14722
+ ),
14723
+ /* @__PURE__ */ jsxs101("div", { className: "relative w-full", children: [
14724
+ /* @__PURE__ */ jsxs101(
14725
+ "button",
14726
+ {
14727
+ id: triggerId,
14728
+ ref: triggerRef,
14729
+ type: "button",
14730
+ "aria-haspopup": "listbox",
14731
+ "aria-expanded": isOpen,
14732
+ "aria-controls": listboxId,
14733
+ "aria-labelledby": hasValue && valueId ? `${labelId} ${valueId}` : labelId,
14734
+ "aria-describedby": describedErrorId,
14735
+ "aria-invalid": hasInvalidState,
14736
+ "aria-busy": loading,
14737
+ disabled: isBlocked,
14738
+ onClick: toggleMenu,
14739
+ onKeyDown: handleTriggerKeyDown,
14740
+ onBlur,
14741
+ className: cn(
14742
+ "relative m-0 box-border flex h-12 w-full cursor-pointer items-center justify-between gap-2 rounded-[6px] border-0 px-4 text-left text-[16px] font-medium leading-5 outline-none transition-colors duration-200",
14743
+ isEmpty ? "bg-[var(--chekin-color-surface-input-empty)] text-[var(--chekin-color-gray-1)]" : "bg-transparent text-[var(--chekin-color-brand-navy)]",
14744
+ disabled && "cursor-not-allowed opacity-50",
14745
+ loading && "cursor-progress"
14746
+ ),
14747
+ children: [
14748
+ /* @__PURE__ */ jsx158("span", { id: valueId, className: "block min-w-0 flex-1 truncate text-left", children: valueLabel ?? placeholder ?? label }),
14749
+ /* @__PURE__ */ jsxs101("span", { className: "pointer-events-none flex items-center gap-2 text-[var(--chekin-color-gray-2)]", children: [
14750
+ loading && /* @__PURE__ */ jsx158(ThreeDotsLoader, { height: 18, width: 18 }),
14751
+ /* @__PURE__ */ jsx158(
14752
+ ChevronDown5,
14753
+ {
14754
+ size: 16,
14755
+ className: cn(
14756
+ "transition-transform duration-200",
14757
+ isOpen && "rotate-180 text-[var(--chekin-color-brand-blue)]"
14758
+ )
14759
+ }
14760
+ )
14761
+ ] })
14762
+ ]
14763
+ }
14764
+ ),
14765
+ /* @__PURE__ */ jsx158(
14766
+ Fieldset,
14767
+ {
14768
+ isFocused: isOpen,
14769
+ invalid: hasInvalidState,
14770
+ isEmpty,
14771
+ isActivated: !isEmpty || isOpen,
14772
+ disabled,
14773
+ loading,
14774
+ htmlFor: triggerId,
14775
+ labelId,
14776
+ legend: typeof label === "string" ? label : void 0,
14777
+ label,
14778
+ tooltip,
14779
+ onClick: !isBlocked ? toggleMenu : void 0
14780
+ }
14781
+ ),
14782
+ isOpen && /* @__PURE__ */ jsxs101(
14783
+ "div",
14784
+ {
14785
+ className: cn(
14786
+ "absolute left-0 right-0 top-full z-20 overflow-hidden rounded-b-lg bg-white shadow-[0_30px_30px_0_rgba(33,72,255,0.2)]",
14787
+ dropdownClassName
14788
+ ),
14789
+ children: [
14790
+ searchable && /* @__PURE__ */ jsx158("div", { className: "border-b border-[#f2f4f8] px-4 pb-2 pt-3", children: /* @__PURE__ */ jsx158(
14791
+ "input",
14792
+ {
14793
+ ref: searchInputRef,
14794
+ type: "text",
14795
+ value: searchValue,
14796
+ placeholder: searchPlaceholder,
14797
+ onChange: handleSearchChange,
14798
+ onKeyDown: handleSearchKeyDown,
14799
+ autoComplete: "off",
14800
+ "aria-controls": listboxId,
14801
+ "aria-activedescendant": highlightedIndex >= 0 ? getOptionId2(highlightedIndex) : void 0,
14802
+ className: "m-0 box-border h-9 w-full rounded-md border border-[var(--chekin-color-gray-3)] bg-white px-3 text-[16px] font-medium text-[var(--chekin-color-brand-navy)] outline-none transition-colors placeholder:text-[var(--chekin-color-gray-1)] focus:border-[var(--chekin-color-brand-blue)]"
14803
+ }
14804
+ ) }),
14805
+ itemCount === 0 ? /* @__PURE__ */ jsx158("div", { className: "px-4 py-[20px] text-left text-[16px] text-[var(--chekin-color-brand-navy)]", children: emptyMessage ?? "No options" }) : /* @__PURE__ */ jsx158(
14806
+ "div",
14807
+ {
14808
+ ref: scrollRef,
14809
+ className: cn("overflow-y-auto", menuClassName),
14810
+ style: { height: `${measuredListHeight}px` },
14811
+ children: /* @__PURE__ */ jsx158(
14812
+ "div",
14813
+ {
14814
+ id: listboxId,
14815
+ role: "listbox",
14816
+ tabIndex: -1,
14817
+ "aria-labelledby": labelId,
14818
+ "aria-describedby": describedErrorId,
14819
+ "aria-activedescendant": highlightedIndex >= 0 ? getOptionId2(highlightedIndex) : void 0,
14820
+ className: "relative w-full",
14821
+ style: { height: `${totalSize}px` },
14822
+ children: virtualItems.map((virtualItem) => {
14823
+ const isLoaderRow = virtualItem.index >= filteredOptions.length;
14824
+ const option = filteredOptions[virtualItem.index];
14825
+ const isSelected = !isLoaderRow && option ? option.value === value?.value : false;
14826
+ const isHighlighted = virtualItem.index === highlightedIndex;
14827
+ const isOptionDisabled = Boolean(isBlocked || option?.isDisabled);
14828
+ return /* @__PURE__ */ jsx158(
14829
+ "div",
14830
+ {
14831
+ "data-index": virtualItem.index,
14832
+ className: "absolute left-0 top-0 w-full",
14833
+ style: {
14834
+ height: `${virtualItem.size}px`,
14835
+ transform: `translateY(${virtualItem.start}px)`
14836
+ },
14837
+ children: isLoaderRow ? /* @__PURE__ */ jsxs101("div", { className: "flex h-full items-center justify-center gap-2 px-4 text-[14px] font-medium text-[var(--chekin-color-gray-1)]", children: [
14838
+ /* @__PURE__ */ jsx158(ThreeDotsLoader, { height: 18, width: 18 }),
14839
+ /* @__PURE__ */ jsx158("span", { children: loadingMoreText })
14840
+ ] }) : /* @__PURE__ */ jsxs101(
14841
+ "button",
14842
+ {
14843
+ id: getOptionId2(virtualItem.index),
14844
+ type: "button",
14845
+ role: "option",
14846
+ "aria-selected": isSelected,
14847
+ "aria-disabled": isOptionDisabled,
14848
+ tabIndex: -1,
14849
+ disabled: isOptionDisabled,
14850
+ onClick: () => option && handleSelect(option),
14851
+ onMouseMove: () => setHighlightedIndex(virtualItem.index),
14852
+ className: cn(
14853
+ "flex h-full w-full items-start justify-between border-0 border-b border-[#f2f4f8] bg-white px-4 text-left text-[16px] font-medium leading-5 text-[var(--chekin-color-brand-navy)] outline-none transition-colors",
14854
+ isHighlighted && !isSelected && "cursor-pointer text-[var(--chekin-color-brand-blue)]",
14855
+ isSelected && "cursor-default font-bold text-[var(--chekin-color-brand-navy)]",
14856
+ isOptionDisabled && "cursor-default opacity-30"
14857
+ ),
14858
+ children: [
14859
+ /* @__PURE__ */ jsx158("span", { className: "block break-words", children: option?.label }),
14860
+ option?.description && /* @__PURE__ */ jsx158("span", { className: "ml-2 mt-[3px] shrink-0 text-[12px] font-bold italic text-[#777e91]", children: option.description })
14861
+ ]
14862
+ }
14863
+ )
14864
+ },
14865
+ virtualItem.key
14866
+ );
14867
+ })
14868
+ }
14869
+ )
14870
+ }
14871
+ )
14872
+ ]
14873
+ }
14874
+ )
14875
+ ] }),
14876
+ !errorMessage && optional && /* @__PURE__ */ jsx158("span", { className: "mt-[1px] block text-left text-[14px] font-medium text-[var(--chekin-color-gray-1)]", children: typeof optional === "string" ? optional : "optional" }),
14877
+ !errorMessage && helperText && /* @__PURE__ */ jsx158("span", { className: "mt-[1px] block text-[12px] font-normal text-[var(--chekin-color-gray-1)]", children: helperText }),
14878
+ errorMessage && !hideErrorMessage && /* @__PURE__ */ jsx158(
14879
+ FieldErrorMessage,
14880
+ {
14881
+ id: errorId,
14882
+ message: errorMessage,
14883
+ className: "mt-[1px] text-[14px]"
14884
+ }
14885
+ )
14886
+ ] })
14887
+ ]
14888
+ }
14889
+ );
14890
+ }
14891
+ var DashboardInfiniteScrollSelect = React58.forwardRef(
14892
+ DashboardInfiniteScrollSelectInternal
14893
+ );
14894
+
14895
+ // src/searchable-select/SearchableSelect.tsx
14896
+ import * as React59 from "react";
14897
+ import { ChevronDown as ChevronDown6, Search as Search4 } from "lucide-react";
14898
+ import { useVirtualizer as useVirtualizer3 } from "@tanstack/react-virtual";
14899
+ import { useCallback as useCallback35 } from "react";
14900
+ import { jsx as jsx159, jsxs as jsxs102 } from "react/jsx-runtime";
14901
+ var ROW_HEIGHT = 48;
14902
+ var DESKTOP_LIST_HEIGHT = 280;
14903
+ var MOBILE_LIST_HEIGHT = 420;
14904
+ var LOAD_MORE_THRESHOLD = 6;
14905
+ function defaultFilter(option, searchValue) {
14906
+ return String(option.label).toLowerCase().includes(searchValue.trim().toLowerCase());
14907
+ }
14908
+ var SearchableSelectInternal = ({
14909
+ options,
14910
+ value,
14911
+ onChange,
14912
+ onBlur,
14913
+ onOpenChange,
14914
+ searchValue,
14915
+ onSearchChange,
14916
+ filterOption = defaultFilter,
14917
+ loading,
14918
+ hasNextPage,
14919
+ onLoadMore,
14920
+ variant = "default",
14921
+ label,
14922
+ topLabel,
14923
+ placeholder,
14924
+ searchPlaceholder = "Search...",
14925
+ mobileTitle,
14926
+ getValueLabel,
14927
+ disabled,
14928
+ error,
14929
+ invalid,
14930
+ optional,
14931
+ tooltip,
14932
+ hideErrorMessage,
14933
+ name,
14934
+ className,
14935
+ dropdownClassName,
14936
+ menuClassName,
14937
+ noOptionsMessage,
14938
+ loadingMessage
14939
+ }, ref) => {
14940
+ const { isMatch: isMobile2 } = useScreenResize(DEVICE.mobileXL);
14941
+ const reactId = React59.useId();
14942
+ const [open, setOpen] = React59.useState(false);
14943
+ const [internalSearchValue, setInternalSearchValue] = React59.useState("");
14944
+ const [highlightedIndex, setHighlightedIndex] = React59.useState(-1);
14945
+ const containerRef = React59.useRef(null);
14946
+ const triggerRef = React59.useRef(null);
14947
+ const inputRef = React59.useRef(null);
14948
+ const listboxId = `${reactId}-listbox`;
14949
+ const labelId = `${reactId}-label`;
14950
+ const valueId = `${reactId}-value`;
14951
+ const helperTextId = `${reactId}-helper`;
14952
+ const errorId = `${reactId}-error`;
14953
+ const searchInputId = `${reactId}-search`;
14954
+ const effectiveSearchValue = searchValue ?? internalSearchValue;
14955
+ const shouldFilterLocally = !onSearchChange && filterOption !== null;
14956
+ const visibleOptions = React59.useMemo(() => {
14957
+ if (!shouldFilterLocally || !effectiveSearchValue) {
14958
+ return options;
14959
+ }
14960
+ return options.filter((option) => filterOption(option, effectiveSearchValue));
14961
+ }, [effectiveSearchValue, filterOption, options, shouldFilterLocally]);
14962
+ const selectedIndex = React59.useMemo(
14963
+ () => visibleOptions.findIndex((option) => option.value === value?.value),
14964
+ [value?.value, visibleOptions]
14965
+ );
14966
+ const helperText = placeholder ?? label;
14967
+ const valueLabel = value ? getValueLabel?.(value) ?? String(value.label) : void 0;
14968
+ const isBlocked = Boolean(disabled) || Boolean(loading);
14969
+ const triggerError = error ?? invalid;
14970
+ const describedBy = error && !hideErrorMessage ? errorId : void 0;
14971
+ const activeOptionId = highlightedIndex >= 0 ? getOptionId(reactId, highlightedIndex) : void 0;
14972
+ useOutsideClick({
14973
+ elementRef: containerRef,
14974
+ onOutsideClick: () => closeSelect(),
14975
+ isDisabled: !open || isMobile2
14976
+ });
14977
+ const handleOnOpenChange = useEvent(onOpenChange);
14978
+ const setSelectOpen = useCallback35(
14979
+ (nextOpen, options2) => {
14980
+ setOpen(nextOpen);
14981
+ handleOnOpenChange?.(nextOpen);
14982
+ if (!nextOpen && options2?.restoreFocus) {
14983
+ triggerRef.current?.focus();
14984
+ }
14985
+ },
14986
+ [handleOnOpenChange]
14987
+ );
14988
+ React59.useEffect(() => {
14989
+ if (isBlocked) {
14990
+ setSelectOpen(false);
14991
+ return;
14992
+ }
14993
+ if (!open) return;
14994
+ const frameId = window.requestAnimationFrame(() => {
14995
+ inputRef.current?.focus();
14996
+ });
14997
+ return () => {
14998
+ window.cancelAnimationFrame(frameId);
14999
+ };
15000
+ }, [isBlocked, open, setSelectOpen]);
15001
+ React59.useEffect(() => {
15002
+ if (!open) {
15003
+ setHighlightedIndex(-1);
15004
+ return;
15005
+ }
15006
+ setHighlightedIndex((currentIndex) => {
15007
+ if (currentIndex >= 0 && currentIndex < visibleOptions.length && !visibleOptions[currentIndex]?.isDisabled) {
15008
+ return currentIndex;
15009
+ }
15010
+ return selectedIndex >= 0 ? selectedIndex : getFirstEnabledIndex(visibleOptions);
15011
+ });
15012
+ }, [open, selectedIndex, visibleOptions]);
15013
+ function openSelect() {
15014
+ if (isBlocked) return;
15015
+ setSelectOpen(true);
15016
+ }
15017
+ function closeSelect() {
15018
+ setSelectOpen(false, { restoreFocus: true });
15019
+ }
15020
+ function handleSearchChange(nextValue) {
15021
+ if (!onSearchChange) {
15022
+ setInternalSearchValue(nextValue);
15023
+ }
15024
+ onSearchChange?.(nextValue);
15025
+ }
15026
+ function handleSelect(option) {
15027
+ if (isBlocked || option.isDisabled) return;
15028
+ onChange(option);
15029
+ setSelectOpen(false, { restoreFocus: true });
15030
+ }
15031
+ function moveHighlight(step) {
15032
+ const startIndex = highlightedIndex >= 0 ? highlightedIndex + step : step === 1 ? 0 : visibleOptions.length - 1;
15033
+ const nextIndex = getNextEnabledIndex(visibleOptions, startIndex, step);
15034
+ if (nextIndex >= 0) {
15035
+ setHighlightedIndex(nextIndex);
15036
+ }
15037
+ }
15038
+ function handleTriggerKeyDown(event) {
15039
+ if (isBlocked) return;
15040
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown" || event.key === "ArrowUp") {
15041
+ event.preventDefault();
15042
+ openSelect();
15043
+ }
15044
+ }
15045
+ function handleSearchKeyDown(event) {
15046
+ if (event.key === "Escape") {
15047
+ event.preventDefault();
15048
+ closeSelect();
15049
+ return;
15050
+ }
15051
+ if (event.key === "ArrowDown") {
15052
+ event.preventDefault();
15053
+ moveHighlight(1);
15054
+ return;
15055
+ }
15056
+ if (event.key === "ArrowUp") {
15057
+ event.preventDefault();
15058
+ moveHighlight(-1);
15059
+ return;
15060
+ }
15061
+ if (event.key === "Enter") {
15062
+ event.preventDefault();
15063
+ const option = visibleOptions[highlightedIndex];
15064
+ if (option) {
15065
+ handleSelect(option);
15066
+ }
15067
+ }
15068
+ }
15069
+ const content = /* @__PURE__ */ jsx159(
15070
+ SearchableSelectContent,
15071
+ {
15072
+ inputId: searchInputId,
15073
+ listboxId,
15074
+ labelId,
15075
+ activeOptionId,
15076
+ inputRef,
15077
+ options: visibleOptions,
15078
+ value,
15079
+ searchValue: effectiveSearchValue,
15080
+ searchPlaceholder,
15081
+ highlightedIndex,
15082
+ loading,
15083
+ hasNextPage,
15084
+ onLoadMore,
15085
+ menuClassName,
15086
+ noOptionsMessage,
15087
+ loadingMessage,
15088
+ height: isMobile2 ? MOBILE_LIST_HEIGHT : DESKTOP_LIST_HEIGHT,
15089
+ idPrefix: reactId,
15090
+ onSearchChange: handleSearchChange,
15091
+ onSearchKeyDown: handleSearchKeyDown,
15092
+ onOptionClick: handleSelect,
15093
+ onOptionHover: setHighlightedIndex
15094
+ }
15095
+ );
15096
+ React59.useImperativeHandle(ref, () => triggerRef.current, []);
15097
+ return /* @__PURE__ */ jsxs102("div", { ref: containerRef, className: cn("relative w-full max-w-[425px]", className), children: [
15098
+ name && /* @__PURE__ */ jsx159("input", { type: "hidden", name, value: value ? String(value.value) : "" }),
15099
+ /* @__PURE__ */ jsx159(
15100
+ FieldTrigger,
15101
+ {
15102
+ id: `${reactId}-trigger`,
15103
+ ref: triggerRef,
15104
+ variant,
15105
+ "aria-haspopup": "listbox",
15106
+ "aria-expanded": open,
15107
+ "aria-controls": listboxId,
15108
+ label,
15109
+ topLabel,
15110
+ labelId,
15111
+ valueId,
15112
+ helperTextId,
15113
+ errorId: error ? errorId : void 0,
15114
+ labelText: topLabel ? helperText : void 0,
15115
+ valueText: valueLabel,
15116
+ placeholder: helperText,
15117
+ describedBy,
15118
+ error: triggerError,
15119
+ loading,
15120
+ optional,
15121
+ tooltip,
15122
+ forceLabelText: Boolean(optional) || Boolean(tooltip),
15123
+ hideErrorMessage,
15124
+ disabled,
15125
+ onClick: () => {
15126
+ if (open) {
15127
+ closeSelect();
15128
+ return;
15129
+ }
15130
+ openSelect();
15131
+ },
15132
+ onKeyDown: handleTriggerKeyDown,
15133
+ onBlur,
15134
+ trailingAdornment: /* @__PURE__ */ jsx159(
15135
+ ChevronDown6,
15136
+ {
15137
+ className: cn(
15138
+ "h-6 w-6 text-[#1F1F1B] transition-transform",
15139
+ open && "rotate-180"
15140
+ )
15141
+ }
15142
+ )
15143
+ }
15144
+ ),
15145
+ isMobile2 ? /* @__PURE__ */ jsx159(
15146
+ Drawer,
15147
+ {
15148
+ open,
15149
+ onOpenChange: (nextOpen) => {
15150
+ if (isBlocked && nextOpen) return;
13564
15151
  if (nextOpen) {
13565
15152
  setSelectOpen(true);
13566
15153
  return;
13567
15154
  }
13568
15155
  closeSelect();
13569
15156
  },
13570
- children: /* @__PURE__ */ jsxs96(DrawerContent, { onClose: closeSelect, lockScroll: false, children: [
13571
- /* @__PURE__ */ jsx152(DrawerTitle, { className: "sr-only", children: mobileTitle ?? label }),
13572
- /* @__PURE__ */ jsx152(DrawerDescription, { className: "sr-only", children: label }),
13573
- /* @__PURE__ */ jsx152("div", { className: "px-5 pb-5 pt-1", children: content })
15157
+ children: /* @__PURE__ */ jsxs102(DrawerContent, { onClose: closeSelect, lockScroll: false, children: [
15158
+ /* @__PURE__ */ jsx159(DrawerTitle, { className: "sr-only", children: mobileTitle ?? label }),
15159
+ /* @__PURE__ */ jsx159(DrawerDescription, { className: "sr-only", children: label }),
15160
+ /* @__PURE__ */ jsx159("div", { className: "px-5 pb-5 pt-1", children: content })
13574
15161
  ] })
13575
15162
  }
13576
- ) : open ? /* @__PURE__ */ jsx152(
15163
+ ) : open ? /* @__PURE__ */ jsx159(
13577
15164
  "div",
13578
15165
  {
13579
15166
  className: cn(
@@ -13585,7 +15172,7 @@ var SearchableSelectInternal = ({
13585
15172
  ) : null
13586
15173
  ] });
13587
15174
  };
13588
- var SearchableSelect = React53.forwardRef(
15175
+ var SearchableSelect = React59.forwardRef(
13589
15176
  SearchableSelectInternal
13590
15177
  );
13591
15178
  function SearchableSelectContent({
@@ -13612,11 +15199,11 @@ function SearchableSelectContent({
13612
15199
  onOptionClick,
13613
15200
  onOptionHover
13614
15201
  }) {
13615
- const listRef = React53.useRef(null);
13616
- const lastLoadMoreOptionsLengthRef = React53.useRef(null);
13617
- const previousHighlightedIndexRef = React53.useRef(highlightedIndex);
15202
+ const listRef = React59.useRef(null);
15203
+ const lastLoadMoreOptionsLengthRef = React59.useRef(null);
15204
+ const previousHighlightedIndexRef = React59.useRef(highlightedIndex);
13618
15205
  const rowCount = options.length + (loading && options.length > 0 ? 1 : 0);
13619
- const virtualizer = useVirtualizer2({
15206
+ const virtualizer = useVirtualizer3({
13620
15207
  count: rowCount,
13621
15208
  getScrollElement: () => listRef.current,
13622
15209
  estimateSize: () => ROW_HEIGHT,
@@ -13625,7 +15212,7 @@ function SearchableSelectContent({
13625
15212
  const virtualItems = virtualizer.getVirtualItems();
13626
15213
  const emptyMessage = noOptionsMessage?.() ?? "No matches found";
13627
15214
  const loadingText = loadingMessage?.() ?? "Loading...";
13628
- React53.useEffect(() => {
15215
+ React59.useEffect(() => {
13629
15216
  const lastItem = virtualItems[virtualItems.length - 1];
13630
15217
  const shouldLoadMore = !!lastItem && hasNextPage && !loading && lastItem.index >= options.length - LOAD_MORE_THRESHOLD;
13631
15218
  if (shouldLoadMore && lastLoadMoreOptionsLengthRef.current !== options.length) {
@@ -13633,23 +15220,23 @@ function SearchableSelectContent({
13633
15220
  onLoadMore?.();
13634
15221
  }
13635
15222
  }, [hasNextPage, loading, onLoadMore, options.length, virtualItems]);
13636
- React53.useEffect(() => {
15223
+ React59.useEffect(() => {
13637
15224
  const hasHighlightedIndexChanged = previousHighlightedIndexRef.current !== highlightedIndex;
13638
15225
  previousHighlightedIndexRef.current = highlightedIndex;
13639
15226
  if (highlightedIndex >= 0 && hasHighlightedIndexChanged) {
13640
15227
  virtualizer.scrollToIndex(highlightedIndex, { align: "auto" });
13641
15228
  }
13642
15229
  }, [highlightedIndex, virtualizer]);
13643
- return /* @__PURE__ */ jsxs96("div", { className: "p-2", children: [
13644
- /* @__PURE__ */ jsxs96("div", { className: "relative mb-2", children: [
13645
- /* @__PURE__ */ jsx152(
15230
+ return /* @__PURE__ */ jsxs102("div", { className: "p-2", children: [
15231
+ /* @__PURE__ */ jsxs102("div", { className: "relative mb-2", children: [
15232
+ /* @__PURE__ */ jsx159(
13646
15233
  Search4,
13647
15234
  {
13648
15235
  "aria-hidden": "true",
13649
15236
  className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-[#9696B9]"
13650
15237
  }
13651
15238
  ),
13652
- /* @__PURE__ */ jsx152(
15239
+ /* @__PURE__ */ jsx159(
13653
15240
  "input",
13654
15241
  {
13655
15242
  id: inputId,
@@ -13668,7 +15255,7 @@ function SearchableSelectContent({
13668
15255
  }
13669
15256
  )
13670
15257
  ] }),
13671
- loading && options.length === 0 ? /* @__PURE__ */ jsx152("div", { className: "px-4 py-5 text-center text-base leading-6 text-[#6C6C6C]", children: loadingText }) : options.length === 0 ? /* @__PURE__ */ jsx152("div", { className: "px-4 py-5 text-center text-base leading-6 text-[#6C6C6C]", children: emptyMessage }) : /* @__PURE__ */ jsx152(
15258
+ loading && options.length === 0 ? /* @__PURE__ */ jsx159("div", { className: "px-4 py-5 text-center text-base leading-6 text-[#6C6C6C]", children: loadingText }) : options.length === 0 ? /* @__PURE__ */ jsx159("div", { className: "px-4 py-5 text-center text-base leading-6 text-[#6C6C6C]", children: emptyMessage }) : /* @__PURE__ */ jsx159(
13672
15259
  "div",
13673
15260
  {
13674
15261
  id: listboxId,
@@ -13677,7 +15264,7 @@ function SearchableSelectContent({
13677
15264
  "aria-labelledby": labelId,
13678
15265
  className: cn("overflow-y-auto outline-none", menuClassName),
13679
15266
  style: { height: Math.min(height, rowCount * ROW_HEIGHT) },
13680
- children: /* @__PURE__ */ jsx152(
15267
+ children: /* @__PURE__ */ jsx159(
13681
15268
  "div",
13682
15269
  {
13683
15270
  className: "relative w-full",
@@ -13685,7 +15272,7 @@ function SearchableSelectContent({
13685
15272
  children: virtualItems.map((virtualItem) => {
13686
15273
  const option = options[virtualItem.index];
13687
15274
  if (!option) {
13688
- return /* @__PURE__ */ jsx152(
15275
+ return /* @__PURE__ */ jsx159(
13689
15276
  "div",
13690
15277
  {
13691
15278
  className: "absolute left-0 top-0 flex w-full items-center px-4 text-base leading-6 text-[#6C6C6C]",
@@ -13700,7 +15287,7 @@ function SearchableSelectContent({
13700
15287
  }
13701
15288
  const isSelected = value?.value === option.value;
13702
15289
  const isHighlighted = virtualItem.index === highlightedIndex;
13703
- return /* @__PURE__ */ jsx152(
15290
+ return /* @__PURE__ */ jsx159(
13704
15291
  "button",
13705
15292
  {
13706
15293
  id: getOptionId(idPrefix, virtualItem.index),
@@ -13722,7 +15309,7 @@ function SearchableSelectContent({
13722
15309
  height: `${virtualItem.size}px`,
13723
15310
  transform: `translateY(${virtualItem.start}px)`
13724
15311
  },
13725
- children: /* @__PURE__ */ jsx152("span", { className: "truncate text-center", children: String(option.label) })
15312
+ children: /* @__PURE__ */ jsx159("span", { className: "truncate text-center", children: String(option.label) })
13726
15313
  },
13727
15314
  `${String(option.value)}-${virtualItem.index}`
13728
15315
  );
@@ -13808,14 +15395,14 @@ function getErrorMessage(error) {
13808
15395
 
13809
15396
  // src/lib/toastResponseError.tsx
13810
15397
  import i18next from "i18next";
13811
- import { jsx as jsx153, jsxs as jsxs97 } from "react/jsx-runtime";
15398
+ import { jsx as jsx160, jsxs as jsxs103 } from "react/jsx-runtime";
13812
15399
  function addSupportEmailToMessage(message, prefixText) {
13813
15400
  if (typeof message !== "string") {
13814
15401
  return message;
13815
15402
  }
13816
15403
  const builtMessage = `${prefixText ? `${prefixText} ` : ""}${message}`;
13817
- return /* @__PURE__ */ jsxs97("div", { children: [
13818
- /* @__PURE__ */ jsx153("div", { children: builtMessage }),
15404
+ return /* @__PURE__ */ jsxs103("div", { children: [
15405
+ /* @__PURE__ */ jsx160("div", { children: builtMessage }),
13819
15406
  i18next.t("reach_us_at_email")
13820
15407
  ] });
13821
15408
  }
@@ -13876,6 +15463,11 @@ export {
13876
15463
  CopyString,
13877
15464
  CustomCheckboxDropdownGroup,
13878
15465
  DEVICE_BREAKPOINTS,
15466
+ DashboardCreatableMultiSelect,
15467
+ DashboardInfiniteScrollSelect,
15468
+ DashboardInput,
15469
+ DashboardMultiSelect,
15470
+ DashboardSelect,
13879
15471
  DataTable,
13880
15472
  DatePicker,
13881
15473
  DateTableFilter,