@almadar/std 16.230.0 → 16.231.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/behaviors/behaviors-registry.json +1080 -78
  2. package/behaviors/lolo/ui/core/atoms/std-language-picker.lolo +52 -0
  3. package/behaviors/lolo/ui/core/atoms/std-site-header.lolo +77 -15
  4. package/behaviors/lolo/ui/core/atoms/std-step-flow.lolo +1 -0
  5. package/behaviors/lolo/ui/core/molecules/ui-header.lolo +1 -0
  6. package/behaviors/lolo/ui/core/molecules/ui-icon-button.lolo +105 -0
  7. package/behaviors/lolo/ui/core/molecules/ui-menu.lolo +1 -0
  8. package/behaviors/lolo/ui/core/molecules/ui-top-nav-item.lolo +53 -0
  9. package/behaviors/lolo/ui/core/organisms/ui-dock-layout.lolo +35 -5
  10. package/behaviors/lolo-behavior-contracts.json +1 -1
  11. package/behaviors/registry/factory-signatures.json +1 -1
  12. package/behaviors/registry/ui/core/atoms/std-language-picker.orb +285 -0
  13. package/behaviors/registry/ui/core/atoms/std-site-header.orb +348 -74
  14. package/behaviors/registry/ui/core/atoms/std-step-flow.orb +2 -1
  15. package/dist/behaviors/exports-reader.js +2413 -2353
  16. package/dist/behaviors/functions/index.d.ts +83 -5
  17. package/dist/behaviors/functions/index.js +2409 -2353
  18. package/dist/behaviors/index.d.ts +1 -1
  19. package/dist/behaviors/index.js +2414 -2354
  20. package/dist/behaviors/query.js +2413 -2353
  21. package/dist/behaviors-embeddings.hash.json +3 -3
  22. package/dist/behaviors-embeddings.json +7 -3
  23. package/dist/behaviors-registry.json +1080 -78
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +2414 -2354
  26. package/dist/knob-embeddings.hash.json +3 -3
  27. package/dist/knob-embeddings.json +29 -1
  28. package/dist/registry/factory-signatures.json +1 -1
  29. package/package.json +2 -2
@@ -0,0 +1,52 @@
1
+ app std-language-picker "1.0.0"
2
+ "std-language-picker — the language switcher of a multilingual site or app: a globe button showing the current language code that opens a menu listing every language in its own name, with the current one ticked. Each entry links to the same page in that language. Routing convention: the default language lives at the root and every other language under a `/<code>/` prefix (`/pricing`, `/ar/pricing`, `/sl/pricing`), so each language has its own stable URL that can be linked from outside and indexed by search engines. Pick for public websites and app chrome that serve more than one language; std-site-header embeds it."
3
+ type SiteLanguage = { code : string!, label : string!, href : string! }
4
+ orbital LanguagePickerOrbital {
5
+ entity LanguagePickerView [runtime] {
6
+ id : string!
7
+ }
8
+
9
+ trait LanguagePickerRender -> @rebindable LanguagePickerView [interaction, instance] {
10
+ initial: idle
11
+
12
+ state idle {
13
+ INIT -> idle
14
+ (render-ui main @config.pickerContent)
15
+ }
16
+
17
+ config {
18
+ languages : [SiteLanguage] = [{ code: "en", label: "English", href: "/" }, { code: "ar", label: "العربية", href: "/ar/" }, { code: "sl", label: "Slovenščina", href: "/sl/" }]
19
+ @label "Languages"
20
+ @description "Every language this page exists in, each named in its own language, with the href of THIS page in that language. The default language's href has no prefix; the others start with /<code>/."
21
+ @synonyms "locales, translations, language list, language switcher, i18n"
22
+ @tier "presentation"
23
+ currentLanguage : string = "en"
24
+ @label "Current language"
25
+ @description "The code of the language this page is in; shown on the button and ticked in the menu"
26
+ @synonyms "locale, active language, page language"
27
+ @tier "presentation"
28
+ pickerContent : render-ui = {
29
+ type: menu
30
+ position: bottom-end
31
+ className: (if (== (array/len @config.languages) 0) hidden "")
32
+ trigger: {
33
+ type: button
34
+ variant: ghost
35
+ size: sm
36
+ icon: globe
37
+ label: (str/upper @config.currentLanguage)
38
+ }
39
+ items: (array/map @config.languages (fn entry {
40
+ id: (object/get @entry code "")
41
+ label: (object/get @entry label "")
42
+ href: (object/get @entry href "")
43
+ icon: (if (== (object/get @entry code "") @config.currentLanguage) check "")
44
+ }))
45
+ }
46
+ @label "Picker body"
47
+ @tier "internal"
48
+ }
49
+ }
50
+
51
+ page "/language-picker" as LanguagePickerPage -> LanguagePickerRender
52
+ }
@@ -1,7 +1,10 @@
1
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! }
2
+ "std-site-header — the sticky top bar of a public website: brand (logo + name), navigation links with the current page marked (a link with children opens a dropdown), an optional language picker (std-language-picker: the same page in each language, default language at the root and the others under /<code>/), and an optional call-to-action button. On small screens the links fold into a menu opened by a toggle, with child links indented under their parent and the call-to-action button at the bottom. 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!, children : [SiteNavLink] }
4
+ type SiteLanguage = { code : string!, label : string!, href : string! }
4
5
  orbital SiteHeaderOrbital {
6
+ uses LanguagePicker from "std/behaviors/std-language-picker"
7
+
5
8
  entity SiteHeaderView [runtime] {
6
9
  id : string!
7
10
  menuOpen : boolean = false
@@ -59,6 +62,16 @@ orbital SiteHeaderOrbital {
59
62
  @label "Current page path"
60
63
  @description "Marks the matching link as active"
61
64
  @tier "presentation"
65
+ languages : [SiteLanguage] = []
66
+ @label "Languages"
67
+ @description "Every language this page exists in, each named in its own language, with the href of THIS page in that language (default language at the root, others under /<code>/). Empty hides the language picker."
68
+ @synonyms "locales, translations, language switcher, i18n"
69
+ @tier "presentation"
70
+ currentLanguage : string = "en"
71
+ @label "Current language"
72
+ @description "The code of the language this page is in"
73
+ @synonyms "locale, active language, page language"
74
+ @tier "presentation"
62
75
  actionLabel : string = ""
63
76
  @label "Header action label"
64
77
  @description "Call-to-action button at the right; empty hides it"
@@ -79,13 +92,18 @@ orbital SiteHeaderOrbital {
79
92
  showMenuToggle: false
80
93
  brandName: @config.brandName
81
94
  logoSrc: @config.logoSrc
82
- className: "hidden md:flex"
95
+ className: "hidden lg:flex"
83
96
  navigationItems: (array/map @config.links (fn entry {
84
97
  label: (object/get @entry label "")
85
98
  href: (object/get @entry href "")
86
99
  active: (== (object/get @entry href "") @config.currentPath)
100
+ children: (array/map (object/get @entry children []) (fn child {
101
+ label: (object/get @child label "")
102
+ href: (object/get @child href "")
103
+ active: (== (object/get @child href "") @config.currentPath)
104
+ }))
87
105
  }))
88
- actions: {
106
+ actions: [@trait.SiteHeaderLanguages, {
89
107
  type: button
90
108
  label: @config.actionLabel
91
109
  href: @config.actionHref
@@ -94,7 +112,7 @@ orbital SiteHeaderOrbital {
94
112
  action: NAV_LINK
95
113
  actionPayload: { href: @config.actionHref, label: @config.actionLabel }
96
114
  className: (if (== @config.actionLabel "") hidden "")
97
- }
115
+ }]
98
116
  }, {
99
117
  type: header
100
118
  variant: mobile
@@ -104,22 +122,59 @@ orbital SiteHeaderOrbital {
104
122
  onMenuToggle: MENU_TOGGLE
105
123
  brandName: @config.brandName
106
124
  logoSrc: @config.logoSrc
107
- className: "md:hidden"
125
+ className: "lg:hidden"
126
+ actions: [@trait.SiteHeaderLanguages]
108
127
  }, {
109
128
  type: stack
110
129
  direction: vertical
111
130
  gap: xs
112
131
  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 {
132
+ className: (if @entity.menuOpen "lg:hidden border-b border-border bg-card px-4 py-3" hidden)
133
+ children: [{
134
+ type: stack
135
+ direction: vertical
136
+ gap: xs
137
+ align: stretch
138
+ children: (array/map @config.links (fn (entry) {
139
+ type: stack
140
+ direction: vertical
141
+ gap: xs
142
+ align: stretch
143
+ children: [{
144
+ type: button
145
+ variant: (if (== (object/get @entry href "") @config.currentPath) secondary ghost)
146
+ label: (object/get @entry label "")
147
+ href: (object/get @entry href "")
148
+ action: NAV_LINK
149
+ actionPayload: { href: (object/get @entry href ""), label: (object/get @entry label "") }
150
+ className: "justify-start"
151
+ }, {
152
+ type: stack
153
+ direction: vertical
154
+ gap: xs
155
+ align: stretch
156
+ className: "ps-6"
157
+ children: (array/map (object/get @entry children []) (fn (child) {
158
+ type: button
159
+ variant: (if (== (object/get @child href "") @config.currentPath) secondary ghost)
160
+ label: (object/get @child label "")
161
+ href: (object/get @child href "")
162
+ action: NAV_LINK
163
+ actionPayload: { href: (object/get @child href ""), label: (object/get @child label "") }
164
+ className: "justify-start"
165
+ }))
166
+ }]
167
+ }))
168
+ }, {
115
169
  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 "")
170
+ label: @config.actionLabel
171
+ href: @config.actionHref
172
+ variant: primary
173
+ size: md
119
174
  action: NAV_LINK
120
- actionPayload: { href: (object/get @entry href ""), label: (object/get @entry label "") }
121
- className: "justify-start"
122
- }))
175
+ actionPayload: { href: @config.actionHref, label: @config.actionLabel }
176
+ className: (if (== @config.actionLabel "") hidden "mt-2 w-full")
177
+ }]
123
178
  }]
124
179
  }
125
180
  @label "Header body"
@@ -127,5 +182,12 @@ orbital SiteHeaderOrbital {
127
182
  }
128
183
  }
129
184
 
130
- page "/site-header" as SiteHeaderPage -> SiteHeaderRender
185
+ trait SiteHeaderLanguages = LanguagePicker.traits.LanguagePickerRender -> SiteHeaderView {
186
+ config {
187
+ languages: @config.languages
188
+ currentLanguage: @config.currentLanguage
189
+ }
190
+ }
191
+
192
+ page "/site-header" as SiteHeaderPage -> SiteHeaderRender, SiteHeaderLanguages
131
193
  }
@@ -530,6 +530,7 @@ orbital StepFlowOrbital {
530
530
  variant: primary
531
531
  }]
532
532
  direction: horizontal
533
+ wrap: true
533
534
  gap: sm
534
535
  type: stack
535
536
  }]
@@ -8,6 +8,7 @@ orbital HeaderOrbital {
8
8
  icon : icon
9
9
  badge : string
10
10
  active : boolean
11
+ children : [HeaderNavigationItemsItem]
11
12
  }
12
13
  type HeaderUserAvatar = {
13
14
  src : asset
@@ -0,0 +1,105 @@
1
+ app ui-icon-button "1.0.0"
2
+ "IconButton — UI factory (1:1 with the @almadar/ui icon-button pattern)."
3
+ ;; @pattern "icon-button"
4
+ orbital IconButtonOrbital {
5
+ type IconButtonIconAsset = {
6
+ url : asset!
7
+ role : string!
8
+ category : string!
9
+ animations : [string]
10
+ style : "pixel" | "vector" | "hd" | "1-bit" | "isometric"
11
+ variant : string
12
+ dimension : "2d" | "3d"
13
+ aspect : "1:1" | "16:9" | "5:7" | "8:1" | "4:1" | "5:3" | "1:2"
14
+ atlas : asset
15
+ sprite : string
16
+ name : string
17
+ thumbnailUrl : string
18
+ }
19
+
20
+ entity IconButtonItem [runtime] {
21
+ id : string!
22
+ }
23
+
24
+ trait IconButtonRender -> @rebindable IconButtonItem [interaction, instance] {
25
+ initial: idle
26
+
27
+ state idle {
28
+ INIT -> idle
29
+ (render-ui main {
30
+ className: @config.className
31
+ variant: @config.variant
32
+ size: @config.size
33
+ isLoading: @config.isLoading
34
+ iconAsset: @config.iconAsset
35
+ action: @config.action
36
+ actionPayload: @config.actionPayload
37
+ disabled: @config.disabled
38
+ href: @config.href
39
+ icon: @config.icon
40
+ label: @config.label
41
+ tooltipPosition: @config.tooltipPosition
42
+ type: icon-button
43
+ })
44
+ }
45
+
46
+ emits {
47
+ @config.action -> external { }
48
+ @description "Declarative event name — emits UI:{action} via eventBus on click"
49
+ @tier "essential"
50
+ }
51
+
52
+ config {
53
+ className : string
54
+ @label "Class Name"
55
+ @description "Additional CSS classes applied to the root element."
56
+ @tier "presentation"
57
+ variant : "primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "default" | "link" = ghost
58
+ @label "Variant"
59
+ @description "variant prop"
60
+ @tier "presentation"
61
+ size : "sm" | "md" | "lg" = sm
62
+ @label "Size"
63
+ @description "size prop"
64
+ @tier "presentation"
65
+ isLoading : boolean
66
+ @label "Is Loading"
67
+ @description "isLoading prop"
68
+ @tier "presentation"
69
+ iconAsset : IconButtonIconAsset
70
+ @label "Icon Asset"
71
+ @description "Asset image rendered as the leading icon; takes precedence over icon/leftIcon when provided."
72
+ @tier "presentation"
73
+ action : event = "ACTION"
74
+ @label "Action"
75
+ @description "Declarative event name — emits UI:{action} via eventBus on click"
76
+ @tier "presentation"
77
+ actionPayload : @payload @config.action
78
+ @label "Action Payload"
79
+ @description "Payload to include with the action event"
80
+ @tier "presentation"
81
+ disabled : boolean
82
+ @label "Disabled"
83
+ @description "Disable the button (greys out, blocks click events)"
84
+ @tier "presentation"
85
+ href : string
86
+ @label "Href"
87
+ @description "Makes the button a link: `#anchor` scrolls, an absolute URL loads, a path navigates in-app"
88
+ @tier "presentation"
89
+ icon : icon = "circle"
90
+ @label "Icon"
91
+ @description "icon prop"
92
+ @tier "presentation"
93
+ label : string = ""
94
+ @label "Label"
95
+ @description "What the button does — its accessible name and its tooltip."
96
+ @tier "presentation"
97
+ tooltipPosition : "top" | "bottom" | "left" | "right" = right
98
+ @label "Tooltip Position"
99
+ @description "Where the tooltip opens."
100
+ @tier "presentation"
101
+ }
102
+ }
103
+
104
+ page "/icon-button" as IconButtonPage -> IconButtonRender
105
+ }
@@ -10,6 +10,7 @@ orbital MenuOrbital {
10
10
  disabled : boolean
11
11
  title : string
12
12
  event : event
13
+ href : string
13
14
  url : string
14
15
  variant : "default" | "danger"
15
16
  subMenu : [MenuItemsItem]
@@ -0,0 +1,53 @@
1
+ app ui-top-nav-item "1.0.0"
2
+ "TopNavItem — UI factory (1:1 with the @almadar/ui top-nav-item pattern)."
3
+ ;; @pattern "top-nav-item"
4
+ orbital TopNavItemOrbital {
5
+ type TopNavItemItem = {
6
+ label : string!
7
+ href : string
8
+ icon : icon
9
+ badge : string
10
+ active : boolean
11
+ children : [TopNavItemItem]
12
+ }
13
+
14
+ entity TopNavItemItem [runtime] {
15
+ id : string!
16
+ }
17
+
18
+ trait TopNavItemRender -> @rebindable TopNavItemItem [interaction, instance] {
19
+ initial: idle
20
+
21
+ state idle {
22
+ INIT -> idle
23
+ (render-ui main {
24
+ item: @config.item
25
+ activeHref: @config.activeHref
26
+ tone: @config.tone
27
+ className: @config.className
28
+ type: top-nav-item
29
+ })
30
+ }
31
+
32
+ config {
33
+ item : TopNavItemItem = { label: "Label", href: "Href", icon: "circle", badge: "Badge", active: false, children: [] }
34
+ @label "Item"
35
+ @description "item prop"
36
+ @tier "presentation"
37
+ activeHref : string
38
+ @label "Active Href"
39
+ @description "The href of the active page, used to mark the item (or its parent) active."
40
+ @tier "presentation"
41
+ tone : "solid" | "soft" = solid
42
+ @label "Tone"
43
+ @description "Active styling: `solid` fills with the primary colour (dashboard top bar); `soft` tints it (site header)."
44
+ @tier "presentation"
45
+ className : string
46
+ @label "Class Name"
47
+ @description "className prop"
48
+ @tier "presentation"
49
+ }
50
+ }
51
+
52
+ page "/top-nav-item" as TopNavItemPage -> TopNavItemRender
53
+ }
@@ -32,6 +32,12 @@ orbital DockLayoutOrbital {
32
32
  bottomPanelMinSize: @config.bottomPanelMinSize
33
33
  secondarySidebarCollapsed: @config.secondarySidebarCollapsed
34
34
  onSecondarySidebarCollapsedChange: @config.onSecondarySidebarCollapsedChange
35
+ compact: @config.compact
36
+ secondarySidebarLabel: @config.secondarySidebarLabel
37
+ secondarySidebarIcon: @config.secondarySidebarIcon
38
+ bottomPanelLabel: @config.bottomPanelLabel
39
+ bottomPanelIcon: @config.bottomPanelIcon
40
+ topBarActions: @config.topBarActions
35
41
  className: @config.className
36
42
  railClassName: @config.railClassName
37
43
  sidebarClassName: @config.sidebarClassName
@@ -96,15 +102,15 @@ orbital DockLayoutOrbital {
96
102
  @label "Secondary Sidebar"
97
103
  @description "Collapsible right sidebar."
98
104
  @tier "presentation"
99
- railWidth : number = 56
105
+ railWidth : number
100
106
  @label "Rail Width"
101
- @description "Width of `rail` in pixels. @default 56"
107
+ @description "Width of `rail` in pixels; the rail sizes the column itself when omitted."
102
108
  @tier "presentation"
103
109
  secondarySidebarWidth : number = 280
104
110
  @label "Secondary Sidebar Width"
105
111
  @description "Width of `secondarySidebar` in pixels (fixed — not resizable). @default 280"
106
112
  @tier "presentation"
107
- sidebarCollapsed : boolean = false
113
+ sidebarCollapsed : boolean
108
114
  @label "Sidebar Collapsed"
109
115
  @description "Whether `sidebar` is collapsed. @default false"
110
116
  @tier "presentation"
@@ -124,7 +130,7 @@ orbital DockLayoutOrbital {
124
130
  @label "Sidebar Min Size"
125
131
  @description "Minimum sidebar size in pixels, forwarded to SplitPane's `minSize`. @default 160"
126
132
  @tier "presentation"
127
- bottomPanelCollapsed : boolean = false
133
+ bottomPanelCollapsed : boolean
128
134
  @label "Bottom Panel Collapsed"
129
135
  @description "Whether `bottomPanel` is collapsed. @default false"
130
136
  @tier "presentation"
@@ -144,7 +150,7 @@ orbital DockLayoutOrbital {
144
150
  @label "Bottom Panel Min Size"
145
151
  @description "Minimum bottom panel size in pixels, forwarded to SplitPane's `minSize`. @default 120"
146
152
  @tier "presentation"
147
- secondarySidebarCollapsed : boolean = false
153
+ secondarySidebarCollapsed : boolean
148
154
  @label "Secondary Sidebar Collapsed"
149
155
  @description "Whether `secondarySidebar` is collapsed. @default false"
150
156
  @tier "presentation"
@@ -152,6 +158,30 @@ orbital DockLayoutOrbital {
152
158
  @label "On Secondary Sidebar Collapsed Change"
153
159
  @description "onSecondarySidebarCollapsedChange prop"
154
160
  @tier "presentation"
161
+ compact : boolean
162
+ @label "Compact"
163
+ @description "The mobile variant; decided by the viewport (narrower than 1024px) when omitted."
164
+ @tier "presentation"
165
+ secondarySidebarLabel : string
166
+ @label "Secondary Sidebar Label"
167
+ @description "Compact: the top-bar button that opens `secondarySidebar` (e.g. 'Inspector', 'Chat')."
168
+ @tier "presentation"
169
+ secondarySidebarIcon : icon
170
+ @label "Secondary Sidebar Icon"
171
+ @description "secondarySidebarIcon prop"
172
+ @tier "presentation"
173
+ bottomPanelLabel : string
174
+ @label "Bottom Panel Label"
175
+ @description "Compact: the top-bar button that opens `bottomPanel`."
176
+ @tier "presentation"
177
+ bottomPanelIcon : icon
178
+ @label "Bottom Panel Icon"
179
+ @description "bottomPanelIcon prop"
180
+ @tier "presentation"
181
+ topBarActions : node
182
+ @label "Top Bar Actions"
183
+ @description "Compact: the host's own actions at the end of the top bar (e.g. Run)."
184
+ @tier "presentation"
155
185
  className : string
156
186
  @label "Class Name"
157
187
  @description "Additional CSS classes on the root frame."