@ziyarago/ui 0.17.0 → 0.18.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/CHANGELOG.md +6 -0
- package/dist/llms-full.txt +6 -3
- package/dist/llms.txt +1 -1
- package/dist/manifest.json +20 -5
- package/dist/style.css +7 -1
- package/package.json +1 -1
- package/src/core/components.js +50 -1
- package/src/i18n/components/TopNav.js +3 -3
- package/src/icons/builtin.js +6 -0
- package/src/meta/navigation.js +5 -3
- package/src/styles/components.css +1 -1
- package/src/styles/components8.css +6 -0
- package/types/react.d.ts +14 -3
- package/types/vue.d.ts +14 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [0.18.0](https://github.com/ziyarago/ui/compare/v0.17.0...v0.18.0) (2026-10-21)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* TopNav sub-menus with icons and overflow into a More menu, no edge fade ([ed1addd](https://github.com/ziyarago/ui/commit/ed1addd0d9a9844b4e6e23bbe86b18a5a01a74be))
|
|
6
|
+
|
|
1
7
|
## [0.17.0](https://github.com/ziyarago/ui/compare/v0.16.0...v0.17.0) (2026-10-21)
|
|
2
8
|
|
|
3
9
|
### Features
|
package/dist/llms-full.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> ZiyaraGo UI — glass design system for Umrah and Hajj products. OKLCH tokens, two palettes, dark and light, RTL, Thmanyah. One framework-neutral core with Vue 3, Nuxt and React adapters, 102 free components and 6 page templates (more in @ziyarago/ui-pro).
|
|
4
4
|
|
|
5
|
-
Version 0.
|
|
5
|
+
Version 0.18.0. Docs: https://ziyara.vip . Manifest (machine readable): https://ziyara.vip/manifest.json
|
|
6
6
|
|
|
7
7
|
## Setup
|
|
8
8
|
- import { UiButton } from '@ziyarago/ui/vue'
|
|
@@ -1828,16 +1828,19 @@ Notes:
|
|
|
1828
1828
|
Horizontal app header with a brand area, navigation items and an actions area.
|
|
1829
1829
|
Props:
|
|
1830
1830
|
- `brand`: string | VNode. Logo or product name on the left.
|
|
1831
|
-
- `items`: { value: string; label: string; icon?: string; count?: string | number }[] = "[]". Navigation entries. count renders a small counter after the label.
|
|
1831
|
+
- `items`: { value: string; label: string; icon?: string; count?: string | number; children?: ({ value: string; label: string; icon?: string; count?: string | number; disabled?: boolean } | { heading: string } | { separator: true })[] }[] = "[]". Navigation entries. count renders a small counter after the label. An entry with children becomes a drop-down: click or ArrowDown opens a menu of its children (each with an optional icon and count, headings and separators allowed); selecting one calls change with the child value. The entry is marked current when one of its children is.
|
|
1832
1832
|
- `value`: string. Value of the active item (aria-current="page").
|
|
1833
|
+
- `overflow`: 'menu' | 'none' = "menu". 'menu': entries that do not fit move into a trailing "More" drop-down (measured after render and on resize; server rendering shows all entries). 'none': no collapsing, the row scrolls sideways and sub-menus are clipped, so avoid children with it.
|
|
1834
|
+
- `moreLabel`: string = "More". Accessible name of the overflow drop-down button.
|
|
1833
1835
|
- `size`: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = "md". Scale of header padding, item height and text.
|
|
1834
1836
|
Slots:
|
|
1835
1837
|
- actions: Right side of the header (buttons, avatar). React also accepts an actions prop.
|
|
1836
1838
|
Events:
|
|
1837
|
-
- change: Called with the value of the clicked item.
|
|
1839
|
+
- change: Called with the value of the clicked item or sub-menu item.
|
|
1838
1840
|
Notes:
|
|
1839
1841
|
- Controlled: update value yourself in the change handler.
|
|
1840
1842
|
- Items use count; SubNav uses badge for the same purpose.
|
|
1843
|
+
- Entries with children and the More menu share the Dropdown keyboard behaviour: ArrowDown opens, arrows and Home/End move, Escape closes and returns focus to the button.
|
|
1841
1844
|
|
|
1842
1845
|
## UiSideNav (navigation)
|
|
1843
1846
|
Vertical sidebar with a brand, grouped navigation items, a footer and an optional collapse toggle.
|
package/dist/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> ZiyaraGo UI — glass design system for Umrah and Hajj products. OKLCH tokens, two palettes, dark and light, RTL, Thmanyah. One framework-neutral core with Vue 3, Nuxt and React adapters, 102 free components and 6 page templates (more in @ziyarago/ui-pro).
|
|
4
4
|
|
|
5
|
-
Version 0.
|
|
5
|
+
Version 0.18.0. Docs: https://ziyara.vip . Manifest (machine readable): https://ziyara.vip/manifest.json
|
|
6
6
|
|
|
7
7
|
## Setup
|
|
8
8
|
- import { UiButton } from '@ziyarago/ui/vue'
|
package/dist/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziyarago/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"homepage": "https://ziyara.vip",
|
|
5
5
|
"imports": {
|
|
6
6
|
"vue": "import { UiButton } from '@ziyarago/ui/vue'",
|
|
@@ -12173,14 +12173,28 @@
|
|
|
12173
12173
|
"description": "Logo or product name on the left."
|
|
12174
12174
|
},
|
|
12175
12175
|
"items": {
|
|
12176
|
-
"type": "{ value: string; label: string; icon?: string; count?: string | number }[]",
|
|
12176
|
+
"type": "{ value: string; label: string; icon?: string; count?: string | number; children?: ({ value: string; label: string; icon?: string; count?: string | number; disabled?: boolean } | { heading: string } | { separator: true })[] }[]",
|
|
12177
12177
|
"default": "[]",
|
|
12178
|
-
"description": "Navigation entries. count renders a small counter after the label."
|
|
12178
|
+
"description": "Navigation entries. count renders a small counter after the label. An entry with children becomes a drop-down: click or ArrowDown opens a menu of its children (each with an optional icon and count, headings and separators allowed); selecting one calls change with the child value. The entry is marked current when one of its children is."
|
|
12179
12179
|
},
|
|
12180
12180
|
"value": {
|
|
12181
12181
|
"type": "string",
|
|
12182
12182
|
"description": "Value of the active item (aria-current=\"page\")."
|
|
12183
12183
|
},
|
|
12184
|
+
"overflow": {
|
|
12185
|
+
"type": "'menu' | 'none'",
|
|
12186
|
+
"values": [
|
|
12187
|
+
"menu",
|
|
12188
|
+
"none"
|
|
12189
|
+
],
|
|
12190
|
+
"default": "menu",
|
|
12191
|
+
"description": "'menu': entries that do not fit move into a trailing \"More\" drop-down (measured after render and on resize; server rendering shows all entries). 'none': no collapsing, the row scrolls sideways and sub-menus are clipped, so avoid children with it."
|
|
12192
|
+
},
|
|
12193
|
+
"moreLabel": {
|
|
12194
|
+
"type": "string",
|
|
12195
|
+
"default": "More",
|
|
12196
|
+
"description": "Accessible name of the overflow drop-down button."
|
|
12197
|
+
},
|
|
12184
12198
|
"size": {
|
|
12185
12199
|
"type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'",
|
|
12186
12200
|
"values": [
|
|
@@ -12198,11 +12212,12 @@
|
|
|
12198
12212
|
"actions": "Right side of the header (buttons, avatar). React also accepts an actions prop."
|
|
12199
12213
|
},
|
|
12200
12214
|
"events": {
|
|
12201
|
-
"change": "Called with the value of the clicked item."
|
|
12215
|
+
"change": "Called with the value of the clicked item or sub-menu item."
|
|
12202
12216
|
},
|
|
12203
12217
|
"notes": [
|
|
12204
12218
|
"Controlled: update value yourself in the change handler.",
|
|
12205
|
-
"Items use count; SubNav uses badge for the same purpose."
|
|
12219
|
+
"Items use count; SubNav uses badge for the same purpose.",
|
|
12220
|
+
"Entries with children and the More menu share the Dropdown keyboard behaviour: ArrowDown opens, arrows and Home/End move, Escape closes and returns focus to the button."
|
|
12206
12221
|
]
|
|
12207
12222
|
},
|
|
12208
12223
|
{
|
package/dist/style.css
CHANGED
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
.zg-call{display:grid;grid-template-columns:36px minmax(0,1fr) auto;gap:12px;align-items:center;padding:10px 12px;border-radius:18px;background:var(--zg-s2)}
|
|
249
249
|
@media(prefers-reduced-motion:reduce){.zg-root *{animation-duration:.01ms!important;transition-duration:.01ms!important}}
|
|
250
250
|
|
|
251
|
-
.zg-topnav__items
|
|
251
|
+
.zg-topnav__items .zg-navitem{padding-inline:12px}
|
|
252
252
|
|
|
253
253
|
|
|
254
254
|
/* ./components2.css */
|
|
@@ -577,6 +577,12 @@
|
|
|
577
577
|
.zg-tip--left:hover::before,.zg-tip--right:hover::before{top:0;bottom:0;height:auto;width:10px}
|
|
578
578
|
.zg-tip--left:hover::before{left:auto;right:100%}.zg-tip--right:hover::before{right:auto;left:100%}
|
|
579
579
|
.zg-tip[data-tip-off]::after{opacity:0!important;pointer-events:none!important}.zg-tip[data-tip-off]::before{display:none}
|
|
580
|
+
/* TopNav: no edge fade; items that do not fit move into a "More" menu, sub-menus open under their item */
|
|
581
|
+
.zg-topnav__items{overflow:visible;flex-wrap:nowrap}.zg-topnav__items[data-overflow="none"]{overflow-x:auto}
|
|
582
|
+
.zg-topnav__dd{display:flex}.zg-topnav__dd>.zg-navitem{height:100%}.zg-topnav__dd .zg-menu{top:calc(100% + 10px);min-width:220px}
|
|
583
|
+
.zg-topnav__dd>.zg-navitem[aria-expanded="true"] .zg-icon:last-child:not(:first-child){transform:rotate(180deg)}
|
|
584
|
+
.zg-menu__i[aria-current="page"]{background:var(--zg-s2);font-weight:700}.zg-menu__i .zg-navitem__count{margin-inline-start:auto}
|
|
585
|
+
.zg-menu__h{padding:8px 12px 4px;font:600 12px var(--zg-font);letter-spacing:.06em;text-transform:uppercase;color:var(--zg-text-3)}
|
|
580
586
|
|
|
581
587
|
|
|
582
588
|
/* ./charts.css */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziyarago/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "ZiyaraGo UI — glass design system for Umrah and Hajj products. OKLCH tokens, two palettes, dark and light, RTL, Thmanyah. One framework-neutral core with Vue 3, Nuxt and React adapters, 102 free components and 6 page templates (more in @ziyarago/ui-pro).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui",
|
package/src/core/components.js
CHANGED
|
@@ -59,6 +59,33 @@ const fmt = {
|
|
|
59
59
|
sar: n => (n == null || Number.isNaN(n)) ? '—' : 'SAR\u00a0' + String(Math.round(n)).replace(/\B(?=(\d{3})+(?!\d))/g, '\u2009'),
|
|
60
60
|
dur: (s, u) => { if (s == null || Number.isNaN(+s)) return '—'; s = Math.max(0, Math.round(+s)); const m = Math.floor(s / 60), r = s % 60; return `${m} ${(u && u.m) || 'm'} ${String(r).padStart(2, '0')} ${(u && u.s) || 's'}`; },
|
|
61
61
|
};
|
|
62
|
+
// TopNav overflow: items that do not fit move into a trailing "More" menu. Measured in the browser after render (ResizeObserver on the header);
|
|
63
|
+
// item widths are cached from the render where every item is visible, so hidden items need no measuring. SSR renders every item.
|
|
64
|
+
const tn = new WeakMap();
|
|
65
|
+
const tnMeasure = (el, ctx) => {
|
|
66
|
+
if (!el || !ctx.collapse || typeof ResizeObserver === 'undefined') return;
|
|
67
|
+
let r = tn.get(el);
|
|
68
|
+
if (!r) { r = { w: {}, sig: '' }; r.ro = new ResizeObserver(() => r.run()); tn.set(el, r); if (el.parentElement) r.ro.observe(el.parentElement); }
|
|
69
|
+
r.ctx = ctx;
|
|
70
|
+
r.run = () => {
|
|
71
|
+
const { items, more, set, state } = r.ctx, kids = [...el.children], header = el.parentElement;
|
|
72
|
+
if (!header || !items.length) return;
|
|
73
|
+
const sig = items.map(i => i.value).join('|');
|
|
74
|
+
if (sig !== r.sig) { r.sig = sig; r.w = {}; }
|
|
75
|
+
const n = items.length, shownN = kids.length - (more ? 1 : 0);
|
|
76
|
+
for (let i = 0; i < shownN; i++) r.w[items[i].value] = kids[i].offsetWidth;
|
|
77
|
+
if (more) r.w.__more = kids[kids.length - 1].offsetWidth;
|
|
78
|
+
if (items.some(i => r.w[i.value] == null)) { if (state.fit != null) set({ fit: null }); return; }
|
|
79
|
+
const hs = getComputedStyle(header), es = getComputedStyle(el), bar = header.querySelector('.zg-topnav__brand'), act = header.querySelector('.zg-topnav__actions');
|
|
80
|
+
const gap = parseFloat(hs.columnGap) || 0, ig = parseFloat(es.columnGap) || 0;
|
|
81
|
+
const avail = header.clientWidth - parseFloat(hs.paddingLeft) - parseFloat(hs.paddingRight) - (bar ? bar.offsetWidth : 0) - (act ? act.offsetWidth : 0) - 2 * gap - parseFloat(es.paddingLeft) - parseFloat(es.paddingRight);
|
|
82
|
+
const total = items.reduce((a, i) => a + r.w[i.value], 0) + ig * (n - 1);
|
|
83
|
+
let want = n;
|
|
84
|
+
if (total > avail) { let acc = r.w.__more || 56, k = 0; for (const i of items) { const need = r.w[i.value] + ig; if (acc + need <= avail) { acc += need; k++; } else break; } want = k; }
|
|
85
|
+
if (want !== (state.fit == null ? n : state.fit)) set({ fit: want >= n ? null : want });
|
|
86
|
+
};
|
|
87
|
+
r.run();
|
|
88
|
+
};
|
|
62
89
|
const nav = (h, it, cur, onChange, collapsed) => h('button', { key: it.value, class: 'zg-navitem', 'aria-current': it.value === cur ? 'page' : undefined, title: collapsed ? it.label : undefined, onClick: () => onChange && onChange(it.value) },
|
|
63
90
|
it.icon ? icon(h, it.icon, 18) : null, h('span', null, it.label), it.count ? h('span', { class: 'zg-navitem__count' }, it.count) : null);
|
|
64
91
|
|
|
@@ -116,7 +143,29 @@ export const components = {
|
|
|
116
143
|
return h('div', { class: 'zg-table-wrap', tabIndex: 0 }, h('table', { class: 'zg-table' }, h('thead', null, h('tr', null, p.onSelect ? h('th', { style: { width: '44px' } }, h('button', { type: 'button', role: 'checkbox', class: 'zg-check', 'aria-checked': String(!!all), 'aria-label': (p.labels && p.labels.selectAll) || t('DataTable', 'selectAll'), onClick: () => p.onSelect(all ? [] : rows.map(r => r.id)) }, h('span', { class: 'zg-check__box' }, all ? icon(h, 'check', 14) : null))) : null, ...cols.map(th))),
|
|
117
144
|
h('tbody', null, ...(rows.length ? rows.map((r, ri) => h('tr', { key: r.id, 'aria-selected': sel.includes(r.id) ? 'true' : undefined, class: p.onRowClick ? 'zg-tr--click' : undefined, onClick: p.onRowClick ? () => p.onRowClick(r, ri) : undefined }, p.onSelect ? h('td', null, h('button', { type: 'button', role: 'checkbox', class: 'zg-check', 'aria-checked': String(sel.includes(r.id)), 'aria-label': (p.labels && p.labels.selectRow) || t('DataTable', 'selectRow'), onClick: () => p.onSelect(sel.includes(r.id) ? sel.filter(i => i !== r.id) : [...sel, r.id]) }, h('span', { class: 'zg-check__box' }, sel.includes(r.id) ? icon(h, 'check', 14) : null))) : null, ...cols.map(c => h('td', { key: c.key, class: c.num ? 'num' : undefined, style: cs(c) }, c.render ? c.render(r[c.key], r, h) : (r[c.key] ?? '—'))))) : [h('tr', { key: 'e' }, h('td', { colSpan: cols.length + 1 }, h('div', { class: 'zg-empty' }, slots.empty || p.empty || '—')))])))); } },
|
|
118
145
|
Timeline: { render: ({ h, props: p }) => h('div', { class: 'zg-timeline' }, ...(p.items || []).map((it, i, a) => h('div', { key: i, class: 'zg-tl' }, h('div', { class: 'zg-tl__rail' }, h('span', { class: 'zg-tl__dot' }), i < a.length - 1 ? h('span', { class: 'zg-tl__line' }) : null), h('div', { class: 'zg-tl__body' }, h('b', null, it.title), it.text ? h('span', null, it.text) : null, h('span', { class: 'zg-tl__time' }, it.time))))) },
|
|
119
|
-
TopNav: {
|
|
146
|
+
TopNav: { state: { open: null, fit: null }, render: ({ h, props: p, slots, state, set }) => {
|
|
147
|
+
const items = p.items || [], collapse = p.overflow !== 'none';
|
|
148
|
+
const fit = collapse && state.fit != null && state.fit < items.length ? state.fit : items.length;
|
|
149
|
+
const shown = items.slice(0, fit), rest = items.slice(fit);
|
|
150
|
+
const more = rest.length ? { value: '__more', label: p.moreLabel || t('TopNav', 'more'), icon: 'ellipsis', children: rest.flatMap(it => it.children && it.children.length ? [{ heading: it.label }, ...it.children] : [it]) } : null;
|
|
151
|
+
const close = () => set({ open: null });
|
|
152
|
+
const entry = it => {
|
|
153
|
+
const kids = it.children;
|
|
154
|
+
if (!kids || !kids.length) return nav(h, it, p.value, p.onChange);
|
|
155
|
+
const open = state.open === it.value, active = it.value !== '__more' ? kids.some(c => c.value === p.value) : rest.some(r => r.value === p.value || (r.children || []).some(c => c.value === p.value));
|
|
156
|
+
const flat = kids.map(c => ({ value: c.value, disabled: c.separator || c.heading || c.disabled }));
|
|
157
|
+
return h('div', { key: it.value, class: 'zg-dd zg-topnav__dd' },
|
|
158
|
+
h('button', { type: 'button', class: 'zg-navitem', 'aria-haspopup': 'menu', 'aria-expanded': String(open), 'aria-current': active ? 'page' : undefined, onClick: () => set({ open: open ? null : it.value }), onKeydown: openKeys(open, () => set({ open: it.value })) },
|
|
159
|
+
it.icon ? icon(h, it.icon, 18) : null, it.value === '__more' ? h('span', { class: 'zg-sr' }, it.label) : h('span', null, it.label), it.count ? h('span', { class: 'zg-navitem__count' }, it.count) : null, it.value === '__more' ? null : icon(h, 'chevron-down', 14)),
|
|
160
|
+
open ? h('div', { class: 'zg-menu', role: 'menu', 'data-zg-dd': '', ref: ddRef(close, { focus: true }), onKeydown: listKeys('[role=menuitem]', { wrap: true, onTab: e => { const tr = trigger(e.currentTarget); tr && tr.focus(); close(); } }) },
|
|
161
|
+
...kids.map((c, i) => c.separator ? h('div', { key: 's' + i, class: 'zg-menu__sep', role: 'separator' }) : c.heading ? h('div', { key: 'h' + i, class: 'zg-menu__h', role: 'presentation' }, c.heading)
|
|
162
|
+
: h('button', { key: c.value, type: 'button', role: 'menuitem', tabIndex: tabIdx(flat, x => x.value === p.value)(i), disabled: c.disabled, 'aria-disabled': c.disabled ? 'true' : undefined, 'aria-current': c.value === p.value ? 'page' : undefined, class: 'zg-menu__i', onClick: e => { toTrigger(e); close(); p.onChange && p.onChange(c.value); } },
|
|
163
|
+
c.icon ? icon(h, c.icon, 16) : null, h('span', null, c.label), c.count ? h('span', { class: 'zg-navitem__count' }, c.count) : null))) : null);
|
|
164
|
+
};
|
|
165
|
+
const measure = el => tnMeasure(el, { items, more, set, state, collapse });
|
|
166
|
+
return h('header', { class: 'zg-topnav' }, h('div', { class: 'zg-topnav__brand' }, p.brand),
|
|
167
|
+
h('nav', { class: 'zg-topnav__items', 'data-overflow': collapse ? 'menu' : 'none', 'aria-label': t('TopNav', 'label'), ref: measure }, ...shown.map(entry), more ? entry(more) : null),
|
|
168
|
+
h('div', { class: 'zg-topnav__actions' }, slots.actions || p.actions || null)); } },
|
|
120
169
|
SideNav: { render: ({ h, props: p, slots }) => h('aside', { class: cx('zg-sidenav', p.collapsed && 'zg-sidenav--collapsed') }, h('div', { class: 'zg-sidenav__brand' }, p.brand), ...(p.items || []).map(it => it.group ? h('div', { key: it.group, class: 'zg-sidenav__group', style: p.collapsed ? { display: 'none' } : undefined }, it.group) : nav(h, it, p.value, p.onChange, p.collapsed)), h('div', { class: 'zg-sidenav__sp' }), slots.footer || p.footer || null,
|
|
121
170
|
(p.onToggle || p.collapsible) ? h('button', { type: 'button', class: 'zg-navitem', onClick: p.onToggle, 'aria-label': t('SideNav', 'toggle') }, icon(h, p.collapsed ? 'panel-left-open' : 'panel-left-close', 18), h('span', null, p.collapseLabel || t('SideNav', 'collapse'))) : null) },
|
|
122
171
|
AppShell: { state: { collapsed: false }, render: ({ C, h, props: p, children, slots, state, set }) => {
|
package/src/icons/builtin.js
CHANGED
|
@@ -27,7 +27,10 @@ export default {
|
|
|
27
27
|
"component": "<svg class=\"lucide lucide-component\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M15.536 11.293a1 1 0 0 0 0 1.414l2.376 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z\" /><path d=\"M2.297 11.293a1 1 0 0 0 0 1.414l2.377 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414L6.088 8.916a1 1 0 0 0-1.414 0z\" /><path d=\"M8.916 17.912a1 1 0 0 0 0 1.415l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.415l-2.377-2.376a1 1 0 0 0-1.414 0z\" /><path d=\"M8.916 4.674a1 1 0 0 0 0 1.414l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z\" /></svg>",
|
|
28
28
|
"contact": "<svg class=\"lucide lucide-contact\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M16 2v2\" /><path d=\"M7 22v-2a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v2\" /><path d=\"M8 2v2\" /><circle cx=\"12\" cy=\"11\" r=\"3\" /><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" /></svg>",
|
|
29
29
|
"copy": "<svg class=\"lucide lucide-copy\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" /><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" /></svg>",
|
|
30
|
+
"currency": "<svg class=\"lucide lucide-currency\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><circle cx=\"12\" cy=\"12\" r=\"8\" /><line x1=\"3\" x2=\"6\" y1=\"3\" y2=\"6\" /><line x1=\"21\" x2=\"18\" y1=\"3\" y2=\"6\" /><line x1=\"3\" x2=\"6\" y1=\"21\" y2=\"18\" /><line x1=\"21\" x2=\"18\" y1=\"21\" y2=\"18\" /></svg>",
|
|
31
|
+
"donut": "<svg class=\"lucide lucide-donut\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M20.5 10a2.5 2.5 0 0 1-2.4-3H18a2.95 2.95 0 0 1-2.6-4.4 10 10 0 1 0 6.3 7.1c-.3.2-.8.3-1.2.3\" /><circle cx=\"12\" cy=\"12\" r=\"3\" /></svg>",
|
|
30
32
|
"dot": "<svg class=\"lucide lucide-dot\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><circle cx=\"12.1\" cy=\"12.1\" r=\"1\" /></svg>",
|
|
33
|
+
"ellipsis": "<svg class=\"lucide lucide-ellipsis\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><circle cx=\"12\" cy=\"12\" r=\"1\" /><circle cx=\"19\" cy=\"12\" r=\"1\" /><circle cx=\"5\" cy=\"12\" r=\"1\" /></svg>",
|
|
31
34
|
"ellipsis-vertical": "<svg class=\"lucide lucide-ellipsis-vertical\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><circle cx=\"12\" cy=\"12\" r=\"1\" /><circle cx=\"12\" cy=\"5\" r=\"1\" /><circle cx=\"12\" cy=\"19\" r=\"1\" /></svg>",
|
|
32
35
|
"expand": "<svg class=\"lucide lucide-expand\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"m21 21-6-6m6 6v-4.8m0 4.8h-4.8\" /><path d=\"M3 16.2V21m0 0h4.8M3 21l6-6\" /><path d=\"M21 7.8V3m0 0h-4.8M21 3l-6 6\" /><path d=\"M3 7.8V3m0 0h4.8M3 3l6 6\" /></svg>",
|
|
33
36
|
"external-link": "<svg class=\"lucide lucide-external-link\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M15 3h6v6\" /><path d=\"M10 14 21 3\" /><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" /></svg>",
|
|
@@ -37,6 +40,7 @@ export default {
|
|
|
37
40
|
"file-check-2": "<svg class=\"lucide lucide-file-check-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4\" /><path d=\"M14 2v4a2 2 0 0 0 2 2h4\" /><path d=\"m3 15 2 2 4-4\" /></svg>",
|
|
38
41
|
"file-code-2": "<svg class=\"lucide lucide-file-code-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4\" /><path d=\"M14 2v4a2 2 0 0 0 2 2h4\" /><path d=\"m5 12-3 3 3 3\" /><path d=\"m9 18 3-3-3-3\" /></svg>",
|
|
39
42
|
"filter": "<svg class=\"lucide lucide-filter\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\" /></svg>",
|
|
43
|
+
"focus": "<svg class=\"lucide lucide-focus\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><circle cx=\"12\" cy=\"12\" r=\"3\" /><path d=\"M3 7V5a2 2 0 0 1 2-2h2\" /><path d=\"M17 3h2a2 2 0 0 1 2 2v2\" /><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\" /><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\" /></svg>",
|
|
40
44
|
"frame": "<svg class=\"lucide lucide-frame\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><line x1=\"22\" x2=\"2\" y1=\"6\" y2=\"6\" /><line x1=\"22\" x2=\"2\" y1=\"18\" y2=\"18\" /><line x1=\"6\" x2=\"6\" y1=\"2\" y2=\"22\" /><line x1=\"18\" x2=\"18\" y1=\"2\" y2=\"22\" /></svg>",
|
|
41
45
|
"ghost": "<svg class=\"lucide lucide-ghost\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M9 10h.01\" /><path d=\"M15 10h.01\" /><path d=\"M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z\" /></svg>",
|
|
42
46
|
"grip-vertical": "<svg class=\"lucide lucide-grip-vertical\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><circle cx=\"9\" cy=\"12\" r=\"1\" /><circle cx=\"9\" cy=\"5\" r=\"1\" /><circle cx=\"9\" cy=\"19\" r=\"1\" /><circle cx=\"15\" cy=\"12\" r=\"1\" /><circle cx=\"15\" cy=\"5\" r=\"1\" /><circle cx=\"15\" cy=\"19\" r=\"1\" /></svg>",
|
|
@@ -62,12 +66,14 @@ export default {
|
|
|
62
66
|
"panel-left-close": "<svg class=\"lucide lucide-panel-left-close\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /><path d=\"m16 15-3-3 3-3\" /></svg>",
|
|
63
67
|
"panel-left-open": "<svg class=\"lucide lucide-panel-left-open\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /><path d=\"m14 9 3 3-3 3\" /></svg>",
|
|
64
68
|
"pencil": "<svg class=\"lucide lucide-pencil\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\" /><path d=\"m15 5 4 4\" /></svg>",
|
|
69
|
+
"percent": "<svg class=\"lucide lucide-percent\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><line x1=\"19\" x2=\"5\" y1=\"5\" y2=\"19\" /><circle cx=\"6.5\" cy=\"6.5\" r=\"2.5\" /><circle cx=\"17.5\" cy=\"17.5\" r=\"2.5\" /></svg>",
|
|
65
70
|
"phone": "<svg class=\"lucide lucide-phone\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\" /></svg>",
|
|
66
71
|
"phone-off": "<svg class=\"lucide lucide-phone-off\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7 2 2 0 0 1 1.72 2v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.42 19.42 0 0 1-3.33-2.67m-2.67-3.34a19.79 19.79 0 0 1-3.07-8.63A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91\" /><line x1=\"22\" x2=\"2\" y1=\"2\" y2=\"22\" /></svg>",
|
|
67
72
|
"pill": "<svg class=\"lucide lucide-pill\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"m10.5 20.5 10-10a4.95 4.95 0 1 0-7-7l-10 10a4.95 4.95 0 1 0 7 7Z\" /><path d=\"m8.5 8.5 7 7\" /></svg>",
|
|
68
73
|
"play": "<svg class=\"lucide lucide-play\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><polygon points=\"6 3 20 12 6 21 6 3\" /></svg>",
|
|
69
74
|
"plus": "<svg class=\"lucide lucide-plus\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M5 12h14\" /><path d=\"M12 5v14\" /></svg>",
|
|
70
75
|
"pointer": "<svg class=\"lucide lucide-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M22 14a8 8 0 0 1-8 8\" /><path d=\"M18 11v-1a2 2 0 0 0-2-2a2 2 0 0 0-2 2\" /><path d=\"M14 10V9a2 2 0 0 0-2-2a2 2 0 0 0-2 2v1\" /><path d=\"M10 9.5V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v10\" /><path d=\"M18 11a2 2 0 1 1 4 0v3a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\" /></svg>",
|
|
76
|
+
"presentation": "<svg class=\"lucide lucide-presentation\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M2 3h20\" /><path d=\"M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3\" /><path d=\"m7 21 5-5 5 5\" /></svg>",
|
|
71
77
|
"quote": "<svg class=\"lucide lucide-quote\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\" /><path d=\"M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\" /></svg>",
|
|
72
78
|
"radio": "<svg class=\"lucide lucide-radio\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M4.9 19.1C1 15.2 1 8.8 4.9 4.9\" /><path d=\"M7.8 16.2c-2.3-2.3-2.3-6.1 0-8.5\" /><circle cx=\"12\" cy=\"12\" r=\"2\" /><path d=\"M16.2 7.8c2.3 2.3 2.3 6.1 0 8.5\" /><path d=\"M19.1 4.9C23 8.8 23 15.1 19.1 19\" /></svg>",
|
|
73
79
|
"refresh-cw": "<svg class=\"lucide lucide-refresh-cw\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ><path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" /><path d=\"M21 3v5h-5\" /><path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" /><path d=\"M8 16H3v5\" /></svg>",
|
package/src/meta/navigation.js
CHANGED
|
@@ -9,13 +9,15 @@ export default {
|
|
|
9
9
|
description: 'Horizontal app header with a brand area, navigation items and an actions area.',
|
|
10
10
|
props: {
|
|
11
11
|
brand: { type: 'string | VNode', description: 'Logo or product name on the left.' },
|
|
12
|
-
items: { type: '{ value: string; label: string; icon?: string; count?: string | number }[]', default: '[]', description: 'Navigation entries. count renders a small counter after the label.' },
|
|
12
|
+
items: { type: '{ value: string; label: string; icon?: string; count?: string | number; children?: ({ value: string; label: string; icon?: string; count?: string | number; disabled?: boolean } | { heading: string } | { separator: true })[] }[]', default: '[]', description: 'Navigation entries. count renders a small counter after the label. An entry with children becomes a drop-down: click or ArrowDown opens a menu of its children (each with an optional icon and count, headings and separators allowed); selecting one calls change with the child value. The entry is marked current when one of its children is.' },
|
|
13
13
|
value: current,
|
|
14
|
+
overflow: { type: "'menu' | 'none'", values: ['menu', 'none'], default: 'menu', description: "'menu': entries that do not fit move into a trailing \"More\" drop-down (measured after render and on resize; server rendering shows all entries). 'none': no collapsing, the row scrolls sideways and sub-menus are clipped, so avoid children with it." },
|
|
15
|
+
moreLabel: { type: 'string', default: 'More', description: 'Accessible name of the overflow drop-down button.' },
|
|
14
16
|
size: size('header padding, item height and text'),
|
|
15
17
|
},
|
|
16
18
|
slots: { actions: 'Right side of the header (buttons, avatar). React also accepts an actions prop.' },
|
|
17
|
-
events: { change: 'Called with the value of the clicked item.' },
|
|
18
|
-
notes: ['Controlled: update value yourself in the change handler.', 'Items use count; SubNav uses badge for the same purpose.'],
|
|
19
|
+
events: { change: 'Called with the value of the clicked item or sub-menu item.' },
|
|
20
|
+
notes: ['Controlled: update value yourself in the change handler.', 'Items use count; SubNav uses badge for the same purpose.', 'Entries with children and the More menu share the Dropdown keyboard behaviour: ArrowDown opens, arrows and Home/End move, Escape closes and returns focus to the button.'],
|
|
19
21
|
},
|
|
20
22
|
|
|
21
23
|
SideNav: {
|
|
@@ -166,4 +166,4 @@
|
|
|
166
166
|
.zg-call{display:grid;grid-template-columns:36px minmax(0,1fr) auto;gap:12px;align-items:center;padding:10px 12px;border-radius:18px;background:var(--zg-s2)}
|
|
167
167
|
@media(prefers-reduced-motion:reduce){.zg-root *{animation-duration:.01ms!important;transition-duration:.01ms!important}}
|
|
168
168
|
|
|
169
|
-
.zg-topnav__items
|
|
169
|
+
.zg-topnav__items .zg-navitem{padding-inline:12px}
|
|
@@ -120,3 +120,9 @@
|
|
|
120
120
|
.zg-tip--left:hover::before,.zg-tip--right:hover::before{top:0;bottom:0;height:auto;width:10px}
|
|
121
121
|
.zg-tip--left:hover::before{left:auto;right:100%}.zg-tip--right:hover::before{right:auto;left:100%}
|
|
122
122
|
.zg-tip[data-tip-off]::after{opacity:0!important;pointer-events:none!important}.zg-tip[data-tip-off]::before{display:none}
|
|
123
|
+
/* TopNav: no edge fade; items that do not fit move into a "More" menu, sub-menus open under their item */
|
|
124
|
+
.zg-topnav__items{overflow:visible;flex-wrap:nowrap}.zg-topnav__items[data-overflow="none"]{overflow-x:auto}
|
|
125
|
+
.zg-topnav__dd{display:flex}.zg-topnav__dd>.zg-navitem{height:100%}.zg-topnav__dd .zg-menu{top:calc(100% + 10px);min-width:220px}
|
|
126
|
+
.zg-topnav__dd>.zg-navitem[aria-expanded="true"] .zg-icon:last-child:not(:first-child){transform:rotate(180deg)}
|
|
127
|
+
.zg-menu__i[aria-current="page"]{background:var(--zg-s2);font-weight:700}.zg-menu__i .zg-navitem__count{margin-inline-start:auto}
|
|
128
|
+
.zg-menu__h{padding:8px 12px 4px;font:600 12px var(--zg-font);letter-spacing:.06em;text-transform:uppercase;color:var(--zg-text-3)}
|
package/types/react.d.ts
CHANGED
|
@@ -3695,24 +3695,35 @@ export const UiTooltip: ComponentType<UiTooltipProps>;
|
|
|
3695
3695
|
* Horizontal app header with a brand area, navigation items and an actions area.
|
|
3696
3696
|
* Note: Controlled: update value yourself in the change handler.
|
|
3697
3697
|
* Note: Items use count; SubNav uses badge for the same purpose.
|
|
3698
|
+
* Note: Entries with children and the More menu share the Dropdown keyboard behaviour: ArrowDown opens, arrows and Home/End move, Escape closes and returns focus to the button.
|
|
3698
3699
|
*/
|
|
3699
3700
|
export interface UiTopNavProps {
|
|
3700
3701
|
/** Logo or product name on the left. */
|
|
3701
3702
|
brand?: string | ReactNode;
|
|
3702
3703
|
/**
|
|
3703
|
-
* Navigation entries. count renders a small counter after the label.
|
|
3704
|
+
* Navigation entries. count renders a small counter after the label. An entry with children becomes a drop-down: click or ArrowDown opens a menu of its children (each with an optional icon and count, headings and separators allowed); selecting one calls change with the child value. The entry is marked current when one of its children is.
|
|
3704
3705
|
* @default []
|
|
3705
3706
|
*/
|
|
3706
|
-
items?: { value: string; label: string; icon?: string; count?: string | number }[];
|
|
3707
|
+
items?: { value: string; label: string; icon?: string; count?: string | number; children?: ({ value: string; label: string; icon?: string; count?: string | number; disabled?: boolean } | { heading: string } | { separator: true })[] }[];
|
|
3707
3708
|
/** Value of the active item (aria-current="page"). */
|
|
3708
3709
|
value?: string;
|
|
3710
|
+
/**
|
|
3711
|
+
* 'menu': entries that do not fit move into a trailing "More" drop-down (measured after render and on resize; server rendering shows all entries). 'none': no collapsing, the row scrolls sideways and sub-menus are clipped, so avoid children with it.
|
|
3712
|
+
* @default 'menu'
|
|
3713
|
+
*/
|
|
3714
|
+
overflow?: 'menu' | 'none';
|
|
3715
|
+
/**
|
|
3716
|
+
* Accessible name of the overflow drop-down button.
|
|
3717
|
+
* @default 'More'
|
|
3718
|
+
*/
|
|
3719
|
+
moreLabel?: string;
|
|
3709
3720
|
/**
|
|
3710
3721
|
* Scale of header padding, item height and text.
|
|
3711
3722
|
* @default 'md'
|
|
3712
3723
|
*/
|
|
3713
3724
|
size?: Size;
|
|
3714
3725
|
/**
|
|
3715
|
-
* Called with the value of the clicked item.
|
|
3726
|
+
* Called with the value of the clicked item or sub-menu item.
|
|
3716
3727
|
* @event change
|
|
3717
3728
|
*/
|
|
3718
3729
|
onChange?: (value: string) => void;
|
package/types/vue.d.ts
CHANGED
|
@@ -3727,24 +3727,35 @@ export const UiTooltip: UiVueComponent<UiTooltipProps, UiTooltipSlots>;
|
|
|
3727
3727
|
* Horizontal app header with a brand area, navigation items and an actions area.
|
|
3728
3728
|
* Note: Controlled: update value yourself in the change handler.
|
|
3729
3729
|
* Note: Items use count; SubNav uses badge for the same purpose.
|
|
3730
|
+
* Note: Entries with children and the More menu share the Dropdown keyboard behaviour: ArrowDown opens, arrows and Home/End move, Escape closes and returns focus to the button.
|
|
3730
3731
|
*/
|
|
3731
3732
|
export interface UiTopNavProps {
|
|
3732
3733
|
/** Logo or product name on the left. */
|
|
3733
3734
|
brand?: string | VNode;
|
|
3734
3735
|
/**
|
|
3735
|
-
* Navigation entries. count renders a small counter after the label.
|
|
3736
|
+
* Navigation entries. count renders a small counter after the label. An entry with children becomes a drop-down: click or ArrowDown opens a menu of its children (each with an optional icon and count, headings and separators allowed); selecting one calls change with the child value. The entry is marked current when one of its children is.
|
|
3736
3737
|
* @default []
|
|
3737
3738
|
*/
|
|
3738
|
-
items?: { value: string; label: string; icon?: string; count?: string | number }[];
|
|
3739
|
+
items?: { value: string; label: string; icon?: string; count?: string | number; children?: ({ value: string; label: string; icon?: string; count?: string | number; disabled?: boolean } | { heading: string } | { separator: true })[] }[];
|
|
3739
3740
|
/** Value of the active item (aria-current="page"). */
|
|
3740
3741
|
value?: string;
|
|
3742
|
+
/**
|
|
3743
|
+
* 'menu': entries that do not fit move into a trailing "More" drop-down (measured after render and on resize; server rendering shows all entries). 'none': no collapsing, the row scrolls sideways and sub-menus are clipped, so avoid children with it.
|
|
3744
|
+
* @default 'menu'
|
|
3745
|
+
*/
|
|
3746
|
+
overflow?: 'menu' | 'none';
|
|
3747
|
+
/**
|
|
3748
|
+
* Accessible name of the overflow drop-down button.
|
|
3749
|
+
* @default 'More'
|
|
3750
|
+
*/
|
|
3751
|
+
moreLabel?: string;
|
|
3741
3752
|
/**
|
|
3742
3753
|
* Scale of header padding, item height and text.
|
|
3743
3754
|
* @default 'md'
|
|
3744
3755
|
*/
|
|
3745
3756
|
size?: Size;
|
|
3746
3757
|
/**
|
|
3747
|
-
* Called with the value of the clicked item.
|
|
3758
|
+
* Called with the value of the clicked item or sub-menu item.
|
|
3748
3759
|
* @event change
|
|
3749
3760
|
*/
|
|
3750
3761
|
onChange?: (value: string) => void;
|