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(nl.slice(Math.max(0, idx - 1)))) score += 5;
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((a, b) => a.score === b.score ? a.idx - b.idx : a.score - b.score);
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((val) => {
211
- if (!treeOptions) return void 0;
212
- const stack = [...treeOptions];
213
- while (stack.length) {
214
- const n = stack.pop();
215
- if (n.value === val) return n.label;
216
- if (n.children) stack.push(...n.children);
217
- }
218
- return void 0;
219
- }, [treeOptions]);
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(new Set(norm(q).split(/\s+/).filter(Boolean))).sort((a, b) => b.length - a.length);
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) merged.push({ ...r });
273
- else merged[merged.length - 1].end = Math.max(merged[merged.length - 1].end, r.end);
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) parts.push(/* @__PURE__ */ React.createElement("span", { key: `t-${i}-pre` }, label.slice(cursor, r.start)));
279
- parts.push(/* @__PURE__ */ React.createElement("span", { key: `t-${i}-hl`, className: "bg-blue-100/60 text-grey-900 rounded-[2px] px-0.5" }, label.slice(r.start, r.end)));
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) parts.push(/* @__PURE__ */ React.createElement("span", { key: "t-last" }, label.slice(cursor)));
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(([categoryName, categoryOptions]) => {
429
- const filtered = categoryOptions.filter(
430
- (opt) => !query || effectiveOptions.some((eff) => eff.value === opt.value && filteredOptions.some((filt) => filt.value === opt.value))
431
- );
432
- if (!filtered.length) return null;
433
- 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) => {
434
- const isSelected = selectedValues.includes(option.value);
435
- return /* @__PURE__ */ React.createElement(
436
- CommandItem,
437
- {
438
- key: option.value,
439
- onSelect: () => toggleOption(option.value),
440
- className: "cursor-pointer"
441
- },
442
- /* @__PURE__ */ React.createElement(
443
- "div",
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
- className: cn(
446
- "flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400",
447
- isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
448
- )
471
+ key: option.value,
472
+ onSelect: () => toggleOption(option.value),
473
+ className: "cursor-pointer"
449
474
  },
450
- /* @__PURE__ */ React.createElement(Check, { className: "h-4 w-4" })
451
- ),
452
- /* @__PURE__ */ React.createElement("span", { className: "text-grey-800" }, highlight(option.label, query))
453
- );
454
- }));
455
- }) : filteredOptions.map((option) => {
456
- const isSelected = selectedValues.includes(option.value);
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("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, 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" })), /* @__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 acc += treeSelectionStrategy === "all" ? 1 + countAll(n.children) : countAll(n.children);
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?: "filled" | "default" | "borderless" | null | undefined;
759
- size?: "small" | "large" | "default" | null | undefined;
760
- radius?: "small" | "large" | "default" | "full" | null | undefined;
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<HTMLButtonElement | HTMLElement | HTMLDivElement | HTMLOListElement | HTMLLIElement | HTMLAnchorElement | HTMLSpanElement | HTMLHeadingElement | HTMLParagraphElement | HTMLInputElement | HTMLLabelElement | 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 | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
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?: "filled" | "default" | "borderless" | null | undefined;
1101
- size?: "small" | "large" | "default" | null | undefined;
1102
- radius?: "small" | "large" | "default" | "full" | null | undefined;
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> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lecom-ui",
3
- "version": "5.3.41",
3
+ "version": "5.3.42",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "dist/index.js",