@almadar/std 16.228.0 → 16.229.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/behaviors-registry.json +97602 -98073
- package/behaviors/lolo/infra/atoms/std-notify-on-event.lolo +2 -2
- package/behaviors/lolo/ui/core/atoms/std-book-reader.lolo +316 -0
- package/behaviors/lolo/ui/core/atoms/std-card-grid.lolo +172 -0
- package/behaviors/lolo/ui/core/atoms/std-hero.lolo +247 -0
- package/behaviors/lolo/ui/core/atoms/std-media-section.lolo +154 -0
- package/behaviors/lolo/ui/core/atoms/std-pricing.lolo +177 -0
- package/behaviors/lolo/ui/core/atoms/std-prose.lolo +85 -0
- package/behaviors/lolo/ui/core/atoms/std-site-footer.lolo +159 -0
- package/behaviors/lolo/ui/core/atoms/std-site-header.lolo +131 -0
- package/behaviors/lolo/ui/core/atoms/std-stat-band.lolo +83 -0
- package/behaviors/lolo/ui/core/atoms/std-stats.lolo +4 -5
- package/behaviors/lolo/ui/core/atoms/std-steps.lolo +124 -0
- package/behaviors/lolo/ui/core/atoms/ui-box.lolo +5 -0
- package/behaviors/lolo/ui/core/atoms/ui-button.lolo +6 -1
- package/behaviors/lolo/ui/core/atoms/ui-image.lolo +64 -0
- package/behaviors/lolo/ui/{marketing/atoms → core/molecules}/ui-animated-counter.lolo +11 -6
- package/behaviors/lolo/ui/core/organisms/ui-chat-bar.lolo +5 -0
- package/behaviors/lolo/ui/game/atoms/ui-canvas-2d.lolo +1 -1
- package/behaviors/lolo-behavior-contracts.json +1 -1
- package/behaviors/registry/factory-signatures.json +1 -1
- package/behaviors/registry/infra/atoms/std-notify-on-event.orb +45 -9
- package/behaviors/registry/ui/core/atoms/std-book-reader.orb +1269 -0
- package/behaviors/registry/ui/core/atoms/std-card-grid.orb +826 -0
- package/behaviors/registry/ui/core/atoms/std-hero.orb +811 -0
- package/behaviors/registry/ui/core/atoms/std-media-section.orb +740 -0
- package/behaviors/registry/ui/core/atoms/std-pricing.orb +751 -0
- package/behaviors/registry/ui/core/atoms/std-prose.orb +264 -0
- package/behaviors/registry/ui/core/atoms/std-site-footer.orb +589 -0
- package/behaviors/registry/ui/core/atoms/std-site-header.orb +530 -0
- package/behaviors/registry/ui/core/atoms/std-stat-band.orb +311 -0
- package/behaviors/registry/ui/core/atoms/std-stats.orb +4 -5
- package/behaviors/registry/ui/core/atoms/std-steps.orb +532 -0
- package/behaviors/registry/ui/{marketing → core}/atoms/ui-animated-graphic.orb +20 -20
- package/behaviors/registry/ui/{marketing → core}/atoms/ui-animated-reveal.orb +20 -20
- package/behaviors/registry/ui/core/atoms/ui-box.orb +7 -0
- package/behaviors/registry/ui/core/atoms/ui-button.orb +9 -1
- package/behaviors/registry/ui/core/atoms/ui-image.orb +231 -0
- package/behaviors/registry/ui/{marketing → core}/atoms/ui-pattern-tile.orb +20 -20
- package/behaviors/registry/ui/{marketing/atoms → core/molecules}/ui-animated-counter.orb +33 -26
- package/behaviors/registry/ui/{marketing/atoms → core/molecules}/ui-feature-card.orb +20 -20
- package/behaviors/registry/ui/{marketing/atoms → core/molecules}/ui-geometric-pattern.orb +20 -20
- package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +7 -0
- package/behaviors/registry/ui/{marketing → core}/templates/ui-auth-layout.orb +20 -20
- package/behaviors/registry/ui/game/atoms/ui-canvas-2d.orb +1 -1
- package/behaviors/signatures.lolo +1070 -2984
- package/canonical-operators.json +3 -3
- package/dist/behaviors/exports-reader.js +3818 -10339
- package/dist/behaviors/functions/index.d.ts +3965 -6984
- package/dist/behaviors/functions/index.js +3786 -10195
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +3819 -10340
- package/dist/behaviors/query.js +3818 -10339
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +77 -237
- package/dist/behaviors-registry.json +97602 -98073
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3821 -10342
- package/dist/knob-embeddings.hash.json +3 -3
- package/dist/knob-embeddings.json +352 -1212
- package/dist/modules/core.js +2 -2
- package/dist/modules/index.js +2 -2
- package/dist/registry/factory-signatures.json +1 -1
- package/dist/registry.js +2 -2
- package/i18n/ar.json +8 -4
- package/i18n/en.json +4 -0
- package/i18n/sl.json +8 -4
- package/package.json +4 -6
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-article.lolo +0 -31
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-cta.lolo +0 -93
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-features.lolo +0 -83
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-footer.lolo +0 -72
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-hero.lolo +0 -131
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-nav.lolo +0 -86
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-pricing.lolo +0 -85
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-showcase.lolo +0 -87
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-split.lolo +0 -50
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-stats.lolo +0 -43
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-steps.lolo +0 -48
- package/behaviors/lolo/ui/marketing/atoms/std-marketing-team.lolo +0 -51
- package/behaviors/lolo/ui/marketing/atoms/ui-article-section.lolo +0 -44
- package/behaviors/lolo/ui/marketing/atoms/ui-case-study-card.lolo +0 -60
- package/behaviors/lolo/ui/marketing/atoms/ui-community-links.lolo +0 -67
- package/behaviors/lolo/ui/marketing/atoms/ui-content-section.lolo +0 -44
- package/behaviors/lolo/ui/marketing/atoms/ui-cta-banner.lolo +0 -68
- package/behaviors/lolo/ui/marketing/atoms/ui-hero-section.lolo +0 -112
- package/behaviors/lolo/ui/marketing/atoms/ui-install-box.lolo +0 -39
- package/behaviors/lolo/ui/marketing/atoms/ui-marketing-footer.lolo +0 -58
- package/behaviors/lolo/ui/marketing/atoms/ui-marketing-stat-card.lolo +0 -45
- package/behaviors/lolo/ui/marketing/atoms/ui-pricing-card.lolo +0 -70
- package/behaviors/lolo/ui/marketing/atoms/ui-pricing-grid.lolo +0 -49
- package/behaviors/lolo/ui/marketing/atoms/ui-pull-quote.lolo +0 -34
- package/behaviors/lolo/ui/marketing/atoms/ui-service-catalog.lolo +0 -40
- package/behaviors/lolo/ui/marketing/atoms/ui-showcase-card.lolo +0 -64
- package/behaviors/lolo/ui/marketing/atoms/ui-split-section.lolo +0 -69
- package/behaviors/lolo/ui/marketing/atoms/ui-stats-grid.lolo +0 -44
- package/behaviors/lolo/ui/marketing/atoms/ui-step-flow.lolo +0 -51
- package/behaviors/lolo/ui/marketing/atoms/ui-tag-cloud.lolo +0 -45
- package/behaviors/lolo/ui/marketing/atoms/ui-team-card.lolo +0 -54
- package/behaviors/lolo/ui/marketing/organisms/ui-book-chapter-view.lolo +0 -63
- package/behaviors/lolo/ui/marketing/organisms/ui-book-cover-page.lolo +0 -54
- package/behaviors/lolo/ui/marketing/organisms/ui-book-nav-bar.lolo +0 -49
- package/behaviors/lolo/ui/marketing/organisms/ui-book-table-of-contents.lolo +0 -70
- package/behaviors/lolo/ui/marketing/organisms/ui-book-viewer.lolo +0 -161
- package/behaviors/lolo/ui/marketing/organisms/ui-case-study-organism.lolo +0 -153
- package/behaviors/lolo/ui/marketing/organisms/ui-feature-grid-organism.lolo +0 -159
- package/behaviors/lolo/ui/marketing/organisms/ui-hero-organism.lolo +0 -162
- package/behaviors/lolo/ui/marketing/organisms/ui-pricing-organism.lolo +0 -155
- package/behaviors/lolo/ui/marketing/organisms/ui-showcase-organism.lolo +0 -164
- package/behaviors/lolo/ui/marketing/organisms/ui-stats-organism.lolo +0 -142
- package/behaviors/lolo/ui/marketing/organisms/ui-step-flow-organism.lolo +0 -165
- package/behaviors/lolo/ui/marketing/organisms/ui-team-organism.lolo +0 -152
- package/behaviors/lolo/ui/marketing/templates/ui-about-page-template.lolo +0 -105
- package/behaviors/lolo/ui/marketing/templates/ui-feature-detail-page-template.lolo +0 -93
- package/behaviors/lolo/ui/marketing/templates/ui-landing-page-template.lolo +0 -144
- package/behaviors/lolo/ui/marketing/templates/ui-pricing-page-template.lolo +0 -89
- package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +0 -121
- package/behaviors/registry/ui/marketing/atoms/std-marketing-cta.orb +0 -360
- package/behaviors/registry/ui/marketing/atoms/std-marketing-features.orb +0 -305
- package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +0 -265
- package/behaviors/registry/ui/marketing/atoms/std-marketing-hero.orb +0 -424
- package/behaviors/registry/ui/marketing/atoms/std-marketing-nav.orb +0 -288
- package/behaviors/registry/ui/marketing/atoms/std-marketing-pricing.orb +0 -366
- package/behaviors/registry/ui/marketing/atoms/std-marketing-showcase.orb +0 -415
- package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +0 -152
- package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +0 -151
- package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +0 -221
- package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +0 -239
- package/behaviors/registry/ui/marketing/atoms/ui-article-section.orb +0 -176
- package/behaviors/registry/ui/marketing/atoms/ui-case-study-card.orb +0 -195
- package/behaviors/registry/ui/marketing/atoms/ui-community-links.orb +0 -254
- package/behaviors/registry/ui/marketing/atoms/ui-content-section.orb +0 -182
- package/behaviors/registry/ui/marketing/atoms/ui-cta-banner.orb +0 -254
- package/behaviors/registry/ui/marketing/atoms/ui-hero-section.orb +0 -345
- package/behaviors/registry/ui/marketing/atoms/ui-install-box.orb +0 -163
- package/behaviors/registry/ui/marketing/atoms/ui-marketing-footer.orb +0 -298
- package/behaviors/registry/ui/marketing/atoms/ui-marketing-stat-card.orb +0 -177
- package/behaviors/registry/ui/marketing/atoms/ui-pricing-card.orb +0 -237
- package/behaviors/registry/ui/marketing/atoms/ui-pricing-grid.orb +0 -313
- package/behaviors/registry/ui/marketing/atoms/ui-pull-quote.orb +0 -156
- package/behaviors/registry/ui/marketing/atoms/ui-service-catalog.orb +0 -205
- package/behaviors/registry/ui/marketing/atoms/ui-showcase-card.orb +0 -221
- package/behaviors/registry/ui/marketing/atoms/ui-split-section.orb +0 -239
- package/behaviors/registry/ui/marketing/atoms/ui-stats-grid.orb +0 -202
- package/behaviors/registry/ui/marketing/atoms/ui-step-flow.orb +0 -236
- package/behaviors/registry/ui/marketing/atoms/ui-tag-cloud.orb +0 -217
- package/behaviors/registry/ui/marketing/atoms/ui-team-card.orb +0 -186
- package/behaviors/registry/ui/marketing/organisms/ui-book-chapter-view.orb +0 -277
- package/behaviors/registry/ui/marketing/organisms/ui-book-cover-page.orb +0 -190
- package/behaviors/registry/ui/marketing/organisms/ui-book-nav-bar.orb +0 -183
- package/behaviors/registry/ui/marketing/organisms/ui-book-table-of-contents.orb +0 -286
- package/behaviors/registry/ui/marketing/organisms/ui-book-viewer.orb +0 -553
- package/behaviors/registry/ui/marketing/organisms/ui-case-study-organism.orb +0 -507
- package/behaviors/registry/ui/marketing/organisms/ui-feature-grid-organism.orb +0 -504
- package/behaviors/registry/ui/marketing/organisms/ui-hero-organism.orb +0 -635
- package/behaviors/registry/ui/marketing/organisms/ui-pricing-organism.orb +0 -539
- package/behaviors/registry/ui/marketing/organisms/ui-showcase-organism.orb +0 -542
- package/behaviors/registry/ui/marketing/organisms/ui-stats-organism.orb +0 -447
- package/behaviors/registry/ui/marketing/organisms/ui-step-flow-organism.orb +0 -505
- package/behaviors/registry/ui/marketing/organisms/ui-team-organism.orb +0 -494
- package/behaviors/registry/ui/marketing/templates/ui-about-page-template.orb +0 -752
- package/behaviors/registry/ui/marketing/templates/ui-feature-detail-page-template.orb +0 -638
- package/behaviors/registry/ui/marketing/templates/ui-landing-page-template.orb +0 -1028
- package/behaviors/registry/ui/marketing/templates/ui-pricing-page-template.orb +0 -603
- /package/behaviors/lolo/ui/{marketing → core}/atoms/ui-animated-graphic.lolo +0 -0
- /package/behaviors/lolo/ui/{marketing → core}/atoms/ui-animated-reveal.lolo +0 -0
- /package/behaviors/lolo/ui/{marketing → core}/atoms/ui-pattern-tile.lolo +0 -0
- /package/behaviors/lolo/ui/{marketing/atoms → core/molecules}/ui-feature-card.lolo +0 -0
- /package/behaviors/lolo/ui/{marketing/atoms → core/molecules}/ui-geometric-pattern.lolo +0 -0
- /package/behaviors/lolo/ui/{marketing → core}/templates/ui-auth-layout.lolo +0 -0
|
@@ -92,7 +92,7 @@ orbital NotifyOnEventOrbital {
|
|
|
92
92
|
recipient: @entity.recipient
|
|
93
93
|
recordedAt: @now
|
|
94
94
|
severity: @entity.severity
|
|
95
|
-
}) (if (and (str/includes @entity.prefQuietHours "-") ["!=", (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)] (if ["<", (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)] (and [">=", (time/hour @now), (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2)] ["<", (time/hour @now), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)]) (or [">=", (time/hour @now), (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2)] ["<", (time/hour @now), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)]))) (persist create NotificationRecord {
|
|
95
|
+
}) (if (and (str/includes @entity.prefQuietHours "-") ["!=", (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)] (if ["<", (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)] (and [">=", (str/padStart (str/concat "" (time/hour @now)) 2 "0"), (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2)] ["<", (str/padStart (str/concat "" (time/hour @now)) 2 "0"), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)]) (or [">=", (str/padStart (str/concat "" (time/hour @now)) 2 "0"), (str/slice (array/first (str/split @entity.prefQuietHours "-")) 0 2)] ["<", (str/padStart (str/concat "" (time/hour @now)) 2 "0"), (str/slice (array/nth (str/split @entity.prefQuietHours "-") 1) 0 2)]))) (persist create NotificationRecord {
|
|
96
96
|
channel: @entity.channel
|
|
97
97
|
dispatched: false
|
|
98
98
|
error: "quiet-hours"
|
|
@@ -427,7 +427,7 @@ orbital NotifyOnEventOrbital {
|
|
|
427
427
|
@description "Signing secret forwarded to the webhook service so the receiving endpoint can verify the payload. Ignored when `webhookUrl` is blank."
|
|
428
428
|
@synonyms "signing secret, hmac secret, webhook signature, shared secret"
|
|
429
429
|
@tier "internal"
|
|
430
|
-
template : string = ""
|
|
430
|
+
template : string = "You have a new notification"
|
|
431
431
|
@label "Message template"
|
|
432
432
|
@description "Text shown to the recipient; supports payload interpolation"
|
|
433
433
|
@synonyms "notification text, message body, alert text"
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
app std-book-reader "1.0.0"
|
|
2
|
+
"std-book-reader — reads a multi-chapter book one chapter at a time. Opens on a cover (cover image, title, subtitle, author, a start button and the table of contents); reading shows a contents rail with the current chapter marked, the chapter title and progress, the chapter text (markdown) and previous/next buttons. Supports right-to-left books. Emits CHAPTER_OPENED on every chapter change. Pick for handbooks, manifestos, course readers and long-form guides."
|
|
3
|
+
type BookChapter = { title : string!, content : string! }
|
|
4
|
+
orbital BookReaderOrbital {
|
|
5
|
+
|
|
6
|
+
entity BookReaderView [runtime] {
|
|
7
|
+
id : string!
|
|
8
|
+
chapterIndex : number = 0
|
|
9
|
+
chapterTitle : string = ""
|
|
10
|
+
chapterContent : string = ""
|
|
11
|
+
progressLabel : string = ""
|
|
12
|
+
isFirst : boolean = true
|
|
13
|
+
isLast : boolean = false
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
trait BookReaderRead -> @rebindable BookReaderView [interaction, instance] {
|
|
17
|
+
initial: cover
|
|
18
|
+
|
|
19
|
+
state cover {
|
|
20
|
+
INIT -> cover
|
|
21
|
+
(render-ui main @config.coverContent)
|
|
22
|
+
START_READING -> reading
|
|
23
|
+
(set @entity.chapterIndex 0)
|
|
24
|
+
(set @entity.chapterTitle (object/get (array/nth @config.chapters 0) title ""))
|
|
25
|
+
(set @entity.chapterContent (object/get (array/nth @config.chapters 0) content ""))
|
|
26
|
+
(set @entity.isFirst true)
|
|
27
|
+
(set @entity.isLast (<= (array/len @config.chapters) 1))
|
|
28
|
+
(set @entity.progressLabel (str/concat "1 / " (array/len @config.chapters)))
|
|
29
|
+
(render-ui main @config.readingContent)
|
|
30
|
+
(emit CHAPTER_OPENED { index: 0, title: @entity.chapterTitle })
|
|
31
|
+
OPEN_CHAPTER -> reading
|
|
32
|
+
(set @entity.chapterIndex ?index)
|
|
33
|
+
(set @entity.chapterTitle (object/get (array/nth @config.chapters ?index) title ""))
|
|
34
|
+
(set @entity.chapterContent (object/get (array/nth @config.chapters ?index) content ""))
|
|
35
|
+
(set @entity.isFirst (== ?index 0))
|
|
36
|
+
(set @entity.isLast (>= ?index (- (array/len @config.chapters) 1)))
|
|
37
|
+
(set @entity.progressLabel (str/concat (+ ?index 1) " / " (array/len @config.chapters)))
|
|
38
|
+
(render-ui main @config.readingContent)
|
|
39
|
+
(emit CHAPTER_OPENED { index: ?index, title: @entity.chapterTitle })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
state reading {
|
|
43
|
+
INIT -> reading
|
|
44
|
+
(render-ui main @config.readingContent)
|
|
45
|
+
OPEN_CHAPTER -> reading
|
|
46
|
+
(set @entity.chapterIndex ?index)
|
|
47
|
+
(set @entity.chapterTitle (object/get (array/nth @config.chapters ?index) title ""))
|
|
48
|
+
(set @entity.chapterContent (object/get (array/nth @config.chapters ?index) content ""))
|
|
49
|
+
(set @entity.isFirst (== ?index 0))
|
|
50
|
+
(set @entity.isLast (>= ?index (- (array/len @config.chapters) 1)))
|
|
51
|
+
(set @entity.progressLabel (str/concat (+ ?index 1) " / " (array/len @config.chapters)))
|
|
52
|
+
(render-ui main @config.readingContent)
|
|
53
|
+
(emit CHAPTER_OPENED { index: ?index, title: @entity.chapterTitle })
|
|
54
|
+
NEXT_CHAPTER -> reading when (not @entity.isLast)
|
|
55
|
+
(set @entity.chapterIndex (+ @entity.chapterIndex 1))
|
|
56
|
+
(set @entity.chapterTitle (object/get (array/nth @config.chapters @entity.chapterIndex) title ""))
|
|
57
|
+
(set @entity.chapterContent (object/get (array/nth @config.chapters @entity.chapterIndex) content ""))
|
|
58
|
+
(set @entity.isFirst false)
|
|
59
|
+
(set @entity.isLast (>= @entity.chapterIndex (- (array/len @config.chapters) 1)))
|
|
60
|
+
(set @entity.progressLabel (str/concat (+ @entity.chapterIndex 1) " / " (array/len @config.chapters)))
|
|
61
|
+
(render-ui main @config.readingContent)
|
|
62
|
+
(emit CHAPTER_OPENED { index: @entity.chapterIndex, title: @entity.chapterTitle })
|
|
63
|
+
PREV_CHAPTER -> reading when (not @entity.isFirst)
|
|
64
|
+
(set @entity.chapterIndex (- @entity.chapterIndex 1))
|
|
65
|
+
(set @entity.chapterTitle (object/get (array/nth @config.chapters @entity.chapterIndex) title ""))
|
|
66
|
+
(set @entity.chapterContent (object/get (array/nth @config.chapters @entity.chapterIndex) content ""))
|
|
67
|
+
(set @entity.isFirst (== @entity.chapterIndex 0))
|
|
68
|
+
(set @entity.isLast false)
|
|
69
|
+
(set @entity.progressLabel (str/concat (+ @entity.chapterIndex 1) " / " (array/len @config.chapters)))
|
|
70
|
+
(render-ui main @config.readingContent)
|
|
71
|
+
(emit CHAPTER_OPENED { index: @entity.chapterIndex, title: @entity.chapterTitle })
|
|
72
|
+
BACK_TO_COVER -> cover
|
|
73
|
+
(render-ui main @config.coverContent)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
emits {
|
|
77
|
+
CHAPTER_OPENED -> external {
|
|
78
|
+
index : number
|
|
79
|
+
title : string
|
|
80
|
+
}
|
|
81
|
+
@description "The reader moved to a chapter; carries its index and title."
|
|
82
|
+
@synonyms "page turned, chapter changed, reading progress"
|
|
83
|
+
@tier "domain"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
listens {
|
|
87
|
+
OPEN_CHAPTER {
|
|
88
|
+
index : number!
|
|
89
|
+
}
|
|
90
|
+
@description "Jump to a chapter from the table of contents."
|
|
91
|
+
@tier "internal"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
config {
|
|
95
|
+
title : string = "Untitled book"
|
|
96
|
+
@label "Title"
|
|
97
|
+
@tier "presentation"
|
|
98
|
+
subtitle : string = ""
|
|
99
|
+
@label "Subtitle"
|
|
100
|
+
@tier "presentation"
|
|
101
|
+
author : string = ""
|
|
102
|
+
@label "Author"
|
|
103
|
+
@tier "presentation"
|
|
104
|
+
coverImage : string = ""
|
|
105
|
+
@label "Cover image"
|
|
106
|
+
@description "Cover image URL; empty hides it"
|
|
107
|
+
@tier "presentation"
|
|
108
|
+
direction : "ltr" | "rtl" = ltr
|
|
109
|
+
@label "Text direction"
|
|
110
|
+
@description "rtl for Arabic, Hebrew and other right-to-left books"
|
|
111
|
+
@synonyms "right to left, arabic book"
|
|
112
|
+
@tier "presentation"
|
|
113
|
+
chapters : [BookChapter] = [{ title: "Chapter one", content: "The first chapter's text, in **markdown**." }, { title: "Chapter two", content: "The second chapter's text." }]
|
|
114
|
+
@label "Chapters"
|
|
115
|
+
@description "Ordered chapters: a title and markdown content each"
|
|
116
|
+
@synonyms "sections, parts, pages, table of contents"
|
|
117
|
+
@tier "presentation"
|
|
118
|
+
startLabel : string = "Start reading"
|
|
119
|
+
@label "Start button label"
|
|
120
|
+
@tier "presentation"
|
|
121
|
+
contentsLabel : string = "Contents"
|
|
122
|
+
@label "Contents heading"
|
|
123
|
+
@tier "presentation"
|
|
124
|
+
previousLabel : string = "Previous"
|
|
125
|
+
@label "Previous button label"
|
|
126
|
+
@tier "presentation"
|
|
127
|
+
nextLabel : string = "Next"
|
|
128
|
+
@label "Next button label"
|
|
129
|
+
@tier "presentation"
|
|
130
|
+
coverLabel : string = "Cover"
|
|
131
|
+
@label "Back-to-cover label"
|
|
132
|
+
@tier "presentation"
|
|
133
|
+
coverContent : render-ui = {
|
|
134
|
+
type: box
|
|
135
|
+
paddingY: "2xl"
|
|
136
|
+
fullWidth: true
|
|
137
|
+
dir: @config.direction
|
|
138
|
+
children: [{
|
|
139
|
+
type: container
|
|
140
|
+
size: md
|
|
141
|
+
maxWidth: md
|
|
142
|
+
padding: lg
|
|
143
|
+
children: [{
|
|
144
|
+
type: stack
|
|
145
|
+
direction: vertical
|
|
146
|
+
gap: xl
|
|
147
|
+
children: [{
|
|
148
|
+
type: stack
|
|
149
|
+
direction: vertical
|
|
150
|
+
gap: md
|
|
151
|
+
align: center
|
|
152
|
+
children: [{
|
|
153
|
+
type: image
|
|
154
|
+
src: @config.coverImage
|
|
155
|
+
alt: @config.title
|
|
156
|
+
rounded: lg
|
|
157
|
+
bordered: true
|
|
158
|
+
loading: eager
|
|
159
|
+
className: "max-w-xs"
|
|
160
|
+
}, {
|
|
161
|
+
type: typography
|
|
162
|
+
content: @config.title
|
|
163
|
+
variant: h1
|
|
164
|
+
weight: bold
|
|
165
|
+
align: center
|
|
166
|
+
className: "tracking-tight text-balance"
|
|
167
|
+
}, {
|
|
168
|
+
type: typography
|
|
169
|
+
content: @config.subtitle
|
|
170
|
+
variant: large
|
|
171
|
+
color: muted
|
|
172
|
+
align: center
|
|
173
|
+
className: (if (== @config.subtitle "") hidden "text-pretty")
|
|
174
|
+
}, {
|
|
175
|
+
type: typography
|
|
176
|
+
content: @config.author
|
|
177
|
+
variant: label
|
|
178
|
+
color: muted
|
|
179
|
+
align: center
|
|
180
|
+
className: (if (== @config.author "") hidden "")
|
|
181
|
+
}, {
|
|
182
|
+
type: button
|
|
183
|
+
label: @config.startLabel
|
|
184
|
+
variant: primary
|
|
185
|
+
size: lg
|
|
186
|
+
action: START_READING
|
|
187
|
+
className: (if (== (array/len @config.chapters) 0) hidden "")
|
|
188
|
+
}]
|
|
189
|
+
}, {
|
|
190
|
+
type: stack
|
|
191
|
+
direction: vertical
|
|
192
|
+
gap: xs
|
|
193
|
+
className: (if (== (array/len @config.chapters) 0) hidden "")
|
|
194
|
+
children: [{
|
|
195
|
+
type: typography
|
|
196
|
+
content: @config.contentsLabel
|
|
197
|
+
variant: label
|
|
198
|
+
weight: semibold
|
|
199
|
+
}, {
|
|
200
|
+
type: stack
|
|
201
|
+
direction: vertical
|
|
202
|
+
gap: none
|
|
203
|
+
align: start
|
|
204
|
+
children: (array/map @config.chapters (fn chapter {
|
|
205
|
+
type: button
|
|
206
|
+
variant: link
|
|
207
|
+
label: (str/concat (+ @index 1) ". " (object/get @chapter title ""))
|
|
208
|
+
action: OPEN_CHAPTER
|
|
209
|
+
actionPayload: { index: @index }
|
|
210
|
+
}))
|
|
211
|
+
}]
|
|
212
|
+
}]
|
|
213
|
+
}]
|
|
214
|
+
}]
|
|
215
|
+
}
|
|
216
|
+
@label "Cover body"
|
|
217
|
+
@tier "internal"
|
|
218
|
+
readingContent : render-ui = {
|
|
219
|
+
type: box
|
|
220
|
+
paddingY: xl
|
|
221
|
+
fullWidth: true
|
|
222
|
+
dir: @config.direction
|
|
223
|
+
children: [{
|
|
224
|
+
type: container
|
|
225
|
+
size: xl
|
|
226
|
+
maxWidth: xl
|
|
227
|
+
padding: lg
|
|
228
|
+
children: [{
|
|
229
|
+
type: split
|
|
230
|
+
ratio: "1:3"
|
|
231
|
+
gap: xl
|
|
232
|
+
children: [{
|
|
233
|
+
type: stack
|
|
234
|
+
direction: vertical
|
|
235
|
+
gap: xs
|
|
236
|
+
align: start
|
|
237
|
+
className: "lg:sticky lg:top-6 self-start"
|
|
238
|
+
children: [{
|
|
239
|
+
type: button
|
|
240
|
+
variant: link
|
|
241
|
+
label: @config.coverLabel
|
|
242
|
+
leftIcon: book-open
|
|
243
|
+
action: BACK_TO_COVER
|
|
244
|
+
}, {
|
|
245
|
+
type: typography
|
|
246
|
+
content: @config.contentsLabel
|
|
247
|
+
variant: label
|
|
248
|
+
weight: semibold
|
|
249
|
+
className: "pt-2"
|
|
250
|
+
}, {
|
|
251
|
+
type: stack
|
|
252
|
+
direction: vertical
|
|
253
|
+
gap: none
|
|
254
|
+
align: start
|
|
255
|
+
children: (array/map @config.chapters (fn chapter {
|
|
256
|
+
type: button
|
|
257
|
+
variant: link
|
|
258
|
+
label: (object/get @chapter title "")
|
|
259
|
+
action: OPEN_CHAPTER
|
|
260
|
+
actionPayload: { index: @index }
|
|
261
|
+
className: (if (== @index @entity.chapterIndex) "text-foreground font-semibold" "")
|
|
262
|
+
}))
|
|
263
|
+
}]
|
|
264
|
+
}, {
|
|
265
|
+
type: stack
|
|
266
|
+
direction: vertical
|
|
267
|
+
gap: lg
|
|
268
|
+
children: [{
|
|
269
|
+
type: typography
|
|
270
|
+
content: @entity.progressLabel
|
|
271
|
+
variant: caption
|
|
272
|
+
color: muted
|
|
273
|
+
}, {
|
|
274
|
+
type: typography
|
|
275
|
+
content: @entity.chapterTitle
|
|
276
|
+
variant: h2
|
|
277
|
+
weight: bold
|
|
278
|
+
className: "tracking-tight"
|
|
279
|
+
}, {
|
|
280
|
+
type: markdown-content
|
|
281
|
+
content: @entity.chapterContent
|
|
282
|
+
direction: @config.direction
|
|
283
|
+
}, {
|
|
284
|
+
type: divider
|
|
285
|
+
}, {
|
|
286
|
+
type: stack
|
|
287
|
+
direction: horizontal
|
|
288
|
+
gap: md
|
|
289
|
+
justify: between
|
|
290
|
+
children: [{
|
|
291
|
+
type: button
|
|
292
|
+
variant: secondary
|
|
293
|
+
label: @config.previousLabel
|
|
294
|
+
leftIcon: (if (== @config.direction rtl) chevron-right chevron-left)
|
|
295
|
+
action: PREV_CHAPTER
|
|
296
|
+
disabled: @entity.isFirst
|
|
297
|
+
}, {
|
|
298
|
+
type: button
|
|
299
|
+
variant: primary
|
|
300
|
+
label: @config.nextLabel
|
|
301
|
+
rightIcon: (if (== @config.direction rtl) chevron-left chevron-right)
|
|
302
|
+
action: NEXT_CHAPTER
|
|
303
|
+
disabled: @entity.isLast
|
|
304
|
+
}]
|
|
305
|
+
}]
|
|
306
|
+
}]
|
|
307
|
+
}]
|
|
308
|
+
}]
|
|
309
|
+
}
|
|
310
|
+
@label "Reading body"
|
|
311
|
+
@tier "internal"
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
page "/book" as BookReaderPage -> BookReaderRead
|
|
316
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
app std-card-grid "1.0.0"
|
|
2
|
+
"std-card-grid — a titled grid of content cards from a config list. Each card can carry an image (screenshots, portfolio, case studies), a portrait (team members), an icon, a badge, a title, a description and a link. `look` picks media cards, centered profile cards, or plain text cards. Pick for showcases, team pages, case studies, service catalogs and testimonials."
|
|
3
|
+
type CardItem = { title : string!, description : string, image : string, imageAlt : string, avatar : string, icon : string, badge : string, meta : string, href : string, linkLabel : string }
|
|
4
|
+
orbital CardGridOrbital {
|
|
5
|
+
|
|
6
|
+
entity CardGridView [runtime] {
|
|
7
|
+
id : string!
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
trait CardGridRender -> @rebindable CardGridView [interaction, instance] {
|
|
11
|
+
initial: idle
|
|
12
|
+
|
|
13
|
+
state idle {
|
|
14
|
+
INIT -> idle
|
|
15
|
+
(render-ui main {
|
|
16
|
+
type: box
|
|
17
|
+
paddingY: xl
|
|
18
|
+
bg: (if (== @config.surface muted) muted transparent)
|
|
19
|
+
fullWidth: true
|
|
20
|
+
children: [{
|
|
21
|
+
type: container
|
|
22
|
+
size: xl
|
|
23
|
+
maxWidth: xl
|
|
24
|
+
padding: lg
|
|
25
|
+
children: [{ type: stack, direction: vertical, gap: xl, children: [{
|
|
26
|
+
type: stack
|
|
27
|
+
direction: vertical
|
|
28
|
+
gap: sm
|
|
29
|
+
align: (if (== @config.alignment center) center start)
|
|
30
|
+
className: (if (== @config.heading "") (if (== @config.lede "") hidden "") "")
|
|
31
|
+
children: [{
|
|
32
|
+
type: typography
|
|
33
|
+
content: @config.heading
|
|
34
|
+
variant: h2
|
|
35
|
+
weight: bold
|
|
36
|
+
align: (if (== @config.alignment center) center left)
|
|
37
|
+
className: (if (== @config.heading "") hidden "tracking-tight text-balance")
|
|
38
|
+
}, {
|
|
39
|
+
type: typography
|
|
40
|
+
content: @config.lede
|
|
41
|
+
variant: large
|
|
42
|
+
color: muted
|
|
43
|
+
align: (if (== @config.alignment center) center left)
|
|
44
|
+
className: (if (== @config.lede "") hidden "max-w-2xl text-pretty")
|
|
45
|
+
}]
|
|
46
|
+
}, {
|
|
47
|
+
type: simple-grid
|
|
48
|
+
cols: (math/min (math/max @config.columns 1) 6)
|
|
49
|
+
gap: lg
|
|
50
|
+
children: (array/map @config.items (fn item {
|
|
51
|
+
type: card
|
|
52
|
+
look: (if (== @config.look media) tile-image-first elevated)
|
|
53
|
+
padding: (if (== @config.look media) none md)
|
|
54
|
+
className: "h-full"
|
|
55
|
+
children: [{
|
|
56
|
+
type: image
|
|
57
|
+
src: (object/get @item image "")
|
|
58
|
+
alt: (object/get @item imageAlt (object/get @item title ""))
|
|
59
|
+
aspect: "16/9"
|
|
60
|
+
rounded: none
|
|
61
|
+
}, {
|
|
62
|
+
type: stack
|
|
63
|
+
direction: vertical
|
|
64
|
+
gap: sm
|
|
65
|
+
align: (if (== @config.look profile) center start)
|
|
66
|
+
className: (if (== @config.look media) "p-5" "")
|
|
67
|
+
children: [{
|
|
68
|
+
type: avatar
|
|
69
|
+
src: (object/get @item avatar "")
|
|
70
|
+
name: (object/get @item title "")
|
|
71
|
+
size: xl
|
|
72
|
+
className: (if (== (object/get @item avatar "") "") hidden "")
|
|
73
|
+
}, {
|
|
74
|
+
type: icon
|
|
75
|
+
name: (object/get @item icon "")
|
|
76
|
+
size: lg
|
|
77
|
+
className: (if (== (object/get @item icon "") "") hidden "text-primary")
|
|
78
|
+
}, {
|
|
79
|
+
type: badge
|
|
80
|
+
label: (object/get @item badge "")
|
|
81
|
+
variant: primary
|
|
82
|
+
}, {
|
|
83
|
+
type: typography
|
|
84
|
+
content: (object/get @item title "")
|
|
85
|
+
variant: h4
|
|
86
|
+
weight: semibold
|
|
87
|
+
align: (if (== @config.look profile) center left)
|
|
88
|
+
}, {
|
|
89
|
+
type: typography
|
|
90
|
+
content: (object/get @item meta "")
|
|
91
|
+
variant: caption
|
|
92
|
+
color: muted
|
|
93
|
+
align: (if (== @config.look profile) center left)
|
|
94
|
+
className: (if (== (object/get @item meta "") "") hidden "")
|
|
95
|
+
}, {
|
|
96
|
+
type: typography
|
|
97
|
+
content: (object/get @item description "")
|
|
98
|
+
variant: body
|
|
99
|
+
color: muted
|
|
100
|
+
align: (if (== @config.look profile) center left)
|
|
101
|
+
className: (if (== (object/get @item description "") "") hidden "text-pretty")
|
|
102
|
+
}, {
|
|
103
|
+
type: button
|
|
104
|
+
label: (object/get @item linkLabel "")
|
|
105
|
+
href: (object/get @item href "")
|
|
106
|
+
variant: link
|
|
107
|
+
rightIcon: arrow-right
|
|
108
|
+
action: CARD_OPEN
|
|
109
|
+
actionPayload: { href: (object/get @item href ""), title: (object/get @item title "") }
|
|
110
|
+
className: (if (== (object/get @item linkLabel "") "") hidden "")
|
|
111
|
+
}]
|
|
112
|
+
}]
|
|
113
|
+
}))
|
|
114
|
+
}] }]
|
|
115
|
+
}]
|
|
116
|
+
})
|
|
117
|
+
CARD_OPEN -> idle
|
|
118
|
+
(emit CARD_OPENED { href: ?href, title: ?title })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
emits {
|
|
122
|
+
CARD_OPENED -> external {
|
|
123
|
+
href : string
|
|
124
|
+
title : string
|
|
125
|
+
}
|
|
126
|
+
@description "A card's link was clicked; carries its href and title."
|
|
127
|
+
@tier "domain"
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
listens {
|
|
131
|
+
CARD_OPEN {
|
|
132
|
+
href : string
|
|
133
|
+
title : string
|
|
134
|
+
}
|
|
135
|
+
@description "Card link click."
|
|
136
|
+
@tier "internal"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
config {
|
|
140
|
+
heading : string = ""
|
|
141
|
+
@label "Heading"
|
|
142
|
+
@description "Section heading above the grid; empty hides it"
|
|
143
|
+
@synonyms "title"
|
|
144
|
+
@tier "presentation"
|
|
145
|
+
lede : string = ""
|
|
146
|
+
@label "Supporting text"
|
|
147
|
+
@description "Text under the heading; empty hides it"
|
|
148
|
+
@tier "presentation"
|
|
149
|
+
alignment : "center" | "start" = center
|
|
150
|
+
@label "Heading alignment"
|
|
151
|
+
@tier "presentation"
|
|
152
|
+
items : [CardItem] = [{ title: "First card", description: "What this card is about." }, { title: "Second card", description: "What this card is about." }, { title: "Third card", description: "What this card is about." }]
|
|
153
|
+
@label "Cards"
|
|
154
|
+
@description "One card per entry: title plus any of image, avatar, icon, badge, meta, description, href + linkLabel"
|
|
155
|
+
@synonyms "items, entries, showcase, portfolio, team members, case studies, services, testimonials"
|
|
156
|
+
@tier "presentation"
|
|
157
|
+
look : "media" | "profile" | "plain" = plain
|
|
158
|
+
@label "Card look"
|
|
159
|
+
@description "media = image-led cards, profile = centered portrait cards, plain = text cards"
|
|
160
|
+
@tier "presentation"
|
|
161
|
+
columns : number = 3
|
|
162
|
+
@label "Max columns"
|
|
163
|
+
@tier "presentation"
|
|
164
|
+
surface : "plain" | "muted" = plain
|
|
165
|
+
@label "Surface"
|
|
166
|
+
@description "Background behind the section"
|
|
167
|
+
@tier "presentation"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
page "/card-grid" as CardGridPage -> CardGridRender
|
|
172
|
+
}
|