@meddleware/ui 0.1.12 → 0.1.13
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/README.md +25 -4
- package/dist/base.css +1 -1
- package/dist/components/AppFooter.vue.d.ts +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/safe-href.d.ts +8 -0
- package/dist/status.d.ts +4 -2
- package/dist/ui.js +145 -91
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @meddleware/ui
|
|
2
2
|
|
|
3
|
-
Shared Vue 3 component library for the `@meddleware` UIs. Delivers a layout shell (header, sidebar, footer), colour-mode control, and UI primitives — all styled with [`@meddleware/design-tokens`](https://www.npmjs.com/package/@meddleware/design-tokens)
|
|
3
|
+
Shared Vue 3 component library for the `@meddleware` UIs. Delivers a layout shell (header, sidebar, footer), colour-mode control, and UI primitives — all styled with [`@meddleware/design-tokens`](https://www.npmjs.com/package/@meddleware/design-tokens): a warm-neutral canvas with functional primary/rainbow accents, sacred-geometry (φ/Fibonacci) type + spacing scales, and optional seasonal theming.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -14,18 +14,39 @@ yarn add @meddleware/ui @meddleware/design-tokens
|
|
|
14
14
|
|
|
15
15
|
## Setup
|
|
16
16
|
|
|
17
|
-
Import
|
|
17
|
+
Import the CSS once at your application entry point:
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
// src/main.ts (or equivalent)
|
|
21
|
-
import '@meddleware/design-tokens/tokens.css'
|
|
22
|
-
import '@meddleware/
|
|
21
|
+
import '@meddleware/design-tokens/tokens.css' // required — registers CSS custom properties
|
|
22
|
+
import '@meddleware/design-tokens/seasons.css' // optional — enables data-season theming
|
|
23
|
+
import '@meddleware/ui/base.css' // optional — element defaults + scale + utilities
|
|
23
24
|
import { createApp } from 'vue'
|
|
24
25
|
import App from './App.vue'
|
|
25
26
|
|
|
26
27
|
createApp(App).mount('#app')
|
|
27
28
|
```
|
|
28
29
|
|
|
30
|
+
## Styling, scales & utilities
|
|
31
|
+
|
|
32
|
+
Components consume the design-token **role** tokens (`--accent`, `--warning`, `--focus-ring`, …) and
|
|
33
|
+
the **sacred-geometry scales** (`--space-*`, `--font-size-*`, `--leading-*`, `--tracking-*`) — never
|
|
34
|
+
colour-named or magic-number values. Focus states use the dedicated `--focus-ring` (blue) so they are
|
|
35
|
+
always visible and never read as an error. Component **props and accessibility are unchanged** by the
|
|
36
|
+
theming system — only the styling tokens they resolve to.
|
|
37
|
+
|
|
38
|
+
`base.css` also ships opt-in utilities (respecting `prefers-reduced-motion`):
|
|
39
|
+
|
|
40
|
+
| Utility | Purpose |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `.mw-noise` | Subtle CSS-native SVG-noise background layer (controlled imperfection over flat polish). |
|
|
43
|
+
| `.mw-mono` | Monospace font (`--mw-font-mono`). |
|
|
44
|
+
| `.mw-spinner` | Sigil-like ring loader that settles into a simple form. |
|
|
45
|
+
| `.mw-hand-drawn` | Empty positioned **placeholder hook** for bespoke hand-drawn SVG/canvas added later — drop an `<svg>`/`<canvas>` inside, or target `.mw-hand-drawn > svg` from your app. |
|
|
46
|
+
|
|
47
|
+
Seasonal theming is entirely in `@meddleware/design-tokens` (import `seasons.css` + set
|
|
48
|
+
`data-season`); the components pick it up automatically through the role tokens.
|
|
49
|
+
|
|
29
50
|
## Exports
|
|
30
51
|
|
|
31
52
|
### Layout shell
|
package/dist/base.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
*,:before,:after{box-sizing:border-box}html,body{margin:0;padding:0}body{background:var(--bg);min-height:100vh;color:var(--text);font-family:var(--mw-font-sans);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;font-size:16px;line-height:1.55}:where(ul,ol):where([role=list],[role=listitem]){margin:0;padding:0;list-style:none}:where(img,svg,video,canvas){max-width:100%;display:block}:where(fieldset){border:0;margin:0;padding:0}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}:where(button,input,select,textarea){font-family:inherit}:where(a,button,input,select,textarea):focus-visible{outline:2px solid var(--accent);outline-offset:2px}.mw-mono{font-family:var(--mw-font-mono)}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.001ms!important;animation-duration:.001ms!important}}.mw-header[data-v-ad7cd1c5]{height:var(--mw-header-height,56px);background:var(--_bg);color:var(--_text);border-bottom:1px solid var(--_border);font-family:var(--mw-font-sans);align-items:center;gap:1rem;padding:0 1rem;display:flex}.mw-header--sticky[data-v-ad7cd1c5]{z-index:50;position:sticky;top:0}.mw-header__brand[data-v-ad7cd1c5]{letter-spacing:.01em;white-space:nowrap;align-items:center;gap:.5rem;font-weight:650;display:flex}.mw-header__center[data-v-ad7cd1c5]{flex:auto;min-width:0}.mw-header__actions[data-v-ad7cd1c5]{align-items:center;gap:.5rem;margin-left:auto;display:flex}.mw-sidebar[data-v-23c3c7f3]{height:100%;width:var(--mw-sidebar-width,240px);background:var(--_bg);color:var(--_text);border-right:1px solid var(--_border);font-family:var(--mw-font-sans);flex-direction:column;display:flex}.mw-sidebar__head[data-v-23c3c7f3]{border-bottom:1px solid var(--_border);padding:1rem}.mw-sidebar__nav[data-v-23c3c7f3]{flex-direction:column;flex:auto;gap:.25rem;padding:.75rem;display:flex;overflow-y:auto}.mw-sidebar__body[data-v-23c3c7f3]{flex-shrink:0}.mw-sidebar__foot[data-v-23c3c7f3]{border-top:1px solid var(--_border);color:var(--_muted);padding:.75rem 1rem;font-size:.85rem}.mw-footer[data-v-88269247]{background:var(--_bg);color:var(--_muted);border-top:1px solid var(--_border);font-family:var(--mw-font-sans);flex-wrap:wrap;align-items:center;gap:1rem;padding:.75rem 1rem;font-size:.85rem;display:flex}.mw-footer--transparent[data-v-88269247]{border-top:1px solid var(--border)}.mw-footer__center[data-v-88269247]{flex:auto;min-width:0}.mw-footer__end[data-v-88269247]{align-items:center;gap:1rem;margin-left:auto;display:flex}.mw-footer__docs-link[data-v-88269247]{color:inherit;text-underline-offset:2px;opacity:.7;text-decoration:underline}.mw-footer__docs-link[data-v-88269247]:hover{opacity:1}.mw-mode[data-v-186f8312]{border:1px solid var(--_border,var(--border));border-radius:var(--mw-radius,10px);background:color-mix(in srgb, var(--_text,var(--text)) 6%, transparent);gap:2px;padding:2px;display:inline-flex}.mw-mode__btn[data-v-186f8312]{border-radius:calc(var(--mw-radius,10px) - 3px);color:var(--_text,var(--text));font:inherit;cursor:pointer;opacity:.7;background:0 0;border:0;align-items:center;gap:.35rem;padding:.25rem .5rem;font-size:.8rem;display:inline-flex}.mw-mode__btn[data-v-186f8312]:hover{opacity:1}.mw-mode__btn.is-active[data-v-186f8312]{opacity:1;background:color-mix(in srgb, var(--_text,var(--text)) 14%, transparent)}.mw-mode__btn[data-v-186f8312]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}@media (width<=640px){.mw-mode__label[data-v-186f8312]{display:none}}.mw-btn[data-v-299de2c3]{border-radius:var(--mw-radius,10px);font:inherit;cursor:pointer;border:1px solid #0000;justify-content:center;align-items:center;gap:.4rem;padding:.5rem .9rem;font-weight:550;transition:filter .12s,background .12s;display:inline-flex}.mw-btn[data-v-299de2c3]:disabled{opacity:.55;cursor:not-allowed}.mw-btn[data-v-299de2c3]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.mw-btn--primary[data-v-299de2c3]{background:var(--accent);color:var(--accent-contrast)}.mw-btn--primary[data-v-299de2c3]:not(:disabled):hover{filter:brightness(1.08)}.mw-btn--secondary[data-v-299de2c3]{background:var(--secondary);color:var(--secondary-contrast)}.mw-btn--secondary[data-v-299de2c3]:not(:disabled):hover{filter:brightness(1.08)}.mw-btn--ghost[data-v-299de2c3]{color:var(--text);border-color:var(--border);background:0 0}.mw-btn--ghost[data-v-299de2c3]:not(:disabled):hover{background:var(--lift)}.mw-btn--danger[data-v-299de2c3]{background:var(--danger);color:var(--mw-neutral-000)}.mw-btn--danger[data-v-299de2c3]:not(:disabled):hover{filter:brightness(1.08)}.mw-card[data-v-fd2fd7ab]{background:var(--surface);border:1px solid var(--border);border-radius:var(--mw-radius,10px);color:var(--text);overflow:hidden}.mw-card__header[data-v-fd2fd7ab]{border-bottom:1px solid var(--border);padding:.85rem 1rem}.mw-card__title[data-v-fd2fd7ab]{margin:0;font-size:1rem;font-weight:600}.mw-card__body[data-v-fd2fd7ab]{padding:1rem}.mw-card__footer[data-v-fd2fd7ab]{border-top:1px solid var(--border);background:var(--lift);padding:.75rem 1rem}.mw-select[data-v-b9468387]{position:relative}.mw-select select[data-v-b9468387]{appearance:none;background:var(--surface);width:100%;color:var(--text);border:1px solid var(--border);border-radius:var(--mw-radius,10px);font:inherit;padding:.5rem 2.5rem .5rem .7rem}.mw-select select[data-v-b9468387]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.mw-select__chevron[data-v-b9468387]{pointer-events:none;stroke:var(--muted);stroke-width:1.5px;fill:none;position:absolute;top:50%;right:.75rem;transform:translateY(-50%)}.mw-notice[data-v-6f53d0be]{border:1px solid var(--border);border-radius:var(--mw-radius,10px);background:var(--lift);color:var(--text);border-left-width:3px;margin:0;padding:.6rem .8rem;font-size:.9rem}.mw-notice--error[data-v-6f53d0be]{border-left-color:var(--danger);color:var(--danger);background:color-mix(in srgb, var(--danger) 8%, transparent)}.mw-notice--ok[data-v-6f53d0be]{border-left-color:var(--ok);color:var(--ok);background:color-mix(in srgb, var(--ok) 8%, transparent)}.sidebar-item[data-v-cc70da78]{border-radius:var(--mw-radius,10px);width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;opacity:.85;background:0 0;border:0;align-items:center;gap:.6rem;padding:.55rem .7rem;display:flex}.sidebar-item[data-v-cc70da78]:hover:not(:disabled){background:color-mix(in srgb, currentColor 10%, transparent);opacity:1}.sidebar-item.is-active[data-v-cc70da78]{background:color-mix(in srgb, var(--accent) 26%, transparent);opacity:1}.sidebar-item[data-v-cc70da78]:disabled{cursor:default}.sidebar-item[data-v-cc70da78]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.sidebar-item__icon[data-v-cc70da78]{text-align:center;width:1.1rem}.mw-tab-nav[data-v-7c93ad15]{border-bottom:2px solid var(--border);gap:.25rem;display:flex}.mw-tab-nav__tab[data-v-7c93ad15]{appearance:none;cursor:pointer;color:var(--muted);background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-2px;padding:.5rem 1rem;font-size:.95rem;transition:color .1s,border-color .1s}.mw-tab-nav__tab[data-v-7c93ad15]:hover{color:var(--text)}.mw-tab-nav__tab--active[data-v-7c93ad15]{border-bottom-color:var(--accent);color:var(--text);font-weight:600}.ca-root[data-v-08c3420b]{align-items:center;gap:.35em;display:inline-flex}.ca-value[data-v-08c3420b]{font-family:monospace;font-size:inherit}.ca-copy[data-v-08c3420b]{color:var(--muted,#888);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;line-height:1;transition:color .15s;display:inline-flex}.ca-copy[data-v-08c3420b]:hover{color:var(--text,#f0f0f0)}.ca-copy--copied[data-v-08c3420b]{color:var(--accent,#6366f1)}.ca-icon[data-v-08c3420b]{display:block}.el-root[data-v-7a44607e]{font-family:monospace;font-size:inherit;color:var(--accent,#6366f1);text-underline-offset:2px;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;transition:color .15s}.el-root[data-v-7a44607e]:hover{color:var(--text,#f0f0f0);text-decoration-style:solid}.status-widget[data-v-20197983]{color:inherit;opacity:.85;align-items:center;gap:.4rem;font-size:.8rem;text-decoration:none;display:inline-flex}.status-widget[data-v-20197983]:hover{opacity:1}.status-widget__dot[data-v-20197983]{border-radius:50%;flex-shrink:0;width:.55rem;height:.55rem}.status-widget--ok .status-widget__dot[data-v-20197983]{background:var(--mw-ok-500)}.status-widget--degraded .status-widget__dot[data-v-20197983]{background:var(--mw-gold-500)}.status-widget--error .status-widget__dot[data-v-20197983]{background:var(--mw-danger-500)}
|
|
1
|
+
*,:before,:after{box-sizing:border-box}html,body{margin:0;padding:0}body{background:var(--bg);min-height:100vh;color:var(--text);font-family:var(--mw-font-sans);font-size:var(--font-size-base);line-height:var(--leading-normal);letter-spacing:var(--tracking-normal);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility}:where(ul,ol):where([role=list],[role=listitem]){margin:0;padding:0;list-style:none}:where(img,svg,video,canvas){max-width:100%;display:block}:where(fieldset){border:0;margin:0;padding:0}a{color:var(--accent);transition:color var(--transition-base);text-decoration:none}a:hover{text-decoration:underline}:where(button,input,select,textarea){font-family:inherit}:where(a,button,input,select,textarea):focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}.mw-mono{font-family:var(--mw-font-mono)}.mw-noise{isolation:isolate;position:relative}.mw-noise:before{content:"";z-index:-1;background-image:var(--noise-overlay);opacity:var(--noise-opacity);pointer-events:none;background-repeat:repeat;position:absolute;inset:0}.mw-hand-drawn{display:inline-flex;position:relative}.mw-spinner{width:var(--space-sm);height:var(--space-sm);border:2px solid var(--border);border-top-color:var(--accent);animation:mw-spin var(--transition-slow) linear infinite;border-radius:50%;display:inline-block}@keyframes mw-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.001ms!important;animation-duration:.001ms!important}.mw-spinner{border-top-color:var(--accent);animation:none}}.mw-header[data-v-9b9826d5]{align-items:center;gap:var(--space-sm);height:var(--mw-header-height,56px);padding:0 var(--space-sm);background:var(--_bg);color:var(--_text);border-bottom:1px solid var(--_border);font-family:var(--mw-font-sans);display:flex}.mw-header--sticky[data-v-9b9826d5]{z-index:50;position:sticky;top:0}.mw-header__brand[data-v-9b9826d5]{align-items:center;gap:var(--space-2xs);letter-spacing:var(--tracking-wide);white-space:nowrap;font-weight:650;display:flex}.mw-header__center[data-v-9b9826d5]{flex:auto;min-width:0}.mw-header__actions[data-v-9b9826d5]{align-items:center;gap:var(--space-2xs);margin-left:auto;display:flex}.mw-sidebar[data-v-a2b8405c]{height:100%;width:var(--mw-sidebar-width,240px);background:var(--_bg);color:var(--_text);border-right:1px solid var(--_border);font-family:var(--mw-font-sans);flex-direction:column;display:flex}.mw-sidebar__head[data-v-a2b8405c]{padding:var(--space-sm);border-bottom:1px solid var(--_border)}.mw-sidebar__nav[data-v-a2b8405c]{gap:var(--space-3xs);padding:var(--space-xs);flex-direction:column;flex:auto;display:flex;overflow-y:auto}.mw-sidebar__body[data-v-a2b8405c]{flex-shrink:0}.mw-sidebar__foot[data-v-a2b8405c]{padding:var(--space-xs) var(--space-sm);border-top:1px solid var(--_border);color:var(--_muted);font-size:var(--font-size-sm)}.mw-footer[data-v-979579a9]{align-items:center;gap:var(--space-sm);padding:var(--space-xs) var(--space-sm);background:var(--_bg);color:var(--_muted);border-top:1px solid var(--_border);font-family:var(--mw-font-sans);font-size:var(--font-size-sm);flex-wrap:wrap;display:flex}.mw-footer--transparent[data-v-979579a9]{border-top:1px solid var(--border)}.mw-footer__center[data-v-979579a9]{flex:auto;min-width:0}.mw-footer__end[data-v-979579a9]{align-items:center;gap:var(--space-sm);margin-left:auto;display:flex}.mw-footer__docs-link[data-v-979579a9]{color:inherit;text-underline-offset:2px;opacity:.7;text-decoration:underline}.mw-footer__docs-link[data-v-979579a9]:hover{opacity:1}.mw-mode[data-v-e2ea0d79]{border:1px solid var(--_border,var(--border));border-radius:var(--radius);background:color-mix(in srgb, var(--_text,var(--text)) 6%, transparent);gap:2px;padding:2px;display:inline-flex}.mw-mode__btn[data-v-e2ea0d79]{align-items:center;gap:var(--space-3xs);padding:var(--space-3xs) var(--space-2xs);border-radius:calc(var(--radius) - 3px);color:var(--_text,var(--text));font:inherit;font-size:var(--font-size-sm);cursor:pointer;opacity:.7;transition:opacity var(--transition-base), background var(--transition-base);background:0 0;border:0;display:inline-flex}.mw-mode__btn[data-v-e2ea0d79]:hover{opacity:1}.mw-mode__btn.is-active[data-v-e2ea0d79]{opacity:1;background:color-mix(in srgb, var(--_text,var(--text)) 14%, transparent)}.mw-mode__btn[data-v-e2ea0d79]:focus-visible{outline:2px solid var(--focus-ring);outline-offset:1px}@media (width<=640px){.mw-mode__label[data-v-e2ea0d79]{display:none}}.mw-btn[data-v-bc33cc23]{justify-content:center;align-items:center;gap:var(--space-2xs);padding:var(--space-2xs) var(--space-xs);border-radius:var(--radius);font:inherit;cursor:pointer;transition:filter var(--transition-base), background var(--transition-base);border:1px solid #0000;font-weight:550;display:inline-flex}.mw-btn[data-v-bc33cc23]:disabled{opacity:.55;cursor:not-allowed}.mw-btn[data-v-bc33cc23]:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}.mw-btn--primary[data-v-bc33cc23]{background:var(--accent);color:var(--accent-contrast)}.mw-btn--primary[data-v-bc33cc23]:not(:disabled):hover{filter:brightness(1.08)}.mw-btn--secondary[data-v-bc33cc23]{background:var(--secondary);color:var(--secondary-contrast)}.mw-btn--secondary[data-v-bc33cc23]:not(:disabled):hover{filter:brightness(1.08)}.mw-btn--ghost[data-v-bc33cc23]{color:var(--text);border-color:var(--border);background:0 0}.mw-btn--ghost[data-v-bc33cc23]:not(:disabled):hover{background:var(--lift)}.mw-btn--danger[data-v-bc33cc23]{background:var(--danger);color:var(--accent-contrast)}.mw-btn--danger[data-v-bc33cc23]:not(:disabled):hover{filter:brightness(1.08)}.mw-card[data-v-883f87f5]{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);color:var(--text);overflow:hidden}.mw-card__header[data-v-883f87f5]{padding:var(--space-xs) var(--space-sm);border-bottom:1px solid var(--border)}.mw-card__title[data-v-883f87f5]{font-size:var(--font-size-base);margin:0;font-weight:600}.mw-card__body[data-v-883f87f5]{padding:var(--space-sm)}.mw-card__footer[data-v-883f87f5]{padding:var(--space-xs) var(--space-sm);border-top:1px solid var(--border);background:var(--lift)}.mw-select[data-v-7e206184]{position:relative}.mw-select select[data-v-7e206184]{appearance:none;width:100%;padding:var(--space-2xs) calc(var(--space-md) + var(--space-2xs)) var(--space-2xs) var(--space-xs);background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:var(--radius);font:inherit}.mw-select select[data-v-7e206184]:focus-visible{outline:2px solid var(--focus-ring);outline-offset:1px}.mw-select__chevron[data-v-7e206184]{right:var(--space-xs);pointer-events:none;stroke:var(--muted);stroke-width:1.5px;fill:none;position:absolute;top:50%;transform:translateY(-50%)}.mw-notice[data-v-ee7fffb1]{padding:var(--space-2xs) var(--space-xs);border:1px solid var(--border);border-radius:var(--radius);background:var(--lift);color:var(--text);font-size:var(--font-size-sm);border-left-width:3px;margin:0}.mw-notice--error[data-v-ee7fffb1]{border-left-color:var(--danger);color:var(--danger);background:color-mix(in srgb, var(--danger) 8%, transparent)}.mw-notice--ok[data-v-ee7fffb1]{border-left-color:var(--ok);color:var(--ok);background:color-mix(in srgb, var(--ok) 8%, transparent)}.sidebar-item[data-v-8da2d583]{align-items:center;gap:var(--space-2xs);width:100%;padding:var(--space-2xs) var(--space-xs);border-radius:var(--radius);color:inherit;font:inherit;text-align:left;cursor:pointer;opacity:.85;transition:background var(--transition-base), opacity var(--transition-base);background:0 0;border:0;display:flex}.sidebar-item[data-v-8da2d583]:hover:not(:disabled){background:color-mix(in srgb, currentColor 10%, transparent);opacity:1}.sidebar-item.is-active[data-v-8da2d583]{background:color-mix(in srgb, var(--accent) 26%, transparent);opacity:1}.sidebar-item[data-v-8da2d583]:disabled{cursor:default}.sidebar-item[data-v-8da2d583]:focus-visible{outline:2px solid var(--focus-ring);outline-offset:1px}.sidebar-item__icon[data-v-8da2d583]{text-align:center;width:1.1rem}.mw-tab-nav[data-v-97d31503]{gap:var(--space-3xs);border-bottom:2px solid var(--border);display:flex}.mw-tab-nav__tab[data-v-97d31503]{appearance:none;padding:var(--space-2xs) var(--space-sm);cursor:pointer;font-size:var(--font-size-base);color:var(--muted);transition:color var(--transition-base), border-color var(--transition-base);background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-2px}.mw-tab-nav__tab[data-v-97d31503]:hover{color:var(--text)}.mw-tab-nav__tab--active[data-v-97d31503]{border-bottom-color:var(--accent);color:var(--text);font-weight:600}.ca-root[data-v-b43dabdd]{align-items:center;gap:.35em;display:inline-flex}.ca-value[data-v-b43dabdd]{font-family:var(--mw-font-mono,monospace);font-size:inherit}.ca-copy[data-v-b43dabdd]{color:var(--muted,#888);cursor:pointer;transition:color var(--transition-base);background:0 0;border:none;justify-content:center;align-items:center;padding:0;line-height:1;display:inline-flex}.ca-copy[data-v-b43dabdd]:hover{color:var(--text,#f0f0f0)}.ca-copy--copied[data-v-b43dabdd]{color:var(--accent,#6366f1)}.ca-icon[data-v-b43dabdd]{display:block}.el-root[data-v-073d1bbe]{font-family:monospace;font-size:inherit;color:var(--accent,#6366f1);text-underline-offset:2px;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;transition:color .15s}.el-root[data-v-073d1bbe]:hover{color:var(--text,#f0f0f0);text-decoration-style:solid}.status-widget[data-v-6436368e]{align-items:center;gap:var(--space-2xs);color:inherit;font-size:var(--font-size-sm);opacity:.85;transition:opacity var(--transition-base);text-decoration:none;display:inline-flex}.status-widget[data-v-6436368e]:hover{opacity:1}.status-widget__dot[data-v-6436368e]{width:var(--space-2xs);height:var(--space-2xs);border-radius:50%;flex-shrink:0}.status-widget--ok .status-widget__dot[data-v-6436368e]{background:var(--ok)}.status-widget--degraded .status-widget__dot[data-v-6436368e]{background:var(--warning)}.status-widget--error .status-widget__dot[data-v-6436368e]{background:var(--danger)}
|
|
2
2
|
/*$vite$:1*/
|
|
@@ -9,6 +9,11 @@ type __VLS_Props = {
|
|
|
9
9
|
* Use `VITE_DOCS_URL` in the consuming app to make this configurable per deployment.
|
|
10
10
|
*/
|
|
11
11
|
docsUrl?: string;
|
|
12
|
+
/**
|
|
13
|
+
* When set, renders a "Developer docs" link pointing at this URL.
|
|
14
|
+
* Use `VITE_DEV_URL` in the consuming app to make this configurable per deployment.
|
|
15
|
+
*/
|
|
16
|
+
devUrl?: string;
|
|
12
17
|
};
|
|
13
18
|
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
|
|
14
19
|
type __VLS_Slots = {} & {
|
package/dist/index.d.ts
CHANGED
|
@@ -19,4 +19,5 @@ export { useColorMode } from './composables/useColorMode.js';
|
|
|
19
19
|
export type { ColorMode } from './composables/useColorMode.js';
|
|
20
20
|
export type { PanelVariant, PanelColors } from './internal/panel.js';
|
|
21
21
|
export { isStatusLevel, parseSnapshot } from './status.js';
|
|
22
|
+
export { safeHref } from './safe-href.js';
|
|
22
23
|
export type { StatusLevel, StatusComponent, StatusGroup, StatusSnapshot } from './status.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate a consumer-supplied URL before binding it to an `href` attribute.
|
|
3
|
+
*
|
|
4
|
+
* Allows `https:` (all hosts) and `http:` on `localhost`/`127.0.0.1` (dev only).
|
|
5
|
+
* Returns `undefined` for `javascript:`, `data:`, or any other disallowed scheme so Vue
|
|
6
|
+
* renders no `href` attribute rather than a potentially-executable link.
|
|
7
|
+
*/
|
|
8
|
+
export declare function safeHref(url: string | undefined | null): string | undefined;
|
package/dist/status.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ export interface StatusSnapshot {
|
|
|
21
21
|
export declare function isStatusLevel(s: unknown): s is StatusLevel;
|
|
22
22
|
/**
|
|
23
23
|
* Parse and validate a raw API response as a `StatusSnapshot`.
|
|
24
|
-
* Returns `null` if the required fields are absent or have unexpected types
|
|
25
|
-
*
|
|
24
|
+
* Returns `null` if the required top-level fields are absent or have unexpected types.
|
|
25
|
+
* Per-group and per-component fields are sanitized: unknown status values are coerced to
|
|
26
|
+
* `'unknown'`; name fields are stripped of HTML-sensitive characters. Groups or components
|
|
27
|
+
* with empty/missing names are dropped.
|
|
26
28
|
*/
|
|
27
29
|
export declare function parseSnapshot(raw: unknown): StatusSnapshot | null;
|
package/dist/ui.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, createTextVNode as a, defineComponent as o, mergeProps as s, normalizeClass as c, normalizeStyle as l, onMounted as
|
|
1
|
+
import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, createTextVNode as a, defineComponent as o, mergeProps as s, normalizeClass as c, normalizeStyle as l, onMounted as ee, onUnmounted as te, openBlock as u, ref as d, renderList as f, renderSlot as p, toDisplayString as m, unref as h, useModel as g, vModelSelect as ne, watch as re, withDirectives as ie } from "vue";
|
|
2
2
|
//#region src/internal/panel.ts
|
|
3
|
-
function
|
|
3
|
+
function _(e, t) {
|
|
4
4
|
let n;
|
|
5
5
|
return n = e === "transparent" ? {
|
|
6
6
|
"--_bg": "transparent",
|
|
@@ -35,33 +35,33 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
setup(e) {
|
|
38
|
-
let n = e, a = t(() =>
|
|
39
|
-
return (t, n) => (
|
|
38
|
+
let n = e, a = t(() => _(n.variant, n.colors));
|
|
39
|
+
return (t, n) => (u(), r("header", {
|
|
40
40
|
class: c(["mw-header", [`mw-header--${e.variant}`, { "mw-header--sticky": e.sticky }]]),
|
|
41
41
|
style: l(a.value)
|
|
42
42
|
}, [
|
|
43
|
-
i("div", ae, [
|
|
44
|
-
i("div", oe, [
|
|
45
|
-
i("div", se, [
|
|
43
|
+
i("div", ae, [p(t.$slots, "brand", {}, void 0, !0)]),
|
|
44
|
+
i("div", oe, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
45
|
+
i("div", se, [p(t.$slots, "actions", {}, void 0, !0)])
|
|
46
46
|
], 6));
|
|
47
47
|
}
|
|
48
|
-
}),
|
|
48
|
+
}), v = (e, t) => {
|
|
49
49
|
let n = e.__vccOpts || e;
|
|
50
50
|
for (let [e, r] of t) n[e] = r;
|
|
51
51
|
return n;
|
|
52
|
-
},
|
|
52
|
+
}, le = /*#__PURE__*/ v(ce, [["__scopeId", "data-v-9b9826d5"]]), ue = {
|
|
53
53
|
key: 0,
|
|
54
54
|
class: "mw-sidebar__head"
|
|
55
|
-
},
|
|
55
|
+
}, de = {
|
|
56
56
|
class: "mw-sidebar__nav",
|
|
57
57
|
"aria-label": "Primary"
|
|
58
|
-
},
|
|
58
|
+
}, y = {
|
|
59
59
|
key: 1,
|
|
60
60
|
class: "mw-sidebar__body"
|
|
61
|
-
},
|
|
61
|
+
}, b = {
|
|
62
62
|
key: 2,
|
|
63
63
|
class: "mw-sidebar__foot"
|
|
64
|
-
},
|
|
64
|
+
}, x = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
65
65
|
__name: "AppSidebar",
|
|
66
66
|
props: {
|
|
67
67
|
variant: { default: "dark" },
|
|
@@ -70,44 +70,67 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
70
70
|
},
|
|
71
71
|
setup(e) {
|
|
72
72
|
let a = e, o = t(() => {
|
|
73
|
-
let e =
|
|
73
|
+
let e = _(a.variant, a.colors);
|
|
74
74
|
return a.width && (e["--mw-sidebar-width"] = a.width), e;
|
|
75
75
|
});
|
|
76
|
-
return (t, a) => (
|
|
76
|
+
return (t, a) => (u(), r("aside", {
|
|
77
77
|
class: c(["mw-sidebar", `mw-sidebar--${e.variant}`]),
|
|
78
78
|
style: l(o.value)
|
|
79
79
|
}, [
|
|
80
|
-
t.$slots.head ? (
|
|
81
|
-
i("nav",
|
|
82
|
-
t.$slots.body ? (
|
|
83
|
-
t.$slots.foot ? (
|
|
80
|
+
t.$slots.head ? (u(), r("div", ue, [p(t.$slots, "head", {}, void 0, !0)])) : n("", !0),
|
|
81
|
+
i("nav", de, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
82
|
+
t.$slots.body ? (u(), r("div", y, [p(t.$slots, "body", {}, void 0, !0)])) : n("", !0),
|
|
83
|
+
t.$slots.foot ? (u(), r("div", b, [p(t.$slots, "foot", {}, void 0, !0)])) : n("", !0)
|
|
84
84
|
], 6));
|
|
85
85
|
}
|
|
86
|
-
}), [["__scopeId", "data-v-
|
|
86
|
+
}), [["__scopeId", "data-v-a2b8405c"]]);
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/safe-href.ts
|
|
89
|
+
function S(e) {
|
|
90
|
+
if (e) try {
|
|
91
|
+
let t = new URL(e);
|
|
92
|
+
if (t.protocol === "https:" || t.protocol === "http:" && (t.hostname === "localhost" || t.hostname === "127.0.0.1")) return e;
|
|
93
|
+
} catch {}
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/components/AppFooter.vue?vue&type=script&setup=true&lang.ts
|
|
97
|
+
var C = { class: "mw-footer__start" }, w = { class: "mw-footer__center" }, T = { class: "mw-footer__end" }, E = ["href"], D = ["href"], O = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
87
98
|
__name: "AppFooter",
|
|
88
99
|
props: {
|
|
89
100
|
variant: { default: "transparent" },
|
|
90
101
|
colors: {},
|
|
91
|
-
docsUrl: {}
|
|
102
|
+
docsUrl: {},
|
|
103
|
+
devUrl: {}
|
|
92
104
|
},
|
|
93
105
|
setup(e) {
|
|
94
|
-
let a = e, o = t(() =>
|
|
95
|
-
return (t, a) => (
|
|
106
|
+
let a = e, o = t(() => _(a.variant, a.colors));
|
|
107
|
+
return (t, a) => (u(), r("footer", {
|
|
96
108
|
class: c(["mw-footer", `mw-footer--${e.variant}`]),
|
|
97
109
|
style: l(o.value)
|
|
98
110
|
}, [
|
|
99
|
-
i("div",
|
|
100
|
-
i("div",
|
|
101
|
-
i("div",
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
i("div", C, [p(t.$slots, "start", {}, void 0, !0)]),
|
|
112
|
+
i("div", w, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
113
|
+
i("div", T, [
|
|
114
|
+
p(t.$slots, "end", {}, void 0, !0),
|
|
115
|
+
e.docsUrl ? (u(), r("a", {
|
|
116
|
+
key: 0,
|
|
117
|
+
href: h(S)(e.docsUrl),
|
|
118
|
+
target: "_blank",
|
|
119
|
+
rel: "noopener noreferrer",
|
|
120
|
+
class: "mw-footer__docs-link"
|
|
121
|
+
}, "Documentation", 8, E)) : n("", !0),
|
|
122
|
+
e.devUrl ? (u(), r("a", {
|
|
123
|
+
key: 1,
|
|
124
|
+
href: h(S)(e.devUrl),
|
|
125
|
+
target: "_blank",
|
|
126
|
+
rel: "noopener noreferrer",
|
|
127
|
+
"aria-label": "Developer documentation",
|
|
128
|
+
class: "mw-footer__docs-link"
|
|
129
|
+
}, "Developer docs", 8, D)) : n("", !0)
|
|
130
|
+
])
|
|
108
131
|
], 6));
|
|
109
132
|
}
|
|
110
|
-
}), [["__scopeId", "data-v-
|
|
133
|
+
}), [["__scopeId", "data-v-979579a9"]]), k = {
|
|
111
134
|
class: "mw-mode",
|
|
112
135
|
role: "group",
|
|
113
136
|
"aria-label": "Colour mode"
|
|
@@ -115,7 +138,7 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
115
138
|
"aria-pressed",
|
|
116
139
|
"title",
|
|
117
140
|
"onClick"
|
|
118
|
-
], j = { "aria-hidden": "true" }, M = { class: "mw-mode__label" }, N = /*#__PURE__*/
|
|
141
|
+
], j = { "aria-hidden": "true" }, M = { class: "mw-mode__label" }, N = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
119
142
|
__name: "ColorModeControl",
|
|
120
143
|
props: {
|
|
121
144
|
modelValue: {},
|
|
@@ -136,16 +159,16 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
136
159
|
dark: "☾",
|
|
137
160
|
system: "🖵"
|
|
138
161
|
};
|
|
139
|
-
return (o, s) => (
|
|
162
|
+
return (o, s) => (u(), r("div", k, [(u(!0), r(e, null, f(t.modes, (e) => (u(), r("button", {
|
|
140
163
|
key: e,
|
|
141
164
|
type: "button",
|
|
142
165
|
class: c(["mw-mode__btn", { "is-active": t.modelValue === e }]),
|
|
143
166
|
"aria-pressed": t.modelValue === e,
|
|
144
167
|
title: n[e],
|
|
145
168
|
onClick: (t) => o.$emit("update:modelValue", e)
|
|
146
|
-
}, [i("span", j,
|
|
169
|
+
}, [i("span", j, m(a[e]), 1), i("span", M, m(n[e]), 1)], 10, A))), 128))]));
|
|
147
170
|
}
|
|
148
|
-
}), [["__scopeId", "data-v-
|
|
171
|
+
}), [["__scopeId", "data-v-e2ea0d79"]]), P = ["type", "disabled"], F = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
149
172
|
__name: "UiButton",
|
|
150
173
|
props: {
|
|
151
174
|
variant: { default: "primary" },
|
|
@@ -156,29 +179,29 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
156
179
|
}
|
|
157
180
|
},
|
|
158
181
|
setup(e) {
|
|
159
|
-
return (t, n) => (
|
|
182
|
+
return (t, n) => (u(), r("button", {
|
|
160
183
|
type: e.type,
|
|
161
184
|
disabled: e.disabled,
|
|
162
185
|
class: c(["mw-btn", `mw-btn--${e.variant}`])
|
|
163
|
-
}, [
|
|
186
|
+
}, [p(t.$slots, "default", {}, void 0, !0)], 10, P));
|
|
164
187
|
}
|
|
165
|
-
}), [["__scopeId", "data-v-
|
|
188
|
+
}), [["__scopeId", "data-v-bc33cc23"]]), I = { class: "mw-card" }, L = {
|
|
166
189
|
key: 0,
|
|
167
190
|
class: "mw-card__header"
|
|
168
191
|
}, R = { class: "mw-card__title" }, z = { class: "mw-card__body" }, B = {
|
|
169
192
|
key: 1,
|
|
170
193
|
class: "mw-card__footer"
|
|
171
|
-
}, V = /*#__PURE__*/
|
|
194
|
+
}, V = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
172
195
|
__name: "UiCard",
|
|
173
196
|
props: { title: {} },
|
|
174
197
|
setup(e) {
|
|
175
|
-
return (t, a) => (
|
|
176
|
-
e.title || t.$slots.header ? (
|
|
177
|
-
i("div", z, [
|
|
178
|
-
t.$slots.footer ? (
|
|
198
|
+
return (t, a) => (u(), r("section", I, [
|
|
199
|
+
e.title || t.$slots.header ? (u(), r("header", L, [p(t.$slots, "header", {}, () => [i("h3", R, m(e.title), 1)], !0)])) : n("", !0),
|
|
200
|
+
i("div", z, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
201
|
+
t.$slots.footer ? (u(), r("footer", B, [p(t.$slots, "footer", {}, void 0, !0)])) : n("", !0)
|
|
179
202
|
]));
|
|
180
203
|
}
|
|
181
|
-
}), [["__scopeId", "data-v-
|
|
204
|
+
}), [["__scopeId", "data-v-883f87f5"]]), H = { class: "mw-select" }, fe = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
182
205
|
inheritAttrs: !1,
|
|
183
206
|
__name: "UiSelect",
|
|
184
207
|
props: {
|
|
@@ -187,8 +210,8 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
187
210
|
},
|
|
188
211
|
emits: ["update:modelValue"],
|
|
189
212
|
setup(e) {
|
|
190
|
-
let t =
|
|
191
|
-
return (e, n) => (
|
|
213
|
+
let t = g(e, "modelValue");
|
|
214
|
+
return (e, n) => (u(), r("div", H, [ie(i("select", s(e.$attrs, { "onUpdate:modelValue": n[0] ||= (e) => t.value = e }), [p(e.$slots, "default", {}, void 0, !0)], 16), [[ne, t.value]]), n[1] ||= i("svg", {
|
|
192
215
|
class: "mw-select__chevron",
|
|
193
216
|
xmlns: "http://www.w3.org/2000/svg",
|
|
194
217
|
width: "12",
|
|
@@ -197,7 +220,7 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
197
220
|
"aria-hidden": "true"
|
|
198
221
|
}, [i("path", { d: "M1 1l5 5 5-5" })], -1)]));
|
|
199
222
|
}
|
|
200
|
-
}), [["__scopeId", "data-v-
|
|
223
|
+
}), [["__scopeId", "data-v-7e206184"]]), pe = ["role"], me = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
201
224
|
__name: "UiNotice",
|
|
202
225
|
props: { type: {} },
|
|
203
226
|
setup(e) {
|
|
@@ -205,16 +228,16 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
205
228
|
if (n.type === "error") return "alert";
|
|
206
229
|
if (n.type === "ok") return "status";
|
|
207
230
|
});
|
|
208
|
-
return (t, n) => (
|
|
231
|
+
return (t, n) => (u(), r("p", {
|
|
209
232
|
class: c(["mw-notice", e.type && e.type !== "info" ? `mw-notice--${e.type}` : ""]),
|
|
210
233
|
role: i.value
|
|
211
|
-
}, [
|
|
234
|
+
}, [p(t.$slots, "default", {}, void 0, !0)], 10, pe));
|
|
212
235
|
}
|
|
213
|
-
}), [["__scopeId", "data-v-
|
|
236
|
+
}), [["__scopeId", "data-v-ee7fffb1"]]), he = ["disabled", "aria-current"], ge = {
|
|
214
237
|
key: 0,
|
|
215
238
|
class: "sidebar-item__icon",
|
|
216
239
|
"aria-hidden": "true"
|
|
217
|
-
},
|
|
240
|
+
}, _e = { class: "sidebar-item__label" }, ve = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
218
241
|
__name: "SidebarItem",
|
|
219
242
|
props: {
|
|
220
243
|
label: {},
|
|
@@ -229,14 +252,14 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
229
252
|
}
|
|
230
253
|
},
|
|
231
254
|
setup(e) {
|
|
232
|
-
return (t, a) => (
|
|
255
|
+
return (t, a) => (u(), r("button", {
|
|
233
256
|
type: "button",
|
|
234
257
|
class: c(["sidebar-item", { "is-active": e.active }]),
|
|
235
258
|
disabled: e.disabled,
|
|
236
259
|
"aria-current": e.active ? "page" : void 0
|
|
237
|
-
}, [e.icon ? (
|
|
260
|
+
}, [e.icon ? (u(), r("span", ge, m(e.icon), 1)) : n("", !0), i("span", _e, m(e.label), 1)], 10, he));
|
|
238
261
|
}
|
|
239
|
-
}), [["__scopeId", "data-v-
|
|
262
|
+
}), [["__scopeId", "data-v-8da2d583"]]), ye = ["aria-label"], be = ["aria-current", "onClick"], xe = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
240
263
|
__name: "AppTabNav",
|
|
241
264
|
props: {
|
|
242
265
|
tabs: {},
|
|
@@ -246,18 +269,18 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
246
269
|
emits: ["update:modelValue"],
|
|
247
270
|
setup(t, { emit: n }) {
|
|
248
271
|
let i = n;
|
|
249
|
-
return (n, a) => (
|
|
272
|
+
return (n, a) => (u(), r("nav", {
|
|
250
273
|
class: "mw-tab-nav",
|
|
251
274
|
"aria-label": t.ariaLabel
|
|
252
|
-
}, [(
|
|
275
|
+
}, [(u(!0), r(e, null, f(t.tabs, (e) => (u(), r("button", {
|
|
253
276
|
key: e.id,
|
|
254
277
|
type: "button",
|
|
255
278
|
class: c(["mw-tab-nav__tab", { "mw-tab-nav__tab--active": t.modelValue === e.id }]),
|
|
256
279
|
"aria-current": t.modelValue === e.id ? "page" : void 0,
|
|
257
280
|
onClick: (t) => i("update:modelValue", e.id)
|
|
258
|
-
},
|
|
281
|
+
}, m(e.label), 11, be))), 128))], 8, ye));
|
|
259
282
|
}
|
|
260
|
-
}), [["__scopeId", "data-v-
|
|
283
|
+
}), [["__scopeId", "data-v-97d31503"]]), Se = { class: "ca-root" }, Ce = ["title"], we = ["title", "aria-label"], Te = {
|
|
261
284
|
key: 0,
|
|
262
285
|
class: "ca-icon",
|
|
263
286
|
viewBox: "0 0 24 24",
|
|
@@ -269,7 +292,7 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
269
292
|
"stroke-linecap": "round",
|
|
270
293
|
"stroke-linejoin": "round",
|
|
271
294
|
"aria-hidden": "true"
|
|
272
|
-
},
|
|
295
|
+
}, Ee = {
|
|
273
296
|
key: 1,
|
|
274
297
|
class: "ca-icon",
|
|
275
298
|
viewBox: "0 0 24 24",
|
|
@@ -281,7 +304,7 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
281
304
|
"stroke-linecap": "round",
|
|
282
305
|
"stroke-linejoin": "round",
|
|
283
306
|
"aria-hidden": "true"
|
|
284
|
-
},
|
|
307
|
+
}, De = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
285
308
|
__name: "CopyableAddress",
|
|
286
309
|
props: {
|
|
287
310
|
address: {},
|
|
@@ -293,7 +316,7 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
293
316
|
label: { default: "Copy" }
|
|
294
317
|
},
|
|
295
318
|
setup(e) {
|
|
296
|
-
let n = e, o =
|
|
319
|
+
let n = e, o = d(!1), s = t(() => {
|
|
297
320
|
if (!n.truncate) return n.address;
|
|
298
321
|
let [e, t] = n.chars;
|
|
299
322
|
return `${n.address.slice(0, e)}…${n.address.slice(-t)}`;
|
|
@@ -303,25 +326,25 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
303
326
|
o.value = !1;
|
|
304
327
|
}, 1500);
|
|
305
328
|
}
|
|
306
|
-
return (t, n) => (
|
|
329
|
+
return (t, n) => (u(), r("span", Se, [i("span", {
|
|
307
330
|
class: "ca-value",
|
|
308
331
|
title: e.address
|
|
309
|
-
}, [
|
|
332
|
+
}, [p(t.$slots, "default", {}, () => [a(m(s.value), 1)], !0)], 8, Ce), i("button", {
|
|
310
333
|
type: "button",
|
|
311
334
|
class: c(["ca-copy", { "ca-copy--copied": o.value }]),
|
|
312
335
|
title: o.value ? "Copied!" : e.label,
|
|
313
336
|
"aria-label": o.value ? "Copied" : e.label,
|
|
314
337
|
onClick: l
|
|
315
|
-
}, [o.value ? (
|
|
338
|
+
}, [o.value ? (u(), r("svg", Te, [...n[0] ||= [i("polyline", { points: "20 6 9 17 4 12" }, null, -1)]])) : (u(), r("svg", Ee, [...n[1] ||= [i("rect", {
|
|
316
339
|
x: "9",
|
|
317
340
|
y: "9",
|
|
318
341
|
width: "13",
|
|
319
342
|
height: "13",
|
|
320
343
|
rx: "2",
|
|
321
344
|
ry: "2"
|
|
322
|
-
}, null, -1), i("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" }, null, -1)]]))], 10,
|
|
345
|
+
}, null, -1), i("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" }, null, -1)]]))], 10, we)]));
|
|
323
346
|
}
|
|
324
|
-
}), [["__scopeId", "data-v-
|
|
347
|
+
}), [["__scopeId", "data-v-b43dabdd"]]), Oe = ["href", "title"], ke = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
325
348
|
__name: "ExplorerLink",
|
|
326
349
|
props: {
|
|
327
350
|
href: {},
|
|
@@ -339,31 +362,62 @@ var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se
|
|
|
339
362
|
let [e, t] = n.chars;
|
|
340
363
|
return `${n.value.slice(0, e)}…${n.value.slice(-t)}`;
|
|
341
364
|
});
|
|
342
|
-
return (t, n) => (
|
|
365
|
+
return (t, n) => (u(), r("a", {
|
|
343
366
|
class: "el-root",
|
|
344
|
-
href: e.href,
|
|
367
|
+
href: h(S)(e.href),
|
|
345
368
|
target: "_blank",
|
|
346
369
|
rel: "noopener noreferrer",
|
|
347
370
|
title: e.value
|
|
348
|
-
}, [
|
|
371
|
+
}, [p(t.$slots, "default", {}, () => [a(m(i.value), 1)], !0)], 8, Oe));
|
|
349
372
|
}
|
|
350
|
-
}), [["__scopeId", "data-v-
|
|
373
|
+
}), [["__scopeId", "data-v-073d1bbe"]]), Ae = /* @__PURE__ */ new Set([
|
|
351
374
|
"operational",
|
|
352
375
|
"degraded",
|
|
353
376
|
"down",
|
|
354
377
|
"unknown"
|
|
355
378
|
]);
|
|
379
|
+
function U(e) {
|
|
380
|
+
return typeof e == "string" && Ae.has(e);
|
|
381
|
+
}
|
|
382
|
+
function W(e) {
|
|
383
|
+
return U(e) ? e : "unknown";
|
|
384
|
+
}
|
|
356
385
|
function G(e) {
|
|
357
|
-
return typeof e
|
|
386
|
+
return typeof e != "string" || e.trim() === "" ? "" : e.replace(/[<>&"]/g, "");
|
|
387
|
+
}
|
|
388
|
+
function je(e) {
|
|
389
|
+
if (typeof e != "object" || !e) return null;
|
|
390
|
+
let t = e, n = G(t.name);
|
|
391
|
+
return n ? {
|
|
392
|
+
name: n,
|
|
393
|
+
status: W(t.status)
|
|
394
|
+
} : null;
|
|
395
|
+
}
|
|
396
|
+
function Me(e) {
|
|
397
|
+
if (typeof e != "object" || !e) return null;
|
|
398
|
+
let t = e, n = G(t.name);
|
|
399
|
+
if (!n) return null;
|
|
400
|
+
let r = Array.isArray(t.components) ? t.components.map(je).filter((e) => e !== null) : [];
|
|
401
|
+
return {
|
|
402
|
+
name: n,
|
|
403
|
+
status: W(t.status),
|
|
404
|
+
components: r
|
|
405
|
+
};
|
|
358
406
|
}
|
|
359
407
|
function K(e) {
|
|
360
408
|
if (typeof e != "object" || !e) return null;
|
|
361
409
|
let t = e;
|
|
362
|
-
|
|
410
|
+
if (!U(t.overall) || typeof t.generated_at != "string" || !Array.isArray(t.groups)) return null;
|
|
411
|
+
let n = t.groups.map(Me).filter((e) => e !== null);
|
|
412
|
+
return {
|
|
413
|
+
generated_at: t.generated_at,
|
|
414
|
+
overall: t.overall,
|
|
415
|
+
groups: n
|
|
416
|
+
};
|
|
363
417
|
}
|
|
364
418
|
//#endregion
|
|
365
419
|
//#region src/components/StatusWidget.vue?vue&type=script&setup=true&lang.ts
|
|
366
|
-
var
|
|
420
|
+
var Ne = ["href", "title"], q = { class: "status-widget__label" }, Pe = /*#__PURE__*/ v(/* @__PURE__ */ o({
|
|
367
421
|
__name: "StatusWidget",
|
|
368
422
|
props: {
|
|
369
423
|
apiUrl: { default: "https://status.meddleware.co.uk/api/status" },
|
|
@@ -381,8 +435,8 @@ var Ee = ["href", "title"], q = { class: "status-widget__label" }, De = /*#__PUR
|
|
|
381
435
|
degraded: "Degraded",
|
|
382
436
|
down: "Major outage",
|
|
383
437
|
unknown: "Status unknown"
|
|
384
|
-
}, o =
|
|
385
|
-
async function
|
|
438
|
+
}, o = d("ok"), s = d("All systems operational"), l = null;
|
|
439
|
+
async function f() {
|
|
386
440
|
try {
|
|
387
441
|
let e = await fetch(t.apiUrl);
|
|
388
442
|
if (!e.ok) throw Error(`HTTP ${e.status}`);
|
|
@@ -393,42 +447,42 @@ var Ee = ["href", "title"], q = { class: "status-widget__label" }, De = /*#__PUR
|
|
|
393
447
|
o.value = "error", s.value = "Status unavailable";
|
|
394
448
|
}
|
|
395
449
|
}
|
|
396
|
-
return
|
|
397
|
-
|
|
398
|
-
}),
|
|
450
|
+
return ee(() => {
|
|
451
|
+
f(), l = setInterval(f, t.pollInterval);
|
|
452
|
+
}), te(() => {
|
|
399
453
|
l !== null && clearInterval(l);
|
|
400
|
-
}), (t, n) => (
|
|
401
|
-
href: e.href,
|
|
454
|
+
}), (t, n) => (u(), r("a", {
|
|
455
|
+
href: h(S)(e.href),
|
|
402
456
|
target: "_blank",
|
|
403
|
-
rel: "noopener",
|
|
457
|
+
rel: "noopener noreferrer",
|
|
404
458
|
class: c(["status-widget", `status-widget--${o.value}`]),
|
|
405
459
|
title: `Platform status: ${s.value}`
|
|
406
460
|
}, [n[0] ||= i("span", {
|
|
407
461
|
class: "status-widget__dot",
|
|
408
462
|
"aria-hidden": "true"
|
|
409
|
-
}, null, -1), i("span", q,
|
|
463
|
+
}, null, -1), i("span", q, m(s.value), 1)], 10, Ne));
|
|
410
464
|
}
|
|
411
|
-
}), [["__scopeId", "data-v-
|
|
465
|
+
}), [["__scopeId", "data-v-6436368e"]]), J = {
|
|
412
466
|
mainnet: "https://suivision.xyz",
|
|
413
467
|
testnet: "https://testnet.suivision.xyz",
|
|
414
468
|
devnet: "https://devnet.suivision.xyz"
|
|
415
469
|
};
|
|
416
|
-
function
|
|
470
|
+
function Fe(e, t, n = "testnet") {
|
|
417
471
|
return `${J[n] ?? J.testnet}/${e}/${t}`;
|
|
418
472
|
}
|
|
419
473
|
//#endregion
|
|
420
474
|
//#region src/composables/useColorMode.ts
|
|
421
|
-
var Y = "mw-color-mode", X =
|
|
422
|
-
function
|
|
475
|
+
var Y = "mw-color-mode", X = d("system"), Z = !1;
|
|
476
|
+
function Ie() {
|
|
423
477
|
return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
424
478
|
}
|
|
425
479
|
function Q(e) {
|
|
426
|
-
return e === "dark" || e === "system" &&
|
|
480
|
+
return e === "dark" || e === "system" && Ie();
|
|
427
481
|
}
|
|
428
482
|
function $(e) {
|
|
429
483
|
typeof document > "u" || document.documentElement.setAttribute("data-theme", Q(e) ? "dark" : "light");
|
|
430
484
|
}
|
|
431
|
-
function
|
|
485
|
+
function Le(e = "system") {
|
|
432
486
|
if (!Z) {
|
|
433
487
|
Z = !0;
|
|
434
488
|
let t = null;
|
|
@@ -458,4 +512,4 @@ function Ae(e = "system") {
|
|
|
458
512
|
};
|
|
459
513
|
}
|
|
460
514
|
//#endregion
|
|
461
|
-
export { O as AppFooter,
|
|
515
|
+
export { O as AppFooter, le as AppHeader, x as AppSidebar, xe as AppTabNav, N as ColorModeControl, De as CopyableAddress, ke as ExplorerLink, ve as SidebarItem, Pe as StatusWidget, F as UiButton, V as UiCard, me as UiNotice, fe as UiSelect, U as isStatusLevel, K as parseSnapshot, S as safeHref, Fe as suiExplorerUrl, Le as useColorMode };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meddleware/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Shared Vue 3 component library for @meddleware UIs \u2014 layout shell (header/sidebar/footer), colour-mode control, and primitives. Built on @meddleware/design-tokens.",
|
|
5
5
|
"homepage": "https://docs.meddleware.co.uk/",
|
|
6
6
|
"license": "0BSD",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"vue": "^3.5.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@meddleware/design-tokens": "^0.1.
|
|
34
|
+
"@meddleware/design-tokens": "^0.1.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
38
38
|
"typescript": "^6.0.0",
|
|
39
39
|
"vite": "^8.2.2",
|
|
40
|
-
"vitest": "~
|
|
40
|
+
"vitest": "~5.0.1",
|
|
41
41
|
"vue": "^3.5.42",
|
|
42
42
|
"vue-tsc": "~3.3.11"
|
|
43
43
|
},
|