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