casino-ui 0.1.0
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/README.md +213 -0
- package/dist/assets/assets/card-back.svg +43 -0
- package/dist/assets/assets/card-shoe-overlay.svg +14 -0
- package/dist/assets/card-back.svg +43 -0
- package/dist/assets/card-shoe-overlay.svg +14 -0
- package/dist/casino-ui.css +2 -0
- package/dist/components/bet-panel.d.ts +41 -0
- package/dist/components/bet-panel.d.ts.map +1 -0
- package/dist/components/bet-panel.js +37 -0
- package/dist/components/bet-panel.js.map +1 -0
- package/dist/components/button.d.ts +15 -0
- package/dist/components/button.d.ts.map +1 -0
- package/dist/components/button.js +27 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/card-score-badge.d.ts +9 -0
- package/dist/components/card-score-badge.d.ts.map +1 -0
- package/dist/components/card-score-badge.js +20 -0
- package/dist/components/card-score-badge.js.map +1 -0
- package/dist/components/card-shoe.d.ts +6 -0
- package/dist/components/card-shoe.d.ts.map +1 -0
- package/dist/components/card-shoe.js +14 -0
- package/dist/components/card-shoe.js.map +1 -0
- package/dist/components/card-table.d.ts +7 -0
- package/dist/components/card-table.d.ts.map +1 -0
- package/dist/components/card-table.js +6 -0
- package/dist/components/card-table.js.map +1 -0
- package/dist/components/chip-rack.d.ts +6 -0
- package/dist/components/chip-rack.d.ts.map +1 -0
- package/dist/components/chip-rack.js +13 -0
- package/dist/components/chip-rack.js.map +1 -0
- package/dist/components/chip.d.ts +49 -0
- package/dist/components/chip.d.ts.map +1 -0
- package/dist/components/chip.js +81 -0
- package/dist/components/chip.js.map +1 -0
- package/dist/components/game-footer.d.ts +29 -0
- package/dist/components/game-footer.d.ts.map +1 -0
- package/dist/components/game-footer.js +72 -0
- package/dist/components/game-footer.js.map +1 -0
- package/dist/components/game-info-dialog.d.ts +23 -0
- package/dist/components/game-info-dialog.d.ts.map +1 -0
- package/dist/components/game-info-dialog.js +26 -0
- package/dist/components/game-info-dialog.js.map +1 -0
- package/dist/components/icon.d.ts +10 -0
- package/dist/components/icon.d.ts.map +1 -0
- package/dist/components/icon.js +59 -0
- package/dist/components/icon.js.map +1 -0
- package/dist/components/poker-card.d.ts +15 -0
- package/dist/components/poker-card.d.ts.map +1 -0
- package/dist/components/poker-card.js +77 -0
- package/dist/components/poker-card.js.map +1 -0
- package/dist/components/result-badge.d.ts +14 -0
- package/dist/components/result-badge.d.ts.map +1 -0
- package/dist/components/result-badge.js +71 -0
- package/dist/components/result-badge.js.map +1 -0
- package/dist/components/switch-table-dialog.d.ts +10 -0
- package/dist/components/switch-table-dialog.d.ts.map +1 -0
- package/dist/components/switch-table-dialog.js +51 -0
- package/dist/components/switch-table-dialog.js.map +1 -0
- package/dist/components/toast-container.d.ts +8 -0
- package/dist/components/toast-container.d.ts.map +1 -0
- package/dist/components/toast-container.js +8 -0
- package/dist/components/toast-container.js.map +1 -0
- package/dist/components/toast-helpers.d.ts +22 -0
- package/dist/components/toast-helpers.d.ts.map +1 -0
- package/dist/components/toast-helpers.js +47 -0
- package/dist/components/toast-helpers.js.map +1 -0
- package/dist/components/toast.d.ts +26 -0
- package/dist/components/toast.d.ts.map +1 -0
- package/dist/components/toast.js +49 -0
- package/dist/components/toast.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +14 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +35 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +14 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/drawer.js +35 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +39 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/stories/BetPanel.stories.d.ts +10 -0
- package/dist/stories/BetPanel.stories.d.ts.map +1 -0
- package/dist/stories/BetPanel.stories.js +34 -0
- package/dist/stories/BetPanel.stories.js.map +1 -0
- package/dist/stories/Button.stories.d.ts +13 -0
- package/dist/stories/Button.stories.d.ts.map +1 -0
- package/dist/stories/Button.stories.js +39 -0
- package/dist/stories/Button.stories.js.map +1 -0
- package/dist/stories/CardScoreBadge.stories.d.ts +8 -0
- package/dist/stories/CardScoreBadge.stories.d.ts.map +1 -0
- package/dist/stories/CardScoreBadge.stories.js +21 -0
- package/dist/stories/CardScoreBadge.stories.js.map +1 -0
- package/dist/stories/CardShoe.stories.d.ts +7 -0
- package/dist/stories/CardShoe.stories.d.ts.map +1 -0
- package/dist/stories/CardShoe.stories.js +8 -0
- package/dist/stories/CardShoe.stories.js.map +1 -0
- package/dist/stories/CardTable.stories.d.ts +7 -0
- package/dist/stories/CardTable.stories.d.ts.map +1 -0
- package/dist/stories/CardTable.stories.js +15 -0
- package/dist/stories/CardTable.stories.js.map +1 -0
- package/dist/stories/Chip.stories.d.ts +11 -0
- package/dist/stories/Chip.stories.d.ts.map +1 -0
- package/dist/stories/Chip.stories.js +32 -0
- package/dist/stories/Chip.stories.js.map +1 -0
- package/dist/stories/ChipRack.stories.d.ts +7 -0
- package/dist/stories/ChipRack.stories.d.ts.map +1 -0
- package/dist/stories/ChipRack.stories.js +8 -0
- package/dist/stories/ChipRack.stories.js.map +1 -0
- package/dist/stories/Dialog.stories.d.ts +6 -0
- package/dist/stories/Dialog.stories.d.ts.map +1 -0
- package/dist/stories/Dialog.stories.js +15 -0
- package/dist/stories/Dialog.stories.js.map +1 -0
- package/dist/stories/GameFooter.stories.d.ts +7 -0
- package/dist/stories/GameFooter.stories.d.ts.map +1 -0
- package/dist/stories/GameFooter.stories.js +37 -0
- package/dist/stories/GameFooter.stories.js.map +1 -0
- package/dist/stories/Icon.stories.d.ts +9 -0
- package/dist/stories/Icon.stories.d.ts.map +1 -0
- package/dist/stories/Icon.stories.js +27 -0
- package/dist/stories/Icon.stories.js.map +1 -0
- package/dist/stories/PokerCard.stories.d.ts +14 -0
- package/dist/stories/PokerCard.stories.d.ts.map +1 -0
- package/dist/stories/PokerCard.stories.js +40 -0
- package/dist/stories/PokerCard.stories.js.map +1 -0
- package/dist/stories/ResultBadge.stories.d.ts +11 -0
- package/dist/stories/ResultBadge.stories.d.ts.map +1 -0
- package/dist/stories/ResultBadge.stories.js +32 -0
- package/dist/stories/ResultBadge.stories.js.map +1 -0
- package/dist/stories/Toast.stories.d.ts +10 -0
- package/dist/stories/Toast.stories.d.ts.map +1 -0
- package/dist/stories/Toast.stories.js +34 -0
- package/dist/stories/Toast.stories.js.map +1 -0
- package/dist/styles/casino-ui-base.css +310 -0
- package/dist/styles/styles/casino-ui-base.css +310 -0
- package/dist/styles/styles/toast.css +52 -0
- package/dist/styles/toast.css +52 -0
- package/dist/toast.css +52 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/format-amount.d.ts +2 -0
- package/dist/utils/format-amount.d.ts.map +1 -0
- package/dist/utils/format-amount.js +31 -0
- package/dist/utils/format-amount.js.map +1 -0
- package/package.json +58 -0
- package/src/assets/card-back.svg +43 -0
- package/src/assets/card-shoe-overlay.svg +14 -0
- package/src/components/bet-panel.tsx +275 -0
- package/src/components/button.tsx +80 -0
- package/src/components/card-score-badge.tsx +61 -0
- package/src/components/card-shoe.tsx +52 -0
- package/src/components/card-table.tsx +182 -0
- package/src/components/chip-rack.tsx +55 -0
- package/src/components/chip.tsx +203 -0
- package/src/components/game-footer.tsx +356 -0
- package/src/components/game-info-dialog.tsx +245 -0
- package/src/components/icon.tsx +94 -0
- package/src/components/poker-card.tsx +192 -0
- package/src/components/result-badge.tsx +157 -0
- package/src/components/switch-table-dialog.tsx +211 -0
- package/src/components/toast-container.tsx +25 -0
- package/src/components/toast-helpers.ts +79 -0
- package/src/components/toast.tsx +282 -0
- package/src/components/ui/dialog.tsx +134 -0
- package/src/components/ui/drawer.tsx +132 -0
- package/src/components/ui/dropdown-menu.tsx +210 -0
- package/src/env.d.ts +6 -0
- package/src/index.ts +88 -0
- package/src/lib/utils.ts +6 -0
- package/src/stories/BetPanel.stories.tsx +113 -0
- package/src/stories/Button.stories.tsx +55 -0
- package/src/stories/CardScoreBadge.stories.tsx +34 -0
- package/src/stories/CardShoe.stories.tsx +12 -0
- package/src/stories/Chip.stories.tsx +51 -0
- package/src/stories/ChipRack.stories.tsx +12 -0
- package/src/stories/Dialog.stories.tsx +45 -0
- package/src/stories/GameFooter.stories.tsx +45 -0
- package/src/stories/Icon.stories.tsx +49 -0
- package/src/stories/PokerCard.stories.tsx +72 -0
- package/src/stories/ResultBadge.stories.tsx +51 -0
- package/src/stories/Toast.stories.tsx +71 -0
- package/src/styles/casino-ui-base.css +310 -0
- package/src/styles/toast.css +52 -0
- package/src/types.ts +11 -0
- package/src/utils/format-amount.ts +35 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
3
|
+
import { Check, ChevronRight, Circle } from "lucide-react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
|
|
7
|
+
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
8
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
9
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
10
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
11
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
12
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
13
|
+
|
|
14
|
+
function DropdownMenuSubTrigger({
|
|
15
|
+
className,
|
|
16
|
+
inset,
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
20
|
+
inset?: boolean;
|
|
21
|
+
}) {
|
|
22
|
+
return (
|
|
23
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
24
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
25
|
+
className={cn(
|
|
26
|
+
"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
27
|
+
inset && "pl-8",
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
<ChevronRight className="ml-auto" />
|
|
34
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function DropdownMenuSubContent({
|
|
39
|
+
className,
|
|
40
|
+
...props
|
|
41
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
|
42
|
+
return (
|
|
43
|
+
<DropdownMenuPrimitive.SubContent
|
|
44
|
+
data-slot="dropdown-menu-sub-content"
|
|
45
|
+
className={cn(
|
|
46
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
47
|
+
className,
|
|
48
|
+
)}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function DropdownMenuContent({
|
|
55
|
+
className,
|
|
56
|
+
sideOffset = 4,
|
|
57
|
+
container,
|
|
58
|
+
...props
|
|
59
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content> & {
|
|
60
|
+
container?: HTMLDivElement | null;
|
|
61
|
+
}) {
|
|
62
|
+
return (
|
|
63
|
+
<DropdownMenuPrimitive.Portal container={container ?? undefined}>
|
|
64
|
+
<DropdownMenuPrimitive.Content
|
|
65
|
+
data-slot="dropdown-menu-content"
|
|
66
|
+
sideOffset={sideOffset}
|
|
67
|
+
className={cn(
|
|
68
|
+
"z-50 sm:min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
|
69
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
70
|
+
className,
|
|
71
|
+
)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
</DropdownMenuPrimitive.Portal>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function DropdownMenuItem({
|
|
79
|
+
className,
|
|
80
|
+
inset,
|
|
81
|
+
...props
|
|
82
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
83
|
+
inset?: boolean;
|
|
84
|
+
}) {
|
|
85
|
+
return (
|
|
86
|
+
<DropdownMenuPrimitive.Item
|
|
87
|
+
data-slot="dropdown-menu-item"
|
|
88
|
+
className={cn(
|
|
89
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
90
|
+
inset && "pl-8",
|
|
91
|
+
className,
|
|
92
|
+
)}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function DropdownMenuCheckboxItem({
|
|
99
|
+
className,
|
|
100
|
+
children,
|
|
101
|
+
checked,
|
|
102
|
+
...props
|
|
103
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
|
104
|
+
return (
|
|
105
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
106
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
107
|
+
className={cn(
|
|
108
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
109
|
+
className,
|
|
110
|
+
)}
|
|
111
|
+
checked={checked}
|
|
112
|
+
{...props}
|
|
113
|
+
>
|
|
114
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
115
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
116
|
+
<Check className="h-4 w-4" />
|
|
117
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
118
|
+
</span>
|
|
119
|
+
{children}
|
|
120
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function DropdownMenuRadioItem({
|
|
125
|
+
className,
|
|
126
|
+
children,
|
|
127
|
+
...props
|
|
128
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
|
129
|
+
return (
|
|
130
|
+
<DropdownMenuPrimitive.RadioItem
|
|
131
|
+
data-slot="dropdown-menu-radio-item"
|
|
132
|
+
className={cn(
|
|
133
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
134
|
+
className,
|
|
135
|
+
)}
|
|
136
|
+
{...props}
|
|
137
|
+
>
|
|
138
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
139
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
140
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
141
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
142
|
+
</span>
|
|
143
|
+
{children}
|
|
144
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function DropdownMenuLabel({
|
|
149
|
+
className,
|
|
150
|
+
inset,
|
|
151
|
+
...props
|
|
152
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
|
153
|
+
inset?: boolean;
|
|
154
|
+
}) {
|
|
155
|
+
return (
|
|
156
|
+
<DropdownMenuPrimitive.Label
|
|
157
|
+
data-slot="dropdown-menu-label"
|
|
158
|
+
className={cn(
|
|
159
|
+
"px-2 py-1.5 text-sm font-semibold",
|
|
160
|
+
inset && "pl-8",
|
|
161
|
+
className,
|
|
162
|
+
)}
|
|
163
|
+
{...props}
|
|
164
|
+
/>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function DropdownMenuSeparator({
|
|
169
|
+
className,
|
|
170
|
+
...props
|
|
171
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
172
|
+
return (
|
|
173
|
+
<DropdownMenuPrimitive.Separator
|
|
174
|
+
data-slot="dropdown-menu-separator"
|
|
175
|
+
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
|
176
|
+
{...props}
|
|
177
|
+
/>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function DropdownMenuShortcut({
|
|
182
|
+
className,
|
|
183
|
+
...props
|
|
184
|
+
}: React.HTMLAttributes<HTMLSpanElement>) {
|
|
185
|
+
return (
|
|
186
|
+
<span
|
|
187
|
+
data-slot="dropdown-menu-shortcut"
|
|
188
|
+
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
|
189
|
+
{...props}
|
|
190
|
+
/>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export {
|
|
195
|
+
DropdownMenu,
|
|
196
|
+
DropdownMenuTrigger,
|
|
197
|
+
DropdownMenuContent,
|
|
198
|
+
DropdownMenuItem,
|
|
199
|
+
DropdownMenuCheckboxItem,
|
|
200
|
+
DropdownMenuRadioItem,
|
|
201
|
+
DropdownMenuLabel,
|
|
202
|
+
DropdownMenuSeparator,
|
|
203
|
+
DropdownMenuShortcut,
|
|
204
|
+
DropdownMenuGroup,
|
|
205
|
+
DropdownMenuPortal,
|
|
206
|
+
DropdownMenuSub,
|
|
207
|
+
DropdownMenuSubContent,
|
|
208
|
+
DropdownMenuSubTrigger,
|
|
209
|
+
DropdownMenuRadioGroup,
|
|
210
|
+
};
|
package/src/env.d.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Components
|
|
2
|
+
export { Button, buttonVariants, type ButtonProps } from "./components/button";
|
|
3
|
+
export {
|
|
4
|
+
default as Chip,
|
|
5
|
+
CHIP_PRESETS,
|
|
6
|
+
CHIP_DENOMINATIONS,
|
|
7
|
+
getChipDenominationForAmount,
|
|
8
|
+
type ChipDenomination,
|
|
9
|
+
} from "./components/chip";
|
|
10
|
+
export { ChipRack } from "./components/chip-rack";
|
|
11
|
+
export { PokerCard, type Suit, type Rank } from "./components/poker-card";
|
|
12
|
+
export { CardShoe } from "./components/card-shoe";
|
|
13
|
+
export { default as CardTable } from "./components/card-table";
|
|
14
|
+
export { default as CardScoreBadge } from "./components/card-score-badge";
|
|
15
|
+
export { ResultBadge, type ResultType } from "./components/result-badge";
|
|
16
|
+
export { Icon } from "./components/icon";
|
|
17
|
+
export { GameFooter } from "./components/game-footer";
|
|
18
|
+
export { default as GameInfoDialog } from "./components/game-info-dialog";
|
|
19
|
+
export { default as SwitchTableDialog } from "./components/switch-table-dialog";
|
|
20
|
+
export {
|
|
21
|
+
BetPanelRoot,
|
|
22
|
+
BetPanelInput,
|
|
23
|
+
BetPanelActions,
|
|
24
|
+
BetPanelChips,
|
|
25
|
+
BetPanelTimer,
|
|
26
|
+
BetPanelFoldingInfo,
|
|
27
|
+
} from "./components/bet-panel";
|
|
28
|
+
|
|
29
|
+
// Toast system
|
|
30
|
+
export { CasinoToastContainer } from "./components/toast-container";
|
|
31
|
+
export { toast } from "./components/toast-helpers";
|
|
32
|
+
export type {
|
|
33
|
+
EphemeralVariant,
|
|
34
|
+
StatusVariant,
|
|
35
|
+
ToastAction,
|
|
36
|
+
} from "./components/toast";
|
|
37
|
+
|
|
38
|
+
// Utilities
|
|
39
|
+
export { cn } from "./lib/utils";
|
|
40
|
+
export { formatAmountDirect } from "./utils/format-amount";
|
|
41
|
+
|
|
42
|
+
// Types
|
|
43
|
+
export type { CoinInfo } from "./types";
|
|
44
|
+
|
|
45
|
+
// UI primitives
|
|
46
|
+
export {
|
|
47
|
+
Dialog,
|
|
48
|
+
DialogClose,
|
|
49
|
+
DialogContent,
|
|
50
|
+
DialogDescription,
|
|
51
|
+
DialogFooter,
|
|
52
|
+
DialogHeader,
|
|
53
|
+
DialogOverlay,
|
|
54
|
+
DialogPortal,
|
|
55
|
+
DialogTitle,
|
|
56
|
+
DialogTrigger,
|
|
57
|
+
} from "./components/ui/dialog";
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
Drawer,
|
|
61
|
+
DrawerPortal,
|
|
62
|
+
DrawerOverlay,
|
|
63
|
+
DrawerTrigger,
|
|
64
|
+
DrawerClose,
|
|
65
|
+
DrawerContent,
|
|
66
|
+
DrawerHeader,
|
|
67
|
+
DrawerFooter,
|
|
68
|
+
DrawerTitle,
|
|
69
|
+
DrawerDescription,
|
|
70
|
+
} from "./components/ui/drawer";
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
DropdownMenu,
|
|
74
|
+
DropdownMenuTrigger,
|
|
75
|
+
DropdownMenuContent,
|
|
76
|
+
DropdownMenuItem,
|
|
77
|
+
DropdownMenuCheckboxItem,
|
|
78
|
+
DropdownMenuRadioItem,
|
|
79
|
+
DropdownMenuLabel,
|
|
80
|
+
DropdownMenuSeparator,
|
|
81
|
+
DropdownMenuShortcut,
|
|
82
|
+
DropdownMenuGroup,
|
|
83
|
+
DropdownMenuPortal,
|
|
84
|
+
DropdownMenuSub,
|
|
85
|
+
DropdownMenuSubContent,
|
|
86
|
+
DropdownMenuSubTrigger,
|
|
87
|
+
DropdownMenuRadioGroup,
|
|
88
|
+
} from "./components/ui/dropdown-menu";
|
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
BetPanelRoot,
|
|
5
|
+
BetPanelInput,
|
|
6
|
+
BetPanelActions,
|
|
7
|
+
BetPanelChips,
|
|
8
|
+
BetPanelTimer,
|
|
9
|
+
BetPanelFoldingInfo,
|
|
10
|
+
} from "../components/bet-panel";
|
|
11
|
+
import { Button } from "../components/button";
|
|
12
|
+
import Chip, { CHIP_DENOMINATIONS } from "../components/chip";
|
|
13
|
+
|
|
14
|
+
const meta: Meta = {
|
|
15
|
+
title: "Components/BetPanel",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj;
|
|
20
|
+
|
|
21
|
+
export const FullBetPanel: Story = {
|
|
22
|
+
render: () => {
|
|
23
|
+
const [value, setValue] = useState("0");
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="px-2">
|
|
27
|
+
<BetPanelRoot>
|
|
28
|
+
<div className="flex items-center gap-6 w-full">
|
|
29
|
+
<BetPanelInput
|
|
30
|
+
balance="100.00"
|
|
31
|
+
coinInfo={{ name: "SUI", symbol: "SUI", coinType: "sui/sui", image: "", decimal: 9, factor: 1 }}
|
|
32
|
+
value={value}
|
|
33
|
+
setValue={setValue}
|
|
34
|
+
setOriginalBetSize={() => {}}
|
|
35
|
+
getMaxBet={() => 100}
|
|
36
|
+
setError={() => {}}
|
|
37
|
+
/>
|
|
38
|
+
<BetPanelChips>
|
|
39
|
+
{CHIP_DENOMINATIONS.map((denom) => (
|
|
40
|
+
<Chip
|
|
41
|
+
key={denom}
|
|
42
|
+
denomination={denom}
|
|
43
|
+
chipClass="w-8 h-8 md:w-11 md:h-11"
|
|
44
|
+
onClick={() => setValue((Number(value) + denom).toString())}
|
|
45
|
+
isButton
|
|
46
|
+
/>
|
|
47
|
+
))}
|
|
48
|
+
</BetPanelChips>
|
|
49
|
+
<BetPanelActions>
|
|
50
|
+
<Button variant="tertiary">Undo</Button>
|
|
51
|
+
<Button variant="tertiary">Clear</Button>
|
|
52
|
+
<Button variant="primary" className="h-10">Deal Now</Button>
|
|
53
|
+
</BetPanelActions>
|
|
54
|
+
</div>
|
|
55
|
+
</BetPanelRoot>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const Timer: Story = {
|
|
62
|
+
render: () => (
|
|
63
|
+
<div style={{ width: 400 }}>
|
|
64
|
+
<BetPanelTimer remainingTime={15} progress={75} isWarning={false} isActive />
|
|
65
|
+
</div>
|
|
66
|
+
),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const TimerWarning: Story = {
|
|
70
|
+
render: () => (
|
|
71
|
+
<div style={{ width: 400 }}>
|
|
72
|
+
<BetPanelTimer remainingTime={3} progress={15} isWarning isActive />
|
|
73
|
+
</div>
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const FoldingInfo: Story = {
|
|
78
|
+
render: () => {
|
|
79
|
+
const [open, setOpen] = useState(true);
|
|
80
|
+
return (
|
|
81
|
+
<div style={{ width: 400 }} className="bg-panel-bg rounded-xl p-4">
|
|
82
|
+
<Button variant="tertiary" onClick={() => setOpen(!open)} className="mb-2">
|
|
83
|
+
Toggle
|
|
84
|
+
</Button>
|
|
85
|
+
<BetPanelFoldingInfo open={open}>
|
|
86
|
+
<div className="flex items-center justify-center pb-2">
|
|
87
|
+
<span className="text-sm font-semibold text-white">Placing bet...</span>
|
|
88
|
+
</div>
|
|
89
|
+
</BetPanelFoldingInfo>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const InputWithError: Story = {
|
|
96
|
+
render: () => {
|
|
97
|
+
const [value, setValue] = useState("999");
|
|
98
|
+
return (
|
|
99
|
+
<div style={{ width: 300 }}>
|
|
100
|
+
<BetPanelInput
|
|
101
|
+
balance="10.00"
|
|
102
|
+
coinInfo={{ name: "SUI", symbol: "SUI", coinType: "sui/sui", image: "", decimal: 9, factor: 1 }}
|
|
103
|
+
value={value}
|
|
104
|
+
setValue={setValue}
|
|
105
|
+
setOriginalBetSize={() => {}}
|
|
106
|
+
getMaxBet={() => 10}
|
|
107
|
+
error="Insufficient balance"
|
|
108
|
+
setError={() => {}}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Button } from "../components/button";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Button> = {
|
|
5
|
+
title: "Components/Button",
|
|
6
|
+
component: Button,
|
|
7
|
+
argTypes: {
|
|
8
|
+
variant: {
|
|
9
|
+
control: "select",
|
|
10
|
+
options: ["primary", "secondary", "tertiary", "grey_pure"],
|
|
11
|
+
},
|
|
12
|
+
fullWidth: { control: "boolean" },
|
|
13
|
+
disabled: { control: "boolean" },
|
|
14
|
+
loading: { control: "boolean" },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof Button>;
|
|
20
|
+
|
|
21
|
+
export const Primary: Story = {
|
|
22
|
+
args: { variant: "primary", children: "Deal Now" },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Secondary: Story = {
|
|
26
|
+
args: { variant: "secondary", children: "Skip" },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Tertiary: Story = {
|
|
30
|
+
args: { variant: "tertiary", children: "Undo" },
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const GreyPure: Story = {
|
|
34
|
+
args: { variant: "grey_pure", children: "Clear" },
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const Disabled: Story = {
|
|
38
|
+
args: { variant: "primary", children: "Deal Now", disabled: true },
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const FullWidth: Story = {
|
|
42
|
+
args: { variant: "primary", children: "Start Playing", fullWidth: true },
|
|
43
|
+
decorators: [(Story) => <div style={{ width: 300 }}><Story /></div>],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const AllVariants: Story = {
|
|
47
|
+
render: () => (
|
|
48
|
+
<div className="flex flex-col gap-3">
|
|
49
|
+
<Button variant="primary">Primary (Green)</Button>
|
|
50
|
+
<Button variant="secondary">Secondary (Blue)</Button>
|
|
51
|
+
<Button variant="tertiary">Tertiary (Grey)</Button>
|
|
52
|
+
<Button variant="grey_pure">Grey Pure</Button>
|
|
53
|
+
</div>
|
|
54
|
+
),
|
|
55
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import CardScoreBadge from "../components/card-score-badge";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof CardScoreBadge> = {
|
|
5
|
+
title: "Components/CardScoreBadge",
|
|
6
|
+
component: CardScoreBadge,
|
|
7
|
+
argTypes: {
|
|
8
|
+
type: {
|
|
9
|
+
control: "select",
|
|
10
|
+
options: ["default", "win", "lose", "bust", "blackjack", "push", "even", "surrender"],
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
type Story = StoryObj<typeof CardScoreBadge>;
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
args: { type: "default", children: "17" },
|
|
20
|
+
decorators: [(Story) => <div className="relative w-20 h-20"><Story /></div>],
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const AllTypes: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<div className="flex gap-6">
|
|
26
|
+
{(["default", "win", "lose", "bust", "blackjack", "push", "even", "surrender"] as const).map((type) => (
|
|
27
|
+
<div key={type} className="relative w-16 h-16 flex flex-col items-center">
|
|
28
|
+
<CardScoreBadge type={type}>21</CardScoreBadge>
|
|
29
|
+
<span className="absolute top-2 text-xs text-text-secondary">{type}</span>
|
|
30
|
+
</div>
|
|
31
|
+
))}
|
|
32
|
+
</div>
|
|
33
|
+
),
|
|
34
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { CardShoe } from "../components/card-shoe";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof CardShoe> = {
|
|
5
|
+
title: "Components/CardShoe",
|
|
6
|
+
component: CardShoe,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default meta;
|
|
10
|
+
type Story = StoryObj<typeof CardShoe>;
|
|
11
|
+
|
|
12
|
+
export const Default: Story = {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import Chip, { CHIP_DENOMINATIONS, type ChipDenomination } from "../components/chip";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Chip> = {
|
|
5
|
+
title: "Components/Chip",
|
|
6
|
+
component: Chip,
|
|
7
|
+
argTypes: {
|
|
8
|
+
denomination: {
|
|
9
|
+
control: "select",
|
|
10
|
+
options: CHIP_DENOMINATIONS,
|
|
11
|
+
},
|
|
12
|
+
isButton: { control: "boolean" },
|
|
13
|
+
selected: { control: "boolean" },
|
|
14
|
+
showText: { control: "boolean" },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof Chip>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
args: { denomination: 100, isButton: true },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Selected: Story = {
|
|
26
|
+
args: { denomination: 25, isButton: true, selected: true },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const WithAmount: Story = {
|
|
30
|
+
args: { amount: 42.5, isButton: false },
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const AllDenominations: Story = {
|
|
34
|
+
render: () => (
|
|
35
|
+
<div className="flex gap-2 items-end">
|
|
36
|
+
{CHIP_DENOMINATIONS.map((denom) => (
|
|
37
|
+
<Chip key={denom} denomination={denom} isButton showText />
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const StaticChips: Story = {
|
|
44
|
+
render: () => (
|
|
45
|
+
<div className="flex gap-2">
|
|
46
|
+
{CHIP_DENOMINATIONS.map((denom) => (
|
|
47
|
+
<Chip key={denom} denomination={denom} showText />
|
|
48
|
+
))}
|
|
49
|
+
</div>
|
|
50
|
+
),
|
|
51
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { ChipRack } from "../components/chip-rack";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof ChipRack> = {
|
|
5
|
+
title: "Components/ChipRack",
|
|
6
|
+
component: ChipRack,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default meta;
|
|
10
|
+
type Story = StoryObj<typeof ChipRack>;
|
|
11
|
+
|
|
12
|
+
export const Default: Story = {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
Dialog,
|
|
5
|
+
DialogContent,
|
|
6
|
+
DialogHeader,
|
|
7
|
+
DialogTitle,
|
|
8
|
+
DialogDescription,
|
|
9
|
+
DialogFooter,
|
|
10
|
+
DialogClose,
|
|
11
|
+
} from "../components/ui/dialog";
|
|
12
|
+
import { Button } from "../components/button";
|
|
13
|
+
|
|
14
|
+
const meta: Meta = {
|
|
15
|
+
title: "Primitives/Dialog",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
render: () => {
|
|
23
|
+
const [open, setOpen] = useState(false);
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<Button variant="primary" onClick={() => setOpen(true)}>Open Dialog</Button>
|
|
27
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
28
|
+
<DialogContent className="w-100 rounded-xl bg-surface-400">
|
|
29
|
+
<DialogHeader className="flex flex-col gap-2 p-6">
|
|
30
|
+
<DialogTitle className="text-2xl font-bold">Dialog Title</DialogTitle>
|
|
31
|
+
<DialogDescription>This is a dialog description.</DialogDescription>
|
|
32
|
+
</DialogHeader>
|
|
33
|
+
<div className="px-6 py-4">
|
|
34
|
+
<p className="text-sm text-text-secondary">Dialog body content goes here.</p>
|
|
35
|
+
</div>
|
|
36
|
+
<DialogFooter className="px-6 pb-6">
|
|
37
|
+
<Button variant="tertiary" onClick={() => setOpen(false)}>Cancel</Button>
|
|
38
|
+
<Button variant="primary" onClick={() => setOpen(false)}>Confirm</Button>
|
|
39
|
+
</DialogFooter>
|
|
40
|
+
</DialogContent>
|
|
41
|
+
</Dialog>
|
|
42
|
+
</>
|
|
43
|
+
);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { GameFooter } from "../components/game-footer";
|
|
3
|
+
import { CasinoToastContainer } from "../components/toast-container";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof GameFooter> = {
|
|
6
|
+
title: "Components/GameFooter",
|
|
7
|
+
component: GameFooter,
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (
|
|
10
|
+
<div style={{ width: 900 }}>
|
|
11
|
+
<Story />
|
|
12
|
+
<CasinoToastContainer />
|
|
13
|
+
</div>
|
|
14
|
+
),
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof GameFooter>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
tableId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
|
24
|
+
shareBaseUrl: "https://example.com/blackjack",
|
|
25
|
+
badges: {
|
|
26
|
+
houseEdge: "0.5",
|
|
27
|
+
minBet: "0.1",
|
|
28
|
+
coinInfo: { name: "SUI", symbol: "SUI", coinType: "sui/sui", image: "", decimal: 9, factor: 1 },
|
|
29
|
+
},
|
|
30
|
+
tabsContents: {
|
|
31
|
+
table: <div className="text-white p-4">Table info content</div>,
|
|
32
|
+
howToPlay: <div className="text-white p-4">How to play content</div>,
|
|
33
|
+
balance: <div className="text-white p-4">Balance content</div>,
|
|
34
|
+
},
|
|
35
|
+
volumeSlider: {
|
|
36
|
+
globalVolume: 0.7,
|
|
37
|
+
setGlobalVolume: () => {},
|
|
38
|
+
setPrevVolume: () => {},
|
|
39
|
+
},
|
|
40
|
+
onToggleMute: () => {},
|
|
41
|
+
onJoin: () => {},
|
|
42
|
+
gameTitle: "Blackjack",
|
|
43
|
+
gameDescription: "Classic Blackjack. Play solo or join a multiplayer table.",
|
|
44
|
+
},
|
|
45
|
+
};
|