hudini 0.2.1 → 0.3.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 (38) hide show
  1. package/README.md +187 -3
  2. package/dist/components/column/column.d.ts +88 -0
  3. package/dist/components/column/column.d.ts.map +1 -0
  4. package/dist/components/column/column.js +142 -0
  5. package/dist/components/column/column.js.map +1 -0
  6. package/dist/components/column/column.spec.d.ts +2 -0
  7. package/dist/components/column/column.spec.d.ts.map +1 -0
  8. package/dist/components/column/column.spec.js +147 -0
  9. package/dist/components/column/column.spec.js.map +1 -0
  10. package/dist/components/column/index.d.ts +2 -0
  11. package/dist/components/column/index.d.ts.map +1 -0
  12. package/dist/components/column/index.js +2 -0
  13. package/dist/components/column/index.js.map +1 -0
  14. package/dist/components/index.d.ts +2 -0
  15. package/dist/components/index.d.ts.map +1 -1
  16. package/dist/components/index.js +2 -0
  17. package/dist/components/index.js.map +1 -1
  18. package/dist/components/layout/layout-utils.d.ts +13 -0
  19. package/dist/components/layout/layout-utils.d.ts.map +1 -0
  20. package/dist/components/layout/layout-utils.js +38 -0
  21. package/dist/components/layout/layout-utils.js.map +1 -0
  22. package/dist/components/layout/layout-utils.spec.d.ts +2 -0
  23. package/dist/components/layout/layout-utils.spec.d.ts.map +1 -0
  24. package/dist/components/layout/layout-utils.spec.js +70 -0
  25. package/dist/components/layout/layout-utils.spec.js.map +1 -0
  26. package/dist/components/row/index.d.ts +2 -0
  27. package/dist/components/row/index.d.ts.map +1 -0
  28. package/dist/components/row/index.js +2 -0
  29. package/dist/components/row/index.js.map +1 -0
  30. package/dist/components/row/row.d.ts +87 -0
  31. package/dist/components/row/row.d.ts.map +1 -0
  32. package/dist/components/row/row.js +139 -0
  33. package/dist/components/row/row.js.map +1 -0
  34. package/dist/components/row/row.spec.d.ts +2 -0
  35. package/dist/components/row/row.spec.d.ts.map +1 -0
  36. package/dist/components/row/row.spec.js +146 -0
  37. package/dist/components/row/row.spec.js.map +1 -0
  38. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <img src="data/hudini.png" alt="hudini" />
1
+ <img src="data/hudini.png" style="max-width: 500px" alt="hudini" />
2
2
 
3
3
  # 🎩 Hudini
4
4
 
@@ -6,11 +6,12 @@
6
6
 
7
7
  **Hudini** is a collection of reusable, themeable UI components for Phaser games. Named after the famous magician Houdini and HUD (Head-Up Display), it provides a magical toolkit for building consistent game interfaces.
8
8
 
9
+ > Important: Hudini is fully type‑safe. The entire library is written in TypeScript and uses strict, explicit types for all public APIs (components, layout options, and plugin configuration). You get compile‑time validation and rich IntelliSense everywhere—no runtime guessing.
10
+
9
11
  ## ✨ Features
10
12
 
11
13
  - 🎨 **Themeable** - Dark/light themes with full customization
12
- - 🔊 **Sound Integration** - Built-in sound effects for interactions
13
- - 📦 **Zero Dependencies** - Only requires Phaser as peer dependency
14
+ - 📦 **Phaser-wind Dependency** - Only requires [Phaser-wind](https://github.com/renatocassino/phaser-toolkit/tree/main/packages/phaser-wind)
14
15
  - 🎯 **TypeScript First** - Full type safety and IntelliSense
15
16
  - 🧪 **Tested** - Comprehensive test coverage
16
17
 
@@ -23,3 +24,186 @@ yarn add hudini
23
24
  # or
24
25
  pnpm add hudini
25
26
  ```
27
+
28
+ ## 🔌 Installation (Plugin Setup)
29
+
30
+ Hudini is built on top of `phaser-wind` for theming and UI primitives. The Hudini plugin will automatically install the `phaser-wind` plugin if it is not already registered. You only need to add Hudini to your Phaser game configuration.
31
+
32
+ Basic setup with the default light theme:
33
+
34
+ ```ts
35
+ import Phaser from 'phaser';
36
+ import {
37
+ HudiniPlugin,
38
+ HUDINI_KEY,
39
+ HudiniPluginData,
40
+ createTheme,
41
+ } from 'hudini';
42
+
43
+ const theme = createTheme({
44
+ colors: {
45
+ primary: 'red-300',
46
+ secondary: 'blue-300',
47
+ },
48
+ // This theme is a phaser-wind theme conf. You can read more in https://github.com/renatocassino/phaser-toolkit/tree/main/packages/phaser-wind
49
+ });
50
+
51
+ type Theme = typeof theme;
52
+
53
+ new Phaser.Game({
54
+ type: Phaser.AUTO,
55
+ width: 800,
56
+ height: 600,
57
+ backgroundColor: '#1a1a1a',
58
+ plugins: {
59
+ global: [
60
+ {
61
+ key: HUDINI_KEY,
62
+ plugin: HudiniPlugin,
63
+ mapping: HUDINI_KEY,
64
+ data: {
65
+ theme,
66
+ } as HudiniPluginData<Theme>,
67
+ /**
68
+ * If you want to use a default theme, you can import "defaultLightTheme" from hudini
69
+ * data: {
70
+ * theme: defaultLightTheme,
71
+ * } as HudiniPluginData<Theme>
72
+ */
73
+ },
74
+ ],
75
+ },
76
+ });
77
+ ```
78
+
79
+ Notes:
80
+
81
+ - Hudini will ensure `phaser-wind` is available internally. If you prefer, you can also register `phaser-wind` explicitly before Hudini and pass a custom theme.
82
+ - You can pass `darkMode: true` (when no custom theme is provided) to use the default dark theme.
83
+
84
+ ### Requirements
85
+
86
+ - Phaser (peer dependency)
87
+
88
+ ```bash
89
+ pnpm add phaser
90
+ ```
91
+
92
+ ### Import
93
+
94
+ ```ts
95
+ import { Column, Row, IconButton } from 'hudini';
96
+ ```
97
+
98
+ ### Live examples
99
+
100
+ Check the Storybook for live, interactive examples: [Hudini on Storybook](https://renatocassino.github.io/phaser-toolkit/?path=/story/hudini--index)
101
+
102
+ ## 🧩 Components
103
+
104
+ ### Column
105
+
106
+ Stacks children vertically with spacing, horizontal alignment, and configurable vertical origin.
107
+
108
+ ```ts
109
+ // inside a Phaser.Scene (e.g., in create())
110
+ const spriteA = this.add.sprite(0, 0, 'player');
111
+ const spriteB = this.add.sprite(0, 0, 'enemy');
112
+
113
+ const column = new Column({
114
+ scene: this,
115
+ x: 400,
116
+ y: 300,
117
+ gap: 12, // default: 8
118
+ align: 'center', // 'left' | 'center' | 'right'
119
+ verticalOrigin: 'top', // 'top' | 'center' | 'bottom'
120
+ children: [spriteA, spriteB],
121
+ });
122
+
123
+ // Update layout options later
124
+ column.setGap(20);
125
+ column.setAlign('left');
126
+
127
+ // Add items dynamically
128
+ const spriteC = this.add.sprite(0, 0, 'coin');
129
+ column.addChild(spriteC); // triggers relayout by default
130
+ ```
131
+
132
+ Key points:
133
+
134
+ - Horizontal alignment aligns each child's left/center/right edge correctly, respecting per-child origin.
135
+ - `verticalOrigin` controls where the content starts from within the container.
136
+ - The container's position `(x, y)` is the center of the overall content area.
137
+
138
+ ### Row
139
+
140
+ Arranges children horizontally with spacing, vertical alignment, and configurable horizontal origin.
141
+
142
+ ```ts
143
+ // inside a Phaser.Scene (e.g., in create())
144
+ const heart = this.add.sprite(0, 0, 'heart');
145
+ const gem = this.add.sprite(0, 0, 'gem');
146
+
147
+ const row = new Row({
148
+ scene: this,
149
+ x: 400,
150
+ y: 80,
151
+ gap: 10, // default: 8
152
+ align: 'center', // 'top' | 'center' | 'bottom'
153
+ horizontalOrigin: 'center', // 'left' | 'center' | 'right'
154
+ children: [heart, gem],
155
+ });
156
+
157
+ row.setGap(16);
158
+ row.setAlign('top');
159
+
160
+ const star = this.add.sprite(0, 0, 'star');
161
+ row.addChild(star);
162
+ ```
163
+
164
+ Key points:
165
+
166
+ - Vertical alignment aligns each child's top/center/bottom edge correctly, respecting per-child origin.
167
+ - `horizontalOrigin` controls where the content starts from within the container.
168
+ - The container's position `(x, y)` is the center of the overall content area.
169
+
170
+ ### IconButton
171
+
172
+ An interactive circular icon button with hover and click animations, built on top of `phaser-wind` and `font-awesome-for-phaser`.
173
+
174
+ ```ts
175
+ import { IconButton } from 'hudini';
176
+ // inside a Phaser.Scene (e.g., in create())
177
+
178
+ const btn = new IconButton({
179
+ scene: this,
180
+ x: 100,
181
+ y: 100,
182
+ icon: 'solid/heart', // any IconKey from font-awesome-for-phaser
183
+ size: 'lg', // FontSizeKey or a number (px)
184
+ color: 'red', // any base color from phaser-wind (except black/white)
185
+ onClick: () => {
186
+ // your click handler
187
+ },
188
+ });
189
+
190
+ this.add.existing(btn);
191
+ ```
192
+
193
+ Notes:
194
+
195
+ - Hover scales the icon subtly, click animates press/release.
196
+ - Colors and sizes integrate with `phaser-wind` theme tokens.
197
+
198
+ ## 📦 API Surfaces
199
+
200
+ - `Column` and `Row` are `Phaser.GameObjects.Container` subclasses. Useful methods:
201
+ - `setGap(gap: number): void`
202
+ - `setAlign(...)`: Column → `'left'|'center'|'right'`, Row → `'top'|'center'|'bottom'`
203
+ - `addChild(child, relayout = true): this`
204
+ - `addChildren(children, relayout = true): this`
205
+ - `IconButton` constructor accepts `{ scene, x, y, icon, size?, color?, onClick? }`.
206
+
207
+ ## 🔗 Storybook
208
+
209
+ Explore all components and props in Storybook: [Hudini on Storybook](https://renatocassino.github.io/phaser-toolkit/?path=/story/hudini--index)
@@ -0,0 +1,88 @@
1
+ import { GameObjects, Scene } from 'phaser';
2
+ /** Horizontal alignment options for column items */
3
+ export type HorizontalAlign = 'left' | 'center' | 'right';
4
+ /** Parameters for creating a Column container */
5
+ export type ColumnParams = {
6
+ /** The scene this column belongs to */
7
+ scene: Scene;
8
+ /** X coordinate of the column */
9
+ x: number;
10
+ /** Y coordinate of the column */
11
+ y: number;
12
+ /** Gap between elements in pixels */
13
+ gap?: number;
14
+ /** Horizontal alignment of elements */
15
+ align?: HorizontalAlign;
16
+ /** Initial child elements */
17
+ children?: GameObjects.GameObject[];
18
+ /** Vertical origin point of the column */
19
+ verticalOrigin?: 'top' | 'center' | 'bottom';
20
+ };
21
+ /**
22
+ * Column is a layout container that stacks children vertically with a gap.
23
+ * The container position (x, y) represents the center of the whole column.
24
+ */
25
+ export declare class Column extends GameObjects.Container {
26
+ /** Gap between elements in pixels */
27
+ private gap;
28
+ /** Horizontal alignment of elements */
29
+ private align;
30
+ /** Vertical origin point of the column */
31
+ private verticalOrigin;
32
+ /**
33
+ * Creates a new Column container
34
+ * @param params Configuration parameters for the column
35
+ */
36
+ constructor({ scene, x, y, gap, align, children, verticalOrigin, }: ColumnParams);
37
+ /**
38
+ * Sets the spacing between children and relayouts
39
+ * @param gap Gap in pixels between elements
40
+ */
41
+ setGap(gap: number): void;
42
+ /**
43
+ * Sets the horizontal alignment and relayouts
44
+ * @param align New horizontal alignment
45
+ */
46
+ setAlign(align: HorizontalAlign): void;
47
+ /**
48
+ * Adds a child game object to the column
49
+ * @param child Game object to add
50
+ * @param relayout Whether to relayout after adding (default: true)
51
+ * @returns This column instance for chaining
52
+ */
53
+ addChild(child: GameObjects.GameObject, relayout?: boolean): this;
54
+ /**
55
+ * Adds multiple children to the column
56
+ * @param children Array of game objects to add
57
+ * @param relayout Whether to relayout after adding (default: true)
58
+ * @returns This column instance for chaining
59
+ */
60
+ addChildren(children: GameObjects.GameObject[], relayout?: boolean): this;
61
+ /**
62
+ * Recomputes children's positions and updates this container size
63
+ * Positions are calculated based on alignment, origins and gaps
64
+ */
65
+ layout(): void;
66
+ /**
67
+ * Gets the display width of a game object
68
+ * @param child GameObject to measure
69
+ * @returns Display width in pixels
70
+ */
71
+ getDisplayWidth(child: GameObjects.GameObject): number;
72
+ /**
73
+ * Gets the display height of a game object
74
+ * @param child GameObject to measure
75
+ * @returns Display height in pixels
76
+ */
77
+ getDisplayHeight(child: GameObjects.GameObject): number;
78
+ /**
79
+ * Gets the normalized origin point of a game object
80
+ * @param child GameObject to get origin from
81
+ * @returns Object with normalized x,y coordinates of the origin point
82
+ */
83
+ getNormalizedOrigin(child: GameObjects.GameObject): {
84
+ x: number;
85
+ y: number;
86
+ };
87
+ }
88
+ //# sourceMappingURL=column.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column.d.ts","sourceRoot":"","sources":["../../../src/components/column/column.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAS5C,oDAAoD;AACpD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,iDAAiD;AACjD,MAAM,MAAM,YAAY,GAAG;IACzB,uCAAuC;IACvC,KAAK,EAAE,KAAK,CAAC;IACb,iCAAiC;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,iCAAiC;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,EAAE,CAAC;IACpC,0CAA0C;IAC1C,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC9C,CAAC;AAEF;;;GAGG;AACH,qBAAa,MAAO,SAAQ,WAAW,CAAC,SAAS;IAC/C,qCAAqC;IACrC,OAAO,CAAC,GAAG,CAAS;IACpB,uCAAuC;IACvC,OAAO,CAAC,KAAK,CAAkB;IAC/B,0CAA0C;IAC1C,OAAO,CAAC,cAAc,CAA8B;IAEpD;;;OAGG;gBACS,EACV,KAAK,EACL,CAAC,EACD,CAAC,EACD,GAAiB,EACjB,KAAgB,EAChB,QAAa,EACb,cAAsB,GACvB,EAAE,YAAY;IAaf;;;OAGG;IACI,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKhC;;;OAGG;IACI,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAK7C;;;;;OAKG;IACI,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,EAAE,QAAQ,GAAE,OAAc,GAAG,IAAI;IAM9E;;;;;OAKG;IACI,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,EAAE,EAAE,QAAQ,GAAE,OAAc,GAAG,IAAI;IAMtF;;;OAGG;IACI,MAAM,IAAI,IAAI;IAkDrB;;;;OAIG;IACI,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG,MAAM;IAI7D;;;;OAIG;IACI,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG,MAAM;IAI9D;;;;OAIG;IACI,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;CAGpF"}
@@ -0,0 +1,142 @@
1
+ /* eslint-disable complexity */
2
+ import { GameObjects } from 'phaser';
3
+ import { DEFAULT_GAP, getDisplayHeightOf, getDisplayWidthOf, getNormalizedOriginOf, } from '../layout/layout-utils';
4
+ /**
5
+ * Column is a layout container that stacks children vertically with a gap.
6
+ * The container position (x, y) represents the center of the whole column.
7
+ */
8
+ export class Column extends GameObjects.Container {
9
+ /** Gap between elements in pixels */
10
+ gap;
11
+ /** Horizontal alignment of elements */
12
+ align;
13
+ /** Vertical origin point of the column */
14
+ verticalOrigin;
15
+ /**
16
+ * Creates a new Column container
17
+ * @param params Configuration parameters for the column
18
+ */
19
+ constructor({ scene, x, y, gap = DEFAULT_GAP, align = 'center', children = [], verticalOrigin = 'top', }) {
20
+ super(scene, x, y);
21
+ this.gap = gap;
22
+ this.align = align;
23
+ this.verticalOrigin = verticalOrigin;
24
+ if (children.length > 0) {
25
+ this.add(children);
26
+ }
27
+ this.layout();
28
+ }
29
+ /**
30
+ * Sets the spacing between children and relayouts
31
+ * @param gap Gap in pixels between elements
32
+ */
33
+ setGap(gap) {
34
+ this.gap = gap;
35
+ this.layout();
36
+ }
37
+ /**
38
+ * Sets the horizontal alignment and relayouts
39
+ * @param align New horizontal alignment
40
+ */
41
+ setAlign(align) {
42
+ this.align = align;
43
+ this.layout();
44
+ }
45
+ /**
46
+ * Adds a child game object to the column
47
+ * @param child Game object to add
48
+ * @param relayout Whether to relayout after adding (default: true)
49
+ * @returns This column instance for chaining
50
+ */
51
+ addChild(child, relayout = true) {
52
+ this.add(child);
53
+ if (relayout)
54
+ this.layout();
55
+ return this;
56
+ }
57
+ /**
58
+ * Adds multiple children to the column
59
+ * @param children Array of game objects to add
60
+ * @param relayout Whether to relayout after adding (default: true)
61
+ * @returns This column instance for chaining
62
+ */
63
+ addChildren(children, relayout = true) {
64
+ if (children.length > 0)
65
+ this.add(children);
66
+ if (relayout)
67
+ this.layout();
68
+ return this;
69
+ }
70
+ /**
71
+ * Recomputes children's positions and updates this container size
72
+ * Positions are calculated based on alignment, origins and gaps
73
+ */
74
+ layout() {
75
+ const children = this.list;
76
+ if (children.length === 0) {
77
+ // Reset size when empty
78
+ this.setSize(0, 0);
79
+ return;
80
+ }
81
+ // Measure sizes and origins
82
+ const entries = children.map((child) => ({
83
+ child,
84
+ width: this.getDisplayWidth(child),
85
+ height: this.getDisplayHeight(child),
86
+ origin: this.getNormalizedOrigin(child),
87
+ }));
88
+ const maxWidth = entries.reduce((m, s) => Math.max(m, s.width), 0);
89
+ const totalHeight = entries.reduce((sum, s) => sum + s.height, 0) + this.gap * (entries.length - 1);
90
+ // Determine top of content based on verticalOrigin
91
+ const contentTopY = this.verticalOrigin === 'top' ? 0 : this.verticalOrigin === 'center' ? -totalHeight / 2 : -totalHeight;
92
+ // Walk from top to bottom, aligning considering each child's origin
93
+ let cursorTopY = contentTopY;
94
+ for (const { child, width, height, origin } of entries) {
95
+ // Horizontal alignment: align left/right edges or centers correctly using origin
96
+ let x = 0;
97
+ if (this.align === 'left') {
98
+ // place child's left edge at content left
99
+ x = -maxWidth / 2 + origin.x * width;
100
+ }
101
+ else if (this.align === 'right') {
102
+ // place child's right edge at content right
103
+ x = maxWidth / 2 - (1 - origin.x) * width;
104
+ }
105
+ else {
106
+ // center alignment: center of child at 0 accounting for origin
107
+ x = (origin.x - 0.5) * width;
108
+ }
109
+ // Vertical position so that child's top is at cursorTopY
110
+ const y = cursorTopY + origin.y * height;
111
+ child.setPosition(x, y);
112
+ cursorTopY += height + this.gap;
113
+ }
114
+ // Update this container size to match content bounds
115
+ this.setSize(maxWidth, totalHeight);
116
+ }
117
+ /**
118
+ * Gets the display width of a game object
119
+ * @param child GameObject to measure
120
+ * @returns Display width in pixels
121
+ */
122
+ getDisplayWidth(child) {
123
+ return getDisplayWidthOf(child);
124
+ }
125
+ /**
126
+ * Gets the display height of a game object
127
+ * @param child GameObject to measure
128
+ * @returns Display height in pixels
129
+ */
130
+ getDisplayHeight(child) {
131
+ return getDisplayHeightOf(child);
132
+ }
133
+ /**
134
+ * Gets the normalized origin point of a game object
135
+ * @param child GameObject to get origin from
136
+ * @returns Object with normalized x,y coordinates of the origin point
137
+ */
138
+ getNormalizedOrigin(child) {
139
+ return getNormalizedOriginOf(child);
140
+ }
141
+ }
142
+ //# sourceMappingURL=column.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column.js","sourceRoot":"","sources":["../../../src/components/column/column.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=column.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column.spec.d.ts","sourceRoot":"","sources":["../../../src/components/column/column.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,147 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ /* eslint-disable max-lines-per-function */
3
+ import { Scene } from 'phaser';
4
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
5
+ // Mock to phaser with type to avoid canvas dependency in runtime
6
+ vi.mock('phaser', () => {
7
+ class Scene {
8
+ }
9
+ class Container {
10
+ list = [];
11
+ x;
12
+ y;
13
+ width = 0;
14
+ height = 0;
15
+ // scene is accepted but not used in the mock
16
+ constructor(_scene, x, y) {
17
+ this.x = x;
18
+ this.y = y;
19
+ }
20
+ add(child) {
21
+ if (Array.isArray(child)) {
22
+ this.list.push(...child);
23
+ }
24
+ else {
25
+ this.list.push(child);
26
+ }
27
+ return this;
28
+ }
29
+ setSize(width, height) {
30
+ this.width = width;
31
+ this.height = height;
32
+ return this;
33
+ }
34
+ }
35
+ const GameObjects = { Container };
36
+ return { GameObjects, Scene };
37
+ });
38
+ import { Column } from './column';
39
+ class TestChild {
40
+ displayWidth;
41
+ width;
42
+ displayHeight;
43
+ height;
44
+ originX;
45
+ originY;
46
+ displayOriginX;
47
+ displayOriginY;
48
+ lastPosition = null;
49
+ constructor(params = {}) {
50
+ Object.assign(this, params);
51
+ }
52
+ setPosition(x, y) {
53
+ this.lastPosition = { x, y };
54
+ }
55
+ getBounds() {
56
+ return {
57
+ width: this.width ?? this.displayWidth ?? 0,
58
+ height: this.height ?? this.displayHeight ?? 0,
59
+ };
60
+ }
61
+ }
62
+ let scene;
63
+ beforeEach(() => {
64
+ scene = new Scene();
65
+ });
66
+ describe('Column layout', () => {
67
+ it('centers children by default with verticalOrigin top', () => {
68
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
69
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
70
+ const col = new Column({ scene, x: 0, y: 0, gap: 10, align: 'center', verticalOrigin: 'top', children: [] });
71
+ col.addChildren([a, b]);
72
+ // After construction or addition, layout is applied
73
+ expect(a.lastPosition).toEqual({ x: 0, y: 25 }); // 0 + 0.5*50
74
+ expect(b.lastPosition).toEqual({ x: 0, y: 110 }); // (50 + 10) + 0.5*100
75
+ // width = max child width; height = sum + gaps
76
+ // maxWidth = 200; totalHeight = 50 + 100 + 10 = 160
77
+ expect(col.width).toBe(200);
78
+ expect(col.height).toBe(160);
79
+ });
80
+ it('align left positions children at content left edge', () => {
81
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
82
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
83
+ const col = new Column({ scene, x: 0, y: 0, gap: 10, align: 'left', verticalOrigin: 'top', children: [a, b] });
84
+ // maxWidth = 200
85
+ expect(a.lastPosition?.x).toBe(-50); // -maxWidth/2 + 0.5*100 = -100 + 50
86
+ expect(b.lastPosition?.x).toBe(0); // -100 + 0.5*200 = 0
87
+ expect(col.width).toBe(200);
88
+ expect(col.height).toBe(160);
89
+ });
90
+ it('align right positions children at content right edge', () => {
91
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
92
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
93
+ new Column({ scene, x: 0, y: 0, gap: 10, align: 'right', verticalOrigin: 'top', children: [a, b] });
94
+ expect(a.lastPosition?.x).toBe(50); // +maxWidth/2 - (1-0.5)*100 = 100 - 50
95
+ expect(b.lastPosition?.x).toBe(0); // 100 - (1-0.5)*200 = 0
96
+ });
97
+ it('verticalOrigin center shifts content up by half height', () => {
98
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
99
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
100
+ // totalHeight = 50 + 100 + 10 = 160; top starts at -80
101
+ new Column({ scene, x: 0, y: 0, gap: 10, align: 'center', verticalOrigin: 'center', children: [a, b] });
102
+ expect(a.lastPosition?.y).toBe(-80 + 0.5 * 50); // -55
103
+ expect(b.lastPosition?.y).toBe(-80 + 50 + 10 + 0.5 * 100); // -80 + 60 + 50 = 30
104
+ });
105
+ it('respects per-child origin when computing alignment and positions', () => {
106
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50, originX: 0.0, originY: 0.0 });
107
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100, originX: 1.0, originY: 1.0 });
108
+ // maxWidth = 200; totalHeight = 160; top = 0 (verticalOrigin top)
109
+ new Column({ scene, x: 0, y: 0, gap: 10, align: 'left', verticalOrigin: 'top', children: [a, b] });
110
+ // a: x = -100 + 0*100 = -100; y = 0 + 0*50 = 0
111
+ expect(a.lastPosition).toEqual({ x: -100, y: 0 });
112
+ // cursor = 50 + 10 = 60; b: x = -100 + 1*200 = 100; y = 60 + 1*100 = 160
113
+ expect(b.lastPosition).toEqual({ x: 100, y: 160 });
114
+ });
115
+ it('setGap and setAlign trigger relayout', () => {
116
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
117
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
118
+ const col = new Column({ scene, x: 0, y: 0, children: [a, b] }); // default gap=8, align=center, verticalOrigin=top
119
+ // Initial state with gap=8
120
+ expect(b.lastPosition?.y).toBe(50 + 8 + 50); // 108
121
+ col.setGap(20); // changes layout
122
+ expect(b.lastPosition?.y).toBe(50 + 20 + 50); // 120
123
+ col.setAlign('left');
124
+ // maxWidth=200 => a.x = -100 + 0.5*100 = -50; b.x = -100 + 0.5*200 = 0
125
+ expect(a.lastPosition?.x).toBe(-50);
126
+ expect(b.lastPosition?.x).toBe(0);
127
+ });
128
+ it('addChild/addChildren optionally avoid relayout when requested', () => {
129
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
130
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
131
+ const col = new Column({ scene, x: 0, y: 0, children: [a] });
132
+ // b added without relayout
133
+ col.addChild(b, false);
134
+ const before = b.lastPosition;
135
+ expect(before).toBeNull();
136
+ // When calling layout, positions are calculated
137
+ col.layout();
138
+ expect(b.lastPosition).not.toBeNull();
139
+ });
140
+ it('empty column has size 0,0', () => {
141
+ const col = new Column({ scene, x: 0, y: 0, children: [] });
142
+ // After constructor, layout runs and sizes to 0,0
143
+ expect(col.width).toBe(0);
144
+ expect(col.height).toBe(0);
145
+ });
146
+ });
147
+ //# sourceMappingURL=column.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column.spec.js","sourceRoot":"","sources":["../../../src/components/column/column.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './column';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/column/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './column';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/column/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
@@ -1,2 +1,4 @@
1
+ export * from './column';
1
2
  export * from './icon-button';
3
+ export * from './row';
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC"}
@@ -1,2 +1,4 @@
1
+ export * from './column';
1
2
  export * from './icon-button';
3
+ export * from './row';
2
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { GameObjects } from 'phaser';
2
+ /** Default gap between elements in pixels */
3
+ export declare const DEFAULT_GAP = 8;
4
+ /** Measures the display width of a game object, with fallbacks */
5
+ export declare const getDisplayWidthOf: (child: GameObjects.GameObject) => number;
6
+ /** Measures the display height of a game object, with fallbacks */
7
+ export declare const getDisplayHeightOf: (child: GameObjects.GameObject) => number;
8
+ /** Returns normalized origin (0..1) for a game object */
9
+ export declare const getNormalizedOriginOf: (child: GameObjects.GameObject) => {
10
+ x: number;
11
+ y: number;
12
+ };
13
+ //# sourceMappingURL=layout-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-utils.d.ts","sourceRoot":"","sources":["../../../src/components/layout/layout-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,6CAA6C;AAC7C,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,GAAI,OAAO,WAAW,CAAC,UAAU,KAAG,MAUjE,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,GAAI,OAAO,WAAW,CAAC,UAAU,KAAG,MAUlE,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,qBAAqB,GAAI,OAAO,WAAW,CAAC,UAAU,KAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAwB3F,CAAC"}
@@ -0,0 +1,38 @@
1
+ /** Default gap between elements in pixels */
2
+ export const DEFAULT_GAP = 8;
3
+ /** Measures the display width of a game object, with fallbacks */
4
+ export const getDisplayWidthOf = (child) => {
5
+ const childTyped = child;
6
+ if (typeof childTyped.displayWidth === 'number')
7
+ return childTyped.displayWidth;
8
+ if (typeof childTyped.width === 'number')
9
+ return childTyped.width;
10
+ const bounds = childTyped.getBounds?.();
11
+ return bounds ? bounds.width : 0;
12
+ };
13
+ /** Measures the display height of a game object, with fallbacks */
14
+ export const getDisplayHeightOf = (child) => {
15
+ const childTyped = child;
16
+ if (typeof childTyped.displayHeight === 'number')
17
+ return childTyped.displayHeight;
18
+ if (typeof childTyped.height === 'number')
19
+ return childTyped.height;
20
+ const bounds = childTyped.getBounds?.();
21
+ return bounds ? bounds.height : 0;
22
+ };
23
+ /** Returns normalized origin (0..1) for a game object */
24
+ export const getNormalizedOriginOf = (child) => {
25
+ const width = getDisplayWidthOf(child);
26
+ const height = getDisplayHeightOf(child);
27
+ const childTyped = child;
28
+ let ox = typeof childTyped.originX === 'number' ? childTyped.originX : undefined;
29
+ let oy = typeof childTyped.originY === 'number' ? childTyped.originY : undefined;
30
+ if (ox === undefined && typeof childTyped.displayOriginX === 'number' && width > 0) {
31
+ ox = childTyped.displayOriginX / width;
32
+ }
33
+ if (oy === undefined && typeof childTyped.displayOriginY === 'number' && height > 0) {
34
+ oy = childTyped.displayOriginY / height;
35
+ }
36
+ return { x: ox ?? 0.5, y: oy ?? 0.5 };
37
+ };
38
+ //# sourceMappingURL=layout-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-utils.js","sourceRoot":"","sources":["../../../src/components/layout/layout-utils.ts"],"names":[],"mappings":"AAGA,6CAA6C;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,kEAAkE;AAClE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAAU,EAAE;IACzE,MAAM,UAAU,GAAG,KAIlB,CAAC;IACF,IAAI,OAAO,UAAU,CAAC,YAAY,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,YAAY,CAAC;IAChF,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,KAAe,CAAC;IAC5E,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,mEAAmE;AACnE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAA6B,EAAU,EAAE;IAC1E,MAAM,UAAU,GAAG,KAIlB,CAAC;IACF,IAAI,OAAO,UAAU,CAAC,aAAa,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,aAAa,CAAC;IAClF,IAAI,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,MAAgB,CAAC;IAC9E,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAA6B,EAA4B,EAAE;IAC/F,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAEzC,MAAM,UAAU,GAAG,KAKlB,CAAC;IAEF,IAAI,EAAE,GACJ,OAAO,UAAU,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,IAAI,EAAE,GACJ,OAAO,UAAU,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1E,IAAI,EAAE,KAAK,SAAS,IAAI,OAAO,UAAU,CAAC,cAAc,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACnF,EAAE,GAAG,UAAU,CAAC,cAAc,GAAG,KAAK,CAAC;IACzC,CAAC;IACD,IAAI,EAAE,KAAK,SAAS,IAAI,OAAO,UAAU,CAAC,cAAc,KAAK,QAAQ,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACpF,EAAE,GAAG,UAAU,CAAC,cAAc,GAAG,MAAM,CAAC;IAC1C,CAAC;IAED,OAAO,EAAE,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC;AACxC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=layout-utils.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-utils.spec.d.ts","sourceRoot":"","sources":["../../../src/components/layout/layout-utils.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { DEFAULT_GAP, getDisplayHeightOf, getDisplayWidthOf, getNormalizedOriginOf, } from './layout-utils';
3
+ // Helper to satisfy typing without importing Phaser types in tests
4
+ const asGO = (o) => o;
5
+ describe('layout-utils', () => {
6
+ it('DEFAULT_GAP should be 8', () => {
7
+ expect(DEFAULT_GAP).toBe(8);
8
+ });
9
+ describe('getDisplayWidthOf', () => {
10
+ it('prefers displayWidth when present', () => {
11
+ const obj = asGO({ displayWidth: 120, width: 200, getBounds: () => ({ width: 300 }) });
12
+ expect(getDisplayWidthOf(obj)).toBe(120);
13
+ });
14
+ it('falls back to width when displayWidth is absent', () => {
15
+ const obj = asGO({ width: 200, getBounds: () => ({ width: 300 }) });
16
+ expect(getDisplayWidthOf(obj)).toBe(200);
17
+ });
18
+ it('falls back to getBounds().width when both displayWidth and width are absent', () => {
19
+ const obj = asGO({ getBounds: () => ({ width: 300 }) });
20
+ expect(getDisplayWidthOf(obj)).toBe(300);
21
+ });
22
+ it('returns 0 when nothing is available', () => {
23
+ const obj = asGO({});
24
+ expect(getDisplayWidthOf(obj)).toBe(0);
25
+ });
26
+ });
27
+ describe('getDisplayHeightOf', () => {
28
+ it('prefers displayHeight when present', () => {
29
+ const obj = asGO({ displayHeight: 110, height: 210, getBounds: () => ({ height: 310 }) });
30
+ expect(getDisplayHeightOf(obj)).toBe(110);
31
+ });
32
+ it('falls back to height when displayHeight is absent', () => {
33
+ const obj = asGO({ height: 210, getBounds: () => ({ height: 310 }) });
34
+ expect(getDisplayHeightOf(obj)).toBe(210);
35
+ });
36
+ it('falls back to getBounds().height when both displayHeight and height are absent', () => {
37
+ const obj = asGO({ getBounds: () => ({ height: 310 }) });
38
+ expect(getDisplayHeightOf(obj)).toBe(310);
39
+ });
40
+ it('returns 0 when nothing is available', () => {
41
+ const obj = asGO({});
42
+ expect(getDisplayHeightOf(obj)).toBe(0);
43
+ });
44
+ });
45
+ describe('getNormalizedOriginOf', () => {
46
+ it('returns originX/Y when provided', () => {
47
+ const obj = asGO({ originX: 0.2, originY: 0.8, displayWidth: 100, displayHeight: 100 });
48
+ expect(getNormalizedOriginOf(obj)).toEqual({ x: 0.2, y: 0.8 });
49
+ });
50
+ it('computes from displayOriginX/Y over displayWidth/Height when originX/Y absent', () => {
51
+ const obj = asGO({ displayOriginX: 25, displayOriginY: 50, displayWidth: 100, displayHeight: 200 });
52
+ // x = 25/100 = 0.25, y = 50/200 = 0.25
53
+ expect(getNormalizedOriginOf(obj)).toEqual({ x: 0.25, y: 0.25 });
54
+ });
55
+ it('defaults to 0.5 when origins are missing and size is zero', () => {
56
+ const obj = asGO({ displayOriginX: 10, displayOriginY: 10, displayWidth: 0, displayHeight: 0 });
57
+ expect(getNormalizedOriginOf(obj)).toEqual({ x: 0.5, y: 0.5 });
58
+ });
59
+ it('uses mixed fallbacks per axis independently', () => {
60
+ const obj = asGO({
61
+ originX: 0.1, // should take precedence on X
62
+ displayOriginY: 30,
63
+ displayHeight: 120, // Y should be 30/120 = 0.25
64
+ displayWidth: 400,
65
+ });
66
+ expect(getNormalizedOriginOf(obj)).toEqual({ x: 0.1, y: 0.25 });
67
+ });
68
+ });
69
+ });
70
+ //# sourceMappingURL=layout-utils.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-utils.spec.js","sourceRoot":"","sources":["../../../src/components/layout/layout-utils.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './row';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/row/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './row';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/row/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { GameObjects, Scene } from 'phaser';
2
+ /** Vertical alignment options for row items */
3
+ export type VerticalAlign = 'top' | 'center' | 'bottom';
4
+ /** Parameters for creating a Row container */
5
+ export type RowParams = {
6
+ /** The scene this row belongs to */
7
+ scene: Scene;
8
+ /** X coordinate of the row */
9
+ x: number;
10
+ /** Y coordinate of the row */
11
+ y: number;
12
+ /** Gap between elements in pixels */
13
+ gap?: number;
14
+ /** Vertical alignment of elements */
15
+ align?: VerticalAlign;
16
+ /** Initial child elements */
17
+ children?: GameObjects.GameObject[];
18
+ /** Horizontal origin point of the row */
19
+ horizontalOrigin?: 'left' | 'center' | 'right';
20
+ };
21
+ /**
22
+ * Row is a layout container that arranges children horizontally with a gap.
23
+ * The container position (x, y) represents the center of the whole row.
24
+ */
25
+ export declare class Row extends GameObjects.Container {
26
+ /** Gap between elements in pixels */
27
+ private gap;
28
+ /** Vertical alignment of elements */
29
+ private align;
30
+ /** Horizontal origin point of the row */
31
+ private horizontalOrigin;
32
+ /**
33
+ * Creates a new Row container
34
+ * @param params Configuration parameters for the row
35
+ */
36
+ constructor({ scene, x, y, gap, align, children, horizontalOrigin, }: RowParams);
37
+ /**
38
+ * Sets the gap between elements and updates layout
39
+ * @param gap Gap size in pixels
40
+ */
41
+ setGap(gap: number): void;
42
+ /**
43
+ * Sets the vertical alignment and updates layout
44
+ * @param align New vertical alignment
45
+ */
46
+ setAlign(align: VerticalAlign): void;
47
+ /**
48
+ * Adds a single child to the row
49
+ * @param child GameObject to add
50
+ * @param relayout Whether to update layout after adding
51
+ * @returns This row instance for chaining
52
+ */
53
+ addChild(child: GameObjects.GameObject, relayout?: boolean): this;
54
+ /**
55
+ * Adds multiple children to the row
56
+ * @param children Array of GameObjects to add
57
+ * @param relayout Whether to update layout after adding
58
+ * @returns This row instance for chaining
59
+ */
60
+ addChildren(children: GameObjects.GameObject[], relayout?: boolean): this;
61
+ /**
62
+ * Recomputes children's positions and updates this container size
63
+ */
64
+ layout(): void;
65
+ /**
66
+ * Gets the display width of a game object
67
+ * @param child GameObject to measure
68
+ * @returns Display width in pixels
69
+ */
70
+ getDisplayWidth(child: GameObjects.GameObject): number;
71
+ /**
72
+ * Gets the display height of a game object
73
+ * @param child GameObject to measure
74
+ * @returns Display height in pixels
75
+ */
76
+ getDisplayHeight(child: GameObjects.GameObject): number;
77
+ /**
78
+ * Gets the normalized origin point of a game object
79
+ * @param child GameObject to get origin from
80
+ * @returns Object with normalized x,y coordinates of the origin point
81
+ */
82
+ getNormalizedOrigin(child: GameObjects.GameObject): {
83
+ x: number;
84
+ y: number;
85
+ };
86
+ }
87
+ //# sourceMappingURL=row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row.d.ts","sourceRoot":"","sources":["../../../src/components/row/row.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAS5C,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,oCAAoC;IACpC,KAAK,EAAE,KAAK,CAAC;IACb,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,EAAE,CAAC;IACpC,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CAChD,CAAC;AAEF;;;GAGG;AACH,qBAAa,GAAI,SAAQ,WAAW,CAAC,SAAS;IAC5C,qCAAqC;IACrC,OAAO,CAAC,GAAG,CAAS;IACpB,qCAAqC;IACrC,OAAO,CAAC,KAAK,CAAgB;IAC7B,yCAAyC;IACzC,OAAO,CAAC,gBAAgB,CAA8B;IAEtD;;;OAGG;gBACS,EACV,KAAK,EACL,CAAC,EACD,CAAC,EACD,GAAiB,EACjB,KAAgB,EAChB,QAAa,EACb,gBAA2B,GAC5B,EAAE,SAAS;IAcZ;;;OAGG;IACI,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKhC;;;OAGG;IACI,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAK3C;;;;;OAKG;IACI,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,EAAE,QAAQ,GAAE,OAAc,GAAG,IAAI;IAM9E;;;;;OAKG;IACI,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,EAAE,EAAE,QAAQ,GAAE,OAAc,GAAG,IAAI;IAMtF;;OAEG;IACI,MAAM,IAAI,IAAI;IAgDrB;;;;OAIG;IACI,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG,MAAM;IAI7D;;;;OAIG;IACI,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG,MAAM;IAI9D;;;;OAIG;IACI,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;CAGpF"}
@@ -0,0 +1,139 @@
1
+ /* eslint-disable complexity */
2
+ import { GameObjects } from 'phaser';
3
+ import { DEFAULT_GAP, getDisplayHeightOf, getDisplayWidthOf, getNormalizedOriginOf, } from '../layout/layout-utils';
4
+ /**
5
+ * Row is a layout container that arranges children horizontally with a gap.
6
+ * The container position (x, y) represents the center of the whole row.
7
+ */
8
+ export class Row extends GameObjects.Container {
9
+ /** Gap between elements in pixels */
10
+ gap;
11
+ /** Vertical alignment of elements */
12
+ align;
13
+ /** Horizontal origin point of the row */
14
+ horizontalOrigin;
15
+ /**
16
+ * Creates a new Row container
17
+ * @param params Configuration parameters for the row
18
+ */
19
+ constructor({ scene, x, y, gap = DEFAULT_GAP, align = 'center', children = [], horizontalOrigin = 'center', }) {
20
+ super(scene, x, y);
21
+ this.gap = gap;
22
+ this.align = align;
23
+ this.horizontalOrigin = horizontalOrigin;
24
+ if (children.length > 0) {
25
+ this.add(children);
26
+ }
27
+ this.layout();
28
+ }
29
+ /**
30
+ * Sets the gap between elements and updates layout
31
+ * @param gap Gap size in pixels
32
+ */
33
+ setGap(gap) {
34
+ this.gap = gap;
35
+ this.layout();
36
+ }
37
+ /**
38
+ * Sets the vertical alignment and updates layout
39
+ * @param align New vertical alignment
40
+ */
41
+ setAlign(align) {
42
+ this.align = align;
43
+ this.layout();
44
+ }
45
+ /**
46
+ * Adds a single child to the row
47
+ * @param child GameObject to add
48
+ * @param relayout Whether to update layout after adding
49
+ * @returns This row instance for chaining
50
+ */
51
+ addChild(child, relayout = true) {
52
+ this.add(child);
53
+ if (relayout)
54
+ this.layout();
55
+ return this;
56
+ }
57
+ /**
58
+ * Adds multiple children to the row
59
+ * @param children Array of GameObjects to add
60
+ * @param relayout Whether to update layout after adding
61
+ * @returns This row instance for chaining
62
+ */
63
+ addChildren(children, relayout = true) {
64
+ if (children.length > 0)
65
+ this.add(children);
66
+ if (relayout)
67
+ this.layout();
68
+ return this;
69
+ }
70
+ /**
71
+ * Recomputes children's positions and updates this container size
72
+ */
73
+ layout() {
74
+ const children = this.list;
75
+ if (children.length === 0) {
76
+ this.setSize(0, 0);
77
+ return;
78
+ }
79
+ // Measure sizes and origins
80
+ const entries = children.map((child) => ({
81
+ child,
82
+ width: this.getDisplayWidth(child),
83
+ height: this.getDisplayHeight(child),
84
+ origin: this.getNormalizedOrigin(child),
85
+ }));
86
+ const maxHeight = entries.reduce((m, s) => Math.max(m, s.height), 0);
87
+ const totalWidth = entries.reduce((sum, s) => sum + s.width, 0) + this.gap * (entries.length - 1);
88
+ // Determine left of content based on horizontalOrigin
89
+ const contentLeftX = this.horizontalOrigin === 'left' ? 0 : this.horizontalOrigin === 'center' ? -totalWidth / 2 : -totalWidth;
90
+ // Walk left to right, aligning considering each child's origin
91
+ let cursorLeftX = contentLeftX;
92
+ for (const { child, width, height, origin } of entries) {
93
+ // Vertical alignment: align top/bottom edges or centers correctly using origin
94
+ let y = 0;
95
+ if (this.align === 'top') {
96
+ // place child's top edge at content top
97
+ y = -maxHeight / 2 + origin.y * height;
98
+ }
99
+ else if (this.align === 'bottom') {
100
+ // place child's bottom edge at content bottom
101
+ y = maxHeight / 2 - (1 - origin.y) * height;
102
+ }
103
+ else {
104
+ // center alignment
105
+ y = (origin.y - 0.5) * height;
106
+ }
107
+ // Horizontal position so that child's left is at cursorLeftX
108
+ const x = cursorLeftX + origin.x * width;
109
+ child.setPosition(x, y);
110
+ cursorLeftX += width + this.gap;
111
+ }
112
+ this.setSize(totalWidth, maxHeight);
113
+ }
114
+ /**
115
+ * Gets the display width of a game object
116
+ * @param child GameObject to measure
117
+ * @returns Display width in pixels
118
+ */
119
+ getDisplayWidth(child) {
120
+ return getDisplayWidthOf(child);
121
+ }
122
+ /**
123
+ * Gets the display height of a game object
124
+ * @param child GameObject to measure
125
+ * @returns Display height in pixels
126
+ */
127
+ getDisplayHeight(child) {
128
+ return getDisplayHeightOf(child);
129
+ }
130
+ /**
131
+ * Gets the normalized origin point of a game object
132
+ * @param child GameObject to get origin from
133
+ * @returns Object with normalized x,y coordinates of the origin point
134
+ */
135
+ getNormalizedOrigin(child) {
136
+ return getNormalizedOriginOf(child);
137
+ }
138
+ }
139
+ //# sourceMappingURL=row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row.js","sourceRoot":"","sources":["../../../src/components/row/row.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=row.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row.spec.d.ts","sourceRoot":"","sources":["../../../src/components/row/row.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ /* eslint-disable max-lines-per-function */
3
+ import { Scene } from 'phaser';
4
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
5
+ // Typed mock of 'phaser' to avoid canvas dependency
6
+ vi.mock('phaser', () => {
7
+ class Scene {
8
+ }
9
+ class Container {
10
+ list = [];
11
+ x;
12
+ y;
13
+ width = 0;
14
+ height = 0;
15
+ constructor(_scene, x, y) {
16
+ this.x = x;
17
+ this.y = y;
18
+ }
19
+ add(child) {
20
+ if (Array.isArray(child)) {
21
+ this.list.push(...child);
22
+ }
23
+ else {
24
+ this.list.push(child);
25
+ }
26
+ return this;
27
+ }
28
+ setSize(width, height) {
29
+ this.width = width;
30
+ this.height = height;
31
+ return this;
32
+ }
33
+ }
34
+ const GameObjects = { Container };
35
+ return { GameObjects, Scene };
36
+ });
37
+ import { Row } from './row';
38
+ class TestChild {
39
+ displayWidth;
40
+ width;
41
+ displayHeight;
42
+ height;
43
+ originX;
44
+ originY;
45
+ displayOriginX;
46
+ displayOriginY;
47
+ lastPosition = null;
48
+ constructor(params = {}) {
49
+ Object.assign(this, params);
50
+ }
51
+ setPosition(x, y) {
52
+ this.lastPosition = { x, y };
53
+ }
54
+ getBounds() {
55
+ return {
56
+ width: this.width ?? this.displayWidth ?? 0,
57
+ height: this.height ?? this.displayHeight ?? 0,
58
+ };
59
+ }
60
+ }
61
+ let scene;
62
+ beforeEach(() => {
63
+ scene = new Scene();
64
+ });
65
+ describe('Row layout', () => {
66
+ it('centers children by default with horizontalOrigin center', () => {
67
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
68
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
69
+ const row = new Row({ scene, x: 0, y: 0, gap: 10, align: 'center', horizontalOrigin: 'center', children: [] });
70
+ row.addChildren([a, b]);
71
+ // totalWidth = 100 + 200 + 10 = 310; contentLeft = -155
72
+ expect(a.lastPosition).toEqual({ x: -155 + 0.5 * 100, y: 0 }); // -105, 0
73
+ expect(b.lastPosition).toEqual({ x: -45 + 0.5 * 200, y: 0 }); // 55, 0
74
+ // width = totalWidth; height = max child height
75
+ expect(row.width).toBe(310);
76
+ expect(row.height).toBe(100);
77
+ });
78
+ it('align top positions children at content top edge', () => {
79
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
80
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
81
+ const row = new Row({ scene, x: 0, y: 0, gap: 10, align: 'top', horizontalOrigin: 'center', children: [a, b] });
82
+ // maxHeight = 100
83
+ expect(a.lastPosition?.y).toBe(-50 + 0.5 * 50); // -25
84
+ expect(b.lastPosition?.y).toBe(-50 + 0.5 * 100); // 0
85
+ expect(row.width).toBe(310);
86
+ expect(row.height).toBe(100);
87
+ });
88
+ it('align bottom positions children at content bottom edge', () => {
89
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
90
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
91
+ new Row({ scene, x: 0, y: 0, gap: 10, align: 'bottom', horizontalOrigin: 'center', children: [a, b] });
92
+ expect(a.lastPosition?.y).toBe(50 - (1 - 0.5) * 50); // 25
93
+ expect(b.lastPosition?.y).toBe(50 - (1 - 0.5) * 100); // 0
94
+ });
95
+ it('horizontalOrigin left places content starting at x=0', () => {
96
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
97
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
98
+ const row = new Row({ scene, x: 0, y: 0, gap: 10, align: 'center', horizontalOrigin: 'left', children: [a, b] });
99
+ expect(a.lastPosition?.x).toBe(0 + 0.5 * 100); // 50
100
+ expect(b.lastPosition?.x).toBe(110 + 0.5 * 200); // 210
101
+ expect(row.width).toBe(310);
102
+ expect(row.height).toBe(100);
103
+ });
104
+ it('respects per-child origin when computing alignment and positions', () => {
105
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50, originX: 0.0, originY: 0.0 });
106
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100, originX: 1.0, originY: 1.0 });
107
+ // totalWidth = 310; left = 0 (horizontalOrigin left); maxHeight = 100
108
+ new Row({ scene, x: 0, y: 0, gap: 10, align: 'top', horizontalOrigin: 'left', children: [a, b] });
109
+ // a: x = 0 + 0*100 = 0; y = -50 + 0*50 = -50
110
+ expect(a.lastPosition).toEqual({ x: 0, y: -50 });
111
+ // cursor = 0 + 100 + 10 = 110; b: x = 110 + 1*200 = 310; y = -50 + 1*100 = 50
112
+ expect(b.lastPosition).toEqual({ x: 310, y: 50 });
113
+ });
114
+ it('setGap and setAlign trigger relayout', () => {
115
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
116
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
117
+ const row = new Row({ scene, x: 0, y: 0, children: [a, b] }); // default gap=8, align=center, horizontalOrigin=center
118
+ // Initial container width with gap=8
119
+ const initialWidth = row.width;
120
+ row.setGap(20); // triggers layout
121
+ const afterWidth = row.width;
122
+ expect(afterWidth).toBe(initialWidth + (20 - 8));
123
+ row.setAlign('top');
124
+ // For align top, y positions as computed earlier with maxHeight=100
125
+ expect(a.lastPosition?.y).toBe(-50 + 0.5 * 50); // -25
126
+ expect(b.lastPosition?.y).toBe(-50 + 0.5 * 100); // 0
127
+ });
128
+ it('addChild/addChildren optionally avoid relayout when requested', () => {
129
+ const a = new TestChild({ displayWidth: 100, displayHeight: 50 });
130
+ const b = new TestChild({ displayWidth: 200, displayHeight: 100 });
131
+ const row = new Row({ scene, x: 0, y: 0, children: [a] });
132
+ // b added without relayout
133
+ row.addChild(b, false);
134
+ const before = b.lastPosition;
135
+ expect(before).toBeNull();
136
+ // layout computes positions
137
+ row.layout();
138
+ expect(b.lastPosition).not.toBeNull();
139
+ });
140
+ it('empty row has size 0,0', () => {
141
+ const row = new Row({ scene, x: 0, y: 0, children: [] });
142
+ expect(row.width).toBe(0);
143
+ expect(row.height).toBe(0);
144
+ });
145
+ });
146
+ //# sourceMappingURL=row.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row.spec.js","sourceRoot":"","sources":["../../../src/components/row/row.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hudini",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "🎩 Magical Phaser UI components - Reusable HUD elements for game development. Is magic, like a wizard",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",