@casinogate/ui 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,171 +1,967 @@
1
- # @cg/ui
1
+ # @casinogate/ui
2
2
 
3
- A modern, type-safe UI component library built with Svelte 5, TypeScript, and TailwindCSS. Designed for building beautiful, accessible, and performant user interfaces.
3
+ A modern, type-safe UI component library built with Svelte 5, TypeScript, and TailwindCSS. Designed for building beautiful, accessible, and performant user interfaces with a comprehensive theming system powered by CSS variables.
4
4
 
5
- ## Features
5
+ ## 🎨 [View Live Component Documentation](https://static.casinogate.dev/components/master/)
6
6
 
7
- - 🚀 **Svelte 5** - Built with the latest Svelte features including runes and modern APIs
7
+ Explore our complete component library, interactive examples, and design guidelines in Storybook.
8
+
9
+ ---
10
+
11
+ ## 📚 Table of Contents
12
+
13
+ - [Overview](#overview)
14
+ - [Installation](#-installation)
15
+ - [Quick Start](#-quick-start)
16
+ - [Theming with CSS Variables](#-theming-with-css-variables)
17
+ - [Understanding the Theming System](#understanding-the-theming-system)
18
+ - [How to Customize Your Theme](#how-to-customize-your-theme)
19
+ - [Dark Mode Support](#dark-mode-support)
20
+ - [Complete CSS Variables Reference](#-complete-css-variables-reference)
21
+ - [Color System](#color-system)
22
+ - [Typography](#typography)
23
+ - [Spacing & Layout](#spacing--layout)
24
+ - [Effects](#effects)
25
+ - [Integration Examples](#-integration-examples)
26
+ - [Component Usage](#-component-usage)
27
+ - [Development](#-development)
28
+ - [Contributing](#-contributing)
29
+
30
+ ---
31
+
32
+ ## Overview
33
+
34
+ **@casinogate/ui** is the shared component library for CasinoGate applications, providing:
35
+
36
+ - **🎯 Purpose**: Unified UI components across all CasinoGate products
37
+ - **📦 Where Used**: Web applications, admin panels, and customer-facing interfaces
38
+ - **🎨 Design System**: Complete design token system with CSS variables for full customization
39
+ - **♿ Accessibility**: WCAG 2.1 AA compliant components built on [bits-ui](https://bits-ui.com)
40
+ - **🚀 Performance**: Optimized for production with tree-shaking and minimal bundle size
41
+
42
+ ### Key Features
43
+
44
+ - ✨ **Svelte 5** - Built with the latest Svelte features including runes
8
45
  - 📝 **TypeScript** - Fully typed with comprehensive type definitions
9
- - 🎨 **TailwindCSS** - Utility-first styling with custom design tokens
10
- - **Accessible** - Built on top of [bits-ui](https://bits-ui.com) for robust accessibility
11
- - 🎭 **Variants** - Flexible styling with [tailwind-variants](https://www.tailwind-variants.org/)
12
- - 📚 **Storybook** - Comprehensive component documentation and examples
13
- - 🔧 **Developer-friendly** - Excellent IntelliSense and autocompletion support
46
+ - 🎨 **CSS Variables** - Complete theming control without rebuilding
47
+ - 🌓 **Dark Mode** - Built-in dark theme support
48
+ - 🎭 **Variants** - Flexible component styling with [tailwind-variants](https://www.tailwind-variants.org/)
49
+ - 📚 **Documented** - Comprehensive Storybook documentation
50
+ - 🔧 **Developer Experience** - Excellent IntelliSense and autocompletion
51
+
52
+ ---
14
53
 
15
54
  ## 📦 Installation
16
55
 
56
+ ### Using pnpm (Recommended)
57
+
58
+ ```bash
59
+ pnpm add @casinogate/ui
60
+ ```
61
+
62
+ ### Using npm
63
+
17
64
  ```bash
18
- # Using pnpm (recommended)
19
- pnpm add @cg/ui
65
+ npm install @casinogate/ui
66
+ ```
20
67
 
21
- # Using npm
22
- npm install @cg/ui
68
+ ### Using yarn
23
69
 
24
- # Using yarn
25
- yarn add @cg/ui
70
+ ```bash
71
+ yarn add @casinogate/ui
26
72
  ```
27
73
 
28
74
  ### Peer Dependencies
29
75
 
30
- Make sure you have Svelte 5 installed:
76
+ Ensure you have Svelte 5 installed:
31
77
 
32
78
  ```bash
33
- pnpm add svelte@^5.0.0
79
+ pnpm add svelte@^5.36.1
34
80
  ```
35
81
 
36
- ## 🎨 Styling & Customization
82
+ ---
83
+
84
+ ## 🚀 Quick Start
37
85
 
38
- ### Using Tailwind Variants
86
+ ### 1. Import Styles
39
87
 
40
- Components are built with `tailwind-variants` for powerful styling:
88
+ Import the CSS file in your root layout or main entry point:
41
89
 
42
90
  ```svelte
91
+ <!-- +layout.svelte or app.html -->
43
92
  <script>
44
- import { Button } from '@cg/ui';
45
-
46
- // Access the styles function directly
47
- const customButtonStyles = Button.styles({
48
- variant: 'primary',
49
- size: 'lg',
50
- // Override with custom classes
51
- class: 'my-custom-class',
93
+ import '@casinogate/ui/styles.css';
94
+ </script>
95
+ ```
96
+
97
+ ### 2. Use Components
98
+
99
+ ```svelte
100
+ <script lang="ts">
101
+ import { Button, Input, DataTable } from '@casinogate/ui';
102
+ </script>
103
+
104
+ <div class="app">
105
+ <Button variant="primary" size="lg">Click Me</Button>
106
+ <Input placeholder="Enter your name..." />
107
+ </div>
108
+ ```
109
+
110
+ ### 3. Customize Theme (Optional)
111
+
112
+ Override CSS variables to match your brand:
113
+
114
+ ```css
115
+ /* app.css or global stylesheet */
116
+ :root {
117
+ --cg-ui-primary-hue: 280; /* Purple theme */
118
+ --cg-ui-primary-saturation: 85%;
119
+ }
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 🎨 Theming with CSS Variables
125
+
126
+ ### Understanding the Theming System
127
+
128
+ The component library uses a **two-tier CSS variable system** for maximum flexibility:
129
+
130
+ #### 1. **Palette Variables** (Low-level)
131
+
132
+ Base color definitions in `:root` that you can override:
133
+
134
+ ```css
135
+ :root {
136
+ /* Control primary color palette */
137
+ --cg-ui-primary-hue: 220;
138
+ --cg-ui-primary-saturation: 80%;
139
+
140
+ /* These generate shades automatically */
141
+ --cg-ui-palette-primary-100: hsla(220, 80%, 38%, 1);
142
+ --cg-ui-palette-primary-80: hsla(220, 80%, 50%, 1);
143
+ --cg-ui-palette-primary-60: hsla(220, 80%, 64%, 1);
144
+ }
145
+ ```
146
+
147
+ #### 2. **Semantic Variables** (High-level)
148
+
149
+ Purpose-driven variables that reference palette colors:
150
+
151
+ ```css
152
+ @theme inline {
153
+ /* Components use semantic names */
154
+ --color-surface-primary: var(--cg-ui-palette-primary-80);
155
+ --color-fg-primary: var(--cg-ui-palette-primary-80);
156
+ --color-stroke-primary: var(--cg-ui-palette-primary-80);
157
+ }
158
+ ```
159
+
160
+ ### How to Customize Your Theme
161
+
162
+ #### Method 1: Override Hue & Saturation (Recommended)
163
+
164
+ Change just two variables to rebrand the entire interface:
165
+
166
+ ```css
167
+ /* Your global CSS file */
168
+ :root {
169
+ /* Change primary color to purple */
170
+ --cg-ui-primary-hue: 280;
171
+ --cg-ui-primary-saturation: 85%;
172
+
173
+ /* Change neutral gray tones */
174
+ --cg-ui-neutral-hue: 270;
175
+ --cg-ui-neutral-saturation: 15%;
176
+ }
177
+ ```
178
+
179
+ #### Method 2: Override Specific Palette Colors
180
+
181
+ For precise control over individual shades:
182
+
183
+ ```css
184
+ :root {
185
+ /* Override specific primary shades */
186
+ --cg-ui-palette-primary-100: #2d1b69;
187
+ --cg-ui-palette-primary-80: #4c2a9f;
188
+ --cg-ui-palette-primary-60: #7c5ac7;
189
+
190
+ /* Override system colors */
191
+ --cg-ui-palette-system-success-100: #00a86b;
192
+ --cg-ui-palette-system-error-100: #ff3b30;
193
+ }
194
+ ```
195
+
196
+ #### Method 3: Override Semantic Variables
197
+
198
+ Target specific component contexts:
199
+
200
+ ```css
201
+ :root {
202
+ /* Change button backgrounds without affecting other primary uses */
203
+ --color-surface-primary: #ff6b6b;
204
+ --color-surface-primary-active: #ff5252;
205
+
206
+ /* Customize form field borders */
207
+ --color-stroke-default: #d1d5db;
208
+ --color-stroke-focus: #3b82f6;
209
+ }
210
+ ```
211
+
212
+ #### Method 4: Scoped Theming
213
+
214
+ Apply different themes to specific sections:
215
+
216
+ ```css
217
+ /* Default theme */
218
+ :root {
219
+ --cg-ui-primary-hue: 220;
220
+ }
221
+
222
+ /* Special section with different branding */
223
+ .promotional-section {
224
+ --cg-ui-primary-hue: 340; /* Red theme */
225
+ --cg-ui-primary-saturation: 90%;
226
+ }
227
+ ```
228
+
229
+ ```svelte
230
+ <div class="promotional-section">
231
+ <!-- Buttons here will use the red theme -->
232
+ <Button variant="primary">Special Offer</Button>
233
+ </div>
234
+ ```
235
+
236
+ ### Dark Mode Support
237
+
238
+ The library includes a complete dark theme that activates with `.dark` class or `data-theme="dark"` attribute.
239
+
240
+ #### Method 1: Using Class Toggle
241
+
242
+ ```svelte
243
+ <script lang="ts">
244
+ import { Button } from '@casinogate/ui';
245
+ import '@casinogate/ui/styles.css';
246
+
247
+ let isDark = $state(false);
248
+
249
+ function toggleTheme() {
250
+ isDark = !isDark;
251
+ document.documentElement.classList.toggle('dark', isDark);
252
+ }
253
+ </script>
254
+
255
+ <body class:dark={isDark}>
256
+ <Button onclick={toggleTheme}>
257
+ {isDark ? '☀️ Light Mode' : '🌙 Dark Mode'}
258
+ </Button>
259
+ </body>
260
+ ```
261
+
262
+ #### Method 2: Using Data Attribute
263
+
264
+ ```svelte
265
+ <script lang="ts">
266
+ let theme = $state<'light' | 'dark'>('light');
267
+
268
+ function toggleTheme() {
269
+ theme = theme === 'light' ? 'dark' : 'light';
270
+ document.documentElement.setAttribute('data-theme', theme);
271
+ }
272
+ </script>
273
+
274
+ <html data-theme={theme}>
275
+ <!-- Your app -->
276
+ </html>
277
+ ```
278
+
279
+ #### Method 3: Respecting System Preference
280
+
281
+ ```svelte
282
+ <script lang="ts">
283
+ import { onMount } from 'svelte';
284
+
285
+ onMount(() => {
286
+ const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
287
+ document.documentElement.classList.toggle('dark', isDark);
288
+
289
+ // Listen for system changes
290
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
291
+ document.documentElement.classList.toggle('dark', e.matches);
292
+ });
52
293
  });
53
294
  </script>
295
+ ```
296
+
297
+ #### Customizing Dark Mode Colors
54
298
 
55
- <button class={customButtonStyles.root()}> Custom Styled Button </button>
299
+ Override dark theme colors specifically:
300
+
301
+ ```css
302
+ .dark,
303
+ [data-theme='dark'] {
304
+ /* Custom dark mode primary color */
305
+ --cg-ui-primary-hue: 160; /* Teal in dark mode */
306
+ --cg-ui-primary-saturation: 80%;
307
+
308
+ /* Adjust neutral darkness */
309
+ --cg-ui-palette-neutral-100: hsla(220, 50%, 5%, 1);
310
+ --cg-ui-palette-neutral-80: hsla(220, 50%, 10%, 1);
311
+ }
56
312
  ```
57
313
 
58
- ### CSS Custom Properties
314
+ ---
315
+
316
+ ## 📋 Complete CSS Variables Reference
317
+
318
+ ### Color System
319
+
320
+ #### Primary Colors
321
+
322
+ Control the main brand color used throughout the interface.
323
+
324
+ | Variable | Default (Light) | Dark Mode | Description |
325
+ | ----------------------------- | ------------------------ | ------------------------ | ------------------------- |
326
+ | `--cg-ui-primary-hue` | `220` | `160` | Primary color hue (0-360) |
327
+ | `--cg-ui-primary-saturation` | `80%` | `80%` | Primary color saturation |
328
+ | `--cg-ui-palette-primary-100` | `hsla(220, 80%, 38%, 1)` | `hsla(160, 80%, 28%, 1)` | Darkest primary shade |
329
+ | `--cg-ui-palette-primary-80` | `hsla(220, 80%, 50%, 1)` | `hsla(160, 80%, 40%, 1)` | Standard primary color |
330
+ | `--cg-ui-palette-primary-60` | `hsla(220, 80%, 64%, 1)` | `hsla(160, 80%, 64%, 1)` | Light primary shade |
331
+ | `--cg-ui-palette-primary-40` | `hsla(220, 80%, 94%, 1)` | `hsla(160, 80%, 94%, 1)` | Very light primary |
332
+ | `--cg-ui-palette-primary-10` | `hsla(220, 80%, 97%, 1)` | `hsla(160, 80%, 97%, 1)` | Subtlest primary tint |
333
+
334
+ **Usage in components:** Buttons, links, focus states, active selections
335
+
336
+ #### Neutral Colors
337
+
338
+ Grayscale palette for text, borders, backgrounds, and UI elements.
59
339
 
60
- Components support CSS custom properties for theming:
340
+ | Variable | Default (Light) | Dark Mode | Description |
341
+ | ----------------------------- | ------------------------ | ------------------------ | ----------------------------- |
342
+ | `--cg-ui-neutral-hue` | `230` | `225` | Neutral color hue |
343
+ | `--cg-ui-neutral-saturation` | `20%` | `50%` | Neutral color saturation |
344
+ | `--cg-ui-palette-neutral-100` | `hsla(230, 20%, 12%, 1)` | `hsla(225, 50%, 8%, 1)` | Darkest gray (text) |
345
+ | `--cg-ui-palette-neutral-80` | `hsla(230, 20%, 20%, 1)` | `hsla(225, 50%, 12%, 1)` | Dark gray |
346
+ | `--cg-ui-palette-neutral-60` | `hsla(230, 20%, 40%, 1)` | `hsla(225, 50%, 16%, 1)` | Medium gray |
347
+ | `--cg-ui-palette-neutral-50` | `hsla(230, 20%, 58%, 1)` | `hsla(225, 50%, 28%, 1)` | Mid-tone gray |
348
+ | `--cg-ui-palette-neutral-40` | `hsla(230, 20%, 78%, 1)` | Fixed | Light gray (borders) |
349
+ | `--cg-ui-palette-neutral-20` | `hsla(230, 20%, 95%, 1)` | Fixed | Very light gray (backgrounds) |
350
+ | `--cg-ui-palette-neutral-10` | `hsla(230, 20%, 98%, 1)` | Fixed | Subtlest gray |
351
+ | `--cg-ui-palette-neutral-0` | `hsla(0, 0%, 100%, 1)` | Fixed | Pure white |
352
+ | `--cg-ui-palette-neutral-01` | `hsla(0, 0%, 100%, 0.1)` | Fixed | Transparent white overlay |
353
+
354
+ **Usage in components:** Text, borders, dividers, card backgrounds, disabled states
355
+
356
+ #### System Colors
357
+
358
+ Semantic colors for states and notifications.
359
+
360
+ ##### Error Colors
361
+
362
+ | Variable | Default | Description |
363
+ | ---------------------------------- | ----------------------- | --------------------- |
364
+ | `--cg-ui-palette-system-error-100` | `hsla(2, 100%, 40%, 1)` | Error text and icons |
365
+ | `--cg-ui-palette-system-error-10` | `hsla(3, 67%, 93%, 1)` | Error background tint |
366
+
367
+ ##### Warning Colors
368
+
369
+ | Variable | Default (Light) | Dark Mode | Description |
370
+ | ------------------------------------ | ------------------------ | ----------------------- | ----------------------- |
371
+ | `--cg-ui-palette-system-warning-100` | `hsla(52, 100%, 50%, 1)` | `hsla(32, 98%, 40%, 1)` | Warning text and icons |
372
+ | `--cg-ui-palette-system-warning-10` | `hsla(18, 88%, 94%, 1)` | `hsla(18, 88%, 94%, 1)` | Warning background tint |
373
+
374
+ ##### Success Colors
375
+
376
+ | Variable | Default | Description |
377
+ | ------------------------------------ | ------------------------- | ----------------------- |
378
+ | `--cg-ui-palette-system-success-100` | `hsla(162, 100%, 25%, 1)` | Success text and icons |
379
+ | `--cg-ui-palette-system-success-10` | `hsla(162, 64%, 94%, 1)` | Success background tint |
380
+
381
+ ##### Info Colors
382
+
383
+ | Variable | Default | Description |
384
+ | --------------------------------- | ------------------------ | -------------------- |
385
+ | `--cg-ui-palette-system-info-100` | `hsla(232, 22%, 29%, 1)` | Info text and icons |
386
+ | `--cg-ui-palette-system-info-10` | `hsla(240, 12%, 93%, 1)` | Info background tint |
387
+
388
+ **Usage in components:** Alerts, toasts, validation messages, status badges
389
+
390
+ #### Semantic Color Variables
391
+
392
+ Purpose-driven variables used directly by components (defined in `@theme inline`).
393
+
394
+ ##### Surface Colors (Backgrounds)
395
+
396
+ | Variable | References | Description |
397
+ | -------------------------------------- | ----------------------------- | ---------------------------- |
398
+ | `--color-surface-primary` | `--cg-ui-palette-primary-80` | Primary button background |
399
+ | `--color-surface-primary-active` | `--cg-ui-palette-primary-60` | Primary button hover/active |
400
+ | `--color-surface-primary-light` | `--cg-ui-palette-primary-40` | Light primary surface |
401
+ | `--color-surface-primary-light-active` | `--cg-ui-palette-primary-10` | Light primary surface active |
402
+ | `--color-surface-darkest` | `--cg-ui-palette-neutral-100` | Darkest surface |
403
+ | `--color-surface-dark` | `--cg-ui-palette-neutral-80` | Dark surface |
404
+ | `--color-surface-regular` | `--cg-ui-palette-neutral-50` | Regular surface |
405
+ | `--color-surface-semilight` | `--cg-ui-palette-neutral-40` | Semi-light surface |
406
+ | `--color-surface-light` | `--cg-ui-palette-neutral-20` | Light surface (cards) |
407
+ | `--color-surface-lightest` | `--cg-ui-palette-neutral-10` | Lightest surface |
408
+ | `--color-surface-white` | `--cg-ui-palette-neutral-0` | White surface |
409
+ | `--color-surface-hover` | `--cg-ui-palette-neutral-01` | Hover overlay |
410
+
411
+ ##### Background Colors (Page-level)
412
+
413
+ | Variable | References | Description |
414
+ | ------------------ | ----------------------------- | -------------------- |
415
+ | `--color-bg-white` | `--cg-ui-palette-neutral-0` | White background |
416
+ | `--color-bg-main` | `--cg-ui-palette-neutral-20` | Main page background |
417
+ | `--color-bg-dark` | `--cg-ui-palette-neutral-100` | Dark background |
418
+
419
+ ##### Foreground Colors (Text)
420
+
421
+ | Variable | References | Description |
422
+ | ---------------------- | ------------------------------------ | -------------------- |
423
+ | `--color-fg-darkest` | `--cg-ui-palette-neutral-100` | Primary text color |
424
+ | `--color-fg-dark` | `--cg-ui-palette-neutral-80` | Dark text |
425
+ | `--color-fg-medium` | `--cg-ui-palette-neutral-60` | Medium text |
426
+ | `--color-fg-regular` | `--cg-ui-palette-neutral-50` | Regular text |
427
+ | `--color-fg-semilight` | `--cg-ui-palette-neutral-40` | Light text |
428
+ | `--color-fg-primary` | `--cg-ui-palette-primary-80` | Primary colored text |
429
+ | `--color-fg-white` | `--cg-ui-palette-neutral-0` | White text |
430
+ | `--color-fg-error` | `--cg-ui-palette-system-error-100` | Error text |
431
+ | `--color-fg-success` | `--cg-ui-palette-system-success-100` | Success text |
432
+
433
+ ##### Stroke Colors (Borders)
434
+
435
+ | Variable | References | Description |
436
+ | ------------------------ | ---------------------------------- | -------------------- |
437
+ | `--color-stroke-default` | `--cg-ui-palette-neutral-40` | Default border color |
438
+ | `--color-stroke-minimum` | `--cg-ui-palette-neutral-10` | Minimal border |
439
+ | `--color-stroke-focus` | `--cg-ui-palette-primary-60` | Focus ring border |
440
+ | `--color-stroke-primary` | `--cg-ui-palette-primary-80` | Primary border |
441
+ | `--color-stroke-divider` | `--cg-ui-palette-neutral-20` | Divider lines |
442
+ | `--color-stroke-error` | `--cg-ui-palette-system-error-100` | Error border |
443
+
444
+ ##### Icon Colors
445
+
446
+ | Variable | References | Description |
447
+ | ---------------------- | ---------------------------- | ------------------ |
448
+ | `--color-icon-regular` | `--cg-ui-palette-neutral-50` | Regular icon color |
449
+ | `--color-icon-default` | `--cg-ui-palette-neutral-40` | Default icon color |
450
+ | `--color-icon-primary` | `--cg-ui-palette-primary-80` | Primary icon color |
451
+ | `--color-icon-focus` | `--cg-ui-palette-primary-60` | Focused icon color |
452
+ | `--color-icon-white` | `--cg-ui-palette-neutral-0` | White icon |
453
+
454
+ ##### State Colors
455
+
456
+ | Variable | References | Description |
457
+ | ----------------------------- | ------------------------------------ | ------------------ |
458
+ | `--color-state-error` | `--cg-ui-palette-system-error-100` | Error state |
459
+ | `--color-state-error-light` | `--cg-ui-palette-system-error-10` | Error background |
460
+ | `--color-state-warning` | `--cg-ui-palette-system-warning-100` | Warning state |
461
+ | `--color-state-warning-light` | `--cg-ui-palette-system-warning-10` | Warning background |
462
+ | `--color-state-success` | `--cg-ui-palette-system-success-100` | Success state |
463
+ | `--color-state-success-light` | `--cg-ui-palette-system-success-10` | Success background |
464
+ | `--color-state-info` | `--cg-ui-palette-system-info-100` | Info state |
465
+ | `--color-state-info-light` | `--cg-ui-palette-system-info-10` | Info background |
466
+
467
+ ### Typography
468
+
469
+ Font sizes and line heights defined relative to a base size of 16px.
470
+
471
+ | Variable | Default | Computed Value | Description |
472
+ | ---------------------- | ---------------------- | ----------------- | ----------------------------- |
473
+ | `--cg-ui-fz-base` | `16` | — | Base font size multiplier |
474
+ | `--cg-ui-fz-heading` | `calc(16 / 16 * 1rem)` | `1rem` (16px) | Heading font size |
475
+ | `--cg-ui-lh-heading` | `calc(22 / 16 * 1rem)` | `1.375rem` (22px) | Heading line height |
476
+ | `--cg-ui-fz-heading-2` | `calc(16 / 16 * 1rem)` | `1rem` (16px) | Secondary heading size |
477
+ | `--cg-ui-lh-heading-2` | `calc(18 / 16 * 1rem)` | `1.125rem` (18px) | Secondary heading line height |
478
+ | `--cg-ui-fz-body` | `calc(14 / 16 * 1rem)` | `0.875rem` (14px) | Body text size |
479
+ | `--cg-ui-lh-body` | `calc(18 / 16 * 1rem)` | `1.125rem` (18px) | Body line height |
480
+ | `--cg-ui-fz-body-2` | `calc(14 / 16 * 1rem)` | `0.875rem` (14px) | Secondary body size |
481
+ | `--cg-ui-lh-body-2` | `calc(16 / 16 * 1rem)` | `1rem` (16px) | Secondary body line height |
482
+ | `--cg-ui-fz-caption` | `calc(12 / 16 * 1rem)` | `0.75rem` (12px) | Caption text size |
483
+ | `--cg-ui-lh-caption` | `calc(18 / 16 * 1rem)` | `1.125rem` (18px) | Caption line height |
484
+ | `--cg-ui-fz-caption-2` | `calc(12 / 16 * 1rem)` | `0.75rem` (12px) | Secondary caption size |
485
+ | `--cg-ui-lh-caption-2` | `calc(16 / 16 * 1rem)` | `1rem` (16px) | Secondary caption line height |
486
+
487
+ **Semantic Typography Variables** (for component use)
488
+
489
+ | Variable | References | Usage |
490
+ | ------------------------------- | ---------------------- | ------------------------------ |
491
+ | `--text-heading` | `--cg-ui-fz-heading` | Headings font size |
492
+ | `--text-heading--line-height` | `--cg-ui-lh-heading` | Headings line height |
493
+ | `--text-heading-2` | `--cg-ui-fz-heading-2` | Secondary headings |
494
+ | `--text-heading-2--line-height` | `--cg-ui-lh-heading-2` | Secondary headings line height |
495
+ | `--text-body` | `--cg-ui-fz-body` | Body text |
496
+ | `--text-body--line-height` | `--cg-ui-lh-body` | Body line height |
497
+ | `--text-body-2` | `--cg-ui-fz-body-2` | Secondary body text |
498
+ | `--text-body-2--line-height` | `--cg-ui-lh-body-2` | Secondary body line height |
499
+ | `--text-caption` | `--cg-ui-fz-caption` | Captions |
500
+ | `--text-caption--line-height` | `--cg-ui-lh-caption` | Caption line height |
501
+ | `--text-caption-2` | `--cg-ui-fz-caption-2` | Secondary captions |
502
+ | `--text-caption-2--line-height` | `--cg-ui-lh-caption-2` | Secondary caption line height |
503
+
504
+ ### Spacing & Layout
505
+
506
+ #### Base Numbers
507
+
508
+ Foundation spacing values used to generate other measurements.
509
+
510
+ | Variable | Value (px) | Description |
511
+ | --------------------- | ---------- | --------------------- |
512
+ | `--cg-ui-number-null` | `0` | Zero spacing |
513
+ | `--cg-ui-number-xxxs` | `2` | 2px |
514
+ | `--cg-ui-number-xxs` | `4` | 4px |
515
+ | `--cg-ui-number-xs` | `6` | 6px |
516
+ | `--cg-ui-number-sm` | `8` | 8px |
517
+ | `--cg-ui-number-md` | `12` | 12px |
518
+ | `--cg-ui-number-lg` | `16` | 16px |
519
+ | `--cg-ui-number-xl` | `20` | 20px |
520
+ | `--cg-ui-number-2xl` | `24` | 24px |
521
+ | `--cg-ui-number-xxl` | `40` | 40px |
522
+ | `--cg-ui-number-2xxl` | `48` | 48px |
523
+ | `--cg-ui-number-max` | `360` | Maximum value (360px) |
524
+
525
+ #### Border Radius
526
+
527
+ | Variable | Formula | Computed | Usage |
528
+ | --------------- | ----------------- | -------- | ---------------- |
529
+ | `--radius-null` | `calc(0 * 1px)` | `0px` | No rounding |
530
+ | `--radius-xxxs` | `calc(2 * 1px)` | `2px` | Minimal rounding |
531
+ | `--radius-xxs` | `calc(4 * 1px)` | `4px` | Very small |
532
+ | `--radius-xs` | `calc(6 * 1px)` | `6px` | Small |
533
+ | `--radius-sm` | `calc(8 * 1px)` | `8px` | Default buttons |
534
+ | `--radius-md` | `calc(12 * 1px)` | `12px` | Cards, panels |
535
+ | `--radius-lg` | `calc(16 * 1px)` | `16px` | Large cards |
536
+ | `--radius-xl` | `calc(20 * 1px)` | `20px` | Extra large |
537
+ | `--radius-2xl` | `calc(24 * 1px)` | `24px` | Very round |
538
+ | `--radius-xxl` | `calc(40 * 1px)` | `40px` | Super round |
539
+ | `--radius-2xxl` | `calc(48 * 1px)` | `48px` | Maximum rounding |
540
+ | `--radius-max` | `calc(360 * 1px)` | `360px` | Pill shape |
541
+
542
+ #### Breakpoints
543
+
544
+ Responsive design breakpoints for media queries.
545
+
546
+ | Variable | Value | Device Target |
547
+ | ------------------------- | -------- | ----------------------------- |
548
+ | `--breakpoint-phone-sm` | `320px` | Small phones |
549
+ | `--breakpoint-phone` | `375px` | Standard phones |
550
+ | `--breakpoint-phone-lg` | `425px` | Large phones |
551
+ | `--breakpoint-tablet-sm` | `640px` | Small tablets |
552
+ | `--breakpoint-tablet` | `768px` | Standard tablets |
553
+ | `--breakpoint-tablet-lg` | `1024px` | Large tablets / small laptops |
554
+ | `--breakpoint-desktop-sm` | `1280px` | Small desktops |
555
+ | `--breakpoint-desktop` | `1440px` | Standard desktops |
556
+ | `--breakpoint-desktop-lg` | `1920px` | Large desktops |
557
+
558
+ ### Effects
559
+
560
+ #### Shadows
561
+
562
+ | Variable | Value | Usage |
563
+ | ----------------------------- | --------------------------------------- | --------------------- |
564
+ | `--cg-ui-shadow-toast` | `0px 0px 8px 0px hsla(0, 0%, 0%, 0.2)` | Toast notifications |
565
+ | `--cg-ui-shadow-switch-thumb` | `0px 1px 1px 0px hsla(0, 0%, 0%, 0.25)` | Switch toggle thumb |
566
+ | `--cg-ui-shadow-segment-item` | `0px 0px 4px 0px hsla(0, 0%, 0%, 0.1)` | Segment control items |
567
+
568
+ ##### Semantic Shadow Variables
569
+
570
+ | Variable | References | Usage |
571
+ | ------------------------ | ----------------------------- | ----------------- |
572
+ | `--shadow-toast` | `--cg-ui-shadow-toast` | Toast component |
573
+ | `--shadow-switch-thumb` | `--cg-ui-shadow-switch-thumb` | Switch component |
574
+ | `--shadow-segment-thumb` | `--cg-ui-shadow-segment-item` | Segment component |
575
+
576
+ #### Blur Effects
577
+
578
+ | Variable | Formula | Computed | Usage |
579
+ | ------------ | ---------------- | -------- | ---------------- |
580
+ | `--blur-xxs` | `calc(4 * 1px)` | `4px` | Minimal blur |
581
+ | `--blur-xs` | `calc(6 * 1px)` | `6px` | Extra small blur |
582
+ | `--blur-sm` | `calc(8 * 1px)` | `8px` | Small blur |
583
+ | `--blur-md` | `calc(12 * 1px)` | `12px` | Medium blur |
584
+ | `--blur-lg` | `calc(16 * 1px)` | `16px` | Large blur |
585
+ | `--blur-xl` | `calc(20 * 1px)` | `20px` | Extra large blur |
586
+ | `--blur-2xl` | `calc(24 * 1px)` | `24px` | Maximum blur |
587
+
588
+ ---
589
+
590
+ ## 💡 Integration Examples
591
+
592
+ ### Example 1: Basic Brand Customization
61
593
 
62
594
  ```css
595
+ /* styles/theme.css */
63
596
  :root {
64
- --color-primary: #3b82f6;
65
- --color-secondary: #6b7280;
66
- /* Override default colors */
597
+ /* Rebrand to purple */
598
+ --cg-ui-primary-hue: 280;
599
+ --cg-ui-primary-saturation: 85%;
600
+
601
+ /* Adjust border roundness */
602
+ --cg-ui-number-sm: 12; /* Makes buttons more rounded */
67
603
  }
68
604
  ```
69
605
 
70
- ### Custom Classes
606
+ ```svelte
607
+ <!-- App.svelte -->
608
+ <script lang="ts">
609
+ import { Button } from '@casinogate/ui';
610
+ import '@casinogate/ui/styles.css';
611
+ import './styles/theme.css';
612
+ </script>
613
+
614
+ <Button variant="primary">Branded Button</Button>
615
+ ```
616
+
617
+ ### Example 2: Component-Specific Overrides
618
+
619
+ ```svelte
620
+ <script lang="ts">
621
+ import { Button, Card } from '@casinogate/ui';
622
+ </script>
623
+
624
+ <div class="custom-section">
625
+ <Card>
626
+ <h2>Special Offer</h2>
627
+ <Button variant="primary">Claim Now</Button>
628
+ </Card>
629
+ </div>
630
+
631
+ <style>
632
+ .custom-section {
633
+ /* Override just for this section */
634
+ --color-surface-primary: #ff6b6b;
635
+ --color-surface-primary-active: #ff5252;
636
+ --radius-sm: 16px;
637
+ }
638
+ </style>
639
+ ```
640
+
641
+ ### Example 3: Dynamic Theme Switching
642
+
643
+ ```svelte
644
+ <script lang="ts">
645
+ import { Button } from '@casinogate/ui';
646
+
647
+ type Theme = 'blue' | 'purple' | 'green';
648
+
649
+ let currentTheme = $state<Theme>('blue');
650
+
651
+ const themes = {
652
+ blue: { hue: 220, sat: 80 },
653
+ purple: { hue: 280, sat: 85 },
654
+ green: { hue: 160, sat: 80 },
655
+ };
656
+
657
+ function applyTheme(theme: Theme) {
658
+ const { hue, sat } = themes[theme];
659
+ document.documentElement.style.setProperty('--cg-ui-primary-hue', String(hue));
660
+ document.documentElement.style.setProperty('--cg-ui-primary-saturation', `${sat}%`);
661
+ currentTheme = theme;
662
+ }
663
+ </script>
664
+
665
+ <div>
666
+ <h2>Select Theme</h2>
667
+ <Button onclick={() => applyTheme('blue')}>Blue</Button>
668
+ <Button onclick={() => applyTheme('purple')}>Purple</Button>
669
+ <Button onclick={() => applyTheme('green')}>Green</Button>
670
+ </div>
671
+ ```
71
672
 
72
- Add custom classes using the `class` prop:
673
+ ### Example 4: CSS-in-JS with Inline Styles
73
674
 
74
675
  ```svelte
75
- <Button class="my-4 transition-transform hover:scale-105">Custom Button</Button>
676
+ <script lang="ts">
677
+ import { DataTable } from '@casinogate/ui';
678
+
679
+ const customColors = {
680
+ '--color-surface-light': '#f0f9ff',
681
+ '--color-stroke-default': '#bae6fd',
682
+ '--radius-md': '12px',
683
+ };
684
+ </script>
685
+
686
+ <div
687
+ style={Object.entries(customColors)
688
+ .map(([k, v]) => `${k}:${v}`)
689
+ .join(';')}
690
+ >
691
+ <DataTable {table} />
692
+ </div>
693
+ ```
694
+
695
+ ---
696
+
697
+ ## 📦 Component Usage
698
+
699
+ ### Available Components
700
+
701
+ ```typescript
702
+ import {
703
+ // Form Controls
704
+ Button,
705
+ Input,
706
+ Checkbox,
707
+ Switch,
708
+ Select,
709
+
710
+ // Data Display
711
+ DataTable,
712
+ DataTablePrimitive,
713
+
714
+ // Navigation
715
+ Pagination,
716
+ Segment,
717
+
718
+ // Feedback
719
+ Toast,
720
+ Spinner,
721
+ Skeleton,
722
+
723
+ // Layout
724
+ Collapsible,
725
+
726
+ // Icons
727
+ Icons, // All icon components
728
+ } from '@casinogate/ui';
76
729
  ```
77
730
 
731
+ ### Component Documentation
732
+
733
+ Each component has detailed documentation in Storybook:
734
+
735
+ - **Interactive Examples**: [View in Storybook](https://static.casinogate.dev/components/master/)
736
+ - **Props API**: TypeScript definitions with JSDoc
737
+ - **Variants**: All available style variants
738
+ - **Accessibility**: ARIA attributes and keyboard support
739
+
740
+ ### Example: Button Component
741
+
742
+ ```svelte
743
+ <script lang="ts">
744
+ import { Button } from '@casinogate/ui';
745
+ </script>
746
+
747
+ <!-- Variants -->
748
+ <Button variant="primary">Primary</Button>
749
+ <Button variant="secondary">Secondary</Button>
750
+ <Button variant="outline">Outline</Button>
751
+ <Button variant="ghost">Ghost</Button>
752
+
753
+ <!-- Sizes -->
754
+ <Button size="sm">Small</Button>
755
+ <Button size="md">Medium</Button>
756
+ <Button size="lg">Large</Button>
757
+
758
+ <!-- Custom styling -->
759
+ <Button class="custom-class" style="--color-surface-primary: #ff6b6b;">Custom Color</Button>
760
+ ```
761
+
762
+ ### Example: DataTable Component
763
+
764
+ See the complete [DataTable Guide](./src/components/data-table/README.md) for advanced usage.
765
+
766
+ ```svelte
767
+ <script lang="ts">
768
+ import { DataTable, createTable, rowModels } from '@casinogate/ui';
769
+ import type { ColumnDef } from '@casinogate/ui';
770
+
771
+ type User = {
772
+ id: number;
773
+ name: string;
774
+ email: string;
775
+ };
776
+
777
+ const data: User[] = [
778
+ { id: 1, name: 'John Doe', email: 'john@example.com' },
779
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
780
+ ];
781
+
782
+ const columns: ColumnDef<User>[] = [
783
+ { accessorKey: 'id', header: 'ID' },
784
+ { accessorKey: 'name', header: 'Name' },
785
+ { accessorKey: 'email', header: 'Email' },
786
+ ];
787
+
788
+ const table = createTable({
789
+ get data() {
790
+ return data;
791
+ },
792
+ columns,
793
+ getCoreRowModel: rowModels.coreRowModel(),
794
+ });
795
+ </script>
796
+
797
+ <DataTable {table} />
798
+ ```
799
+
800
+ ---
801
+
78
802
  ## 🔧 Development
79
803
 
80
804
  ### Prerequisites
81
805
 
82
- - Node.js >= 22.14.0
83
- - pnpm >= 9.5.0
806
+ - **Node.js**: >= 22.14.0
807
+ - **pnpm**: >= 9.5.0
84
808
 
85
809
  ### Setup
86
810
 
87
811
  ```bash
88
- # Clone and install dependencies
812
+ # Clone the repository
89
813
  git clone <repo-url>
90
814
  cd cg-components/packages/cg-ui
815
+
816
+ # Install dependencies
91
817
  pnpm install
92
818
  ```
93
819
 
94
820
  ### Available Scripts
95
821
 
96
- ```bash
97
- # Development
98
- pnpm dev # Start development server
99
- pnpm storybook # Start Storybook
100
-
101
- # Building
102
- pnpm build # Build the library
103
- pnpm prepack # Prepare for publishing
104
-
105
- # Quality Assurance
106
- pnpm check # Type checking
107
- pnpm check:watch # Type checking in watch mode
108
- pnpm lint # Lint code
109
- pnpm format # Format code
110
-
111
- # Documentation
112
- pnpm build-storybook # Build Storybook for deployment
113
- ```
822
+ | Command | Description |
823
+ | ---------------------- | ---------------------------------- |
824
+ | `pnpm dev` | Start development server with HMR |
825
+ | `pnpm build` | Build library for production |
826
+ | `pnpm storybook` | Start Storybook on port 6006 |
827
+ | `pnpm build-storybook` | Build static Storybook site |
828
+ | `pnpm check` | Run TypeScript type checking |
829
+ | `pnpm check:watch` | Type checking in watch mode |
830
+ | `pnpm lint` | Lint code with ESLint and Prettier |
831
+ | `pnpm format` | Format code with Prettier |
832
+ | `pnpm prepack` | Prepare package for publishing |
114
833
 
115
834
  ### Project Structure
116
835
 
117
- ```
836
+ ```text
118
837
  packages/cg-ui/
119
838
  ├── src/
120
839
  │ ├── components/ # UI components
121
- │ │ └── button/
122
- │ │ ├── button.component.svelte
123
- │ │ └── index.ts
840
+ │ │ ├── button/
841
+ │ │ ├── data-table/
842
+ │ │ └── ...
843
+ │ ├── assets/
844
+ │ │ └── css/
845
+ │ │ ├── root.css # Main entry point
846
+ │ │ └── theme.css # CSS variables
124
847
  │ ├── internal/ # Internal utilities
125
- │ │ ├── types/ # TypeScript type definitions
126
- │ │ └── utils/ # Utility functions
127
- │ ├── stories/ # Storybook stories
128
- │ ├── assets/ # CSS and static assets
848
+ │ │ ├── types/ # TypeScript definitions
849
+ │ │ └── utils/ # Helper functions
129
850
  │ └── index.ts # Main export file
130
851
  ├── dist/ # Built output (generated)
131
- ├── build/ # SvelteKit build output
852
+ ├── components/ # Compiled components
853
+ │ └── assets/
854
+ │ └── css/
855
+ │ └── root.css # Bundled CSS
132
856
  └── storybook-static/ # Built Storybook (generated)
133
857
  ```
134
858
 
135
- ## 📚 Documentation
136
-
137
- - **Storybook**: Run `pnpm storybook` to explore components interactively
138
- - **Type Definitions**: Comprehensive TypeScript definitions included
139
- - **Examples**: Check the `src/stories/` directory for usage examples
859
+ ---
140
860
 
141
861
  ## 🤝 Contributing
142
862
 
143
- 1. **Create a new component** in `src/components/`
144
- 2. **Add TypeScript types** and exports
145
- 3. **Create Storybook stories** in `src/stories/`
146
- 4. **Write tests** (coming soon)
147
- 5. **Update documentation**
863
+ ### Adding a New Component
864
+
865
+ 1. **Create component directory**
866
+
867
+ ```bash
868
+ mkdir -p src/components/my-component
869
+ ```
870
+
871
+ 2. **Create component files**
872
+
873
+ ```text
874
+ src/components/my-component/
875
+ ├── my-component.svelte # Main component
876
+ ├── my-component.stories.svelte # Storybook stories
877
+ ├── index.ts # Exports
878
+ └── README.md # Documentation (optional)
879
+ ```
880
+
881
+ 3. **Export from main index**
882
+
883
+ ```typescript
884
+ // src/index.ts
885
+ export { default as MyComponent } from './components/my-component/my-component.svelte';
886
+ ```
887
+
888
+ 4. **Add to Storybook**
889
+
890
+ Create stories showcasing all variants and use cases.
891
+
892
+ ### Component Guidelines
893
+
894
+ - ✅ **Accessibility First**: Use bits-ui primitives when available
895
+ - ✅ **Type Safety**: Provide comprehensive TypeScript definitions
896
+ - ✅ **CSS Variables**: Use semantic variables, not hardcoded colors
897
+ - ✅ **Documentation**: Add Storybook stories with examples
898
+ - ✅ **Consistency**: Follow patterns from existing components
899
+ - ✅ **Testing**: (Coming soon) Write unit and integration tests
900
+
901
+ ### Adding New CSS Variables
902
+
903
+ 1. **Add to palette** (`:root` in `theme.css`)
904
+
905
+ ```css
906
+ :root {
907
+ --cg-ui-palette-accent-100: hsla(180, 80%, 40%, 1);
908
+ }
909
+ ```
148
910
 
149
- ### Component Development Guidelines
911
+ 2. **Add semantic variable** (`@theme inline` in `theme.css`)
150
912
 
151
- 1. **Accessibility First**: Use bits-ui primitives when possible
152
- 2. **Type Safety**: Provide comprehensive TypeScript definitions
153
- 3. **Consistent API**: Follow established patterns from existing components
154
- 4. **Documentation**: Every component should have Storybook stories
155
- 5. **Styling**: Use tailwind-variants for flexible styling options
913
+ ```css
914
+ @theme inline {
915
+ --color-accent: var(--cg-ui-palette-accent-100);
916
+ }
917
+ ```
918
+
919
+ 3. **Document in README** (this file)
920
+
921
+ 4. **Use in components**
922
+
923
+ ```svelte
924
+ <style>
925
+ .my-component {
926
+ background-color: var(--color-accent);
927
+ }
928
+ </style>
929
+ ```
930
+
931
+ ### Submitting Changes
932
+
933
+ 1. Create a feature branch
934
+ 2. Make your changes
935
+ 3. Run `pnpm check` and `pnpm lint`
936
+ 4. Test in Storybook
937
+ 5. Create a pull request
938
+ 6. Request review from UI team
939
+
940
+ ---
941
+
942
+ ## 📚 Additional Resources
943
+
944
+ - **Live Storybook**: [https://static.casinogate.dev/components/master/](https://static.casinogate.dev/components/master/)
945
+ - **Monorepo Documentation**: [Root README](../../README.md)
946
+ - **DevOps Guide**: [Publishing & Deployment](../../docs/DEVOPS.md)
947
+ - **Svelte 5 Docs**: [https://svelte.dev/docs](https://svelte.dev/docs)
948
+ - **TailwindCSS**: [https://tailwindcss.com](https://tailwindcss.com)
949
+ - **bits-ui**: [https://bits-ui.com](https://bits-ui.com)
950
+
951
+ ---
156
952
 
157
953
  ## 📄 License
158
954
 
159
955
  ISC
160
956
 
161
- ## 🔗 Links
957
+ ---
958
+
959
+ ## 🙋 Support
162
960
 
163
- - [Svelte 5 Documentation](https://svelte.dev/docs/svelte/overview)
164
- - [TailwindCSS](https://tailwindcss.com/)
165
- - [bits-ui](https://bits-ui.com/) - Accessible component primitives
166
- - [tailwind-variants](https://www.tailwind-variants.org/) - Styling utilities
167
- - [Storybook](https://storybook.js.org/) - Component documentation
961
+ - **Questions?** Check the [Storybook documentation](https://static.casinogate.dev/components/master/)
962
+ - **Issues?** Contact the UI team or file an issue
963
+ - **Feature Requests?** Submit a proposal through the team channels
168
964
 
169
965
  ---
170
966
 
171
- Made with ❤️ by the CG team
967
+ Made with ❤️ by the CasinoGate team