@itilite/lumina-ui 1.1.9 → 1.1.11
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/atom/RangePicker/RangePicker.js +5 -4
- package/dist/atom/RangePicker/RangePicker.mjs +3 -3
- package/dist/atom/Select/Select.js +5 -4
- package/dist/atom/Select/Select.mjs +1 -1
- package/dist/chunk-2QQU6BYR.mjs +678 -0
- package/dist/chunk-35KDS27M.mjs +618 -0
- package/dist/chunk-5PFI6XBL.mjs +618 -0
- package/dist/chunk-E4FCLHYA.mjs +678 -0
- package/dist/chunk-W7J4GMPI.mjs +618 -0
- package/dist/chunk-Y3BIY4DW.mjs +618 -0
- package/dist/chunk-YO5EDEA6.mjs +618 -0
- package/dist/chunk-ZGFE3OPJ.mjs +678 -0
- package/dist/index.js +5 -4
- package/dist/index.mjs +12 -12
- package/dist/styles.css +233 -232
- package/package.json +1 -1
|
@@ -0,0 +1,678 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Tooltip_default
|
|
3
|
+
} from "./chunk-MLCMZRUC.mjs";
|
|
4
|
+
import {
|
|
5
|
+
LoadingSpinner_default
|
|
6
|
+
} from "./chunk-QKTMWS4J.mjs";
|
|
7
|
+
import {
|
|
8
|
+
__objRest,
|
|
9
|
+
__spreadProps,
|
|
10
|
+
__spreadValues
|
|
11
|
+
} from "./chunk-FWCSY2DS.mjs";
|
|
12
|
+
|
|
13
|
+
// src/atom/Select/Select.tsx
|
|
14
|
+
import { memo as memo3, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
15
|
+
import clsx from "clsx";
|
|
16
|
+
|
|
17
|
+
// src/icons/Chevron.tsx
|
|
18
|
+
import * as React from "react";
|
|
19
|
+
import { jsx } from "react/jsx-runtime";
|
|
20
|
+
var Chevron = React.memo(
|
|
21
|
+
(_a) => {
|
|
22
|
+
var _b = _a, { size = 16, color = "#6b7280", className } = _b, rest = __objRest(_b, ["size", "color", "className"]);
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
"svg",
|
|
25
|
+
__spreadProps(__spreadValues({
|
|
26
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
27
|
+
width: size,
|
|
28
|
+
height: size,
|
|
29
|
+
fill: "none",
|
|
30
|
+
viewBox: "0 0 16 16",
|
|
31
|
+
className
|
|
32
|
+
}, rest), {
|
|
33
|
+
children: /* @__PURE__ */ jsx(
|
|
34
|
+
"path",
|
|
35
|
+
{
|
|
36
|
+
fill: color,
|
|
37
|
+
d: "M11.78 6.22a.75.75 0 00-1.06 0L8 8.94 5.28 6.22a.75.75 0 00-1.06 1.06l3.25 3.25a.75.75 0 001.06 0l3.25-3.25a.75.75 0 000-1.06z"
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
Chevron.displayName = "Chevron";
|
|
45
|
+
|
|
46
|
+
// src/icons/CrossV2.tsx
|
|
47
|
+
import * as React2 from "react";
|
|
48
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
49
|
+
var CrossV2 = React2.memo(
|
|
50
|
+
(_a) => {
|
|
51
|
+
var _b = _a, { size = 16, color = "#111827", className } = _b, rest = __objRest(_b, ["size", "color", "className"]);
|
|
52
|
+
return /* @__PURE__ */ jsx2(
|
|
53
|
+
"svg",
|
|
54
|
+
__spreadProps(__spreadValues({
|
|
55
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
56
|
+
width: size,
|
|
57
|
+
height: size,
|
|
58
|
+
fill: "none",
|
|
59
|
+
viewBox: "0 0 20 20"
|
|
60
|
+
}, rest), {
|
|
61
|
+
children: /* @__PURE__ */ jsx2(
|
|
62
|
+
"path",
|
|
63
|
+
{
|
|
64
|
+
fill: color,
|
|
65
|
+
d: "M4.411 4.41a.833.833 0 0 1 1.179 0L10 8.822l4.411-4.41a.833.833 0 1 1 1.179 1.178L11.179 10l4.41 4.41a.833.833 0 0 1-1.178 1.18l-4.41-4.411-4.411 4.41a.833.833 0 1 1-1.179-1.178L8.821 10l-4.41-4.41a.833.833 0 0 1 0-1.18"
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
CrossV2.displayName = "CrossV2";
|
|
73
|
+
|
|
74
|
+
// src/icons/Lock.tsx
|
|
75
|
+
import React3 from "react";
|
|
76
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
77
|
+
var Lock = React3.memo((_a) => {
|
|
78
|
+
var _b = _a, { size = 16, color = "#000" } = _b, rest = __objRest(_b, ["size", "color"]);
|
|
79
|
+
return /* @__PURE__ */ jsx3(
|
|
80
|
+
"svg",
|
|
81
|
+
__spreadProps(__spreadValues({
|
|
82
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
83
|
+
width: size,
|
|
84
|
+
height: size,
|
|
85
|
+
fill: "none",
|
|
86
|
+
viewBox: "0 0 16 16"
|
|
87
|
+
}, rest), {
|
|
88
|
+
children: /* @__PURE__ */ jsx3(
|
|
89
|
+
"path",
|
|
90
|
+
{
|
|
91
|
+
fill: color,
|
|
92
|
+
d: "M9 9a1 1 0 11-2 0 1 1 0 012 0zM5 4h-.5A2.5 2.5 0 002 6.5v5A2.5 2.5 0 004.5 14h7a2.5 2.5 0 002.5-2.5v-5A2.5 2.5 0 0011.5 4H11v-.5a3 3 0 00-6 0V4zm1-.5a2 2 0 114 0V4H6v-.5zM11.5 5A1.5 1.5 0 0113 6.5v5a1.5 1.5 0 01-1.5 1.5h-7A1.5 1.5 0 013 11.5v-5A1.5 1.5 0 014.5 5h7z"
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// src/atom/Select/Select.tsx
|
|
100
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
101
|
+
var Select = ({
|
|
102
|
+
label,
|
|
103
|
+
mandatory = false,
|
|
104
|
+
error = false,
|
|
105
|
+
options = [],
|
|
106
|
+
valueSelected = "",
|
|
107
|
+
// Keep for backward compatibility
|
|
108
|
+
value: _valueProp,
|
|
109
|
+
// Rename to avoid potential conflicts with native value attribute
|
|
110
|
+
onChange,
|
|
111
|
+
onSearch,
|
|
112
|
+
isLoading = false,
|
|
113
|
+
disabled = false,
|
|
114
|
+
disabledTooltip = "",
|
|
115
|
+
className = "",
|
|
116
|
+
dropdownClassName = "",
|
|
117
|
+
optionClassName = "",
|
|
118
|
+
style = {},
|
|
119
|
+
showDisplayValue = false,
|
|
120
|
+
// New prop to show displayValue instead of label
|
|
121
|
+
allowClear = true,
|
|
122
|
+
enableSearch = true,
|
|
123
|
+
doubleCharSearch = false,
|
|
124
|
+
id,
|
|
125
|
+
name,
|
|
126
|
+
tabIndex,
|
|
127
|
+
// Add tabIndex prop
|
|
128
|
+
// Additional styling props
|
|
129
|
+
size = "default",
|
|
130
|
+
// 'small', 'default', 'large'
|
|
131
|
+
variant = "default",
|
|
132
|
+
// 'default', 'filled', 'outlined'
|
|
133
|
+
wrapperClassName = "",
|
|
134
|
+
inputClassName = "",
|
|
135
|
+
// Custom class for input element specifically
|
|
136
|
+
labelClassName = "",
|
|
137
|
+
// Custom class for label element specifically
|
|
138
|
+
height = "tw-h-12",
|
|
139
|
+
// Custom height
|
|
140
|
+
experience = "business"
|
|
141
|
+
}) => {
|
|
142
|
+
const normalizeValue = useCallback(
|
|
143
|
+
(val) => {
|
|
144
|
+
if (val === null || val === void 0) return "";
|
|
145
|
+
return String(val);
|
|
146
|
+
},
|
|
147
|
+
[]
|
|
148
|
+
);
|
|
149
|
+
const validatedOptions = useMemo(() => {
|
|
150
|
+
if (!Array.isArray(options)) return [];
|
|
151
|
+
return options.filter(
|
|
152
|
+
(opt) => opt && typeof opt === "object" && opt.value !== void 0 && opt.value !== null && opt.label !== void 0
|
|
153
|
+
);
|
|
154
|
+
}, [options]);
|
|
155
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
156
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
157
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
158
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
159
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
160
|
+
const [selectedValue, setSelectedValue] = useState(() => {
|
|
161
|
+
const initialValue = valueSelected;
|
|
162
|
+
if (initialValue === null || initialValue === void 0) return "";
|
|
163
|
+
return String(initialValue);
|
|
164
|
+
});
|
|
165
|
+
const inputRef = useRef(null);
|
|
166
|
+
const inputValueRef = useRef("");
|
|
167
|
+
const dropdownRef = useRef(null);
|
|
168
|
+
const optionRefs = useRef([]);
|
|
169
|
+
const optionListRef = useRef(null);
|
|
170
|
+
const blurTimeoutRef = useRef(null);
|
|
171
|
+
const hoverTimeoutRef = useRef(null);
|
|
172
|
+
const isActive = isFocused || Boolean(selectedValue) || Boolean(valueSelected) || Boolean(searchTerm);
|
|
173
|
+
const sizeClasses = useMemo(() => {
|
|
174
|
+
switch (size) {
|
|
175
|
+
case "small":
|
|
176
|
+
return {
|
|
177
|
+
input: "tw-h-6 tw-px-3 tw-typography-caption1Bold !tw-rounded-lg",
|
|
178
|
+
padding: "tw-px-2 tw-py-1",
|
|
179
|
+
labelActive: "tw-top-0.5 tw-typography-caption2",
|
|
180
|
+
labelInactive: "tw-top-1.5 tw-typography-caption3"
|
|
181
|
+
};
|
|
182
|
+
case "medium":
|
|
183
|
+
return {
|
|
184
|
+
input: "tw-h-10 tw-px-4 tw-typography-body2",
|
|
185
|
+
padding: label ? "tw-pt-4 tw-pb-1" : "tw-py-2",
|
|
186
|
+
labelActive: "tw-top-1 tw-typography-caption3",
|
|
187
|
+
labelInactive: "tw-top-2.5 tw-typography-body2"
|
|
188
|
+
};
|
|
189
|
+
case "large":
|
|
190
|
+
return {
|
|
191
|
+
input: "tw-h-16 tw-px-5 tw-typography-bodyLarge",
|
|
192
|
+
padding: label ? "tw-pt-8 tw-pb-4" : "tw-py-5",
|
|
193
|
+
labelActive: "tw-top-1 tw-typography-caption2",
|
|
194
|
+
labelInactive: "tw-top-5 tw-typography-body1"
|
|
195
|
+
};
|
|
196
|
+
default:
|
|
197
|
+
return {
|
|
198
|
+
input: height + " tw-px-4 tw-typography-bodyLarge",
|
|
199
|
+
padding: label ? "tw-pt-6 tw-pb-3" : "tw-py-3",
|
|
200
|
+
labelActive: "tw-top-1 tw-typography-caption3",
|
|
201
|
+
labelInactive: "tw-top-3.5 tw-typography-body2"
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}, [size, label, height]);
|
|
205
|
+
const variantClasses = useMemo(() => {
|
|
206
|
+
switch (variant) {
|
|
207
|
+
case "filled":
|
|
208
|
+
return "tw-bg-gray-50 tw-border-transparent";
|
|
209
|
+
case "outlined":
|
|
210
|
+
return "tw-bg-transparent tw-border-2";
|
|
211
|
+
default:
|
|
212
|
+
return " tw-border";
|
|
213
|
+
}
|
|
214
|
+
}, [variant]);
|
|
215
|
+
const handleBlur = useCallback(() => {
|
|
216
|
+
blurTimeoutRef.current = setTimeout(() => {
|
|
217
|
+
setIsOpen(false);
|
|
218
|
+
setSearchTerm("");
|
|
219
|
+
setHighlightedIndex(-1);
|
|
220
|
+
blurTimeoutRef.current = null;
|
|
221
|
+
setIsFocused(false);
|
|
222
|
+
}, 150);
|
|
223
|
+
}, []);
|
|
224
|
+
const handleSearchChange = useCallback(
|
|
225
|
+
(e) => {
|
|
226
|
+
var _a;
|
|
227
|
+
const searchValue = doubleCharSearch ? e.target.value.slice(0, 2) || "" : e.target.value;
|
|
228
|
+
if (doubleCharSearch) {
|
|
229
|
+
setSearchTerm(searchValue);
|
|
230
|
+
} else {
|
|
231
|
+
setSearchTerm(searchValue);
|
|
232
|
+
}
|
|
233
|
+
setIsOpen(true);
|
|
234
|
+
setHighlightedIndex(-1);
|
|
235
|
+
if (onSearch && typeof onSearch === "function") {
|
|
236
|
+
onSearch(searchValue);
|
|
237
|
+
}
|
|
238
|
+
(_a = optionListRef == null ? void 0 : optionListRef.current) == null ? void 0 : _a.scrollTo({
|
|
239
|
+
top: 0,
|
|
240
|
+
behavior: "smooth"
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
[doubleCharSearch, onSearch]
|
|
244
|
+
);
|
|
245
|
+
const handleOptionSelect = useCallback(
|
|
246
|
+
(option) => {
|
|
247
|
+
var _a;
|
|
248
|
+
if (blurTimeoutRef.current) {
|
|
249
|
+
clearTimeout(blurTimeoutRef.current);
|
|
250
|
+
blurTimeoutRef.current = null;
|
|
251
|
+
}
|
|
252
|
+
inputValueRef.current = option.label;
|
|
253
|
+
const normalizedValue = normalizeValue(option.value);
|
|
254
|
+
setSelectedValue(normalizedValue);
|
|
255
|
+
setSearchTerm("");
|
|
256
|
+
setIsOpen(false);
|
|
257
|
+
if (enableSearch) {
|
|
258
|
+
setIsFocused(false);
|
|
259
|
+
}
|
|
260
|
+
setIsHovering(false);
|
|
261
|
+
if (onChange) onChange(option.value);
|
|
262
|
+
if (enableSearch) (_a = inputRef.current) == null ? void 0 : _a.blur();
|
|
263
|
+
},
|
|
264
|
+
[normalizeValue, onChange, enableSearch]
|
|
265
|
+
);
|
|
266
|
+
const handleClear = useCallback(
|
|
267
|
+
(e) => {
|
|
268
|
+
var _a;
|
|
269
|
+
inputValueRef.current = "";
|
|
270
|
+
e.stopPropagation();
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
setSelectedValue("");
|
|
273
|
+
setSearchTerm("");
|
|
274
|
+
if (enableSearch) {
|
|
275
|
+
setIsOpen(true);
|
|
276
|
+
setIsFocused(true);
|
|
277
|
+
(_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
278
|
+
} else {
|
|
279
|
+
setIsOpen(false);
|
|
280
|
+
setIsFocused(false);
|
|
281
|
+
}
|
|
282
|
+
if (onChange) onChange(null);
|
|
283
|
+
},
|
|
284
|
+
[onChange, enableSearch]
|
|
285
|
+
);
|
|
286
|
+
useEffect(() => {
|
|
287
|
+
if (!validatedOptions.length) {
|
|
288
|
+
setSelectedValue("");
|
|
289
|
+
setSearchTerm("");
|
|
290
|
+
inputValueRef.current = "";
|
|
291
|
+
}
|
|
292
|
+
}, [validatedOptions.length]);
|
|
293
|
+
useEffect(() => {
|
|
294
|
+
const externalValue = _valueProp !== void 0 ? _valueProp : valueSelected;
|
|
295
|
+
const newValue = normalizeValue(externalValue);
|
|
296
|
+
setSelectedValue((prevValue) => {
|
|
297
|
+
const prevNormalized = normalizeValue(prevValue);
|
|
298
|
+
return prevNormalized !== newValue ? newValue : prevValue;
|
|
299
|
+
});
|
|
300
|
+
}, [valueSelected, _valueProp, normalizeValue]);
|
|
301
|
+
useEffect(() => {
|
|
302
|
+
const handleClickOutside = (event) => {
|
|
303
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
304
|
+
if (blurTimeoutRef.current) {
|
|
305
|
+
clearTimeout(blurTimeoutRef.current);
|
|
306
|
+
blurTimeoutRef.current = null;
|
|
307
|
+
}
|
|
308
|
+
setIsOpen(false);
|
|
309
|
+
setIsFocused(false);
|
|
310
|
+
setSearchTerm("");
|
|
311
|
+
setHighlightedIndex(-1);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
315
|
+
return () => {
|
|
316
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
317
|
+
if (blurTimeoutRef.current) {
|
|
318
|
+
clearTimeout(blurTimeoutRef.current);
|
|
319
|
+
}
|
|
320
|
+
if (hoverTimeoutRef.current) {
|
|
321
|
+
clearTimeout(hoverTimeoutRef.current);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
}, []);
|
|
325
|
+
const getDisplayValue = useCallback(() => {
|
|
326
|
+
if (selectedValue && (validatedOptions == null ? void 0 : validatedOptions.length) > 0) {
|
|
327
|
+
const selected = validatedOptions.find(
|
|
328
|
+
(opt) => normalizeValue(opt.value) === normalizeValue(selectedValue)
|
|
329
|
+
);
|
|
330
|
+
if (selected) {
|
|
331
|
+
return showDisplayValue && selected.displayValue ? selected.displayValue : selected.label;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (selectedValue && (!validatedOptions || validatedOptions.length === 0)) {
|
|
335
|
+
return selectedValue;
|
|
336
|
+
}
|
|
337
|
+
return "";
|
|
338
|
+
}, [selectedValue, validatedOptions, showDisplayValue, normalizeValue]);
|
|
339
|
+
const filteredOptions = useMemo(() => {
|
|
340
|
+
var _a;
|
|
341
|
+
if (!enableSearch) {
|
|
342
|
+
return validatedOptions;
|
|
343
|
+
}
|
|
344
|
+
(_a = dropdownRef.current) == null ? void 0 : _a.scrollTo(0, 0);
|
|
345
|
+
const updatedFilteredOptions = validatedOptions.filter((option) => {
|
|
346
|
+
var _a2;
|
|
347
|
+
return (_a2 = option == null ? void 0 : option.label) == null ? void 0 : _a2.toLowerCase().includes(searchTerm == null ? void 0 : searchTerm.toLowerCase());
|
|
348
|
+
});
|
|
349
|
+
return updatedFilteredOptions;
|
|
350
|
+
}, [validatedOptions, searchTerm, enableSearch]);
|
|
351
|
+
const getSelectedOptionIndex = useCallback(() => {
|
|
352
|
+
if (!selectedValue || !filteredOptions.length) {
|
|
353
|
+
return 0;
|
|
354
|
+
}
|
|
355
|
+
const index = filteredOptions.findIndex(
|
|
356
|
+
(option) => normalizeValue(option.value) === normalizeValue(selectedValue)
|
|
357
|
+
);
|
|
358
|
+
return index >= 0 ? index : 0;
|
|
359
|
+
}, [selectedValue, filteredOptions, normalizeValue]);
|
|
360
|
+
const handleInputInteraction = useCallback(
|
|
361
|
+
(_e) => {
|
|
362
|
+
var _a;
|
|
363
|
+
if (blurTimeoutRef.current) {
|
|
364
|
+
clearTimeout(blurTimeoutRef.current);
|
|
365
|
+
blurTimeoutRef.current = null;
|
|
366
|
+
}
|
|
367
|
+
if (isOpen) {
|
|
368
|
+
setIsOpen(false);
|
|
369
|
+
setIsFocused(false);
|
|
370
|
+
setSearchTerm("");
|
|
371
|
+
setHighlightedIndex(-1);
|
|
372
|
+
(_a = inputRef.current) == null ? void 0 : _a.blur();
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
setIsFocused(true);
|
|
376
|
+
setIsOpen(true);
|
|
377
|
+
setHighlightedIndex(getSelectedOptionIndex());
|
|
378
|
+
if (inputRef.current) {
|
|
379
|
+
inputRef.current.focus();
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
[isOpen, getSelectedOptionIndex]
|
|
383
|
+
);
|
|
384
|
+
const handleKeyDown = useCallback(
|
|
385
|
+
(e) => {
|
|
386
|
+
var _a;
|
|
387
|
+
if (!isOpen) return;
|
|
388
|
+
switch (e.key) {
|
|
389
|
+
case "ArrowDown":
|
|
390
|
+
e.preventDefault();
|
|
391
|
+
setHighlightedIndex((prev) => {
|
|
392
|
+
const nextIndex = prev < filteredOptions.length - 1 ? prev + 1 : prev;
|
|
393
|
+
return nextIndex;
|
|
394
|
+
});
|
|
395
|
+
break;
|
|
396
|
+
case "ArrowUp":
|
|
397
|
+
e.preventDefault();
|
|
398
|
+
setHighlightedIndex((prev) => {
|
|
399
|
+
const nextIndex = prev > 0 ? prev - 1 : prev;
|
|
400
|
+
return nextIndex;
|
|
401
|
+
});
|
|
402
|
+
break;
|
|
403
|
+
case "Enter":
|
|
404
|
+
e.preventDefault();
|
|
405
|
+
if (highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {
|
|
406
|
+
handleOptionSelect(filteredOptions[highlightedIndex]);
|
|
407
|
+
}
|
|
408
|
+
break;
|
|
409
|
+
case "Escape":
|
|
410
|
+
e.preventDefault();
|
|
411
|
+
setIsOpen(false);
|
|
412
|
+
setIsFocused(false);
|
|
413
|
+
setSearchTerm("");
|
|
414
|
+
setHighlightedIndex(-1);
|
|
415
|
+
(_a = inputRef.current) == null ? void 0 : _a.blur();
|
|
416
|
+
break;
|
|
417
|
+
default:
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
[isOpen, highlightedIndex, filteredOptions, handleOptionSelect]
|
|
422
|
+
);
|
|
423
|
+
useEffect(() => {
|
|
424
|
+
if (highlightedIndex >= 0 && optionRefs.current[highlightedIndex]) {
|
|
425
|
+
optionRefs.current[highlightedIndex].scrollIntoView({
|
|
426
|
+
block: "nearest",
|
|
427
|
+
behavior: "smooth"
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}, [highlightedIndex]);
|
|
431
|
+
useEffect(() => {
|
|
432
|
+
optionRefs.current = [];
|
|
433
|
+
}, [filteredOptions]);
|
|
434
|
+
const handleMouseEnter = useCallback(() => {
|
|
435
|
+
if (hoverTimeoutRef.current) {
|
|
436
|
+
clearTimeout(hoverTimeoutRef.current);
|
|
437
|
+
}
|
|
438
|
+
if (!isHovering) {
|
|
439
|
+
setIsHovering(true);
|
|
440
|
+
}
|
|
441
|
+
}, [isHovering]);
|
|
442
|
+
const handleMouseLeave = useCallback(() => {
|
|
443
|
+
hoverTimeoutRef.current = setTimeout(() => {
|
|
444
|
+
setIsHovering(false);
|
|
445
|
+
}, 50);
|
|
446
|
+
}, []);
|
|
447
|
+
const handleChevronClick = useCallback(
|
|
448
|
+
(e) => {
|
|
449
|
+
var _a;
|
|
450
|
+
e.preventDefault();
|
|
451
|
+
if (blurTimeoutRef.current) {
|
|
452
|
+
clearTimeout(blurTimeoutRef.current);
|
|
453
|
+
blurTimeoutRef.current = null;
|
|
454
|
+
}
|
|
455
|
+
if (isOpen) {
|
|
456
|
+
setIsOpen(false);
|
|
457
|
+
setIsFocused(false);
|
|
458
|
+
setSearchTerm("");
|
|
459
|
+
setHighlightedIndex(-1);
|
|
460
|
+
(_a = inputRef.current) == null ? void 0 : _a.blur();
|
|
461
|
+
} else {
|
|
462
|
+
if (inputRef.current) {
|
|
463
|
+
inputRef.current.focus();
|
|
464
|
+
}
|
|
465
|
+
handleInputInteraction();
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
[isOpen, handleInputInteraction]
|
|
469
|
+
);
|
|
470
|
+
const InputWrapper = ({ children }) => {
|
|
471
|
+
if (disabled && disabledTooltip)
|
|
472
|
+
return /* @__PURE__ */ jsx4(Tooltip_default, { title: disabledTooltip, children });
|
|
473
|
+
return children;
|
|
474
|
+
};
|
|
475
|
+
return /* @__PURE__ */ jsx4(InputWrapper, { children: /* @__PURE__ */ jsxs(
|
|
476
|
+
"div",
|
|
477
|
+
{
|
|
478
|
+
style,
|
|
479
|
+
className: clsx("tw-relative tw-w-full", wrapperClassName, {
|
|
480
|
+
"tw-cursor-not-allowed": disabled
|
|
481
|
+
}),
|
|
482
|
+
ref: dropdownRef,
|
|
483
|
+
onMouseEnter: handleMouseEnter,
|
|
484
|
+
onMouseLeave: handleMouseLeave,
|
|
485
|
+
children: [
|
|
486
|
+
/* @__PURE__ */ jsxs("div", { className: "tw-relative", children: [
|
|
487
|
+
/* @__PURE__ */ jsx4(
|
|
488
|
+
"input",
|
|
489
|
+
{
|
|
490
|
+
ref: inputRef,
|
|
491
|
+
type: "text",
|
|
492
|
+
id,
|
|
493
|
+
name,
|
|
494
|
+
tabIndex,
|
|
495
|
+
autoComplete: "off",
|
|
496
|
+
autoCorrect: "off",
|
|
497
|
+
autoCapitalize: "off",
|
|
498
|
+
spellCheck: "false",
|
|
499
|
+
value: isFocused && enableSearch ? searchTerm : getDisplayValue(),
|
|
500
|
+
onChange: enableSearch ? handleSearchChange : void 0,
|
|
501
|
+
onClick: handleInputInteraction,
|
|
502
|
+
onKeyDown: handleKeyDown,
|
|
503
|
+
className: clsx(
|
|
504
|
+
"tw-w-full tw-rounded-xl tw-outline-none tw-transition-all tw-duration-200 tw-cursor-pointer tw-border-solid tw-text-color-text-default",
|
|
505
|
+
sizeClasses.input,
|
|
506
|
+
sizeClasses.padding,
|
|
507
|
+
variantClasses,
|
|
508
|
+
{
|
|
509
|
+
"tw-bg-white": valueSelected || getDisplayValue() || isFocused,
|
|
510
|
+
"tw-bg-color-gray-5": !valueSelected || !getDisplayValue(),
|
|
511
|
+
"!tw-bg-[#F8F7F6] tw-cursor-not-allowed tw-pointer-events-none": disabled
|
|
512
|
+
},
|
|
513
|
+
// Conditional padding based on label presence
|
|
514
|
+
!label && "tw-flex tw-items-center",
|
|
515
|
+
{
|
|
516
|
+
"!tw-border-color-primary": isFocused && experience === "business"
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"!tw-border-[#804D7B]": isFocused && experience === "personal"
|
|
520
|
+
},
|
|
521
|
+
error ? "!tw-border-color-text-critical " : "tw-border-[#EBE3DD] hover:tw-border-[#C5B7AC]",
|
|
522
|
+
// Add focus state styling
|
|
523
|
+
"focus:tw-shadow-sm focus:tw-ring-offset-1",
|
|
524
|
+
className,
|
|
525
|
+
inputClassName
|
|
526
|
+
// Put inputClassName last so it can override default classes
|
|
527
|
+
),
|
|
528
|
+
readOnly: !isFocused || !enableSearch
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
label && size !== "small" && /* @__PURE__ */ jsxs(
|
|
532
|
+
"label",
|
|
533
|
+
{
|
|
534
|
+
htmlFor: id,
|
|
535
|
+
className: clsx(
|
|
536
|
+
"tw-absolute tw-left-[18px] tw-pointer-events-none tw-transition-all tw-duration-200 tw-ease-out tw-text-gray-500",
|
|
537
|
+
isActive ? sizeClasses.labelActive : sizeClasses.labelInactive,
|
|
538
|
+
error && "tw-text-color-text-critical",
|
|
539
|
+
labelClassName
|
|
540
|
+
),
|
|
541
|
+
children: [
|
|
542
|
+
label,
|
|
543
|
+
mandatory && /* @__PURE__ */ jsx4("span", { className: "tw-text-color-text-critical tw-ml-1", children: "*" })
|
|
544
|
+
]
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
/* @__PURE__ */ jsxs(
|
|
548
|
+
"div",
|
|
549
|
+
{
|
|
550
|
+
className: clsx(
|
|
551
|
+
"tw-absolute tw-right-3 tw--translate-y-1/2 tw-flex tw-items-center",
|
|
552
|
+
{
|
|
553
|
+
"!tw-right-[5px]": doubleCharSearch && !(isHovering && selectedValue && allowClear),
|
|
554
|
+
"tw-top-3 !tw-right-2": size === "small",
|
|
555
|
+
"tw-top-1/2": size !== "small"
|
|
556
|
+
}
|
|
557
|
+
),
|
|
558
|
+
children: [
|
|
559
|
+
disabled && /* @__PURE__ */ jsx4("div", { className: "tw-absolute tw-right-0 -tw-top-2", children: /* @__PURE__ */ jsx4(Lock, { size: 16 }) }),
|
|
560
|
+
isLoading ? /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(LoadingSpinner_default, { size: "xs" }) }) : /* @__PURE__ */ jsx4(
|
|
561
|
+
"div",
|
|
562
|
+
{
|
|
563
|
+
className: clsx(
|
|
564
|
+
"tw-transition-all tw-duration-200 tw-cursor-pointer tw-flex tw-items-center",
|
|
565
|
+
// Only rotate chevron when open and not showing clear icon
|
|
566
|
+
isOpen && !(isHovering && selectedValue && allowClear) && "-tw-rotate-180"
|
|
567
|
+
),
|
|
568
|
+
onMouseDown: (e) => {
|
|
569
|
+
if (isHovering && selectedValue && allowClear) {
|
|
570
|
+
handleClear(e);
|
|
571
|
+
} else {
|
|
572
|
+
handleChevronClick(e);
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
children: disabled ? null : isHovering && selectedValue && allowClear ? /* @__PURE__ */ jsx4(
|
|
576
|
+
CrossV2,
|
|
577
|
+
{
|
|
578
|
+
color: "#111827",
|
|
579
|
+
className: clsx({ "tw-mr-1": size !== "small" }),
|
|
580
|
+
size: size === "small" ? 12 : 16
|
|
581
|
+
}
|
|
582
|
+
) : /* @__PURE__ */ jsx4(
|
|
583
|
+
Chevron,
|
|
584
|
+
{
|
|
585
|
+
className: clsx("tw-text-gray-400"),
|
|
586
|
+
color: "#6B7280"
|
|
587
|
+
}
|
|
588
|
+
)
|
|
589
|
+
}
|
|
590
|
+
)
|
|
591
|
+
]
|
|
592
|
+
}
|
|
593
|
+
)
|
|
594
|
+
] }),
|
|
595
|
+
isOpen && /* @__PURE__ */ jsx4(
|
|
596
|
+
"div",
|
|
597
|
+
{
|
|
598
|
+
className: clsx(
|
|
599
|
+
"tw-absolute tw-z-[100] tw-w-full tw-mt-0 tw-bg-white tw-border tw-border-[#ebe3dd] tw-border-solid tw-rounded-xl tw-shadow-lg tw-overflow-y-auto tw-py-1",
|
|
600
|
+
{ "tw-max-h-60": !doubleCharSearch },
|
|
601
|
+
{ "tw-max-h-44": doubleCharSearch },
|
|
602
|
+
dropdownClassName
|
|
603
|
+
),
|
|
604
|
+
ref: optionListRef,
|
|
605
|
+
children: filteredOptions.length > 0 ? filteredOptions.map((option, index) => /* @__PURE__ */ jsx4(
|
|
606
|
+
"div",
|
|
607
|
+
{
|
|
608
|
+
ref: (el) => optionRefs.current[index] = el,
|
|
609
|
+
onClick: () => handleOptionSelect(option),
|
|
610
|
+
onMouseEnter: () => setHighlightedIndex(index),
|
|
611
|
+
className: clsx(
|
|
612
|
+
"tw-transition-all tw-duration-150",
|
|
613
|
+
{ "tw-typography-body2": size !== "small" },
|
|
614
|
+
{ "tw-typography-caption1": size === "small" },
|
|
615
|
+
optionClassName
|
|
616
|
+
),
|
|
617
|
+
children: /* @__PURE__ */ jsx4(
|
|
618
|
+
"div",
|
|
619
|
+
{
|
|
620
|
+
className: clsx(
|
|
621
|
+
"tw-px-4 tw-cursor-pointer tw-py-2 tw-mx-0.5 tw-rounded-xl",
|
|
622
|
+
normalizeValue(selectedValue) === normalizeValue(option.value) ? experience === "personal" ? "tw-bg-[#f1e8fa]" : "tw-bg-[#fff1e1]" : (
|
|
623
|
+
// Highlighted option styling (keyboard navigation)
|
|
624
|
+
index === highlightedIndex ? "tw-bg-[#f3f4f6] tw-text-gray-900" : (
|
|
625
|
+
// Default option styling
|
|
626
|
+
"tw-text-gray-900 hover:tw-bg-[#1118270a]"
|
|
627
|
+
)
|
|
628
|
+
)
|
|
629
|
+
),
|
|
630
|
+
children: option.label
|
|
631
|
+
}
|
|
632
|
+
)
|
|
633
|
+
},
|
|
634
|
+
doubleCharSearch ? option.label : option.value
|
|
635
|
+
)) : /* @__PURE__ */ jsx4("div", { className: "tw-px-4 tw-py-3 tw-text-gray-500 tw-text-sm", children: "No options found" })
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
) });
|
|
641
|
+
};
|
|
642
|
+
var arePropsEqual = (prevProps, nextProps) => {
|
|
643
|
+
var _a, _b;
|
|
644
|
+
const criticalProps = [
|
|
645
|
+
"value",
|
|
646
|
+
"valueSelected",
|
|
647
|
+
"options",
|
|
648
|
+
"error",
|
|
649
|
+
"disabled",
|
|
650
|
+
"label",
|
|
651
|
+
"mandatory"
|
|
652
|
+
];
|
|
653
|
+
for (const prop of criticalProps) {
|
|
654
|
+
if (prevProps[prop] !== nextProps[prop]) {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (((_a = prevProps.options) == null ? void 0 : _a.length) !== ((_b = nextProps.options) == null ? void 0 : _b.length)) {
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
if (prevProps.options && nextProps.options) {
|
|
662
|
+
for (let i = 0; i < prevProps.options.length; i++) {
|
|
663
|
+
const prevOpt = prevProps.options[i];
|
|
664
|
+
const nextOpt = nextProps.options[i];
|
|
665
|
+
if ((prevOpt == null ? void 0 : prevOpt.value) !== (nextOpt == null ? void 0 : nextOpt.value) || (prevOpt == null ? void 0 : prevOpt.label) !== (nextOpt == null ? void 0 : nextOpt.label)) {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return true;
|
|
671
|
+
};
|
|
672
|
+
Select.displayName = "Select";
|
|
673
|
+
var Select_default = memo3(Select, arePropsEqual);
|
|
674
|
+
|
|
675
|
+
export {
|
|
676
|
+
Select,
|
|
677
|
+
Select_default
|
|
678
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -837,7 +837,7 @@ var Select = ({
|
|
|
837
837
|
switch (size) {
|
|
838
838
|
case "small":
|
|
839
839
|
return {
|
|
840
|
-
input: "tw-h-6 tw-
|
|
840
|
+
input: "tw-h-6 tw-typography-caption1Bold !tw-rounded-lg",
|
|
841
841
|
padding: "tw-px-2 tw-py-1",
|
|
842
842
|
labelActive: "tw-top-0.5 tw-typography-caption2",
|
|
843
843
|
labelInactive: "tw-top-1.5 tw-typography-caption3"
|
|
@@ -1214,7 +1214,7 @@ var Select = ({
|
|
|
1214
1214
|
"tw-absolute tw-right-3 tw--translate-y-1/2 tw-flex tw-items-center",
|
|
1215
1215
|
{
|
|
1216
1216
|
"!tw-right-[5px]": doubleCharSearch && !(isHovering && selectedValue && allowClear),
|
|
1217
|
-
"tw-top-3
|
|
1217
|
+
"tw-top-3 !tw-right-2": size === "small",
|
|
1218
1218
|
"tw-top-1/2": size !== "small"
|
|
1219
1219
|
}
|
|
1220
1220
|
),
|
|
@@ -1272,8 +1272,9 @@ var Select = ({
|
|
|
1272
1272
|
onClick: () => handleOptionSelect(option),
|
|
1273
1273
|
onMouseEnter: () => setHighlightedIndex(index),
|
|
1274
1274
|
className: (0, import_clsx8.default)(
|
|
1275
|
-
"tw-transition-all tw-duration-150
|
|
1276
|
-
|
|
1275
|
+
"tw-transition-all tw-duration-150",
|
|
1276
|
+
{ "tw-typography-body2": size !== "small" },
|
|
1277
|
+
{ "tw-typography-caption1": size === "small" },
|
|
1277
1278
|
optionClassName
|
|
1278
1279
|
),
|
|
1279
1280
|
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|