@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,188 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Separator } from "@/components/primitives/Separator";
3
+
4
+ const meta: Meta<typeof Separator> = {
5
+ title: "Primitives/Separator",
6
+ component: Separator,
7
+ parameters: {
8
+ layout: "centered",
9
+ },
10
+ argTypes: {
11
+ color: {
12
+ control: "select",
13
+ options: ["default", "subtle"],
14
+ },
15
+ orientation: {
16
+ control: "select",
17
+ options: ["horizontal", "vertical"],
18
+ },
19
+ label: {
20
+ control: "text",
21
+ },
22
+ },
23
+ };
24
+
25
+ export default meta;
26
+
27
+ export const Horizontal: StoryObj<typeof Separator> = {
28
+ render: () => (
29
+ <div className="w-64">
30
+ <p className="text-foreground">Content above</p>
31
+ <Separator className="my-4" />
32
+ <p className="text-foreground">Content below</p>
33
+ </div>
34
+ ),
35
+ };
36
+
37
+ export const Vertical: StoryObj<typeof Separator> = {
38
+ render: () => (
39
+ <div className="flex h-8 items-center gap-4">
40
+ <span className="text-foreground">Left</span>
41
+ <Separator orientation="vertical" className="h-full" />
42
+ <span className="text-foreground">Right</span>
43
+ </div>
44
+ ),
45
+ };
46
+
47
+ export const DefaultColor: StoryObj<typeof Separator> = {
48
+ render: () => (
49
+ <div className="w-64">
50
+ <p className="mb-2 text-sm text-muted-foreground">Default color</p>
51
+ <Separator color="default" />
52
+ </div>
53
+ ),
54
+ };
55
+
56
+ export const SubtleColor: StoryObj<typeof Separator> = {
57
+ render: () => (
58
+ <div className="w-64">
59
+ <p className="mb-2 text-sm text-muted-foreground">Subtle color</p>
60
+ <Separator color="subtle" />
61
+ </div>
62
+ ),
63
+ };
64
+
65
+ export const AllVariants: StoryObj<typeof Separator> = {
66
+ render: () => (
67
+ <div className="flex flex-col gap-8">
68
+ <div>
69
+ <p className="mb-2 text-sm text-muted-foreground">
70
+ Horizontal - Default
71
+ </p>
72
+ <div className="w-64">
73
+ <Separator color="default" orientation="horizontal" />
74
+ </div>
75
+ </div>
76
+ <div>
77
+ <p className="mb-2 text-sm text-muted-foreground">
78
+ Horizontal - Subtle
79
+ </p>
80
+ <div className="w-64">
81
+ <Separator color="subtle" orientation="horizontal" />
82
+ </div>
83
+ </div>
84
+ <div>
85
+ <p className="mb-2 text-sm text-muted-foreground">Vertical - Default</p>
86
+ <div className="flex h-16 items-center gap-4">
87
+ <span className="text-foreground">A</span>
88
+ <Separator
89
+ color="default"
90
+ orientation="vertical"
91
+ className="h-full"
92
+ />
93
+ <span className="text-foreground">B</span>
94
+ <Separator
95
+ color="default"
96
+ orientation="vertical"
97
+ className="h-full"
98
+ />
99
+ <span className="text-foreground">C</span>
100
+ </div>
101
+ </div>
102
+ <div>
103
+ <p className="mb-2 text-sm text-muted-foreground">Vertical - Subtle</p>
104
+ <div className="flex h-16 items-center gap-4">
105
+ <span className="text-foreground">A</span>
106
+ <Separator color="subtle" orientation="vertical" className="h-full" />
107
+ <span className="text-foreground">B</span>
108
+ <Separator color="subtle" orientation="vertical" className="h-full" />
109
+ <span className="text-foreground">C</span>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ ),
114
+ };
115
+
116
+ export const InCard: StoryObj<typeof Separator> = {
117
+ render: () => (
118
+ <div className="w-80 rounded-lg border border-border bg-background p-4">
119
+ <h3 className="font-medium text-foreground">Card Title</h3>
120
+ <p className="mt-1 text-sm text-muted-foreground">
121
+ Some description text
122
+ </p>
123
+ <Separator className="my-4" />
124
+ <div className="flex justify-between text-sm">
125
+ <span className="text-muted-foreground">Price</span>
126
+ <span className="text-foreground">0.5 ETH</span>
127
+ </div>
128
+ <Separator className="my-4" />
129
+ <div className="flex justify-between text-sm">
130
+ <span className="text-muted-foreground">Status</span>
131
+ <span className="text-success">Active</span>
132
+ </div>
133
+ </div>
134
+ ),
135
+ };
136
+
137
+ export const WithLabel: StoryObj<typeof Separator> = {
138
+ render: () => (
139
+ <div className="w-80">
140
+ <p className="text-foreground">Content above</p>
141
+ <Separator label="Section" className="my-2" />
142
+ <p className="text-foreground">Content below</p>
143
+ </div>
144
+ ),
145
+ };
146
+
147
+ export const WithLabelSubtle: StoryObj<typeof Separator> = {
148
+ render: () => (
149
+ <div className="w-80">
150
+ <p className="text-foreground">Content above</p>
151
+ <Separator label="Group A" color="subtle" className="my-2" />
152
+ <p className="text-foreground">Content below</p>
153
+ </div>
154
+ ),
155
+ };
156
+
157
+ export const VerticalWithLabel: StoryObj<typeof Separator> = {
158
+ render: () => (
159
+ <div className="flex h-32 items-center">
160
+ <span className="text-foreground">Left</span>
161
+ <Separator orientation="vertical" label="A" className="mx-2 h-full" />
162
+ <span className="text-foreground">Right</span>
163
+ </div>
164
+ ),
165
+ };
166
+
167
+ export const LabelsInCard: StoryObj<typeof Separator> = {
168
+ render: () => (
169
+ <div className="w-80 rounded-lg border border-border bg-background p-4">
170
+ <h3 className="font-medium text-foreground">Transaction Details</h3>
171
+ <Separator label="From" className="my-2" />
172
+ <div className="flex justify-between text-sm">
173
+ <span className="text-muted-foreground">Address</span>
174
+ <span className="text-foreground">0x1234...5678</span>
175
+ </div>
176
+ <Separator label="To" className="my-2" />
177
+ <div className="flex justify-between text-sm">
178
+ <span className="text-muted-foreground">Address</span>
179
+ <span className="text-foreground">0xabcd...efgh</span>
180
+ </div>
181
+ <Separator label="Amount" color="subtle" className="my-2" />
182
+ <div className="flex justify-between text-sm">
183
+ <span className="text-muted-foreground">Value</span>
184
+ <span className="text-foreground">1.5 ETH</span>
185
+ </div>
186
+ </div>
187
+ ),
188
+ };
@@ -0,0 +1,138 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Skeleton } from "@/components/primitives/Skeleton";
3
+ import { Text } from "@/components/primitives/Text";
4
+
5
+ const meta: Meta<typeof Skeleton> = {
6
+ title: "Primitives/Skeleton",
7
+ component: Skeleton,
8
+ parameters: {
9
+ layout: "centered",
10
+ },
11
+ };
12
+
13
+ export default meta;
14
+
15
+ export const Basic: StoryObj<typeof Skeleton> = {
16
+ render: () => <Skeleton className="h-4 w-32" />,
17
+ };
18
+
19
+ export const TextLine: StoryObj<typeof Skeleton> = {
20
+ render: () => (
21
+ <div className="w-64 space-y-2">
22
+ <Skeleton className="h-4 w-full" />
23
+ <Skeleton className="h-4 w-3/4" />
24
+ <Skeleton className="h-4 w-1/2" />
25
+ </div>
26
+ ),
27
+ };
28
+
29
+ export const Avatar: StoryObj<typeof Skeleton> = {
30
+ render: () => <Skeleton className="size-12 rounded-full" />,
31
+ };
32
+
33
+ export const Card: StoryObj<typeof Skeleton> = {
34
+ render: () => (
35
+ <div className="w-80 rounded-lg border border-border bg-background p-4">
36
+ <div className="flex items-center gap-3">
37
+ <Skeleton className="size-10 rounded-full" />
38
+ <div className="flex-1 space-y-2">
39
+ <Skeleton className="h-4 w-24" />
40
+ <Skeleton className="h-3 w-16" />
41
+ </div>
42
+ </div>
43
+ <div className="mt-4 space-y-2">
44
+ <Skeleton className="h-4 w-full" />
45
+ <Skeleton className="h-4 w-full" />
46
+ <Skeleton className="h-4 w-2/3" />
47
+ </div>
48
+ </div>
49
+ ),
50
+ };
51
+
52
+ export const BidCard: StoryObj<typeof Skeleton> = {
53
+ render: () => (
54
+ <div className="w-80 rounded-lg border border-border bg-muted p-4">
55
+ <div className="flex items-start justify-between gap-2">
56
+ <Skeleton className="h-4 w-16" />
57
+ <Skeleton className="h-4 w-24" />
58
+ </div>
59
+ <div className="mt-3 flex justify-between">
60
+ <Skeleton className="h-5 w-20" />
61
+ <div className="flex items-center gap-2">
62
+ <Skeleton className="size-4 rounded-full" />
63
+ <Skeleton className="h-4 w-16" />
64
+ </div>
65
+ </div>
66
+ <Skeleton className="mt-4 h-9 w-full rounded-md" />
67
+ </div>
68
+ ),
69
+ };
70
+
71
+ export const TableRow: StoryObj<typeof Skeleton> = {
72
+ render: () => (
73
+ <div className="w-96">
74
+ {[1, 2, 3].map((i) => (
75
+ <div
76
+ key={i}
77
+ className="flex items-center justify-between border-b border-border px-4 py-3"
78
+ >
79
+ <div className="flex items-center gap-3">
80
+ <Skeleton className="h-4 w-6" />
81
+ <Skeleton className="size-6 rounded-full" />
82
+ <Skeleton className="h-4 w-24" />
83
+ </div>
84
+ <div className="flex items-center gap-4">
85
+ <Skeleton className="h-4 w-16" />
86
+ <Skeleton className="h-3 w-10" />
87
+ </div>
88
+ </div>
89
+ ))}
90
+ </div>
91
+ ),
92
+ };
93
+
94
+ export const WithText: StoryObj<typeof Skeleton> = {
95
+ render: () => (
96
+ <div className="space-y-4">
97
+ <div>
98
+ <p className="mb-2 text-sm text-muted-foreground">
99
+ Skeleton wrapping text content
100
+ </p>
101
+ <Text render={<p />} size="3">
102
+ <Skeleton>This text is hidden but defines width</Skeleton>
103
+ </Text>
104
+ </div>
105
+ <div>
106
+ <p className="mb-2 text-sm text-muted-foreground">
107
+ Skeleton with placeholder text
108
+ </p>
109
+ <Text render={<p />} size="2">
110
+ <Skeleton>0.00420 ETH</Skeleton>
111
+ </Text>
112
+ </div>
113
+ </div>
114
+ ),
115
+ };
116
+
117
+ export const Sizes: StoryObj<typeof Skeleton> = {
118
+ render: () => (
119
+ <div className="flex flex-col gap-4">
120
+ <div>
121
+ <p className="mb-2 text-xs text-muted-foreground">Small (h-3)</p>
122
+ <Skeleton className="h-3 w-24" />
123
+ </div>
124
+ <div>
125
+ <p className="mb-2 text-xs text-muted-foreground">Default (h-4)</p>
126
+ <Skeleton className="h-4 w-32" />
127
+ </div>
128
+ <div>
129
+ <p className="mb-2 text-xs text-muted-foreground">Medium (h-6)</p>
130
+ <Skeleton className="h-6 w-40" />
131
+ </div>
132
+ <div>
133
+ <p className="mb-2 text-xs text-muted-foreground">Large (h-10)</p>
134
+ <Skeleton className="h-10 w-48" />
135
+ </div>
136
+ </div>
137
+ ),
138
+ };
@@ -0,0 +1,321 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import React from "react";
3
+ import {
4
+ CursorGrowIcon,
5
+ SteppedInput,
6
+ } from "@/components/primitives/SteppedInput";
7
+
8
+ const meta: Meta<typeof SteppedInput.Root> = {
9
+ title: "Primitives/SteppedInput",
10
+ component: SteppedInput.Root,
11
+ parameters: {
12
+ layout: "centered",
13
+ },
14
+ decorators: [
15
+ (Story) => (
16
+ <div className="flex flex-col items-center gap-4 rounded-lg p-8">
17
+ <Story />
18
+ </div>
19
+ ),
20
+ ],
21
+ };
22
+
23
+ export default meta;
24
+
25
+ export const Basic: StoryObj<typeof SteppedInput.Root> = {
26
+ render: () => {
27
+ const [value, setValue] = React.useState(BigInt(100));
28
+ const getTickSize = () => BigInt(10);
29
+
30
+ return (
31
+ <SteppedInput.Root
32
+ value={value}
33
+ onChange={setValue}
34
+ getTickSize={getTickSize}
35
+ >
36
+ <SteppedInput.Group>
37
+ <SteppedInput.Decrement />
38
+ <SteppedInput.ScrubArea>
39
+ <SteppedInput.ScrubAreaCursor>
40
+ <CursorGrowIcon />
41
+ </SteppedInput.ScrubAreaCursor>
42
+ <SteppedInput.Input />
43
+ </SteppedInput.ScrubArea>
44
+ <SteppedInput.Increment />
45
+ </SteppedInput.Group>
46
+ </SteppedInput.Root>
47
+ );
48
+ },
49
+ };
50
+
51
+ export const WithMinMax: StoryObj<typeof SteppedInput.Root> = {
52
+ render: () => {
53
+ const [value, setValue] = React.useState(BigInt(50));
54
+ const getTickSize = () => BigInt(5);
55
+
56
+ return (
57
+ <div className="flex flex-col gap-2">
58
+ <span className="text-text-tertiary text-xs">Min 0, Max 100</span>
59
+ <SteppedInput.Root
60
+ value={value}
61
+ onChange={setValue}
62
+ min={BigInt(0)}
63
+ max={BigInt(100)}
64
+ getTickSize={getTickSize}
65
+ >
66
+ <SteppedInput.Group>
67
+ <SteppedInput.Decrement />
68
+ <SteppedInput.ScrubArea>
69
+ <SteppedInput.ScrubAreaCursor>
70
+ <CursorGrowIcon />
71
+ </SteppedInput.ScrubAreaCursor>
72
+ <SteppedInput.Input />
73
+ </SteppedInput.ScrubArea>
74
+ <SteppedInput.Increment />
75
+ </SteppedInput.Group>
76
+ </SteppedInput.Root>
77
+ </div>
78
+ );
79
+ },
80
+ };
81
+
82
+ export const DynamicStepSize: StoryObj<typeof SteppedInput.Root> = {
83
+ render: () => {
84
+ const [value, setValue] = React.useState(BigInt(1000));
85
+ const getTickSize = (currentValue: bigint) => {
86
+ if (currentValue < BigInt(100)) return BigInt(1);
87
+ if (currentValue < BigInt(1000)) return BigInt(10);
88
+ return BigInt(100);
89
+ };
90
+
91
+ return (
92
+ <SteppedInput.Root
93
+ value={value}
94
+ onChange={setValue}
95
+ getTickSize={getTickSize}
96
+ >
97
+ <div className="flex flex-col gap-2">
98
+ <span className="text-text-tertiary text-xs">
99
+ Step size changes based on value (1, 10, or 100)
100
+ </span>
101
+ <SteppedInput.Group>
102
+ <SteppedInput.Decrement />
103
+ <SteppedInput.ScrubArea>
104
+ <SteppedInput.ScrubAreaCursor>
105
+ <CursorGrowIcon />
106
+ </SteppedInput.ScrubAreaCursor>
107
+ <SteppedInput.Input />
108
+ </SteppedInput.ScrubArea>
109
+ <SteppedInput.Increment />
110
+ </SteppedInput.Group>
111
+ </div>
112
+ </SteppedInput.Root>
113
+ );
114
+ },
115
+ };
116
+
117
+ export const Disabled: StoryObj<typeof SteppedInput.Root> = {
118
+ render: () => {
119
+ const [value, setValue] = React.useState(BigInt(500));
120
+ const getTickSize = () => BigInt(50);
121
+
122
+ return (
123
+ <SteppedInput.Root
124
+ value={value}
125
+ onChange={setValue}
126
+ getTickSize={getTickSize}
127
+ disabled
128
+ >
129
+ <SteppedInput.Group>
130
+ <SteppedInput.Decrement />
131
+ <SteppedInput.ScrubArea>
132
+ <SteppedInput.ScrubAreaCursor>
133
+ <CursorGrowIcon />
134
+ </SteppedInput.ScrubAreaCursor>
135
+ <SteppedInput.Input />
136
+ </SteppedInput.ScrubArea>
137
+ <SteppedInput.Increment />
138
+ </SteppedInput.Group>
139
+ </SteppedInput.Root>
140
+ );
141
+ },
142
+ };
143
+
144
+ const WEI_PER_ETH = BigInt(10 ** 18);
145
+
146
+ export const EthereumPrice: StoryObj<typeof SteppedInput.Root> = {
147
+ render: () => {
148
+ const [value, setValue] = React.useState(
149
+ (BigInt(245) * WEI_PER_ETH) / BigInt(10),
150
+ );
151
+ const getTickSize = () => WEI_PER_ETH / BigInt(100);
152
+
153
+ return (
154
+ <div className="flex flex-col gap-2">
155
+ <span className="text-text-tertiary text-xs">
156
+ Amount (in base units)
157
+ </span>
158
+ <SteppedInput.Root
159
+ value={value}
160
+ onChange={setValue}
161
+ min={WEI_PER_ETH / BigInt(10)}
162
+ max={WEI_PER_ETH * BigInt(100)}
163
+ getTickSize={getTickSize}
164
+ decimals={18}
165
+ >
166
+ <SteppedInput.Group>
167
+ <SteppedInput.Decrement />
168
+ <SteppedInput.ScrubArea>
169
+ <SteppedInput.ScrubAreaCursor>
170
+ <CursorGrowIcon />
171
+ </SteppedInput.ScrubAreaCursor>
172
+ <SteppedInput.Input />
173
+ </SteppedInput.ScrubArea>
174
+ <SteppedInput.Increment />
175
+ </SteppedInput.Group>
176
+ </SteppedInput.Root>
177
+ </div>
178
+ );
179
+ },
180
+ };
181
+
182
+ export const CustomValueDisplay: StoryObj<typeof SteppedInput.Root> = {
183
+ render: () => {
184
+ const [value, setValue] = React.useState(
185
+ (BigInt(150) * WEI_PER_ETH) / BigInt(10),
186
+ );
187
+ const getTickSize = () => WEI_PER_ETH / BigInt(100);
188
+
189
+ return (
190
+ <SteppedInput.Root
191
+ value={value}
192
+ onChange={setValue}
193
+ min={WEI_PER_ETH / BigInt(10)}
194
+ max={WEI_PER_ETH * BigInt(100)}
195
+ getTickSize={getTickSize}
196
+ decimals={18}
197
+ >
198
+ <SteppedInput.Group>
199
+ <SteppedInput.Decrement />
200
+
201
+ <SteppedInput.ScrubArea>
202
+ <SteppedInput.ScrubAreaCursor>
203
+ <CursorGrowIcon />
204
+ </SteppedInput.ScrubAreaCursor>
205
+ <SteppedInput.Value>
206
+ {({ inputValue }) => (
207
+ <span className="font-mono text-success">
208
+ {inputValue.toFixed(4)}
209
+ </span>
210
+ )}
211
+ </SteppedInput.Value>
212
+ </SteppedInput.ScrubArea>
213
+ <SteppedInput.Increment />
214
+ </SteppedInput.Group>
215
+ </SteppedInput.Root>
216
+ );
217
+ },
218
+ };
219
+
220
+ export const SnapToTick: StoryObj<typeof SteppedInput.Root> = {
221
+ render: () => {
222
+ // Demonstrate snapToTick with different rounding modes
223
+ // Using cents: tick size is $10 (1000 cents)
224
+ const [valueUp, setValueUp] = React.useState(BigInt(1050)); // $10.50 -> snaps to $20
225
+ const [valueDown, setValueDown] = React.useState(BigInt(1050)); // $10.50 -> snaps to $10
226
+ const [valueNearest, setValueNearest] = React.useState(BigInt(1050)); // $10.50 -> snaps to $10
227
+
228
+ const getTickSize = () => BigInt(1000); // $10 in cents
229
+ return (
230
+ <div className="flex flex-col gap-6">
231
+ <div className="text-sm text-muted-foreground">
232
+ Tick size: $10. Try dragging to see values snap to the grid.
233
+ </div>
234
+
235
+ <div className="flex flex-col gap-2">
236
+ <span className="text-sm font-medium">
237
+ snapToTick=&quot;up&quot; (always round up)
238
+ </span>
239
+ <span className="text-xs text-muted-foreground">
240
+ Current: ${(Number(valueUp) / 100).toFixed(2)}
241
+ </span>
242
+ <SteppedInput.Root
243
+ value={valueUp}
244
+ onChange={setValueUp}
245
+ min={BigInt(1000)}
246
+ getTickSize={getTickSize}
247
+ decimals={2}
248
+ snapToTick="up"
249
+ >
250
+ <SteppedInput.Group>
251
+ <SteppedInput.Decrement />
252
+ <SteppedInput.ScrubArea>
253
+ <SteppedInput.ScrubAreaCursor>
254
+ <CursorGrowIcon />
255
+ </SteppedInput.ScrubAreaCursor>
256
+ <SteppedInput.Input />
257
+ </SteppedInput.ScrubArea>
258
+ <SteppedInput.Increment />
259
+ </SteppedInput.Group>
260
+ </SteppedInput.Root>
261
+ </div>
262
+
263
+ <div className="flex flex-col gap-2">
264
+ <span className="text-sm font-medium">
265
+ snapToTick=&quot;down&quot; (always round down)
266
+ </span>
267
+ <span className="text-xs text-muted-foreground">
268
+ Current: ${(Number(valueDown) / 100).toFixed(2)}
269
+ </span>
270
+ <SteppedInput.Root
271
+ value={valueDown}
272
+ onChange={setValueDown}
273
+ min={BigInt(1000)}
274
+ getTickSize={getTickSize}
275
+ decimals={2}
276
+ snapToTick="down"
277
+ >
278
+ <SteppedInput.Group>
279
+ <SteppedInput.Decrement />
280
+ <SteppedInput.ScrubArea>
281
+ <SteppedInput.ScrubAreaCursor>
282
+ <CursorGrowIcon />
283
+ </SteppedInput.ScrubAreaCursor>
284
+ <SteppedInput.Input />
285
+ </SteppedInput.ScrubArea>
286
+ <SteppedInput.Increment />
287
+ </SteppedInput.Group>
288
+ </SteppedInput.Root>
289
+ </div>
290
+
291
+ <div className="flex flex-col gap-2">
292
+ <span className="text-sm font-medium">
293
+ snapToTick=&quot;nearest&quot; (round to nearest)
294
+ </span>
295
+ <span className="text-xs text-muted-foreground">
296
+ Current: ${(Number(valueNearest) / 100).toFixed(2)}
297
+ </span>
298
+ <SteppedInput.Root
299
+ value={valueNearest}
300
+ onChange={setValueNearest}
301
+ min={BigInt(1000)}
302
+ getTickSize={getTickSize}
303
+ decimals={2}
304
+ snapToTick="nearest"
305
+ >
306
+ <SteppedInput.Group>
307
+ <SteppedInput.Decrement />
308
+ <SteppedInput.ScrubArea>
309
+ <SteppedInput.ScrubAreaCursor>
310
+ <CursorGrowIcon />
311
+ </SteppedInput.ScrubAreaCursor>
312
+ <SteppedInput.Input />
313
+ </SteppedInput.ScrubArea>
314
+ <SteppedInput.Increment />
315
+ </SteppedInput.Group>
316
+ </SteppedInput.Root>
317
+ </div>
318
+ </div>
319
+ );
320
+ },
321
+ };