@energy8platform/shell 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html.cjs.js +214 -69
- package/dist/html.cjs.js.map +1 -1
- package/dist/html.d.ts +31 -4
- package/dist/html.esm.js +214 -69
- package/dist/html.esm.js.map +1 -1
- package/dist/index.cjs.js +148 -42
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +31 -4
- package/dist/index.esm.js +148 -42
- package/dist/index.esm.js.map +1 -1
- package/dist/pixi.cjs.js +451 -107
- package/dist/pixi.cjs.js.map +1 -1
- package/dist/pixi.d.ts +31 -4
- package/dist/pixi.esm.js +451 -107
- package/dist/pixi.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ShellController.ts +183 -43
- package/src/core/state.ts +1 -0
- package/src/core/types.ts +40 -4
- package/src/core/version.ts +1 -1
- package/src/ui/html/components/BottomBar.ts +71 -32
- package/src/ui/html/components/pickers.ts +13 -1
- package/src/ui/html/shell.css.ts +19 -3
- package/src/ui/pixi/components/BottomBar.ts +280 -64
- package/src/ui/pixi/components/GameInfo.ts +52 -13
- package/src/ui/pixi/components/pickers.ts +66 -15
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { PixiComponentContext, ShellLayer } from '../context';
|
|
2
2
|
import { CardModal } from '../primitives/card';
|
|
3
3
|
import { Chip } from '../primitives/controls';
|
|
4
|
-
import { FlexBox } from '../primitives/flex';
|
|
4
|
+
import { FlexBox, type Sizable } from '../primitives/flex';
|
|
5
|
+
import { ScrollBox } from '../primitives/scroll';
|
|
5
6
|
|
|
6
7
|
interface Choice {
|
|
7
8
|
id: string;
|
|
@@ -13,8 +14,15 @@ interface SheetOpts {
|
|
|
13
14
|
title: string;
|
|
14
15
|
choices: Choice[];
|
|
15
16
|
selected: string;
|
|
16
|
-
/** Chips per row — a fixed number, or `{ wide, mobile }` that reflows with the layout.
|
|
17
|
+
/** Chips per row — a fixed number, or `{ wide, mobile }` that reflows with the layout.
|
|
18
|
+
* With `autoFit`, this is the *maximum* column count; the grid drops to fewer when the labels
|
|
19
|
+
* are too wide to fit that many. */
|
|
17
20
|
columns: number | { wide: number; mobile: number };
|
|
21
|
+
/** Size the columns to the widest chip label (instead of always packing `columns`), and cap the
|
|
22
|
+
* grid height with a scroll region. For variable-width labels (a wide currency's bet values)
|
|
23
|
+
* this reflows + scrolls rather than clipping — the Pixi analogue of the HTML shell's
|
|
24
|
+
* `auto-fill minmax` + `overflow-y:auto`. */
|
|
25
|
+
autoFit?: boolean;
|
|
18
26
|
/** Max card width in em (the 6-wide bet picker needs 44em vs the 28em default). */
|
|
19
27
|
maxEm?: number;
|
|
20
28
|
confirmLabel: string;
|
|
@@ -36,8 +44,24 @@ class PickerModal extends CardModal {
|
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
/** A centred picker (chips grid + accent Confirm) on the shared card modal. */
|
|
47
|
+
/** A ScrollBox that reports a fixed box to the FlexBox layout — so a capped, scrolling grid slots
|
|
48
|
+
* into the card body like any other sized child (measured/positioned by its viewport, not its
|
|
49
|
+
* full content bounds). */
|
|
50
|
+
class SizedScrollBox extends ScrollBox implements Sizable {
|
|
51
|
+
constructor(private readonly boxW: number, private readonly boxH: number, canvas?: HTMLCanvasElement) {
|
|
52
|
+
super(canvas);
|
|
53
|
+
this.setViewport(boxW, boxH);
|
|
54
|
+
}
|
|
55
|
+
measureSize(): { w: number; h: number } {
|
|
56
|
+
return { w: this.boxW, h: this.boxH };
|
|
57
|
+
}
|
|
58
|
+
setLayoutSize(): void {
|
|
59
|
+
/* fixed viewport — ignore layout-imposed sizing */
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
39
63
|
function buildSheet(host: PixiComponentContext, opts: SheetOpts): ShellLayer {
|
|
40
|
-
const
|
|
64
|
+
const maxColumns = typeof opts.columns === 'number'
|
|
41
65
|
? opts.columns
|
|
42
66
|
: host.layout === 'mobile' ? opts.columns.mobile : opts.columns.wide;
|
|
43
67
|
|
|
@@ -91,27 +115,53 @@ function buildSheet(host: PixiComponentContext, opts: SheetOpts): ShellLayer {
|
|
|
91
115
|
const em = modal.emSize;
|
|
92
116
|
const gap = 0.65 * em;
|
|
93
117
|
const innerW = modal.cardWidth - 2.4 * em;
|
|
118
|
+
|
|
119
|
+
// Build the chips first (at natural width) so autoFit can measure the widest label.
|
|
120
|
+
for (let i = 0; i < opts.choices.length; i++) {
|
|
121
|
+
const c = opts.choices[i];
|
|
122
|
+
const chipIndex = i;
|
|
123
|
+
chips.push(new Chip(host, c.id, c.label, chipIndex === focusIndex, em, (id) => {
|
|
124
|
+
const idx = opts.choices.findIndex((ch) => ch.id === id);
|
|
125
|
+
if (idx >= 0) setHighlight(idx);
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Column count: with autoFit, drop below the max until the widest label fits. Short labels
|
|
130
|
+
// (a normal currency) exceed the max and clamp back to it — so the compact 6-wide layout is
|
|
131
|
+
// preserved and only wide currencies reflow to fewer columns.
|
|
132
|
+
let columns = maxColumns;
|
|
133
|
+
if (opts.autoFit) {
|
|
134
|
+
const widest = chips.reduce((m, ch) => Math.max(m, ch.measureSize().w), 0);
|
|
135
|
+
const fitCols = Math.floor((innerW + gap) / (widest + gap));
|
|
136
|
+
columns = Math.max(1, Math.min(maxColumns, fitCols));
|
|
137
|
+
}
|
|
94
138
|
const colW = (innerW - gap * (columns - 1)) / columns;
|
|
95
139
|
|
|
96
140
|
const grid = new FlexBox({ direction: 'column', align: 'start', gap });
|
|
97
|
-
for (let i = 0; i <
|
|
98
|
-
const rowChoices = opts.choices.slice(i, i + columns);
|
|
141
|
+
for (let i = 0; i < chips.length; i += columns) {
|
|
99
142
|
const row = new FlexBox({ direction: 'row', align: 'center', gap });
|
|
100
|
-
for (let j = 0; j <
|
|
101
|
-
const
|
|
102
|
-
const chipIndex = i + j;
|
|
103
|
-
const chip = new Chip(host, c.id, c.label, chipIndex === focusIndex, em, (id) => {
|
|
104
|
-
const idx = opts.choices.findIndex((ch) => ch.id === id);
|
|
105
|
-
if (idx >= 0) setHighlight(idx);
|
|
106
|
-
});
|
|
143
|
+
for (let j = 0; j < columns && i + j < chips.length; j++) {
|
|
144
|
+
const chip = chips[i + j];
|
|
107
145
|
chip.setLayoutSize(colW, undefined);
|
|
108
|
-
chips.push(chip);
|
|
109
146
|
row.add(chip);
|
|
110
147
|
}
|
|
111
|
-
row.layout();
|
|
112
148
|
grid.add(row);
|
|
113
149
|
}
|
|
114
|
-
|
|
150
|
+
|
|
151
|
+
// Cap the grid height and scroll when the ladder overflows — the Pixi analogue of the HTML
|
|
152
|
+
// shell's `max-height:min(50vh,28em); overflow-y:auto`. (Mask hit-testing clips to the viewport
|
|
153
|
+
// but still lets clicks through to chips inside it — verified against pixi.js 8.16's
|
|
154
|
+
// EventBoundary.) When it fits, drop the scroll box entirely so nothing is masked needlessly.
|
|
155
|
+
const gridH = grid.measureSize().h;
|
|
156
|
+
const maxGridH = Math.min(host.screenH * 0.5, 28 * em);
|
|
157
|
+
if (opts.autoFit && gridH > maxGridH) {
|
|
158
|
+
const scroll = new SizedScrollBox(innerW, maxGridH, host.canvas);
|
|
159
|
+
scroll.content.addChild(grid);
|
|
160
|
+
scroll.refresh();
|
|
161
|
+
modal.body.add(scroll);
|
|
162
|
+
} else {
|
|
163
|
+
modal.body.add(grid);
|
|
164
|
+
}
|
|
115
165
|
|
|
116
166
|
modal.setActions([
|
|
117
167
|
{
|
|
@@ -130,6 +180,7 @@ export function openBetPicker(host: PixiComponentContext): ShellLayer {
|
|
|
130
180
|
tag: 'bet-modal',
|
|
131
181
|
title: host.t('Bet'),
|
|
132
182
|
columns: { wide: 6, mobile: 3 },
|
|
183
|
+
autoFit: true, // reflow columns + scroll when a wide currency makes the labels grow
|
|
133
184
|
maxEm: 44, // wider card to fit 6 chips/row
|
|
134
185
|
confirmLabel: host.t('Confirm'),
|
|
135
186
|
choices: host.state.availableBets.map((b) => ({ id: String(b), label: host.fmt(b) })),
|