@energy8platform/game-engine 0.15.0 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +29 -19
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +29 -19
- package/dist/index.esm.js.map +1 -1
- package/dist/react-jsx.d.ts +68 -48
- package/dist/react.cjs.js +29 -19
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.d.ts +600 -1
- package/dist/react.esm.js +29 -19
- package/dist/react.esm.js.map +1 -1
- package/dist/ui.cjs.js +29 -19
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +29 -19
- package/dist/ui.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/react/index.ts +6 -0
- package/src/react/jsx-runtime.ts +102 -57
- package/src/ui/FlexContainer.ts +29 -19
package/src/react/jsx-runtime.ts
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* JSX prop types for the PixiJS React reconciler.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* The engine auto-augments `react`'s module-scoped `JSX.IntrinsicElements`
|
|
5
|
+
* with every registered element (`<flexContainer>`, `<button>`, `<label>`,
|
|
6
|
+
* `<labelValue>`, etc). Because the augmentation is scoped to the `react`
|
|
7
|
+
* module (not the legacy global `JSX` namespace), it reliably wins over
|
|
8
|
+
* `@types/react`'s HTML defaults for colliding names like `<button>` / `<label>`.
|
|
5
9
|
*
|
|
6
|
-
*
|
|
10
|
+
* **Consumers don't need any shim.** Any import from `@energy8platform/game-engine/react`
|
|
11
|
+
* (e.g. `createPixiRoot`, `extendUIElements`, `ReactScene` — you're already
|
|
12
|
+
* importing these to boot the reconciler) pulls this module in and the JSX
|
|
13
|
+
* types activate automatically.
|
|
7
14
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
15
|
+
* If a project imports only from `/ui` or `/core` and never touches `/react`,
|
|
16
|
+
* add a one-line side-effect import to trigger the augmentation:
|
|
10
17
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* // app/src/pixi-jsx.d.ts
|
|
20
|
+
* import '@energy8platform/game-engine/react-jsx';
|
|
21
|
+
* ```
|
|
13
22
|
*
|
|
14
|
-
* Dash-notation
|
|
23
|
+
* Dash-notation for nested config objects is supported:
|
|
15
24
|
* <button colors-default={0xff0000} colors-hover={0x00ff00} />
|
|
16
25
|
*/
|
|
17
26
|
|
|
@@ -34,7 +43,7 @@ import type { ToggleConfig } from '../ui/Toggle';
|
|
|
34
43
|
|
|
35
44
|
// ─── Event props ─────────────────────────────────────────
|
|
36
45
|
|
|
37
|
-
interface PixiEventProps {
|
|
46
|
+
export interface PixiEventProps {
|
|
38
47
|
onClick?: (e: any) => void;
|
|
39
48
|
onPointerDown?: (e: any) => void;
|
|
40
49
|
onPointerUp?: (e: any) => void;
|
|
@@ -58,7 +67,7 @@ interface PixiEventProps {
|
|
|
58
67
|
|
|
59
68
|
// ─── Base container props (shared by all elements) ───────
|
|
60
69
|
|
|
61
|
-
interface BaseProps extends PixiEventProps {
|
|
70
|
+
export interface BaseProps extends PixiEventProps {
|
|
62
71
|
key?: React.Key;
|
|
63
72
|
ref?: React.Ref<any>;
|
|
64
73
|
children?: React.ReactNode;
|
|
@@ -113,13 +122,13 @@ interface BaseProps extends PixiEventProps {
|
|
|
113
122
|
|
|
114
123
|
// ─── PixiJS primitive elements ───────────────────────────
|
|
115
124
|
|
|
116
|
-
interface SpriteProps extends BaseProps {
|
|
125
|
+
export interface SpriteProps extends BaseProps {
|
|
117
126
|
texture?: string | Texture;
|
|
118
127
|
anchor?: number | { x: number; y: number };
|
|
119
128
|
tint?: number;
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
interface TextProps extends BaseProps {
|
|
131
|
+
export interface TextProps extends BaseProps {
|
|
123
132
|
text?: string;
|
|
124
133
|
style?: Partial<TextStyle>;
|
|
125
134
|
anchor?: number | { x: number; y: number };
|
|
@@ -131,7 +140,7 @@ interface TextProps extends BaseProps {
|
|
|
131
140
|
'style-letterSpacing'?: number;
|
|
132
141
|
}
|
|
133
142
|
|
|
134
|
-
interface GraphicsProps extends BaseProps {
|
|
143
|
+
export interface GraphicsProps extends BaseProps {
|
|
135
144
|
/** Draw function: receives the Graphics instance, called on mount and updates */
|
|
136
145
|
draw?: (g: any) => void;
|
|
137
146
|
/**
|
|
@@ -144,9 +153,29 @@ interface GraphicsProps extends BaseProps {
|
|
|
144
153
|
height?: number;
|
|
145
154
|
}
|
|
146
155
|
|
|
156
|
+
export interface AnimatedSpriteProps extends BaseProps {
|
|
157
|
+
textures?: Texture[];
|
|
158
|
+
animationSpeed?: number;
|
|
159
|
+
loop?: boolean;
|
|
160
|
+
playing?: boolean;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface NineSliceSpriteProps extends BaseProps {
|
|
164
|
+
texture?: string | Texture;
|
|
165
|
+
leftWidth?: number;
|
|
166
|
+
topHeight?: number;
|
|
167
|
+
rightWidth?: number;
|
|
168
|
+
bottomHeight?: number;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface TilingSpriteProps extends BaseProps {
|
|
172
|
+
texture?: string | Texture;
|
|
173
|
+
tilePosition?: { x: number; y: number };
|
|
174
|
+
}
|
|
175
|
+
|
|
147
176
|
// ─── Engine UI component props ───────────────────────────
|
|
148
177
|
|
|
149
|
-
interface ButtonComponentProps extends BaseProps, Omit<ButtonConfig, 'colors' | 'textStyle'> {
|
|
178
|
+
export interface ButtonComponentProps extends BaseProps, Omit<ButtonConfig, 'colors' | 'textStyle'> {
|
|
150
179
|
// Full object form
|
|
151
180
|
colors?: Partial<Record<ButtonState, number>>;
|
|
152
181
|
textStyle?: Record<string, unknown>;
|
|
@@ -170,7 +199,7 @@ interface ButtonComponentProps extends BaseProps, Omit<ButtonConfig, 'colors' |
|
|
|
170
199
|
onPress?: () => void;
|
|
171
200
|
}
|
|
172
201
|
|
|
173
|
-
interface LabelComponentProps extends BaseProps, Omit<LabelConfig, 'style'> {
|
|
202
|
+
export interface LabelComponentProps extends BaseProps, Omit<LabelConfig, 'style'> {
|
|
174
203
|
style?: Partial<TextStyle>;
|
|
175
204
|
'style-fontSize'?: number;
|
|
176
205
|
'style-fill'?: number | string;
|
|
@@ -179,7 +208,7 @@ interface LabelComponentProps extends BaseProps, Omit<LabelConfig, 'style'> {
|
|
|
179
208
|
'style-letterSpacing'?: number;
|
|
180
209
|
}
|
|
181
210
|
|
|
182
|
-
interface LabelValueComponentProps extends Omit<BaseProps, 'width' | 'height' | 'label'>,
|
|
211
|
+
export interface LabelValueComponentProps extends Omit<BaseProps, 'width' | 'height' | 'label'>,
|
|
183
212
|
Omit<LabelValueConfig, 'labelStyle' | 'valueStyle'> {
|
|
184
213
|
labelStyle?: Partial<TextStyle>;
|
|
185
214
|
valueStyle?: Partial<TextStyle>;
|
|
@@ -196,11 +225,11 @@ interface LabelValueComponentProps extends Omit<BaseProps, 'width' | 'height' |
|
|
|
196
225
|
'valueStyle-fontWeight'?: string;
|
|
197
226
|
}
|
|
198
227
|
|
|
199
|
-
interface PanelComponentProps extends BaseProps, Omit<PanelConfig, 'layout'> {
|
|
228
|
+
export interface PanelComponentProps extends BaseProps, Omit<PanelConfig, 'layout'> {
|
|
200
229
|
layout?: Partial<FlexContainerConfig>;
|
|
201
230
|
}
|
|
202
231
|
|
|
203
|
-
interface FlexContainerComponentProps extends Omit<BaseProps, 'width' | 'height'>, FlexContainerConfig {
|
|
232
|
+
export interface FlexContainerComponentProps extends Omit<BaseProps, 'width' | 'height'>, FlexContainerConfig {
|
|
204
233
|
padding?: number | [number, number, number, number];
|
|
205
234
|
paddingTop?: number;
|
|
206
235
|
paddingRight?: number;
|
|
@@ -211,7 +240,7 @@ interface FlexContainerComponentProps extends Omit<BaseProps, 'width' | 'height'
|
|
|
211
240
|
height?: number | string;
|
|
212
241
|
}
|
|
213
242
|
|
|
214
|
-
interface ProgressBarComponentProps extends BaseProps, ProgressBarConfig {
|
|
243
|
+
export interface ProgressBarComponentProps extends BaseProps, ProgressBarConfig {
|
|
215
244
|
progress?: number;
|
|
216
245
|
/** Custom track background (string texture name, Texture, or Container) */
|
|
217
246
|
trackView?: ViewInput;
|
|
@@ -219,7 +248,7 @@ interface ProgressBarComponentProps extends BaseProps, ProgressBarConfig {
|
|
|
219
248
|
fillView?: ViewInput;
|
|
220
249
|
}
|
|
221
250
|
|
|
222
|
-
interface ScrollContainerComponentProps extends BaseProps, Omit<ScrollContainerConfig, 'width' | 'height'> {
|
|
251
|
+
export interface ScrollContainerComponentProps extends BaseProps, Omit<ScrollContainerConfig, 'width' | 'height'> {
|
|
223
252
|
width: number;
|
|
224
253
|
height: number;
|
|
225
254
|
/** Show scrollbar indicator */
|
|
@@ -232,32 +261,32 @@ interface ScrollContainerComponentProps extends BaseProps, Omit<ScrollContainerC
|
|
|
232
261
|
scrollbarAlpha?: number;
|
|
233
262
|
}
|
|
234
263
|
|
|
235
|
-
interface ModalComponentProps extends BaseProps, ModalConfig {
|
|
264
|
+
export interface ModalComponentProps extends BaseProps, ModalConfig {
|
|
236
265
|
onClose?: () => void;
|
|
237
266
|
}
|
|
238
267
|
|
|
239
|
-
interface ToastComponentProps extends BaseProps, ToastConfig {
|
|
268
|
+
export interface ToastComponentProps extends BaseProps, ToastConfig {
|
|
240
269
|
/** Custom background view */
|
|
241
270
|
backgroundView?: ViewInput;
|
|
242
271
|
}
|
|
243
272
|
|
|
244
|
-
interface BalanceDisplayComponentProps extends BaseProps, BalanceDisplayConfig {
|
|
273
|
+
export interface BalanceDisplayComponentProps extends BaseProps, BalanceDisplayConfig {
|
|
245
274
|
/** Current balance value */
|
|
246
275
|
value?: number;
|
|
247
276
|
}
|
|
248
277
|
|
|
249
|
-
interface WinDisplayComponentProps extends BaseProps, WinDisplayConfig {}
|
|
278
|
+
export interface WinDisplayComponentProps extends BaseProps, WinDisplayConfig {}
|
|
250
279
|
|
|
251
|
-
interface LayoutComponentProps extends BaseProps, LayoutConfig {}
|
|
280
|
+
export interface LayoutComponentProps extends BaseProps, LayoutConfig {}
|
|
252
281
|
|
|
253
|
-
interface SliderComponentProps extends BaseProps, Omit<SliderConfig, 'width' | 'height'> {
|
|
282
|
+
export interface SliderComponentProps extends BaseProps, Omit<SliderConfig, 'width' | 'height'> {
|
|
254
283
|
width?: number;
|
|
255
284
|
height?: number;
|
|
256
285
|
onUpdate?: (value: number) => void;
|
|
257
286
|
onChange?: (value: number) => void;
|
|
258
287
|
}
|
|
259
288
|
|
|
260
|
-
interface ToggleComponentProps extends BaseProps, Omit<ToggleConfig, 'width' | 'height'> {
|
|
289
|
+
export interface ToggleComponentProps extends BaseProps, Omit<ToggleConfig, 'width' | 'height'> {
|
|
261
290
|
width?: number;
|
|
262
291
|
height?: number;
|
|
263
292
|
onView?: ViewInput;
|
|
@@ -265,37 +294,53 @@ interface ToggleComponentProps extends BaseProps, Omit<ToggleConfig, 'width' | '
|
|
|
265
294
|
onChange?: (value: boolean) => void;
|
|
266
295
|
}
|
|
267
296
|
|
|
268
|
-
// ───
|
|
297
|
+
// ─── IntrinsicElements map ───────────────────────────────
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Complete element → prop-type map for all engine-registered JSX elements.
|
|
301
|
+
* Also consumable directly for typing custom wrappers around engine elements.
|
|
302
|
+
*/
|
|
303
|
+
export interface EngineIntrinsicElements {
|
|
304
|
+
// PixiJS primitives
|
|
305
|
+
container: BaseProps;
|
|
306
|
+
sprite: SpriteProps;
|
|
307
|
+
text: TextProps;
|
|
308
|
+
graphics: GraphicsProps;
|
|
309
|
+
animatedSprite: AnimatedSpriteProps;
|
|
310
|
+
nineSliceSprite: NineSliceSpriteProps;
|
|
311
|
+
tilingSprite: TilingSpriteProps;
|
|
312
|
+
|
|
313
|
+
// Engine UI components
|
|
314
|
+
button: ButtonComponentProps;
|
|
315
|
+
label: LabelComponentProps;
|
|
316
|
+
labelValue: LabelValueComponentProps;
|
|
317
|
+
panel: PanelComponentProps;
|
|
318
|
+
flexContainer: FlexContainerComponentProps;
|
|
319
|
+
progressBar: ProgressBarComponentProps;
|
|
320
|
+
scrollContainer: ScrollContainerComponentProps;
|
|
321
|
+
modal: ModalComponentProps;
|
|
322
|
+
toast: ToastComponentProps;
|
|
323
|
+
balanceDisplay: BalanceDisplayComponentProps;
|
|
324
|
+
winDisplay: WinDisplayComponentProps;
|
|
325
|
+
layout: LayoutComponentProps;
|
|
326
|
+
slider: SliderComponentProps;
|
|
327
|
+
toggle: ToggleComponentProps;
|
|
328
|
+
}
|
|
269
329
|
|
|
270
|
-
|
|
330
|
+
// ─── Auto-augment React's JSX namespace ──────────────────
|
|
331
|
+
//
|
|
332
|
+
// React 19 scopes `JSX.IntrinsicElements` inside `declare module 'react'`,
|
|
333
|
+
// so we augment the same module. `extends EngineIntrinsicElements {}` adds
|
|
334
|
+
// every engine element to the interface the reconciler sees.
|
|
335
|
+
//
|
|
336
|
+
// Interface merging with `@types/react`'s HTML defaults: property names
|
|
337
|
+
// unique to the engine (`flexContainer`, `labelValue`, `button` since it
|
|
338
|
+
// carries our ButtonComponentProps, etc.) merge cleanly. For HTML-colliding
|
|
339
|
+
// names (`button`, `label`), this module-scoped augmentation takes precedence
|
|
340
|
+
// over the legacy global JSX namespace in React-19 apps.
|
|
341
|
+
|
|
342
|
+
declare module 'react' {
|
|
271
343
|
namespace JSX {
|
|
272
|
-
interface IntrinsicElements {
|
|
273
|
-
// PixiJS primitives
|
|
274
|
-
container: BaseProps;
|
|
275
|
-
sprite: SpriteProps;
|
|
276
|
-
text: TextProps;
|
|
277
|
-
graphics: GraphicsProps;
|
|
278
|
-
animatedSprite: BaseProps & { textures?: Texture[]; animationSpeed?: number; loop?: boolean; playing?: boolean };
|
|
279
|
-
nineSliceSprite: BaseProps & { texture?: string | Texture; leftWidth?: number; topHeight?: number; rightWidth?: number; bottomHeight?: number };
|
|
280
|
-
tilingSprite: BaseProps & { texture?: string | Texture; tilePosition?: { x: number; y: number } };
|
|
281
|
-
|
|
282
|
-
// Engine UI components
|
|
283
|
-
button: ButtonComponentProps;
|
|
284
|
-
label: LabelComponentProps;
|
|
285
|
-
labelValue: LabelValueComponentProps;
|
|
286
|
-
panel: PanelComponentProps;
|
|
287
|
-
flexContainer: FlexContainerComponentProps;
|
|
288
|
-
progressBar: ProgressBarComponentProps;
|
|
289
|
-
scrollContainer: ScrollContainerComponentProps;
|
|
290
|
-
modal: ModalComponentProps;
|
|
291
|
-
toast: ToastComponentProps;
|
|
292
|
-
balanceDisplay: BalanceDisplayComponentProps;
|
|
293
|
-
winDisplay: WinDisplayComponentProps;
|
|
294
|
-
layout: LayoutComponentProps;
|
|
295
|
-
slider: SliderComponentProps;
|
|
296
|
-
toggle: ToggleComponentProps;
|
|
297
|
-
}
|
|
344
|
+
interface IntrinsicElements extends EngineIntrinsicElements {}
|
|
298
345
|
}
|
|
299
346
|
}
|
|
300
|
-
|
|
301
|
-
export {};
|
package/src/ui/FlexContainer.ts
CHANGED
|
@@ -118,26 +118,31 @@ function measureChild(
|
|
|
118
118
|
const cfg = child._flexConfig;
|
|
119
119
|
const resolvedLW = resolveDimension(cfg?.layoutWidth, parentContentW);
|
|
120
120
|
const resolvedLH = resolveDimension(cfg?.layoutHeight, parentContentH);
|
|
121
|
-
if (resolvedLW !== undefined && resolvedLH !== undefined) {
|
|
122
|
-
return { w: resolvedLW, h: resolvedLH, ox: 0, oy: 0 };
|
|
123
|
-
}
|
|
124
121
|
|
|
125
|
-
//
|
|
122
|
+
// FlexContainer children are top-left origin by construction, so `ox/oy = 0`
|
|
123
|
+
// is correct and we can skip the `getLocalBounds()` call entirely.
|
|
126
124
|
if (child instanceof FlexContainer) {
|
|
127
125
|
const fc = child;
|
|
128
126
|
const w = fc._explicitWidth > 0 ? fc._explicitWidth : (fc._computedWidth > 0 ? fc._computedWidth : undefined);
|
|
129
127
|
const h = fc._explicitHeight > 0 ? fc._explicitHeight : (fc._computedHeight > 0 ? fc._computedHeight : undefined);
|
|
130
128
|
if (w !== undefined && h !== undefined) {
|
|
131
|
-
return { w, h, ox: 0, oy: 0 };
|
|
129
|
+
return { w: resolvedLW ?? w, h: resolvedLH ?? h, ox: 0, oy: 0 };
|
|
132
130
|
}
|
|
133
131
|
}
|
|
134
132
|
|
|
135
|
-
// Use localBounds to get the true visual
|
|
136
|
-
//
|
|
133
|
+
// Use localBounds to get the true visual origin offset.
|
|
134
|
+
// We take `ox/oy` from bounds unconditionally — a user-supplied `layoutWidth/Height`
|
|
135
|
+
// overrides the SIZE used by flex (protection against pre-paint bounds of 0), but
|
|
136
|
+
// it must NOT erase the center-anchor compensation: Button/Label views are drawn at
|
|
137
|
+
// `(-w/2..w/2)` and their bounds.x = -w/2 is what lets `layoutLine` place the
|
|
138
|
+
// visible rectangle where the layout intends.
|
|
137
139
|
const bounds = child.getLocalBounds();
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
return {
|
|
141
|
+
w: resolvedLW ?? bounds.width,
|
|
142
|
+
h: resolvedLH ?? bounds.height,
|
|
143
|
+
ox: bounds.x,
|
|
144
|
+
oy: bounds.y,
|
|
145
|
+
};
|
|
141
146
|
}
|
|
142
147
|
|
|
143
148
|
// ─── Layout items within a single line ───────────────────
|
|
@@ -699,25 +704,30 @@ export class FlexContainer extends Container {
|
|
|
699
704
|
}
|
|
700
705
|
|
|
701
706
|
// Position flexExclude children (absolute positioning).
|
|
702
|
-
// All position props describe the visual (bounds) rectangle
|
|
703
|
-
//
|
|
707
|
+
// All position props describe the visual (bounds) rectangle. We derive the
|
|
708
|
+
// visual rectangle directly from `getLocalBounds()` rather than the
|
|
709
|
+
// layout-config `w`/`h` returned by measureChild — those may differ from
|
|
710
|
+
// actual bounds when the user pins `layoutWidth`/`layoutHeight` to a value
|
|
711
|
+
// that doesn't match the child's real visual extent (e.g. a Button whose
|
|
712
|
+
// text overflows its configured `width`). Mixing layout size with real
|
|
713
|
+
// bounds-origin would shift the visual center off the requested point.
|
|
704
714
|
// `centerX/centerY` take precedence over `left/right` / `top/bottom` on each axis.
|
|
705
715
|
for (const child of this._layoutChildren) {
|
|
706
716
|
if (!child._flexConfig?.flexExclude) continue;
|
|
707
717
|
const cfg = child._flexConfig;
|
|
708
|
-
const
|
|
718
|
+
const bounds = child.getLocalBounds();
|
|
709
719
|
const cw = this._computedWidth;
|
|
710
720
|
const ch = this._computedHeight;
|
|
711
721
|
|
|
712
722
|
const centerX = resolveDimension(cfg.centerX, pctRefW);
|
|
713
|
-
if (centerX !== undefined) child.x = centerX -
|
|
714
|
-
else if (cfg.left !== undefined) child.x = cfg.left -
|
|
715
|
-
else if (cfg.right !== undefined) child.x = cw -
|
|
723
|
+
if (centerX !== undefined) child.x = centerX - bounds.x - bounds.width / 2;
|
|
724
|
+
else if (cfg.left !== undefined) child.x = cfg.left - bounds.x;
|
|
725
|
+
else if (cfg.right !== undefined) child.x = cw - cfg.right - bounds.x - bounds.width;
|
|
716
726
|
|
|
717
727
|
const centerY = resolveDimension(cfg.centerY, pctRefH);
|
|
718
|
-
if (centerY !== undefined) child.y = centerY -
|
|
719
|
-
else if (cfg.top !== undefined) child.y = cfg.top -
|
|
720
|
-
else if (cfg.bottom !== undefined) child.y = ch -
|
|
728
|
+
if (centerY !== undefined) child.y = centerY - bounds.y - bounds.height / 2;
|
|
729
|
+
else if (cfg.top !== undefined) child.y = cfg.top - bounds.y;
|
|
730
|
+
else if (cfg.bottom !== undefined) child.y = ch - cfg.bottom - bounds.y - bounds.height;
|
|
721
731
|
}
|
|
722
732
|
}
|
|
723
733
|
|