@ship-it-ui/ui 0.0.12 → 0.0.13

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.js CHANGED
@@ -3109,7 +3109,8 @@ var Carousel = forwardRef44(function Carousel2({
3109
3109
  });
3110
3110
  const viewportRef = useRef8(null);
3111
3111
  const internalScrollRef = useRef8(false);
3112
- const wrapInProgressRef = useRef8(false);
3112
+ const goToInProgressRef = useRef8(false);
3113
+ const wrapInFlightRef = useRef8(null);
3113
3114
  const activeIdx = active ?? 0;
3114
3115
  const domIndexFor = useCallback9((real) => isLooping ? real + 1 : real, [isLooping]);
3115
3116
  const goTo = useCallback9(
@@ -3118,13 +3119,31 @@ var Carousel = forwardRef44(function Carousel2({
3118
3119
  setActive(next);
3119
3120
  const node = viewportRef.current;
3120
3121
  if (node) {
3122
+ const width = node.clientWidth;
3123
+ if (isLooping && wrapInFlightRef.current !== null && width > 0) {
3124
+ const rebaseTarget = wrapInFlightRef.current === N + 1 ? 0 : wrapInFlightRef.current === 0 ? N + 1 : null;
3125
+ if (rebaseTarget !== null) {
3126
+ const rebaseSlide = node.children[rebaseTarget];
3127
+ if (rebaseSlide) {
3128
+ internalScrollRef.current = true;
3129
+ rebaseSlide.scrollIntoView({
3130
+ behavior: "instant",
3131
+ block: "nearest",
3132
+ inline: "start"
3133
+ });
3134
+ }
3135
+ }
3136
+ wrapInFlightRef.current = null;
3137
+ }
3121
3138
  const isNextWrap = loopMode === "circular" && activeIdx === N - 1 && i === activeIdx + 1;
3122
3139
  const isPrevWrap = loopMode === "circular" && activeIdx === 0 && i === activeIdx - 1;
3123
3140
  const targetDom = isNextWrap ? N + 1 : isPrevWrap ? 0 : domIndexFor(next);
3124
3141
  const slide = node.children[targetDom];
3125
3142
  if (slide) {
3126
3143
  internalScrollRef.current = true;
3127
- if (isNextWrap || isPrevWrap) wrapInProgressRef.current = true;
3144
+ goToInProgressRef.current = true;
3145
+ if (isNextWrap) wrapInFlightRef.current = N + 1;
3146
+ else if (isPrevWrap) wrapInFlightRef.current = 0;
3128
3147
  slide.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "start" });
3129
3148
  }
3130
3149
  }
@@ -3139,37 +3158,54 @@ var Carousel = forwardRef44(function Carousel2({
3139
3158
  if (width === 0) return;
3140
3159
  const domIdx = Math.round(node.scrollLeft / width);
3141
3160
  if (!isLooping) {
3161
+ if (goToInProgressRef.current) {
3162
+ if (domIdx === activeIdx) goToInProgressRef.current = false;
3163
+ return;
3164
+ }
3142
3165
  if (domIdx !== activeIdx) setActive(domIdx);
3143
3166
  return;
3144
3167
  }
3145
3168
  if (domIdx === 0) {
3146
- if (wrapInProgressRef.current && node.scrollLeft > 1) return;
3169
+ if (goToInProgressRef.current && node.scrollLeft > 1) return;
3147
3170
  const realTwin = node.children[N];
3148
3171
  if (realTwin) {
3149
3172
  internalScrollRef.current = true;
3150
3173
  realTwin.scrollIntoView({ behavior: "instant", block: "nearest", inline: "start" });
3151
3174
  }
3152
3175
  if (activeIdx !== N - 1) setActive(N - 1);
3153
- wrapInProgressRef.current = false;
3176
+ goToInProgressRef.current = false;
3177
+ wrapInFlightRef.current = null;
3154
3178
  return;
3155
3179
  }
3156
3180
  if (domIdx === N + 1) {
3157
- if (wrapInProgressRef.current && node.scrollLeft < (N + 1) * width - 1) return;
3181
+ if (goToInProgressRef.current && node.scrollLeft < (N + 1) * width - 1) return;
3158
3182
  const realTwin = node.children[1];
3159
3183
  if (realTwin) {
3160
3184
  internalScrollRef.current = true;
3161
3185
  realTwin.scrollIntoView({ behavior: "instant", block: "nearest", inline: "start" });
3162
3186
  }
3163
3187
  if (activeIdx !== 0) setActive(0);
3164
- wrapInProgressRef.current = false;
3188
+ goToInProgressRef.current = false;
3189
+ wrapInFlightRef.current = null;
3165
3190
  return;
3166
3191
  }
3167
- if (wrapInProgressRef.current) return;
3168
3192
  const realIdx = domIdx - 1;
3193
+ if (goToInProgressRef.current) {
3194
+ if (realIdx === activeIdx) goToInProgressRef.current = false;
3195
+ return;
3196
+ }
3169
3197
  if (realIdx !== activeIdx) setActive(realIdx);
3170
3198
  };
3199
+ const onPointerDown = () => {
3200
+ goToInProgressRef.current = false;
3201
+ wrapInFlightRef.current = null;
3202
+ };
3171
3203
  node.addEventListener("scroll", onScroll, { passive: true });
3172
- return () => node.removeEventListener("scroll", onScroll);
3204
+ node.addEventListener("pointerdown", onPointerDown, { passive: true });
3205
+ return () => {
3206
+ node.removeEventListener("scroll", onScroll);
3207
+ node.removeEventListener("pointerdown", onPointerDown);
3208
+ };
3173
3209
  }, [activeIdx, isLooping, N, setActive]);
3174
3210
  useEffect8(() => {
3175
3211
  if (internalScrollRef.current) {
@@ -3305,19 +3341,32 @@ var Carousel = forwardRef44(function Carousel2({
3305
3341
  }
3306
3342
  )
3307
3343
  ] }),
3308
- renderThumbnail && /* @__PURE__ */ jsx45("div", { className: "mt-2 flex gap-2 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: items.map((item, i) => /* @__PURE__ */ jsx45(
3309
- "button",
3310
- {
3311
- type: "button",
3312
- "aria-label": `Show slide ${i + 1}`,
3313
- onClick: () => goTo(i),
3314
- className: cn(
3315
- "shrink-0 cursor-pointer overflow-hidden rounded transition-opacity",
3316
- i === activeIdx ? "ring-accent opacity-100 ring-2" : "opacity-60 hover:opacity-100"
3317
- ),
3318
- children: renderThumbnail(item, i)
3319
- },
3320
- i
3344
+ renderThumbnail && /* @__PURE__ */ jsx45("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) => (
3345
+ // The active ring is applied to the rendered thumbnail (the
3346
+ // button's first child) rather than the button itself, so it
3347
+ // traces whatever border-radius the consumer's thumbnail
3348
+ // already has. Picking a fixed radius here would always be
3349
+ // wrong for one consumer or another — `rounded-lg` thumbs got
3350
+ // a 4px-radius ring; future thumbs could be circular or
3351
+ // square. `box-shadow` (what `ring-2` compiles to) follows
3352
+ // the child's `border-radius` automatically, so this is
3353
+ // self-adjusting.
3354
+ /* @__PURE__ */ jsx45(
3355
+ "button",
3356
+ {
3357
+ type: "button",
3358
+ "aria-label": `Show slide ${i + 1}`,
3359
+ onClick: () => goTo(i),
3360
+ "data-active": i === activeIdx ? "true" : void 0,
3361
+ className: cn(
3362
+ "shrink-0 cursor-pointer transition-opacity",
3363
+ "[&[data-active]>*]:ring-accent [&[data-active]>*]:ring-2",
3364
+ i === activeIdx ? "opacity-100" : "opacity-60 hover:opacity-100"
3365
+ ),
3366
+ children: renderThumbnail(item, i)
3367
+ },
3368
+ i
3369
+ )
3321
3370
  )) })
3322
3371
  ]
3323
3372
  }