phaser-wind 0.3.0 → 0.5.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 (85) hide show
  1. package/README.md +170 -413
  2. package/dist/components/column.d.ts +2 -0
  3. package/dist/components/column.d.ts.map +1 -0
  4. package/dist/components/column.js +2 -0
  5. package/dist/components/column.js.map +1 -0
  6. package/dist/core/color.d.ts +149 -282
  7. package/dist/core/color.d.ts.map +1 -1
  8. package/dist/core/color.js +117 -298
  9. package/dist/core/color.js.map +1 -1
  10. package/dist/core/color.spec.js +46 -55
  11. package/dist/core/color.spec.js.map +1 -1
  12. package/dist/core/font-size.d.ts +36 -15
  13. package/dist/core/font-size.d.ts.map +1 -1
  14. package/dist/core/font-size.js +42 -47
  15. package/dist/core/font-size.js.map +1 -1
  16. package/dist/core/font-size.spec.js +55 -43
  17. package/dist/core/font-size.spec.js.map +1 -1
  18. package/dist/core/font.d.ts +18 -91
  19. package/dist/core/font.d.ts.map +1 -1
  20. package/dist/core/font.js +33 -174
  21. package/dist/core/font.js.map +1 -1
  22. package/dist/core/font.spec.js +45 -49
  23. package/dist/core/font.spec.js.map +1 -1
  24. package/dist/core/index.d.ts +1 -1
  25. package/dist/core/index.js +1 -1
  26. package/dist/core/{pallete.d.ts → palette.d.ts} +2 -2
  27. package/dist/core/{pallete.d.ts.map → palette.d.ts.map} +1 -1
  28. package/dist/core/{pallete.js → palette.js} +2 -2
  29. package/dist/core/{pallete.js.map → palette.js.map} +1 -1
  30. package/dist/core/radius.d.ts +19 -24
  31. package/dist/core/radius.d.ts.map +1 -1
  32. package/dist/core/radius.js +20 -28
  33. package/dist/core/radius.js.map +1 -1
  34. package/dist/core/radius.spec.js +28 -33
  35. package/dist/core/radius.spec.js.map +1 -1
  36. package/dist/core/shadow.d.ts +18 -10
  37. package/dist/core/shadow.d.ts.map +1 -1
  38. package/dist/core/shadow.js +29 -19
  39. package/dist/core/shadow.js.map +1 -1
  40. package/dist/core/shadow.spec.d.ts +2 -0
  41. package/dist/core/shadow.spec.d.ts.map +1 -0
  42. package/dist/core/shadow.spec.js +21 -0
  43. package/dist/core/shadow.spec.js.map +1 -0
  44. package/dist/core/spacing.d.ts +22 -29
  45. package/dist/core/spacing.d.ts.map +1 -1
  46. package/dist/core/spacing.js +27 -39
  47. package/dist/core/spacing.js.map +1 -1
  48. package/dist/core/spacing.spec.js +18 -29
  49. package/dist/core/spacing.spec.js.map +1 -1
  50. package/dist/exceptions.d.ts +1 -0
  51. package/dist/exceptions.d.ts.map +1 -0
  52. package/dist/exceptions.js +2 -0
  53. package/dist/exceptions.js.map +1 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +2 -0
  57. package/dist/index.js.map +1 -1
  58. package/dist/plugin/index.d.ts +2 -0
  59. package/dist/plugin/index.d.ts.map +1 -0
  60. package/dist/plugin/index.js +2 -0
  61. package/dist/plugin/index.js.map +1 -0
  62. package/dist/plugin/plugin.d.ts +71 -0
  63. package/dist/plugin/plugin.d.ts.map +1 -0
  64. package/dist/plugin/plugin.js +91 -0
  65. package/dist/plugin/plugin.js.map +1 -0
  66. package/dist/scene/index.d.ts +2 -0
  67. package/dist/scene/index.d.ts.map +1 -0
  68. package/dist/scene/index.js +2 -0
  69. package/dist/scene/index.js.map +1 -0
  70. package/dist/scene/scene-with-phaser-wind.d.ts +11 -0
  71. package/dist/scene/scene-with-phaser-wind.d.ts.map +1 -0
  72. package/dist/scene/scene-with-phaser-wind.js +11 -0
  73. package/dist/scene/scene-with-phaser-wind.js.map +1 -0
  74. package/dist/theme/theme-config.d.ts +24 -48
  75. package/dist/theme/theme-config.d.ts.map +1 -1
  76. package/dist/theme/theme-config.js +4 -1
  77. package/dist/theme/theme-config.js.map +1 -1
  78. package/dist/theme/theme-manager.d.ts +1 -106
  79. package/dist/theme/theme-manager.d.ts.map +1 -1
  80. package/dist/theme/theme-manager.js +1 -187
  81. package/dist/theme/theme-manager.js.map +1 -1
  82. package/dist/theme/type.d.ts +48 -0
  83. package/dist/theme/type.d.ts.map +1 -1
  84. package/dist/theme/type.js +1 -1
  85. package/package.json +3 -3
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  >
9
9
  > **Love Tailwind CSS but stuck with Phaser?**
10
10
  >
11
- > **Welcome to Phaser Wind** - bringing the joy and simplicity of Tailwind CSS design tokens to Phaser games! 🎮✨
11
+ > **Welcome to Phaser Wind** - bring the joy and simplicity of Tailwind-like design tokens to Phaser games! 🎮✨
12
12
 
13
13
  [![NPM Version](https://img.shields.io/npm/v/phaser-wind)](https://www.npmjs.com/package/phaser-wind)
14
14
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -37,6 +37,7 @@ const title = this.add.text(200, 100, 'Game Title', {
37
37
  ### The Solution 🌟
38
38
 
39
39
  ```typescript
40
+ // No theme needed. Just import and go!
40
41
  import { Color, FontSize } from 'phaser-wind';
41
42
 
42
43
  // Clean, semantic, consistent!
@@ -56,15 +57,14 @@ const title = this.add.text(200, 100, 'Game Title', {
56
57
 
57
58
  ## 🚀 Features
58
59
 
59
- - 🎨 **Complete Tailwind Color Palette** - All 22 color families with 11 shades each
60
- - 📐 **Semantic Font Sizes** - From `xs` to `6xl`, just like Tailwind
61
- - 🎨 **Structured Theme System** - Nested design tokens for colors, fonts, spacing, typography, and effects
62
- - 🔄 **Dynamic Theme Switching** - Change themes at runtime with full type safety
63
- - 🎯 **Smart Token Resolution** - Themes can reference other theme tokens automatically
60
+ - 🎨 **Complete Tailwind-like Color Palette** - 22 families × 11 shades
61
+ - 📐 **Semantic Font Sizes** - From `xs` to `6xl`
62
+ - 🧩 **Default constants ready-to-use** - `Color`, `FontSize`, `Spacing`, `Radius`, `Shadow`
63
+ - 🧭 **Optional theme system (typed)** - Add your own tokens with strong typing
64
64
  - 🔧 **TypeScript First** - Full type safety and IntelliSense
65
- - 🎮 **Phaser Ready** - Designed specifically for Phaser 3 games
65
+ - 🎮 **Phaser Ready** - Global plugin for easy access in scenes
66
66
  - 🌈 **Consistent Design** - No more guessing colors and sizes
67
- - 📦 **Tiny Bundle** - Zero runtime overhead, just better DX
67
+ - 📦 **Tiny Bundle** - Great DX, minimal overhead
68
68
 
69
69
  ---
70
70
 
@@ -80,9 +80,9 @@ pnpm add phaser-wind
80
80
 
81
81
  ---
82
82
 
83
- ## 🎨 Color System
83
+ ## 🎨 Color System (no theme)
84
84
 
85
- ### Complete Tailwind Palette
85
+ ### Complete Palette
86
86
 
87
87
  Access all Tailwind colors with semantic naming:
88
88
 
@@ -110,7 +110,7 @@ const whiteBackground = Color.hex('white'); // 0xFFFFFF
110
110
 
111
111
  ---
112
112
 
113
- ## 📏 Font Size System
113
+ ## 📏 Font Size System (no theme)
114
114
 
115
115
  ### Semantic Sizing
116
116
 
@@ -149,457 +149,222 @@ const responsiveText = FontSize.rem('xl'); // 1.25
149
149
 
150
150
  ---
151
151
 
152
- ## 🎨 Theme System
152
+ ## 🧪 Strong typing (no theme)
153
153
 
154
- Phaser Wind includes a powerful **structured theme system** that lets you organize your design tokens into logical categories and create consistent, reusable designs.
154
+ All APIs are strongly typed. Invalid tokens break at compile time:
155
155
 
156
- ### 🏗️ **Theme Structure**
156
+ ```ts
157
+ import { Color, FontSize, Spacing, Radius, Shadow } from 'phaser-wind';
157
158
 
158
- ```typescript
159
- import { createTheme, ThemeManager } from 'phaser-wind';
160
-
161
- const gameTheme = createTheme({
162
- fonts: {
163
- primary: 'Inter, system-ui, sans-serif',
164
- display: 'Orbitron, monospace', // Sci-fi font for headers
165
- ui: 'Roboto, Arial, sans-serif',
166
- },
167
- colors: {
168
- primary: 'purple-600',
169
- secondary: 'cyan-500',
170
- 'ui-background': 'slate-900',
171
- 'player-health': 'green-500',
172
- 'enemy-health': 'red-600',
173
- },
174
- spacing: {
175
- xs: 4,
176
- sm: 8,
177
- md: 16,
178
- lg: 24,
179
- xl: 32,
180
- },
181
- typography: {
182
- heading: {
183
- fontSize: '2xl',
184
- fontFamily: 'fonts.display', // 🔗 References fonts.display!
185
- fontWeight: 600,
186
- lineHeight: 1.2,
187
- },
188
- body: {
189
- fontSize: 'md',
190
- fontFamily: 'fonts.primary',
191
- fontWeight: 400,
192
- lineHeight: 1.5,
193
- },
194
- },
195
- effects: {
196
- 'glow-primary': {
197
- blur: 8,
198
- color: 'colors.primary', // 🔗 References colors.primary!
199
- alpha: 0.6,
200
- },
201
- },
202
- // Custom categories work too!
203
- animations: {
204
- duration: 300,
205
- easing: 'ease-out',
206
- },
207
- });
159
+ // ✅ OK
160
+ Color.rgb('blue-500');
161
+ FontSize.css('lg');
162
+ Spacing.px('16');
163
+ Radius.css('sm');
164
+ Shadow.get('md');
208
165
 
209
- // Initialize your theme
210
- ThemeManager.init(gameTheme);
166
+ // Compile-time errors
167
+ // Color.rgb('blue-501');
168
+ // FontSize.css('huge');
169
+ // Spacing.px('97');
170
+ // Radius.css('xxl');
171
+ // Shadow.get('mega');
211
172
  ```
212
173
 
213
- ### 🎯 **Using Theme Tokens**
174
+ ---
214
175
 
215
- ```typescript
216
- import { Color, Font, FontSize, Spacing, ThemeManager } from 'phaser-wind';
176
+ ## 🧱 Token Reference
217
177
 
218
- // Colors - automatically looks in colors.*
219
- const primaryColor = Color.rgb('primary'); // Gets colors.primary
220
- const uiBackground = Color.hex('ui-background'); // Gets colors.ui-background
178
+ ### Colors
221
179
 
222
- // Fonts
223
- const displayFont = Font.family('display'); // Gets fonts.display
224
- const primaryFont = Font.family('primary'); // Gets fonts.primary
180
+ - Families: `slate`, `gray`, `zinc`, `neutral`, `stone`, `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose`
181
+ - Shades: `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`
182
+ - Special: `black`, `white`
225
183
 
226
- // Spacing
227
- const mediumSpace = Spacing.px('md'); // Gets spacing.md (16px)
228
- const largeSpace = Spacing.px('lg'); // Gets spacing.lg (24px)
184
+ ### Font Size
229
185
 
230
- // Complete typography styles - using basic components for now
231
- const headingStyle = {
232
- fontSize: FontSize.css('2xl'),
233
- fontFamily: Font.family('display'),
234
- fontWeight: 'bold',
235
- };
186
+ - Keys: `xs`, `sm`, `base`, `lg`, `xl`, `2xl`, `3xl`, `4xl`, `5xl`, `6xl`
236
187
 
237
- // Custom tokens
238
- const animDuration = ThemeManager.getToken('animations.duration'); // 300
239
- ```
188
+ ### Spacing
240
189
 
241
- ### 🔄 **Dynamic Theme Switching**
190
+ - Keys (px scale ×4): `0`, `px(=1)`, `0.5`, `1`, `1.5`, `2`, `2.5`, `3`, `3.5`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `14`, `16`, `20`, `24`, `28`, `32`, `36`, `40`, `44`, `48`, `52`, `56`, `60`, `64`, `72`, `80`, `96`
242
191
 
243
- ```typescript
244
- // Register multiple themes
245
- ThemeManager.registerTheme('light', lightTheme);
246
- ThemeManager.registerTheme('dark', darkTheme);
247
- ThemeManager.registerTheme('cyberpunk', cyberpunkTheme);
248
-
249
- // Switch themes instantly
250
- ThemeManager.setTheme('dark');
251
-
252
- // Listen for theme changes
253
- ThemeManager.onThemeChange(newTheme => {
254
- console.log('Theme changed!', newTheme);
255
- // Update your game UI here
256
- });
192
+ ### Radius
257
193
 
258
- // Get available themes
259
- const themes = ThemeManager.getRegisteredThemes(); // ['light', 'dark', 'cyberpunk']
260
- ```
194
+ - Keys: `none`, `sm`, `default`, `md`, `lg`, `xl`, `2xl`, `3xl`, `full`
261
195
 
262
- ### 🎮 **Real Game Example**
196
+ ### Shadow
263
197
 
264
- ```typescript
265
- export class GameScene extends Phaser.Scene {
266
- create() {
267
- // Player health bar with theme colors
268
- const healthWidth = Spacing.px('24'); // 96px
269
- const healthHeight = Spacing.px('4'); // 16px
270
-
271
- this.add.rectangle(
272
- 50,
273
- 50,
274
- healthWidth,
275
- healthHeight,
276
- Color.hex('player-health')
277
- ); // Green from theme
278
-
279
- // Game title with theme typography
280
- this.add
281
- .text(400, 50, 'CYBER QUEST', {
282
- fontSize: FontSize.css('4xl'),
283
- fontFamily: Font.family('display'),
284
- color: Color.rgb('primary'), // Purple from theme
285
- })
286
- .setOrigin(0.5);
287
-
288
- // UI button with consistent spacing and colors
289
- this.createButton(
290
- 400,
291
- 400,
292
- 'START GAME',
293
- Spacing.px('16'), // 64px width
294
- Spacing.px('6') // 24px height
295
- );
296
- }
198
+ - Default keys: `sm`, `md`, `lg`, `xl`, `2xl`, `inner`
297
199
 
298
- createButton(
299
- x: number,
300
- y: number,
301
- text: string,
302
- width: number,
303
- height: number
304
- ) {
305
- const button = this.add
306
- .rectangle(x, y, width, height, Color.hex('ui-background'))
307
- .setInteractive()
308
- .on('pointerover', () => button.setFillStyle(Color.hex('secondary')))
309
- .on('pointerout', () => button.setFillStyle(Color.hex('ui-background')));
310
-
311
- this.add
312
- .text(x, y, text, {
313
- fontSize: FontSize.css('base'),
314
- fontFamily: Font.family('primary'),
315
- color: Color.rgb('primary'),
316
- })
317
- .setOrigin(0.5);
318
- }
319
- }
320
- ```
321
-
322
- ### 🎨 **Pre-built Themes**
323
-
324
- ```typescript
325
- import { defaultLightTheme, defaultDarkTheme } from 'phaser-wind';
326
-
327
- // Light theme with professional colors
328
- ThemeManager.init(defaultLightTheme);
200
+ ---
329
201
 
330
- // Dark theme perfect for games
331
- ThemeManager.init(defaultDarkTheme);
202
+ ## 🎨 Theming
332
203
 
333
- // Create variations
334
- const winterTheme = ThemeManager.extendCurrentTheme({
335
- 'colors.primary': 'blue-400',
336
- 'colors.secondary': 'cyan-300',
337
- 'colors.accent': 'white',
338
- });
339
- ```
204
+ Phaser Wind also provides a typed theme system via a Phaser plugin. You get the same API surface (`color`, `fontSize`, `spacing`, `radius`, `font`, `shadow`) but narrowed to your custom tokens.
340
205
 
341
- ### 🔗 **Smart Token References**
206
+ ### 1) Create a theme
342
207
 
343
- Themes can reference other tokens using dot notation:
208
+ ```ts
209
+ import { createTheme, type CreateTheme } from 'phaser-wind';
344
210
 
345
- ```typescript
346
- const theme = createTheme({
211
+ export const theme = createTheme({
212
+ fonts: {
213
+ primary: 'Inter, system-ui, sans-serif',
214
+ display: 'Orbitron, monospace',
215
+ },
216
+ fontSizes: {
217
+ // optional overrides
218
+ },
347
219
  colors: {
348
- brand: 'purple-600',
220
+ primary: 'blue-600',
221
+ background: 'slate-900',
349
222
  danger: 'red-500',
350
223
  },
351
- typography: {
352
- title: {
353
- fontSize: '4xl',
354
- fontFamily: 'fonts.display', // 🔗 Auto-resolves to fonts.display
355
- color: 'colors.brand', // 🔗 Auto-resolves to purple-600
356
- },
224
+ spacing: {
225
+ gutter: 24,
226
+ },
227
+ radius: {
228
+ card: 12,
357
229
  },
358
230
  effects: {
359
- 'brand-glow': {
360
- color: 'colors.brand', // 🔗 Auto-resolves to purple-600
361
- blur: 8,
362
- },
231
+ glow: { blur: 8, offsetX: 0, offsetY: 0, alpha: 0.6 },
363
232
  },
364
- });
233
+ } satisfies CreateTheme<any>);
234
+
235
+ export type ThemeType = typeof theme;
365
236
  ```
366
237
 
367
- ---
238
+ ### 2) Install the plugin in Phaser
239
+
240
+ ```ts
241
+ import {
242
+ PhaserWindPlugin,
243
+ PHASER_WIND_KEY,
244
+ defaultLightTheme,
245
+ } from 'phaser-wind';
246
+ import { theme } from './theme';
247
+
248
+ new Phaser.Game({
249
+ plugins: {
250
+ global: [
251
+ {
252
+ key: PHASER_WIND_KEY,
253
+ plugin: PhaserWindPlugin,
254
+ mapping: PHASER_WIND_KEY, // scene.pw
255
+ data: { theme }, // or { theme: defaultLightTheme }
256
+ },
257
+ ],
258
+ },
259
+ });
260
+ ```
368
261
 
369
- ## 💡 Real-World Examples
262
+ ### 3) How to get strong types in your scene
370
263
 
371
- ### Game UI Components
264
+ #### 3.1 Lazy way. Define a module and all scenes should be have the "pw" instance
372
265
 
373
- ```typescript
374
- import { Color, FontSize } from 'phaser-wind';
266
+ ```ts
267
+ // src/my-theme.ts
268
+ import 'phaser';
269
+ import type { PhaserWindPlugin } from 'phaser-wind';
270
+ import type { ThemeType } from './theme';
375
271
 
376
- export class GameScene extends Phaser.Scene {
377
- create() {
378
- // Main title
379
- this.add
380
- .text(400, 100, 'SPACE RAIDERS', {
381
- fontSize: FontSize.css('5xl'),
382
- fill: Color.rgb('yellow-400'),
383
- stroke: Color.rgb('yellow-800'),
384
- strokeThickness: 2,
385
- })
386
- .setOrigin(0.5);
387
-
388
- // Score display
389
- this.add.text(50, 50, 'Score: 12,500', {
390
- fontSize: FontSize.css('xl'),
391
- fill: Color.rgb('green-400'),
392
- });
393
-
394
- // Health bar background
395
- const healthBg = this.add.graphics();
396
- healthBg.fillStyle(Color.hex('red-900'));
397
- healthBg.fillRect(50, 100, 200, 20);
398
-
399
- // Health bar fill
400
- const healthFill = this.add.graphics();
401
- healthFill.fillStyle(Color.hex('red-500'));
402
- healthFill.fillRect(52, 102, 156, 16); // 80% health
403
-
404
- // Game over screen
405
- this.add.rectangle(400, 300, 600, 400, Color.hex('slate-900'), 0.9);
406
-
407
- this.add
408
- .text(400, 250, 'GAME OVER', {
409
- fontSize: FontSize.css('4xl'),
410
- fill: Color.rgb('red-500'),
411
- })
412
- .setOrigin(0.5);
413
-
414
- this.add
415
- .text(400, 320, 'Final Score: 12,500', {
416
- fontSize: FontSize.css('2xl'),
417
- fill: Color.rgb('slate-300'),
418
- })
419
- .setOrigin(0.5);
272
+ const theme = const theme = createTheme({
273
+ colors: {
274
+ brand: 'purple-600',
275
+ danger: 'red-500',
420
276
  }
421
- }
422
- ```
423
-
424
- ### Button System
277
+ });
278
+ export type ThemeType = typeof theme;
425
279
 
426
- ```typescript
427
- class GameButton {
428
- constructor(
429
- scene: Phaser.Scene,
430
- x: number,
431
- y: number,
432
- text: string,
433
- variant: 'primary' | 'secondary' | 'danger' = 'primary'
434
- ) {
435
- const colors = {
436
- primary: {
437
- bg: Color.hex('blue-600'),
438
- bgHover: Color.hex('blue-700'),
439
- text: Color.rgb('white'),
440
- },
441
- secondary: {
442
- bg: Color.hex('slate-600'),
443
- bgHover: Color.hex('slate-700'),
444
- text: Color.rgb('slate-100'),
445
- },
446
- danger: {
447
- bg: Color.hex('red-600'),
448
- bgHover: Color.hex('red-700'),
449
- text: Color.rgb('white'),
450
- },
451
- };
452
-
453
- const style = colors[variant];
454
-
455
- // Background
456
- this.background = scene.add
457
- .rectangle(x, y, 200, 50, style.bg)
458
- .setInteractive()
459
- .on('pointerover', () => this.background.setFillStyle(style.bgHover))
460
- .on('pointerout', () => this.background.setFillStyle(style.bg));
461
-
462
- // Text
463
- this.text = scene.add
464
- .text(x, y, text, {
465
- fontSize: FontSize.css('lg'),
466
- fill: style.text,
467
- })
468
- .setOrigin(0.5);
280
+ declare module 'phaser' {
281
+ interface Scene {
282
+ pw: PhaserWindPlugin<ThemeType>;
469
283
  }
470
284
  }
471
285
 
472
- // Usage
473
- const playButton = new GameButton(this, 400, 200, 'PLAY', 'primary');
474
- const settingsButton = new GameButton(this, 400, 280, 'SETTINGS', 'secondary');
475
- const quitButton = new GameButton(this, 400, 360, 'QUIT', 'danger');
476
- ```
477
-
478
- ### Particle Effects with Color Harmony
286
+ // In your scene
479
287
 
480
- ```typescript
481
- // Create harmonious particle effects
482
- this.add.particles(player.x, player.y, 'sparkle', {
483
- speed: { min: 50, max: 100 },
484
- tint: [
485
- Color.hex('blue-400'),
486
- Color.hex('blue-500'),
487
- Color.hex('blue-600'),
488
- Color.hex('cyan-400'),
489
- Color.hex('cyan-500'),
490
- ],
491
- lifespan: 1000,
492
- });
288
+ class MyCustomScene extends Phaser.Scene {
289
+ create(): void {
290
+ this.pw // <-- Valid instance in your ts file
493
291
  ```
494
292
 
495
- ---
496
-
497
- ## 🎮 Integration with Phaser
293
+ #### 3.1 - Cast way
498
294
 
499
- ### Scene Setup
295
+ The original `Phaser.Scene` does not know the `pw` from Phaser-wind. You can make a simple cast to solve this problem
500
296
 
501
- ```typescript
502
- import { Color, FontSize } from 'phaser-wind';
297
+ ```ts
298
+ import Phaser from 'phaser';
299
+ import { type ThemeType } from 'src/theme.ts' // In your project
503
300
 
504
- export class MenuScene extends Phaser.Scene {
505
- constructor() {
506
- super({ key: 'MenuScene' });
507
- }
301
+ class MyCustomScene extends Phaser.Scene {
302
+ create(): void {
303
+ const { pw } = (this as unknown as SceneWithPhaserWind<Theme>); // cast to get the pw property
304
+ this.cameras.main.setBackgroundColor(pw.color.slate(900));
508
305
 
509
- create() {
510
- // Background gradient effect
511
- const bg = this.add.graphics();
512
- bg.fillGradientStyle(
513
- Color.hex('slate-900'), // top-left
514
- Color.hex('slate-800'), // top-right
515
- Color.hex('slate-800'), // bottom-left
516
- Color.hex('slate-700') // bottom-right
517
- );
518
- bg.fillRect(0, 0, this.cameras.main.width, this.cameras.main.height);
519
-
520
- // Consistent UI elements
521
- this.createTitle();
522
- this.createMenu();
523
- }
306
+ this.add
307
+ .text(300, 100, 'Primary color', {
308
+ fontSize: pw.fontSize.css('2xl'), // use the pw property to get the font size
309
+ color: pw.color.rgb('primary'), // use the pw property to get the color with type safety
310
+ })
311
+ .setOrigin(0.5);
312
+ ```
524
313
 
525
- private createTitle() {
526
- this.add
527
- .text(this.cameras.main.centerX, 150, 'MY AWESOME GAME', {
528
- fontSize: FontSize.css('4xl'),
529
- fill: Color.rgb('yellow-400'),
530
- stroke: Color.rgb('yellow-700'),
531
- strokeThickness: 3,
532
- })
533
- .setOrigin(0.5);
534
- }
314
+ #### 3.2 - Inheritance way
535
315
 
536
- private createMenu() {
537
- const menuItems = ['Play', 'Options', 'Credits', 'Quit'];
538
-
539
- menuItems.forEach((item, index) => {
540
- this.add
541
- .text(this.cameras.main.centerX, 250 + index * 60, item, {
542
- fontSize: FontSize.css('xl'),
543
- fill: Color.rgb('slate-300'),
544
- })
545
- .setOrigin(0.5)
546
- .setInteractive()
547
- .on('pointerover', function () {
548
- this.setTint(Color.hex('yellow-400'));
549
- })
550
- .on('pointerout', function () {
551
- this.clearTint();
552
- });
553
- });
554
- }
555
- }
556
- ```
316
+ Phaser-wind export an abstract class to type the `Phaser.Scene` and add the attribute `pw`.
557
317
 
558
- ---
318
+ ```ts
319
+ import Phaser from 'phaser';
320
+ import { type ThemeType } from 'src/theme.ts' // In your project
559
321
 
560
- ## 🔧 Advanced Usage
322
+ class PreviewScene extends SceneWithPhaserWind<ThemeType> { // Inherit from SceneWithPhaserWind to get the pw property
323
+ create(): void {
324
+ const { color, fontSize, spacing, radius, font, shadow } = this.pw; // Don't need to cast because we're using the generic type
561
325
 
562
- ### Custom Color Schemes
326
+ // Type-narrowed to your theme
327
+ color.rgb('primary');
328
+ fontSize.css('lg');
329
+ spacing.px('gutter');
330
+ radius.css('card');
331
+ font.family('display');
332
+ shadow.get('glow');
563
333
 
564
- ```typescript
565
- // Create consistent themes
566
- const darkTheme = {
567
- background: Color.hex('slate-900'),
568
- surface: Color.hex('slate-800'),
569
- primary: Color.hex('blue-500'),
570
- secondary: Color.hex('slate-600'),
571
- text: Color.rgb('slate-100'),
572
- textMuted: Color.rgb('slate-400'),
573
- };
574
-
575
- const lightTheme = {
576
- background: Color.hex('slate-50'),
577
- surface: Color.hex('white'),
578
- primary: Color.hex('blue-600'),
579
- secondary: Color.hex('slate-200'),
580
- text: Color.rgb('slate-900'),
581
- textMuted: Color.rgb('slate-600'),
582
- };
334
+ // ❌ Compile-time errors
335
+ // color.rgb('blue-501');
336
+ // spacing.px('unknown');
583
337
  ```
584
338
 
585
- ### Responsive Text Sizing
339
+ ### 🎮 **Real Game Example**
586
340
 
587
- ```typescript
588
- // Scale text based on screen size
589
- const getResponsiveTextSize = (baseSize: FontSizeKey): string => {
590
- const scale = this.cameras.main.width / 1920; // Base on 1920px width
591
- const basePixels = FontSize.px(baseSize);
592
- return `${Math.round(basePixels * scale)}px`;
593
- };
594
-
595
- this.add.text(x, y, 'Responsive Text', {
596
- fontSize: getResponsiveTextSize('2xl'),
597
- fill: Color.rgb('blue-500'),
341
+ You can check some examples in our [Storybook in this clicking here](https://renatocassino.github.io/phaser-toolkit).
342
+
343
+ ### 🎨 **Pre-built Themes**
344
+
345
+ ```ts
346
+ import {
347
+ PhaserWindPlugin,
348
+ PHASER_WIND_KEY,
349
+ defaultLightTheme,
350
+ // or defaultDarkTheme
351
+ } from 'phaser-wind';
352
+ import { theme } from './theme';
353
+
354
+ new Phaser.Game({
355
+ plugins: {
356
+ global: [
357
+ {
358
+ key: PHASER_WIND_KEY,
359
+ plugin: PhaserWindPlugin,
360
+ mapping: PHASER_WIND_KEY, // scene.pw
361
+ data: { theme: defaultLighTheme }, // or { theme: defaultDarkTheme }
362
+ },
363
+ ],
364
+ },
598
365
  });
599
366
  ```
600
367
 
601
- ---
602
-
603
368
  ## 🤝 Why "Wind" instead of "Tailwind"?
604
369
 
605
370
  We love Tailwind CSS, but we're not affiliated with them. "Phaser Wind" captures the essence:
@@ -627,16 +392,6 @@ Plus, `phaser-wind` is way easier to type than `phaser-tailwind-css-design-token
627
392
 
628
393
  ---
629
394
 
630
- ## 🔮 Coming Soon
631
-
632
- - 📐 **Layout Utilities** - Flexbox-inspired alignment helpers
633
- - 📱 **Responsive Utilities** - Breakpoint-based design tokens
634
- - ⚡ **Animation Presets** - Smooth, consistent transitions
635
- - 🎮 **Component Library** - Pre-built Phaser components with theme support
636
- - 🔧 **CLI Tool** - Generate themes and components from the command line
637
-
638
- ---
639
-
640
395
  ## 🤝 Contributing
641
396
 
642
397
  We'd love your help making Phaser Wind even better!
@@ -653,6 +408,8 @@ We'd love your help making Phaser Wind even better!
653
408
 
654
409
  MIT © [CassinoDev](https://github.com/cassinodev)
655
410
 
411
+ Do you want to play? Go to [games.cassino.dev](https://games.cassino.dev).
412
+
656
413
  ---
657
414
 
658
415
  ## 🌟 Show Your Support