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.
Files changed (367) hide show
  1. package/README.md +114 -0
  2. package/dist/global.d.ts +503 -0
  3. package/dist/host.d.ts +61 -0
  4. package/dist/inject.js +4730 -0
  5. package/dist/types/animate/animate.d.ts +20 -0
  6. package/dist/types/animate/bezier.d.ts +2 -0
  7. package/dist/types/animate/easings.d.ts +21 -0
  8. package/dist/types/canvas/Canvas.d.ts +168 -0
  9. package/dist/types/core/Aspect.d.ts +171 -0
  10. package/dist/types/core/InspectorUI.d.ts +88 -0
  11. package/dist/types/core/StateMachine.d.ts +81 -0
  12. package/dist/types/core/color.d.ts +13 -0
  13. package/dist/types/core/compWrite.d.ts +11 -0
  14. package/dist/types/core/events.d.ts +11 -0
  15. package/dist/types/core/fields.d.ts +58 -0
  16. package/dist/types/core/registry.d.ts +7 -0
  17. package/dist/types/core/signals.d.ts +29 -0
  18. package/dist/types/core/time.d.ts +31 -0
  19. package/dist/types/g2/Camera2D.d.ts +19 -0
  20. package/dist/types/g2/CharacterController2D.d.ts +134 -0
  21. package/dist/types/g2/Node2D.d.ts +91 -0
  22. package/dist/types/g2/OneWay2D.d.ts +24 -0
  23. package/dist/types/g2/Physics2D.d.ts +147 -0
  24. package/dist/types/g2/Scene2D.d.ts +72 -0
  25. package/dist/types/g2/Shape2D.d.ts +58 -0
  26. package/dist/types/g2/Sprite.d.ts +51 -0
  27. package/dist/types/g2/SpriteAnimation.d.ts +50 -0
  28. package/dist/types/g2/SpriteSheet.d.ts +69 -0
  29. package/dist/types/g2/Texture2D.d.ts +16 -0
  30. package/dist/types/g2/Tilemap.d.ts +20 -0
  31. package/dist/types/g2/Tileset.d.ts +32 -0
  32. package/dist/types/g2/Trigger2D.d.ts +20 -0
  33. package/dist/types/g2/autotile.d.ts +133 -0
  34. package/dist/types/g2/cells.d.ts +14 -0
  35. package/dist/types/g2/defineScene2d.d.ts +141 -0
  36. package/dist/types/g2/groups2d.d.ts +16 -0
  37. package/dist/types/g2/loop.d.ts +4 -0
  38. package/dist/types/g2/scenarios2d.d.ts +30 -0
  39. package/dist/types/g2/touch.d.ts +2 -0
  40. package/dist/types/gl/Camera.d.ts +79 -0
  41. package/dist/types/gl/CameraPlace.d.ts +26 -0
  42. package/dist/types/gl/CharacterController.d.ts +98 -0
  43. package/dist/types/gl/Gearbox.d.ts +86 -0
  44. package/dist/types/gl/Geometry.d.ts +39 -0
  45. package/dist/types/gl/IK.d.ts +53 -0
  46. package/dist/types/gl/InstancedMesh.d.ts +46 -0
  47. package/dist/types/gl/Light.d.ts +73 -0
  48. package/dist/types/gl/Lightmap.d.ts +85 -0
  49. package/dist/types/gl/Locomotion.d.ts +279 -0
  50. package/dist/types/gl/Material.d.ts +100 -0
  51. package/dist/types/gl/Mesh.d.ts +33 -0
  52. package/dist/types/gl/Model.d.ts +53 -0
  53. package/dist/types/gl/NavAgent.d.ts +99 -0
  54. package/dist/types/gl/NavMesh.d.ts +169 -0
  55. package/dist/types/gl/Node.d.ts +99 -0
  56. package/dist/types/gl/Noise.d.ts +20 -0
  57. package/dist/types/gl/Particles.d.ts +277 -0
  58. package/dist/types/gl/Physics.d.ts +91 -0
  59. package/dist/types/gl/Plane.d.ts +19 -0
  60. package/dist/types/gl/Ragdoll.d.ts +86 -0
  61. package/dist/types/gl/Ray.d.ts +8 -0
  62. package/dist/types/gl/Scene.d.ts +221 -0
  63. package/dist/types/gl/Shape.d.ts +122 -0
  64. package/dist/types/gl/Terrain.d.ts +280 -0
  65. package/dist/types/gl/Texture.d.ts +27 -0
  66. package/dist/types/gl/Trigger.d.ts +10 -0
  67. package/dist/types/gl/Vehicle.d.ts +191 -0
  68. package/dist/types/gl/Wheel.d.ts +95 -0
  69. package/dist/types/gl/animation/AnimationClip.d.ts +60 -0
  70. package/dist/types/gl/animation/Animator.d.ts +219 -0
  71. package/dist/types/gl/animation/Layer.d.ts +31 -0
  72. package/dist/types/gl/animation/Loop.d.ts +17 -0
  73. package/dist/types/gl/animation/Playback.d.ts +36 -0
  74. package/dist/types/gl/animation/core.d.ts +367 -0
  75. package/dist/types/gl/controls.d.ts +19 -0
  76. package/dist/types/gl/physicsEvents.d.ts +1 -0
  77. package/dist/types/gl/scenarios.d.ts +98 -0
  78. package/dist/types/gl/state.d.ts +5 -0
  79. package/dist/types/gl/terrainMesh.d.ts +46 -0
  80. package/dist/types/gl/touch.d.ts +2 -0
  81. package/dist/types/inject.d.ts +123 -0
  82. package/dist/types/math/Mathf.d.ts +39 -0
  83. package/dist/types/math/mat4.d.ts +66 -0
  84. package/dist/types/math/quat.d.ts +53 -0
  85. package/dist/types/math/vec.d.ts +129 -0
  86. package/dist/types/net/codec.d.ts +25 -0
  87. package/dist/types/net/core.d.ts +106 -0
  88. package/dist/types/net/index.d.ts +80 -0
  89. package/dist/types/net/replication.d.ts +101 -0
  90. package/dist/types/plugins/camera.d.ts +25 -0
  91. package/dist/types/plugins/geolocation.d.ts +39 -0
  92. package/dist/types/plugins/oauth.d.ts +25 -0
  93. package/dist/types/plugins/permission.d.ts +1 -0
  94. package/dist/types/plugins/push.d.ts +46 -0
  95. package/dist/types/plugins/qr.d.ts +21 -0
  96. package/dist/types/plugins/service.d.ts +33 -0
  97. package/dist/types/runtime/app.d.ts +67 -0
  98. package/dist/types/runtime/appEvents.d.ts +7 -0
  99. package/dist/types/runtime/channel.d.ts +1 -0
  100. package/dist/types/runtime/clipboard.d.ts +7 -0
  101. package/dist/types/runtime/datetime.d.ts +80 -0
  102. package/dist/types/runtime/device.d.ts +126 -0
  103. package/dist/types/runtime/fetch.d.ts +31 -0
  104. package/dist/types/runtime/files.d.ts +33 -0
  105. package/dist/types/runtime/input.d.ts +121 -0
  106. package/dist/types/runtime/media.d.ts +46 -0
  107. package/dist/types/runtime/misc.d.ts +11 -0
  108. package/dist/types/runtime/net.d.ts +15 -0
  109. package/dist/types/runtime/rpc.d.ts +44 -0
  110. package/dist/types/runtime/service.d.ts +1 -0
  111. package/dist/types/runtime/share.d.ts +2 -0
  112. package/dist/types/runtime/storage.d.ts +5 -0
  113. package/dist/types/runtime/touch.d.ts +56 -0
  114. package/dist/types/scene/defineScene.d.ts +296 -0
  115. package/dist/types/scene/editorPlugins.d.ts +82 -0
  116. package/dist/types/scene/gizmos.d.ts +56 -0
  117. package/dist/types/scene/grammar.d.ts +56 -0
  118. package/dist/types/scene/level.d.ts +98 -0
  119. package/dist/types/scene/material.d.ts +76 -0
  120. package/dist/types/server/auth/appConfig.d.ts +16 -0
  121. package/dist/types/server/auth/global.d.ts +56 -0
  122. package/dist/types/server/auth/models.d.ts +164 -0
  123. package/dist/types/server/auth/types.d.ts +56 -0
  124. package/dist/types/server/channel.d.ts +28 -0
  125. package/dist/types/server/context.d.ts +27 -0
  126. package/dist/types/server/db/defineDb.d.ts +36 -0
  127. package/dist/types/server/db/fields.d.ts +146 -0
  128. package/dist/types/server/db/index.d.ts +6 -0
  129. package/dist/types/server/db/marci/query.d.ts +326 -0
  130. package/dist/types/server/db/types.d.ts +163 -0
  131. package/dist/types/server/errors.d.ts +8 -0
  132. package/dist/types/server/inject.d.ts +5 -0
  133. package/dist/types/ui/NativeView.d.ts +38 -0
  134. package/dist/types/ui/UI.d.ts +27 -0
  135. package/dist/types/ui/UIBottomSheet.d.ts +71 -0
  136. package/dist/types/ui/UIButton.d.ts +30 -0
  137. package/dist/types/ui/UIContainer.d.ts +33 -0
  138. package/dist/types/ui/UIImage.d.ts +35 -0
  139. package/dist/types/ui/UIInput.d.ts +110 -0
  140. package/dist/types/ui/UIModal.d.ts +70 -0
  141. package/dist/types/ui/UINode.d.ts +363 -0
  142. package/dist/types/ui/UIPager.d.ts +123 -0
  143. package/dist/types/ui/UIPopover.d.ts +39 -0
  144. package/dist/types/ui/UIScreen.d.ts +57 -0
  145. package/dist/types/ui/UIScrollable.d.ts +40 -0
  146. package/dist/types/ui/UISpacer.d.ts +9 -0
  147. package/dist/types/ui/UITabs.d.ts +96 -0
  148. package/dist/types/ui/UIText.d.ts +19 -0
  149. package/dist/types/ui/UIVideo.d.ts +28 -0
  150. package/dist/types/ui/UIVirtualizedList.d.ts +97 -0
  151. package/dist/types/ui/UIWidget.d.ts +65 -0
  152. package/dist/types/ui/fonts.d.ts +9 -0
  153. package/dist/types/ui/presentable.d.ts +68 -0
  154. package/dist/types/ui/router.d.ts +40 -0
  155. package/dist/types/ui/theme.d.ts +26 -0
  156. package/dist/types.json +1 -0
  157. package/package.json +46 -0
  158. package/prompts/2d.md +395 -0
  159. package/prompts/3d-scene-files.md +113 -0
  160. package/prompts/3d-scene.md +119 -0
  161. package/prompts/3d.md +303 -0
  162. package/prompts/README.md +142 -0
  163. package/prompts/ar.md +109 -0
  164. package/prompts/canvas.md +27 -0
  165. package/prompts/compose.ts +46 -0
  166. package/prompts/concept.md +49 -0
  167. package/prompts/core-design.md +75 -0
  168. package/prompts/core.md +264 -0
  169. package/prompts/design.md +218 -0
  170. package/prompts/dist/2d-game.md +1530 -0
  171. package/prompts/dist/3d-app.md +1672 -0
  172. package/prompts/dist/ar-app.md +1548 -0
  173. package/prompts/dist/concept.md +49 -0
  174. package/prompts/dist/design.md +498 -0
  175. package/prompts/dist/ui-app.md +1134 -0
  176. package/prompts/index.md +37 -0
  177. package/prompts/intake-prompt.md +33 -0
  178. package/prompts/namer-prompt.md +12 -0
  179. package/prompts/router-prompt.md +50 -0
  180. package/prompts/select.ts +111 -0
  181. package/prompts/ui-design.md +203 -0
  182. package/prompts/ui.md +803 -0
  183. package/src/animate/animate.ts +238 -0
  184. package/src/animate/bezier.ts +138 -0
  185. package/src/animate/easings.ts +126 -0
  186. package/src/bridges.d.ts +1345 -0
  187. package/src/canvas/Canvas.ts +305 -0
  188. package/src/compile/__tests__/assetIconMacro.test.ts +219 -0
  189. package/src/compile/__tests__/assetMacro.test.ts +74 -0
  190. package/src/compile/__tests__/assetName.test.ts +55 -0
  191. package/src/compile/__tests__/compile.test.ts +287 -0
  192. package/src/compile/__tests__/detectEntry.test.ts +132 -0
  193. package/src/compile/__tests__/fontMacro.test.ts +199 -0
  194. package/src/compile/aspectMacro.ts +86 -0
  195. package/src/compile/assetIconMacro.ts +384 -0
  196. package/src/compile/assetMacro.ts +146 -0
  197. package/src/compile/assetName.ts +50 -0
  198. package/src/compile/bundler.ts +287 -0
  199. package/src/compile/compileProject.ts +127 -0
  200. package/src/compile/detectEntry.ts +128 -0
  201. package/src/compile/fontMacro.ts +459 -0
  202. package/src/compile/fontRegistry.ts +78 -0
  203. package/src/compile/header.ts +67 -0
  204. package/src/compile/index.ts +100 -0
  205. package/src/compile/libraryImports.ts +52 -0
  206. package/src/compile/liteMaterial.ts +247 -0
  207. package/src/compile/sceneEditor.ts +88 -0
  208. package/src/compile/serverSplit.ts +233 -0
  209. package/src/compile/serverTypes.ts +227 -0
  210. package/src/compile/sfnt.ts +98 -0
  211. package/src/compile/shaderSchema.ts +202 -0
  212. package/src/compile/shaderTargets.ts +77 -0
  213. package/src/compile/sourcemap.ts +25 -0
  214. package/src/core/Aspect.ts +568 -0
  215. package/src/core/InspectorUI.ts +212 -0
  216. package/src/core/StateMachine.ts +308 -0
  217. package/src/core/__tests__/stateMachine.test.ts +132 -0
  218. package/src/core/color.ts +66 -0
  219. package/src/core/compWrite.ts +42 -0
  220. package/src/core/events.ts +38 -0
  221. package/src/core/fields.ts +120 -0
  222. package/src/core/registry.ts +23 -0
  223. package/src/core/signals.ts +277 -0
  224. package/src/core/time.ts +84 -0
  225. package/src/g2/Camera2D.ts +40 -0
  226. package/src/g2/CharacterController2D.ts +276 -0
  227. package/src/g2/Node2D.ts +267 -0
  228. package/src/g2/OneWay2D.ts +66 -0
  229. package/src/g2/Physics2D.ts +346 -0
  230. package/src/g2/Scene2D.ts +209 -0
  231. package/src/g2/Shape2D.ts +259 -0
  232. package/src/g2/Sprite.ts +89 -0
  233. package/src/g2/SpriteAnimation.ts +171 -0
  234. package/src/g2/SpriteSheet.ts +166 -0
  235. package/src/g2/Texture2D.ts +47 -0
  236. package/src/g2/Tilemap.ts +41 -0
  237. package/src/g2/Tileset.ts +71 -0
  238. package/src/g2/Trigger2D.ts +77 -0
  239. package/src/g2/autotile.ts +433 -0
  240. package/src/g2/cells.ts +91 -0
  241. package/src/g2/defineScene2d.ts +381 -0
  242. package/src/g2/groups2d.ts +106 -0
  243. package/src/g2/loop.ts +50 -0
  244. package/src/g2/scenarios2d.ts +69 -0
  245. package/src/g2/touch.ts +83 -0
  246. package/src/gl/Camera.ts +160 -0
  247. package/src/gl/CameraPlace.ts +52 -0
  248. package/src/gl/CharacterController.ts +238 -0
  249. package/src/gl/Gearbox.ts +212 -0
  250. package/src/gl/Geometry.ts +279 -0
  251. package/src/gl/IK.ts +193 -0
  252. package/src/gl/InstancedMesh.ts +132 -0
  253. package/src/gl/Light.ts +135 -0
  254. package/src/gl/Lightmap.ts +402 -0
  255. package/src/gl/Locomotion.ts +498 -0
  256. package/src/gl/Material.ts +279 -0
  257. package/src/gl/Mesh.ts +83 -0
  258. package/src/gl/Model.ts +124 -0
  259. package/src/gl/NavAgent.ts +337 -0
  260. package/src/gl/NavMesh.ts +397 -0
  261. package/src/gl/Node.ts +350 -0
  262. package/src/gl/Noise.ts +30 -0
  263. package/src/gl/Particles.ts +676 -0
  264. package/src/gl/Physics.ts +222 -0
  265. package/src/gl/Plane.ts +53 -0
  266. package/src/gl/Ragdoll.ts +270 -0
  267. package/src/gl/Ray.ts +16 -0
  268. package/src/gl/Scene.ts +505 -0
  269. package/src/gl/Shape.ts +409 -0
  270. package/src/gl/Terrain.ts +1092 -0
  271. package/src/gl/Texture.ts +63 -0
  272. package/src/gl/Trigger.ts +45 -0
  273. package/src/gl/Vehicle.ts +473 -0
  274. package/src/gl/Wheel.ts +240 -0
  275. package/src/gl/animation/AnimationClip.ts +204 -0
  276. package/src/gl/animation/Animator.ts +329 -0
  277. package/src/gl/animation/Layer.ts +39 -0
  278. package/src/gl/animation/Loop.ts +31 -0
  279. package/src/gl/animation/Playback.ts +52 -0
  280. package/src/gl/animation/core.ts +670 -0
  281. package/src/gl/controls.ts +95 -0
  282. package/src/gl/physicsEvents.ts +20 -0
  283. package/src/gl/scenarios.ts +291 -0
  284. package/src/gl/state.ts +6 -0
  285. package/src/gl/terrainMesh.ts +219 -0
  286. package/src/gl/touch.ts +68 -0
  287. package/src/host.d.ts +61 -0
  288. package/src/inject.ts +203 -0
  289. package/src/math/Mathf.ts +118 -0
  290. package/src/math/mat4.ts +278 -0
  291. package/src/math/quat.ts +232 -0
  292. package/src/math/vec.ts +255 -0
  293. package/src/net/codec.ts +119 -0
  294. package/src/net/core.ts +384 -0
  295. package/src/net/index.ts +181 -0
  296. package/src/net/replication.ts +622 -0
  297. package/src/plugins/camera.ts +81 -0
  298. package/src/plugins/geolocation.ts +123 -0
  299. package/src/plugins/oauth.ts +61 -0
  300. package/src/plugins/permission.ts +7 -0
  301. package/src/plugins/push.ts +132 -0
  302. package/src/plugins/qr.ts +73 -0
  303. package/src/plugins/service.ts +47 -0
  304. package/src/runtime/app.ts +101 -0
  305. package/src/runtime/appEvents.ts +54 -0
  306. package/src/runtime/channel.ts +61 -0
  307. package/src/runtime/clipboard.ts +20 -0
  308. package/src/runtime/datetime.ts +329 -0
  309. package/src/runtime/device.ts +293 -0
  310. package/src/runtime/fetch.ts +77 -0
  311. package/src/runtime/files.ts +108 -0
  312. package/src/runtime/input.ts +175 -0
  313. package/src/runtime/media.ts +111 -0
  314. package/src/runtime/misc.ts +16 -0
  315. package/src/runtime/net.ts +36 -0
  316. package/src/runtime/rpc.ts +218 -0
  317. package/src/runtime/service.ts +83 -0
  318. package/src/runtime/share.ts +9 -0
  319. package/src/runtime/storage.ts +13 -0
  320. package/src/runtime/touch.ts +76 -0
  321. package/src/scene/defineScene.ts +1396 -0
  322. package/src/scene/editorPlugins.ts +110 -0
  323. package/src/scene/gizmos.ts +148 -0
  324. package/src/scene/grammar.ts +120 -0
  325. package/src/scene/level.ts +296 -0
  326. package/src/scene/material.ts +188 -0
  327. package/src/server/auth/appConfig.ts +12 -0
  328. package/src/server/auth/global.ts +80 -0
  329. package/src/server/auth/host.ts +318 -0
  330. package/src/server/auth/models.ts +83 -0
  331. package/src/server/auth/types.ts +50 -0
  332. package/src/server/channel.ts +56 -0
  333. package/src/server/context.ts +36 -0
  334. package/src/server/db/defineDb.ts +237 -0
  335. package/src/server/db/fields.ts +132 -0
  336. package/src/server/db/httpTransport.ts +93 -0
  337. package/src/server/db/index.ts +7 -0
  338. package/src/server/db/marci/query.ts +412 -0
  339. package/src/server/db/types.ts +202 -0
  340. package/src/server/errors.ts +12 -0
  341. package/src/server/host.ts +74 -0
  342. package/src/server/inject.ts +13 -0
  343. package/src/server/runtime.ts +133 -0
  344. package/src/server/validate.ts +87 -0
  345. package/src/ui/NativeView.ts +142 -0
  346. package/src/ui/UI.ts +39 -0
  347. package/src/ui/UIBottomSheet.ts +139 -0
  348. package/src/ui/UIButton.ts +101 -0
  349. package/src/ui/UIContainer.ts +60 -0
  350. package/src/ui/UIImage.ts +83 -0
  351. package/src/ui/UIInput.ts +185 -0
  352. package/src/ui/UIModal.ts +139 -0
  353. package/src/ui/UINode.ts +830 -0
  354. package/src/ui/UIPager.ts +362 -0
  355. package/src/ui/UIPopover.ts +100 -0
  356. package/src/ui/UIScreen.ts +123 -0
  357. package/src/ui/UIScrollable.ts +87 -0
  358. package/src/ui/UISpacer.ts +14 -0
  359. package/src/ui/UITabs.ts +236 -0
  360. package/src/ui/UIText.ts +51 -0
  361. package/src/ui/UIVideo.ts +88 -0
  362. package/src/ui/UIVirtualizedList.ts +241 -0
  363. package/src/ui/UIWidget.ts +127 -0
  364. package/src/ui/fonts.ts +13 -0
  365. package/src/ui/presentable.ts +117 -0
  366. package/src/ui/router.ts +132 -0
  367. package/src/ui/theme.ts +84 -0
@@ -0,0 +1,185 @@
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
+ }
@@ -0,0 +1,139 @@
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
+ }