@chekinapp/ui 0.0.67 → 0.0.69

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