@sesionario/blocks 1.20.0 → 1.22.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/README.md CHANGED
@@ -6,6 +6,81 @@ This package is the Sesionario-specific successor to `@algenium/blocks`. It ship
6
6
 
7
7
  Shared feedback patterns include `ConfirmDestructiveDialog` (confirm before delete/mute and similar irreversible actions).
8
8
 
9
+ ### Read-first editable sections (`EditableSection`, `DataList`, `FieldMessage`)
10
+
11
+ Settings and profile data should be readable by default, then turn into a real `<form>` when the person chooses Edit. The primitives are chrome-free — no Card, border, or title — so you place actions in your own layout (`CardAction`, page header, dialog, or a bare section).
12
+
13
+ ```tsx
14
+ import {
15
+ EditableSection,
16
+ DataList,
17
+ DataListItem,
18
+ FieldMessage,
19
+ } from "@sesionario/blocks";
20
+
21
+ <EditableSection
22
+ labelledBy="fiscal-title"
23
+ isDirty={dirty}
24
+ onDiscard={() => reset()}
25
+ onSave={async () => {
26
+ /* throw on validation/API failure so edit mode stays open */
27
+ await save();
28
+ }}
29
+ labels={{
30
+ edit: t("edit"),
31
+ save: t("save"),
32
+ saving: t("saving"),
33
+ cancel: t("cancel"),
34
+ saved: t("saved"),
35
+ }}
36
+ readView={() => (
37
+ <DataList>
38
+ <DataListItem label="RFC">{rfc}</DataListItem>
39
+ </DataList>
40
+ )}
41
+ editView={() => (
42
+ <div className="flex flex-col gap-1.5">
43
+ <label htmlFor="rfc">RFC</label>
44
+ <input id="rfc" value={rfc} onChange={...} aria-invalid={!!error} aria-describedby="rfc-err" />
45
+ <FieldMessage id="rfc-err">{error}</FieldMessage>
46
+ </div>
47
+ )}
48
+ >
49
+ {({ actions, content, status }) => (
50
+ <Card>
51
+ <CardHeader>
52
+ <CardTitle id="fiscal-title">Datos fiscales</CardTitle>
53
+ <CardAction>{actions}</CardAction>
54
+ </CardHeader>
55
+ <CardContent>
56
+ {content}
57
+ {status}
58
+ </CardContent>
59
+ </Card>
60
+ )}
61
+ </EditableSection>
62
+ ```
63
+
64
+ Headless alternative: `useEditableSection` for card-less surfaces (dialogs, table rows, page headers).
65
+
66
+ Optional progressive-enhancement CSS for a smoother height change (Chromium 129+; no-op elsewhere). Honor reduced motion:
67
+
68
+ ```css
69
+ @supports (interpolate-size: allow-keywords) {
70
+ .sesionario-editable-section-content {
71
+ interpolate-size: allow-keywords;
72
+ transition: min-height 200ms ease;
73
+ }
74
+ }
75
+ @media (prefers-reduced-motion: reduce) {
76
+ .sesionario-editable-section-content {
77
+ transition: none;
78
+ }
79
+ }
80
+ ```
81
+
82
+ Pass `stableHeight` for small (1–2 field) sections if you want later toggles to keep a cached `min-height`.
83
+
9
84
  ## Install
10
85
 
11
86
  ```bash
package/dist/index.cjs CHANGED
@@ -456,6 +456,348 @@ function ConfirmDestructiveDialog({
456
456
  ] })
457
457
  ] }) });
458
458
  }
459
+
460
+ // src/components/editable/types.ts
461
+ var DEFAULT_EDITABLE_SECTION_LABELS = {
462
+ edit: "Editar",
463
+ save: "Guardar",
464
+ saving: "Guardando\u2026",
465
+ cancel: "Cancelar",
466
+ saved: "Guardado",
467
+ discardTitle: "\xBFDescartar cambios?",
468
+ discardDescription: "Si sales ahora, se perder\xE1n los cambios que no hayas guardado.",
469
+ discardConfirm: "Descartar",
470
+ discardCancel: "Seguir editando"
471
+ };
472
+
473
+ // src/components/editable/useEditableSection.ts
474
+ function focusFirstField(container) {
475
+ if (!container) return;
476
+ const target = container.querySelector(
477
+ "[data-autofocus], input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), [contenteditable='true']"
478
+ );
479
+ target?.focus();
480
+ }
481
+ function useEditableSection({
482
+ onSave,
483
+ onDiscard,
484
+ isDirty = false,
485
+ labelledBy,
486
+ title,
487
+ labels,
488
+ stableHeight = false
489
+ }) {
490
+ const resolvedLabels = {
491
+ ...DEFAULT_EDITABLE_SECTION_LABELS,
492
+ ...labels
493
+ };
494
+ const [mode, setMode] = React7.useState("reading");
495
+ const [status, setStatus] = React7.useState(null);
496
+ const [confirmOpen, setConfirmOpen] = React7.useState(false);
497
+ const [minHeightPx, setMinHeightPx] = React7.useState(void 0);
498
+ const contentRef = React7.useRef(null);
499
+ const editButtonRef = React7.useRef(null);
500
+ const measuredHeightRef = React7.useRef(0);
501
+ const shouldFocusEditRef = React7.useRef(false);
502
+ const shouldFocusFirstFieldRef = React7.useRef(false);
503
+ const editButtonId = React7.useId();
504
+ const contentFormId = React7.useId();
505
+ const isEditing = mode === "editing" || mode === "saving";
506
+ const isSaving = mode === "saving";
507
+ React7.useEffect(() => {
508
+ if (mode === "reading" && shouldFocusEditRef.current) {
509
+ shouldFocusEditRef.current = false;
510
+ editButtonRef.current?.focus();
511
+ return;
512
+ }
513
+ if (mode === "editing" && shouldFocusFirstFieldRef.current) {
514
+ shouldFocusFirstFieldRef.current = false;
515
+ const invalid = contentRef.current?.querySelector(
516
+ "[aria-invalid='true']"
517
+ );
518
+ if (invalid) {
519
+ invalid.focus();
520
+ return;
521
+ }
522
+ focusFirstField(contentRef.current);
523
+ }
524
+ }, [mode]);
525
+ const exitToReading = React7.useCallback(() => {
526
+ setConfirmOpen(false);
527
+ shouldFocusEditRef.current = true;
528
+ setMode("reading");
529
+ onDiscard?.();
530
+ }, [onDiscard]);
531
+ const startEdit = React7.useCallback(() => {
532
+ setStatus(null);
533
+ shouldFocusFirstFieldRef.current = true;
534
+ setMode("editing");
535
+ }, []);
536
+ const requestCancel = React7.useCallback(() => {
537
+ if (isSaving) return;
538
+ if (isDirty) {
539
+ setConfirmOpen(true);
540
+ return;
541
+ }
542
+ exitToReading();
543
+ }, [exitToReading, isDirty, isSaving]);
544
+ const handleSubmit = React7.useCallback(
545
+ (event) => {
546
+ event.preventDefault();
547
+ if (isSaving) return;
548
+ void (async () => {
549
+ setMode("saving");
550
+ setStatus(null);
551
+ try {
552
+ await onSave();
553
+ setStatus(resolvedLabels.saved);
554
+ shouldFocusEditRef.current = true;
555
+ setMode("reading");
556
+ } catch {
557
+ shouldFocusFirstFieldRef.current = true;
558
+ setMode("editing");
559
+ }
560
+ })();
561
+ },
562
+ [isSaving, onSave, resolvedLabels.saved]
563
+ );
564
+ const handleFormKeyDown = React7.useCallback(
565
+ (event) => {
566
+ if (event.key !== "Escape") return;
567
+ event.preventDefault();
568
+ requestCancel();
569
+ },
570
+ [requestCancel]
571
+ );
572
+ React7.useEffect(() => {
573
+ if (!stableHeight || !isEditing) return;
574
+ const el = contentRef.current;
575
+ if (!el) return;
576
+ const measure = () => {
577
+ const height = el.getBoundingClientRect().height;
578
+ if (height > measuredHeightRef.current) {
579
+ measuredHeightRef.current = height;
580
+ setMinHeightPx(height);
581
+ }
582
+ };
583
+ measure();
584
+ const observer = new ResizeObserver(measure);
585
+ observer.observe(el);
586
+ return () => observer.disconnect();
587
+ }, [isEditing, stableHeight]);
588
+ const editButtonNameProps = labelledBy != null ? { "aria-labelledby": `${labelledBy} ${editButtonId}` } : title != null && title.length > 0 ? { "aria-label": `${resolvedLabels.edit} ${title}` } : { "aria-label": resolvedLabels.edit };
589
+ return {
590
+ mode,
591
+ isEditing,
592
+ isSaving,
593
+ startEdit,
594
+ requestCancel,
595
+ formProps: {
596
+ onSubmit: handleSubmit,
597
+ onKeyDown: handleFormKeyDown,
598
+ noValidate: true
599
+ },
600
+ contentRef,
601
+ editButtonRef,
602
+ contentFormId,
603
+ editButtonProps: {
604
+ type: "button",
605
+ id: editButtonId,
606
+ onClick: startEdit,
607
+ ref: editButtonRef,
608
+ ...editButtonNameProps
609
+ },
610
+ saveButtonProps: {
611
+ type: "submit",
612
+ disabled: isSaving
613
+ },
614
+ cancelButtonProps: {
615
+ type: "button",
616
+ onClick: requestCancel,
617
+ disabled: isSaving
618
+ },
619
+ status,
620
+ statusProps: {
621
+ role: "status",
622
+ "aria-live": "polite",
623
+ className: "sr-only"
624
+ },
625
+ confirmDiscard: {
626
+ open: confirmOpen,
627
+ onOpenChange: setConfirmOpen,
628
+ title: resolvedLabels.discardTitle,
629
+ description: resolvedLabels.discardDescription,
630
+ confirmLabel: resolvedLabels.discardConfirm,
631
+ cancelLabel: resolvedLabels.discardCancel,
632
+ onConfirm: exitToReading
633
+ },
634
+ resolvedLabels,
635
+ contentStyle: stableHeight && minHeightPx != null ? { minHeight: minHeightPx } : void 0,
636
+ actionsClassName: "flex min-h-9 min-w-[11rem] flex-wrap items-center justify-end gap-2"
637
+ };
638
+ }
639
+ function EditableSection({
640
+ readView,
641
+ editView,
642
+ children,
643
+ className,
644
+ ...options
645
+ }) {
646
+ const section = useEditableSection(options);
647
+ const {
648
+ isEditing,
649
+ isSaving,
650
+ formProps,
651
+ contentRef,
652
+ contentFormId,
653
+ editButtonProps,
654
+ saveButtonProps,
655
+ cancelButtonProps,
656
+ status,
657
+ statusProps,
658
+ confirmDiscard,
659
+ resolvedLabels,
660
+ contentStyle,
661
+ actionsClassName,
662
+ mode
663
+ } = section;
664
+ const actionButtons = !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", size: "sm", ...editButtonProps, children: resolvedLabels.edit }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
665
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", size: "sm", ...cancelButtonProps, children: resolvedLabels.cancel }),
666
+ /* @__PURE__ */ jsxRuntime.jsx(
667
+ Button,
668
+ {
669
+ size: "sm",
670
+ type: "submit",
671
+ form: contentFormId,
672
+ disabled: saveButtonProps.disabled,
673
+ children: isSaving ? resolvedLabels.saving : resolvedLabels.save
674
+ }
675
+ )
676
+ ] });
677
+ const actions = /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "editable-section-actions", className: actionsClassName, children: actionButtons });
678
+ const content = isEditing ? /* @__PURE__ */ jsxRuntime.jsx(
679
+ "form",
680
+ {
681
+ id: contentFormId,
682
+ ref: contentRef,
683
+ "data-slot": "editable-section-content",
684
+ className: cn("sesionario-editable-section-content space-y-4"),
685
+ style: contentStyle,
686
+ ...formProps,
687
+ children: editView()
688
+ }
689
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
690
+ "div",
691
+ {
692
+ ref: contentRef,
693
+ "data-slot": "editable-section-content",
694
+ className: "sesionario-editable-section-content",
695
+ style: contentStyle,
696
+ children: readView()
697
+ }
698
+ );
699
+ const statusNode = /* @__PURE__ */ jsxRuntime.jsx("span", { ...statusProps, "data-slot": "editable-section-status", children: status });
700
+ const dialog = /* @__PURE__ */ jsxRuntime.jsx(
701
+ ConfirmDestructiveDialog,
702
+ {
703
+ open: confirmDiscard.open,
704
+ onOpenChange: confirmDiscard.onOpenChange,
705
+ title: confirmDiscard.title,
706
+ description: confirmDiscard.description,
707
+ confirmLabel: confirmDiscard.confirmLabel,
708
+ cancelLabel: confirmDiscard.cancelLabel,
709
+ onConfirm: confirmDiscard.onConfirm
710
+ }
711
+ );
712
+ if (children) {
713
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
714
+ children({
715
+ actions,
716
+ content,
717
+ status: statusNode,
718
+ mode,
719
+ isSaving,
720
+ isEditing
721
+ }),
722
+ dialog
723
+ ] });
724
+ }
725
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "editable-section", className: cn("space-y-4", className), children: [
726
+ actions,
727
+ content,
728
+ statusNode,
729
+ dialog
730
+ ] });
731
+ }
732
+ function DataList({ className, ...props }) {
733
+ return /* @__PURE__ */ jsxRuntime.jsx(
734
+ "dl",
735
+ {
736
+ "data-slot": "data-list",
737
+ className: cn("grid gap-4 sm:grid-cols-2", className),
738
+ ...props
739
+ }
740
+ );
741
+ }
742
+ function DataListItem({
743
+ label,
744
+ children,
745
+ empty = "\u2014",
746
+ className,
747
+ labelClassName,
748
+ valueClassName
749
+ }) {
750
+ const isEmpty = children == null || children === false || typeof children === "string" && children.trim().length === 0;
751
+ return /* @__PURE__ */ jsxRuntime.jsxs(
752
+ "div",
753
+ {
754
+ "data-slot": "data-list-item",
755
+ className: cn("flex flex-col gap-1.5", className),
756
+ children: [
757
+ /* @__PURE__ */ jsxRuntime.jsx(
758
+ "dt",
759
+ {
760
+ className: cn(
761
+ "text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
762
+ labelClassName
763
+ ),
764
+ children: label
765
+ }
766
+ ),
767
+ /* @__PURE__ */ jsxRuntime.jsx(
768
+ "dd",
769
+ {
770
+ className: cn(
771
+ "text-sm wrap-break-word",
772
+ isEmpty && "text-muted-foreground",
773
+ valueClassName
774
+ ),
775
+ children: isEmpty ? empty : children
776
+ }
777
+ )
778
+ ]
779
+ }
780
+ );
781
+ }
782
+ function FieldMessage({
783
+ id,
784
+ children,
785
+ className,
786
+ ...props
787
+ }) {
788
+ const hasMessage = children != null && children !== false && !(typeof children === "string" && children.trim().length === 0);
789
+ return /* @__PURE__ */ jsxRuntime.jsx(
790
+ "p",
791
+ {
792
+ id,
793
+ role: hasMessage ? "alert" : void 0,
794
+ "data-slot": "field-message",
795
+ className: cn("min-h-5 text-xs text-destructive", className),
796
+ ...props,
797
+ children: hasMessage ? children : "\xA0"
798
+ }
799
+ );
800
+ }
459
801
  var COLLAPSED_MAX_HEIGHT_REM = 11;
460
802
  function ExpandableText({
461
803
  children,
@@ -1344,13 +1686,13 @@ function TenantAvatar({
1344
1686
  logo,
1345
1687
  size = "md"
1346
1688
  }) {
1347
- const sizeClass = size === "sm" ? "size-6 rounded-md" : "size-8 rounded-lg";
1689
+ const sizeClass = size === "sm" ? "size-6" : "size-8";
1348
1690
  const textClass = size === "sm" ? "text-xs" : "text-sm";
1349
1691
  return /* @__PURE__ */ jsxRuntime.jsx(
1350
1692
  "div",
1351
1693
  {
1352
1694
  className: cn(
1353
- "flex shrink-0 items-center justify-center overflow-hidden font-medium",
1695
+ "flex shrink-0 items-center justify-center overflow-hidden rounded-full font-medium",
1354
1696
  sizeClass
1355
1697
  ),
1356
1698
  style: logo ? void 0 : avatarFallbackStyle(name),
@@ -1371,7 +1713,7 @@ function SwitcherSkeleton({
1371
1713
  "pointer-events-none flex size-8 items-center justify-center rounded-md",
1372
1714
  className
1373
1715
  ),
1374
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8 shrink-0 animate-pulse rounded-lg bg-muted" })
1716
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8 shrink-0 animate-pulse rounded-full bg-muted" })
1375
1717
  }
1376
1718
  );
1377
1719
  }
@@ -1384,7 +1726,7 @@ function SwitcherSkeleton({
1384
1726
  className
1385
1727
  ),
1386
1728
  children: [
1387
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8 shrink-0 animate-pulse rounded-lg bg-muted" }),
1729
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8 shrink-0 animate-pulse rounded-full bg-muted" }),
1388
1730
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
1389
1731
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
1390
1732
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-16 animate-pulse rounded bg-muted" })
@@ -1427,7 +1769,7 @@ function OrgSwitcher({
1427
1769
  triggerClassNameProp
1428
1770
  ),
1429
1771
  children: [
1430
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-8 items-center justify-center rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "size-4 text-muted-foreground" }) }),
1772
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-8 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "size-4 text-muted-foreground" }) }),
1431
1773
  !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid min-w-0 flex-1 text-left leading-tight", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: labels.empty }) }) : null
1432
1774
  ]
1433
1775
  }
@@ -1444,7 +1786,7 @@ function OrgSwitcher({
1444
1786
  className
1445
1787
  ),
1446
1788
  children: [
1447
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-8 items-center justify-center rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "size-4 text-muted-foreground" }) }),
1789
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-8 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "size-4 text-muted-foreground" }) }),
1448
1790
  !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid min-w-0 flex-1 text-left leading-tight", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium text-muted-foreground", children: labels.empty }) }) : null
1449
1791
  ]
1450
1792
  }
@@ -2330,8 +2672,6 @@ function AvatarEditor({
2330
2672
  canvas.width = displaySize;
2331
2673
  canvas.height = displaySize;
2332
2674
  ctx.clearRect(0, 0, displaySize, displaySize);
2333
- ctx.fillStyle = "#1a1a2e";
2334
- ctx.fillRect(0, 0, displaySize, displaySize);
2335
2675
  ctx.save();
2336
2676
  ctx.translate(displaySize / 2, displaySize / 2);
2337
2677
  ctx.rotate(rotation * Math.PI / 180);
@@ -2353,28 +2693,6 @@ function AvatarEditor({
2353
2693
  drawHeight
2354
2694
  );
2355
2695
  ctx.restore();
2356
- ctx.globalCompositeOperation = "destination-in";
2357
- ctx.beginPath();
2358
- ctx.arc(
2359
- displaySize / 2,
2360
- displaySize / 2,
2361
- displaySize / 2 - 4,
2362
- 0,
2363
- Math.PI * 2
2364
- );
2365
- ctx.fill();
2366
- ctx.globalCompositeOperation = "source-over";
2367
- ctx.strokeStyle = "hsl(var(--primary))";
2368
- ctx.lineWidth = 3;
2369
- ctx.beginPath();
2370
- ctx.arc(
2371
- displaySize / 2,
2372
- displaySize / 2,
2373
- displaySize / 2 - 2,
2374
- 0,
2375
- Math.PI * 2
2376
- );
2377
- ctx.stroke();
2378
2696
  const dataUrl = generateOutput();
2379
2697
  if (dataUrl) {
2380
2698
  onChange?.(dataUrl);
@@ -2480,6 +2798,8 @@ function AvatarEditor({
2480
2798
  const gapSize = isLarge ? "gap-6" : "gap-4";
2481
2799
  const controlGap = isLarge ? "gap-3" : "gap-2";
2482
2800
  const sliderHeight = isLarge ? "[&_[role=slider]]:h-6 [&_[role=slider]]:w-6" : "";
2801
+ const guideRadius = size / 2 - 2;
2802
+ const guideCenter = size / 2;
2483
2803
  return /* @__PURE__ */ jsxRuntime.jsxs(
2484
2804
  "div",
2485
2805
  {
@@ -2543,6 +2863,36 @@ function AvatarEditor({
2543
2863
  onTouchEnd: handleMouseUp
2544
2864
  }
2545
2865
  ),
2866
+ imageLoaded && /* @__PURE__ */ jsxRuntime.jsxs(
2867
+ "svg",
2868
+ {
2869
+ width: size,
2870
+ height: size,
2871
+ className: "pointer-events-none absolute inset-0",
2872
+ "aria-hidden": "true",
2873
+ children: [
2874
+ /* @__PURE__ */ jsxRuntime.jsx(
2875
+ "path",
2876
+ {
2877
+ d: `M0 0H${size}V${size}H0Z M${guideCenter - guideRadius} ${guideCenter}a${guideRadius} ${guideRadius} 0 1 0 ${guideRadius * 2} 0a${guideRadius} ${guideRadius} 0 1 0 ${-guideRadius * 2} 0`,
2878
+ fill: "rgb(0 0 0 / 0.45)",
2879
+ fillRule: "evenodd"
2880
+ }
2881
+ ),
2882
+ /* @__PURE__ */ jsxRuntime.jsx(
2883
+ "circle",
2884
+ {
2885
+ cx: guideCenter,
2886
+ cy: guideCenter,
2887
+ r: guideRadius,
2888
+ fill: "none",
2889
+ stroke: "hsl(var(--primary))",
2890
+ strokeWidth: "3"
2891
+ }
2892
+ )
2893
+ ]
2894
+ }
2895
+ ),
2546
2896
  showGrid && imageLoaded && /* @__PURE__ */ jsxRuntime.jsx(
2547
2897
  "div",
2548
2898
  {
@@ -6990,6 +7340,32 @@ function PaymentIcon({
6990
7340
  }
6991
7341
  );
6992
7342
  }
7343
+ var BrandX = React7.forwardRef(function BrandX2({
7344
+ className,
7345
+ size = 24,
7346
+ "aria-label": ariaLabel,
7347
+ "aria-labelledby": ariaLabelledby,
7348
+ ...props
7349
+ }, ref) {
7350
+ const labelled = Boolean(ariaLabel || ariaLabelledby);
7351
+ return /* @__PURE__ */ jsxRuntime.jsx(
7352
+ "svg",
7353
+ {
7354
+ ref,
7355
+ xmlns: "http://www.w3.org/2000/svg",
7356
+ viewBox: "0 0 24 24",
7357
+ fill: "currentColor",
7358
+ ...props,
7359
+ "aria-label": ariaLabel,
7360
+ "aria-labelledby": ariaLabelledby,
7361
+ "aria-hidden": labelled ? void 0 : true,
7362
+ width: size,
7363
+ height: size,
7364
+ className: cn("shrink-0", className),
7365
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z" })
7366
+ }
7367
+ );
7368
+ });
6993
7369
  function MessageGroup({ className, ...props }) {
6994
7370
  return /* @__PURE__ */ jsxRuntime.jsx(
6995
7371
  "div",
@@ -8334,14 +8710,19 @@ Object.defineProperty(exports, "useMessageScrollerVisibility", {
8334
8710
  });
8335
8711
  exports.AvatarEditor = AvatarEditor;
8336
8712
  exports.AvatarEditorDialog = AvatarEditorDialog;
8713
+ exports.BrandX = BrandX;
8337
8714
  exports.Bubble = Bubble;
8338
8715
  exports.BubbleContent = BubbleContent;
8339
8716
  exports.BubbleGroup = BubbleGroup;
8340
8717
  exports.BubbleReactions = BubbleReactions;
8341
8718
  exports.ChatMessageList = ChatMessageList;
8342
8719
  exports.ConfirmDestructiveDialog = ConfirmDestructiveDialog;
8720
+ exports.DEFAULT_EDITABLE_SECTION_LABELS = DEFAULT_EDITABLE_SECTION_LABELS;
8721
+ exports.DataList = DataList;
8722
+ exports.DataListItem = DataListItem;
8343
8723
  exports.DropdownMenuItem = DropdownMenuItem;
8344
8724
  exports.DropdownMenuSeparator = DropdownMenuSeparator;
8725
+ exports.EditableSection = EditableSection;
8345
8726
  exports.EmojiInput = EmojiInput;
8346
8727
  exports.EmojiPicker = EmojiPicker;
8347
8728
  exports.EmojiPickerPopover = EmojiPickerPopover;
@@ -8356,6 +8737,7 @@ exports.EmptyTitle = EmptyTitle;
8356
8737
  exports.ErrorState = ErrorState;
8357
8738
  exports.ExpandableText = ExpandableText;
8358
8739
  exports.FeedVideoPlayer = FeedVideoPlayer;
8740
+ exports.FieldMessage = FieldMessage;
8359
8741
  exports.ImageLightbox = ImageLightbox;
8360
8742
  exports.LanguageContext = LanguageContext;
8361
8743
  exports.LanguageSwitcher = LanguageSwitcher;
@@ -8414,6 +8796,7 @@ exports.paymentTypeFromStripeBrand = paymentTypeFromStripeBrand;
8414
8796
  exports.shouldRetryLiveEdge404 = shouldRetryLiveEdge404;
8415
8797
  exports.useDebouncedValue = useDebouncedValue;
8416
8798
  exports.useDebouncedValueStrict = useDebouncedValueStrict;
8799
+ exports.useEditableSection = useEditableSection;
8417
8800
  exports.useFeedExclusivePlayback = useFeedExclusivePlayback;
8418
8801
  exports.useHlsPlayback = useHlsPlayback;
8419
8802
  exports.useLanguageContext = useLanguageContext;