lecodes-sdk 0.19.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/README.md +114 -0
- package/dist/global.d.ts +503 -0
- package/dist/host.d.ts +61 -0
- package/dist/inject.js +4730 -0
- package/dist/types/animate/animate.d.ts +20 -0
- package/dist/types/animate/bezier.d.ts +2 -0
- package/dist/types/animate/easings.d.ts +21 -0
- package/dist/types/canvas/Canvas.d.ts +168 -0
- package/dist/types/core/Aspect.d.ts +171 -0
- package/dist/types/core/InspectorUI.d.ts +88 -0
- package/dist/types/core/StateMachine.d.ts +81 -0
- package/dist/types/core/color.d.ts +13 -0
- package/dist/types/core/compWrite.d.ts +11 -0
- package/dist/types/core/events.d.ts +11 -0
- package/dist/types/core/fields.d.ts +58 -0
- package/dist/types/core/registry.d.ts +7 -0
- package/dist/types/core/signals.d.ts +29 -0
- package/dist/types/core/time.d.ts +31 -0
- package/dist/types/g2/Camera2D.d.ts +19 -0
- package/dist/types/g2/CharacterController2D.d.ts +134 -0
- package/dist/types/g2/Node2D.d.ts +91 -0
- package/dist/types/g2/OneWay2D.d.ts +24 -0
- package/dist/types/g2/Physics2D.d.ts +147 -0
- package/dist/types/g2/Scene2D.d.ts +72 -0
- package/dist/types/g2/Shape2D.d.ts +58 -0
- package/dist/types/g2/Sprite.d.ts +51 -0
- package/dist/types/g2/SpriteAnimation.d.ts +50 -0
- package/dist/types/g2/SpriteSheet.d.ts +69 -0
- package/dist/types/g2/Texture2D.d.ts +16 -0
- package/dist/types/g2/Tilemap.d.ts +20 -0
- package/dist/types/g2/Tileset.d.ts +32 -0
- package/dist/types/g2/Trigger2D.d.ts +20 -0
- package/dist/types/g2/autotile.d.ts +133 -0
- package/dist/types/g2/cells.d.ts +14 -0
- package/dist/types/g2/defineScene2d.d.ts +141 -0
- package/dist/types/g2/groups2d.d.ts +16 -0
- package/dist/types/g2/loop.d.ts +4 -0
- package/dist/types/g2/scenarios2d.d.ts +30 -0
- package/dist/types/g2/touch.d.ts +2 -0
- package/dist/types/gl/Camera.d.ts +79 -0
- package/dist/types/gl/CameraPlace.d.ts +26 -0
- package/dist/types/gl/CharacterController.d.ts +98 -0
- package/dist/types/gl/Gearbox.d.ts +86 -0
- package/dist/types/gl/Geometry.d.ts +39 -0
- package/dist/types/gl/IK.d.ts +53 -0
- package/dist/types/gl/InstancedMesh.d.ts +46 -0
- package/dist/types/gl/Light.d.ts +73 -0
- package/dist/types/gl/Lightmap.d.ts +85 -0
- package/dist/types/gl/Locomotion.d.ts +279 -0
- package/dist/types/gl/Material.d.ts +100 -0
- package/dist/types/gl/Mesh.d.ts +33 -0
- package/dist/types/gl/Model.d.ts +53 -0
- package/dist/types/gl/NavAgent.d.ts +99 -0
- package/dist/types/gl/NavMesh.d.ts +169 -0
- package/dist/types/gl/Node.d.ts +99 -0
- package/dist/types/gl/Noise.d.ts +20 -0
- package/dist/types/gl/Particles.d.ts +277 -0
- package/dist/types/gl/Physics.d.ts +91 -0
- package/dist/types/gl/Plane.d.ts +19 -0
- package/dist/types/gl/Ragdoll.d.ts +86 -0
- package/dist/types/gl/Ray.d.ts +8 -0
- package/dist/types/gl/Scene.d.ts +221 -0
- package/dist/types/gl/Shape.d.ts +122 -0
- package/dist/types/gl/Terrain.d.ts +280 -0
- package/dist/types/gl/Texture.d.ts +27 -0
- package/dist/types/gl/Trigger.d.ts +10 -0
- package/dist/types/gl/Vehicle.d.ts +191 -0
- package/dist/types/gl/Wheel.d.ts +95 -0
- package/dist/types/gl/animation/AnimationClip.d.ts +60 -0
- package/dist/types/gl/animation/Animator.d.ts +219 -0
- package/dist/types/gl/animation/Layer.d.ts +31 -0
- package/dist/types/gl/animation/Loop.d.ts +17 -0
- package/dist/types/gl/animation/Playback.d.ts +36 -0
- package/dist/types/gl/animation/core.d.ts +367 -0
- package/dist/types/gl/controls.d.ts +19 -0
- package/dist/types/gl/physicsEvents.d.ts +1 -0
- package/dist/types/gl/scenarios.d.ts +98 -0
- package/dist/types/gl/state.d.ts +5 -0
- package/dist/types/gl/terrainMesh.d.ts +46 -0
- package/dist/types/gl/touch.d.ts +2 -0
- package/dist/types/inject.d.ts +123 -0
- package/dist/types/math/Mathf.d.ts +39 -0
- package/dist/types/math/mat4.d.ts +66 -0
- package/dist/types/math/quat.d.ts +53 -0
- package/dist/types/math/vec.d.ts +129 -0
- package/dist/types/net/codec.d.ts +25 -0
- package/dist/types/net/core.d.ts +106 -0
- package/dist/types/net/index.d.ts +80 -0
- package/dist/types/net/replication.d.ts +101 -0
- package/dist/types/plugins/camera.d.ts +25 -0
- package/dist/types/plugins/geolocation.d.ts +39 -0
- package/dist/types/plugins/oauth.d.ts +25 -0
- package/dist/types/plugins/permission.d.ts +1 -0
- package/dist/types/plugins/push.d.ts +46 -0
- package/dist/types/plugins/qr.d.ts +21 -0
- package/dist/types/plugins/service.d.ts +33 -0
- package/dist/types/runtime/app.d.ts +67 -0
- package/dist/types/runtime/appEvents.d.ts +7 -0
- package/dist/types/runtime/channel.d.ts +1 -0
- package/dist/types/runtime/clipboard.d.ts +7 -0
- package/dist/types/runtime/datetime.d.ts +80 -0
- package/dist/types/runtime/device.d.ts +126 -0
- package/dist/types/runtime/fetch.d.ts +31 -0
- package/dist/types/runtime/files.d.ts +33 -0
- package/dist/types/runtime/input.d.ts +121 -0
- package/dist/types/runtime/media.d.ts +46 -0
- package/dist/types/runtime/misc.d.ts +11 -0
- package/dist/types/runtime/net.d.ts +15 -0
- package/dist/types/runtime/rpc.d.ts +44 -0
- package/dist/types/runtime/service.d.ts +1 -0
- package/dist/types/runtime/share.d.ts +2 -0
- package/dist/types/runtime/storage.d.ts +5 -0
- package/dist/types/runtime/touch.d.ts +56 -0
- package/dist/types/scene/defineScene.d.ts +296 -0
- package/dist/types/scene/editorPlugins.d.ts +82 -0
- package/dist/types/scene/gizmos.d.ts +56 -0
- package/dist/types/scene/grammar.d.ts +56 -0
- package/dist/types/scene/level.d.ts +98 -0
- package/dist/types/scene/material.d.ts +76 -0
- package/dist/types/server/auth/appConfig.d.ts +16 -0
- package/dist/types/server/auth/global.d.ts +56 -0
- package/dist/types/server/auth/models.d.ts +164 -0
- package/dist/types/server/auth/types.d.ts +56 -0
- package/dist/types/server/channel.d.ts +28 -0
- package/dist/types/server/context.d.ts +27 -0
- package/dist/types/server/db/defineDb.d.ts +36 -0
- package/dist/types/server/db/fields.d.ts +146 -0
- package/dist/types/server/db/index.d.ts +6 -0
- package/dist/types/server/db/marci/query.d.ts +326 -0
- package/dist/types/server/db/types.d.ts +163 -0
- package/dist/types/server/errors.d.ts +8 -0
- package/dist/types/server/inject.d.ts +5 -0
- package/dist/types/ui/NativeView.d.ts +38 -0
- package/dist/types/ui/UI.d.ts +27 -0
- package/dist/types/ui/UIBottomSheet.d.ts +71 -0
- package/dist/types/ui/UIButton.d.ts +30 -0
- package/dist/types/ui/UIContainer.d.ts +33 -0
- package/dist/types/ui/UIImage.d.ts +35 -0
- package/dist/types/ui/UIInput.d.ts +110 -0
- package/dist/types/ui/UIModal.d.ts +70 -0
- package/dist/types/ui/UINode.d.ts +363 -0
- package/dist/types/ui/UIPager.d.ts +123 -0
- package/dist/types/ui/UIPopover.d.ts +39 -0
- package/dist/types/ui/UIScreen.d.ts +57 -0
- package/dist/types/ui/UIScrollable.d.ts +40 -0
- package/dist/types/ui/UISpacer.d.ts +9 -0
- package/dist/types/ui/UITabs.d.ts +96 -0
- package/dist/types/ui/UIText.d.ts +19 -0
- package/dist/types/ui/UIVideo.d.ts +28 -0
- package/dist/types/ui/UIVirtualizedList.d.ts +97 -0
- package/dist/types/ui/UIWidget.d.ts +65 -0
- package/dist/types/ui/fonts.d.ts +9 -0
- package/dist/types/ui/presentable.d.ts +68 -0
- package/dist/types/ui/router.d.ts +40 -0
- package/dist/types/ui/theme.d.ts +26 -0
- package/dist/types.json +1 -0
- package/package.json +46 -0
- package/prompts/2d.md +395 -0
- package/prompts/3d-scene-files.md +113 -0
- package/prompts/3d-scene.md +119 -0
- package/prompts/3d.md +303 -0
- package/prompts/README.md +142 -0
- package/prompts/ar.md +109 -0
- package/prompts/canvas.md +27 -0
- package/prompts/compose.ts +46 -0
- package/prompts/concept.md +49 -0
- package/prompts/core-design.md +75 -0
- package/prompts/core.md +264 -0
- package/prompts/design.md +218 -0
- package/prompts/dist/2d-game.md +1530 -0
- package/prompts/dist/3d-app.md +1672 -0
- package/prompts/dist/ar-app.md +1548 -0
- package/prompts/dist/concept.md +49 -0
- package/prompts/dist/design.md +498 -0
- package/prompts/dist/ui-app.md +1134 -0
- package/prompts/index.md +37 -0
- package/prompts/intake-prompt.md +33 -0
- package/prompts/namer-prompt.md +12 -0
- package/prompts/router-prompt.md +50 -0
- package/prompts/select.ts +111 -0
- package/prompts/ui-design.md +203 -0
- package/prompts/ui.md +803 -0
- package/src/animate/animate.ts +238 -0
- package/src/animate/bezier.ts +138 -0
- package/src/animate/easings.ts +126 -0
- package/src/bridges.d.ts +1345 -0
- package/src/canvas/Canvas.ts +305 -0
- package/src/compile/__tests__/assetIconMacro.test.ts +219 -0
- package/src/compile/__tests__/assetMacro.test.ts +74 -0
- package/src/compile/__tests__/assetName.test.ts +55 -0
- package/src/compile/__tests__/compile.test.ts +287 -0
- package/src/compile/__tests__/detectEntry.test.ts +132 -0
- package/src/compile/__tests__/fontMacro.test.ts +199 -0
- package/src/compile/aspectMacro.ts +86 -0
- package/src/compile/assetIconMacro.ts +384 -0
- package/src/compile/assetMacro.ts +146 -0
- package/src/compile/assetName.ts +50 -0
- package/src/compile/bundler.ts +287 -0
- package/src/compile/compileProject.ts +127 -0
- package/src/compile/detectEntry.ts +128 -0
- package/src/compile/fontMacro.ts +459 -0
- package/src/compile/fontRegistry.ts +78 -0
- package/src/compile/header.ts +67 -0
- package/src/compile/index.ts +100 -0
- package/src/compile/libraryImports.ts +52 -0
- package/src/compile/liteMaterial.ts +247 -0
- package/src/compile/sceneEditor.ts +88 -0
- package/src/compile/serverSplit.ts +233 -0
- package/src/compile/serverTypes.ts +227 -0
- package/src/compile/sfnt.ts +98 -0
- package/src/compile/shaderSchema.ts +202 -0
- package/src/compile/shaderTargets.ts +77 -0
- package/src/compile/sourcemap.ts +25 -0
- package/src/core/Aspect.ts +568 -0
- package/src/core/InspectorUI.ts +212 -0
- package/src/core/StateMachine.ts +308 -0
- package/src/core/__tests__/stateMachine.test.ts +132 -0
- package/src/core/color.ts +66 -0
- package/src/core/compWrite.ts +42 -0
- package/src/core/events.ts +38 -0
- package/src/core/fields.ts +120 -0
- package/src/core/registry.ts +23 -0
- package/src/core/signals.ts +277 -0
- package/src/core/time.ts +84 -0
- package/src/g2/Camera2D.ts +40 -0
- package/src/g2/CharacterController2D.ts +276 -0
- package/src/g2/Node2D.ts +267 -0
- package/src/g2/OneWay2D.ts +66 -0
- package/src/g2/Physics2D.ts +346 -0
- package/src/g2/Scene2D.ts +209 -0
- package/src/g2/Shape2D.ts +259 -0
- package/src/g2/Sprite.ts +89 -0
- package/src/g2/SpriteAnimation.ts +171 -0
- package/src/g2/SpriteSheet.ts +166 -0
- package/src/g2/Texture2D.ts +47 -0
- package/src/g2/Tilemap.ts +41 -0
- package/src/g2/Tileset.ts +71 -0
- package/src/g2/Trigger2D.ts +77 -0
- package/src/g2/autotile.ts +433 -0
- package/src/g2/cells.ts +91 -0
- package/src/g2/defineScene2d.ts +381 -0
- package/src/g2/groups2d.ts +106 -0
- package/src/g2/loop.ts +50 -0
- package/src/g2/scenarios2d.ts +69 -0
- package/src/g2/touch.ts +83 -0
- package/src/gl/Camera.ts +160 -0
- package/src/gl/CameraPlace.ts +52 -0
- package/src/gl/CharacterController.ts +238 -0
- package/src/gl/Gearbox.ts +212 -0
- package/src/gl/Geometry.ts +279 -0
- package/src/gl/IK.ts +193 -0
- package/src/gl/InstancedMesh.ts +132 -0
- package/src/gl/Light.ts +135 -0
- package/src/gl/Lightmap.ts +402 -0
- package/src/gl/Locomotion.ts +498 -0
- package/src/gl/Material.ts +279 -0
- package/src/gl/Mesh.ts +83 -0
- package/src/gl/Model.ts +124 -0
- package/src/gl/NavAgent.ts +337 -0
- package/src/gl/NavMesh.ts +397 -0
- package/src/gl/Node.ts +350 -0
- package/src/gl/Noise.ts +30 -0
- package/src/gl/Particles.ts +676 -0
- package/src/gl/Physics.ts +222 -0
- package/src/gl/Plane.ts +53 -0
- package/src/gl/Ragdoll.ts +270 -0
- package/src/gl/Ray.ts +16 -0
- package/src/gl/Scene.ts +505 -0
- package/src/gl/Shape.ts +409 -0
- package/src/gl/Terrain.ts +1092 -0
- package/src/gl/Texture.ts +63 -0
- package/src/gl/Trigger.ts +45 -0
- package/src/gl/Vehicle.ts +473 -0
- package/src/gl/Wheel.ts +240 -0
- package/src/gl/animation/AnimationClip.ts +204 -0
- package/src/gl/animation/Animator.ts +329 -0
- package/src/gl/animation/Layer.ts +39 -0
- package/src/gl/animation/Loop.ts +31 -0
- package/src/gl/animation/Playback.ts +52 -0
- package/src/gl/animation/core.ts +670 -0
- package/src/gl/controls.ts +95 -0
- package/src/gl/physicsEvents.ts +20 -0
- package/src/gl/scenarios.ts +291 -0
- package/src/gl/state.ts +6 -0
- package/src/gl/terrainMesh.ts +219 -0
- package/src/gl/touch.ts +68 -0
- package/src/host.d.ts +61 -0
- package/src/inject.ts +203 -0
- package/src/math/Mathf.ts +118 -0
- package/src/math/mat4.ts +278 -0
- package/src/math/quat.ts +232 -0
- package/src/math/vec.ts +255 -0
- package/src/net/codec.ts +119 -0
- package/src/net/core.ts +384 -0
- package/src/net/index.ts +181 -0
- package/src/net/replication.ts +622 -0
- package/src/plugins/camera.ts +81 -0
- package/src/plugins/geolocation.ts +123 -0
- package/src/plugins/oauth.ts +61 -0
- package/src/plugins/permission.ts +7 -0
- package/src/plugins/push.ts +132 -0
- package/src/plugins/qr.ts +73 -0
- package/src/plugins/service.ts +47 -0
- package/src/runtime/app.ts +101 -0
- package/src/runtime/appEvents.ts +54 -0
- package/src/runtime/channel.ts +61 -0
- package/src/runtime/clipboard.ts +20 -0
- package/src/runtime/datetime.ts +329 -0
- package/src/runtime/device.ts +293 -0
- package/src/runtime/fetch.ts +77 -0
- package/src/runtime/files.ts +108 -0
- package/src/runtime/input.ts +175 -0
- package/src/runtime/media.ts +111 -0
- package/src/runtime/misc.ts +16 -0
- package/src/runtime/net.ts +36 -0
- package/src/runtime/rpc.ts +218 -0
- package/src/runtime/service.ts +83 -0
- package/src/runtime/share.ts +9 -0
- package/src/runtime/storage.ts +13 -0
- package/src/runtime/touch.ts +76 -0
- package/src/scene/defineScene.ts +1396 -0
- package/src/scene/editorPlugins.ts +110 -0
- package/src/scene/gizmos.ts +148 -0
- package/src/scene/grammar.ts +120 -0
- package/src/scene/level.ts +296 -0
- package/src/scene/material.ts +188 -0
- package/src/server/auth/appConfig.ts +12 -0
- package/src/server/auth/global.ts +80 -0
- package/src/server/auth/host.ts +318 -0
- package/src/server/auth/models.ts +83 -0
- package/src/server/auth/types.ts +50 -0
- package/src/server/channel.ts +56 -0
- package/src/server/context.ts +36 -0
- package/src/server/db/defineDb.ts +237 -0
- package/src/server/db/fields.ts +132 -0
- package/src/server/db/httpTransport.ts +93 -0
- package/src/server/db/index.ts +7 -0
- package/src/server/db/marci/query.ts +412 -0
- package/src/server/db/types.ts +202 -0
- package/src/server/errors.ts +12 -0
- package/src/server/host.ts +74 -0
- package/src/server/inject.ts +13 -0
- package/src/server/runtime.ts +133 -0
- package/src/server/validate.ts +87 -0
- package/src/ui/NativeView.ts +142 -0
- package/src/ui/UI.ts +39 -0
- package/src/ui/UIBottomSheet.ts +139 -0
- package/src/ui/UIButton.ts +101 -0
- package/src/ui/UIContainer.ts +60 -0
- package/src/ui/UIImage.ts +83 -0
- package/src/ui/UIInput.ts +185 -0
- package/src/ui/UIModal.ts +139 -0
- package/src/ui/UINode.ts +830 -0
- package/src/ui/UIPager.ts +362 -0
- package/src/ui/UIPopover.ts +100 -0
- package/src/ui/UIScreen.ts +123 -0
- package/src/ui/UIScrollable.ts +87 -0
- package/src/ui/UISpacer.ts +14 -0
- package/src/ui/UITabs.ts +236 -0
- package/src/ui/UIText.ts +51 -0
- package/src/ui/UIVideo.ts +88 -0
- package/src/ui/UIVirtualizedList.ts +241 -0
- package/src/ui/UIWidget.ts +127 -0
- package/src/ui/fonts.ts +13 -0
- package/src/ui/presentable.ts +117 -0
- package/src/ui/router.ts +132 -0
- package/src/ui/theme.ts +84 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Design rules
|
|
2
|
+
|
|
3
|
+
## Folder layout
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
design/
|
|
7
|
+
screens/<id>.ts one file = one screen; default-exports the screen; the FILENAME is its identity
|
|
8
|
+
shared/tokens.ts the brand: colors, spacing, radius, type scale — every screen's only source of values
|
|
9
|
+
shared/ui.ts the component kit: buttons, fields, cards, sheets — screens compose these
|
|
10
|
+
shared/tabs.ts the app's tab bar, declared ONCE via defineTabs (see below)
|
|
11
|
+
meta.json the app map: descriptions, roles, groups, edges — READ here, WRITE via design_map
|
|
12
|
+
spec.md the concept narrative: data model, actors, rules & decisions
|
|
13
|
+
assets/ vendored icons/fonts and images (listed under [Assets])
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Build the brand kit first
|
|
17
|
+
|
|
18
|
+
A design that looks designed starts from a kit, not from screens. On a new design, before the first
|
|
19
|
+
screen: `shared/tokens.ts` (a real palette — surfaces, text tiers, one or two accents, status
|
|
20
|
+
colors; a spacing/radius/type scale), then `shared/ui.ts` with the components the app will clearly
|
|
21
|
+
need. The kit outlives the design: when the app is built, it IMPORTS `shared/tokens.ts` (and the
|
|
22
|
+
presentational components of `shared/ui.ts`) unchanged — so build tokens on `theme()`, one live
|
|
23
|
+
table for design and app alike, and shape components as things worth keeping. Screens then read as
|
|
24
|
+
composition:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// design/shared/tokens.ts — surfaces dark-to-light, text in tiers, accents as a family.
|
|
28
|
+
// ONE theme() call registers the vars and returns the accessors ("var(--x)" strings); the system
|
|
29
|
+
// key `color` in the same table sets the app-wide default text color. Re-calling theme() with new
|
|
30
|
+
// values (dark mode, brand swap) restyles every screen — and later the built app — live.
|
|
31
|
+
const palette = {
|
|
32
|
+
bg: "#080808", card: "#161618", cardAlt: "#1d1d20", field: "#101012",
|
|
33
|
+
border: "#2a2a2e", text: "#ffffff", muted: "#8a8a93", faint: "#5a5b62",
|
|
34
|
+
accent: "#00BFC2", accentPressed: "#00999b", accentDeep: "#0c4e4f", onAccent: "#05201f",
|
|
35
|
+
success: "#30D158", danger: "#F83131", scrim: "#000000b3",
|
|
36
|
+
// theme SYSTEM keys — SDK-rendered chrome reads these. `color` = default text color everywhere;
|
|
37
|
+
// the other four brand the tab bar (defineTabs here, UITabs in the built app). Mirror the brand:
|
|
38
|
+
color: "#ffffff",
|
|
39
|
+
primaryColor: "#00BFC2", mutedColor: "#8a8a93", tabbarBg: "#161618", screenBg: "#080808",
|
|
40
|
+
}
|
|
41
|
+
export const colors: { [K in keyof typeof palette]: string } = theme(palette)
|
|
42
|
+
export const spacing = { xs: 4, sm: 8, md: 12, lg: 16, xl: 20, xxl: 24 }
|
|
43
|
+
export const radius = { sm: 8, md: 12, lg: 16, pill: 999 }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// design/shared/ui.ts — excerpts; the kit grows with the design
|
|
48
|
+
import { colors, spacing, radius } from "./tokens"
|
|
49
|
+
|
|
50
|
+
export const PrimaryButton = (label: string, o: { name?: string, disabled?: boolean } = {}) =>
|
|
51
|
+
UIButton(UIText(label).style({ fontSize: 16, fontWeight: 700, color: o.disabled ? colors.muted : colors.onAccent }))
|
|
52
|
+
.style({ height: 52, borderRadius: radius.md, bgColor: o.disabled ? colors.accentDeep : colors.accent,
|
|
53
|
+
justifyContent: "center", alignItems: "center", name: o.name, onPressed: { bgColor: colors.accentPressed } })
|
|
54
|
+
|
|
55
|
+
export const SectionLabel = (t: string) =>
|
|
56
|
+
UIText(t.toUpperCase()).style({ fontSize: 11, fontWeight: 600, letterSpacing: 2, color: colors.faint })
|
|
57
|
+
|
|
58
|
+
// A field is a STATIC MOCK — the value is drawn as text (see ui rules); passwords as dots.
|
|
59
|
+
export const Field = (o: { label?: string, value?: string, placeholder?: string, focused?: boolean }) =>
|
|
60
|
+
UIColumn(
|
|
61
|
+
o.label ? SectionLabel(o.label) : null,
|
|
62
|
+
UIRow(UIText(o.value ?? o.placeholder ?? "").style({ flexGrow: 1, fontSize: 16, color: o.value ? colors.text : colors.muted }))
|
|
63
|
+
.style({ height: 52, px: 16, alignItems: "center", bgColor: colors.field, borderRadius: radius.md,
|
|
64
|
+
border: `1px solid ${o.focused ? colors.accent : colors.border}` }),
|
|
65
|
+
).style({ gap: spacing.sm })
|
|
66
|
+
|
|
67
|
+
// Bottom sheet shell — a real modal: the scrim is overlayColor, the box is just the bottom stack.
|
|
68
|
+
export const Sheet = (...children: UINodeChild[]) => {
|
|
69
|
+
const sheet = UIWidget(children).style({
|
|
70
|
+
left: 0, right: 0, bottom: 0, px: spacing.lg, pb: "calc(safe-bottom + 16px)", gap: spacing.sm,
|
|
71
|
+
overlayColor: colors.scrim,
|
|
72
|
+
})
|
|
73
|
+
return sheet.onOverlayTap(() => sheet.hide())
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Full-screen confirm — full-inset box, centered card, NO onOverlayTap (a confirm demands a choice).
|
|
77
|
+
export const ConfirmDialog = (o: { title: string, body?: string, confirmLabel: string, confirmName: string }) =>
|
|
78
|
+
UIWidget(
|
|
79
|
+
UIColumn(
|
|
80
|
+
UIText(o.title).style({ fontSize: 17, fontWeight: 700, color: colors.text, textAlign: "center" }),
|
|
81
|
+
o.body ? UIText(o.body).style({ fontSize: 14, color: colors.muted, textAlign: "center", lineHeight: "1.4em" }) : null,
|
|
82
|
+
PrimaryButton("Cancel", { name: "cancel" }),
|
|
83
|
+
).style({ bgColor: colors.card, borderRadius: radius.lg, p: spacing.xl, gap: spacing.lg, width: "86%", maxWidth: 360 }),
|
|
84
|
+
).style({ top: 0, left: 0, right: 0, bottom: 0, justifyContent: "center", alignItems: "center", overlayColor: colors.scrim })
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Screen rules
|
|
88
|
+
|
|
89
|
+
- **One file = one screen.** `screens/<id>.ts` default-exports either a value
|
|
90
|
+
(`export default UIScreen(...).style({...})`) or a function of state (below). Ids are
|
|
91
|
+
lowercase `[a-z0-9-]`.
|
|
92
|
+
- **Screens are islands.** A screen imports ONLY from `../shared/` — never another screen, no props.
|
|
93
|
+
- **Mock data is the domain.** Realistic inline mock data at the top of the file — the entities and
|
|
94
|
+
fields ARE the future schema. Real names, real prices, plausible dates, in the product's language
|
|
95
|
+
(match the user's) — never "Lorem ipsum" or "Item 1". Where a list can be empty, design the empty
|
|
96
|
+
state too.
|
|
97
|
+
- Give a `name` style (`.style({ name: "submit" })`) to elements that edges refer to — nothing else
|
|
98
|
+
needs names.
|
|
99
|
+
|
|
100
|
+
## Screen states (variants)
|
|
101
|
+
|
|
102
|
+
A screen with more than one look (list vs empty, sheet open, confirm dialog) is ONE file whose
|
|
103
|
+
default export is a function of a state string typed as a string-literal union — the union IS the
|
|
104
|
+
state list, and the parameter default is the canonical state the board shows first. Overlays are
|
|
105
|
+
shown from a state branch, never embedded in the layout:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
// design/screens/schedule.ts
|
|
109
|
+
import { colors, spacing } from "../shared/tokens"
|
|
110
|
+
import { mainTabs } from "../shared/tabs"
|
|
111
|
+
import { Sheet, PrimaryButton, SectionLabel, ClassCard, EmptyDay } from "../shared/ui"
|
|
112
|
+
|
|
113
|
+
const classes = [
|
|
114
|
+
{ start: "18:00", end: "19:00", title: "Calisthenics", trainer: "A. Razgulin", price: 800, booked: true },
|
|
115
|
+
{ start: "19:30", end: "21:00", title: "Acrobatics workshop", trainer: "A. Razgulin", price: 1000, seats: 2 },
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
const FilterSheet = () => Sheet(
|
|
119
|
+
/* chip groups… */
|
|
120
|
+
PrimaryButton("Show 1 class", { name: "apply" }),
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
export default (state: "default" | "empty" | "filters" = "default") => {
|
|
124
|
+
if (state === "filters") FilterSheet().show()
|
|
125
|
+
return UIScreen(
|
|
126
|
+
UIScrollable(
|
|
127
|
+
SectionLabel("Today"),
|
|
128
|
+
state === "empty" ? EmptyDay() : UIColumn(classes.map((c) => ClassCard(c, { name: "class" }))).style({ gap: spacing.sm }),
|
|
129
|
+
).style({ flexGrow: 1, flexShrink: 1, px: spacing.xl, pt: spacing.md, gap: spacing.lg }),
|
|
130
|
+
mainTabs.bar("schedule"),
|
|
131
|
+
).style({ bgColor: colors.bg, pt: "safe-top" })
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Derive per-state data at the top (`const items = state === "empty" ? [] : MOCK`). The board shows a
|
|
136
|
+
state switcher; edges may target `id@state`.
|
|
137
|
+
|
|
138
|
+
## The map — design_map, never meta.json
|
|
139
|
+
|
|
140
|
+
`design/meta.json` is the app map: every screen's description/group/role and the edges between
|
|
141
|
+
screens. You READ it from `[File contents]`; you change it ONLY through the `design_map` tool —
|
|
142
|
+
never with a `<file>` write (positions on it are the developer's, and the board may have edited it
|
|
143
|
+
while you were replying). In the same reply that creates screen files, register them:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
design_map ops: [
|
|
147
|
+
{ op: "screen", id: "login", desc: "Phone + password sign-in", group: "Onboarding", role: "auth" },
|
|
148
|
+
{ op: "screen", id: "schedule", desc: "Client home — day schedule", role: "list" },
|
|
149
|
+
{ op: "edge", from: "login", to: "schedule", label: "Sign in", activator: "login" },
|
|
150
|
+
{ op: "edge", from: "schedule", to: "schedule@filters", label: "Filters", activator: "filters" }
|
|
151
|
+
]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
- New screens get NO position from you — the board auto-places them next to their edge neighbours.
|
|
155
|
+
- **Edges are forward intent only.** Never draw back/dismiss/logout edges (the navigation stack
|
|
156
|
+
implies returns), and never draw edges between tab screens (the bar already navigates).
|
|
157
|
+
- An edge to the same screen's `id@state` is a *state link* — "tapping X puts this screen into
|
|
158
|
+
state Y"; the board renders it as a chip on the activator element.
|
|
159
|
+
- **Group every screen** by user-facing area (2–6 per group: Onboarding, Checkout…), **tag its
|
|
160
|
+
`role`** (`list`, `detail`, `form`, `auth`, `modal`…). Don't regroup existing screens unless asked.
|
|
161
|
+
|
|
162
|
+
## The tab bar
|
|
163
|
+
|
|
164
|
+
Declared ONCE in `shared/tabs.ts` — the board discovers it from source and renders it as a rail
|
|
165
|
+
with lanes; tab switching needs NO edges. `defineTabs` is an SDK global: the standard themed
|
|
166
|
+
bottom bar, the same look the built app's `UITabs` renders. The keys are screen ids (each tab's
|
|
167
|
+
root, in tab order), literals only; icons are always `assetIcon(...)` calls:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
// design/shared/tabs.ts — this declaration is the whole file
|
|
171
|
+
export const mainTabs = defineTabs({
|
|
172
|
+
schedule: { label: "Schedule", icon: assetIcon("lucide:calendar") },
|
|
173
|
+
profile: { label: "Profile", icon: assetIcon("lucide:user") },
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
A screen that shows the bar mounts it with a literal tab id — roots AND pushed details that keep
|
|
178
|
+
the bar; a screen that doesn't mount it is a full-screen push. Mount the bar alone when the screen
|
|
179
|
+
owns its layout (`mainTabs.bar("schedule")`, as above) or wrap content with
|
|
180
|
+
`mainTabs.screen("home", [...])`. Restyle through the theme's system keys — `primaryColor`,
|
|
181
|
+
`mutedColor`, `tabbarBg`, `screenBg`, set in `shared/tokens.ts` — never by reimplementing the
|
|
182
|
+
bar. Keep the `defineTabs({...})` declaration and `.screen("<tab>", ...)` / `.bar("<tab>")` call
|
|
183
|
+
shapes intact — the board parses them.
|
|
184
|
+
|
|
185
|
+
## Icons & fonts
|
|
186
|
+
|
|
187
|
+
`assetIcon("pack:name")` inlines a registry icon at compile time — the ONLY way to make an icon
|
|
188
|
+
(never hand-write its `{ svg }` result — that renders blank). Use real icons freely on every
|
|
189
|
+
screen. Vendored copies (`design/assets/icons/`, listed under `[Assets]`) resolve first; anything
|
|
190
|
+
else is fetched from the icon registry automatically. The main pack is `lucide` (kebab-case names:
|
|
191
|
+
`"lucide:bell"`, `"lucide:chevron-right"`); an unknown name is a compile error with "did you mean"
|
|
192
|
+
suggestions. Wrap each icon in a tiny factory in `shared/ui.ts`
|
|
193
|
+
(`Icon.bell = (c, s = 20) => UIImage(assetIcon("lucide:bell")).style({ width: s, height: s, tintColor: c })`).
|
|
194
|
+
|
|
195
|
+
`font("id")` works the same way — registry families load from the font CDN, no vendoring needed:
|
|
196
|
+
`theme({ fontFamily: font("manrope") })`, or per-node `.style({ fontFamily: font("rubik") })`.
|
|
197
|
+
An unknown id or weight is a compile error listing what exists. Only project font files
|
|
198
|
+
(`font("./Brand.ttf")`) must already be pushed.
|
|
199
|
+
|
|
200
|
+
## spec.md — the concept
|
|
201
|
+
|
|
202
|
+
The narrative half of the design: the **data model** (entities + fields), the **actors** (who uses
|
|
203
|
+
the app, what each may do), and the **rules & decisions** (validation, edge cases, choices made).
|
|
204
|
+
Prose, co-owned with the developer — edit it with normal `<file>` writes; half-filled is fine. Link
|
|
205
|
+
screens as `[[screen-id]]`. The mock data at the top of each screen is the first draft of the data
|
|
206
|
+
model — promote entities that stabilize into spec.md tables. When you make a design decision worth
|
|
207
|
+
keeping, write it down here instead of leaving it in chat.
|
|
208
|
+
|
|
209
|
+
## Working style
|
|
210
|
+
|
|
211
|
+
- Read meta.json, `shared/tokens.ts` and the `shared/ui.ts` signatures before changing anything;
|
|
212
|
+
open only the screens you need.
|
|
213
|
+
- Design in coherent flows (onboarding → main → detail), not isolated screens; a screen is a
|
|
214
|
+
moment in a flow. Prefer several focused screens over one mega-screen.
|
|
215
|
+
- The developer watches the board live — your files render as tiles the moment they land, and the
|
|
216
|
+
selected tile arrives as `[Design]` context: treat it as the subject of an ambiguous instruction.
|
|
217
|
+
- Make it look designed: every value from tokens, one accent doing the talking, realistic content
|
|
218
|
+
density, empty states designed, press feedback on tappables.
|