@ziyarago/ui 0.13.0 → 0.15.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 +12 -0
- package/README.md +5 -5
- package/dist/llms-full.txt +3 -3
- package/dist/llms.txt +2 -2
- package/dist/manifest.json +316 -2
- package/docs/INTEGRATION.md +14 -0
- package/package.json +10 -25
- package/src/core/components.js +0 -11
- package/src/core/components2.js +1 -71
- package/src/core/components3.js +2 -44
- package/src/core/components4.js +0 -38
- package/src/core/components6.js +0 -50
- package/src/core/components7.js +0 -34
- package/src/core/index.js +6 -0
- package/src/core/pages.js +2 -36
- package/src/i18n/components/index.js +0 -72
- package/src/internal.js +10 -0
- package/src/meta/index.js +15 -0
- package/src/meta/pages.js +1 -1
- package/src/nuxt/module.mjs +9 -1
- package/src/react/index.js +8 -107
- package/src/resolver.js +17 -4
- package/src/vue/index.js +9 -2
- package/types/core.d.ts +3 -0
- package/types/internal.d.ts +30 -0
- package/types/meta.d.ts +8 -0
- package/types/nuxt.d.ts +2 -0
- package/types/react.d.ts +138 -4143
- package/types/resolver.d.ts +2 -0
- package/types/vue-global.d.ts +0 -106
- package/types/vue.d.ts +147 -3598
- package/docs/MIGRATION.md +0 -455
- package/src/compat/index.js +0 -469
- package/src/compat/map.js +0 -282
- package/src/compat/resolver.js +0 -22
- package/src/compat/vite.js +0 -29
- package/src/i18n/components/ActionCard.js +0 -5
- package/src/i18n/components/Actionsheet.js +0 -5
- package/src/i18n/components/CallCard.js +0 -5
- package/src/i18n/components/CallRow.js +0 -5
- package/src/i18n/components/Carousel.js +0 -5
- package/src/i18n/components/ChartCard.js +0 -5
- package/src/i18n/components/ChatAi.js +0 -5
- package/src/i18n/components/ChipInput.js +0 -5
- package/src/i18n/components/ContactPanel.js +0 -5
- package/src/i18n/components/DataGroup.js +0 -5
- package/src/i18n/components/DealCard.js +0 -5
- package/src/i18n/components/FullscreenDialog.js +0 -5
- package/src/i18n/components/Gallery.js +0 -5
- package/src/i18n/components/GuestCard.js +0 -5
- package/src/i18n/components/ImageUpload.js +0 -5
- package/src/i18n/components/ImageViewer.js +0 -5
- package/src/i18n/components/IncomingCall.js +0 -5
- package/src/i18n/components/InlineEdit.js +0 -5
- package/src/i18n/components/IntegrationCard.js +0 -5
- package/src/i18n/components/Map.js +0 -5
- package/src/i18n/components/NotificationBell.js +0 -5
- package/src/i18n/components/PricingCard.js +0 -5
- package/src/i18n/components/QiblaCompass.js +0 -5
- package/src/i18n/components/RamadanTracker.js +0 -5
- package/src/i18n/components/RangeCalendar.js +0 -5
- package/src/i18n/components/RangeSlider.js +0 -5
- package/src/i18n/components/RichEditor.js +0 -5
- package/src/i18n/components/Screensaver.js +0 -5
- package/src/i18n/components/Sortable.js +0 -5
- package/src/i18n/components/StepDialog.js +0 -5
- package/src/i18n/components/StepForm.js +0 -5
- package/src/i18n/components/TabTiles.js +0 -5
- package/src/i18n/components/Tour.js +0 -5
- package/src/i18n/components/TourCard.js +0 -5
- package/src/i18n/components/TourPopover.js +0 -5
- package/src/i18n/components/TreeSelect.js +0 -5
- package/types/compat-resolver.d.ts +0 -12
- package/types/compat-vite.d.ts +0 -11
- package/types/compat.d.ts +0 -176
package/src/core/components6.js
CHANGED
|
@@ -1,59 +1,9 @@
|
|
|
1
1
|
// @ziyarago/ui · components, part 6 — last catalog gaps: TreeSelect, ContextMenu, Sortable, Map, Screensaver, ImageUpload, Tour.
|
|
2
|
-
import { t } from '../i18n/index.js';
|
|
3
2
|
import { icon, cx, ddRef } from './components.js';
|
|
4
|
-
import { trap, life } from './dialog.js';
|
|
5
3
|
import { listKeys, tabIdx } from './keys.js';
|
|
6
|
-
const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
7
|
-
|
|
8
4
|
export const more6 = {
|
|
9
|
-
TreeSelect: { state: { open: false, q: '', ex: {} }, render: ({ h, props: p, state, set }) => {
|
|
10
|
-
const flat = (ns, d = 0) => ns.flatMap(n => [{ ...n, d }, ...(n.children ? flat(n.children, d + 1) : [])]), all = flat(p.nodes || []), cur = all.find(n => n.id === p.modelValue), q = state.q.toLowerCase();
|
|
11
|
-
const node = (n, d) => { const has = n.children && n.children.length, o = q ? true : (state.ex[n.id] ?? d < 1);
|
|
12
|
-
if (q && !all.filter(x => x.label.toLowerCase().includes(q)).some(x => x.id === n.id || (n.children || []).some(function f(c) { return c.id === x.id || (c.children || []).some(f); }))) return null;
|
|
13
|
-
return h('div', { key: n.id }, h('button', { type: 'button', role: 'treeitem', disabled: n.disabled, 'aria-disabled': n.disabled ? 'true' : undefined, class: cx('zg-tree__n', n.id === p.modelValue && 'zg-tree__n--on'), style: { paddingInlineStart: 8 + d * 18 + 'px', width: '100%' }, onClick: () => { if (has && !q) set({ ex: { ...state.ex, [n.id]: !o } }); if (!has || p.selectGroups) { set({ open: false, q: '' }); p.onChange && p.onChange(n.id); } } }, has ? icon(h, o ? 'chevron-down' : 'chevron-right', 14) : h('span', { style: { width: '14px' } }), n.label), has && o ? n.children.map(c => node(c, d + 1)) : null); };
|
|
14
|
-
return h('div', { class: 'zg-field' }, p.label ? h('span', { class: 'zg-label' }, p.label) : null, h('div', { class: 'zg-select' }, h('button', { type: 'button', class: 'zg-btn zg-select__trigger', 'aria-haspopup': 'tree', 'aria-expanded': String(state.open && !p.disabled), disabled: p.disabled, style: { height: 'var(--zg-h-lg)' }, onClick: () => set({ open: !state.open }) }, h('span', null, cur ? cur.label : (p.placeholder || '—')), icon(h, 'chevron-down', 16)),
|
|
15
|
-
state.open && !p.disabled ? h('div', { class: 'zg-select__list', role: 'tree', 'data-zg-dd': '', ref: ddRef(() => set({ open: false, q: '' })), style: { padding: '8px' } }, h('span', { class: 'zg-input', style: { '--h': '36px', marginBottom: '6px' } }, icon(h, 'search', 14), h('input', { value: state.q, placeholder: t('TreeSelect', 'search'), onInput: e => set({ q: e.target.value }) })), ...(p.nodes || []).map(n => node(n, 0))) : null)); } },
|
|
16
5
|
ContextMenu: { state: { x: 0, y: 0, open: false }, render: ({ h, props: p, state, set, children }) => {
|
|
17
6
|
const close = () => set({ open: false });
|
|
18
7
|
return h('div', { class: 'zg-ctx', onContextmenu: e => { e.preventDefault(); set({ open: true, x: e.clientX, y: e.clientY }); } }, ...children,
|
|
19
8
|
state.open ? h('div', { class: 'zg-ctx__scrim', onClick: close, onContextmenu: e => { e.preventDefault(); close(); } }, h('div', { class: 'zg-menu', role: 'menu', 'data-zg-dd': '', ref: ddRef(close, { self: true, focus: true }), onKeydown: listKeys('[role=menuitem]', { wrap: true, onTab: close }), style: { position: 'fixed', left: Math.min(state.x, innerWidth - 240) + 'px', top: Math.min(state.y, innerHeight - (p.items || []).length * 42 - 20) + 'px', insetInlineStart: 'auto' }, onClick: e => e.stopPropagation() }, ...(p.items || []).map((it, i, all) => it.separator ? h('div', { key: i, class: 'zg-menu__sep', role: 'separator' }) : h('button', { key: i, type: 'button', role: 'menuitem', tabIndex: tabIdx(all.map(x => ({ disabled: x.separator || x.disabled })), () => false)(i), class: cx('zg-menu__i', it.tone === 'danger' && 'zg-menu__i--danger'), onClick: () => { close(); p.onSelect && p.onSelect(it.value); } }, it.icon ? icon(h, it.icon, 16) : null, it.label, it.shortcut ? h('span', { class: 'zg-kbd' }, it.shortcut) : null)))) : null); } },
|
|
20
|
-
Sortable: { state: { drag: null, over: null }, render: ({ h, props: p, state, set }) => { const items = p.items || [];
|
|
21
|
-
const drop = (to, f) => { const from = f === undefined ? state.drag : f; set({ drag: null, over: null }); if (from == null || from === to) return; const a = items.slice(); const [m] = a.splice(from, 1); a.splice(to, 0, m); p.onChange && p.onChange(a); };
|
|
22
|
-
return h('div', { class: 'zg-sort', role: 'list' }, ...items.map((it, i) => h('div', { key: it.id ?? i, role: 'listitem', class: cx('zg-sort__i', state.over === i && state.drag !== i && 'is-over', state.drag === i && 'is-drag'), draggable: 'true', onDragstart: e => { e.dataTransfer.effectAllowed = 'move'; try { e.dataTransfer.setData('text/plain', String(i)); } catch (x) {} set({ drag: i }); }, onDragover: e => { e.preventDefault(); if (state.over !== i) set({ over: i }); }, onDrop: e => { e.preventDefault(); drop(i); }, onDragend: () => set({ drag: null, over: null }) },
|
|
23
|
-
h('span', { class: 'zg-sort__h', 'aria-hidden': 'true' }, icon(h, 'grip-vertical', 16)), h('div', { style: { flex: 1, minWidth: 0 } }, p.render ? p.render(it, i) : h('b', null, it.label)),
|
|
24
|
-
h('span', { style: { display: 'flex', gap: '2px' } }, h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--sm zg-ibtn--ghost', 'aria-label': t('Sortable', 'moveUp'), disabled: i === 0, onClick: () => drop(i - 1, i) }, icon(h, 'chevron-up', 14)), h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--sm zg-ibtn--ghost', 'aria-label': t('Sortable', 'moveDown'), disabled: i === items.length - 1, onClick: () => drop(i + 1, i) }, icon(h, 'chevron-down', 14)))))); } },
|
|
25
|
-
Map: { state: { lon: null, lat: null, z: null, dk: null, w: null }, render: ({ h, props: p, state, set }) => {
|
|
26
|
-
const W = state.w || p.width || 640, H = p.height || 360, z = state.z ?? p.zoom ?? 14, lat0 = state.lat ?? p.lat ?? 21.4225, lon0 = state.lon ?? p.lon ?? 39.8262, n = 2 ** z;
|
|
27
|
-
const mpx = (lat, lon, nn) => [(lon + 180) / 360 * nn * 256, (1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * nn * 256], px = (lat, lon) => mpx(lat, lon, n);
|
|
28
|
-
const [cx0, cy0] = mpx(lat0, lon0, n), x0 = cx0 - W / 2, y0 = cy0 - H / 2, dark = p.theme ? p.theme === 'dark' : state.dk === true;
|
|
29
|
-
const tiles = []; for (let tx = Math.floor(x0 / 256); tx <= Math.floor((x0 + W) / 256); tx++) for (let ty = Math.floor(y0 / 256); ty <= Math.floor((y0 + H) / 256); ty++) if (ty >= 0 && ty < n) tiles.push(h('img', { key: tx + '_' + ty, alt: '', draggable: 'false', src: `https://${'abc'[(tx + ty) & 1]}.basemaps.cartocdn.com/${p.style || (dark ? 'dark_all' : 'light_all')}/${z}/${((tx % n) + n) % n}/${ty}.png`, style: { position: 'absolute', left: (tx * 256 - x0) + 'px', top: (ty * 256 - y0) + 'px', width: '256px', height: '256px' } }));
|
|
30
|
-
const unpx = (x, y, nn) => [Math.atan(Math.sinh(Math.PI * (1 - 2 * y / (nn * 256)))) * 180 / Math.PI, x / (nn * 256) * 360 - 180];
|
|
31
|
-
const emit = (la, lo, zz) => { p.onMove && p.onMove({ lat: la, lon: lo, zoom: zz }); if (zz !== z) p.onZoom && p.onZoom(zz); };
|
|
32
|
-
const zoomAt = (dz, ox, oy) => { const nz = clamp(z + dz, 3, 18); if (nz === z) return; const s = 2 ** (nz - z), nn = 2 ** nz, [la, lo] = unpx((cx0 + ox) * s - ox, (cy0 + oy) * s - oy, nn); set({ z: nz, lat: la, lon: lo }); emit(la, lo, nz); };
|
|
33
|
-
const rel = (e, el) => { const q = el.getBoundingClientRect(); return [e.clientX - q.left - q.width / 2, e.clientY - q.top - q.height / 2]; };
|
|
34
|
-
const pan = e => { if (e.button > 0 || !e.isPrimary) return; const el = e.currentTarget, sx = e.clientX, sy = e.clientY, pid = e.pointerId; let cap = false;
|
|
35
|
-
const mv = ev => { if (ev.pointerId !== pid) return; const dx = ev.clientX - sx, dy = ev.clientY - sy; if (!cap) { if (Math.abs(dx) + Math.abs(dy) < 4) return; cap = true; try { el.setPointerCapture(pid); } catch (x) {} } const [la, lo] = unpx(cx0 - dx, cy0 - dy, n); set({ lat: la, lon: lo }); emit(la, lo, z); };
|
|
36
|
-
const up = ev => { if (ev.pointerId !== pid) return; el.removeEventListener('pointermove', mv); el.removeEventListener('pointerup', up); el.removeEventListener('pointercancel', up); };
|
|
37
|
-
el.addEventListener('pointermove', mv); el.addEventListener('pointerup', up); el.addEventListener('pointercancel', up); };
|
|
38
|
-
const mk = (p.markers || []).map((m, i) => { const [mx, my] = px(m.lat, m.lon); return h('button', { key: 'm' + i, type: 'button', class: cx('zg-pin', m.tone && 'zg-t-' + m.tone), title: m.label, style: { left: (mx - x0) + 'px', top: (my - y0) + 'px' }, onClick: () => p.onSelect && p.onSelect(m) }, icon(h, m.icon || 'map-pin', 16)); });
|
|
39
|
-
const stop = e => e.stopPropagation(), zb = (dz, k, d, ic) => h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--sm', 'aria-label': (p.labels && p.labels[k]) || d, onPointerdown: stop, onDblclick: stop, onClick: () => zoomAt(dz, 0, 0) }, icon(h, ic, 16));
|
|
40
|
-
return h('div', { class: 'zg-map', role: 'application', 'aria-label': p.label || t('Map', 'label'), style: { height: H + 'px' }, onPointerdown: pan, onDblclick: e => { const [ox, oy] = rel(e, e.currentTarget); zoomAt(1, ox, oy); },
|
|
41
|
-
ref: el => { if (!el) return; el.__zgw = e => { e.preventDefault(); const t = Date.now(); if (t - (el.__zgt || 0) < 180) return; el.__zgt = t; const [ox, oy] = rel(e, el); zoomAt(e.deltaY < 0 ? 1 : -1, ox, oy); };
|
|
42
|
-
if (!el.__zgi) { el.__zgi = 1; el.addEventListener('wheel', e => el.__zgw(e), { passive: false }); if (typeof ResizeObserver !== 'undefined') new ResizeObserver(() => { const w = Math.round(el.clientWidth); if (w && w !== el.__zgl) { el.__zgl = w; set({ w }); } }).observe(el); }
|
|
43
|
-
if (p.theme == null && state.dk == null) set({ dk: !!el.closest('[data-theme="dark"]') }); } }, ...tiles, ...mk,
|
|
44
|
-
h('div', { class: 'zg-map__z' }, zb(1, 'zoomIn', t('Map', 'zoomIn'), 'plus'), zb(-1, 'zoomOut', t('Map', 'zoomOut'), 'minus')),
|
|
45
|
-
h('span', { class: 'zg-map__c' }, '© OpenStreetMap · CARTO')); } },
|
|
46
|
-
ImageUpload: { state: { src: null }, render: ({ h, props: p, state, set }) => { const src = state.src || p.modelValue, round = p.shape === 'circle';
|
|
47
|
-
return h('div', { class: 'zg-field' }, p.label ? h('span', { class: 'zg-label' }, p.label) : null, h('label', { class: 'zg-imgup', style: { aspectRatio: p.aspect || '1/1', maxWidth: (({ xs: 112, sm: 128, md: 160, lg: 192, xl: 224 })[p.size] || p.size || 160) + 'px', borderRadius: round ? '50%' : '24px', backgroundImage: src ? `url(${src})` : undefined } }, src ? null : h('span', { class: 'zg-imgup__e' }, icon(h, 'image-up', 24), h('span', { class: 'zg-hint' }, p.hint || t('ImageUpload', 'upload'))), h('span', { class: 'zg-imgup__o' }, icon(h, 'camera', 18)),
|
|
48
|
-
h('input', { type: 'file', accept: 'image/*', style: { display: 'none' }, onChange: e => { const f = e.target.files[0]; if (!f) return; const r = new FileReader(); r.onload = () => { set({ src: r.result }); p.onChange && p.onChange(r.result, f); }; r.readAsDataURL(f); } }))); } },
|
|
49
|
-
Screensaver: { state: { t: 0 }, render: ({ h, props: p, state, set }) => { if (!p.open) return p.idleMs > 0 ? h('span', { hidden: true, 'aria-hidden': 'true', ref: life({ idleMs: p.idleMs, onIdle: p.onIdle, mount: (el, get) => { let tm; const arm = () => { clearTimeout(tm); tm = setTimeout(() => { const o = get(); o.onIdle && o.onIdle(); }, get().idleMs); }, evs = ['pointermove', 'pointerdown', 'keydown', 'wheel', 'touchstart']; evs.forEach(e => document.addEventListener(e, arm, { passive: true })); arm(); return () => { clearTimeout(tm); evs.forEach(e => document.removeEventListener(e, arm)); }; } }) }) : null;
|
|
50
|
-
const d = new Date(state.t || 0), pad = n => String(n).padStart(2, '0'), ph = (d.getSeconds() % 40) / 40;
|
|
51
|
-
return h('div', { class: 'zg-saver', role: 'dialog', 'aria-modal': 'true', 'aria-label': t('Screensaver', 'label'), tabIndex: 0, ref: trap({ onClose: p.onClose, onKey: e => { if (e.key === 'Tab') return false; p.onClose && p.onClose(); return true; }, mount: el => { const id = setInterval(() => set({ t: Date.now() }), 1000); set({ t: Date.now() }); return () => clearInterval(id); } }), onClick: p.onClose }, h('span', { class: 'zg-saver__g', style: { left: (10 + ph * 60) + '%', top: (20 + Math.sin(ph * 6.28) * 18) + '%' } }),
|
|
52
|
-
h('div', { class: 'zg-saver__c' }, h('span', { class: 'zg-saver__m', style: { backgroundImage: 'url(assets/brand/ziyarago-mark.svg)' } }), h('b', { class: 'zg-num', style: { fontSize: 'clamp(64px,12vw,160px)', fontWeight: 200, letterSpacing: '-.04em', lineHeight: 1 } }, state.t ? pad(d.getHours()) + ':' + pad(d.getMinutes()) : '--:--'), h('span', { style: { color: 'var(--zg-text-2)', fontSize: '18px' } }, state.t ? new Intl.DateTimeFormat(p.locale || 'en-GB', { weekday: 'long', day: 'numeric', month: 'long' }).format(d) : '\u00a0'), p.hint ? h('span', { class: 'zg-hint' }, p.hint) : null)); } },
|
|
53
|
-
Tour: { state: { i: 0, r: null }, render: ({ C, h, props: p, state, set }) => { if (!p.open) return null; const st = p.steps || [], i = clamp(p.step != null ? p.step : state.i, 0, Math.max(0, st.length - 1)), s = st[i] || {};
|
|
54
|
-
const measure = () => { if (state.r || state.busy || !s.target) return; const el0 = document.querySelector(s.target); if (!el0) return; state.busy = true; setTimeout(() => { const el = document.querySelector(s.target) || el0, q = el.getBoundingClientRect(); if (q.top < 80 || q.bottom > innerHeight - 220) { let a = el.parentElement; while (a && !(/(auto|scroll)/.test(getComputedStyle(a).overflowY) && a.scrollHeight > a.clientHeight + 4)) a = a.parentElement; const dy = q.top - innerHeight / 3; if (a) a.scrollTop += dy; else window.scrollTo(0, window.scrollY + dy); } setTimeout(() => { state.busy = false; set({ r: (document.querySelector(s.target) || el).getBoundingClientRect() }); }, 160); }, 0); };
|
|
55
|
-
const r = state.r, pad = 8, below = r ? r.bottom + 12 + 190 < innerHeight : true;
|
|
56
|
-
const go = d => { const n = clamp(i + d, 0, st.length - 1); if (n === i) return; set({ i: n, r: null }); p.onStep && p.onStep(n); }, done = () => { set({ i: 0, r: null }); p.onClose && p.onClose(); };
|
|
57
|
-
return h('div', { class: 'zg-tourov', role: 'dialog', 'aria-label': t('Tour', 'label'), ref: el => { if (el) measure(); trap({ focus: false, onClose: done, mount: () => () => set({ i: 0, r: null }), onKey: e => { const rtl = document.documentElement.dir === 'rtl', k = e.key === 'ArrowRight' ? (rtl ? -1 : 1) : e.key === 'ArrowLeft' ? (rtl ? 1 : -1) : 0; if (k) { e.preventDefault(); go(k); return true; } } })(el); } }, r ? h('span', { class: 'zg-tourov__cut', style: { left: (r.left - pad) + 'px', top: (r.top - pad) + 'px', width: (r.width + pad * 2) + 'px', height: (r.height + pad * 2) + 'px' } }) : h('span', { class: 'zg-tourov__full' }),
|
|
58
|
-
h('div', { style: { position: 'fixed', zIndex: 2, left: r ? clamp(r.left, 12, innerWidth - 392) + 'px' : '50%', top: r ? (below ? r.bottom + 12 : Math.max(12, r.top - 12 - 190)) + 'px' : '40%', transform: r ? 'none' : 'translateX(-50%)' } }, h(C.TourPopover, { title: s.title, text: s.text, step: (i + 1) + ' / ' + st.length, last: i === st.length - 1, onBack: i ? () => go(-1) : null, onNext: () => i === st.length - 1 ? done() : go(1), onClose: done }))); } }
|
|
59
9
|
};
|
package/src/core/components7.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// @ziyarago/ui · components, part 7 — gluestack parity: typography, layout primitives, Link, Pressable, Icon, Portal, sheets, ImageViewer, ChatAi, LiquidGlass.
|
|
2
|
-
import { t } from '../i18n/index.js';
|
|
3
2
|
import { icon, cx } from './components.js';
|
|
4
3
|
import { trap } from './dialog.js';
|
|
5
4
|
const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
@@ -7,19 +6,6 @@ const sp = v => (typeof v === 'number' ? v + 'px' : v);
|
|
|
7
6
|
const stack = (dir) => ({ render: ({ h, props: p, children }) => h(p.as || 'div', { class: 'zg-stack', style: { flexDirection: dir, gap: sp(p.gap ?? 12), alignItems: p.align, justifyContent: p.justify, flexWrap: p.wrap ? 'wrap' : undefined, ...(p.style || {}) } }, ...children) });
|
|
8
7
|
|
|
9
8
|
export const more7 = {
|
|
10
|
-
QiblaCompass: { render: ({ h, props: p }) => {
|
|
11
|
-
const px = { xs: 120, sm: 160, md: 200, lg: 250, xl: 300 }[p.size] || (Number(p.size) > 0 ? Number(p.size) : 200), norm = v => ((Number(v) || 0) % 360 + 360) % 360, b = norm(p.bearing), hd = norm(p.heading), deg = Math.round(b), ticks = [];
|
|
12
|
-
for (let i = 0; i < 72; i++) { const major = i % 9 === 0, a = i * 5 * Math.PI / 180, r1 = 92, r2 = major ? 80 : i % 3 ? 87 : 84; ticks.push(h('line', { key: i, class: major ? 'zg-qb__tk zg-qb__tk--m' : 'zg-qb__tk', x1: +(100 + Math.sin(a) * r1).toFixed(2), y1: +(100 - Math.cos(a) * r1).toFixed(2), x2: +(100 + Math.sin(a) * r2).toFixed(2), y2: +(100 - Math.cos(a) * r2).toFixed(2) })); }
|
|
13
|
-
return h('div', { class: 'zg-qb zg-dm', role: 'img', 'aria-label': t('QiblaCompass', 'label', { deg }), style: { width: px + 'px' } },
|
|
14
|
-
h('svg', { class: 'zg-qb__svg', viewBox: '0 0 200 200', 'aria-hidden': 'true', focusable: 'false' },
|
|
15
|
-
h('circle', { class: 'zg-qb__ring', cx: 100, cy: 100, r: 98 }),
|
|
16
|
-
h('g', { class: 'zg-qb__dial', transform: `rotate(${-hd} 100 100)` }, ...ticks, h('path', { class: 'zg-qb__n', d: 'M100 6 L106 20 L94 20 Z' })),
|
|
17
|
-
h('g', { class: 'zg-qb__ptr', transform: `rotate(${b - hd} 100 100)` },
|
|
18
|
-
h('line', { class: 'zg-qb__ln', x1: 100, y1: 100, x2: 100, y2: 46 }),
|
|
19
|
-
h('rect', { class: 'zg-qb__kb', x: 88, y: 24, width: 24, height: 24, rx: 5 }),
|
|
20
|
-
h('rect', { class: 'zg-qb__kg', x: 88, y: 31, width: 24, height: 4 })),
|
|
21
|
-
h('circle', { class: 'zg-qb__hub', cx: 100, cy: 100, r: 5 })),
|
|
22
|
-
h('div', { class: 'zg-qb__txt' }, h('b', { class: 'zg-num' }, deg + '°'), h('span', null, t('QiblaCompass', 'qibla')), p.distance ? h('small', null, p.distance) : null)); } },
|
|
23
9
|
Heading: { render: ({ h, props: p, children }) => h('h' + clamp(p.level || 2, 1, 6), { class: cx('zg-heading', 'zg-heading--' + (p.size || 'lg'), p.brand && 'zg-heading--brand') }, ...children) },
|
|
24
10
|
Text: { render: ({ h, props: p, children }) => h(p.as || 'p', { class: cx('zg-text', 'zg-text--' + (p.size || 'md'), p.tone && 'zg-text--' + p.tone, p.bold && 'zg-text--bold', p.truncate && 'zg-text--truncate') }, ...children) },
|
|
25
11
|
Box: { render: ({ h, props: p, children }) => h(p.as || 'div', { class: cx('zg-box', p.glass && 'zg-glass'), style: { padding: sp(p.p), ...(p.style || {}) } }, ...children) },
|
|
@@ -31,26 +17,6 @@ export const more7 = {
|
|
|
31
17
|
Pressable: { render: ({ h, props: p, children }) => h(p.as || 'button', { type: (p.as || 'button') === 'button' ? 'button' : undefined, class: 'zg-press', disabled: p.disabled, 'aria-label': p.label, onClick: p.onClick }, ...children) },
|
|
32
18
|
Icon: { render: ({ h, props: p }) => icon(h, p.name || 'circle', { xs: 14, sm: 16, md: 20, lg: 24, xl: 32 }[p.size] || p.size || 20) },
|
|
33
19
|
Portal: { render: ({ props: p, children, portal }) => (portal ? portal(children, p.to) : null) },
|
|
34
|
-
LiquidGlass: { render: ({ h, props: p, children }) => h('div', { class: 'zg-liquid', style: { '--zg-liquid-r': sp(p.radius ?? 24), '--zg-liquid-b': sp(p.blur ?? 18) } }, ...children) },
|
|
35
20
|
BottomSheet: { render: ({ h, props: p, children, slots }) => !p.open ? null : h('div', { class: 'zg-modal-scrim zg-sheet-scrim', onClick: p.onClose }, h('div', { class: 'zg-sheet', role: 'dialog', 'aria-modal': 'true', 'aria-label': p.title, ref: trap({ onClose: p.onClose }), style: { maxHeight: sp(p.maxHeight || '85vh') }, onClick: e => e.stopPropagation() },
|
|
36
21
|
h('span', { class: 'zg-sheet__grab', 'aria-hidden': 'true' }), p.title ? h('h3', { class: 'zg-sheet__t' }, p.title) : null, h('div', { class: 'zg-sheet__b' }, ...children), (slots.footer || p.footer) ? h('div', { class: 'zg-sheet__f' }, slots.footer || p.footer) : null)) },
|
|
37
|
-
Actionsheet: { render: ({ C, h, props: p }) => h(C.BottomSheet, { open: p.open, size: p.size, onClose: p.onClose, title: p.title },
|
|
38
|
-
h('div', { class: 'zg-as' }, ...(p.items || []).map((it, i) => h('button', { key: i, type: 'button', class: cx('zg-as__i', it.tone && 'zg-as__i--' + it.tone), disabled: it.disabled, onClick: () => { it.onClick && it.onClick(); p.onSelect && p.onSelect(it); p.onClose && p.onClose(); } }, it.icon ? icon(h, it.icon, 18) : null, h('span', null, it.label)))),
|
|
39
|
-
h('button', { type: 'button', class: 'zg-as__i zg-as__i--cancel', onClick: p.onClose }, p.cancelLabel || t('Actionsheet', 'cancel'))) },
|
|
40
|
-
ImageViewer: { state: { i: null }, render: ({ h, props: p, state, set }) => {
|
|
41
|
-
if (!p.open) return null;
|
|
42
|
-
const im = p.images || [], i = clamp(state.i ?? p.index ?? 0, 0, Math.max(0, im.length - 1)), go = d => set({ i: (i + d + im.length) % im.length });
|
|
43
|
-
return h('div', { class: 'zg-iv', role: 'dialog', 'aria-modal': 'true', 'aria-label': p.alt || t('ImageViewer', 'label'), onClick: p.onClose },
|
|
44
|
-
h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--ghost zg-iv__x', 'aria-label': t('ImageViewer', 'close'), onClick: p.onClose }, icon(h, 'x', 20)),
|
|
45
|
-
im.length > 1 ? h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--ghost zg-iv__p', 'aria-label': t('ImageViewer', 'previous'), onClick: e => { e.stopPropagation(); go(-1); } }, icon(h, 'chevron-left', 22)) : null,
|
|
46
|
-
h('img', { class: 'zg-iv__img', src: im[i], alt: p.alt || '', onClick: e => e.stopPropagation() }),
|
|
47
|
-
im.length > 1 ? h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--ghost zg-iv__n', 'aria-label': t('ImageViewer', 'next'), onClick: e => { e.stopPropagation(); go(1); } }, icon(h, 'chevron-right', 22)) : null,
|
|
48
|
-
h('span', { class: 'zg-badge zg-iv__c' }, `${i + 1} / ${im.length}`)); } },
|
|
49
|
-
ChatAi: { state: { q: '' }, render: ({ h, props: p, state, set }) => {
|
|
50
|
-
const send = () => { const t = state.q.trim(); if (!t || p.loading) return; set({ q: '' }); p.onSend && p.onSend(t); };
|
|
51
|
-
return h('section', { class: 'zg-chat zg-glass', 'aria-label': p.title || t('ChatAi', 'assistant') },
|
|
52
|
-
p.title ? h('div', { class: 'zg-chat__h' }, h('b', null, p.title), p.subtitle ? h('span', { class: 'zg-hint' }, p.subtitle) : null) : null,
|
|
53
|
-
h('div', { class: 'zg-chat__m', role: 'log', 'aria-live': 'polite' }, ...(p.messages || []).map((m, i) => h('div', { key: i, class: cx('zg-chat__b', 'zg-chat__b--' + (m.role === 'user' ? 'user' : 'ai')) }, m.text)), p.loading ? h('div', { class: 'zg-chat__b zg-chat__b--ai zg-chat__dots', 'aria-label': t('ChatAi', 'typing') }, h('i'), h('i'), h('i')) : null),
|
|
54
|
-
h('div', { class: 'zg-chat__f' }, h('input', { class: 'zg-chat__in', value: state.q, placeholder: p.placeholder || t('ChatAi', 'placeholder'), 'aria-label': t('ChatAi', 'message'), onInput: e => set({ q: e.target.value }), onKeydown: e => { if (e.key === 'Enter') { e.preventDefault(); send(); } } }),
|
|
55
|
-
h('button', { type: 'button', class: 'zg-ibtn zg-ibtn--brand', 'aria-label': t('ChatAi', 'send'), disabled: p.loading || !state.q.trim(), onClick: send }, icon(h, 'send', 18)))); } },
|
|
56
22
|
};
|
package/src/core/index.js
CHANGED
|
@@ -7,5 +7,11 @@ import { more6 } from './components6.js';
|
|
|
7
7
|
import { more7 } from './components7.js';
|
|
8
8
|
export const components = { ...base, ...more, ...more3, ...more4, ...more6, ...more7, ...pages };
|
|
9
9
|
export { fmt, setIconBase, rules };
|
|
10
|
+
/** Extension API: adds definitions to the shared registry (used by add-on packages such as @ziyarago/ui-pro). Registering the very same definition twice is a no-op (Vue and React adapters can both load one plugin). */
|
|
11
|
+
export function registerComponents(defs, { override = false } = {}) {
|
|
12
|
+
for (const name of Object.keys(defs)) if (!override && name in components && components[name] !== defs[name]) throw new Error(`@ziyarago/ui: component "${name}" is already registered (pass { override: true } to replace it)`);
|
|
13
|
+
Object.assign(components, defs);
|
|
14
|
+
return components;
|
|
15
|
+
}
|
|
10
16
|
export { LOCALES, FREE_LOCALES, t, setUiLocale, getUiLocale, setUiMessages, isRtlLocale, subscribeUiLocale, getUiVersion, defineMessages } from '../i18n/index.js';
|
|
11
17
|
import '../i18n/components/index.js';
|
package/src/core/pages.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ziyarago/ui · page templates — real slot contracts. Put inside <UiAppShell>, fill only the slots you need.
|
|
2
2
|
// Vue: <UiPageDashboard title="Dashboard"><template #kpis>…</template></UiPageDashboard>
|
|
3
3
|
// React: <UiPageDashboard title="Dashboard" kpis={<…/>} />
|
|
4
|
-
import { cx } from './components.js';
|
|
5
4
|
|
|
6
5
|
const region = (h, id, kids, stick) => (kids == null || (Array.isArray(kids) && !kids.length)) ? null : h('div', { key: id, class: stick ? 'zg-pg__r zg-pg__stick' : 'zg-pg__r', 'data-slot': id }, kids);
|
|
7
6
|
|
|
@@ -15,7 +14,7 @@ const draw = (h, node, ctx) => {
|
|
|
15
14
|
return null;
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
const page = (name, slots, tree) => [name, {
|
|
17
|
+
export const page = (name, slots, tree) => [name, {
|
|
19
18
|
slots,
|
|
20
19
|
render: ({ C, h, props: p, slots: s }) => {
|
|
21
20
|
const header = () => s.header ? region(h, 'header', s.header) : (p.title ? h('div', { class: 'zg-pg__r', 'data-slot': 'header' }, h('div', { class: 'zg-page-head' }, h('div', { style: { flex: 1, minWidth: 0 } }, p.crumbs ? h(C.Breadcrumbs, { items: p.crumbs }) : null, h('h1', null, p.title), p.subtitle ? h('p', null, p.subtitle) : null), s.actions || null)) : (s.actions ? h('div', { class: 'zg-pg__r', 'data-slot': 'header' }, h('div', { class: 'zg-page-head', style: { justifyContent: 'flex-end' } }, s.actions)) : null));
|
|
@@ -25,47 +24,14 @@ const page = (name, slots, tree) => [name, {
|
|
|
25
24
|
|
|
26
25
|
const T = Object.fromEntries([
|
|
27
26
|
page('PageDashboard', ['header', 'hero', 'kpis', 'occupancy', 'funnel', 'top', 'activity'], ['col', 'header', ['auto', 340, 'hero', 'kpis'], ['auto', 360, 'occupancy', 'funnel'], ['auto', 360, 'top', 'activity']]),
|
|
28
|
-
page('PagePatterns', ['header', 'hero', 'strip', 'statlines', 'chartcard', 'tiles', 'listrows', 'countries', 'versus', 'segbar', 'activity', 'actioncard'], ['col', 'header', ['auto', 340, 'hero', 'strip'], 'statlines', ['auto', 360, 'chartcard', 'tiles'], ['auto', 320, 'listrows', 'countries', 'versus'], 'segbar', ['auto', 360, 'activity', 'actioncard']]),
|
|
29
|
-
page('PageCrm', ['header', 'summary', 'filters', 'board', 'calls'], ['col', 'header', 'summary', 'filters', 'board', 'calls']),
|
|
30
|
-
page('PageBookings', ['header', 'stats', 'toolbar', 'bulk', 'table', 'pager'], ['col', 'header', 'stats', 'toolbar', 'bulk', 'table', 'pager']),
|
|
31
|
-
page('PageCatalog', ['header', 'filters', 'toolbar', 'grid', 'pager'], ['col', 'header', ['wrap', ['filters'], ['toolbar', 'grid', 'pager'], 260]]),
|
|
32
|
-
page('PageDetail', ['header', 'gallery', 'summary', 'tabs', 'history', 'booking'], ['col', 'header', ['two', ['gallery', 'summary', 'tabs', 'history'], ['booking']]]),
|
|
33
27
|
page('PageSettings', ['header', 'subnav', 'profile', 'notifications', 'integrations', 'danger'], ['col', 'header', ['wrap', ['subnav'], ['profile', 'notifications', 'integrations', 'danger'], 220]]),
|
|
34
28
|
page('PageUserList', ['header', 'stats', 'filters', 'toolbar', 'table', 'drawer'], ['col', 'header', 'stats', ['two', ['filters', 'toolbar', 'table'], ['drawer']]]),
|
|
35
|
-
page('PageProfile', ['header', 'profile', 'tabs', 'about', 'activity', 'plan'], ['col', 'header', 'profile', 'tabs', ['wrap', ['about'], ['activity', 'plan'], 320]]),
|
|
36
|
-
page('PageForm', ['header', 'main', 'media', 'side', 'actions'], ['col', 'header', ['two', ['main', 'media'], ['side']]]),
|
|
37
|
-
page('PageOrder', ['header', 'status', 'items', 'shipping', 'side'], ['col', 'header', 'status', ['two', ['items', 'shipping'], ['side']]]),
|
|
38
|
-
page('PageAccount', ['header', 'tabs', 'panel'], ['col', 'header', 'tabs', 'panel']),
|
|
39
29
|
page('PagePricing', ['header', 'toggle', 'plans', 'faq'], ['col', 'header', 'toggle', 'plans', 'faq']),
|
|
40
|
-
page('PageFaq', ['header', 'search', 'cats', 'answers', 'contact'], ['col', 'header', 'search', ['wrap', ['cats'], ['answers'], 200], 'contact']),
|
|
41
|
-
page('PageLanding', ['hero', 'logos', 'features', 'proof', 'pricing', 'cta', 'footer'], ['col', 'hero', 'logos', 'features', 'proof', 'pricing', 'cta', 'footer']),
|
|
42
|
-
page('PageOnboarding', ['header', 'progress', 'steps', 'checklist', 'tips'], ['col', 'header', 'progress', ['two', ['steps', 'checklist'], ['tips']]]),
|
|
43
|
-
page('PageCheckout', ['header', 'steps', 'items', 'address', 'payment', 'summary'], ['col', 'header', 'steps', ['two', ['items', 'address', 'payment'], ['summary']]]),
|
|
44
|
-
page('PageInbox', ['header', 'filters', 'list', 'thread', 'composer', 'customer'], ['col', 'header', ['wrap', ['filters', 'list'], [['two', ['thread', 'composer'], ['customer']]], 320]]),
|
|
45
|
-
page('PageNotifications', ['header', 'filters', 'feed', 'empty'], ['col', 'header', 'filters', 'feed', 'empty']),
|
|
46
|
-
page('PageAnalytics', ['header', 'period', 'kpis', 'trend', 'breakdown', 'table'], ['col', 'header', 'period', 'kpis', ['auto', 420, 'trend', 'breakdown'], 'table']),
|
|
47
|
-
page('PageCalendar', ['header', 'toolbar', 'grid', 'mini', 'details'], ['col', 'header', 'toolbar', ['two', ['grid'], ['mini', 'details']]]),
|
|
48
|
-
page('PageKanban', ['header', 'filters', 'board', 'detail'], ['col', 'header', 'filters', ['two', ['board'], ['detail']]]),
|
|
49
|
-
page('PageBilling', ['header', 'plan', 'usage', 'invoices', 'methods', 'upgrade'], ['col', 'header', ['two', ['plan', 'usage', 'invoices'], ['methods', 'upgrade']]]),
|
|
50
|
-
page('PageTeam', ['header', 'stats', 'members', 'roles', 'invite'], ['col', 'header', 'stats', ['two', ['members', 'roles'], ['invite']]]),
|
|
51
|
-
page('PageIntegrations', ['header', 'filters', 'connections', 'keys', 'webhooks'], ['col', 'header', 'filters', 'connections', ['auto', 420, 'keys', 'webhooks']]),
|
|
52
|
-
page('PageSearch', ['header', 'search', 'filters', 'results', 'empty'], ['col', 'header', 'search', ['wrap', ['filters'], ['results', 'empty'], 260]]),
|
|
53
|
-
page('PageArticle', ['header', 'cover', 'body', 'toc', 'share', 'related'], ['col', 'header', 'cover', ['two', ['body', 'share', 'related'], ['toc'], 'sticky:toc']]),
|
|
54
|
-
page('PageChangelog', ['header', 'filters', 'timeline', 'subscribe'], ['col', 'header', ['two', ['filters', 'timeline'], ['subscribe'], 'sticky:subscribe']]),
|
|
55
|
-
page('PageHelp', ['header', 'search', 'categories', 'popular', 'contact'], ['col', 'header', 'search', 'categories', ['auto', 360, 'popular', 'contact']]),
|
|
56
|
-
page('PageStates', ['header', 'empty', 'noresults', 'forbidden', 'offline', 'error', 'loading', 'success'], ['col', 'header', ['auto', 300, 'empty', 'noresults', 'forbidden'], ['auto', 300, 'offline', 'error', 'loading'], 'success']),
|
|
57
|
-
page('PageLegal', ['header', 'meta', 'toc', 'document', 'contact'], ['col', 'header', 'meta', ['wrap', ['toc'], ['document', 'contact'], 260, 'sticky:toc']]),
|
|
58
|
-
page('PageLocations', ['header', 'filters', 'list', 'map'], ['col', 'header', 'filters', ['wrap', ['list'], ['map'], 380, 'sticky:map']]),
|
|
59
|
-
page('PageBookingFlow', ['header', 'steps', 'content', 'nav', 'summary'], ['col', 'header', 'steps', ['two', ['content', 'nav'], ['summary'], 'sticky:summary']]),
|
|
60
|
-
page('PageItinerary', ['header', 'days', 'timeline', 'transport', 'hotel', 'summary'], ['col', 'header', 'days', ['two', ['timeline', 'transport', 'hotel'], ['summary'], 'sticky:summary']]),
|
|
61
|
-
page('PagePrayer', ['header', 'location', 'today', 'month', 'qibla'], ['col', 'header', 'location', ['two', ['today', 'month'], ['qibla'], 'sticky:qibla']]),
|
|
62
|
-
page('PageGroupManager', ['header', 'trip', 'toolbar', 'bulk', 'pilgrims', 'rooms', 'payments'], ['col', 'header', 'trip', ['two', ['toolbar', 'bulk', 'pilgrims', 'rooms'], ['payments'], 'sticky:payments']]),
|
|
63
|
-
page('PageTourPublic', ['header', 'gallery', 'highlights', 'itinerary', 'included', 'reviews', 'booking'], ['col', 'header', 'gallery', ['two', ['highlights', 'itinerary', 'included', 'reviews'], ['booking'], 'sticky:booking']])
|
|
64
30
|
]);
|
|
65
31
|
|
|
66
32
|
T.PageAuth = { slots: ['background', 'logo', 'aside', 'form', 'footer'], render: ({ C, h, props: p, slots: s }) => {
|
|
67
33
|
const body = [s.form || null, s.footer ? h('div', { class: 'zg-pg__r', 'data-slot': 'footer' }, s.footer) : null];
|
|
68
|
-
if (['photo', 'light', 'tint'].includes(p.layout)) return h(C.AuthShowcase, { variant: p.layout, title: p.title, subtitle: p.subtitle, logo: s.logo, footer: s.footer, image: p.image, headline: p.headline, caption: p.caption, quote: p.quote, chips: p.chips, people: p.people, proof: p.proof, proofHint: p.proofHint }, s.form || null);
|
|
34
|
+
if (C.AuthShowcase && ['photo', 'light', 'tint'].includes(p.layout)) return h(C.AuthShowcase, { variant: p.layout, title: p.title, subtitle: p.subtitle, logo: s.logo, footer: s.footer, image: p.image, headline: p.headline, caption: p.caption, quote: p.quote, chips: p.chips, people: p.people, proof: p.proof, proofHint: p.proofHint }, s.form || null);
|
|
69
35
|
return p.layout === 'split'
|
|
70
36
|
? h(C.AuthSplit, { title: p.title, subtitle: p.subtitle, logo: s.logo, aside: s.aside }, ...body)
|
|
71
37
|
: h('div', { class: 'zg-pgauth' }, s.background ? h('div', { class: 'zg-pg__r zg-pgauth__bg', 'data-slot': 'background' }, s.background) : null, h('div', { class: 'zg-pgauth__c' }, h(C.AuthLayout, { title: p.title, subtitle: p.subtitle, logo: s.logo }, ...body)));
|
|
@@ -1,141 +1,69 @@
|
|
|
1
1
|
// generated by scripts/i18n-index.mjs: do not edit
|
|
2
2
|
import { defineMessages } from '../index.js';
|
|
3
|
-
import ActionCard from './ActionCard.js';
|
|
4
|
-
import Actionsheet from './Actionsheet.js';
|
|
5
3
|
import Alert from './Alert.js';
|
|
6
4
|
import Breadcrumbs from './Breadcrumbs.js';
|
|
7
5
|
import Calendar from './Calendar.js';
|
|
8
|
-
import CallCard from './CallCard.js';
|
|
9
|
-
import CallRow from './CallRow.js';
|
|
10
|
-
import Carousel from './Carousel.js';
|
|
11
|
-
import ChartCard from './ChartCard.js';
|
|
12
|
-
import ChatAi from './ChatAi.js';
|
|
13
6
|
import Chip from './Chip.js';
|
|
14
|
-
import ChipInput from './ChipInput.js';
|
|
15
7
|
import CodeInput from './CodeInput.js';
|
|
16
8
|
import Combobox from './Combobox.js';
|
|
17
9
|
import CommandPalette from './CommandPalette.js';
|
|
18
10
|
import ConfirmDialog from './ConfirmDialog.js';
|
|
19
|
-
import ContactPanel from './ContactPanel.js';
|
|
20
11
|
import CopyButton from './CopyButton.js';
|
|
21
|
-
import DataGroup from './DataGroup.js';
|
|
22
12
|
import DataState from './DataState.js';
|
|
23
13
|
import DataTable from './DataTable.js';
|
|
24
14
|
import DatePicker from './DatePicker.js';
|
|
25
|
-
import DealCard from './DealCard.js';
|
|
26
15
|
import Drawer from './Drawer.js';
|
|
27
16
|
import ErrorPage from './ErrorPage.js';
|
|
28
17
|
import FileUpload from './FileUpload.js';
|
|
29
|
-
import FullscreenDialog from './FullscreenDialog.js';
|
|
30
|
-
import Gallery from './Gallery.js';
|
|
31
|
-
import GuestCard from './GuestCard.js';
|
|
32
|
-
import ImageUpload from './ImageUpload.js';
|
|
33
|
-
import ImageViewer from './ImageViewer.js';
|
|
34
|
-
import IncomingCall from './IncomingCall.js';
|
|
35
|
-
import InlineEdit from './InlineEdit.js';
|
|
36
|
-
import IntegrationCard from './IntegrationCard.js';
|
|
37
18
|
import LoginForm from './LoginForm.js';
|
|
38
|
-
import Map from './Map.js';
|
|
39
19
|
import Modal from './Modal.js';
|
|
40
20
|
import MultiSelect from './MultiSelect.js';
|
|
41
|
-
import NotificationBell from './NotificationBell.js';
|
|
42
21
|
import NumberInput from './NumberInput.js';
|
|
43
22
|
import Pagination from './Pagination.js';
|
|
44
23
|
import PasswordInput from './PasswordInput.js';
|
|
45
24
|
import Popconfirm from './Popconfirm.js';
|
|
46
|
-
import PricingCard from './PricingCard.js';
|
|
47
25
|
import Progress from './Progress.js';
|
|
48
|
-
import QiblaCompass from './QiblaCompass.js';
|
|
49
|
-
import RamadanTracker from './RamadanTracker.js';
|
|
50
|
-
import RangeCalendar from './RangeCalendar.js';
|
|
51
|
-
import RangeSlider from './RangeSlider.js';
|
|
52
26
|
import Rating from './Rating.js';
|
|
53
|
-
import RichEditor from './RichEditor.js';
|
|
54
|
-
import Screensaver from './Screensaver.js';
|
|
55
27
|
import SearchInput from './SearchInput.js';
|
|
56
28
|
import SideNav from './SideNav.js';
|
|
57
29
|
import Snackbar from './Snackbar.js';
|
|
58
30
|
import SocialAuth from './SocialAuth.js';
|
|
59
|
-
import Sortable from './Sortable.js';
|
|
60
31
|
import Spinner from './Spinner.js';
|
|
61
32
|
import StatusPage from './StatusPage.js';
|
|
62
|
-
import StepDialog from './StepDialog.js';
|
|
63
|
-
import StepForm from './StepForm.js';
|
|
64
|
-
import TabTiles from './TabTiles.js';
|
|
65
33
|
import Tag from './Tag.js';
|
|
66
34
|
import TopNav from './TopNav.js';
|
|
67
|
-
import Tour from './Tour.js';
|
|
68
|
-
import TourCard from './TourCard.js';
|
|
69
|
-
import TourPopover from './TourPopover.js';
|
|
70
|
-
import TreeSelect from './TreeSelect.js';
|
|
71
35
|
import Validation from './Validation.js';
|
|
72
36
|
|
|
73
|
-
defineMessages('ActionCard', ActionCard);
|
|
74
|
-
defineMessages('Actionsheet', Actionsheet);
|
|
75
37
|
defineMessages('Alert', Alert);
|
|
76
38
|
defineMessages('Breadcrumbs', Breadcrumbs);
|
|
77
39
|
defineMessages('Calendar', Calendar);
|
|
78
|
-
defineMessages('CallCard', CallCard);
|
|
79
|
-
defineMessages('CallRow', CallRow);
|
|
80
|
-
defineMessages('Carousel', Carousel);
|
|
81
|
-
defineMessages('ChartCard', ChartCard);
|
|
82
|
-
defineMessages('ChatAi', ChatAi);
|
|
83
40
|
defineMessages('Chip', Chip);
|
|
84
|
-
defineMessages('ChipInput', ChipInput);
|
|
85
41
|
defineMessages('CodeInput', CodeInput);
|
|
86
42
|
defineMessages('Combobox', Combobox);
|
|
87
43
|
defineMessages('CommandPalette', CommandPalette);
|
|
88
44
|
defineMessages('ConfirmDialog', ConfirmDialog);
|
|
89
|
-
defineMessages('ContactPanel', ContactPanel);
|
|
90
45
|
defineMessages('CopyButton', CopyButton);
|
|
91
|
-
defineMessages('DataGroup', DataGroup);
|
|
92
46
|
defineMessages('DataState', DataState);
|
|
93
47
|
defineMessages('DataTable', DataTable);
|
|
94
48
|
defineMessages('DatePicker', DatePicker);
|
|
95
|
-
defineMessages('DealCard', DealCard);
|
|
96
49
|
defineMessages('Drawer', Drawer);
|
|
97
50
|
defineMessages('ErrorPage', ErrorPage);
|
|
98
51
|
defineMessages('FileUpload', FileUpload);
|
|
99
|
-
defineMessages('FullscreenDialog', FullscreenDialog);
|
|
100
|
-
defineMessages('Gallery', Gallery);
|
|
101
|
-
defineMessages('GuestCard', GuestCard);
|
|
102
|
-
defineMessages('ImageUpload', ImageUpload);
|
|
103
|
-
defineMessages('ImageViewer', ImageViewer);
|
|
104
|
-
defineMessages('IncomingCall', IncomingCall);
|
|
105
|
-
defineMessages('InlineEdit', InlineEdit);
|
|
106
|
-
defineMessages('IntegrationCard', IntegrationCard);
|
|
107
52
|
defineMessages('LoginForm', LoginForm);
|
|
108
|
-
defineMessages('Map', Map);
|
|
109
53
|
defineMessages('Modal', Modal);
|
|
110
54
|
defineMessages('MultiSelect', MultiSelect);
|
|
111
|
-
defineMessages('NotificationBell', NotificationBell);
|
|
112
55
|
defineMessages('NumberInput', NumberInput);
|
|
113
56
|
defineMessages('Pagination', Pagination);
|
|
114
57
|
defineMessages('PasswordInput', PasswordInput);
|
|
115
58
|
defineMessages('Popconfirm', Popconfirm);
|
|
116
|
-
defineMessages('PricingCard', PricingCard);
|
|
117
59
|
defineMessages('Progress', Progress);
|
|
118
|
-
defineMessages('QiblaCompass', QiblaCompass);
|
|
119
|
-
defineMessages('RamadanTracker', RamadanTracker);
|
|
120
|
-
defineMessages('RangeCalendar', RangeCalendar);
|
|
121
|
-
defineMessages('RangeSlider', RangeSlider);
|
|
122
60
|
defineMessages('Rating', Rating);
|
|
123
|
-
defineMessages('RichEditor', RichEditor);
|
|
124
|
-
defineMessages('Screensaver', Screensaver);
|
|
125
61
|
defineMessages('SearchInput', SearchInput);
|
|
126
62
|
defineMessages('SideNav', SideNav);
|
|
127
63
|
defineMessages('Snackbar', Snackbar);
|
|
128
64
|
defineMessages('SocialAuth', SocialAuth);
|
|
129
|
-
defineMessages('Sortable', Sortable);
|
|
130
65
|
defineMessages('Spinner', Spinner);
|
|
131
66
|
defineMessages('StatusPage', StatusPage);
|
|
132
|
-
defineMessages('StepDialog', StepDialog);
|
|
133
|
-
defineMessages('StepForm', StepForm);
|
|
134
|
-
defineMessages('TabTiles', TabTiles);
|
|
135
67
|
defineMessages('Tag', Tag);
|
|
136
68
|
defineMessages('TopNav', TopNav);
|
|
137
|
-
defineMessages('Tour', Tour);
|
|
138
|
-
defineMessages('TourCard', TourCard);
|
|
139
|
-
defineMessages('TourPopover', TourPopover);
|
|
140
|
-
defineMessages('TreeSelect', TreeSelect);
|
|
141
69
|
defineMessages('Validation', Validation);
|
package/src/internal.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Semi-internal entry for add-on packages such as @ziyarago/ui-pro. Not part of the public API: it can change in any minor release.
|
|
2
|
+
// It re-exports the helpers the component definitions are built from, so a plugin does not copy them.
|
|
3
|
+
export { cx, pick, INPUT_ATTRS, DZ, dzp, dzf, dzb, ddRef, icon, fmt } from './core/components.js';
|
|
4
|
+
export { trap, life } from './core/dialog.js';
|
|
5
|
+
export { rove, tabIdx, listKeys, openKeys, focusIn, toTrigger, trigger } from './core/keys.js';
|
|
6
|
+
export { rules } from './core/components4.js';
|
|
7
|
+
export { page } from './core/pages.js';
|
|
8
|
+
export { t, getUiLocale, intlLocale, defineMessages } from './i18n/index.js';
|
|
9
|
+
export { registerComponents, components } from './core/index.js';
|
|
10
|
+
export { BOOL_PROPS } from './core/bools.js';
|
package/src/meta/index.js
CHANGED
|
@@ -11,4 +11,19 @@ import domain from './domain.js';
|
|
|
11
11
|
import pages from './pages.js';
|
|
12
12
|
|
|
13
13
|
export const meta = { ...typography, ...layout, ...actions, ...forms, ...data, ...feedback, ...overlay, ...navigation, ...media, ...domain, ...pages };
|
|
14
|
+
import { PRO_NAMES } from './tiers.js';
|
|
15
|
+
export { PRO, PRO_NAMES, isPro } from './tiers.js';
|
|
16
|
+
export { GROUPS } from './groups.js';
|
|
17
|
+
import { GROUPS } from './groups.js';
|
|
18
|
+
/** Extension API: adds API metadata for plugin components. `tiers` marks names as Pro, `groups` ({ id, title, blurb, names }) lists them in the manifest. */
|
|
19
|
+
export function registerMeta(extra, { tiers, groups } = {}) {
|
|
20
|
+
Object.assign(meta, extra);
|
|
21
|
+
for (const n of tiers || []) PRO_NAMES.add(n);
|
|
22
|
+
for (const g of groups || []) {
|
|
23
|
+
const ex = GROUPS.find(x => x.id === g.id);
|
|
24
|
+
if (ex) ex.names.push(...g.names.filter(n => !ex.names.includes(n)));
|
|
25
|
+
else GROUPS.push({ blurb: '', title: g.id, ...g, names: [...g.names] });
|
|
26
|
+
}
|
|
27
|
+
return meta;
|
|
28
|
+
}
|
|
14
29
|
export default meta;
|
package/src/meta/pages.js
CHANGED
|
@@ -481,7 +481,7 @@ export default {
|
|
|
481
481
|
PageAuth: {
|
|
482
482
|
description: 'Sign-in page template without the app shell, as a centered card or a split layout.',
|
|
483
483
|
props: {
|
|
484
|
-
layout: { forwarded: true, type: "'card' | 'split' | 'photo' | 'light' | 'tint'", values: ['card', 'split', 'photo', 'light', 'tint'], default: 'card', description: "'split' uses AuthSplit with a side panel. 'photo', 'light' and 'tint' use AuthShowcase with a media panel. Anything else renders a centered AuthLayout card over the background." },
|
|
484
|
+
layout: { forwarded: true, type: "'card' | 'split' | 'photo' | 'light' | 'tint'", values: ['card', 'split', 'photo', 'light', 'tint'], default: 'card', description: "'split' uses AuthSplit with a side panel. 'photo', 'light' and 'tint' use AuthShowcase with a media panel (Pro: needs @ziyarago/ui-pro, otherwise they fall back to the centered card). Anything else renders a centered AuthLayout card over the background." },
|
|
485
485
|
image: { forwarded: true, type: 'string', description: 'Media image URL; photo, light and tint layouts.' },
|
|
486
486
|
headline: { forwarded: true, type: 'string', description: 'Large text on the media panel; photo and tint.' },
|
|
487
487
|
caption: { forwarded: true, type: 'string', description: 'Small text on the media panel or glass bar.' },
|
package/src/nuxt/module.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// Nuxt 3/4 module. nuxt.config: modules: ['@ziyarago/ui/nuxt'], ziyarago: { theme: true }
|
|
2
2
|
import { defineNuxtModule, addComponent, addImports, addPlugin, createResolver } from '@nuxt/kit';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
3
4
|
import { components } from '../core/index.js';
|
|
4
5
|
import { themeInitScript } from '../theme.js';
|
|
5
6
|
|
|
6
7
|
export default defineNuxtModule({
|
|
7
8
|
meta: { name: '@ziyarago/ui', configKey: 'ziyarago', compatibility: { nuxt: '>=3.0.0' } },
|
|
8
|
-
defaults: { css: true, prefix: 'Ui', theme: { theme: 'dark', palette: 'gold', dir: 'ltr', bg: 'none', locale: 'en' } },
|
|
9
|
+
defaults: { css: true, plugins: [], prefix: 'Ui', theme: { theme: 'dark', palette: 'gold', dir: 'ltr', bg: 'none', locale: 'en' } },
|
|
9
10
|
setup(opts, nuxt) {
|
|
10
11
|
const { resolve } = createResolver(import.meta.url);
|
|
11
12
|
if (opts.css) nuxt.options.css.push('@ziyarago/ui/style.css');
|
|
@@ -13,6 +14,13 @@ export default defineNuxtModule({
|
|
|
13
14
|
for (const name of Object.keys(components)) {
|
|
14
15
|
addComponent({ name: opts.prefix + name, export: opts.prefix + name, filePath: '@ziyarago/ui/vue' });
|
|
15
16
|
}
|
|
17
|
+
for (const pkg of opts.plugins) {
|
|
18
|
+
nuxt.options.build.transpile.push(pkg);
|
|
19
|
+
let names = [];
|
|
20
|
+
try { names = createRequire(import.meta.url)(pkg + '/names'); } catch { try { names = createRequire(nuxt.options.rootDir + '/')(pkg + '/names'); } catch { console.warn(`[@ziyarago/ui] plugin ${pkg}: cannot load ${pkg}/names`); } }
|
|
21
|
+
for (const name of names) addComponent({ name: opts.prefix + name, export: 'Ui' + name, filePath: pkg + '/vue' });
|
|
22
|
+
if (opts.css) nuxt.options.css.push(pkg + '/style.css');
|
|
23
|
+
}
|
|
16
24
|
addImports([
|
|
17
25
|
{ name: 'useUiTheme', from: '@ziyarago/ui/theme' },
|
|
18
26
|
{ name: 'fmt', from: '@ziyarago/ui/vue' },
|