@moku-labs/game 0.0.2 → 0.0.3

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 (35) hide show
  1. package/README.md +89 -21
  2. package/dist/assets.d.mts +58 -6
  3. package/dist/assets.mjs +1630 -234
  4. package/dist/commands-BOxqlv7w.d.mts +99 -0
  5. package/dist/control.d.mts +3 -92
  6. package/dist/control.mjs +3 -757
  7. package/dist/define-BMo0pHe_.d.mts +51 -0
  8. package/dist/{registry-DlpRCibU.mjs → dev-CcwFrwok.mjs} +30 -1
  9. package/dist/index.d.mts +217 -29
  10. package/dist/index.mjs +6179 -727
  11. package/dist/inspect.d.mts +10 -8
  12. package/dist/inspect.mjs +2 -518
  13. package/dist/jsx-dev-runtime.d.mts +1 -1
  14. package/dist/jsx-runtime.d.mts +1 -1
  15. package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-8H4AJuhK.mjs} +1 -0
  16. package/dist/run-tlcn1w7y.mjs +944 -0
  17. package/dist/{runtime-DiOTkDZz.d.mts → runtime-BstIkrhH.d.mts} +1 -1
  18. package/dist/sources-BooL2MsX.mjs +545 -0
  19. package/dist/testing.d.mts +305 -3
  20. package/dist/testing.mjs +2056 -2
  21. package/dist/types-BTycq8_Z.d.mts +1196 -0
  22. package/dist/{types-yg_ywtT-.d.mts → types-C0SLQsx0.d.mts} +230 -31
  23. package/dist/types-Cjf3ywai.d.mts +5982 -0
  24. package/dist/{define-sFoO3y6X.d.mts → types-D0uYTTC3.d.mts} +180 -51
  25. package/dist/{types-DWILGrPn.d.mts → types-DgwbzDLP.d.mts} +87 -19
  26. package/dist/types-KlE_GL1z.d.mts +1444 -0
  27. package/dist/{visual-BDUHSRvf.mjs → visual-NPrDkvUk.mjs} +19 -13
  28. package/package.json +17 -2
  29. package/dist/headless-CvamCUcR.mjs +0 -186
  30. package/dist/headless-KaSWcd0s.d.mts +0 -181
  31. package/dist/types-BxkNNYul.d.mts +0 -2840
  32. package/dist/types-CTPS9GBu.d.mts +0 -742
  33. package/dist/types-DD-QrG_z.d.mts +0 -588
  34. package/dist/types-DYLnSgMI.d.mts +0 -570
  35. package/dist/types-JNc_UQBo.d.mts +0 -2896
@@ -1,11 +1,10 @@
1
- import { D as Hint, L as Json, T as Descriptor, k as Api, lt as Require, t as Api$1 } from "./types-JNc_UQBo.mjs";
2
- import { E as ViewHandle, M as ComponentValue, N as Entity, O as AnyComponentType, S as ProjectionMotion, b as MotionHandle, c as Point$1, j as ComponentType, l as ViewportSize, m as ChangeHook, t as Api$3, u as Api$2, y as Motion } from "./types-BxkNNYul.mjs";
1
+ import { At as Json, D as ProjectionMotion, I as ComponentType, L as ComponentValue, N as AnyComponentType, P as AnyComponentValue, R as Entity, St as Api, T as MotionHandle, bt as Hint, h as Api$2, j as ViewHandle, m as ViewportSize, nn as Require, p as Point$1, q as Api$1, t as Api$3, vt as Descriptor, w as Motion, y as ChangeHook } from "./types-Cjf3ywai.mjs";
3
2
  import { Log } from "@moku-labs/common/browser";
4
3
  import { PluginCtx } from "@moku-labs/core";
5
4
 
6
5
  //#region src/plugins/input/types.d.ts
7
6
  declare namespace types_d_exports$1 {
8
- export { Config$1 as Config, Deps, Direction, GesturePhase, InputApi, InputCtx, KernelSlice, KeyInput, KeyListener, Point, RawSample, State$1 as State, TapListener, Target };
7
+ export { Config$1 as Config, Deps, Direction, GesturePhase, InputApi, InputCtx, KernelSlice, KeyInput, KeyListener, Point, PointerListener, RawSample, State$1 as State, TapListener, Target };
9
8
  }
10
9
  /**
11
10
  * A point in reference units, as `renderer.viewport.toReference` answers it.
@@ -79,6 +78,19 @@ type GesturePhase = "idle" | "pressed" | "longPressed" | "dragging";
79
78
  * ```
80
79
  */
81
80
  type TapListener = (entity: Entity) => void;
81
+ /**
82
+ * What `onPointer` registers: called with the raw sample inside the DOM listener, for the kinds
83
+ * `down`, `up` and `cancel`, right after the sample is queued.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const lifts: RawSample[] = [];
88
+ * const listener: PointerListener = sample => {
89
+ * if (sample.kind === "up") lifts.push(sample);
90
+ * };
91
+ * ```
92
+ */
93
+ type PointerListener = (sample: RawSample) => void;
82
94
  /**
83
95
  * One key press as `onKey` hands it to a listener: the DOM `KeyboardEvent.key` and whether Shift
84
96
  * was held.
@@ -165,7 +177,8 @@ type State$1 = {
165
177
  offFrame: (() => void) | undefined;
166
178
  detach: (() => void) | undefined; /** Registered through `onTap`, called in this order on every tap. */
167
179
  tapListeners: TapListener[]; /** Registered through `onKey`, called in this order on every key. */
168
- keyListeners: KeyListener[]; /** Takes the one `keydown` listener off `window`; set while a canvas is attached. */
180
+ keyListeners: KeyListener[]; /** Registered through `onPointer`, called in this order inside the DOM listener. */
181
+ pointerListeners: PointerListener[]; /** Takes the one `keydown` listener off `window`; set while a canvas is attached. */
169
182
  detachKeys: (() => void) | undefined; /** `time.wake`, bound in `onInit`: every pointer sample leaves the idle frame rate. */
170
183
  wake: (() => void) | undefined; /** The cursor last written on the attached canvas; `undefined` while nothing was written. */
171
184
  cursor: string | undefined; /** Component types other plugins registered through `controls.add`, once per registration. */
@@ -259,9 +272,34 @@ type InputApi = {
259
272
  * ```
260
273
  */
261
274
  onTap(fn: TapListener): () => void;
275
+ /**
276
+ * Registers a listener called synchronously inside the DOM pointer listener, right after the
277
+ * sample is queued, for `pointerdown`, `pointerup` and `pointercancel`. It is the one place a
278
+ * browser call that needs the user gesture can run, such as `focus()` on a text field: in the
279
+ * next frame iOS shows no keyboard. Never called for a move, a leave or a lost capture, and never
280
+ * by `tap`, `press`, `drag` or `swipe`, which have no DOM moment. The sample is raw: client px,
281
+ * no hit test. Listeners run in registration order; a listener that throws is logged with the
282
+ * sample kind, and the listeners after it still run.
283
+ *
284
+ * @param fn - What to run with the raw sample.
285
+ * @returns The remover; call it to stop listening.
286
+ * @example
287
+ * ```ts
288
+ * // ui opens the keyboard the moment the finger lifts on a text field, inside the DOM listener.
289
+ * const off = ctx.require(inputPlugin).onPointer(sample => {
290
+ * if (sample.kind === "up" && fieldAt(sample.clientX, sample.clientY) !== undefined) element.focus({ preventScroll: true });
291
+ * if (sample.kind === "down" && fieldAt(sample.clientX, sample.clientY) === undefined) element.blur();
292
+ * });
293
+ * // a tap on the Rename field on an iPhone: the keyboard shows; a tap on the parchment next to it: the keyboard hides
294
+ * off(); // in onStop
295
+ * ```
296
+ */
297
+ onPointer(fn: PointerListener): () => void;
262
298
  /**
263
299
  * Registers a listener called on every key pressed while the canvas is attached, and on every
264
- * `key` call. Listeners run in registration order, all of them, each time. A listener that
300
+ * `pressKey` call. A key typed into a text field is not handed over, except Enter and Escape,
301
+ * and an Enter that commits an IME composition is dropped. Listeners run in registration order,
302
+ * all of them, each time. A listener that
265
303
  * returns `true` marks the key handled, and input calls `preventDefault()` on the DOM event. A
266
304
  * listener that throws is logged with its key, and the listeners after it still run.
267
305
  *
@@ -718,7 +756,8 @@ type SpriteFit = "fill" | "contain" | "cover";
718
756
  /**
719
757
  * One textured quad. `texture` is an asset key; `defineGame` narrows it to the game's keys.
720
758
  * `width` and `height` are the box in reference units; 0 on an axis keeps the texture's own size
721
- * there. `anchor` is the point of the box that sits on the `Transform`.
759
+ * there. `anchor` is the point of the box that sits on the `Transform`. `alpha` fades the quad
760
+ * and the entity's children.
722
761
  *
723
762
  * @example
724
763
  * ```ts
@@ -740,16 +779,23 @@ type SpriteValue = {
740
779
  /**
741
780
  * A stretchable panel. The slice borders come with the texture, not with the component. `debug`
742
781
  * strokes the bounds and the four cut lines over the panel: cyan, red when the corners overlap or
743
- * the texture is missing.
782
+ * the texture is missing. `clip` masks the children of the entity to the `width × height` box,
783
+ * the same rule as `Shape.clip`: the mask is a filled rectangle and is never drawn, and the panel
784
+ * itself is never masked. `alpha` fades the panel and the entity's children.
744
785
  *
745
786
  * @example
746
787
  * ```ts
747
788
  * const value: NineSliceValue = {
748
- * texture: "ui.panel", width: 600, height: 320, alpha: 1, tint: 0xffffff, debug: false
789
+ * texture: "ui.panel", width: 600, height: 320, alpha: 1, tint: 0xffffff, debug: false,
790
+ * clip: false
749
791
  * };
750
792
  * // The board tray, outlined while its insets are checked.
751
793
  * const tray: NineSliceValue = {
752
- * texture: "board.board-tray", width: 1000, height: 1040, alpha: 1, tint: 0xffffff, debug: true
794
+ * ...value, texture: "board.board-tray", width: 1000, height: 1040, debug: true
795
+ * };
796
+ * // A text field: a long value never draws outside the frame.
797
+ * const field: NineSliceValue = {
798
+ * ...value, texture: "ui.field", width: 480, height: 96, clip: true
753
799
  * };
754
800
  * ```
755
801
  */
@@ -760,6 +806,7 @@ type NineSliceValue = {
760
806
  alpha: number;
761
807
  tint: number;
762
808
  debug: boolean;
809
+ clip: boolean;
763
810
  };
764
811
  /**
765
812
  * The escape hatch: the game owns a Pixi object and `sync` only attaches and detaches it.
@@ -776,10 +823,11 @@ type DisplayValue = {
776
823
  * A filled rounded rectangle or a triangle, anchored at the top left of the `Transform`. `kind`
777
824
  * picks the outline: `"rect"` (the default) or `"triangle"`, which fills its `w × h` box pointing
778
825
  * right (rotate the element for another direction) and ignores `radius`. `fillAlpha` is the alpha
779
- * of the fill alone: 0 draws only the stroke, a ring. `alpha` fades the whole shape. `dash` is the
826
+ * of the fill alone: 0 draws only the stroke, a ring. `alpha` fades the whole shape and the
827
+ * entity's children: a disabled button at 0.6 draws its icon at 0.6 too. `dash` is the
780
828
  * dash length of the stroke in reference units, with gaps of half a dash; 0 strokes a solid line.
781
829
  * `clip` masks the children of the entity to the shape, always solid, which is how `ui` draws a
782
- * scroll and an overflow.
830
+ * scroll and an overflow. The shape itself is never masked, so its stroke is drawn whole.
783
831
  *
784
832
  * @example
785
833
  * ```ts
@@ -838,7 +886,7 @@ declare const Transform: ComponentType<TransformValue>;
838
886
  declare const Sprite: ComponentType<SpriteValue>;
839
887
  /**
840
888
  * A stretchable panel, sized in reference units, with its own alpha and tint. `debug: true` draws
841
- * the slice outline over it.
889
+ * the slice outline over it. `clip: true` masks the children of the entity to the panel box.
842
890
  */
843
891
  declare const NineSlice: ComponentType<{
844
892
  texture: string;
@@ -847,6 +895,7 @@ declare const NineSlice: ComponentType<{
847
895
  alpha: number;
848
896
  tint: number;
849
897
  debug: boolean;
898
+ clip: boolean;
850
899
  }>;
851
900
  /**
852
901
  * The entity this view moves with. `0` means no parent.
@@ -1282,6 +1331,31 @@ type ImageFit = ("contain" | "cover" | "fill") & Brand<"ImageFit">;
1282
1331
  type ScrollAxis = ("x" | "y") & Brand<"ScrollAxis">;
1283
1332
  /** The world projections whose live views a container draws inside itself. */
1284
1333
  type HostedProjections = readonly string[] & Brand<"HostedProjections">;
1334
+ /** The local field of the nearest component instance a text field writes on every keystroke. */
1335
+ type InputLocal = string & Brand<"InputLocal">;
1336
+ /** The intent a text field answers on Enter, with `{ [local]: value }` as the payload. */
1337
+ type InputSubmit = string & Brand<"InputSubmit">;
1338
+ /** The longest value of a text field, in UTF-16 units. */
1339
+ type InputMaxLength = number & Brand<"InputMaxLength">;
1340
+ /** What an empty text field shows at half alpha; also the label a screen reader says. */
1341
+ type InputPlaceholder = (string | Message) & Brand<"InputPlaceholder">;
1342
+ /** The keyboard a text field opens: plain text, a decimal pad or an email keyboard. */
1343
+ type TextInputKind = ("text" | "number" | "email") & Brand<"TextInputKind">;
1344
+ /** The text style key of a field's value, its placeholder and its caret height. */
1345
+ type InputTextStyle = string & Brand<"InputTextStyle">;
1346
+ /**
1347
+ * Extra component values an element's entity carries, beside the ones the tag writes itself. Any
1348
+ * component or tag works: a filter of `effects`, or a game's own component. A value whose type the
1349
+ * element owns (`Transform`, `Box`, `Shape`, `Tappable`, ...) is dropped and logged as
1350
+ * `ui:component-owned`; the element keeps its own.
1351
+ *
1352
+ * @example
1353
+ * ```tsx
1354
+ * <button key="claim" intent="claim" components={[Glow({ strength: 2 })]} />;
1355
+ * // the button entity carries Glow({ strength: 2 }) next to Tappable, Shape and Box
1356
+ * ```
1357
+ */
1358
+ type ElementComponents = readonly AnyComponentValue[] & Brand<"ElementComponents">;
1285
1359
  /**
1286
1360
  * The props every tag takes, with the key kept out: JSX passes it as the third argument.
1287
1361
  *
@@ -1397,6 +1471,26 @@ type PanelProps = CommonProps;
1397
1471
  type ScrollProps = CommonProps & {
1398
1472
  axis?: ScrollAxis;
1399
1473
  };
1474
+ /**
1475
+ * What a text field takes. `local` is required: every keystroke writes that field of the local
1476
+ * state of the nearest component, and Enter answers `submit` with `{ [local]: value }`. `style` is
1477
+ * the layout style of the field box.
1478
+ *
1479
+ * @example
1480
+ * ```tsx
1481
+ * // The name field of a rename popup. The player types "Alex": local.name is "Alex".
1482
+ * <input key="nameField" local="name" maxLength={16} submit="save" placeholder="Your name" />;
1483
+ * // Enter then answers the gate with { intent: "save", payload: { name: "Alex" } }
1484
+ * ```
1485
+ */
1486
+ type InputProps = CommonProps & {
1487
+ local: InputLocal;
1488
+ submit?: InputSubmit;
1489
+ maxLength?: InputMaxLength;
1490
+ placeholder?: InputPlaceholder;
1491
+ kind?: TextInputKind;
1492
+ textStyle?: InputTextStyle;
1493
+ };
1400
1494
  /**
1401
1495
  * The thirteen tags a screen is written with.
1402
1496
  *
@@ -1418,7 +1512,7 @@ type UiIntrinsicElements = {
1418
1512
  text: TextTagProps;
1419
1513
  button: ButtonTagProps;
1420
1514
  scroll: ScrollProps;
1421
- input: BoxProps;
1515
+ input: InputProps;
1422
1516
  };
1423
1517
  /**
1424
1518
  * The props of one tag with its `style` narrowed to the asset keys of one game, so a nine-slice
@@ -1436,14 +1530,19 @@ type Restyled<Properties, Asset extends string> = Properties extends unknown ? O
1436
1530
  /**
1437
1531
  * The same tags with the asset keys, text style keys and message keys of one game. `uiFor`
1438
1532
  * carries it, so a game can name the type of its own intrinsics. The asset keys narrow `texture`,
1439
- * `name` and the `nineSlice` of every style.
1533
+ * `name` and the `nineSlice` of every style; the text style keys narrow the `style` of a text
1534
+ * and the `textStyle` of a field; the message keys narrow `content` and `placeholder`.
1440
1535
  *
1441
1536
  * @example
1442
1537
  * ```ts
1443
1538
  * type Tags = IntrinsicElementsFor<"ui.coin", "digits", "hud.coins">;
1444
1539
  * ```
1445
1540
  */
1446
- type IntrinsicElementsFor<Asset extends string, TextStyleKey extends string, StringKey extends string> = { [Tag in Exclude<keyof UiIntrinsicElements, "image" | "icon" | "text">]: Restyled<UiIntrinsicElements[Tag], Asset> } & {
1541
+ type IntrinsicElementsFor<Asset extends string, TextStyleKey extends string, StringKey extends string> = { [Tag in Exclude<keyof UiIntrinsicElements, "image" | "icon" | "text" | "input">]: Restyled<UiIntrinsicElements[Tag], Asset> } & {
1542
+ input: Restyled<Omit<InputProps, "textStyle" | "placeholder">, Asset> & {
1543
+ textStyle?: TextStyleKey;
1544
+ placeholder?: string | Message<StringKey>;
1545
+ };
1447
1546
  image: Restyled<CommonProps, Asset> & {
1448
1547
  texture: Asset;
1449
1548
  fit?: "contain" | "cover" | "fill";
@@ -1679,7 +1778,9 @@ type Instance = {
1679
1778
  * `rect` is natural: under a `fit` ancestor it is the rect before that ancestor's scale. `fit`
1680
1779
  * is the element's own fit scale (1 without `fit: "contain"`), and `rest` the rest `Transform`
1681
1780
  * last written for it. `loop` is the motion of the running `loop` hook, kept apart from
1682
- * `handles`: it never ends, so the exit sweep must not wait for it.
1781
+ * `handles`: it never ends, so the exit sweep must not wait for it. `extras` holds the values of
1782
+ * the `components` prop added last time, by component name; `warnedOwned` the names of the
1783
+ * `components` values the element owns that were already logged.
1683
1784
  */
1684
1785
  type Element = {
1685
1786
  entity: Entity;
@@ -1715,6 +1816,8 @@ type Element = {
1715
1816
  live: boolean;
1716
1817
  entered: boolean;
1717
1818
  dropKey: (() => void) | undefined;
1819
+ extras: ReadonlyMap<string, AnyComponentValue>;
1820
+ warnedOwned: Set<string>;
1718
1821
  };
1719
1822
  /**
1720
1823
  * The popup side of a root: the handler that shows it now and the root it was opened over.
@@ -1768,11 +1871,107 @@ type FocusState = {
1768
1871
  ring: Entity;
1769
1872
  } | undefined;
1770
1873
  drawn: DrawnRing | undefined;
1771
- tapping: boolean;
1874
+ tapping: boolean; /** The focus came from a finger on a text field: the element is focused, no ring is drawn. */
1875
+ ringless: boolean;
1876
+ };
1877
+ /**
1878
+ * The text of the field being edited, as the frame step last read it from the hidden input, or
1879
+ * as `fill` wrote it. Indexes count UTF-16 units, as the DOM does.
1880
+ *
1881
+ * @example
1882
+ * ```ts
1883
+ * // "Alex" typed, the caret at the end, nothing selected.
1884
+ * const mirror: Mirror = { value: "Alex", selectionStart: 4, selectionEnd: 4, direction: "none" };
1885
+ * ```
1886
+ */
1887
+ type Mirror = {
1888
+ value: string;
1889
+ selectionStart: number;
1890
+ selectionEnd: number;
1891
+ direction: "forward" | "backward" | "none";
1892
+ };
1893
+ /**
1894
+ * The part of the value an IME is composing, between `compositionstart` and `compositionend`.
1895
+ *
1896
+ * @example
1897
+ * ```ts
1898
+ * const composing: Composing = { start: 4, end: 6 };
1899
+ * ```
1900
+ */
1901
+ type Composing = {
1902
+ start: number;
1903
+ end: number;
1904
+ };
1905
+ /** The keyboard a text field opens. */
1906
+ type FieldKind = "text" | "number" | "email";
1907
+ /** The four ui-owned entities a field is drawn with besides its own, each with `Parent` = field. */
1908
+ type FieldParts = {
1909
+ selection: Entity;
1910
+ text: Entity;
1911
+ caret: Entity;
1912
+ composing: Entity;
1913
+ };
1914
+ /**
1915
+ * One text field: its entity and the props of the `input` tag, filled at enter and dropped at the
1916
+ * despawn. `instance` is the nearest component instance, the one whose `local` the field writes.
1917
+ */
1918
+ type Field = {
1919
+ entity: Entity;
1920
+ key: string | undefined;
1921
+ root: Entity;
1922
+ instance: string | undefined;
1923
+ local: string;
1924
+ submit: string | undefined;
1925
+ maxLength: number | undefined;
1926
+ kind: FieldKind;
1927
+ textStyle: string;
1928
+ placeholder: string | Message | undefined;
1929
+ parts: FieldParts | undefined; /** What the parts were last written with, so a field laid out the same way writes nothing. */
1930
+ drawn: string | undefined;
1931
+ /**
1932
+ * A fingerprint of what the field was last laid out from, so a still field is neither measured
1933
+ * nor laid out. `undefined` lays it out again: before its first placement, and after `text`
1934
+ * resolved its text part again, as it does when a font arrives.
1935
+ */
1936
+ inputs: string | undefined;
1937
+ };
1938
+ /**
1939
+ * Where the keyboard stands, in CSS px: the height it covers at the bottom of the window, the
1940
+ * window height it was read with, and the lift the editing field's root is moved up by.
1941
+ */
1942
+ type Keyboard = {
1943
+ inset: number;
1944
+ innerHeight: number;
1945
+ lift: number;
1946
+ };
1947
+ /**
1948
+ * The root the keyboard lift was last written on: its root element, the lift in reference units,
1949
+ * and the rest pose it was added to, so a new rest is lifted again.
1950
+ */
1951
+ type Lifted = {
1952
+ element: Entity;
1953
+ units: number;
1954
+ rest: TransformValue;
1955
+ };
1956
+ /**
1957
+ * The text input: the one hidden DOM input (none headless), the field being edited, the mirror of
1958
+ * the text, the composing range, the keyboard, the root lifted above it, the listeners of the
1959
+ * element (removed in `onStop`) and the viewport watcher (removed when the editing ends).
1960
+ */
1961
+ type TextState = {
1962
+ element: HTMLInputElement | undefined;
1963
+ editing: Entity | undefined;
1964
+ mirror: Mirror;
1965
+ composing: Composing | undefined;
1966
+ keyboard: Keyboard;
1967
+ lifted: Lifted | undefined;
1968
+ placed: string | undefined;
1969
+ watching: (() => void) | undefined;
1970
+ cleanups: Array<() => void>;
1772
1971
  };
1773
1972
  /**
1774
1973
  * jsx module state. `hosts` holds the elements with a `hosts` prop; `hosted` maps a world view to
1775
- * the element that hosts it.
1974
+ * the element that hosts it; `fields` holds the text fields by entity.
1776
1975
  */
1777
1976
  type JsxState = {
1778
1977
  components: Map<string, AnyComponentDefinition>;
@@ -1787,25 +1986,23 @@ type JsxState = {
1787
1986
  hosted: Map<Entity, Entity>;
1788
1987
  reconciles: number;
1789
1988
  focus: FocusState;
1989
+ fields: Map<Entity, Field>;
1990
+ text: TextState;
1790
1991
  };
1791
1992
  /**
1792
1993
  * One node of the snapshot `tree()` answers with. `rect` is natural: under a `fit` ancestor it
1793
1994
  * is the rect before that ancestor's scale. An element with `fit: "contain"` adds `fitScale`,
1794
- * the scale it is drawn at.
1995
+ * the scale it is drawn at. An `input` adds `value`: the text being typed while it is edited,
1996
+ * else the local field it writes.
1795
1997
  *
1796
1998
  * @example
1797
1999
  * ```ts
1798
- * // The board slot of a merge game on an iPhone SE.
1799
- * const node: UiNode = {
1800
- * key: "boardSlot", type: "stack", rect: { x: 55, y: 223, w: 970, h: 970 },
1801
- * style: { width: 970, height: 970, fit: "contain" },
1802
- * state: {
1803
- * pressed: false, hover: false, focus: false, disabled: false, active: false, selected: false,
1804
- * covered: false
1805
- * },
1806
- * fitScale: 0.8,
1807
- * children: []
1808
- * };
2000
+ * // A profile screen before the player types: its name field shows the value, not its parts.
2001
+ * const field = app.ui.tree().children[0];
2002
+ * field?.key; // "nickField"
2003
+ * field?.rect; // { x: 0, y: 0, w: 400, h: 80 }
2004
+ * field?.value; // ""
2005
+ * field?.children; // []
1809
2006
  * ```
1810
2007
  */
1811
2008
  type UiNode = {
@@ -1821,6 +2018,7 @@ type UiNode = {
1821
2018
  state: IsFlags;
1822
2019
  local?: Record<string, unknown>;
1823
2020
  fitScale?: number;
2021
+ value?: string;
1824
2022
  children: UiNode[];
1825
2023
  };
1826
2024
  /**
@@ -1853,7 +2051,8 @@ type CommonProps = {
1853
2051
  selected?: boolean;
1854
2052
  }; /** The motion hooks; `undefined` written out stops a running loop, as leaving it out does. */
1855
2053
  motion?: ElementMotion | undefined;
1856
- children?: JsxChild;
2054
+ children?: JsxChild; /** Extra components the element's entity carries, beside the ones the tag writes itself. */
2055
+ components?: ElementComponents;
1857
2056
  };
1858
2057
  //#endregion
1859
2058
  export { Transform as A, types_d_exports as B, NineSliceValue as C, Sprite as D, ShapeValue as E, Events as F, InputApi as H, I18nApi as I, Message as L, sprite as M, Argument as N, SpriteOptions as O, Config as P, State as R, NineSlice as S, Shape as T, State$1 as U, Config$1 as V, types_d_exports$1 as W, Style as _, JsxChild as a, defineComponent as b, UiNode as c, popup as d, defineTokens as f, ResolvedStyle as g, IsFlags as h, Finding as i, TransformValue as j, SpriteValue as k, Box as l, UiIntrinsicElements as m, ElementChange as n, JsxState as o, IntrinsicElementsFor as p, ElementMotion as r, PopupComponent as s, DescriptionNode as t, LocalWrite as u, StylesState as v, Parent as w, Display as x, WhenFlags as y, TypedTr as z };