@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
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
app std-site-footer "1.0.0"
|
|
2
|
+
"std-site-footer — the footer at the bottom of a public site: brand name and tagline, columns of links, and a bottom row with the copyright line and legal links. Links follow `href` (in-app path, #anchor, or absolute URL) and each click emits FOOTER_LINK_CLICKED. Pick for marketing sites, docs portals and product websites."
|
|
3
|
+
type FooterLink = { label : string!, href : string! }
|
|
4
|
+
type FooterColumn = { title : string!, links : [FooterLink] }
|
|
5
|
+
orbital SiteFooterOrbital {
|
|
6
|
+
|
|
7
|
+
entity SiteFooterView [runtime] {
|
|
8
|
+
id : string!
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
trait SiteFooterRender -> @rebindable SiteFooterView [interaction, instance] {
|
|
12
|
+
initial: idle
|
|
13
|
+
|
|
14
|
+
state idle {
|
|
15
|
+
INIT -> idle
|
|
16
|
+
(render-ui main {
|
|
17
|
+
type: box
|
|
18
|
+
paddingY: xl
|
|
19
|
+
border: true
|
|
20
|
+
fullWidth: true
|
|
21
|
+
className: "border-x-0 border-b-0"
|
|
22
|
+
children: [{
|
|
23
|
+
type: container
|
|
24
|
+
size: xl
|
|
25
|
+
maxWidth: xl
|
|
26
|
+
padding: lg
|
|
27
|
+
children: [{
|
|
28
|
+
type: stack
|
|
29
|
+
direction: vertical
|
|
30
|
+
gap: xl
|
|
31
|
+
children: [{
|
|
32
|
+
type: split
|
|
33
|
+
ratio: "1:2"
|
|
34
|
+
gap: xl
|
|
35
|
+
children: [{
|
|
36
|
+
type: stack
|
|
37
|
+
direction: vertical
|
|
38
|
+
gap: sm
|
|
39
|
+
children: [{
|
|
40
|
+
type: typography
|
|
41
|
+
content: @config.brandName
|
|
42
|
+
variant: h5
|
|
43
|
+
weight: bold
|
|
44
|
+
}, {
|
|
45
|
+
type: typography
|
|
46
|
+
content: @config.tagline
|
|
47
|
+
variant: body2
|
|
48
|
+
color: muted
|
|
49
|
+
className: (if (== @config.tagline "") hidden "max-w-xs text-pretty")
|
|
50
|
+
}]
|
|
51
|
+
}, {
|
|
52
|
+
type: simple-grid
|
|
53
|
+
cols: (math/min (math/max (array/len @config.columns) 1) 4)
|
|
54
|
+
gap: lg
|
|
55
|
+
children: (array/map @config.columns (fn column {
|
|
56
|
+
type: stack
|
|
57
|
+
direction: vertical
|
|
58
|
+
gap: sm
|
|
59
|
+
children: [{
|
|
60
|
+
type: typography
|
|
61
|
+
content: (object/get @column title "")
|
|
62
|
+
variant: label
|
|
63
|
+
weight: semibold
|
|
64
|
+
}, {
|
|
65
|
+
type: stack
|
|
66
|
+
direction: vertical
|
|
67
|
+
gap: xs
|
|
68
|
+
align: start
|
|
69
|
+
children: (array/map (object/get @column links []) (fn entry {
|
|
70
|
+
type: button
|
|
71
|
+
variant: link
|
|
72
|
+
label: (object/get @entry label "")
|
|
73
|
+
href: (object/get @entry href "")
|
|
74
|
+
action: FOOTER_LINK
|
|
75
|
+
actionPayload: { label: (object/get @entry label ""), href: (object/get @entry href "") }
|
|
76
|
+
}))
|
|
77
|
+
}]
|
|
78
|
+
}))
|
|
79
|
+
}]
|
|
80
|
+
}, {
|
|
81
|
+
type: divider
|
|
82
|
+
}, {
|
|
83
|
+
type: stack
|
|
84
|
+
direction: horizontal
|
|
85
|
+
gap: md
|
|
86
|
+
wrap: true
|
|
87
|
+
align: center
|
|
88
|
+
justify: between
|
|
89
|
+
children: [{
|
|
90
|
+
type: typography
|
|
91
|
+
content: @config.copyright
|
|
92
|
+
variant: caption
|
|
93
|
+
color: muted
|
|
94
|
+
}, {
|
|
95
|
+
type: stack
|
|
96
|
+
direction: horizontal
|
|
97
|
+
gap: md
|
|
98
|
+
wrap: true
|
|
99
|
+
children: (array/map @config.legalLinks (fn entry {
|
|
100
|
+
type: button
|
|
101
|
+
variant: link
|
|
102
|
+
label: (object/get @entry label "")
|
|
103
|
+
href: (object/get @entry href "")
|
|
104
|
+
action: FOOTER_LINK
|
|
105
|
+
actionPayload: { label: (object/get @entry label ""), href: (object/get @entry href "") }
|
|
106
|
+
}))
|
|
107
|
+
}]
|
|
108
|
+
}]
|
|
109
|
+
}]
|
|
110
|
+
}]
|
|
111
|
+
})
|
|
112
|
+
FOOTER_LINK -> idle
|
|
113
|
+
(emit FOOTER_LINK_CLICKED { label: ?label, href: ?href })
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
emits {
|
|
117
|
+
FOOTER_LINK_CLICKED -> external {
|
|
118
|
+
label : string
|
|
119
|
+
href : string
|
|
120
|
+
}
|
|
121
|
+
@description "A footer link was clicked; carries its label and href."
|
|
122
|
+
@tier "domain"
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
listens {
|
|
126
|
+
FOOTER_LINK {
|
|
127
|
+
label : string
|
|
128
|
+
href : string
|
|
129
|
+
}
|
|
130
|
+
@description "Footer link click."
|
|
131
|
+
@tier "internal"
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
config {
|
|
135
|
+
brandName : string = "Almadar"
|
|
136
|
+
@label "Brand name"
|
|
137
|
+
@synonyms "company, product name, logo text"
|
|
138
|
+
@tier "presentation"
|
|
139
|
+
tagline : string = ""
|
|
140
|
+
@label "Tagline"
|
|
141
|
+
@description "One line under the brand name; empty hides it"
|
|
142
|
+
@tier "presentation"
|
|
143
|
+
columns : [FooterColumn] = [{ title: "Product", links: [{ label: "Features", href: "/features" }, { label: "Pricing", href: "/pricing" }] }, { title: "Company", links: [{ label: "About", href: "/about" }, { label: "Blog", href: "/blog" }] }]
|
|
144
|
+
@label "Link columns"
|
|
145
|
+
@description "Each column: a title and its links (label + href)"
|
|
146
|
+
@synonyms "sitemap, footer menu, footer navigation"
|
|
147
|
+
@tier "presentation"
|
|
148
|
+
copyright : string = "© Almadar"
|
|
149
|
+
@label "Copyright line"
|
|
150
|
+
@tier "presentation"
|
|
151
|
+
legalLinks : [FooterLink] = []
|
|
152
|
+
@label "Legal links"
|
|
153
|
+
@description "Links in the bottom row, e.g. Privacy and Terms"
|
|
154
|
+
@tier "presentation"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
page "/site-footer" as SiteFooterPage -> SiteFooterRender
|
|
159
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
app std-site-header "1.0.0"
|
|
2
|
+
"std-site-header — the sticky top bar of a public website: brand (logo + name), navigation links with the current page marked, and an optional call-to-action button. On small screens the links fold into a menu opened by a toggle. Links follow `href` (in-app path, #anchor, or absolute URL); the header action and the small-screen menu links also emit NAV_CLICKED { href, label }. Pick for marketing sites, docs portals and product websites; for signed-in app chrome use std-app-layout."
|
|
3
|
+
type SiteNavLink = { label : string!, href : string! }
|
|
4
|
+
orbital SiteHeaderOrbital {
|
|
5
|
+
entity SiteHeaderView [runtime] {
|
|
6
|
+
id : string!
|
|
7
|
+
menuOpen : boolean = false
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
trait SiteHeaderRender -> @rebindable SiteHeaderView [interaction, instance] {
|
|
11
|
+
initial: idle
|
|
12
|
+
|
|
13
|
+
state idle {
|
|
14
|
+
INIT -> idle
|
|
15
|
+
(set @entity.menuOpen false)
|
|
16
|
+
(render-ui main @config.headerContent)
|
|
17
|
+
MENU_TOGGLE -> idle
|
|
18
|
+
(set @entity.menuOpen (not @entity.menuOpen))
|
|
19
|
+
(render-ui main @config.headerContent)
|
|
20
|
+
NAV_LINK -> idle
|
|
21
|
+
(set @entity.menuOpen false)
|
|
22
|
+
(render-ui main @config.headerContent)
|
|
23
|
+
(emit NAV_CLICKED { href: ?href, label: ?label })
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
emits {
|
|
27
|
+
NAV_CLICKED -> external {
|
|
28
|
+
href : string
|
|
29
|
+
label : string
|
|
30
|
+
}
|
|
31
|
+
@description "A navigation link or the header action was clicked; carries its href and label."
|
|
32
|
+
@synonyms "menu click, nav click, header link"
|
|
33
|
+
@tier "domain"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
listens {
|
|
37
|
+
NAV_LINK {
|
|
38
|
+
href : string
|
|
39
|
+
label : string
|
|
40
|
+
}
|
|
41
|
+
@description "Navigation link click."
|
|
42
|
+
@tier "internal"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
config {
|
|
46
|
+
brandName : string = "Almadar"
|
|
47
|
+
@label "Brand name"
|
|
48
|
+
@synonyms "site name, company, logo text"
|
|
49
|
+
@tier "presentation"
|
|
50
|
+
logoSrc : string = ""
|
|
51
|
+
@label "Logo image"
|
|
52
|
+
@description "Logo URL; empty shows the name only"
|
|
53
|
+
@tier "presentation"
|
|
54
|
+
links : [SiteNavLink] = [{ label: "Features", href: "/features" }, { label: "Pricing", href: "/pricing" }, { label: "About", href: "/about" }]
|
|
55
|
+
@label "Navigation links"
|
|
56
|
+
@synonyms "menu, nav items, top navigation"
|
|
57
|
+
@tier "presentation"
|
|
58
|
+
currentPath : string = "/"
|
|
59
|
+
@label "Current page path"
|
|
60
|
+
@description "Marks the matching link as active"
|
|
61
|
+
@tier "presentation"
|
|
62
|
+
actionLabel : string = ""
|
|
63
|
+
@label "Header action label"
|
|
64
|
+
@description "Call-to-action button at the right; empty hides it"
|
|
65
|
+
@synonyms "cta, sign up button, get started"
|
|
66
|
+
@tier "presentation"
|
|
67
|
+
actionHref : string = ""
|
|
68
|
+
@label "Header action link"
|
|
69
|
+
@tier "presentation"
|
|
70
|
+
headerContent : render-ui = {
|
|
71
|
+
type: stack
|
|
72
|
+
direction: vertical
|
|
73
|
+
gap: none
|
|
74
|
+
className: "sticky top-0 z-50"
|
|
75
|
+
children: [{
|
|
76
|
+
type: header
|
|
77
|
+
variant: desktop
|
|
78
|
+
sticky: false
|
|
79
|
+
showMenuToggle: false
|
|
80
|
+
brandName: @config.brandName
|
|
81
|
+
logoSrc: @config.logoSrc
|
|
82
|
+
className: "hidden md:flex"
|
|
83
|
+
navigationItems: (array/map @config.links (fn entry {
|
|
84
|
+
label: (object/get @entry label "")
|
|
85
|
+
href: (object/get @entry href "")
|
|
86
|
+
active: (== (object/get @entry href "") @config.currentPath)
|
|
87
|
+
}))
|
|
88
|
+
actions: {
|
|
89
|
+
type: button
|
|
90
|
+
label: @config.actionLabel
|
|
91
|
+
href: @config.actionHref
|
|
92
|
+
variant: primary
|
|
93
|
+
size: sm
|
|
94
|
+
action: NAV_LINK
|
|
95
|
+
actionPayload: { href: @config.actionHref, label: @config.actionLabel }
|
|
96
|
+
className: (if (== @config.actionLabel "") hidden "")
|
|
97
|
+
}
|
|
98
|
+
}, {
|
|
99
|
+
type: header
|
|
100
|
+
variant: mobile
|
|
101
|
+
sticky: false
|
|
102
|
+
showMenuToggle: true
|
|
103
|
+
isMenuOpen: @entity.menuOpen
|
|
104
|
+
onMenuToggle: MENU_TOGGLE
|
|
105
|
+
brandName: @config.brandName
|
|
106
|
+
logoSrc: @config.logoSrc
|
|
107
|
+
className: "md:hidden"
|
|
108
|
+
}, {
|
|
109
|
+
type: stack
|
|
110
|
+
direction: vertical
|
|
111
|
+
gap: xs
|
|
112
|
+
align: stretch
|
|
113
|
+
className: (if @entity.menuOpen "md:hidden border-b border-border bg-card px-4 py-3" hidden)
|
|
114
|
+
children: (array/map @config.links (fn entry {
|
|
115
|
+
type: button
|
|
116
|
+
variant: (if (== (object/get @entry href "") @config.currentPath) secondary ghost)
|
|
117
|
+
label: (object/get @entry label "")
|
|
118
|
+
href: (object/get @entry href "")
|
|
119
|
+
action: NAV_LINK
|
|
120
|
+
actionPayload: { href: (object/get @entry href ""), label: (object/get @entry label "") }
|
|
121
|
+
className: "justify-start"
|
|
122
|
+
}))
|
|
123
|
+
}]
|
|
124
|
+
}
|
|
125
|
+
@label "Header body"
|
|
126
|
+
@tier "internal"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
page "/site-header" as SiteHeaderPage -> SiteHeaderRender
|
|
131
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
app std-stat-band "1.0.0"
|
|
2
|
+
"std-stat-band — a band of headline figures from a config list: each item a big value (a number or short text such as '99.9%', '3x' or 'Open source') over a short label, centered in a row that wraps on small screens, under an optional heading. Display only — for figures computed from data use std-stats. Pick for 'by the numbers' strips on landing, about and product pages."
|
|
3
|
+
type StatBandItem = { value : string!, label : string! }
|
|
4
|
+
orbital StatBandOrbital {
|
|
5
|
+
|
|
6
|
+
entity StatBandView [runtime] {
|
|
7
|
+
id : string!
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
trait StatBandRender -> @rebindable StatBandView [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: [{
|
|
26
|
+
type: stack
|
|
27
|
+
direction: vertical
|
|
28
|
+
gap: lg
|
|
29
|
+
children: [{
|
|
30
|
+
type: typography
|
|
31
|
+
content: @config.heading
|
|
32
|
+
variant: h3
|
|
33
|
+
weight: bold
|
|
34
|
+
align: center
|
|
35
|
+
className: (if (== @config.heading "") hidden "tracking-tight")
|
|
36
|
+
}, {
|
|
37
|
+
type: simple-grid
|
|
38
|
+
cols: (math/min (math/max (array/len @config.items) 1) 4)
|
|
39
|
+
gap: lg
|
|
40
|
+
children: (array/map @config.items (fn item {
|
|
41
|
+
type: stack
|
|
42
|
+
direction: vertical
|
|
43
|
+
gap: xs
|
|
44
|
+
align: center
|
|
45
|
+
children: [{
|
|
46
|
+
type: typography
|
|
47
|
+
content: (object/get @item value "")
|
|
48
|
+
variant: h2
|
|
49
|
+
weight: bold
|
|
50
|
+
align: center
|
|
51
|
+
className: "tracking-tight text-primary"
|
|
52
|
+
}, {
|
|
53
|
+
type: typography
|
|
54
|
+
content: (object/get @item label "")
|
|
55
|
+
variant: body
|
|
56
|
+
color: muted
|
|
57
|
+
align: center
|
|
58
|
+
}]
|
|
59
|
+
}))
|
|
60
|
+
}]
|
|
61
|
+
}]
|
|
62
|
+
}]
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
config {
|
|
67
|
+
heading : string = ""
|
|
68
|
+
@label "Heading"
|
|
69
|
+
@description "Heading above the figures; empty hides it"
|
|
70
|
+
@tier "presentation"
|
|
71
|
+
items : [StatBandItem] = [{ value: "120+", label: "Building blocks" }, { value: "3", label: "Languages" }, { value: "99.9%", label: "Uptime" }]
|
|
72
|
+
@label "Figures"
|
|
73
|
+
@description "One entry per figure: value (number or short text) and label"
|
|
74
|
+
@synonyms "stats, numbers, metrics, kpis, by the numbers"
|
|
75
|
+
@tier "presentation"
|
|
76
|
+
surface : "plain" | "muted" = plain
|
|
77
|
+
@label "Surface"
|
|
78
|
+
@tier "presentation"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
page "/stat-band" as StatBandPage -> StatBandRender
|
|
83
|
+
}
|
|
@@ -367,11 +367,10 @@ orbital StatsItemOrbital {
|
|
|
367
367
|
type: typography
|
|
368
368
|
variant: caption
|
|
369
369
|
}, {
|
|
370
|
-
className: tabular-nums
|
|
371
|
-
|
|
372
|
-
type:
|
|
373
|
-
|
|
374
|
-
weight: semibold
|
|
370
|
+
className: "text-2xl font-semibold tabular-nums"
|
|
371
|
+
format: @card.format
|
|
372
|
+
type: animated-counter
|
|
373
|
+
value: @card.value
|
|
375
374
|
}, {
|
|
376
375
|
color: muted
|
|
377
376
|
content: @card.suffix
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
app std-steps "1.0.0"
|
|
2
|
+
"std-steps — a numbered 'how it works' sequence from a config list: a numbered marker (or icon), a title and a short description per step, laid out as a row of columns or a vertical list, under an optional heading. Display only — for an interactive stepper use std-step-flow or std-wizard. Pick for onboarding explainers, process overviews and learning paths."
|
|
3
|
+
type StepItem = { title : string!, description : string, icon : string }
|
|
4
|
+
orbital StepsOrbital {
|
|
5
|
+
|
|
6
|
+
entity StepsView [runtime] {
|
|
7
|
+
id : string!
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
trait StepsRender -> @rebindable StepsView [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: (if (== @config.layout vertical) 1 (math/min (math/max (array/len @config.steps) 1) 4))
|
|
49
|
+
gap: lg
|
|
50
|
+
children: (array/map @config.steps (fn step {
|
|
51
|
+
type: stack
|
|
52
|
+
direction: (if (== @config.layout vertical) horizontal vertical)
|
|
53
|
+
gap: md
|
|
54
|
+
align: start
|
|
55
|
+
children: [{
|
|
56
|
+
type: box
|
|
57
|
+
rounded: full
|
|
58
|
+
bg: primary
|
|
59
|
+
className: "flex h-10 w-10 shrink-0 items-center justify-center text-primary-foreground"
|
|
60
|
+
children: [{
|
|
61
|
+
type: typography
|
|
62
|
+
content: (if (== (object/get @step icon "") "") (str/concat "" (+ @index 1)) "")
|
|
63
|
+
variant: label
|
|
64
|
+
weight: bold
|
|
65
|
+
color: inherit
|
|
66
|
+
className: (if (== (object/get @step icon "") "") "" hidden)
|
|
67
|
+
}, {
|
|
68
|
+
type: icon
|
|
69
|
+
name: (object/get @step icon "")
|
|
70
|
+
size: sm
|
|
71
|
+
className: (if (== (object/get @step icon "") "") hidden "")
|
|
72
|
+
}]
|
|
73
|
+
}, {
|
|
74
|
+
type: stack
|
|
75
|
+
direction: vertical
|
|
76
|
+
gap: xs
|
|
77
|
+
children: [{
|
|
78
|
+
type: typography
|
|
79
|
+
content: (object/get @step title "")
|
|
80
|
+
variant: h5
|
|
81
|
+
weight: semibold
|
|
82
|
+
}, {
|
|
83
|
+
type: typography
|
|
84
|
+
content: (object/get @step description "")
|
|
85
|
+
variant: body
|
|
86
|
+
color: muted
|
|
87
|
+
className: (if (== (object/get @step description "") "") hidden "text-pretty")
|
|
88
|
+
}]
|
|
89
|
+
}]
|
|
90
|
+
}))
|
|
91
|
+
}] }]
|
|
92
|
+
}]
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
config {
|
|
97
|
+
heading : string = ""
|
|
98
|
+
@label "Heading"
|
|
99
|
+
@description "Section heading above the steps; empty hides it"
|
|
100
|
+
@synonyms "title"
|
|
101
|
+
@tier "presentation"
|
|
102
|
+
lede : string = ""
|
|
103
|
+
@label "Supporting text"
|
|
104
|
+
@tier "presentation"
|
|
105
|
+
alignment : "center" | "start" = center
|
|
106
|
+
@label "Heading alignment"
|
|
107
|
+
@tier "presentation"
|
|
108
|
+
steps : [StepItem] = [{ title: "Describe it", description: "Say what you want in plain words." }, { title: "Review it", description: "Check the plan before anything is built." }, { title: "Ship it", description: "Publish when it looks right." }]
|
|
109
|
+
@label "Steps"
|
|
110
|
+
@description "One entry per step: title, optional description and icon (an icon replaces the step number)"
|
|
111
|
+
@synonyms "how it works, process, stages, phases, path"
|
|
112
|
+
@tier "presentation"
|
|
113
|
+
layout : "row" | "vertical" = row
|
|
114
|
+
@label "Layout"
|
|
115
|
+
@description "row = side-by-side columns, vertical = a top-to-bottom list"
|
|
116
|
+
@tier "presentation"
|
|
117
|
+
surface : "plain" | "muted" = plain
|
|
118
|
+
@label "Surface"
|
|
119
|
+
@tier "presentation"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
page "/steps" as StepsPage -> StepsRender
|
|
124
|
+
}
|
|
@@ -13,6 +13,7 @@ orbital BoxOrbital {
|
|
|
13
13
|
INIT -> idle
|
|
14
14
|
(render-ui main {
|
|
15
15
|
className: @config.className
|
|
16
|
+
dir: @config.dir
|
|
16
17
|
padding: @config.padding
|
|
17
18
|
paddingX: @config.paddingX
|
|
18
19
|
paddingY: @config.paddingY
|
|
@@ -54,6 +55,10 @@ orbital BoxOrbital {
|
|
|
54
55
|
@label "Class Name"
|
|
55
56
|
@description "Additional CSS classes applied to the root element."
|
|
56
57
|
@tier "presentation"
|
|
58
|
+
dir : string
|
|
59
|
+
@label "Dir"
|
|
60
|
+
@description "Text direction for this subtree: 'ltr', 'rtl' (Arabic/Hebrew content) or 'auto'"
|
|
61
|
+
@tier "presentation"
|
|
57
62
|
padding : "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" = none
|
|
58
63
|
@label "Padding"
|
|
59
64
|
@description "Padding on all sides"
|
|
@@ -40,6 +40,7 @@ orbital ButtonOrbital {
|
|
|
40
40
|
actionPayload: @config.actionPayload
|
|
41
41
|
label: @config.label
|
|
42
42
|
disabled: @config.disabled
|
|
43
|
+
href: @config.href
|
|
43
44
|
type: button
|
|
44
45
|
})
|
|
45
46
|
}
|
|
@@ -55,7 +56,7 @@ orbital ButtonOrbital {
|
|
|
55
56
|
@label "Class Name"
|
|
56
57
|
@description "Additional CSS classes applied to the root element."
|
|
57
58
|
@tier "presentation"
|
|
58
|
-
variant : "primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "default" = primary
|
|
59
|
+
variant : "primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "default" | "link" = primary
|
|
59
60
|
@label "Variant"
|
|
60
61
|
@description "variant prop"
|
|
61
62
|
@tier "presentation"
|
|
@@ -103,6 +104,10 @@ orbital ButtonOrbital {
|
|
|
103
104
|
@label "Disabled"
|
|
104
105
|
@description "Disable the button (greys out, blocks click events)"
|
|
105
106
|
@tier "presentation"
|
|
107
|
+
href : string
|
|
108
|
+
@label "Href"
|
|
109
|
+
@description "Makes the button a link: `#anchor` scrolls, an absolute URL loads, a path navigates in-app"
|
|
110
|
+
@tier "presentation"
|
|
106
111
|
}
|
|
107
112
|
}
|
|
108
113
|
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
app ui-image "1.0.0"
|
|
2
|
+
"Image — UI factory (1:1 with the @almadar/ui image pattern)."
|
|
3
|
+
;; @pattern "image"
|
|
4
|
+
orbital ImageOrbital {
|
|
5
|
+
entity ImageItem [runtime] {
|
|
6
|
+
id : string!
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
trait ImageRender -> @rebindable ImageItem [interaction, instance] {
|
|
10
|
+
initial: idle
|
|
11
|
+
|
|
12
|
+
state idle {
|
|
13
|
+
INIT -> idle
|
|
14
|
+
(render-ui main {
|
|
15
|
+
src: @config.src
|
|
16
|
+
alt: @config.alt
|
|
17
|
+
fit: @config.fit
|
|
18
|
+
aspect: @config.aspect
|
|
19
|
+
rounded: @config.rounded
|
|
20
|
+
bordered: @config.bordered
|
|
21
|
+
loading: @config.loading
|
|
22
|
+
className: @config.className
|
|
23
|
+
type: image
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
config {
|
|
28
|
+
src : asset = "https://almadar-kflow-assets.web.app/shared/ui-roguelike-board/default/units/player.png"
|
|
29
|
+
@label "Src"
|
|
30
|
+
@description "Image source URL"
|
|
31
|
+
@tier "presentation"
|
|
32
|
+
alt : string = ""
|
|
33
|
+
@label "Alt"
|
|
34
|
+
@description "Alternative text; empty string marks the image decorative"
|
|
35
|
+
@tier "presentation"
|
|
36
|
+
fit : "cover" | "contain" | "fill" | "none" = cover
|
|
37
|
+
@label "Fit"
|
|
38
|
+
@description "How the image fills its box"
|
|
39
|
+
@tier "presentation"
|
|
40
|
+
aspect : "auto" | "1/1" | "4/3" | "3/2" | "16/9" | "21/9" = auto
|
|
41
|
+
@label "Aspect"
|
|
42
|
+
@description "Fixed aspect ratio of the box; 'auto' keeps the image's own"
|
|
43
|
+
@tier "presentation"
|
|
44
|
+
rounded : "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "full" = md
|
|
45
|
+
@label "Rounded"
|
|
46
|
+
@description "Corner rounding"
|
|
47
|
+
@tier "presentation"
|
|
48
|
+
bordered : boolean = false
|
|
49
|
+
@label "Bordered"
|
|
50
|
+
@description "Draw a subtle border around the image"
|
|
51
|
+
@tier "presentation"
|
|
52
|
+
loading : "lazy" | "eager" = lazy
|
|
53
|
+
@label "Loading"
|
|
54
|
+
@description "'lazy' defers off-screen images; 'eager' for above-the-fold media"
|
|
55
|
+
@tier "presentation"
|
|
56
|
+
className : string
|
|
57
|
+
@label "Class Name"
|
|
58
|
+
@description "Additional class names"
|
|
59
|
+
@tier "presentation"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
page "/image" as ImagePage -> ImageRender
|
|
64
|
+
}
|
|
@@ -13,6 +13,7 @@ orbital AnimatedCounterOrbital {
|
|
|
13
13
|
INIT -> idle
|
|
14
14
|
(render-ui main {
|
|
15
15
|
value: @config.value
|
|
16
|
+
label: @config.label
|
|
16
17
|
duration: @config.duration
|
|
17
18
|
prefix: @config.prefix
|
|
18
19
|
suffix: @config.suffix
|
|
@@ -25,23 +26,27 @@ orbital AnimatedCounterOrbital {
|
|
|
25
26
|
config {
|
|
26
27
|
value : scalar = ""
|
|
27
28
|
@label "Value"
|
|
28
|
-
@description "
|
|
29
|
+
@description "Target value. Strings may carry display affixes (e.g. '500+', '99.9%', '$1.2M')."
|
|
29
30
|
@tier "presentation"
|
|
30
|
-
|
|
31
|
+
label : string
|
|
32
|
+
@label "Label"
|
|
33
|
+
@description "Label displayed below the number"
|
|
34
|
+
@tier "presentation"
|
|
35
|
+
duration : number = 1500
|
|
31
36
|
@label "Duration"
|
|
32
|
-
@description "Animation duration in
|
|
37
|
+
@description "Animation duration in ms"
|
|
33
38
|
@tier "presentation"
|
|
34
39
|
prefix : string
|
|
35
40
|
@label "Prefix"
|
|
36
|
-
@description "Text
|
|
41
|
+
@description "Text displayed before the number"
|
|
37
42
|
@tier "presentation"
|
|
38
43
|
suffix : string
|
|
39
44
|
@label "Suffix"
|
|
40
|
-
@description "Text
|
|
45
|
+
@description "Text displayed after the number"
|
|
41
46
|
@tier "presentation"
|
|
42
47
|
format : string
|
|
43
48
|
@label "Format"
|
|
44
|
-
@description "
|
|
49
|
+
@description "'number' (locale grouping), 'currency' ($x.xx), 'percent' (rounded %). Unset keeps the value's own decimals."
|
|
45
50
|
@tier "presentation"
|
|
46
51
|
className : string
|
|
47
52
|
@label "Class Name"
|