@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.
- package/LICENSE +21 -0
- package/dist/components/blocks/auction/Auction.d.ts +49 -0
- package/dist/components/blocks/auction/Auction.js +44 -0
- package/dist/components/blocks/auction/AuctionBidForm.d.ts +11 -0
- package/dist/components/blocks/auction/AuctionBidForm.js +88 -0
- package/dist/components/blocks/auction/AuctionBidInput.d.ts +9 -0
- package/dist/components/blocks/auction/AuctionBidInput.js +99 -0
- package/dist/components/blocks/auction/AuctionContext.d.ts +71 -0
- package/dist/components/blocks/auction/AuctionContext.js +228 -0
- package/dist/components/blocks/auction/AuctionInfo.d.ts +9 -0
- package/dist/components/blocks/auction/AuctionInfo.js +37 -0
- package/dist/components/blocks/auction/AuctionLayout.d.ts +63 -0
- package/dist/components/blocks/auction/AuctionLayout.js +80 -0
- package/dist/components/blocks/auction/AuctionRankings.d.ts +16 -0
- package/dist/components/blocks/auction/AuctionRankings.js +334 -0
- package/dist/components/blocks/auction/AuctionStatusTag.d.ts +15 -0
- package/dist/components/blocks/auction/AuctionStatusTag.js +60 -0
- package/dist/components/blocks/auction/AuctionSuggestedBids.d.ts +38 -0
- package/dist/components/blocks/auction/AuctionSuggestedBids.js +116 -0
- package/dist/components/blocks/auction/AuctionYourBidCard.d.ts +27 -0
- package/dist/components/blocks/auction/AuctionYourBidCard.js +94 -0
- package/dist/components/blocks/auction/AuctionYourBids.d.ts +9 -0
- package/dist/components/blocks/auction/AuctionYourBids.js +49 -0
- package/dist/components/blocks/auction/index.d.ts +12 -0
- package/dist/components/blocks/index.d.ts +12 -0
- package/dist/components/index.d.ts +28 -0
- package/dist/components/primitives/Button.d.ts +31 -0
- package/dist/components/primitives/Button.js +117 -0
- package/dist/components/primitives/Drawer.d.ts +43 -0
- package/dist/components/primitives/Drawer.js +51 -0
- package/dist/components/primitives/Feedback.d.ts +28 -0
- package/dist/components/primitives/Feedback.js +147 -0
- package/dist/components/primitives/MorphDialog.d.ts +39 -0
- package/dist/components/primitives/MorphDialog.js +87 -0
- package/dist/components/primitives/Price.d.ts +84 -0
- package/dist/components/primitives/Price.js +255 -0
- package/dist/components/primitives/PriceInput.d.ts +33 -0
- package/dist/components/primitives/PriceInput.js +25 -0
- package/dist/components/primitives/Receipt.d.ts +164 -0
- package/dist/components/primitives/Receipt.js +344 -0
- package/dist/components/primitives/Scale.d.ts +67 -0
- package/dist/components/primitives/Scale.js +132 -0
- package/dist/components/primitives/Separator.d.ts +22 -0
- package/dist/components/primitives/Separator.js +62 -0
- package/dist/components/primitives/Skeleton.d.ts +14 -0
- package/dist/components/primitives/Skeleton.js +20 -0
- package/dist/components/primitives/SteppedInput.d.ts +94 -0
- package/dist/components/primitives/SteppedInput.js +154 -0
- package/dist/components/primitives/Tabs.d.ts +37 -0
- package/dist/components/primitives/Tabs.js +99 -0
- package/dist/components/primitives/Tag.d.ts +24 -0
- package/dist/components/primitives/Tag.js +22 -0
- package/dist/components/primitives/Text.d.ts +32 -0
- package/dist/components/primitives/Text.js +65 -0
- package/dist/components/primitives/countdown/Countdown.d.ts +24 -0
- package/dist/components/primitives/countdown/Countdown.js +22 -0
- package/dist/components/primitives/framed-image/FramedImage.d.ts +13 -0
- package/dist/components/primitives/framed-image/FramedImage.js +37 -0
- package/dist/components/primitives/index.d.ts +17 -0
- package/dist/components/primitives/ranked-list/Ranking.d.ts +117 -0
- package/dist/components/primitives/ranked-list/Ranking.js +219 -0
- package/dist/components/primitives/ranked-list/index.d.ts +1 -0
- package/dist/hooks/useCountdown.d.ts +20 -0
- package/dist/hooks/useCountdown.js +75 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +36 -0
- package/dist/lib/cn.d.ts +6 -0
- package/dist/lib/cn.js +75 -0
- package/dist/lib/motion.d.ts +19 -0
- package/dist/lib/motion.js +43 -0
- package/dist/types/index.d.ts +120 -0
- package/dist/utils/format.d.ts +38 -0
- package/dist/utils/format.js +103 -0
- package/dist/utils/rank-utils.d.ts +34 -0
- package/dist/utils/rank-utils.js +80 -0
- package/dist/utils/tick-validation.d.ts +22 -0
- package/dist/utils/tick-validation.js +40 -0
- package/package.json +92 -0
- package/src/components/blocks/auction/Auction.tsx +74 -0
- package/src/components/blocks/auction/AuctionArtwork.tsx +4 -0
- package/src/components/blocks/auction/AuctionBidForm.tsx +138 -0
- package/src/components/blocks/auction/AuctionBidInput.tsx +166 -0
- package/src/components/blocks/auction/AuctionContext.tsx +401 -0
- package/src/components/blocks/auction/AuctionInfo.tsx +36 -0
- package/src/components/blocks/auction/AuctionLayout.tsx +200 -0
- package/src/components/blocks/auction/AuctionRankings.tsx +435 -0
- package/src/components/blocks/auction/AuctionStatusTag.tsx +98 -0
- package/src/components/blocks/auction/AuctionSuggestedBids.tsx +203 -0
- package/src/components/blocks/auction/AuctionYourBidCard.tsx +125 -0
- package/src/components/blocks/auction/AuctionYourBids.tsx +61 -0
- package/src/components/blocks/auction/index.ts +42 -0
- package/src/components/blocks/index.ts +1 -0
- package/src/components/index.ts +2 -0
- package/src/components/primitives/Button.tsx +183 -0
- package/src/components/primitives/Drawer.tsx +125 -0
- package/src/components/primitives/Feedback.tsx +185 -0
- package/src/components/primitives/MorphDialog.tsx +160 -0
- package/src/components/primitives/Price.tsx +394 -0
- package/src/components/primitives/PriceInput.tsx +48 -0
- package/src/components/primitives/Receipt.tsx +711 -0
- package/src/components/primitives/Scale.tsx +287 -0
- package/src/components/primitives/Separator.tsx +87 -0
- package/src/components/primitives/Skeleton.tsx +33 -0
- package/src/components/primitives/SteppedInput.tsx +313 -0
- package/src/components/primitives/Tabs.tsx +161 -0
- package/src/components/primitives/Tag.tsx +48 -0
- package/src/components/primitives/Text.tsx +102 -0
- package/src/components/primitives/countdown/Countdown.tsx +43 -0
- package/src/components/primitives/countdown/index.ts +2 -0
- package/src/components/primitives/framed-image/FramedImage.tsx +51 -0
- package/src/components/primitives/framed-image/index.ts +1 -0
- package/src/components/primitives/index.ts +42 -0
- package/src/components/primitives/ranked-list/RankedList.tsx +9 -0
- package/src/components/primitives/ranked-list/Ranking.tsx +454 -0
- package/src/components/primitives/ranked-list/index.ts +8 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useCountdown.ts +91 -0
- package/src/index.ts +130 -0
- package/src/lib/cn.ts +81 -0
- package/src/lib/index.ts +2 -0
- package/src/lib/motion.ts +55 -0
- package/src/public/lea-83-time-walk.png +0 -0
- package/src/public/lea-83-time-walk.webp +0 -0
- package/src/stories/Auction.stories.tsx +658 -0
- package/src/stories/AuctionLayout.stories.tsx +313 -0
- package/src/stories/AuctionStatusTag.stories.tsx +166 -0
- package/src/stories/AuctionYourBidCard.stories.tsx +257 -0
- package/src/stories/Button.stories.tsx +306 -0
- package/src/stories/Countdown.stories.tsx +158 -0
- package/src/stories/Feedback.stories.tsx +80 -0
- package/src/stories/FramedImage.stories.tsx +46 -0
- package/src/stories/MorphDialog.stories.tsx +88 -0
- package/src/stories/Price.stories.tsx +292 -0
- package/src/stories/RankedList.stories.tsx +190 -0
- package/src/stories/Receipt.stories.tsx +221 -0
- package/src/stories/Scale.stories.tsx +578 -0
- package/src/stories/Separator.stories.tsx +188 -0
- package/src/stories/Skeleton.stories.tsx +138 -0
- package/src/stories/SteppedInput.stories.tsx +321 -0
- package/src/stories/Tabs.stories.tsx +215 -0
- package/src/stories/Tag.stories.tsx +138 -0
- package/src/stories/Text.stories.tsx +245 -0
- package/src/styles/globals.css +39 -0
- package/src/styles/index.css +4 -0
- package/src/styles/theme/animation.css +11 -0
- package/src/styles/theme/color.css +185 -0
- package/src/styles/theme/index.css +3 -0
- package/src/styles/theme/typography.css +3 -0
- package/src/styles/utility.css +8 -0
- package/src/types/index.ts +149 -0
- package/src/utils/format.ts +130 -0
- package/src/utils/index.ts +16 -0
- package/src/utils/rank-utils.ts +131 -0
- package/src/utils/tick-validation.ts +65 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Tabs as TabsPrimitive } from "@base-ui/react/tabs";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { cn } from "@/lib/cn";
|
|
7
|
+
|
|
8
|
+
export type TabsContextType = {
|
|
9
|
+
layout: "default" | "centered";
|
|
10
|
+
variant: "default" | "underline" | "segmented";
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const TabsLayoutContext = React.createContext<TabsContextType>({
|
|
14
|
+
layout: "default",
|
|
15
|
+
variant: "default",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
interface TabsProps extends React.ComponentProps<typeof TabsPrimitive.Root> {
|
|
19
|
+
layout?: TabsContextType["layout"];
|
|
20
|
+
variant?: TabsContextType["variant"];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function Tabs({
|
|
24
|
+
className,
|
|
25
|
+
layout = "default",
|
|
26
|
+
variant = "default",
|
|
27
|
+
...props
|
|
28
|
+
}: TabsProps): React.ReactElement {
|
|
29
|
+
return (
|
|
30
|
+
<TabsLayoutContext value={{ layout, variant }}>
|
|
31
|
+
<TabsPrimitive.Root
|
|
32
|
+
className={cn("flex flex-col", className)}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
</TabsLayoutContext>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const tabsListVariants = cva("relative flex", {
|
|
40
|
+
variants: {
|
|
41
|
+
layout: {
|
|
42
|
+
default: "items-center gap-5",
|
|
43
|
+
centered: "justify-between px-1",
|
|
44
|
+
},
|
|
45
|
+
variant: {
|
|
46
|
+
default: "border-b border-b-border pb-4",
|
|
47
|
+
underline: "border-b border-b-border pb-4",
|
|
48
|
+
segmented:
|
|
49
|
+
"inline-flex items-center gap-1 rounded-lg border border-border bg-muted/30 p-1",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
defaultVariants: {
|
|
53
|
+
layout: "default",
|
|
54
|
+
variant: "default",
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
function TabsList({
|
|
59
|
+
children,
|
|
60
|
+
className,
|
|
61
|
+
...props
|
|
62
|
+
}: React.ComponentProps<typeof TabsPrimitive.List>): React.ReactElement {
|
|
63
|
+
const context = React.useContext(TabsLayoutContext);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<TabsPrimitive.List
|
|
67
|
+
className={cn(
|
|
68
|
+
tabsListVariants({
|
|
69
|
+
layout: context.layout,
|
|
70
|
+
variant: context.variant,
|
|
71
|
+
}),
|
|
72
|
+
context.variant === "segmented" &&
|
|
73
|
+
context.layout === "centered" &&
|
|
74
|
+
"justify-start px-1",
|
|
75
|
+
className,
|
|
76
|
+
)}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
{children}
|
|
80
|
+
{context.variant === "underline" ? <TabsIndicator /> : null}
|
|
81
|
+
</TabsPrimitive.List>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function TabsIndicator({
|
|
86
|
+
className,
|
|
87
|
+
...props
|
|
88
|
+
}: React.ComponentProps<typeof TabsPrimitive.Indicator>): React.ReactElement {
|
|
89
|
+
const context = React.useContext(TabsLayoutContext);
|
|
90
|
+
return (
|
|
91
|
+
<TabsPrimitive.Indicator
|
|
92
|
+
className={cn(
|
|
93
|
+
"absolute bottom-0 left-0 z-1 h-[3px] w-(--active-tab-width) translate-x-(--active-tab-left) bg-foreground transition-transform duration-200 ease-in-out",
|
|
94
|
+
{
|
|
95
|
+
"w-[calc(var(--active-tab-width)+4px)]":
|
|
96
|
+
context.layout === "centered",
|
|
97
|
+
"translate-x-[calc(var(--active-tab-left)-4px)]":
|
|
98
|
+
context.layout === "centered",
|
|
99
|
+
},
|
|
100
|
+
className,
|
|
101
|
+
)}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const tabVariants = cva(
|
|
108
|
+
"relative rounded-xs font-sans text-sm leading-none whitespace-nowrap text-muted-foreground after:pointer-events-auto after:absolute after:z-0 after:rounded-xs after:bg-transparent after:content-[''] hover:text-foreground focus-visible:ring focus-visible:outline-none data-active:text-foreground",
|
|
109
|
+
{
|
|
110
|
+
variants: {
|
|
111
|
+
layout: {
|
|
112
|
+
default: "after:-inset-x-2.5 after:-inset-y-1.5",
|
|
113
|
+
centered: "w-full after:inset-x-0 after:-inset-y-1.5",
|
|
114
|
+
},
|
|
115
|
+
variant: {
|
|
116
|
+
default: "",
|
|
117
|
+
underline: "",
|
|
118
|
+
segmented:
|
|
119
|
+
"rounded-md border border-transparent px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors after:hidden hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background data-active:border-border data-active:bg-background data-active:text-foreground data-active:shadow-[0_1px_2px_0_rgb(0,0,0,0.04)] aria-selected:border-border aria-selected:bg-background aria-selected:text-foreground aria-selected:shadow-[0_1px_2px_0_rgb(0,0,0,0.04)]",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
defaultVariants: {
|
|
123
|
+
layout: "default",
|
|
124
|
+
variant: "default",
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
function Tab({
|
|
130
|
+
className,
|
|
131
|
+
...props
|
|
132
|
+
}: React.ComponentProps<typeof TabsPrimitive.Tab>): React.ReactElement {
|
|
133
|
+
const context = React.useContext(TabsLayoutContext);
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<TabsPrimitive.Tab
|
|
137
|
+
className={cn(
|
|
138
|
+
tabVariants({ layout: context.layout, variant: context.variant }),
|
|
139
|
+
context.variant === "segmented" &&
|
|
140
|
+
context.layout === "centered" &&
|
|
141
|
+
"w-auto",
|
|
142
|
+
className,
|
|
143
|
+
)}
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function TabsPanel({
|
|
150
|
+
className,
|
|
151
|
+
...props
|
|
152
|
+
}: React.ComponentProps<typeof TabsPrimitive.Panel>): React.ReactElement {
|
|
153
|
+
return (
|
|
154
|
+
<TabsPrimitive.Panel
|
|
155
|
+
className={cn("focus-visible:outline-none", className)}
|
|
156
|
+
{...props}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { Tabs, TabsList, TabsIndicator, Tab, TabsPanel };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
import { cn } from "@/lib/cn";
|
|
3
|
+
import { Text, type TextProps } from "./Text";
|
|
4
|
+
|
|
5
|
+
type TagVariantsProps = {
|
|
6
|
+
type?: "informative" | "interactive";
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const tagVariants = (props: TagVariantsProps) => {
|
|
10
|
+
const baseClasses =
|
|
11
|
+
"inline-flex rounded-xs border border-solid border-border bg-muted px-1 leading-none";
|
|
12
|
+
const typeClasses = {
|
|
13
|
+
informative: "",
|
|
14
|
+
interactive:
|
|
15
|
+
"underline hover:bg-accent-hover focus-visible:ring focus-visible:outline-none",
|
|
16
|
+
};
|
|
17
|
+
return `${baseClasses} ${typeClasses[props.type ?? "informative"]}`;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type BaseTagProps = Omit<TextProps, "render"> & TagVariantsProps;
|
|
21
|
+
|
|
22
|
+
type TagInformativeProps = BaseTagProps & {
|
|
23
|
+
type?: "informative";
|
|
24
|
+
} & Omit<React.ComponentProps<"span">, "color">;
|
|
25
|
+
|
|
26
|
+
type TagButtonProps = BaseTagProps & {
|
|
27
|
+
type: "interactive";
|
|
28
|
+
} & Omit<React.ComponentProps<"button">, "type">;
|
|
29
|
+
|
|
30
|
+
export type TagProps = TagInformativeProps | TagButtonProps;
|
|
31
|
+
export type TagElement = HTMLSpanElement | HTMLButtonElement;
|
|
32
|
+
|
|
33
|
+
export function Tag({
|
|
34
|
+
className,
|
|
35
|
+
type = "informative",
|
|
36
|
+
children,
|
|
37
|
+
...rest
|
|
38
|
+
}: TagProps): React.ReactElement {
|
|
39
|
+
return (
|
|
40
|
+
<Text
|
|
41
|
+
render={type === "interactive" ? <button type="button" /> : <span />}
|
|
42
|
+
className={cn(tagVariants({ type }), className)}
|
|
43
|
+
{...rest}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
</Text>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
2
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { cn } from "@/lib/cn";
|
|
6
|
+
|
|
7
|
+
const textVariants = cva("font-sans", {
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
"1": "text-xs leading-[18px]",
|
|
11
|
+
"2": "text-sm leading-[21px]",
|
|
12
|
+
"3": "text-base leading-6",
|
|
13
|
+
"4": "text-xl leading-7",
|
|
14
|
+
"5": "text-2xl leading-8",
|
|
15
|
+
"6": "text-[28px] leading-9",
|
|
16
|
+
"7": "text-[32px] leading-10",
|
|
17
|
+
"8": "text-[36px] leading-[44px]",
|
|
18
|
+
"9": "text-5xl leading-[56px]",
|
|
19
|
+
},
|
|
20
|
+
weight: {
|
|
21
|
+
regular: "font-normal",
|
|
22
|
+
medium: "font-medium",
|
|
23
|
+
semibold: "font-semibold",
|
|
24
|
+
},
|
|
25
|
+
align: {
|
|
26
|
+
left: "text-left",
|
|
27
|
+
center: "text-center",
|
|
28
|
+
right: "text-right",
|
|
29
|
+
},
|
|
30
|
+
color: {
|
|
31
|
+
primary: "text-foreground",
|
|
32
|
+
secondary: "text-muted-foreground",
|
|
33
|
+
tertiary: "text-muted-foreground",
|
|
34
|
+
disabled: "text-disabled-foreground",
|
|
35
|
+
current: "text-current",
|
|
36
|
+
success: "text-success",
|
|
37
|
+
error: "text-destructive",
|
|
38
|
+
},
|
|
39
|
+
tabularNums: {
|
|
40
|
+
true: "tabular-nums",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
defaultVariants: {
|
|
44
|
+
size: "2",
|
|
45
|
+
weight: "regular",
|
|
46
|
+
color: "primary",
|
|
47
|
+
},
|
|
48
|
+
}) as (props?: {
|
|
49
|
+
size?: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
|
|
50
|
+
weight?: "regular" | "medium" | "semibold";
|
|
51
|
+
align?: "left" | "center" | "right";
|
|
52
|
+
color?:
|
|
53
|
+
| "primary"
|
|
54
|
+
| "secondary"
|
|
55
|
+
| "tertiary"
|
|
56
|
+
| "disabled"
|
|
57
|
+
| "current"
|
|
58
|
+
| "success"
|
|
59
|
+
| "error";
|
|
60
|
+
tabularNums?: true;
|
|
61
|
+
className?: string;
|
|
62
|
+
}) => string;
|
|
63
|
+
|
|
64
|
+
type TextVariants = typeof textVariants;
|
|
65
|
+
|
|
66
|
+
export interface TextProps
|
|
67
|
+
extends VariantProps<TextVariants>,
|
|
68
|
+
Omit<useRender.ComponentProps<"span">, "color"> {}
|
|
69
|
+
|
|
70
|
+
export type TextElement = React.ComponentRef<"span">;
|
|
71
|
+
|
|
72
|
+
export function Text({
|
|
73
|
+
as,
|
|
74
|
+
className,
|
|
75
|
+
align,
|
|
76
|
+
size,
|
|
77
|
+
weight,
|
|
78
|
+
color,
|
|
79
|
+
tabularNums,
|
|
80
|
+
render,
|
|
81
|
+
ref,
|
|
82
|
+
...props
|
|
83
|
+
}: TextProps & { as?: React.ElementType }): React.ReactElement {
|
|
84
|
+
const defaultProps: useRender.ElementProps<"span"> = {
|
|
85
|
+
className: cn(
|
|
86
|
+
textVariants({ align, size, weight, color, tabularNums }),
|
|
87
|
+
className,
|
|
88
|
+
),
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const element = useRender({
|
|
92
|
+
defaultTagName: "span",
|
|
93
|
+
render: render ?? (as ? React.createElement(as) : undefined),
|
|
94
|
+
props: mergeProps<"span">(defaultProps, props),
|
|
95
|
+
ref: ref,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return element;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { textVariants };
|
|
102
|
+
export type { VariantProps };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Text } from "@/components/primitives";
|
|
4
|
+
import { type UseCountdownResult, useCountdown } from "@/hooks";
|
|
5
|
+
|
|
6
|
+
export interface CountdownProps {
|
|
7
|
+
/** Target date to count down to */
|
|
8
|
+
to: Date;
|
|
9
|
+
/** Show full format even when not expired (default: only show when expired) */
|
|
10
|
+
showWhenExpired?: boolean;
|
|
11
|
+
/** Stop counting up when countdown reaches zero (default: false - keeps counting up) */
|
|
12
|
+
stopOnExpired?: boolean;
|
|
13
|
+
/** Custom className */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Custom renderer - receives full countdown state */
|
|
16
|
+
children?: (result: UseCountdownResult) => React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function Countdown({
|
|
20
|
+
to,
|
|
21
|
+
showWhenExpired = false,
|
|
22
|
+
stopOnExpired = false,
|
|
23
|
+
className,
|
|
24
|
+
children,
|
|
25
|
+
}: CountdownProps): React.ReactElement | null {
|
|
26
|
+
const result = useCountdown(to, { stopOnExpired });
|
|
27
|
+
|
|
28
|
+
if (!showWhenExpired && result.remainingMs === null) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const display = result.timeString ?? "00d:00h:00m:00s";
|
|
33
|
+
|
|
34
|
+
if (children) {
|
|
35
|
+
return <>{children(result)}</>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Text className={className} tabularNums suppressHydrationWarning>
|
|
40
|
+
{display}
|
|
41
|
+
</Text>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { motion } from "motion/react";
|
|
4
|
+
import { cn } from "@/lib";
|
|
5
|
+
import { MorphDialog } from "../MorphDialog";
|
|
6
|
+
|
|
7
|
+
export interface FramedImageProps {
|
|
8
|
+
src: string;
|
|
9
|
+
alt?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function FramedImage({
|
|
14
|
+
src,
|
|
15
|
+
alt,
|
|
16
|
+
className,
|
|
17
|
+
}: FramedImageProps): React.ReactElement {
|
|
18
|
+
return (
|
|
19
|
+
<MorphDialog
|
|
20
|
+
className={cn(
|
|
21
|
+
"relative h-full min-h-0 w-full min-w-0 flex-1 rounded-md bg-accent",
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
triggerClassName="h-full w-full"
|
|
25
|
+
popupClassName="flex items-center justify-center"
|
|
26
|
+
popupAriaLabel={alt ?? "Expanded image preview"}
|
|
27
|
+
contentClosesDialog
|
|
28
|
+
trigger={
|
|
29
|
+
<div className="absolute inset-0 flex items-center justify-center p-5">
|
|
30
|
+
{/* biome-ignore lint/performance/noImgElement: shared UI stays framework-agnostic. */}
|
|
31
|
+
<motion.img
|
|
32
|
+
src={src}
|
|
33
|
+
alt={alt ?? ""}
|
|
34
|
+
className="h-full w-full cursor-pointer object-contain"
|
|
35
|
+
whileHover={{ scale: 1.02 }}
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
}
|
|
39
|
+
content={
|
|
40
|
+
<div className="flex items-center justify-center">
|
|
41
|
+
{/* biome-ignore lint/performance/noImgElement: shared UI stays framework-agnostic. */}
|
|
42
|
+
<img
|
|
43
|
+
src={src}
|
|
44
|
+
alt={alt ?? ""}
|
|
45
|
+
className="block max-h-[90vh] max-w-[90vw] rounded-lg object-contain"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FramedImage, type FramedImageProps } from "./FramedImage";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type { ButtonElement, ButtonProps } from "./Button";
|
|
2
|
+
export { Button, buttonVariants } from "./Button";
|
|
3
|
+
export * from "./countdown";
|
|
4
|
+
export { Drawer, type DrawerProps } from "./Drawer";
|
|
5
|
+
export { Feedback } from "./Feedback";
|
|
6
|
+
export * from "./framed-image";
|
|
7
|
+
export { MorphDialog, type MorphDialogProps } from "./MorphDialog";
|
|
8
|
+
export type {
|
|
9
|
+
FormatPriceOptions,
|
|
10
|
+
PriceProps,
|
|
11
|
+
PriceSymbolProps,
|
|
12
|
+
PriceValueProps,
|
|
13
|
+
} from "./Price";
|
|
14
|
+
export { formatPrice, Price } from "./Price";
|
|
15
|
+
export { PriceInput } from "./PriceInput";
|
|
16
|
+
export type {
|
|
17
|
+
ReceiptDiscountProps,
|
|
18
|
+
ReceiptFeeProps,
|
|
19
|
+
ReceiptFooterProps,
|
|
20
|
+
ReceiptHeaderProps,
|
|
21
|
+
ReceiptItemProps,
|
|
22
|
+
ReceiptPriceProps,
|
|
23
|
+
ReceiptProps,
|
|
24
|
+
ReceiptSeparatorProps,
|
|
25
|
+
ReceiptSubtotalProps,
|
|
26
|
+
ReceiptTaxProps,
|
|
27
|
+
ReceiptTotalProps,
|
|
28
|
+
} from "./Receipt";
|
|
29
|
+
export { Receipt } from "./Receipt";
|
|
30
|
+
export * from "./ranked-list";
|
|
31
|
+
export type { ScaleTickContext, ScaleValue, SnapMode } from "./Scale";
|
|
32
|
+
export { Scale, useScale } from "./Scale";
|
|
33
|
+
export { Separator } from "./Separator";
|
|
34
|
+
export type { SkeletonElement, SkeletonProps } from "./Skeleton";
|
|
35
|
+
export { Skeleton } from "./Skeleton";
|
|
36
|
+
export { CursorGrowIcon, SteppedInput } from "./SteppedInput";
|
|
37
|
+
export type { TabsContextType } from "./Tabs";
|
|
38
|
+
export { Tab, Tabs, TabsIndicator, TabsList, TabsPanel } from "./Tabs";
|
|
39
|
+
export type { TagElement, TagProps } from "./Tag";
|
|
40
|
+
export { Tag } from "./Tag";
|
|
41
|
+
export type { TextElement, TextProps } from "./Text";
|
|
42
|
+
export { Text, textVariants } from "./Text";
|