@ship-it-ui/ui 0.0.12 → 0.0.14

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
@@ -3266,7 +3266,9 @@ var Carousel = (0, import_react52.forwardRef)(function Carousel2({
3266
3266
  });
3267
3267
  const viewportRef = (0, import_react52.useRef)(null);
3268
3268
  const internalScrollRef = (0, import_react52.useRef)(false);
3269
- const wrapInProgressRef = (0, import_react52.useRef)(false);
3269
+ const goToInProgressRef = (0, import_react52.useRef)(false);
3270
+ const wrapInFlightRef = (0, import_react52.useRef)(null);
3271
+ const rebaseConsumeRef = (0, import_react52.useRef)(null);
3270
3272
  const activeIdx = active ?? 0;
3271
3273
  const domIndexFor = (0, import_react52.useCallback)((real) => isLooping ? real + 1 : real, [isLooping]);
3272
3274
  const goTo = (0, import_react52.useCallback)(
@@ -3275,13 +3277,32 @@ var Carousel = (0, import_react52.forwardRef)(function Carousel2({
3275
3277
  setActive(next);
3276
3278
  const node = viewportRef.current;
3277
3279
  if (node) {
3280
+ const width = node.clientWidth;
3281
+ if (isLooping && wrapInFlightRef.current !== null && width > 0) {
3282
+ const rebaseTarget = wrapInFlightRef.current === N + 1 ? 0 : wrapInFlightRef.current === 0 ? N + 1 : null;
3283
+ if (rebaseTarget !== null) {
3284
+ const rebaseSlide = node.children[rebaseTarget];
3285
+ if (rebaseSlide) {
3286
+ internalScrollRef.current = true;
3287
+ rebaseConsumeRef.current = rebaseTarget;
3288
+ rebaseSlide.scrollIntoView({
3289
+ behavior: "instant",
3290
+ block: "nearest",
3291
+ inline: "start"
3292
+ });
3293
+ }
3294
+ }
3295
+ wrapInFlightRef.current = null;
3296
+ }
3278
3297
  const isNextWrap = loopMode === "circular" && activeIdx === N - 1 && i === activeIdx + 1;
3279
3298
  const isPrevWrap = loopMode === "circular" && activeIdx === 0 && i === activeIdx - 1;
3280
3299
  const targetDom = isNextWrap ? N + 1 : isPrevWrap ? 0 : domIndexFor(next);
3281
3300
  const slide = node.children[targetDom];
3282
3301
  if (slide) {
3283
3302
  internalScrollRef.current = true;
3284
- if (isNextWrap || isPrevWrap) wrapInProgressRef.current = true;
3303
+ goToInProgressRef.current = true;
3304
+ if (isNextWrap) wrapInFlightRef.current = N + 1;
3305
+ else if (isPrevWrap) wrapInFlightRef.current = 0;
3285
3306
  slide.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "start" });
3286
3307
  }
3287
3308
  }
@@ -3296,37 +3317,59 @@ var Carousel = (0, import_react52.forwardRef)(function Carousel2({
3296
3317
  if (width === 0) return;
3297
3318
  const domIdx = Math.round(node.scrollLeft / width);
3298
3319
  if (!isLooping) {
3320
+ if (goToInProgressRef.current) {
3321
+ if (domIdx === activeIdx) goToInProgressRef.current = false;
3322
+ return;
3323
+ }
3299
3324
  if (domIdx !== activeIdx) setActive(domIdx);
3300
3325
  return;
3301
3326
  }
3327
+ if (rebaseConsumeRef.current !== null) {
3328
+ if (domIdx === rebaseConsumeRef.current) return;
3329
+ rebaseConsumeRef.current = null;
3330
+ }
3302
3331
  if (domIdx === 0) {
3303
- if (wrapInProgressRef.current && node.scrollLeft > 1) return;
3332
+ if (goToInProgressRef.current && node.scrollLeft > 1) return;
3304
3333
  const realTwin = node.children[N];
3305
3334
  if (realTwin) {
3306
3335
  internalScrollRef.current = true;
3307
3336
  realTwin.scrollIntoView({ behavior: "instant", block: "nearest", inline: "start" });
3308
3337
  }
3309
3338
  if (activeIdx !== N - 1) setActive(N - 1);
3310
- wrapInProgressRef.current = false;
3339
+ goToInProgressRef.current = false;
3340
+ wrapInFlightRef.current = null;
3311
3341
  return;
3312
3342
  }
3313
3343
  if (domIdx === N + 1) {
3314
- if (wrapInProgressRef.current && node.scrollLeft < (N + 1) * width - 1) return;
3344
+ if (goToInProgressRef.current && node.scrollLeft < (N + 1) * width - 1) return;
3315
3345
  const realTwin = node.children[1];
3316
3346
  if (realTwin) {
3317
3347
  internalScrollRef.current = true;
3318
3348
  realTwin.scrollIntoView({ behavior: "instant", block: "nearest", inline: "start" });
3319
3349
  }
3320
3350
  if (activeIdx !== 0) setActive(0);
3321
- wrapInProgressRef.current = false;
3351
+ goToInProgressRef.current = false;
3352
+ wrapInFlightRef.current = null;
3322
3353
  return;
3323
3354
  }
3324
- if (wrapInProgressRef.current) return;
3325
3355
  const realIdx = domIdx - 1;
3356
+ if (goToInProgressRef.current) {
3357
+ if (realIdx === activeIdx) goToInProgressRef.current = false;
3358
+ return;
3359
+ }
3326
3360
  if (realIdx !== activeIdx) setActive(realIdx);
3327
3361
  };
3362
+ const onPointerDown = () => {
3363
+ goToInProgressRef.current = false;
3364
+ wrapInFlightRef.current = null;
3365
+ rebaseConsumeRef.current = null;
3366
+ };
3328
3367
  node.addEventListener("scroll", onScroll, { passive: true });
3329
- return () => node.removeEventListener("scroll", onScroll);
3368
+ node.addEventListener("pointerdown", onPointerDown, { passive: true });
3369
+ return () => {
3370
+ node.removeEventListener("scroll", onScroll);
3371
+ node.removeEventListener("pointerdown", onPointerDown);
3372
+ };
3330
3373
  }, [activeIdx, isLooping, N, setActive]);
3331
3374
  (0, import_react52.useEffect)(() => {
3332
3375
  if (internalScrollRef.current) {
@@ -3462,19 +3505,32 @@ var Carousel = (0, import_react52.forwardRef)(function Carousel2({
3462
3505
  }
3463
3506
  )
3464
3507
  ] }),
3465
- renderThumbnail && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "mt-2 flex gap-2 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3466
- "button",
3467
- {
3468
- type: "button",
3469
- "aria-label": `Show slide ${i + 1}`,
3470
- onClick: () => goTo(i),
3471
- className: cn(
3472
- "shrink-0 cursor-pointer overflow-hidden rounded transition-opacity",
3473
- i === activeIdx ? "ring-accent opacity-100 ring-2" : "opacity-60 hover:opacity-100"
3474
- ),
3475
- children: renderThumbnail(item, i)
3476
- },
3477
- i
3508
+ renderThumbnail && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "-mx-0.5 mt-1.5 flex gap-2 overflow-x-auto p-0.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: items.map((item, i) => (
3509
+ // The active ring is applied to the rendered thumbnail (the
3510
+ // button's first child) rather than the button itself, so it
3511
+ // traces whatever border-radius the consumer's thumbnail
3512
+ // already has. Picking a fixed radius here would always be
3513
+ // wrong for one consumer or another — `rounded-lg` thumbs got
3514
+ // a 4px-radius ring; future thumbs could be circular or
3515
+ // square. `box-shadow` (what `ring-2` compiles to) follows
3516
+ // the child's `border-radius` automatically, so this is
3517
+ // self-adjusting.
3518
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3519
+ "button",
3520
+ {
3521
+ type: "button",
3522
+ "aria-label": `Show slide ${i + 1}`,
3523
+ onClick: () => goTo(i),
3524
+ "data-active": i === activeIdx ? "true" : void 0,
3525
+ className: cn(
3526
+ "shrink-0 cursor-pointer transition-opacity",
3527
+ "[&[data-active]>*]:ring-accent [&[data-active]>*]:ring-2",
3528
+ i === activeIdx ? "opacity-100" : "opacity-60 hover:opacity-100"
3529
+ ),
3530
+ children: renderThumbnail(item, i)
3531
+ },
3532
+ i
3533
+ )
3478
3534
  )) })
3479
3535
  ]
3480
3536
  }
@@ -5220,7 +5276,7 @@ var ListingDetail = (0, import_react61.forwardRef)(function ListingDetail2({
5220
5276
  items: photos,
5221
5277
  index: galleryIndex,
5222
5278
  onIndexChange: setGalleryIndex,
5223
- loop,
5279
+ loop: Boolean(loop),
5224
5280
  title: lightboxTitle,
5225
5281
  renderItem: (src, i) => renderPhoto ? renderPhoto(src, i, "lightbox") : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("img", { src, alt: "", className: "max-h-[88vh] max-w-[92vw] object-contain" })
5226
5282
  }