@patternmode/aperto 0.1.4 → 0.2.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/README.md +34 -0
- package/dist/index.d.ts +163 -43
- package/dist/index.js +447 -641
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,52 +1,30 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
// src/Aperto/
|
|
3
|
+
// src/Aperto/aperto-group.tsx
|
|
4
4
|
import { ChevronLeft, ChevronRight, X } from "lucide-react";
|
|
5
|
-
import {
|
|
6
|
-
useCallback as useCallback3,
|
|
7
|
-
useId as useId2,
|
|
8
|
-
useLayoutEffect,
|
|
9
|
-
useMemo as useMemo3,
|
|
10
|
-
useReducer,
|
|
11
|
-
useRef
|
|
12
|
-
} from "react";
|
|
5
|
+
import { useId as useId2, useLayoutEffect, useReducer, useRef } from "react";
|
|
13
6
|
|
|
14
7
|
// src/aperto-content.tsx
|
|
15
8
|
import * as Dialog from "@radix-ui/react-dialog";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
useMotionValue,
|
|
19
|
-
useSpring,
|
|
20
|
-
useTransform
|
|
21
|
-
} from "motion/react";
|
|
22
|
-
import {
|
|
23
|
-
forwardRef,
|
|
24
|
-
useCallback,
|
|
25
|
-
useMemo,
|
|
26
|
-
useState
|
|
27
|
-
} from "react";
|
|
9
|
+
import { m, useMotionValue, useSpring, useTransform } from "motion/react";
|
|
10
|
+
import { useState } from "react";
|
|
28
11
|
|
|
29
12
|
// src/context.ts
|
|
30
|
-
import { createContext,
|
|
13
|
+
import { createContext, use } from "react";
|
|
31
14
|
var ApertoContext = createContext(null);
|
|
32
|
-
|
|
33
|
-
const ctx =
|
|
15
|
+
var useApertoContext = () => {
|
|
16
|
+
const ctx = use(ApertoContext);
|
|
34
17
|
if (!ctx) {
|
|
35
18
|
throw new Error("Aperto components must be used within <Aperto.Root>");
|
|
36
19
|
}
|
|
37
20
|
return ctx;
|
|
38
|
-
}
|
|
21
|
+
};
|
|
39
22
|
|
|
40
23
|
// src/physics.ts
|
|
41
24
|
var RESISTANCE_DIVISOR = 20;
|
|
42
25
|
var RESISTANCE_SCALE = 4;
|
|
43
26
|
var RESISTANCE_MIN = 0.1;
|
|
44
|
-
|
|
45
|
-
return Math.max(
|
|
46
|
-
RESISTANCE_MIN,
|
|
47
|
-
1 - Math.log(distance / RESISTANCE_DIVISOR + 1) / RESISTANCE_SCALE
|
|
48
|
-
);
|
|
49
|
-
}
|
|
27
|
+
var calculateResistance = (distance) => Math.max(RESISTANCE_MIN, 1 - Math.log(distance / RESISTANCE_DIVISOR + 1) / RESISTANCE_SCALE);
|
|
50
28
|
var SCALE_INPUT = [0, 50, 100];
|
|
51
29
|
var SCALE_OUTPUT = [1, 0.98, 0.95];
|
|
52
30
|
var OPACITY_INPUT = [0, 80];
|
|
@@ -56,57 +34,57 @@ var DEFAULT_VELOCITY_THRESHOLD = 500;
|
|
|
56
34
|
|
|
57
35
|
// src/motion-tokens.ts
|
|
58
36
|
var durations = {
|
|
59
|
-
|
|
60
|
-
|
|
37
|
+
moderate: 0.4,
|
|
38
|
+
snappy: 0.22
|
|
61
39
|
};
|
|
62
40
|
var easings = {
|
|
63
41
|
customGentle: [0.25, 0.1, 0.12, 1],
|
|
64
42
|
snappy: [0.22, 1, 0.36, 1]
|
|
65
43
|
};
|
|
66
44
|
var springs = {
|
|
67
|
-
bouncy: {
|
|
68
|
-
natural: {
|
|
69
|
-
snappy: {
|
|
70
|
-
stiff: {
|
|
45
|
+
bouncy: { damping: 12, mass: 1, stiffness: 260 },
|
|
46
|
+
natural: { damping: 20, mass: 1, stiffness: 200 },
|
|
47
|
+
snappy: { damping: 28, mass: 0.8, stiffness: 400 },
|
|
48
|
+
stiff: { damping: 30, mass: 1, stiffness: 500 }
|
|
71
49
|
};
|
|
72
50
|
|
|
73
51
|
// src/presets.ts
|
|
74
52
|
var PRESETS = {
|
|
75
|
-
|
|
76
|
-
transition: { ease: easings.snappy, duration: durations.snappy },
|
|
53
|
+
bouncy: {
|
|
77
54
|
drag: {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
55
|
+
damping: springs.snappy.damping,
|
|
56
|
+
restDelta: 0.01,
|
|
57
|
+
stiffness: springs.snappy.stiffness
|
|
58
|
+
},
|
|
59
|
+
transition: {
|
|
60
|
+
damping: springs.bouncy.damping,
|
|
61
|
+
mass: springs.bouncy.mass,
|
|
62
|
+
stiffness: springs.bouncy.stiffness,
|
|
63
|
+
type: "spring"
|
|
81
64
|
}
|
|
82
65
|
},
|
|
66
|
+
reduced: {
|
|
67
|
+
drag: { damping: 50, restDelta: 0.1, stiffness: 1e3 },
|
|
68
|
+
transition: { duration: 0.01, ease: "linear" }
|
|
69
|
+
},
|
|
83
70
|
smooth: {
|
|
84
|
-
transition: { ease: easings.customGentle, duration: durations.moderate },
|
|
85
71
|
drag: {
|
|
86
|
-
stiffness: springs.natural.stiffness,
|
|
87
72
|
damping: springs.natural.damping,
|
|
88
|
-
restDelta: 0.01
|
|
89
|
-
|
|
90
|
-
},
|
|
91
|
-
bouncy: {
|
|
92
|
-
transition: {
|
|
93
|
-
type: "spring",
|
|
94
|
-
stiffness: springs.bouncy.stiffness,
|
|
95
|
-
damping: springs.bouncy.damping,
|
|
96
|
-
mass: springs.bouncy.mass
|
|
73
|
+
restDelta: 0.01,
|
|
74
|
+
stiffness: springs.natural.stiffness
|
|
97
75
|
},
|
|
98
|
-
|
|
99
|
-
stiffness: springs.snappy.stiffness,
|
|
100
|
-
damping: springs.snappy.damping,
|
|
101
|
-
restDelta: 0.01
|
|
102
|
-
}
|
|
76
|
+
transition: { duration: durations.moderate, ease: easings.customGentle }
|
|
103
77
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
78
|
+
snappy: {
|
|
79
|
+
drag: {
|
|
80
|
+
damping: springs.stiff.damping,
|
|
81
|
+
restDelta: 0.01,
|
|
82
|
+
stiffness: springs.stiff.stiffness
|
|
83
|
+
},
|
|
84
|
+
transition: { duration: durations.snappy, ease: easings.snappy }
|
|
107
85
|
}
|
|
108
86
|
};
|
|
109
|
-
|
|
87
|
+
var resolvePreset = (componentType, componentMotion, globalPreset, variants, reduceMotion) => {
|
|
110
88
|
if (reduceMotion) {
|
|
111
89
|
return PRESETS.reduced;
|
|
112
90
|
}
|
|
@@ -117,148 +95,127 @@ function resolvePreset(componentType, componentMotion, globalPreset, variants, r
|
|
|
117
95
|
return PRESETS[variants[componentType]];
|
|
118
96
|
}
|
|
119
97
|
return PRESETS[globalPreset];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return preset.drag;
|
|
123
|
-
}
|
|
98
|
+
};
|
|
99
|
+
var getDragSpring = (preset) => preset.drag;
|
|
124
100
|
|
|
125
101
|
// src/aperto-content.tsx
|
|
126
102
|
import { jsx } from "react/jsx-runtime";
|
|
127
|
-
var ApertoContent =
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
opacity: opacityMotion,
|
|
191
|
-
scale: scaleMotion,
|
|
192
|
-
x: springX,
|
|
193
|
-
y: springY,
|
|
194
|
-
...placement === "center" ? {
|
|
195
|
-
left: "50%",
|
|
196
|
-
top: "50%",
|
|
197
|
-
translate: "-50% -50%"
|
|
198
|
-
} : {},
|
|
199
|
-
...style
|
|
200
|
-
}),
|
|
201
|
-
[
|
|
202
|
-
isDismissible,
|
|
203
|
-
isDragging,
|
|
204
|
-
opacityMotion,
|
|
205
|
-
placement,
|
|
206
|
-
scaleMotion,
|
|
207
|
-
springX,
|
|
208
|
-
springY,
|
|
209
|
-
style
|
|
210
|
-
]
|
|
211
|
-
);
|
|
212
|
-
return /* @__PURE__ */ jsx(Dialog.Content, { asChild: true, forceMount: true, ...props, children: /* @__PURE__ */ jsx(
|
|
213
|
-
m.div,
|
|
214
|
-
{
|
|
215
|
-
className,
|
|
216
|
-
"data-slot": "aperto-content",
|
|
217
|
-
drag: isDismissible,
|
|
218
|
-
dragConstraints: { bottom: 0, left: 0, right: 0, top: 0 },
|
|
219
|
-
dragElastic: 0,
|
|
220
|
-
dragMomentum: false,
|
|
221
|
-
dragSnapToOrigin: true,
|
|
222
|
-
layout: contentLayoutId ? true : void 0,
|
|
223
|
-
layoutId: contentLayoutId,
|
|
224
|
-
onDrag: isDismissible ? handleDrag : void 0,
|
|
225
|
-
onDragEnd: isDismissible ? handleDragEnd : void 0,
|
|
226
|
-
ref,
|
|
227
|
-
style: motionStyle,
|
|
228
|
-
transition: resolved.transition,
|
|
229
|
-
children
|
|
230
|
-
}
|
|
231
|
-
) });
|
|
103
|
+
var ApertoContent = ({
|
|
104
|
+
children,
|
|
105
|
+
className,
|
|
106
|
+
motion: motionOverride,
|
|
107
|
+
placement = "center",
|
|
108
|
+
ref,
|
|
109
|
+
sharedLayoutId,
|
|
110
|
+
style,
|
|
111
|
+
...props
|
|
112
|
+
}) => {
|
|
113
|
+
const ctx = useApertoContext();
|
|
114
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
115
|
+
const resolved = resolvePreset(
|
|
116
|
+
"content",
|
|
117
|
+
motionOverride,
|
|
118
|
+
ctx.presetName,
|
|
119
|
+
ctx.variants,
|
|
120
|
+
ctx.reduceMotion
|
|
121
|
+
);
|
|
122
|
+
const contentLayoutId = sharedLayoutId === false ? void 0 : sharedLayoutId ?? `${ctx.layoutId}-shared`;
|
|
123
|
+
const dragSpring = getDragSpring(resolved);
|
|
124
|
+
const isDismissible = ctx.dismissible !== false;
|
|
125
|
+
const dismissConfig = typeof ctx.dismissible === "object" ? ctx.dismissible : {};
|
|
126
|
+
const distanceThreshold = dismissConfig.threshold ?? DEFAULT_DISTANCE_THRESHOLD;
|
|
127
|
+
const velocityThreshold = dismissConfig.velocity ?? DEFAULT_VELOCITY_THRESHOLD;
|
|
128
|
+
const dragX = useMotionValue(0);
|
|
129
|
+
const dragY = useMotionValue(0);
|
|
130
|
+
const springX = useSpring(dragX, dragSpring);
|
|
131
|
+
const springY = useSpring(dragY, dragSpring);
|
|
132
|
+
const distance = useTransform(() => Math.hypot(springX.get(), springY.get()));
|
|
133
|
+
const scaleMotion = useTransform(distance, SCALE_INPUT, SCALE_OUTPUT);
|
|
134
|
+
const opacityMotion = useTransform(distance, OPACITY_INPUT, OPACITY_OUTPUT);
|
|
135
|
+
const resistance = useTransform(distance, calculateResistance);
|
|
136
|
+
const { onOpenChange } = ctx;
|
|
137
|
+
const handleDrag = (_event, info) => {
|
|
138
|
+
if (!isDragging) {
|
|
139
|
+
setIsDragging(true);
|
|
140
|
+
}
|
|
141
|
+
const r = resistance.get();
|
|
142
|
+
dragX.set(info.offset.x * r);
|
|
143
|
+
dragY.set(info.offset.y * r);
|
|
144
|
+
};
|
|
145
|
+
const handleDragEnd = (_event, info) => {
|
|
146
|
+
setIsDragging(false);
|
|
147
|
+
const speed = Math.hypot(info.velocity.x, info.velocity.y);
|
|
148
|
+
const dist = Math.hypot(info.offset.x, info.offset.y);
|
|
149
|
+
if (speed > velocityThreshold || dist > distanceThreshold) {
|
|
150
|
+
onOpenChange(false);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
dragX.set(0);
|
|
154
|
+
dragY.set(0);
|
|
155
|
+
};
|
|
156
|
+
const placementStyle = placement === "center" ? {
|
|
157
|
+
left: "50%",
|
|
158
|
+
top: "50%",
|
|
159
|
+
translate: "-50% -50%"
|
|
160
|
+
} : {};
|
|
161
|
+
let cursor;
|
|
162
|
+
if (isDragging) {
|
|
163
|
+
cursor = "grabbing";
|
|
164
|
+
} else if (isDismissible) {
|
|
165
|
+
cursor = "grab";
|
|
232
166
|
}
|
|
233
|
-
|
|
167
|
+
const motionStyle = {
|
|
168
|
+
cursor,
|
|
169
|
+
opacity: opacityMotion,
|
|
170
|
+
scale: scaleMotion,
|
|
171
|
+
x: springX,
|
|
172
|
+
y: springY,
|
|
173
|
+
...placementStyle,
|
|
174
|
+
...style
|
|
175
|
+
};
|
|
176
|
+
return /* @__PURE__ */ jsx(Dialog.Content, { asChild: true, forceMount: true, ...props, children: /* @__PURE__ */ jsx(
|
|
177
|
+
m.div,
|
|
178
|
+
{
|
|
179
|
+
className,
|
|
180
|
+
"data-slot": "aperto-content",
|
|
181
|
+
drag: isDismissible,
|
|
182
|
+
dragConstraints: { bottom: 0, left: 0, right: 0, top: 0 },
|
|
183
|
+
dragElastic: 0,
|
|
184
|
+
dragMomentum: false,
|
|
185
|
+
dragSnapToOrigin: true,
|
|
186
|
+
layout: contentLayoutId ? true : void 0,
|
|
187
|
+
layoutId: contentLayoutId,
|
|
188
|
+
onDrag: isDismissible ? handleDrag : void 0,
|
|
189
|
+
onDragEnd: isDismissible ? handleDragEnd : void 0,
|
|
190
|
+
ref,
|
|
191
|
+
style: motionStyle,
|
|
192
|
+
transition: resolved.transition,
|
|
193
|
+
children
|
|
194
|
+
}
|
|
195
|
+
) });
|
|
196
|
+
};
|
|
234
197
|
ApertoContent.displayName = "ApertoContent";
|
|
235
198
|
|
|
236
199
|
// src/aperto-description.tsx
|
|
237
200
|
import * as Dialog2 from "@radix-ui/react-dialog";
|
|
238
|
-
import { forwardRef as forwardRef2 } from "react";
|
|
239
201
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
240
|
-
var ApertoDescription =
|
|
241
|
-
return /* @__PURE__ */ jsx2(Dialog2.Description, { "data-slot": "aperto-description", ref, ...props });
|
|
242
|
-
});
|
|
202
|
+
var ApertoDescription = ({ ref, ...props }) => /* @__PURE__ */ jsx2(Dialog2.Description, { "data-slot": "aperto-description", ref, ...props });
|
|
243
203
|
ApertoDescription.displayName = "ApertoDescription";
|
|
244
204
|
|
|
245
205
|
// src/aperto-group-context.ts
|
|
246
|
-
import { createContext as createContext2,
|
|
247
|
-
var ApertoGroupContext = createContext2(
|
|
248
|
-
|
|
249
|
-
);
|
|
250
|
-
function useApertoGroup() {
|
|
251
|
-
const ctx = useContext2(ApertoGroupContext);
|
|
206
|
+
import { createContext as createContext2, use as use2 } from "react";
|
|
207
|
+
var ApertoGroupContext = createContext2(null);
|
|
208
|
+
var useApertoGroup = () => {
|
|
209
|
+
const ctx = use2(ApertoGroupContext);
|
|
252
210
|
if (!ctx) {
|
|
253
211
|
throw new Error("Aperto.Thumbnail must be used within <Aperto.Group>");
|
|
254
212
|
}
|
|
255
213
|
return ctx;
|
|
256
|
-
}
|
|
214
|
+
};
|
|
257
215
|
|
|
258
216
|
// src/aperto-overlay.tsx
|
|
259
217
|
import * as Dialog3 from "@radix-ui/react-dialog";
|
|
260
218
|
import { m as m2 } from "motion/react";
|
|
261
|
-
import { forwardRef as forwardRef3 } from "react";
|
|
262
219
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
263
220
|
var OVERLAY_TRANSITION = {
|
|
264
221
|
duration: 0.3,
|
|
@@ -268,52 +225,40 @@ var OVERLAY_TRANSITION_REDUCED = {
|
|
|
268
225
|
duration: 0.01,
|
|
269
226
|
ease: "linear"
|
|
270
227
|
};
|
|
271
|
-
var ApertoOverlay =
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
{
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
);
|
|
228
|
+
var ApertoOverlay = ({ className, fadeOut, ref, style }) => {
|
|
229
|
+
const ctx = useApertoContext();
|
|
230
|
+
const transition = ctx.reduceMotion ? OVERLAY_TRANSITION_REDUCED : OVERLAY_TRANSITION;
|
|
231
|
+
return /* @__PURE__ */ jsx3(Dialog3.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsx3(
|
|
232
|
+
m2.div,
|
|
233
|
+
{
|
|
234
|
+
animate: { opacity: fadeOut ? 0 : 1 },
|
|
235
|
+
className,
|
|
236
|
+
"data-slot": "aperto-overlay",
|
|
237
|
+
exit: { opacity: 0 },
|
|
238
|
+
initial: { opacity: 0 },
|
|
239
|
+
ref,
|
|
240
|
+
style,
|
|
241
|
+
transition
|
|
242
|
+
}
|
|
243
|
+
) });
|
|
244
|
+
};
|
|
290
245
|
ApertoOverlay.displayName = "ApertoOverlay";
|
|
291
246
|
|
|
292
247
|
// src/aperto-portal.tsx
|
|
293
248
|
import * as Dialog4 from "@radix-ui/react-dialog";
|
|
294
249
|
import { AnimatePresence } from "motion/react";
|
|
295
250
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
296
|
-
|
|
251
|
+
var ApertoPortal = ({ children, container }) => {
|
|
297
252
|
const { open } = useApertoContext();
|
|
298
253
|
return /* @__PURE__ */ jsx4(AnimatePresence, { children: open && /* @__PURE__ */ jsx4(Dialog4.Portal, { container, forceMount: true, children }) });
|
|
299
|
-
}
|
|
254
|
+
};
|
|
300
255
|
|
|
301
256
|
// src/aperto-root.tsx
|
|
302
257
|
import * as Dialog5 from "@radix-ui/react-dialog";
|
|
303
|
-
import {
|
|
304
|
-
|
|
305
|
-
LayoutGroup,
|
|
306
|
-
LazyMotion,
|
|
307
|
-
useReducedMotion
|
|
308
|
-
} from "motion/react";
|
|
309
|
-
import {
|
|
310
|
-
useCallback as useCallback2,
|
|
311
|
-
useId,
|
|
312
|
-
useMemo as useMemo2,
|
|
313
|
-
useState as useState2
|
|
314
|
-
} from "react";
|
|
258
|
+
import { domMax, LayoutGroup, LazyMotion, useReducedMotion } from "motion/react";
|
|
259
|
+
import { useId, useState as useState2 } from "react";
|
|
315
260
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
316
|
-
|
|
261
|
+
var ApertoRoot = ({
|
|
317
262
|
children,
|
|
318
263
|
dismissible = true,
|
|
319
264
|
layoutId: layoutIdProp,
|
|
@@ -322,7 +267,7 @@ function ApertoRoot({
|
|
|
322
267
|
onOpenChange: controlledOnOpenChange,
|
|
323
268
|
reduceMotion: reduceMotionProp,
|
|
324
269
|
...dialogProps
|
|
325
|
-
}) {
|
|
270
|
+
}) => {
|
|
326
271
|
const generatedId = useId();
|
|
327
272
|
const layoutId = layoutIdProp ?? `aperto-${generatedId}`;
|
|
328
273
|
const systemReducedMotion = useReducedMotion() ?? false;
|
|
@@ -330,67 +275,46 @@ function ApertoRoot({
|
|
|
330
275
|
const [internalOpen, setInternalOpen] = useState2(false);
|
|
331
276
|
const isControlled = controlledOpen !== void 0;
|
|
332
277
|
const open = isControlled ? controlledOpen : internalOpen;
|
|
333
|
-
const onOpenChange =
|
|
334
|
-
(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
},
|
|
340
|
-
[isControlled, controlledOnOpenChange]
|
|
341
|
-
);
|
|
278
|
+
const onOpenChange = (nextOpen) => {
|
|
279
|
+
if (!isControlled) {
|
|
280
|
+
setInternalOpen(nextOpen);
|
|
281
|
+
}
|
|
282
|
+
controlledOnOpenChange?.(nextOpen);
|
|
283
|
+
};
|
|
342
284
|
const globalPresetName = typeof motionProp === "string" ? motionProp : "smooth";
|
|
343
285
|
const variants = typeof motionProp === "object" ? motionProp : void 0;
|
|
344
286
|
const presetName = shouldReduce ? "reduced" : globalPresetName;
|
|
345
287
|
const preset = PRESETS[presetName];
|
|
346
|
-
const contextValue =
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}),
|
|
357
|
-
[
|
|
358
|
-
dismissible,
|
|
359
|
-
layoutId,
|
|
360
|
-
onOpenChange,
|
|
361
|
-
open,
|
|
362
|
-
preset,
|
|
363
|
-
presetName,
|
|
364
|
-
shouldReduce,
|
|
365
|
-
variants
|
|
366
|
-
]
|
|
367
|
-
);
|
|
288
|
+
const contextValue = {
|
|
289
|
+
dismissible,
|
|
290
|
+
layoutId,
|
|
291
|
+
onOpenChange,
|
|
292
|
+
open,
|
|
293
|
+
preset,
|
|
294
|
+
presetName,
|
|
295
|
+
reduceMotion: shouldReduce,
|
|
296
|
+
variants
|
|
297
|
+
};
|
|
368
298
|
return /* @__PURE__ */ jsx5(ApertoContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx5(Dialog5.Root, { onOpenChange, open, ...dialogProps, children: /* @__PURE__ */ jsx5(LazyMotion, { features: domMax, children: /* @__PURE__ */ jsx5(LayoutGroup, { id: layoutId, children }) }) }) });
|
|
369
|
-
}
|
|
299
|
+
};
|
|
370
300
|
|
|
371
301
|
// src/aperto-title.tsx
|
|
372
302
|
import * as Dialog6 from "@radix-ui/react-dialog";
|
|
373
|
-
import { forwardRef as forwardRef4 } from "react";
|
|
374
303
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
375
|
-
var ApertoTitle =
|
|
376
|
-
return /* @__PURE__ */ jsx6(Dialog6.Title, { "data-slot": "aperto-title", ref, ...props });
|
|
377
|
-
});
|
|
304
|
+
var ApertoTitle = ({ ref, ...props }) => /* @__PURE__ */ jsx6(Dialog6.Title, { "data-slot": "aperto-title", ref, ...props });
|
|
378
305
|
ApertoTitle.displayName = "ApertoTitle";
|
|
379
306
|
|
|
380
307
|
// src/expanded-media-stage.tsx
|
|
381
|
-
import {
|
|
382
|
-
AnimatePresence as AnimatePresence2,
|
|
383
|
-
m as m3
|
|
384
|
-
} from "motion/react";
|
|
308
|
+
import { AnimatePresence as AnimatePresence2, m as m3 } from "motion/react";
|
|
385
309
|
|
|
386
310
|
// src/media-rendering.tsx
|
|
387
311
|
import { createElement } from "react";
|
|
388
312
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
389
|
-
|
|
313
|
+
var renderDefaultImage = (props) => {
|
|
390
314
|
const { item: _item, variant: _variant, ...imageProps } = props;
|
|
391
315
|
return createElement("img", { ...imageProps, alt: imageProps.alt ?? "" });
|
|
392
|
-
}
|
|
393
|
-
|
|
316
|
+
};
|
|
317
|
+
var renderDefaultVideo = (props) => {
|
|
394
318
|
const { item: _item, variant, ...videoProps } = props;
|
|
395
319
|
if (variant === "thumbnail") {
|
|
396
320
|
return createElement("img", {
|
|
@@ -399,12 +323,12 @@ function renderDefaultVideo(props) {
|
|
|
399
323
|
});
|
|
400
324
|
}
|
|
401
325
|
return /* @__PURE__ */ jsx7("video", { ...videoProps, children: /* @__PURE__ */ jsx7("track", { kind: "captions", src: props.item.captionsSrc ?? "data:text/vtt," }) });
|
|
402
|
-
}
|
|
403
|
-
|
|
326
|
+
};
|
|
327
|
+
var ApertoThumbnailMedia = ({
|
|
404
328
|
item,
|
|
405
329
|
renderImage,
|
|
406
330
|
renderVideo
|
|
407
|
-
}) {
|
|
331
|
+
}) => {
|
|
408
332
|
if (item.type === "image") {
|
|
409
333
|
const imageProps = {
|
|
410
334
|
alt: "",
|
|
@@ -426,12 +350,12 @@ function ApertoThumbnailMedia({
|
|
|
426
350
|
width: item.width
|
|
427
351
|
};
|
|
428
352
|
return (renderVideo ?? renderDefaultVideo)(videoProps);
|
|
429
|
-
}
|
|
430
|
-
|
|
353
|
+
};
|
|
354
|
+
var ApertoExpandedMedia = ({
|
|
431
355
|
item,
|
|
432
356
|
renderImage,
|
|
433
357
|
renderVideo
|
|
434
|
-
}) {
|
|
358
|
+
}) => {
|
|
435
359
|
if (item.type === "image") {
|
|
436
360
|
const imageProps = {
|
|
437
361
|
alt: item.alt,
|
|
@@ -454,12 +378,12 @@ function ApertoExpandedMedia({
|
|
|
454
378
|
width: item.width
|
|
455
379
|
};
|
|
456
380
|
return (renderVideo ?? renderDefaultVideo)(videoProps);
|
|
457
|
-
}
|
|
458
|
-
|
|
381
|
+
};
|
|
382
|
+
var ApertoTransitionMedia = ({
|
|
459
383
|
item,
|
|
460
384
|
renderImage,
|
|
461
385
|
renderVideo
|
|
462
|
-
}) {
|
|
386
|
+
}) => {
|
|
463
387
|
if (item.type === "image") {
|
|
464
388
|
const imageProps = {
|
|
465
389
|
alt: item.alt,
|
|
@@ -481,18 +405,12 @@ function ApertoTransitionMedia({
|
|
|
481
405
|
width: item.width
|
|
482
406
|
};
|
|
483
407
|
return (renderVideo ?? renderDefaultVideo)(videoProps);
|
|
484
|
-
}
|
|
408
|
+
};
|
|
485
409
|
|
|
486
410
|
// src/media-utils.ts
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
function getMediaKey(item, index) {
|
|
491
|
-
return item.id ?? `${item.type}:${item.src}:${index}`;
|
|
492
|
-
}
|
|
493
|
-
function getDescriptionProps(item) {
|
|
494
|
-
return item.description ? {} : { "aria-describedby": void 0 };
|
|
495
|
-
}
|
|
411
|
+
var getMediaLabel = (item) => item.title ?? item.alt ?? "media";
|
|
412
|
+
var getMediaKey = (item, index) => item.id ?? `${item.type}:${item.src}:${index}`;
|
|
413
|
+
var getDescriptionProps = (item) => item.description ? {} : { "aria-describedby": void 0 };
|
|
496
414
|
|
|
497
415
|
// src/expanded-media-stage.tsx
|
|
498
416
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -535,20 +453,12 @@ var expandedMediaVariants = {
|
|
|
535
453
|
scale: 1,
|
|
536
454
|
x: 0
|
|
537
455
|
},
|
|
538
|
-
enter: ({
|
|
539
|
-
direction,
|
|
540
|
-
offset,
|
|
541
|
-
scale
|
|
542
|
-
}) => ({
|
|
456
|
+
enter: ({ direction, offset, scale }) => ({
|
|
543
457
|
opacity: 0,
|
|
544
458
|
scale: direction === 0 ? 1 : scale,
|
|
545
459
|
x: direction * offset
|
|
546
460
|
}),
|
|
547
|
-
exit: ({
|
|
548
|
-
direction,
|
|
549
|
-
offset,
|
|
550
|
-
scale
|
|
551
|
-
}) => ({
|
|
461
|
+
exit: ({ direction, offset, scale }) => ({
|
|
552
462
|
opacity: 0,
|
|
553
463
|
scale: direction === 0 ? 1 : scale,
|
|
554
464
|
x: direction * -offset
|
|
@@ -568,14 +478,14 @@ var reducedExpandedMediaVariants = {
|
|
|
568
478
|
x: 0
|
|
569
479
|
}
|
|
570
480
|
};
|
|
571
|
-
|
|
481
|
+
var ApertoExpandedMediaStage = ({
|
|
572
482
|
direction,
|
|
573
483
|
index,
|
|
574
484
|
item,
|
|
575
485
|
navigationMotion,
|
|
576
486
|
renderImage,
|
|
577
487
|
renderVideo
|
|
578
|
-
}) {
|
|
488
|
+
}) => {
|
|
579
489
|
const ctx = useApertoContext();
|
|
580
490
|
const preset = NAVIGATION_MOTION_PRESETS[navigationMotion];
|
|
581
491
|
const transition = ctx.reduceMotion ? REDUCED_EXPANDED_MEDIA_TRANSITION : preset.transition;
|
|
@@ -597,25 +507,18 @@ function ApertoExpandedMediaStage({
|
|
|
597
507
|
initial: "enter",
|
|
598
508
|
transition,
|
|
599
509
|
variants,
|
|
600
|
-
children: /* @__PURE__ */ jsx8(
|
|
601
|
-
ApertoExpandedMedia,
|
|
602
|
-
{
|
|
603
|
-
item,
|
|
604
|
-
renderImage,
|
|
605
|
-
renderVideo
|
|
606
|
-
}
|
|
607
|
-
)
|
|
510
|
+
children: /* @__PURE__ */ jsx8(ApertoExpandedMedia, { item, renderImage, renderVideo })
|
|
608
511
|
},
|
|
609
512
|
getMediaKey(item, index)
|
|
610
513
|
) });
|
|
611
|
-
}
|
|
514
|
+
};
|
|
612
515
|
|
|
613
516
|
// src/media-transition.tsx
|
|
614
517
|
import { m as m4 } from "motion/react";
|
|
615
518
|
import { useEffect } from "react";
|
|
616
519
|
|
|
617
520
|
// src/media-transition-utils.ts
|
|
618
|
-
|
|
521
|
+
var rectFromElement = (element) => {
|
|
619
522
|
if (!element) {
|
|
620
523
|
return null;
|
|
621
524
|
}
|
|
@@ -626,36 +529,29 @@ function rectFromElement(element) {
|
|
|
626
529
|
top: rect.top,
|
|
627
530
|
width: rect.width
|
|
628
531
|
};
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
function transitionDurationMs(transition) {
|
|
639
|
-
return typeof transition.duration === "number" ? transition.duration * 1e3 : 450;
|
|
640
|
-
}
|
|
532
|
+
};
|
|
533
|
+
var rectTarget = (rect) => ({
|
|
534
|
+
height: rect.height,
|
|
535
|
+
left: rect.left,
|
|
536
|
+
top: rect.top,
|
|
537
|
+
width: rect.width
|
|
538
|
+
});
|
|
539
|
+
var transitionDurationMs = (transition) => typeof transition.duration === "number" ? transition.duration * 1e3 : 450;
|
|
641
540
|
|
|
642
541
|
// src/media-transition.tsx
|
|
643
542
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
644
|
-
|
|
543
|
+
var ApertoMediaTransitionClone = ({
|
|
645
544
|
onComplete,
|
|
646
545
|
renderImage,
|
|
647
546
|
renderVideo,
|
|
648
547
|
transition
|
|
649
|
-
}) {
|
|
548
|
+
}) => {
|
|
650
549
|
const ctx = useApertoContext();
|
|
651
550
|
useEffect(() => {
|
|
652
551
|
if (!transition?.to) {
|
|
653
552
|
return;
|
|
654
553
|
}
|
|
655
|
-
const timer = setTimeout(
|
|
656
|
-
onComplete,
|
|
657
|
-
transitionDurationMs(ctx.preset.transition)
|
|
658
|
-
);
|
|
554
|
+
const timer = setTimeout(onComplete, transitionDurationMs(ctx.preset.transition));
|
|
659
555
|
return () => clearTimeout(timer);
|
|
660
556
|
}, [ctx.preset.transition, onComplete, transition]);
|
|
661
557
|
if (!transition?.to) {
|
|
@@ -686,24 +582,23 @@ function ApertoMediaTransitionClone({
|
|
|
686
582
|
)
|
|
687
583
|
}
|
|
688
584
|
);
|
|
689
|
-
}
|
|
585
|
+
};
|
|
690
586
|
|
|
691
|
-
// src/Aperto/
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
}
|
|
702
|
-
function apertoGroupReducer(state, action) {
|
|
587
|
+
// src/Aperto/aperto-group-state.ts
|
|
588
|
+
var getInitialGroupState = (initialIndex) => ({
|
|
589
|
+
closing: false,
|
|
590
|
+
internalIndex: initialIndex,
|
|
591
|
+
layoutSourceIndex: initialIndex,
|
|
592
|
+
mediaTransition: null,
|
|
593
|
+
navigationDirection: 0,
|
|
594
|
+
open: false
|
|
595
|
+
});
|
|
596
|
+
var apertoGroupReducer = (state, action) => {
|
|
703
597
|
switch (action.type) {
|
|
704
|
-
case "close-without-transition":
|
|
598
|
+
case "close-without-transition": {
|
|
705
599
|
return { ...state, closing: false, mediaTransition: null, open: false };
|
|
706
|
-
|
|
600
|
+
}
|
|
601
|
+
case "complete-opening-target": {
|
|
707
602
|
if (state.mediaTransition?.phase !== "opening" || state.mediaTransition.to) {
|
|
708
603
|
return state;
|
|
709
604
|
}
|
|
@@ -711,21 +606,24 @@ function apertoGroupReducer(state, action) {
|
|
|
711
606
|
...state,
|
|
712
607
|
mediaTransition: { ...state.mediaTransition, to: action.rect }
|
|
713
608
|
};
|
|
714
|
-
|
|
609
|
+
}
|
|
610
|
+
case "finish-transition": {
|
|
715
611
|
return {
|
|
716
612
|
...state,
|
|
717
613
|
closing: false,
|
|
718
614
|
mediaTransition: null,
|
|
719
615
|
open: state.mediaTransition?.phase === "closing" ? false : state.open
|
|
720
616
|
};
|
|
721
|
-
|
|
617
|
+
}
|
|
618
|
+
case "navigate": {
|
|
722
619
|
return {
|
|
723
620
|
...state,
|
|
724
621
|
internalIndex: action.index,
|
|
725
622
|
layoutSourceIndex: action.index,
|
|
726
623
|
navigationDirection: action.direction
|
|
727
624
|
};
|
|
728
|
-
|
|
625
|
+
}
|
|
626
|
+
case "open-at-index": {
|
|
729
627
|
return {
|
|
730
628
|
...state,
|
|
731
629
|
closing: false,
|
|
@@ -735,21 +633,28 @@ function apertoGroupReducer(state, action) {
|
|
|
735
633
|
navigationDirection: 0,
|
|
736
634
|
open: true
|
|
737
635
|
};
|
|
738
|
-
|
|
636
|
+
}
|
|
637
|
+
case "set-index": {
|
|
739
638
|
return { ...state, internalIndex: action.index };
|
|
740
|
-
|
|
639
|
+
}
|
|
640
|
+
case "set-open": {
|
|
741
641
|
return action.open ? { ...state, closing: false, open: true } : { ...state, open: false };
|
|
742
|
-
|
|
642
|
+
}
|
|
643
|
+
case "start-close": {
|
|
743
644
|
return {
|
|
744
645
|
...state,
|
|
745
646
|
closing: true,
|
|
746
647
|
mediaTransition: action.transition
|
|
747
648
|
};
|
|
649
|
+
}
|
|
650
|
+
default: {
|
|
651
|
+
return state;
|
|
652
|
+
}
|
|
748
653
|
}
|
|
749
|
-
}
|
|
654
|
+
};
|
|
750
655
|
|
|
751
|
-
// src/Aperto/
|
|
752
|
-
|
|
656
|
+
// src/Aperto/aperto-keyboard.ts
|
|
657
|
+
var shouldIgnoreKeyboardNavigationTarget = (target) => {
|
|
753
658
|
if (!(target instanceof Element)) {
|
|
754
659
|
return false;
|
|
755
660
|
}
|
|
@@ -758,11 +663,45 @@ function shouldIgnoreKeyboardNavigationTarget(target) {
|
|
|
758
663
|
'input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="textbox"], audio, video'
|
|
759
664
|
)
|
|
760
665
|
);
|
|
761
|
-
}
|
|
666
|
+
};
|
|
762
667
|
|
|
763
|
-
// src/Aperto/
|
|
668
|
+
// src/Aperto/aperto-group.tsx
|
|
764
669
|
import { Fragment, jsx as jsx10, jsxs } from "react/jsx-runtime";
|
|
765
|
-
|
|
670
|
+
var ApertoMediaNavigationButtons = ({
|
|
671
|
+
classNames,
|
|
672
|
+
enabled,
|
|
673
|
+
onNext,
|
|
674
|
+
onPrevious
|
|
675
|
+
}) => {
|
|
676
|
+
if (!enabled) {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
680
|
+
/* @__PURE__ */ jsx10(
|
|
681
|
+
"button",
|
|
682
|
+
{
|
|
683
|
+
"aria-label": "Previous media",
|
|
684
|
+
className: classNames?.previousButton,
|
|
685
|
+
"data-slot": "aperto-previous-button",
|
|
686
|
+
onClick: onPrevious,
|
|
687
|
+
type: "button",
|
|
688
|
+
children: /* @__PURE__ */ jsx10(ChevronLeft, { "aria-hidden": "true", size: 18, strokeWidth: 2 })
|
|
689
|
+
}
|
|
690
|
+
),
|
|
691
|
+
/* @__PURE__ */ jsx10(
|
|
692
|
+
"button",
|
|
693
|
+
{
|
|
694
|
+
"aria-label": "Next media",
|
|
695
|
+
className: classNames?.nextButton,
|
|
696
|
+
"data-slot": "aperto-next-button",
|
|
697
|
+
onClick: onNext,
|
|
698
|
+
type: "button",
|
|
699
|
+
children: /* @__PURE__ */ jsx10(ChevronRight, { "aria-hidden": "true", size: 18, strokeWidth: 2 })
|
|
700
|
+
}
|
|
701
|
+
)
|
|
702
|
+
] });
|
|
703
|
+
};
|
|
704
|
+
var ApertoGroup = ({
|
|
766
705
|
children,
|
|
767
706
|
classNames,
|
|
768
707
|
dismissible,
|
|
@@ -774,13 +713,9 @@ function ApertoGroup({
|
|
|
774
713
|
onIndexChange,
|
|
775
714
|
renderImage,
|
|
776
715
|
renderVideo
|
|
777
|
-
}) {
|
|
716
|
+
}) => {
|
|
778
717
|
const generatedId = useId2();
|
|
779
|
-
const [state, dispatch] = useReducer(
|
|
780
|
-
apertoGroupReducer,
|
|
781
|
-
initialIndex,
|
|
782
|
-
getInitialGroupState
|
|
783
|
-
);
|
|
718
|
+
const [state, dispatch] = useReducer(apertoGroupReducer, initialIndex, getInitialGroupState);
|
|
784
719
|
const isControlled = controlledIndex !== void 0;
|
|
785
720
|
const index = isControlled ? controlledIndex : state.internalIndex;
|
|
786
721
|
const activeMedia = media[index] ?? media[0];
|
|
@@ -790,63 +725,47 @@ function ApertoGroup({
|
|
|
790
725
|
thumbnailRefs.current = /* @__PURE__ */ new Map();
|
|
791
726
|
}
|
|
792
727
|
const thumbnailMap = thumbnailRefs.current;
|
|
793
|
-
const sharedLayoutIdForIndex =
|
|
794
|
-
(nextIndex) => `aperto-group-${generatedId}-${nextIndex}-shared`,
|
|
795
|
-
[generatedId]
|
|
796
|
-
);
|
|
728
|
+
const sharedLayoutIdForIndex = (nextIndex) => `aperto-group-${generatedId}-${nextIndex}-shared`;
|
|
797
729
|
const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);
|
|
798
|
-
const
|
|
799
|
-
|
|
800
|
-
if (
|
|
730
|
+
const setExpandedMediaNode = (node) => {
|
|
731
|
+
expandedMediaRef.current = node;
|
|
732
|
+
if (node) {
|
|
733
|
+
const targetRect = rectFromElement(node);
|
|
734
|
+
if (targetRect) {
|
|
735
|
+
dispatch({ rect: targetRect, type: "complete-opening-target" });
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
const registerThumbnail = (thumbIndex, node) => {
|
|
740
|
+
if (node) {
|
|
741
|
+
thumbnailMap.set(thumbIndex, node);
|
|
801
742
|
return;
|
|
802
743
|
}
|
|
803
|
-
|
|
804
|
-
}
|
|
805
|
-
const setExpandedMediaNode = useCallback3(
|
|
806
|
-
(node) => {
|
|
807
|
-
expandedMediaRef.current = node;
|
|
808
|
-
if (node) {
|
|
809
|
-
measureOpeningTarget(node);
|
|
810
|
-
}
|
|
811
|
-
},
|
|
812
|
-
[measureOpeningTarget]
|
|
813
|
-
);
|
|
814
|
-
const registerThumbnail = useCallback3(
|
|
815
|
-
(thumbIndex, node) => {
|
|
816
|
-
if (node) {
|
|
817
|
-
thumbnailMap.set(thumbIndex, node);
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
thumbnailMap.delete(thumbIndex);
|
|
821
|
-
},
|
|
822
|
-
[thumbnailMap]
|
|
823
|
-
);
|
|
744
|
+
thumbnailMap.delete(thumbIndex);
|
|
745
|
+
};
|
|
824
746
|
useLayoutEffect(() => {
|
|
825
747
|
if (state.mediaTransition?.phase !== "opening" || state.mediaTransition.to || !expandedMediaRef.current) {
|
|
826
748
|
return;
|
|
827
749
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
const openAtIndex =
|
|
840
|
-
(thumbIndex)
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
[media, onIndexChange, thumbnailMap]
|
|
848
|
-
);
|
|
849
|
-
const startClose = useCallback3(() => {
|
|
750
|
+
const targetRect = rectFromElement(expandedMediaRef.current);
|
|
751
|
+
if (targetRect) {
|
|
752
|
+
dispatch({ rect: targetRect, type: "complete-opening-target" });
|
|
753
|
+
}
|
|
754
|
+
}, [state.mediaTransition]);
|
|
755
|
+
const setIndex = (nextIndex) => {
|
|
756
|
+
if (!isControlled) {
|
|
757
|
+
dispatch({ index: nextIndex, type: "set-index" });
|
|
758
|
+
}
|
|
759
|
+
onIndexChange?.(nextIndex);
|
|
760
|
+
};
|
|
761
|
+
const openAtIndex = (thumbIndex) => {
|
|
762
|
+
const sourceRect = rectFromElement(thumbnailMap.get(thumbIndex) ?? null);
|
|
763
|
+
const item = media[thumbIndex];
|
|
764
|
+
const transition = sourceRect && item ? { from: sourceRect, item, phase: "opening" } : null;
|
|
765
|
+
dispatch({ index: thumbIndex, transition, type: "open-at-index" });
|
|
766
|
+
onIndexChange?.(thumbIndex);
|
|
767
|
+
};
|
|
768
|
+
const startClose = () => {
|
|
850
769
|
if (!state.open || state.closing) {
|
|
851
770
|
return;
|
|
852
771
|
}
|
|
@@ -865,86 +784,59 @@ function ApertoGroup({
|
|
|
865
784
|
},
|
|
866
785
|
type: "start-close"
|
|
867
786
|
});
|
|
868
|
-
}
|
|
869
|
-
const handleCloseAutoFocus =
|
|
870
|
-
(
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
[index, thumbnailMap]
|
|
875
|
-
);
|
|
876
|
-
const handleMediaTransitionComplete = useCallback3(() => {
|
|
787
|
+
};
|
|
788
|
+
const handleCloseAutoFocus = (event) => {
|
|
789
|
+
event.preventDefault();
|
|
790
|
+
thumbnailMap.get(index)?.focus({ preventScroll: true });
|
|
791
|
+
};
|
|
792
|
+
const handleMediaTransitionComplete = () => {
|
|
877
793
|
dispatch({ type: "finish-transition" });
|
|
878
|
-
}
|
|
879
|
-
const handleOpenChange =
|
|
880
|
-
(nextOpen)
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
setIndex,
|
|
900
|
-
sharedLayoutId,
|
|
901
|
-
sharedLayoutIdForIndex
|
|
902
|
-
}),
|
|
903
|
-
[
|
|
904
|
-
classNames,
|
|
905
|
-
index,
|
|
906
|
-
media,
|
|
907
|
-
state.open,
|
|
908
|
-
openAtIndex,
|
|
909
|
-
registerThumbnail,
|
|
910
|
-
renderImage,
|
|
911
|
-
renderVideo,
|
|
912
|
-
setIndex,
|
|
913
|
-
sharedLayoutId,
|
|
914
|
-
sharedLayoutIdForIndex
|
|
915
|
-
]
|
|
916
|
-
);
|
|
794
|
+
};
|
|
795
|
+
const handleOpenChange = (nextOpen) => {
|
|
796
|
+
if (nextOpen) {
|
|
797
|
+
dispatch({ open: true, type: "set-open" });
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
startClose();
|
|
801
|
+
};
|
|
802
|
+
const value = {
|
|
803
|
+
classNames,
|
|
804
|
+
index,
|
|
805
|
+
media,
|
|
806
|
+
open: state.open,
|
|
807
|
+
openAtIndex,
|
|
808
|
+
registerThumbnail,
|
|
809
|
+
renderImage,
|
|
810
|
+
renderVideo,
|
|
811
|
+
setIndex,
|
|
812
|
+
sharedLayoutId,
|
|
813
|
+
sharedLayoutIdForIndex
|
|
814
|
+
};
|
|
917
815
|
const hasNavigation = media.length > 1;
|
|
918
|
-
const navigateToIndex =
|
|
919
|
-
(nextIndex,
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
[onIndexChange]
|
|
924
|
-
);
|
|
925
|
-
const goToPrevious = useCallback3(() => {
|
|
816
|
+
const navigateToIndex = (nextIndex, direction) => {
|
|
817
|
+
dispatch({ direction, index: nextIndex, type: "navigate" });
|
|
818
|
+
onIndexChange?.(nextIndex);
|
|
819
|
+
};
|
|
820
|
+
const goToPrevious = () => {
|
|
926
821
|
navigateToIndex((index - 1 + media.length) % media.length, -1);
|
|
927
|
-
}
|
|
928
|
-
const goToNext =
|
|
822
|
+
};
|
|
823
|
+
const goToNext = () => {
|
|
929
824
|
navigateToIndex((index + 1) % media.length, 1);
|
|
930
|
-
}
|
|
931
|
-
const handleContentKeyDown =
|
|
932
|
-
(event)
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
[goToNext, goToPrevious]
|
|
946
|
-
);
|
|
947
|
-
const expandedMediaStyle = useMemo3(() => {
|
|
825
|
+
};
|
|
826
|
+
const handleContentKeyDown = (event) => {
|
|
827
|
+
if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || shouldIgnoreKeyboardNavigationTarget(event.target)) {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (event.key === "ArrowLeft") {
|
|
831
|
+
event.preventDefault();
|
|
832
|
+
goToPrevious();
|
|
833
|
+
}
|
|
834
|
+
if (event.key === "ArrowRight") {
|
|
835
|
+
event.preventDefault();
|
|
836
|
+
goToNext();
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
const expandedMediaStyle = (() => {
|
|
948
840
|
if (!activeMedia?.width || !activeMedia.height) {
|
|
949
841
|
return void 0;
|
|
950
842
|
}
|
|
@@ -953,7 +845,7 @@ function ApertoGroup({
|
|
|
953
845
|
"--aperto-expanded-aspect-ratio-height": activeMedia.height,
|
|
954
846
|
"--aperto-expanded-aspect-ratio-width": activeMedia.width
|
|
955
847
|
};
|
|
956
|
-
}
|
|
848
|
+
})();
|
|
957
849
|
return /* @__PURE__ */ jsx10(ApertoGroupContext.Provider, { value, children: /* @__PURE__ */ jsxs(
|
|
958
850
|
ApertoRoot,
|
|
959
851
|
{
|
|
@@ -964,13 +856,7 @@ function ApertoGroup({
|
|
|
964
856
|
children: [
|
|
965
857
|
children,
|
|
966
858
|
activeMedia ? /* @__PURE__ */ jsxs(ApertoPortal, { children: [
|
|
967
|
-
/* @__PURE__ */ jsx10(
|
|
968
|
-
ApertoOverlay,
|
|
969
|
-
{
|
|
970
|
-
className: classNames?.overlay,
|
|
971
|
-
fadeOut: state.closing
|
|
972
|
-
}
|
|
973
|
-
),
|
|
859
|
+
/* @__PURE__ */ jsx10(ApertoOverlay, { className: classNames?.overlay, fadeOut: state.closing }),
|
|
974
860
|
/* @__PURE__ */ jsxs(
|
|
975
861
|
ApertoContent,
|
|
976
862
|
{
|
|
@@ -981,36 +867,28 @@ function ApertoGroup({
|
|
|
981
867
|
sharedLayoutId: false,
|
|
982
868
|
...getDescriptionProps(activeMedia),
|
|
983
869
|
children: [
|
|
984
|
-
/* @__PURE__ */ jsxs(
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
enabled: hasNavigation,
|
|
1007
|
-
onNext: goToNext,
|
|
1008
|
-
onPrevious: goToPrevious
|
|
1009
|
-
}
|
|
1010
|
-
)
|
|
1011
|
-
]
|
|
1012
|
-
}
|
|
1013
|
-
),
|
|
870
|
+
/* @__PURE__ */ jsxs("div", { "data-slot": "aperto-media", ref: setExpandedMediaNode, style: expandedMediaStyle, children: [
|
|
871
|
+
/* @__PURE__ */ jsx10(
|
|
872
|
+
ApertoExpandedMediaStage,
|
|
873
|
+
{
|
|
874
|
+
direction: state.navigationDirection,
|
|
875
|
+
index,
|
|
876
|
+
item: activeMedia,
|
|
877
|
+
navigationMotion,
|
|
878
|
+
renderImage,
|
|
879
|
+
renderVideo
|
|
880
|
+
}
|
|
881
|
+
),
|
|
882
|
+
/* @__PURE__ */ jsx10(
|
|
883
|
+
ApertoMediaNavigationButtons,
|
|
884
|
+
{
|
|
885
|
+
classNames,
|
|
886
|
+
enabled: hasNavigation,
|
|
887
|
+
onNext: goToNext,
|
|
888
|
+
onPrevious: goToPrevious
|
|
889
|
+
}
|
|
890
|
+
)
|
|
891
|
+
] }),
|
|
1014
892
|
/* @__PURE__ */ jsx10(ApertoTitle, { children: activeMedia.title ?? getMediaLabel(activeMedia) }),
|
|
1015
893
|
activeMedia.description ? /* @__PURE__ */ jsx10(ApertoDescription, { children: activeMedia.description }) : null,
|
|
1016
894
|
hasNavigation ? /* @__PURE__ */ jsxs("div", { className: classNames?.counter, "data-slot": "aperto-counter", children: [
|
|
@@ -1045,157 +923,85 @@ function ApertoGroup({
|
|
|
1045
923
|
]
|
|
1046
924
|
}
|
|
1047
925
|
) });
|
|
1048
|
-
}
|
|
1049
|
-
function ApertoMediaNavigationButtons({
|
|
1050
|
-
classNames,
|
|
1051
|
-
enabled,
|
|
1052
|
-
onNext,
|
|
1053
|
-
onPrevious
|
|
1054
|
-
}) {
|
|
1055
|
-
if (!enabled) {
|
|
1056
|
-
return null;
|
|
1057
|
-
}
|
|
1058
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1059
|
-
/* @__PURE__ */ jsx10(
|
|
1060
|
-
"button",
|
|
1061
|
-
{
|
|
1062
|
-
"aria-label": "Previous media",
|
|
1063
|
-
className: classNames?.previousButton,
|
|
1064
|
-
"data-slot": "aperto-previous-button",
|
|
1065
|
-
onClick: onPrevious,
|
|
1066
|
-
type: "button",
|
|
1067
|
-
children: /* @__PURE__ */ jsx10(ChevronLeft, { "aria-hidden": "true", size: 18, strokeWidth: 2 })
|
|
1068
|
-
}
|
|
1069
|
-
),
|
|
1070
|
-
/* @__PURE__ */ jsx10(
|
|
1071
|
-
"button",
|
|
1072
|
-
{
|
|
1073
|
-
"aria-label": "Next media",
|
|
1074
|
-
className: classNames?.nextButton,
|
|
1075
|
-
"data-slot": "aperto-next-button",
|
|
1076
|
-
onClick: onNext,
|
|
1077
|
-
type: "button",
|
|
1078
|
-
children: /* @__PURE__ */ jsx10(ChevronRight, { "aria-hidden": "true", size: 18, strokeWidth: 2 })
|
|
1079
|
-
}
|
|
1080
|
-
)
|
|
1081
|
-
] });
|
|
1082
|
-
}
|
|
926
|
+
};
|
|
1083
927
|
|
|
1084
928
|
// src/aperto-close.tsx
|
|
1085
929
|
import * as Dialog7 from "@radix-ui/react-dialog";
|
|
1086
930
|
import { X as X2 } from "lucide-react";
|
|
1087
|
-
import { forwardRef as forwardRef5 } from "react";
|
|
1088
931
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1089
|
-
var ApertoClose =
|
|
1090
|
-
return /* @__PURE__ */ jsx11(Dialog7.Close, { "data-slot": "aperto-close", ref, ...props, children: children ?? /* @__PURE__ */ jsx11(X2, { "aria-hidden": "true", size: 17, strokeWidth: 2 }) });
|
|
1091
|
-
});
|
|
932
|
+
var ApertoClose = ({ children, ref, ...props }) => /* @__PURE__ */ jsx11(Dialog7.Close, { "data-slot": "aperto-close", ref, ...props, children: children ?? /* @__PURE__ */ jsx11(X2, { "aria-hidden": "true", size: 17, strokeWidth: 2 }) });
|
|
1092
933
|
ApertoClose.displayName = "ApertoClose";
|
|
1093
934
|
|
|
1094
935
|
// src/aperto-trigger.tsx
|
|
1095
936
|
import * as Dialog8 from "@radix-ui/react-dialog";
|
|
1096
937
|
import { m as m5 } from "motion/react";
|
|
1097
|
-
import { forwardRef as forwardRef6 } from "react";
|
|
1098
938
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1099
939
|
var TRIGGER_OPEN_Z_INDEX = 1e3;
|
|
1100
|
-
var ApertoTrigger =
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
layoutId
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
940
|
+
var ApertoTrigger = ({
|
|
941
|
+
active,
|
|
942
|
+
children,
|
|
943
|
+
motion: motionOverride,
|
|
944
|
+
ref,
|
|
945
|
+
sharedLayoutId,
|
|
946
|
+
...props
|
|
947
|
+
}) => {
|
|
948
|
+
const ctx = useApertoContext();
|
|
949
|
+
const shouldRaise = ctx.open && (active ?? true);
|
|
950
|
+
const zIndex = shouldRaise ? TRIGGER_OPEN_Z_INDEX : 0;
|
|
951
|
+
const resolved = resolvePreset(
|
|
952
|
+
"trigger",
|
|
953
|
+
motionOverride,
|
|
954
|
+
ctx.presetName,
|
|
955
|
+
ctx.variants,
|
|
956
|
+
ctx.reduceMotion
|
|
957
|
+
);
|
|
958
|
+
const layoutId = sharedLayoutId === false ? void 0 : sharedLayoutId ?? `${ctx.layoutId}-shared`;
|
|
959
|
+
return /* @__PURE__ */ jsx12(Dialog8.Trigger, { asChild: true, ref, ...props, children: /* @__PURE__ */ jsx12(
|
|
960
|
+
m5.button,
|
|
961
|
+
{
|
|
962
|
+
"data-aperto-active": shouldRaise ? "" : void 0,
|
|
963
|
+
"data-slot": "aperto-trigger",
|
|
964
|
+
layout: true,
|
|
965
|
+
layoutCrossfade: false,
|
|
966
|
+
layoutId,
|
|
967
|
+
style: { zIndex },
|
|
968
|
+
transition: resolved.transition,
|
|
969
|
+
type: "button",
|
|
970
|
+
children
|
|
971
|
+
},
|
|
972
|
+
layoutId ?? "unshared"
|
|
973
|
+
) });
|
|
974
|
+
};
|
|
1130
975
|
ApertoTrigger.displayName = "ApertoTrigger";
|
|
1131
976
|
|
|
1132
|
-
// src/Aperto/
|
|
977
|
+
// src/Aperto/aperto-single.tsx
|
|
1133
978
|
import { jsx as jsx13, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1134
|
-
|
|
979
|
+
var ApertoSingle = ({
|
|
1135
980
|
classNames,
|
|
1136
981
|
dismissible,
|
|
1137
982
|
media,
|
|
1138
983
|
renderImage,
|
|
1139
984
|
renderVideo
|
|
1140
|
-
}) {
|
|
985
|
+
}) => {
|
|
1141
986
|
const label = getMediaLabel(media);
|
|
1142
987
|
const title = media.title ?? label;
|
|
1143
988
|
return /* @__PURE__ */ jsxs2(ApertoRoot, { dismissible, children: [
|
|
1144
|
-
/* @__PURE__ */ jsx13(
|
|
1145
|
-
ApertoTrigger,
|
|
1146
|
-
{
|
|
1147
|
-
"aria-label": `Open ${label}`,
|
|
1148
|
-
className: classNames?.thumbnail,
|
|
1149
|
-
children: /* @__PURE__ */ jsx13(
|
|
1150
|
-
ApertoThumbnailMedia,
|
|
1151
|
-
{
|
|
1152
|
-
item: media,
|
|
1153
|
-
renderImage,
|
|
1154
|
-
renderVideo
|
|
1155
|
-
}
|
|
1156
|
-
)
|
|
1157
|
-
}
|
|
1158
|
-
),
|
|
989
|
+
/* @__PURE__ */ jsx13(ApertoTrigger, { "aria-label": `Open ${label}`, className: classNames?.thumbnail, children: /* @__PURE__ */ jsx13(ApertoThumbnailMedia, { item: media, renderImage, renderVideo }) }),
|
|
1159
990
|
/* @__PURE__ */ jsxs2(ApertoPortal, { children: [
|
|
1160
991
|
/* @__PURE__ */ jsx13(ApertoOverlay, { className: classNames?.overlay }),
|
|
1161
|
-
/* @__PURE__ */ jsxs2(
|
|
1162
|
-
|
|
1163
|
-
{
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
/* @__PURE__ */ jsx13(
|
|
1168
|
-
ApertoExpandedMedia,
|
|
1169
|
-
{
|
|
1170
|
-
item: media,
|
|
1171
|
-
renderImage,
|
|
1172
|
-
renderVideo
|
|
1173
|
-
}
|
|
1174
|
-
),
|
|
1175
|
-
/* @__PURE__ */ jsx13(ApertoTitle, { children: title }),
|
|
1176
|
-
media.description ? /* @__PURE__ */ jsx13(ApertoDescription, { children: media.description }) : null,
|
|
1177
|
-
/* @__PURE__ */ jsx13(
|
|
1178
|
-
ApertoClose,
|
|
1179
|
-
{
|
|
1180
|
-
"aria-label": "Close",
|
|
1181
|
-
className: classNames?.closeButton,
|
|
1182
|
-
type: "button"
|
|
1183
|
-
}
|
|
1184
|
-
)
|
|
1185
|
-
]
|
|
1186
|
-
}
|
|
1187
|
-
)
|
|
992
|
+
/* @__PURE__ */ jsxs2(ApertoContent, { className: classNames?.content, ...getDescriptionProps(media), children: [
|
|
993
|
+
/* @__PURE__ */ jsx13(ApertoExpandedMedia, { item: media, renderImage, renderVideo }),
|
|
994
|
+
/* @__PURE__ */ jsx13(ApertoTitle, { children: title }),
|
|
995
|
+
media.description ? /* @__PURE__ */ jsx13(ApertoDescription, { children: media.description }) : null,
|
|
996
|
+
/* @__PURE__ */ jsx13(ApertoClose, { "aria-label": "Close", className: classNames?.closeButton, type: "button" })
|
|
997
|
+
] })
|
|
1188
998
|
] })
|
|
1189
999
|
] });
|
|
1190
|
-
}
|
|
1000
|
+
};
|
|
1191
1001
|
|
|
1192
|
-
// src/Aperto/
|
|
1002
|
+
// src/Aperto/aperto-thumbnail.tsx
|
|
1193
1003
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1194
|
-
|
|
1195
|
-
children,
|
|
1196
|
-
className,
|
|
1197
|
-
index
|
|
1198
|
-
}) {
|
|
1004
|
+
var ApertoThumbnail = ({ children, className, index }) => {
|
|
1199
1005
|
const group = useApertoGroup();
|
|
1200
1006
|
const media = group.media[index];
|
|
1201
1007
|
if (!media) {
|
|
@@ -1220,7 +1026,7 @@ function ApertoThumbnail({
|
|
|
1220
1026
|
)
|
|
1221
1027
|
}
|
|
1222
1028
|
);
|
|
1223
|
-
}
|
|
1029
|
+
};
|
|
1224
1030
|
|
|
1225
1031
|
// src/index.ts
|
|
1226
1032
|
var ApertoPrimitive = {
|