@vforsh/phaser-dev-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 (54) hide show
  1. package/README.md +198 -0
  2. package/dist/DebugBadge.d.ts +62 -0
  3. package/dist/DebugBadge.d.ts.map +1 -0
  4. package/dist/DebugBadge.js +206 -0
  5. package/dist/DebugBadge.js.map +1 -0
  6. package/dist/DebugButton.d.ts +94 -0
  7. package/dist/DebugButton.d.ts.map +1 -0
  8. package/dist/DebugButton.js +311 -0
  9. package/dist/DebugButton.js.map +1 -0
  10. package/dist/DebugColumnContainer.d.ts +38 -0
  11. package/dist/DebugColumnContainer.d.ts.map +1 -0
  12. package/dist/DebugColumnContainer.js +69 -0
  13. package/dist/DebugColumnContainer.js.map +1 -0
  14. package/dist/DebugGridContainer.d.ts +44 -0
  15. package/dist/DebugGridContainer.d.ts.map +1 -0
  16. package/dist/DebugGridContainer.js +64 -0
  17. package/dist/DebugGridContainer.js.map +1 -0
  18. package/dist/DebugLabel.d.ts +33 -0
  19. package/dist/DebugLabel.d.ts.map +1 -0
  20. package/dist/DebugLabel.js +37 -0
  21. package/dist/DebugLabel.js.map +1 -0
  22. package/dist/DebugPanel.d.ts +67 -0
  23. package/dist/DebugPanel.d.ts.map +1 -0
  24. package/dist/DebugPanel.js +138 -0
  25. package/dist/DebugPanel.js.map +1 -0
  26. package/dist/DebugProgressBar.d.ts +47 -0
  27. package/dist/DebugProgressBar.d.ts.map +1 -0
  28. package/dist/DebugProgressBar.js +129 -0
  29. package/dist/DebugProgressBar.js.map +1 -0
  30. package/dist/DebugRowContainer.d.ts +40 -0
  31. package/dist/DebugRowContainer.d.ts.map +1 -0
  32. package/dist/DebugRowContainer.js +91 -0
  33. package/dist/DebugRowContainer.js.map +1 -0
  34. package/dist/DebugScrollContainer.d.ts +138 -0
  35. package/dist/DebugScrollContainer.d.ts.map +1 -0
  36. package/dist/DebugScrollContainer.js +413 -0
  37. package/dist/DebugScrollContainer.js.map +1 -0
  38. package/dist/DebugSwitchButton.d.ts +111 -0
  39. package/dist/DebugSwitchButton.d.ts.map +1 -0
  40. package/dist/DebugSwitchButton.js +317 -0
  41. package/dist/DebugSwitchButton.js.map +1 -0
  42. package/dist/index.d.ts +23 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +20 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/types.d.ts +37 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +2 -0
  49. package/dist/types.js.map +1 -0
  50. package/dist/utils.d.ts +31 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +62 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +44 -0
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # phaser-dev-ui
2
+
3
+ Pure-code debug UI primitives for Phaser 3 games — panels, buttons, labels, badges, progress bars, switch buttons, scroll containers, and layout containers. No assets required.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bun install
9
+ ```
10
+
11
+ Requires [Phaser](https://phaser.io) 3.88.2 as a peer dependency.
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ bun run build # Build dist/
17
+ bun run playground # Run the playground (dev server with hot reload)
18
+ bun run typecheck # TypeScript check
19
+ ```
20
+
21
+ ## Overview
22
+
23
+ A set of utility functions and classes for creating developer/debug UIs entirely through code in Phaser 3 games — no sprites, atlases, or external assets required. Everything is rendered with `Phaser.GameObjects.Graphics` and `Phaser.GameObjects.Text`.
24
+
25
+ The system is designed with a fluent, chainable API and dark-theme defaults matching typical dev-tool aesthetics.
26
+
27
+ ## Available Components
28
+
29
+ ### `createDebugPanel`
30
+
31
+ - **Description**: The foundational container for any debug UI. A rounded rectangle with customizable background color, border, corner radius, and optional drop shadow.
32
+ - **Usage**: Use as the root element for popups, toolbars, or floating UI. Extends `Phaser.GameObjects.Container`, so you can add children directly.
33
+
34
+ ### `createDebugLabel`
35
+
36
+ - **Description**: A simple text label. Extends `Phaser.GameObjects.Text` with dark-theme defaults (white text, Verdana font).
37
+ - **Usage**: Titles, descriptions, status text, or any textual information in your debug UI.
38
+
39
+ ### `createDebugButton`
40
+
41
+ - **Description**: An interactive button with built-in styling for normal, hover, and disabled states. Customizable size, text, colors (background, text, outline), and corner radius.
42
+ - **Usage**: Use for any action that requires a click — confirming an action, closing a panel, triggering a debug function.
43
+ - **Enabled contract**: Set `enabled: false` during creation or call `.setEnabled(false)` later. Disabled buttons are dimmed, ignore hover highlight, and are non-interactable.
44
+
45
+ ### `createDebugBadge`
46
+
47
+ - **Description**: A compact, display-only text badge with a rounded background. Optimized for short labels (e.g. "NEW", "WIP", "x2"). Auto-sizes to fit text content.
48
+ - **Usage**: Overlay on top of debug buttons or panels to show state markers, counters, or tags.
49
+
50
+ ### `createDebugSwitchButton`
51
+
52
+ - **Description**: A cycling button that navigates through a list of key-value options with left/right arrow triangles. Emits an `option-changed` event.
53
+ - **Usage**: Settings with predefined states — quality levels, difficulty, toggling modes.
54
+ - **Enabled contract**: Supports `enabled` at creation and runtime `.setEnabled()`. When disabled, arrows are non-interactable and the whole control is visually dimmed.
55
+
56
+ ### `createDebugProgressBar`
57
+
58
+ - **Description**: A horizontal progress bar displaying a normalized 0–1 value. Track + fill with rounded corners.
59
+ - **Usage**: Loading progress, health, capacity, or any real-time metric.
60
+
61
+ ### `createDebugScrollContainer`
62
+
63
+ - **Description**: A masked vertical scroll viewport with wheel scrolling and optional visual scrollbar.
64
+ - **Usage**: Long debug forms/lists inside a fixed panel area. Add items with `addItem()`/`addItems()`, then call `.layout()` after child bounds change.
65
+
66
+ ### Layout Containers
67
+
68
+ - **`createRowContainer`**: Arranges children horizontally with configurable spacing, padding, and direction.
69
+ - **`createColumnContainer`**: Arranges children vertically with configurable spacing, padding, and direction.
70
+ - **`createGridContainer`**: Arranges children in a grid with configurable columns, cell size, and spacing.
71
+ - **Usage**: Group related UI elements. After adding items via `addItem()` or `addItems()`, call `.layout()` to reposition children. Containers are invisible positioning helpers and can be nested.
72
+
73
+ ## Example: Creating a Settings Popup
74
+
75
+ ```typescript
76
+ import {
77
+ createDebugPanel,
78
+ createDebugLabel,
79
+ createDebugButton,
80
+ createDebugBadge,
81
+ createDebugSwitchButton,
82
+ createDebugProgressBar,
83
+ createRowContainer,
84
+ } from '@vforsh/phaser-dev-ui'
85
+
86
+ // 1. Create the main panel
87
+ const panel = createDebugPanel(this, {
88
+ width: 500,
89
+ height: 350,
90
+ cornerRadius: 15,
91
+ position: { x: 400, y: 300 },
92
+ blockInputEvents: true,
93
+ })
94
+
95
+ // 2. Add a title label
96
+ const titleLabel = createDebugLabel(this, {
97
+ text: 'Settings',
98
+ fontSize: 32,
99
+ isBold: true,
100
+ position: { x: 0, y: -120 },
101
+ })
102
+ panel.add(titleLabel)
103
+
104
+ // 3. Add a switch button for quality settings
105
+ const qualitySwitch = createDebugSwitchButton(this, {
106
+ options: [
107
+ { key: 'low', value: 'Low Quality' },
108
+ { key: 'medium', value: 'Medium Quality' },
109
+ { key: 'high', value: 'High Quality' },
110
+ ],
111
+ size: { width: 300, height: 50 },
112
+ bgColor: '#333333',
113
+ textColor: '#ffffff',
114
+ arrowColor: '#ffffff',
115
+ position: { x: 0, y: -20 },
116
+ })
117
+
118
+ qualitySwitch.onOptionChanged((option) => {
119
+ console.log(`Quality changed to: ${option.key}`)
120
+ })
121
+
122
+ panel.add(qualitySwitch)
123
+
124
+ // 4. Add a progress bar
125
+ const loadBar = createDebugProgressBar(this, {
126
+ width: 300,
127
+ height: 12,
128
+ fillColor: '#4caf50',
129
+ position: { x: 0, y: 40 },
130
+ })
131
+ loadBar.setValue(0.7)
132
+ panel.add(loadBar)
133
+
134
+ // 5. Create action buttons
135
+ const cancelButton = createDebugButton(this, {
136
+ text: 'Cancel',
137
+ width: 140,
138
+ height: 60,
139
+ enabled: false,
140
+ onClick: () => panel.destroy(),
141
+ })
142
+
143
+ const saveButton = createDebugButton(this, {
144
+ text: 'Save',
145
+ width: 140,
146
+ height: 60,
147
+ onClick: () => {
148
+ console.log('Settings saved!')
149
+ panel.destroy()
150
+ },
151
+ })
152
+
153
+ // 6. Add a badge overlay
154
+ const badge = createDebugBadge(this, {
155
+ text: 'WIP',
156
+ position: { x: 60, y: -20 },
157
+ })
158
+ cancelButton.add(badge)
159
+
160
+ // 7. Use a Row Container for button layout
161
+ const buttonRow = createRowContainer(this, { spacingX: 20 })
162
+ buttonRow.addItems([cancelButton, saveButton])
163
+ buttonRow.layout()
164
+ buttonRow.setPosition(0, 120)
165
+ panel.add(buttonRow)
166
+
167
+ // 8. Toggle disabled state at runtime
168
+ cancelButton.setEnabled(true)
169
+ qualitySwitch.setEnabled(true)
170
+ ```
171
+
172
+ ### Breakdown
173
+
174
+ 1. **Panel Creation**: `DebugPanel` extends `Phaser.GameObjects.Container`. Set `blockInputEvents: true` for modal popups to prevent clicks from passing through.
175
+ 2. **Title Label**: `DebugLabel` extends `Phaser.GameObjects.Text`. Add it to the panel container with `panel.add()`. Position with the `position` option (relative to panel center).
176
+ 3. **Switch Button**: Created with options array. Use `.onOptionChanged()` to listen for changes.
177
+ 4. **Progress Bar**: Normalized 0–1 value. Call `.setValue()` to update.
178
+ 5. **Action Buttons**: Created with `onClick` handler. `enabled: false` starts the button disabled.
179
+ 6. **Badge Overlay**: `DebugBadge` added as a child of a button — auto-sizes to text.
180
+ 7. **Row Container**: Call `.addItems()` then `.layout()` to arrange children horizontally. Position the container itself within the panel.
181
+
182
+ ## Coordinate System
183
+
184
+ All primitives use Phaser's coordinate system:
185
+ - Origin (0, 0) is at the **top-left** of the game canvas
186
+ - **Y increases downward**
187
+ - All primitives default to origin `(0.5, 0.5)` — position refers to the center
188
+
189
+ When adding children to a `DebugPanel`, positions are relative to the panel's center (0, 0).
190
+
191
+ ## Best Practices
192
+
193
+ - **Use Layout Containers**: For groups of two or more elements, use `createRowContainer`, `createColumnContainer`, or `createGridContainer`. Call `.layout()` after adding all items.
194
+ - **Chainable API**: Most methods return `this` — chain style calls: `createDebugButton(scene, {...}).setBgColor('#f00').setTextColor('#fff')`.
195
+ - **Disabled semantics**: Disabled controls are dimmed, ignore hover, and block interaction.
196
+ - **Scene parameter**: Every factory function takes a `Phaser.Scene` as the first argument. The created game object is auto-added to the scene.
197
+ - **Event Handling**: Use `onClick` option for buttons, `.onOptionChanged()` for switch buttons. Direct Phaser events via `.on()` also work.
198
+ - **Cleanup**: Call `.destroy()` on any primitive to remove it and all its children from the scene.
@@ -0,0 +1,62 @@
1
+ import type { DebugImageIconOptions, HexColor, Position } from "./types.js";
2
+ export interface DebugBadgeStyleOptions {
3
+ bgColor?: HexColor;
4
+ textColor?: HexColor;
5
+ paddingX?: number;
6
+ paddingY?: number;
7
+ cornerRadius?: number;
8
+ minWidth?: number;
9
+ height?: number;
10
+ }
11
+ export interface CreateDebugBadgeOptions extends DebugBadgeStyleOptions {
12
+ /** Badge text content (optional; allow icon-only badges). */
13
+ text?: string;
14
+ /** Optional image icon rendered next to text (or standalone for icon-only badges). */
15
+ icon?: DebugImageIconOptions;
16
+ /** Font family (default: "Verdana"). */
17
+ fontFamily?: string;
18
+ /** Font size (default: 14). */
19
+ fontSize?: number;
20
+ /** Bold text (default: true). */
21
+ isBold?: boolean;
22
+ /** Position (optional). */
23
+ position?: Position;
24
+ }
25
+ /**
26
+ * A compact display-only badge for debug HUD.
27
+ *
28
+ * Shows short tags — build version, mode flag, active bonus, etc.
29
+ * Auto-sizes to fit text content with configurable padding.
30
+ * Chainable API.
31
+ */
32
+ export declare class DebugBadge extends Phaser.GameObjects.Container {
33
+ private _bg;
34
+ private _label;
35
+ private _icon;
36
+ private _paddingX;
37
+ private _paddingY;
38
+ private _cornerRadius;
39
+ private _minWidth;
40
+ private _height;
41
+ private _bgColor;
42
+ private _textColor;
43
+ private _iconOptions;
44
+ constructor(scene: Phaser.Scene, options: CreateDebugBadgeOptions);
45
+ setText(text: string): this;
46
+ setIcon(icon: DebugImageIconOptions | null): this;
47
+ setBgColor(color: HexColor): this;
48
+ setTextColor(color: HexColor): this;
49
+ setPadding(options: {
50
+ x?: number;
51
+ y?: number;
52
+ }): this;
53
+ setCornerRadius(radius: number): this;
54
+ setMinWidth(minWidth: number): this;
55
+ setBadgeHeight(height: number): this;
56
+ setStyle(options: DebugBadgeStyleOptions): this;
57
+ private refreshLayout;
58
+ private applyIconTint;
59
+ private redrawBg;
60
+ }
61
+ export declare function createDebugBadge(scene: Phaser.Scene, options: CreateDebugBadgeOptions): DebugBadge;
62
+ //# sourceMappingURL=DebugBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugBadge.d.ts","sourceRoot":"","sources":["../src/DebugBadge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG3E,MAAM,WAAW,sBAAsB;IACtC,OAAO,CAAC,EAAE,QAAQ,CAAA;IAClB,SAAS,CAAC,EAAE,QAAQ,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACtE,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,IAAI,CAAC,EAAE,qBAAqB,CAAA;IAC5B,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACnB;AAED;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,MAAM,CAAC,WAAW,CAAC,SAAS;IAC3D,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,KAAK,CAAwC;IAErD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,YAAY,CAAqC;gBAE7C,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB;IAwDjE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3B,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI;IAyBjD,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAMjC,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IASnC,UAAU,CAAC,OAAO,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOrD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMrC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMnC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMpC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAe/C,OAAO,CAAC,aAAa;IA8CrB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,QAAQ;CAiBhB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,GAAG,UAAU,CAElG"}
@@ -0,0 +1,206 @@
1
+ import { estimateTextWidth, getDevicePixelRatio, hexToColorAlpha } from "./utils.js";
2
+ /**
3
+ * A compact display-only badge for debug HUD.
4
+ *
5
+ * Shows short tags — build version, mode flag, active bonus, etc.
6
+ * Auto-sizes to fit text content with configurable padding.
7
+ * Chainable API.
8
+ */
9
+ export class DebugBadge extends Phaser.GameObjects.Container {
10
+ _bg;
11
+ _label;
12
+ _icon = null;
13
+ _paddingX;
14
+ _paddingY;
15
+ _cornerRadius;
16
+ _minWidth;
17
+ _height;
18
+ _bgColor;
19
+ _textColor;
20
+ _iconOptions = null;
21
+ constructor(scene, options) {
22
+ const { text = "", icon, bgColor = "#000000", textColor = "#e5e5e5", fontSize = 14, fontFamily = "Verdana", isBold = true, cornerRadius = 10, paddingX = 8, paddingY = 4, minWidth = 22, height = 22, position, } = options;
23
+ super(scene, position?.x ?? 0, position?.y ?? 0);
24
+ this._paddingX = paddingX;
25
+ this._paddingY = paddingY;
26
+ this._cornerRadius = cornerRadius;
27
+ this._minWidth = minWidth;
28
+ this._height = height;
29
+ this._bgColor = bgColor;
30
+ this._textColor = textColor;
31
+ this._bg = scene.add.graphics();
32
+ const tc = hexToColorAlpha(textColor);
33
+ this._label = scene.add.text(0, 0, text, {
34
+ fontFamily,
35
+ fontSize: `${fontSize}px`,
36
+ fontStyle: isBold ? "bold" : "normal",
37
+ color: `#${tc.color.toString(16).padStart(6, "0")}`,
38
+ align: "center",
39
+ resolution: getDevicePixelRatio(),
40
+ });
41
+ this._label.setOrigin(0.5, 0.5);
42
+ this._label.setAlpha(tc.alpha);
43
+ if (icon) {
44
+ this._icon = scene.add.image(0, 0, icon.key, icon.frame);
45
+ this._icon.setOrigin(0.5, 0.5);
46
+ this._iconOptions = icon;
47
+ }
48
+ const children = [this._bg];
49
+ if (this._icon)
50
+ children.push(this._icon);
51
+ children.push(this._label);
52
+ this.add(children);
53
+ this.refreshLayout();
54
+ scene.add.existing(this);
55
+ }
56
+ setText(text) {
57
+ this._label.setText(text);
58
+ this.refreshLayout();
59
+ return this;
60
+ }
61
+ setIcon(icon) {
62
+ if (!icon) {
63
+ if (this._icon) {
64
+ this.remove(this._icon);
65
+ this._icon.destroy();
66
+ this._icon = null;
67
+ }
68
+ this._iconOptions = null;
69
+ this.refreshLayout();
70
+ return this;
71
+ }
72
+ if (!this._icon) {
73
+ this._icon = this.scene.add.image(0, 0, icon.key, icon.frame);
74
+ this._icon.setOrigin(0.5, 0.5);
75
+ this.addAt(this._icon, 1);
76
+ }
77
+ else {
78
+ this._icon.setTexture(icon.key, icon.frame);
79
+ }
80
+ this._iconOptions = icon;
81
+ this.refreshLayout();
82
+ return this;
83
+ }
84
+ setBgColor(color) {
85
+ this._bgColor = color;
86
+ this.redrawBg(this.width, this.height);
87
+ return this;
88
+ }
89
+ setTextColor(color) {
90
+ this._textColor = color;
91
+ const c = hexToColorAlpha(color);
92
+ this._label.setColor(`#${c.color.toString(16).padStart(6, "0")}`);
93
+ this._label.setAlpha(c.alpha);
94
+ this.applyIconTint();
95
+ return this;
96
+ }
97
+ setPadding(options) {
98
+ if (options.x !== undefined)
99
+ this._paddingX = Math.max(0, options.x);
100
+ if (options.y !== undefined)
101
+ this._paddingY = Math.max(0, options.y);
102
+ this.refreshLayout();
103
+ return this;
104
+ }
105
+ setCornerRadius(radius) {
106
+ this._cornerRadius = Math.max(0, radius);
107
+ this.redrawBg(this.width, this.height);
108
+ return this;
109
+ }
110
+ setMinWidth(minWidth) {
111
+ this._minWidth = Math.max(0, minWidth);
112
+ this.refreshLayout();
113
+ return this;
114
+ }
115
+ setBadgeHeight(height) {
116
+ this._height = Math.max(1, height);
117
+ this.refreshLayout();
118
+ return this;
119
+ }
120
+ setStyle(options) {
121
+ if (options.bgColor)
122
+ this._bgColor = options.bgColor;
123
+ if (options.textColor)
124
+ this.setTextColor(options.textColor);
125
+ if (options.paddingX !== undefined || options.paddingY !== undefined) {
126
+ this.setPadding({ x: options.paddingX, y: options.paddingY });
127
+ }
128
+ if (options.cornerRadius !== undefined)
129
+ this._cornerRadius = Math.max(0, options.cornerRadius);
130
+ if (options.minWidth !== undefined)
131
+ this._minWidth = Math.max(0, options.minWidth);
132
+ if (options.height !== undefined)
133
+ this._height = Math.max(1, options.height);
134
+ this.refreshLayout();
135
+ return this;
136
+ }
137
+ // -- Internal --
138
+ refreshLayout() {
139
+ const fontSize = parseInt(this._label.style.fontSize) || 14;
140
+ let targetHeight = Math.max(this._height, fontSize * 1.2 + this._paddingY * 2 + 2);
141
+ const hasText = this._label.text.length > 0;
142
+ this._label.setVisible(hasText);
143
+ const icon = this._icon;
144
+ const iconOpt = this._iconOptions;
145
+ const gap = iconOpt?.gap ?? 8;
146
+ this.applyIconTint();
147
+ const iconW = icon ? icon.displayWidth : 0;
148
+ const textWidth = estimateTextWidth(this._label.text, fontSize);
149
+ const fudge = textWidth > 0 ? 10 : 0;
150
+ const contentW = iconW + (iconW > 0 && textWidth > 0 ? gap : 0) + textWidth + fudge;
151
+ const targetWidth = Math.max(this._minWidth, contentW + this._paddingX * 2);
152
+ this.setSize(targetWidth, targetHeight);
153
+ this.redrawBg(targetWidth, targetHeight);
154
+ // Re-center label/icon as a group (origin 0.5 for both).
155
+ const labelW = hasText ? this._label.width : 0;
156
+ const groupW = iconW + labelW + (iconW > 0 && labelW > 0 ? gap : 0);
157
+ if (!iconW && labelW) {
158
+ this._label.setPosition(0, 0);
159
+ return;
160
+ }
161
+ if (iconW && !labelW) {
162
+ icon.setPosition(0, 0);
163
+ return;
164
+ }
165
+ if (!iconW && !labelW)
166
+ return;
167
+ const startX = -groupW / 2;
168
+ const side = iconOpt?.side ?? "left";
169
+ if (side === "left") {
170
+ icon.setPosition(startX + iconW / 2, 0);
171
+ this._label.setPosition(startX + iconW + gap + labelW / 2, 0);
172
+ }
173
+ else {
174
+ this._label.setPosition(startX + labelW / 2, 0);
175
+ icon.setPosition(startX + labelW + gap + iconW / 2, 0);
176
+ }
177
+ }
178
+ applyIconTint() {
179
+ if (!this._icon)
180
+ return;
181
+ const iconOpt = this._iconOptions;
182
+ const tintHex = iconOpt?.tint ?? this._textColor;
183
+ const c = hexToColorAlpha(tintHex);
184
+ this._icon.setTint(c.color);
185
+ this._icon.setAlpha(c.alpha * (iconOpt?.alpha ?? 1));
186
+ }
187
+ redrawBg(w, h) {
188
+ const fontSize = parseInt(this._label.style.fontSize) || 14;
189
+ const textWidth = estimateTextWidth(this._label.text, fontSize);
190
+ const iconW = this._icon ? this._icon.displayWidth : 0;
191
+ const gap = this._iconOptions?.gap ?? 8;
192
+ const fudge = textWidth > 0 ? 10 : 0;
193
+ const contentW = iconW + (iconW > 0 && textWidth > 0 ? gap : 0) + textWidth + fudge;
194
+ const width = w ?? Math.max(this._minWidth, contentW + this._paddingX * 2);
195
+ const height = h ?? Math.max(this._height, fontSize * 1.2 + this._paddingY * 2 + 2);
196
+ const radius = Math.min(this._cornerRadius, height / 2);
197
+ const c = hexToColorAlpha(this._bgColor);
198
+ this._bg.clear();
199
+ this._bg.fillStyle(c.color, c.alpha);
200
+ this._bg.fillRoundedRect(-width / 2, -height / 2, width, height, radius);
201
+ }
202
+ }
203
+ export function createDebugBadge(scene, options) {
204
+ return new DebugBadge(scene, options);
205
+ }
206
+ //# sourceMappingURL=DebugBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugBadge.js","sourceRoot":"","sources":["../src/DebugBadge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import type { ClickHandler, DebugImageIconOptions, HexColor, Position, Size } from "./types.js";
2
+ export interface CreateDebugButtonOptions {
3
+ /** Button text (default: "Button") */
4
+ text?: string;
5
+ /** Optional image icon rendered next to text (or standalone for icon-only buttons). */
6
+ icon?: DebugImageIconOptions;
7
+ /** Button width (default: 160) */
8
+ width?: number;
9
+ /** Button height (default: 80) */
10
+ height?: number;
11
+ /** Corner radius (default: 10) */
12
+ cornerRadius?: number;
13
+ /** Enable stroke outline (default: true) */
14
+ stroke?: boolean;
15
+ /** Enable shadow (default: true) */
16
+ shadow?: boolean;
17
+ /** Font size (default: 20) */
18
+ fontSize?: number;
19
+ /** Font family (default: "Verdana") */
20
+ fontFamily?: string;
21
+ /** Bold text (default: true) */
22
+ isBold?: boolean;
23
+ /** Click handler (optional) */
24
+ onClick?: ClickHandler<DebugButton>;
25
+ /** Enabled state (default: true) */
26
+ enabled?: boolean;
27
+ /** Position (optional) */
28
+ position?: Position;
29
+ }
30
+ /**
31
+ * An interactive debug button with hover/disabled visual states.
32
+ *
33
+ * Renders background, optional shadow, optional stroke border, and centered text.
34
+ * Supports normal → hover → disabled state transitions with automatic color dimming.
35
+ * Chainable API.
36
+ */
37
+ export declare class DebugButton extends Phaser.GameObjects.Container {
38
+ private _bg;
39
+ private _shadow;
40
+ private _label;
41
+ private _icon;
42
+ private _hitZone;
43
+ private _width;
44
+ private _height;
45
+ private _cornerRadius;
46
+ private _shadowVisible;
47
+ private _outlineThickness;
48
+ private _normalBgColor;
49
+ private _hoverBgColor;
50
+ private _normalOutlineColor;
51
+ private _hoverOutlineColor;
52
+ private _normalTextColor;
53
+ private _hoverTextColor;
54
+ private _disabledBgColor;
55
+ private _disabledOutlineColor;
56
+ private _disabledTextColor;
57
+ private _isHovering;
58
+ private _isEnabled;
59
+ private _iconOptions;
60
+ constructor(scene: Phaser.Scene, options?: CreateDebugButtonOptions);
61
+ setBgColor(color: HexColor, hoverColor?: HexColor): this;
62
+ setOutline(color: HexColor, thickness: number, hoverColor?: HexColor): this;
63
+ setText(text: string): this;
64
+ setTextColor(color: HexColor, hoverColor?: HexColor): this;
65
+ setIcon(icon: DebugImageIconOptions | null): this;
66
+ setEnabled(enabled: boolean): this;
67
+ isEnabled(): boolean;
68
+ setShadowEnabled(enabled: boolean): this;
69
+ setButtonSize(width: number, height: number): this;
70
+ setStyle(options: {
71
+ size?: Size;
72
+ bgColor?: HexColor;
73
+ bgHoverColor?: HexColor;
74
+ outlineColor?: HexColor;
75
+ outlineHoverColor?: HexColor;
76
+ outlineThickness?: number;
77
+ text?: string;
78
+ textColor?: HexColor;
79
+ textHoverColor?: HexColor;
80
+ shadowEnabled?: boolean;
81
+ }): this;
82
+ onClick(handler: ClickHandler<DebugButton>): this;
83
+ getLabel(): Phaser.GameObjects.Text;
84
+ getIcon(): Phaser.GameObjects.Image | null;
85
+ private refreshContentLayout;
86
+ private setupInteraction;
87
+ private resolveVisualState;
88
+ private getColorForState;
89
+ private syncDerivedDisabledColors;
90
+ private applyVisualState;
91
+ private redraw;
92
+ }
93
+ export declare function createDebugButton(scene: Phaser.Scene, options?: CreateDebugButtonOptions): DebugButton;
94
+ //# sourceMappingURL=DebugButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugButton.d.ts","sourceRoot":"","sources":["../src/DebugButton.ts"],"names":[],"mappings":"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"}