@m3000/market 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/blocks/auction/Auction.d.ts +49 -0
  3. package/dist/components/blocks/auction/Auction.js +44 -0
  4. package/dist/components/blocks/auction/AuctionBidForm.d.ts +11 -0
  5. package/dist/components/blocks/auction/AuctionBidForm.js +88 -0
  6. package/dist/components/blocks/auction/AuctionBidInput.d.ts +9 -0
  7. package/dist/components/blocks/auction/AuctionBidInput.js +99 -0
  8. package/dist/components/blocks/auction/AuctionContext.d.ts +71 -0
  9. package/dist/components/blocks/auction/AuctionContext.js +228 -0
  10. package/dist/components/blocks/auction/AuctionInfo.d.ts +9 -0
  11. package/dist/components/blocks/auction/AuctionInfo.js +37 -0
  12. package/dist/components/blocks/auction/AuctionLayout.d.ts +63 -0
  13. package/dist/components/blocks/auction/AuctionLayout.js +80 -0
  14. package/dist/components/blocks/auction/AuctionRankings.d.ts +16 -0
  15. package/dist/components/blocks/auction/AuctionRankings.js +334 -0
  16. package/dist/components/blocks/auction/AuctionStatusTag.d.ts +15 -0
  17. package/dist/components/blocks/auction/AuctionStatusTag.js +60 -0
  18. package/dist/components/blocks/auction/AuctionSuggestedBids.d.ts +38 -0
  19. package/dist/components/blocks/auction/AuctionSuggestedBids.js +116 -0
  20. package/dist/components/blocks/auction/AuctionYourBidCard.d.ts +27 -0
  21. package/dist/components/blocks/auction/AuctionYourBidCard.js +94 -0
  22. package/dist/components/blocks/auction/AuctionYourBids.d.ts +9 -0
  23. package/dist/components/blocks/auction/AuctionYourBids.js +49 -0
  24. package/dist/components/blocks/auction/index.d.ts +12 -0
  25. package/dist/components/blocks/index.d.ts +12 -0
  26. package/dist/components/index.d.ts +28 -0
  27. package/dist/components/primitives/Button.d.ts +31 -0
  28. package/dist/components/primitives/Button.js +117 -0
  29. package/dist/components/primitives/Drawer.d.ts +43 -0
  30. package/dist/components/primitives/Drawer.js +51 -0
  31. package/dist/components/primitives/Feedback.d.ts +28 -0
  32. package/dist/components/primitives/Feedback.js +147 -0
  33. package/dist/components/primitives/MorphDialog.d.ts +39 -0
  34. package/dist/components/primitives/MorphDialog.js +87 -0
  35. package/dist/components/primitives/Price.d.ts +84 -0
  36. package/dist/components/primitives/Price.js +255 -0
  37. package/dist/components/primitives/PriceInput.d.ts +33 -0
  38. package/dist/components/primitives/PriceInput.js +25 -0
  39. package/dist/components/primitives/Receipt.d.ts +164 -0
  40. package/dist/components/primitives/Receipt.js +344 -0
  41. package/dist/components/primitives/Scale.d.ts +67 -0
  42. package/dist/components/primitives/Scale.js +132 -0
  43. package/dist/components/primitives/Separator.d.ts +22 -0
  44. package/dist/components/primitives/Separator.js +62 -0
  45. package/dist/components/primitives/Skeleton.d.ts +14 -0
  46. package/dist/components/primitives/Skeleton.js +20 -0
  47. package/dist/components/primitives/SteppedInput.d.ts +94 -0
  48. package/dist/components/primitives/SteppedInput.js +154 -0
  49. package/dist/components/primitives/Tabs.d.ts +37 -0
  50. package/dist/components/primitives/Tabs.js +99 -0
  51. package/dist/components/primitives/Tag.d.ts +24 -0
  52. package/dist/components/primitives/Tag.js +22 -0
  53. package/dist/components/primitives/Text.d.ts +32 -0
  54. package/dist/components/primitives/Text.js +65 -0
  55. package/dist/components/primitives/countdown/Countdown.d.ts +24 -0
  56. package/dist/components/primitives/countdown/Countdown.js +22 -0
  57. package/dist/components/primitives/framed-image/FramedImage.d.ts +13 -0
  58. package/dist/components/primitives/framed-image/FramedImage.js +37 -0
  59. package/dist/components/primitives/index.d.ts +17 -0
  60. package/dist/components/primitives/ranked-list/Ranking.d.ts +117 -0
  61. package/dist/components/primitives/ranked-list/Ranking.js +219 -0
  62. package/dist/components/primitives/ranked-list/index.d.ts +1 -0
  63. package/dist/hooks/useCountdown.d.ts +20 -0
  64. package/dist/hooks/useCountdown.js +75 -0
  65. package/dist/index.d.ts +36 -0
  66. package/dist/index.js +36 -0
  67. package/dist/lib/cn.d.ts +6 -0
  68. package/dist/lib/cn.js +75 -0
  69. package/dist/lib/motion.d.ts +19 -0
  70. package/dist/lib/motion.js +43 -0
  71. package/dist/types/index.d.ts +120 -0
  72. package/dist/utils/format.d.ts +38 -0
  73. package/dist/utils/format.js +103 -0
  74. package/dist/utils/rank-utils.d.ts +34 -0
  75. package/dist/utils/rank-utils.js +80 -0
  76. package/dist/utils/tick-validation.d.ts +22 -0
  77. package/dist/utils/tick-validation.js +40 -0
  78. package/package.json +92 -0
  79. package/src/components/blocks/auction/Auction.tsx +74 -0
  80. package/src/components/blocks/auction/AuctionArtwork.tsx +4 -0
  81. package/src/components/blocks/auction/AuctionBidForm.tsx +138 -0
  82. package/src/components/blocks/auction/AuctionBidInput.tsx +166 -0
  83. package/src/components/blocks/auction/AuctionContext.tsx +401 -0
  84. package/src/components/blocks/auction/AuctionInfo.tsx +36 -0
  85. package/src/components/blocks/auction/AuctionLayout.tsx +200 -0
  86. package/src/components/blocks/auction/AuctionRankings.tsx +435 -0
  87. package/src/components/blocks/auction/AuctionStatusTag.tsx +98 -0
  88. package/src/components/blocks/auction/AuctionSuggestedBids.tsx +203 -0
  89. package/src/components/blocks/auction/AuctionYourBidCard.tsx +125 -0
  90. package/src/components/blocks/auction/AuctionYourBids.tsx +61 -0
  91. package/src/components/blocks/auction/index.ts +42 -0
  92. package/src/components/blocks/index.ts +1 -0
  93. package/src/components/index.ts +2 -0
  94. package/src/components/primitives/Button.tsx +183 -0
  95. package/src/components/primitives/Drawer.tsx +125 -0
  96. package/src/components/primitives/Feedback.tsx +185 -0
  97. package/src/components/primitives/MorphDialog.tsx +160 -0
  98. package/src/components/primitives/Price.tsx +394 -0
  99. package/src/components/primitives/PriceInput.tsx +48 -0
  100. package/src/components/primitives/Receipt.tsx +711 -0
  101. package/src/components/primitives/Scale.tsx +287 -0
  102. package/src/components/primitives/Separator.tsx +87 -0
  103. package/src/components/primitives/Skeleton.tsx +33 -0
  104. package/src/components/primitives/SteppedInput.tsx +313 -0
  105. package/src/components/primitives/Tabs.tsx +161 -0
  106. package/src/components/primitives/Tag.tsx +48 -0
  107. package/src/components/primitives/Text.tsx +102 -0
  108. package/src/components/primitives/countdown/Countdown.tsx +43 -0
  109. package/src/components/primitives/countdown/index.ts +2 -0
  110. package/src/components/primitives/framed-image/FramedImage.tsx +51 -0
  111. package/src/components/primitives/framed-image/index.ts +1 -0
  112. package/src/components/primitives/index.ts +42 -0
  113. package/src/components/primitives/ranked-list/RankedList.tsx +9 -0
  114. package/src/components/primitives/ranked-list/Ranking.tsx +454 -0
  115. package/src/components/primitives/ranked-list/index.ts +8 -0
  116. package/src/hooks/index.ts +1 -0
  117. package/src/hooks/useCountdown.ts +91 -0
  118. package/src/index.ts +130 -0
  119. package/src/lib/cn.ts +81 -0
  120. package/src/lib/index.ts +2 -0
  121. package/src/lib/motion.ts +55 -0
  122. package/src/public/lea-83-time-walk.png +0 -0
  123. package/src/public/lea-83-time-walk.webp +0 -0
  124. package/src/stories/Auction.stories.tsx +658 -0
  125. package/src/stories/AuctionLayout.stories.tsx +313 -0
  126. package/src/stories/AuctionStatusTag.stories.tsx +166 -0
  127. package/src/stories/AuctionYourBidCard.stories.tsx +257 -0
  128. package/src/stories/Button.stories.tsx +306 -0
  129. package/src/stories/Countdown.stories.tsx +158 -0
  130. package/src/stories/Feedback.stories.tsx +80 -0
  131. package/src/stories/FramedImage.stories.tsx +46 -0
  132. package/src/stories/MorphDialog.stories.tsx +88 -0
  133. package/src/stories/Price.stories.tsx +292 -0
  134. package/src/stories/RankedList.stories.tsx +190 -0
  135. package/src/stories/Receipt.stories.tsx +221 -0
  136. package/src/stories/Scale.stories.tsx +578 -0
  137. package/src/stories/Separator.stories.tsx +188 -0
  138. package/src/stories/Skeleton.stories.tsx +138 -0
  139. package/src/stories/SteppedInput.stories.tsx +321 -0
  140. package/src/stories/Tabs.stories.tsx +215 -0
  141. package/src/stories/Tag.stories.tsx +138 -0
  142. package/src/stories/Text.stories.tsx +245 -0
  143. package/src/styles/globals.css +39 -0
  144. package/src/styles/index.css +4 -0
  145. package/src/styles/theme/animation.css +11 -0
  146. package/src/styles/theme/color.css +185 -0
  147. package/src/styles/theme/index.css +3 -0
  148. package/src/styles/theme/typography.css +3 -0
  149. package/src/styles/utility.css +8 -0
  150. package/src/types/index.ts +149 -0
  151. package/src/utils/format.ts +130 -0
  152. package/src/utils/index.ts +16 -0
  153. package/src/utils/rank-utils.ts +131 -0
  154. package/src/utils/tick-validation.ts +65 -0
@@ -0,0 +1,125 @@
1
+ "use client";
2
+
3
+ import { Drawer as DrawerPrimitive } from "@base-ui/react/drawer";
4
+ import type * as React from "react";
5
+ import { cn } from "@/lib/cn";
6
+
7
+ type OpenChangeDetails = Parameters<
8
+ NonNullable<React.ComponentProps<typeof DrawerPrimitive.Root>["onOpenChange"]>
9
+ >[1];
10
+
11
+ export interface DrawerProps {
12
+ trigger: React.ReactElement;
13
+ children: React.ReactNode;
14
+ open?: boolean;
15
+ defaultOpen?: boolean;
16
+ onOpenChange?: (open: boolean, eventDetails: OpenChangeDetails) => void;
17
+ className?: string;
18
+ triggerClassName?: string;
19
+ panelClassName?: string;
20
+ backdropClassName?: string;
21
+ title?: React.ReactNode;
22
+ description?: React.ReactNode;
23
+ side?: "left" | "right";
24
+ modal?: React.ComponentProps<typeof DrawerPrimitive.Root>["modal"];
25
+ initialFocus?: React.ComponentProps<
26
+ typeof DrawerPrimitive.Popup
27
+ >["initialFocus"];
28
+ finalFocus?: React.ComponentProps<typeof DrawerPrimitive.Popup>["finalFocus"];
29
+ popupAriaLabel?: string;
30
+ }
31
+
32
+ export function Drawer({
33
+ trigger,
34
+ children,
35
+ open,
36
+ defaultOpen = false,
37
+ onOpenChange,
38
+ className,
39
+ triggerClassName,
40
+ panelClassName,
41
+ backdropClassName,
42
+ title,
43
+ description,
44
+ side = "right",
45
+ modal = true,
46
+ initialFocus,
47
+ finalFocus,
48
+ popupAriaLabel,
49
+ }: DrawerProps): React.ReactElement {
50
+ const sideClassName =
51
+ side === "left" ? "inset-y-0 left-0 h-full" : "inset-y-0 right-0 h-full";
52
+ const swipeDirection = side === "left" ? "left" : "right";
53
+
54
+ return (
55
+ <DrawerPrimitive.Root
56
+ open={open}
57
+ defaultOpen={defaultOpen}
58
+ onOpenChange={onOpenChange}
59
+ modal={modal}
60
+ swipeDirection={swipeDirection}
61
+ >
62
+ <div className={className}>
63
+ <DrawerPrimitive.Trigger
64
+ className={cn("outline-none", triggerClassName)}
65
+ render={trigger}
66
+ />
67
+ </div>
68
+
69
+ <DrawerPrimitive.Portal>
70
+ <DrawerPrimitive.Backdrop
71
+ className={(state) =>
72
+ cn(
73
+ "fixed inset-0 z-60 bg-background/70 backdrop-blur-sm transition-opacity duration-150 ease-out",
74
+ (state.transitionStatus === "starting" ||
75
+ state.transitionStatus === "ending") &&
76
+ "opacity-0",
77
+ backdropClassName,
78
+ )
79
+ }
80
+ />
81
+
82
+ <DrawerPrimitive.Viewport className="fixed inset-0 z-70 overflow-hidden">
83
+ <DrawerPrimitive.Popup
84
+ aria-label={popupAriaLabel}
85
+ initialFocus={initialFocus}
86
+ finalFocus={finalFocus}
87
+ className={cn(
88
+ "fixed z-70 flex h-full w-auto outline-none transition-transform duration-200 ease-out",
89
+ sideClassName,
90
+ )}
91
+ style={(state) => ({
92
+ transform:
93
+ state.transitionStatus === "starting" ||
94
+ state.transitionStatus === "ending"
95
+ ? side === "left"
96
+ ? "translateX(-100%)"
97
+ : "translateX(100%)"
98
+ : "translateX(var(--drawer-swipe-movement-x, 0px))",
99
+ })}
100
+ >
101
+ <DrawerPrimitive.Content
102
+ className={cn(
103
+ "flex h-full w-[max(50vw,24rem)] max-w-none flex-col border-border bg-background shadow-2xl sm:w-[max(50vw,28rem)]",
104
+ side === "left" ? "border-r" : "border-l",
105
+ panelClassName,
106
+ )}
107
+ >
108
+ {title ? (
109
+ <DrawerPrimitive.Title className="sr-only">
110
+ {title}
111
+ </DrawerPrimitive.Title>
112
+ ) : null}
113
+ {description ? (
114
+ <DrawerPrimitive.Description className="sr-only">
115
+ {description}
116
+ </DrawerPrimitive.Description>
117
+ ) : null}
118
+ {children}
119
+ </DrawerPrimitive.Content>
120
+ </DrawerPrimitive.Popup>
121
+ </DrawerPrimitive.Viewport>
122
+ </DrawerPrimitive.Portal>
123
+ </DrawerPrimitive.Root>
124
+ );
125
+ }
@@ -0,0 +1,185 @@
1
+ import { AnimatePresence, motion } from "motion/react";
2
+ import * as React from "react";
3
+ import { createContext, useContext } from "react";
4
+ import { cn } from "@/lib/cn";
5
+
6
+ type FeedbackPosition = "bottom" | "top" | "left" | "right";
7
+
8
+ interface FeedbackContextValue {
9
+ show: boolean;
10
+ position: FeedbackPosition;
11
+ transition: {
12
+ stiffness: number;
13
+ damping: number;
14
+ };
15
+ }
16
+
17
+ const FeedbackContext = createContext<FeedbackContextValue | null>(null);
18
+
19
+ function useFeedback() {
20
+ const context = useContext(FeedbackContext);
21
+ if (!context) {
22
+ throw new Error("Feedback.Content must be used within Feedback.Root");
23
+ }
24
+ return context;
25
+ }
26
+
27
+ const positionStyles: Record<FeedbackPosition, string> = {
28
+ bottom: "top-full right-0 left-0",
29
+ top: "bottom-full right-0 left-0",
30
+ left: "right-full top-0 bottom-0",
31
+ right: "left-full top-0 bottom-0",
32
+ };
33
+
34
+ const initialAnimations: Record<FeedbackPosition, { x?: string; y?: string }> =
35
+ {
36
+ bottom: { y: "-100%" },
37
+ top: { y: "100%" },
38
+ left: { x: "100%" },
39
+ right: { x: "-100%" },
40
+ };
41
+
42
+ interface FeedbackRootProps {
43
+ children: React.ReactNode;
44
+ show?: boolean;
45
+ position?: FeedbackPosition;
46
+ className?: string;
47
+ transition?: {
48
+ stiffness?: number;
49
+ damping?: number;
50
+ };
51
+ }
52
+
53
+ const FeedbackRoot: React.FC<FeedbackRootProps> = ({
54
+ children,
55
+ show = false,
56
+ position = "bottom",
57
+ className,
58
+ transition = { stiffness: 300, damping: 20 },
59
+ }): React.ReactElement => {
60
+ const contextValue = React.useMemo(
61
+ () => ({
62
+ show,
63
+ position,
64
+ transition: {
65
+ stiffness: transition.stiffness ?? 300,
66
+ damping: transition.damping ?? 20,
67
+ },
68
+ }),
69
+ [show, position, transition],
70
+ );
71
+
72
+ return (
73
+ <FeedbackContext.Provider value={contextValue}>
74
+ <span className={cn("relative inline-block", className)}>
75
+ {React.Children.map(children, (child) => {
76
+ if (React.isValidElement(child) && child.type === FeedbackContent) {
77
+ return child;
78
+ }
79
+ return <span className="relative z-10">{child}</span>;
80
+ })}
81
+ </span>
82
+ </FeedbackContext.Provider>
83
+ );
84
+ };
85
+
86
+ type ContentTransitionMode = "crossfade" | "slide-up" | "slide-down";
87
+
88
+ interface FeedbackContentProps {
89
+ children: React.ReactNode;
90
+ className?: string;
91
+ contentKey?: string | number;
92
+ mode?: ContentTransitionMode;
93
+ }
94
+
95
+ const contentAnimations = {
96
+ crossfade: {
97
+ initial: { opacity: 0 },
98
+ animate: { opacity: 1 },
99
+ exit: { opacity: 0 },
100
+ },
101
+ "slide-up": {
102
+ initial: { opacity: 0, y: 8 },
103
+ animate: { opacity: 1, y: 0 },
104
+ exit: { opacity: 0, y: -8 },
105
+ },
106
+ "slide-down": {
107
+ initial: { opacity: 0, y: -8 },
108
+ animate: { opacity: 1, y: 0 },
109
+ exit: { opacity: 0, y: 8 },
110
+ },
111
+ } as const;
112
+
113
+ function getContentKey(children: React.ReactNode): string {
114
+ if (typeof children === "string" || typeof children === "number") {
115
+ return String(children);
116
+ }
117
+ if (React.isValidElement(children)) {
118
+ return children.key ?? JSON.stringify(children.props);
119
+ }
120
+ return JSON.stringify(children);
121
+ }
122
+
123
+ const FeedbackContent: React.FC<FeedbackContentProps> = ({
124
+ children,
125
+ className,
126
+ contentKey,
127
+ mode = "slide-up",
128
+ }): React.ReactElement => {
129
+ const { show, position, transition } = useFeedback();
130
+
131
+ const key = contentKey ?? getContentKey(children);
132
+ const contentAnimation = contentAnimations[mode];
133
+
134
+ return (
135
+ <AnimatePresence mode="wait">
136
+ {show && (
137
+ <motion.div
138
+ key="feedback-container"
139
+ initial={{
140
+ ...initialAnimations[position],
141
+ opacity: 0,
142
+ rotateZ: 5,
143
+ }}
144
+ animate={{ x: "0%", y: "0%", opacity: 1, rotateZ: 0 }}
145
+ exit={{ ...initialAnimations[position], opacity: 0, rotateZ: 0 }}
146
+ className={cn(
147
+ "absolute z-0 flex items-center justify-center",
148
+ positionStyles[position],
149
+ className,
150
+ )}
151
+ transition={{
152
+ type: "spring",
153
+ stiffness: transition.stiffness,
154
+ damping: transition.damping,
155
+ }}
156
+ >
157
+ <AnimatePresence mode="wait">
158
+ <motion.span
159
+ key={key}
160
+ initial={contentAnimation.initial}
161
+ animate={contentAnimation.animate}
162
+ exit={contentAnimation.exit}
163
+ transition={{
164
+ duration: 0.2,
165
+ ease: "easeInOut",
166
+ }}
167
+ >
168
+ {children}
169
+ </motion.span>
170
+ </AnimatePresence>
171
+ </motion.div>
172
+ )}
173
+ </AnimatePresence>
174
+ );
175
+ };
176
+
177
+ interface FeedbackComponent {
178
+ Root: React.FC<FeedbackRootProps>;
179
+ Content: React.FC<FeedbackContentProps>;
180
+ }
181
+
182
+ export const Feedback: FeedbackComponent = {
183
+ Root: FeedbackRoot,
184
+ Content: FeedbackContent,
185
+ };
@@ -0,0 +1,160 @@
1
+ "use client";
2
+
3
+ import { Dialog } from "@base-ui/react/dialog";
4
+ import {
5
+ AnimatePresence,
6
+ LayoutGroup,
7
+ motion,
8
+ useReducedMotion,
9
+ } from "motion/react";
10
+ import type * as React from "react";
11
+ import { useCallback, useId, useMemo, useState } from "react";
12
+ import { cn, springs, transitions } from "@/lib";
13
+
14
+ type OpenChangeDetails = Parameters<
15
+ NonNullable<React.ComponentProps<typeof Dialog.Root>["onOpenChange"]>
16
+ >[1];
17
+
18
+ export interface MorphDialogProps {
19
+ trigger: React.ReactNode;
20
+ content: React.ReactNode;
21
+ contentClosesDialog?: boolean;
22
+ open?: boolean;
23
+ defaultOpen?: boolean;
24
+ onOpenChange?: (open: boolean, eventDetails: OpenChangeDetails) => void;
25
+ className?: string;
26
+ triggerClassName?: string;
27
+ popupClassName?: string;
28
+ backdropClassName?: string;
29
+ modal?: React.ComponentProps<typeof Dialog.Root>["modal"];
30
+ initialFocus?: React.ComponentProps<typeof Dialog.Popup>["initialFocus"];
31
+ finalFocus?: React.ComponentProps<typeof Dialog.Popup>["finalFocus"];
32
+ popupAriaLabel?: string;
33
+ }
34
+
35
+ export function MorphDialog({
36
+ trigger,
37
+ content,
38
+ contentClosesDialog = false,
39
+ open,
40
+ defaultOpen = false,
41
+ onOpenChange,
42
+ className,
43
+ triggerClassName,
44
+ popupClassName,
45
+ backdropClassName,
46
+ modal = true,
47
+ initialFocus,
48
+ finalFocus,
49
+ popupAriaLabel,
50
+ }: MorphDialogProps): React.ReactElement {
51
+ const generatedId = useId();
52
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
53
+ const prefersReducedMotion = useReducedMotion();
54
+
55
+ const isControlled = open !== undefined;
56
+ const isOpen = isControlled ? open : uncontrolledOpen;
57
+ const layoutId = useMemo(
58
+ () => `morph-dialog-${generatedId.replace(/:/g, "")}`,
59
+ [generatedId],
60
+ );
61
+
62
+ const handleOpenChange = useCallback(
63
+ (nextOpen: boolean, eventDetails: OpenChangeDetails) => {
64
+ if (!isControlled) {
65
+ setUncontrolledOpen(nextOpen);
66
+ }
67
+ onOpenChange?.(nextOpen, eventDetails);
68
+ },
69
+ [isControlled, onOpenChange],
70
+ );
71
+
72
+ const handleBackdropClick = useCallback(() => {
73
+ handleOpenChange(false, {} as OpenChangeDetails);
74
+ }, [handleOpenChange]);
75
+
76
+ const handleContentClick = useCallback(
77
+ (event: React.MouseEvent<HTMLDivElement>) => {
78
+ event.stopPropagation();
79
+ },
80
+ [],
81
+ );
82
+
83
+ return (
84
+ <LayoutGroup id={layoutId}>
85
+ <Dialog.Root open={isOpen} onOpenChange={handleOpenChange} modal={modal}>
86
+ <div className={className}>
87
+ <Dialog.Trigger
88
+ className={cn(
89
+ "block cursor-pointer appearance-none border-0 bg-transparent p-0 text-left outline-none disabled:cursor-default",
90
+ triggerClassName,
91
+ )}
92
+ >
93
+ <motion.div
94
+ layout={!prefersReducedMotion}
95
+ layoutId={prefersReducedMotion ? undefined : layoutId}
96
+ transition={springs.quick}
97
+ className="h-full w-full"
98
+ >
99
+ {trigger}
100
+ </motion.div>
101
+ </Dialog.Trigger>
102
+ </div>
103
+
104
+ <Dialog.Portal>
105
+ <Dialog.Backdrop
106
+ className={cn(
107
+ "fixed inset-0 z-60 cursor-pointer backdrop-blur-sm transition-opacity duration-150 ease-out",
108
+ isOpen ? "opacity-100" : "opacity-0",
109
+ backdropClassName,
110
+ )}
111
+ onClick={handleBackdropClick}
112
+ />
113
+
114
+ <Dialog.Popup
115
+ aria-label={popupAriaLabel}
116
+ initialFocus={initialFocus}
117
+ finalFocus={finalFocus}
118
+ className="fixed inset-0 z-70 flex items-center justify-center p-5 outline-none sm:p-8"
119
+ onClick={handleBackdropClick}
120
+ >
121
+ <AnimatePresence initial={false}>
122
+ {isOpen ? (
123
+ <motion.div
124
+ key="morph-dialog-content"
125
+ layout={!prefersReducedMotion}
126
+ layoutId={prefersReducedMotion ? undefined : layoutId}
127
+ initial={
128
+ prefersReducedMotion ? { opacity: 0, scale: 0.98 } : false
129
+ }
130
+ animate={{ opacity: 1, scale: 1 }}
131
+ exit={
132
+ prefersReducedMotion
133
+ ? { opacity: 0, scale: 0.98 }
134
+ : undefined
135
+ }
136
+ transition={
137
+ prefersReducedMotion ? transitions.fade : springs.quick
138
+ }
139
+ className={cn(
140
+ "pointer-events-auto max-h-[90vh] max-w-[90vw]",
141
+ popupClassName,
142
+ )}
143
+ onClick={handleContentClick}
144
+ >
145
+ {contentClosesDialog ? (
146
+ <Dialog.Close className="block cursor-pointer appearance-none border-0 bg-transparent p-0 text-left outline-none">
147
+ {content}
148
+ </Dialog.Close>
149
+ ) : (
150
+ content
151
+ )}
152
+ </motion.div>
153
+ ) : null}
154
+ </AnimatePresence>
155
+ </Dialog.Popup>
156
+ </Dialog.Portal>
157
+ </Dialog.Root>
158
+ </LayoutGroup>
159
+ );
160
+ }