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