@patternmode/aperto 0.1.2 → 0.1.4
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 +1 -0
- package/dist/index.js +281 -185
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +20 -17
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -6,16 +6,15 @@ import {
|
|
|
6
6
|
useCallback as useCallback3,
|
|
7
7
|
useId as useId2,
|
|
8
8
|
useLayoutEffect,
|
|
9
|
-
useMemo as
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
useMemo as useMemo3,
|
|
10
|
+
useReducer,
|
|
11
|
+
useRef
|
|
12
12
|
} from "react";
|
|
13
|
-
import { flushSync } from "react-dom";
|
|
14
13
|
|
|
15
14
|
// src/aperto-content.tsx
|
|
16
15
|
import * as Dialog from "@radix-ui/react-dialog";
|
|
17
16
|
import {
|
|
18
|
-
|
|
17
|
+
m,
|
|
19
18
|
useMotionValue,
|
|
20
19
|
useSpring,
|
|
21
20
|
useTransform
|
|
@@ -211,7 +210,7 @@ var ApertoContent = forwardRef(
|
|
|
211
210
|
]
|
|
212
211
|
);
|
|
213
212
|
return /* @__PURE__ */ jsx(Dialog.Content, { asChild: true, forceMount: true, ...props, children: /* @__PURE__ */ jsx(
|
|
214
|
-
|
|
213
|
+
m.div,
|
|
215
214
|
{
|
|
216
215
|
className,
|
|
217
216
|
"data-slot": "aperto-content",
|
|
@@ -258,7 +257,7 @@ function useApertoGroup() {
|
|
|
258
257
|
|
|
259
258
|
// src/aperto-overlay.tsx
|
|
260
259
|
import * as Dialog3 from "@radix-ui/react-dialog";
|
|
261
|
-
import {
|
|
260
|
+
import { m as m2 } from "motion/react";
|
|
262
261
|
import { forwardRef as forwardRef3 } from "react";
|
|
263
262
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
264
263
|
var OVERLAY_TRANSITION = {
|
|
@@ -274,7 +273,7 @@ var ApertoOverlay = forwardRef3(
|
|
|
274
273
|
const ctx = useApertoContext();
|
|
275
274
|
const transition = ctx.reduceMotion ? OVERLAY_TRANSITION_REDUCED : OVERLAY_TRANSITION;
|
|
276
275
|
return /* @__PURE__ */ jsx3(Dialog3.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsx3(
|
|
277
|
-
|
|
276
|
+
m2.div,
|
|
278
277
|
{
|
|
279
278
|
animate: { opacity: fadeOut ? 0 : 1 },
|
|
280
279
|
className,
|
|
@@ -301,10 +300,16 @@ function ApertoPortal({ children, container }) {
|
|
|
301
300
|
|
|
302
301
|
// src/aperto-root.tsx
|
|
303
302
|
import * as Dialog5 from "@radix-ui/react-dialog";
|
|
304
|
-
import {
|
|
303
|
+
import {
|
|
304
|
+
domMax,
|
|
305
|
+
LayoutGroup,
|
|
306
|
+
LazyMotion,
|
|
307
|
+
useReducedMotion
|
|
308
|
+
} from "motion/react";
|
|
305
309
|
import {
|
|
306
310
|
useCallback as useCallback2,
|
|
307
311
|
useId,
|
|
312
|
+
useMemo as useMemo2,
|
|
308
313
|
useState as useState2
|
|
309
314
|
} from "react";
|
|
310
315
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
@@ -338,22 +343,29 @@ function ApertoRoot({
|
|
|
338
343
|
const variants = typeof motionProp === "object" ? motionProp : void 0;
|
|
339
344
|
const presetName = shouldReduce ? "reduced" : globalPresetName;
|
|
340
345
|
const preset = PRESETS[presetName];
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
346
|
+
const contextValue = useMemo2(
|
|
347
|
+
() => ({
|
|
348
|
+
dismissible,
|
|
349
|
+
layoutId,
|
|
350
|
+
onOpenChange,
|
|
351
|
+
open,
|
|
352
|
+
preset,
|
|
353
|
+
presetName,
|
|
354
|
+
reduceMotion: shouldReduce,
|
|
355
|
+
variants
|
|
356
|
+
}),
|
|
357
|
+
[
|
|
358
|
+
dismissible,
|
|
359
|
+
layoutId,
|
|
360
|
+
onOpenChange,
|
|
361
|
+
open,
|
|
362
|
+
preset,
|
|
363
|
+
presetName,
|
|
364
|
+
shouldReduce,
|
|
365
|
+
variants
|
|
366
|
+
]
|
|
356
367
|
);
|
|
368
|
+
return /* @__PURE__ */ jsx5(ApertoContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx5(Dialog5.Root, { onOpenChange, open, ...dialogProps, children: /* @__PURE__ */ jsx5(LazyMotion, { features: domMax, children: /* @__PURE__ */ jsx5(LayoutGroup, { id: layoutId, children }) }) }) });
|
|
357
369
|
}
|
|
358
370
|
|
|
359
371
|
// src/aperto-title.tsx
|
|
@@ -368,32 +380,31 @@ ApertoTitle.displayName = "ApertoTitle";
|
|
|
368
380
|
// src/expanded-media-stage.tsx
|
|
369
381
|
import {
|
|
370
382
|
AnimatePresence as AnimatePresence2,
|
|
371
|
-
|
|
383
|
+
m as m3
|
|
372
384
|
} from "motion/react";
|
|
373
385
|
|
|
374
386
|
// src/media-rendering.tsx
|
|
387
|
+
import { createElement } from "react";
|
|
375
388
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
376
|
-
function getMediaLabel(item) {
|
|
377
|
-
return item.title ?? item.alt ?? "media";
|
|
378
|
-
}
|
|
379
|
-
function getMediaKey(item, index) {
|
|
380
|
-
return item.id ?? `${item.type}:${item.src}:${index}`;
|
|
381
|
-
}
|
|
382
|
-
function getDescriptionProps(item) {
|
|
383
|
-
return item.description ? {} : { "aria-describedby": void 0 };
|
|
384
|
-
}
|
|
385
389
|
function renderDefaultImage(props) {
|
|
386
390
|
const { item: _item, variant: _variant, ...imageProps } = props;
|
|
387
|
-
return
|
|
391
|
+
return createElement("img", { ...imageProps, alt: imageProps.alt ?? "" });
|
|
388
392
|
}
|
|
389
393
|
function renderDefaultVideo(props) {
|
|
390
394
|
const { item: _item, variant, ...videoProps } = props;
|
|
391
395
|
if (variant === "thumbnail") {
|
|
392
|
-
return
|
|
396
|
+
return createElement("img", {
|
|
397
|
+
alt: videoProps["aria-label"] ?? "",
|
|
398
|
+
src: props.item.thumbnailSrc
|
|
399
|
+
});
|
|
393
400
|
}
|
|
394
|
-
return /* @__PURE__ */ jsx7("video", { ...videoProps });
|
|
401
|
+
return /* @__PURE__ */ jsx7("video", { ...videoProps, children: /* @__PURE__ */ jsx7("track", { kind: "captions", src: props.item.captionsSrc ?? "data:text/vtt," }) });
|
|
395
402
|
}
|
|
396
|
-
function
|
|
403
|
+
function ApertoThumbnailMedia({
|
|
404
|
+
item,
|
|
405
|
+
renderImage,
|
|
406
|
+
renderVideo
|
|
407
|
+
}) {
|
|
397
408
|
if (item.type === "image") {
|
|
398
409
|
const imageProps = {
|
|
399
410
|
alt: "",
|
|
@@ -416,7 +427,11 @@ function renderThumbnail(item, renderImage, renderVideo) {
|
|
|
416
427
|
};
|
|
417
428
|
return (renderVideo ?? renderDefaultVideo)(videoProps);
|
|
418
429
|
}
|
|
419
|
-
function
|
|
430
|
+
function ApertoExpandedMedia({
|
|
431
|
+
item,
|
|
432
|
+
renderImage,
|
|
433
|
+
renderVideo
|
|
434
|
+
}) {
|
|
420
435
|
if (item.type === "image") {
|
|
421
436
|
const imageProps = {
|
|
422
437
|
alt: item.alt,
|
|
@@ -440,7 +455,11 @@ function renderExpandedMedia(item, renderImage, renderVideo) {
|
|
|
440
455
|
};
|
|
441
456
|
return (renderVideo ?? renderDefaultVideo)(videoProps);
|
|
442
457
|
}
|
|
443
|
-
function
|
|
458
|
+
function ApertoTransitionMedia({
|
|
459
|
+
item,
|
|
460
|
+
renderImage,
|
|
461
|
+
renderVideo
|
|
462
|
+
}) {
|
|
444
463
|
if (item.type === "image") {
|
|
445
464
|
const imageProps = {
|
|
446
465
|
alt: item.alt,
|
|
@@ -464,6 +483,17 @@ function renderTransitionMedia(item, renderImage, renderVideo) {
|
|
|
464
483
|
return (renderVideo ?? renderDefaultVideo)(videoProps);
|
|
465
484
|
}
|
|
466
485
|
|
|
486
|
+
// src/media-utils.ts
|
|
487
|
+
function getMediaLabel(item) {
|
|
488
|
+
return item.title ?? item.alt ?? "media";
|
|
489
|
+
}
|
|
490
|
+
function getMediaKey(item, index) {
|
|
491
|
+
return item.id ?? `${item.type}:${item.src}:${index}`;
|
|
492
|
+
}
|
|
493
|
+
function getDescriptionProps(item) {
|
|
494
|
+
return item.description ? {} : { "aria-describedby": void 0 };
|
|
495
|
+
}
|
|
496
|
+
|
|
467
497
|
// src/expanded-media-stage.tsx
|
|
468
498
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
469
499
|
var NAVIGATION_MOTION_PRESETS = {
|
|
@@ -556,7 +586,7 @@ function ApertoExpandedMediaStage({
|
|
|
556
586
|
scale: preset.scale
|
|
557
587
|
};
|
|
558
588
|
return /* @__PURE__ */ jsx8(AnimatePresence2, { custom: animationCustom, initial: false, mode: "sync", children: /* @__PURE__ */ jsx8(
|
|
559
|
-
|
|
589
|
+
m3.div,
|
|
560
590
|
{
|
|
561
591
|
animate: "center",
|
|
562
592
|
custom: animationCustom,
|
|
@@ -567,18 +597,24 @@ function ApertoExpandedMediaStage({
|
|
|
567
597
|
initial: "enter",
|
|
568
598
|
transition,
|
|
569
599
|
variants,
|
|
570
|
-
children:
|
|
600
|
+
children: /* @__PURE__ */ jsx8(
|
|
601
|
+
ApertoExpandedMedia,
|
|
602
|
+
{
|
|
603
|
+
item,
|
|
604
|
+
renderImage,
|
|
605
|
+
renderVideo
|
|
606
|
+
}
|
|
607
|
+
)
|
|
571
608
|
},
|
|
572
609
|
getMediaKey(item, index)
|
|
573
610
|
) });
|
|
574
611
|
}
|
|
575
612
|
|
|
576
613
|
// src/media-transition.tsx
|
|
577
|
-
import {
|
|
578
|
-
motion as motion4
|
|
579
|
-
} from "motion/react";
|
|
614
|
+
import { m as m4 } from "motion/react";
|
|
580
615
|
import { useEffect } from "react";
|
|
581
|
-
|
|
616
|
+
|
|
617
|
+
// src/media-transition-utils.ts
|
|
582
618
|
function rectFromElement(element) {
|
|
583
619
|
if (!element) {
|
|
584
620
|
return null;
|
|
@@ -602,6 +638,9 @@ function rectTarget(rect) {
|
|
|
602
638
|
function transitionDurationMs(transition) {
|
|
603
639
|
return typeof transition.duration === "number" ? transition.duration * 1e3 : 450;
|
|
604
640
|
}
|
|
641
|
+
|
|
642
|
+
// src/media-transition.tsx
|
|
643
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
605
644
|
function ApertoMediaTransitionClone({
|
|
606
645
|
onComplete,
|
|
607
646
|
renderImage,
|
|
@@ -623,7 +662,7 @@ function ApertoMediaTransitionClone({
|
|
|
623
662
|
return null;
|
|
624
663
|
}
|
|
625
664
|
return /* @__PURE__ */ jsx9(
|
|
626
|
-
|
|
665
|
+
m4.div,
|
|
627
666
|
{
|
|
628
667
|
animate: rectTarget(transition.to),
|
|
629
668
|
"aria-hidden": "true",
|
|
@@ -634,15 +673,81 @@ function ApertoMediaTransitionClone({
|
|
|
634
673
|
overflow: "hidden",
|
|
635
674
|
pointerEvents: "none",
|
|
636
675
|
position: "fixed",
|
|
637
|
-
|
|
638
|
-
zIndex: 1002
|
|
676
|
+
zIndex: 30
|
|
639
677
|
},
|
|
640
678
|
transition: ctx.preset.transition,
|
|
641
|
-
children:
|
|
679
|
+
children: /* @__PURE__ */ jsx9(
|
|
680
|
+
ApertoTransitionMedia,
|
|
681
|
+
{
|
|
682
|
+
item: transition.item,
|
|
683
|
+
renderImage,
|
|
684
|
+
renderVideo
|
|
685
|
+
}
|
|
686
|
+
)
|
|
642
687
|
}
|
|
643
688
|
);
|
|
644
689
|
}
|
|
645
690
|
|
|
691
|
+
// src/Aperto/ApertoGroupState.ts
|
|
692
|
+
function getInitialGroupState(initialIndex) {
|
|
693
|
+
return {
|
|
694
|
+
closing: false,
|
|
695
|
+
internalIndex: initialIndex,
|
|
696
|
+
layoutSourceIndex: initialIndex,
|
|
697
|
+
mediaTransition: null,
|
|
698
|
+
navigationDirection: 0,
|
|
699
|
+
open: false
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
function apertoGroupReducer(state, action) {
|
|
703
|
+
switch (action.type) {
|
|
704
|
+
case "close-without-transition":
|
|
705
|
+
return { ...state, closing: false, mediaTransition: null, open: false };
|
|
706
|
+
case "complete-opening-target":
|
|
707
|
+
if (state.mediaTransition?.phase !== "opening" || state.mediaTransition.to) {
|
|
708
|
+
return state;
|
|
709
|
+
}
|
|
710
|
+
return {
|
|
711
|
+
...state,
|
|
712
|
+
mediaTransition: { ...state.mediaTransition, to: action.rect }
|
|
713
|
+
};
|
|
714
|
+
case "finish-transition":
|
|
715
|
+
return {
|
|
716
|
+
...state,
|
|
717
|
+
closing: false,
|
|
718
|
+
mediaTransition: null,
|
|
719
|
+
open: state.mediaTransition?.phase === "closing" ? false : state.open
|
|
720
|
+
};
|
|
721
|
+
case "navigate":
|
|
722
|
+
return {
|
|
723
|
+
...state,
|
|
724
|
+
internalIndex: action.index,
|
|
725
|
+
layoutSourceIndex: action.index,
|
|
726
|
+
navigationDirection: action.direction
|
|
727
|
+
};
|
|
728
|
+
case "open-at-index":
|
|
729
|
+
return {
|
|
730
|
+
...state,
|
|
731
|
+
closing: false,
|
|
732
|
+
internalIndex: action.index,
|
|
733
|
+
layoutSourceIndex: action.index,
|
|
734
|
+
mediaTransition: action.transition,
|
|
735
|
+
navigationDirection: 0,
|
|
736
|
+
open: true
|
|
737
|
+
};
|
|
738
|
+
case "set-index":
|
|
739
|
+
return { ...state, internalIndex: action.index };
|
|
740
|
+
case "set-open":
|
|
741
|
+
return action.open ? { ...state, closing: false, open: true } : { ...state, open: false };
|
|
742
|
+
case "start-close":
|
|
743
|
+
return {
|
|
744
|
+
...state,
|
|
745
|
+
closing: true,
|
|
746
|
+
mediaTransition: action.transition
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
646
751
|
// src/Aperto/ApertoKeyboard.ts
|
|
647
752
|
function shouldIgnoreKeyboardNavigationTarget(target) {
|
|
648
753
|
if (!(target instanceof Element)) {
|
|
@@ -671,33 +776,31 @@ function ApertoGroup({
|
|
|
671
776
|
renderVideo
|
|
672
777
|
}) {
|
|
673
778
|
const generatedId = useId2();
|
|
674
|
-
const [
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
779
|
+
const [state, dispatch] = useReducer(
|
|
780
|
+
apertoGroupReducer,
|
|
781
|
+
initialIndex,
|
|
782
|
+
getInitialGroupState
|
|
783
|
+
);
|
|
679
784
|
const isControlled = controlledIndex !== void 0;
|
|
680
|
-
const index = isControlled ? controlledIndex : internalIndex;
|
|
785
|
+
const index = isControlled ? controlledIndex : state.internalIndex;
|
|
681
786
|
const activeMedia = media[index] ?? media[0];
|
|
682
|
-
const [layoutSourceIndex, setLayoutSourceIndex] = useState3(index);
|
|
683
787
|
const expandedMediaRef = useRef(null);
|
|
684
|
-
const thumbnailRefs = useRef(
|
|
788
|
+
const thumbnailRefs = useRef(null);
|
|
789
|
+
if (thumbnailRefs.current === null) {
|
|
790
|
+
thumbnailRefs.current = /* @__PURE__ */ new Map();
|
|
791
|
+
}
|
|
792
|
+
const thumbnailMap = thumbnailRefs.current;
|
|
685
793
|
const sharedLayoutIdForIndex = useCallback3(
|
|
686
794
|
(nextIndex) => `aperto-group-${generatedId}-${nextIndex}-shared`,
|
|
687
795
|
[generatedId]
|
|
688
796
|
);
|
|
689
|
-
const sharedLayoutId = sharedLayoutIdForIndex(layoutSourceIndex);
|
|
797
|
+
const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);
|
|
690
798
|
const measureOpeningTarget = useCallback3((node) => {
|
|
691
799
|
const targetRect = rectFromElement(node);
|
|
692
800
|
if (!targetRect) {
|
|
693
801
|
return;
|
|
694
802
|
}
|
|
695
|
-
|
|
696
|
-
if (current?.phase !== "opening" || current.to) {
|
|
697
|
-
return current;
|
|
698
|
-
}
|
|
699
|
-
return { ...current, to: targetRect };
|
|
700
|
-
});
|
|
803
|
+
dispatch({ rect: targetRect, type: "complete-opening-target" });
|
|
701
804
|
}, []);
|
|
702
805
|
const setExpandedMediaNode = useCallback3(
|
|
703
806
|
(node) => {
|
|
@@ -711,23 +814,23 @@ function ApertoGroup({
|
|
|
711
814
|
const registerThumbnail = useCallback3(
|
|
712
815
|
(thumbIndex, node) => {
|
|
713
816
|
if (node) {
|
|
714
|
-
|
|
817
|
+
thumbnailMap.set(thumbIndex, node);
|
|
715
818
|
return;
|
|
716
819
|
}
|
|
717
|
-
|
|
820
|
+
thumbnailMap.delete(thumbIndex);
|
|
718
821
|
},
|
|
719
|
-
[]
|
|
822
|
+
[thumbnailMap]
|
|
720
823
|
);
|
|
721
824
|
useLayoutEffect(() => {
|
|
722
|
-
if (mediaTransition?.phase !== "opening" || mediaTransition.to || !expandedMediaRef.current) {
|
|
825
|
+
if (state.mediaTransition?.phase !== "opening" || state.mediaTransition.to || !expandedMediaRef.current) {
|
|
723
826
|
return;
|
|
724
827
|
}
|
|
725
828
|
measureOpeningTarget(expandedMediaRef.current);
|
|
726
|
-
}, [measureOpeningTarget, mediaTransition]);
|
|
829
|
+
}, [measureOpeningTarget, state.mediaTransition]);
|
|
727
830
|
const setIndex = useCallback3(
|
|
728
831
|
(nextIndex) => {
|
|
729
832
|
if (!isControlled) {
|
|
730
|
-
|
|
833
|
+
dispatch({ index: nextIndex, type: "set-index" });
|
|
731
834
|
}
|
|
732
835
|
onIndexChange?.(nextIndex);
|
|
733
836
|
},
|
|
@@ -735,78 +838,60 @@ function ApertoGroup({
|
|
|
735
838
|
);
|
|
736
839
|
const openAtIndex = useCallback3(
|
|
737
840
|
(thumbIndex) => {
|
|
738
|
-
const sourceRect = rectFromElement(
|
|
739
|
-
thumbnailRefs.current.get(thumbIndex) ?? null
|
|
740
|
-
);
|
|
841
|
+
const sourceRect = rectFromElement(thumbnailMap.get(thumbIndex) ?? null);
|
|
741
842
|
const item = media[thumbIndex];
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
sourceRect && item ? { from: sourceRect, item, phase: "opening" } : null
|
|
746
|
-
);
|
|
747
|
-
setNavigationDirection(0);
|
|
748
|
-
setLayoutSourceIndex(thumbIndex);
|
|
749
|
-
setIndex(thumbIndex);
|
|
750
|
-
setOpen(true);
|
|
751
|
-
});
|
|
843
|
+
const transition = sourceRect && item ? { from: sourceRect, item, phase: "opening" } : null;
|
|
844
|
+
dispatch({ index: thumbIndex, transition, type: "open-at-index" });
|
|
845
|
+
onIndexChange?.(thumbIndex);
|
|
752
846
|
},
|
|
753
|
-
[media,
|
|
847
|
+
[media, onIndexChange, thumbnailMap]
|
|
754
848
|
);
|
|
755
849
|
const startClose = useCallback3(() => {
|
|
756
|
-
if (!open || closing) {
|
|
850
|
+
if (!state.open || state.closing) {
|
|
757
851
|
return;
|
|
758
852
|
}
|
|
759
853
|
const sourceRect = rectFromElement(expandedMediaRef.current);
|
|
760
|
-
const targetRect = rectFromElement(
|
|
761
|
-
thumbnailRefs.current.get(index) ?? null
|
|
762
|
-
);
|
|
854
|
+
const targetRect = rectFromElement(thumbnailMap.get(index) ?? null);
|
|
763
855
|
if (!activeMedia || !sourceRect || !targetRect) {
|
|
764
|
-
|
|
765
|
-
setClosing(false);
|
|
766
|
-
setOpen(false);
|
|
856
|
+
dispatch({ type: "close-without-transition" });
|
|
767
857
|
return;
|
|
768
858
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
setMediaTransition({
|
|
859
|
+
dispatch({
|
|
860
|
+
transition: {
|
|
772
861
|
from: sourceRect,
|
|
773
862
|
item: activeMedia,
|
|
774
863
|
phase: "closing",
|
|
775
864
|
to: targetRect
|
|
776
|
-
}
|
|
865
|
+
},
|
|
866
|
+
type: "start-close"
|
|
777
867
|
});
|
|
778
|
-
}, [activeMedia, closing,
|
|
868
|
+
}, [activeMedia, index, state.closing, state.open, thumbnailMap]);
|
|
779
869
|
const handleCloseAutoFocus = useCallback3(
|
|
780
870
|
(event) => {
|
|
781
871
|
event.preventDefault();
|
|
782
|
-
|
|
872
|
+
thumbnailMap.get(index)?.focus({ preventScroll: true });
|
|
783
873
|
},
|
|
784
|
-
[index]
|
|
874
|
+
[index, thumbnailMap]
|
|
785
875
|
);
|
|
786
876
|
const handleMediaTransitionComplete = useCallback3(() => {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
setClosing(false);
|
|
790
|
-
}
|
|
791
|
-
setMediaTransition(null);
|
|
792
|
-
}, [mediaTransition?.phase]);
|
|
877
|
+
dispatch({ type: "finish-transition" });
|
|
878
|
+
}, []);
|
|
793
879
|
const handleOpenChange = useCallback3(
|
|
794
880
|
(nextOpen) => {
|
|
795
881
|
if (nextOpen) {
|
|
796
|
-
|
|
797
|
-
setOpen(true);
|
|
882
|
+
dispatch({ open: true, type: "set-open" });
|
|
798
883
|
return;
|
|
799
884
|
}
|
|
800
885
|
startClose();
|
|
801
886
|
},
|
|
802
887
|
[startClose]
|
|
803
888
|
);
|
|
804
|
-
const value =
|
|
889
|
+
const value = useMemo3(
|
|
805
890
|
() => ({
|
|
806
891
|
classNames,
|
|
807
892
|
index,
|
|
808
893
|
media,
|
|
809
|
-
open,
|
|
894
|
+
open: state.open,
|
|
810
895
|
openAtIndex,
|
|
811
896
|
registerThumbnail,
|
|
812
897
|
renderImage,
|
|
@@ -819,7 +904,7 @@ function ApertoGroup({
|
|
|
819
904
|
classNames,
|
|
820
905
|
index,
|
|
821
906
|
media,
|
|
822
|
-
open,
|
|
907
|
+
state.open,
|
|
823
908
|
openAtIndex,
|
|
824
909
|
registerThumbnail,
|
|
825
910
|
renderImage,
|
|
@@ -832,11 +917,10 @@ function ApertoGroup({
|
|
|
832
917
|
const hasNavigation = media.length > 1;
|
|
833
918
|
const navigateToIndex = useCallback3(
|
|
834
919
|
(nextIndex, direction) => {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
setIndex(nextIndex);
|
|
920
|
+
dispatch({ direction, index: nextIndex, type: "navigate" });
|
|
921
|
+
onIndexChange?.(nextIndex);
|
|
838
922
|
},
|
|
839
|
-
[
|
|
923
|
+
[onIndexChange]
|
|
840
924
|
);
|
|
841
925
|
const goToPrevious = useCallback3(() => {
|
|
842
926
|
navigateToIndex((index - 1 + media.length) % media.length, -1);
|
|
@@ -860,7 +944,7 @@ function ApertoGroup({
|
|
|
860
944
|
},
|
|
861
945
|
[goToNext, goToPrevious]
|
|
862
946
|
);
|
|
863
|
-
const expandedMediaStyle =
|
|
947
|
+
const expandedMediaStyle = useMemo3(() => {
|
|
864
948
|
if (!activeMedia?.width || !activeMedia.height) {
|
|
865
949
|
return void 0;
|
|
866
950
|
}
|
|
@@ -876,16 +960,22 @@ function ApertoGroup({
|
|
|
876
960
|
dismissible,
|
|
877
961
|
motion: motionProp,
|
|
878
962
|
onOpenChange: handleOpenChange,
|
|
879
|
-
open,
|
|
963
|
+
open: state.open,
|
|
880
964
|
children: [
|
|
881
965
|
children,
|
|
882
966
|
activeMedia ? /* @__PURE__ */ jsxs(ApertoPortal, { children: [
|
|
883
|
-
/* @__PURE__ */ jsx10(
|
|
967
|
+
/* @__PURE__ */ jsx10(
|
|
968
|
+
ApertoOverlay,
|
|
969
|
+
{
|
|
970
|
+
className: classNames?.overlay,
|
|
971
|
+
fadeOut: state.closing
|
|
972
|
+
}
|
|
973
|
+
),
|
|
884
974
|
/* @__PURE__ */ jsxs(
|
|
885
975
|
ApertoContent,
|
|
886
976
|
{
|
|
887
977
|
className: classNames?.content,
|
|
888
|
-
"data-aperto-transition": mediaTransition?.phase,
|
|
978
|
+
"data-aperto-transition": state.mediaTransition?.phase,
|
|
889
979
|
onCloseAutoFocus: handleCloseAutoFocus,
|
|
890
980
|
onKeyDown: hasNavigation ? handleContentKeyDown : void 0,
|
|
891
981
|
sharedLayoutId: false,
|
|
@@ -901,7 +991,7 @@ function ApertoGroup({
|
|
|
901
991
|
/* @__PURE__ */ jsx10(
|
|
902
992
|
ApertoExpandedMediaStage,
|
|
903
993
|
{
|
|
904
|
-
direction: navigationDirection,
|
|
994
|
+
direction: state.navigationDirection,
|
|
905
995
|
index,
|
|
906
996
|
item: activeMedia,
|
|
907
997
|
navigationMotion,
|
|
@@ -909,44 +999,15 @@ function ApertoGroup({
|
|
|
909
999
|
renderVideo
|
|
910
1000
|
}
|
|
911
1001
|
),
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
children: /* @__PURE__ */ jsx10(
|
|
922
|
-
ChevronLeft,
|
|
923
|
-
{
|
|
924
|
-
"aria-hidden": "true",
|
|
925
|
-
size: 18,
|
|
926
|
-
strokeWidth: 2
|
|
927
|
-
}
|
|
928
|
-
)
|
|
929
|
-
}
|
|
930
|
-
),
|
|
931
|
-
/* @__PURE__ */ jsx10(
|
|
932
|
-
"button",
|
|
933
|
-
{
|
|
934
|
-
"aria-label": "Next media",
|
|
935
|
-
className: classNames?.nextButton,
|
|
936
|
-
"data-slot": "aperto-next-button",
|
|
937
|
-
onClick: goToNext,
|
|
938
|
-
type: "button",
|
|
939
|
-
children: /* @__PURE__ */ jsx10(
|
|
940
|
-
ChevronRight,
|
|
941
|
-
{
|
|
942
|
-
"aria-hidden": "true",
|
|
943
|
-
size: 18,
|
|
944
|
-
strokeWidth: 2
|
|
945
|
-
}
|
|
946
|
-
)
|
|
947
|
-
}
|
|
948
|
-
)
|
|
949
|
-
] }) : null
|
|
1002
|
+
/* @__PURE__ */ jsx10(
|
|
1003
|
+
ApertoMediaNavigationButtons,
|
|
1004
|
+
{
|
|
1005
|
+
classNames,
|
|
1006
|
+
enabled: hasNavigation,
|
|
1007
|
+
onNext: goToNext,
|
|
1008
|
+
onPrevious: goToPrevious
|
|
1009
|
+
}
|
|
1010
|
+
)
|
|
950
1011
|
]
|
|
951
1012
|
}
|
|
952
1013
|
),
|
|
@@ -977,7 +1038,7 @@ function ApertoGroup({
|
|
|
977
1038
|
onComplete: handleMediaTransitionComplete,
|
|
978
1039
|
renderImage,
|
|
979
1040
|
renderVideo,
|
|
980
|
-
transition: mediaTransition
|
|
1041
|
+
transition: state.mediaTransition
|
|
981
1042
|
}
|
|
982
1043
|
)
|
|
983
1044
|
] }) : null
|
|
@@ -985,6 +1046,40 @@ function ApertoGroup({
|
|
|
985
1046
|
}
|
|
986
1047
|
) });
|
|
987
1048
|
}
|
|
1049
|
+
function ApertoMediaNavigationButtons({
|
|
1050
|
+
classNames,
|
|
1051
|
+
enabled,
|
|
1052
|
+
onNext,
|
|
1053
|
+
onPrevious
|
|
1054
|
+
}) {
|
|
1055
|
+
if (!enabled) {
|
|
1056
|
+
return null;
|
|
1057
|
+
}
|
|
1058
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1059
|
+
/* @__PURE__ */ jsx10(
|
|
1060
|
+
"button",
|
|
1061
|
+
{
|
|
1062
|
+
"aria-label": "Previous media",
|
|
1063
|
+
className: classNames?.previousButton,
|
|
1064
|
+
"data-slot": "aperto-previous-button",
|
|
1065
|
+
onClick: onPrevious,
|
|
1066
|
+
type: "button",
|
|
1067
|
+
children: /* @__PURE__ */ jsx10(ChevronLeft, { "aria-hidden": "true", size: 18, strokeWidth: 2 })
|
|
1068
|
+
}
|
|
1069
|
+
),
|
|
1070
|
+
/* @__PURE__ */ jsx10(
|
|
1071
|
+
"button",
|
|
1072
|
+
{
|
|
1073
|
+
"aria-label": "Next media",
|
|
1074
|
+
className: classNames?.nextButton,
|
|
1075
|
+
"data-slot": "aperto-next-button",
|
|
1076
|
+
onClick: onNext,
|
|
1077
|
+
type: "button",
|
|
1078
|
+
children: /* @__PURE__ */ jsx10(ChevronRight, { "aria-hidden": "true", size: 18, strokeWidth: 2 })
|
|
1079
|
+
}
|
|
1080
|
+
)
|
|
1081
|
+
] });
|
|
1082
|
+
}
|
|
988
1083
|
|
|
989
1084
|
// src/aperto-close.tsx
|
|
990
1085
|
import * as Dialog7 from "@radix-ui/react-dialog";
|
|
@@ -998,34 +1093,15 @@ ApertoClose.displayName = "ApertoClose";
|
|
|
998
1093
|
|
|
999
1094
|
// src/aperto-trigger.tsx
|
|
1000
1095
|
import * as Dialog8 from "@radix-ui/react-dialog";
|
|
1001
|
-
import {
|
|
1002
|
-
import {
|
|
1003
|
-
forwardRef as forwardRef6,
|
|
1004
|
-
useCallback as useCallback4,
|
|
1005
|
-
useEffect as useEffect2,
|
|
1006
|
-
useState as useState4
|
|
1007
|
-
} from "react";
|
|
1096
|
+
import { m as m5 } from "motion/react";
|
|
1097
|
+
import { forwardRef as forwardRef6 } from "react";
|
|
1008
1098
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1009
1099
|
var TRIGGER_OPEN_Z_INDEX = 1e3;
|
|
1010
1100
|
var ApertoTrigger = forwardRef6(
|
|
1011
1101
|
({ active, children, motion: motionOverride, sharedLayoutId, ...props }, ref) => {
|
|
1012
1102
|
const ctx = useApertoContext();
|
|
1013
1103
|
const shouldRaise = ctx.open && (active ?? true);
|
|
1014
|
-
const
|
|
1015
|
-
shouldRaise ? TRIGGER_OPEN_Z_INDEX : 0
|
|
1016
|
-
);
|
|
1017
|
-
useEffect2(() => {
|
|
1018
|
-
if (shouldRaise) {
|
|
1019
|
-
setZIndex(TRIGGER_OPEN_Z_INDEX);
|
|
1020
|
-
} else if (ctx.open) {
|
|
1021
|
-
setZIndex(0);
|
|
1022
|
-
}
|
|
1023
|
-
}, [ctx.open, shouldRaise]);
|
|
1024
|
-
const handleLayoutAnimationComplete = useCallback4(() => {
|
|
1025
|
-
if (!shouldRaise) {
|
|
1026
|
-
setZIndex(0);
|
|
1027
|
-
}
|
|
1028
|
-
}, [shouldRaise]);
|
|
1104
|
+
const zIndex = shouldRaise ? TRIGGER_OPEN_Z_INDEX : 0;
|
|
1029
1105
|
const resolved = resolvePreset(
|
|
1030
1106
|
"trigger",
|
|
1031
1107
|
motionOverride,
|
|
@@ -1035,14 +1111,13 @@ var ApertoTrigger = forwardRef6(
|
|
|
1035
1111
|
);
|
|
1036
1112
|
const layoutId = sharedLayoutId === false ? void 0 : sharedLayoutId ?? `${ctx.layoutId}-shared`;
|
|
1037
1113
|
return /* @__PURE__ */ jsx12(Dialog8.Trigger, { asChild: true, ref, ...props, children: /* @__PURE__ */ jsx12(
|
|
1038
|
-
|
|
1114
|
+
m5.button,
|
|
1039
1115
|
{
|
|
1040
1116
|
"data-aperto-active": shouldRaise ? "" : void 0,
|
|
1041
1117
|
"data-slot": "aperto-trigger",
|
|
1042
1118
|
layout: true,
|
|
1043
1119
|
layoutCrossfade: false,
|
|
1044
1120
|
layoutId,
|
|
1045
|
-
onLayoutAnimationComplete: handleLayoutAnimationComplete,
|
|
1046
1121
|
style: { zIndex },
|
|
1047
1122
|
transition: resolved.transition,
|
|
1048
1123
|
type: "button",
|
|
@@ -1071,7 +1146,14 @@ function ApertoSingle({
|
|
|
1071
1146
|
{
|
|
1072
1147
|
"aria-label": `Open ${label}`,
|
|
1073
1148
|
className: classNames?.thumbnail,
|
|
1074
|
-
children:
|
|
1149
|
+
children: /* @__PURE__ */ jsx13(
|
|
1150
|
+
ApertoThumbnailMedia,
|
|
1151
|
+
{
|
|
1152
|
+
item: media,
|
|
1153
|
+
renderImage,
|
|
1154
|
+
renderVideo
|
|
1155
|
+
}
|
|
1156
|
+
)
|
|
1075
1157
|
}
|
|
1076
1158
|
),
|
|
1077
1159
|
/* @__PURE__ */ jsxs2(ApertoPortal, { children: [
|
|
@@ -1082,7 +1164,14 @@ function ApertoSingle({
|
|
|
1082
1164
|
className: classNames?.content,
|
|
1083
1165
|
...getDescriptionProps(media),
|
|
1084
1166
|
children: [
|
|
1085
|
-
|
|
1167
|
+
/* @__PURE__ */ jsx13(
|
|
1168
|
+
ApertoExpandedMedia,
|
|
1169
|
+
{
|
|
1170
|
+
item: media,
|
|
1171
|
+
renderImage,
|
|
1172
|
+
renderVideo
|
|
1173
|
+
}
|
|
1174
|
+
),
|
|
1086
1175
|
/* @__PURE__ */ jsx13(ApertoTitle, { children: title }),
|
|
1087
1176
|
media.description ? /* @__PURE__ */ jsx13(ApertoDescription, { children: media.description }) : null,
|
|
1088
1177
|
/* @__PURE__ */ jsx13(
|
|
@@ -1121,7 +1210,14 @@ function ApertoThumbnail({
|
|
|
1121
1210
|
onClick: () => group.openAtIndex(index),
|
|
1122
1211
|
ref: (node) => group.registerThumbnail(index, node),
|
|
1123
1212
|
sharedLayoutId: false,
|
|
1124
|
-
children: children ??
|
|
1213
|
+
children: children ?? /* @__PURE__ */ jsx14(
|
|
1214
|
+
ApertoThumbnailMedia,
|
|
1215
|
+
{
|
|
1216
|
+
item: media,
|
|
1217
|
+
renderImage: group.renderImage,
|
|
1218
|
+
renderVideo: group.renderVideo
|
|
1219
|
+
}
|
|
1220
|
+
)
|
|
1125
1221
|
}
|
|
1126
1222
|
);
|
|
1127
1223
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Aperto/ApertoGroup.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-transition.tsx","../src/Aperto/ApertoKeyboard.ts","../src/aperto-close.tsx","../src/aperto-trigger.tsx","../src/Aperto/ApertoSingle.tsx","../src/Aperto/ApertoThumbnail.tsx","../src/index.ts"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeft, ChevronRight, X } from \"lucide-react\";\nimport {\n\ttype CSSProperties,\n\ttype KeyboardEvent,\n\tuseCallback,\n\tuseId,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\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 {\n\tApertoExpandedMediaStage,\n\ttype NavigationDirection,\n} from \"../expanded-media-stage\";\nimport { getDescriptionProps, getMediaLabel } from \"../media-rendering\";\nimport {\n\ttype ApertoMediaTransition,\n\tApertoMediaTransitionClone,\n\trectFromElement,\n} from \"../media-transition\";\nimport { shouldIgnoreKeyboardNavigationTarget } from \"./ApertoKeyboard\";\nimport type { ApertoGroupProps } from \"./ApertoTypes\";\n\nexport function ApertoGroup({\n\tchildren,\n\tclassNames,\n\tdismissible,\n\tindex: controlledIndex,\n\tinitialIndex = 0,\n\tmedia,\n\tmotion: motionProp,\n\tnavigationMotion = \"glide\",\n\tonIndexChange,\n\trenderImage,\n\trenderVideo,\n}: ApertoGroupProps) {\n\tconst generatedId = useId();\n\tconst [internalIndex, setInternalIndex] = useState(initialIndex);\n\tconst [open, setOpen] = useState(false);\n\tconst [closing, setClosing] = useState(false);\n\tconst [mediaTransition, setMediaTransition] =\n\t\tuseState<ApertoMediaTransition | null>(null);\n\tconst [navigationDirection, setNavigationDirection] =\n\t\tuseState<NavigationDirection>(0);\n\tconst isControlled = controlledIndex !== undefined;\n\tconst index = isControlled ? controlledIndex : internalIndex;\n\tconst activeMedia = media[index] ?? media[0];\n\tconst [layoutSourceIndex, setLayoutSourceIndex] = useState(index);\n\tconst expandedMediaRef = useRef<HTMLDivElement | null>(null);\n\tconst thumbnailRefs = useRef(new Map<number, HTMLButtonElement>());\n\tconst sharedLayoutIdForIndex = useCallback(\n\t\t(nextIndex: number) => `aperto-group-${generatedId}-${nextIndex}-shared`,\n\t\t[generatedId],\n\t);\n\tconst sharedLayoutId = sharedLayoutIdForIndex(layoutSourceIndex);\n\tconst measureOpeningTarget = useCallback((node: HTMLDivElement) => {\n\t\tconst targetRect = rectFromElement(node);\n\t\tif (!targetRect) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetMediaTransition((current) => {\n\t\t\tif (current?.phase !== \"opening\" || current.to) {\n\t\t\t\treturn current;\n\t\t\t}\n\t\t\treturn { ...current, to: targetRect };\n\t\t});\n\t}, []);\n\tconst setExpandedMediaNode = useCallback(\n\t\t(node: HTMLDivElement | null) => {\n\t\t\texpandedMediaRef.current = node;\n\t\t\tif (node) {\n\t\t\t\tmeasureOpeningTarget(node);\n\t\t\t}\n\t\t},\n\t\t[measureOpeningTarget],\n\t);\n\n\tconst registerThumbnail = useCallback(\n\t\t(thumbIndex: number, node: HTMLButtonElement | null) => {\n\t\t\tif (node) {\n\t\t\t\tthumbnailRefs.current.set(thumbIndex, node);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthumbnailRefs.current.delete(thumbIndex);\n\t\t},\n\t\t[],\n\t);\n\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\tmediaTransition?.phase !== \"opening\" ||\n\t\t\tmediaTransition.to ||\n\t\t\t!expandedMediaRef.current\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tmeasureOpeningTarget(expandedMediaRef.current);\n\t}, [measureOpeningTarget, mediaTransition]);\n\n\tconst setIndex = useCallback(\n\t\t(nextIndex: number) => {\n\t\t\tif (!isControlled) {\n\t\t\t\tsetInternalIndex(nextIndex);\n\t\t\t}\n\t\t\tonIndexChange?.(nextIndex);\n\t\t},\n\t\t[isControlled, onIndexChange],\n\t);\n\n\tconst openAtIndex = useCallback(\n\t\t(thumbIndex: number) => {\n\t\t\tconst sourceRect = rectFromElement(\n\t\t\t\tthumbnailRefs.current.get(thumbIndex) ?? null,\n\t\t\t);\n\t\t\tconst item = media[thumbIndex];\n\n\t\t\tflushSync(() => {\n\t\t\t\tsetClosing(false);\n\t\t\t\tsetMediaTransition(\n\t\t\t\t\tsourceRect && item\n\t\t\t\t\t\t? { from: sourceRect, item, phase: \"opening\" }\n\t\t\t\t\t\t: null,\n\t\t\t\t);\n\t\t\t\tsetNavigationDirection(0);\n\t\t\t\tsetLayoutSourceIndex(thumbIndex);\n\t\t\t\tsetIndex(thumbIndex);\n\t\t\t\tsetOpen(true);\n\t\t\t});\n\t\t},\n\t\t[media, setIndex],\n\t);\n\n\tconst startClose = useCallback(() => {\n\t\tif (!open || closing) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst sourceRect = rectFromElement(expandedMediaRef.current);\n\t\tconst targetRect = rectFromElement(\n\t\t\tthumbnailRefs.current.get(index) ?? null,\n\t\t);\n\n\t\tif (!activeMedia || !sourceRect || !targetRect) {\n\t\t\tsetMediaTransition(null);\n\t\t\tsetClosing(false);\n\t\t\tsetOpen(false);\n\t\t\treturn;\n\t\t}\n\n\t\tflushSync(() => {\n\t\t\tsetClosing(true);\n\t\t\tsetMediaTransition({\n\t\t\t\tfrom: sourceRect,\n\t\t\t\titem: activeMedia,\n\t\t\t\tphase: \"closing\",\n\t\t\t\tto: targetRect,\n\t\t\t});\n\t\t});\n\t}, [activeMedia, closing, index, open]);\n\n\tconst handleCloseAutoFocus = useCallback(\n\t\t(event: Event) => {\n\t\t\tevent.preventDefault();\n\t\t\tthumbnailRefs.current.get(index)?.focus({ preventScroll: true });\n\t\t},\n\t\t[index],\n\t);\n\n\tconst handleMediaTransitionComplete = useCallback(() => {\n\t\tif (mediaTransition?.phase === \"closing\") {\n\t\t\tsetOpen(false);\n\t\t\tsetClosing(false);\n\t\t}\n\t\tsetMediaTransition(null);\n\t}, [mediaTransition?.phase]);\n\n\tconst handleOpenChange = useCallback(\n\t\t(nextOpen: boolean) => {\n\t\t\tif (nextOpen) {\n\t\t\t\tsetClosing(false);\n\t\t\t\tsetOpen(true);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tstartClose();\n\t\t},\n\t\t[startClose],\n\t);\n\n\tconst value = useMemo(\n\t\t() => ({\n\t\t\tclassNames,\n\t\t\tindex,\n\t\t\tmedia,\n\t\t\topen,\n\t\t\topenAtIndex,\n\t\t\tregisterThumbnail,\n\t\t\trenderImage,\n\t\t\trenderVideo,\n\t\t\tsetIndex,\n\t\t\tsharedLayoutId,\n\t\t\tsharedLayoutIdForIndex,\n\t\t}),\n\t\t[\n\t\t\tclassNames,\n\t\t\tindex,\n\t\t\tmedia,\n\t\t\topen,\n\t\t\topenAtIndex,\n\t\t\tregisterThumbnail,\n\t\t\trenderImage,\n\t\t\trenderVideo,\n\t\t\tsetIndex,\n\t\t\tsharedLayoutId,\n\t\t\tsharedLayoutIdForIndex,\n\t\t],\n\t);\n\tconst hasNavigation = media.length > 1;\n\tconst navigateToIndex = useCallback(\n\t\t(nextIndex: number, direction: NavigationDirection) => {\n\t\t\tsetNavigationDirection(direction);\n\t\t\tsetLayoutSourceIndex(nextIndex);\n\t\t\tsetIndex(nextIndex);\n\t\t},\n\t\t[setIndex],\n\t);\n\tconst goToPrevious = useCallback(() => {\n\t\tnavigateToIndex((index - 1 + media.length) % media.length, -1);\n\t}, [index, media.length, navigateToIndex]);\n\tconst goToNext = useCallback(() => {\n\t\tnavigateToIndex((index + 1) % media.length, 1);\n\t}, [index, media.length, navigateToIndex]);\n\tconst handleContentKeyDown = useCallback(\n\t\t(event: KeyboardEvent<HTMLDivElement>) => {\n\t\t\tif (\n\t\t\t\tevent.defaultPrevented ||\n\t\t\t\tevent.altKey ||\n\t\t\t\tevent.ctrlKey ||\n\t\t\t\tevent.metaKey ||\n\t\t\t\tshouldIgnoreKeyboardNavigationTarget(event.target)\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.key === \"ArrowLeft\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tgoToPrevious();\n\t\t\t}\n\n\t\t\tif (event.key === \"ArrowRight\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tgoToNext();\n\t\t\t}\n\t\t},\n\t\t[goToNext, goToPrevious],\n\t);\n\tconst expandedMediaStyle = useMemo((): CSSProperties | undefined => {\n\t\tif (!activeMedia?.width || !activeMedia.height) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\t\"--aperto-expanded-aspect-ratio\": `${activeMedia.width} / ${activeMedia.height}`,\n\t\t\t\"--aperto-expanded-aspect-ratio-height\": activeMedia.height,\n\t\t\t\"--aperto-expanded-aspect-ratio-width\": activeMedia.width,\n\t\t} as CSSProperties;\n\t}, [activeMedia?.height, activeMedia?.width]);\n\n\treturn (\n\t\t<ApertoGroupContext.Provider value={value}>\n\t\t\t<ApertoRoot\n\t\t\t\tdismissible={dismissible}\n\t\t\t\tmotion={motionProp}\n\t\t\t\tonOpenChange={handleOpenChange}\n\t\t\t\topen={open}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t{activeMedia ? (\n\t\t\t\t\t<ApertoPortal>\n\t\t\t\t\t\t<ApertoOverlay className={classNames?.overlay} fadeOut={closing} />\n\t\t\t\t\t\t<ApertoContent\n\t\t\t\t\t\t\tclassName={classNames?.content}\n\t\t\t\t\t\t\tdata-aperto-transition={mediaTransition?.phase}\n\t\t\t\t\t\t\tonCloseAutoFocus={handleCloseAutoFocus}\n\t\t\t\t\t\t\tonKeyDown={hasNavigation ? handleContentKeyDown : undefined}\n\t\t\t\t\t\t\tsharedLayoutId={false}\n\t\t\t\t\t\t\t{...getDescriptionProps(activeMedia)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tdata-slot=\"aperto-media\"\n\t\t\t\t\t\t\t\tref={setExpandedMediaNode}\n\t\t\t\t\t\t\t\tstyle={expandedMediaStyle}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ApertoExpandedMediaStage\n\t\t\t\t\t\t\t\t\tdirection={navigationDirection}\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\titem={activeMedia}\n\t\t\t\t\t\t\t\t\tnavigationMotion={navigationMotion}\n\t\t\t\t\t\t\t\t\trenderImage={renderImage}\n\t\t\t\t\t\t\t\t\trenderVideo={renderVideo}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{hasNavigation ? (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Previous media\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={classNames?.previousButton}\n\t\t\t\t\t\t\t\t\t\t\tdata-slot=\"aperto-previous-button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={goToPrevious}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<ChevronLeft\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize={18}\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Next media\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={classNames?.nextButton}\n\t\t\t\t\t\t\t\t\t\t\tdata-slot=\"aperto-next-button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={goToNext}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<ChevronRight\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize={18}\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<ApertoTitle>\n\t\t\t\t\t\t\t\t{activeMedia.title ?? getMediaLabel(activeMedia)}\n\t\t\t\t\t\t\t</ApertoTitle>\n\t\t\t\t\t\t\t{activeMedia.description ? (\n\t\t\t\t\t\t\t\t<ApertoDescription>{activeMedia.description}</ApertoDescription>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{hasNavigation ? (\n\t\t\t\t\t\t\t\t<div className={classNames?.counter} data-slot=\"aperto-counter\">\n\t\t\t\t\t\t\t\t\t{index + 1} / {media.length}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t\t\t\t\tclassName={classNames?.closeButton}\n\t\t\t\t\t\t\t\tdata-slot=\"aperto-close\"\n\t\t\t\t\t\t\t\tonClick={startClose}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<X aria-hidden=\"true\" size={17} strokeWidth={2} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</ApertoContent>\n\t\t\t\t\t\t<ApertoMediaTransitionClone\n\t\t\t\t\t\t\tonComplete={handleMediaTransitionComplete}\n\t\t\t\t\t\t\trenderImage={renderImage}\n\t\t\t\t\t\t\trenderVideo={renderVideo}\n\t\t\t\t\t\t\ttransition={mediaTransition}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ApertoPortal>\n\t\t\t\t) : null}\n\t\t\t</ApertoRoot>\n\t\t</ApertoGroupContext.Provider>\n\t);\n}\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport {\n\ttype MotionStyle,\n\tmotion,\n\ttype PanInfo,\n\tuseMotionValue,\n\tuseSpring,\n\tuseTransform,\n} from \"motion/react\";\nimport {\n\ttype ComponentPropsWithoutRef,\n\tforwardRef,\n\tuseCallback,\n\tuseMemo,\n\tuseState,\n} from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport {\n\tcalculateResistance,\n\tDEFAULT_DISTANCE_THRESHOLD,\n\tDEFAULT_VELOCITY_THRESHOLD,\n\tOPACITY_INPUT,\n\tOPACITY_OUTPUT,\n\tSCALE_INPUT,\n\tSCALE_OUTPUT,\n} from \"./physics\";\nimport { getDragSpring, resolvePreset } from \"./presets\";\nimport type { DismissibleConfig, MotionPresetName } from \"./types\";\n\nexport interface ApertoContentProps\n\textends Omit<\n\t\tComponentPropsWithoutRef<typeof Dialog.Content>,\n\t\t\"asChild\" | \"forceMount\"\n\t> {\n\t/** Motion preset override for this content panel, independent of the root preset. */\n\tmotion?: MotionPresetName;\n\t/** Built-in positioning strategy. Use \"none\" for custom primitive compositions. */\n\tplacement?: \"center\" | \"none\";\n\t/** Internal shared layout ID override for grouped media. */\n\tsharedLayoutId?: string | false;\n}\n\nconst ApertoContent = forwardRef<HTMLDivElement, ApertoContentProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tmotion: motionOverride,\n\t\t\tplacement = \"center\",\n\t\t\tsharedLayoutId,\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst ctx = useApertoContext();\n\t\tconst [isDragging, setIsDragging] = useState(false);\n\t\tconst resolved = resolvePreset(\n\t\t\t\"content\",\n\t\t\tmotionOverride,\n\t\t\tctx.presetName,\n\t\t\tctx.variants,\n\t\t\tctx.reduceMotion,\n\t\t);\n\n\t\tconst contentLayoutId =\n\t\t\tsharedLayoutId === false\n\t\t\t\t? undefined\n\t\t\t\t: (sharedLayoutId ?? `${ctx.layoutId}-shared`);\n\n\t\tconst dragSpring = getDragSpring(resolved);\n\t\tconst isDismissible = ctx.dismissible !== false;\n\n\t\tconst dismissConfig: DismissibleConfig =\n\t\t\ttypeof ctx.dismissible === \"object\" ? ctx.dismissible : {};\n\t\tconst distanceThreshold =\n\t\t\tdismissConfig.threshold ?? DEFAULT_DISTANCE_THRESHOLD;\n\t\tconst velocityThreshold =\n\t\t\tdismissConfig.velocity ?? DEFAULT_VELOCITY_THRESHOLD;\n\n\t\tconst dragX = useMotionValue(0);\n\t\tconst dragY = useMotionValue(0);\n\t\tconst springX = useSpring(dragX, dragSpring);\n\t\tconst springY = useSpring(dragY, dragSpring);\n\n\t\tconst distance = useTransform(() =>\n\t\t\tMath.hypot(springX.get(), springY.get()),\n\t\t);\n\t\tconst scaleMotion = useTransform(distance, SCALE_INPUT, SCALE_OUTPUT);\n\t\tconst opacityMotion = useTransform(distance, OPACITY_INPUT, OPACITY_OUTPUT);\n\t\tconst resistance = useTransform(distance, calculateResistance);\n\n\t\tconst handleDrag = useCallback(\n\t\t\t(_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n\t\t\t\tif (!isDragging) {\n\t\t\t\t\tsetIsDragging(true);\n\t\t\t\t}\n\t\t\t\tconst r = resistance.get();\n\t\t\t\tdragX.set(info.offset.x * r);\n\t\t\t\tdragY.set(info.offset.y * r);\n\t\t\t},\n\t\t\t[dragX, dragY, isDragging, resistance],\n\t\t);\n\n\t\tconst handleDragEnd = useCallback(\n\t\t\t(_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n\t\t\t\tsetIsDragging(false);\n\t\t\t\tconst speed = Math.hypot(info.velocity.x, info.velocity.y);\n\t\t\t\tconst dist = Math.hypot(info.offset.x, info.offset.y);\n\n\t\t\t\tif (speed > velocityThreshold || dist > distanceThreshold) {\n\t\t\t\t\tctx.onOpenChange(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tdragX.set(0);\n\t\t\t\tdragY.set(0);\n\t\t\t},\n\t\t\t[ctx.onOpenChange, distanceThreshold, dragX, dragY, velocityThreshold],\n\t\t);\n\n\t\tconst motionStyle = useMemo(\n\t\t\t(): MotionStyle => ({\n\t\t\t\tcursor: isDragging ? \"grabbing\" : isDismissible ? \"grab\" : undefined,\n\t\t\t\topacity: opacityMotion,\n\t\t\t\tscale: scaleMotion,\n\t\t\t\tx: springX,\n\t\t\t\ty: springY,\n\t\t\t\t...(placement === \"center\"\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tleft: \"50%\",\n\t\t\t\t\t\t\ttop: \"50%\",\n\t\t\t\t\t\t\ttranslate: \"-50% -50%\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\t...style,\n\t\t\t}),\n\t\t\t[\n\t\t\t\tisDismissible,\n\t\t\t\tisDragging,\n\t\t\t\topacityMotion,\n\t\t\t\tplacement,\n\t\t\t\tscaleMotion,\n\t\t\t\tspringX,\n\t\t\t\tspringY,\n\t\t\t\tstyle,\n\t\t\t],\n\t\t);\n\n\t\treturn (\n\t\t\t<Dialog.Content asChild forceMount {...props}>\n\t\t\t\t<motion.div\n\t\t\t\t\tclassName={className}\n\t\t\t\t\tdata-slot=\"aperto-content\"\n\t\t\t\t\tdrag={isDismissible}\n\t\t\t\t\tdragConstraints={{ bottom: 0, left: 0, right: 0, top: 0 }}\n\t\t\t\t\tdragElastic={0}\n\t\t\t\t\tdragMomentum={false}\n\t\t\t\t\tdragSnapToOrigin\n\t\t\t\t\tlayout={contentLayoutId ? true : undefined}\n\t\t\t\t\tlayoutId={contentLayoutId}\n\t\t\t\t\tonDrag={isDismissible ? handleDrag : undefined}\n\t\t\t\t\tonDragEnd={isDismissible ? handleDragEnd : undefined}\n\t\t\t\t\tref={ref}\n\t\t\t\t\tstyle={motionStyle}\n\t\t\t\t\ttransition={resolved.transition}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</motion.div>\n\t\t\t</Dialog.Content>\n\t\t);\n\t},\n);\n\nApertoContent.displayName = \"ApertoContent\";\n\nexport { ApertoContent };\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type { ApertoContextValue } from \"./types\";\n\nexport const ApertoContext = createContext<ApertoContextValue | null>(null);\n\nexport function useApertoContext(): ApertoContextValue {\n\tconst ctx = useContext(ApertoContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"Aperto components must be used within <Aperto.Root>\");\n\t}\n\treturn 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 function calculateResistance(distance: number): number {\n\treturn Math.max(\n\t\tRESISTANCE_MIN,\n\t\t1 - Math.log(distance / RESISTANCE_DIVISOR + 1) / RESISTANCE_SCALE,\n\t);\n}\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\tsnappy: 0.22,\n\tmoderate: 0.4,\n} as const;\n\nexport const easings = {\n\tcustomGentle: [0.25, 0.1, 0.12, 1],\n\tsnappy: [0.22, 1, 0.36, 1],\n} satisfies Record<string, Easing>;\n\nexport const springs = {\n\tbouncy: { stiffness: 260, damping: 12, mass: 1 },\n\tnatural: { stiffness: 200, damping: 20, mass: 1 },\n\tsnappy: { stiffness: 400, damping: 28, mass: 0.8 },\n\tstiff: { stiffness: 500, damping: 30, mass: 1 },\n} as const;\n","import { durations, easings, springs } from \"./motion-tokens\";\nimport type {\n\tDragSpringConfig,\n\tMotionPreset,\n\tMotionPresetName,\n\tMotionVariants,\n} 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\tsnappy: {\n\t\ttransition: { ease: easings.snappy, duration: durations.snappy },\n\t\tdrag: {\n\t\t\tstiffness: springs.stiff.stiffness,\n\t\t\tdamping: springs.stiff.damping,\n\t\t\trestDelta: 0.01,\n\t\t},\n\t},\n\tsmooth: {\n\t\ttransition: { ease: easings.customGentle, duration: durations.moderate },\n\t\tdrag: {\n\t\t\tstiffness: springs.natural.stiffness,\n\t\t\tdamping: springs.natural.damping,\n\t\t\trestDelta: 0.01,\n\t\t},\n\t},\n\tbouncy: {\n\t\ttransition: {\n\t\t\ttype: \"spring\",\n\t\t\tstiffness: springs.bouncy.stiffness,\n\t\t\tdamping: springs.bouncy.damping,\n\t\t\tmass: springs.bouncy.mass,\n\t\t},\n\t\tdrag: {\n\t\t\tstiffness: springs.snappy.stiffness,\n\t\t\tdamping: springs.snappy.damping,\n\t\t\trestDelta: 0.01,\n\t\t},\n\t},\n\treduced: {\n\t\ttransition: { ease: \"linear\", duration: 0.01 },\n\t\tdrag: { stiffness: 1000, damping: 50, restDelta: 0.1 },\n\t},\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 function resolvePreset(\n\tcomponentType: ComponentType,\n\tcomponentMotion: MotionPresetName | undefined,\n\tglobalPreset: MotionPresetName,\n\tvariants: MotionVariants | undefined,\n\treduceMotion: boolean,\n): MotionPreset {\n\tif (reduceMotion) {\n\t\treturn PRESETS.reduced;\n\t}\n\n\t// 1. Component-level override\n\tif (componentMotion) {\n\t\treturn PRESETS[componentMotion];\n\t}\n\n\t// 2. Per-component variant\n\tif (variants?.[componentType]) {\n\t\treturn PRESETS[variants[componentType]];\n\t}\n\n\t// 3. Global preset\n\treturn PRESETS[globalPreset];\n}\n\n/** Extract the drag spring config from a preset */\nexport function getDragSpring(preset: MotionPreset): DragSpringConfig {\n\treturn preset.drag;\n}\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\n\nconst ApertoDescription = forwardRef<\n\tHTMLParagraphElement,\n\tComponentPropsWithoutRef<typeof Dialog.Description>\n>((props, ref) => {\n\treturn (\n\t\t<Dialog.Description data-slot=\"aperto-description\" ref={ref} {...props} />\n\t);\n});\n\nApertoDescription.displayName = \"ApertoDescription\";\n\nexport { ApertoDescription };\n","import { createContext, useContext } from \"react\";\nimport type {\n\tApertoClassNames,\n\tApertoMediaItem,\n\tRenderImage,\n\tRenderVideo,\n} from \"./types\";\n\nexport interface ApertoGroupContextValue {\n\tclassNames?: ApertoClassNames;\n\tindex: number;\n\tmedia: ApertoMediaItem[];\n\topen: boolean;\n\topenAtIndex: (index: number) => void;\n\tregisterThumbnail: (index: number, node: HTMLButtonElement | null) => void;\n\trenderImage?: RenderImage;\n\trenderVideo?: RenderVideo;\n\tsetIndex: (index: number) => void;\n\tsharedLayoutId: string;\n\tsharedLayoutIdForIndex: (index: number) => string;\n}\n\nexport const ApertoGroupContext = createContext<ApertoGroupContextValue | null>(\n\tnull,\n);\n\nexport function useApertoGroup(): ApertoGroupContextValue {\n\tconst ctx = useContext(ApertoGroupContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"Aperto.Thumbnail must be used within <Aperto.Group>\");\n\t}\n\treturn ctx;\n}\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { motion, type Transition } from \"motion/react\";\nimport { forwardRef } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { easings } from \"./motion-tokens\";\n\nexport interface ApertoOverlayProps {\n\tclassName?: string;\n\t/** Internal flag used to fade the overlay during measured close transitions. */\n\tfadeOut?: boolean;\n\tstyle?: React.CSSProperties;\n}\n\n/** Overlay always fades gently regardless of the content's motion preset. */\nconst OVERLAY_TRANSITION: Transition = {\n\tduration: 0.3,\n\tease: easings.customGentle,\n};\n\nconst OVERLAY_TRANSITION_REDUCED: Transition = {\n\tduration: 0.01,\n\tease: \"linear\",\n};\n\nconst ApertoOverlay = forwardRef<HTMLDivElement, ApertoOverlayProps>(\n\t({ className, fadeOut, style }, ref) => {\n\t\tconst ctx = useApertoContext();\n\t\tconst transition = ctx.reduceMotion\n\t\t\t? OVERLAY_TRANSITION_REDUCED\n\t\t\t: OVERLAY_TRANSITION;\n\n\t\treturn (\n\t\t\t<Dialog.Overlay asChild forceMount>\n\t\t\t\t<motion.div\n\t\t\t\t\tanimate={{ opacity: fadeOut ? 0 : 1 }}\n\t\t\t\t\tclassName={className}\n\t\t\t\t\tdata-slot=\"aperto-overlay\"\n\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\tref={ref}\n\t\t\t\t\tstyle={style}\n\t\t\t\t\ttransition={transition}\n\t\t\t\t/>\n\t\t\t</Dialog.Overlay>\n\t\t);\n\t},\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\tchildren: ReactNode;\n\t/** Container element for the portal (default: document.body) */\n\tcontainer?: HTMLElement;\n}\n\nfunction ApertoPortal({ children, container }: ApertoPortalProps) {\n\tconst { open } = useApertoContext();\n\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t{open && (\n\t\t\t\t<Dialog.Portal container={container} forceMount>\n\t\t\t\t\t{children}\n\t\t\t\t</Dialog.Portal>\n\t\t\t)}\n\t\t</AnimatePresence>\n\t);\n}\n\nexport { ApertoPortal };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { LayoutGroup, useReducedMotion } from \"motion/react\";\nimport {\n\ttype ComponentPropsWithoutRef,\n\ttype ReactNode,\n\tuseCallback,\n\tuseId,\n\tuseState,\n} from \"react\";\n\nimport { ApertoContext } from \"./context\";\nimport { PRESETS } from \"./presets\";\nimport type {\n\tDismissibleConfig,\n\tMotionPresetName,\n\tMotionVariants,\n} from \"./types\";\n\nexport interface ApertoRootProps\n\textends Omit<\n\t\tComponentPropsWithoutRef<typeof Dialog.Root>,\n\t\t\"open\" | \"onOpenChange\"\n\t> {\n\tchildren: ReactNode;\n\t/** Whether dragging can dismiss the content (default: true) */\n\tdismissible?: boolean | DismissibleConfig;\n\t/** Layout ID for shared element transition (auto-generated if omitted) */\n\tlayoutId?: string;\n\t/** Motion preset or per-component variants */\n\tmotion?: MotionPresetName | MotionVariants;\n\t/** Controlled open state */\n\topen?: boolean;\n\t/** Callback when open state changes */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Force reduced motion regardless of system preference */\n\treduceMotion?: boolean;\n}\n\nfunction ApertoRoot({\n\tchildren,\n\tdismissible = true,\n\tlayoutId: layoutIdProp,\n\tmotion: motionProp = \"smooth\",\n\topen: controlledOpen,\n\tonOpenChange: controlledOnOpenChange,\n\treduceMotion: reduceMotionProp,\n\t...dialogProps\n}: ApertoRootProps) {\n\tconst generatedId = useId();\n\tconst layoutId = layoutIdProp ?? `aperto-${generatedId}`;\n\tconst systemReducedMotion = useReducedMotion() ?? false;\n\tconst shouldReduce = reduceMotionProp ?? systemReducedMotion;\n\n\t// Uncontrolled state fallback\n\tconst [internalOpen, setInternalOpen] = useState(false);\n\tconst isControlled = controlledOpen !== undefined;\n\tconst open = isControlled ? controlledOpen : internalOpen;\n\n\tconst onOpenChange = useCallback(\n\t\t(nextOpen: boolean) => {\n\t\t\tif (!isControlled) {\n\t\t\t\tsetInternalOpen(nextOpen);\n\t\t\t}\n\t\t\tcontrolledOnOpenChange?.(nextOpen);\n\t\t},\n\t\t[isControlled, controlledOnOpenChange],\n\t);\n\n\t// Resolve global preset name\n\tconst globalPresetName: MotionPresetName =\n\t\ttypeof motionProp === \"string\" ? motionProp : \"smooth\";\n\tconst variants: MotionVariants | undefined =\n\t\ttypeof motionProp === \"object\" ? motionProp : undefined;\n\n\tconst presetName: MotionPresetName = shouldReduce\n\t\t? \"reduced\"\n\t\t: globalPresetName;\n\tconst preset = PRESETS[presetName];\n\n\treturn (\n\t\t<ApertoContext.Provider\n\t\t\tvalue={{\n\t\t\t\tdismissible,\n\t\t\t\tlayoutId,\n\t\t\t\tonOpenChange,\n\t\t\t\topen,\n\t\t\t\tpreset,\n\t\t\t\tpresetName,\n\t\t\t\treduceMotion: shouldReduce,\n\t\t\t\tvariants,\n\t\t\t}}\n\t\t>\n\t\t\t<Dialog.Root onOpenChange={onOpenChange} open={open} {...dialogProps}>\n\t\t\t\t<LayoutGroup id={layoutId}>{children}</LayoutGroup>\n\t\t\t</Dialog.Root>\n\t\t</ApertoContext.Provider>\n\t);\n}\n\nexport { ApertoRoot };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\n\nconst ApertoTitle = forwardRef<\n\tHTMLHeadingElement,\n\tComponentPropsWithoutRef<typeof Dialog.Title>\n>((props, ref) => {\n\treturn <Dialog.Title data-slot=\"aperto-title\" ref={ref} {...props} />;\n});\n\nApertoTitle.displayName = \"ApertoTitle\";\n\nexport { ApertoTitle };\n","import {\n\tAnimatePresence,\n\tmotion,\n\ttype TargetAndTransition,\n\ttype Transition,\n} from \"motion/react\";\nimport { useApertoContext } from \"./context\";\nimport { getMediaKey, renderExpandedMedia } from \"./media-rendering\";\nimport type {\n\tApertoMediaItem,\n\tNavigationMotionPresetName,\n\tRenderImage,\n\tRenderVideo,\n} from \"./types\";\n\nexport type NavigationDirection = -1 | 0 | 1;\n\ninterface NavigationMotionPreset {\n\toffset: number;\n\tscale: number;\n\ttransition: Transition;\n}\n\ninterface NavigationAnimationCustom {\n\tdirection: NavigationDirection;\n\toffset: number;\n\tscale: number;\n}\n\nconst NAVIGATION_MOTION_PRESETS: Record<\n\tNavigationMotionPresetName,\n\tNavigationMotionPreset\n> = {\n\tfloat: {\n\t\toffset: 96,\n\t\tscale: 0.97,\n\t\ttransition: {\n\t\t\topacity: { duration: 0.34, ease: [0.45, 0, 0.2, 1] },\n\t\t\tscale: { damping: 26, mass: 1.15, stiffness: 80, type: \"spring\" },\n\t\t\tx: { damping: 26, mass: 1.15, stiffness: 80, type: \"spring\" },\n\t\t},\n\t},\n\tglide: {\n\t\toffset: 58,\n\t\tscale: 0.984,\n\t\ttransition: {\n\t\t\topacity: { duration: 0.24, ease: [0.4, 0, 0.2, 1] },\n\t\t\tscale: { damping: 28, mass: 0.95, stiffness: 150, type: \"spring\" },\n\t\t\tx: { damping: 28, mass: 0.95, stiffness: 150, type: \"spring\" },\n\t\t},\n\t},\n\tsnap: {\n\t\toffset: 38,\n\t\tscale: 0.996,\n\t\ttransition: {\n\t\t\topacity: { duration: 0.12, ease: [0.2, 0, 0, 1] },\n\t\t\tscale: { damping: 34, mass: 0.7, stiffness: 420, type: \"spring\" },\n\t\t\tx: { damping: 34, mass: 0.7, stiffness: 420, type: \"spring\" },\n\t\t},\n\t},\n};\n\nconst REDUCED_EXPANDED_MEDIA_TRANSITION: Transition = {\n\tduration: 0.12,\n\tease: \"linear\",\n};\n\nconst expandedMediaVariants = {\n\tcenter: {\n\t\topacity: 1,\n\t\tscale: 1,\n\t\tx: 0,\n\t},\n\tenter: ({\n\t\tdirection,\n\t\toffset,\n\t\tscale,\n\t}: NavigationAnimationCustom): TargetAndTransition => ({\n\t\topacity: 0,\n\t\tscale: direction === 0 ? 1 : scale,\n\t\tx: direction * offset,\n\t}),\n\texit: ({\n\t\tdirection,\n\t\toffset,\n\t\tscale,\n\t}: NavigationAnimationCustom): TargetAndTransition => ({\n\t\topacity: 0,\n\t\tscale: direction === 0 ? 1 : scale,\n\t\tx: direction * -offset,\n\t}),\n};\n\nconst reducedExpandedMediaVariants = {\n\tcenter: {\n\t\topacity: 1,\n\t\tx: 0,\n\t},\n\tenter: {\n\t\topacity: 0,\n\t\tx: 0,\n\t},\n\texit: {\n\t\topacity: 0,\n\t\tx: 0,\n\t},\n};\n\nexport function ApertoExpandedMediaStage({\n\tdirection,\n\tindex,\n\titem,\n\tnavigationMotion,\n\trenderImage,\n\trenderVideo,\n}: {\n\tdirection: NavigationDirection;\n\tindex: number;\n\titem: ApertoMediaItem;\n\tnavigationMotion: NavigationMotionPresetName;\n\trenderImage?: RenderImage;\n\trenderVideo?: RenderVideo;\n}) {\n\tconst ctx = useApertoContext();\n\tconst preset = NAVIGATION_MOTION_PRESETS[navigationMotion];\n\tconst transition = ctx.reduceMotion\n\t\t? REDUCED_EXPANDED_MEDIA_TRANSITION\n\t\t: preset.transition;\n\tconst variants = ctx.reduceMotion\n\t\t? reducedExpandedMediaVariants\n\t\t: expandedMediaVariants;\n\tconst animationCustom: NavigationAnimationCustom = {\n\t\tdirection,\n\t\toffset: preset.offset,\n\t\tscale: preset.scale,\n\t};\n\n\treturn (\n\t\t<AnimatePresence custom={animationCustom} initial={false} mode=\"sync\">\n\t\t\t<motion.div\n\t\t\t\tanimate=\"center\"\n\t\t\t\tcustom={animationCustom}\n\t\t\t\tdata-navigation-direction={direction}\n\t\t\t\tdata-navigation-motion={navigationMotion}\n\t\t\t\tdata-slot=\"aperto-media-stage\"\n\t\t\t\texit=\"exit\"\n\t\t\t\tinitial=\"enter\"\n\t\t\t\tkey={getMediaKey(item, index)}\n\t\t\t\ttransition={transition}\n\t\t\t\tvariants={variants}\n\t\t\t>\n\t\t\t\t{renderExpandedMedia(item, renderImage, renderVideo)}\n\t\t\t</motion.div>\n\t\t</AnimatePresence>\n\t);\n}\n","import type { ReactNode } from \"react\";\nimport type { ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nexport function getMediaLabel(item: ApertoMediaItem): string {\n\treturn item.title ?? item.alt ?? \"media\";\n}\n\nexport function getMediaKey(item: ApertoMediaItem, index: number): string {\n\treturn item.id ?? `${item.type}:${item.src}:${index}`;\n}\n\nexport function getDescriptionProps(item: ApertoMediaItem): {\n\t\"aria-describedby\"?: undefined;\n} {\n\treturn item.description ? {} : { \"aria-describedby\": undefined };\n}\n\nfunction renderDefaultImage(props: Parameters<RenderImage>[0]): ReactNode {\n\tconst { item: _item, variant: _variant, ...imageProps } = props;\n\treturn <img {...imageProps} alt={imageProps.alt ?? \"\"} />;\n}\n\nfunction renderDefaultVideo(props: Parameters<RenderVideo>[0]): ReactNode {\n\tconst { item: _item, variant, ...videoProps } = props;\n\tif (variant === \"thumbnail\") {\n\t\treturn (\n\t\t\t<img alt={videoProps[\"aria-label\"] ?? \"\"} src={props.item.thumbnailSrc} />\n\t\t);\n\t}\n\treturn <video {...videoProps} />;\n}\n\nexport function renderThumbnail(\n\titem: ApertoMediaItem,\n\trenderImage?: RenderImage,\n\trenderVideo?: RenderVideo,\n): ReactNode {\n\tif (item.type === \"image\") {\n\t\tconst imageProps: Parameters<RenderImage>[0] = {\n\t\t\talt: \"\",\n\t\t\theight: item.height,\n\t\t\titem,\n\t\t\tsrc: item.thumbnailSrc ?? item.src,\n\t\t\tvariant: \"thumbnail\",\n\t\t\twidth: item.width,\n\t\t};\n\t\treturn (renderImage ?? renderDefaultImage)(imageProps);\n\t}\n\n\tconst videoProps: Parameters<RenderVideo>[0] = {\n\t\t\"aria-label\": item.alt ?? item.title ?? \"Video thumbnail\",\n\t\theight: item.height,\n\t\titem,\n\t\tposter: item.poster,\n\t\tsrc: item.thumbnailSrc,\n\t\tvariant: \"thumbnail\",\n\t\twidth: item.width,\n\t};\n\treturn (renderVideo ?? renderDefaultVideo)(videoProps);\n}\n\nexport function renderExpandedMedia(\n\titem: ApertoMediaItem,\n\trenderImage?: RenderImage,\n\trenderVideo?: RenderVideo,\n): ReactNode {\n\tif (item.type === \"image\") {\n\t\tconst imageProps: Parameters<RenderImage>[0] = {\n\t\t\talt: item.alt,\n\t\t\theight: item.height,\n\t\t\titem,\n\t\t\tsrc: item.src,\n\t\t\tvariant: \"expanded\",\n\t\t\twidth: item.width,\n\t\t};\n\t\treturn (renderImage ?? renderDefaultImage)(imageProps);\n\t}\n\n\tconst videoProps: Parameters<RenderVideo>[0] = {\n\t\t\"aria-label\": item.alt ?? item.title ?? \"Video\",\n\t\tcontrols: true,\n\t\theight: item.height,\n\t\titem,\n\t\tposter: item.poster,\n\t\tsrc: item.src,\n\t\tvariant: \"expanded\",\n\t\twidth: item.width,\n\t};\n\treturn (renderVideo ?? renderDefaultVideo)(videoProps);\n}\n\nexport function renderTransitionMedia(\n\titem: ApertoMediaItem,\n\trenderImage?: RenderImage,\n\trenderVideo?: RenderVideo,\n): ReactNode {\n\tif (item.type === \"image\") {\n\t\tconst imageProps: Parameters<RenderImage>[0] = {\n\t\t\talt: item.alt,\n\t\t\theight: item.height,\n\t\t\titem,\n\t\t\tsrc: item.src,\n\t\t\tvariant: \"expanded\",\n\t\t\twidth: item.width,\n\t\t};\n\t\treturn (renderImage ?? renderDefaultImage)(imageProps);\n\t}\n\n\tconst videoProps: Parameters<RenderVideo>[0] = {\n\t\t\"aria-label\": item.alt ?? item.title ?? \"Video\",\n\t\theight: item.height,\n\t\titem,\n\t\tposter: item.poster,\n\t\tsrc: item.src,\n\t\tvariant: \"expanded\",\n\t\twidth: item.width,\n\t};\n\treturn (renderVideo ?? renderDefaultVideo)(videoProps);\n}\n","import {\n\tmotion,\n\ttype TargetAndTransition,\n\ttype Transition,\n} from \"motion/react\";\nimport { useEffect } from \"react\";\nimport { useApertoContext } from \"./context\";\nimport { renderTransitionMedia } from \"./media-rendering\";\nimport type { ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nexport interface ApertoRect {\n\theight: number;\n\tleft: number;\n\ttop: number;\n\twidth: number;\n}\n\nexport interface ApertoMediaTransition {\n\tfrom: ApertoRect;\n\titem: ApertoMediaItem;\n\tphase: \"opening\" | \"closing\";\n\tto?: ApertoRect;\n}\n\nexport function rectFromElement(element: Element | null): ApertoRect | null {\n\tif (!element) {\n\t\treturn null;\n\t}\n\n\tconst rect = element.getBoundingClientRect();\n\treturn {\n\t\theight: rect.height,\n\t\tleft: rect.left,\n\t\ttop: rect.top,\n\t\twidth: rect.width,\n\t};\n}\n\nfunction rectTarget(rect: ApertoRect): TargetAndTransition {\n\treturn {\n\t\theight: rect.height,\n\t\tleft: rect.left,\n\t\ttop: rect.top,\n\t\twidth: rect.width,\n\t};\n}\n\nfunction transitionDurationMs(transition: Transition): number {\n\treturn typeof transition.duration === \"number\"\n\t\t? transition.duration * 1000\n\t\t: 450;\n}\n\nexport function ApertoMediaTransitionClone({\n\tonComplete,\n\trenderImage,\n\trenderVideo,\n\ttransition,\n}: {\n\tonComplete: () => void;\n\trenderImage?: RenderImage;\n\trenderVideo?: RenderVideo;\n\ttransition: ApertoMediaTransition | null;\n}) {\n\tconst ctx = useApertoContext();\n\n\tuseEffect(() => {\n\t\tif (!transition?.to) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst timer = setTimeout(\n\t\t\tonComplete,\n\t\t\ttransitionDurationMs(ctx.preset.transition),\n\t\t);\n\t\treturn () => clearTimeout(timer);\n\t}, [ctx.preset.transition, onComplete, transition]);\n\n\tif (!transition?.to) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<motion.div\n\t\t\tanimate={rectTarget(transition.to)}\n\t\t\taria-hidden=\"true\"\n\t\t\tdata-slot=\"aperto-transition-media\"\n\t\t\tinitial={rectTarget(transition.from)}\n\t\t\tstyle={{\n\t\t\t\tborderRadius: \"var(--aperto-radius, 0.5rem)\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t\tpointerEvents: \"none\",\n\t\t\t\tposition: \"fixed\",\n\t\t\t\twillChange: \"left, top, width, height\",\n\t\t\t\tzIndex: 1002,\n\t\t\t}}\n\t\t\ttransition={ctx.preset.transition}\n\t\t>\n\t\t\t{renderTransitionMedia(transition.item, renderImage, renderVideo)}\n\t\t</motion.div>\n\t);\n}\n","export function shouldIgnoreKeyboardNavigationTarget(\n\ttarget: EventTarget | null,\n): boolean {\n\tif (!(target instanceof Element)) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\t(target as HTMLElement).isContentEditable ||\n\t\tBoolean(\n\t\t\ttarget.closest(\n\t\t\t\t'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"textbox\"], audio, video',\n\t\t\t),\n\t\t)\n\t);\n}\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\n\nconst ApertoClose = forwardRef<\n\tHTMLButtonElement,\n\tComponentPropsWithoutRef<typeof Dialog.Close>\n>(({ children, ...props }, ref) => {\n\treturn (\n\t\t<Dialog.Close data-slot=\"aperto-close\" ref={ref} {...props}>\n\t\t\t{children ?? <X aria-hidden=\"true\" size={17} strokeWidth={2} />}\n\t\t</Dialog.Close>\n\t);\n});\n\nApertoClose.displayName = \"ApertoClose\";\n\nexport { ApertoClose };\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { motion } from \"motion/react\";\nimport {\n\ttype ComponentPropsWithoutRef,\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseState,\n} 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\n\textends ComponentPropsWithoutRef<typeof Dialog.Trigger> {\n\t/** Internal flag used by grouped thumbnails to raise only the active trigger. */\n\tactive?: boolean;\n\t/** Override motion preset for this trigger */\n\tmotion?: MotionPresetName;\n\t/** Internal shared layout ID override for grouped thumbnails. */\n\tsharedLayoutId?: string | false;\n}\n\nconst ApertoTrigger = forwardRef<HTMLButtonElement, ApertoTriggerProps>(\n\t(\n\t\t{ active, children, motion: motionOverride, sharedLayoutId, ...props },\n\t\tref,\n\t) => {\n\t\tconst ctx = useApertoContext();\n\t\tconst shouldRaise = ctx.open && (active ?? true);\n\t\tconst [zIndex, setZIndex] = useState(\n\t\t\tshouldRaise ? TRIGGER_OPEN_Z_INDEX : 0,\n\t\t);\n\n\t\tuseEffect(() => {\n\t\t\tif (shouldRaise) {\n\t\t\t\tsetZIndex(TRIGGER_OPEN_Z_INDEX);\n\t\t\t} else if (ctx.open) {\n\t\t\t\tsetZIndex(0);\n\t\t\t}\n\t\t}, [ctx.open, shouldRaise]);\n\n\t\tconst handleLayoutAnimationComplete = useCallback(() => {\n\t\t\tif (!shouldRaise) {\n\t\t\t\tsetZIndex(0);\n\t\t\t}\n\t\t}, [shouldRaise]);\n\n\t\tconst resolved = resolvePreset(\n\t\t\t\"trigger\",\n\t\t\tmotionOverride,\n\t\t\tctx.presetName,\n\t\t\tctx.variants,\n\t\t\tctx.reduceMotion,\n\t\t);\n\t\tconst layoutId =\n\t\t\tsharedLayoutId === false\n\t\t\t\t? undefined\n\t\t\t\t: (sharedLayoutId ?? `${ctx.layoutId}-shared`);\n\n\t\treturn (\n\t\t\t<Dialog.Trigger asChild ref={ref} {...props}>\n\t\t\t\t<motion.button\n\t\t\t\t\tdata-aperto-active={shouldRaise ? \"\" : undefined}\n\t\t\t\t\tdata-slot=\"aperto-trigger\"\n\t\t\t\t\tkey={layoutId ?? \"unshared\"}\n\t\t\t\t\tlayout\n\t\t\t\t\tlayoutCrossfade={false}\n\t\t\t\t\tlayoutId={layoutId}\n\t\t\t\t\tonLayoutAnimationComplete={handleLayoutAnimationComplete}\n\t\t\t\t\tstyle={{ zIndex }}\n\t\t\t\t\ttransition={resolved.transition}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</motion.button>\n\t\t\t</Dialog.Trigger>\n\t\t);\n\t},\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 {\n\tgetDescriptionProps,\n\tgetMediaLabel,\n\trenderExpandedMedia,\n\trenderThumbnail,\n} from \"../media-rendering\";\nimport type { ApertoProps } from \"./ApertoTypes\";\n\nexport function ApertoSingle({\n\tclassNames,\n\tdismissible,\n\tmedia,\n\trenderImage,\n\trenderVideo,\n}: ApertoProps) {\n\tconst label = getMediaLabel(media);\n\tconst title = media.title ?? label;\n\n\treturn (\n\t\t<ApertoRoot dismissible={dismissible}>\n\t\t\t<ApertoTrigger\n\t\t\t\taria-label={`Open ${label}`}\n\t\t\t\tclassName={classNames?.thumbnail}\n\t\t\t>\n\t\t\t\t{renderThumbnail(media, renderImage, renderVideo)}\n\t\t\t</ApertoTrigger>\n\t\t\t<ApertoPortal>\n\t\t\t\t<ApertoOverlay className={classNames?.overlay} />\n\t\t\t\t<ApertoContent\n\t\t\t\t\tclassName={classNames?.content}\n\t\t\t\t\t{...getDescriptionProps(media)}\n\t\t\t\t>\n\t\t\t\t\t{renderExpandedMedia(media, renderImage, renderVideo)}\n\t\t\t\t\t<ApertoTitle>{title}</ApertoTitle>\n\t\t\t\t\t{media.description ? (\n\t\t\t\t\t\t<ApertoDescription>{media.description}</ApertoDescription>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<ApertoClose\n\t\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t\t\tclassName={classNames?.closeButton}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t/>\n\t\t\t\t</ApertoContent>\n\t\t\t</ApertoPortal>\n\t\t</ApertoRoot>\n\t);\n}\n","\"use client\";\n\nimport { useApertoGroup } from \"../aperto-group-context\";\nimport { ApertoTrigger } from \"../aperto-trigger\";\nimport { getMediaLabel, renderThumbnail } from \"../media-rendering\";\nimport type { ApertoThumbnailProps } from \"./ApertoTypes\";\n\nexport function ApertoThumbnail({\n\tchildren,\n\tclassName,\n\tindex,\n}: ApertoThumbnailProps) {\n\tconst group = useApertoGroup();\n\tconst media = group.media[index];\n\n\tif (!media) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<ApertoTrigger\n\t\t\tactive={group.index === index}\n\t\t\taria-label={`Open ${getMediaLabel(media)}`}\n\t\t\tclassName={className ?? group.classNames?.thumbnail}\n\t\t\tonClick={() => group.openAtIndex(index)}\n\t\t\tref={(node) => group.registerThumbnail(index, node)}\n\t\t\tsharedLayoutId={false}\n\t\t>\n\t\t\t{children ?? renderThumbnail(media, group.renderImage, group.renderVideo)}\n\t\t</ApertoTrigger>\n\t);\n}\n","\"use client\";\n\n/**\n * @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 {\n\tApertoGroup,\n\ttype ApertoGroupProps,\n\ttype ApertoProps,\n\tApertoSingle,\n\tApertoThumbnail,\n\ttype ApertoThumbnailProps,\n} from \"./aperto\";\nimport { ApertoClose } from \"./aperto-close\";\nimport { ApertoContent, type ApertoContentProps } from \"./aperto-content\";\nimport { ApertoDescription } from \"./aperto-description\";\nimport { ApertoOverlay, type ApertoOverlayProps } from \"./aperto-overlay\";\nimport { ApertoPortal, type ApertoPortalProps } from \"./aperto-portal\";\nimport { ApertoRoot, type ApertoRootProps } from \"./aperto-root\";\nimport { ApertoTitle } from \"./aperto-title\";\nimport { ApertoTrigger, type ApertoTriggerProps } from \"./aperto-trigger\";\n\n/** Lower-level compound component namespace for advanced composition. */\nconst ApertoPrimitive = {\n\tClose: ApertoClose,\n\tContent: ApertoContent,\n\tDescription: ApertoDescription,\n\tOverlay: ApertoOverlay,\n\tPortal: ApertoPortal,\n\tRoot: ApertoRoot,\n\tTitle: ApertoTitle,\n\tTrigger: ApertoTrigger,\n};\n\n/** Primary media-first component namespace. */\nconst Aperto = Object.assign(ApertoSingle, {\n\tGroup: ApertoGroup,\n\tPrimitive: ApertoPrimitive,\n\tThumbnail: ApertoThumbnail,\n});\n\n// Preset system\nexport { PRESETS, resolvePreset } from \"./presets\";\n// Types\nexport type {\n\tApertoClassNames,\n\tApertoImageItem,\n\tApertoMediaItem,\n\tApertoVideoItem,\n\tDismissibleConfig,\n\tDragSpringConfig,\n\tMotionPreset,\n\tMotionPresetName,\n\tMotionProp,\n\tMotionVariants,\n\tNavigationMotionPresetName,\n\tRenderImage,\n\tRenderVideo,\n} from \"./types\";\n// Named exports for tree-shaking\nexport {\n\tAperto,\n\tApertoClose,\n\tApertoContent,\n\ttype ApertoContentProps,\n\tApertoDescription,\n\tApertoGroup,\n\ttype ApertoGroupProps,\n\tApertoOverlay,\n\ttype ApertoOverlayProps,\n\tApertoPortal,\n\ttype ApertoPortalProps,\n\tApertoPrimitive,\n\ttype ApertoProps,\n\tApertoRoot,\n\ttype ApertoRootProps,\n\tApertoThumbnail,\n\ttype ApertoThumbnailProps,\n\tApertoTitle,\n\tApertoTrigger,\n\ttype ApertoTriggerProps,\n};\n"],"mappings":"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","names":["useCallback","useId","useMemo","useState","Dialog","forwardRef","jsx","createContext","useContext","Dialog","motion","forwardRef","jsx","forwardRef","motion","Dialog","jsx","Dialog","useCallback","useState","jsx","useState","useCallback","Dialog","forwardRef","jsx","AnimatePresence","motion","jsx","jsx","AnimatePresence","motion","motion","jsx","motion","jsx","useId","useState","useCallback","useMemo","Dialog","X","forwardRef","jsx","Dialog","motion","forwardRef","useCallback","useEffect","useState","jsx","forwardRef","useState","useEffect","useCallback","motion","jsx","jsxs","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/Aperto/ApertoGroup.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/ApertoGroupState.ts","../src/Aperto/ApertoKeyboard.ts","../src/aperto-close.tsx","../src/aperto-trigger.tsx","../src/Aperto/ApertoSingle.tsx","../src/Aperto/ApertoThumbnail.tsx","../src/index.ts"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeft, ChevronRight, X } from \"lucide-react\";\nimport {\n type CSSProperties,\n type KeyboardEvent,\n useCallback,\n useId,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n} 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 {\n ApertoExpandedMediaStage,\n type NavigationDirection,\n} 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 \"./ApertoGroupState\";\nimport { shouldIgnoreKeyboardNavigationTarget } from \"./ApertoKeyboard\";\nimport type { ApertoGroupProps } from \"./ApertoTypes\";\n\nexport function 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(\n apertoGroupReducer,\n initialIndex,\n getInitialGroupState\n );\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 = useCallback(\n (nextIndex: number) => `aperto-group-${generatedId}-${nextIndex}-shared`,\n [generatedId]\n );\n const sharedLayoutId = sharedLayoutIdForIndex(state.layoutSourceIndex);\n const measureOpeningTarget = useCallback((node: HTMLDivElement) => {\n const targetRect = rectFromElement(node);\n if (!targetRect) {\n return;\n }\n dispatch({ rect: targetRect, type: \"complete-opening-target\" });\n }, []);\n const setExpandedMediaNode = useCallback(\n (node: HTMLDivElement | null) => {\n expandedMediaRef.current = node;\n if (node) {\n measureOpeningTarget(node);\n }\n },\n [measureOpeningTarget]\n );\n\n const registerThumbnail = useCallback(\n (thumbIndex: number, node: HTMLButtonElement | null) => {\n if (node) {\n thumbnailMap.set(thumbIndex, node);\n return;\n }\n thumbnailMap.delete(thumbIndex);\n },\n [thumbnailMap]\n );\n\n useLayoutEffect(() => {\n if (\n state.mediaTransition?.phase !== \"opening\" ||\n state.mediaTransition.to ||\n !expandedMediaRef.current\n ) {\n return;\n }\n\n measureOpeningTarget(expandedMediaRef.current);\n }, [measureOpeningTarget, state.mediaTransition]);\n\n const setIndex = useCallback(\n (nextIndex: number) => {\n if (!isControlled) {\n dispatch({ index: nextIndex, type: \"set-index\" });\n }\n onIndexChange?.(nextIndex);\n },\n [isControlled, onIndexChange]\n );\n\n const openAtIndex = useCallback(\n (thumbIndex: number) => {\n const sourceRect = rectFromElement(thumbnailMap.get(thumbIndex) ?? null);\n const item = media[thumbIndex];\n const transition =\n sourceRect && item\n ? { from: sourceRect, item, phase: \"opening\" as const }\n : null;\n\n dispatch({ index: thumbIndex, transition, type: \"open-at-index\" });\n onIndexChange?.(thumbIndex);\n },\n [media, onIndexChange, thumbnailMap]\n );\n\n const startClose = useCallback(() => {\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 }, [activeMedia, index, state.closing, state.open, thumbnailMap]);\n\n const handleCloseAutoFocus = useCallback(\n (event: Event) => {\n event.preventDefault();\n thumbnailMap.get(index)?.focus({ preventScroll: true });\n },\n [index, thumbnailMap]\n );\n\n const handleMediaTransitionComplete = useCallback(() => {\n dispatch({ type: \"finish-transition\" });\n }, []);\n\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n if (nextOpen) {\n dispatch({ open: true, type: \"set-open\" });\n return;\n }\n\n startClose();\n },\n [startClose]\n );\n\n const value = useMemo(\n () => ({\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 [\n classNames,\n index,\n media,\n state.open,\n openAtIndex,\n registerThumbnail,\n renderImage,\n renderVideo,\n setIndex,\n sharedLayoutId,\n sharedLayoutIdForIndex,\n ]\n );\n const hasNavigation = media.length > 1;\n const navigateToIndex = useCallback(\n (nextIndex: number, direction: NavigationDirection) => {\n dispatch({ direction, index: nextIndex, type: \"navigate\" });\n onIndexChange?.(nextIndex);\n },\n [onIndexChange]\n );\n const goToPrevious = useCallback(() => {\n navigateToIndex((index - 1 + media.length) % media.length, -1);\n }, [index, media.length, navigateToIndex]);\n const goToNext = useCallback(() => {\n navigateToIndex((index + 1) % media.length, 1);\n }, [index, media.length, navigateToIndex]);\n const handleContentKeyDown = useCallback(\n (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 [goToNext, goToPrevious]\n );\n const expandedMediaStyle = useMemo((): 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 }, [activeMedia?.height, activeMedia?.width]);\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\n className={classNames?.overlay}\n fadeOut={state.closing}\n />\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\n data-slot=\"aperto-media\"\n ref={setExpandedMediaNode}\n style={expandedMediaStyle}\n >\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>\n {activeMedia.title ?? getMediaLabel(activeMedia)}\n </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\nfunction 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","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport {\n type MotionStyle,\n m,\n type PanInfo,\n useMotionValue,\n useSpring,\n useTransform,\n} from \"motion/react\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n useCallback,\n useMemo,\n useState,\n} 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 ComponentPropsWithoutRef<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 = forwardRef<HTMLDivElement, ApertoContentProps>(\n (\n {\n children,\n className,\n motion: motionOverride,\n placement = \"center\",\n sharedLayoutId,\n style,\n ...props\n },\n ref\n ) => {\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\n ? undefined\n : (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 =\n dismissConfig.threshold ?? DEFAULT_DISTANCE_THRESHOLD;\n const velocityThreshold =\n 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(() =>\n Math.hypot(springX.get(), springY.get())\n );\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\n const handleDrag = useCallback(\n (_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 [dragX, dragY, isDragging, resistance]\n );\n\n const handleDragEnd = useCallback(\n (_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 ctx.onOpenChange(false);\n return;\n }\n\n dragX.set(0);\n dragY.set(0);\n },\n [ctx.onOpenChange, distanceThreshold, dragX, dragY, velocityThreshold]\n );\n\n const motionStyle = useMemo(\n (): MotionStyle => ({\n cursor: isDragging ? \"grabbing\" : isDismissible ? \"grab\" : undefined,\n opacity: opacityMotion,\n scale: scaleMotion,\n x: springX,\n y: springY,\n ...(placement === \"center\"\n ? {\n left: \"50%\",\n top: \"50%\",\n translate: \"-50% -50%\",\n }\n : {}),\n ...style,\n }),\n [\n isDismissible,\n isDragging,\n opacityMotion,\n placement,\n scaleMotion,\n springX,\n springY,\n style,\n ]\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);\n\nApertoContent.displayName = \"ApertoContent\";\n\nexport { ApertoContent };\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\n\nimport type { ApertoContextValue } from \"./types\";\n\nexport const ApertoContext = createContext<ApertoContextValue | null>(null);\n\nexport function useApertoContext(): ApertoContextValue {\n const ctx = useContext(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 function calculateResistance(distance: number): number {\n return Math.max(\n RESISTANCE_MIN,\n 1 - Math.log(distance / RESISTANCE_DIVISOR + 1) / RESISTANCE_SCALE\n );\n}\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 snappy: 0.22,\n moderate: 0.4,\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: { stiffness: 260, damping: 12, mass: 1 },\n natural: { stiffness: 200, damping: 20, mass: 1 },\n snappy: { stiffness: 400, damping: 28, mass: 0.8 },\n stiff: { stiffness: 500, damping: 30, mass: 1 },\n} as const;\n","import { durations, easings, springs } from \"./motion-tokens\";\nimport type {\n DragSpringConfig,\n MotionPreset,\n MotionPresetName,\n MotionVariants,\n} 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 snappy: {\n transition: { ease: easings.snappy, duration: durations.snappy },\n drag: {\n stiffness: springs.stiff.stiffness,\n damping: springs.stiff.damping,\n restDelta: 0.01,\n },\n },\n smooth: {\n transition: { ease: easings.customGentle, duration: durations.moderate },\n drag: {\n stiffness: springs.natural.stiffness,\n damping: springs.natural.damping,\n restDelta: 0.01,\n },\n },\n bouncy: {\n transition: {\n type: \"spring\",\n stiffness: springs.bouncy.stiffness,\n damping: springs.bouncy.damping,\n mass: springs.bouncy.mass,\n },\n drag: {\n stiffness: springs.snappy.stiffness,\n damping: springs.snappy.damping,\n restDelta: 0.01,\n },\n },\n reduced: {\n transition: { ease: \"linear\", duration: 0.01 },\n drag: { stiffness: 1000, damping: 50, restDelta: 0.1 },\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 function 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 function getDragSpring(preset: MotionPreset): DragSpringConfig {\n return preset.drag;\n}\n","\"use client\";\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\n\nconst ApertoDescription = forwardRef<\n HTMLParagraphElement,\n ComponentPropsWithoutRef<typeof Dialog.Description>\n>((props, ref) => {\n return (\n <Dialog.Description data-slot=\"aperto-description\" ref={ref} {...props} />\n );\n});\n\nApertoDescription.displayName = \"ApertoDescription\";\n\nexport { ApertoDescription };\n","import { createContext, useContext } from \"react\";\n\nimport type {\n ApertoClassNames,\n ApertoMediaItem,\n RenderImage,\n RenderVideo,\n} 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>(\n null\n);\n\nexport function useApertoGroup(): ApertoGroupContextValue {\n const ctx = useContext(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, type Transition } from \"motion/react\";\nimport { forwardRef } 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 style?: React.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 = forwardRef<HTMLDivElement, ApertoOverlayProps>(\n ({ className, fadeOut, style }, ref) => {\n const ctx = useApertoContext();\n const transition = ctx.reduceMotion\n ? OVERLAY_TRANSITION_REDUCED\n : 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);\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\nfunction 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 {\n domMax,\n LayoutGroup,\n LazyMotion,\n useReducedMotion,\n} from \"motion/react\";\nimport {\n type ComponentPropsWithoutRef,\n type ReactNode,\n useCallback,\n useId,\n useMemo,\n useState,\n} from \"react\";\n\nimport { ApertoContext } from \"./context\";\nimport { PRESETS } from \"./presets\";\nimport type {\n DismissibleConfig,\n MotionPresetName,\n MotionVariants,\n} 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\nfunction 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 = useCallback(\n (nextOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(nextOpen);\n }\n controlledOnOpenChange?.(nextOpen);\n },\n [isControlled, controlledOnOpenChange]\n );\n\n // Resolve global preset name\n const globalPresetName: MotionPresetName =\n typeof motionProp === \"string\" ? motionProp : \"smooth\";\n const variants: MotionVariants | undefined =\n typeof motionProp === \"object\" ? motionProp : undefined;\n\n const presetName: MotionPresetName = shouldReduce\n ? \"reduced\"\n : globalPresetName;\n const preset = PRESETS[presetName];\n const contextValue = useMemo(\n () => ({\n dismissible,\n layoutId,\n onOpenChange,\n open,\n preset,\n presetName,\n reduceMotion: shouldReduce,\n variants,\n }),\n [\n dismissible,\n layoutId,\n onOpenChange,\n open,\n preset,\n presetName,\n shouldReduce,\n variants,\n ]\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 ComponentPropsWithoutRef, forwardRef } from \"react\";\n\nconst ApertoTitle = forwardRef<\n HTMLHeadingElement,\n ComponentPropsWithoutRef<typeof Dialog.Title>\n>((props, ref) => {\n return <Dialog.Title data-slot=\"aperto-title\" ref={ref} {...props} />;\n});\n\nApertoTitle.displayName = \"ApertoTitle\";\n\nexport { ApertoTitle };\n","import {\n AnimatePresence,\n m,\n type TargetAndTransition,\n type Transition,\n} 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<\n NavigationMotionPresetName,\n NavigationMotionPreset\n> = {\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: ({\n direction,\n offset,\n scale,\n }: NavigationAnimationCustom): TargetAndTransition => ({\n opacity: 0,\n scale: direction === 0 ? 1 : scale,\n x: direction * offset,\n }),\n exit: ({\n direction,\n offset,\n scale,\n }: 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 function 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\n ? REDUCED_EXPANDED_MEDIA_TRANSITION\n : preset.transition;\n const variants = ctx.reduceMotion\n ? reducedExpandedMediaVariants\n : 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\n item={item}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n </m.div>\n </AnimatePresence>\n );\n}\n","import { createElement, type ReactNode } from \"react\";\n\nimport type { ApertoMediaItem, RenderImage, RenderVideo } from \"./types\";\n\nfunction renderDefaultImage(props: Parameters<RenderImage>[0]): ReactNode {\n const { item: _item, variant: _variant, ...imageProps } = props;\n return createElement(\"img\", { ...imageProps, alt: imageProps.alt ?? \"\" });\n}\n\nfunction 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 function 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 function 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 function 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 function getMediaLabel(item: ApertoMediaItem): string {\n return item.title ?? item.alt ?? \"media\";\n}\n\nexport function getMediaKey(item: ApertoMediaItem, index: number): string {\n return item.id ?? `${item.type}:${item.src}:${index}`;\n}\n\nexport function getDescriptionProps(item: ApertoMediaItem): {\n \"aria-describedby\"?: undefined;\n} {\n return item.description ? {} : { \"aria-describedby\": undefined };\n}\n","import { m } from \"motion/react\";\nimport { useEffect } from \"react\";\n\nimport { useApertoContext } from \"./context\";\nimport { ApertoTransitionMedia } from \"./media-rendering\";\nimport {\n type ApertoMediaTransition,\n rectTarget,\n transitionDurationMs,\n} from \"./media-transition-utils\";\nimport type { RenderImage, RenderVideo } from \"./types\";\n\nexport function 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(\n onComplete,\n transitionDurationMs(ctx.preset.transition)\n );\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\";\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: import(\"./types\").ApertoMediaItem;\n phase: \"opening\" | \"closing\";\n to?: ApertoRect;\n}\n\nexport function 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 function rectTarget(rect: ApertoRect): TargetAndTransition {\n return {\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n };\n}\n\nexport function transitionDurationMs(transition: Transition): number {\n return typeof transition.duration === \"number\"\n ? transition.duration * 1000\n : 450;\n}\n","import type { NavigationDirection } from \"../expanded-media-stage\";\nimport type {\n ApertoMediaTransition,\n ApertoRect,\n} 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 function getInitialGroupState(initialIndex: number): ApertoGroupState {\n return {\n closing: false,\n internalIndex: initialIndex,\n layoutSourceIndex: initialIndex,\n mediaTransition: null,\n navigationDirection: 0,\n open: false,\n };\n}\n\nexport function 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 case \"complete-opening-target\":\n if (\n state.mediaTransition?.phase !== \"opening\" ||\n state.mediaTransition.to\n ) {\n return state;\n }\n return {\n ...state,\n mediaTransition: { ...state.mediaTransition, to: action.rect },\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 case \"navigate\":\n return {\n ...state,\n internalIndex: action.index,\n layoutSourceIndex: action.index,\n navigationDirection: action.direction,\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 case \"set-index\":\n return { ...state, internalIndex: action.index };\n case \"set-open\":\n return action.open\n ? { ...state, closing: false, open: true }\n : { ...state, open: false };\n case \"start-close\":\n return {\n ...state,\n closing: true,\n mediaTransition: action.transition,\n };\n }\n}\n","export function shouldIgnoreKeyboardNavigationTarget(\n target: EventTarget | null\n): 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 ComponentPropsWithoutRef, forwardRef } from \"react\";\n\nconst ApertoClose = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof Dialog.Close>\n>(({ children, ...props }, ref) => {\n return (\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});\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 ComponentPropsWithoutRef, forwardRef } 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 ComponentPropsWithoutRef<\n typeof Dialog.Trigger\n> {\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 = forwardRef<HTMLButtonElement, ApertoTriggerProps>(\n (\n { active, children, motion: motionOverride, sharedLayoutId, ...props },\n ref\n ) => {\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\n ? undefined\n : (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);\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 \"./ApertoTypes\";\n\nexport function 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\n aria-label={`Open ${label}`}\n className={classNames?.thumbnail}\n >\n <ApertoThumbnailMedia\n item={media}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n </ApertoTrigger>\n <ApertoPortal>\n <ApertoOverlay className={classNames?.overlay} />\n <ApertoContent\n className={classNames?.content}\n {...getDescriptionProps(media)}\n >\n <ApertoExpandedMedia\n item={media}\n renderImage={renderImage}\n renderVideo={renderVideo}\n />\n <ApertoTitle>{title}</ApertoTitle>\n {media.description ? (\n <ApertoDescription>{media.description}</ApertoDescription>\n ) : null}\n <ApertoClose\n aria-label=\"Close\"\n className={classNames?.closeButton}\n type=\"button\"\n />\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 \"./ApertoTypes\";\n\nexport function ApertoThumbnail({\n children,\n className,\n index,\n}: 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 * @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 {\n ApertoGroup,\n type ApertoGroupProps,\n type ApertoProps,\n ApertoSingle,\n ApertoThumbnail,\n type ApertoThumbnailProps,\n} from \"./aperto\";\nimport { ApertoClose } from \"./aperto-close\";\nimport { ApertoContent, type ApertoContentProps } from \"./aperto-content\";\nimport { ApertoDescription } from \"./aperto-description\";\nimport { ApertoOverlay, type ApertoOverlayProps } from \"./aperto-overlay\";\nimport { ApertoPortal, type ApertoPortalProps } from \"./aperto-portal\";\nimport { ApertoRoot, type ApertoRootProps } from \"./aperto-root\";\nimport { ApertoTitle } from \"./aperto-title\";\nimport { ApertoTrigger, 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":["useCallback","useId","useMemo","Dialog","forwardRef","jsx","createContext","useContext","Dialog","m","forwardRef","jsx","forwardRef","m","Dialog","jsx","Dialog","useCallback","useMemo","useState","jsx","useState","useCallback","useMemo","Dialog","forwardRef","jsx","AnimatePresence","m","jsx","jsx","AnimatePresence","m","m","jsx","m","jsx","useId","useCallback","useMemo","Dialog","X","forwardRef","jsx","Dialog","m","forwardRef","jsx","forwardRef","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]>*{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,24 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternmode/aperto",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Opinionated, styled thumbnail-to-expanded media transitions for React.",
|
|
5
|
+
"homepage": "https://github.com/howells/patternmode/tree/main/packages/aperto#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/howells/patternmode/issues"
|
|
8
|
+
},
|
|
5
9
|
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"sideEffects": [
|
|
8
|
-
"**/*.css"
|
|
9
|
-
],
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+ssh://git@github.com/howells/patternmode.git",
|
|
13
13
|
"directory": "packages/aperto"
|
|
14
14
|
},
|
|
15
|
-
"bugs": {
|
|
16
|
-
"url": "https://github.com/howells/patternmode/issues"
|
|
17
|
-
},
|
|
18
|
-
"homepage": "https://github.com/howells/patternmode/tree/main/packages/aperto#readme",
|
|
19
15
|
"files": [
|
|
20
16
|
"dist"
|
|
21
17
|
],
|
|
18
|
+
"type": "module",
|
|
19
|
+
"sideEffects": [
|
|
20
|
+
"**/*.css"
|
|
21
|
+
],
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
22
25
|
"exports": {
|
|
23
26
|
".": {
|
|
24
27
|
"types": "./dist/index.d.ts",
|
|
@@ -26,9 +29,6 @@
|
|
|
26
29
|
},
|
|
27
30
|
"./styles.css": "./dist/styles.css"
|
|
28
31
|
},
|
|
29
|
-
"main": "./dist/index.js",
|
|
30
|
-
"module": "./dist/index.js",
|
|
31
|
-
"types": "./dist/index.d.ts",
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
@@ -38,19 +38,22 @@
|
|
|
38
38
|
"motion": "^12.38.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
+
"@howells/lint": "^0.2.0",
|
|
41
42
|
"@howells/typescript-config": "^0.1.2",
|
|
42
43
|
"@tailwindcss/cli": "^4.3.0",
|
|
43
44
|
"@testing-library/jest-dom": "^6.9.1",
|
|
44
45
|
"@testing-library/react": "^16.3.2",
|
|
45
46
|
"@testing-library/user-event": "^14.6.1",
|
|
46
|
-
"@types/react": "^19.2.
|
|
47
|
-
"@types/react-dom": "^19.2.
|
|
47
|
+
"@types/react": "^19.2.14",
|
|
48
|
+
"@types/react-dom": "^19.2.3",
|
|
48
49
|
"concurrently": "^9.2.1",
|
|
49
50
|
"jsdom": "^29.1.1",
|
|
51
|
+
"react": "^19.2.3",
|
|
52
|
+
"react-dom": "^19.2.3",
|
|
50
53
|
"tailwindcss": "^4.3.0",
|
|
51
54
|
"tsup": "^8.5.1",
|
|
52
55
|
"typescript": "^6.0.3",
|
|
53
|
-
"vitest": "^4.
|
|
56
|
+
"vitest": "^4.1.6"
|
|
54
57
|
},
|
|
55
58
|
"peerDependencies": {
|
|
56
59
|
"react": ">=18.2.0 <20",
|
|
@@ -62,8 +65,8 @@
|
|
|
62
65
|
"dev": "concurrently \"pnpm dev:js\" \"pnpm dev:styles\"",
|
|
63
66
|
"dev:js": "tsup --watch",
|
|
64
67
|
"dev:styles": "tailwindcss -i styles.css -o dist/styles.css --watch",
|
|
65
|
-
"lint": "howells-
|
|
66
|
-
"lint:
|
|
68
|
+
"lint": "howells-ox-check .",
|
|
69
|
+
"lint:fix": "howells-ox-fix .",
|
|
67
70
|
"test": "vitest run --passWithNoTests",
|
|
68
71
|
"typecheck": "tsc --noEmit"
|
|
69
72
|
}
|