@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.cjs +1868 -271
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +180 -11
- package/dist/index.d.ts +180 -11
- package/dist/index.js +1867 -275
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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-
|
|
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-[
|
|
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:
|
|
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
|
|
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 =
|
|
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/
|
|
13321
|
+
// src/dashboard/input/Input.tsx
|
|
13309
13322
|
import * as React53 from "react";
|
|
13310
|
-
import {
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
import { jsx as jsx152, jsxs as jsxs96 } from "react/jsx-runtime";
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
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
|
-
|
|
13332
|
+
label,
|
|
13344
13333
|
tooltip,
|
|
13345
|
-
|
|
13346
|
-
|
|
13334
|
+
legend,
|
|
13335
|
+
onClick,
|
|
13336
|
+
htmlFor,
|
|
13337
|
+
labelId,
|
|
13338
|
+
readOnly,
|
|
13339
|
+
loading,
|
|
13340
|
+
disabled,
|
|
13347
13341
|
className,
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
|
|
13364
|
-
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
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
|
-
|
|
13387
|
+
"fieldset",
|
|
13514
13388
|
{
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
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-
|
|
13552
|
-
|
|
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
|
-
|
|
13559
|
-
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
|
|
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__ */
|
|
13571
|
-
/* @__PURE__ */
|
|
13572
|
-
/* @__PURE__ */
|
|
13573
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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 =
|
|
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 =
|
|
13616
|
-
const lastLoadMoreOptionsLengthRef =
|
|
13617
|
-
const previousHighlightedIndexRef =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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__ */
|
|
13644
|
-
/* @__PURE__ */
|
|
13645
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
13818
|
-
/* @__PURE__ */
|
|
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,
|