lecodes-cli 0.18.2 → 0.19.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.js +1866 -301
- package/package.json +14 -12
- package/runtime/scene-harness.json +1 -1
- package/runtime/sdk-types.json +1 -1
- package/src/api.ts +302 -0
- package/src/browserAuth.ts +87 -0
- package/src/cmgenTool.ts +104 -0
- package/src/commands/app.ts +891 -0
- package/src/commands/appAndroid.ts +603 -0
- package/src/commands/appDesktop.ts +326 -0
- package/src/commands/appDesktopMac.ts +470 -0
- package/src/commands/appIcon.ts +187 -0
- package/src/commands/appShared.ts +448 -0
- package/src/commands/appTemplates.ts +883 -0
- package/src/commands/appTemplatesAndroid.ts +599 -0
- package/src/commands/appTemplatesGradlew.ts +9 -0
- package/src/commands/assets.ts +28 -0
- package/src/commands/clone.ts +60 -0
- package/src/commands/compile.ts +253 -0
- package/src/commands/create.ts +59 -0
- package/src/commands/design.ts +863 -0
- package/src/commands/designTemplates.ts +11 -0
- package/src/commands/desktop.ts +122 -0
- package/src/commands/dev.ts +214 -0
- package/src/commands/diff.ts +59 -0
- package/src/commands/init.ts +191 -0
- package/src/commands/install.ts +198 -0
- package/src/commands/lightmap.ts +290 -0
- package/src/commands/link.ts +147 -0
- package/src/commands/login.ts +24 -0
- package/src/commands/navmesh.ts +225 -0
- package/src/commands/pn.ts +305 -0
- package/src/commands/projectTemplates.ts +129 -0
- package/src/commands/pull.ts +109 -0
- package/src/commands/push.ts +173 -0
- package/src/commands/render.ts +414 -0
- package/src/commands/scene.ts +148 -0
- package/src/commands/shaders.ts +157 -0
- package/src/commands/status.ts +29 -0
- package/src/commands/test.ts +370 -0
- package/src/commands/thumbs.ts +178 -0
- package/src/commands/types.ts +87 -0
- package/src/commands/update.ts +190 -0
- package/src/compile/assetIcons.ts +214 -0
- package/src/compile/collect.ts +46 -0
- package/src/compile/collectLocal.ts +37 -0
- package/src/compile/designCompile.ts +104 -0
- package/src/compile/fonts.ts +156 -0
- package/src/compile/headlessBundle.ts +129 -0
- package/src/compile/nativeStack.ts +21 -0
- package/src/compile/projectCompile.ts +109 -0
- package/src/compile/sceneCompile.ts +113 -0
- package/src/compile/screenEntry.ts +127 -0
- package/src/compile/shaders.ts +245 -0
- package/src/config.ts +42 -0
- package/src/designMeta.ts +35 -0
- package/src/desktopRenderer.ts +532 -0
- package/src/desktopScript.ts +276 -0
- package/src/dev/clientTemplates.ts +160 -0
- package/src/dev/devServer.ts +292 -0
- package/src/dev/wsServer.ts +144 -0
- package/src/distRoot.ts +20 -0
- package/src/ignore.ts +163 -0
- package/src/index.ts +491 -0
- package/src/lecodes-3d-editor.d.ts +41 -0
- package/src/lecodes-assets.d.ts +7 -0
- package/src/lecodes-design.d.ts +191 -0
- package/src/lecodes-renderer.d.ts +131 -0
- package/src/localFiles.ts +144 -0
- package/src/manifest.ts +46 -0
- package/src/matcTool.ts +137 -0
- package/src/peers.ts +40 -0
- package/src/project.ts +61 -0
- package/src/projectEnv.ts +94 -0
- package/src/qrcode-terminal.d.ts +9 -0
- package/src/releases.ts +125 -0
- package/src/serverDiff.ts +78 -0
- package/src/textDiff.ts +103 -0
- package/src/types.ts +0 -0
- package/src/util.ts +146 -0
- package/runtime/sdk/animate/animate.ts +0 -238
- package/runtime/sdk/animate/bezier.ts +0 -138
- package/runtime/sdk/animate/easings.ts +0 -126
- package/runtime/sdk/canvas/Canvas.ts +0 -305
- package/runtime/sdk/core/Aspect.ts +0 -512
- package/runtime/sdk/core/InspectorUI.ts +0 -212
- package/runtime/sdk/core/color.ts +0 -66
- package/runtime/sdk/core/compWrite.ts +0 -42
- package/runtime/sdk/core/events.ts +0 -38
- package/runtime/sdk/core/fields.ts +0 -120
- package/runtime/sdk/core/registry.ts +0 -23
- package/runtime/sdk/core/signals.ts +0 -277
- package/runtime/sdk/core/time.ts +0 -81
- package/runtime/sdk/g2/Camera2D.ts +0 -40
- package/runtime/sdk/g2/CharacterController2D.ts +0 -276
- package/runtime/sdk/g2/Node2D.ts +0 -267
- package/runtime/sdk/g2/OneWay2D.ts +0 -66
- package/runtime/sdk/g2/Physics2D.ts +0 -346
- package/runtime/sdk/g2/Scene2D.ts +0 -209
- package/runtime/sdk/g2/Shape2D.ts +0 -259
- package/runtime/sdk/g2/Sprite.ts +0 -89
- package/runtime/sdk/g2/SpriteAnimation.ts +0 -171
- package/runtime/sdk/g2/SpriteSheet.ts +0 -166
- package/runtime/sdk/g2/Texture2D.ts +0 -47
- package/runtime/sdk/g2/Tilemap.ts +0 -41
- package/runtime/sdk/g2/Tileset.ts +0 -71
- package/runtime/sdk/g2/Trigger2D.ts +0 -77
- package/runtime/sdk/g2/autotile.ts +0 -433
- package/runtime/sdk/g2/cells.ts +0 -91
- package/runtime/sdk/g2/defineScene2d.ts +0 -381
- package/runtime/sdk/g2/groups2d.ts +0 -106
- package/runtime/sdk/g2/loop.ts +0 -50
- package/runtime/sdk/g2/scenarios2d.ts +0 -69
- package/runtime/sdk/g2/touch.ts +0 -83
- package/runtime/sdk/gl/Camera.ts +0 -160
- package/runtime/sdk/gl/CameraPlace.ts +0 -52
- package/runtime/sdk/gl/CharacterController.ts +0 -238
- package/runtime/sdk/gl/Gearbox.ts +0 -212
- package/runtime/sdk/gl/Geometry.ts +0 -279
- package/runtime/sdk/gl/IK.ts +0 -193
- package/runtime/sdk/gl/InstancedMesh.ts +0 -132
- package/runtime/sdk/gl/Light.ts +0 -99
- package/runtime/sdk/gl/Lightmap.ts +0 -179
- package/runtime/sdk/gl/Material.ts +0 -245
- package/runtime/sdk/gl/Mesh.ts +0 -83
- package/runtime/sdk/gl/Model.ts +0 -64
- package/runtime/sdk/gl/Node.ts +0 -350
- package/runtime/sdk/gl/Noise.ts +0 -30
- package/runtime/sdk/gl/Particles.ts +0 -676
- package/runtime/sdk/gl/Physics.ts +0 -222
- package/runtime/sdk/gl/Plane.ts +0 -53
- package/runtime/sdk/gl/Ray.ts +0 -16
- package/runtime/sdk/gl/Scene.ts +0 -479
- package/runtime/sdk/gl/Shape.ts +0 -377
- package/runtime/sdk/gl/Texture.ts +0 -46
- package/runtime/sdk/gl/Trigger.ts +0 -45
- package/runtime/sdk/gl/Vehicle.ts +0 -473
- package/runtime/sdk/gl/Wheel.ts +0 -240
- package/runtime/sdk/gl/animation/AnimationClip.ts +0 -204
- package/runtime/sdk/gl/animation/Animator.ts +0 -87
- package/runtime/sdk/gl/animation/Layer.ts +0 -29
- package/runtime/sdk/gl/animation/Loop.ts +0 -25
- package/runtime/sdk/gl/animation/Playback.ts +0 -43
- package/runtime/sdk/gl/animation/core.ts +0 -294
- package/runtime/sdk/gl/controls.ts +0 -95
- package/runtime/sdk/gl/physicsEvents.ts +0 -20
- package/runtime/sdk/gl/scenarios.ts +0 -291
- package/runtime/sdk/gl/state.ts +0 -6
- package/runtime/sdk/gl/touch.ts +0 -68
- package/runtime/sdk/inject.ts +0 -186
- package/runtime/sdk/math/Mathf.ts +0 -118
- package/runtime/sdk/math/mat4.ts +0 -278
- package/runtime/sdk/math/quat.ts +0 -232
- package/runtime/sdk/math/vec.ts +0 -255
- package/runtime/sdk/plugins/camera.ts +0 -81
- package/runtime/sdk/plugins/geolocation.ts +0 -123
- package/runtime/sdk/plugins/oauth.ts +0 -61
- package/runtime/sdk/plugins/permission.ts +0 -7
- package/runtime/sdk/plugins/push.ts +0 -132
- package/runtime/sdk/plugins/qr.ts +0 -73
- package/runtime/sdk/plugins/service.ts +0 -47
- package/runtime/sdk/runtime/app.ts +0 -101
- package/runtime/sdk/runtime/appEvents.ts +0 -54
- package/runtime/sdk/runtime/channel.ts +0 -61
- package/runtime/sdk/runtime/clipboard.ts +0 -20
- package/runtime/sdk/runtime/datetime.ts +0 -329
- package/runtime/sdk/runtime/device.ts +0 -293
- package/runtime/sdk/runtime/fetch.ts +0 -77
- package/runtime/sdk/runtime/files.ts +0 -23
- package/runtime/sdk/runtime/input.ts +0 -175
- package/runtime/sdk/runtime/media.ts +0 -111
- package/runtime/sdk/runtime/misc.ts +0 -16
- package/runtime/sdk/runtime/net.ts +0 -36
- package/runtime/sdk/runtime/rpc.ts +0 -218
- package/runtime/sdk/runtime/service.ts +0 -83
- package/runtime/sdk/runtime/share.ts +0 -9
- package/runtime/sdk/runtime/storage.ts +0 -13
- package/runtime/sdk/runtime/touch.ts +0 -76
- package/runtime/sdk/scene/defineScene.ts +0 -1227
- package/runtime/sdk/scene/editorPlugins.ts +0 -92
- package/runtime/sdk/scene/gizmos.ts +0 -148
- package/runtime/sdk/scene/grammar.ts +0 -120
- package/runtime/sdk/scene/material.ts +0 -188
- package/runtime/sdk/server/auth/appConfig.ts +0 -12
- package/runtime/sdk/server/auth/global.ts +0 -80
- package/runtime/sdk/server/auth/host.ts +0 -318
- package/runtime/sdk/server/auth/models.ts +0 -83
- package/runtime/sdk/server/auth/types.ts +0 -50
- package/runtime/sdk/server/channel.ts +0 -56
- package/runtime/sdk/server/context.ts +0 -36
- package/runtime/sdk/server/db/defineDb.ts +0 -237
- package/runtime/sdk/server/db/fields.ts +0 -132
- package/runtime/sdk/server/db/httpTransport.ts +0 -93
- package/runtime/sdk/server/db/index.ts +0 -7
- package/runtime/sdk/server/db/marci/query.ts +0 -412
- package/runtime/sdk/server/db/types.ts +0 -202
- package/runtime/sdk/server/errors.ts +0 -12
- package/runtime/sdk/server/host.ts +0 -74
- package/runtime/sdk/server/inject.ts +0 -13
- package/runtime/sdk/server/runtime.ts +0 -133
- package/runtime/sdk/server/validate.ts +0 -87
- package/runtime/sdk/ui/NativeView.ts +0 -142
- package/runtime/sdk/ui/UI.ts +0 -39
- package/runtime/sdk/ui/UIBottomSheet.ts +0 -139
- package/runtime/sdk/ui/UIButton.ts +0 -101
- package/runtime/sdk/ui/UIContainer.ts +0 -60
- package/runtime/sdk/ui/UIImage.ts +0 -83
- package/runtime/sdk/ui/UIInput.ts +0 -185
- package/runtime/sdk/ui/UIModal.ts +0 -139
- package/runtime/sdk/ui/UINode.ts +0 -826
- package/runtime/sdk/ui/UIPager.ts +0 -362
- package/runtime/sdk/ui/UIPopover.ts +0 -100
- package/runtime/sdk/ui/UIScreen.ts +0 -123
- package/runtime/sdk/ui/UIScrollable.ts +0 -87
- package/runtime/sdk/ui/UISpacer.ts +0 -14
- package/runtime/sdk/ui/UITabs.ts +0 -236
- package/runtime/sdk/ui/UIText.ts +0 -51
- package/runtime/sdk/ui/UIVideo.ts +0 -88
- package/runtime/sdk/ui/UIVirtualizedList.ts +0 -241
- package/runtime/sdk/ui/UIWidget.ts +0 -127
- package/runtime/sdk/ui/fonts.ts +0 -13
- package/runtime/sdk/ui/presentable.ts +0 -117
- package/runtime/sdk/ui/router.ts +0 -132
- package/runtime/sdk/ui/theme.ts +0 -84
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { ClickEvent, TouchStartEvent, LongPressEvent } from "../runtime/touch"
|
|
2
|
-
import type { ClickEvent as ClickEventType, TouchStartEvent as TouchStartEventType, LongPressEvent as LongPressEventType } from "../runtime/touch"
|
|
3
|
-
import { type ElementStyle, type ContainerStyle, ContainerElement, buildUI, type DrawableStyle, type UIChildArg, type UIContainerBase, type UINodeChild, type ChildrenFn, type BaseStyle, type Color } from "./UINode"
|
|
4
|
-
|
|
5
|
-
export type UIButtonStyle = ElementStyle & DrawableStyle & ContainerStyle & { rippleColor?: Color | "default" }
|
|
6
|
-
|
|
7
|
-
/** A tappable container — row + centered children by default. Press feedback via the `onPressed`
|
|
8
|
-
* style block, the `$pressed` class, or `rippleColor`. */
|
|
9
|
-
export interface UIButton extends UIContainerBase<UIButtonStyle & { onPressed?: UIButtonStyle & { duration?: number } }, DrawableStyle & BaseStyle> {
|
|
10
|
-
readonly type: "button",
|
|
11
|
-
|
|
12
|
-
/** Fired on a completed tap/click. */
|
|
13
|
-
onClick(callback: (ev: ClickEventType<UIButton>) => void): this,
|
|
14
|
-
/** Fired when a touch begins; `ev.track(...)` takes over the rest of the gesture (dragging). */
|
|
15
|
-
onTouchStart(callback: (ev: TouchStartEventType<UIButton>) => void): this,
|
|
16
|
-
/** Fired when a finger is held on the button past the long-press threshold. The event can
|
|
17
|
-
* `ev.track(...)` the rest of the gesture (like `onTouchStart`), so a hold can flow straight into
|
|
18
|
-
* dragging the element. A handled long-press suppresses the click that would follow the release. */
|
|
19
|
-
onLongPress(callback: (ev: LongPressEventType<UIButton>) => void): this,
|
|
20
|
-
/** Is a finger currently down on the button? */
|
|
21
|
-
isPressed(): boolean,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class ButtonElement extends ContainerElement<"button"> {
|
|
26
|
-
|
|
27
|
-
readonly clickListeners: any[] = []
|
|
28
|
-
readonly touchStartListeners: any[] = []
|
|
29
|
-
readonly longPressListeners: any[] = []
|
|
30
|
-
|
|
31
|
-
onClick (callback: any): this {
|
|
32
|
-
this.clickListeners.push(callback)
|
|
33
|
-
return this
|
|
34
|
-
}
|
|
35
|
-
_emitClick(pointerId: number, clientX: number, clientY: number) {
|
|
36
|
-
const touchEvent = new ClickEvent(clientX, clientY, pointerId)
|
|
37
|
-
touchEvent.target = this
|
|
38
|
-
for (let callback of this.clickListeners) {
|
|
39
|
-
callback(touchEvent)
|
|
40
|
-
}
|
|
41
|
-
return null
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
onTouchStart (callback: any): this {
|
|
45
|
-
this.touchStartListeners.push(callback)
|
|
46
|
-
return this
|
|
47
|
-
}
|
|
48
|
-
_emitTouchStart(pointerId: number, clientX: number, clientY: number): any {
|
|
49
|
-
const touchEvent = new TouchStartEvent(clientX, clientY, pointerId)
|
|
50
|
-
touchEvent.target = this
|
|
51
|
-
for (let callback of this.touchStartListeners) {
|
|
52
|
-
callback(touchEvent)
|
|
53
|
-
if ((touchEvent as any)._trackHandler) {
|
|
54
|
-
return (touchEvent as any)._trackHandler
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return null
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
onLongPress (callback: any): this {
|
|
61
|
-
this.longPressListeners.push(callback)
|
|
62
|
-
return this
|
|
63
|
-
}
|
|
64
|
-
// Fired by the host when the finger is held past the long-press threshold. Returns null when
|
|
65
|
-
// nothing is listening — the host then lets the trailing click through as usual. Otherwise it
|
|
66
|
-
// returns an object whose presence tells the host to swallow that click, carrying the optional
|
|
67
|
-
// drag handler a listener registered via `ev.track(...)` for the host to drive the gesture.
|
|
68
|
-
_emitLongPress(pointerId: number, clientX: number, clientY: number): any {
|
|
69
|
-
if (this.longPressListeners.length === 0) return null
|
|
70
|
-
const longPressEvent = new LongPressEvent(clientX, clientY, pointerId)
|
|
71
|
-
longPressEvent.target = this
|
|
72
|
-
for (let callback of this.longPressListeners) {
|
|
73
|
-
callback(longPressEvent)
|
|
74
|
-
}
|
|
75
|
-
return { track: (longPressEvent as any)._trackHandler ?? null }
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
isPressed(): boolean {
|
|
79
|
-
if (!this._id) return false
|
|
80
|
-
return _creatorUI.isButtonPressed(this._id)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Buttons are row + centered by default: the icon+label button is the norm, and yoga's column
|
|
85
|
-
// default was a recurring authoring/codegen trap.
|
|
86
|
-
const BUTTON_DEFAULTS = { flexDirection: "row", justifyContent: "center", alignItems: "center" } as const
|
|
87
|
-
|
|
88
|
-
const makeButton = (style: any, children: any) => new ButtonElement("button", style, children)
|
|
89
|
-
|
|
90
|
-
/** @internal Compiler fast path (chisel `flatten_ui` raw lowering) — see UIContainer. */
|
|
91
|
-
export const __UIButton = (children: UINodeChild[] | ChildrenFn): UIButton => makeButton({ ...BUTTON_DEFAULTS }, children)
|
|
92
|
-
|
|
93
|
-
/** Create a button (row + centered by default — the icon+label shape). Same argument forms as
|
|
94
|
-
* `UIColumn`; attach behavior with `.onClick(...)`. */
|
|
95
|
-
export function UIButton(...children: UIChildArg[]): UIButton;
|
|
96
|
-
export function UIButton(children: UINodeChild[] | ChildrenFn): UIButton;
|
|
97
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
98
|
-
export function UIButton(style: UIButtonStyle, children?: UINodeChild[] | ChildrenFn): UIButton;
|
|
99
|
-
export function UIButton(...args: any[]): UIButton {
|
|
100
|
-
return buildUI(args, BUTTON_DEFAULTS, makeButton)
|
|
101
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { ContainerElement, buildUI, type ChildrenFn, type ContainerStyle, type DrawableStyle, type ElementStyle, type UIChildArg, type UIContainerBase, type UINodeChild } from "./UINode"
|
|
2
|
-
|
|
3
|
-
export type UIContainerStyle = ElementStyle & DrawableStyle & ContainerStyle
|
|
4
|
-
|
|
5
|
-
/** A vertical flex container — children stack top to bottom. */
|
|
6
|
-
export interface UIColumn extends UIContainerBase<UIContainerStyle> {
|
|
7
|
-
readonly type: "column",
|
|
8
|
-
}
|
|
9
|
-
const makeColumn = (style: any, children: any) => new ContainerElement("column", style, children)
|
|
10
|
-
|
|
11
|
-
/** @internal Compiler fast path (chisel `flatten_ui` raw lowering): construction with a proven
|
|
12
|
-
* plain-children array — or a reactive ChildrenFn (the Element constructor branches on
|
|
13
|
-
* `typeof === "function"` either way) — skipping the buildUI argument dispatch entirely. */
|
|
14
|
-
export const __UIColumn = (children: UINodeChild[] | ChildrenFn): UIColumn => makeColumn({}, children)
|
|
15
|
-
export const __UIRow = (children: UINodeChild[] | ChildrenFn): UIRow => makeRow({ flexDirection: "row" }, children)
|
|
16
|
-
export const __UIBox = (children: UINodeChild[] | ChildrenFn): UIBox => makeBox({ ...BOX_DEFAULTS }, children)
|
|
17
|
-
|
|
18
|
-
/** Create a vertical flex container. Children are variadic — arrays flatten one level, falsy
|
|
19
|
-
* entries are skipped; a lone function makes the children reactive. */
|
|
20
|
-
export function UIColumn(...children: UIChildArg[]): UIColumn
|
|
21
|
-
export function UIColumn(children: UINodeChild[] | ChildrenFn): UIColumn
|
|
22
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
23
|
-
export function UIColumn(style: UIContainerStyle, children?: UINodeChild[] | ChildrenFn): UIColumn
|
|
24
|
-
export function UIColumn(...args: any[]): UIColumn {
|
|
25
|
-
return buildUI(args, null, makeColumn)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** A horizontal flex container — children flow left to right. */
|
|
29
|
-
export interface UIRow extends UIContainerBase<UIContainerStyle> {
|
|
30
|
-
readonly type: "row",
|
|
31
|
-
}
|
|
32
|
-
const ROW_DEFAULTS = { flexDirection: "row" } as const
|
|
33
|
-
const makeRow = (style: any, children: any) => new ContainerElement("row", style, children)
|
|
34
|
-
|
|
35
|
-
/** Create a horizontal flex container (same argument forms as `UIColumn`). */
|
|
36
|
-
export function UIRow(...children: UIChildArg[]): UIRow
|
|
37
|
-
export function UIRow(children: UINodeChild[] | ChildrenFn): UIRow
|
|
38
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
39
|
-
export function UIRow(style: UIContainerStyle, children?: UINodeChild[] | ChildrenFn): UIRow
|
|
40
|
-
export function UIRow(...args: any[]): UIRow {
|
|
41
|
-
return buildUI(args, ROW_DEFAULTS, makeRow)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** A centering container — `justifyContent`/`alignItems` default to center. */
|
|
45
|
-
export interface UIBox extends UIContainerBase<UIContainerStyle> {
|
|
46
|
-
readonly type: "box",
|
|
47
|
-
}
|
|
48
|
-
const BOX_DEFAULTS = { justifyContent: "center", alignItems: "center" } as const
|
|
49
|
-
|
|
50
|
-
const makeBox = (style: any, children: any) => new ContainerElement("box", style, children)
|
|
51
|
-
|
|
52
|
-
/** Create a centering container — children are centered on both axes by default (icon badges,
|
|
53
|
-
* avatars, empty states). Same argument forms as `UIColumn`. */
|
|
54
|
-
export function UIBox(...children: UIChildArg[]): UIBox
|
|
55
|
-
export function UIBox(children: UINodeChild[] | ChildrenFn): UIBox
|
|
56
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
57
|
-
export function UIBox(style: UIContainerStyle, children?: UINodeChild[] | ChildrenFn): UIBox
|
|
58
|
-
export function UIBox(...args: any[]): UIBox {
|
|
59
|
-
return buildUI(args, BOX_DEFAULTS, makeBox)
|
|
60
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import type { FetchResponse } from "../runtime/fetch"
|
|
2
|
-
import type { SvgSourceValue as SvgSource } from "../runtime/misc"
|
|
3
|
-
import type { File } from "../runtime/fetch"
|
|
4
|
-
import { Canvas, isCanvas } from "../canvas/Canvas"
|
|
5
|
-
import { Element, type Color, type ElementStyle, type UIElementBase } from "./UINode"
|
|
6
|
-
|
|
7
|
-
export type UIImageStyle = ElementStyle & { borderRadius?: number, objectFit?: "cover" | "contain" | "fill", tintColor?: Color }
|
|
8
|
-
|
|
9
|
-
/** A baked Canvas surface as an image source. The UI backend resolves it to a UI texture — see
|
|
10
|
-
* docs/canvas-contract.md ("Pending"). */
|
|
11
|
-
export type CanvasImageSource = { canvasSurface: number }
|
|
12
|
-
|
|
13
|
-
/** Accepted image sources. A Canvas is baked to a surface marker on assign. */
|
|
14
|
-
export type ImageSource = string | FetchResponse | File | SvgSource | Canvas
|
|
15
|
-
|
|
16
|
-
const toSrc = (src: ImageSource): string | FetchResponse | File | SvgSource | CanvasImageSource =>
|
|
17
|
-
// _bakeSurfaceForUI (not _bakeSurface) also flags the canvas UI-bound, so canvas.update() later
|
|
18
|
-
// refreshes this image node in place — that's what makes an animated UIImage(canvas) update.
|
|
19
|
-
isCanvas(src) ? { canvasSurface: src._bakeSurfaceForUI() } : src
|
|
20
|
-
|
|
21
|
-
/** The stored/resolved image source (a Canvas is resolved to a surface marker). */
|
|
22
|
-
export type ResolvedImageSource = string | FetchResponse | File | SvgSource | CanvasImageSource
|
|
23
|
-
|
|
24
|
-
/** An image element. Sources: URL / `asset(...)`, fetch response / File, an SVG source
|
|
25
|
-
* (`assetIcon`), or a live Canvas (`canvas.update()` refreshes the node in place). */
|
|
26
|
-
export interface UIImage extends UIElementBase<UIImageStyle> {
|
|
27
|
-
readonly type: "image",
|
|
28
|
-
/** The image source — writable to swap the picture in place. */
|
|
29
|
-
get src(): ResolvedImageSource
|
|
30
|
-
set src(value: ImageSource)
|
|
31
|
-
|
|
32
|
-
/** Render only a sub-rectangle of the source texture (texture pixels) — the atlas/spritesheet
|
|
33
|
-
* primitive: crop once, then swap the rect per frame for sprite animation. The rect's w/h
|
|
34
|
-
* become the node's intrinsic size and override `objectFit` — the cropped frame fills the box. */
|
|
35
|
-
setSourceRect(x: number, y: number, w: number, h: number): this
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
class ImageElement extends Element<"image"> {
|
|
39
|
-
private _src: ResolvedImageSource
|
|
40
|
-
// Current source sub-rect; undefined until the first setSourceRect. Kept on the node (not
|
|
41
|
-
// just sent as a command) so a crop set while detached (_id == 0) is reapplied at mount —
|
|
42
|
-
// the viewer reads it when it creates the element.
|
|
43
|
-
private _sourceRect?: [number, number, number, number]
|
|
44
|
-
constructor(style: any, src: ImageSource) {
|
|
45
|
-
super("image", style)
|
|
46
|
-
this._src = toSrc(src)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
get src(): ResolvedImageSource {
|
|
50
|
-
return this._src
|
|
51
|
-
}
|
|
52
|
-
set src(value: ImageSource) {
|
|
53
|
-
this._src = toSrc(value)
|
|
54
|
-
if (this._id !== 0) {
|
|
55
|
-
_creatorUI.updateNode(this._id, "src", this._src)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
setSourceRect(x: number, y: number, w: number, h: number): this {
|
|
60
|
-
// Stash on the node so a crop set before mount is reapplied when the element is created.
|
|
61
|
-
this._sourceRect = [x, y, w, h]
|
|
62
|
-
// Live mutation: fast channel (not _style → no PX_VALUE density scaling: these are texture
|
|
63
|
-
// pixels, a different coordinate space). On a detached node there is nothing to mutate yet —
|
|
64
|
-
// the stash above carries it to mount. The viewer decides relayout vs draw-only by comparing
|
|
65
|
-
// w/h against the rect it has stashed on the element.
|
|
66
|
-
if (this._id !== 0) {
|
|
67
|
-
_creatorUI.setSourceRect(this._id, x, y, w, h)
|
|
68
|
-
}
|
|
69
|
-
return this
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Create an image element from a source (see {@link ImageSource}). */
|
|
74
|
-
export function UIImage(src: ImageSource): UIImage
|
|
75
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
76
|
-
export function UIImage(style: UIImageStyle, src: ImageSource): UIImage
|
|
77
|
-
export function UIImage(...args: [ImageSource] | [UIImageStyle, ImageSource]): UIImage {
|
|
78
|
-
if (args.length === 1) {
|
|
79
|
-
return new ImageElement({}, args[0])
|
|
80
|
-
} else {
|
|
81
|
-
return new ImageElement(args[0], args[1])
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { type ElementStyle, type DrawableStyle, Element, type TextStyle, type Color, type BaseStyle, type UIElementBase } from "./UINode";
|
|
2
|
-
|
|
3
|
-
type InputStyle = {
|
|
4
|
-
placeholder?: string,
|
|
5
|
-
placeholderColor?: Color,
|
|
6
|
-
/**
|
|
7
|
-
* Keyboard hint, NOT a validator — `number` does not block pasted letters; validate in your own
|
|
8
|
-
* onChange. The phone-pad value is `phone` (LeCodes has no `tel`).
|
|
9
|
-
*
|
|
10
|
-
* `date` / `time` are PICKER kinds, not keyboards: the host opens its native picker in the
|
|
11
|
-
* keyboard slot (iOS wheels / browser calendar) and free typing is disabled. `value` is always
|
|
12
|
-
* canonical — `YYYY-MM-DD` for `date`, `HH:MM` (24h) for `time` — while the field displays a
|
|
13
|
-
* localized string; set/compare values in the canonical form only.
|
|
14
|
-
*/
|
|
15
|
-
type?: "text" | "password" | "search" | "phone" | "email" | "number" | "decimal" | "url"
|
|
16
|
-
| "date" | "time",
|
|
17
|
-
/**
|
|
18
|
-
* What the layout does while the keyboard is up (decided by the FOCUSED input). `true` (default):
|
|
19
|
-
* the layout viewport shrinks to the area above the keyboard — one relayout. `false`: the keyboard
|
|
20
|
-
* overlays the UI with NO layout recalculation — for chat composers that manage their own inset
|
|
21
|
-
* (pair with `app.keyboardHeight` / the app `"keyboard"` event) and full-screen canvases where a
|
|
22
|
-
* reflow is worse than overlap.
|
|
23
|
-
*/
|
|
24
|
-
keyboardShrink?: boolean,
|
|
25
|
-
/**
|
|
26
|
-
* Whether a tap on a non-interactive area dismisses the keyboard while THIS input is focused
|
|
27
|
-
* (like `keyboardShrink`, the policy of the focused input). `true` (default): tapping dead
|
|
28
|
-
* space blurs — but a tap on a button or another input NEVER dismisses; the control acts and
|
|
29
|
-
* focus stays. `false`: taps never dismiss — the chat-composer policy. `blur()`, the return
|
|
30
|
-
* key (per `enterKey`), and the platform's own gestures (iOS drag-down over the keyboard)
|
|
31
|
-
* still work in both modes. Scrolling never dismisses the keyboard on any setting.
|
|
32
|
-
*/
|
|
33
|
-
keyboardDismiss?: boolean,
|
|
34
|
-
/** Hard cap on the text length — enforced by the host while typing/pasting. */
|
|
35
|
-
maxLength?: number,
|
|
36
|
-
/** Auto-capitalization hint; omitted = platform default. */
|
|
37
|
-
autocapitalize?: "none" | "words" | "sentences" | "characters",
|
|
38
|
-
/** Enable/disable the platform autocorrection & suggestions; omitted = platform default. */
|
|
39
|
-
autocorrect?: boolean,
|
|
40
|
-
}
|
|
41
|
-
export type UIInputStyle = ElementStyle & DrawableStyle & TextStyle & InputStyle
|
|
42
|
-
|
|
43
|
-
/** UIInput-only (a UITextArea's Enter is a newline, period): the return-key label. */
|
|
44
|
-
type SubmitStyle = {
|
|
45
|
-
/**
|
|
46
|
-
* Return-key label. On submit the keyboard dismisses UNLESS `enterKey` is `"next"` — then the
|
|
47
|
-
* app is expected to call `otherInput.focus()` from `onSubmit`, so the keyboard never blinks.
|
|
48
|
-
*/
|
|
49
|
-
enterKey?: "done" | "go" | "next" | "search" | "send",
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** A single-line text input. Keyboard/picker kind via the `type` style, return-key behavior via
|
|
53
|
-
* `enterKey` + `onSubmit`; keyboard policy on `keyboardShrink`/`keyboardDismiss`. */
|
|
54
|
-
export interface UIInput extends UIElementBase<UIInputStyle & SubmitStyle & { onFocused?: UIInputStyle & { duration?: number } }, DrawableStyle & BaseStyle> {
|
|
55
|
-
readonly type: "input",
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* The field's text. Writable at any time — set it BEFORE the screen opens to pre-fill a form
|
|
59
|
-
* (settings, edit-profile); the value is stashed on the node and applied when the host builds
|
|
60
|
-
* it. Reads return the live text while the screen is open, and the last value you set while it
|
|
61
|
-
* isn't. The user's typing is not preserved across close/open (use `keepAlive()` for that).
|
|
62
|
-
*/
|
|
63
|
-
value: string
|
|
64
|
-
|
|
65
|
-
/** The text changed — fires on every user edit. */
|
|
66
|
-
onChange(callback: (value: string) => void): UIInput
|
|
67
|
-
/** Gained focus (keyboard opens). */
|
|
68
|
-
onFocus(callback: () => void): UIInput
|
|
69
|
-
/** Lost focus. */
|
|
70
|
-
onBlur(callback: () => void): UIInput
|
|
71
|
-
/** The keyboard's return key was pressed. `value` is the current text. See `enterKey`. */
|
|
72
|
-
onSubmit(callback: (value: string) => void): UIInput
|
|
73
|
-
|
|
74
|
-
/** Focus the input (opens the keyboard). No-op before mount. */
|
|
75
|
-
focus(): void
|
|
76
|
-
/** Release focus (dismisses the keyboard when this input held it). */
|
|
77
|
-
blur(): void
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** A multi-line text field — see the {@link UITextArea} factory for the auto-grow contract. */
|
|
81
|
-
export interface UITextArea extends UIElementBase<UIInputStyle & { onFocused?: UIInputStyle & { duration?: number } }, DrawableStyle & BaseStyle> {
|
|
82
|
-
readonly type: "textarea",
|
|
83
|
-
|
|
84
|
-
/** The field's text — same contract as {@link UIInput.value}: settable before mount to pre-fill. */
|
|
85
|
-
value: string
|
|
86
|
-
|
|
87
|
-
/** The text changed — fires on every user edit. */
|
|
88
|
-
onChange(callback: (value: string) => void): UITextArea
|
|
89
|
-
/** Gained focus (keyboard opens). */
|
|
90
|
-
onFocus(callback: () => void): UITextArea
|
|
91
|
-
/** Lost focus. */
|
|
92
|
-
onBlur(callback: () => void): UITextArea
|
|
93
|
-
|
|
94
|
-
/** Focus the text area (opens the keyboard). No-op before mount. */
|
|
95
|
-
focus(): void
|
|
96
|
-
/** Release focus (dismisses the keyboard when this text area held it). */
|
|
97
|
-
blur(): void
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
class InputElement<T extends "input" | "textarea"> extends Element<T> {
|
|
101
|
-
|
|
102
|
-
readonly cl: Function[] = []
|
|
103
|
-
readonly fl: Function[] = []
|
|
104
|
-
readonly bl: Function[] = []
|
|
105
|
-
readonly sl: Function[] = []
|
|
106
|
-
|
|
107
|
-
/** @internal The value as last set by CODE. Hosts read it at node creation (after the initial
|
|
108
|
-
* style, so a `date` field's canonical parse and `maxLength` are already in place), which is
|
|
109
|
-
* what makes a value assigned before mount — a pre-filled settings form — land on the field.
|
|
110
|
-
* Same pre-mount stash as UIImage's `_sourceRect`. Typing does NOT sync back here: while
|
|
111
|
-
* mounted the HOST owns the text (IME composition, paste, the maxLength clamp, date/time
|
|
112
|
-
* canonicalization) and the getter reads it over the bridge. So on a remount the field comes
|
|
113
|
-
* back with the last code-set value, not what the user typed — screens that must keep live
|
|
114
|
-
* editing state across close/open use `keepAlive()`, the mechanism built for it. */
|
|
115
|
-
_value = ""
|
|
116
|
-
|
|
117
|
-
get value() {
|
|
118
|
-
// Mounted: the host is authoritative. Unmounted: what code last set (0 => never mounted).
|
|
119
|
-
return this._id !== 0 ? _creatorUI.getTextValue(this._id) : this._value
|
|
120
|
-
}
|
|
121
|
-
set value(value: string) {
|
|
122
|
-
this._value = value
|
|
123
|
-
if (this._id !== 0) {
|
|
124
|
-
_creatorUI.updateNode(this._id, "value", value)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// `phone` is SDK-surface only — hosts (and the web's verbatim `el.type`) keep HTML's `tel` as
|
|
129
|
-
// the wire format, so the rename never reaches them.
|
|
130
|
-
_mapStyle(style: any): void {
|
|
131
|
-
if (style.type === "phone") style.type = "tel"
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
onChange (callback: (value: string) => void): this {
|
|
135
|
-
this.cl.push(callback)
|
|
136
|
-
return this
|
|
137
|
-
}
|
|
138
|
-
onFocus(callback: () => void): this {
|
|
139
|
-
this.fl.push(callback)
|
|
140
|
-
return this
|
|
141
|
-
}
|
|
142
|
-
onBlur(callback: () => void): this {
|
|
143
|
-
this.bl.push(callback)
|
|
144
|
-
return this
|
|
145
|
-
}
|
|
146
|
-
onSubmit(callback: (value: string) => void): this {
|
|
147
|
-
this.sl.push(callback)
|
|
148
|
-
return this
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Focus rides the existing value channel (updateNode "focus") — no new ABI method.
|
|
152
|
-
focus(): void {
|
|
153
|
-
if (this._id !== 0) {
|
|
154
|
-
_creatorUI.updateNode(this._id, "focus", true)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
blur(): void {
|
|
158
|
-
if (this._id !== 0) {
|
|
159
|
-
_creatorUI.updateNode(this._id, "focus", false)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/** Create a single-line text input. Read/write the text via `.value`, listen with
|
|
165
|
-
* `onChange`/`onSubmit`; style keys `placeholder`, `type`, `enterKey`, … configure it. */
|
|
166
|
-
export function UIInput(): UIInput;
|
|
167
|
-
export function UIInput(style: UIInputStyle): UIInput;
|
|
168
|
-
export function UIInput(style?: UIInputStyle): UIInput {
|
|
169
|
-
// One text line as the floor — an unstyled input must never collapse to 0 height.
|
|
170
|
-
return new InputElement("input", { minHeight: "1.2em", ...style })
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Multi-line text field. Enter is a newline (submit lives on UIInput / your own button).
|
|
175
|
-
*
|
|
176
|
-
* Auto-grow: with no explicit `height` the field measures its own content and grows line by
|
|
177
|
-
* line — clamp the range with `minHeight` / `maxHeight` (past `maxHeight` the text scrolls
|
|
178
|
-
* inside). A fixed `height` opts out and scrolls internally from the start. Chat composers are
|
|
179
|
-
* the canonical use: a bare textarea in a padded pill, `maxHeight` at ~5 lines.
|
|
180
|
-
*/
|
|
181
|
-
export function UITextArea(): UITextArea;
|
|
182
|
-
export function UITextArea(style: UIInputStyle): UITextArea;
|
|
183
|
-
export function UITextArea(style?: UIInputStyle): UITextArea {
|
|
184
|
-
return new InputElement("textarea", { minHeight: "1.2em", ...style })
|
|
185
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { type UIWidget, type UIWidgetStyle, WidgetElement } from "./UIWidget"
|
|
2
|
-
import { buildUI, type BaseStyle, type ChildrenFn, type Color, type DrawableStyle, type UIChildArg, type UINodeChild } from "./UINode"
|
|
3
|
-
|
|
4
|
-
export type UIModalStyle = UIWidgetStyle
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* The modal's hidden pose: `show()` animates from it, `hide()` animates to it. `duration` (ms)
|
|
8
|
-
* applies to both directions.
|
|
9
|
-
*/
|
|
10
|
-
export type UIModalTransition = DrawableStyle & BaseStyle & {
|
|
11
|
-
overlayColor?: Color | null,
|
|
12
|
-
duration?: number,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const MODAL_ANIM_MS = 200
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* A dialog: a `UIWidget` with the modal boilerplate built in. Comes with a scrim
|
|
19
|
-
* (`overlayColor: "rgba(0, 0, 0, 0.5)"` unless overridden), animates on `show()`/`hide()`
|
|
20
|
-
* (a 200 ms fade by default — swap the pose via `transition()`; the exit plays with
|
|
21
|
-
* `commit: false`, so the style is intact for the next show), and closes itself on a scrim tap
|
|
22
|
-
* or the Android back button (disable via `dismissible(false)`). Everything else is a plain
|
|
23
|
-
* widget — same styling, children, touch and `attachTo()` surface; create it **once** at module
|
|
24
|
-
* scope and reuse it.
|
|
25
|
-
*/
|
|
26
|
-
export interface UIModal extends UIWidget {
|
|
27
|
-
/** Mount as an overlay and play the entrance transition. No-op while already open. */
|
|
28
|
-
show(): void,
|
|
29
|
-
/** Play the exit transition, then unmount. No-op while closed or already closing. */
|
|
30
|
-
hide(): void,
|
|
31
|
-
/** True from `show()` until `hide()` starts (already false during the exit animation). */
|
|
32
|
-
readonly isOpen: boolean,
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Replace the show/hide animation. `hidden` is the off-screen pose — `show()` animates from
|
|
36
|
-
* it, `hide()` animates to it. Default `{ opacity: 0, duration: 200 }` (a fade); the pose
|
|
37
|
-
* replaces it wholesale, so a slide without a fade is just the slide. The scrim keeps its own
|
|
38
|
-
* fade unless the pose sets `overlayColor` itself.
|
|
39
|
-
*
|
|
40
|
-
* ```ts
|
|
41
|
-
* sheet.transition({ transform: "translateY(480px)", duration: 250 }) // bottom sheet
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
transition(hidden: UIModalTransition): this,
|
|
45
|
-
|
|
46
|
-
/** Called when `show()` mounts the modal. */
|
|
47
|
-
onOpen(callback: () => void): this,
|
|
48
|
-
/** Called when the modal starts closing — scrim tap, back button, or a `hide()` call. */
|
|
49
|
-
onClose(callback: () => void): this,
|
|
50
|
-
/** `dismissible(false)` keeps scrim taps and the back button from closing the modal
|
|
51
|
-
* (forced-choice dialogs). Default `true`. */
|
|
52
|
-
dismissible(enabled: boolean): this,
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export class ModalElement extends WidgetElement {
|
|
56
|
-
_open = false
|
|
57
|
-
_dismissible = true
|
|
58
|
-
_transition: UIModalTransition = { opacity: 0 }
|
|
59
|
-
_closeTimer?: ReturnType<typeof setTimeout>
|
|
60
|
-
readonly _openListeners: (() => void)[] = []
|
|
61
|
-
readonly _closeListeners: (() => void)[] = []
|
|
62
|
-
|
|
63
|
-
constructor(style: UIModalStyle, children: UINodeChild[] | ChildrenFn) {
|
|
64
|
-
super("widget", { overlayColor: "rgba(0, 0, 0, 0.5)", ...style }, children)
|
|
65
|
-
this.onOverlayTap(() => { if (this._dismissible) this.hide() })
|
|
66
|
-
this.onBackPressed(() => { if (this._dismissible) this.hide() })
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// The full animate argument: hidden pose + duration, plus the scrim fade — only when the
|
|
70
|
-
// modal actually has a scrim (overlayColor: null opts out; animating a null scrim would
|
|
71
|
-
// create the intercepting layer) and the pose doesn't drive the scrim itself.
|
|
72
|
-
private _pose(extra?: Record<string, unknown>): Record<string, unknown> {
|
|
73
|
-
const pose: Record<string, unknown> = { duration: MODAL_ANIM_MS, ...this._transition, ...extra }
|
|
74
|
-
const overlayColor = (this._style as UIModalStyle).overlayColor
|
|
75
|
-
if (pose.overlayColor === undefined && overlayColor !== undefined && overlayColor !== null) {
|
|
76
|
-
pose.overlayColor = "transparent"
|
|
77
|
-
}
|
|
78
|
-
return pose
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private get _duration(): number {
|
|
82
|
-
return this._transition.duration ?? MODAL_ANIM_MS
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
transition(hidden: UIModalTransition): this {
|
|
86
|
-
this._transition = hidden
|
|
87
|
-
return this
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
show(): void {
|
|
91
|
-
if (this._open) return
|
|
92
|
-
if (this._closeTimer !== undefined) { // reopened mid exit: finish that hide now
|
|
93
|
-
clearTimeout(this._closeTimer)
|
|
94
|
-
this._closeTimer = undefined
|
|
95
|
-
super.hide()
|
|
96
|
-
}
|
|
97
|
-
this._open = true
|
|
98
|
-
super.show()
|
|
99
|
-
this.animateFrom(this._pose())
|
|
100
|
-
for (const callback of this._openListeners) callback()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
hide(): void {
|
|
104
|
-
if (!this._open) return
|
|
105
|
-
this._open = false
|
|
106
|
-
this.animateTo(this._pose({ commit: false }))
|
|
107
|
-
this._closeTimer = setTimeout(() => { this._closeTimer = undefined; super.hide() }, this._duration)
|
|
108
|
-
for (const callback of this._closeListeners) callback()
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
get isOpen(): boolean {
|
|
112
|
-
return this._open
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
onOpen(callback: () => void): this {
|
|
116
|
-
this._openListeners.push(callback)
|
|
117
|
-
return this
|
|
118
|
-
}
|
|
119
|
-
onClose(callback: () => void): this {
|
|
120
|
-
this._closeListeners.push(callback)
|
|
121
|
-
return this
|
|
122
|
-
}
|
|
123
|
-
dismissible(enabled: boolean): this {
|
|
124
|
-
this._dismissible = enabled
|
|
125
|
-
return this
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const makeModal = (style: any, children: any) => new ModalElement(style, children)
|
|
130
|
-
|
|
131
|
-
/** Create a modal dialog (see {@link UIModal}) — create once at module scope, then
|
|
132
|
-
* `show()`/`hide()`. Same argument forms as `UIColumn`. */
|
|
133
|
-
export function UIModal(...children: UIChildArg[]): UIModal;
|
|
134
|
-
export function UIModal(children: UINodeChild[] | ChildrenFn): UIModal;
|
|
135
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
136
|
-
export function UIModal(style: UIModalStyle, children?: UINodeChild[] | ChildrenFn): UIModal;
|
|
137
|
-
export function UIModal(...args: any[]): UIModal {
|
|
138
|
-
return buildUI(args, null, makeModal)
|
|
139
|
-
}
|