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.
Files changed (196) hide show
  1. package/README.md +213 -0
  2. package/dist/assets/assets/card-back.svg +43 -0
  3. package/dist/assets/assets/card-shoe-overlay.svg +14 -0
  4. package/dist/assets/card-back.svg +43 -0
  5. package/dist/assets/card-shoe-overlay.svg +14 -0
  6. package/dist/casino-ui.css +2 -0
  7. package/dist/components/bet-panel.d.ts +41 -0
  8. package/dist/components/bet-panel.d.ts.map +1 -0
  9. package/dist/components/bet-panel.js +37 -0
  10. package/dist/components/bet-panel.js.map +1 -0
  11. package/dist/components/button.d.ts +15 -0
  12. package/dist/components/button.d.ts.map +1 -0
  13. package/dist/components/button.js +27 -0
  14. package/dist/components/button.js.map +1 -0
  15. package/dist/components/card-score-badge.d.ts +9 -0
  16. package/dist/components/card-score-badge.d.ts.map +1 -0
  17. package/dist/components/card-score-badge.js +20 -0
  18. package/dist/components/card-score-badge.js.map +1 -0
  19. package/dist/components/card-shoe.d.ts +6 -0
  20. package/dist/components/card-shoe.d.ts.map +1 -0
  21. package/dist/components/card-shoe.js +14 -0
  22. package/dist/components/card-shoe.js.map +1 -0
  23. package/dist/components/card-table.d.ts +7 -0
  24. package/dist/components/card-table.d.ts.map +1 -0
  25. package/dist/components/card-table.js +6 -0
  26. package/dist/components/card-table.js.map +1 -0
  27. package/dist/components/chip-rack.d.ts +6 -0
  28. package/dist/components/chip-rack.d.ts.map +1 -0
  29. package/dist/components/chip-rack.js +13 -0
  30. package/dist/components/chip-rack.js.map +1 -0
  31. package/dist/components/chip.d.ts +49 -0
  32. package/dist/components/chip.d.ts.map +1 -0
  33. package/dist/components/chip.js +81 -0
  34. package/dist/components/chip.js.map +1 -0
  35. package/dist/components/game-footer.d.ts +29 -0
  36. package/dist/components/game-footer.d.ts.map +1 -0
  37. package/dist/components/game-footer.js +72 -0
  38. package/dist/components/game-footer.js.map +1 -0
  39. package/dist/components/game-info-dialog.d.ts +23 -0
  40. package/dist/components/game-info-dialog.d.ts.map +1 -0
  41. package/dist/components/game-info-dialog.js +26 -0
  42. package/dist/components/game-info-dialog.js.map +1 -0
  43. package/dist/components/icon.d.ts +10 -0
  44. package/dist/components/icon.d.ts.map +1 -0
  45. package/dist/components/icon.js +59 -0
  46. package/dist/components/icon.js.map +1 -0
  47. package/dist/components/poker-card.d.ts +15 -0
  48. package/dist/components/poker-card.d.ts.map +1 -0
  49. package/dist/components/poker-card.js +77 -0
  50. package/dist/components/poker-card.js.map +1 -0
  51. package/dist/components/result-badge.d.ts +14 -0
  52. package/dist/components/result-badge.d.ts.map +1 -0
  53. package/dist/components/result-badge.js +71 -0
  54. package/dist/components/result-badge.js.map +1 -0
  55. package/dist/components/switch-table-dialog.d.ts +10 -0
  56. package/dist/components/switch-table-dialog.d.ts.map +1 -0
  57. package/dist/components/switch-table-dialog.js +51 -0
  58. package/dist/components/switch-table-dialog.js.map +1 -0
  59. package/dist/components/toast-container.d.ts +8 -0
  60. package/dist/components/toast-container.d.ts.map +1 -0
  61. package/dist/components/toast-container.js +8 -0
  62. package/dist/components/toast-container.js.map +1 -0
  63. package/dist/components/toast-helpers.d.ts +22 -0
  64. package/dist/components/toast-helpers.d.ts.map +1 -0
  65. package/dist/components/toast-helpers.js +47 -0
  66. package/dist/components/toast-helpers.js.map +1 -0
  67. package/dist/components/toast.d.ts +26 -0
  68. package/dist/components/toast.d.ts.map +1 -0
  69. package/dist/components/toast.js +49 -0
  70. package/dist/components/toast.js.map +1 -0
  71. package/dist/components/ui/dialog.d.ts +14 -0
  72. package/dist/components/ui/dialog.d.ts.map +1 -0
  73. package/dist/components/ui/dialog.js +35 -0
  74. package/dist/components/ui/dialog.js.map +1 -0
  75. package/dist/components/ui/drawer.d.ts +14 -0
  76. package/dist/components/ui/drawer.d.ts.map +1 -0
  77. package/dist/components/ui/drawer.js +35 -0
  78. package/dist/components/ui/drawer.js.map +1 -0
  79. package/dist/components/ui/dropdown-menu.d.ts +27 -0
  80. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  81. package/dist/components/ui/dropdown-menu.js +39 -0
  82. package/dist/components/ui/dropdown-menu.js.map +1 -0
  83. package/dist/index.d.ts +23 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +25 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/lib/utils.d.ts +3 -0
  88. package/dist/lib/utils.d.ts.map +1 -0
  89. package/dist/lib/utils.js +6 -0
  90. package/dist/lib/utils.js.map +1 -0
  91. package/dist/stories/BetPanel.stories.d.ts +10 -0
  92. package/dist/stories/BetPanel.stories.d.ts.map +1 -0
  93. package/dist/stories/BetPanel.stories.js +34 -0
  94. package/dist/stories/BetPanel.stories.js.map +1 -0
  95. package/dist/stories/Button.stories.d.ts +13 -0
  96. package/dist/stories/Button.stories.d.ts.map +1 -0
  97. package/dist/stories/Button.stories.js +39 -0
  98. package/dist/stories/Button.stories.js.map +1 -0
  99. package/dist/stories/CardScoreBadge.stories.d.ts +8 -0
  100. package/dist/stories/CardScoreBadge.stories.d.ts.map +1 -0
  101. package/dist/stories/CardScoreBadge.stories.js +21 -0
  102. package/dist/stories/CardScoreBadge.stories.js.map +1 -0
  103. package/dist/stories/CardShoe.stories.d.ts +7 -0
  104. package/dist/stories/CardShoe.stories.d.ts.map +1 -0
  105. package/dist/stories/CardShoe.stories.js +8 -0
  106. package/dist/stories/CardShoe.stories.js.map +1 -0
  107. package/dist/stories/CardTable.stories.d.ts +7 -0
  108. package/dist/stories/CardTable.stories.d.ts.map +1 -0
  109. package/dist/stories/CardTable.stories.js +15 -0
  110. package/dist/stories/CardTable.stories.js.map +1 -0
  111. package/dist/stories/Chip.stories.d.ts +11 -0
  112. package/dist/stories/Chip.stories.d.ts.map +1 -0
  113. package/dist/stories/Chip.stories.js +32 -0
  114. package/dist/stories/Chip.stories.js.map +1 -0
  115. package/dist/stories/ChipRack.stories.d.ts +7 -0
  116. package/dist/stories/ChipRack.stories.d.ts.map +1 -0
  117. package/dist/stories/ChipRack.stories.js +8 -0
  118. package/dist/stories/ChipRack.stories.js.map +1 -0
  119. package/dist/stories/Dialog.stories.d.ts +6 -0
  120. package/dist/stories/Dialog.stories.d.ts.map +1 -0
  121. package/dist/stories/Dialog.stories.js +15 -0
  122. package/dist/stories/Dialog.stories.js.map +1 -0
  123. package/dist/stories/GameFooter.stories.d.ts +7 -0
  124. package/dist/stories/GameFooter.stories.d.ts.map +1 -0
  125. package/dist/stories/GameFooter.stories.js +37 -0
  126. package/dist/stories/GameFooter.stories.js.map +1 -0
  127. package/dist/stories/Icon.stories.d.ts +9 -0
  128. package/dist/stories/Icon.stories.d.ts.map +1 -0
  129. package/dist/stories/Icon.stories.js +27 -0
  130. package/dist/stories/Icon.stories.js.map +1 -0
  131. package/dist/stories/PokerCard.stories.d.ts +14 -0
  132. package/dist/stories/PokerCard.stories.d.ts.map +1 -0
  133. package/dist/stories/PokerCard.stories.js +40 -0
  134. package/dist/stories/PokerCard.stories.js.map +1 -0
  135. package/dist/stories/ResultBadge.stories.d.ts +11 -0
  136. package/dist/stories/ResultBadge.stories.d.ts.map +1 -0
  137. package/dist/stories/ResultBadge.stories.js +32 -0
  138. package/dist/stories/ResultBadge.stories.js.map +1 -0
  139. package/dist/stories/Toast.stories.d.ts +10 -0
  140. package/dist/stories/Toast.stories.d.ts.map +1 -0
  141. package/dist/stories/Toast.stories.js +34 -0
  142. package/dist/stories/Toast.stories.js.map +1 -0
  143. package/dist/styles/casino-ui-base.css +310 -0
  144. package/dist/styles/styles/casino-ui-base.css +310 -0
  145. package/dist/styles/styles/toast.css +52 -0
  146. package/dist/styles/toast.css +52 -0
  147. package/dist/toast.css +52 -0
  148. package/dist/types.d.ts +11 -0
  149. package/dist/types.d.ts.map +1 -0
  150. package/dist/types.js +2 -0
  151. package/dist/types.js.map +1 -0
  152. package/dist/utils/format-amount.d.ts +2 -0
  153. package/dist/utils/format-amount.d.ts.map +1 -0
  154. package/dist/utils/format-amount.js +31 -0
  155. package/dist/utils/format-amount.js.map +1 -0
  156. package/package.json +58 -0
  157. package/src/assets/card-back.svg +43 -0
  158. package/src/assets/card-shoe-overlay.svg +14 -0
  159. package/src/components/bet-panel.tsx +275 -0
  160. package/src/components/button.tsx +80 -0
  161. package/src/components/card-score-badge.tsx +61 -0
  162. package/src/components/card-shoe.tsx +52 -0
  163. package/src/components/card-table.tsx +182 -0
  164. package/src/components/chip-rack.tsx +55 -0
  165. package/src/components/chip.tsx +203 -0
  166. package/src/components/game-footer.tsx +356 -0
  167. package/src/components/game-info-dialog.tsx +245 -0
  168. package/src/components/icon.tsx +94 -0
  169. package/src/components/poker-card.tsx +192 -0
  170. package/src/components/result-badge.tsx +157 -0
  171. package/src/components/switch-table-dialog.tsx +211 -0
  172. package/src/components/toast-container.tsx +25 -0
  173. package/src/components/toast-helpers.ts +79 -0
  174. package/src/components/toast.tsx +282 -0
  175. package/src/components/ui/dialog.tsx +134 -0
  176. package/src/components/ui/drawer.tsx +132 -0
  177. package/src/components/ui/dropdown-menu.tsx +210 -0
  178. package/src/env.d.ts +6 -0
  179. package/src/index.ts +88 -0
  180. package/src/lib/utils.ts +6 -0
  181. package/src/stories/BetPanel.stories.tsx +113 -0
  182. package/src/stories/Button.stories.tsx +55 -0
  183. package/src/stories/CardScoreBadge.stories.tsx +34 -0
  184. package/src/stories/CardShoe.stories.tsx +12 -0
  185. package/src/stories/Chip.stories.tsx +51 -0
  186. package/src/stories/ChipRack.stories.tsx +12 -0
  187. package/src/stories/Dialog.stories.tsx +45 -0
  188. package/src/stories/GameFooter.stories.tsx +45 -0
  189. package/src/stories/Icon.stories.tsx +49 -0
  190. package/src/stories/PokerCard.stories.tsx +72 -0
  191. package/src/stories/ResultBadge.stories.tsx +51 -0
  192. package/src/stories/Toast.stories.tsx +71 -0
  193. package/src/styles/casino-ui-base.css +310 -0
  194. package/src/styles/toast.css +52 -0
  195. package/src/types.ts +11 -0
  196. package/src/utils/format-amount.ts +35 -0
@@ -0,0 +1,157 @@
1
+ import { cn } from "../lib/utils";
2
+
3
+ export type ResultType =
4
+ | "win"
5
+ | "lose"
6
+ | "bust"
7
+ | "push"
8
+ | "blackjack"
9
+ | "even"
10
+ | "surrender";
11
+
12
+ interface ResultBadgeProps {
13
+ type: ResultType;
14
+ amount?: string;
15
+ showPayout?: boolean;
16
+ assetIconUrl?: string | React.ReactNode;
17
+ isUSD?: boolean;
18
+ className?: string;
19
+ isMobile?: boolean;
20
+ isMobileSeat?: boolean;
21
+ }
22
+
23
+ const BADGE_STYLES: Record<
24
+ ResultType,
25
+ { border: string; text: string; bg: string; shadow?: string }
26
+ > = {
27
+ win: {
28
+ border: "border-[#8BB339]",
29
+ text: "text-[#8BB339]",
30
+ bg: "bg-[rgba(199,254,81,0.08)]",
31
+ },
32
+ lose: {
33
+ border: "border-[#DB375E]",
34
+ text: "text-[#DB375E]",
35
+ bg: "bg-[rgba(219,55,94,0.08)]",
36
+ },
37
+ bust: {
38
+ border: "border-[#DB375E]",
39
+ text: "text-[#DB375E]",
40
+ bg: "bg-[rgba(219,55,94,0.08)]",
41
+ },
42
+ push: {
43
+ border: "border-[#7454F0]",
44
+ text: "text-[#7454F0]",
45
+ bg: "bg-[#7454F0]/12",
46
+ },
47
+ blackjack: {
48
+ border: "border-[#FF5C05]",
49
+ text: "text-[#FF5C05]",
50
+ bg: "bg-[rgba(255,92,5,0.08)]",
51
+ shadow: "shadow-[0_0_5px_2px_rgba(255,92,5,0.6)]",
52
+ },
53
+ even: {
54
+ border: "border-[#7454F0]",
55
+ text: "text-[#7454F0]",
56
+ bg: "bg-[#7454F0]/12",
57
+ },
58
+ surrender: {
59
+ border: "border-[#8A8A8A]",
60
+ text: "text-[#8A8A8A]",
61
+ bg: "bg-[rgba(138,138,138,0.08)]",
62
+ },
63
+ };
64
+
65
+ const PAYOUT_TEXT_COLORS: Record<ResultType, string> = {
66
+ win: "text-[#8BB339]",
67
+ lose: "text-[#DB375E]",
68
+ bust: "text-[#DB375E]",
69
+ push: "text-[#BFBFBF]",
70
+ blackjack: "text-brand",
71
+ even: "text-[#7454F0]",
72
+ surrender: "text-[#BFBFBF]",
73
+ };
74
+
75
+ const LABELS: Record<ResultType, string> = {
76
+ win: "Win",
77
+ lose: "Lose",
78
+ bust: "Bust",
79
+ push: "Push",
80
+ blackjack: "Blackjack",
81
+ even: "Break Even",
82
+ surrender: "Surrender",
83
+ };
84
+
85
+ export function ResultBadge({
86
+ type,
87
+ amount = "0",
88
+ showPayout = false,
89
+ assetIconUrl,
90
+ isUSD = false,
91
+ className,
92
+ isMobile = false,
93
+ isMobileSeat = false,
94
+ }: ResultBadgeProps) {
95
+ const style = BADGE_STYLES[type];
96
+
97
+ return (
98
+ <div
99
+ className={cn(
100
+ "flex items-center justify-center border",
101
+ isMobile
102
+ ? isMobileSeat
103
+ ? "w-18.5 h-4.5 rounded-sm p-1"
104
+ : "w-18.5 h-5.5 rounded-sm px-1 py-1.5"
105
+ : "w-25 h-6.5 rounded-md p-1",
106
+ style.border,
107
+ style.bg,
108
+ style.shadow,
109
+ className,
110
+ )}
111
+ >
112
+ {showPayout ? (
113
+ <div className="flex items-center gap-1">
114
+ {isUSD ? (
115
+ <span
116
+ className={cn(
117
+ "text-xs ",
118
+ isMobile
119
+ ? "leading-2.5 font-semibold"
120
+ : "leading-3.5 font-bold",
121
+ PAYOUT_TEXT_COLORS[type],
122
+ )}
123
+ >
124
+ $
125
+ </span>
126
+ ) : assetIconUrl ? (
127
+ typeof assetIconUrl === "string" ? (
128
+ <img src={assetIconUrl} alt="" className="w-4 h-4" />
129
+ ) : (
130
+ <div className="w-4 h-4">{assetIconUrl}</div>
131
+ )
132
+ ) : null}
133
+ <span
134
+ className={cn(
135
+ "text-xs",
136
+ isMobile ? "leading-2.5 font-semibold" : "leading-3.5 font-bold",
137
+ PAYOUT_TEXT_COLORS[type],
138
+ )}
139
+ >
140
+ {amount}
141
+ </span>
142
+ </div>
143
+ ) : (
144
+ <span
145
+ className={cn(
146
+ isMobile
147
+ ? "text-xs leading-2.5"
148
+ : "text-sm leading-3.5 font-semibold",
149
+ style.text,
150
+ )}
151
+ >
152
+ {LABELS[type]}
153
+ </span>
154
+ )}
155
+ </div>
156
+ );
157
+ }
@@ -0,0 +1,211 @@
1
+ import { useState, useCallback } from "react";
2
+ import {
3
+ Dialog,
4
+ DialogClose,
5
+ DialogContent,
6
+ DialogFooter,
7
+ DialogHeader,
8
+ DialogTitle,
9
+ } from "./ui/dialog";
10
+ import {
11
+ Drawer,
12
+ DrawerClose,
13
+ DrawerContent,
14
+ DrawerFooter,
15
+ DrawerHeader,
16
+ DrawerTitle,
17
+ } from "./ui/drawer";
18
+ import { Icon } from "./icon";
19
+ import { Button } from "./button";
20
+ import { toast } from "./toast-helpers";
21
+
22
+ interface SwitchTableDialogProps {
23
+ open: boolean;
24
+ onOpenChange: (open: boolean) => void;
25
+ currentTableId: string;
26
+ onJoin: (tableIdOrLink: string) => void;
27
+ isMobile?: boolean;
28
+ }
29
+
30
+ function SwitchTableBody({
31
+ currentTableId,
32
+ inputValue,
33
+ onInputChange,
34
+ }: {
35
+ currentTableId: string;
36
+ inputValue: string;
37
+ onInputChange: (value: string) => void;
38
+ }) {
39
+ const [copied, setCopied] = useState(false);
40
+
41
+ const handleCopy = useCallback(async () => {
42
+ try {
43
+ await navigator.clipboard.writeText(currentTableId);
44
+ setCopied(true);
45
+ setTimeout(() => setCopied(false), 2000);
46
+ } catch {
47
+ toast.status.error("Failed to copy table ID");
48
+ }
49
+ }, [currentTableId]);
50
+
51
+ return (
52
+ <div className="w-full flex flex-col gap-3 px-5">
53
+ <div className="w-full flex items-center gap-2">
54
+ <span className="text-text-secondary text-sm">Current table ID:</span>
55
+ <span className="font-semibold text-white truncate w-40 text-sm">
56
+ {currentTableId}
57
+ </span>
58
+ <button
59
+ type="button"
60
+ onClick={handleCopy}
61
+ className="min-w-4 cursor-pointer text-text-secondary transition-colors hover:text-white"
62
+ >
63
+ {copied ? (
64
+ <Icon icon="check" className="size-4 text-accent-success" />
65
+ ) : (
66
+ <Icon icon="copy" className="size-4" />
67
+ )}
68
+ </button>
69
+ </div>
70
+
71
+ <input
72
+ type="text"
73
+ value={inputValue}
74
+ onChange={(e) => onInputChange(e.target.value)}
75
+ placeholder="Enter a table ID"
76
+ className="w-full rounded-xl border border-button-grey bg-surface-500 p-3 text-sm text-white placeholder:text-text-secondary outline-none focus:border-surface-200 ease-in-out duration-300"
77
+ />
78
+
79
+ <div className="flex items-center gap-2 text-xs text-text-secondary">
80
+ <Icon icon="info" className="size-4 shrink-0" />
81
+ <span>Leaving this table will end the current game.</span>
82
+ </div>
83
+ </div>
84
+ );
85
+ }
86
+
87
+ function SwitchTableFooter({
88
+ inputValue,
89
+ onCancel,
90
+ onJoin,
91
+ }: {
92
+ inputValue: string;
93
+ onCancel: () => void;
94
+ onJoin: () => void;
95
+ }) {
96
+ return (
97
+ <div className="w-full flex items-center gap-3">
98
+ <Button
99
+ variant="tertiary"
100
+ type="button"
101
+ onClick={onCancel}
102
+ className="w-full flex-1 min-w-0 h-10 rounded-xl"
103
+ >
104
+ Cancel
105
+ </Button>
106
+ <Button
107
+ variant="primary"
108
+ type="button"
109
+ onClick={onJoin}
110
+ disabled={!inputValue.trim()}
111
+ className="w-full flex-1 min-w-0 h-10 rounded-xl"
112
+ >
113
+ Join
114
+ </Button>
115
+ </div>
116
+ );
117
+ }
118
+
119
+ function SwitchTableDialog({
120
+ open,
121
+ onOpenChange,
122
+ currentTableId,
123
+ onJoin,
124
+ isMobile = false,
125
+ }: SwitchTableDialogProps) {
126
+ const [inputValue, setInputValue] = useState("");
127
+
128
+ const handleJoin = useCallback(() => {
129
+ const trimmed = inputValue.trim();
130
+
131
+ if (!trimmed) return;
132
+
133
+ const uuidRegex =
134
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
135
+ const isUuid = uuidRegex.test(trimmed);
136
+
137
+ if (!isUuid) {
138
+ toast.status.error("Invalid table ID");
139
+ return;
140
+ }
141
+
142
+ setInputValue("");
143
+ onOpenChange(false);
144
+ onJoin(trimmed);
145
+ }, [inputValue, onOpenChange, onJoin]);
146
+
147
+ const handleCancel = useCallback(() => {
148
+ setInputValue("");
149
+ onOpenChange(false);
150
+ }, [onOpenChange]);
151
+
152
+ if (isMobile) {
153
+ return (
154
+ <Drawer open={open} onOpenChange={onOpenChange}>
155
+ <DrawerContent className="rounded-t-xl overflow-clip bg-surface-400 border-none">
156
+ <DrawerHeader className="flex items-start justify-between p-5">
157
+ <DrawerTitle className="text-2xl font-bold text-left">
158
+ Switch Table
159
+ </DrawerTitle>
160
+ <DrawerClose className="min-w-6 cursor-pointer opacity-70 transition-opacity hover:opacity-100">
161
+ <Icon icon="x" className="size-6" />
162
+ </DrawerClose>
163
+ </DrawerHeader>
164
+
165
+ <SwitchTableBody
166
+ currentTableId={currentTableId}
167
+ inputValue={inputValue}
168
+ onInputChange={setInputValue}
169
+ />
170
+
171
+ <DrawerFooter className="border-t border-surface-300 bg-surface-450 px-5 pt-5 pb-6 mt-5">
172
+ <SwitchTableFooter
173
+ inputValue={inputValue}
174
+ onCancel={handleCancel}
175
+ onJoin={handleJoin}
176
+ />
177
+ </DrawerFooter>
178
+ </DrawerContent>
179
+ </Drawer>
180
+ );
181
+ }
182
+
183
+ return (
184
+ <Dialog open={open} onOpenChange={onOpenChange}>
185
+ <DialogContent className="w-100 rounded-xl overflow-clip bg-surface-400 gap-5">
186
+ <DialogHeader className="flex items-start justify-between px-5 pt-5">
187
+ <DialogTitle className="text-2xl font-bold">Switch Table</DialogTitle>
188
+ <DialogClose className="min-w-6 cursor-pointer opacity-70 transition-opacity hover:opacity-100">
189
+ <Icon icon="x" className="size-6" />
190
+ </DialogClose>
191
+ </DialogHeader>
192
+
193
+ <SwitchTableBody
194
+ currentTableId={currentTableId}
195
+ inputValue={inputValue}
196
+ onInputChange={setInputValue}
197
+ />
198
+
199
+ <DialogFooter className="border-t border-surface-300 bg-surface-450 px-5 pt-5 pb-6">
200
+ <SwitchTableFooter
201
+ inputValue={inputValue}
202
+ onCancel={handleCancel}
203
+ onJoin={handleJoin}
204
+ />
205
+ </DialogFooter>
206
+ </DialogContent>
207
+ </Dialog>
208
+ );
209
+ }
210
+
211
+ export default SwitchTableDialog;
@@ -0,0 +1,25 @@
1
+ import { ToastContainer, Zoom, type ToastPosition } from "react-toastify";
2
+ import "react-toastify/dist/ReactToastify.css";
3
+ import "../styles/toast.css";
4
+
5
+ export function CasinoToastContainer({
6
+ limit = 5,
7
+ position = "bottom-left",
8
+ }: {
9
+ limit?: number;
10
+ position?: ToastPosition;
11
+ } = {}) {
12
+ return (
13
+ <div className="casino-toast">
14
+ <ToastContainer
15
+ position={position}
16
+ limit={limit}
17
+ newestOnTop
18
+ pauseOnFocusLoss={false}
19
+ transition={Zoom}
20
+ draggable={false}
21
+ hideProgressBar
22
+ />
23
+ </div>
24
+ );
25
+ }
@@ -0,0 +1,79 @@
1
+ import { toast as toastify } from "react-toastify";
2
+ import {
3
+ EphemeralToast,
4
+ StatusToast,
5
+ ActionToast,
6
+ type ToastAction,
7
+ type EphemeralVariant,
8
+ type StatusVariant,
9
+ } from "./toast";
10
+ import React from "react";
11
+
12
+ function renderEphemeral(message: string, variant: EphemeralVariant) {
13
+ toastify(React.createElement(EphemeralToast, { message, variant }), {
14
+ autoClose: 2500,
15
+ closeButton: false,
16
+ closeOnClick: true,
17
+ });
18
+ }
19
+
20
+ function renderStatus(
21
+ message: string,
22
+ variant: StatusVariant,
23
+ opts?: { title?: string },
24
+ ) {
25
+ const toastId = toastify(
26
+ ({ closeToast }) =>
27
+ React.createElement(StatusToast, {
28
+ message,
29
+ variant,
30
+ title: opts?.title,
31
+ onClose: () => closeToast?.(),
32
+ }),
33
+ {
34
+ autoClose: 5000,
35
+ closeButton: false,
36
+ closeOnClick: false,
37
+ },
38
+ );
39
+ return toastId;
40
+ }
41
+
42
+ function renderAction(opts: {
43
+ title?: string;
44
+ message: string;
45
+ actions: ToastAction[];
46
+ }) {
47
+ const toastId = toastify(
48
+ ({ closeToast }) =>
49
+ React.createElement(ActionToast, {
50
+ message: opts.message,
51
+ title: opts.title,
52
+ actions: opts.actions,
53
+ onClose: () => closeToast?.(),
54
+ }),
55
+ {
56
+ autoClose: false,
57
+ closeButton: false,
58
+ closeOnClick: false,
59
+ },
60
+ );
61
+ return toastId;
62
+ }
63
+
64
+ export const toast = {
65
+ info: (message: string) => renderEphemeral(message, "info"),
66
+ success: (message: string) => renderEphemeral(message, "success"),
67
+
68
+ status: {
69
+ info: (message: string, opts?: { title?: string }) =>
70
+ renderStatus(message, "info", opts),
71
+ success: (message: string, opts?: { title?: string }) =>
72
+ renderStatus(message, "success", opts),
73
+ error: (message: string, opts?: { title?: string }) =>
74
+ renderStatus(message, "error", opts),
75
+ },
76
+
77
+ action: (opts: { title?: string; message: string; actions: ToastAction[] }) =>
78
+ renderAction(opts),
79
+ } as const;