@skalfa/skalfa-component 1.0.52 → 1.0.54
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/input/InputDate.component.d.ts +1 -0
- package/dist/input/InputDate.component.js +47 -29
- package/dist/input/InputDatetime.component.js +2 -2
- package/dist/input/InputImage.component.d.ts +2 -0
- package/dist/input/InputImage.component.js +54 -18
- package/dist/input/InputTime.component.d.ts +5 -3
- package/dist/input/InputTime.component.js +109 -28
- package/dist/input/Select.component.d.ts +7 -2
- package/dist/input/Select.component.js +91 -38
- package/package.json +1 -1
- package/src/input/InputDate.component.tsx +95 -55
- package/src/input/InputDatetime.component.tsx +2 -0
- package/src/input/InputImage.component.tsx +71 -21
- package/src/input/InputTime.component.tsx +218 -58
- package/src/input/Select.component.tsx +111 -53
|
@@ -15,6 +15,8 @@ export interface SelectOptionProps {
|
|
|
15
15
|
value : string | number;
|
|
16
16
|
searchable ?: string[];
|
|
17
17
|
customLabel ?: ReactNode;
|
|
18
|
+
customOption ?: ((option: any) => ReactNode) | ReactNode;
|
|
19
|
+
[key: string] : any;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
export interface SelectProps {
|
|
@@ -35,7 +37,7 @@ export interface SelectProps {
|
|
|
35
37
|
|
|
36
38
|
options ?: SelectOptionProps[];
|
|
37
39
|
searchable ?: boolean;
|
|
38
|
-
serverOptionControl ?: ApiType & { cacheName?: string |
|
|
40
|
+
serverOptionControl ?: ApiType & { cacheName?: string | boolean; selectableOption?: string[] };
|
|
39
41
|
idbOptionControl ?: { store: string, labelKey: string, valueKey: string };
|
|
40
42
|
serverSearchable ?: boolean;
|
|
41
43
|
includedOptions ?: SelectOptionProps[];
|
|
@@ -45,6 +47,8 @@ export interface SelectProps {
|
|
|
45
47
|
maxShowOption ?: number;
|
|
46
48
|
creatable ?: boolean | string;
|
|
47
49
|
creatableLabel ?: string;
|
|
50
|
+
customOption ?: (option: any) => ReactNode;
|
|
51
|
+
selectableOption ?: string[];
|
|
48
52
|
|
|
49
53
|
onChange ?: (value: any, data?: any) => any;
|
|
50
54
|
register ?: (name: string, validations?: ValidationRules) => void;
|
|
@@ -83,9 +87,11 @@ export function SelectComponent({
|
|
|
83
87
|
exceptOptions = [],
|
|
84
88
|
tempOptions,
|
|
85
89
|
newOption,
|
|
86
|
-
maxShowOption
|
|
90
|
+
maxShowOption,
|
|
87
91
|
creatable,
|
|
88
92
|
creatableLabel,
|
|
93
|
+
customOption,
|
|
94
|
+
selectableOption,
|
|
89
95
|
|
|
90
96
|
register,
|
|
91
97
|
unregister,
|
|
@@ -184,13 +190,27 @@ export function SelectComponent({
|
|
|
184
190
|
let newFilteredOptions: SelectOptionProps[] = [];
|
|
185
191
|
|
|
186
192
|
if (searchable && !serverSearchable && dataOptions?.length) {
|
|
187
|
-
if (e
|
|
188
|
-
|
|
193
|
+
if (e?.target?.value) {
|
|
194
|
+
const val = e.target.value.toLowerCase();
|
|
195
|
+
const matched = dataOptions.filter((opt) => {
|
|
196
|
+
if (opt.searchable?.some((s) => s.toLowerCase().indexOf(val) > -1)) return true;
|
|
197
|
+
if (typeof opt.label === "string" && opt.label.toLowerCase().indexOf(val) > -1) return true;
|
|
198
|
+
if (typeof opt.code === "string" && opt.code.toLowerCase().indexOf(val) > -1) return true;
|
|
199
|
+
if (typeof opt.name === "string" && opt.name.toLowerCase().indexOf(val) > -1) return true;
|
|
200
|
+
return false;
|
|
201
|
+
});
|
|
202
|
+
newFilteredOptions = typeof maxShowOption === "number" && maxShowOption > 0
|
|
203
|
+
? matched.slice(0, maxShowOption)
|
|
204
|
+
: matched;
|
|
189
205
|
} else {
|
|
190
|
-
newFilteredOptions =
|
|
206
|
+
newFilteredOptions = typeof maxShowOption === "number" && maxShowOption > 0
|
|
207
|
+
? dataOptions.slice(0, maxShowOption)
|
|
208
|
+
: dataOptions;
|
|
191
209
|
}
|
|
192
210
|
} else {
|
|
193
|
-
newFilteredOptions =
|
|
211
|
+
newFilteredOptions = typeof maxShowOption === "number" && maxShowOption > 0
|
|
212
|
+
? (dataOptions || []).slice(0, maxShowOption)
|
|
213
|
+
: (dataOptions || []);
|
|
194
214
|
}
|
|
195
215
|
|
|
196
216
|
setActiveOption(-1);
|
|
@@ -251,40 +271,68 @@ export function SelectComponent({
|
|
|
251
271
|
const fetchOptions = async () => {
|
|
252
272
|
setLoadingOption(true);
|
|
253
273
|
|
|
274
|
+
const selectableOpt = selectableOption || serverOptionControl?.selectableOption || serverOptionControl?.params?.selectableOption;
|
|
275
|
+
|
|
254
276
|
const serverControl = {
|
|
255
277
|
...serverOptionControl,
|
|
256
|
-
params:
|
|
257
|
-
|
|
278
|
+
params: {
|
|
279
|
+
...(serverOptionControl?.params || {}),
|
|
280
|
+
...(selectableOpt ? { selectableOption: selectableOpt } : {}),
|
|
281
|
+
...(serverSearchable ? { search: keywordSearch } : {}),
|
|
282
|
+
},
|
|
283
|
+
headers: { "X-Option": 1, ...(serverOptionControl?.headers || {}) }
|
|
258
284
|
};
|
|
259
285
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
[...(mutateOptions?.data?.data || []), ...(includedOptions || [])].filter(
|
|
286
|
+
const cacheKey = typeof serverOptionControl?.cacheName === "string" && serverOptionControl.cacheName.trim() !== ""
|
|
287
|
+
? serverOptionControl.cacheName
|
|
288
|
+
: serverOptionControl?.cacheName === true
|
|
289
|
+
? `option_${serverOptionControl?.path || serverOptionControl?.url}`
|
|
290
|
+
: null;
|
|
291
|
+
|
|
292
|
+
if (cacheKey) {
|
|
293
|
+
const getCacheOptions = await cavity.get(cacheKey);
|
|
294
|
+
const cacheData = getCacheOptions?.data;
|
|
295
|
+
const cacheOptions = (Array.isArray(cacheData?.data) ? cacheData.data : Array.isArray(cacheData) ? cacheData : []) as SelectOptionProps[];
|
|
296
|
+
|
|
297
|
+
if (cacheOptions?.length) {
|
|
298
|
+
const cached = [...cacheOptions, ...includedOptions].filter(
|
|
274
299
|
(op: SelectOptionProps) => !exceptOptions?.includes(op.value)
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
|
|
300
|
+
);
|
|
301
|
+
setDataOptions(cached);
|
|
302
|
+
setFilteredOptions(typeof maxShowOption === "number" && maxShowOption > 0 ? cached.slice(0, maxShowOption) : cached);
|
|
303
|
+
setLoadingOption(false);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
278
307
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
308
|
+
const mutateOptions = await api(serverControl || {});
|
|
309
|
+
const fetchedData = mutateOptions?.data?.data || mutateOptions?.data || [];
|
|
310
|
+
const optionsData = Array.isArray(fetchedData) ? fetchedData.map((item: any) => {
|
|
311
|
+
if (item && typeof item === "object") {
|
|
312
|
+
return {
|
|
313
|
+
...item,
|
|
314
|
+
name: item.name ?? item.label,
|
|
315
|
+
label: item.label ?? item.name ?? item.code ?? item.value,
|
|
316
|
+
};
|
|
285
317
|
}
|
|
286
|
-
|
|
318
|
+
return item;
|
|
319
|
+
}) : [];
|
|
320
|
+
|
|
321
|
+
const finalOptions = [...optionsData, ...(includedOptions || [])].filter(
|
|
322
|
+
(op: SelectOptionProps) => !exceptOptions?.includes(op.value)
|
|
323
|
+
);
|
|
324
|
+
setDataOptions(finalOptions);
|
|
325
|
+
setFilteredOptions(typeof maxShowOption === "number" && maxShowOption > 0 ? finalOptions.slice(0, maxShowOption) : finalOptions);
|
|
326
|
+
setShowOption(true);
|
|
327
|
+
|
|
328
|
+
if (cacheKey) {
|
|
329
|
+
cavity.set({
|
|
330
|
+
key: cacheKey,
|
|
331
|
+
data: mutateOptions?.data,
|
|
332
|
+
expired: 5,
|
|
333
|
+
});
|
|
287
334
|
}
|
|
335
|
+
setLoadingOption(false);
|
|
288
336
|
};
|
|
289
337
|
|
|
290
338
|
const fetchIdbOptions = async () => {
|
|
@@ -309,6 +357,7 @@ export function SelectComponent({
|
|
|
309
357
|
})
|
|
310
358
|
|
|
311
359
|
setDataOptions(rows);
|
|
360
|
+
setFilteredOptions(typeof maxShowOption === "number" && maxShowOption > 0 ? rows.slice(0, maxShowOption) : rows);
|
|
312
361
|
setLoadingOption(false);
|
|
313
362
|
}
|
|
314
363
|
};
|
|
@@ -402,7 +451,8 @@ export function SelectComponent({
|
|
|
402
451
|
placeholder={!inputHandler.value || (Array.isArray(inputHandler.value) && !inputHandler.value.length) ? placeholder : ""}
|
|
403
452
|
disabled={disabled}
|
|
404
453
|
className={cn(
|
|
405
|
-
"input cursor-pointer",
|
|
454
|
+
"input cursor-pointer pr-10",
|
|
455
|
+
clearable && "pr-18",
|
|
406
456
|
leftIcon && "input-with-left-icon",
|
|
407
457
|
rightIcon && "input-with-right-icon",
|
|
408
458
|
isCreatingNew && "pl-[4.8rem]",
|
|
@@ -493,22 +543,23 @@ export function SelectComponent({
|
|
|
493
543
|
return (
|
|
494
544
|
<div key={key} className="input-values-item">
|
|
495
545
|
<span>{dataOptions?.find((option) => option.value == item)?.label}</span>
|
|
496
|
-
<
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
546
|
+
<div className="input-values-delete">
|
|
547
|
+
<Icon
|
|
548
|
+
icon="solid/times"
|
|
549
|
+
onClick={() => {
|
|
550
|
+
const values = Array().concat(inputHandler.value);
|
|
551
|
+
const index = values.findIndex((val: string | number) => val == item);
|
|
552
|
+
|
|
553
|
+
inputHandler.setValue(values.filter((_, val) => val != index));
|
|
554
|
+
|
|
555
|
+
if (!values.filter((_, val) => val != index)?.length) {
|
|
556
|
+
setInputShowValue("");
|
|
557
|
+
serverSearchable && setKeyword("");
|
|
558
|
+
onChange?.("");
|
|
559
|
+
}
|
|
560
|
+
}}
|
|
561
|
+
/>
|
|
562
|
+
</div>
|
|
512
563
|
</div>
|
|
513
564
|
);
|
|
514
565
|
})}
|
|
@@ -650,7 +701,7 @@ export function SelectComponent({
|
|
|
650
701
|
return (
|
|
651
702
|
<li
|
|
652
703
|
className={cn(
|
|
653
|
-
"input-suggest",
|
|
704
|
+
"input-suggest flex items-center",
|
|
654
705
|
(key == activeOption || selected) && "input-suggest-active",
|
|
655
706
|
pcn<CT>(className, "suggest-item"),
|
|
656
707
|
(key == activeOption || selected) && pcn<CT>(className, "suggest-item", "active")
|
|
@@ -669,8 +720,11 @@ export function SelectComponent({
|
|
|
669
720
|
setIsCreatingNew(false);
|
|
670
721
|
|
|
671
722
|
if (!multiple) {
|
|
672
|
-
|
|
673
|
-
|
|
723
|
+
const displayLabel = typeof option.label === "string" || typeof option.label === "number"
|
|
724
|
+
? option.label
|
|
725
|
+
: (option.name || option.code || option.value);
|
|
726
|
+
setInputShowValue(displayLabel);
|
|
727
|
+
serverSearchable && setKeyword(typeof displayLabel === "string" ? displayLabel : "");
|
|
674
728
|
inputHandler.setValue(option.value);
|
|
675
729
|
onChange?.(option.value, option);
|
|
676
730
|
} else {
|
|
@@ -700,7 +754,11 @@ export function SelectComponent({
|
|
|
700
754
|
className="select-suggest-check"
|
|
701
755
|
/>
|
|
702
756
|
)}
|
|
703
|
-
{
|
|
757
|
+
{customOption
|
|
758
|
+
? customOption(option)
|
|
759
|
+
: (option.customOption
|
|
760
|
+
? (typeof option.customOption === "function" ? option.customOption(option) : option.customOption)
|
|
761
|
+
: (option.customLabel || option.label))}
|
|
704
762
|
</li>
|
|
705
763
|
);
|
|
706
764
|
})}
|