@carouseldeck/react-18 0.0.0-stage → 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.
- package/LICENSE +21 -0
- package/README.md +34 -2
- package/dist/curve.d.ts +33 -0
- package/dist/curve.js +12 -0
- package/dist/fade.d.ts +24 -0
- package/dist/fade.js +32 -0
- package/dist/index.d.ts +218 -0
- package/dist/index.js +535 -0
- package/dist/theme.css +184 -0
- package/package.json +55 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pedro Sousa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @carouseldeck/react-18
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@carouseldeck/react` built for React 18. It has the same components, props and
|
|
4
|
+
types, from the same source.
|
|
5
|
+
|
|
6
|
+
On React 18, install it in place of `@carouseldeck/react` and import from
|
|
7
|
+
`@carouseldeck/react-18`. It is published at the same version as
|
|
8
|
+
`@carouseldeck/react`, from 1.2.0.
|
|
9
|
+
|
|
10
|
+
## How it is built
|
|
11
|
+
|
|
12
|
+
The source in `packages/react/src` is written for React 19, and this package
|
|
13
|
+
does not change it. The React 19 package ships the same code it did before,
|
|
14
|
+
at the same size. This package's build (`vite.config.ts`) adapts the source to
|
|
15
|
+
React 18:
|
|
16
|
+
|
|
17
|
+
- `src/react.ts` stands in for `react`. `use` reads a context with
|
|
18
|
+
`useContext`, a context renders as React 18's provider, and
|
|
19
|
+
`useLayoutEffect` is `useEffect` on the server, where React 18 warns about
|
|
20
|
+
it. In development, it reports a React other than 18.
|
|
21
|
+
- `src/jsx-runtime.ts` stands in for `react/jsx-runtime`. `inert` renders as
|
|
22
|
+
React 18 needs it. The deck's `<style>` elements render just before the
|
|
23
|
+
viewport, one per deck, because React 18 does not hoist them, and its CSS
|
|
24
|
+
is set as HTML, because React 18's server renderer escapes `>`.
|
|
25
|
+
- Every component in the source is wrapped in `forwardRef` (`src/with-ref.ts`),
|
|
26
|
+
so a `ref` reaches its element as it does in React 19.
|
|
27
|
+
|
|
28
|
+
The package has no `react-server` entry: React 18 has no server components.
|
|
29
|
+
|
|
30
|
+
## Tests
|
|
31
|
+
|
|
32
|
+
`pnpm test:react-18` builds this package, then type-checks a consumer
|
|
33
|
+
(`test/consumer.tsx`) with React 18's types. It then runs the React package's
|
|
34
|
+
tests on React 18 against the build (`vitest.react-18.config.ts` at the repo
|
|
35
|
+
root), with this package's own tests in `test/`.
|
package/dist/curve.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Effect } from './index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fans the slides along an arc around the focal slide while the viewport
|
|
4
|
+
* scrolls, snaps and drags natively (ADR-0006). Pass it to `Deck.Viewport`'s
|
|
5
|
+
* `effect`:
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { curve } from '@carouseldeck/react/curve';
|
|
9
|
+
*
|
|
10
|
+
* <Deck.Viewport effect={curve}>…</Deck.Viewport>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* The slides keep their place in the deck, their size, gap and alignment, and
|
|
14
|
+
* snap as they would without the curve, in pages too. Each slide's content,
|
|
15
|
+
* its children, turns about its centre and drops across the axis to sit on a
|
|
16
|
+
* circle under the focal slide, and the slide fades with its distance from
|
|
17
|
+
* it, following its progress. Give each slide one child that fills it, styled
|
|
18
|
+
* as the slide is seen: a slide's own background stays in place, and several
|
|
19
|
+
* children each turn about their own centre. The circle's radius, in slides,
|
|
20
|
+
* is `--deck-curve-radius`, 4 by default and never 0 or less: set it in CSS
|
|
21
|
+
* on the viewport, per breakpoint if needed. A slide a radius away or more has
|
|
22
|
+
* turned a quarter and faded out.
|
|
23
|
+
*
|
|
24
|
+
* Each slide contains its layout, so its turned content is drawn on the arc
|
|
25
|
+
* but adds nothing the viewport can scroll to, and focus never scrolls the
|
|
26
|
+
* viewport after it. The viewport clips across the axis, so the arc never
|
|
27
|
+
* shows a scrollbar: give it padding there to show more of the arc. A
|
|
28
|
+
* vertical deck's arc bends toward the inline end, and a right-to-left deck's
|
|
29
|
+
* mirrors. Under reduced motion the content stays flat
|
|
30
|
+
* and the slides only fade.
|
|
31
|
+
*/
|
|
32
|
+
export declare const curve: Effect;
|
|
33
|
+
//# sourceMappingURL=curve.d.ts.map
|
package/dist/curve.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region ../react/src/curve.ts
|
|
3
|
+
var e = "[data-carouseldeck-effect=curve]>[data-carouseldeck-slide]", t = `${e}>*`, n = "var(--carouseldeck-curve-progress)", r = "var(--carouseldeck-curve-radius)", i = "var(--carouseldeck-curve-x)", a = "var(--carouseldeck-curve-turn)", o = "var(--carouseldeck-curve-drop)", s = "var(--carouseldeck-curve-sign)", c = {
|
|
4
|
+
name: "curve",
|
|
5
|
+
css: `:where(${e}){--carouseldeck-curve-progress:var(--deck-slide-progress,0);--carouseldeck-curve-radius:max(var(--deck-curve-radius,4),0.001);--carouseldeck-curve-x:clamp(-1,${n}/${r},1);--carouseldeck-curve-turn:asin(${i});--carouseldeck-curve-drop:calc(${r}*(1 - sqrt(1 - ${i}*${i})));--carouseldeck-curve-sign:1;opacity:calc(1 - max(${i},-1*${i}))}:where(${e}:dir(rtl)){--carouseldeck-curve-sign:-1}:where(${t}){transform:rotate(90deg) translateX(calc(${o}*100%)) rotate(-90deg) rotate(calc(${s}*${a}))}:where([data-orientation=vertical]${t}){transform:rotate(-90deg) translateY(calc(${s}*${o}*100%)) rotate(90deg) rotate(calc(-1*${s}*${a}))}@media (prefers-reduced-motion:reduce){:where(${t}){transform:none}}`,
|
|
6
|
+
layout: (e) => ({
|
|
7
|
+
viewport: e === "vertical" ? { overflowX: "hidden" } : { overflowY: "hidden" },
|
|
8
|
+
slide: { contain: "layout" }
|
|
9
|
+
})
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { c as curve };
|
package/dist/fade.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Effect } from './index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Crossfades the slides in place while the viewport scrolls, snaps and drags
|
|
4
|
+
* natively (ADR-0006). Pass it to `Deck.Viewport`'s `effect`:
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* import { fade } from '@carouseldeck/react/fade';
|
|
8
|
+
*
|
|
9
|
+
* <Deck.Viewport effect={fade}>…</Deck.Viewport>
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* The slides are stacked with `position: sticky` over an empty snap target
|
|
13
|
+
* per slide, which gives the viewport its scroll length and snap points. Each
|
|
14
|
+
* slide's opacity follows its progress, 1 at the focal position and 0 a slide
|
|
15
|
+
* away; under reduced motion it cuts from one slide to the next halfway
|
|
16
|
+
* instead. Only the focal slide can be seen, so every other slide is inert.
|
|
17
|
+
*
|
|
18
|
+
* Each slide fills the viewport and snaps at its start: a fade shows one slide
|
|
19
|
+
* at a time, so slide size, alignment and group snapping (pages) do not apply.
|
|
20
|
+
* A horizontal deck is as tall as its tallest slide; a vertical one needs a
|
|
21
|
+
* height, as any vertical deck does.
|
|
22
|
+
*/
|
|
23
|
+
export declare const fade: Effect;
|
|
24
|
+
//# sourceMappingURL=fade.d.ts.map
|
package/dist/fade.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region ../react/src/stacked.ts
|
|
3
|
+
var e = (e, t) => {
|
|
4
|
+
let n = e === "vertical", r = `repeat(${Math.max(t, 1)}, 100%)`, i = n ? "gridRow" : "gridColumn", a = n ? "gridColumn" : "gridRow";
|
|
5
|
+
return {
|
|
6
|
+
viewport: {
|
|
7
|
+
display: "grid",
|
|
8
|
+
gridTemplateColumns: n ? "100%" : r,
|
|
9
|
+
gridTemplateRows: n ? r : "100%"
|
|
10
|
+
},
|
|
11
|
+
slide: {
|
|
12
|
+
[a]: "1",
|
|
13
|
+
[i]: "1 / -1",
|
|
14
|
+
[n ? "alignSelf" : "justifySelf"]: "start",
|
|
15
|
+
[n ? "height" : "width"]: `calc(100% / ${Math.max(t, 1)})`,
|
|
16
|
+
position: "sticky",
|
|
17
|
+
[n ? "top" : "insetInlineStart"]: 0,
|
|
18
|
+
scrollSnapAlign: "none"
|
|
19
|
+
},
|
|
20
|
+
target: (e) => ({
|
|
21
|
+
[a]: "1",
|
|
22
|
+
[i]: String(e + 1),
|
|
23
|
+
scrollSnapAlign: "start"
|
|
24
|
+
})
|
|
25
|
+
};
|
|
26
|
+
}, t = "[data-carouseldeck-effect=fade]>[data-carouseldeck-slide]", n = (e) => `--carouseldeck-fade-progress:var(--deck-slide-progress,${e})`, r = "var(--carouseldeck-fade-progress)", i = `--carouseldeck-fade-distance:min(max(${r},-1*${r}),1)`, a = {
|
|
27
|
+
name: "fade",
|
|
28
|
+
css: `:where(${t}){${n(1)};${i};opacity:calc(1 - var(--carouseldeck-fade-distance))}:where(${t}[data-focal]){${n(0)}}@media (prefers-reduced-motion:reduce){:where(${t}){opacity:clamp(0,min(0.5 + ${r},0.501 - ${r})*1000,1)}}`,
|
|
29
|
+
layout: e
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { a as fade };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { type ComponentProps, type CSSProperties, type Ref } from 'react';
|
|
2
|
+
import { type Orientation } from '@carouseldeck/core';
|
|
3
|
+
export type { Orientation };
|
|
4
|
+
/** What `Deck.Root`'s `handleRef` exposes: moves for event handlers that
|
|
5
|
+
* should not round-trip through state. Each fires `onIndexChange` when the deck
|
|
6
|
+
* settles on a new snap point. */
|
|
7
|
+
export interface RootHandle {
|
|
8
|
+
/** Scrolls to a snap point, clamped to the snap points there are. */
|
|
9
|
+
scrollTo(index: number): void;
|
|
10
|
+
/** Scrolls one snap point on. */
|
|
11
|
+
next(): void;
|
|
12
|
+
/** Scrolls one snap point back. */
|
|
13
|
+
prev(): void;
|
|
14
|
+
}
|
|
15
|
+
interface RootBaseProps extends ComponentProps<'div'> {
|
|
16
|
+
/** The deck's moves; `ref` is the region element, as on every primitive. */
|
|
17
|
+
handleRef?: Ref<RootHandle>;
|
|
18
|
+
/** Whether a mouse can drag the deck, settling on a snap point when it lets
|
|
19
|
+
* go. A drag never clicks what it started on. Touch, pen and trackpad
|
|
20
|
+
* always scroll natively. Defaults to true. */
|
|
21
|
+
drag?: boolean;
|
|
22
|
+
/** Called once each time the focal slide changes, with its slide index,
|
|
23
|
+
* or -1 when no slide snaps: when a scroll settles, never during one, and
|
|
24
|
+
* not for where the deck starts. */
|
|
25
|
+
onFocalChange?: (slide: number) => void;
|
|
26
|
+
/** Whether clicking a slide brings it to the focal position, as near as
|
|
27
|
+
* the scroll range allows; with pages, its page. A click that ends a mouse
|
|
28
|
+
* drag does not, nor does a keyboard click (Enter or Space on a control),
|
|
29
|
+
* nor a programmatic `element.click()` (detail 0): call `scrollTo` on the
|
|
30
|
+
* handle instead. Defaults to false. */
|
|
31
|
+
clickToFocus?: boolean;
|
|
32
|
+
/** The axis the deck scrolls along. A vertical deck needs a height, set on
|
|
33
|
+
* `Deck.Viewport` in CSS. Horizontal follows the writing direction: in a
|
|
34
|
+
* right-to-left document the deck starts at the right and Next moves left.
|
|
35
|
+
* Defaults to horizontal. */
|
|
36
|
+
orientation?: Orientation;
|
|
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. 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. */
|
|
49
|
+
loop?: boolean;
|
|
50
|
+
/** Moves the deck one snap point on every this many milliseconds, counted
|
|
51
|
+
* from when it comes to rest, and stops at the last, unless the deck
|
|
52
|
+
* loops, or where a step leaves the deck where it was, as when a
|
|
53
|
+
* controlled parent refuses it. A pointer over the deck or a hidden
|
|
54
|
+
* document pauses it; focus entering the deck, other than on
|
|
55
|
+
* `Deck.AutoplayToggle`, or the user moving it stops it until the toggle
|
|
56
|
+
* starts it again, and so does a preference for reduced motion, from the
|
|
57
|
+
* start. Pair it with `Deck.AutoplayToggle` (WCAG 2.2.2). Off by default. */
|
|
58
|
+
autoplay?: number;
|
|
59
|
+
}
|
|
60
|
+
/** Controlled like a React input's `value`: the deck scrolls to `index` when
|
|
61
|
+
* it changes. A scroll that settles elsewhere calls `onIndexChange`, and the
|
|
62
|
+
* deck returns to `index` unless the parent takes the new one. */
|
|
63
|
+
interface ControlledProps {
|
|
64
|
+
/** The snap point to rest at. */
|
|
65
|
+
index: number;
|
|
66
|
+
defaultIndex?: never;
|
|
67
|
+
/** Called once each time the viewport settles on a new snap point other
|
|
68
|
+
* than `index`; never for a move to `index`. Without it, every scroll returns
|
|
69
|
+
* to `index`, and development warns. */
|
|
70
|
+
onIndexChange?: (index: number) => void;
|
|
71
|
+
}
|
|
72
|
+
interface UncontrolledProps {
|
|
73
|
+
index?: never;
|
|
74
|
+
/** The snap point to start at, clamped to the snap points there are.
|
|
75
|
+
* Read once, on mount. */
|
|
76
|
+
defaultIndex?: number;
|
|
77
|
+
/** Called once each time the viewport settles on a new snap point. */
|
|
78
|
+
onIndexChange?: (index: number) => void;
|
|
79
|
+
}
|
|
80
|
+
export type RootProps = RootBaseProps & (ControlledProps | UncontrolledProps);
|
|
81
|
+
/** One deck: a labelled carousel region holding a viewport, its controls and
|
|
82
|
+
* a live region announcing the slide the user moves it to. */
|
|
83
|
+
export declare function Root({ index, defaultIndex, onIndexChange, handleRef, drag, onFocalChange, clickToFocus, orientation, loop, autoplay, children, onFocus, onPointerEnter, onPointerLeave, onPointerDown, onKeyDown, onWheel, ...props }: RootProps): import("react").JSX.Element;
|
|
84
|
+
/** What `useSlide` reports about the slide it is called in. */
|
|
85
|
+
export interface UseSlideResult {
|
|
86
|
+
/** The index of the slide, also in a loop's copy of it. */
|
|
87
|
+
index: number;
|
|
88
|
+
/** Which side of the slides a loop's copy is on; undefined in a slide. */
|
|
89
|
+
copy: 'before' | 'after' | undefined;
|
|
90
|
+
}
|
|
91
|
+
/** The slide a component is rendered in: its index, and whether it is a
|
|
92
|
+
* loop's copy, so stateful content, such as a video player, can render
|
|
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`. */
|
|
97
|
+
export declare function useSlide(): UseSlideResult;
|
|
98
|
+
/**
|
|
99
|
+
* A transition built on progress while the viewport keeps scrolling natively
|
|
100
|
+
* (GLOSSARY.md), passed to `Deck.Viewport`'s `effect`. Each effect is its own
|
|
101
|
+
* entry point, such as `@carouseldeck/react/fade`, so a deck that imports none
|
|
102
|
+
* ships none of their code.
|
|
103
|
+
*/
|
|
104
|
+
export interface Effect {
|
|
105
|
+
/** Names the effect's stylesheet, so a page holds one copy of it. */
|
|
106
|
+
name: string;
|
|
107
|
+
/** The effect's appearance, read from `--deck-slide-progress` and the
|
|
108
|
+
* slides' data attributes. Zero-specificity `:where()` rules, so consumer
|
|
109
|
+
* CSS overrides any of them (ADR-0003). */
|
|
110
|
+
css: string;
|
|
111
|
+
/** The structural styles the effect needs, set inline as the deck's own
|
|
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. */
|
|
119
|
+
layout?: (orientation: Orientation, count: number) => {
|
|
120
|
+
viewport?: CSSProperties;
|
|
121
|
+
slide?: CSSProperties;
|
|
122
|
+
target?: (index: number) => CSSProperties;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export interface ViewportProps extends ComponentProps<'div'> {
|
|
126
|
+
/** An effect, imported from its own entry point, such as `fade` from
|
|
127
|
+
* `@carouseldeck/react/fade`. */
|
|
128
|
+
effect?: Effect;
|
|
129
|
+
}
|
|
130
|
+
/** The native scroll container. Its children are the deck's slides; with
|
|
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. */
|
|
136
|
+
export declare function Viewport({ style, children, effect, ...props }: ViewportProps): import("react").JSX.Element;
|
|
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.
|
|
141
|
+
* For CSS to read, it carries `--deck-slide-index`, its index, and
|
|
142
|
+
* `--deck-slide-count`, the number of slides, copies not counted, from the
|
|
143
|
+
* first render; `--deck-slide-progress`, its signed distance from the focal
|
|
144
|
+
* position in slides, from the first render too, server HTML included,
|
|
145
|
+
* counted from the slide the deck starts at; and once mounted, `data-in-view` while any of
|
|
146
|
+
* it is in view. Progress and in-view are kept up to date as the deck scrolls
|
|
147
|
+
* without a React render. Where an effect stacks the slides, as fade does, every slide but the focal
|
|
148
|
+
* one is inert. */
|
|
149
|
+
export declare function Slide({ style, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
150
|
+
/** What `useDeck` reports about the deck it is called in. */
|
|
151
|
+
export interface UseDeckResult {
|
|
152
|
+
/** The current index: the snap point the deck rests at, a page when it
|
|
153
|
+
* snaps in pages. Until the viewport is measured, the index it starts at,
|
|
154
|
+
* clamped to the slides, as Counter shows it. */
|
|
155
|
+
index: number;
|
|
156
|
+
/** The snap points, so the pages; null until the viewport is measured, as
|
|
157
|
+
* on the server. */
|
|
158
|
+
count: number | null;
|
|
159
|
+
/** Whether `Deck.Root` has `loop`. */
|
|
160
|
+
loop: boolean;
|
|
161
|
+
/** Whether every slide fits, so there is nowhere to go: Prev, Next, Dots,
|
|
162
|
+
* Counter and AutoplayToggle are then absent. False until the viewport is
|
|
163
|
+
* measured. */
|
|
164
|
+
fits: boolean;
|
|
165
|
+
/** Whether `prev()` can move the deck: when `Deck.Prev` is enabled. */
|
|
166
|
+
canPrev: boolean;
|
|
167
|
+
/** Whether `next()` can move the deck: when `Deck.Next` is enabled. */
|
|
168
|
+
canNext: boolean;
|
|
169
|
+
/** Scrolls to a snap point, clamped to the snap points there are. */
|
|
170
|
+
scrollTo(index: number): void;
|
|
171
|
+
/** Scrolls one snap point on. */
|
|
172
|
+
next(): void;
|
|
173
|
+
/** Scrolls one snap point back. */
|
|
174
|
+
prev(): void;
|
|
175
|
+
}
|
|
176
|
+
/** The deck a component is rendered in: its state, as Prev and Next read it,
|
|
177
|
+
* and Dots and Counter once the viewport is measured, and its moves, so a
|
|
178
|
+
* consumer can build those controls from their own components. A move stops
|
|
179
|
+
* autoplay, as a built-in control's does. Like the primitives, it never
|
|
180
|
+
* re-renders while the deck scrolls (ADR-0003): it re-renders whenever
|
|
181
|
+
* `Deck.Root` does, as when the deck settles somewhere new, its snap points
|
|
182
|
+
* change or, with `autoplay`, autoplay starts, stops or pauses. Throws
|
|
183
|
+
* outside a `Deck.Root`. */
|
|
184
|
+
export declare function useDeck(): UseDeckResult;
|
|
185
|
+
/** Moves the deck one snap point back. Disabled at the first unless the deck
|
|
186
|
+
* loops; absent when every slide fits. Marked `data-carouseldeck-prev` for CSS
|
|
187
|
+
* to select. */
|
|
188
|
+
export declare function Prev(props: ComponentProps<'button'>): import("react").JSX.Element | null;
|
|
189
|
+
/** Moves the deck one snap point on. Disabled at the last unless the deck
|
|
190
|
+
* loops; absent when every slide fits. Marked `data-carouseldeck-next` for CSS
|
|
191
|
+
* to select. */
|
|
192
|
+
export declare function Next(props: ComponentProps<'button'>): import("react").JSX.Element | null;
|
|
193
|
+
/** A labelled group of buttons, one per page: one per snap point, so with
|
|
194
|
+
* several slides in a page a dot stands for the page, not a slide (ADR-0004).
|
|
195
|
+
* The current one carries `aria-current`; the group's data attributes are the
|
|
196
|
+
* deck's state, which a consumer's cannot overwrite. Absent when every slide
|
|
197
|
+
* fits. */
|
|
198
|
+
export declare function Dots(props: Omit<ComponentProps<'div'>, 'children'>): import("react").JSX.Element | null;
|
|
199
|
+
/** The current page and the total, as "3 / 10": counts pages, as Dots do.
|
|
200
|
+
* Absent when every slide fits. Not a live region: each slide is already
|
|
201
|
+
* labelled "n of m". Its data attributes are the deck's state, which
|
|
202
|
+
* a consumer's cannot overwrite. */
|
|
203
|
+
export declare function Counter(props: Omit<ComponentProps<'span'>, 'children'>): import("react").JSX.Element | null;
|
|
204
|
+
/**
|
|
205
|
+
* Stops and starts `Deck.Root`'s `autoplay`, so motion can always be stopped
|
|
206
|
+
* (WCAG 2.2.2). Its name is the action it takes, "Stop slide rotation" or
|
|
207
|
+
* "Start slide rotation", rather than `aria-pressed` (APG carousel); it is
|
|
208
|
+
* marked `data-playing` while autoplay is on, paused by a pointer or not.
|
|
209
|
+
* Children replace the visible name: give both states, shown by
|
|
210
|
+
* `data-playing` in CSS. Place it first among the deck's controls, ahead of
|
|
211
|
+
* the slides, so keyboard users reach it before the moving content. Focus on
|
|
212
|
+
* it does not stop autoplay, so it can be pressed. Starting autoplay where it
|
|
213
|
+
* stopped at the last snap point rewinds to the first. A consumer's
|
|
214
|
+
* `onClick` runs first and can cancel the toggle with `preventDefault()`.
|
|
215
|
+
* Absent without `autoplay`, and when every slide fits.
|
|
216
|
+
*/
|
|
217
|
+
export declare function AutoplayToggle({ onClick, children, ...props }: ComponentProps<'button'>): import("react").JSX.Element | null;
|
|
218
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
"use client";
|
|
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, 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
|
+
//#region src/with-ref.ts
|
|
6
|
+
function x(e, t) {
|
|
7
|
+
let n = r((t, n) => e(n === null ? t : {
|
|
8
|
+
...t,
|
|
9
|
+
ref: n
|
|
10
|
+
}));
|
|
11
|
+
return n.displayName = t, n;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/react.ts
|
|
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 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
|
+
return (t, n, r) => {
|
|
19
|
+
if (typeof t != "string") return e(t, n, r);
|
|
20
|
+
let i = n;
|
|
21
|
+
if ("inert" in i) {
|
|
22
|
+
let e = i.inert === "" || !!i.inert;
|
|
23
|
+
i = {
|
|
24
|
+
...i,
|
|
25
|
+
inert: e ? "" : void 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (t === "style" && "precedence" in i) {
|
|
29
|
+
let { children: e, ...t } = i;
|
|
30
|
+
delete t.href, delete t.precedence;
|
|
31
|
+
let n = String(e).replace(/<\/style/gi, "<\\/style");
|
|
32
|
+
i = {
|
|
33
|
+
...t,
|
|
34
|
+
dangerouslySetInnerHTML: { __html: n }
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if ("data-carouseldeck-viewport" in i && Array.isArray(i.children)) {
|
|
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
|
+
...i,
|
|
41
|
+
children: a
|
|
42
|
+
})] }, r);
|
|
43
|
+
}
|
|
44
|
+
return e(t, i, r);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
var D = E(y), ee = E(b), O = S(null);
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region ../react/src/slides-in.ts
|
|
50
|
+
function k(n, r) {
|
|
51
|
+
for (let a of e.toArray(n)) {
|
|
52
|
+
if (!i(a)) continue;
|
|
53
|
+
if (a.type === r) return e.toArray(a.props.children).length;
|
|
54
|
+
if (typeof a.type != "string" && a.type !== t) continue;
|
|
55
|
+
let n = k(a.props.children, r);
|
|
56
|
+
if (n !== null) return n;
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region ../react/src/index.tsx
|
|
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);
|
|
72
|
+
if (!t) throw Error(`Deck.${e} must be inside Deck.Root`);
|
|
73
|
+
return t;
|
|
74
|
+
}
|
|
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(() => {
|
|
77
|
+
let n = e ?? t ?? 0;
|
|
78
|
+
return Number.isFinite(n) ? n : 0;
|
|
79
|
+
});
|
|
80
|
+
process.env.NODE_ENV !== "production" && ie(e, t, n);
|
|
81
|
+
let [E, j] = d({
|
|
82
|
+
index: T,
|
|
83
|
+
count: null,
|
|
84
|
+
slide: null,
|
|
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;
|
|
92
|
+
if (!e) throw Error("Deck.Root must contain a Deck.Viewport");
|
|
93
|
+
let t, n, r = _(e, {
|
|
94
|
+
index: T,
|
|
95
|
+
orientation: R.current,
|
|
96
|
+
onChange(r) {
|
|
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;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return N.current = r, () => {
|
|
103
|
+
r.destroy(), N.current = null;
|
|
104
|
+
};
|
|
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);
|
|
111
|
+
}, [l]);
|
|
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");
|
|
120
|
+
}
|
|
121
|
+
}, [
|
|
122
|
+
e,
|
|
123
|
+
E.index,
|
|
124
|
+
E.count
|
|
125
|
+
]);
|
|
126
|
+
let Y = p !== void 0;
|
|
127
|
+
w(() => {
|
|
128
|
+
if (!Y) return;
|
|
129
|
+
let e = matchMedia("(prefers-reduced-motion: reduce)"), t = () => {
|
|
130
|
+
e.matches && B(!1);
|
|
131
|
+
};
|
|
132
|
+
return t(), e.addEventListener("change", t), () => e.removeEventListener("change", t);
|
|
133
|
+
}, [Y]), s(() => {
|
|
134
|
+
if (!Y) return;
|
|
135
|
+
let e = () => ce(document.visibilityState === "hidden");
|
|
136
|
+
return e(), document.addEventListener("visibilitychange", e), () => document.removeEventListener("visibilitychange", e);
|
|
137
|
+
}, [Y]);
|
|
138
|
+
let X = Y && z && !se && !U && E.count !== null && !H(E.count);
|
|
139
|
+
s(() => {
|
|
140
|
+
if (!X) return;
|
|
141
|
+
let e, t = () => {
|
|
142
|
+
G.current = !0, q.current = null, B(!1);
|
|
143
|
+
}, n = () => {
|
|
144
|
+
let r = N.current;
|
|
145
|
+
if (r) {
|
|
146
|
+
if (r.target() !== null || W.current || document.visibilityState === "hidden") {
|
|
147
|
+
e = setTimeout(n, p);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (q.current === E.index) {
|
|
151
|
+
t();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
q.current = E.index, K.current = !0, r.next(), r.target() === null && t();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
return e = setTimeout(n, p), () => clearTimeout(e);
|
|
158
|
+
}, [
|
|
159
|
+
X,
|
|
160
|
+
p,
|
|
161
|
+
E.index
|
|
162
|
+
]);
|
|
163
|
+
let le = () => {
|
|
164
|
+
if (z) {
|
|
165
|
+
B(!1);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
q.current = null, G.current && (G.current = !1, K.current = !0, N.current?.scrollTo(0)), B(!0);
|
|
169
|
+
}, Z = ({ target: e }) => {
|
|
170
|
+
let t = e;
|
|
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());
|
|
173
|
+
c(r, () => ({
|
|
174
|
+
scrollTo: (e) => Q()?.scrollTo(e),
|
|
175
|
+
next: () => Q()?.next(),
|
|
176
|
+
prev: () => Q()?.prev()
|
|
177
|
+
}), []);
|
|
178
|
+
let de = C(O), fe = E.count === null ? k(m, ue) ?? de : null;
|
|
179
|
+
return /* @__PURE__ */ D(O, {
|
|
180
|
+
value: null,
|
|
181
|
+
children: /* @__PURE__ */ D(te, {
|
|
182
|
+
value: {
|
|
183
|
+
...E,
|
|
184
|
+
slides: fe,
|
|
185
|
+
initialIndex: T,
|
|
186
|
+
orientation: l,
|
|
187
|
+
loop: f,
|
|
188
|
+
viewportRef: M,
|
|
189
|
+
engineRef: N,
|
|
190
|
+
hasAutoplay: Y,
|
|
191
|
+
playing: z,
|
|
192
|
+
togglePlaying: le,
|
|
193
|
+
userMove: $
|
|
194
|
+
},
|
|
195
|
+
children: /* @__PURE__ */ ee("div", {
|
|
196
|
+
role: "region",
|
|
197
|
+
"aria-roledescription": "carousel",
|
|
198
|
+
"data-index": E.index,
|
|
199
|
+
...S,
|
|
200
|
+
onFocus: (e) => {
|
|
201
|
+
h?.(e);
|
|
202
|
+
let t = e.target;
|
|
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);
|
|
205
|
+
},
|
|
206
|
+
onPointerEnter: (e) => {
|
|
207
|
+
g?.(e), W.current = !0, Y && V(!0);
|
|
208
|
+
},
|
|
209
|
+
onPointerLeave: (e) => {
|
|
210
|
+
v?.(e), W.current = !1, Y && V(!1);
|
|
211
|
+
},
|
|
212
|
+
onPointerDown: (e) => {
|
|
213
|
+
y?.(e), Z(e);
|
|
214
|
+
},
|
|
215
|
+
onKeyDown: (e) => {
|
|
216
|
+
b?.(e), Z(e);
|
|
217
|
+
},
|
|
218
|
+
onWheel: (e) => {
|
|
219
|
+
x?.(e), Z(e);
|
|
220
|
+
},
|
|
221
|
+
children: [m, /* @__PURE__ */ D("div", {
|
|
222
|
+
"aria-live": X ? "off" : "polite",
|
|
223
|
+
"aria-atomic": "true",
|
|
224
|
+
"data-carouseldeck-live": "",
|
|
225
|
+
style: ne,
|
|
226
|
+
children: ae
|
|
227
|
+
})]
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
var ne = {
|
|
233
|
+
position: "absolute",
|
|
234
|
+
width: 1,
|
|
235
|
+
height: 1,
|
|
236
|
+
margin: -1,
|
|
237
|
+
padding: 0,
|
|
238
|
+
overflow: "hidden",
|
|
239
|
+
clip: "rect(0 0 0 0)",
|
|
240
|
+
whiteSpace: "nowrap",
|
|
241
|
+
border: 0
|
|
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) {
|
|
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());
|
|
245
|
+
s(() => {
|
|
246
|
+
let e = (e, t) => {
|
|
247
|
+
l.current.has(e) || (l.current.add(e), console.error(t));
|
|
248
|
+
};
|
|
249
|
+
a && e("both", "Deck.Root takes either index or defaultIndex, not both. Pass index with onIndexChange for a controlled deck, or defaultIndex for an uncontrolled one."), o && e("switched", `Deck.Root is changing ${i ? "a controlled deck to be uncontrolled" : "an uncontrolled deck to be controlled"}. A deck should not switch between the two: choose index or defaultIndex for its whole life.`), c && e("readOnly", "Deck.Root was given index without onIndexChange, so a scroll will return the deck to index. Pass onIndexChange to follow the scroll, or defaultIndex for an uncontrolled deck.");
|
|
250
|
+
}, [
|
|
251
|
+
a,
|
|
252
|
+
o,
|
|
253
|
+
c,
|
|
254
|
+
i
|
|
255
|
+
]);
|
|
256
|
+
}
|
|
257
|
+
var F = S(null);
|
|
258
|
+
function I() {
|
|
259
|
+
let e = C(F);
|
|
260
|
+
if (!e) throw Error("Deck.useSlide must be inside Deck.Slide");
|
|
261
|
+
return {
|
|
262
|
+
index: e.index,
|
|
263
|
+
copy: e.copy
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
var L = {
|
|
267
|
+
horizontal: {
|
|
268
|
+
display: "flex",
|
|
269
|
+
overflowX: "auto",
|
|
270
|
+
scrollSnapType: "x mandatory"
|
|
271
|
+
},
|
|
272
|
+
vertical: {
|
|
273
|
+
display: "flex",
|
|
274
|
+
flexDirection: "column",
|
|
275
|
+
overflowY: "auto",
|
|
276
|
+
scrollSnapType: "y mandatory"
|
|
277
|
+
}
|
|
278
|
+
};
|
|
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(() => {
|
|
282
|
+
c.current?.refresh();
|
|
283
|
+
}, [
|
|
284
|
+
c,
|
|
285
|
+
h.length,
|
|
286
|
+
v,
|
|
287
|
+
_,
|
|
288
|
+
y,
|
|
289
|
+
k
|
|
290
|
+
]);
|
|
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
|
+
});
|
|
309
|
+
return /* @__PURE__ */ ee("div", {
|
|
310
|
+
ref: s,
|
|
311
|
+
tabIndex: 0,
|
|
312
|
+
"data-carouseldeck-viewport": "",
|
|
313
|
+
"data-orientation": l,
|
|
314
|
+
"data-carouseldeck-effect": a?.name,
|
|
315
|
+
"data-carouseldeck-loop": g ? _ ? "shells" : "copies" : void 0,
|
|
316
|
+
style: {
|
|
317
|
+
...L[l],
|
|
318
|
+
...x?.viewport,
|
|
319
|
+
...n
|
|
320
|
+
},
|
|
321
|
+
...o,
|
|
322
|
+
children: [
|
|
323
|
+
/* @__PURE__ */ D("style", {
|
|
324
|
+
href: "carouseldeck-slide",
|
|
325
|
+
precedence: "carouseldeck",
|
|
326
|
+
children: B
|
|
327
|
+
}),
|
|
328
|
+
a && /* @__PURE__ */ D("style", {
|
|
329
|
+
href: `carouseldeck-${a.name}`,
|
|
330
|
+
precedence: "carouseldeck",
|
|
331
|
+
children: a.css
|
|
332
|
+
}),
|
|
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", {
|
|
357
|
+
"aria-hidden": "true",
|
|
358
|
+
"data-carouseldeck-snap-target": "",
|
|
359
|
+
style: S(t)
|
|
360
|
+
}, `target-${t}`))
|
|
361
|
+
]
|
|
362
|
+
});
|
|
363
|
+
}
|
|
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);
|
|
398
|
+
if (!r) throw Error("Deck.Slide must be inside Deck.Viewport");
|
|
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(() => {
|
|
401
|
+
if (!d) return;
|
|
402
|
+
let e = f.current, t = document.activeElement?.closest("[data-carouseldeck-slide][inert]");
|
|
403
|
+
e && t?.parentElement === e && e.focus({ preventScroll: !0 });
|
|
404
|
+
}, [d, f]), /* @__PURE__ */ D("div", {
|
|
405
|
+
role: "group",
|
|
406
|
+
"aria-roledescription": "slide",
|
|
407
|
+
"aria-label": `${i + 1} of ${a}`,
|
|
408
|
+
"data-carouseldeck-slide": "",
|
|
409
|
+
"data-carouseldeck-copy": s,
|
|
410
|
+
"data-carouseldeck-placed": r.placed === void 0 ? void 0 : "",
|
|
411
|
+
"aria-hidden": s ? !0 : void 0,
|
|
412
|
+
"data-current": l ? "" : void 0,
|
|
413
|
+
"data-focal": u ? "" : void 0,
|
|
414
|
+
inert: d,
|
|
415
|
+
style: {
|
|
416
|
+
flexShrink: 0,
|
|
417
|
+
"--deck-slide-index": i,
|
|
418
|
+
"--deck-slide-count": a,
|
|
419
|
+
"--deck-slide-progress": r.progress,
|
|
420
|
+
...r.placed !== void 0 && { "--carouseldeck-placed": r.placed },
|
|
421
|
+
...c && se,
|
|
422
|
+
...r.style,
|
|
423
|
+
...e
|
|
424
|
+
},
|
|
425
|
+
...t
|
|
426
|
+
});
|
|
427
|
+
}
|
|
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);
|
|
431
|
+
return {
|
|
432
|
+
index: o,
|
|
433
|
+
count: n,
|
|
434
|
+
loop: i,
|
|
435
|
+
fits: s,
|
|
436
|
+
canPrev: !s && (i || o !== 0),
|
|
437
|
+
canNext: !s && (i || n === null || o < n - 1),
|
|
438
|
+
scrollTo: (e) => a()?.scrollTo(e),
|
|
439
|
+
next: () => a()?.next(),
|
|
440
|
+
prev: () => a()?.prev()
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function ce() {
|
|
444
|
+
return U("useDeck");
|
|
445
|
+
}
|
|
446
|
+
function W({ atEnd: e, step: t, label: n, onClick: r, disabled: i, children: a, ...o }) {
|
|
447
|
+
return /* @__PURE__ */ D("button", {
|
|
448
|
+
type: "button",
|
|
449
|
+
...o,
|
|
450
|
+
disabled: e || i,
|
|
451
|
+
"data-disabled": e || i ? "" : void 0,
|
|
452
|
+
onClick: (e) => {
|
|
453
|
+
r?.(e), e.defaultPrevented || t();
|
|
454
|
+
},
|
|
455
|
+
children: a ?? n
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
function G(e) {
|
|
459
|
+
let { fits: t, canPrev: n, prev: r } = U("Prev");
|
|
460
|
+
return t ? null : /* @__PURE__ */ D(Q, {
|
|
461
|
+
...e,
|
|
462
|
+
"data-carouseldeck-prev": "",
|
|
463
|
+
atEnd: !n,
|
|
464
|
+
step: r,
|
|
465
|
+
label: "Previous"
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
function K(e) {
|
|
469
|
+
let { fits: t, canNext: n, next: r } = U("Next");
|
|
470
|
+
return t ? null : /* @__PURE__ */ D(Q, {
|
|
471
|
+
...e,
|
|
472
|
+
"data-carouseldeck-next": "",
|
|
473
|
+
atEnd: !n,
|
|
474
|
+
step: r,
|
|
475
|
+
label: "Next"
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
function q(e) {
|
|
479
|
+
let { index: t, count: n, slides: r, initialIndex: i, userMove: a } = N(e);
|
|
480
|
+
return n !== null || r === null ? {
|
|
481
|
+
index: t,
|
|
482
|
+
count: n,
|
|
483
|
+
userMove: a
|
|
484
|
+
} : {
|
|
485
|
+
index: A(i, r),
|
|
486
|
+
count: r,
|
|
487
|
+
userMove: a
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
function J(e) {
|
|
491
|
+
let { index: t, count: n, userMove: r } = q("Dots");
|
|
492
|
+
return H(n) ? null : /* @__PURE__ */ D("div", {
|
|
493
|
+
role: "group",
|
|
494
|
+
"aria-label": "Choose page",
|
|
495
|
+
...e,
|
|
496
|
+
"data-carouseldeck-dots": "",
|
|
497
|
+
"data-index": n === null ? void 0 : t,
|
|
498
|
+
"data-count": n ?? void 0,
|
|
499
|
+
children: Array.from({ length: n ?? 0 }, (e, n) => /* @__PURE__ */ D("button", {
|
|
500
|
+
type: "button",
|
|
501
|
+
"aria-label": `Go to page ${n + 1}`,
|
|
502
|
+
"aria-current": n === t ? "true" : void 0,
|
|
503
|
+
"data-index": n,
|
|
504
|
+
onClick: () => r()?.scrollTo(n)
|
|
505
|
+
}, n))
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
function Y(e) {
|
|
509
|
+
let { index: t, count: n } = q("Counter");
|
|
510
|
+
if (H(n)) return null;
|
|
511
|
+
let r = n !== null;
|
|
512
|
+
return /* @__PURE__ */ D("span", {
|
|
513
|
+
...e,
|
|
514
|
+
"data-carouseldeck-counter": "",
|
|
515
|
+
"data-index": r ? t : void 0,
|
|
516
|
+
"data-count": r ? n : void 0,
|
|
517
|
+
children: r && `${t + 1} / ${n}`
|
|
518
|
+
});
|
|
519
|
+
}
|
|
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", {
|
|
523
|
+
type: "button",
|
|
524
|
+
...n,
|
|
525
|
+
"data-carouseldeck-autoplay-toggle": "",
|
|
526
|
+
"data-playing": i ? "" : void 0,
|
|
527
|
+
onClick: (t) => {
|
|
528
|
+
e?.(t), t.defaultPrevented || a();
|
|
529
|
+
},
|
|
530
|
+
children: t ?? (i ? "Stop slide rotation" : "Start slide rotation")
|
|
531
|
+
});
|
|
532
|
+
}
|
|
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");
|
|
534
|
+
//#endregion
|
|
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/dist/theme.css
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @carouseldeck/react/theme.css: an optional appearance for a deck's controls,
|
|
3
|
+
* Prev, Next, Dots, Counter and AutoplayToggle. Slides and their geometry
|
|
4
|
+
* stay your CSS (ADR-0003), and a deck works without this file.
|
|
5
|
+
*
|
|
6
|
+
* Every rule is wrapped in :where(), so any selector of yours beats it. Every
|
|
7
|
+
* themed value is a custom property below; set one on the deck or any
|
|
8
|
+
* ancestor to override its default.
|
|
9
|
+
*
|
|
10
|
+
* --deck-control-color: #1a1a1a
|
|
11
|
+
* Text of Prev, Next, the counter and the stopped autoplay toggle.
|
|
12
|
+
* --deck-control-background: #ffffff
|
|
13
|
+
* Background of Prev, Next and the autoplay toggle.
|
|
14
|
+
* --deck-control-hover-background: #f0f0f0
|
|
15
|
+
* Their background under a pointer.
|
|
16
|
+
* --deck-control-border: 1px solid #767676
|
|
17
|
+
* Their border.
|
|
18
|
+
* --deck-control-radius: 0.375rem
|
|
19
|
+
* Their corner radius.
|
|
20
|
+
* --deck-control-padding: 0.375rem 0.75rem
|
|
21
|
+
* Their padding.
|
|
22
|
+
* --deck-control-font-size: 0.875rem
|
|
23
|
+
* Their font size, and the counter's.
|
|
24
|
+
* --deck-control-disabled-opacity: 0.4
|
|
25
|
+
* Opacity of Prev or Next while disabled, at either end.
|
|
26
|
+
* --deck-control-active-background: var(--deck-accent, #0b5cd5)
|
|
27
|
+
* Background of the autoplay toggle while autoplay plays, paused by a
|
|
28
|
+
* pointer or not; stopped, it looks like Prev and Next.
|
|
29
|
+
* --deck-control-active-color: #ffffff
|
|
30
|
+
* Its text while autoplay plays.
|
|
31
|
+
* --deck-dot-color: #767676
|
|
32
|
+
* A dot that is not the current page.
|
|
33
|
+
* --deck-dot-hover-color: #1a1a1a
|
|
34
|
+
* A dot that is not the current page, under a pointer.
|
|
35
|
+
* --deck-dot-size: 0.625rem
|
|
36
|
+
* The diameter of the dot drawn.
|
|
37
|
+
* --deck-dot-current-width: 1.25rem
|
|
38
|
+
* The width of the current page's dot, wider than the others so it
|
|
39
|
+
* stands out by shape as well as colour.
|
|
40
|
+
* --deck-dot-radius: 9999px
|
|
41
|
+
* A dot's corner radius; past half its side it rounds a dot to a circle
|
|
42
|
+
* and the current one to a pill.
|
|
43
|
+
* --deck-dot-target-size: 1.5rem
|
|
44
|
+
* The square a dot answers clicks in, the dot centred in it.
|
|
45
|
+
* --deck-dot-gap: 0.25rem
|
|
46
|
+
* Space between dot targets.
|
|
47
|
+
* --deck-accent: #0b5cd5
|
|
48
|
+
* The current page's dot, the focus ring and the playing toggle.
|
|
49
|
+
* --deck-focus-width: 2px
|
|
50
|
+
* Width of the focus ring a keyboard user sees.
|
|
51
|
+
* --deck-focus-offset: 2px
|
|
52
|
+
* Space between a control and its focus ring.
|
|
53
|
+
* --deck-transition-duration: 150ms
|
|
54
|
+
* How long hover and state changes fade; none under reduced motion.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
:where(
|
|
58
|
+
[data-carouseldeck-prev],
|
|
59
|
+
[data-carouseldeck-next],
|
|
60
|
+
[data-carouseldeck-autoplay-toggle]
|
|
61
|
+
) {
|
|
62
|
+
padding: var(--deck-control-padding, 0.375rem 0.75rem);
|
|
63
|
+
border: var(--deck-control-border, 1px solid #767676);
|
|
64
|
+
border-radius: var(--deck-control-radius, 0.375rem);
|
|
65
|
+
background-color: var(--deck-control-background, #ffffff);
|
|
66
|
+
color: var(--deck-control-color, #1a1a1a);
|
|
67
|
+
font: inherit;
|
|
68
|
+
font-size: var(--deck-control-font-size, 0.875rem);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:where(
|
|
72
|
+
[data-carouseldeck-prev],
|
|
73
|
+
[data-carouseldeck-next],
|
|
74
|
+
[data-carouseldeck-autoplay-toggle]
|
|
75
|
+
):where(:hover:not(:disabled)) {
|
|
76
|
+
background-color: var(--deck-control-hover-background, #f0f0f0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
:where([data-carouseldeck-autoplay-toggle][data-playing]) {
|
|
80
|
+
background-color: var(
|
|
81
|
+
--deck-control-active-background,
|
|
82
|
+
var(--deck-accent, #0b5cd5)
|
|
83
|
+
);
|
|
84
|
+
color: var(--deck-control-active-color, #ffffff);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:where([data-carouseldeck-prev], [data-carouseldeck-next]):where(:disabled) {
|
|
88
|
+
opacity: var(--deck-control-disabled-opacity, 0.4);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:where([data-carouseldeck-dots]) {
|
|
92
|
+
display: flex;
|
|
93
|
+
gap: var(--deck-dot-gap, 0.25rem);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
:where([data-carouseldeck-dots] > button) {
|
|
97
|
+
box-sizing: border-box;
|
|
98
|
+
inline-size: var(--deck-dot-target-size, 1.5rem);
|
|
99
|
+
block-size: var(--deck-dot-target-size, 1.5rem);
|
|
100
|
+
padding: calc(
|
|
101
|
+
(var(--deck-dot-target-size, 1.5rem) - var(--deck-dot-size, 0.625rem)) / 2
|
|
102
|
+
);
|
|
103
|
+
border: 0;
|
|
104
|
+
border-radius: var(--deck-dot-radius, 9999px);
|
|
105
|
+
background-color: var(--deck-dot-color, #767676);
|
|
106
|
+
background-clip: content-box;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
:where([data-carouseldeck-dots] > button[aria-current='true']) {
|
|
110
|
+
inline-size: calc(
|
|
111
|
+
var(--deck-dot-target-size, 1.5rem) - var(--deck-dot-size, 0.625rem) +
|
|
112
|
+
var(--deck-dot-current-width, 1.25rem)
|
|
113
|
+
);
|
|
114
|
+
background-color: var(--deck-accent, #0b5cd5);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
:where([data-carouseldeck-dots] > button:not([aria-current='true']):hover) {
|
|
118
|
+
background-color: var(--deck-dot-hover-color, #1a1a1a);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Forced colours paint every background the page colour, dots included:
|
|
122
|
+
* draw them in system colours instead, the current and a hovered one
|
|
123
|
+
* highlighted. The playing toggle is highlighted too, so it still differs
|
|
124
|
+
* from the stopped one. */
|
|
125
|
+
@media (forced-colors: active) {
|
|
126
|
+
:where([data-carouseldeck-dots] > button) {
|
|
127
|
+
forced-color-adjust: none;
|
|
128
|
+
background-color: CanvasText;
|
|
129
|
+
outline-color: CanvasText;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
:where(
|
|
133
|
+
[data-carouseldeck-dots] > button[aria-current='true'],
|
|
134
|
+
[data-carouseldeck-dots] > button:hover
|
|
135
|
+
) {
|
|
136
|
+
background-color: Highlight;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:where([data-carouseldeck-autoplay-toggle][data-playing]) {
|
|
140
|
+
forced-color-adjust: none;
|
|
141
|
+
border-color: ButtonText;
|
|
142
|
+
background-color: Highlight;
|
|
143
|
+
color: HighlightText;
|
|
144
|
+
outline-color: CanvasText;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:where([data-carouseldeck-counter]) {
|
|
149
|
+
color: var(--deck-control-color, #1a1a1a);
|
|
150
|
+
font-size: var(--deck-control-font-size, 0.875rem);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
:where(
|
|
154
|
+
[data-carouseldeck-prev],
|
|
155
|
+
[data-carouseldeck-next],
|
|
156
|
+
[data-carouseldeck-autoplay-toggle],
|
|
157
|
+
[data-carouseldeck-dots] > button
|
|
158
|
+
) {
|
|
159
|
+
transition:
|
|
160
|
+
background-color var(--deck-transition-duration, 150ms),
|
|
161
|
+
color var(--deck-transition-duration, 150ms),
|
|
162
|
+
opacity var(--deck-transition-duration, 150ms);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
:where(
|
|
166
|
+
[data-carouseldeck-prev],
|
|
167
|
+
[data-carouseldeck-next],
|
|
168
|
+
[data-carouseldeck-autoplay-toggle],
|
|
169
|
+
[data-carouseldeck-dots] > button
|
|
170
|
+
):where(:focus-visible) {
|
|
171
|
+
outline: var(--deck-focus-width, 2px) solid var(--deck-accent, #0b5cd5);
|
|
172
|
+
outline-offset: var(--deck-focus-offset, 2px);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@media (prefers-reduced-motion: reduce) {
|
|
176
|
+
:where(
|
|
177
|
+
[data-carouseldeck-prev],
|
|
178
|
+
[data-carouseldeck-next],
|
|
179
|
+
[data-carouseldeck-autoplay-toggle],
|
|
180
|
+
[data-carouseldeck-dots] > button
|
|
181
|
+
) {
|
|
182
|
+
transition: none;
|
|
183
|
+
}
|
|
184
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carouseldeck/react-18",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "@carouseldeck/react built for React 18: headless, composable carousel primitives on native scroll snap.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://carousel.deck.cool",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/pedrosousa13/deck-cool.git",
|
|
10
|
+
"directory": "decks/carouseldeck/packages/react-18"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"sideEffects": [
|
|
14
|
+
"*.css"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./fade": {
|
|
22
|
+
"types": "./dist/fade.d.ts",
|
|
23
|
+
"default": "./dist/fade.js"
|
|
24
|
+
},
|
|
25
|
+
"./curve": {
|
|
26
|
+
"types": "./dist/curve.d.ts",
|
|
27
|
+
"default": "./dist/curve.js"
|
|
28
|
+
},
|
|
29
|
+
"./theme.css": {
|
|
30
|
+
"default": "./dist/theme.css"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"provenance": true
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@carouseldeck/core": "1.3.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"react": ">=18 <19",
|
|
45
|
+
"react-dom": ">=18 <19"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react": "18.3.31",
|
|
49
|
+
"@types/react-dom": "18.3.7",
|
|
50
|
+
"react": "18.3.1",
|
|
51
|
+
"react-dom": "18.3.1",
|
|
52
|
+
"vite": "8.3.1",
|
|
53
|
+
"@carouseldeck/react": "1.3.0"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "vite build"
|
|
57
|
+
}
|
|
6
58
|
}
|