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,275 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "../lib/utils";
|
|
3
|
+
import type { CoinInfo } from "../types";
|
|
4
|
+
/* -------------------------------------------------------------------------- */
|
|
5
|
+
/* Betting Mode Components */
|
|
6
|
+
/* -------------------------------------------------------------------------- */
|
|
7
|
+
|
|
8
|
+
interface BetPanelRootProps extends React.ComponentProps<"div"> {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function BetPanelRoot({ className, children, ...props }: BetPanelRootProps) {
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
data-slot="bet-panel"
|
|
16
|
+
className={cn(
|
|
17
|
+
"flex flex-col justify-end items-center rounded-xl bg-panel-bg p-3 sm:px-5 sm:py-4 overflow-x-clip",
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface BetPanelFoldingInfoProps extends React.ComponentProps<"div"> {
|
|
28
|
+
open: boolean;
|
|
29
|
+
children: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function BetPanelFoldingInfo({
|
|
33
|
+
className,
|
|
34
|
+
open,
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
}: BetPanelFoldingInfoProps) {
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
className={cn(
|
|
41
|
+
"w-full grid duration-300 ease-in-out",
|
|
42
|
+
open ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
>
|
|
46
|
+
<div className="overflow-hidden">{children}</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface BetPanelInputProps extends React.ComponentProps<"div"> {
|
|
52
|
+
label?: string;
|
|
53
|
+
balance?: string;
|
|
54
|
+
coinInfo?: CoinInfo;
|
|
55
|
+
value?: string;
|
|
56
|
+
setValue: React.Dispatch<React.SetStateAction<string>>;
|
|
57
|
+
setOriginalBetSize: (size: number | ((prev: number) => number)) => void;
|
|
58
|
+
getMaxBet: () => number;
|
|
59
|
+
error?: string;
|
|
60
|
+
setError: (error?: string) => void;
|
|
61
|
+
disabled?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function BetPanelInput({
|
|
65
|
+
className,
|
|
66
|
+
label = "Balance",
|
|
67
|
+
balance,
|
|
68
|
+
coinInfo,
|
|
69
|
+
value,
|
|
70
|
+
setValue,
|
|
71
|
+
getMaxBet,
|
|
72
|
+
setOriginalBetSize,
|
|
73
|
+
error,
|
|
74
|
+
setError,
|
|
75
|
+
disabled,
|
|
76
|
+
...props
|
|
77
|
+
}: BetPanelInputProps) {
|
|
78
|
+
const isUSD = coinInfo?.coinType?.toLowerCase().includes("usd") ?? false;
|
|
79
|
+
const regex = /^[0-9.]+$/;
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
data-slot="bet-panel-input"
|
|
84
|
+
className={cn(
|
|
85
|
+
"relative flex flex-1 sm:flex-none sm:w-[234px] shrink-0 flex-col gap-1",
|
|
86
|
+
disabled && "opacity-60 pointer-events-none",
|
|
87
|
+
className,
|
|
88
|
+
)}
|
|
89
|
+
{...props}
|
|
90
|
+
>
|
|
91
|
+
<div className="hidden sm:flex items-center justify-between leading-4.5 h-4.5 text-sm font-semibold text-[#BFBFBF]">
|
|
92
|
+
<span>{label}</span>
|
|
93
|
+
{balance != null && (
|
|
94
|
+
<div className="flex items-center gap-2">
|
|
95
|
+
<span>{balance}</span>
|
|
96
|
+
<span>{coinInfo?.symbol}</span>
|
|
97
|
+
</div>
|
|
98
|
+
)}
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<div className="relative flex flex-col items-center">
|
|
102
|
+
<div
|
|
103
|
+
className={cn(
|
|
104
|
+
"flex w-full items-center rounded-lg sm:rounded-xl border bg-surface-600 h-10 sm:h-12 px-3 py-2 transition-colors",
|
|
105
|
+
error ? "border-accent-error" : "border-button-grey",
|
|
106
|
+
)}
|
|
107
|
+
>
|
|
108
|
+
<div className="flex flex-1 items-center gap-1">
|
|
109
|
+
{isUSD ? (
|
|
110
|
+
<span>$</span>
|
|
111
|
+
) : coinInfo?.image ? (
|
|
112
|
+
typeof coinInfo.image === "string" ? (
|
|
113
|
+
<img
|
|
114
|
+
src={coinInfo.image}
|
|
115
|
+
alt={coinInfo.symbol}
|
|
116
|
+
className="size-4 object-contain"
|
|
117
|
+
/>
|
|
118
|
+
) : (
|
|
119
|
+
<div className="min-w-4 h-4 w-4 object-contain">
|
|
120
|
+
{coinInfo.image}
|
|
121
|
+
</div>
|
|
122
|
+
)
|
|
123
|
+
) : null}
|
|
124
|
+
<input
|
|
125
|
+
type="text"
|
|
126
|
+
inputMode="decimal"
|
|
127
|
+
value={value ?? ""}
|
|
128
|
+
onChange={(e) => {
|
|
129
|
+
if (
|
|
130
|
+
regex.test(e.target.value) ||
|
|
131
|
+
e.target.value === "" ||
|
|
132
|
+
e.target.value === "."
|
|
133
|
+
) {
|
|
134
|
+
setValue?.(e.target.value);
|
|
135
|
+
}
|
|
136
|
+
}}
|
|
137
|
+
className="w-full min-w-0 bg-transparent text-base font-semibold text-white tracking-tight outline-none placeholder:text-white/30"
|
|
138
|
+
placeholder="0.00"
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div className="flex items-center gap-1 shrink-0">
|
|
143
|
+
<button
|
|
144
|
+
type="button"
|
|
145
|
+
onClick={() => setValue((Number(value) * 2).toString())}
|
|
146
|
+
className="hidden sm:block rounded-lg bg-surface-300 px-2.5 py-2 text-xs font-semibold text-white transition-colors hover:bg-action-hover active:bg-action-active"
|
|
147
|
+
>
|
|
148
|
+
2x
|
|
149
|
+
</button>
|
|
150
|
+
<button
|
|
151
|
+
type="button"
|
|
152
|
+
onClick={() => setValue(getMaxBet().toString())}
|
|
153
|
+
className="rounded-md sm:rounded-lg bg-surface-300 px-2 sm:px-2.5 py-1 sm:py-2 text-xs font-semibold text-white transition-colors hover:bg-action-hover active:bg-action-active"
|
|
154
|
+
>
|
|
155
|
+
MAX
|
|
156
|
+
</button>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<div
|
|
161
|
+
className={cn(
|
|
162
|
+
"absolute top-10 sm:top-12 left-1/2 -translate-x-1/2 grid w-full transition-[grid-template-rows] duration-300 ease-out z-30",
|
|
163
|
+
error ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
|
|
164
|
+
)}
|
|
165
|
+
>
|
|
166
|
+
<div className="overflow-hidden">
|
|
167
|
+
<div className="mx-auto flex w-[90%] sm:w-[210px] items-center justify-center rounded-b-xl bg-accent-error py-1 px-2.5 sm:py-2">
|
|
168
|
+
<span className="text-center text-xs font-semibold text-white">
|
|
169
|
+
{error}
|
|
170
|
+
</span>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
interface BetPanelChipsProps extends React.ComponentProps<"div"> {
|
|
180
|
+
disabled?: boolean;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function BetPanelChips({ className, disabled, ...props }: BetPanelChipsProps) {
|
|
184
|
+
return (
|
|
185
|
+
<div
|
|
186
|
+
data-slot="bet-panel-chips"
|
|
187
|
+
className={cn(
|
|
188
|
+
"min-w-0 w-full flex h-full items-center justify-between sm:justify-start sm:gap-1 transition-opacity",
|
|
189
|
+
disabled && "opacity-60 pointer-events-none",
|
|
190
|
+
className,
|
|
191
|
+
)}
|
|
192
|
+
{...props}
|
|
193
|
+
/>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
interface BetPanelActionsProps extends React.ComponentProps<"div"> {
|
|
198
|
+
disabled?: boolean;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function BetPanelActions({
|
|
202
|
+
className,
|
|
203
|
+
disabled,
|
|
204
|
+
...props
|
|
205
|
+
}: BetPanelActionsProps) {
|
|
206
|
+
return (
|
|
207
|
+
<div
|
|
208
|
+
data-slot="bet-panel-actions"
|
|
209
|
+
className={cn(
|
|
210
|
+
"flex items-center gap-2 shrink-0 transition-opacity select-none",
|
|
211
|
+
disabled && "opacity-50 pointer-events-none",
|
|
212
|
+
className,
|
|
213
|
+
)}
|
|
214
|
+
{...props}
|
|
215
|
+
/>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* -------------------------------------------------------------------------- */
|
|
220
|
+
/* Timer Component (shared by Action & Insurance panels) */
|
|
221
|
+
/* -------------------------------------------------------------------------- */
|
|
222
|
+
|
|
223
|
+
interface BetPanelTimerProps {
|
|
224
|
+
remainingTime: number;
|
|
225
|
+
progress: number;
|
|
226
|
+
isWarning: boolean;
|
|
227
|
+
isActive: boolean;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function BetPanelTimer({
|
|
231
|
+
remainingTime,
|
|
232
|
+
progress,
|
|
233
|
+
isWarning,
|
|
234
|
+
isActive,
|
|
235
|
+
}: BetPanelTimerProps) {
|
|
236
|
+
if (!isActive) return null;
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<div className="flex h-6 w-full items-center gap-3 py-1">
|
|
240
|
+
<span
|
|
241
|
+
className={cn(
|
|
242
|
+
"shrink-0 text-xs tabular-nums",
|
|
243
|
+
isWarning ? "text-red-500 animate-pulse" : "text-accent-success",
|
|
244
|
+
)}
|
|
245
|
+
style={{ fontFamily: "var(--font-dm-mono)", fontWeight: 500 }}
|
|
246
|
+
>
|
|
247
|
+
{remainingTime}s
|
|
248
|
+
</span>
|
|
249
|
+
<div className="relative h-1.5 flex-1 rounded-full bg-surface-650">
|
|
250
|
+
<div
|
|
251
|
+
className={cn(
|
|
252
|
+
"absolute inset-y-0 left-0 rounded-full transition-[width] duration-1000 ease-linear shadow-[inset_0px_1px_2px_0px_rgba(255,255,255,0.15)]",
|
|
253
|
+
isWarning
|
|
254
|
+
? "bg-red-500"
|
|
255
|
+
: "bg-linear-to-r from-accent-success to-timer-end",
|
|
256
|
+
)}
|
|
257
|
+
style={{ width: `${progress}%` }}
|
|
258
|
+
/>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* -------------------------------------------------------------------------- */
|
|
265
|
+
/* Exports */
|
|
266
|
+
/* -------------------------------------------------------------------------- */
|
|
267
|
+
|
|
268
|
+
export {
|
|
269
|
+
BetPanelTimer,
|
|
270
|
+
BetPanelInput,
|
|
271
|
+
BetPanelActions,
|
|
272
|
+
BetPanelChips,
|
|
273
|
+
BetPanelRoot,
|
|
274
|
+
BetPanelFoldingInfo,
|
|
275
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../lib/utils";
|
|
6
|
+
|
|
7
|
+
const buttonVariants = cva(
|
|
8
|
+
"flex h-11 items-center justify-center border-2 rounded-lg cursor-pointer whitespace-nowrap select-none disabled:pointer-events-none disabled:opacity-50",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
primary:
|
|
13
|
+
"px-6 py-3 green-action-button text-base font-semibold text-black tracking-tight",
|
|
14
|
+
secondary:
|
|
15
|
+
"px-6 py-3 blue-action-button text-base font-semibold text-black tracking-tight",
|
|
16
|
+
tertiary:
|
|
17
|
+
"px-3 py-2 grey-action-button text-sm font-semibold text-white",
|
|
18
|
+
grey_pure:
|
|
19
|
+
"px-3 py-2 border-button-grey text-sm font-semibold text-white bg-surface-300 hover:bg-action-hover active:bg-action-active",
|
|
20
|
+
},
|
|
21
|
+
fullWidth: {
|
|
22
|
+
true: "w-full",
|
|
23
|
+
false: "",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: "primary",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export interface ButtonProps
|
|
33
|
+
extends
|
|
34
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
35
|
+
VariantProps<typeof buttonVariants> {
|
|
36
|
+
asChild?: boolean;
|
|
37
|
+
before?: React.ReactNode;
|
|
38
|
+
loading?: boolean;
|
|
39
|
+
noLoadingWhenDisabled?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
43
|
+
(
|
|
44
|
+
{
|
|
45
|
+
className,
|
|
46
|
+
variant,
|
|
47
|
+
fullWidth,
|
|
48
|
+
asChild = false,
|
|
49
|
+
disabled,
|
|
50
|
+
before,
|
|
51
|
+
children,
|
|
52
|
+
loading,
|
|
53
|
+
noLoadingWhenDisabled = false,
|
|
54
|
+
...props
|
|
55
|
+
},
|
|
56
|
+
ref,
|
|
57
|
+
) => {
|
|
58
|
+
return (
|
|
59
|
+
<button
|
|
60
|
+
className={cn(
|
|
61
|
+
"relative overflow-clip ease-in-out duration-300",
|
|
62
|
+
buttonVariants({ variant, fullWidth, className }),
|
|
63
|
+
)}
|
|
64
|
+
type="button"
|
|
65
|
+
ref={ref}
|
|
66
|
+
disabled={disabled || loading}
|
|
67
|
+
{...props}
|
|
68
|
+
>
|
|
69
|
+
{before}
|
|
70
|
+
|
|
71
|
+
<div className="inline-flex sm:flex-1 items-center justify-center">
|
|
72
|
+
{children}
|
|
73
|
+
</div>
|
|
74
|
+
</button>
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
Button.displayName = "Button";
|
|
79
|
+
|
|
80
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { cn } from "../lib/utils";
|
|
2
|
+
|
|
3
|
+
interface CardScoreBadgeProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
type:
|
|
6
|
+
| "default"
|
|
7
|
+
| "win"
|
|
8
|
+
| "lose"
|
|
9
|
+
| "bust"
|
|
10
|
+
| "blackjack"
|
|
11
|
+
| "push"
|
|
12
|
+
| "even"
|
|
13
|
+
| "surrender";
|
|
14
|
+
children?: React.ReactNode;
|
|
15
|
+
isMobileSmallHeight?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const BADGE_COLORS = {
|
|
19
|
+
default: "bg-surface-300",
|
|
20
|
+
push: "bg-surface-300",
|
|
21
|
+
win: "bg-[#8BB339]",
|
|
22
|
+
lose: "bg-[#DB375E]",
|
|
23
|
+
bust: "bg-[#DB375E]",
|
|
24
|
+
blackjack: "bg-[#FF5C05]",
|
|
25
|
+
even: "bg-card-border",
|
|
26
|
+
surrender: "bg-[#8A8A8A]",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const CardScoreBadge = ({
|
|
30
|
+
type = "default",
|
|
31
|
+
className,
|
|
32
|
+
children,
|
|
33
|
+
isMobileSmallHeight = false,
|
|
34
|
+
}: CardScoreBadgeProps) => {
|
|
35
|
+
const badgeColor = BADGE_COLORS[type];
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
className={cn(
|
|
40
|
+
"pointer-events-none absolute bottom-1 right-0 z-10 select-none text-center",
|
|
41
|
+
className,
|
|
42
|
+
isMobileSmallHeight ? "h-4 min-w-4" : "h-5.5 min-w-5.5",
|
|
43
|
+
)}
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
className={cn(
|
|
47
|
+
"relative w-full h-full flex items-center justify-center rounded font-bold",
|
|
48
|
+
badgeColor,
|
|
49
|
+
isMobileSmallHeight ? "p-0.5 text-[8px]" : "p-1 text-[10px]",
|
|
50
|
+
)}
|
|
51
|
+
style={{
|
|
52
|
+
boxShadow: "0 2px 0 0 #404040",
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
{children}
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default CardScoreBadge;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { PokerCard } from "./poker-card";
|
|
3
|
+
import cardShoeOverlay from "../assets/card-shoe-overlay.svg";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
|
|
6
|
+
interface CardShoeProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const CARD_COUNT = 4;
|
|
11
|
+
const CARD_OFFSET_Y = 2.5; // px vertical offset between stacked cards
|
|
12
|
+
|
|
13
|
+
export const CardShoe = forwardRef<HTMLDivElement, CardShoeProps>(
|
|
14
|
+
({ className }, ref) => {
|
|
15
|
+
return (
|
|
16
|
+
<div
|
|
17
|
+
className={cn(
|
|
18
|
+
"relative w-12.5 h-28.5 border-[2.4px] rounded-t-[3.6px] rounded-b-[9.6px] overflow-hidden",
|
|
19
|
+
"bg-card-shoe-bg border-card-shoe-border shadow-[0px_2px_0px_0px_#122741]",
|
|
20
|
+
className,
|
|
21
|
+
)}
|
|
22
|
+
>
|
|
23
|
+
{/* Stacked card backs visible through the shoe opening */}
|
|
24
|
+
<div
|
|
25
|
+
ref={ref}
|
|
26
|
+
className="absolute bottom-[4px] left-1/2 -translate-x-1/2"
|
|
27
|
+
>
|
|
28
|
+
{Array.from({ length: CARD_COUNT }).map((_, i) => (
|
|
29
|
+
<div
|
|
30
|
+
key={i}
|
|
31
|
+
className="absolute left-1/2 -translate-x-1/2 select-none"
|
|
32
|
+
style={{
|
|
33
|
+
bottom: `${i * CARD_OFFSET_Y}px`,
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
<PokerCard side="back" showShadow={false} />
|
|
37
|
+
</div>
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
{/* Shoe overlay with semicircular cutout */}
|
|
42
|
+
<img
|
|
43
|
+
src={cardShoeOverlay}
|
|
44
|
+
alt=""
|
|
45
|
+
className="absolute top-0 left-0 pointer-events-none w-12.5"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
CardShoe.displayName = "CardShoe";
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
type DivProps = React.HTMLAttributes<HTMLDivElement>;
|
|
2
|
+
|
|
3
|
+
interface ICardTableProp {
|
|
4
|
+
className?: DivProps["className"];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const CardTable = ({ className }: ICardTableProp) => {
|
|
8
|
+
return (
|
|
9
|
+
<div className={className}>
|
|
10
|
+
<svg
|
|
11
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
12
|
+
width="1114"
|
|
13
|
+
height="521"
|
|
14
|
+
viewBox="0 0 1114 521"
|
|
15
|
+
fill="none"
|
|
16
|
+
>
|
|
17
|
+
<g filter="url(#filter0_din_6221_41932)">
|
|
18
|
+
<mask id="path-1-inside-1_6221_41932" fill="white">
|
|
19
|
+
<path d="M4 17C4 7.61116 11.6112 0 21 0H1093C1102.39 0 1110 7.61116 1110 17V113C1110 333.914 930.914 513 710 513H404C183.086 513 4 333.914 4 113V17Z" />
|
|
20
|
+
</mask>
|
|
21
|
+
<path
|
|
22
|
+
d="M4 17C4 7.61116 11.6112 0 21 0H1093C1102.39 0 1110 7.61116 1110 17V113C1110 333.914 930.914 513 710 513H404C183.086 513 4 333.914 4 113V17Z"
|
|
23
|
+
fill="url(#paint0_linear_6221_41932)"
|
|
24
|
+
/>
|
|
25
|
+
<path
|
|
26
|
+
d="M4 17C4 7.61116 11.6112 0 21 0H1093C1102.39 0 1110 7.61116 1110 17V113C1110 333.914 930.914 513 710 513H404C183.086 513 4 333.914 4 113V17Z"
|
|
27
|
+
stroke="url(#paint1_linear_6221_41932)"
|
|
28
|
+
strokeWidth="50"
|
|
29
|
+
mask="url(#path-1-inside-1_6221_41932)"
|
|
30
|
+
/>
|
|
31
|
+
</g>
|
|
32
|
+
<defs>
|
|
33
|
+
<filter
|
|
34
|
+
id="filter0_din_6221_41932"
|
|
35
|
+
x="0"
|
|
36
|
+
y="0"
|
|
37
|
+
width="1114"
|
|
38
|
+
height="521"
|
|
39
|
+
filterUnits="userSpaceOnUse"
|
|
40
|
+
colorInterpolationFilters="sRGB"
|
|
41
|
+
>
|
|
42
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
43
|
+
<feColorMatrix
|
|
44
|
+
in="SourceAlpha"
|
|
45
|
+
type="matrix"
|
|
46
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
47
|
+
result="hardAlpha"
|
|
48
|
+
/>
|
|
49
|
+
<feOffset dy="4" />
|
|
50
|
+
<feGaussianBlur stdDeviation="2" />
|
|
51
|
+
<feComposite in2="hardAlpha" operator="out" />
|
|
52
|
+
<feColorMatrix
|
|
53
|
+
type="matrix"
|
|
54
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
|
55
|
+
/>
|
|
56
|
+
<feBlend
|
|
57
|
+
mode="normal"
|
|
58
|
+
in2="BackgroundImageFix"
|
|
59
|
+
result="effect1_dropShadow_6221_41932"
|
|
60
|
+
/>
|
|
61
|
+
<feBlend
|
|
62
|
+
mode="normal"
|
|
63
|
+
in="SourceGraphic"
|
|
64
|
+
in2="BackgroundImageFix"
|
|
65
|
+
result="shape"
|
|
66
|
+
/>
|
|
67
|
+
<feColorMatrix
|
|
68
|
+
in="SourceAlpha"
|
|
69
|
+
type="matrix"
|
|
70
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
71
|
+
result="hardAlpha"
|
|
72
|
+
/>
|
|
73
|
+
<feMorphology
|
|
74
|
+
radius="35"
|
|
75
|
+
operator="erode"
|
|
76
|
+
in="SourceAlpha"
|
|
77
|
+
result="effect2_innerShadow_6221_41932"
|
|
78
|
+
/>
|
|
79
|
+
<feOffset dy="4" />
|
|
80
|
+
<feGaussianBlur stdDeviation="5.45" />
|
|
81
|
+
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
82
|
+
<feColorMatrix
|
|
83
|
+
type="matrix"
|
|
84
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0"
|
|
85
|
+
/>
|
|
86
|
+
<feBlend
|
|
87
|
+
mode="normal"
|
|
88
|
+
in2="shape"
|
|
89
|
+
result="effect2_innerShadow_6221_41932"
|
|
90
|
+
/>
|
|
91
|
+
<feTurbulence
|
|
92
|
+
type="fractalNoise"
|
|
93
|
+
baseFrequency="0.5 0.5"
|
|
94
|
+
stitchTiles="stitch"
|
|
95
|
+
numOctaves="3"
|
|
96
|
+
result="noise"
|
|
97
|
+
seed="9045"
|
|
98
|
+
/>
|
|
99
|
+
<feColorMatrix
|
|
100
|
+
in="noise"
|
|
101
|
+
type="luminanceToAlpha"
|
|
102
|
+
result="alphaNoise"
|
|
103
|
+
/>
|
|
104
|
+
<feComponentTransfer in="alphaNoise" result="coloredNoise1">
|
|
105
|
+
<feFuncA
|
|
106
|
+
type="discrete"
|
|
107
|
+
tableValues="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
|
|
108
|
+
/>
|
|
109
|
+
</feComponentTransfer>
|
|
110
|
+
<feComposite
|
|
111
|
+
operator="in"
|
|
112
|
+
in2="effect2_innerShadow_6221_41932"
|
|
113
|
+
in="coloredNoise1"
|
|
114
|
+
result="noise1Clipped"
|
|
115
|
+
/>
|
|
116
|
+
<feComponentTransfer in="alphaNoise" result="coloredNoise2">
|
|
117
|
+
<feFuncA
|
|
118
|
+
type="discrete"
|
|
119
|
+
tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "
|
|
120
|
+
/>
|
|
121
|
+
</feComponentTransfer>
|
|
122
|
+
<feComposite
|
|
123
|
+
operator="in"
|
|
124
|
+
in2="effect2_innerShadow_6221_41932"
|
|
125
|
+
in="coloredNoise2"
|
|
126
|
+
result="noise2Clipped"
|
|
127
|
+
/>
|
|
128
|
+
<feFlood floodColor="rgba(0, 0, 0, 0.05)" result="color1Flood" />
|
|
129
|
+
<feComposite
|
|
130
|
+
operator="in"
|
|
131
|
+
in2="noise1Clipped"
|
|
132
|
+
in="color1Flood"
|
|
133
|
+
result="color1"
|
|
134
|
+
/>
|
|
135
|
+
<feFlood floodColor="rgba(255, 255, 255, 0)" result="color2Flood" />
|
|
136
|
+
<feComposite
|
|
137
|
+
operator="in"
|
|
138
|
+
in2="noise2Clipped"
|
|
139
|
+
in="color2Flood"
|
|
140
|
+
result="color2"
|
|
141
|
+
/>
|
|
142
|
+
<feMerge result="effect3_noise_6221_41932">
|
|
143
|
+
<feMergeNode in="effect2_innerShadow_6221_41932" />
|
|
144
|
+
<feMergeNode in="color1" />
|
|
145
|
+
<feMergeNode in="color2" />
|
|
146
|
+
</feMerge>
|
|
147
|
+
<feBlend
|
|
148
|
+
mode="normal"
|
|
149
|
+
in="effect3_noise_6221_41932"
|
|
150
|
+
in2="effect1_dropShadow_6221_41932"
|
|
151
|
+
result="effect3_noise_6221_41932"
|
|
152
|
+
/>
|
|
153
|
+
</filter>
|
|
154
|
+
<linearGradient
|
|
155
|
+
id="paint0_linear_6221_41932"
|
|
156
|
+
x1="557"
|
|
157
|
+
y1="0"
|
|
158
|
+
x2="557"
|
|
159
|
+
y2="513"
|
|
160
|
+
gradientUnits="userSpaceOnUse"
|
|
161
|
+
>
|
|
162
|
+
<stop stopColor="#0B3E2C" />
|
|
163
|
+
<stop offset="1" stopColor="#14945B" />
|
|
164
|
+
</linearGradient>
|
|
165
|
+
<linearGradient
|
|
166
|
+
id="paint1_linear_6221_41932"
|
|
167
|
+
x1="557"
|
|
168
|
+
y1="0"
|
|
169
|
+
x2="557"
|
|
170
|
+
y2="513"
|
|
171
|
+
gradientUnits="userSpaceOnUse"
|
|
172
|
+
>
|
|
173
|
+
<stop stopColor="#271709" />
|
|
174
|
+
<stop offset="1" stopColor="#311D0B" />
|
|
175
|
+
</linearGradient>
|
|
176
|
+
</defs>
|
|
177
|
+
</svg>
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export default CardTable;
|