@almadar/std 16.183.0 → 16.185.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/behaviors/lolo/ui/core/.hand-authored.json +4 -0
- package/behaviors/lolo/ui/core/atoms/std-browse.lolo +11 -0
- package/behaviors/lolo/ui/core/atoms/std-related.lolo +86 -9
- package/behaviors/lolo/ui/core/atoms/std-rich-editor.lolo +368 -1
- package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +62 -2
- package/behaviors/lolo/ui/core/atoms/std-thread.lolo +43 -2
- package/behaviors/lolo/ui/core/atoms/std-tree.lolo +247 -0
- package/behaviors/lolo/ui/core/atoms/std-version-history.lolo +110 -2
- package/behaviors/lolo/ui/core/molecules/ui-file-tree.lolo +18 -2
- package/behaviors/lolo/ui/core/organisms/ui-detail-panel.lolo +12 -2
- package/behaviors/lolo/ui/core/organisms/ui-form-section.lolo +2 -2
- package/behaviors/lolo/ui/core/organisms/ui-form.lolo +2 -2
- package/behaviors/lolo/ui/game/atoms/std-tutorial-autodemo.lolo +136 -0
- package/behaviors/lolo/ui/game/atoms/std-tutorial-overlay.lolo +41 -8
- package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +3 -3
- package/behaviors/registry/ui/core/atoms/std-browse.orb +17 -0
- package/behaviors/registry/ui/core/atoms/std-related.orb +256 -3
- package/behaviors/registry/ui/core/atoms/std-rich-editor.orb +898 -1
- package/behaviors/registry/ui/core/atoms/std-tag-taxonomy.orb +240 -8
- package/behaviors/registry/ui/core/atoms/std-thread.orb +254 -4
- package/behaviors/registry/ui/core/atoms/std-tree.orb +656 -0
- package/behaviors/registry/ui/core/atoms/std-version-history.orb +479 -6
- package/behaviors/registry/ui/core/molecules/ui-file-tree.orb +43 -19
- package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +37 -3
- package/behaviors/registry/ui/core/organisms/ui-form-section.orb +8 -2
- package/behaviors/registry/ui/core/organisms/ui-form.orb +8 -2
- package/behaviors/registry/ui/game/atoms/std-tutorial-autodemo.orb +732 -0
- package/behaviors/registry/ui/game/atoms/std-tutorial-overlay.orb +305 -153
- package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +26 -0
- package/dist/behaviors/exports-reader.js +5132 -2398
- package/dist/behaviors/functions/index.d.ts +261 -44
- package/dist/behaviors/functions/index.js +5118 -2396
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +5133 -2399
- package/dist/behaviors/query.js +5132 -2398
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +310 -302
- package/dist/behaviors-registry.json +820 -35
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5133 -2399
- package/dist/knob-embeddings.hash.json +3 -3
- package/dist/knob-embeddings.json +1 -1
- package/dist/registry/factory-signatures.json +1 -1
- package/package.json +2 -2
|
@@ -9,6 +9,12 @@ orbital FileTreeOrbital {
|
|
|
9
9
|
size : number
|
|
10
10
|
language : string
|
|
11
11
|
}
|
|
12
|
+
type FileTreeItemsItem = {
|
|
13
|
+
id : string!
|
|
14
|
+
label : string!
|
|
15
|
+
parentId : string
|
|
16
|
+
icon : string
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
entity FileTreeItem [runtime] {
|
|
14
20
|
id : string!
|
|
@@ -21,8 +27,10 @@ orbital FileTreeOrbital {
|
|
|
21
27
|
INIT -> idle
|
|
22
28
|
(render-ui main {
|
|
23
29
|
tree: @config.tree
|
|
30
|
+
items: @config.items
|
|
24
31
|
selectedPath: @config.selectedPath
|
|
25
32
|
onFileSelect: @config.onFileSelect
|
|
33
|
+
onNodeSelect: @config.onNodeSelect
|
|
26
34
|
className: @config.className
|
|
27
35
|
indent: @config.indent
|
|
28
36
|
type: file-tree
|
|
@@ -38,9 +46,13 @@ orbital FileTreeOrbital {
|
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
config {
|
|
41
|
-
tree : [FileTreeTreeItem] = [
|
|
49
|
+
tree : [FileTreeTreeItem] = []
|
|
42
50
|
@label "Tree"
|
|
43
|
-
@description "The tree data"
|
|
51
|
+
@description "The tree data (pre-nested). Ignored when `items` is provided."
|
|
52
|
+
@tier "presentation"
|
|
53
|
+
items : [FileTreeItemsItem] = []
|
|
54
|
+
@label "Items"
|
|
55
|
+
@description "Flat node list, nested by `parentId` at render time — takes precedence over `tree` when provided. A `parentId` with no matching row renders that node as a root rather than dropping it."
|
|
44
56
|
@tier "presentation"
|
|
45
57
|
selectedPath : string
|
|
46
58
|
@label "Selected Path"
|
|
@@ -50,6 +62,10 @@ orbital FileTreeOrbital {
|
|
|
50
62
|
@label "On File Select"
|
|
51
63
|
@description "Called when a file is clicked"
|
|
52
64
|
@tier "presentation"
|
|
65
|
+
onNodeSelect : string = ""
|
|
66
|
+
@label "On Node Select"
|
|
67
|
+
@description "Called when a node is clicked, in flat `items` mode; carries the selected node's id. Presence-gated: binding this prop is what turns on the click-to-select affordance, mirroring Badge's `onRemove`."
|
|
68
|
+
@tier "presentation"
|
|
53
69
|
className : string
|
|
54
70
|
@label "Class Name"
|
|
55
71
|
@description "CSS class"
|
|
@@ -41,7 +41,11 @@ orbital DetailPanelOrbital {
|
|
|
41
41
|
header : string
|
|
42
42
|
type : string
|
|
43
43
|
values : [string]
|
|
44
|
-
relation :
|
|
44
|
+
relation : DetailPanelFieldsItemRelation
|
|
45
|
+
}
|
|
46
|
+
type DetailPanelFieldsItemRelation = {
|
|
47
|
+
entity : string!
|
|
48
|
+
cardinality : "one" | "many" | "one-to-many" | "many-to-one" | "many-to-many"
|
|
45
49
|
}
|
|
46
50
|
type DetailPanelRelationsDataValueItem = {
|
|
47
51
|
value : string!
|
|
@@ -74,6 +78,7 @@ orbital DetailPanelOrbital {
|
|
|
74
78
|
selectedIds: @config.selectedIds
|
|
75
79
|
entity: @entity
|
|
76
80
|
title: @config.title
|
|
81
|
+
onTitleCommit: @config.onTitleCommit
|
|
77
82
|
subtitle: @config.subtitle
|
|
78
83
|
status: @config.status
|
|
79
84
|
avatar: @config.avatar
|
|
@@ -109,6 +114,7 @@ orbital DetailPanelOrbital {
|
|
|
109
114
|
selectedIds: @config.selectedIds
|
|
110
115
|
entity: @payload.data
|
|
111
116
|
title: @config.title
|
|
117
|
+
onTitleCommit: @config.onTitleCommit
|
|
112
118
|
subtitle: @config.subtitle
|
|
113
119
|
status: @config.status
|
|
114
120
|
avatar: @config.avatar
|
|
@@ -188,6 +194,10 @@ orbital DetailPanelOrbital {
|
|
|
188
194
|
@label "Title"
|
|
189
195
|
@description "title prop"
|
|
190
196
|
@tier "presentation"
|
|
197
|
+
onTitleCommit : string = ""
|
|
198
|
+
@label "On Title Commit"
|
|
199
|
+
@description "When bound, the title becomes editable in place: clicking it swaps the heading for an input, Enter or blur commits, Escape reverts. Receives the committed title and the record's id so the host can persist a partial update. Unbound, the title stays a plain heading."
|
|
200
|
+
@tier "presentation"
|
|
191
201
|
subtitle : string
|
|
192
202
|
@label "Subtitle"
|
|
193
203
|
@description "subtitle prop"
|
|
@@ -224,7 +234,7 @@ orbital DetailPanelOrbital {
|
|
|
224
234
|
@label "Slide Over"
|
|
225
235
|
@description "slideOver prop"
|
|
226
236
|
@tier "presentation"
|
|
227
|
-
fields : [DetailPanelFieldsItem] = [{ key: "Key", header: "Header", type: "Type", values: ["Item", "Item 2"], relation: "
|
|
237
|
+
fields : [DetailPanelFieldsItem] = [{ key: "Key", header: "Header", type: "Type", values: ["Item", "Item 2"], relation: { entity: "Entity", cardinality: one } }, { key: "Key 2", header: "Header 2", type: "Type 2", values: ["Item", "Item 2"], relation: { entity: "Entity 2", cardinality: many } }]
|
|
228
238
|
@label "Fields"
|
|
229
239
|
@description "Fields to display - accepts string[], {key, header}[], or DetailField[]"
|
|
230
240
|
@tier "presentation"
|
|
@@ -29,7 +29,7 @@ orbital FormSectionOrbital {
|
|
|
29
29
|
type FormSectionFieldsItemRelation = {
|
|
30
30
|
entity : string!
|
|
31
31
|
displayField : string
|
|
32
|
-
cardinality : "one" | "many"
|
|
32
|
+
cardinality : "one" | "many" | "one-to-many" | "many-to-one" | "many-to-many"
|
|
33
33
|
}
|
|
34
34
|
type FormSectionFieldsItemValidation = {
|
|
35
35
|
enum : [string]
|
|
@@ -108,7 +108,7 @@ orbital FormSectionOrbital {
|
|
|
108
108
|
type FormSectionSectionsItemFieldsItemRelation = {
|
|
109
109
|
entity : string!
|
|
110
110
|
displayField : string
|
|
111
|
-
cardinality : "one" | "many"
|
|
111
|
+
cardinality : "one" | "many" | "one-to-many" | "many-to-one" | "many-to-many"
|
|
112
112
|
}
|
|
113
113
|
type FormSectionSectionsItemFieldsItemValidation = {
|
|
114
114
|
enum : [string]
|
|
@@ -29,7 +29,7 @@ orbital FormOrbital {
|
|
|
29
29
|
type FormFieldsItemRelation = {
|
|
30
30
|
entity : string!
|
|
31
31
|
displayField : string
|
|
32
|
-
cardinality : "one" | "many"
|
|
32
|
+
cardinality : "one" | "many" | "one-to-many" | "many-to-one" | "many-to-many"
|
|
33
33
|
}
|
|
34
34
|
type FormFieldsItemValidation = {
|
|
35
35
|
enum : [string]
|
|
@@ -108,7 +108,7 @@ orbital FormOrbital {
|
|
|
108
108
|
type FormSectionsItemFieldsItemRelation = {
|
|
109
109
|
entity : string!
|
|
110
110
|
displayField : string
|
|
111
|
-
cardinality : "one" | "many"
|
|
111
|
+
cardinality : "one" | "many" | "one-to-many" | "many-to-one" | "many-to-many"
|
|
112
112
|
}
|
|
113
113
|
type FormSectionsItemFieldsItemValidation = {
|
|
114
114
|
enum : [string]
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
app std-tutorial-autodemo "1.0.0"
|
|
2
|
+
"Generic scripted input-replay atom: the demo half of a tutorial. Holds one or more named cue scripts (each an ordered list of { at, event, arg } rows where at is a millisecond offset and event is LEFT/RIGHT/JUMP/STOP); listens for TUTORIAL_DEMO_START { demoId } (from std-tutorial-overlay's demoId step) and plays the matching script on a 32ms clock, emitting the semantic DEMO_LEFT / DEMO_RIGHT / DEMO_JUMP / DEMO_STOP events the host board maps onto its own movement. TUTORIAL_DEMO_STOP, DEMO_CANCEL (real user input), or exhausting the cue list end the demo and emit DEMO_STOP so the character stops moving. Renders a small Demo badge while playing. Domain-agnostic: the demo never emits board events (OW_*, etc.) — the organism maps DEMO_* to its own steering, so a demo cannot self-cancel through the board's input path."
|
|
3
|
+
orbital TutorialAutoDemoOrbital {
|
|
4
|
+
type DemoCue = {
|
|
5
|
+
at : number!
|
|
6
|
+
event : string!
|
|
7
|
+
arg : number
|
|
8
|
+
}
|
|
9
|
+
type DemoScript = {
|
|
10
|
+
id : string!
|
|
11
|
+
cues : [DemoCue]!
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
entity AutoDemoData [runtime] {
|
|
15
|
+
id : string!
|
|
16
|
+
playing : boolean = false
|
|
17
|
+
scriptId : string = ""
|
|
18
|
+
elapsed : number = 0
|
|
19
|
+
cueIndex : number = 0
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
trait AutoDemo -> @rebindable AutoDemoData [interaction, instance] {
|
|
23
|
+
initial: idle
|
|
24
|
+
|
|
25
|
+
state idle {
|
|
26
|
+
INIT -> idle
|
|
27
|
+
(render-ui hud-top null)
|
|
28
|
+
|
|
29
|
+
TUTORIAL_DEMO_START -> playing
|
|
30
|
+
(set @entity.scriptId @payload.demoId)
|
|
31
|
+
(set @entity.elapsed 0)
|
|
32
|
+
(set @entity.cueIndex 0)
|
|
33
|
+
(set @entity.playing true)
|
|
34
|
+
(render-ui hud-top {
|
|
35
|
+
type: badge
|
|
36
|
+
label: "Demo"
|
|
37
|
+
variant: "info"
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
TUTORIAL_DEMO_STOP -> idle
|
|
41
|
+
(render-ui hud-top null)
|
|
42
|
+
|
|
43
|
+
DEMO_CANCEL -> idle
|
|
44
|
+
(render-ui hud-top null)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
state playing {
|
|
48
|
+
TUTORIAL_DEMO_START -> playing
|
|
49
|
+
(set @entity.scriptId @payload.demoId)
|
|
50
|
+
(set @entity.elapsed 0)
|
|
51
|
+
(set @entity.cueIndex 0)
|
|
52
|
+
(render-ui hud-top {
|
|
53
|
+
type: badge
|
|
54
|
+
label: "Demo"
|
|
55
|
+
variant: "info"
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
TUTORIAL_DEMO_STOP -> idle
|
|
59
|
+
(set @entity.playing false)
|
|
60
|
+
(render-ui hud-top null)
|
|
61
|
+
(emit DEMO_STOP {})
|
|
62
|
+
|
|
63
|
+
DEMO_CANCEL -> idle
|
|
64
|
+
(set @entity.playing false)
|
|
65
|
+
(render-ui hud-top null)
|
|
66
|
+
(emit DEMO_STOP {})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
ticks {
|
|
70
|
+
demoTick every 32ms when (== @entity.playing true)
|
|
71
|
+
(set @entity.elapsed (+ @entity.elapsed 32))
|
|
72
|
+
(let ((scriptMatch (array/filter @config.scripts (fn s (== (object/get @s id) @entity.scriptId)))))
|
|
73
|
+
(let ((cueList (if (> (array/len @scriptMatch) 0) (object/get (array/first @scriptMatch) cues []) [])))
|
|
74
|
+
(let ((cue (if (< @entity.cueIndex (array/len @cueList)) (array/nth @cueList @entity.cueIndex) { at: 999999, event: "" })))
|
|
75
|
+
(do
|
|
76
|
+
(if (<= (object/get @cue at 0) @entity.elapsed)
|
|
77
|
+
(do
|
|
78
|
+
(set @entity.cueIndex (+ @entity.cueIndex 1))
|
|
79
|
+
(if (== (object/get @cue event "") "LEFT") (emit DEMO_LEFT {}) null)
|
|
80
|
+
(if (== (object/get @cue event "") "RIGHT") (emit DEMO_RIGHT {}) null)
|
|
81
|
+
(if (== (object/get @cue event "") "JUMP") (emit DEMO_JUMP {}) null)
|
|
82
|
+
(if (== (object/get @cue event "") "STOP") (emit DEMO_STOP {}) null))
|
|
83
|
+
null)
|
|
84
|
+
(if (>= @entity.cueIndex (array/len @cueList))
|
|
85
|
+
(do
|
|
86
|
+
(set @entity.playing false)
|
|
87
|
+
(render-ui hud-top null)
|
|
88
|
+
(emit DEMO_STOP {}))
|
|
89
|
+
null)))))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
listens {
|
|
93
|
+
TUTORIAL_DEMO_START {
|
|
94
|
+
demoId : string!
|
|
95
|
+
}
|
|
96
|
+
@description "A tutorial step carrying a demoId was shown (std-tutorial-overlay); begin playing the cue script whose id matches demoId."
|
|
97
|
+
@tier "domain"
|
|
98
|
+
TUTORIAL_DEMO_STOP {
|
|
99
|
+
}
|
|
100
|
+
@description "The tutorial left a demo step or was dismissed; stop the demo and release control."
|
|
101
|
+
@tier "domain"
|
|
102
|
+
DEMO_CANCEL {
|
|
103
|
+
}
|
|
104
|
+
@description "Real user input was received by the host board; stop the demo immediately and hand control back to the player."
|
|
105
|
+
@tier "domain"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
emits {
|
|
109
|
+
DEMO_LEFT -> external {
|
|
110
|
+
}
|
|
111
|
+
@description "Scripted run-left cue; the host board maps this to its own steer-left."
|
|
112
|
+
@tier "domain"
|
|
113
|
+
DEMO_RIGHT -> external {
|
|
114
|
+
}
|
|
115
|
+
@description "Scripted run-right cue; the host board maps this to its own steer-right."
|
|
116
|
+
@tier "domain"
|
|
117
|
+
DEMO_JUMP -> external {
|
|
118
|
+
}
|
|
119
|
+
@description "Scripted jump cue; the host board maps this to its own jump."
|
|
120
|
+
@tier "domain"
|
|
121
|
+
DEMO_STOP -> external {
|
|
122
|
+
}
|
|
123
|
+
@description "Scripted stop cue (or demo end/cancel); the host board maps this to stop movement."
|
|
124
|
+
@tier "domain"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
config {
|
|
128
|
+
scripts : [DemoScript] = []
|
|
129
|
+
@label "Scripts"
|
|
130
|
+
@description "Named cue scripts keyed by the tutorial step's demoId; each cue fires its event after `at` milliseconds of the demo clock."
|
|
131
|
+
@tier "domain"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
page "/tutorial-autodemo" as TutorialAutoDemoPage -> AutoDemo
|
|
136
|
+
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
app std-tutorial-overlay "1.0.0"
|
|
2
|
-
"Tutorial modal with
|
|
2
|
+
"Tutorial modal with live-demo steps for game boards and learning shells: a paged overlay — title, a live previewTrait frame playing the mechanic via std-tutorial-autodemo (a bare game canvas, no shell chrome), one line of body copy, a step counter, and Back / Next / Skip — composed entirely from registered render types (stack + text + button + trait frame) into the overlay slot, so no new UI component is needed. autoShow opens it on INIT for first-time players; a board's help button re-opens it any time via SHOW (which rewinds to step one). DISMISS (or finishing the last step) marks the run done, clears the overlay, and emits TUTORIAL_DONE so the board can unpause or log. Steps are pure config — a board teaches a new mechanic by adding one { id, title, body, demoId } row plus a previewTrait binding."
|
|
3
3
|
orbital TutorialOverlayOrbital {
|
|
4
4
|
type TutorialStep = {
|
|
5
5
|
id : string!
|
|
6
6
|
title : string!
|
|
7
7
|
body : string
|
|
8
|
-
|
|
9
|
-
mediaAlt : string
|
|
8
|
+
demoId : string
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
entity TutorialState [runtime, shared] {
|
|
@@ -15,6 +14,15 @@ orbital TutorialOverlayOrbital {
|
|
|
15
14
|
done : boolean = false
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
trait TutorialEmptyPreview -> TutorialState [interaction, instance] {
|
|
18
|
+
initial: idle
|
|
19
|
+
|
|
20
|
+
state idle {
|
|
21
|
+
INIT -> idle
|
|
22
|
+
(render-ui overlay null)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
18
26
|
trait TutorialOverlay -> @rebindable TutorialState [interaction, instance] {
|
|
19
27
|
initial: hidden
|
|
20
28
|
|
|
@@ -32,7 +40,7 @@ orbital TutorialOverlayOrbital {
|
|
|
32
40
|
className: "bg-card text-card-foreground border border-border rounded-lg shadow-lg p-6 max-w-md mx-auto mt-16"
|
|
33
41
|
children: [
|
|
34
42
|
{ type: typography, content: (object/get (array/nth @config.steps 0) title), variant: "h4", weight: "bold" }
|
|
35
|
-
|
|
43
|
+
@config.previewTrait
|
|
36
44
|
{ type: typography, content: (object/get (array/nth @config.steps 0) body), variant: "body" }
|
|
37
45
|
{ type: typography, content: (str/concat "1 / " (array/len @config.steps)), variant: "caption", align: "center" }
|
|
38
46
|
{ type: stack, direction: horizontal, justify: "center", className: "pt-2", children: [
|
|
@@ -41,6 +49,8 @@ orbital TutorialOverlayOrbital {
|
|
|
41
49
|
] }
|
|
42
50
|
]
|
|
43
51
|
})
|
|
52
|
+
(when (!= (object/get (array/nth @config.steps 0) demoId "") "")
|
|
53
|
+
(do (emit TUTORIAL_DEMO_START { demoId: (object/get (array/nth @config.steps 0) demoId "") })))
|
|
44
54
|
|
|
45
55
|
SHOW -> showing
|
|
46
56
|
(set @entity.step 0)
|
|
@@ -50,7 +60,7 @@ orbital TutorialOverlayOrbital {
|
|
|
50
60
|
className: "bg-card text-card-foreground border border-border rounded-lg shadow-lg p-6 max-w-md mx-auto mt-16"
|
|
51
61
|
children: [
|
|
52
62
|
{ type: typography, content: (object/get (array/nth @config.steps 0) title), variant: "h4", weight: "bold" }
|
|
53
|
-
|
|
63
|
+
@config.previewTrait
|
|
54
64
|
{ type: typography, content: (object/get (array/nth @config.steps 0) body), variant: "body" }
|
|
55
65
|
{ type: typography, content: (str/concat "1 / " (array/len @config.steps)), variant: "caption", align: "center" }
|
|
56
66
|
{ type: stack, direction: horizontal, justify: "center", className: "pt-2", children: [
|
|
@@ -59,6 +69,8 @@ orbital TutorialOverlayOrbital {
|
|
|
59
69
|
] }
|
|
60
70
|
]
|
|
61
71
|
})
|
|
72
|
+
(when (!= (object/get (array/nth @config.steps 0) demoId "") "")
|
|
73
|
+
(do (emit TUTORIAL_DEMO_START { demoId: (object/get (array/nth @config.steps 0) demoId "") })))
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
state showing {
|
|
@@ -70,7 +82,7 @@ orbital TutorialOverlayOrbital {
|
|
|
70
82
|
className: "bg-card text-card-foreground border border-border rounded-lg shadow-lg p-6 max-w-md mx-auto mt-16"
|
|
71
83
|
children: [
|
|
72
84
|
{ type: typography, content: (object/get (array/nth @config.steps @entity.step) title), variant: "h4", weight: "bold" }
|
|
73
|
-
|
|
85
|
+
@config.previewTrait
|
|
74
86
|
{ type: typography, content: (object/get (array/nth @config.steps @entity.step) body), variant: "body" }
|
|
75
87
|
{ type: typography, content: (str/concat (+ @entity.step 1) " / " (array/len @config.steps)), variant: "caption", align: "center" }
|
|
76
88
|
{ type: stack, direction: horizontal, justify: "center", className: "pt-2", children: [
|
|
@@ -80,10 +92,14 @@ orbital TutorialOverlayOrbital {
|
|
|
80
92
|
] }
|
|
81
93
|
]
|
|
82
94
|
})
|
|
95
|
+
(emit TUTORIAL_DEMO_STOP {})
|
|
96
|
+
(when (!= (object/get (array/nth @config.steps @entity.step) demoId "") "")
|
|
97
|
+
(do (emit TUTORIAL_DEMO_START { demoId: (object/get (array/nth @config.steps @entity.step) demoId "") })))
|
|
83
98
|
|
|
84
99
|
TUT_NEXT -> hidden when (>= (+ @entity.step 1) (array/len @config.steps))
|
|
85
100
|
(set @entity.done true)
|
|
86
101
|
(render-ui overlay null)
|
|
102
|
+
(emit TUTORIAL_DEMO_STOP {})
|
|
87
103
|
(emit TUTORIAL_DONE { id: "tutorial" })
|
|
88
104
|
|
|
89
105
|
TUT_BACK -> showing when (> @entity.step 0)
|
|
@@ -94,7 +110,7 @@ orbital TutorialOverlayOrbital {
|
|
|
94
110
|
className: "bg-card text-card-foreground border border-border rounded-lg shadow-lg p-6 max-w-md mx-auto mt-16"
|
|
95
111
|
children: [
|
|
96
112
|
{ type: typography, content: (object/get (array/nth @config.steps @entity.step) title), variant: "h4", weight: "bold" }
|
|
97
|
-
|
|
113
|
+
@config.previewTrait
|
|
98
114
|
{ type: typography, content: (object/get (array/nth @config.steps @entity.step) body), variant: "body" }
|
|
99
115
|
{ type: typography, content: (str/concat (+ @entity.step 1) " / " (array/len @config.steps)), variant: "caption", align: "center" }
|
|
100
116
|
{ type: stack, direction: horizontal, justify: "center", className: "pt-2", children: [
|
|
@@ -104,10 +120,14 @@ orbital TutorialOverlayOrbital {
|
|
|
104
120
|
] }
|
|
105
121
|
]
|
|
106
122
|
})
|
|
123
|
+
(emit TUTORIAL_DEMO_STOP {})
|
|
124
|
+
(when (!= (object/get (array/nth @config.steps @entity.step) demoId "") "")
|
|
125
|
+
(do (emit TUTORIAL_DEMO_START { demoId: (object/get (array/nth @config.steps @entity.step) demoId "") })))
|
|
107
126
|
|
|
108
127
|
TUT_DISMISS -> hidden
|
|
109
128
|
(set @entity.done true)
|
|
110
129
|
(render-ui overlay null)
|
|
130
|
+
(emit TUTORIAL_DEMO_STOP {})
|
|
111
131
|
(emit TUTORIAL_DONE { id: "tutorial" })
|
|
112
132
|
}
|
|
113
133
|
|
|
@@ -142,6 +162,15 @@ orbital TutorialOverlayOrbital {
|
|
|
142
162
|
}
|
|
143
163
|
@description "The tutorial was finished or skipped; boards unpause or log completion."
|
|
144
164
|
@tier "domain"
|
|
165
|
+
TUTORIAL_DEMO_START -> external {
|
|
166
|
+
demoId : string!
|
|
167
|
+
}
|
|
168
|
+
@description "Emitted when a tutorial step carrying a demoId is shown; the composed std-tutorial-autodemo atom plays that scripted demo."
|
|
169
|
+
@tier "domain"
|
|
170
|
+
TUTORIAL_DEMO_STOP -> external {
|
|
171
|
+
}
|
|
172
|
+
@description "Emitted when the tutorial leaves a demo step (next/back) or is dismissed/finished; the autodemo atom stops and releases control."
|
|
173
|
+
@tier "domain"
|
|
145
174
|
}
|
|
146
175
|
|
|
147
176
|
listens {
|
|
@@ -151,7 +180,11 @@ orbital TutorialOverlayOrbital {
|
|
|
151
180
|
config {
|
|
152
181
|
steps : [TutorialStep] = []
|
|
153
182
|
@label "Steps"
|
|
154
|
-
@description "One row per tutorial page: title, one line of body copy, and
|
|
183
|
+
@description "One row per tutorial page: title, one line of body copy, and an optional demoId that plays a scripted live demo (std-tutorial-autodemo) for the mechanic being taught."
|
|
184
|
+
@tier "presentation"
|
|
185
|
+
previewTrait : trait = @trait.TutorialEmptyPreview
|
|
186
|
+
@label "Preview trait"
|
|
187
|
+
@description "Trait rendered in the media position of the modal — the live, demo-driven preview of the mechanic (a bare game canvas, no shell chrome). '@trait.TutorialEmptyPreview' leaves the slot blank. Override with '@trait.<TraitName>' to show a board's live frame."
|
|
155
188
|
@tier "presentation"
|
|
156
189
|
autoShow : boolean = true
|
|
157
190
|
@label "Auto Show"
|
|
@@ -307,15 +307,15 @@ orbital MathCanvasOrbital {
|
|
|
307
307
|
@tier "presentation"
|
|
308
308
|
backgroundColor : string
|
|
309
309
|
@label "Background Color"
|
|
310
|
-
@description "Canvas fill color;
|
|
310
|
+
@description "Canvas fill color; `var(--token, fallback)` strings resolve against the active theme. Default transparent."
|
|
311
311
|
@tier "presentation"
|
|
312
312
|
gridColor : string = "var(--color-border, #9ca3af)"
|
|
313
313
|
@label "Grid Color"
|
|
314
|
-
@description "Grid line color; theme
|
|
314
|
+
@description "Grid line color; resolves theme tokens (default `var(--color-border, #9ca3af)`)."
|
|
315
315
|
@tier "presentation"
|
|
316
316
|
axisColor : string = "var(--color-muted-foreground, #374151)"
|
|
317
317
|
@label "Axis Color"
|
|
318
|
-
@description "Axis line color; theme
|
|
318
|
+
@description "Axis line color; resolves theme tokens (default `var(--color-muted-foreground, #374151)`)."
|
|
319
319
|
@tier "presentation"
|
|
320
320
|
showTickLabels : boolean = false
|
|
321
321
|
@label "Show Tick Labels"
|
|
@@ -945,6 +945,17 @@
|
|
|
945
945
|
"tier": "internal",
|
|
946
946
|
"type": "string"
|
|
947
947
|
},
|
|
948
|
+
"include": {
|
|
949
|
+
"default": [],
|
|
950
|
+
"description": "Entity relation field names to hydrate on fetch (e.g. a `tag : Category` field named `tag`), so grid columns can use dot-paths like tag.name. Empty = no hydration, the default.",
|
|
951
|
+
"items": {
|
|
952
|
+
"type": "string"
|
|
953
|
+
},
|
|
954
|
+
"label": "Which relation fields to hydrate?",
|
|
955
|
+
"synonyms": "relation hydration, populate relations, joined fields, hydrate relations",
|
|
956
|
+
"tier": "internal",
|
|
957
|
+
"type": "[string]"
|
|
958
|
+
},
|
|
948
959
|
"initialFilterField": {
|
|
949
960
|
"default": "",
|
|
950
961
|
"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.",
|
|
@@ -1727,6 +1738,7 @@
|
|
|
1727
1738
|
]
|
|
1728
1739
|
]
|
|
1729
1740
|
],
|
|
1741
|
+
"include": "@config.include",
|
|
1730
1742
|
"limit": "@config.pageSize",
|
|
1731
1743
|
"offset": 0.0
|
|
1732
1744
|
}
|
|
@@ -1888,6 +1900,7 @@
|
|
|
1888
1900
|
]
|
|
1889
1901
|
]
|
|
1890
1902
|
],
|
|
1903
|
+
"include": "@config.include",
|
|
1891
1904
|
"limit": "@config.pageSize",
|
|
1892
1905
|
"offset": 0.0
|
|
1893
1906
|
}
|
|
@@ -1945,6 +1958,7 @@
|
|
|
1945
1958
|
]
|
|
1946
1959
|
]
|
|
1947
1960
|
],
|
|
1961
|
+
"include": "@config.include",
|
|
1948
1962
|
"limit": "@config.pageSize",
|
|
1949
1963
|
"offset": 0.0
|
|
1950
1964
|
}
|
|
@@ -2002,6 +2016,7 @@
|
|
|
2002
2016
|
]
|
|
2003
2017
|
]
|
|
2004
2018
|
],
|
|
2019
|
+
"include": "@config.include",
|
|
2005
2020
|
"limit": "@config.pageSize",
|
|
2006
2021
|
"offset": 0.0
|
|
2007
2022
|
}
|
|
@@ -2039,6 +2054,7 @@
|
|
|
2039
2054
|
"@user.id"
|
|
2040
2055
|
]
|
|
2041
2056
|
],
|
|
2057
|
+
"include": "@config.include",
|
|
2042
2058
|
"limit": "@config.pageSize",
|
|
2043
2059
|
"offset": [
|
|
2044
2060
|
"*",
|
|
@@ -2218,6 +2234,7 @@
|
|
|
2218
2234
|
]
|
|
2219
2235
|
]
|
|
2220
2236
|
],
|
|
2237
|
+
"include": "@config.include",
|
|
2221
2238
|
"limit": "@config.pageSize",
|
|
2222
2239
|
"offset": 0.0
|
|
2223
2240
|
}
|