@almadar/std 16.151.0 → 16.153.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 (151) hide show
  1. package/behaviors/lolo/infra/atoms/std-data-erasure.lolo +5 -1
  2. package/behaviors/lolo/ui/core/atoms/std-browse.lolo +15 -4
  3. package/behaviors/lolo/ui/core/molecules/ui-data-list.lolo +12 -0
  4. package/behaviors/lolo/ui/core/molecules/ui-emoji-picker.lolo +56 -0
  5. package/behaviors/lolo/ui/core/molecules/ui-popover.lolo +39 -0
  6. package/behaviors/lolo/ui/core/molecules/ui-table-view.lolo +11 -0
  7. package/behaviors/lolo/ui/game/atoms/ui-draw-group.lolo +54 -0
  8. package/behaviors/lolo/ui/game/atoms/ui-draw-shape.lolo +6 -1
  9. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite.lolo +2 -2
  10. package/behaviors/lolo/ui/game/atoms/ui-svg-draw-group.lolo +58 -0
  11. package/behaviors/lolo/ui/game/atoms/ui-svg-draw-shape.lolo +103 -0
  12. package/behaviors/lolo/ui/game/atoms/ui-svg-draw-text.lolo +58 -0
  13. package/behaviors/lolo/ui/game/molecules/ui-canvas-2d.lolo +11 -1
  14. package/behaviors/lolo/ui/game/molecules/ui-canvas.lolo +10 -0
  15. package/behaviors/lolo/ui/game/molecules/ui-draw-shape-layer.lolo +3 -2
  16. package/behaviors/lolo/ui/game/molecules/ui-svg-draw-shape-layer.lolo +52 -0
  17. package/behaviors/lolo/ui/game/molecules/ui-svg-stage.lolo +98 -0
  18. package/behaviors/lolo/ui/game/organisms/ui-fishing-board.lolo +8 -8
  19. package/behaviors/lolo/ui/game/organisms/ui-physics-sandbox-board.lolo +5 -5
  20. package/behaviors/lolo/ui/game/organisms/ui-roguelike-board.lolo +5 -5
  21. package/behaviors/lolo/ui/game/organisms/ui-sokoban-board.lolo +5 -5
  22. package/behaviors/lolo/ui/game/organisms/ui-state-architect-board.lolo +4 -4
  23. package/behaviors/lolo/ui/game/organisms/ui-winter-ski-board.lolo +7 -7
  24. package/behaviors/registry/factory-signatures.json +6211 -2181
  25. package/behaviors/registry/infra/atoms/std-approval-gate.orb +16 -8
  26. package/behaviors/registry/infra/atoms/std-cache-aside.orb +62 -31
  27. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +32 -16
  28. package/behaviors/registry/infra/atoms/std-data-erasure.orb +17 -9
  29. package/behaviors/registry/infra/atoms/std-mod-queue.orb +16 -8
  30. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +28 -14
  31. package/behaviors/registry/ml/molecules/std-escalating-decision.orb +10 -5
  32. package/behaviors/registry/ml/molecules/std-knowledge-tracing.orb +4 -2
  33. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +2 -1
  34. package/behaviors/registry/ui/core/atoms/std-browse.orb +108 -28
  35. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +2 -1
  36. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +4 -2
  37. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +6 -3
  38. package/behaviors/registry/ui/core/atoms/std-gallery.orb +18 -9
  39. package/behaviors/registry/ui/core/atoms/std-import.orb +4 -2
  40. package/behaviors/registry/ui/core/molecules/ui-data-list.orb +21 -0
  41. package/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +214 -0
  42. package/behaviors/registry/ui/core/molecules/ui-popover.orb +112 -1
  43. package/behaviors/registry/ui/core/molecules/ui-table-view.orb +44 -0
  44. package/behaviors/registry/ui/game/atoms/std-arcade-flow.orb +1 -0
  45. package/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -0
  46. package/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -0
  47. package/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -0
  48. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -0
  49. package/behaviors/registry/ui/game/atoms/std-gather.orb +1 -0
  50. package/behaviors/registry/ui/game/atoms/std-gold.orb +1 -0
  51. package/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -0
  52. package/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -0
  53. package/behaviors/registry/ui/game/atoms/std-market-flow.orb +1 -0
  54. package/behaviors/registry/ui/game/atoms/std-objective-flow.orb +1 -0
  55. package/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -0
  56. package/behaviors/registry/ui/game/atoms/std-patience.orb +1 -0
  57. package/behaviors/registry/ui/game/atoms/std-production.orb +1 -0
  58. package/behaviors/registry/ui/game/atoms/std-round-flow.orb +1 -0
  59. package/behaviors/registry/ui/game/atoms/std-score.orb +1 -0
  60. package/behaviors/registry/ui/game/atoms/std-survival-flow.orb +1 -0
  61. package/behaviors/registry/ui/game/atoms/std-xp.orb +1 -0
  62. package/behaviors/registry/ui/game/atoms/ui-draw-group.orb +196 -0
  63. package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +9 -1
  64. package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +2 -2
  65. package/behaviors/registry/ui/game/atoms/ui-svg-draw-group.orb +186 -0
  66. package/behaviors/registry/ui/game/atoms/ui-svg-draw-shape.orb +259 -0
  67. package/behaviors/registry/ui/game/atoms/ui-svg-draw-text.orb +195 -0
  68. package/behaviors/registry/ui/game/molecules/std-worldmap-board-2d.orb +6 -3
  69. package/behaviors/registry/ui/game/molecules/ui-canvas-2d.orb +16 -1
  70. package/behaviors/registry/ui/game/molecules/ui-canvas.orb +14 -0
  71. package/behaviors/registry/ui/game/molecules/ui-draw-shape-layer.orb +9 -1
  72. package/behaviors/registry/ui/game/molecules/ui-svg-draw-shape-layer.orb +188 -0
  73. package/behaviors/registry/ui/game/molecules/ui-svg-stage.orb +362 -0
  74. package/behaviors/registry/ui/game/organisms/ui-fishing-board.orb +16 -16
  75. package/behaviors/registry/ui/game/organisms/ui-physics-sandbox-board.orb +10 -10
  76. package/behaviors/registry/ui/game/organisms/ui-roguelike-board.orb +10 -10
  77. package/behaviors/registry/ui/game/organisms/ui-sokoban-board.orb +10 -10
  78. package/behaviors/registry/ui/game/organisms/ui-state-architect-board.orb +8 -8
  79. package/behaviors/registry/ui/game/organisms/ui-winter-ski-board.orb +14 -14
  80. package/dist/behaviors/behaviors-embeddings.json +371 -343
  81. package/dist/behaviors/behaviors-registry.json +4851 -2388
  82. package/dist/behaviors/exports-reader.js +3409 -3101
  83. package/dist/behaviors/functions/index.d.ts +609 -6
  84. package/dist/behaviors/functions/index.js +3389 -3102
  85. package/dist/behaviors/index.d.ts +1 -1
  86. package/dist/behaviors/index.js +3410 -3102
  87. package/dist/behaviors/knob-embeddings.json +1 -1
  88. package/dist/behaviors/query.js +3409 -3101
  89. package/dist/behaviors/registry/factory-signatures.json +6211 -2181
  90. package/dist/behaviors/registry/infra/atoms/std-approval-gate.orb +16 -8
  91. package/dist/behaviors/registry/infra/atoms/std-cache-aside.orb +62 -31
  92. package/dist/behaviors/registry/infra/atoms/std-circuit-breaker.orb +32 -16
  93. package/dist/behaviors/registry/infra/atoms/std-data-erasure.orb +17 -9
  94. package/dist/behaviors/registry/infra/atoms/std-mod-queue.orb +16 -8
  95. package/dist/behaviors/registry/infra/atoms/std-rate-limiter.orb +28 -14
  96. package/dist/behaviors/registry/ml/molecules/std-escalating-decision.orb +10 -5
  97. package/dist/behaviors/registry/ml/molecules/std-knowledge-tracing.orb +4 -2
  98. package/dist/behaviors/registry/ui/core/atoms/std-billable-hour.orb +2 -1
  99. package/dist/behaviors/registry/ui/core/atoms/std-browse.orb +108 -28
  100. package/dist/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +2 -1
  101. package/dist/behaviors/registry/ui/core/atoms/std-esign-flow.orb +4 -2
  102. package/dist/behaviors/registry/ui/core/atoms/std-esign-request.orb +6 -3
  103. package/dist/behaviors/registry/ui/core/atoms/std-gallery.orb +18 -9
  104. package/dist/behaviors/registry/ui/core/atoms/std-import.orb +4 -2
  105. package/dist/behaviors/registry/ui/core/molecules/ui-data-list.orb +21 -0
  106. package/dist/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +214 -0
  107. package/dist/behaviors/registry/ui/core/molecules/ui-popover.orb +112 -1
  108. package/dist/behaviors/registry/ui/core/molecules/ui-table-view.orb +44 -0
  109. package/dist/behaviors/registry/ui/game/atoms/std-arcade-flow.orb +1 -0
  110. package/dist/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -0
  111. package/dist/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -0
  112. package/dist/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -0
  113. package/dist/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -0
  114. package/dist/behaviors/registry/ui/game/atoms/std-gather.orb +1 -0
  115. package/dist/behaviors/registry/ui/game/atoms/std-gold.orb +1 -0
  116. package/dist/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -0
  117. package/dist/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -0
  118. package/dist/behaviors/registry/ui/game/atoms/std-market-flow.orb +1 -0
  119. package/dist/behaviors/registry/ui/game/atoms/std-objective-flow.orb +1 -0
  120. package/dist/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -0
  121. package/dist/behaviors/registry/ui/game/atoms/std-patience.orb +1 -0
  122. package/dist/behaviors/registry/ui/game/atoms/std-production.orb +1 -0
  123. package/dist/behaviors/registry/ui/game/atoms/std-round-flow.orb +1 -0
  124. package/dist/behaviors/registry/ui/game/atoms/std-score.orb +1 -0
  125. package/dist/behaviors/registry/ui/game/atoms/std-survival-flow.orb +1 -0
  126. package/dist/behaviors/registry/ui/game/atoms/std-xp.orb +1 -0
  127. package/dist/behaviors/registry/ui/game/atoms/ui-draw-group.orb +196 -0
  128. package/dist/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +9 -1
  129. package/dist/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +2 -2
  130. package/dist/behaviors/registry/ui/game/atoms/ui-svg-draw-group.orb +186 -0
  131. package/dist/behaviors/registry/ui/game/atoms/ui-svg-draw-shape.orb +259 -0
  132. package/dist/behaviors/registry/ui/game/atoms/ui-svg-draw-text.orb +195 -0
  133. package/dist/behaviors/registry/ui/game/molecules/std-worldmap-board-2d.orb +6 -3
  134. package/dist/behaviors/registry/ui/game/molecules/ui-canvas-2d.orb +16 -1
  135. package/dist/behaviors/registry/ui/game/molecules/ui-canvas.orb +14 -0
  136. package/dist/behaviors/registry/ui/game/molecules/ui-draw-shape-layer.orb +9 -1
  137. package/dist/behaviors/registry/ui/game/molecules/ui-svg-draw-shape-layer.orb +188 -0
  138. package/dist/behaviors/registry/ui/game/molecules/ui-svg-stage.orb +362 -0
  139. package/dist/behaviors/registry/ui/game/organisms/ui-fishing-board.orb +16 -16
  140. package/dist/behaviors/registry/ui/game/organisms/ui-physics-sandbox-board.orb +10 -10
  141. package/dist/behaviors/registry/ui/game/organisms/ui-roguelike-board.orb +10 -10
  142. package/dist/behaviors/registry/ui/game/organisms/ui-sokoban-board.orb +10 -10
  143. package/dist/behaviors/registry/ui/game/organisms/ui-state-architect-board.orb +8 -8
  144. package/dist/behaviors/registry/ui/game/organisms/ui-winter-ski-board.orb +14 -14
  145. package/dist/behaviors-embeddings.json +371 -343
  146. package/dist/behaviors-registry.json +4851 -2388
  147. package/dist/index.d.ts +1 -1
  148. package/dist/index.js +3410 -3102
  149. package/dist/knob-embeddings.json +1 -1
  150. package/dist/registry/factory-signatures.json +6211 -2181
  151. package/package.json +2 -2
@@ -211,7 +211,11 @@ orbital DataErasureOrbital {
211
211
  }
212
212
 
213
213
  state browsing {
214
- CANCEL_ERASURE -> loading
214
+ ;; Stays in `browsing`: this persist's result arms (ErasureSaved /
215
+ ;; ErasureSaveFailed) are declared here. Leaving for `loading` landed the
216
+ ;; save on a deaf state and wedged the panel on its spinner — the
217
+ ;; ErasureSaved arm below is what moves to `loading` to re-fetch.
218
+ CANCEL_ERASURE -> browsing
215
219
  (set @entity.id ?id)
216
220
  (set @entity.status cancelled)
217
221
  (persist update ErasureRequest @entity {
@@ -1,4 +1,4 @@
1
- app std-browse "2.4.0"
1
+ app std-browse "2.5.0"
2
2
  "std-browse as a Function — single primitive: data-grid. Owns the fetch + REFETCH (query/filter/page) state machine. Consumers configure fields/imageField/itemActions/cols/gap/variant; the atom renders the grid. Each `fields[]` entry accepts `{ name, label, variant }` plus optional `referenceEntity` + `displayField` to render a foreign-key column as the joined entity's display value (data-grid resolves @list[referenceEntity] at render time when both keys are present). `browseLook` (table default / dense / feed / gallery / master-detail / triage) selects one of six render bodies; dense/feed/gallery were folded in from std-browse-dense/-feed/-gallery (Phase 5.B); master-detail (split record view driven by the guarded VIEW/CLOSE self-transitions) and triage (inbox rows) were folded in 2026-07-26. Consumers retarget by setting browseLook."
3
3
  type FieldSpec = { name : string!, label : string, variant : h3 | h4 | body | caption | badge | small | progress, icon : string, format : date | currency | number | boolean | percent, key : string, header : string }
4
4
  type ItemAction = { label : string!, event : string, navigatesTo : string, variant : primary | secondary | ghost | danger, icon : string }
@@ -43,6 +43,7 @@ orbital BrowseItemOrbital {
43
43
  columns: @config.columns
44
44
  emptyMessage: "No records"
45
45
  itemActions: @config.itemActions
46
+ itemClickEvent: VIEW
46
47
  look: dense
47
48
  maxInlineActions: @config.maxInlineActions
48
49
  pageSize: @config.displayPageSize
@@ -75,7 +76,7 @@ orbital BrowseItemOrbital {
75
76
  INIT -> loading
76
77
  (fetch BrowseItem {
77
78
  emit: { failure: BrowseItemLoadFailed, success: BrowseItemLoaded }
78
- filter: (or ["=", @config.scopeField, ""] ["=", (object/get @entity @config.scopeField), @user.id])
79
+ filter: (and (or ["=", @config.scopeField, ""] ["=", (object/get @entity @config.scopeField), @user.id]) (or ["=", @config.initialFilterField, ""] ["=", (object/get @entity @config.initialFilterField), @config.initialFilterValue]))
79
80
  limit: @config.pageSize
80
81
  offset: 0
81
82
  })
@@ -104,7 +105,7 @@ orbital BrowseItemOrbital {
104
105
  INIT -> loading
105
106
  (fetch BrowseItem {
106
107
  emit: { failure: BrowseItemLoadFailed, success: BrowseItemLoaded }
107
- filter: (or ["=", @config.scopeField, ""] ["=", (object/get @entity @config.scopeField), @user.id])
108
+ filter: (and (or ["=", @config.scopeField, ""] ["=", (object/get @entity @config.scopeField), @user.id]) (or ["=", @config.initialFilterField, ""] ["=", (object/get @entity @config.initialFilterField), @config.initialFilterValue]))
108
109
  limit: @config.pageSize
109
110
  offset: 0
110
111
  })
@@ -161,7 +162,7 @@ orbital BrowseItemOrbital {
161
162
  INIT -> loading
162
163
  (fetch BrowseItem {
163
164
  emit: { failure: BrowseItemLoadFailed, success: BrowseItemLoaded }
164
- filter: (or ["=", @config.scopeField, ""] ["=", (object/get @entity @config.scopeField), @user.id])
165
+ filter: (and (or ["=", @config.scopeField, ""] ["=", (object/get @entity @config.scopeField), @user.id]) (or ["=", @config.initialFilterField, ""] ["=", (object/get @entity @config.initialFilterField), @config.initialFilterValue]))
165
166
  limit: @config.pageSize
166
167
  offset: 0
167
168
  })
@@ -353,6 +354,16 @@ orbital BrowseItemOrbital {
353
354
  @description "Name the field on this entity that holds the viewer's id (e.g. memberId, patientId, assignee). When set, the list loads ONLY rows whose that field equals @user.id — the 'my bookings' / 'my appointments' shape. Left blank the list loads every row, which is the default. Declared, never inferred: guessing the column from its name would silently scope the wrong one."
354
355
  @synonyms "owner field, my records, only mine, only my own, scope to user, per-user list, mine only, owned by me"
355
356
  @tier "policy"
357
+ initialFilterField : string = ""
358
+ @label "Which field does the first load filter on?"
359
+ @description "Name the field the INITIAL load filters on, paired with initialFilterValue. This is the detail half of a list-detail pair: a thread that must wait for a conversation to be picked sets the field to its parent key and leaves the value blank, so the first load matches nothing and the empty state shows instead of every record in the table. REFETCH_FILTER then supplies the real selection. Left blank the first load is unfiltered, which is the default."
360
+ @synonyms "initial filter, first load filter, wait for selection, detail pane filter, requires selection, start empty"
361
+ @tier "policy"
362
+ initialFilterValue : string = ""
363
+ @label "What value does the first load filter for?"
364
+ @description "The value initialFilterField must equal on the first load. Blank is meaningful: it matches only records whose field is itself blank, which for a detail pane is normally none — that is how a thread stays empty until its parent is selected."
365
+ @synonyms "initial filter value, first load value, default selection"
366
+ @tier "policy"
356
367
  selectable : boolean = false
357
368
  @label "Show row selection checkboxes?"
358
369
  @description "Adds a checkbox column with select-all to the dense table. Enable only when the surface offers bulk actions — checkboxes with nothing to act on are a dead affordance."
@@ -84,6 +84,8 @@ orbital DataListOrbital {
84
84
  loadMoreEvent: @config.loadMoreEvent
85
85
  hasMore: @config.hasMore
86
86
  pageSize: @config.pageSize
87
+ sortBy: @config.sortBy
88
+ sortDirection: @config.sortDirection
87
89
  look: @config.look
88
90
  type: data-list
89
91
  })
@@ -123,6 +125,8 @@ orbital DataListOrbital {
123
125
  loadMoreEvent: @config.loadMoreEvent
124
126
  hasMore: @config.hasMore
125
127
  pageSize: @config.pageSize
128
+ sortBy: @config.sortBy
129
+ sortDirection: @config.sortDirection
126
130
  look: @config.look
127
131
  type: data-list
128
132
  })
@@ -303,6 +307,14 @@ orbital DataListOrbital {
303
307
  @label "Page Size"
304
308
  @description "Max items to show before 'Show More' button. Defaults to 5. Set to 0 to disable."
305
309
  @tier "presentation"
310
+ sortBy : string
311
+ @label "Sort By"
312
+ @description "Field name to order rows by. Values are compared by their own type — numbers numerically, date-like strings chronologically, everything else alphabetically — never by what the field is called. Empty cells sort last. Unset leaves the incoming order untouched. Orders only the rows already fetched: a collection larger than its `limit` still needs ordering at the data layer."
313
+ @tier "presentation"
314
+ sortDirection : "asc" | "desc" = asc
315
+ @label "Sort Direction"
316
+ @description "Direction for `sortBy`. Defaults to ascending."
317
+ @tier "presentation"
306
318
  look : "dense" | "spacious" | "striped" | "borderless" | "card-rows" = dense
307
319
  @label "Look"
308
320
  @description "Layer 2 visual treatment — mirrors the `entity-table` look enum so data-grid / data-list / entity-table share one knob name from authors."
@@ -0,0 +1,56 @@
1
+ app ui-emoji-picker "1.0.0"
2
+ "EmojiPicker — UI factory (1:1 with the @almadar/ui emoji-picker pattern)."
3
+ orbital EmojiPickerOrbital {
4
+ entity EmojiPickerItem [runtime] {
5
+ id : string!
6
+ }
7
+
8
+ trait EmojiPickerRender -> @rebindable EmojiPickerItem [interaction, instance] {
9
+ initial: idle
10
+
11
+ state idle {
12
+ INIT -> idle
13
+ (render-ui main {
14
+ pickEvent: @config.pickEvent
15
+ position: @config.position
16
+ triggerIcon: @config.triggerIcon
17
+ triggerLabel: @config.triggerLabel
18
+ className: @config.className
19
+ type: emoji-picker
20
+ })
21
+ }
22
+
23
+ emits {
24
+ @config.pickEvent -> external {
25
+ id : string
26
+ }
27
+ @description "Declarative event name — picking an emoji emits UI:{pickEvent} with { emoji } via eventBus"
28
+ @tier "essential"
29
+ }
30
+
31
+ config {
32
+ pickEvent : string = "PICK"
33
+ @label "Pick Event"
34
+ @description "Declarative event name — picking an emoji emits UI:{pickEvent} with { emoji } via eventBus"
35
+ @tier "presentation"
36
+ position : "top" | "bottom" = top
37
+ @label "Position"
38
+ @description "Which side of the trigger the panel opens on"
39
+ @tier "presentation"
40
+ triggerIcon : icon
41
+ @label "Trigger Icon"
42
+ @description "Icon shown on the trigger button"
43
+ @tier "presentation"
44
+ triggerLabel : string = "Add emoji"
45
+ @label "Trigger Label"
46
+ @description "Accessible label for the trigger button"
47
+ @tier "presentation"
48
+ className : string
49
+ @label "Class Name"
50
+ @description "Additional CSS classes applied to the trigger button"
51
+ @tier "presentation"
52
+ }
53
+ }
54
+
55
+ page "/emoji-picker" as EmojiPickerPage -> EmojiPickerRender
56
+ }
@@ -3,6 +3,7 @@ app ui-popover "1.0.0"
3
3
  orbital PopoverOrbital {
4
4
  entity PopoverItem [runtime] {
5
5
  id : string!
6
+ open : boolean
6
7
  }
7
8
 
8
9
  trait PopoverRender -> @rebindable PopoverItem [interaction, instance] {
@@ -10,15 +11,45 @@ orbital PopoverOrbital {
10
11
 
11
12
  state idle {
12
13
  INIT -> idle
14
+ (set @entity.open @config.open)
13
15
  (render-ui main {
14
16
  content: @config.content
15
17
  children: @config.children
16
18
  position: @config.position
17
19
  trigger: @config.trigger
18
20
  showArrow: @config.showArrow
21
+ open: @entity.open
22
+ onOpenChange: @config.onOpenChange
19
23
  className: @config.className
20
24
  type: popover
21
25
  })
26
+ OPEN_CHANGE -> idle
27
+ (set @entity.open ?open)
28
+ (render-ui main {
29
+ content: @config.content
30
+ children: @config.children
31
+ position: @config.position
32
+ trigger: @config.trigger
33
+ showArrow: @config.showArrow
34
+ open: @entity.open
35
+ onOpenChange: @config.onOpenChange
36
+ className: @config.className
37
+ type: popover
38
+ })
39
+ }
40
+
41
+ emits {
42
+ @config.onOpenChange -> external {
43
+ open : boolean
44
+ }
45
+ @description "Fired when the popover wants to change visibility (trigger click, outside click)"
46
+ @tier "essential"
47
+ }
48
+
49
+ listens {
50
+ OPEN_CHANGE {
51
+ open : boolean
52
+ }
22
53
  }
23
54
 
24
55
  config {
@@ -42,6 +73,14 @@ orbital PopoverOrbital {
42
73
  @label "Show Arrow"
43
74
  @description "Show arrow"
44
75
  @tier "presentation"
76
+ open : boolean
77
+ @label "Open"
78
+ @description "Controlled open state. When set, the host owns visibility and the popover reports intent through onOpenChange instead of toggling itself."
79
+ @tier "presentation"
80
+ onOpenChange : string = "OPEN_CHANGE"
81
+ @label "On Open Change"
82
+ @description "Fired when the popover wants to change visibility (trigger click, outside click)"
83
+ @tier "presentation"
45
84
  className : string
46
85
  @label "Class Name"
47
86
  @description "Additional CSS classes"
@@ -66,6 +66,7 @@ orbital TableViewOrbital {
66
66
  fields: @config.fields
67
67
  itemActions: @config.itemActions
68
68
  maxInlineActions: @config.maxInlineActions
69
+ itemClickEvent: @config.itemClickEvent
69
70
  selectable: @config.selectable
70
71
  selectEvent: @config.selectEvent
71
72
  selectedIds: @config.selectedIds
@@ -96,6 +97,7 @@ orbital TableViewOrbital {
96
97
  fields: @config.fields
97
98
  itemActions: @config.itemActions
98
99
  maxInlineActions: @config.maxInlineActions
100
+ itemClickEvent: @config.itemClickEvent
99
101
  selectable: @config.selectable
100
102
  selectEvent: @config.selectEvent
101
103
  selectedIds: @config.selectedIds
@@ -114,6 +116,11 @@ orbital TableViewOrbital {
114
116
  }
115
117
 
116
118
  emits {
119
+ @config.itemClickEvent -> external {
120
+ id : string
121
+ }
122
+ @description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract."
123
+ @tier "essential"
117
124
  @config.selectEvent -> external {
118
125
  id : string
119
126
  }
@@ -184,6 +191,10 @@ orbital TableViewOrbital {
184
191
  @label "Max Inline Actions"
185
192
  @description "Max inline action buttons before the rest collapse into a '⋯' overflow menu. Omit = all inline."
186
193
  @tier "presentation"
194
+ itemClickEvent : string = "ITEM_CLICK"
195
+ @label "Item Click Event"
196
+ @description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract."
197
+ @tier "presentation"
187
198
  selectable : boolean = false
188
199
  @label "Selectable"
189
200
  @description "Render a leading checkbox column. Selection changes emit `selectEvent`."
@@ -0,0 +1,54 @@
1
+ app ui-draw-group "1.0.0"
2
+ "DrawGroup — UI factory (1:1 with the @almadar/ui draw-group pattern)."
3
+ orbital DrawGroupOrbital {
4
+ type DrawGroupPosition = {
5
+ x : number!
6
+ y : number!
7
+ z : number
8
+ }
9
+
10
+ entity DrawGroupItem [runtime] {
11
+ id : string!
12
+ }
13
+
14
+ trait DrawGroupRender -> @rebindable DrawGroupItem [interaction, instance] {
15
+ initial: idle
16
+
17
+ state idle {
18
+ INIT -> idle
19
+ (render-ui main {
20
+ position: @config.position
21
+ scale: @config.scale
22
+ rotate: @config.rotate
23
+ opacity: @config.opacity
24
+ items: @config.items
25
+ type: draw-group
26
+ })
27
+ }
28
+
29
+ config {
30
+ position : DrawGroupPosition = { x: 1, y: 1, z: 1 }
31
+ @label "Position"
32
+ @description "Logical scene position; the projector maps it to pixels / world."
33
+ @tier "presentation"
34
+ scale : number
35
+ @label "Scale"
36
+ @description "Uniform scale applied to the whole group."
37
+ @tier "presentation"
38
+ rotate : number
39
+ @label "Rotate"
40
+ @description "Rotation in radians (painter units)."
41
+ @tier "presentation"
42
+ opacity : number
43
+ @label "Opacity"
44
+ @description "0..1 opacity."
45
+ @tier "presentation"
46
+ items : [json] = []
47
+ @label "Items"
48
+ @description "The grouped drawables, painted through the normal dispatch."
49
+ @tier "presentation"
50
+ }
51
+ }
52
+
53
+ page "/draw-group" as DrawGroupPage -> DrawGroupRender
54
+ }
@@ -27,6 +27,7 @@ orbital DrawShapeOrbital {
27
27
  offsetX: @config.offsetX
28
28
  offsetY: @config.offsetY
29
29
  points: @config.points
30
+ d: @config.d
30
31
  fill: @config.fill
31
32
  stroke: @config.stroke
32
33
  strokeWidth: @config.strokeWidth
@@ -36,7 +37,7 @@ orbital DrawShapeOrbital {
36
37
  }
37
38
 
38
39
  config {
39
- shape : "cell" | "rect" | "ellipse" | "poly" = cell
40
+ shape : "cell" | "rect" | "ellipse" | "poly" | "path" = cell
40
41
  @label "Shape"
41
42
  @description "shape prop"
42
43
  @tier "presentation"
@@ -76,6 +77,10 @@ orbital DrawShapeOrbital {
76
77
  @label "Points"
77
78
  @description "Poly vertices as world-unit offsets relative to the cell's projected top-left."
78
79
  @tier "presentation"
80
+ d : string
81
+ @label "D"
82
+ @description "SVG path data in world units relative to the cell's projected top-left — same coordinate convention as `points`."
83
+ @tier "presentation"
79
84
  fill : string
80
85
  @label "Fill"
81
86
  @description "fill prop"
@@ -61,11 +61,11 @@ orbital DrawSpriteOrbital {
61
61
  @tier "presentation"
62
62
  width : number
63
63
  @label "Width"
64
- @description "Draw width in world units (fractions of `projector.tileWidth`); omittedresolved source width in px."
64
+ @description "Draw width in world units (fractions of `projector.tileWidth`). Omittedone cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`."
65
65
  @tier "presentation"
66
66
  height : number
67
67
  @label "Height"
68
- @description "Draw height in world units (fractions of `projector.tileWidth`); omittedresolved source height in px."
68
+ @description "Draw height in world units (fractions of `projector.tileWidth`). Omittedone cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`."
69
69
  @tier "presentation"
70
70
  frame : json = {}
71
71
  @label "Frame"
@@ -0,0 +1,58 @@
1
+ app ui-svg-draw-group "1.0.0"
2
+ "SvgDrawGroup — UI factory (1:1 with the @almadar/ui svg-draw-group pattern)."
3
+ orbital SvgDrawGroupOrbital {
4
+ entity SvgDrawGroupItem [runtime] {
5
+ id : string!
6
+ }
7
+
8
+ trait SvgDrawGroupRender -> @rebindable SvgDrawGroupItem [interaction, instance] {
9
+ initial: idle
10
+
11
+ state idle {
12
+ INIT -> idle
13
+ (render-ui main {
14
+ x: @config.x
15
+ y: @config.y
16
+ scale: @config.scale
17
+ rotate: @config.rotate
18
+ opacity: @config.opacity
19
+ className: @config.className
20
+ children: @config.children
21
+ type: svg-draw-group
22
+ })
23
+ }
24
+
25
+ config {
26
+ x : number = 0
27
+ @label "X"
28
+ @description "Grid-cell x of the group's origin."
29
+ @tier "presentation"
30
+ y : number = 0
31
+ @label "Y"
32
+ @description "Grid-cell y of the group's origin."
33
+ @tier "presentation"
34
+ scale : number
35
+ @label "Scale"
36
+ @description "Uniform scale applied after the translate."
37
+ @tier "presentation"
38
+ rotate : number
39
+ @label "Rotate"
40
+ @description "Rotation in degrees applied after the translate."
41
+ @tier "presentation"
42
+ opacity : number
43
+ @label "Opacity"
44
+ @description "0..1 opacity."
45
+ @tier "presentation"
46
+ className : string
47
+ @label "Class Name"
48
+ @description "Additional CSS classes"
49
+ @tier "presentation"
50
+ children : node
51
+ @label "Children"
52
+ @description "children prop"
53
+ @tier "presentation"
54
+ }
55
+ }
56
+
57
+ page "/svg-draw-group" as SvgDrawGroupPage -> SvgDrawGroupRender
58
+ }
@@ -0,0 +1,103 @@
1
+ app ui-svg-draw-shape "1.0.0"
2
+ "SvgDrawShape — UI factory (1:1 with the @almadar/ui svg-draw-shape pattern)."
3
+ orbital SvgDrawShapeOrbital {
4
+ entity SvgDrawShapeItem [runtime] {
5
+ id : string!
6
+ }
7
+
8
+ trait SvgDrawShapeRender -> @rebindable SvgDrawShapeItem [interaction, instance] {
9
+ initial: idle
10
+
11
+ state idle {
12
+ INIT -> idle
13
+ (render-ui main {
14
+ shape: @config.shape
15
+ x: @config.x
16
+ y: @config.y
17
+ width: @config.width
18
+ height: @config.height
19
+ radius: @config.radius
20
+ radiusY: @config.radiusY
21
+ points: @config.points
22
+ d: @config.d
23
+ x2: @config.x2
24
+ y2: @config.y2
25
+ fill: @config.fill
26
+ stroke: @config.stroke
27
+ strokeWidth: @config.strokeWidth
28
+ opacity: @config.opacity
29
+ className: @config.className
30
+ type: svg-draw-shape
31
+ })
32
+ }
33
+
34
+ config {
35
+ shape : "rect" | "circle" | "ellipse" | "polygon" | "polyline" | "path" | "line" = rect
36
+ @label "Shape"
37
+ @description "shape prop"
38
+ @tier "presentation"
39
+ x : number = 1
40
+ @label "X"
41
+ @description "Grid-cell x of the element's translated origin."
42
+ @tier "presentation"
43
+ y : number = 1
44
+ @label "Y"
45
+ @description "Grid-cell y of the element's translated origin."
46
+ @tier "presentation"
47
+ width : number
48
+ @label "Width"
49
+ @description "Rect width in cell units."
50
+ @tier "presentation"
51
+ height : number
52
+ @label "Height"
53
+ @description "Rect height in cell units."
54
+ @tier "presentation"
55
+ radius : number
56
+ @label "Radius"
57
+ @description "Circle radius / ellipse horizontal radius in cell units."
58
+ @tier "presentation"
59
+ radiusY : number
60
+ @label "Radius Y"
61
+ @description "Ellipse vertical radius in cell units; omitted → `radius` (a circle)."
62
+ @tier "presentation"
63
+ points : string
64
+ @label "Points"
65
+ @description "Polygon/polyline points, viewBox units relative to the translated origin."
66
+ @tier "presentation"
67
+ d : string
68
+ @label "D"
69
+ @description "Path data, viewBox units relative to the translated origin."
70
+ @tier "presentation"
71
+ x2 : number
72
+ @label "X2"
73
+ @description "Line end x in cell units."
74
+ @tier "presentation"
75
+ y2 : number
76
+ @label "Y2"
77
+ @description "Line end y in cell units."
78
+ @tier "presentation"
79
+ fill : string
80
+ @label "Fill"
81
+ @description "fill prop"
82
+ @tier "presentation"
83
+ stroke : string
84
+ @label "Stroke"
85
+ @description "stroke prop"
86
+ @tier "presentation"
87
+ strokeWidth : number
88
+ @label "Stroke Width"
89
+ @description "strokeWidth prop"
90
+ @tier "presentation"
91
+ opacity : number
92
+ @label "Opacity"
93
+ @description "0..1 opacity."
94
+ @tier "presentation"
95
+ className : string
96
+ @label "Class Name"
97
+ @description "Additional CSS classes"
98
+ @tier "presentation"
99
+ }
100
+ }
101
+
102
+ page "/svg-draw-shape" as SvgDrawShapePage -> SvgDrawShapeRender
103
+ }
@@ -0,0 +1,58 @@
1
+ app ui-svg-draw-text "1.0.0"
2
+ "SvgDrawText — UI factory (1:1 with the @almadar/ui svg-draw-text pattern)."
3
+ orbital SvgDrawTextOrbital {
4
+ entity SvgDrawTextItem [runtime] {
5
+ id : string!
6
+ }
7
+
8
+ trait SvgDrawTextRender -> @rebindable SvgDrawTextItem [interaction, instance] {
9
+ initial: idle
10
+
11
+ state idle {
12
+ INIT -> idle
13
+ (render-ui main {
14
+ x: @config.x
15
+ y: @config.y
16
+ text: @config.text
17
+ size: @config.size
18
+ fill: @config.fill
19
+ anchor: @config.anchor
20
+ className: @config.className
21
+ type: svg-draw-text
22
+ })
23
+ }
24
+
25
+ config {
26
+ x : number = 1
27
+ @label "X"
28
+ @description "Grid-cell x of the text anchor."
29
+ @tier "presentation"
30
+ y : number = 1
31
+ @label "Y"
32
+ @description "Grid-cell y of the text anchor."
33
+ @tier "presentation"
34
+ text : string = ""
35
+ @label "Text"
36
+ @description "The text content."
37
+ @tier "presentation"
38
+ size : number = 12
39
+ @label "Size"
40
+ @description "Font size in viewBox units (default 12)."
41
+ @tier "presentation"
42
+ fill : string = "var(--color-foreground)"
43
+ @label "Fill"
44
+ @description "fill prop"
45
+ @tier "presentation"
46
+ anchor : "start" | "middle" | "end" = middle
47
+ @label "Anchor"
48
+ @description "Text anchor (default 'middle')."
49
+ @tier "presentation"
50
+ className : string
51
+ @label "Class Name"
52
+ @description "Additional CSS classes"
53
+ @tier "presentation"
54
+ }
55
+ }
56
+
57
+ page "/svg-draw-text" as SvgDrawTextPage -> SvgDrawTextRender
58
+ }
@@ -42,6 +42,8 @@ orbital Canvas2dOrbital {
42
42
  keyUpMap: @config.keyUpMap
43
43
  camera: @config.camera
44
44
  scale: @config.scale
45
+ tileWidth: @config.tileWidth
46
+ fit: @config.fit
45
47
  showMinimap: @config.showMinimap
46
48
  followTarget: @config.followTarget
47
49
  cameraPos: @config.cameraPos
@@ -130,7 +132,15 @@ orbital Canvas2dOrbital {
130
132
  @tier "presentation"
131
133
  scale : number = 0.4
132
134
  @label "Scale"
133
- @description "Render scale (0.4 = 40% zoom). Ignored by `free`/`side` (world-pixel-direct)."
135
+ @description "Render scale, legacy-squared semantics: on-screen cell ≈ `256 × scale²` px (the authored contract every board tuned its value for). Converted internally to the single camera zoom against the board's native tile width, so the cell pitch follows the asset while the on-screen size stays as authored. Ignored when `fit` is on; passed through raw for `free`/`side` (world-pixel-direct)."
136
+ @tier "presentation"
137
+ tileWidth : number
138
+ @label "Tile Width"
139
+ @description "Native tile/cell width in source px for this board's asset (e.g. 16 for Kenney tiny-dungeon, ~128 for iso blocks). The grid cell pitch follows the asset, so tile textures map 1:1 (crisp, no stretch). Defaults to the detected atlas tile width, else 256."
140
+ @tier "presentation"
141
+ fit : boolean = false
142
+ @label "Fit"
143
+ @description "Auto-fit the board's grid extent to the viewport (default false — boards render at their authored `scale` and overflow → pan). Opt in for whole-board-overview boards. User wheel/pinch zoom always wins after the initial fit."
134
144
  @tier "presentation"
135
145
  showMinimap : boolean = true
136
146
  @label "Show Minimap"
@@ -19,6 +19,8 @@ orbital CanvasOrbital {
19
19
  isLoading: @config.isLoading
20
20
  unitScale: @config.unitScale
21
21
  showMinimap: @config.showMinimap
22
+ fit: @config.fit
23
+ tileWidth: @config.tileWidth
22
24
  backgroundImage: @config.backgroundImage
23
25
  backgroundColor: @config.backgroundColor
24
26
  worldWidth: @config.worldWidth
@@ -104,6 +106,14 @@ orbital CanvasOrbital {
104
106
  @label "Show Minimap"
105
107
  @description "Minimap overlay (2D)."
106
108
  @tier "presentation"
109
+ fit : boolean
110
+ @label "Fit"
111
+ @description "Auto-fit the board's grid extent to the viewport (2D grid layouts; default false — boards render at their authored `camera.zoom` scale)."
112
+ @tier "presentation"
113
+ tileWidth : number
114
+ @label "Tile Width"
115
+ @description "Native tile/cell width in source px of the board's asset (2D grid layouts; defaults to the detected atlas tile width, else 256)."
116
+ @tier "presentation"
107
117
  backgroundImage : asset
108
118
  @label "Background Image"
109
119
  @description "Backdrop image (2D iso/hex/flat/free/side)."
@@ -3,7 +3,7 @@ app ui-draw-shape-layer "1.0.0"
3
3
  orbital DrawShapeLayerOrbital {
4
4
  type DrawShapeLayerItemsItem = {
5
5
  type : json!
6
- shape : "cell" | "rect" | "ellipse" | "poly"!
6
+ shape : "cell" | "rect" | "ellipse" | "poly" | "path"!
7
7
  position : DrawShapeLayerItemsItemPosition!
8
8
  anchor : json
9
9
  width : number
@@ -13,6 +13,7 @@ orbital DrawShapeLayerOrbital {
13
13
  offsetX : number
14
14
  offsetY : number
15
15
  points : [json]
16
+ d : string
16
17
  fill : string
17
18
  stroke : string
18
19
  strokeWidth : number
@@ -40,7 +41,7 @@ orbital DrawShapeLayerOrbital {
40
41
  }
41
42
 
42
43
  config {
43
- items : [DrawShapeLayerItemsItem] = [{ type: "Type", shape: cell, position: { x: 1, y: 1, z: 1 }, width: 1, height: 1, radiusX: 1, radiusY: 1, offsetX: 1, offsetY: 1, points: [], fill: "Fill", stroke: "Stroke", strokeWidth: 1, opacity: 1 }, { type: "Type 2", shape: rect, position: { x: 2, y: 2, z: 2 }, width: 2, height: 2, radiusX: 2, radiusY: 2, offsetX: 2, offsetY: 2, points: [], fill: "Fill 2", stroke: "Stroke 2", strokeWidth: 2, opacity: 2 }]
44
+ items : [DrawShapeLayerItemsItem] = [{ type: "Type", shape: cell, position: { x: 1, y: 1, z: 1 }, width: 1, height: 1, radiusX: 1, radiusY: 1, offsetX: 1, offsetY: 1, points: [], d: "D", fill: "Fill", stroke: "Stroke", strokeWidth: 1, opacity: 1 }, { type: "Type 2", shape: rect, position: { x: 2, y: 2, z: 2 }, width: 2, height: 2, radiusX: 2, radiusY: 2, offsetX: 2, offsetY: 2, points: [], d: "D 2", fill: "Fill 2", stroke: "Stroke 2", strokeWidth: 2, opacity: 2 }]
44
45
  @label "Items"
45
46
  @description "items prop"
46
47
  @tier "presentation"