@meddleware/ui 0.1.4 → 0.1.6
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/dist/base.css +1 -1
- package/dist/components/StatusWidget.vue.d.ts +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/status.d.ts +27 -0
- package/dist/ui.js +112 -51
- package/package.json +1 -1
package/dist/base.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.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-5aa0ef5a]{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-5aa0ef5a]{border-bottom:1px solid var(--_border);padding:1rem}.mw-sidebar__nav[data-v-5aa0ef5a]{flex-direction:column;flex:auto;gap:.25rem;padding:.75rem;display:flex;overflow-y:auto}.mw-sidebar__foot[data-v-5aa0ef5a]{border-top:1px solid var(--_border);color:var(--_muted);padding:.75rem 1rem;font-size:.85rem}.mw-footer[data-v-c646b8e1]{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-c646b8e1]{border-top:1px solid var(--border)}.mw-footer__center[data-v-c646b8e1]{flex:auto;min-width:0}.mw-footer__end[data-v-c646b8e1]{margin-left:auto}.mw-mode[data-v-e4a6bf1d]{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-e4a6bf1d]{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-e4a6bf1d]:hover{opacity:1}.mw-mode__btn.is-active[data-v-e4a6bf1d]{opacity:1;background:color-mix(in srgb, var(--_text,var(--text)) 14%, transparent)}.mw-mode__btn[data-v-e4a6bf1d]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}@media (width<=640px){.mw-mode__label[data-v-e4a6bf1d]{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-e15afdf7]{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-e15afdf7]:hover:not(:disabled){background:color-mix(in srgb, currentColor 10%, transparent);opacity:1}.sidebar-item.is-active[data-v-e15afdf7]{background:color-mix(in srgb, var(--accent) 26%, transparent);opacity:1}.sidebar-item[data-v-e15afdf7]:disabled{cursor:default}.sidebar-item[data-v-e15afdf7]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.sidebar-item__icon[data-v-e15afdf7]{text-align:center;width:1.1rem}
|
|
1
|
+
.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-5aa0ef5a]{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-5aa0ef5a]{border-bottom:1px solid var(--_border);padding:1rem}.mw-sidebar__nav[data-v-5aa0ef5a]{flex-direction:column;flex:auto;gap:.25rem;padding:.75rem;display:flex;overflow-y:auto}.mw-sidebar__foot[data-v-5aa0ef5a]{border-top:1px solid var(--_border);color:var(--_muted);padding:.75rem 1rem;font-size:.85rem}.mw-footer[data-v-c646b8e1]{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-c646b8e1]{border-top:1px solid var(--border)}.mw-footer__center[data-v-c646b8e1]{flex:auto;min-width:0}.mw-footer__end[data-v-c646b8e1]{margin-left:auto}.mw-mode[data-v-e4a6bf1d]{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-e4a6bf1d]{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-e4a6bf1d]:hover{opacity:1}.mw-mode__btn.is-active[data-v-e4a6bf1d]{opacity:1;background:color-mix(in srgb, var(--_text,var(--text)) 14%, transparent)}.mw-mode__btn[data-v-e4a6bf1d]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}@media (width<=640px){.mw-mode__label[data-v-e4a6bf1d]{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-e15afdf7]{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-e15afdf7]:hover:not(:disabled){background:color-mix(in srgb, currentColor 10%, transparent);opacity:1}.sidebar-item.is-active[data-v-e15afdf7]{background:color-mix(in srgb, var(--accent) 26%, transparent);opacity:1}.sidebar-item[data-v-e15afdf7]:disabled{cursor:default}.sidebar-item[data-v-e15afdf7]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.sidebar-item__icon[data-v-e15afdf7]{text-align:center;width:1.1rem}.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)}
|
|
2
2
|
/*$vite$:1*/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** URL of the `GET /api/status` endpoint to poll. */
|
|
3
|
+
apiUrl?: string;
|
|
4
|
+
/** URL the widget links to (the human-readable status page). */
|
|
5
|
+
href?: string;
|
|
6
|
+
/** Poll interval in milliseconds. */
|
|
7
|
+
pollInterval?: number;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
10
|
+
apiUrl: string;
|
|
11
|
+
href: string;
|
|
12
|
+
pollInterval: number;
|
|
13
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ export { default as UiCard } from './components/UiCard.vue';
|
|
|
7
7
|
export { default as UiSelect } from './components/UiSelect.vue';
|
|
8
8
|
export { default as UiNotice } from './components/UiNotice.vue';
|
|
9
9
|
export { default as SidebarItem } from './components/SidebarItem.vue';
|
|
10
|
+
export { default as StatusWidget } from './components/StatusWidget.vue';
|
|
10
11
|
export { useColorMode } from './composables/useColorMode.js';
|
|
11
12
|
export type { ColorMode } from './composables/useColorMode.js';
|
|
12
13
|
export type { PanelVariant, PanelColors } from './internal/panel.js';
|
|
14
|
+
export { isStatusLevel, parseSnapshot } from './status.js';
|
|
15
|
+
export type { StatusLevel, StatusComponent, StatusGroup, StatusSnapshot } from './status.js';
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Health state values returned by platform-probe's `/api/status` endpoint. */
|
|
2
|
+
export type StatusLevel = 'operational' | 'degraded' | 'down' | 'unknown';
|
|
3
|
+
/** A single monitored component within a group. */
|
|
4
|
+
export interface StatusComponent {
|
|
5
|
+
name: string;
|
|
6
|
+
status: StatusLevel;
|
|
7
|
+
}
|
|
8
|
+
/** A logical capability group containing one or more components. */
|
|
9
|
+
export interface StatusGroup {
|
|
10
|
+
name: string;
|
|
11
|
+
status: StatusLevel;
|
|
12
|
+
components: StatusComponent[];
|
|
13
|
+
}
|
|
14
|
+
/** The full snapshot returned by `GET /api/status`. */
|
|
15
|
+
export interface StatusSnapshot {
|
|
16
|
+
generated_at: string;
|
|
17
|
+
overall: StatusLevel;
|
|
18
|
+
groups: StatusGroup[];
|
|
19
|
+
}
|
|
20
|
+
/** Type guard for `StatusLevel`. Validates that a raw value is one of the known status strings. */
|
|
21
|
+
export declare function isStatusLevel(s: unknown): s is StatusLevel;
|
|
22
|
+
/**
|
|
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
|
+
* so callers can treat an invalid response the same as a network error.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseSnapshot(raw: unknown): StatusSnapshot | null;
|
package/dist/ui.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, mergeProps as o, normalizeClass as s, normalizeStyle as c,
|
|
1
|
+
import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, mergeProps as o, normalizeClass as s, normalizeStyle as c, onMounted as l, onUnmounted as ee, openBlock as u, ref as d, renderList as f, renderSlot as p, toDisplayString as m, useModel as te, vModelSelect as ne, watch as re, withDirectives as ie } from "vue";
|
|
2
2
|
//#region src/internal/panel.ts
|
|
3
3
|
function h(e, t) {
|
|
4
4
|
let n;
|
|
@@ -24,7 +24,7 @@ function h(e, t) {
|
|
|
24
24
|
}
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/components/AppHeader.vue?vue&type=script&setup=true&lang.ts
|
|
27
|
-
var
|
|
27
|
+
var ae = { class: "mw-header__brand" }, oe = { class: "mw-header__center" }, se = { class: "mw-header__actions" }, g = /*@__PURE__*/ a({
|
|
28
28
|
__name: "AppHeader",
|
|
29
29
|
props: {
|
|
30
30
|
variant: { default: "dark" },
|
|
@@ -36,29 +36,29 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
36
36
|
},
|
|
37
37
|
setup(e) {
|
|
38
38
|
let n = e, a = t(() => h(n.variant, n.colors));
|
|
39
|
-
return (t, n) => (
|
|
39
|
+
return (t, n) => (u(), r("header", {
|
|
40
40
|
class: s(["mw-header", [`mw-header--${e.variant}`, { "mw-header--sticky": e.sticky }]]),
|
|
41
41
|
style: c(a.value)
|
|
42
42
|
}, [
|
|
43
|
-
i("div",
|
|
44
|
-
i("div",
|
|
45
|
-
i("div",
|
|
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
|
+
}), _ = (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
|
+
}, v = /*#__PURE__*/ _(g, [["__scopeId", "data-v-ad7cd1c5"]]), y = {
|
|
53
53
|
key: 0,
|
|
54
54
|
class: "mw-sidebar__head"
|
|
55
|
-
},
|
|
55
|
+
}, b = {
|
|
56
56
|
class: "mw-sidebar__nav",
|
|
57
57
|
"aria-label": "Primary"
|
|
58
|
-
},
|
|
58
|
+
}, x = {
|
|
59
59
|
key: 1,
|
|
60
60
|
class: "mw-sidebar__foot"
|
|
61
|
-
},
|
|
61
|
+
}, S = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
62
62
|
__name: "AppSidebar",
|
|
63
63
|
props: {
|
|
64
64
|
variant: { default: "dark" },
|
|
@@ -70,16 +70,16 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
70
70
|
let e = h(a.variant, a.colors);
|
|
71
71
|
return a.width && (e["--mw-sidebar-width"] = a.width), e;
|
|
72
72
|
});
|
|
73
|
-
return (t, a) => (
|
|
73
|
+
return (t, a) => (u(), r("aside", {
|
|
74
74
|
class: s(["mw-sidebar", `mw-sidebar--${e.variant}`]),
|
|
75
75
|
style: c(o.value)
|
|
76
76
|
}, [
|
|
77
|
-
t.$slots.head ? (
|
|
78
|
-
i("nav",
|
|
79
|
-
t.$slots.foot ? (
|
|
77
|
+
t.$slots.head ? (u(), r("div", y, [p(t.$slots, "head", {}, void 0, !0)])) : n("", !0),
|
|
78
|
+
i("nav", b, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
79
|
+
t.$slots.foot ? (u(), r("div", x, [p(t.$slots, "foot", {}, void 0, !0)])) : n("", !0)
|
|
80
80
|
], 6));
|
|
81
81
|
}
|
|
82
|
-
}), [["__scopeId", "data-v-5aa0ef5a"]]),
|
|
82
|
+
}), [["__scopeId", "data-v-5aa0ef5a"]]), C = { class: "mw-footer__start" }, w = { class: "mw-footer__center" }, T = { class: "mw-footer__end" }, E = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
83
83
|
__name: "AppFooter",
|
|
84
84
|
props: {
|
|
85
85
|
variant: { default: "transparent" },
|
|
@@ -87,24 +87,24 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
87
87
|
},
|
|
88
88
|
setup(e) {
|
|
89
89
|
let n = e, a = t(() => h(n.variant, n.colors));
|
|
90
|
-
return (t, n) => (
|
|
90
|
+
return (t, n) => (u(), r("footer", {
|
|
91
91
|
class: s(["mw-footer", `mw-footer--${e.variant}`]),
|
|
92
92
|
style: c(a.value)
|
|
93
93
|
}, [
|
|
94
|
-
i("div",
|
|
95
|
-
i("div",
|
|
96
|
-
i("div",
|
|
94
|
+
i("div", C, [p(t.$slots, "start", {}, void 0, !0)]),
|
|
95
|
+
i("div", w, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
96
|
+
i("div", T, [p(t.$slots, "end", {}, void 0, !0)])
|
|
97
97
|
], 6));
|
|
98
98
|
}
|
|
99
|
-
}), [["__scopeId", "data-v-c646b8e1"]]),
|
|
99
|
+
}), [["__scopeId", "data-v-c646b8e1"]]), D = {
|
|
100
100
|
class: "mw-mode",
|
|
101
101
|
role: "group",
|
|
102
102
|
"aria-label": "Colour mode"
|
|
103
|
-
},
|
|
103
|
+
}, O = [
|
|
104
104
|
"aria-pressed",
|
|
105
105
|
"title",
|
|
106
106
|
"onClick"
|
|
107
|
-
],
|
|
107
|
+
], k = { "aria-hidden": "true" }, A = { class: "mw-mode__label" }, j = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
108
108
|
__name: "ColorModeControl",
|
|
109
109
|
props: {
|
|
110
110
|
modelValue: {},
|
|
@@ -125,16 +125,16 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
125
125
|
dark: "☾",
|
|
126
126
|
system: "◐"
|
|
127
127
|
};
|
|
128
|
-
return (o, c) => (
|
|
128
|
+
return (o, c) => (u(), r("div", D, [(u(!0), r(e, null, f(t.modes, (e) => (u(), r("button", {
|
|
129
129
|
key: e,
|
|
130
130
|
type: "button",
|
|
131
131
|
class: s(["mw-mode__btn", { "is-active": t.modelValue === e }]),
|
|
132
132
|
"aria-pressed": t.modelValue === e,
|
|
133
133
|
title: n[e],
|
|
134
134
|
onClick: (t) => o.$emit("update:modelValue", e)
|
|
135
|
-
}, [i("span",
|
|
135
|
+
}, [i("span", k, m(a[e]), 1), i("span", A, m(n[e]), 1)], 10, O))), 128))]));
|
|
136
136
|
}
|
|
137
|
-
}), [["__scopeId", "data-v-e4a6bf1d"]]),
|
|
137
|
+
}), [["__scopeId", "data-v-e4a6bf1d"]]), M = ["type", "disabled"], N = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
138
138
|
__name: "UiButton",
|
|
139
139
|
props: {
|
|
140
140
|
variant: { default: "primary" },
|
|
@@ -145,29 +145,29 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
147
|
setup(e) {
|
|
148
|
-
return (t, n) => (
|
|
148
|
+
return (t, n) => (u(), r("button", {
|
|
149
149
|
type: e.type,
|
|
150
150
|
disabled: e.disabled,
|
|
151
151
|
class: s(["mw-btn", `mw-btn--${e.variant}`])
|
|
152
|
-
}, [
|
|
152
|
+
}, [p(t.$slots, "default", {}, void 0, !0)], 10, M));
|
|
153
153
|
}
|
|
154
|
-
}), [["__scopeId", "data-v-299de2c3"]]),
|
|
154
|
+
}), [["__scopeId", "data-v-299de2c3"]]), P = { class: "mw-card" }, F = {
|
|
155
155
|
key: 0,
|
|
156
156
|
class: "mw-card__header"
|
|
157
|
-
},
|
|
157
|
+
}, ce = { class: "mw-card__title" }, I = { class: "mw-card__body" }, L = {
|
|
158
158
|
key: 1,
|
|
159
159
|
class: "mw-card__footer"
|
|
160
|
-
},
|
|
160
|
+
}, R = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
161
161
|
__name: "UiCard",
|
|
162
162
|
props: { title: {} },
|
|
163
163
|
setup(e) {
|
|
164
|
-
return (t, a) => (
|
|
165
|
-
e.title || t.$slots.header ? (
|
|
166
|
-
i("div",
|
|
167
|
-
t.$slots.footer ? (
|
|
164
|
+
return (t, a) => (u(), r("section", P, [
|
|
165
|
+
e.title || t.$slots.header ? (u(), r("header", F, [p(t.$slots, "header", {}, () => [i("h3", ce, m(e.title), 1)], !0)])) : n("", !0),
|
|
166
|
+
i("div", I, [p(t.$slots, "default", {}, void 0, !0)]),
|
|
167
|
+
t.$slots.footer ? (u(), r("footer", L, [p(t.$slots, "footer", {}, void 0, !0)])) : n("", !0)
|
|
168
168
|
]));
|
|
169
169
|
}
|
|
170
|
-
}), [["__scopeId", "data-v-fd2fd7ab"]]),
|
|
170
|
+
}), [["__scopeId", "data-v-fd2fd7ab"]]), z = { class: "mw-select" }, B = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
171
171
|
inheritAttrs: !1,
|
|
172
172
|
__name: "UiSelect",
|
|
173
173
|
props: {
|
|
@@ -176,8 +176,8 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
176
176
|
},
|
|
177
177
|
emits: ["update:modelValue"],
|
|
178
178
|
setup(e) {
|
|
179
|
-
let t =
|
|
180
|
-
return (e, n) => (
|
|
179
|
+
let t = te(e, "modelValue");
|
|
180
|
+
return (e, n) => (u(), r("div", z, [ie(i("select", o(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", {
|
|
181
181
|
class: "mw-select__chevron",
|
|
182
182
|
xmlns: "http://www.w3.org/2000/svg",
|
|
183
183
|
width: "12",
|
|
@@ -186,7 +186,7 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
186
186
|
"aria-hidden": "true"
|
|
187
187
|
}, [i("path", { d: "M1 1l5 5 5-5" })], -1)]));
|
|
188
188
|
}
|
|
189
|
-
}), [["__scopeId", "data-v-b9468387"]]),
|
|
189
|
+
}), [["__scopeId", "data-v-b9468387"]]), V = ["role"], H = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
190
190
|
__name: "UiNotice",
|
|
191
191
|
props: { type: {} },
|
|
192
192
|
setup(e) {
|
|
@@ -194,16 +194,16 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
194
194
|
if (n.type === "error") return "alert";
|
|
195
195
|
if (n.type === "ok") return "status";
|
|
196
196
|
});
|
|
197
|
-
return (t, n) => (
|
|
197
|
+
return (t, n) => (u(), r("p", {
|
|
198
198
|
class: s(["mw-notice", e.type && e.type !== "info" ? `mw-notice--${e.type}` : ""]),
|
|
199
199
|
role: i.value
|
|
200
|
-
}, [
|
|
200
|
+
}, [p(t.$slots, "default", {}, void 0, !0)], 10, V));
|
|
201
201
|
}
|
|
202
|
-
}), [["__scopeId", "data-v-6f53d0be"]]),
|
|
202
|
+
}), [["__scopeId", "data-v-6f53d0be"]]), U = ["disabled", "aria-current"], W = {
|
|
203
203
|
key: 0,
|
|
204
204
|
class: "sidebar-item__icon",
|
|
205
205
|
"aria-hidden": "true"
|
|
206
|
-
},
|
|
206
|
+
}, G = { class: "sidebar-item__label" }, le = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
207
207
|
__name: "SidebarItem",
|
|
208
208
|
props: {
|
|
209
209
|
label: {},
|
|
@@ -218,24 +218,85 @@ var re = { class: "mw-header__brand" }, g = { class: "mw-header__center" }, _ =
|
|
|
218
218
|
}
|
|
219
219
|
},
|
|
220
220
|
setup(e) {
|
|
221
|
-
return (t, a) => (
|
|
221
|
+
return (t, a) => (u(), r("button", {
|
|
222
222
|
type: "button",
|
|
223
223
|
class: s(["sidebar-item", { "is-active": e.active }]),
|
|
224
224
|
disabled: e.disabled,
|
|
225
225
|
"aria-current": e.active ? "page" : void 0
|
|
226
|
-
}, [e.icon ? (
|
|
226
|
+
}, [e.icon ? (u(), r("span", W, m(e.icon), 1)) : n("", !0), i("span", G, m(e.label), 1)], 10, U));
|
|
227
227
|
}
|
|
228
|
-
}), [["__scopeId", "data-v-e15afdf7"]]),
|
|
229
|
-
|
|
228
|
+
}), [["__scopeId", "data-v-e15afdf7"]]), ue = /* @__PURE__ */ new Set([
|
|
229
|
+
"operational",
|
|
230
|
+
"degraded",
|
|
231
|
+
"down",
|
|
232
|
+
"unknown"
|
|
233
|
+
]);
|
|
234
|
+
function K(e) {
|
|
235
|
+
return typeof e == "string" && ue.has(e);
|
|
236
|
+
}
|
|
237
|
+
function q(e) {
|
|
238
|
+
if (typeof e != "object" || !e) return null;
|
|
239
|
+
let t = e;
|
|
240
|
+
return !K(t.overall) || typeof t.generated_at != "string" || !Array.isArray(t.groups) ? null : e;
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/components/StatusWidget.vue?vue&type=script&setup=true&lang.ts
|
|
244
|
+
var de = ["href", "title"], J = { class: "status-widget__label" }, fe = /*#__PURE__*/ _(/* @__PURE__ */ a({
|
|
245
|
+
__name: "StatusWidget",
|
|
246
|
+
props: {
|
|
247
|
+
apiUrl: { default: "https://status.meddleware.co.uk/api/status" },
|
|
248
|
+
href: { default: "https://status.meddleware.co.uk" },
|
|
249
|
+
pollInterval: { default: 6e4 }
|
|
250
|
+
},
|
|
251
|
+
setup(e) {
|
|
252
|
+
let t = e, n = {
|
|
253
|
+
operational: "ok",
|
|
254
|
+
degraded: "degraded",
|
|
255
|
+
down: "error",
|
|
256
|
+
unknown: "degraded"
|
|
257
|
+
}, a = {
|
|
258
|
+
operational: "All systems operational",
|
|
259
|
+
degraded: "Degraded",
|
|
260
|
+
down: "Major outage",
|
|
261
|
+
unknown: "Status unknown"
|
|
262
|
+
}, o = d("ok"), c = d("All systems operational"), f = null;
|
|
263
|
+
async function p() {
|
|
264
|
+
try {
|
|
265
|
+
let e = await fetch(t.apiUrl);
|
|
266
|
+
if (!e.ok) throw Error(`HTTP ${e.status}`);
|
|
267
|
+
let r = q(await e.json());
|
|
268
|
+
if (!r) throw Error("unexpected response shape");
|
|
269
|
+
o.value = n[r.overall], c.value = a[r.overall];
|
|
270
|
+
} catch {
|
|
271
|
+
o.value = "error", c.value = "Status unavailable";
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return l(() => {
|
|
275
|
+
p(), f = setInterval(p, t.pollInterval);
|
|
276
|
+
}), ee(() => {
|
|
277
|
+
f !== null && clearInterval(f);
|
|
278
|
+
}), (t, n) => (u(), r("a", {
|
|
279
|
+
href: e.href,
|
|
280
|
+
target: "_blank",
|
|
281
|
+
rel: "noopener",
|
|
282
|
+
class: s(["status-widget", `status-widget--${o.value}`]),
|
|
283
|
+
title: `Platform status: ${c.value}`
|
|
284
|
+
}, [n[0] ||= i("span", {
|
|
285
|
+
class: "status-widget__dot",
|
|
286
|
+
"aria-hidden": "true"
|
|
287
|
+
}, null, -1), i("span", J, m(c.value), 1)], 10, de));
|
|
288
|
+
}
|
|
289
|
+
}), [["__scopeId", "data-v-20197983"]]), Y = "mw-color-mode", X = d("system"), Z = !1;
|
|
290
|
+
function pe() {
|
|
230
291
|
return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
231
292
|
}
|
|
232
293
|
function Q(e) {
|
|
233
|
-
return e === "dark" || e === "system" &&
|
|
294
|
+
return e === "dark" || e === "system" && pe();
|
|
234
295
|
}
|
|
235
296
|
function $(e) {
|
|
236
297
|
typeof document > "u" || document.documentElement.setAttribute("data-theme", Q(e) ? "dark" : "light");
|
|
237
298
|
}
|
|
238
|
-
function
|
|
299
|
+
function me(e = "system") {
|
|
239
300
|
if (!Z) {
|
|
240
301
|
Z = !0;
|
|
241
302
|
let t = null;
|
|
@@ -244,7 +305,7 @@ function oe(e = "system") {
|
|
|
244
305
|
} catch {}
|
|
245
306
|
X.value = t ?? e, $(X.value), typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
|
246
307
|
X.value === "system" && $("system");
|
|
247
|
-
}),
|
|
308
|
+
}), re(X, (e) => {
|
|
248
309
|
$(e);
|
|
249
310
|
try {
|
|
250
311
|
typeof localStorage < "u" && localStorage.setItem(Y, e);
|
|
@@ -265,4 +326,4 @@ function oe(e = "system") {
|
|
|
265
326
|
};
|
|
266
327
|
}
|
|
267
328
|
//#endregion
|
|
268
|
-
export {
|
|
329
|
+
export { E as AppFooter, v as AppHeader, S as AppSidebar, j as ColorModeControl, le as SidebarItem, fe as StatusWidget, N as UiButton, R as UiCard, H as UiNotice, B as UiSelect, K as isStatusLevel, q as parseSnapshot, me 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.6",
|
|
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
|
"license": "0BSD",
|
|
6
6
|
"type": "module",
|