@patternmode/aperto 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as react from 'react';
3
2
  import { ImgHTMLAttributes, ReactNode, VideoHTMLAttributes, ComponentPropsWithRef, Ref, CSSProperties, ComponentPropsWithoutRef } from 'react';
4
3
  import * as Dialog from '@radix-ui/react-dialog';
@@ -179,12 +178,12 @@ interface ApertoThumbnailProps {
179
178
  index: number;
180
179
  }
181
180
 
182
- declare const ApertoGroup: ({ children, classNames, dismissible, index: controlledIndex, initialIndex, media, motion: motionProp, navigationMotion, onIndexChange, renderImage, renderVideo, }: ApertoGroupProps) => react_jsx_runtime.JSX.Element;
181
+ declare const ApertoGroup: ({ children, classNames, dismissible, index, initialIndex, media, motion: motionProp, navigationMotion, onIndexChange, renderImage, renderVideo, }: ApertoGroupProps) => react.JSX.Element;
183
182
 
184
- declare const ApertoThumbnail: ({ children, className, index }: ApertoThumbnailProps) => react_jsx_runtime.JSX.Element | null;
183
+ declare const ApertoThumbnail: ({ children, className, index }: ApertoThumbnailProps) => react.JSX.Element | null;
185
184
 
186
185
  declare const ApertoClose: {
187
- ({ children, ref, ...props }: ComponentPropsWithRef<typeof Dialog.Close>): react_jsx_runtime.JSX.Element;
186
+ ({ children, ref, ...props }: ComponentPropsWithRef<typeof Dialog.Close>): react.JSX.Element;
188
187
  displayName: string;
189
188
  };
190
189
 
@@ -197,12 +196,12 @@ interface ApertoContentProps extends Omit<ComponentPropsWithRef<typeof Dialog.Co
197
196
  sharedLayoutId?: string | false;
198
197
  }
199
198
  declare const ApertoContent: {
200
- ({ children, className, motion: motionOverride, placement, ref, sharedLayoutId, style, ...props }: ApertoContentProps): react_jsx_runtime.JSX.Element;
199
+ ({ children, className, motion: motionOverride, placement, ref, sharedLayoutId, style, ...props }: ApertoContentProps): react.JSX.Element;
201
200
  displayName: string;
202
201
  };
203
202
 
204
203
  declare const ApertoDescription: {
205
- ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Description>): react_jsx_runtime.JSX.Element;
204
+ ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Description>): react.JSX.Element;
206
205
  displayName: string;
207
206
  };
208
207
 
@@ -214,7 +213,7 @@ interface ApertoOverlayProps {
214
213
  style?: CSSProperties;
215
214
  }
216
215
  declare const ApertoOverlay: {
217
- ({ className, fadeOut, ref, style }: ApertoOverlayProps): react_jsx_runtime.JSX.Element;
216
+ ({ className, fadeOut, ref, style }: ApertoOverlayProps): react.JSX.Element;
218
217
  displayName: string;
219
218
  };
220
219
 
@@ -223,7 +222,7 @@ interface ApertoPortalProps {
223
222
  /** Container element for the portal (default: document.body) */
224
223
  container?: HTMLElement;
225
224
  }
226
- declare const ApertoPortal: ({ children, container }: ApertoPortalProps) => react_jsx_runtime.JSX.Element;
225
+ declare const ApertoPortal: ({ children, container }: ApertoPortalProps) => react.JSX.Element;
227
226
 
228
227
  interface ApertoRootProps extends Omit<ComponentPropsWithoutRef<typeof Dialog.Root>, "open" | "onOpenChange"> {
229
228
  children: ReactNode;
@@ -240,10 +239,10 @@ interface ApertoRootProps extends Omit<ComponentPropsWithoutRef<typeof Dialog.Ro
240
239
  /** Force reduced motion regardless of system preference */
241
240
  reduceMotion?: boolean;
242
241
  }
243
- declare const ApertoRoot: ({ children, dismissible, layoutId: layoutIdProp, motion: motionProp, open: controlledOpen, onOpenChange: controlledOnOpenChange, reduceMotion: reduceMotionProp, ...dialogProps }: ApertoRootProps) => react_jsx_runtime.JSX.Element;
242
+ declare const ApertoRoot: ({ children, defaultOpen, dismissible, layoutId: layoutIdProp, motion: motionProp, open: controlledOpen, onOpenChange: controlledOnOpenChange, reduceMotion: reduceMotionProp, ...dialogProps }: ApertoRootProps) => react.JSX.Element;
244
243
 
245
244
  declare const ApertoTitle: {
246
- ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Title>): react_jsx_runtime.JSX.Element;
245
+ ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Title>): react.JSX.Element;
247
246
  displayName: string;
248
247
  };
249
248
 
@@ -256,7 +255,7 @@ interface ApertoTriggerProps extends ComponentPropsWithRef<typeof Dialog.Trigger
256
255
  sharedLayoutId?: string | false;
257
256
  }
258
257
  declare const ApertoTrigger: {
259
- ({ active, children, motion: motionOverride, ref, sharedLayoutId, ...props }: ApertoTriggerProps): react_jsx_runtime.JSX.Element;
258
+ ({ active, children, motion: motionOverride, ref, sharedLayoutId, ...props }: ApertoTriggerProps): react.JSX.Element;
260
259
  displayName: string;
261
260
  };
262
261
 
@@ -264,8 +263,8 @@ declare const ApertoTrigger: {
264
263
  * Motion presets — each bundles transition timing AND drag physics
265
264
  * so "snappy" feels snappy everywhere: open, close, and drag.
266
265
  *
267
- * Curves and springs are local copies of the Howells motion tokens so the
268
- * published package has no private workspace runtime dependencies.
266
+ * Curves and springs come from the shared @howells/motion tokens so motion
267
+ * feel stays consistent across the catalog.
269
268
  */
270
269
  declare const PRESETS: Record<MotionPresetName, MotionPreset>;
271
270
  type ComponentType = "trigger" | "content" | "backdrop";
@@ -282,64 +281,64 @@ declare const resolvePreset: (componentType: ComponentType, componentMotion: Mot
282
281
  /** Lower-level compound component namespace for advanced composition. */
283
282
  declare const ApertoPrimitive: {
284
283
  Close: {
285
- ({ children, ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>>): react_jsx_runtime.JSX.Element;
284
+ ({ children, ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>>): react.JSX.Element;
286
285
  displayName: string;
287
286
  };
288
287
  Content: {
289
- ({ children, className, motion: motionOverride, placement, ref, sharedLayoutId, style, ...props }: ApertoContentProps): react_jsx_runtime.JSX.Element;
288
+ ({ children, className, motion: motionOverride, placement, ref, sharedLayoutId, style, ...props }: ApertoContentProps): react.JSX.Element;
290
289
  displayName: string;
291
290
  };
292
291
  Description: {
293
- ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>>>): react_jsx_runtime.JSX.Element;
292
+ ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>>>): react.JSX.Element;
294
293
  displayName: string;
295
294
  };
296
295
  Overlay: {
297
- ({ className, fadeOut, ref, style }: ApertoOverlayProps): react_jsx_runtime.JSX.Element;
296
+ ({ className, fadeOut, ref, style }: ApertoOverlayProps): react.JSX.Element;
298
297
  displayName: string;
299
298
  };
300
- Portal: ({ children, container }: ApertoPortalProps) => react_jsx_runtime.JSX.Element;
301
- Root: ({ children, dismissible, layoutId: layoutIdProp, motion: motionProp, open: controlledOpen, onOpenChange: controlledOnOpenChange, reduceMotion: reduceMotionProp, ...dialogProps }: ApertoRootProps) => react_jsx_runtime.JSX.Element;
299
+ Portal: ({ children, container }: ApertoPortalProps) => react.JSX.Element;
300
+ Root: ({ children, defaultOpen, dismissible, layoutId: layoutIdProp, motion: motionProp, open: controlledOpen, onOpenChange: controlledOnOpenChange, reduceMotion: reduceMotionProp, ...dialogProps }: ApertoRootProps) => react.JSX.Element;
302
301
  Title: {
303
- ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>>>): react_jsx_runtime.JSX.Element;
302
+ ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>>>): react.JSX.Element;
304
303
  displayName: string;
305
304
  };
306
305
  Trigger: {
307
- ({ active, children, motion: motionOverride, ref, sharedLayoutId, ...props }: ApertoTriggerProps): react_jsx_runtime.JSX.Element;
306
+ ({ active, children, motion: motionOverride, ref, sharedLayoutId, ...props }: ApertoTriggerProps): react.JSX.Element;
308
307
  displayName: string;
309
308
  };
310
309
  };
311
310
  /** Primary media-first component namespace. */
312
- declare const Aperto: (({ classNames, dismissible, media, renderImage, renderVideo, }: ApertoProps) => react_jsx_runtime.JSX.Element) & {
313
- Group: ({ children, classNames, dismissible, index: controlledIndex, initialIndex, media, motion: motionProp, navigationMotion, onIndexChange, renderImage, renderVideo, }: ApertoGroupProps) => react_jsx_runtime.JSX.Element;
311
+ declare const Aperto: (({ classNames, dismissible, media, renderImage, renderVideo, }: ApertoProps) => react.JSX.Element) & {
312
+ Group: ({ children, classNames, dismissible, index, initialIndex, media, motion: motionProp, navigationMotion, onIndexChange, renderImage, renderVideo, }: ApertoGroupProps) => react.JSX.Element;
314
313
  Primitive: {
315
314
  Close: {
316
- ({ children, ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>>): react_jsx_runtime.JSX.Element;
315
+ ({ children, ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>>): react.JSX.Element;
317
316
  displayName: string;
318
317
  };
319
318
  Content: {
320
- ({ children, className, motion: motionOverride, placement, ref, sharedLayoutId, style, ...props }: ApertoContentProps): react_jsx_runtime.JSX.Element;
319
+ ({ children, className, motion: motionOverride, placement, ref, sharedLayoutId, style, ...props }: ApertoContentProps): react.JSX.Element;
321
320
  displayName: string;
322
321
  };
323
322
  Description: {
324
- ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>>>): react_jsx_runtime.JSX.Element;
323
+ ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>>>): react.JSX.Element;
325
324
  displayName: string;
326
325
  };
327
326
  Overlay: {
328
- ({ className, fadeOut, ref, style }: ApertoOverlayProps): react_jsx_runtime.JSX.Element;
327
+ ({ className, fadeOut, ref, style }: ApertoOverlayProps): react.JSX.Element;
329
328
  displayName: string;
330
329
  };
331
- Portal: ({ children, container }: ApertoPortalProps) => react_jsx_runtime.JSX.Element;
332
- Root: ({ children, dismissible, layoutId: layoutIdProp, motion: motionProp, open: controlledOpen, onOpenChange: controlledOnOpenChange, reduceMotion: reduceMotionProp, ...dialogProps }: ApertoRootProps) => react_jsx_runtime.JSX.Element;
330
+ Portal: ({ children, container }: ApertoPortalProps) => react.JSX.Element;
331
+ Root: ({ children, defaultOpen, dismissible, layoutId: layoutIdProp, motion: motionProp, open: controlledOpen, onOpenChange: controlledOnOpenChange, reduceMotion: reduceMotionProp, ...dialogProps }: ApertoRootProps) => react.JSX.Element;
333
332
  Title: {
334
- ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>>>): react_jsx_runtime.JSX.Element;
333
+ ({ ref, ...props }: react.ComponentPropsWithRef<react.ForwardRefExoticComponent<Dialog.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>>>): react.JSX.Element;
335
334
  displayName: string;
336
335
  };
337
336
  Trigger: {
338
- ({ active, children, motion: motionOverride, ref, sharedLayoutId, ...props }: ApertoTriggerProps): react_jsx_runtime.JSX.Element;
337
+ ({ active, children, motion: motionOverride, ref, sharedLayoutId, ...props }: ApertoTriggerProps): react.JSX.Element;
339
338
  displayName: string;
340
339
  };
341
340
  };
342
- Thumbnail: ({ children, className, index }: ApertoThumbnailProps) => react_jsx_runtime.JSX.Element | null;
341
+ Thumbnail: ({ children, className, index }: ApertoThumbnailProps) => react.JSX.Element | null;
343
342
  };
344
343
 
345
344
  export { Aperto, type ApertoClassNames, ApertoClose, ApertoContent, type ApertoContentProps, ApertoDescription, ApertoGroup, type ApertoGroupProps, type ApertoImageItem, type ApertoMediaItem, ApertoOverlay, type ApertoOverlayProps, ApertoPortal, type ApertoPortalProps, ApertoPrimitive, type ApertoProps, ApertoRoot, type ApertoRootProps, ApertoThumbnail, type ApertoThumbnailProps, ApertoTitle, ApertoTrigger, type ApertoTriggerProps, type ApertoVideoItem, type DismissibleConfig, type DragSpringConfig, type MotionPreset, type MotionPresetName, type MotionProp, type MotionVariants, type NavigationMotionPresetName, PRESETS, type RenderImage, type RenderVideo, resolvePreset };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/Aperto/aperto-group.tsx
4
4
  import { ChevronLeft, ChevronRight, X } from "lucide-react";
5
- import { useId as useId2, useLayoutEffect, useReducer, useRef } from "react";
5
+ import { useId as useId2, useLayoutEffect, useReducer, useRef as useRef2 } from "react";
6
6
 
7
7
  // src/aperto-content.tsx
8
8
  import * as Dialog from "@radix-ui/react-dialog";
@@ -32,23 +32,8 @@ var OPACITY_OUTPUT = [1, 0.96];
32
32
  var DEFAULT_DISTANCE_THRESHOLD = 100;
33
33
  var DEFAULT_VELOCITY_THRESHOLD = 500;
34
34
 
35
- // src/motion-tokens.ts
36
- var durations = {
37
- moderate: 0.4,
38
- snappy: 0.22
39
- };
40
- var easings = {
41
- customGentle: [0.25, 0.1, 0.12, 1],
42
- snappy: [0.22, 1, 0.36, 1]
43
- };
44
- var springs = {
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 }
49
- };
50
-
51
35
  // src/presets.ts
36
+ import { durations, easings, springs } from "@howells/motion";
52
37
  var PRESETS = {
53
38
  bouncy: {
54
39
  drag: {
@@ -183,7 +168,7 @@ var ApertoContent = ({
183
168
  dragElastic: 0,
184
169
  dragMomentum: false,
185
170
  dragSnapToOrigin: true,
186
- layout: contentLayoutId ? true : void 0,
171
+ layout: contentLayoutId === void 0 || contentLayoutId === "" ? void 0 : true,
187
172
  layoutId: contentLayoutId,
188
173
  onDrag: isDismissible ? handleDrag : void 0,
189
174
  onDragEnd: isDismissible ? handleDragEnd : void 0,
@@ -216,10 +201,11 @@ var useApertoGroup = () => {
216
201
  // src/aperto-overlay.tsx
217
202
  import * as Dialog3 from "@radix-ui/react-dialog";
218
203
  import { m as m2 } from "motion/react";
204
+ import { easings as easings2 } from "@howells/motion";
219
205
  import { jsx as jsx3 } from "react/jsx-runtime";
220
206
  var OVERLAY_TRANSITION = {
221
207
  duration: 0.3,
222
- ease: easings.customGentle
208
+ ease: easings2.customGentle
223
209
  };
224
210
  var OVERLAY_TRANSITION_REDUCED = {
225
211
  duration: 0.01,
@@ -231,7 +217,7 @@ var ApertoOverlay = ({ className, fadeOut, ref, style }) => {
231
217
  return /* @__PURE__ */ jsx3(Dialog3.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsx3(
232
218
  m2.div,
233
219
  {
234
- animate: { opacity: fadeOut ? 0 : 1 },
220
+ animate: { opacity: fadeOut === true ? 0 : 1 },
235
221
  className,
236
222
  "data-slot": "aperto-overlay",
237
223
  exit: { opacity: 0 },
@@ -260,6 +246,7 @@ import { useId, useState as useState2 } from "react";
260
246
  import { jsx as jsx5 } from "react/jsx-runtime";
261
247
  var ApertoRoot = ({
262
248
  children,
249
+ defaultOpen,
263
250
  dismissible = true,
264
251
  layoutId: layoutIdProp,
265
252
  motion: motionProp = "smooth",
@@ -272,7 +259,7 @@ var ApertoRoot = ({
272
259
  const layoutId = layoutIdProp ?? `aperto-${generatedId}`;
273
260
  const systemReducedMotion = useReducedMotion() ?? false;
274
261
  const shouldReduce = reduceMotionProp ?? systemReducedMotion;
275
- const [internalOpen, setInternalOpen] = useState2(false);
262
+ const [internalOpen, setInternalOpen] = useState2(defaultOpen ?? false);
276
263
  const isControlled = controlledOpen !== void 0;
277
264
  const open = isControlled ? controlledOpen : internalOpen;
278
265
  const onOpenChange = (nextOpen) => {
@@ -410,7 +397,7 @@ var ApertoTransitionMedia = ({
410
397
  // src/media-utils.ts
411
398
  var getMediaLabel = (item) => item.title ?? item.alt ?? "media";
412
399
  var getMediaKey = (item, index) => item.id ?? `${item.type}:${item.src}:${index}`;
413
- var getDescriptionProps = (item) => item.description ? {} : { "aria-describedby": void 0 };
400
+ var getDescriptionProps = (item) => item.description === void 0 || item.description === "" ? { "aria-describedby": void 0 } : {};
414
401
 
415
402
  // src/expanded-media-stage.tsx
416
403
  import { jsx as jsx8 } from "react/jsx-runtime";
@@ -515,7 +502,7 @@ var ApertoExpandedMediaStage = ({
515
502
 
516
503
  // src/media-transition.tsx
517
504
  import { m as m4 } from "motion/react";
518
- import { useEffect } from "react";
505
+ import { useEffect, useRef } from "react";
519
506
 
520
507
  // src/media-transition-utils.ts
521
508
  var rectFromElement = (element) => {
@@ -547,14 +534,24 @@ var ApertoMediaTransitionClone = ({
547
534
  transition
548
535
  }) => {
549
536
  const ctx = useApertoContext();
537
+ const onCompleteRef = useRef(onComplete);
550
538
  useEffect(() => {
551
- if (!transition?.to) {
552
- return;
539
+ onCompleteRef.current = onComplete;
540
+ });
541
+ useEffect(() => {
542
+ let timer;
543
+ if (transition?.to !== void 0) {
544
+ timer = setTimeout(() => {
545
+ onCompleteRef.current();
546
+ }, transitionDurationMs(ctx.preset.transition));
553
547
  }
554
- const timer = setTimeout(onComplete, transitionDurationMs(ctx.preset.transition));
555
- return () => clearTimeout(timer);
556
- }, [ctx.preset.transition, onComplete, transition]);
557
- if (!transition?.to) {
548
+ return () => {
549
+ if (timer !== void 0) {
550
+ clearTimeout(timer);
551
+ }
552
+ };
553
+ }, [ctx.preset.transition, transition]);
554
+ if (transition?.to === void 0) {
558
555
  return null;
559
556
  }
560
557
  return /* @__PURE__ */ jsx9(
@@ -569,7 +566,7 @@ var ApertoMediaTransitionClone = ({
569
566
  overflow: "hidden",
570
567
  pointerEvents: "none",
571
568
  position: "fixed",
572
- zIndex: 30
569
+ zIndex: "var(--patternmode-aperto-clone-z, 1002)"
573
570
  },
574
571
  transition: ctx.preset.transition,
575
572
  children: /* @__PURE__ */ jsx9(
@@ -591,7 +588,8 @@ var getInitialGroupState = (initialIndex) => ({
591
588
  layoutSourceIndex: initialIndex,
592
589
  mediaTransition: null,
593
590
  navigationDirection: 0,
594
- open: false
591
+ open: false,
592
+ openerIndex: null
595
593
  });
596
594
  var apertoGroupReducer = (state, action) => {
597
595
  switch (action.type) {
@@ -631,14 +629,15 @@ var apertoGroupReducer = (state, action) => {
631
629
  layoutSourceIndex: action.index,
632
630
  mediaTransition: action.transition,
633
631
  navigationDirection: 0,
634
- open: true
632
+ open: true,
633
+ openerIndex: action.index
635
634
  };
636
635
  }
637
636
  case "set-index": {
638
637
  return { ...state, internalIndex: action.index };
639
638
  }
640
639
  case "set-open": {
641
- return action.open ? { ...state, closing: false, open: true } : { ...state, open: false };
640
+ return action.open ? { ...state, closing: false, open: true, openerIndex: state.internalIndex } : { ...state, open: false };
642
641
  }
643
642
  case "start-close": {
644
643
  return {
@@ -655,7 +654,7 @@ var apertoGroupReducer = (state, action) => {
655
654
 
656
655
  // src/Aperto/aperto-keyboard.ts
657
656
  var shouldIgnoreKeyboardNavigationTarget = (target) => {
658
- if (!(target instanceof Element)) {
657
+ if (!(target instanceof HTMLElement)) {
659
658
  return false;
660
659
  }
661
660
  return target.isContentEditable || Boolean(
@@ -701,67 +700,150 @@ var ApertoMediaNavigationButtons = ({
701
700
  )
702
701
  ] });
703
702
  };
704
- var ApertoGroup = ({
705
- children,
703
+ var useThumbnailMap = () => {
704
+ const thumbnailRefs = useRef2(null);
705
+ thumbnailRefs.current ??= /* @__PURE__ */ new Map();
706
+ return thumbnailRefs.current;
707
+ };
708
+ var getExpandedMediaStyle = (activeMedia) => {
709
+ if (activeMedia === void 0 || activeMedia.width === void 0 || activeMedia.height === void 0) {
710
+ return void 0;
711
+ }
712
+ return {
713
+ "--aperto-expanded-aspect-ratio": `${activeMedia.width} / ${activeMedia.height}`,
714
+ "--aperto-expanded-aspect-ratio-height": activeMedia.height,
715
+ "--aperto-expanded-aspect-ratio-width": activeMedia.width
716
+ };
717
+ };
718
+ var ApertoGroupPortal = ({
719
+ activeMedia,
706
720
  classNames,
707
- dismissible,
708
- index: controlledIndex,
709
- initialIndex = 0,
710
- media,
711
- motion: motionProp,
712
- navigationMotion = "glide",
713
- onIndexChange,
721
+ expandedMediaStyle,
722
+ handleCloseAutoFocus,
723
+ handleContentKeyDown,
724
+ handleMediaTransitionComplete,
725
+ hasNavigation,
726
+ index,
727
+ mediaLength,
728
+ navigationDirection,
729
+ navigationMotion,
714
730
  renderImage,
715
- renderVideo
731
+ renderVideo,
732
+ setExpandedMediaNode,
733
+ startClose,
734
+ transition,
735
+ goToNext,
736
+ goToPrevious
716
737
  }) => {
717
- const generatedId = useId2();
718
- const [state, dispatch] = useReducer(apertoGroupReducer, initialIndex, getInitialGroupState);
719
- const isControlled = controlledIndex !== void 0;
720
- const index = isControlled ? controlledIndex : state.internalIndex;
721
- const activeMedia = media[index] ?? media[0];
722
- const expandedMediaRef = useRef(null);
723
- const thumbnailRefs = useRef(null);
724
- if (thumbnailRefs.current === null) {
725
- thumbnailRefs.current = /* @__PURE__ */ new Map();
738
+ if (activeMedia === void 0) {
739
+ return null;
726
740
  }
727
- const thumbnailMap = thumbnailRefs.current;
728
- const sharedLayoutIdForIndex = (nextIndex) => `aperto-group-${generatedId}-${nextIndex}-shared`;
729
- const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);
741
+ return /* @__PURE__ */ jsxs(ApertoPortal, { children: [
742
+ /* @__PURE__ */ jsx10(ApertoOverlay, { className: classNames?.overlay, fadeOut: transition?.phase === "closing" }),
743
+ /* @__PURE__ */ jsxs(
744
+ ApertoContent,
745
+ {
746
+ className: classNames?.content,
747
+ "data-aperto-transition": transition?.phase,
748
+ onCloseAutoFocus: handleCloseAutoFocus,
749
+ onKeyDown: handleContentKeyDown,
750
+ sharedLayoutId: false,
751
+ ...getDescriptionProps(activeMedia),
752
+ children: [
753
+ /* @__PURE__ */ jsxs("div", { "data-slot": "aperto-media", ref: setExpandedMediaNode, style: expandedMediaStyle, children: [
754
+ /* @__PURE__ */ jsx10(
755
+ ApertoExpandedMediaStage,
756
+ {
757
+ direction: navigationDirection,
758
+ index,
759
+ item: activeMedia,
760
+ navigationMotion,
761
+ renderImage,
762
+ renderVideo
763
+ }
764
+ ),
765
+ /* @__PURE__ */ jsx10(
766
+ ApertoMediaNavigationButtons,
767
+ {
768
+ classNames,
769
+ enabled: hasNavigation,
770
+ onNext: goToNext,
771
+ onPrevious: goToPrevious
772
+ }
773
+ )
774
+ ] }),
775
+ /* @__PURE__ */ jsx10(ApertoTitle, { children: activeMedia.title ?? getMediaLabel(activeMedia) }),
776
+ activeMedia.description === void 0 || activeMedia.description === "" ? null : /* @__PURE__ */ jsx10(ApertoDescription, { children: activeMedia.description }),
777
+ hasNavigation ? /* @__PURE__ */ jsxs("div", { className: classNames?.counter, "data-slot": "aperto-counter", children: [
778
+ index + 1,
779
+ " / ",
780
+ mediaLength
781
+ ] }) : null,
782
+ /* @__PURE__ */ jsx10(
783
+ "button",
784
+ {
785
+ "aria-label": "Close",
786
+ className: classNames?.closeButton,
787
+ "data-slot": "aperto-close",
788
+ onClick: startClose,
789
+ type: "button",
790
+ children: /* @__PURE__ */ jsx10(X, { "aria-hidden": "true", size: 17, strokeWidth: 2 })
791
+ }
792
+ )
793
+ ]
794
+ }
795
+ ),
796
+ /* @__PURE__ */ jsx10(
797
+ ApertoMediaTransitionClone,
798
+ {
799
+ onComplete: handleMediaTransitionComplete,
800
+ renderImage,
801
+ renderVideo,
802
+ transition
803
+ }
804
+ )
805
+ ] });
806
+ };
807
+ var useApertoMediaLifecycle = ({
808
+ activeMedia,
809
+ dispatch,
810
+ index,
811
+ media,
812
+ onIndexChange,
813
+ state
814
+ }) => {
815
+ const expandedMediaRef = useRef2(null);
816
+ const thumbnailMap = useThumbnailMap();
730
817
  const setExpandedMediaNode = (node) => {
731
818
  expandedMediaRef.current = node;
732
- if (node) {
733
- const targetRect = rectFromElement(node);
734
- if (targetRect) {
735
- dispatch({ rect: targetRect, type: "complete-opening-target" });
736
- }
819
+ if (node === null) {
820
+ return;
821
+ }
822
+ const targetRect = rectFromElement(node);
823
+ if (targetRect !== null) {
824
+ dispatch({ rect: targetRect, type: "complete-opening-target" });
737
825
  }
738
826
  };
739
827
  const registerThumbnail = (thumbIndex, node) => {
740
- if (node) {
828
+ if (node !== null) {
741
829
  thumbnailMap.set(thumbIndex, node);
742
830
  return;
743
831
  }
744
832
  thumbnailMap.delete(thumbIndex);
745
833
  };
746
834
  useLayoutEffect(() => {
747
- if (state.mediaTransition?.phase !== "opening" || state.mediaTransition.to || !expandedMediaRef.current) {
835
+ if (state.mediaTransition?.phase !== "opening" || state.mediaTransition.to !== void 0 || expandedMediaRef.current === null) {
748
836
  return;
749
837
  }
750
838
  const targetRect = rectFromElement(expandedMediaRef.current);
751
- if (targetRect) {
839
+ if (targetRect !== null) {
752
840
  dispatch({ rect: targetRect, type: "complete-opening-target" });
753
841
  }
754
- }, [state.mediaTransition]);
755
- const setIndex = (nextIndex) => {
756
- if (!isControlled) {
757
- dispatch({ index: nextIndex, type: "set-index" });
758
- }
759
- onIndexChange?.(nextIndex);
760
- };
842
+ }, [dispatch, state.mediaTransition]);
761
843
  const openAtIndex = (thumbIndex) => {
762
844
  const sourceRect = rectFromElement(thumbnailMap.get(thumbIndex) ?? null);
763
- const item = media[thumbIndex];
764
- const transition = sourceRect && item ? { from: sourceRect, item, phase: "opening" } : null;
845
+ const item = media[thumbIndex] ?? null;
846
+ const transition = sourceRect === null || item === null ? null : { from: sourceRect, item, phase: "opening" };
765
847
  dispatch({ index: thumbIndex, transition, type: "open-at-index" });
766
848
  onIndexChange?.(thumbIndex);
767
849
  };
@@ -771,23 +853,52 @@ var ApertoGroup = ({
771
853
  }
772
854
  const sourceRect = rectFromElement(expandedMediaRef.current);
773
855
  const targetRect = rectFromElement(thumbnailMap.get(index) ?? null);
774
- if (!activeMedia || !sourceRect || !targetRect) {
856
+ if (activeMedia === void 0 || sourceRect === null || targetRect === null) {
775
857
  dispatch({ type: "close-without-transition" });
776
858
  return;
777
859
  }
778
860
  dispatch({
779
- transition: {
780
- from: sourceRect,
781
- item: activeMedia,
782
- phase: "closing",
783
- to: targetRect
784
- },
861
+ transition: { from: sourceRect, item: activeMedia, phase: "closing", to: targetRect },
785
862
  type: "start-close"
786
863
  });
787
864
  };
788
865
  const handleCloseAutoFocus = (event) => {
789
866
  event.preventDefault();
790
- thumbnailMap.get(index)?.focus({ preventScroll: true });
867
+ const openerThumbnail = state.openerIndex === null ? void 0 : thumbnailMap.get(state.openerIndex);
868
+ const target = openerThumbnail ?? thumbnailMap.get(index);
869
+ target?.focus({ preventScroll: true });
870
+ };
871
+ return { handleCloseAutoFocus, openAtIndex, registerThumbnail, setExpandedMediaNode, startClose };
872
+ };
873
+ var useApertoGroupController = ({
874
+ classNames,
875
+ index: controlledIndex,
876
+ initialIndex = 0,
877
+ media,
878
+ onIndexChange,
879
+ renderImage,
880
+ renderVideo
881
+ }) => {
882
+ const generatedId = useId2();
883
+ const [state, dispatch] = useReducer(apertoGroupReducer, initialIndex, getInitialGroupState);
884
+ const isControlled = controlledIndex !== void 0;
885
+ const index = isControlled ? controlledIndex : state.internalIndex;
886
+ const activeMedia = media[index] ?? media[0];
887
+ const lifecycle = useApertoMediaLifecycle({
888
+ activeMedia,
889
+ dispatch,
890
+ index,
891
+ media,
892
+ onIndexChange,
893
+ state
894
+ });
895
+ const sharedLayoutIdForIndex = (nextIndex) => `aperto-group-${generatedId}-${nextIndex}-shared`;
896
+ const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);
897
+ const setIndex = (nextIndex) => {
898
+ if (!isControlled) {
899
+ dispatch({ index: nextIndex, type: "set-index" });
900
+ }
901
+ onIndexChange?.(nextIndex);
791
902
  };
792
903
  const handleMediaTransitionComplete = () => {
793
904
  dispatch({ type: "finish-transition" });
@@ -797,15 +908,15 @@ var ApertoGroup = ({
797
908
  dispatch({ open: true, type: "set-open" });
798
909
  return;
799
910
  }
800
- startClose();
911
+ lifecycle.startClose();
801
912
  };
802
913
  const value = {
803
914
  classNames,
804
915
  index,
805
916
  media,
806
917
  open: state.open,
807
- openAtIndex,
808
- registerThumbnail,
918
+ openAtIndex: lifecycle.openAtIndex,
919
+ registerThumbnail: lifecycle.registerThumbnail,
809
920
  renderImage,
810
921
  renderVideo,
811
922
  setIndex,
@@ -836,90 +947,78 @@ var ApertoGroup = ({
836
947
  goToNext();
837
948
  }
838
949
  };
839
- const expandedMediaStyle = (() => {
840
- if (!activeMedia?.width || !activeMedia.height) {
841
- return void 0;
842
- }
843
- return {
844
- "--aperto-expanded-aspect-ratio": `${activeMedia.width} / ${activeMedia.height}`,
845
- "--aperto-expanded-aspect-ratio-height": activeMedia.height,
846
- "--aperto-expanded-aspect-ratio-width": activeMedia.width
847
- };
848
- })();
849
- return /* @__PURE__ */ jsx10(ApertoGroupContext.Provider, { value, children: /* @__PURE__ */ jsxs(
950
+ const expandedMediaStyle = getExpandedMediaStyle(activeMedia);
951
+ return {
952
+ activeMedia,
953
+ expandedMediaStyle,
954
+ goToNext,
955
+ goToPrevious,
956
+ handleCloseAutoFocus: lifecycle.handleCloseAutoFocus,
957
+ handleContentKeyDown,
958
+ handleMediaTransitionComplete,
959
+ handleOpenChange,
960
+ hasNavigation,
961
+ index,
962
+ setExpandedMediaNode: lifecycle.setExpandedMediaNode,
963
+ startClose: lifecycle.startClose,
964
+ state,
965
+ value
966
+ };
967
+ };
968
+ var ApertoGroup = ({
969
+ children,
970
+ classNames,
971
+ dismissible,
972
+ index,
973
+ initialIndex,
974
+ media,
975
+ motion: motionProp,
976
+ navigationMotion = "glide",
977
+ onIndexChange,
978
+ renderImage,
979
+ renderVideo
980
+ }) => {
981
+ const controller = useApertoGroupController({
982
+ classNames,
983
+ index,
984
+ initialIndex,
985
+ media,
986
+ onIndexChange,
987
+ renderImage,
988
+ renderVideo
989
+ });
990
+ return /* @__PURE__ */ jsx10(ApertoGroupContext.Provider, { value: controller.value, children: /* @__PURE__ */ jsxs(
850
991
  ApertoRoot,
851
992
  {
852
993
  dismissible,
853
994
  motion: motionProp,
854
- onOpenChange: handleOpenChange,
855
- open: state.open,
995
+ onOpenChange: controller.handleOpenChange,
996
+ open: controller.state.open,
856
997
  children: [
857
998
  children,
858
- activeMedia ? /* @__PURE__ */ jsxs(ApertoPortal, { children: [
859
- /* @__PURE__ */ jsx10(ApertoOverlay, { className: classNames?.overlay, fadeOut: state.closing }),
860
- /* @__PURE__ */ jsxs(
861
- ApertoContent,
862
- {
863
- className: classNames?.content,
864
- "data-aperto-transition": state.mediaTransition?.phase,
865
- onCloseAutoFocus: handleCloseAutoFocus,
866
- onKeyDown: hasNavigation ? handleContentKeyDown : void 0,
867
- sharedLayoutId: false,
868
- ...getDescriptionProps(activeMedia),
869
- children: [
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
- ] }),
892
- /* @__PURE__ */ jsx10(ApertoTitle, { children: activeMedia.title ?? getMediaLabel(activeMedia) }),
893
- activeMedia.description ? /* @__PURE__ */ jsx10(ApertoDescription, { children: activeMedia.description }) : null,
894
- hasNavigation ? /* @__PURE__ */ jsxs("div", { className: classNames?.counter, "data-slot": "aperto-counter", children: [
895
- index + 1,
896
- " / ",
897
- media.length
898
- ] }) : null,
899
- /* @__PURE__ */ jsx10(
900
- "button",
901
- {
902
- "aria-label": "Close",
903
- className: classNames?.closeButton,
904
- "data-slot": "aperto-close",
905
- onClick: startClose,
906
- type: "button",
907
- children: /* @__PURE__ */ jsx10(X, { "aria-hidden": "true", size: 17, strokeWidth: 2 })
908
- }
909
- )
910
- ]
911
- }
912
- ),
913
- /* @__PURE__ */ jsx10(
914
- ApertoMediaTransitionClone,
915
- {
916
- onComplete: handleMediaTransitionComplete,
917
- renderImage,
918
- renderVideo,
919
- transition: state.mediaTransition
920
- }
921
- )
922
- ] }) : null
999
+ /* @__PURE__ */ jsx10(
1000
+ ApertoGroupPortal,
1001
+ {
1002
+ activeMedia: controller.activeMedia,
1003
+ classNames,
1004
+ expandedMediaStyle: controller.expandedMediaStyle,
1005
+ goToNext: controller.goToNext,
1006
+ goToPrevious: controller.goToPrevious,
1007
+ handleCloseAutoFocus: controller.handleCloseAutoFocus,
1008
+ handleContentKeyDown: controller.hasNavigation ? controller.handleContentKeyDown : void 0,
1009
+ handleMediaTransitionComplete: controller.handleMediaTransitionComplete,
1010
+ hasNavigation: controller.hasNavigation,
1011
+ index: controller.index,
1012
+ mediaLength: media.length,
1013
+ navigationDirection: controller.state.navigationDirection,
1014
+ navigationMotion,
1015
+ renderImage,
1016
+ renderVideo,
1017
+ setExpandedMediaNode: controller.setExpandedMediaNode,
1018
+ startClose: controller.startClose,
1019
+ transition: controller.state.mediaTransition
1020
+ }
1021
+ )
923
1022
  ]
924
1023
  }
925
1024
  ) });
@@ -992,7 +1091,7 @@ var ApertoSingle = ({
992
1091
  /* @__PURE__ */ jsxs2(ApertoContent, { className: classNames?.content, ...getDescriptionProps(media), children: [
993
1092
  /* @__PURE__ */ jsx13(ApertoExpandedMedia, { item: media, renderImage, renderVideo }),
994
1093
  /* @__PURE__ */ jsx13(ApertoTitle, { children: title }),
995
- media.description ? /* @__PURE__ */ jsx13(ApertoDescription, { children: media.description }) : null,
1094
+ media.description === void 0 || media.description === "" ? null : /* @__PURE__ */ jsx13(ApertoDescription, { children: media.description }),
996
1095
  /* @__PURE__ */ jsx13(ApertoClose, { "aria-label": "Close", className: classNames?.closeButton, type: "button" })
997
1096
  ] })
998
1097
  ] })
@@ -1013,8 +1112,12 @@ var ApertoThumbnail = ({ children, className, index }) => {
1013
1112
  active: group.index === index,
1014
1113
  "aria-label": `Open ${getMediaLabel(media)}`,
1015
1114
  className: className ?? group.classNames?.thumbnail,
1016
- onClick: () => group.openAtIndex(index),
1017
- ref: (node) => group.registerThumbnail(index, node),
1115
+ onClick: () => {
1116
+ group.openAtIndex(index);
1117
+ },
1118
+ ref: (node) => {
1119
+ group.registerThumbnail(index, node);
1120
+ },
1018
1121
  sharedLayoutId: false,
1019
1122
  children: children ?? /* @__PURE__ */ jsx14(
1020
1123
  ApertoThumbnailMedia,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Aperto/aperto-group.tsx","../src/aperto-content.tsx","../src/context.ts","../src/physics.ts","../src/motion-tokens.ts","../src/presets.ts","../src/aperto-description.tsx","../src/aperto-group-context.ts","../src/aperto-overlay.tsx","../src/aperto-portal.tsx","../src/aperto-root.tsx","../src/aperto-title.tsx","../src/expanded-media-stage.tsx","../src/media-rendering.tsx","../src/media-utils.ts","../src/media-transition.tsx","../src/media-transition-utils.ts","../src/Aperto/aperto-group-state.ts","../src/Aperto/aperto-keyboard.ts","../src/aperto-close.tsx","../src/aperto-trigger.tsx","../src/Aperto/aperto-single.tsx","../src/Aperto/aperto-thumbnail.tsx","../src/index.ts"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeft, ChevronRight, X } from \"lucide-react\";\nimport { useId, useLayoutEffect, useReducer, useRef } from \"react\";\nimport type { CSSProperties, KeyboardEvent } from \"react\";\n\nimport { ApertoContent } from \"../aperto-content\";\nimport { ApertoDescription } from \"../aperto-description\";\nimport { ApertoGroupContext } from \"../aperto-group-context\";\nimport { ApertoOverlay } from \"../aperto-overlay\";\nimport { ApertoPortal } from \"../aperto-portal\";\nimport { ApertoRoot } from \"../aperto-root\";\nimport { ApertoTitle } from \"../aperto-title\";\nimport { ApertoExpandedMediaStage } from \"../expanded-media-stage\";\nimport type { NavigationDirection } from \"../expanded-media-stage\";\nimport { ApertoMediaTransitionClone } from \"../media-transition\";\nimport { rectFromElement } from \"../media-transition-utils\";\nimport { getDescriptionProps, getMediaLabel } from \"../media-utils\";\nimport type { ApertoClassNames } from \"../types\";\nimport { apertoGroupReducer, getInitialGroupState } from \"./aperto-group-state\";\nimport { shouldIgnoreKeyboardNavigationTarget } from \"./aperto-keyboard\";\nimport type { ApertoGroupProps } from \"./aperto-types\";\n\nconst ApertoMediaNavigationButtons = ({\n classNames,\n enabled,\n onNext,\n onPrevious,\n}: {\n classNames: ApertoClassNames | undefined;\n enabled: boolean;\n onNext: () => void;\n onPrevious: () => void;\n}) => {\n if (!enabled) {\n return null;\n }\n\n return (\n <>\n <button\n aria-label=\"Previous media\"\n className={classNames?.previousButton}\n data-slot=\"aperto-previous-button\"\n onClick={onPrevious}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={18} strokeWidth={2} />\n </button>\n <button\n aria-label=\"Next media\"\n className={classNames?.nextButton}\n data-slot=\"aperto-next-button\"\n onClick={onNext}\n type=\"button\"\n >\n <ChevronRight aria-hidden=\"true\" size={18} strokeWidth={2} />\n </button>\n </>\n );\n};\n\nexport const ApertoGroup = ({\n children,\n classNames,\n dismissible,\n index: controlledIndex,\n initialIndex = 0,\n media,\n motion: motionProp,\n navigationMotion = \"glide\",\n onIndexChange,\n renderImage,\n renderVideo,\n}: ApertoGroupProps) => {\n const generatedId = useId();\n const [state, dispatch] = useReducer(apertoGroupReducer, initialIndex, getInitialGroupState);\n const isControlled = controlledIndex !== undefined;\n const index = isControlled ? controlledIndex : state.internalIndex;\n const activeMedia = media[index] ?? media[0];\n const expandedMediaRef = useRef<HTMLDivElement | null>(null);\n const thumbnailRefs = useRef<Map<number, HTMLButtonElement> | null>(null);\n if (thumbnailRefs.current === null) {\n thumbnailRefs.current = new Map();\n }\n const thumbnailMap = thumbnailRefs.current;\n const sharedLayoutIdForIndex = (nextIndex: number) =>\n `aperto-group-${generatedId}-${nextIndex}-shared`;\n const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);\n const setExpandedMediaNode = (node: HTMLDivElement | null) => {\n expandedMediaRef.current = node;\n if (node) {\n const targetRect = rectFromElement(node);\n if (targetRect) {\n dispatch({ rect: targetRect, type: \"complete-opening-target\" });\n }\n }\n };\n\n const registerThumbnail = (thumbIndex: number, node: HTMLButtonElement | null) => {\n if (node) {\n thumbnailMap.set(thumbIndex, node);\n return;\n }\n thumbnailMap.delete(thumbIndex);\n };\n\n useLayoutEffect(() => {\n if (\n state.mediaTransition?.phase !== \"opening\" ||\n state.mediaTransition.to ||\n !expandedMediaRef.current\n ) {\n return;\n }\n\n const targetRect = rectFromElement(expandedMediaRef.current);\n if (targetRect) {\n dispatch({ rect: targetRect, type: \"complete-opening-target\" });\n }\n }, [state.mediaTransition]);\n\n const setIndex = (nextIndex: number) => {\n if (!isControlled) {\n dispatch({ index: nextIndex, type: \"set-index\" });\n }\n onIndexChange?.(nextIndex);\n };\n\n const openAtIndex = (thumbIndex: number) => {\n const sourceRect = rectFromElement(thumbnailMap.get(thumbIndex) ?? null);\n const item = media[thumbIndex];\n const transition =\n sourceRect && item ? { from: sourceRect, item, phase: \"opening\" as const } : null;\n\n dispatch({ index: thumbIndex, transition, type: \"open-at-index\" });\n onIndexChange?.(thumbIndex);\n };\n\n const startClose = () => {\n if (!state.open || state.closing) {\n return;\n }\n\n const sourceRect = rectFromElement(expandedMediaRef.current);\n const targetRect = rectFromElement(thumbnailMap.get(index) ?? null);\n\n if (!activeMedia || !sourceRect || !targetRect) {\n dispatch({ type: \"close-without-transition\" });\n return;\n }\n\n dispatch({\n transition: {\n from: sourceRect,\n item: activeMedia,\n phase: \"closing\",\n to: targetRect,\n },\n type: \"start-close\",\n });\n };\n\n const handleCloseAutoFocus = (event: Event) => {\n event.preventDefault();\n thumbnailMap.get(index)?.focus({ preventScroll: true });\n };\n\n const handleMediaTransitionComplete = () => {\n dispatch({ type: \"finish-transition\" });\n };\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (nextOpen) {\n dispatch({ open: true, type: \"set-open\" });\n return;\n }\n\n startClose();\n };\n\n const value = {\n classNames,\n index,\n media,\n open: state.open,\n openAtIndex,\n registerThumbnail,\n renderImage,\n renderVideo,\n setIndex,\n sharedLayoutId,\n sharedLayoutIdForIndex,\n };\n const hasNavigation = media.length > 1;\n const navigateToIndex = (nextIndex: number, direction: NavigationDirection) => {\n dispatch({ direction, index: nextIndex, type: \"navigate\" });\n onIndexChange?.(nextIndex);\n };\n const goToPrevious = () => {\n navigateToIndex((index - 1 + media.length) % media.length, -1);\n };\n const goToNext = () => {\n navigateToIndex((index + 1) % media.length, 1);\n };\n const handleContentKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n shouldIgnoreKeyboardNavigationTarget(event.target)\n ) {\n return;\n }\n\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n goToPrevious();\n }\n\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n goToNext();\n }\n };\n const expandedMediaStyle = ((): CSSProperties | undefined => {\n if (!activeMedia?.width || !activeMedia.height) {\n return undefined;\n }\n\n return {\n \"--aperto-expanded-aspect-ratio\": `${activeMedia.width} / ${activeMedia.height}`,\n \"--aperto-expanded-aspect-ratio-height\": activeMedia.height,\n \"--aperto-expanded-aspect-ratio-width\": activeMedia.width,\n } as CSSProperties;\n })();\n\n return (\n <ApertoGroupContext.Provider value={value}>\n <ApertoRoot\n dismissible={dismissible}\n motion={motionProp}\n onOpenChange={handleOpenChange}\n open={state.open}\n >\n {children}\n {activeMedia ? (\n <ApertoPortal>\n <ApertoOverlay className={classNames?.overlay} fadeOut={state.closing} />\n <ApertoContent\n className={classNames?.content}\n data-aperto-transition={state.mediaTransition?.phase}\n onCloseAutoFocus={handleCloseAutoFocus}\n onKeyDown={hasNavigation ? handleContentKeyDown : undefined}\n sharedLayoutId={false}\n {...getDescriptionProps(activeMedia)}\n >\n <div data-slot=\"aperto-media\" ref={setExpandedMediaNode} style={expandedMediaStyle}>\n <ApertoExpandedMediaStage\n direction={state.navigationDirection}\n index={index}\n item={activeMedia}\n navigationMotion={navigationMotion}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n <ApertoMediaNavigationButtons\n classNames={classNames}\n enabled={hasNavigation}\n onNext={goToNext}\n onPrevious={goToPrevious}\n />\n </div>\n <ApertoTitle>{activeMedia.title ?? getMediaLabel(activeMedia)}</ApertoTitle>\n {activeMedia.description ? (\n <ApertoDescription>{activeMedia.description}</ApertoDescription>\n ) : null}\n {hasNavigation ? (\n <div className={classNames?.counter} data-slot=\"aperto-counter\">\n {index + 1} / {media.length}\n </div>\n ) : null}\n <button\n aria-label=\"Close\"\n className={classNames?.closeButton}\n data-slot=\"aperto-close\"\n onClick={startClose}\n type=\"button\"\n >\n <X aria-hidden=\"true\" size={17} strokeWidth={2} />\n </button>\n </ApertoContent>\n <ApertoMediaTransitionClone\n onComplete={handleMediaTransitionComplete}\n renderImage={renderImage}\n renderVideo={renderVideo}\n transition={state.mediaTransition}\n />\n </ApertoPortal>\n ) : null}\n </ApertoRoot>\n </ApertoGroupContext.Provider>\n );\n};\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { m, useMotionValue, useSpring, useTransform } from \"motion/react\";\nimport type { MotionStyle, PanInfo } from \"motion/react\";\nimport { useState } from \"react\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport {\n calculateResistance,\n DEFAULT_DISTANCE_THRESHOLD,\n DEFAULT_VELOCITY_THRESHOLD,\n OPACITY_INPUT,\n OPACITY_OUTPUT,\n SCALE_INPUT,\n SCALE_OUTPUT,\n} from \"./physics\";\nimport { getDragSpring, resolvePreset } from \"./presets\";\nimport type { DismissibleConfig, MotionPresetName } from \"./types\";\n\nexport interface ApertoContentProps extends Omit<\n ComponentPropsWithRef<typeof Dialog.Content>,\n \"asChild\" | \"forceMount\"\n> {\n /** Motion preset override for this content panel, independent of the root preset. */\n motion?: MotionPresetName;\n /** Built-in positioning strategy. Use \"none\" for custom primitive compositions. */\n placement?: \"center\" | \"none\";\n /** Internal shared layout ID override for grouped media. */\n sharedLayoutId?: string | false;\n}\n\nconst ApertoContent = ({\n children,\n className,\n motion: motionOverride,\n placement = \"center\",\n ref,\n sharedLayoutId,\n style,\n ...props\n}: ApertoContentProps) => {\n const ctx = useApertoContext();\n const [isDragging, setIsDragging] = useState(false);\n const resolved = resolvePreset(\n \"content\",\n motionOverride,\n ctx.presetName,\n ctx.variants,\n ctx.reduceMotion,\n );\n\n const contentLayoutId =\n sharedLayoutId === false ? undefined : (sharedLayoutId ?? `${ctx.layoutId}-shared`);\n\n const dragSpring = getDragSpring(resolved);\n const isDismissible = ctx.dismissible !== false;\n\n const dismissConfig: DismissibleConfig =\n typeof ctx.dismissible === \"object\" ? ctx.dismissible : {};\n const distanceThreshold = dismissConfig.threshold ?? DEFAULT_DISTANCE_THRESHOLD;\n const velocityThreshold = dismissConfig.velocity ?? DEFAULT_VELOCITY_THRESHOLD;\n\n const dragX = useMotionValue(0);\n const dragY = useMotionValue(0);\n const springX = useSpring(dragX, dragSpring);\n const springY = useSpring(dragY, dragSpring);\n\n const distance = useTransform(() => Math.hypot(springX.get(), springY.get()));\n const scaleMotion = useTransform(distance, SCALE_INPUT, SCALE_OUTPUT);\n const opacityMotion = useTransform(distance, OPACITY_INPUT, OPACITY_OUTPUT);\n const resistance = useTransform(distance, calculateResistance);\n const { onOpenChange } = ctx;\n\n const handleDrag = (_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n if (!isDragging) {\n setIsDragging(true);\n }\n const r = resistance.get();\n dragX.set(info.offset.x * r);\n dragY.set(info.offset.y * r);\n };\n\n const handleDragEnd = (_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n setIsDragging(false);\n const speed = Math.hypot(info.velocity.x, info.velocity.y);\n const dist = Math.hypot(info.offset.x, info.offset.y);\n\n if (speed > velocityThreshold || dist > distanceThreshold) {\n onOpenChange(false);\n return;\n }\n\n dragX.set(0);\n dragY.set(0);\n };\n\n const placementStyle =\n placement === \"center\"\n ? {\n left: \"50%\",\n top: \"50%\",\n translate: \"-50% -50%\",\n }\n : {};\n let cursor: MotionStyle[\"cursor\"];\n\n if (isDragging) {\n cursor = \"grabbing\";\n } else if (isDismissible) {\n cursor = \"grab\";\n }\n\n const motionStyle: MotionStyle = {\n cursor,\n opacity: opacityMotion,\n scale: scaleMotion,\n x: springX,\n y: springY,\n ...placementStyle,\n ...style,\n };\n\n return (\n <Dialog.Content asChild forceMount {...props}>\n <m.div\n className={className}\n data-slot=\"aperto-content\"\n drag={isDismissible}\n dragConstraints={{ bottom: 0, left: 0, right: 0, top: 0 }}\n dragElastic={0}\n dragMomentum={false}\n dragSnapToOrigin\n layout={contentLayoutId ? true : undefined}\n layoutId={contentLayoutId}\n onDrag={isDismissible ? handleDrag : undefined}\n onDragEnd={isDismissible ? handleDragEnd : undefined}\n ref={ref}\n style={motionStyle}\n transition={resolved.transition}\n >\n {children}\n </m.div>\n </Dialog.Content>\n );\n};\n\nApertoContent.displayName = \"ApertoContent\";\n\nexport { ApertoContent };\n","\"use client\";\n\nimport { createContext, use } from \"react\";\n\nimport type { ApertoContextValue } from \"./types\";\n\nexport const ApertoContext = createContext<ApertoContextValue | null>(null);\n\nexport const useApertoContext = (): ApertoContextValue => {\n const ctx = use(ApertoContext);\n if (!ctx) {\n throw new Error(\"Aperto components must be used within <Aperto.Root>\");\n }\n return ctx;\n};\n","/**\n * Drag physics utilities.\n *\n * The logarithmic resistance function creates a rubber-band feel:\n * initial movement is free, but gets progressively harder the further\n * you drag. Combined with spring-smoothed motion values, this produces\n * a natural, elastic gesture.\n */\n\nconst RESISTANCE_DIVISOR = 20;\nconst RESISTANCE_SCALE = 4;\nconst RESISTANCE_MIN = 0.1;\n\n/**\n * Logarithmic resistance — decelerates drag progressively.\n * Returns a multiplier between RESISTANCE_MIN and 1.0.\n *\n * At distance 0: returns 1.0 (full movement)\n * At distance 50: returns ~0.77\n * At distance 100: returns ~0.58\n * At distance 200: returns ~0.42\n */\nexport const calculateResistance = (distance: number): number =>\n Math.max(RESISTANCE_MIN, 1 - Math.log(distance / RESISTANCE_DIVISOR + 1) / RESISTANCE_SCALE);\n\n/** Scale mapping: distance → visual scale (1.0 → 0.95) */\nexport const SCALE_INPUT = [0, 50, 100];\nexport const SCALE_OUTPUT = [1, 0.98, 0.95];\n\n/** Opacity mapping: distance → visual opacity (1.0 → 0.96) */\nexport const OPACITY_INPUT = [0, 80];\nexport const OPACITY_OUTPUT = [1, 0.96];\n\n/** Default dismissal thresholds */\nexport const DEFAULT_DISTANCE_THRESHOLD = 100;\nexport const DEFAULT_VELOCITY_THRESHOLD = 500;\n","import type { Easing } from \"motion/react\";\n\nexport const durations = {\n moderate: 0.4,\n snappy: 0.22,\n} as const;\n\nexport const easings = {\n customGentle: [0.25, 0.1, 0.12, 1],\n snappy: [0.22, 1, 0.36, 1],\n} satisfies Record<string, Easing>;\n\nexport const springs = {\n bouncy: { damping: 12, mass: 1, stiffness: 260 },\n natural: { damping: 20, mass: 1, stiffness: 200 },\n snappy: { damping: 28, mass: 0.8, stiffness: 400 },\n stiff: { damping: 30, mass: 1, stiffness: 500 },\n} as const;\n","import { durations, easings, springs } from \"./motion-tokens\";\nimport type { DragSpringConfig, MotionPreset, MotionPresetName, MotionVariants } from \"./types\";\n\n/**\n * Motion presets — each bundles transition timing AND drag physics\n * so \"snappy\" feels snappy everywhere: open, close, and drag.\n *\n * Curves and springs are local copies of the Howells motion tokens so the\n * published package has no private workspace runtime dependencies.\n */\nexport const PRESETS: Record<MotionPresetName, MotionPreset> = {\n bouncy: {\n drag: {\n damping: springs.snappy.damping,\n restDelta: 0.01,\n stiffness: springs.snappy.stiffness,\n },\n transition: {\n damping: springs.bouncy.damping,\n mass: springs.bouncy.mass,\n stiffness: springs.bouncy.stiffness,\n type: \"spring\",\n },\n },\n reduced: {\n drag: { damping: 50, restDelta: 0.1, stiffness: 1000 },\n transition: { duration: 0.01, ease: \"linear\" },\n },\n smooth: {\n drag: {\n damping: springs.natural.damping,\n restDelta: 0.01,\n stiffness: springs.natural.stiffness,\n },\n transition: { duration: durations.moderate, ease: easings.customGentle },\n },\n snappy: {\n drag: {\n damping: springs.stiff.damping,\n restDelta: 0.01,\n stiffness: springs.stiff.stiffness,\n },\n transition: { duration: durations.snappy, ease: easings.snappy },\n },\n};\n\ntype ComponentType = \"trigger\" | \"content\" | \"backdrop\";\n\n/**\n * Three-level motion resolution:\n * 1. Component-level override (highest)\n * 2. Per-component variant from Root\n * 3. Global preset from Root (lowest)\n *\n * If `prefers-reduced-motion` is active, always returns \"reduced\".\n */\nexport const resolvePreset = (\n componentType: ComponentType,\n componentMotion: MotionPresetName | undefined,\n globalPreset: MotionPresetName,\n variants: MotionVariants | undefined,\n reduceMotion: boolean,\n): MotionPreset => {\n if (reduceMotion) {\n return PRESETS.reduced;\n }\n\n // 1. Component-level override\n if (componentMotion) {\n return PRESETS[componentMotion];\n }\n\n // 2. Per-component variant\n if (variants?.[componentType]) {\n return PRESETS[variants[componentType]];\n }\n\n // 3. Global preset\n return PRESETS[globalPreset];\n};\n\n/** Extract the drag spring config from a preset */\nexport const getDragSpring = (preset: MotionPreset): DragSpringConfig => preset.drag;\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst ApertoDescription = ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Description>) => (\n <Dialog.Description data-slot=\"aperto-description\" ref={ref} {...props} />\n);\n\nApertoDescription.displayName = \"ApertoDescription\";\n\nexport { ApertoDescription };\n","import { createContext, use } from \"react\";\n\nimport type { ApertoClassNames, ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nexport interface ApertoGroupContextValue {\n classNames?: ApertoClassNames;\n index: number;\n media: ApertoMediaItem[];\n open: boolean;\n openAtIndex: (index: number) => void;\n registerThumbnail: (index: number, node: HTMLButtonElement | null) => void;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n setIndex: (index: number) => void;\n sharedLayoutId: string;\n sharedLayoutIdForIndex: (index: number) => string;\n}\n\nexport const ApertoGroupContext = createContext<ApertoGroupContextValue | null>(null);\n\nexport const useApertoGroup = (): ApertoGroupContextValue => {\n const ctx = use(ApertoGroupContext);\n if (!ctx) {\n throw new Error(\"Aperto.Thumbnail must be used within <Aperto.Group>\");\n }\n return ctx;\n};\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { m } from \"motion/react\";\nimport type { Transition } from \"motion/react\";\nimport type { CSSProperties, Ref } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { easings } from \"./motion-tokens\";\n\nexport interface ApertoOverlayProps {\n className?: string;\n /** Internal flag used to fade the overlay during measured close transitions. */\n fadeOut?: boolean;\n ref?: Ref<HTMLDivElement>;\n style?: CSSProperties;\n}\n\n/** Overlay always fades gently regardless of the content's motion preset. */\nconst OVERLAY_TRANSITION: Transition = {\n duration: 0.3,\n ease: easings.customGentle,\n};\n\nconst OVERLAY_TRANSITION_REDUCED: Transition = {\n duration: 0.01,\n ease: \"linear\",\n};\n\nconst ApertoOverlay = ({ className, fadeOut, ref, style }: ApertoOverlayProps) => {\n const ctx = useApertoContext();\n const transition = ctx.reduceMotion ? OVERLAY_TRANSITION_REDUCED : OVERLAY_TRANSITION;\n\n return (\n <Dialog.Overlay asChild forceMount>\n <m.div\n animate={{ opacity: fadeOut ? 0 : 1 }}\n className={className}\n data-slot=\"aperto-overlay\"\n exit={{ opacity: 0 }}\n initial={{ opacity: 0 }}\n ref={ref}\n style={style}\n transition={transition}\n />\n </Dialog.Overlay>\n );\n};\n\nApertoOverlay.displayName = \"ApertoOverlay\";\n\nexport { ApertoOverlay };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { AnimatePresence } from \"motion/react\";\nimport type { ReactNode } from \"react\";\n\nimport { useApertoContext } from \"./context\";\n\nexport interface ApertoPortalProps {\n children: ReactNode;\n /** Container element for the portal (default: document.body) */\n container?: HTMLElement;\n}\n\nconst ApertoPortal = ({ children, container }: ApertoPortalProps) => {\n const { open } = useApertoContext();\n\n return (\n <AnimatePresence>\n {open && (\n <Dialog.Portal container={container} forceMount>\n {children}\n </Dialog.Portal>\n )}\n </AnimatePresence>\n );\n};\n\nexport { ApertoPortal };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { domMax, LayoutGroup, LazyMotion, useReducedMotion } from \"motion/react\";\nimport { useId, useState } from \"react\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\n\nimport { ApertoContext } from \"./context\";\nimport { PRESETS } from \"./presets\";\nimport type { DismissibleConfig, MotionPresetName, MotionVariants } from \"./types\";\n\nexport interface ApertoRootProps extends Omit<\n ComponentPropsWithoutRef<typeof Dialog.Root>,\n \"open\" | \"onOpenChange\"\n> {\n children: ReactNode;\n /** Whether dragging can dismiss the content (default: true) */\n dismissible?: boolean | DismissibleConfig;\n /** Layout ID for shared element transition (auto-generated if omitted) */\n layoutId?: string;\n /** Motion preset or per-component variants */\n motion?: MotionPresetName | MotionVariants;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Force reduced motion regardless of system preference */\n reduceMotion?: boolean;\n}\n\nconst ApertoRoot = ({\n children,\n dismissible = true,\n layoutId: layoutIdProp,\n motion: motionProp = \"smooth\",\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n reduceMotion: reduceMotionProp,\n ...dialogProps\n}: ApertoRootProps) => {\n const generatedId = useId();\n const layoutId = layoutIdProp ?? `aperto-${generatedId}`;\n const systemReducedMotion = useReducedMotion() ?? false;\n const shouldReduce = reduceMotionProp ?? systemReducedMotion;\n\n // Uncontrolled state fallback\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? controlledOpen : internalOpen;\n\n const onOpenChange = (nextOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(nextOpen);\n }\n controlledOnOpenChange?.(nextOpen);\n };\n\n // Resolve global preset name\n const globalPresetName: MotionPresetName = typeof motionProp === \"string\" ? motionProp : \"smooth\";\n const variants: MotionVariants | undefined =\n typeof motionProp === \"object\" ? motionProp : undefined;\n\n const presetName: MotionPresetName = shouldReduce ? \"reduced\" : globalPresetName;\n const preset = PRESETS[presetName];\n const contextValue = {\n dismissible,\n layoutId,\n onOpenChange,\n open,\n preset,\n presetName,\n reduceMotion: shouldReduce,\n variants,\n };\n\n return (\n <ApertoContext.Provider value={contextValue}>\n <Dialog.Root onOpenChange={onOpenChange} open={open} {...dialogProps}>\n <LazyMotion features={domMax}>\n <LayoutGroup id={layoutId}>{children}</LayoutGroup>\n </LazyMotion>\n </Dialog.Root>\n </ApertoContext.Provider>\n );\n};\n\nexport { ApertoRoot };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst ApertoTitle = ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Title>) => (\n <Dialog.Title data-slot=\"aperto-title\" ref={ref} {...props} />\n);\n\nApertoTitle.displayName = \"ApertoTitle\";\n\nexport { ApertoTitle };\n","import { AnimatePresence, m } from \"motion/react\";\nimport type { TargetAndTransition, Transition } from \"motion/react\";\n\nimport { useApertoContext } from \"./context\";\nimport { ApertoExpandedMedia } from \"./media-rendering\";\nimport { getMediaKey } from \"./media-utils\";\nimport type {\n ApertoMediaItem,\n NavigationMotionPresetName,\n RenderImage,\n RenderVideo,\n} from \"./types\";\n\nexport type NavigationDirection = -1 | 0 | 1;\n\ninterface NavigationMotionPreset {\n offset: number;\n scale: number;\n transition: Transition;\n}\n\ninterface NavigationAnimationCustom {\n direction: NavigationDirection;\n offset: number;\n scale: number;\n}\n\nconst NAVIGATION_MOTION_PRESETS: Record<NavigationMotionPresetName, NavigationMotionPreset> = {\n float: {\n offset: 96,\n scale: 0.97,\n transition: {\n opacity: { duration: 0.34, ease: [0.45, 0, 0.2, 1] },\n scale: { damping: 26, mass: 1.15, stiffness: 80, type: \"spring\" },\n x: { damping: 26, mass: 1.15, stiffness: 80, type: \"spring\" },\n },\n },\n glide: {\n offset: 58,\n scale: 0.984,\n transition: {\n opacity: { duration: 0.24, ease: [0.4, 0, 0.2, 1] },\n scale: { damping: 28, mass: 0.95, stiffness: 150, type: \"spring\" },\n x: { damping: 28, mass: 0.95, stiffness: 150, type: \"spring\" },\n },\n },\n snap: {\n offset: 38,\n scale: 0.996,\n transition: {\n opacity: { duration: 0.12, ease: [0.2, 0, 0, 1] },\n scale: { damping: 34, mass: 0.7, stiffness: 420, type: \"spring\" },\n x: { damping: 34, mass: 0.7, stiffness: 420, type: \"spring\" },\n },\n },\n};\n\nconst REDUCED_EXPANDED_MEDIA_TRANSITION: Transition = {\n duration: 0.12,\n ease: \"linear\",\n};\n\nconst expandedMediaVariants = {\n center: {\n opacity: 1,\n scale: 1,\n x: 0,\n },\n enter: ({ direction, offset, scale }: NavigationAnimationCustom): TargetAndTransition => ({\n opacity: 0,\n scale: direction === 0 ? 1 : scale,\n x: direction * offset,\n }),\n exit: ({ direction, offset, scale }: NavigationAnimationCustom): TargetAndTransition => ({\n opacity: 0,\n scale: direction === 0 ? 1 : scale,\n x: direction * -offset,\n }),\n};\n\nconst reducedExpandedMediaVariants = {\n center: {\n opacity: 1,\n x: 0,\n },\n enter: {\n opacity: 0,\n x: 0,\n },\n exit: {\n opacity: 0,\n x: 0,\n },\n};\n\nexport const ApertoExpandedMediaStage = ({\n direction,\n index,\n item,\n navigationMotion,\n renderImage,\n renderVideo,\n}: {\n direction: NavigationDirection;\n index: number;\n item: ApertoMediaItem;\n navigationMotion: NavigationMotionPresetName;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}) => {\n const ctx = useApertoContext();\n const preset = NAVIGATION_MOTION_PRESETS[navigationMotion];\n const transition = ctx.reduceMotion ? REDUCED_EXPANDED_MEDIA_TRANSITION : preset.transition;\n const variants = ctx.reduceMotion ? reducedExpandedMediaVariants : expandedMediaVariants;\n const animationCustom: NavigationAnimationCustom = {\n direction,\n offset: preset.offset,\n scale: preset.scale,\n };\n\n return (\n <AnimatePresence custom={animationCustom} initial={false} mode=\"sync\">\n <m.div\n animate=\"center\"\n custom={animationCustom}\n data-navigation-direction={direction}\n data-navigation-motion={navigationMotion}\n data-slot=\"aperto-media-stage\"\n exit=\"exit\"\n initial=\"enter\"\n key={getMediaKey(item, index)}\n transition={transition}\n variants={variants}\n >\n <ApertoExpandedMedia item={item} renderImage={renderImage} renderVideo={renderVideo} />\n </m.div>\n </AnimatePresence>\n );\n};\n","import { createElement } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport type { ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nconst renderDefaultImage = (props: Parameters<RenderImage>[0]): ReactNode => {\n const { item: _item, variant: _variant, ...imageProps } = props;\n return createElement(\"img\", { ...imageProps, alt: imageProps.alt ?? \"\" });\n};\n\nconst renderDefaultVideo = (props: Parameters<RenderVideo>[0]): ReactNode => {\n const { item: _item, variant, ...videoProps } = props;\n if (variant === \"thumbnail\") {\n return createElement(\"img\", {\n alt: videoProps[\"aria-label\"] ?? \"\",\n src: props.item.thumbnailSrc,\n });\n }\n return (\n <video {...videoProps}>\n <track kind=\"captions\" src={props.item.captionsSrc ?? \"data:text/vtt,\"} />\n </video>\n );\n};\n\nexport const ApertoThumbnailMedia = ({\n item,\n renderImage,\n renderVideo,\n}: {\n item: ApertoMediaItem;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}) => {\n if (item.type === \"image\") {\n const imageProps: Parameters<RenderImage>[0] = {\n alt: \"\",\n height: item.height,\n item,\n src: item.thumbnailSrc ?? item.src,\n variant: \"thumbnail\",\n width: item.width,\n };\n return (renderImage ?? renderDefaultImage)(imageProps);\n }\n\n const videoProps: Parameters<RenderVideo>[0] = {\n \"aria-label\": item.alt ?? item.title ?? \"Video thumbnail\",\n height: item.height,\n item,\n poster: item.poster,\n src: item.thumbnailSrc,\n variant: \"thumbnail\",\n width: item.width,\n };\n return (renderVideo ?? renderDefaultVideo)(videoProps);\n};\n\nexport const ApertoExpandedMedia = ({\n item,\n renderImage,\n renderVideo,\n}: {\n item: ApertoMediaItem;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}) => {\n if (item.type === \"image\") {\n const imageProps: Parameters<RenderImage>[0] = {\n alt: item.alt,\n height: item.height,\n item,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderImage ?? renderDefaultImage)(imageProps);\n }\n\n const videoProps: Parameters<RenderVideo>[0] = {\n \"aria-label\": item.alt ?? item.title ?? \"Video\",\n controls: true,\n height: item.height,\n item,\n poster: item.poster,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderVideo ?? renderDefaultVideo)(videoProps);\n};\n\nexport const ApertoTransitionMedia = ({\n item,\n renderImage,\n renderVideo,\n}: {\n item: ApertoMediaItem;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}) => {\n if (item.type === \"image\") {\n const imageProps: Parameters<RenderImage>[0] = {\n alt: item.alt,\n height: item.height,\n item,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderImage ?? renderDefaultImage)(imageProps);\n }\n\n const videoProps: Parameters<RenderVideo>[0] = {\n \"aria-label\": item.alt ?? item.title ?? \"Video\",\n height: item.height,\n item,\n poster: item.poster,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderVideo ?? renderDefaultVideo)(videoProps);\n};\n","import type { ApertoMediaItem } from \"./types\";\n\nexport const getMediaLabel = (item: ApertoMediaItem): string => item.title ?? item.alt ?? \"media\";\n\nexport const getMediaKey = (item: ApertoMediaItem, index: number): string =>\n item.id ?? `${item.type}:${item.src}:${index}`;\n\nexport const getDescriptionProps = (\n item: ApertoMediaItem,\n): {\n \"aria-describedby\"?: undefined;\n} => (item.description ? {} : { \"aria-describedby\": undefined });\n","import { m } from \"motion/react\";\nimport { useEffect } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { ApertoTransitionMedia } from \"./media-rendering\";\nimport { rectTarget, transitionDurationMs } from \"./media-transition-utils\";\nimport type { ApertoMediaTransition } from \"./media-transition-utils\";\nimport type { RenderImage, RenderVideo } from \"./types\";\n\nexport const ApertoMediaTransitionClone = ({\n onComplete,\n renderImage,\n renderVideo,\n transition,\n}: {\n onComplete: () => void;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n transition: ApertoMediaTransition | null;\n}) => {\n const ctx = useApertoContext();\n\n useEffect(() => {\n if (!transition?.to) {\n return;\n }\n\n const timer = setTimeout(onComplete, transitionDurationMs(ctx.preset.transition));\n return () => clearTimeout(timer);\n }, [ctx.preset.transition, onComplete, transition]);\n\n if (!transition?.to) {\n return null;\n }\n\n return (\n <m.div\n animate={rectTarget(transition.to)}\n aria-hidden=\"true\"\n data-slot=\"aperto-transition-media\"\n initial={rectTarget(transition.from)}\n style={{\n borderRadius: \"var(--aperto-radius, 0.5rem)\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n position: \"fixed\",\n zIndex: 30,\n }}\n transition={ctx.preset.transition}\n >\n <ApertoTransitionMedia\n item={transition.item}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n </m.div>\n );\n};\n","import type { TargetAndTransition, Transition } from \"motion/react\";\nimport type { ApertoMediaItem } from \"./types\";\n\nexport interface ApertoRect {\n height: number;\n left: number;\n top: number;\n width: number;\n}\n\nexport interface ApertoMediaTransition {\n from: ApertoRect;\n item: ApertoMediaItem;\n phase: \"opening\" | \"closing\";\n to?: ApertoRect;\n}\n\nexport const rectFromElement = (element: Element | null): ApertoRect | null => {\n if (!element) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n return {\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n };\n};\n\nexport const rectTarget = (rect: ApertoRect): TargetAndTransition => ({\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n});\n\nexport const transitionDurationMs = (transition: Transition): number =>\n typeof transition.duration === \"number\" ? transition.duration * 1000 : 450;\n","import type { NavigationDirection } from \"../expanded-media-stage\";\nimport type { ApertoMediaTransition, ApertoRect } from \"../media-transition-utils\";\n\nexport interface ApertoGroupState {\n closing: boolean;\n internalIndex: number;\n layoutSourceIndex: number;\n mediaTransition: ApertoMediaTransition | null;\n navigationDirection: NavigationDirection;\n open: boolean;\n}\n\nexport type ApertoGroupAction =\n | { type: \"close-without-transition\" }\n | { type: \"complete-opening-target\"; rect: ApertoRect }\n | { type: \"finish-transition\" }\n | { type: \"navigate\"; direction: NavigationDirection; index: number }\n | {\n type: \"open-at-index\";\n index: number;\n transition: ApertoMediaTransition | null;\n }\n | { type: \"set-index\"; index: number }\n | { type: \"set-open\"; open: boolean }\n | { type: \"start-close\"; transition: ApertoMediaTransition };\n\nexport const getInitialGroupState = (initialIndex: number): ApertoGroupState => ({\n closing: false,\n internalIndex: initialIndex,\n layoutSourceIndex: initialIndex,\n mediaTransition: null,\n navigationDirection: 0,\n open: false,\n});\n\nexport const apertoGroupReducer = (\n state: ApertoGroupState,\n action: ApertoGroupAction,\n): ApertoGroupState => {\n switch (action.type) {\n case \"close-without-transition\": {\n return { ...state, closing: false, mediaTransition: null, open: false };\n }\n case \"complete-opening-target\": {\n if (state.mediaTransition?.phase !== \"opening\" || state.mediaTransition.to) {\n return state;\n }\n return {\n ...state,\n mediaTransition: { ...state.mediaTransition, to: action.rect },\n };\n }\n case \"finish-transition\": {\n return {\n ...state,\n closing: false,\n mediaTransition: null,\n open: state.mediaTransition?.phase === \"closing\" ? false : state.open,\n };\n }\n case \"navigate\": {\n return {\n ...state,\n internalIndex: action.index,\n layoutSourceIndex: action.index,\n navigationDirection: action.direction,\n };\n }\n case \"open-at-index\": {\n return {\n ...state,\n closing: false,\n internalIndex: action.index,\n layoutSourceIndex: action.index,\n mediaTransition: action.transition,\n navigationDirection: 0,\n open: true,\n };\n }\n case \"set-index\": {\n return { ...state, internalIndex: action.index };\n }\n case \"set-open\": {\n return action.open ? { ...state, closing: false, open: true } : { ...state, open: false };\n }\n case \"start-close\": {\n return {\n ...state,\n closing: true,\n mediaTransition: action.transition,\n };\n }\n default: {\n return state;\n }\n }\n};\n","export const shouldIgnoreKeyboardNavigationTarget = (target: EventTarget | null): boolean => {\n if (!(target instanceof Element)) {\n return false;\n }\n\n return (\n (target as HTMLElement).isContentEditable ||\n Boolean(\n target.closest(\n 'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"textbox\"], audio, video',\n ),\n )\n );\n};\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst ApertoClose = ({ children, ref, ...props }: ComponentPropsWithRef<typeof Dialog.Close>) => (\n <Dialog.Close data-slot=\"aperto-close\" ref={ref} {...props}>\n {children ?? <X aria-hidden=\"true\" size={17} strokeWidth={2} />}\n </Dialog.Close>\n);\n\nApertoClose.displayName = \"ApertoClose\";\n\nexport { ApertoClose };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { m } from \"motion/react\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { resolvePreset } from \"./presets\";\nimport type { MotionPresetName } from \"./types\";\n\nconst TRIGGER_OPEN_Z_INDEX = 1000;\n\nexport interface ApertoTriggerProps extends ComponentPropsWithRef<typeof Dialog.Trigger> {\n /** Internal flag used by grouped thumbnails to raise only the active trigger. */\n active?: boolean;\n /** Override motion preset for this trigger */\n motion?: MotionPresetName;\n /** Internal shared layout ID override for grouped thumbnails. */\n sharedLayoutId?: string | false;\n}\n\nconst ApertoTrigger = ({\n active,\n children,\n motion: motionOverride,\n ref,\n sharedLayoutId,\n ...props\n}: ApertoTriggerProps) => {\n const ctx = useApertoContext();\n const shouldRaise = ctx.open && (active ?? true);\n const zIndex = shouldRaise ? TRIGGER_OPEN_Z_INDEX : 0;\n\n const resolved = resolvePreset(\n \"trigger\",\n motionOverride,\n ctx.presetName,\n ctx.variants,\n ctx.reduceMotion,\n );\n const layoutId =\n sharedLayoutId === false ? undefined : (sharedLayoutId ?? `${ctx.layoutId}-shared`);\n\n return (\n <Dialog.Trigger asChild ref={ref} {...props}>\n <m.button\n data-aperto-active={shouldRaise ? \"\" : undefined}\n data-slot=\"aperto-trigger\"\n key={layoutId ?? \"unshared\"}\n layout\n layoutCrossfade={false}\n layoutId={layoutId}\n style={{ zIndex }}\n transition={resolved.transition}\n type=\"button\"\n >\n {children}\n </m.button>\n </Dialog.Trigger>\n );\n};\n\nApertoTrigger.displayName = \"ApertoTrigger\";\n\nexport { ApertoTrigger };\n","\"use client\";\n\nimport { ApertoClose } from \"../aperto-close\";\nimport { ApertoContent } from \"../aperto-content\";\nimport { ApertoDescription } from \"../aperto-description\";\nimport { ApertoOverlay } from \"../aperto-overlay\";\nimport { ApertoPortal } from \"../aperto-portal\";\nimport { ApertoRoot } from \"../aperto-root\";\nimport { ApertoTitle } from \"../aperto-title\";\nimport { ApertoTrigger } from \"../aperto-trigger\";\nimport { ApertoExpandedMedia, ApertoThumbnailMedia } from \"../media-rendering\";\nimport { getDescriptionProps, getMediaLabel } from \"../media-utils\";\nimport type { ApertoProps } from \"./aperto-types\";\n\nexport const ApertoSingle = ({\n classNames,\n dismissible,\n media,\n renderImage,\n renderVideo,\n}: ApertoProps) => {\n const label = getMediaLabel(media);\n const title = media.title ?? label;\n\n return (\n <ApertoRoot dismissible={dismissible}>\n <ApertoTrigger aria-label={`Open ${label}`} className={classNames?.thumbnail}>\n <ApertoThumbnailMedia item={media} renderImage={renderImage} renderVideo={renderVideo} />\n </ApertoTrigger>\n <ApertoPortal>\n <ApertoOverlay className={classNames?.overlay} />\n <ApertoContent className={classNames?.content} {...getDescriptionProps(media)}>\n <ApertoExpandedMedia item={media} renderImage={renderImage} renderVideo={renderVideo} />\n <ApertoTitle>{title}</ApertoTitle>\n {media.description ? <ApertoDescription>{media.description}</ApertoDescription> : null}\n <ApertoClose aria-label=\"Close\" className={classNames?.closeButton} type=\"button\" />\n </ApertoContent>\n </ApertoPortal>\n </ApertoRoot>\n );\n};\n","\"use client\";\n\nimport { useApertoGroup } from \"../aperto-group-context\";\nimport { ApertoTrigger } from \"../aperto-trigger\";\nimport { ApertoThumbnailMedia } from \"../media-rendering\";\nimport { getMediaLabel } from \"../media-utils\";\nimport type { ApertoThumbnailProps } from \"./aperto-types\";\n\nexport const ApertoThumbnail = ({ children, className, index }: ApertoThumbnailProps) => {\n const group = useApertoGroup();\n const media = group.media[index];\n\n if (!media) {\n return null;\n }\n\n return (\n <ApertoTrigger\n active={group.index === index}\n aria-label={`Open ${getMediaLabel(media)}`}\n className={className ?? group.classNames?.thumbnail}\n onClick={() => group.openAtIndex(index)}\n ref={(node) => group.registerThumbnail(index, node)}\n sharedLayoutId={false}\n >\n {children ?? (\n <ApertoThumbnailMedia\n item={media}\n renderImage={group.renderImage}\n renderVideo={group.renderVideo}\n />\n )}\n </ApertoTrigger>\n );\n};\n","\"use client\";\n\n/**\n * Package: @patternmode/aperto\n *\n * Opinionated thumbnail-to-expanded media transitions.\n * Built on Radix Dialog + Motion.\n *\n * Inspired by Cambio (https://github.com/raphaelsalaja/cambio)\n * by Raphael Salaja.\n *\n * @example\n * ```tsx\n * import { Aperto } from \"@patternmode/aperto\";\n *\n * import { Aperto } from \"@patternmode/aperto\";\n * import \"@patternmode/aperto/styles.css\";\n *\n * <Aperto.Group media={media}>\n * {media.map((item, index) => (\n * <Aperto.Thumbnail key={item.id ?? item.src} index={index} />\n * ))}\n * </Aperto.Group>\n * ```\n */\n\nimport { ApertoGroup, ApertoSingle, ApertoThumbnail } from \"./aperto\";\nimport type { ApertoGroupProps, ApertoProps, ApertoThumbnailProps } from \"./aperto\";\nimport { ApertoClose } from \"./aperto-close\";\nimport { ApertoContent } from \"./aperto-content\";\nimport type { ApertoContentProps } from \"./aperto-content\";\nimport { ApertoDescription } from \"./aperto-description\";\nimport { ApertoOverlay } from \"./aperto-overlay\";\nimport type { ApertoOverlayProps } from \"./aperto-overlay\";\nimport { ApertoPortal } from \"./aperto-portal\";\nimport type { ApertoPortalProps } from \"./aperto-portal\";\nimport { ApertoRoot } from \"./aperto-root\";\nimport type { ApertoRootProps } from \"./aperto-root\";\nimport { ApertoTitle } from \"./aperto-title\";\nimport { ApertoTrigger } from \"./aperto-trigger\";\nimport type { ApertoTriggerProps } from \"./aperto-trigger\";\n\n/** Lower-level compound component namespace for advanced composition. */\nconst ApertoPrimitive = {\n Close: ApertoClose,\n Content: ApertoContent,\n Description: ApertoDescription,\n Overlay: ApertoOverlay,\n Portal: ApertoPortal,\n Root: ApertoRoot,\n Title: ApertoTitle,\n Trigger: ApertoTrigger,\n};\n\n/** Primary media-first component namespace. */\nconst Aperto = Object.assign(ApertoSingle, {\n Group: ApertoGroup,\n Primitive: ApertoPrimitive,\n Thumbnail: ApertoThumbnail,\n});\n\n// Preset system\nexport { PRESETS, resolvePreset } from \"./presets\";\n// Types\nexport type {\n ApertoClassNames,\n ApertoImageItem,\n ApertoMediaItem,\n ApertoVideoItem,\n DismissibleConfig,\n DragSpringConfig,\n MotionPreset,\n MotionPresetName,\n MotionProp,\n MotionVariants,\n NavigationMotionPresetName,\n RenderImage,\n RenderVideo,\n} from \"./types\";\n// Named exports for tree-shaking\nexport {\n Aperto,\n ApertoClose,\n ApertoContent,\n type ApertoContentProps,\n ApertoDescription,\n ApertoGroup,\n type ApertoGroupProps,\n ApertoOverlay,\n type ApertoOverlayProps,\n ApertoPortal,\n type ApertoPortalProps,\n ApertoPrimitive,\n type ApertoProps,\n ApertoRoot,\n type ApertoRootProps,\n ApertoThumbnail,\n type ApertoThumbnailProps,\n ApertoTitle,\n ApertoTrigger,\n type ApertoTriggerProps,\n};\n"],"mappings":"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","names":["useId","Dialog","jsx","createContext","use","Dialog","m","jsx","m","Dialog","jsx","Dialog","useState","jsx","useState","Dialog","jsx","AnimatePresence","m","jsx","jsx","AnimatePresence","m","m","jsx","m","jsx","useId","Dialog","X","jsx","Dialog","m","jsx","m","jsx","jsxs","jsx"]}
1
+ {"version":3,"sources":["../src/Aperto/aperto-group.tsx","../src/aperto-content.tsx","../src/context.ts","../src/physics.ts","../src/presets.ts","../src/aperto-description.tsx","../src/aperto-group-context.ts","../src/aperto-overlay.tsx","../src/aperto-portal.tsx","../src/aperto-root.tsx","../src/aperto-title.tsx","../src/expanded-media-stage.tsx","../src/media-rendering.tsx","../src/media-utils.ts","../src/media-transition.tsx","../src/media-transition-utils.ts","../src/Aperto/aperto-group-state.ts","../src/Aperto/aperto-keyboard.ts","../src/aperto-close.tsx","../src/aperto-trigger.tsx","../src/Aperto/aperto-single.tsx","../src/Aperto/aperto-thumbnail.tsx","../src/index.ts"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeft, ChevronRight, X } from \"lucide-react\";\nimport { useId, useLayoutEffect, useReducer, useRef } from \"react\";\nimport type { CSSProperties, Dispatch, KeyboardEvent } from \"react\";\n\nimport { ApertoContent } from \"../aperto-content\";\nimport { ApertoDescription } from \"../aperto-description\";\nimport { ApertoGroupContext } from \"../aperto-group-context\";\nimport { ApertoOverlay } from \"../aperto-overlay\";\nimport { ApertoPortal } from \"../aperto-portal\";\nimport { ApertoRoot } from \"../aperto-root\";\nimport { ApertoTitle } from \"../aperto-title\";\nimport { ApertoExpandedMediaStage } from \"../expanded-media-stage\";\nimport type { NavigationDirection } from \"../expanded-media-stage\";\nimport { ApertoMediaTransitionClone } from \"../media-transition\";\nimport { rectFromElement } from \"../media-transition-utils\";\nimport type { ApertoMediaTransition } from \"../media-transition-utils\";\nimport { getDescriptionProps, getMediaLabel } from \"../media-utils\";\nimport type {\n ApertoClassNames,\n ApertoMediaItem,\n NavigationMotionPresetName,\n RenderImage,\n RenderVideo,\n} from \"../types\";\nimport { apertoGroupReducer, getInitialGroupState } from \"./aperto-group-state\";\nimport type { ApertoGroupAction, ApertoGroupState } from \"./aperto-group-state\";\nimport { shouldIgnoreKeyboardNavigationTarget } from \"./aperto-keyboard\";\nimport type { ApertoGroupProps } from \"./aperto-types\";\n\ntype ApertoExpandedMediaStyle = CSSProperties & {\n \"--aperto-expanded-aspect-ratio\"?: string;\n \"--aperto-expanded-aspect-ratio-height\"?: number;\n \"--aperto-expanded-aspect-ratio-width\"?: number;\n};\ntype ApertoGroupDispatch = Dispatch<ApertoGroupAction>;\n\nconst ApertoMediaNavigationButtons = ({\n classNames,\n enabled,\n onNext,\n onPrevious,\n}: {\n classNames: ApertoClassNames | undefined;\n enabled: boolean;\n onNext: () => void;\n onPrevious: () => void;\n}) => {\n if (!enabled) {\n return null;\n }\n\n return (\n <>\n <button\n aria-label=\"Previous media\"\n className={classNames?.previousButton}\n data-slot=\"aperto-previous-button\"\n onClick={onPrevious}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={18} strokeWidth={2} />\n </button>\n <button\n aria-label=\"Next media\"\n className={classNames?.nextButton}\n data-slot=\"aperto-next-button\"\n onClick={onNext}\n type=\"button\"\n >\n <ChevronRight aria-hidden=\"true\" size={18} strokeWidth={2} />\n </button>\n </>\n );\n};\n\nconst useThumbnailMap = () => {\n const thumbnailRefs = useRef<Map<number, HTMLButtonElement> | null>(null);\n thumbnailRefs.current ??= new Map();\n return thumbnailRefs.current;\n};\n\nconst getExpandedMediaStyle = (\n activeMedia: ApertoMediaItem | undefined,\n): ApertoExpandedMediaStyle | undefined => {\n if (\n activeMedia === undefined ||\n activeMedia.width === undefined ||\n activeMedia.height === undefined\n ) {\n return undefined;\n }\n\n return {\n \"--aperto-expanded-aspect-ratio\": `${activeMedia.width} / ${activeMedia.height}`,\n \"--aperto-expanded-aspect-ratio-height\": activeMedia.height,\n \"--aperto-expanded-aspect-ratio-width\": activeMedia.width,\n };\n};\n\nconst ApertoGroupPortal = ({\n activeMedia,\n classNames,\n expandedMediaStyle,\n handleCloseAutoFocus,\n handleContentKeyDown,\n handleMediaTransitionComplete,\n hasNavigation,\n index,\n mediaLength,\n navigationDirection,\n navigationMotion,\n renderImage,\n renderVideo,\n setExpandedMediaNode,\n startClose,\n transition,\n goToNext,\n goToPrevious,\n}: {\n activeMedia: ApertoMediaItem | undefined;\n classNames: ApertoClassNames | undefined;\n expandedMediaStyle: ApertoExpandedMediaStyle | undefined;\n goToNext: () => void;\n goToPrevious: () => void;\n handleCloseAutoFocus: (event: Event) => void;\n handleContentKeyDown: ((event: KeyboardEvent<HTMLDivElement>) => void) | undefined;\n handleMediaTransitionComplete: () => void;\n hasNavigation: boolean;\n index: number;\n mediaLength: number;\n navigationDirection: NavigationDirection;\n navigationMotion: NavigationMotionPresetName;\n renderImage: RenderImage | undefined;\n renderVideo: RenderVideo | undefined;\n setExpandedMediaNode: (node: HTMLDivElement | null) => void;\n startClose: () => void;\n transition: ApertoMediaTransition | null;\n}) => {\n if (activeMedia === undefined) {\n return null;\n }\n\n return (\n <ApertoPortal>\n <ApertoOverlay className={classNames?.overlay} fadeOut={transition?.phase === \"closing\"} />\n <ApertoContent\n className={classNames?.content}\n data-aperto-transition={transition?.phase}\n onCloseAutoFocus={handleCloseAutoFocus}\n onKeyDown={handleContentKeyDown}\n sharedLayoutId={false}\n {...getDescriptionProps(activeMedia)}\n >\n <div data-slot=\"aperto-media\" ref={setExpandedMediaNode} style={expandedMediaStyle}>\n <ApertoExpandedMediaStage\n direction={navigationDirection}\n index={index}\n item={activeMedia}\n navigationMotion={navigationMotion}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n <ApertoMediaNavigationButtons\n classNames={classNames}\n enabled={hasNavigation}\n onNext={goToNext}\n onPrevious={goToPrevious}\n />\n </div>\n <ApertoTitle>{activeMedia.title ?? getMediaLabel(activeMedia)}</ApertoTitle>\n {activeMedia.description === undefined || activeMedia.description === \"\" ? null : (\n <ApertoDescription>{activeMedia.description}</ApertoDescription>\n )}\n {hasNavigation ? (\n <div className={classNames?.counter} data-slot=\"aperto-counter\">\n {index + 1} / {mediaLength}\n </div>\n ) : null}\n <button\n aria-label=\"Close\"\n className={classNames?.closeButton}\n data-slot=\"aperto-close\"\n onClick={startClose}\n type=\"button\"\n >\n <X aria-hidden=\"true\" size={17} strokeWidth={2} />\n </button>\n </ApertoContent>\n <ApertoMediaTransitionClone\n onComplete={handleMediaTransitionComplete}\n renderImage={renderImage}\n renderVideo={renderVideo}\n transition={transition}\n />\n </ApertoPortal>\n );\n};\n\nconst useApertoMediaLifecycle = ({\n activeMedia,\n dispatch,\n index,\n media,\n onIndexChange,\n state,\n}: {\n activeMedia: ApertoMediaItem | undefined;\n dispatch: ApertoGroupDispatch;\n index: number;\n media: ApertoMediaItem[];\n onIndexChange: ApertoGroupProps[\"onIndexChange\"];\n state: ApertoGroupState;\n}) => {\n const expandedMediaRef = useRef<HTMLDivElement | null>(null);\n const thumbnailMap = useThumbnailMap();\n\n const setExpandedMediaNode = (node: HTMLDivElement | null) => {\n expandedMediaRef.current = node;\n if (node === null) {\n return;\n }\n const targetRect = rectFromElement(node);\n if (targetRect !== null) {\n dispatch({ rect: targetRect, type: \"complete-opening-target\" });\n }\n };\n\n const registerThumbnail = (thumbIndex: number, node: HTMLButtonElement | null) => {\n if (node !== null) {\n thumbnailMap.set(thumbIndex, node);\n return;\n }\n thumbnailMap.delete(thumbIndex);\n };\n\n useLayoutEffect(() => {\n if (\n state.mediaTransition?.phase !== \"opening\" ||\n state.mediaTransition.to !== undefined ||\n expandedMediaRef.current === null\n ) {\n return;\n }\n\n const targetRect = rectFromElement(expandedMediaRef.current);\n if (targetRect !== null) {\n dispatch({ rect: targetRect, type: \"complete-opening-target\" });\n }\n }, [dispatch, state.mediaTransition]);\n\n const openAtIndex = (thumbIndex: number) => {\n const sourceRect = rectFromElement(thumbnailMap.get(thumbIndex) ?? null);\n const item = media[thumbIndex] ?? null;\n const transition =\n sourceRect === null || item === null\n ? null\n : { from: sourceRect, item, phase: \"opening\" as const };\n\n dispatch({ index: thumbIndex, transition, type: \"open-at-index\" });\n onIndexChange?.(thumbIndex);\n };\n\n const startClose = () => {\n if (!state.open || state.closing) {\n return;\n }\n\n const sourceRect = rectFromElement(expandedMediaRef.current);\n const targetRect = rectFromElement(thumbnailMap.get(index) ?? null);\n if (activeMedia === undefined || sourceRect === null || targetRect === null) {\n dispatch({ type: \"close-without-transition\" });\n return;\n }\n\n dispatch({\n transition: { from: sourceRect, item: activeMedia, phase: \"closing\", to: targetRect },\n type: \"start-close\",\n });\n };\n\n const handleCloseAutoFocus = (event: Event) => {\n event.preventDefault();\n // Focus Return: restore focus to the Thumbnail that opened the Media\n // Transition, falling back to the active thumbnail if it unmounted.\n const openerThumbnail =\n state.openerIndex === null ? undefined : thumbnailMap.get(state.openerIndex);\n const target = openerThumbnail ?? thumbnailMap.get(index);\n target?.focus({ preventScroll: true });\n };\n\n return { handleCloseAutoFocus, openAtIndex, registerThumbnail, setExpandedMediaNode, startClose };\n};\n\nconst useApertoGroupController = ({\n classNames,\n index: controlledIndex,\n initialIndex = 0,\n media,\n onIndexChange,\n renderImage,\n renderVideo,\n}: Omit<ApertoGroupProps, \"children\" | \"dismissible\" | \"motion\" | \"navigationMotion\">) => {\n const generatedId = useId();\n const [state, dispatch] = useReducer(apertoGroupReducer, initialIndex, getInitialGroupState);\n const isControlled = controlledIndex !== undefined;\n const index = isControlled ? controlledIndex : state.internalIndex;\n const activeMedia = media[index] ?? media[0];\n const lifecycle = useApertoMediaLifecycle({\n activeMedia,\n dispatch,\n index,\n media,\n onIndexChange,\n state,\n });\n const sharedLayoutIdForIndex = (nextIndex: number) =>\n `aperto-group-${generatedId}-${nextIndex}-shared`;\n const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);\n\n const setIndex = (nextIndex: number) => {\n if (!isControlled) {\n dispatch({ index: nextIndex, type: \"set-index\" });\n }\n onIndexChange?.(nextIndex);\n };\n\n const handleMediaTransitionComplete = () => {\n dispatch({ type: \"finish-transition\" });\n };\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (nextOpen) {\n dispatch({ open: true, type: \"set-open\" });\n return;\n }\n\n lifecycle.startClose();\n };\n\n const value = {\n classNames,\n index,\n media,\n open: state.open,\n openAtIndex: lifecycle.openAtIndex,\n registerThumbnail: lifecycle.registerThumbnail,\n renderImage,\n renderVideo,\n setIndex,\n sharedLayoutId,\n sharedLayoutIdForIndex,\n };\n const hasNavigation = media.length > 1;\n const navigateToIndex = (nextIndex: number, direction: NavigationDirection) => {\n dispatch({ direction, index: nextIndex, type: \"navigate\" });\n onIndexChange?.(nextIndex);\n };\n const goToPrevious = () => {\n navigateToIndex((index - 1 + media.length) % media.length, -1);\n };\n const goToNext = () => {\n navigateToIndex((index + 1) % media.length, 1);\n };\n const handleContentKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n shouldIgnoreKeyboardNavigationTarget(event.target)\n ) {\n return;\n }\n\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n goToPrevious();\n }\n\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n goToNext();\n }\n };\n const expandedMediaStyle = getExpandedMediaStyle(activeMedia);\n\n return {\n activeMedia,\n expandedMediaStyle,\n goToNext,\n goToPrevious,\n handleCloseAutoFocus: lifecycle.handleCloseAutoFocus,\n handleContentKeyDown,\n handleMediaTransitionComplete,\n handleOpenChange,\n hasNavigation,\n index,\n setExpandedMediaNode: lifecycle.setExpandedMediaNode,\n startClose: lifecycle.startClose,\n state,\n value,\n };\n};\n\nexport const ApertoGroup = ({\n children,\n classNames,\n dismissible,\n index,\n initialIndex,\n media,\n motion: motionProp,\n navigationMotion = \"glide\",\n onIndexChange,\n renderImage,\n renderVideo,\n}: ApertoGroupProps) => {\n const controller = useApertoGroupController({\n classNames,\n index,\n initialIndex,\n media,\n onIndexChange,\n renderImage,\n renderVideo,\n });\n\n return (\n <ApertoGroupContext.Provider value={controller.value}>\n <ApertoRoot\n dismissible={dismissible}\n motion={motionProp}\n onOpenChange={controller.handleOpenChange}\n open={controller.state.open}\n >\n {children}\n <ApertoGroupPortal\n activeMedia={controller.activeMedia}\n classNames={classNames}\n expandedMediaStyle={controller.expandedMediaStyle}\n goToNext={controller.goToNext}\n goToPrevious={controller.goToPrevious}\n handleCloseAutoFocus={controller.handleCloseAutoFocus}\n handleContentKeyDown={\n controller.hasNavigation ? controller.handleContentKeyDown : undefined\n }\n handleMediaTransitionComplete={controller.handleMediaTransitionComplete}\n hasNavigation={controller.hasNavigation}\n index={controller.index}\n mediaLength={media.length}\n navigationDirection={controller.state.navigationDirection}\n navigationMotion={navigationMotion}\n renderImage={renderImage}\n renderVideo={renderVideo}\n setExpandedMediaNode={controller.setExpandedMediaNode}\n startClose={controller.startClose}\n transition={controller.state.mediaTransition}\n />\n </ApertoRoot>\n </ApertoGroupContext.Provider>\n );\n};\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { m, useMotionValue, useSpring, useTransform } from \"motion/react\";\nimport type { MotionStyle, PanInfo } from \"motion/react\";\nimport { useState } from \"react\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport {\n calculateResistance,\n DEFAULT_DISTANCE_THRESHOLD,\n DEFAULT_VELOCITY_THRESHOLD,\n OPACITY_INPUT,\n OPACITY_OUTPUT,\n SCALE_INPUT,\n SCALE_OUTPUT,\n} from \"./physics\";\nimport { getDragSpring, resolvePreset } from \"./presets\";\nimport type { DismissibleConfig, MotionPresetName } from \"./types\";\n\nexport interface ApertoContentProps extends Omit<\n ComponentPropsWithRef<typeof Dialog.Content>,\n \"asChild\" | \"forceMount\"\n> {\n /** Motion preset override for this content panel, independent of the root preset. */\n motion?: MotionPresetName;\n /** Built-in positioning strategy. Use \"none\" for custom primitive compositions. */\n placement?: \"center\" | \"none\";\n /** Internal shared layout ID override for grouped media. */\n sharedLayoutId?: string | false;\n}\n\nconst ApertoContent = ({\n children,\n className,\n motion: motionOverride,\n placement = \"center\",\n ref,\n sharedLayoutId,\n style,\n ...props\n}: ApertoContentProps) => {\n const ctx = useApertoContext();\n const [isDragging, setIsDragging] = useState(false);\n const resolved = resolvePreset(\n \"content\",\n motionOverride,\n ctx.presetName,\n ctx.variants,\n ctx.reduceMotion,\n );\n\n const contentLayoutId =\n sharedLayoutId === false ? undefined : (sharedLayoutId ?? `${ctx.layoutId}-shared`);\n\n const dragSpring = getDragSpring(resolved);\n const isDismissible = ctx.dismissible !== false;\n\n const dismissConfig: DismissibleConfig =\n typeof ctx.dismissible === \"object\" ? ctx.dismissible : {};\n const distanceThreshold = dismissConfig.threshold ?? DEFAULT_DISTANCE_THRESHOLD;\n const velocityThreshold = dismissConfig.velocity ?? DEFAULT_VELOCITY_THRESHOLD;\n\n const dragX = useMotionValue(0);\n const dragY = useMotionValue(0);\n const springX = useSpring(dragX, dragSpring);\n const springY = useSpring(dragY, dragSpring);\n\n const distance = useTransform(() => Math.hypot(springX.get(), springY.get()));\n const scaleMotion = useTransform(distance, SCALE_INPUT, SCALE_OUTPUT);\n const opacityMotion = useTransform(distance, OPACITY_INPUT, OPACITY_OUTPUT);\n const resistance = useTransform(distance, calculateResistance);\n const { onOpenChange } = ctx;\n\n const handleDrag = (_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n if (!isDragging) {\n setIsDragging(true);\n }\n const r = resistance.get();\n dragX.set(info.offset.x * r);\n dragY.set(info.offset.y * r);\n };\n\n const handleDragEnd = (_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n setIsDragging(false);\n const speed = Math.hypot(info.velocity.x, info.velocity.y);\n const dist = Math.hypot(info.offset.x, info.offset.y);\n\n if (speed > velocityThreshold || dist > distanceThreshold) {\n onOpenChange(false);\n return;\n }\n\n dragX.set(0);\n dragY.set(0);\n };\n\n const placementStyle =\n placement === \"center\"\n ? {\n left: \"50%\",\n top: \"50%\",\n translate: \"-50% -50%\",\n }\n : {};\n let cursor: MotionStyle[\"cursor\"];\n\n if (isDragging) {\n cursor = \"grabbing\";\n } else if (isDismissible) {\n cursor = \"grab\";\n }\n\n const motionStyle: MotionStyle = {\n cursor,\n opacity: opacityMotion,\n scale: scaleMotion,\n x: springX,\n y: springY,\n ...placementStyle,\n ...style,\n };\n\n return (\n <Dialog.Content asChild forceMount {...props}>\n <m.div\n className={className}\n data-slot=\"aperto-content\"\n drag={isDismissible}\n dragConstraints={{ bottom: 0, left: 0, right: 0, top: 0 }}\n dragElastic={0}\n dragMomentum={false}\n dragSnapToOrigin\n layout={contentLayoutId === undefined || contentLayoutId === \"\" ? undefined : true}\n layoutId={contentLayoutId}\n onDrag={isDismissible ? handleDrag : undefined}\n onDragEnd={isDismissible ? handleDragEnd : undefined}\n ref={ref}\n style={motionStyle}\n transition={resolved.transition}\n >\n {children}\n </m.div>\n </Dialog.Content>\n );\n};\n\nApertoContent.displayName = \"ApertoContent\";\n\nexport { ApertoContent };\n","\"use client\";\n\nimport { createContext, use } from \"react\";\n\nimport type { ApertoContextValue } from \"./types\";\n\nexport const ApertoContext = createContext<ApertoContextValue | null>(null);\n\nexport const useApertoContext = (): ApertoContextValue => {\n const ctx = use(ApertoContext);\n if (!ctx) {\n throw new Error(\"Aperto components must be used within <Aperto.Root>\");\n }\n return ctx;\n};\n","/**\n * Drag physics utilities.\n *\n * The logarithmic resistance function creates a rubber-band feel:\n * initial movement is free, but gets progressively harder the further\n * you drag. Combined with spring-smoothed motion values, this produces\n * a natural, elastic gesture.\n */\n\nconst RESISTANCE_DIVISOR = 20;\nconst RESISTANCE_SCALE = 4;\nconst RESISTANCE_MIN = 0.1;\n\n/**\n * Logarithmic resistance — decelerates drag progressively.\n * Returns a multiplier between RESISTANCE_MIN and 1.0.\n *\n * At distance 0: returns 1.0 (full movement)\n * At distance 50: returns ~0.77\n * At distance 100: returns ~0.58\n * At distance 200: returns ~0.42\n */\nexport const calculateResistance = (distance: number): number =>\n Math.max(RESISTANCE_MIN, 1 - Math.log(distance / RESISTANCE_DIVISOR + 1) / RESISTANCE_SCALE);\n\n/** Scale mapping: distance → visual scale (1.0 → 0.95) */\nexport const SCALE_INPUT = [0, 50, 100];\nexport const SCALE_OUTPUT = [1, 0.98, 0.95];\n\n/** Opacity mapping: distance → visual opacity (1.0 → 0.96) */\nexport const OPACITY_INPUT = [0, 80];\nexport const OPACITY_OUTPUT = [1, 0.96];\n\n/** Default dismissal thresholds */\nexport const DEFAULT_DISTANCE_THRESHOLD = 100;\nexport const DEFAULT_VELOCITY_THRESHOLD = 500;\n","import { durations, easings, springs } from \"@howells/motion\";\nimport type { DragSpringConfig, MotionPreset, MotionPresetName, MotionVariants } from \"./types\";\n\n/**\n * Motion presets — each bundles transition timing AND drag physics\n * so \"snappy\" feels snappy everywhere: open, close, and drag.\n *\n * Curves and springs come from the shared @howells/motion tokens so motion\n * feel stays consistent across the catalog.\n */\nexport const PRESETS: Record<MotionPresetName, MotionPreset> = {\n bouncy: {\n drag: {\n damping: springs.snappy.damping,\n restDelta: 0.01,\n stiffness: springs.snappy.stiffness,\n },\n transition: {\n damping: springs.bouncy.damping,\n mass: springs.bouncy.mass,\n stiffness: springs.bouncy.stiffness,\n type: \"spring\",\n },\n },\n reduced: {\n drag: { damping: 50, restDelta: 0.1, stiffness: 1000 },\n transition: { duration: 0.01, ease: \"linear\" },\n },\n smooth: {\n drag: {\n damping: springs.natural.damping,\n restDelta: 0.01,\n stiffness: springs.natural.stiffness,\n },\n transition: { duration: durations.moderate, ease: easings.customGentle },\n },\n snappy: {\n drag: {\n damping: springs.stiff.damping,\n restDelta: 0.01,\n stiffness: springs.stiff.stiffness,\n },\n transition: { duration: durations.snappy, ease: easings.snappy },\n },\n};\n\ntype ComponentType = \"trigger\" | \"content\" | \"backdrop\";\n\n/**\n * Three-level motion resolution:\n * 1. Component-level override (highest)\n * 2. Per-component variant from Root\n * 3. Global preset from Root (lowest)\n *\n * If `prefers-reduced-motion` is active, always returns \"reduced\".\n */\nexport const resolvePreset = (\n componentType: ComponentType,\n componentMotion: MotionPresetName | undefined,\n globalPreset: MotionPresetName,\n variants: MotionVariants | undefined,\n reduceMotion: boolean,\n): MotionPreset => {\n if (reduceMotion) {\n return PRESETS.reduced;\n }\n\n // 1. Component-level override\n if (componentMotion) {\n return PRESETS[componentMotion];\n }\n\n // 2. Per-component variant\n if (variants?.[componentType]) {\n return PRESETS[variants[componentType]];\n }\n\n // 3. Global preset\n return PRESETS[globalPreset];\n};\n\n/** Extract the drag spring config from a preset */\nexport const getDragSpring = (preset: MotionPreset): DragSpringConfig => preset.drag;\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst ApertoDescription = ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Description>) => (\n <Dialog.Description data-slot=\"aperto-description\" ref={ref} {...props} />\n);\n\nApertoDescription.displayName = \"ApertoDescription\";\n\nexport { ApertoDescription };\n","import { createContext, use } from \"react\";\n\nimport type { ApertoClassNames, ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nexport interface ApertoGroupContextValue {\n classNames?: ApertoClassNames;\n index: number;\n media: ApertoMediaItem[];\n open: boolean;\n openAtIndex: (index: number) => void;\n registerThumbnail: (index: number, node: HTMLButtonElement | null) => void;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n setIndex: (index: number) => void;\n sharedLayoutId: string;\n sharedLayoutIdForIndex: (index: number) => string;\n}\n\nexport const ApertoGroupContext = createContext<ApertoGroupContextValue | null>(null);\n\nexport const useApertoGroup = (): ApertoGroupContextValue => {\n const ctx = use(ApertoGroupContext);\n if (!ctx) {\n throw new Error(\"Aperto.Thumbnail must be used within <Aperto.Group>\");\n }\n return ctx;\n};\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { m } from \"motion/react\";\nimport type { Transition } from \"motion/react\";\nimport type { CSSProperties, Ref } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { easings } from \"@howells/motion\";\n\nexport interface ApertoOverlayProps {\n className?: string;\n /** Internal flag used to fade the overlay during measured close transitions. */\n fadeOut?: boolean;\n ref?: Ref<HTMLDivElement>;\n style?: CSSProperties;\n}\n\n/** Overlay always fades gently regardless of the content's motion preset. */\nconst OVERLAY_TRANSITION: Transition = {\n duration: 0.3,\n ease: easings.customGentle,\n};\n\nconst OVERLAY_TRANSITION_REDUCED: Transition = {\n duration: 0.01,\n ease: \"linear\",\n};\n\nconst ApertoOverlay = ({ className, fadeOut, ref, style }: ApertoOverlayProps) => {\n const ctx = useApertoContext();\n const transition = ctx.reduceMotion ? OVERLAY_TRANSITION_REDUCED : OVERLAY_TRANSITION;\n\n return (\n <Dialog.Overlay asChild forceMount>\n <m.div\n animate={{ opacity: fadeOut === true ? 0 : 1 }}\n className={className}\n data-slot=\"aperto-overlay\"\n exit={{ opacity: 0 }}\n initial={{ opacity: 0 }}\n ref={ref}\n style={style}\n transition={transition}\n />\n </Dialog.Overlay>\n );\n};\n\nApertoOverlay.displayName = \"ApertoOverlay\";\n\nexport { ApertoOverlay };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { AnimatePresence } from \"motion/react\";\nimport type { ReactNode } from \"react\";\n\nimport { useApertoContext } from \"./context\";\n\nexport interface ApertoPortalProps {\n children: ReactNode;\n /** Container element for the portal (default: document.body) */\n container?: HTMLElement;\n}\n\nconst ApertoPortal = ({ children, container }: ApertoPortalProps) => {\n const { open } = useApertoContext();\n\n return (\n <AnimatePresence>\n {open && (\n <Dialog.Portal container={container} forceMount>\n {children}\n </Dialog.Portal>\n )}\n </AnimatePresence>\n );\n};\n\nexport { ApertoPortal };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { domMax, LayoutGroup, LazyMotion, useReducedMotion } from \"motion/react\";\nimport { useId, useState } from \"react\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\n\nimport { ApertoContext } from \"./context\";\nimport { PRESETS } from \"./presets\";\nimport type { DismissibleConfig, MotionPresetName, MotionVariants } from \"./types\";\n\nexport interface ApertoRootProps extends Omit<\n ComponentPropsWithoutRef<typeof Dialog.Root>,\n \"open\" | \"onOpenChange\"\n> {\n children: ReactNode;\n /** Whether dragging can dismiss the content (default: true) */\n dismissible?: boolean | DismissibleConfig;\n /** Layout ID for shared element transition (auto-generated if omitted) */\n layoutId?: string;\n /** Motion preset or per-component variants */\n motion?: MotionPresetName | MotionVariants;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Force reduced motion regardless of system preference */\n reduceMotion?: boolean;\n}\n\nconst ApertoRoot = ({\n children,\n defaultOpen,\n dismissible = true,\n layoutId: layoutIdProp,\n motion: motionProp = \"smooth\",\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n reduceMotion: reduceMotionProp,\n ...dialogProps\n}: ApertoRootProps) => {\n const generatedId = useId();\n const layoutId = layoutIdProp ?? `aperto-${generatedId}`;\n const systemReducedMotion = useReducedMotion() ?? false;\n const shouldReduce = reduceMotionProp ?? systemReducedMotion;\n\n // Uncontrolled state fallback\n const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? controlledOpen : internalOpen;\n\n const onOpenChange = (nextOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(nextOpen);\n }\n controlledOnOpenChange?.(nextOpen);\n };\n\n // Resolve global preset name\n const globalPresetName: MotionPresetName = typeof motionProp === \"string\" ? motionProp : \"smooth\";\n const variants: MotionVariants | undefined =\n typeof motionProp === \"object\" ? motionProp : undefined;\n\n const presetName: MotionPresetName = shouldReduce ? \"reduced\" : globalPresetName;\n const preset = PRESETS[presetName];\n const contextValue = {\n dismissible,\n layoutId,\n onOpenChange,\n open,\n preset,\n presetName,\n reduceMotion: shouldReduce,\n variants,\n };\n\n return (\n <ApertoContext.Provider value={contextValue}>\n <Dialog.Root onOpenChange={onOpenChange} open={open} {...dialogProps}>\n <LazyMotion features={domMax}>\n <LayoutGroup id={layoutId}>{children}</LayoutGroup>\n </LazyMotion>\n </Dialog.Root>\n </ApertoContext.Provider>\n );\n};\n\nexport { ApertoRoot };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst ApertoTitle = ({ ref, ...props }: ComponentPropsWithRef<typeof Dialog.Title>) => (\n <Dialog.Title data-slot=\"aperto-title\" ref={ref} {...props} />\n);\n\nApertoTitle.displayName = \"ApertoTitle\";\n\nexport { ApertoTitle };\n","import { AnimatePresence, m } from \"motion/react\";\nimport type { TargetAndTransition, Transition } from \"motion/react\";\n\nimport { useApertoContext } from \"./context\";\nimport { ApertoExpandedMedia } from \"./media-rendering\";\nimport { getMediaKey } from \"./media-utils\";\nimport type {\n ApertoMediaItem,\n NavigationMotionPresetName,\n RenderImage,\n RenderVideo,\n} from \"./types\";\n\nexport type NavigationDirection = -1 | 0 | 1;\n\ninterface NavigationMotionPreset {\n offset: number;\n scale: number;\n transition: Transition;\n}\n\ninterface NavigationAnimationCustom {\n direction: NavigationDirection;\n offset: number;\n scale: number;\n}\n\nconst NAVIGATION_MOTION_PRESETS: Record<NavigationMotionPresetName, NavigationMotionPreset> = {\n float: {\n offset: 96,\n scale: 0.97,\n transition: {\n opacity: { duration: 0.34, ease: [0.45, 0, 0.2, 1] },\n scale: { damping: 26, mass: 1.15, stiffness: 80, type: \"spring\" },\n x: { damping: 26, mass: 1.15, stiffness: 80, type: \"spring\" },\n },\n },\n glide: {\n offset: 58,\n scale: 0.984,\n transition: {\n opacity: { duration: 0.24, ease: [0.4, 0, 0.2, 1] },\n scale: { damping: 28, mass: 0.95, stiffness: 150, type: \"spring\" },\n x: { damping: 28, mass: 0.95, stiffness: 150, type: \"spring\" },\n },\n },\n snap: {\n offset: 38,\n scale: 0.996,\n transition: {\n opacity: { duration: 0.12, ease: [0.2, 0, 0, 1] },\n scale: { damping: 34, mass: 0.7, stiffness: 420, type: \"spring\" },\n x: { damping: 34, mass: 0.7, stiffness: 420, type: \"spring\" },\n },\n },\n};\n\nconst REDUCED_EXPANDED_MEDIA_TRANSITION: Transition = {\n duration: 0.12,\n ease: \"linear\",\n};\n\nconst expandedMediaVariants = {\n center: {\n opacity: 1,\n scale: 1,\n x: 0,\n },\n enter: ({ direction, offset, scale }: NavigationAnimationCustom): TargetAndTransition => ({\n opacity: 0,\n scale: direction === 0 ? 1 : scale,\n x: direction * offset,\n }),\n exit: ({ direction, offset, scale }: NavigationAnimationCustom): TargetAndTransition => ({\n opacity: 0,\n scale: direction === 0 ? 1 : scale,\n x: direction * -offset,\n }),\n};\n\nconst reducedExpandedMediaVariants = {\n center: {\n opacity: 1,\n x: 0,\n },\n enter: {\n opacity: 0,\n x: 0,\n },\n exit: {\n opacity: 0,\n x: 0,\n },\n};\n\nexport const ApertoExpandedMediaStage = ({\n direction,\n index,\n item,\n navigationMotion,\n renderImage,\n renderVideo,\n}: {\n direction: NavigationDirection;\n index: number;\n item: ApertoMediaItem;\n navigationMotion: NavigationMotionPresetName;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}) => {\n const ctx = useApertoContext();\n const preset = NAVIGATION_MOTION_PRESETS[navigationMotion];\n const transition = ctx.reduceMotion ? REDUCED_EXPANDED_MEDIA_TRANSITION : preset.transition;\n const variants = ctx.reduceMotion ? reducedExpandedMediaVariants : expandedMediaVariants;\n const animationCustom: NavigationAnimationCustom = {\n direction,\n offset: preset.offset,\n scale: preset.scale,\n };\n\n return (\n <AnimatePresence custom={animationCustom} initial={false} mode=\"sync\">\n <m.div\n animate=\"center\"\n custom={animationCustom}\n data-navigation-direction={direction}\n data-navigation-motion={navigationMotion}\n data-slot=\"aperto-media-stage\"\n exit=\"exit\"\n initial=\"enter\"\n key={getMediaKey(item, index)}\n transition={transition}\n variants={variants}\n >\n <ApertoExpandedMedia item={item} renderImage={renderImage} renderVideo={renderVideo} />\n </m.div>\n </AnimatePresence>\n );\n};\n","import { createElement } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport type { ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nconst renderDefaultImage = (props: Parameters<RenderImage>[0]): ReactNode => {\n const { item: _item, variant: _variant, ...imageProps } = props;\n return createElement(\"img\", { ...imageProps, alt: imageProps.alt ?? \"\" });\n};\n\nconst renderDefaultVideo = (props: Parameters<RenderVideo>[0]): ReactNode => {\n const { item: _item, variant, ...videoProps } = props;\n if (variant === \"thumbnail\") {\n return createElement(\"img\", {\n alt: videoProps[\"aria-label\"] ?? \"\",\n src: props.item.thumbnailSrc,\n });\n }\n return (\n <video {...videoProps}>\n <track kind=\"captions\" src={props.item.captionsSrc ?? \"data:text/vtt,\"} />\n </video>\n );\n};\n\nexport const ApertoThumbnailMedia = ({\n item,\n renderImage,\n renderVideo,\n}: {\n item: ApertoMediaItem;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}): ReactNode => {\n if (item.type === \"image\") {\n const imageProps: Parameters<RenderImage>[0] = {\n alt: \"\",\n height: item.height,\n item,\n src: item.thumbnailSrc ?? item.src,\n variant: \"thumbnail\",\n width: item.width,\n };\n return (renderImage ?? renderDefaultImage)(imageProps);\n }\n\n const videoProps: Parameters<RenderVideo>[0] = {\n \"aria-label\": item.alt ?? item.title ?? \"Video thumbnail\",\n height: item.height,\n item,\n poster: item.poster,\n src: item.thumbnailSrc,\n variant: \"thumbnail\",\n width: item.width,\n };\n return (renderVideo ?? renderDefaultVideo)(videoProps);\n};\n\nexport const ApertoExpandedMedia = ({\n item,\n renderImage,\n renderVideo,\n}: {\n item: ApertoMediaItem;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}): ReactNode => {\n if (item.type === \"image\") {\n const imageProps: Parameters<RenderImage>[0] = {\n alt: item.alt,\n height: item.height,\n item,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderImage ?? renderDefaultImage)(imageProps);\n }\n\n const videoProps: Parameters<RenderVideo>[0] = {\n \"aria-label\": item.alt ?? item.title ?? \"Video\",\n controls: true,\n height: item.height,\n item,\n poster: item.poster,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderVideo ?? renderDefaultVideo)(videoProps);\n};\n\nexport const ApertoTransitionMedia = ({\n item,\n renderImage,\n renderVideo,\n}: {\n item: ApertoMediaItem;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n}): ReactNode => {\n if (item.type === \"image\") {\n const imageProps: Parameters<RenderImage>[0] = {\n alt: item.alt,\n height: item.height,\n item,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderImage ?? renderDefaultImage)(imageProps);\n }\n\n const videoProps: Parameters<RenderVideo>[0] = {\n \"aria-label\": item.alt ?? item.title ?? \"Video\",\n height: item.height,\n item,\n poster: item.poster,\n src: item.src,\n variant: \"expanded\",\n width: item.width,\n };\n return (renderVideo ?? renderDefaultVideo)(videoProps);\n};\n","import type { ApertoMediaItem } from \"./types\";\n\nexport const getMediaLabel = (item: ApertoMediaItem): string => item.title ?? item.alt ?? \"media\";\n\nexport const getMediaKey = (item: ApertoMediaItem, index: number): string =>\n item.id ?? `${item.type}:${item.src}:${index}`;\n\nexport const getDescriptionProps = (\n item: ApertoMediaItem,\n): {\n \"aria-describedby\"?: undefined;\n} =>\n item.description === undefined || item.description === \"\"\n ? { \"aria-describedby\": undefined }\n : {};\n","import { m } from \"motion/react\";\nimport { useEffect, useRef } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { ApertoTransitionMedia } from \"./media-rendering\";\nimport { rectTarget, transitionDurationMs } from \"./media-transition-utils\";\nimport type { ApertoMediaTransition } from \"./media-transition-utils\";\nimport type { RenderImage, RenderVideo } from \"./types\";\n\nexport const ApertoMediaTransitionClone = ({\n onComplete,\n renderImage,\n renderVideo,\n transition,\n}: {\n onComplete: () => void;\n renderImage?: RenderImage;\n renderVideo?: RenderVideo;\n transition: ApertoMediaTransition | null;\n}) => {\n const ctx = useApertoContext();\n // Hold the latest onComplete in a ref so parent re-renders (which recreate the\n // callback) do not restart the completion countdown mid-transition.\n const onCompleteRef = useRef(onComplete);\n useEffect(() => {\n onCompleteRef.current = onComplete;\n });\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (transition?.to !== undefined) {\n timer = setTimeout(() => {\n onCompleteRef.current();\n }, transitionDurationMs(ctx.preset.transition));\n }\n\n return () => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n };\n }, [ctx.preset.transition, transition]);\n\n if (transition?.to === undefined) {\n return null;\n }\n\n return (\n <m.div\n animate={rectTarget(transition.to)}\n aria-hidden=\"true\"\n data-slot=\"aperto-transition-media\"\n initial={rectTarget(transition.from)}\n style={{\n borderRadius: \"var(--aperto-radius, 0.5rem)\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n position: \"fixed\",\n zIndex: \"var(--patternmode-aperto-clone-z, 1002)\",\n }}\n transition={ctx.preset.transition}\n >\n <ApertoTransitionMedia\n item={transition.item}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n </m.div>\n );\n};\n","import type { TargetAndTransition, Transition } from \"motion/react\";\nimport type { ApertoMediaItem } from \"./types\";\n\nexport interface ApertoRect {\n height: number;\n left: number;\n top: number;\n width: number;\n}\n\nexport interface ApertoMediaTransition {\n from: ApertoRect;\n item: ApertoMediaItem;\n phase: \"opening\" | \"closing\";\n to?: ApertoRect;\n}\n\nexport const rectFromElement = (element: Element | null): ApertoRect | null => {\n if (!element) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n return {\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n };\n};\n\nexport const rectTarget = (rect: ApertoRect): TargetAndTransition => ({\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n});\n\nexport const transitionDurationMs = (transition: Transition): number =>\n typeof transition.duration === \"number\" ? transition.duration * 1000 : 450;\n","import type { NavigationDirection } from \"../expanded-media-stage\";\nimport type { ApertoMediaTransition, ApertoRect } from \"../media-transition-utils\";\n\nexport interface ApertoGroupState {\n closing: boolean;\n internalIndex: number;\n layoutSourceIndex: number;\n mediaTransition: ApertoMediaTransition | null;\n navigationDirection: NavigationDirection;\n open: boolean;\n /** Index of the thumbnail that opened the Media Transition; focus returns here on close. */\n openerIndex: number | null;\n}\n\nexport type ApertoGroupAction =\n | { type: \"close-without-transition\" }\n | { type: \"complete-opening-target\"; rect: ApertoRect }\n | { type: \"finish-transition\" }\n | { type: \"navigate\"; direction: NavigationDirection; index: number }\n | {\n type: \"open-at-index\";\n index: number;\n transition: ApertoMediaTransition | null;\n }\n | { type: \"set-index\"; index: number }\n | { type: \"set-open\"; open: boolean }\n | { type: \"start-close\"; transition: ApertoMediaTransition };\n\nexport const getInitialGroupState = (initialIndex: number): ApertoGroupState => ({\n closing: false,\n internalIndex: initialIndex,\n layoutSourceIndex: initialIndex,\n mediaTransition: null,\n navigationDirection: 0,\n open: false,\n openerIndex: null,\n});\n\nexport const apertoGroupReducer = (\n state: ApertoGroupState,\n action: ApertoGroupAction,\n): ApertoGroupState => {\n switch (action.type) {\n case \"close-without-transition\": {\n return { ...state, closing: false, mediaTransition: null, open: false };\n }\n case \"complete-opening-target\": {\n if (state.mediaTransition?.phase !== \"opening\" || state.mediaTransition.to) {\n return state;\n }\n return {\n ...state,\n mediaTransition: { ...state.mediaTransition, to: action.rect },\n };\n }\n case \"finish-transition\": {\n return {\n ...state,\n closing: false,\n mediaTransition: null,\n open: state.mediaTransition?.phase === \"closing\" ? false : state.open,\n };\n }\n case \"navigate\": {\n return {\n ...state,\n internalIndex: action.index,\n layoutSourceIndex: action.index,\n navigationDirection: action.direction,\n };\n }\n case \"open-at-index\": {\n return {\n ...state,\n closing: false,\n internalIndex: action.index,\n layoutSourceIndex: action.index,\n mediaTransition: action.transition,\n navigationDirection: 0,\n open: true,\n openerIndex: action.index,\n };\n }\n case \"set-index\": {\n return { ...state, internalIndex: action.index };\n }\n case \"set-open\": {\n return action.open\n ? { ...state, closing: false, open: true, openerIndex: state.internalIndex }\n : { ...state, open: false };\n }\n case \"start-close\": {\n return {\n ...state,\n closing: true,\n mediaTransition: action.transition,\n };\n }\n default: {\n return state;\n }\n }\n};\n","export const shouldIgnoreKeyboardNavigationTarget = (target: EventTarget | null): boolean => {\n if (!(target instanceof HTMLElement)) {\n return false;\n }\n\n return (\n target.isContentEditable ||\n Boolean(\n target.closest(\n 'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"textbox\"], audio, video',\n ),\n )\n );\n};\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst ApertoClose = ({ children, ref, ...props }: ComponentPropsWithRef<typeof Dialog.Close>) => (\n <Dialog.Close data-slot=\"aperto-close\" ref={ref} {...props}>\n {children ?? <X aria-hidden=\"true\" size={17} strokeWidth={2} />}\n </Dialog.Close>\n);\n\nApertoClose.displayName = \"ApertoClose\";\n\nexport { ApertoClose };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { m } from \"motion/react\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { resolvePreset } from \"./presets\";\nimport type { MotionPresetName } from \"./types\";\n\nconst TRIGGER_OPEN_Z_INDEX = 1000;\n\nexport interface ApertoTriggerProps extends ComponentPropsWithRef<typeof Dialog.Trigger> {\n /** Internal flag used by grouped thumbnails to raise only the active trigger. */\n active?: boolean;\n /** Override motion preset for this trigger */\n motion?: MotionPresetName;\n /** Internal shared layout ID override for grouped thumbnails. */\n sharedLayoutId?: string | false;\n}\n\nconst ApertoTrigger = ({\n active,\n children,\n motion: motionOverride,\n ref,\n sharedLayoutId,\n ...props\n}: ApertoTriggerProps) => {\n const ctx = useApertoContext();\n const shouldRaise = ctx.open && (active ?? true);\n const zIndex = shouldRaise ? TRIGGER_OPEN_Z_INDEX : 0;\n\n const resolved = resolvePreset(\n \"trigger\",\n motionOverride,\n ctx.presetName,\n ctx.variants,\n ctx.reduceMotion,\n );\n const layoutId =\n sharedLayoutId === false ? undefined : (sharedLayoutId ?? `${ctx.layoutId}-shared`);\n\n return (\n <Dialog.Trigger asChild ref={ref} {...props}>\n <m.button\n data-aperto-active={shouldRaise ? \"\" : undefined}\n data-slot=\"aperto-trigger\"\n key={layoutId ?? \"unshared\"}\n layout\n layoutCrossfade={false}\n layoutId={layoutId}\n style={{ zIndex }}\n transition={resolved.transition}\n type=\"button\"\n >\n {children}\n </m.button>\n </Dialog.Trigger>\n );\n};\n\nApertoTrigger.displayName = \"ApertoTrigger\";\n\nexport { ApertoTrigger };\n","\"use client\";\n\nimport { ApertoClose } from \"../aperto-close\";\nimport { ApertoContent } from \"../aperto-content\";\nimport { ApertoDescription } from \"../aperto-description\";\nimport { ApertoOverlay } from \"../aperto-overlay\";\nimport { ApertoPortal } from \"../aperto-portal\";\nimport { ApertoRoot } from \"../aperto-root\";\nimport { ApertoTitle } from \"../aperto-title\";\nimport { ApertoTrigger } from \"../aperto-trigger\";\nimport { ApertoExpandedMedia, ApertoThumbnailMedia } from \"../media-rendering\";\nimport { getDescriptionProps, getMediaLabel } from \"../media-utils\";\nimport type { ApertoProps } from \"./aperto-types\";\n\nexport const ApertoSingle = ({\n classNames,\n dismissible,\n media,\n renderImage,\n renderVideo,\n}: ApertoProps) => {\n const label = getMediaLabel(media);\n const title = media.title ?? label;\n\n return (\n <ApertoRoot dismissible={dismissible}>\n <ApertoTrigger aria-label={`Open ${label}`} className={classNames?.thumbnail}>\n <ApertoThumbnailMedia item={media} renderImage={renderImage} renderVideo={renderVideo} />\n </ApertoTrigger>\n <ApertoPortal>\n <ApertoOverlay className={classNames?.overlay} />\n <ApertoContent className={classNames?.content} {...getDescriptionProps(media)}>\n <ApertoExpandedMedia item={media} renderImage={renderImage} renderVideo={renderVideo} />\n <ApertoTitle>{title}</ApertoTitle>\n {media.description === undefined || media.description === \"\" ? null : (\n <ApertoDescription>{media.description}</ApertoDescription>\n )}\n <ApertoClose aria-label=\"Close\" className={classNames?.closeButton} type=\"button\" />\n </ApertoContent>\n </ApertoPortal>\n </ApertoRoot>\n );\n};\n","\"use client\";\n\nimport { useApertoGroup } from \"../aperto-group-context\";\nimport { ApertoTrigger } from \"../aperto-trigger\";\nimport { ApertoThumbnailMedia } from \"../media-rendering\";\nimport { getMediaLabel } from \"../media-utils\";\nimport type { ApertoThumbnailProps } from \"./aperto-types\";\n\nexport const ApertoThumbnail = ({ children, className, index }: ApertoThumbnailProps) => {\n const group = useApertoGroup();\n const media = group.media[index];\n\n if (!media) {\n return null;\n }\n\n return (\n <ApertoTrigger\n active={group.index === index}\n aria-label={`Open ${getMediaLabel(media)}`}\n className={className ?? group.classNames?.thumbnail}\n onClick={() => {\n group.openAtIndex(index);\n }}\n ref={(node) => {\n group.registerThumbnail(index, node);\n }}\n sharedLayoutId={false}\n >\n {children ?? (\n <ApertoThumbnailMedia\n item={media}\n renderImage={group.renderImage}\n renderVideo={group.renderVideo}\n />\n )}\n </ApertoTrigger>\n );\n};\n","\"use client\";\n\n/**\n * Package: @patternmode/aperto\n *\n * Opinionated thumbnail-to-expanded media transitions.\n * Built on Radix Dialog + Motion.\n *\n * Inspired by Cambio (https://github.com/raphaelsalaja/cambio)\n * by Raphael Salaja.\n *\n * @example\n * ```tsx\n * import { Aperto } from \"@patternmode/aperto\";\n *\n * import { Aperto } from \"@patternmode/aperto\";\n * import \"@patternmode/aperto/styles.css\";\n *\n * <Aperto.Group media={media}>\n * {media.map((item, index) => (\n * <Aperto.Thumbnail key={item.id ?? item.src} index={index} />\n * ))}\n * </Aperto.Group>\n * ```\n */\n\nimport { ApertoGroup, ApertoSingle, ApertoThumbnail } from \"./aperto\";\nimport type { ApertoGroupProps, ApertoProps, ApertoThumbnailProps } from \"./aperto\";\nimport { ApertoClose } from \"./aperto-close\";\nimport { ApertoContent } from \"./aperto-content\";\nimport type { ApertoContentProps } from \"./aperto-content\";\nimport { ApertoDescription } from \"./aperto-description\";\nimport { ApertoOverlay } from \"./aperto-overlay\";\nimport type { ApertoOverlayProps } from \"./aperto-overlay\";\nimport { ApertoPortal } from \"./aperto-portal\";\nimport type { ApertoPortalProps } from \"./aperto-portal\";\nimport { ApertoRoot } from \"./aperto-root\";\nimport type { ApertoRootProps } from \"./aperto-root\";\nimport { ApertoTitle } from \"./aperto-title\";\nimport { ApertoTrigger } from \"./aperto-trigger\";\nimport type { ApertoTriggerProps } from \"./aperto-trigger\";\n\n/** Lower-level compound component namespace for advanced composition. */\nconst ApertoPrimitive = {\n Close: ApertoClose,\n Content: ApertoContent,\n Description: ApertoDescription,\n Overlay: ApertoOverlay,\n Portal: ApertoPortal,\n Root: ApertoRoot,\n Title: ApertoTitle,\n Trigger: ApertoTrigger,\n};\n\n/** Primary media-first component namespace. */\nconst Aperto = Object.assign(ApertoSingle, {\n Group: ApertoGroup,\n Primitive: ApertoPrimitive,\n Thumbnail: ApertoThumbnail,\n});\n\n// Preset system\nexport { PRESETS, resolvePreset } from \"./presets\";\n// Types\nexport type {\n ApertoClassNames,\n ApertoImageItem,\n ApertoMediaItem,\n ApertoVideoItem,\n DismissibleConfig,\n DragSpringConfig,\n MotionPreset,\n MotionPresetName,\n MotionProp,\n MotionVariants,\n NavigationMotionPresetName,\n RenderImage,\n RenderVideo,\n} from \"./types\";\n// Named exports for tree-shaking\nexport {\n Aperto,\n ApertoClose,\n ApertoContent,\n type ApertoContentProps,\n ApertoDescription,\n ApertoGroup,\n type ApertoGroupProps,\n ApertoOverlay,\n type ApertoOverlayProps,\n ApertoPortal,\n type ApertoPortalProps,\n ApertoPrimitive,\n type ApertoProps,\n ApertoRoot,\n type ApertoRootProps,\n ApertoThumbnail,\n type ApertoThumbnailProps,\n ApertoTitle,\n ApertoTrigger,\n type ApertoTriggerProps,\n};\n"],"mappings":"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","names":["useId","useRef","Dialog","jsx","createContext","use","Dialog","m","easings","jsx","m","Dialog","jsx","Dialog","useState","jsx","useState","Dialog","jsx","AnimatePresence","m","jsx","jsx","AnimatePresence","m","m","jsx","m","jsx","useRef","useId","Dialog","X","jsx","Dialog","m","jsx","m","jsx","jsxs","jsx"]}
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-leading:initial;--tw-font-weight:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}[data-slot=aperto-trigger]{border-radius:var(--aperto-radius,.5rem);border-style:var(--tw-border-style);padding:calc(var(--spacing,.25rem) * 0);text-align:left;--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-outline-style:none;cursor:zoom-in;transition-property:filter,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s));--tw-duration:.2s;--tw-ease:var(--ease-out,cubic-bezier(0, 0, .2, 1));transition-duration:.2s;transition-timing-function:var(--ease-out,cubic-bezier(0, 0, .2, 1));background-color:#0000;border-width:0;outline-style:none;display:block;position:relative;overflow:hidden}[data-slot=aperto-trigger]:hover{--tw-brightness:brightness(.96);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}[data-slot=aperto-trigger]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#fffc}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-trigger]:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-white,#fff) 80%, transparent)}}[data-slot=aperto-trigger]:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--color-black,#000)}[data-slot=aperto-trigger]>img,[data-slot=aperto-trigger]>video{object-fit:cover;width:100%;height:100%;display:block}[data-slot=aperto-trigger][data-aperto-active]>img,[data-slot=aperto-trigger][data-aperto-active]>video{visibility:hidden}[data-slot=aperto-overlay]{inset:calc(var(--spacing,.25rem) * 0);z-index:1000;background-color:#000c;position:fixed}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-overlay]{background-color:color-mix(in oklab, var(--color-black,#000) 80%, transparent)}}[data-slot=aperto-content]{z-index:1001;justify-content:center;align-items:center;gap:calc(var(--spacing,.25rem) * 3);border-radius:var(--aperto-radius,.5rem);width:fit-content;max-width:min(92vw,1200px);height:fit-content;max-height:min(90vh,920px);padding:calc(var(--spacing,.25rem) * 0);color:var(--color-white,#fff);--tw-outline-style:none;overscroll-behavior:contain;outline-style:none;flex-direction:column;display:flex;position:fixed;overflow:visible}[data-slot=aperto-content]>img,[data-slot=aperto-content]>video,[data-slot=aperto-content]>[data-slot=aperto-media]{border-radius:var(--aperto-radius,.5rem);aspect-ratio:var(--aperto-expanded-aspect-ratio,3 / 2);max-width:90vw;height:auto;max-height:calc(100dvh - 8rem);width:min(var(--aperto-expanded-width,76vw), calc((100dvh - 8rem) * ( var(--aperto-expanded-aspect-ratio-width,3) / var(--aperto-expanded-aspect-ratio-height,2) )), 1000px, 90vw);display:block}[data-slot=aperto-media]{position:relative;overflow:hidden}[data-slot=aperto-media]>img,[data-slot=aperto-media]>video,[data-slot=aperto-media-stage]>img,[data-slot=aperto-media-stage]>video,[data-slot=aperto-transition-media]>img,[data-slot=aperto-transition-media]>video{width:100%;height:100%;display:block}[data-slot=aperto-media-stage]{inset:calc(var(--spacing,.25rem) * 0);position:absolute}[data-slot=aperto-content][data-aperto-transition] [data-slot=aperto-media-stage],[data-slot=aperto-transition-media]{will-change:opacity, transform}[data-slot=aperto-content][data-aperto-transition]>*{opacity:0}@keyframes aperto-control-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-close],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-media]>[data-slot=aperto-previous-button],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-media]>[data-slot=aperto-next-button]{animation:.35s cubic-bezier(.25,.1,.12,1) 80ms both aperto-control-in}[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-title],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-description],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-counter]{animation:.4s cubic-bezier(.25,.1,.12,1) .18s both aperto-control-in}[data-slot=aperto-title]{text-align:center;--tw-leading:var(--leading-snug,1.375);max-width:60ch;font-size:13px;line-height:var(--leading-snug,1.375);--tw-font-weight:var(--font-weight-medium,500);font-weight:var(--font-weight-medium,500);color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-title]{color:color-mix(in oklab, var(--color-white,#fff) 90%, transparent)}}[data-slot=aperto-description]{margin-top:calc(var(--spacing,.25rem) * -1.5);text-align:center;--tw-leading:var(--leading-snug,1.375);max-width:60ch;font-size:13px;line-height:var(--leading-snug,1.375);color:#fff9}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-description]{color:color-mix(in oklab, var(--color-white,#fff) 60%, transparent)}}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{z-index:10;width:calc(var(--spacing,.25rem) * 8);height:calc(var(--spacing,.25rem) * 8);border-style:var(--tw-border-style);background-color:#ffffff1a;border-width:0;border-radius:3.40282e38px;place-items:center;display:grid;position:absolute}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{background-color:color-mix(in oklab, var(--color-white,#fff) 10%, transparent)}}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{color:color-mix(in oklab, var(--color-white,#fff) 70%, transparent)}}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{transition-property:background,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s));--tw-duration:.15s;--tw-ease:var(--ease-out,cubic-bezier(0, 0, .2, 1));transition-duration:.15s;transition-timing-function:var(--ease-out,cubic-bezier(0, 0, .2, 1))}@media (hover:hover) and (pointer:fine){[data-slot=aperto-close]:hover,[data-slot=aperto-previous-button]:hover,[data-slot=aperto-next-button]:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close]:hover,[data-slot=aperto-previous-button]:hover,[data-slot=aperto-next-button]:hover{background-color:color-mix(in oklab, var(--color-white,#fff) 20%, transparent)}}[data-slot=aperto-close]:hover,[data-slot=aperto-previous-button]:hover,[data-slot=aperto-next-button]:hover{color:var(--color-white,#fff)}}[data-slot=aperto-close]:focus-visible,[data-slot=aperto-previous-button]:focus-visible,[data-slot=aperto-next-button]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#fff9}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close]:focus-visible,[data-slot=aperto-previous-button]:focus-visible,[data-slot=aperto-next-button]:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-white,#fff) 60%, transparent)}}[data-slot=aperto-close]:focus-visible,[data-slot=aperto-previous-button]:focus-visible,[data-slot=aperto-next-button]:focus-visible{--tw-outline-style:none;outline-style:none}[data-slot=aperto-close]{top:calc(var(--spacing,.25rem) * 3);right:calc(var(--spacing,.25rem) * 3)}[data-slot=aperto-previous-button]{top:50%;left:calc(var(--spacing,.25rem) * 3);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-slot=aperto-next-button]{top:50%;right:calc(var(--spacing,.25rem) * 3);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-slot=aperto-close]>svg,[data-slot=aperto-previous-button]>svg,[data-slot=aperto-next-button]>svg{pointer-events:none;width:calc(var(--spacing,.25rem) * 4);height:calc(var(--spacing,.25rem) * 4)}[data-slot=aperto-counter]{background-color:#ffffff1a;border-radius:3.40282e38px}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-counter]{background-color:color-mix(in oklab, var(--color-white,#fff) 10%, transparent)}}[data-slot=aperto-counter]{padding-inline:calc(var(--spacing,.25rem) * 2.5);padding-block:calc(var(--spacing,.25rem) * .5);--tw-font-weight:var(--font-weight-medium,500);font-size:11px;font-weight:var(--font-weight-medium,500);color:#ffffff80}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-counter]{color:color-mix(in oklab, var(--color-white,#fff) 50%, transparent)}}@media (max-width:560px){[data-slot=aperto-content]{gap:calc(var(--spacing,.25rem) * 2);max-width:calc(100vw - 1rem)}[data-slot=aperto-content]>img,[data-slot=aperto-content]>video,[data-slot=aperto-content]>[data-slot=aperto-media]{width:min(100vw - 2rem,150dvh - 18rem);max-width:calc(100vw - 2rem);max-height:calc(100dvh - 12rem)}[data-slot=aperto-title],[data-slot=aperto-description]{max-width:calc(100vw - 2rem)}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{width:calc(var(--spacing,.25rem) * 11);height:calc(var(--spacing,.25rem) * 11);touch-action:manipulation}[data-slot=aperto-close]{top:calc(var(--spacing,.25rem) * 2);right:calc(var(--spacing,.25rem) * 2)}[data-slot=aperto-previous-button]{left:calc(var(--spacing,.25rem) * 2)}[data-slot=aperto-next-button]{right:calc(var(--spacing,.25rem) * 2)}}@media (prefers-reduced-motion:reduce){[data-slot=aperto-content]:not([data-aperto-transition])>*{animation:none!important}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-leading:initial;--tw-font-weight:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}[data-slot=aperto-trigger]{border-radius:var(--aperto-radius,.5rem);border-style:var(--tw-border-style);padding:calc(var(--spacing,.25rem) * 0);text-align:left;--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-outline-style:none;cursor:zoom-in;transition-property:filter,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s));--tw-duration:.2s;--tw-ease:var(--ease-out,cubic-bezier(0, 0, .2, 1));transition-duration:.2s;transition-timing-function:var(--ease-out,cubic-bezier(0, 0, .2, 1));background-color:#0000;border-width:0;outline-style:none;display:block;position:relative;overflow:hidden}[data-slot=aperto-trigger]:hover{--tw-brightness:brightness(.96);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}[data-slot=aperto-trigger]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#fffc}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-trigger]:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-white,#fff) 80%, transparent)}}[data-slot=aperto-trigger]:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--color-black,#000)}[data-slot=aperto-trigger]>img,[data-slot=aperto-trigger]>video{object-fit:cover;width:100%;height:100%;display:block}[data-slot=aperto-trigger][data-aperto-active]>img,[data-slot=aperto-trigger][data-aperto-active]>video{visibility:hidden}[data-slot=aperto-overlay]{inset:calc(var(--spacing,.25rem) * 0);z-index:1000;background-color:#000c;position:fixed}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-overlay]{background-color:color-mix(in oklab, var(--color-black,#000) 80%, transparent)}}[data-slot=aperto-content]{z-index:1001;justify-content:center;align-items:center;gap:calc(var(--spacing,.25rem) * 3);border-radius:var(--aperto-radius,.5rem);width:fit-content;max-width:min(92vw,1200px);height:fit-content;max-height:min(90vh,920px);padding:calc(var(--spacing,.25rem) * 0);color:var(--color-white,#fff);--tw-outline-style:none;overscroll-behavior:contain;outline-style:none;flex-direction:column;display:flex;position:fixed;overflow:visible}[data-slot=aperto-content]>img,[data-slot=aperto-content]>video,[data-slot=aperto-content]>[data-slot=aperto-media]{border-radius:var(--aperto-radius,.5rem);aspect-ratio:var(--aperto-expanded-aspect-ratio,3 / 2);max-width:90vw;height:auto;max-height:calc(100dvh - 8rem);width:min(var(--aperto-expanded-width,76vw), calc((100dvh - 8rem) * ( var(--aperto-expanded-aspect-ratio-width,3) / var(--aperto-expanded-aspect-ratio-height,2) )), 1000px, 90vw);display:block}[data-slot=aperto-media]{position:relative;overflow:hidden}[data-slot=aperto-media]>img,[data-slot=aperto-media]>video,[data-slot=aperto-media-stage]>img,[data-slot=aperto-media-stage]>video,[data-slot=aperto-transition-media]>img,[data-slot=aperto-transition-media]>video{width:100%;height:100%;display:block}[data-slot=aperto-media-stage]{inset:calc(var(--spacing,.25rem) * 0);position:absolute}[data-slot=aperto-content][data-aperto-transition] [data-slot=aperto-media-stage],[data-slot=aperto-transition-media]{will-change:opacity, transform}[data-slot=aperto-content][data-aperto-transition]>*{pointer-events:none;opacity:0}@keyframes aperto-control-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-close],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-media]>[data-slot=aperto-previous-button],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-media]>[data-slot=aperto-next-button]{animation:.35s cubic-bezier(.25,.1,.12,1) 80ms both aperto-control-in}[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-title],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-description],[data-slot=aperto-content]:not([data-aperto-transition])>[data-slot=aperto-counter]{animation:.4s cubic-bezier(.25,.1,.12,1) .18s both aperto-control-in}[data-slot=aperto-title]{text-align:center;--tw-leading:var(--leading-snug,1.375);max-width:60ch;font-size:13px;line-height:var(--leading-snug,1.375);--tw-font-weight:var(--font-weight-medium,500);font-weight:var(--font-weight-medium,500);color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-title]{color:color-mix(in oklab, var(--color-white,#fff) 90%, transparent)}}[data-slot=aperto-description]{margin-top:calc(var(--spacing,.25rem) * -1.5);text-align:center;--tw-leading:var(--leading-snug,1.375);max-width:60ch;font-size:13px;line-height:var(--leading-snug,1.375);color:#fff9}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-description]{color:color-mix(in oklab, var(--color-white,#fff) 60%, transparent)}}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{z-index:10;width:calc(var(--spacing,.25rem) * 8);height:calc(var(--spacing,.25rem) * 8);border-style:var(--tw-border-style);background-color:#ffffff1a;border-width:0;border-radius:3.40282e38px;place-items:center;display:grid;position:absolute}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{background-color:color-mix(in oklab, var(--color-white,#fff) 10%, transparent)}}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{color:color-mix(in oklab, var(--color-white,#fff) 70%, transparent)}}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{transition-property:background,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s));--tw-duration:.15s;--tw-ease:var(--ease-out,cubic-bezier(0, 0, .2, 1));transition-duration:.15s;transition-timing-function:var(--ease-out,cubic-bezier(0, 0, .2, 1))}@media (hover:hover) and (pointer:fine){[data-slot=aperto-close]:hover,[data-slot=aperto-previous-button]:hover,[data-slot=aperto-next-button]:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close]:hover,[data-slot=aperto-previous-button]:hover,[data-slot=aperto-next-button]:hover{background-color:color-mix(in oklab, var(--color-white,#fff) 20%, transparent)}}[data-slot=aperto-close]:hover,[data-slot=aperto-previous-button]:hover,[data-slot=aperto-next-button]:hover{color:var(--color-white,#fff)}}[data-slot=aperto-close]:focus-visible,[data-slot=aperto-previous-button]:focus-visible,[data-slot=aperto-next-button]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#fff9}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-close]:focus-visible,[data-slot=aperto-previous-button]:focus-visible,[data-slot=aperto-next-button]:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-white,#fff) 60%, transparent)}}[data-slot=aperto-close]:focus-visible,[data-slot=aperto-previous-button]:focus-visible,[data-slot=aperto-next-button]:focus-visible{--tw-outline-style:none;outline-style:none}[data-slot=aperto-close]{top:calc(var(--spacing,.25rem) * 3);right:calc(var(--spacing,.25rem) * 3)}[data-slot=aperto-previous-button]{top:50%;left:calc(var(--spacing,.25rem) * 3);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-slot=aperto-next-button]{top:50%;right:calc(var(--spacing,.25rem) * 3);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-slot=aperto-close]>svg,[data-slot=aperto-previous-button]>svg,[data-slot=aperto-next-button]>svg{pointer-events:none;width:calc(var(--spacing,.25rem) * 4);height:calc(var(--spacing,.25rem) * 4)}[data-slot=aperto-counter]{background-color:#ffffff1a;border-radius:3.40282e38px}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-counter]{background-color:color-mix(in oklab, var(--color-white,#fff) 10%, transparent)}}[data-slot=aperto-counter]{padding-inline:calc(var(--spacing,.25rem) * 2.5);padding-block:calc(var(--spacing,.25rem) * .5);--tw-font-weight:var(--font-weight-medium,500);font-size:11px;font-weight:var(--font-weight-medium,500);color:#ffffff80}@supports (color:color-mix(in lab, red, red)){[data-slot=aperto-counter]{color:color-mix(in oklab, var(--color-white,#fff) 50%, transparent)}}@media (max-width:560px){[data-slot=aperto-content]{gap:calc(var(--spacing,.25rem) * 2);max-width:calc(100vw - 1rem)}[data-slot=aperto-content]>img,[data-slot=aperto-content]>video,[data-slot=aperto-content]>[data-slot=aperto-media]{width:min(100vw - 2rem,150dvh - 18rem);max-width:calc(100vw - 2rem);max-height:calc(100dvh - 12rem)}[data-slot=aperto-title],[data-slot=aperto-description]{max-width:calc(100vw - 2rem)}[data-slot=aperto-close],[data-slot=aperto-previous-button],[data-slot=aperto-next-button]{width:calc(var(--spacing,.25rem) * 11);height:calc(var(--spacing,.25rem) * 11);touch-action:manipulation}[data-slot=aperto-close]{top:calc(var(--spacing,.25rem) * 2);right:calc(var(--spacing,.25rem) * 2)}[data-slot=aperto-previous-button]{left:calc(var(--spacing,.25rem) * 2)}[data-slot=aperto-next-button]{right:calc(var(--spacing,.25rem) * 2)}}@media (prefers-reduced-motion:reduce){[data-slot=aperto-content]:not([data-aperto-transition])>*{animation:none!important}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternmode/aperto",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Opinionated, styled thumbnail-to-expanded media transitions for React.",
5
5
  "homepage": "https://github.com/howells/patternmode/tree/main/packages/aperto#readme",
6
6
  "bugs": {
@@ -34,26 +34,27 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@radix-ui/react-dialog": "^1.1.15",
37
- "lucide-react": "^1.16.0",
38
- "motion": "^12.38.0"
37
+ "lucide-react": "^1.17.0",
38
+ "motion": "^12.40.0",
39
+ "@howells/motion": "0.1.0"
39
40
  },
40
41
  "devDependencies": {
41
- "@howells/lint": "^0.2.1",
42
- "@howells/typescript-config": "^0.1.2",
42
+ "@howells/lint": "^0.5.0",
43
+ "@howells/typescript-config": "^0.1.6",
43
44
  "@tailwindcss/cli": "^4.3.0",
44
45
  "@testing-library/jest-dom": "^6.9.1",
45
46
  "@testing-library/react": "^16.3.2",
46
47
  "@testing-library/user-event": "^14.6.1",
47
- "@types/react": "^19.2.14",
48
+ "@types/react": "^19.2.17",
48
49
  "@types/react-dom": "^19.2.3",
49
50
  "concurrently": "^9.2.1",
50
51
  "jsdom": "^29.1.1",
51
- "react": "^19.2.3",
52
- "react-dom": "^19.2.3",
52
+ "react": "^19.2.7",
53
+ "react-dom": "^19.2.7",
53
54
  "tailwindcss": "^4.3.0",
54
55
  "tsup": "^8.5.1",
55
56
  "typescript": "^6.0.3",
56
- "vitest": "^4.1.6"
57
+ "vitest": "^4.1.8"
57
58
  },
58
59
  "peerDependencies": {
59
60
  "react": "^19.0.0",
@@ -65,8 +66,8 @@
65
66
  "dev": "concurrently \"pnpm dev:js\" \"pnpm dev:styles\"",
66
67
  "dev:js": "tsup --watch",
67
68
  "dev:styles": "tailwindcss -i styles.css -o dist/styles.css --watch",
68
- "lint": "howells-ox-check .",
69
- "lint:fix": "howells-ox-fix .",
69
+ "lint": "howells-check .",
70
+ "lint:fix": "howells-fix .",
70
71
  "test": "vitest run --passWithNoTests",
71
72
  "typecheck": "tsc --noEmit"
72
73
  }