@sesionario/blocks 1.30.1 → 1.31.1

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 CHANGED
@@ -1173,6 +1173,45 @@ function useZoomPanGestures(options = {}) {
1173
1173
  clearSnapBack
1174
1174
  };
1175
1175
  }
1176
+ function isBrokenImage(img) {
1177
+ return img.complete && img.naturalWidth === 0;
1178
+ }
1179
+ function SafeImage({
1180
+ src,
1181
+ fallback,
1182
+ alt = "",
1183
+ onError,
1184
+ ...imgProps
1185
+ }) {
1186
+ const [failed, setFailed] = React7.useState(false);
1187
+ const imgRef = React7.useRef(null);
1188
+ const resolvedSrc = typeof src === "string" && src.length > 0 ? src : null;
1189
+ React7.useLayoutEffect(() => {
1190
+ setFailed(false);
1191
+ }, [resolvedSrc]);
1192
+ React7.useLayoutEffect(() => {
1193
+ const img = imgRef.current;
1194
+ if (img && isBrokenImage(img)) {
1195
+ setFailed(true);
1196
+ }
1197
+ }, [resolvedSrc, failed]);
1198
+ if (!resolvedSrc || failed) {
1199
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
1200
+ }
1201
+ return /* @__PURE__ */ jsxRuntime.jsx(
1202
+ "img",
1203
+ {
1204
+ ...imgProps,
1205
+ ref: imgRef,
1206
+ src: resolvedSrc,
1207
+ alt,
1208
+ onError: (event) => {
1209
+ setFailed(true);
1210
+ onError?.(event);
1211
+ }
1212
+ }
1213
+ );
1214
+ }
1176
1215
  function ImageLightbox({
1177
1216
  images,
1178
1217
  index,
@@ -1296,7 +1335,7 @@ function ImageLightbox({
1296
1335
  onPointerUp: handlers.onPointerUp,
1297
1336
  onPointerCancel: handlers.onPointerCancel,
1298
1337
  children: /* @__PURE__ */ jsxRuntime.jsx(
1299
- "img",
1338
+ SafeImage,
1300
1339
  {
1301
1340
  src: images[index],
1302
1341
  alt: "",
@@ -1307,7 +1346,14 @@ function ImageLightbox({
1307
1346
  transition,
1308
1347
  cursor: scale > ZOOM_PAN_MIN_SCALE ? "grab" : "default"
1309
1348
  },
1310
- onTransitionEnd: clearSnapBack
1349
+ onTransitionEnd: clearSnapBack,
1350
+ fallback: /* @__PURE__ */ jsxRuntime.jsx(
1351
+ "div",
1352
+ {
1353
+ "aria-hidden": true,
1354
+ className: "h-48 w-full max-w-md rounded-lg bg-muted"
1355
+ }
1356
+ )
1311
1357
  }
1312
1358
  )
1313
1359
  }
@@ -1421,7 +1467,7 @@ function MediaCarousel({
1421
1467
  onPointerUp: handlers.onPointerUp,
1422
1468
  onPointerCancel: handlers.onPointerCancel,
1423
1469
  children: /* @__PURE__ */ jsxRuntime.jsx(
1424
- "img",
1470
+ SafeImage,
1425
1471
  {
1426
1472
  src: item.src,
1427
1473
  alt: item.alt ?? "",
@@ -1432,7 +1478,14 @@ function MediaCarousel({
1432
1478
  transition,
1433
1479
  cursor: scale > ZOOM_PAN_MIN_SCALE ? "grab" : "default"
1434
1480
  },
1435
- onTransitionEnd: clearSnapBack
1481
+ onTransitionEnd: clearSnapBack,
1482
+ fallback: /* @__PURE__ */ jsxRuntime.jsx(
1483
+ "div",
1484
+ {
1485
+ "aria-hidden": true,
1486
+ className: "h-48 w-full max-w-md rounded-lg bg-muted"
1487
+ }
1488
+ )
1436
1489
  }
1437
1490
  )
1438
1491
  }
@@ -2099,15 +2152,27 @@ function TenantAvatar({
2099
2152
  }) {
2100
2153
  const sizeClass = size === "sm" ? "size-6" : "size-8";
2101
2154
  const textClass = size === "sm" ? "text-xs" : "text-sm";
2102
- return /* @__PURE__ */ jsxRuntime.jsx(
2155
+ const initials = getInitials(name);
2156
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2103
2157
  "div",
2104
2158
  {
2105
2159
  className: cn(
2106
- "flex shrink-0 items-center justify-center overflow-hidden rounded-full font-medium",
2160
+ "relative flex shrink-0 items-center justify-center overflow-hidden rounded-full font-medium",
2107
2161
  sizeClass
2108
2162
  ),
2109
- style: logo ? void 0 : avatarFallbackStyle(name),
2110
- children: logo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logo, alt: "", className: "size-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: textClass, children: getInitials(name) })
2163
+ style: avatarFallbackStyle(name),
2164
+ children: [
2165
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: textClass, children: initials }),
2166
+ logo ? /* @__PURE__ */ jsxRuntime.jsx(
2167
+ SafeImage,
2168
+ {
2169
+ src: logo,
2170
+ alt: "",
2171
+ className: "absolute inset-0 size-full object-cover",
2172
+ fallback: null
2173
+ }
2174
+ ) : null
2175
+ ]
2111
2176
  }
2112
2177
  );
2113
2178
  }
@@ -2627,28 +2692,26 @@ function MenuAvatar({
2627
2692
  sizeClass
2628
2693
  }) {
2629
2694
  const initials = getInitials(name);
2630
- return /* @__PURE__ */ jsxRuntime.jsx(
2695
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2631
2696
  "span",
2632
2697
  {
2633
2698
  className: cn(
2634
2699
  "relative flex shrink-0 overflow-hidden rounded-full",
2635
2700
  sizeClass
2636
2701
  ),
2637
- children: image ? /* @__PURE__ */ jsxRuntime.jsx(
2638
- "img",
2639
- {
2640
- src: image,
2641
- alt: "",
2642
- className: "aspect-square size-full object-cover"
2643
- }
2644
- ) : /* @__PURE__ */ jsxRuntime.jsx(
2645
- "span",
2646
- {
2647
- className: "flex size-full items-center justify-center text-xs font-semibold",
2648
- style: avatarFallbackStyle(name),
2649
- children: initials
2650
- }
2651
- )
2702
+ style: avatarFallbackStyle(name),
2703
+ children: [
2704
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-full items-center justify-center text-xs font-semibold", children: initials }),
2705
+ image ? /* @__PURE__ */ jsxRuntime.jsx(
2706
+ SafeImage,
2707
+ {
2708
+ src: image,
2709
+ alt: "",
2710
+ className: "absolute inset-0 aspect-square size-full object-cover",
2711
+ fallback: null
2712
+ }
2713
+ ) : null
2714
+ ]
2652
2715
  }
2653
2716
  );
2654
2717
  }
@@ -3740,30 +3803,31 @@ function AvatarEditorDialog({
3740
3803
  {
3741
3804
  className: "relative w-full h-full rounded-full overflow-hidden bg-muted border-2 border-border flex items-center justify-center",
3742
3805
  style: { width: displaySize, height: displaySize },
3743
- children: value ? /* @__PURE__ */ jsxRuntime.jsx(
3744
- "img",
3806
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3807
+ SafeImage,
3745
3808
  {
3746
- src: value || "/placeholder.svg",
3809
+ src: value,
3747
3810
  alt: "Avatar",
3748
- className: "absolute -inset-px object-cover"
3749
- }
3750
- ) : /* @__PURE__ */ jsxRuntime.jsxs(
3751
- "div",
3752
- {
3753
- className: cn(
3754
- "flex flex-col items-center justify-center text-muted-foreground",
3755
- caption ? "gap-1" : "gap-0"
3756
- ),
3757
- children: [
3758
- /* @__PURE__ */ jsxRuntime.jsx(
3759
- lucideReact.User,
3760
- {
3761
- className: "h-1/2 w-1/2 max-h-[55%] max-w-[55%] shrink-0",
3762
- "aria-hidden": true
3763
- }
3764
- ),
3765
- caption ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-center px-1", children: caption }) : null
3766
- ]
3811
+ className: "absolute -inset-px object-cover",
3812
+ fallback: /* @__PURE__ */ jsxRuntime.jsxs(
3813
+ "div",
3814
+ {
3815
+ className: cn(
3816
+ "flex flex-col items-center justify-center text-muted-foreground",
3817
+ caption ? "gap-1" : "gap-0"
3818
+ ),
3819
+ children: [
3820
+ /* @__PURE__ */ jsxRuntime.jsx(
3821
+ lucideReact.User,
3822
+ {
3823
+ className: "h-1/2 w-1/2 max-h-[55%] max-w-[55%] shrink-0",
3824
+ "aria-hidden": true
3825
+ }
3826
+ ),
3827
+ caption ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-center px-1", children: caption }) : null
3828
+ ]
3829
+ }
3830
+ )
3767
3831
  }
3768
3832
  )
3769
3833
  }
@@ -8829,15 +8893,16 @@ function ListPanel({
8829
8893
  "span",
8830
8894
  {
8831
8895
  className: "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-full text-xs font-semibold text-white",
8832
- style: item.avatarUrl ? void 0 : avatarFallbackStyle(item.title),
8833
- children: item.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(
8834
- "img",
8896
+ style: avatarFallbackStyle(item.title),
8897
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8898
+ SafeImage,
8835
8899
  {
8836
8900
  src: item.avatarUrl,
8837
8901
  alt: "",
8838
- className: "size-full object-cover"
8902
+ className: "size-full object-cover",
8903
+ fallback: getInitials(item.title)
8839
8904
  }
8840
- ) : getInitials(item.title)
8905
+ )
8841
8906
  }
8842
8907
  ),
8843
8908
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
@@ -9414,6 +9479,7 @@ exports.PaymentIcon = PaymentIcon;
9414
9479
  exports.PhoneInput = PhoneInput;
9415
9480
  exports.PlatformAccountMenu = PlatformAccountMenu;
9416
9481
  exports.PlatformNavbar = PlatformNavbar;
9482
+ exports.SafeImage = SafeImage;
9417
9483
  exports.ScrollRestorationProvider = ScrollRestorationProvider;
9418
9484
  exports.SearchCommand = SearchCommand;
9419
9485
  exports.SearchablePicker = SearchablePicker;