@sesionario/blocks 1.7.0 → 1.9.0
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/index.cjs +684 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -1
- package/dist/index.d.ts +99 -1
- package/dist/index.js +683 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -456,6 +456,68 @@ function ConfirmDestructiveDialog({
|
|
|
456
456
|
] })
|
|
457
457
|
] }) });
|
|
458
458
|
}
|
|
459
|
+
var COLLAPSED_MAX_HEIGHT_REM = 11;
|
|
460
|
+
function ExpandableText({
|
|
461
|
+
children,
|
|
462
|
+
expandLabel,
|
|
463
|
+
collapseLabel,
|
|
464
|
+
className,
|
|
465
|
+
textClassName
|
|
466
|
+
}) {
|
|
467
|
+
const [expanded, setExpanded] = React6.useState(false);
|
|
468
|
+
const [overflowing, setOverflowing] = React6.useState(false);
|
|
469
|
+
const contentRef = React6.useRef(null);
|
|
470
|
+
React6.useEffect(() => {
|
|
471
|
+
setExpanded(false);
|
|
472
|
+
}, [children]);
|
|
473
|
+
React6.useLayoutEffect(() => {
|
|
474
|
+
const el = contentRef.current;
|
|
475
|
+
if (!el) return;
|
|
476
|
+
const measure = () => {
|
|
477
|
+
const rootFontSize = Number.parseFloat(
|
|
478
|
+
getComputedStyle(document.documentElement).fontSize
|
|
479
|
+
);
|
|
480
|
+
const maxPx = COLLAPSED_MAX_HEIGHT_REM * (rootFontSize || 16);
|
|
481
|
+
setOverflowing(el.scrollHeight > maxPx + 1);
|
|
482
|
+
};
|
|
483
|
+
measure();
|
|
484
|
+
const observer = new ResizeObserver(measure);
|
|
485
|
+
observer.observe(el);
|
|
486
|
+
return () => observer.disconnect();
|
|
487
|
+
}, [children]);
|
|
488
|
+
const collapsed = !expanded && overflowing;
|
|
489
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
|
|
490
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
491
|
+
"div",
|
|
492
|
+
{
|
|
493
|
+
className: cn(
|
|
494
|
+
collapsed && "max-h-[11rem] overflow-hidden scroll-fade-b"
|
|
495
|
+
),
|
|
496
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
497
|
+
"p",
|
|
498
|
+
{
|
|
499
|
+
ref: contentRef,
|
|
500
|
+
className: cn(
|
|
501
|
+
"whitespace-pre-wrap text-sm leading-relaxed",
|
|
502
|
+
textClassName
|
|
503
|
+
),
|
|
504
|
+
children
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
}
|
|
508
|
+
),
|
|
509
|
+
overflowing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
510
|
+
"button",
|
|
511
|
+
{
|
|
512
|
+
type: "button",
|
|
513
|
+
className: "text-sm font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 rounded-sm",
|
|
514
|
+
"aria-expanded": expanded,
|
|
515
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
516
|
+
children: expanded ? collapseLabel : expandLabel
|
|
517
|
+
}
|
|
518
|
+
) : null
|
|
519
|
+
] });
|
|
520
|
+
}
|
|
459
521
|
var MIN_SCALE = 1;
|
|
460
522
|
var MAX_SCALE = 4;
|
|
461
523
|
var DOUBLE_TAP_MS = 300;
|
|
@@ -1349,7 +1411,7 @@ function LanguageSwitcher({
|
|
|
1349
1411
|
const sizes = sizeClasses2[size];
|
|
1350
1412
|
const shapeClass = shapeClasses2[shape];
|
|
1351
1413
|
const reduceMotion = framerMotion.useReducedMotion();
|
|
1352
|
-
const
|
|
1414
|
+
const defaultLabels5 = {
|
|
1353
1415
|
language: labels.language ?? "Language"
|
|
1354
1416
|
};
|
|
1355
1417
|
if (variant === "mini") {
|
|
@@ -1359,7 +1421,7 @@ function LanguageSwitcher({
|
|
|
1359
1421
|
{
|
|
1360
1422
|
variant: "ghost",
|
|
1361
1423
|
size: "icon",
|
|
1362
|
-
"aria-label":
|
|
1424
|
+
"aria-label": defaultLabels5.language,
|
|
1363
1425
|
className: cn(sizes.buttonMini, shapeClass, className),
|
|
1364
1426
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Languages, { className: sizes.iconMini })
|
|
1365
1427
|
}
|
|
@@ -4286,6 +4348,18 @@ function useDebouncedValueStrict(value, delayMs) {
|
|
|
4286
4348
|
}, [value, delayMs]);
|
|
4287
4349
|
return debounced;
|
|
4288
4350
|
}
|
|
4351
|
+
function useMediaQuery2(query) {
|
|
4352
|
+
const [matches, setMatches] = React6.useState(false);
|
|
4353
|
+
React6.useEffect(() => {
|
|
4354
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
4355
|
+
const mql = window.matchMedia(query);
|
|
4356
|
+
const onChange = () => setMatches(mql.matches);
|
|
4357
|
+
onChange();
|
|
4358
|
+
mql.addEventListener("change", onChange);
|
|
4359
|
+
return () => mql.removeEventListener("change", onChange);
|
|
4360
|
+
}, [query]);
|
|
4361
|
+
return matches;
|
|
4362
|
+
}
|
|
4289
4363
|
function useSearchHotkey(options = {}) {
|
|
4290
4364
|
const { defaultOpen = false, disabled = false } = options;
|
|
4291
4365
|
const [open, setOpen] = React6.useState(defaultOpen);
|
|
@@ -4303,6 +4377,22 @@ function useSearchHotkey(options = {}) {
|
|
|
4303
4377
|
}, [disabled]);
|
|
4304
4378
|
return { open, setOpen, toggle };
|
|
4305
4379
|
}
|
|
4380
|
+
|
|
4381
|
+
// src/components/search/fuzzy.ts
|
|
4382
|
+
function normalize(value) {
|
|
4383
|
+
return value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
4384
|
+
}
|
|
4385
|
+
function fuzzyMatch(query, target) {
|
|
4386
|
+
const q = normalize(query.trim());
|
|
4387
|
+
if (!q) return true;
|
|
4388
|
+
const t = normalize(target);
|
|
4389
|
+
if (t.includes(q)) return true;
|
|
4390
|
+
let qi = 0;
|
|
4391
|
+
for (let ti = 0; ti < t.length && qi < q.length; ti++) {
|
|
4392
|
+
if (t[ti] === q[qi]) qi++;
|
|
4393
|
+
}
|
|
4394
|
+
return qi === q.length;
|
|
4395
|
+
}
|
|
4306
4396
|
function Command({
|
|
4307
4397
|
className,
|
|
4308
4398
|
...props
|
|
@@ -4420,6 +4510,19 @@ function CommandGroup({
|
|
|
4420
4510
|
}
|
|
4421
4511
|
);
|
|
4422
4512
|
}
|
|
4513
|
+
function CommandSeparator({
|
|
4514
|
+
className,
|
|
4515
|
+
...props
|
|
4516
|
+
}) {
|
|
4517
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4518
|
+
cmdk.Command.Separator,
|
|
4519
|
+
{
|
|
4520
|
+
"data-slot": "command-separator",
|
|
4521
|
+
className: cn("-mx-1 h-px bg-border", className),
|
|
4522
|
+
...props
|
|
4523
|
+
}
|
|
4524
|
+
);
|
|
4525
|
+
}
|
|
4423
4526
|
function CommandItem({
|
|
4424
4527
|
className,
|
|
4425
4528
|
...props
|
|
@@ -4436,23 +4539,584 @@ function CommandItem({
|
|
|
4436
4539
|
}
|
|
4437
4540
|
);
|
|
4438
4541
|
}
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4542
|
+
function OptionRow({
|
|
4543
|
+
entry,
|
|
4544
|
+
selected,
|
|
4545
|
+
onSelect,
|
|
4546
|
+
renderOption
|
|
4547
|
+
}) {
|
|
4548
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4549
|
+
CommandItem,
|
|
4550
|
+
{
|
|
4551
|
+
value: entry.value,
|
|
4552
|
+
keywords: [entry.label],
|
|
4553
|
+
onSelect,
|
|
4554
|
+
"data-checked": selected || void 0,
|
|
4555
|
+
children: [
|
|
4556
|
+
renderOption ? renderOption(entry.item, { selected }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.label }),
|
|
4557
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4558
|
+
lucideReact.CheckIcon,
|
|
4559
|
+
{
|
|
4560
|
+
className: cn(
|
|
4561
|
+
"ml-auto size-4 shrink-0",
|
|
4562
|
+
selected ? "opacity-100" : "opacity-0"
|
|
4563
|
+
)
|
|
4564
|
+
}
|
|
4565
|
+
)
|
|
4566
|
+
]
|
|
4567
|
+
},
|
|
4568
|
+
entry.value
|
|
4569
|
+
);
|
|
4443
4570
|
}
|
|
4444
|
-
function
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4571
|
+
function SearchablePickerList({
|
|
4572
|
+
query,
|
|
4573
|
+
onQueryChange,
|
|
4574
|
+
labels,
|
|
4575
|
+
isLoading,
|
|
4576
|
+
hasError,
|
|
4577
|
+
recommended,
|
|
4578
|
+
recent,
|
|
4579
|
+
results,
|
|
4580
|
+
selectedValues,
|
|
4581
|
+
mode,
|
|
4582
|
+
allowEmpty,
|
|
4583
|
+
emptyLabel,
|
|
4584
|
+
onSelectEmpty,
|
|
4585
|
+
onSelectItem,
|
|
4586
|
+
renderOption,
|
|
4587
|
+
createOption,
|
|
4588
|
+
onLoadMore,
|
|
4589
|
+
hasMore,
|
|
4590
|
+
isLoadingMore,
|
|
4591
|
+
listClassName
|
|
4592
|
+
}) {
|
|
4593
|
+
const hasPinned = recommended.length > 0 || recent.length > 0;
|
|
4594
|
+
const hasResults = results.length > 0;
|
|
4595
|
+
const showEmpty = !isLoading && !hasError && !hasPinned && !hasResults && !(allowEmpty && mode === "single");
|
|
4596
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Command, { shouldFilter: false, className: "flex h-full min-h-0 flex-col", children: [
|
|
4597
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4598
|
+
CommandInput,
|
|
4599
|
+
{
|
|
4600
|
+
placeholder: labels.searchPlaceholder,
|
|
4601
|
+
value: query,
|
|
4602
|
+
onValueChange: onQueryChange
|
|
4603
|
+
}
|
|
4604
|
+
),
|
|
4605
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CommandList, { className: cn("min-h-0 flex-1", listClassName), children: [
|
|
4606
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4607
|
+
"div",
|
|
4608
|
+
{
|
|
4609
|
+
className: "flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground",
|
|
4610
|
+
role: "status",
|
|
4611
|
+
children: [
|
|
4612
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin", "aria-hidden": true }),
|
|
4613
|
+
labels.loading
|
|
4614
|
+
]
|
|
4615
|
+
}
|
|
4616
|
+
) : null,
|
|
4617
|
+
hasError && !isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4618
|
+
"div",
|
|
4619
|
+
{
|
|
4620
|
+
className: "py-6 text-center text-sm text-destructive",
|
|
4621
|
+
role: "alert",
|
|
4622
|
+
children: labels.error
|
|
4623
|
+
}
|
|
4624
|
+
) : null,
|
|
4625
|
+
showEmpty ? /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: labels.empty }) : null,
|
|
4626
|
+
allowEmpty && mode === "single" && !query.trim() ? /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4627
|
+
CommandItem,
|
|
4628
|
+
{
|
|
4629
|
+
value: "__empty__",
|
|
4630
|
+
onSelect: () => onSelectEmpty?.(),
|
|
4631
|
+
"data-checked": !selectedValues.size || void 0,
|
|
4632
|
+
children: [
|
|
4633
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-muted-foreground", children: emptyLabel }),
|
|
4634
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4635
|
+
lucideReact.CheckIcon,
|
|
4636
|
+
{
|
|
4637
|
+
className: cn(
|
|
4638
|
+
"ml-auto size-4 shrink-0",
|
|
4639
|
+
selectedValues.size === 0 ? "opacity-100" : "opacity-0"
|
|
4640
|
+
)
|
|
4641
|
+
}
|
|
4642
|
+
)
|
|
4643
|
+
]
|
|
4644
|
+
}
|
|
4645
|
+
) }) : null,
|
|
4646
|
+
recommended.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: labels.recommended, children: recommended.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4647
|
+
OptionRow,
|
|
4648
|
+
{
|
|
4649
|
+
entry,
|
|
4650
|
+
selected: selectedValues.has(entry.value),
|
|
4651
|
+
onSelect: () => onSelectItem(entry.value),
|
|
4652
|
+
renderOption
|
|
4653
|
+
},
|
|
4654
|
+
`rec-${entry.value}`
|
|
4655
|
+
)) }) : null,
|
|
4656
|
+
recent.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: labels.recent, children: recent.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4657
|
+
OptionRow,
|
|
4658
|
+
{
|
|
4659
|
+
entry,
|
|
4660
|
+
selected: selectedValues.has(entry.value),
|
|
4661
|
+
onSelect: () => onSelectItem(entry.value),
|
|
4662
|
+
renderOption
|
|
4663
|
+
},
|
|
4664
|
+
`recent-${entry.value}`
|
|
4665
|
+
)) }) : null,
|
|
4666
|
+
hasPinned && hasResults ? /* @__PURE__ */ jsxRuntime.jsx(CommandSeparator, {}) : null,
|
|
4667
|
+
hasResults ? /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: hasPinned ? labels.results : void 0, children: results.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4668
|
+
OptionRow,
|
|
4669
|
+
{
|
|
4670
|
+
entry,
|
|
4671
|
+
selected: selectedValues.has(entry.value),
|
|
4672
|
+
onSelect: () => onSelectItem(entry.value),
|
|
4673
|
+
renderOption
|
|
4674
|
+
},
|
|
4675
|
+
`res-${entry.value}`
|
|
4676
|
+
)) }) : null,
|
|
4677
|
+
hasMore && onLoadMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4678
|
+
Button,
|
|
4679
|
+
{
|
|
4680
|
+
type: "button",
|
|
4681
|
+
variant: "ghost",
|
|
4682
|
+
size: "sm",
|
|
4683
|
+
className: "w-full",
|
|
4684
|
+
disabled: isLoadingMore,
|
|
4685
|
+
onClick: () => void onLoadMore(),
|
|
4686
|
+
children: isLoadingMore ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4687
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin", "aria-hidden": true }),
|
|
4688
|
+
labels.loading
|
|
4689
|
+
] }) : labels.loadMore
|
|
4690
|
+
}
|
|
4691
|
+
) }) : null,
|
|
4692
|
+
createOption ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4693
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommandSeparator, {}),
|
|
4694
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4695
|
+
CommandItem,
|
|
4696
|
+
{
|
|
4697
|
+
value: "__create__",
|
|
4698
|
+
onSelect: () => createOption.onSelect(),
|
|
4699
|
+
children: createOption.label
|
|
4700
|
+
}
|
|
4701
|
+
) })
|
|
4702
|
+
] }) : null
|
|
4703
|
+
] })
|
|
4704
|
+
] });
|
|
4454
4705
|
}
|
|
4455
4706
|
var defaultLabels3 = {
|
|
4707
|
+
placeholder: "Seleccionar\u2026",
|
|
4708
|
+
searchPlaceholder: "Buscar\u2026",
|
|
4709
|
+
empty: "No se encontraron resultados",
|
|
4710
|
+
loading: "Cargando\u2026",
|
|
4711
|
+
error: "No se pudo cargar la lista",
|
|
4712
|
+
recommended: "Recomendados",
|
|
4713
|
+
recent: "Recientes",
|
|
4714
|
+
results: "Resultados",
|
|
4715
|
+
done: "Listo",
|
|
4716
|
+
cancel: "Cancelar",
|
|
4717
|
+
clear: "Limpiar",
|
|
4718
|
+
selectedCount: (count) => count === 1 ? "1 seleccionado" : `${count} seleccionados`,
|
|
4719
|
+
emptyOption: "Ninguno",
|
|
4720
|
+
loadMore: "Cargar m\xE1s",
|
|
4721
|
+
dialogTitle: "Seleccionar"
|
|
4722
|
+
};
|
|
4723
|
+
function toListItems(items, getOptionValue, getOptionLabel) {
|
|
4724
|
+
if (!items?.length) return [];
|
|
4725
|
+
return items.map((item) => ({
|
|
4726
|
+
item,
|
|
4727
|
+
value: getOptionValue(item),
|
|
4728
|
+
label: getOptionLabel(item)
|
|
4729
|
+
}));
|
|
4730
|
+
}
|
|
4731
|
+
function dedupeByValue(items, exclude = /* @__PURE__ */ new Set()) {
|
|
4732
|
+
const seen = new Set(exclude);
|
|
4733
|
+
const out = [];
|
|
4734
|
+
for (const entry of items) {
|
|
4735
|
+
if (seen.has(entry.value)) continue;
|
|
4736
|
+
seen.add(entry.value);
|
|
4737
|
+
out.push(entry);
|
|
4738
|
+
}
|
|
4739
|
+
return out;
|
|
4740
|
+
}
|
|
4741
|
+
function matchesQuery(entry, query, getOptionKeywords) {
|
|
4742
|
+
if (!query.trim()) return true;
|
|
4743
|
+
if (fuzzyMatch(query, entry.label)) return true;
|
|
4744
|
+
return getOptionKeywords?.(entry.item)?.some(
|
|
4745
|
+
(keyword) => fuzzyMatch(query, keyword)
|
|
4746
|
+
) ?? false;
|
|
4747
|
+
}
|
|
4748
|
+
function SearchablePicker(props) {
|
|
4749
|
+
const {
|
|
4750
|
+
options,
|
|
4751
|
+
fetchOptions,
|
|
4752
|
+
getOptionValue,
|
|
4753
|
+
getOptionLabel,
|
|
4754
|
+
getOptionKeywords,
|
|
4755
|
+
renderOption,
|
|
4756
|
+
renderValue,
|
|
4757
|
+
pinned,
|
|
4758
|
+
labels: userLabels,
|
|
4759
|
+
minQueryLength = 0,
|
|
4760
|
+
debounceMs = 200,
|
|
4761
|
+
disabled,
|
|
4762
|
+
open: openProp,
|
|
4763
|
+
onOpenChange,
|
|
4764
|
+
clearable,
|
|
4765
|
+
allowEmpty,
|
|
4766
|
+
emptyLabel,
|
|
4767
|
+
keepOpenOnSelect,
|
|
4768
|
+
maxSelected,
|
|
4769
|
+
createOption,
|
|
4770
|
+
onLoadMore,
|
|
4771
|
+
hasMore,
|
|
4772
|
+
className,
|
|
4773
|
+
triggerClassName: triggerClassName2,
|
|
4774
|
+
id,
|
|
4775
|
+
"aria-labelledby": ariaLabelledBy,
|
|
4776
|
+
"aria-label": ariaLabel
|
|
4777
|
+
} = props;
|
|
4778
|
+
const mode = props.mode ?? "single";
|
|
4779
|
+
const labels = { ...defaultLabels3, ...userLabels };
|
|
4780
|
+
const resolvedEmptyLabel = emptyLabel ?? labels.emptyOption;
|
|
4781
|
+
const isMobile = useMediaQuery2("(max-width: 767px)");
|
|
4782
|
+
const generatedId = React6.useId();
|
|
4783
|
+
const triggerId = id ?? generatedId;
|
|
4784
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React6.useState(false);
|
|
4785
|
+
const open = openProp ?? uncontrolledOpen;
|
|
4786
|
+
const setOpen = React6.useCallback(
|
|
4787
|
+
(next) => {
|
|
4788
|
+
onOpenChange?.(next);
|
|
4789
|
+
if (openProp === void 0) setUncontrolledOpen(next);
|
|
4790
|
+
},
|
|
4791
|
+
[onOpenChange, openProp]
|
|
4792
|
+
);
|
|
4793
|
+
const [query, setQuery] = React6.useState("");
|
|
4794
|
+
const [remoteItems, setRemoteItems] = React6.useState([]);
|
|
4795
|
+
const [isLoading, setIsLoading] = React6.useState(false);
|
|
4796
|
+
const [hasError, setHasError] = React6.useState(false);
|
|
4797
|
+
const [isLoadingMore, setIsLoadingMore] = React6.useState(false);
|
|
4798
|
+
const debouncedQuery = useDebouncedValue(query, debounceMs);
|
|
4799
|
+
const requestIdRef = React6.useRef(0);
|
|
4800
|
+
const knownItemsRef = React6.useRef(/* @__PURE__ */ new Map());
|
|
4801
|
+
const rememberItems = React6.useCallback(
|
|
4802
|
+
(items) => {
|
|
4803
|
+
for (const item of items) {
|
|
4804
|
+
knownItemsRef.current.set(getOptionValue(item), item);
|
|
4805
|
+
}
|
|
4806
|
+
},
|
|
4807
|
+
[getOptionValue]
|
|
4808
|
+
);
|
|
4809
|
+
React6.useEffect(() => {
|
|
4810
|
+
if (options) rememberItems(options);
|
|
4811
|
+
if (pinned?.recommended) rememberItems(pinned.recommended);
|
|
4812
|
+
if (pinned?.recent) rememberItems(pinned.recent);
|
|
4813
|
+
}, [options, pinned, rememberItems]);
|
|
4814
|
+
React6.useEffect(() => {
|
|
4815
|
+
if (!open) {
|
|
4816
|
+
setQuery("");
|
|
4817
|
+
setRemoteItems([]);
|
|
4818
|
+
setHasError(false);
|
|
4819
|
+
setIsLoading(false);
|
|
4820
|
+
}
|
|
4821
|
+
}, [open]);
|
|
4822
|
+
const trimmedDebounced = debouncedQuery.trim();
|
|
4823
|
+
const shouldFetch = Boolean(fetchOptions) && open && trimmedDebounced.length >= minQueryLength && (trimmedDebounced.length > 0 || !options);
|
|
4824
|
+
React6.useEffect(() => {
|
|
4825
|
+
if (!shouldFetch || !fetchOptions) {
|
|
4826
|
+
if (!trimmedDebounced) {
|
|
4827
|
+
setRemoteItems([]);
|
|
4828
|
+
setHasError(false);
|
|
4829
|
+
setIsLoading(false);
|
|
4830
|
+
}
|
|
4831
|
+
return;
|
|
4832
|
+
}
|
|
4833
|
+
const requestId = ++requestIdRef.current;
|
|
4834
|
+
setIsLoading(true);
|
|
4835
|
+
setHasError(false);
|
|
4836
|
+
fetchOptions(trimmedDebounced).then((result) => {
|
|
4837
|
+
if (requestIdRef.current !== requestId) return;
|
|
4838
|
+
setRemoteItems(result);
|
|
4839
|
+
rememberItems(result);
|
|
4840
|
+
}).catch(() => {
|
|
4841
|
+
if (requestIdRef.current !== requestId) return;
|
|
4842
|
+
setRemoteItems([]);
|
|
4843
|
+
setHasError(true);
|
|
4844
|
+
}).finally(() => {
|
|
4845
|
+
if (requestIdRef.current !== requestId) return;
|
|
4846
|
+
setIsLoading(false);
|
|
4847
|
+
});
|
|
4848
|
+
}, [shouldFetch, fetchOptions, trimmedDebounced, rememberItems]);
|
|
4849
|
+
const selectedValues = React6.useMemo(() => {
|
|
4850
|
+
if (mode === "multiple") {
|
|
4851
|
+
const multiValue = props.value ?? [];
|
|
4852
|
+
return new Set(multiValue);
|
|
4853
|
+
}
|
|
4854
|
+
const singleValue = props.value;
|
|
4855
|
+
return singleValue ? /* @__PURE__ */ new Set([singleValue]) : /* @__PURE__ */ new Set();
|
|
4856
|
+
}, [mode, props]);
|
|
4857
|
+
const selectedValueKey = mode === "multiple" ? (props.value ?? []).join("\0") : props.value ?? "";
|
|
4858
|
+
const selectedItems = React6.useMemo(() => {
|
|
4859
|
+
const values = mode === "multiple" ? selectedValueKey ? selectedValueKey.split("\0") : [] : selectedValueKey ? [selectedValueKey] : [];
|
|
4860
|
+
return values.map((value) => knownItemsRef.current.get(value)).filter((item) => item !== void 0);
|
|
4861
|
+
}, [mode, selectedValueKey, options, pinned, remoteItems]);
|
|
4862
|
+
const queryForFilter = query.trim();
|
|
4863
|
+
const recommended = React6.useMemo(() => {
|
|
4864
|
+
if (queryForFilter) return [];
|
|
4865
|
+
const pinnedValues = /* @__PURE__ */ new Set();
|
|
4866
|
+
const items = dedupeByValue(
|
|
4867
|
+
toListItems(pinned?.recommended, getOptionValue, getOptionLabel)
|
|
4868
|
+
);
|
|
4869
|
+
for (const entry of items) pinnedValues.add(entry.value);
|
|
4870
|
+
return items;
|
|
4871
|
+
}, [queryForFilter, pinned?.recommended, getOptionValue, getOptionLabel]);
|
|
4872
|
+
const recent = React6.useMemo(() => {
|
|
4873
|
+
if (queryForFilter) return [];
|
|
4874
|
+
const exclude = new Set(recommended.map((e) => e.value));
|
|
4875
|
+
return dedupeByValue(
|
|
4876
|
+
toListItems(pinned?.recent, getOptionValue, getOptionLabel),
|
|
4877
|
+
exclude
|
|
4878
|
+
);
|
|
4879
|
+
}, [
|
|
4880
|
+
queryForFilter,
|
|
4881
|
+
pinned?.recent,
|
|
4882
|
+
recommended,
|
|
4883
|
+
getOptionValue,
|
|
4884
|
+
getOptionLabel
|
|
4885
|
+
]);
|
|
4886
|
+
const pinnedValueSet = React6.useMemo(() => {
|
|
4887
|
+
const set = /* @__PURE__ */ new Set();
|
|
4888
|
+
for (const entry of recommended) set.add(entry.value);
|
|
4889
|
+
for (const entry of recent) set.add(entry.value);
|
|
4890
|
+
return set;
|
|
4891
|
+
}, [recommended, recent]);
|
|
4892
|
+
const results = React6.useMemo(() => {
|
|
4893
|
+
const usingRemote = Boolean(fetchOptions) && trimmedDebounced.length >= minQueryLength && (trimmedDebounced.length > 0 || !options);
|
|
4894
|
+
if (usingRemote) {
|
|
4895
|
+
return dedupeByValue(
|
|
4896
|
+
toListItems(remoteItems, getOptionValue, getOptionLabel),
|
|
4897
|
+
queryForFilter ? /* @__PURE__ */ new Set() : pinnedValueSet
|
|
4898
|
+
);
|
|
4899
|
+
}
|
|
4900
|
+
const staticItems = toListItems(options, getOptionValue, getOptionLabel);
|
|
4901
|
+
const filtered = staticItems.filter(
|
|
4902
|
+
(entry) => matchesQuery(entry, queryForFilter, getOptionKeywords)
|
|
4903
|
+
);
|
|
4904
|
+
return dedupeByValue(filtered, queryForFilter ? /* @__PURE__ */ new Set() : pinnedValueSet);
|
|
4905
|
+
}, [
|
|
4906
|
+
fetchOptions,
|
|
4907
|
+
trimmedDebounced,
|
|
4908
|
+
minQueryLength,
|
|
4909
|
+
options,
|
|
4910
|
+
remoteItems,
|
|
4911
|
+
getOptionValue,
|
|
4912
|
+
getOptionLabel,
|
|
4913
|
+
getOptionKeywords,
|
|
4914
|
+
queryForFilter,
|
|
4915
|
+
pinnedValueSet
|
|
4916
|
+
]);
|
|
4917
|
+
const closeOnSelect = keepOpenOnSelect !== void 0 ? !keepOpenOnSelect : mode === "single";
|
|
4918
|
+
const handleSelectEmpty = React6.useCallback(() => {
|
|
4919
|
+
if (mode === "single") {
|
|
4920
|
+
props.onValueChange?.(
|
|
4921
|
+
null
|
|
4922
|
+
);
|
|
4923
|
+
}
|
|
4924
|
+
if (closeOnSelect) setOpen(false);
|
|
4925
|
+
}, [mode, props, closeOnSelect, setOpen]);
|
|
4926
|
+
const handleSelectItem = React6.useCallback(
|
|
4927
|
+
(value) => {
|
|
4928
|
+
if (mode === "multiple") {
|
|
4929
|
+
const current = props.value ?? [];
|
|
4930
|
+
const onChange = props.onValueChange;
|
|
4931
|
+
const exists = current.includes(value);
|
|
4932
|
+
if (exists) {
|
|
4933
|
+
onChange?.(current.filter((v) => v !== value));
|
|
4934
|
+
} else if (maxSelected !== void 0 && current.length >= maxSelected) {
|
|
4935
|
+
return;
|
|
4936
|
+
} else {
|
|
4937
|
+
onChange?.([...current, value]);
|
|
4938
|
+
}
|
|
4939
|
+
if (closeOnSelect) setOpen(false);
|
|
4940
|
+
return;
|
|
4941
|
+
}
|
|
4942
|
+
props.onValueChange?.(
|
|
4943
|
+
value
|
|
4944
|
+
);
|
|
4945
|
+
if (closeOnSelect) setOpen(false);
|
|
4946
|
+
},
|
|
4947
|
+
[mode, props, maxSelected, closeOnSelect, setOpen]
|
|
4948
|
+
);
|
|
4949
|
+
const handleClear = React6.useCallback(
|
|
4950
|
+
(event) => {
|
|
4951
|
+
event.preventDefault();
|
|
4952
|
+
event.stopPropagation();
|
|
4953
|
+
if (mode === "multiple") {
|
|
4954
|
+
props.onValueChange?.(
|
|
4955
|
+
[]
|
|
4956
|
+
);
|
|
4957
|
+
} else {
|
|
4958
|
+
props.onValueChange?.(null);
|
|
4959
|
+
}
|
|
4960
|
+
},
|
|
4961
|
+
[mode, props]
|
|
4962
|
+
);
|
|
4963
|
+
const handleLoadMore = React6.useCallback(async () => {
|
|
4964
|
+
if (!onLoadMore || isLoadingMore) return;
|
|
4965
|
+
setIsLoadingMore(true);
|
|
4966
|
+
try {
|
|
4967
|
+
await onLoadMore();
|
|
4968
|
+
} finally {
|
|
4969
|
+
setIsLoadingMore(false);
|
|
4970
|
+
}
|
|
4971
|
+
}, [onLoadMore, isLoadingMore]);
|
|
4972
|
+
const triggerLabel = React6.useMemo(() => {
|
|
4973
|
+
if (renderValue) {
|
|
4974
|
+
if (mode === "multiple") {
|
|
4975
|
+
return renderValue(selectedItems);
|
|
4976
|
+
}
|
|
4977
|
+
return renderValue(selectedItems[0] ?? null);
|
|
4978
|
+
}
|
|
4979
|
+
if (mode === "multiple") {
|
|
4980
|
+
const count = selectedValues.size;
|
|
4981
|
+
if (count === 0) {
|
|
4982
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: labels.placeholder });
|
|
4983
|
+
}
|
|
4984
|
+
if (selectedItems.length === 1) {
|
|
4985
|
+
return getOptionLabel(selectedItems[0]);
|
|
4986
|
+
}
|
|
4987
|
+
return labels.selectedCount(count);
|
|
4988
|
+
}
|
|
4989
|
+
if (selectedValues.size === 0) {
|
|
4990
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: allowEmpty ? resolvedEmptyLabel : labels.placeholder });
|
|
4991
|
+
}
|
|
4992
|
+
if (selectedItems[0]) {
|
|
4993
|
+
return getOptionLabel(selectedItems[0]);
|
|
4994
|
+
}
|
|
4995
|
+
const only = [...selectedValues][0];
|
|
4996
|
+
return only ?? labels.placeholder;
|
|
4997
|
+
}, [
|
|
4998
|
+
renderValue,
|
|
4999
|
+
mode,
|
|
5000
|
+
selectedItems,
|
|
5001
|
+
selectedValues,
|
|
5002
|
+
labels,
|
|
5003
|
+
getOptionLabel,
|
|
5004
|
+
allowEmpty,
|
|
5005
|
+
resolvedEmptyLabel
|
|
5006
|
+
]);
|
|
5007
|
+
const showClear = clearable && !disabled && (mode === "multiple" ? selectedValues.size > 0 : selectedValues.size > 0);
|
|
5008
|
+
const list = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5009
|
+
SearchablePickerList,
|
|
5010
|
+
{
|
|
5011
|
+
query,
|
|
5012
|
+
onQueryChange: setQuery,
|
|
5013
|
+
labels,
|
|
5014
|
+
isLoading,
|
|
5015
|
+
hasError,
|
|
5016
|
+
recommended,
|
|
5017
|
+
recent,
|
|
5018
|
+
results,
|
|
5019
|
+
selectedValues,
|
|
5020
|
+
mode,
|
|
5021
|
+
allowEmpty,
|
|
5022
|
+
emptyLabel: resolvedEmptyLabel,
|
|
5023
|
+
onSelectEmpty: handleSelectEmpty,
|
|
5024
|
+
onSelectItem: handleSelectItem,
|
|
5025
|
+
renderOption,
|
|
5026
|
+
createOption,
|
|
5027
|
+
onLoadMore: onLoadMore ? handleLoadMore : void 0,
|
|
5028
|
+
hasMore,
|
|
5029
|
+
isLoadingMore,
|
|
5030
|
+
listClassName: isMobile ? "max-h-[min(50vh,360px)]" : "max-h-72"
|
|
5031
|
+
}
|
|
5032
|
+
);
|
|
5033
|
+
const triggerButton = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5034
|
+
Button,
|
|
5035
|
+
{
|
|
5036
|
+
type: "button",
|
|
5037
|
+
variant: "outline",
|
|
5038
|
+
role: "combobox",
|
|
5039
|
+
id: triggerId,
|
|
5040
|
+
"aria-expanded": open,
|
|
5041
|
+
"aria-labelledby": ariaLabelledBy,
|
|
5042
|
+
"aria-label": ariaLabel ?? labels.placeholder,
|
|
5043
|
+
disabled,
|
|
5044
|
+
className: cn("w-full justify-between font-normal", triggerClassName2),
|
|
5045
|
+
children: [
|
|
5046
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: triggerLabel }),
|
|
5047
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "ml-2 size-4 shrink-0 opacity-50", "aria-hidden": true })
|
|
5048
|
+
]
|
|
5049
|
+
}
|
|
5050
|
+
);
|
|
5051
|
+
const clearButton = showClear ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5052
|
+
Button,
|
|
5053
|
+
{
|
|
5054
|
+
type: "button",
|
|
5055
|
+
variant: "ghost",
|
|
5056
|
+
size: "icon-sm",
|
|
5057
|
+
"aria-label": labels.clear,
|
|
5058
|
+
disabled,
|
|
5059
|
+
className: "shrink-0",
|
|
5060
|
+
onClick: handleClear,
|
|
5061
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4" })
|
|
5062
|
+
}
|
|
5063
|
+
) : null;
|
|
5064
|
+
if (isMobile) {
|
|
5065
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex w-full items-center gap-1", className), children: [
|
|
5066
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5067
|
+
"div",
|
|
5068
|
+
{
|
|
5069
|
+
className: "min-w-0 flex-1",
|
|
5070
|
+
onClick: () => {
|
|
5071
|
+
if (!disabled) setOpen(true);
|
|
5072
|
+
},
|
|
5073
|
+
children: triggerButton
|
|
5074
|
+
}
|
|
5075
|
+
),
|
|
5076
|
+
clearButton,
|
|
5077
|
+
/* @__PURE__ */ jsxRuntime.jsx(Drawer, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DrawerContent, { className: "max-h-[90vh]", children: [
|
|
5078
|
+
/* @__PURE__ */ jsxRuntime.jsx(DrawerHeader, { className: "text-left", children: /* @__PURE__ */ jsxRuntime.jsx(DrawerTitle, { children: labels.dialogTitle }) }),
|
|
5079
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-hidden px-2 pb-2", children: list }),
|
|
5080
|
+
mode === "multiple" ? /* @__PURE__ */ jsxRuntime.jsxs(DrawerFooter, { className: "flex-row gap-2", children: [
|
|
5081
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5082
|
+
Button,
|
|
5083
|
+
{
|
|
5084
|
+
type: "button",
|
|
5085
|
+
variant: "outline",
|
|
5086
|
+
className: "flex-1",
|
|
5087
|
+
onClick: () => setOpen(false),
|
|
5088
|
+
children: labels.cancel
|
|
5089
|
+
}
|
|
5090
|
+
),
|
|
5091
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5092
|
+
Button,
|
|
5093
|
+
{
|
|
5094
|
+
type: "button",
|
|
5095
|
+
className: "flex-1",
|
|
5096
|
+
onClick: () => setOpen(false),
|
|
5097
|
+
children: labels.done
|
|
5098
|
+
}
|
|
5099
|
+
)
|
|
5100
|
+
] }) : null
|
|
5101
|
+
] }) })
|
|
5102
|
+
] });
|
|
5103
|
+
}
|
|
5104
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex w-full items-center gap-1", className), children: [
|
|
5105
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, modal: true, children: [
|
|
5106
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: triggerButton }),
|
|
5107
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5108
|
+
PopoverContent,
|
|
5109
|
+
{
|
|
5110
|
+
className: "w-[var(--radix-popover-trigger-width)] min-w-[240px] p-0",
|
|
5111
|
+
align: "start",
|
|
5112
|
+
children: list
|
|
5113
|
+
}
|
|
5114
|
+
)
|
|
5115
|
+
] }) }),
|
|
5116
|
+
clearButton
|
|
5117
|
+
] });
|
|
5118
|
+
}
|
|
5119
|
+
var defaultLabels4 = {
|
|
4456
5120
|
placeholder: "Buscar en toda la plataforma\u2026",
|
|
4457
5121
|
dialogTitle: "Buscar",
|
|
4458
5122
|
dialogDescription: "Busca funcionalidades, eventos, documentos y m\xE1s",
|
|
@@ -4486,7 +5150,7 @@ function SearchCommand({
|
|
|
4486
5150
|
debounceMs = 200,
|
|
4487
5151
|
className
|
|
4488
5152
|
}) {
|
|
4489
|
-
const labels = { ...
|
|
5153
|
+
const labels = { ...defaultLabels4, ...userLabels };
|
|
4490
5154
|
const [query, setQuery] = React6.useState("");
|
|
4491
5155
|
const [hits, setHits] = React6.useState([]);
|
|
4492
5156
|
const [isLoading, setIsLoading] = React6.useState(false);
|
|
@@ -5367,18 +6031,6 @@ function ChatMessageList({
|
|
|
5367
6031
|
/* @__PURE__ */ jsxRuntime.jsx(MessageScrollerButton, {})
|
|
5368
6032
|
] }) });
|
|
5369
6033
|
}
|
|
5370
|
-
function useMediaQuery2(query) {
|
|
5371
|
-
const [matches, setMatches] = React6.useState(false);
|
|
5372
|
-
React6.useEffect(() => {
|
|
5373
|
-
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
5374
|
-
const mql = window.matchMedia(query);
|
|
5375
|
-
const onChange = () => setMatches(mql.matches);
|
|
5376
|
-
onChange();
|
|
5377
|
-
mql.addEventListener("change", onChange);
|
|
5378
|
-
return () => mql.removeEventListener("change", onChange);
|
|
5379
|
-
}, [query]);
|
|
5380
|
-
return matches;
|
|
5381
|
-
}
|
|
5382
6034
|
var RECONNECT_DELAY_MS = 2e3;
|
|
5383
6035
|
function useSupportConversation({
|
|
5384
6036
|
client,
|
|
@@ -6029,6 +6681,7 @@ exports.EmptyMedia = EmptyMedia;
|
|
|
6029
6681
|
exports.EmptyState = EmptyState;
|
|
6030
6682
|
exports.EmptyTitle = EmptyTitle;
|
|
6031
6683
|
exports.ErrorState = ErrorState;
|
|
6684
|
+
exports.ExpandableText = ExpandableText;
|
|
6032
6685
|
exports.ImageLightbox = ImageLightbox;
|
|
6033
6686
|
exports.LanguageContext = LanguageContext;
|
|
6034
6687
|
exports.LanguageSwitcher = LanguageSwitcher;
|
|
@@ -6054,6 +6707,7 @@ exports.MexicoMap = MexicoMap;
|
|
|
6054
6707
|
exports.OrgSwitcher = OrgSwitcher;
|
|
6055
6708
|
exports.PhoneInput = PhoneInput;
|
|
6056
6709
|
exports.SearchCommand = SearchCommand;
|
|
6710
|
+
exports.SearchablePicker = SearchablePicker;
|
|
6057
6711
|
exports.SupportMessengerProvider = SupportMessengerProvider;
|
|
6058
6712
|
exports.ThemeSwitcher = ThemeSwitcher;
|
|
6059
6713
|
exports.VerifiedProfessionalBadge = VerifiedProfessionalBadge;
|
|
@@ -6077,6 +6731,7 @@ exports.useDebouncedValue = useDebouncedValue;
|
|
|
6077
6731
|
exports.useDebouncedValueStrict = useDebouncedValueStrict;
|
|
6078
6732
|
exports.useHlsPlayback = useHlsPlayback;
|
|
6079
6733
|
exports.useLanguageContext = useLanguageContext;
|
|
6734
|
+
exports.useMediaQuery = useMediaQuery2;
|
|
6080
6735
|
exports.usePlaybackStats = usePlaybackStats;
|
|
6081
6736
|
exports.useSearchHotkey = useSearchHotkey;
|
|
6082
6737
|
exports.useSupportConversation = useSupportConversation;
|