@carouseldeck/react-18 1.2.0 → 1.3.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +31 -19
  2. package/dist/index.js +235 -168
  3. package/package.json +4 -4
package/dist/index.d.ts CHANGED
@@ -35,15 +35,17 @@ interface RootBaseProps extends ComponentProps<'div'> {
35
35
  * Defaults to horizontal. */
36
36
  orientation?: Orientation;
37
37
  /** Whether scrolling past the last snap point arrives at the first, and
38
- * back, with no visible jump: Prev and Next are then never disabled.
39
- * `Deck.Viewport` renders a copy of every slide on each side of the
40
- * slides, inert and `aria-hidden`, and the deck jumps from a copy to its
41
- * slide once it rests (clone and jump, ADR-0006, as built in ADR-0009).
42
- * Indexes, Dots and Counter count the slides' snap points only, never the
43
- * copies'. A copy renders the slide's children again, so their state is
44
- * their own and an `id` in a slide repeats; `useSlide` tells them whether
45
- * they are in a copy. A deck whose slides all fit does not loop and renders
46
- * no copies. Defaults to false. */
38
+ * back, with no visible jump: Prev and Next are then never disabled. Each
39
+ * slide's children mount once: `Deck.Viewport` moves the slide nearest the
40
+ * viewport onto empty, inert, `aria-hidden` shells that carry the snap
41
+ * points on each side of it, by `translate` (ADR-0013). A deck whose set
42
+ * of slides is too narrow for a shell to have room beside its own slide
43
+ * falls back to rendering full copies instead (clone and jump, ADR-0006,
44
+ * as built in ADR-0009): a copy renders the slide's children again, so
45
+ * their state is their own and an `id` in a slide repeats; `useSlide`
46
+ * tells them whether they are in one. Indexes, Dots and Counter count the
47
+ * slides' snap points only, never a shell's or a copy's. A deck whose
48
+ * slides all fit does not loop and renders neither. Defaults to false. */
47
49
  loop?: boolean;
48
50
  /** Moves the deck one snap point on every this many milliseconds, counted
49
51
  * from when it comes to rest, and stops at the last, unless the deck
@@ -88,12 +90,14 @@ export interface UseSlideResult {
88
90
  }
89
91
  /** The slide a component is rendered in: its index, and whether it is a
90
92
  * loop's copy, so stateful content, such as a video player, can render
91
- * differently in a copy, which is inert and never focal. Throws outside a
92
- * `Deck.Slide`. */
93
+ * differently in a copy, which is inert and never focal. Each slide mounts
94
+ * once: `copy` is undefined unless the deck's set of slides is too narrow
95
+ * for shells and falls back to rendering copies (ADR-0013). Throws outside
96
+ * a `Deck.Slide`. */
93
97
  export declare function useSlide(): UseSlideResult;
94
98
  /**
95
99
  * A transition built on progress while the viewport keeps scrolling natively
96
- * (CONTEXT.md), passed to `Deck.Viewport`'s `effect`. Each effect is its own
100
+ * (GLOSSARY.md), passed to `Deck.Viewport`'s `effect`. Each effect is its own
97
101
  * entry point, such as `@carouseldeck/react/fade`, so a deck that imports none
98
102
  * ships none of their code.
99
103
  */
@@ -105,11 +109,13 @@ export interface Effect {
105
109
  * CSS overrides any of them (ADR-0003). */
106
110
  css: string;
107
111
  /** The structural styles the effect needs, set inline as the deck's own
108
- * are, for a deck of `count` slides, a loop's copies included. With
109
- * `target`, the viewport holds an empty snap target per slide, and per
110
- * copy, in the order they run, after the slides, styled by it: the slides
111
- * stack in one place, the engine measures each by its target, and every
112
- * slide but the focal one is inert, as it cannot be seen. */
112
+ * are, for a deck of `count` slides: with loop, a small deck's three sets
113
+ * of copies, or, with shells (ADR-0013), all five sets of them instead,
114
+ * each a shell rather than a copy. With `target`, the viewport holds an
115
+ * empty snap target per slide, per copy or per shell, in the order they
116
+ * run, after the slides, styled by it: the slides stack in one place, the
117
+ * engine measures each by its target, and every slide but the focal one
118
+ * is inert, as it cannot be seen. */
113
119
  layout?: (orientation: Orientation, count: number) => {
114
120
  viewport?: CSSProperties;
115
121
  slide?: CSSProperties;
@@ -122,10 +128,16 @@ export interface ViewportProps extends ComponentProps<'div'> {
122
128
  effect?: Effect;
123
129
  }
124
130
  /** The native scroll container. Its children are the deck's slides; with
125
- * `loop`, a copy of every slide on each side of them; an `effect` may add a
126
- * snap target after them for each. */
131
+ * `loop`, two in-flow spacers and empty shells carrying their snap points on
132
+ * each side of them (ADR-0013), or, where the set of slides is too narrow
133
+ * for a shell to have room beside its own slide, a copy of every slide on
134
+ * each side instead; an `effect` may add a snap target after them for each
135
+ * slide, copy or shell. */
127
136
  export declare function Viewport({ style, children, effect, ...props }: ViewportProps): import("react").JSX.Element;
128
137
  /** One slide, labelled "n of m". Its size and alignment are consumer CSS.
138
+ * With loop, it mounts once: shells carry its snap points on each side, and
139
+ * `translate` moves it onto whichever is nearest the viewport (ADR-0013); a
140
+ * deck too narrow for shells copies it instead.
129
141
  * For CSS to read, it carries `--deck-slide-index`, its index, and
130
142
  * `--deck-slide-count`, the number of slides, copies not counted, from the
131
143
  * first render; `--deck-slide-progress`, its signed distance from the focal
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { Children as e, Fragment as t, createContext as n, forwardRef as r, isValidElement as i, useContext as a, useEffect as o, useEffect as s, useImperativeHandle as c, useLayoutEffect as l, useRef as u, useState as d, version as f } from "react";
3
- import { COPY as p, SNAP_TARGET as m, createDeck as h } from "@carouseldeck/core";
4
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
3
+ import { COPY as p, SHELL as m, SNAP_TARGET as h, SPACER as g, createDeck as _ } from "@carouseldeck/core";
4
+ import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
5
5
  //#region src/with-ref.ts
6
- function y(e, t) {
6
+ function x(e, t) {
7
7
  let n = r((t, n) => e(n === null ? t : {
8
8
  ...t,
9
9
  ref: n
@@ -13,8 +13,8 @@ function y(e, t) {
13
13
  //#endregion
14
14
  //#region src/react.ts
15
15
  process.env.NODE_ENV !== "production" && !f.startsWith("18.") && console.error(`@carouseldeck/react-18 is for React 18, and this is React ${f}. Use @carouseldeck/react with React 19.`);
16
- var b = (e) => n(e).Provider, x = (e) => a(e._context), S = typeof window > "u" ? o : l, C = (e) => typeof e == "object" && !!e && e.type === "style";
17
- function w(e) {
16
+ var S = (e) => n(e).Provider, C = (e) => a(e._context), w = typeof window > "u" ? o : l, T = (e) => typeof e == "object" && !!e && e.type === "style";
17
+ function E(e) {
18
18
  return (t, n, r) => {
19
19
  if (typeof t != "string") return e(t, n, r);
20
20
  let i = n;
@@ -35,8 +35,8 @@ function w(e) {
35
35
  };
36
36
  }
37
37
  if ("data-carouseldeck-viewport" in i && Array.isArray(i.children)) {
38
- let e = i.children, n = e.map((e) => C(e) ? e : null), a = e.map((e) => C(e) ? null : e);
39
- return v(g, { children: [...n, v(t, {
38
+ let e = i.children, n = e.map((e) => T(e) ? e : null), a = e.map((e) => T(e) ? null : e);
39
+ return b(v, { children: [...n, b(t, {
40
40
  ...i,
41
41
  children: a
42
42
  })] }, r);
@@ -44,184 +44,192 @@ function w(e) {
44
44
  return e(t, i, r);
45
45
  };
46
46
  }
47
- var T = w(_), ee = w(v), E = b(null);
47
+ var D = E(y), ee = E(b), O = S(null);
48
48
  //#endregion
49
49
  //#region ../react/src/slides-in.ts
50
- function te(n, r) {
50
+ function k(n, r) {
51
51
  for (let a of e.toArray(n)) {
52
52
  if (!i(a)) continue;
53
53
  if (a.type === r) return e.toArray(a.props.children).length;
54
54
  if (typeof a.type != "string" && a.type !== t) continue;
55
- let n = te(a.props.children, r);
55
+ let n = k(a.props.children, r);
56
56
  if (n !== null) return n;
57
57
  }
58
58
  return null;
59
59
  }
60
60
  //#endregion
61
61
  //#region ../react/src/index.tsx
62
- var D = (e, t) => Math.min(Math.max(e, 0), t - 1), ne = b(null);
63
- function O(e) {
64
- let t = x(ne);
62
+ var A = (e, t) => Math.min(Math.max(e, 0), t - 1), j = -.9985;
63
+ function M(e, t) {
64
+ let n = e;
65
+ for (; n <= j;) n += t;
66
+ for (; n > j + t;) n -= t;
67
+ return n;
68
+ }
69
+ var te = S(null);
70
+ function N(e) {
71
+ let t = C(te);
65
72
  if (!t) throw Error(`Deck.${e} must be inside Deck.Root`);
66
73
  return t;
67
74
  }
68
- function k({ index: e, defaultIndex: t, onIndexChange: n, handleRef: r, drag: i = !0, onFocalChange: a, clickToFocus: o = !1, orientation: l = "horizontal", loop: f = !1, autoplay: p, children: m, onFocus: g, onPointerEnter: _, onPointerLeave: v, onPointerDown: y, onKeyDown: b, onWheel: C, ...w }) {
69
- let [O] = d(() => {
75
+ function P({ index: e, defaultIndex: t, onIndexChange: n, handleRef: r, drag: i = !0, onFocalChange: a, clickToFocus: o = !1, orientation: l = "horizontal", loop: f = !1, autoplay: p, children: m, onFocus: h, onPointerEnter: g, onPointerLeave: v, onPointerDown: y, onKeyDown: b, onWheel: x, ...S }) {
76
+ let [T] = d(() => {
70
77
  let n = e ?? t ?? 0;
71
78
  return Number.isFinite(n) ? n : 0;
72
79
  });
73
- process.env.NODE_ENV !== "production" && ae(e, t, n);
74
- let [k, A] = d({
75
- index: O,
80
+ process.env.NODE_ENV !== "production" && ie(e, t, n);
81
+ let [E, j] = d({
82
+ index: T,
76
83
  count: null,
77
84
  slide: null,
78
- focal: null
79
- }), j = u(null), M = u(null), N = u(n), P = u(a), F = u(e), I = u(null), R = u(l), [oe, z] = d(""), [B, V] = d(!0), [H, U] = d(!1), [se, ce] = d(!1), W = u(!1), K = u(!1), q = u(!1), J = u(null);
80
- S(() => {
81
- N.current = n, P.current = a, F.current = e;
82
- }), S(() => {
83
- let e = j.current;
85
+ focal: null,
86
+ copies: !1
87
+ }), M = u(null), N = u(null), P = u(n), F = u(a), I = u(e), L = u(null), R = u(l), [ae, oe] = d(""), [z, B] = d(!0), [se, V] = d(!1), [U, ce] = d(!1), W = u(!1), G = u(!1), K = u(!1), q = u(null);
88
+ w(() => {
89
+ P.current = n, F.current = a, I.current = e;
90
+ }), w(() => {
91
+ let e = M.current;
84
92
  if (!e) throw Error("Deck.Root must contain a Deck.Viewport");
85
- let t, n, r = h(e, {
86
- index: O,
93
+ let t, n, r = _(e, {
94
+ index: T,
87
95
  orientation: R.current,
88
96
  onChange(r) {
89
- A(r);
90
- let i = F.current;
91
- t !== void 0 && r.index !== t && (i === void 0 || r.index !== D(i, r.count)) && (I.current = r.index, N.current?.(r.index)), t !== void 0 && r.index !== t && (K.current = !1, z(r.slide === -1 || q.current ? "" : `Slide ${r.slide + 1} of ${ie(e)}`)), t = r.index, n !== void 0 && r.focal !== n && P.current?.(r.focal), n = r.focal;
97
+ j(r);
98
+ let i = I.current;
99
+ t !== void 0 && r.index !== t && (i === void 0 || r.index !== A(i, r.count)) && (L.current = r.index, P.current?.(r.index)), t !== void 0 && r.index !== t && (G.current = !1, oe(r.slide === -1 || K.current ? "" : `Slide ${r.slide + 1} of ${re(e)}`)), t = r.index, n !== void 0 && r.focal !== n && F.current?.(r.focal), n = r.focal;
92
100
  }
93
101
  });
94
- return M.current = r, () => {
95
- r.destroy(), M.current = null;
102
+ return N.current = r, () => {
103
+ r.destroy(), N.current = null;
96
104
  };
97
- }, [O]), S(() => {
98
- M.current?.setDrag(i);
99
- }, [i]), S(() => {
100
- M.current?.setClickToFocus(o);
101
- }, [o]), S(() => {
102
- R.current = l, M.current?.setOrientation(l);
105
+ }, [T]), w(() => {
106
+ N.current?.setDrag(i);
107
+ }, [i]), w(() => {
108
+ N.current?.setClickToFocus(o);
109
+ }, [o]), w(() => {
110
+ R.current = l, N.current?.setOrientation(l);
103
111
  }, [l]);
104
- let Y = u(e);
105
- S(() => {
106
- let t = M.current, n = e !== Y.current;
107
- n && (q.current = !1, J.current = null), Y.current = e;
108
- let r = I.current;
109
- if (I.current = null, e !== void 0 && k.count !== null && t) {
110
- let i = D(e, k.count), a = t.target();
111
- i !== (a ?? k.index) && (i !== r || a === null) && t.scrollTo(e, n ? "direct" : "short");
112
+ let J = u(e);
113
+ w(() => {
114
+ let t = N.current, n = e !== J.current;
115
+ n && (K.current = !1, q.current = null), J.current = e;
116
+ let r = L.current;
117
+ if (L.current = null, e !== void 0 && E.count !== null && t) {
118
+ let i = A(e, E.count), a = t.target();
119
+ i !== (a ?? E.index) && (i !== r || a === null) && t.scrollTo(e, n ? "direct" : "short");
112
120
  }
113
121
  }, [
114
122
  e,
115
- k.index,
116
- k.count
123
+ E.index,
124
+ E.count
117
125
  ]);
118
- let X = p !== void 0;
119
- S(() => {
120
- if (!X) return;
126
+ let Y = p !== void 0;
127
+ w(() => {
128
+ if (!Y) return;
121
129
  let e = matchMedia("(prefers-reduced-motion: reduce)"), t = () => {
122
- e.matches && V(!1);
130
+ e.matches && B(!1);
123
131
  };
124
132
  return t(), e.addEventListener("change", t), () => e.removeEventListener("change", t);
125
- }, [X]), s(() => {
126
- if (!X) return;
133
+ }, [Y]), s(() => {
134
+ if (!Y) return;
127
135
  let e = () => ce(document.visibilityState === "hidden");
128
136
  return e(), document.addEventListener("visibilitychange", e), () => document.removeEventListener("visibilitychange", e);
129
- }, [X]);
130
- let Z = X && B && !H && !se && k.count !== null && !L(k.count);
137
+ }, [Y]);
138
+ let X = Y && z && !se && !U && E.count !== null && !H(E.count);
131
139
  s(() => {
132
- if (!Z) return;
140
+ if (!X) return;
133
141
  let e, t = () => {
134
- K.current = !0, J.current = null, V(!1);
142
+ G.current = !0, q.current = null, B(!1);
135
143
  }, n = () => {
136
- let r = M.current;
144
+ let r = N.current;
137
145
  if (r) {
138
146
  if (r.target() !== null || W.current || document.visibilityState === "hidden") {
139
147
  e = setTimeout(n, p);
140
148
  return;
141
149
  }
142
- if (J.current === k.index) {
150
+ if (q.current === E.index) {
143
151
  t();
144
152
  return;
145
153
  }
146
- J.current = k.index, q.current = !0, r.next(), r.target() === null && t();
154
+ q.current = E.index, K.current = !0, r.next(), r.target() === null && t();
147
155
  }
148
156
  };
149
157
  return e = setTimeout(n, p), () => clearTimeout(e);
150
158
  }, [
151
- Z,
159
+ X,
152
160
  p,
153
- k.index
161
+ E.index
154
162
  ]);
155
163
  let le = () => {
156
- if (B) {
157
- V(!1);
164
+ if (z) {
165
+ B(!1);
158
166
  return;
159
167
  }
160
- J.current = null, K.current && (K.current = !1, q.current = !0, M.current?.scrollTo(0)), V(!0);
161
- }, Q = ({ target: e }) => {
168
+ q.current = null, G.current && (G.current = !1, K.current = !0, N.current?.scrollTo(0)), B(!0);
169
+ }, Z = ({ target: e }) => {
162
170
  let t = e;
163
- t.closest("[data-carouseldeck-autoplay-toggle]") || (j.current?.contains(t) ? ue() : $());
164
- }, $ = () => (q.current = !1, J.current = null, M.current), ue = () => (X && V(!1), $());
171
+ t.closest("[data-carouseldeck-autoplay-toggle]") || (M.current?.contains(t) ? $() : Q());
172
+ }, Q = () => (K.current = !1, q.current = null, N.current), $ = () => (Y && B(!1), Q());
165
173
  c(r, () => ({
166
- scrollTo: (e) => $()?.scrollTo(e),
167
- next: () => $()?.next(),
168
- prev: () => $()?.prev()
174
+ scrollTo: (e) => Q()?.scrollTo(e),
175
+ next: () => Q()?.next(),
176
+ prev: () => Q()?.prev()
169
177
  }), []);
170
- let de = x(E), fe = k.count === null ? te(m, G) ?? de : null;
171
- return /* @__PURE__ */ T(E, {
178
+ let de = C(O), fe = E.count === null ? k(m, ue) ?? de : null;
179
+ return /* @__PURE__ */ D(O, {
172
180
  value: null,
173
- children: /* @__PURE__ */ T(ne, {
181
+ children: /* @__PURE__ */ D(te, {
174
182
  value: {
175
- ...k,
183
+ ...E,
176
184
  slides: fe,
177
- initialIndex: O,
185
+ initialIndex: T,
178
186
  orientation: l,
179
187
  loop: f,
180
- viewportRef: j,
181
- engineRef: M,
182
- hasAutoplay: X,
183
- playing: B,
188
+ viewportRef: M,
189
+ engineRef: N,
190
+ hasAutoplay: Y,
191
+ playing: z,
184
192
  togglePlaying: le,
185
- userMove: ue
193
+ userMove: $
186
194
  },
187
195
  children: /* @__PURE__ */ ee("div", {
188
196
  role: "region",
189
197
  "aria-roledescription": "carousel",
190
- "data-index": k.index,
191
- ...w,
198
+ "data-index": E.index,
199
+ ...S,
192
200
  onFocus: (e) => {
193
- g?.(e);
201
+ h?.(e);
194
202
  let t = e.target;
195
- for (; t && t.parentElement !== j.current;) t = t.parentElement;
196
- t && !t.contains(e.relatedTarget) && M.current?.target() != null && $(), X && !e.target.closest("[data-carouseldeck-autoplay-toggle]") && V(!1);
203
+ for (; t && t.parentElement !== M.current;) t = t.parentElement;
204
+ t && !t.contains(e.relatedTarget) && N.current?.target() != null && Q(), Y && !e.target.closest("[data-carouseldeck-autoplay-toggle]") && B(!1);
197
205
  },
198
206
  onPointerEnter: (e) => {
199
- _?.(e), W.current = !0, X && U(!0);
207
+ g?.(e), W.current = !0, Y && V(!0);
200
208
  },
201
209
  onPointerLeave: (e) => {
202
- v?.(e), W.current = !1, X && U(!1);
210
+ v?.(e), W.current = !1, Y && V(!1);
203
211
  },
204
212
  onPointerDown: (e) => {
205
- y?.(e), Q(e);
213
+ y?.(e), Z(e);
206
214
  },
207
215
  onKeyDown: (e) => {
208
- b?.(e), Q(e);
216
+ b?.(e), Z(e);
209
217
  },
210
218
  onWheel: (e) => {
211
- C?.(e), Q(e);
219
+ x?.(e), Z(e);
212
220
  },
213
- children: [m, /* @__PURE__ */ T("div", {
214
- "aria-live": Z ? "off" : "polite",
221
+ children: [m, /* @__PURE__ */ D("div", {
222
+ "aria-live": X ? "off" : "polite",
215
223
  "aria-atomic": "true",
216
224
  "data-carouseldeck-live": "",
217
- style: re,
218
- children: oe
225
+ style: ne,
226
+ children: ae
219
227
  })]
220
228
  })
221
229
  })
222
230
  });
223
231
  }
224
- var re = {
232
+ var ne = {
225
233
  position: "absolute",
226
234
  width: 1,
227
235
  height: 1,
@@ -231,8 +239,8 @@ var re = {
231
239
  clip: "rect(0 0 0 0)",
232
240
  whiteSpace: "nowrap",
233
241
  border: 0
234
- }, ie = (e) => [...e.children].filter((e) => !e.hasAttribute(m) && !e.hasAttribute(p)).length;
235
- function ae(e, t, n) {
242
+ }, re = (e) => [...e.children].filter((e) => !e.hasAttribute(h) && !e.hasAttribute(p) && !e.hasAttribute(m) && !e.hasAttribute(g)).length;
243
+ function ie(e, t, n) {
236
244
  let r = e !== void 0, [i] = d(r), a = r && t !== void 0, o = r !== i, c = r && n === void 0, l = u(/* @__PURE__ */ new Set());
237
245
  s(() => {
238
246
  let e = (e, t) => {
@@ -246,16 +254,16 @@ function ae(e, t, n) {
246
254
  i
247
255
  ]);
248
256
  }
249
- var A = b(null);
250
- function j() {
251
- let e = x(A);
257
+ var F = S(null);
258
+ function I() {
259
+ let e = C(F);
252
260
  if (!e) throw Error("Deck.useSlide must be inside Deck.Slide");
253
261
  return {
254
262
  index: e.index,
255
263
  copy: e.copy
256
264
  };
257
265
  }
258
- var M = {
266
+ var L = {
259
267
  horizontal: {
260
268
  display: "flex",
261
269
  overflowX: "auto",
@@ -268,80 +276,138 @@ var M = {
268
276
  scrollSnapType: "y mandatory"
269
277
  }
270
278
  };
271
- function N({ style: n, children: r, effect: a, ...o }) {
272
- let { viewportRef: s, engineRef: c, orientation: l, loop: u, count: d, initialIndex: f } = O("Viewport"), p = e.toArray(r), m = u && !L(d), h = p.length * (m ? 3 : 1), g = a?.layout?.(l, h), _ = g?.target, v = _ !== void 0, y = D(f, p.length), b = p.map((e) => i(e) ? e.key : "").join();
273
- S(() => {
279
+ function R({ style: n, children: r, effect: a, ...o }) {
280
+ let { viewportRef: s, engineRef: c, orientation: l, loop: u, count: d, initialIndex: f, copies: p } = N("Viewport"), m = l === "vertical", h = e.toArray(r), g = u && !H(d), _ = g && !p, v = g && p, y = a?.layout?.(l, h.length)?.target !== void 0, b = h.length * (v ? 3 : _ && y ? 5 : 1), x = a?.layout?.(l, b), S = x?.target, C = A(f, h.length), T = _ && !y, E = (e) => T ? Math.max(-2, Math.min(2, Math.floor((C - e) / h.length + .5))) : 0, O = _ && y, k = h.map((e) => i(e) ? e.key : "").join();
281
+ w(() => {
274
282
  c.current?.refresh();
275
283
  }, [
276
284
  c,
277
- p.length,
278
- m,
285
+ h.length,
279
286
  v,
280
- b
287
+ _,
288
+ y,
289
+ k
281
290
  ]);
282
- let x = (e) => p.map((t, n) => /* @__PURE__ */ T(A, {
283
- value: {
284
- index: n,
285
- count: p.length,
286
- stacked: v,
287
- style: e === "before" ? {
288
- ...g?.slide,
289
- order: -1
290
- } : g?.slide,
291
- progress: n - y + (e === "after" ? p.length : e ? -p.length : 0),
292
- copy: e
293
- },
294
- children: t
295
- }, i(t) ? t.key : n));
291
+ let j = (e) => h.map((t, n) => {
292
+ let r = E(n);
293
+ return /* @__PURE__ */ D(F, {
294
+ value: {
295
+ index: n,
296
+ count: h.length,
297
+ stacked: y,
298
+ style: e === "before" ? {
299
+ ...x?.slide,
300
+ order: -1
301
+ } : x?.slide,
302
+ progress: O ? M(n - C, h.length) : n - C + (e === "after" ? h.length : e ? -h.length : r * h.length),
303
+ placed: !O && r !== 0 ? r * h.length : void 0,
304
+ copy: e
305
+ },
306
+ children: t
307
+ }, i(t) ? t.key : n);
308
+ });
296
309
  return /* @__PURE__ */ ee("div", {
297
310
  ref: s,
298
311
  tabIndex: 0,
299
312
  "data-carouseldeck-viewport": "",
300
313
  "data-orientation": l,
301
314
  "data-carouseldeck-effect": a?.name,
315
+ "data-carouseldeck-loop": g ? _ ? "shells" : "copies" : void 0,
302
316
  style: {
303
- ...M[l],
304
- ...g?.viewport,
317
+ ...L[l],
318
+ ...x?.viewport,
305
319
  ...n
306
320
  },
307
321
  ...o,
308
322
  children: [
309
- /* @__PURE__ */ T("style", {
323
+ /* @__PURE__ */ D("style", {
310
324
  href: "carouseldeck-slide",
311
325
  precedence: "carouseldeck",
312
- children: P
326
+ children: B
313
327
  }),
314
- a && /* @__PURE__ */ T("style", {
328
+ a && /* @__PURE__ */ D("style", {
315
329
  href: `carouseldeck-${a.name}`,
316
330
  precedence: "carouseldeck",
317
331
  children: a.css
318
332
  }),
319
- x(),
320
- m && /* @__PURE__ */ T(t, { children: x("after") }, "after"),
321
- m && /* @__PURE__ */ T(t, { children: x("before") }, "before"),
322
- _ && Array.from({ length: h }, (e, t) => /* @__PURE__ */ T("div", {
333
+ j(),
334
+ v && /* @__PURE__ */ D(t, { children: j("after") }, "after"),
335
+ v && /* @__PURE__ */ D(t, { children: j("before") }, "before"),
336
+ _ && !y && /* @__PURE__ */ D("div", {
337
+ "data-carouseldeck-spacer": "before",
338
+ "aria-hidden": "true",
339
+ style: z(!0, h.length)
340
+ }),
341
+ _ && !y && /* @__PURE__ */ D("div", {
342
+ "data-carouseldeck-spacer": "after",
343
+ "aria-hidden": "true",
344
+ style: z(!1, h.length)
345
+ }),
346
+ _ && ae.flatMap((e) => Array.from({ length: h.length }, (t, n) => /* @__PURE__ */ D("div", {
347
+ "data-carouseldeck-shell": e,
348
+ "data-carouseldeck-snap-target": y ? "" : void 0,
349
+ "aria-hidden": "true",
350
+ inert: !0,
351
+ style: y ? S?.((e + 2) * h.length + n) : {
352
+ ...oe,
353
+ [m ? "insetBlockStart" : "insetInlineStart"]: `${((e + 2) * h.length + n) * 100}%`
354
+ }
355
+ }, `shell:${e}:${n}`))),
356
+ S && !O && Array.from({ length: b }, (e, t) => /* @__PURE__ */ D("div", {
323
357
  "aria-hidden": "true",
324
358
  "data-carouseldeck-snap-target": "",
325
- style: _(t)
359
+ style: S(t)
326
360
  }, `target-${t}`))
327
361
  ]
328
362
  });
329
363
  }
330
- var P = ":where([data-carouseldeck-slide]){width:100%;scroll-snap-align:start}:where([data-orientation=vertical]>[data-carouseldeck-slide]){height:100%}:where([data-carouseldeck-viewport]){scrollbar-width:none}@supports not (scrollbar-width:none){:where([data-carouseldeck-viewport])::-webkit-scrollbar{display:none}}", F = { scrollInitialTarget: "nearest" };
331
- function I({ style: e, ...t }) {
332
- let n = O("Slide"), r = x(A);
364
+ var ae = [
365
+ -2,
366
+ -1,
367
+ 0,
368
+ 1,
369
+ 2
370
+ ], oe = {
371
+ position: "absolute",
372
+ margin: 0,
373
+ padding: 0,
374
+ border: 0,
375
+ scale: "none",
376
+ rotate: "none",
377
+ translate: "none",
378
+ opacity: 0,
379
+ pointerEvents: "none",
380
+ scrollSnapAlign: "none"
381
+ }, z = (e, t) => ({
382
+ ...e && { order: -1 },
383
+ flexGrow: 0,
384
+ flexShrink: 0,
385
+ margin: 0,
386
+ padding: 0,
387
+ border: 0,
388
+ scale: "none",
389
+ rotate: "none",
390
+ translate: "none",
391
+ opacity: 0,
392
+ pointerEvents: "none",
393
+ scrollSnapAlign: "none",
394
+ ...e ? { "--carouseldeck-spacer-estimate": `${2 * t * 100}%` } : { flexBasis: `${2 * t * 100}%` }
395
+ }), B = ":where([data-carouseldeck-slide]){width:100%;scroll-snap-align:start}:where([data-orientation=vertical]>[data-carouseldeck-slide]){height:100%}:where([data-carouseldeck-viewport]){scrollbar-width:none}:where([data-carouseldeck-loop=shells]){position:relative}:where([data-carouseldeck-loop=shells]){overflow-anchor:none}:where([data-carouseldeck-placed]){translate:calc(var(--carouseldeck-placed) * 100%) 0}:where([data-carouseldeck-placed]:dir(rtl)){translate:calc(var(--carouseldeck-placed) * -100%) 0}:where([data-orientation=vertical]>[data-carouseldeck-placed]){translate:0 calc(var(--carouseldeck-placed) * 100%)}@supports (scroll-initial-target: nearest) {:where([data-carouseldeck-spacer=\"before\"]){flex-basis:var(--carouseldeck-spacer-estimate)}}@supports not (scrollbar-width:none){:where([data-carouseldeck-viewport])::-webkit-scrollbar{display:none}}", se = { scrollInitialTarget: "nearest" };
396
+ function V({ style: e, ...t }) {
397
+ let n = N("Slide"), r = C(F);
333
398
  if (!r) throw Error("Deck.Slide must be inside Deck.Viewport");
334
- let { index: i, count: a, stacked: o, copy: s } = r, c = !s && i === D(n.initialIndex, a), l = !s && (n.slide === null ? c : i === n.slide), u = !s && (n.focal === null ? c : i === n.focal), d = s !== void 0 || o && !u, { viewportRef: f } = n;
335
- return S(() => {
399
+ let { index: i, count: a, stacked: o, copy: s } = r, c = !s && i === A(n.initialIndex, a), l = !s && (n.slide === null ? c : i === n.slide), u = !s && (n.focal === null ? c : i === n.focal), d = s !== void 0 || o && !u, { viewportRef: f } = n;
400
+ return w(() => {
336
401
  if (!d) return;
337
402
  let e = f.current, t = document.activeElement?.closest("[data-carouseldeck-slide][inert]");
338
403
  e && t?.parentElement === e && e.focus({ preventScroll: !0 });
339
- }, [d, f]), /* @__PURE__ */ T("div", {
404
+ }, [d, f]), /* @__PURE__ */ D("div", {
340
405
  role: "group",
341
406
  "aria-roledescription": "slide",
342
407
  "aria-label": `${i + 1} of ${a}`,
343
408
  "data-carouseldeck-slide": "",
344
409
  "data-carouseldeck-copy": s,
410
+ "data-carouseldeck-placed": r.placed === void 0 ? void 0 : "",
345
411
  "aria-hidden": s ? !0 : void 0,
346
412
  "data-current": l ? "" : void 0,
347
413
  "data-focal": u ? "" : void 0,
@@ -351,16 +417,17 @@ function I({ style: e, ...t }) {
351
417
  "--deck-slide-index": i,
352
418
  "--deck-slide-count": a,
353
419
  "--deck-slide-progress": r.progress,
354
- ...c && F,
420
+ ...r.placed !== void 0 && { "--carouseldeck-placed": r.placed },
421
+ ...c && se,
355
422
  ...r.style,
356
423
  ...e
357
424
  },
358
425
  ...t
359
426
  });
360
427
  }
361
- var L = (e) => e !== null && e <= 1;
362
- function R(e) {
363
- let t = O(e), { count: n, slides: r, loop: i, userMove: a } = t, o = n === null && r ? D(t.initialIndex, r) : t.index, s = L(n);
428
+ var H = (e) => e !== null && e <= 1;
429
+ function U(e) {
430
+ let t = N(e), { count: n, slides: r, loop: i, userMove: a } = t, o = n === null && r ? A(t.initialIndex, r) : t.index, s = H(n);
364
431
  return {
365
432
  index: o,
366
433
  count: n,
@@ -373,11 +440,11 @@ function R(e) {
373
440
  prev: () => a()?.prev()
374
441
  };
375
442
  }
376
- function oe() {
377
- return R("useDeck");
443
+ function ce() {
444
+ return U("useDeck");
378
445
  }
379
- function z({ atEnd: e, step: t, label: n, onClick: r, disabled: i, children: a, ...o }) {
380
- return /* @__PURE__ */ T("button", {
446
+ function W({ atEnd: e, step: t, label: n, onClick: r, disabled: i, children: a, ...o }) {
447
+ return /* @__PURE__ */ D("button", {
381
448
  type: "button",
382
449
  ...o,
383
450
  disabled: e || i,
@@ -388,9 +455,9 @@ function z({ atEnd: e, step: t, label: n, onClick: r, disabled: i, children: a,
388
455
  children: a ?? n
389
456
  });
390
457
  }
391
- function B(e) {
392
- let { fits: t, canPrev: n, prev: r } = R("Prev");
393
- return t ? null : /* @__PURE__ */ T(q, {
458
+ function G(e) {
459
+ let { fits: t, canPrev: n, prev: r } = U("Prev");
460
+ return t ? null : /* @__PURE__ */ D(Q, {
394
461
  ...e,
395
462
  "data-carouseldeck-prev": "",
396
463
  atEnd: !n,
@@ -398,9 +465,9 @@ function B(e) {
398
465
  label: "Previous"
399
466
  });
400
467
  }
401
- function V(e) {
402
- let { fits: t, canNext: n, next: r } = R("Next");
403
- return t ? null : /* @__PURE__ */ T(q, {
468
+ function K(e) {
469
+ let { fits: t, canNext: n, next: r } = U("Next");
470
+ return t ? null : /* @__PURE__ */ D(Q, {
404
471
  ...e,
405
472
  "data-carouseldeck-next": "",
406
473
  atEnd: !n,
@@ -408,28 +475,28 @@ function V(e) {
408
475
  label: "Next"
409
476
  });
410
477
  }
411
- function H(e) {
412
- let { index: t, count: n, slides: r, initialIndex: i, userMove: a } = O(e);
478
+ function q(e) {
479
+ let { index: t, count: n, slides: r, initialIndex: i, userMove: a } = N(e);
413
480
  return n !== null || r === null ? {
414
481
  index: t,
415
482
  count: n,
416
483
  userMove: a
417
484
  } : {
418
- index: D(i, r),
485
+ index: A(i, r),
419
486
  count: r,
420
487
  userMove: a
421
488
  };
422
489
  }
423
- function U(e) {
424
- let { index: t, count: n, userMove: r } = H("Dots");
425
- return L(n) ? null : /* @__PURE__ */ T("div", {
490
+ function J(e) {
491
+ let { index: t, count: n, userMove: r } = q("Dots");
492
+ return H(n) ? null : /* @__PURE__ */ D("div", {
426
493
  role: "group",
427
494
  "aria-label": "Choose page",
428
495
  ...e,
429
496
  "data-carouseldeck-dots": "",
430
497
  "data-index": n === null ? void 0 : t,
431
498
  "data-count": n ?? void 0,
432
- children: Array.from({ length: n ?? 0 }, (e, n) => /* @__PURE__ */ T("button", {
499
+ children: Array.from({ length: n ?? 0 }, (e, n) => /* @__PURE__ */ D("button", {
433
500
  type: "button",
434
501
  "aria-label": `Go to page ${n + 1}`,
435
502
  "aria-current": n === t ? "true" : void 0,
@@ -438,11 +505,11 @@ function U(e) {
438
505
  }, n))
439
506
  });
440
507
  }
441
- function se(e) {
442
- let { index: t, count: n } = H("Counter");
443
- if (L(n)) return null;
508
+ function Y(e) {
509
+ let { index: t, count: n } = q("Counter");
510
+ if (H(n)) return null;
444
511
  let r = n !== null;
445
- return /* @__PURE__ */ T("span", {
512
+ return /* @__PURE__ */ D("span", {
446
513
  ...e,
447
514
  "data-carouseldeck-counter": "",
448
515
  "data-index": r ? t : void 0,
@@ -450,9 +517,9 @@ function se(e) {
450
517
  children: r && `${t + 1} / ${n}`
451
518
  });
452
519
  }
453
- function ce({ onClick: e, children: t, ...n }) {
454
- let { hasAutoplay: r, playing: i, togglePlaying: a, count: o } = O("AutoplayToggle");
455
- return !r || L(o) ? null : /* @__PURE__ */ T("button", {
520
+ function X({ onClick: e, children: t, ...n }) {
521
+ let { hasAutoplay: r, playing: i, togglePlaying: a, count: o } = N("AutoplayToggle");
522
+ return !r || H(o) ? null : /* @__PURE__ */ D("button", {
456
523
  type: "button",
457
524
  ...n,
458
525
  "data-carouseldeck-autoplay-toggle": "",
@@ -463,6 +530,6 @@ function ce({ onClick: e, children: t, ...n }) {
463
530
  children: t ?? (i ? "Stop slide rotation" : "Start slide rotation")
464
531
  });
465
532
  }
466
- var W = y(k, "Root"), G = y(N, "Viewport"), K = y(I, "Slide"), q = y(z, "StepButton"), J = y(B, "Prev"), Y = y(V, "Next"), X = y(U, "Dots"), Z = y(se, "Counter"), le = y(ce, "AutoplayToggle");
533
+ var le = x(P, "Root"), ue = x(R, "Viewport"), Z = x(V, "Slide"), Q = x(W, "StepButton"), $ = x(G, "Prev"), de = x(K, "Next"), fe = x(J, "Dots"), pe = x(Y, "Counter"), me = x(X, "AutoplayToggle");
467
534
  //#endregion
468
- export { le as AutoplayToggle, Z as Counter, X as Dots, Y as Next, J as Prev, W as Root, K as Slide, G as Viewport, oe as useDeck, j as useSlide };
535
+ export { me as AutoplayToggle, pe as Counter, fe as Dots, de as Next, $ as Prev, le as Root, Z as Slide, ue as Viewport, ce as useDeck, I as useSlide };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@carouseldeck/react-18",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "@carouseldeck/react built for React 18: headless, composable carousel primitives on native scroll snap.",
5
5
  "license": "MIT",
6
- "homepage": "https://slide.deck.cool",
6
+ "homepage": "https://carousel.deck.cool",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/pedrosousa13/deck-cool.git",
@@ -38,7 +38,7 @@
38
38
  "provenance": true
39
39
  },
40
40
  "dependencies": {
41
- "@carouseldeck/core": "1.2.0"
41
+ "@carouseldeck/core": "1.3.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "react": ">=18 <19",
@@ -50,7 +50,7 @@
50
50
  "react": "18.3.1",
51
51
  "react-dom": "18.3.1",
52
52
  "vite": "8.3.1",
53
- "@carouseldeck/react": "1.2.0"
53
+ "@carouseldeck/react": "1.3.0"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "vite build"