lecom-ui 5.3.41 → 5.3.42
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.
|
@@ -18,6 +18,7 @@ const MultiSelect = React.forwardRef(
|
|
|
18
18
|
maxCount = 3,
|
|
19
19
|
modalPopover = false,
|
|
20
20
|
className,
|
|
21
|
+
side = "bottom",
|
|
21
22
|
treeOptions,
|
|
22
23
|
treeSelectionStrategy = "leaf",
|
|
23
24
|
selectAllLabel,
|
|
@@ -29,7 +30,6 @@ const MultiSelect = React.forwardRef(
|
|
|
29
30
|
searchStrategy = "ranked",
|
|
30
31
|
highlightMatches = true,
|
|
31
32
|
allowTypoDistance = 0,
|
|
32
|
-
maxHeight = 320,
|
|
33
33
|
groupedOptions
|
|
34
34
|
}, ref) => {
|
|
35
35
|
const { t } = useTranslation();
|
|
@@ -162,7 +162,10 @@ const MultiSelect = React.forwardRef(
|
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
164
164
|
if (idx === 0) score += 0;
|
|
165
|
-
else if (new RegExp(`(^|s)${escapeRegex(t2)}`).test(
|
|
165
|
+
else if (new RegExp(`(^|s)${escapeRegex(t2)}`).test(
|
|
166
|
+
nl.slice(Math.max(0, idx - 1))
|
|
167
|
+
))
|
|
168
|
+
score += 5;
|
|
166
169
|
else score += 10;
|
|
167
170
|
}
|
|
168
171
|
if (approximate) score += 5;
|
|
@@ -177,7 +180,9 @@ const MultiSelect = React.forwardRef(
|
|
|
177
180
|
const scored = options.map((o, idx) => {
|
|
178
181
|
const res = searchStrategy === "simple" ? norm(o.label).includes(norm(query)) ? 0 : false : effFilterFn(query, o);
|
|
179
182
|
return { o, score: res === false ? Infinity : res, idx };
|
|
180
|
-
}).filter((x) => x.score !== Infinity).sort(
|
|
183
|
+
}).filter((x) => x.score !== Infinity).sort(
|
|
184
|
+
(a, b) => a.score === b.score ? a.idx - b.idx : a.score - b.score
|
|
185
|
+
);
|
|
181
186
|
return scored.map((s) => s.o);
|
|
182
187
|
}, [options, query, effFilterFn, searchStrategy, norm, isTree]);
|
|
183
188
|
const filterTree = React.useCallback(
|
|
@@ -207,25 +212,25 @@ const MultiSelect = React.forwardRef(
|
|
|
207
212
|
React.useEffect(() => {
|
|
208
213
|
if (!treeOptions) return;
|
|
209
214
|
}, [treeQuery, treeOptions]);
|
|
210
|
-
const findTreeLabel = React.useCallback(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
const findTreeLabel = React.useCallback(
|
|
216
|
+
(val) => {
|
|
217
|
+
if (!treeOptions) return void 0;
|
|
218
|
+
const stack = [...treeOptions];
|
|
219
|
+
while (stack.length) {
|
|
220
|
+
const n = stack.pop();
|
|
221
|
+
if (n.value === val) return n.label;
|
|
222
|
+
if (n.children) stack.push(...n.children);
|
|
223
|
+
}
|
|
224
|
+
return void 0;
|
|
225
|
+
},
|
|
226
|
+
[treeOptions]
|
|
227
|
+
);
|
|
220
228
|
const collectAllValues = (node) => {
|
|
221
229
|
const self = treeSelectionStrategy === "all" ? [node.value] : [];
|
|
222
230
|
if (!node.children || node.children.length === 0) {
|
|
223
231
|
return treeSelectionStrategy === "all" ? [node.value] : [node.value];
|
|
224
232
|
}
|
|
225
|
-
return [
|
|
226
|
-
...self,
|
|
227
|
-
...node.children.flatMap((c) => collectAllValues(c))
|
|
228
|
-
];
|
|
233
|
+
return [...self, ...node.children.flatMap((c) => collectAllValues(c))];
|
|
229
234
|
};
|
|
230
235
|
const isNodeFullySelected = (node) => {
|
|
231
236
|
const values = collectAllValues(node);
|
|
@@ -253,7 +258,9 @@ const MultiSelect = React.forwardRef(
|
|
|
253
258
|
(label, q) => {
|
|
254
259
|
if (!highlightMatches || !q) return label;
|
|
255
260
|
const nl = norm(label);
|
|
256
|
-
const tokens = Array.from(
|
|
261
|
+
const tokens = Array.from(
|
|
262
|
+
new Set(norm(q).split(/\s+/).filter(Boolean))
|
|
263
|
+
).sort((a, b) => b.length - a.length);
|
|
257
264
|
if (!tokens.length) return label;
|
|
258
265
|
const ranges = [];
|
|
259
266
|
for (const t2 of tokens) {
|
|
@@ -269,17 +276,35 @@ const MultiSelect = React.forwardRef(
|
|
|
269
276
|
ranges.sort((a, b) => a.start - b.start);
|
|
270
277
|
const merged = [];
|
|
271
278
|
for (const r of ranges) {
|
|
272
|
-
if (!merged.length || r.start > merged[merged.length - 1].end)
|
|
273
|
-
|
|
279
|
+
if (!merged.length || r.start > merged[merged.length - 1].end)
|
|
280
|
+
merged.push({ ...r });
|
|
281
|
+
else
|
|
282
|
+
merged[merged.length - 1].end = Math.max(
|
|
283
|
+
merged[merged.length - 1].end,
|
|
284
|
+
r.end
|
|
285
|
+
);
|
|
274
286
|
}
|
|
275
287
|
const parts = [];
|
|
276
288
|
let cursor = 0;
|
|
277
289
|
merged.forEach((r, i) => {
|
|
278
|
-
if (cursor < r.start)
|
|
279
|
-
|
|
290
|
+
if (cursor < r.start)
|
|
291
|
+
parts.push(
|
|
292
|
+
/* @__PURE__ */ React.createElement("span", { key: `t-${i}-pre` }, label.slice(cursor, r.start))
|
|
293
|
+
);
|
|
294
|
+
parts.push(
|
|
295
|
+
/* @__PURE__ */ React.createElement(
|
|
296
|
+
"span",
|
|
297
|
+
{
|
|
298
|
+
key: `t-${i}-hl`,
|
|
299
|
+
className: "bg-blue-100/60 text-grey-900 rounded-[2px] px-0.5"
|
|
300
|
+
},
|
|
301
|
+
label.slice(r.start, r.end)
|
|
302
|
+
)
|
|
303
|
+
);
|
|
280
304
|
cursor = r.end;
|
|
281
305
|
});
|
|
282
|
-
if (cursor < label.length)
|
|
306
|
+
if (cursor < label.length)
|
|
307
|
+
parts.push(/* @__PURE__ */ React.createElement("span", { key: "t-last" }, label.slice(cursor)));
|
|
283
308
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, parts);
|
|
284
309
|
},
|
|
285
310
|
[highlightMatches, norm]
|
|
@@ -396,6 +421,7 @@ const MultiSelect = React.forwardRef(
|
|
|
396
421
|
"p-0 max-h-80",
|
|
397
422
|
matchTriggerWidth && "w-[var(--radix-popover-trigger-width)]"
|
|
398
423
|
),
|
|
424
|
+
side,
|
|
399
425
|
align: "start",
|
|
400
426
|
onEscapeKeyDown: () => setIsPopoverOpen(false)
|
|
401
427
|
},
|
|
@@ -425,35 +451,45 @@ const MultiSelect = React.forwardRef(
|
|
|
425
451
|
selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ React.createElement(Minus, { className: "h-4 w-4" })
|
|
426
452
|
),
|
|
427
453
|
/* @__PURE__ */ React.createElement("span", { className: "text-grey-800" }, selectAllLabel ?? t("multiSelect.selectAll"))
|
|
428
|
-
), isGrouped ? Object.entries(groupedOptions).map(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
/* @__PURE__ */ React.createElement(
|
|
443
|
-
|
|
454
|
+
), isGrouped ? Object.entries(groupedOptions).map(
|
|
455
|
+
([categoryName, categoryOptions]) => {
|
|
456
|
+
const filtered = categoryOptions.filter(
|
|
457
|
+
(opt) => !query || effectiveOptions.some(
|
|
458
|
+
(eff) => eff.value === opt.value && filteredOptions.some(
|
|
459
|
+
(filt) => filt.value === opt.value
|
|
460
|
+
)
|
|
461
|
+
)
|
|
462
|
+
);
|
|
463
|
+
if (!filtered.length) return null;
|
|
464
|
+
return /* @__PURE__ */ React.createElement("div", { key: categoryName }, /* @__PURE__ */ React.createElement("div", { className: "px-2 py-2 text-xs font-medium text-muted-foreground" }, categoryName), filtered.map((option) => {
|
|
465
|
+
const isSelected = selectedValues.includes(
|
|
466
|
+
option.value
|
|
467
|
+
);
|
|
468
|
+
return /* @__PURE__ */ React.createElement(
|
|
469
|
+
CommandItem,
|
|
444
470
|
{
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
)
|
|
471
|
+
key: option.value,
|
|
472
|
+
onSelect: () => toggleOption(option.value),
|
|
473
|
+
className: "cursor-pointer"
|
|
449
474
|
},
|
|
450
|
-
/* @__PURE__ */ React.createElement(
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
475
|
+
/* @__PURE__ */ React.createElement(
|
|
476
|
+
"div",
|
|
477
|
+
{
|
|
478
|
+
className: cn(
|
|
479
|
+
"flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400",
|
|
480
|
+
isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
|
|
481
|
+
)
|
|
482
|
+
},
|
|
483
|
+
/* @__PURE__ */ React.createElement(Check, { className: "h-4 w-4" })
|
|
484
|
+
),
|
|
485
|
+
/* @__PURE__ */ React.createElement("span", { className: "text-grey-800" }, highlight(option.label, query))
|
|
486
|
+
);
|
|
487
|
+
}));
|
|
488
|
+
}
|
|
489
|
+
) : filteredOptions.map((option) => {
|
|
490
|
+
const isSelected = selectedValues.includes(
|
|
491
|
+
option.value
|
|
492
|
+
);
|
|
457
493
|
return /* @__PURE__ */ React.createElement(
|
|
458
494
|
CommandItem,
|
|
459
495
|
{
|
|
@@ -474,7 +510,24 @@ const MultiSelect = React.forwardRef(
|
|
|
474
510
|
/* @__PURE__ */ React.createElement("span", { className: "text-grey-800" }, highlight(option.label, query))
|
|
475
511
|
);
|
|
476
512
|
})))),
|
|
477
|
-
isTree && /* @__PURE__ */ React.createElement("div", { className: "min-w-[260px]" }, treeSearch && /* @__PURE__ */ React.createElement("div", { className: "px-1 pt-2 pb-0 border-b border-grey-300" }, /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(
|
|
513
|
+
isTree && /* @__PURE__ */ React.createElement("div", { className: "min-w-[260px]" }, treeSearch && /* @__PURE__ */ React.createElement("div", { className: "px-1 pt-2 pb-0 border-b border-grey-300" }, /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(
|
|
514
|
+
"svg",
|
|
515
|
+
{
|
|
516
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground",
|
|
517
|
+
fill: "none",
|
|
518
|
+
stroke: "currentColor",
|
|
519
|
+
viewBox: "0 0 24 24"
|
|
520
|
+
},
|
|
521
|
+
/* @__PURE__ */ React.createElement(
|
|
522
|
+
"path",
|
|
523
|
+
{
|
|
524
|
+
strokeLinecap: "round",
|
|
525
|
+
strokeLinejoin: "round",
|
|
526
|
+
strokeWidth: 2,
|
|
527
|
+
d: "M21 21l-4.35-4.35m0 0A7.5 7.5 0 1 0 5.25 5.25a7.5 7.5 0 0 0 11.4 11.4z"
|
|
528
|
+
}
|
|
529
|
+
)
|
|
530
|
+
), /* @__PURE__ */ React.createElement(
|
|
478
531
|
"input",
|
|
479
532
|
{
|
|
480
533
|
type: "text",
|
|
@@ -503,7 +556,8 @@ const MultiSelect = React.forwardRef(
|
|
|
503
556
|
for (const n of nodes) {
|
|
504
557
|
const hasChildren = !!(n.children && n.children.length);
|
|
505
558
|
if (!hasChildren) acc += 1;
|
|
506
|
-
else
|
|
559
|
+
else
|
|
560
|
+
acc += treeSelectionStrategy === "all" ? 1 + countAll(n.children) : countAll(n.children);
|
|
507
561
|
}
|
|
508
562
|
return acc;
|
|
509
563
|
}(treeOptions) ? /* @__PURE__ */ React.createElement(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ React.createElement(Minus, { className: "h-4 w-4" })
|
package/dist/index.d.ts
CHANGED
|
@@ -755,9 +755,9 @@ interface HeaderProps extends React$1.HTMLAttributes<HTMLElement>, VariantProps<
|
|
|
755
755
|
}
|
|
756
756
|
|
|
757
757
|
declare const inputVariants: (props?: ({
|
|
758
|
-
variant?: "
|
|
759
|
-
size?: "
|
|
760
|
-
radius?: "
|
|
758
|
+
variant?: "default" | "filled" | "borderless" | null | undefined;
|
|
759
|
+
size?: "default" | "small" | "large" | null | undefined;
|
|
760
|
+
radius?: "default" | "small" | "large" | "full" | null | undefined;
|
|
761
761
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
762
762
|
interface InputProps extends Omit<React$1.InputHTMLAttributes<HTMLInputElement>, 'size' | 'sufix' | 'prefix'>, VariantProps<typeof inputVariants> {
|
|
763
763
|
sufix?: React$1.ReactNode;
|
|
@@ -811,6 +811,7 @@ interface MultiSelectProps extends React$1.ButtonHTMLAttributes<HTMLButtonElemen
|
|
|
811
811
|
asChild?: boolean;
|
|
812
812
|
className?: string;
|
|
813
813
|
matchTriggerWidth?: boolean;
|
|
814
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
814
815
|
treeOptions?: MultiSelectTreeOption[];
|
|
815
816
|
treeSelectionStrategy?: 'leaf' | 'all';
|
|
816
817
|
selectAllLabel?: string;
|
|
@@ -942,7 +943,7 @@ declare const RadioGroup: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimi
|
|
|
942
943
|
declare const RadioGroupItem: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupItemProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
|
|
943
944
|
|
|
944
945
|
declare const ResizablePanelGroup: ({ className, ...props }: React$1.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => React$1.JSX.Element;
|
|
945
|
-
declare const ResizablePanel: React$1.ForwardRefExoticComponent<Omit<React$1.HTMLAttributes<
|
|
946
|
+
declare const ResizablePanel: React$1.ForwardRefExoticComponent<Omit<React$1.HTMLAttributes<HTMLDivElement | HTMLElement | HTMLButtonElement | HTMLOListElement | HTMLLIElement | HTMLAnchorElement | HTMLSpanElement | HTMLHeadingElement | HTMLParagraphElement | HTMLLabelElement | HTMLInputElement | HTMLUListElement | HTMLObjectElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLegendElement | HTMLLinkElement | HTMLMapElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPictureElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSourceElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLVideoElement>, "id" | "onResize"> & {
|
|
946
947
|
className?: string;
|
|
947
948
|
collapsedSize?: number | undefined;
|
|
948
949
|
collapsible?: boolean | undefined;
|
|
@@ -1097,9 +1098,9 @@ declare const TabsTrigger: React$1.ForwardRefExoticComponent<Omit<TabsPrimitive.
|
|
|
1097
1098
|
declare const TabsContent: React$1.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
1098
1099
|
|
|
1099
1100
|
declare const textareaVariants: (props?: ({
|
|
1100
|
-
variant?: "
|
|
1101
|
-
size?: "
|
|
1102
|
-
radius?: "
|
|
1101
|
+
variant?: "default" | "filled" | "borderless" | null | undefined;
|
|
1102
|
+
size?: "default" | "small" | "large" | null | undefined;
|
|
1103
|
+
radius?: "default" | "small" | "large" | "full" | null | undefined;
|
|
1103
1104
|
resize?: "default" | "both" | "horizontal" | "vertical" | "vertical-limited" | null | undefined;
|
|
1104
1105
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
1105
1106
|
interface TextareaProps extends React$1.ComponentProps<'textarea'>, VariantProps<typeof textareaVariants> {
|