@filipgutica/ui 1.5.0 → 1.6.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.
@@ -0,0 +1,9 @@
1
+ type __VLS_Props = {
2
+ html: string;
3
+ label: string;
4
+ /** Scales the capture down to the available width instead of scrolling it. */
5
+ fit: boolean;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import type { UiSiteNavGroup } from './UiSiteNav.vue';
2
+ type __VLS_Props = {
3
+ contentId: string;
4
+ label: string;
5
+ groups: readonly UiSiteNavGroup[];
6
+ activeId: string | undefined;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
9
+ navigate: (href: string, click: MouseEvent) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onNavigate?: (href: string, click: MouseEvent) => any;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,40 @@
1
+ export interface UiCaptureItem {
2
+ id: string;
3
+ label: string;
4
+ /** Trusted, checked-in terminal markup. It is rendered as HTML. */
5
+ html: string;
6
+ /** The command that produced the capture, shown below it. */
7
+ command?: string;
8
+ }
9
+ export interface UiCaptureProps {
10
+ items: readonly UiCaptureItem[];
11
+ /** The accessible name of the tab list. */
12
+ label: string;
13
+ /** Prefix for each capture's element ID, so `#frame-<id>` links select its tab. */
14
+ idPrefix?: string;
15
+ }
16
+ type __VLS_Props = UiCaptureProps;
17
+ type __VLS_Slots = {
18
+ /** Text shown below the command, such as what the capture shows. */
19
+ caption?(props: {
20
+ item: UiCaptureItem;
21
+ }): unknown;
22
+ };
23
+ type __VLS_ModelProps = {
24
+ /** The active capture ID. Defaults to the first item. */
25
+ modelValue?: string;
26
+ };
27
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
28
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
29
+ "update:modelValue": (value: string | undefined) => any;
30
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
31
+ "onUpdate:modelValue"?: (value: string | undefined) => any;
32
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
34
+ declare const _default: typeof __VLS_export;
35
+ export default _default;
36
+ type __VLS_WithSlots<T, S> = T & {
37
+ new (): {
38
+ $slots: S;
39
+ };
40
+ };
@@ -0,0 +1,26 @@
1
+ export interface UiCommandItem {
2
+ command: string;
3
+ description?: string;
4
+ }
5
+ export interface UiCommandListProps {
6
+ items: readonly UiCommandItem[];
7
+ /** Adds a copy button to each row once the page is interactive. */
8
+ copyable?: boolean;
9
+ commandHeader?: string;
10
+ descriptionHeader?: string;
11
+ }
12
+ type __VLS_Slots = {
13
+ /** Replaces the plain description, for text with `<kbd>` or `<code>`. */
14
+ description?(props: {
15
+ item: UiCommandItem;
16
+ }): unknown;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<UiCommandListProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<UiCommandListProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
20
+ declare const _default: typeof __VLS_export;
21
+ export default _default;
22
+ type __VLS_WithSlots<T, S> = T & {
23
+ new (): {
24
+ $slots: S;
25
+ };
26
+ };
@@ -0,0 +1,21 @@
1
+ export interface UiSiteNavItem {
2
+ label: string;
3
+ /** A `#id` link is tracked as the reader scrolls and marked as the current location. */
4
+ href: string;
5
+ /** Marks the current page on a multi-page site. */
6
+ current?: boolean;
7
+ /** Shows the label in the monospace font, for command or file names. */
8
+ code?: boolean;
9
+ }
10
+ export interface UiSiteNavGroup {
11
+ label?: string;
12
+ items: readonly UiSiteNavItem[];
13
+ }
14
+ export interface UiSiteNavProps {
15
+ /** The visible heading and accessible name of the navigation. */
16
+ label: string;
17
+ groups: readonly UiSiteNavGroup[];
18
+ }
19
+ declare const __VLS_export: import("vue").DefineComponent<UiSiteNavProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<UiSiteNavProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
+ declare const _default: typeof __VLS_export;
21
+ export default _default;
@@ -1,5 +1,11 @@
1
1
  export { default as UiSiteHeader } from './UiSiteHeader.vue';
2
2
  export type { UiSiteHeaderProps, UiSiteLink } from './UiSiteHeader.vue';
3
+ export { default as UiSiteNav } from './UiSiteNav.vue';
4
+ export type { UiSiteNavGroup, UiSiteNavItem, UiSiteNavProps } from './UiSiteNav.vue';
5
+ export { default as UiCapture } from './UiCapture.vue';
6
+ export type { UiCaptureItem, UiCaptureProps } from './UiCapture.vue';
7
+ export { default as UiCommandList } from './UiCommandList.vue';
8
+ export type { UiCommandItem, UiCommandListProps } from './UiCommandList.vue';
3
9
  export { SITE_PROJECTS } from './projects.js';
4
10
  export type { SiteProject, SiteProjectId } from './projects.js';
5
11
  export { applySiteAppearance, SITE_APPEARANCE_KEY, siteThemeBootScript, useSiteAppearance, } from './appearance.js';
package/dist/site.js CHANGED
@@ -1,41 +1,42 @@
1
- import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, onBeforeUnmount as o, onMounted as s, openBlock as c, ref as l, renderList as u, renderSlot as d, toDisplayString as f, unref as p, useSlots as m, watch as h } from "vue";
2
- import { tryOnMounted as g, usePreferredDark as _, useStorage as v } from "@vueuse/core";
1
+ import { a as e, i as t, n, o as r, r as i, t as a } from "./use-active-section-CiflgGBI.js";
2
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, createVNode as p, defineComponent as m, mergeModels as h, nextTick as g, normalizeClass as _, normalizeStyle as v, onBeforeUnmount as y, onMounted as b, onUnmounted as x, openBlock as S, ref as C, renderList as w, renderSlot as T, shallowRef as E, toDisplayString as D, unref as O, useId as k, useModel as ee, useSlots as A, watch as j, withCtx as M } from "vue";
3
+ import { tryOnMounted as N, usePreferredDark as P, useStorage as F } from "@vueuse/core";
3
4
  //#region src/site/appearance.ts
4
- var y = "tool-site-theme", b = (e) => e === "system" || e === "light" || e === "dark", x = `(function () {
5
+ var I = "tool-site-theme", L = (e) => e === "system" || e === "light" || e === "dark", te = `(function () {
5
6
  var root = document.documentElement, choice;
6
- try { choice = localStorage.getItem('${y}'); } catch (error) {}
7
+ try { choice = localStorage.getItem('${I}'); } catch (error) {}
7
8
  var dark = choice === 'dark';
8
9
  if (choice !== 'light' && choice !== 'dark') {
9
10
  try { dark = matchMedia('(prefers-color-scheme: dark)').matches; } catch (error) {}
10
11
  }
11
12
  root.classList.toggle('dark', dark);
12
13
  if (choice === 'light' || choice === 'dark') root.dataset.theme = choice;
13
- })();`, S = ({ root: e, choice: t, appearance: n }) => {
14
+ })();`, R = ({ root: e, choice: t, appearance: n }) => {
14
15
  e.classList.toggle("dark", n === "dark"), t === "system" ? delete e.dataset.theme : e.dataset.theme = t;
15
- }, C = ({ applyToRoot: e = !0 } = {}) => {
16
- let n = v(y, "system", void 0, {
16
+ }, z = ({ applyToRoot: e = !0 } = {}) => {
17
+ let t = F(I, "system", void 0, {
17
18
  initOnMounted: !0,
18
19
  writeDefaults: !1,
19
20
  onError: () => {},
20
21
  serializer: {
21
- read: (e) => b(e) ? e : "system",
22
+ read: (e) => L(e) ? e : "system",
22
23
  write: (e) => e
23
24
  }
24
- }), r = _(), i = t(() => n.value), a = t(() => n.value === "system" ? r.value ? "dark" : "light" : n.value);
25
- return e && g(() => {
26
- h([i, a], () => S({
25
+ }), n = P(), r = s(() => t.value), i = s(() => t.value === "system" ? n.value ? "dark" : "light" : t.value);
26
+ return e && N(() => {
27
+ j([r, i], () => R({
27
28
  root: document.documentElement,
28
- choice: i.value,
29
- appearance: a.value
29
+ choice: r.value,
30
+ appearance: i.value
30
31
  }), { immediate: !0 });
31
32
  }), {
32
- choice: i,
33
- appearance: a,
33
+ choice: r,
34
+ appearance: i,
34
35
  chooseAppearance: (e) => {
35
- b(e) && (n.value = e);
36
+ L(e) && (t.value = e);
36
37
  }
37
38
  };
38
- }, w = [
39
+ }, B = [
39
40
  {
40
41
  id: "annoterm",
41
42
  label: "annoterm",
@@ -72,24 +73,24 @@ var y = "tool-site-theme", b = (e) => e === "system" || e === "light" || e === "
72
73
  href: "https://filipgutica.github.io/ui/",
73
74
  repository: "https://github.com/filipgutica/ui"
74
75
  }
75
- ], T = { class: "fg-site-header" }, E = { class: "fg-site-header__inner" }, D = ["aria-label"], O = {
76
+ ], ne = { class: "fg-site-header" }, re = { class: "fg-site-header__inner" }, V = ["aria-label"], H = {
76
77
  class: "fg-site-projects__menu fg-site-nav",
77
78
  "aria-label": "Projects"
78
- }, k = ["href", "aria-current"], A = { class: "fg-site-header__end" }, j = {
79
+ }, U = ["href", "aria-current"], W = { class: "fg-site-header__end" }, G = {
79
80
  key: 0,
80
81
  class: "fg-site-header__links",
81
82
  "aria-label": "Site links"
82
- }, M = ["href"], N = {
83
+ }, K = ["href"], q = {
83
84
  key: 0,
84
85
  class: "fg-site-appearance",
85
86
  role: "group",
86
87
  "aria-label": "Color theme"
87
- }, P = [
88
+ }, J = [
88
89
  "aria-label",
89
90
  "title",
90
91
  "aria-pressed",
91
92
  "onClick"
92
- ], F = {
93
+ ], Y = {
93
94
  viewBox: "0 0 24 24",
94
95
  width: "18",
95
96
  height: "18",
@@ -97,17 +98,17 @@ var y = "tool-site-theme", b = (e) => e === "system" || e === "light" || e === "
97
98
  stroke: "currentColor",
98
99
  "stroke-width": "1.5",
99
100
  "aria-hidden": "true"
100
- }, I = {
101
+ }, X = {
101
102
  key: 2,
102
103
  d: "M20.5 13.5A9 9 0 0 1 10.5 3a9 9 0 1 0 10 10.5Z"
103
- }, L = /* @__PURE__ */ a({
104
+ }, ie = /* @__PURE__ */ m({
104
105
  __name: "UiSiteHeader",
105
106
  props: {
106
107
  project: {},
107
108
  links: { default: () => [] }
108
109
  },
109
- setup(a) {
110
- let h = [
110
+ setup(e) {
111
+ let t = [
111
112
  {
112
113
  value: "system",
113
114
  label: "System"
@@ -120,29 +121,29 @@ var y = "tool-site-theme", b = (e) => e === "system" || e === "light" || e === "
120
121
  value: "dark",
121
122
  label: "Dark"
122
123
  }
123
- ], g = t(() => w.find(({ id: e }) => e === a.project)?.label ?? a.project), _ = m().default ? void 0 : C(), v = l(!1), y = l(), b = l(), x = () => {
124
- y.value && (y.value.open = !1);
125
- }, S = (e) => {
126
- e.key !== "Escape" || !y.value?.open || (x(), b.value?.focus());
127
- }, L = (e) => {
128
- e.relatedTarget instanceof Node && !y.value?.contains(e.relatedTarget) && x();
129
- }, R = (e) => {
130
- e.target instanceof Node && !y.value?.contains(e.target) && x();
124
+ ], n = s(() => B.find(({ id: t }) => t === e.project)?.label ?? e.project), r = A().default ? void 0 : z(), i = C(!1), a = C(), c = C(), f = () => {
125
+ a.value && (a.value.open = !1);
126
+ }, p = (e) => {
127
+ e.key !== "Escape" || !a.value?.open || (f(), c.value?.focus());
128
+ }, m = (e) => {
129
+ e.relatedTarget instanceof Node && !a.value?.contains(e.relatedTarget) && f();
130
+ }, h = (e) => {
131
+ e.target instanceof Node && !a.value?.contains(e.target) && f();
131
132
  };
132
- return s(() => {
133
- v.value = !0, document.addEventListener("pointerdown", R);
134
- }), o(() => document.removeEventListener("pointerdown", R)), (t, o) => (c(), r("header", T, [i("div", E, [i("details", {
133
+ return b(() => {
134
+ i.value = !0, document.addEventListener("pointerdown", h);
135
+ }), y(() => document.removeEventListener("pointerdown", h)), (s, f) => (S(), u("header", ne, [d("div", re, [d("details", {
135
136
  ref_key: "menu",
136
- ref: y,
137
+ ref: a,
137
138
  class: "fg-site-projects",
138
- onKeydown: S,
139
- onFocusout: L
140
- }, [i("summary", {
139
+ onKeydown: p,
140
+ onFocusout: m
141
+ }, [d("summary", {
141
142
  ref_key: "trigger",
142
- ref: b,
143
+ ref: c,
143
144
  class: "fg-site-projects__trigger",
144
- "aria-label": `Project: ${g.value}`
145
- }, [i("span", null, f(g.value), 1), o[0] ||= i("svg", {
145
+ "aria-label": `Project: ${n.value}`
146
+ }, [d("span", null, D(n.value), 1), f[0] ||= d("svg", {
146
147
  class: "fg-site-projects__chevron",
147
148
  viewBox: "0 0 16 16",
148
149
  width: "16",
@@ -151,33 +152,357 @@ var y = "tool-site-theme", b = (e) => e === "system" || e === "light" || e === "
151
152
  stroke: "currentColor",
152
153
  "stroke-width": "1.5",
153
154
  "aria-hidden": "true"
154
- }, [i("path", { d: "m4 6 4 4 4-4" })], -1)], 8, D), i("nav", O, [(c(!0), r(e, null, u(p(w), (e) => (c(), r("a", {
155
- key: e.id,
156
- href: e.href,
157
- "aria-current": e.id === a.project ? "page" : void 0
158
- }, f(e.label), 9, k))), 128))])], 544), i("div", A, [a.links.length > 0 ? (c(), r("nav", j, [(c(!0), r(e, null, u(a.links, (e) => (c(), r("a", {
155
+ }, [d("path", { d: "m4 6 4 4 4-4" })], -1)], 8, V), d("nav", H, [(S(!0), u(o, null, w(O(B), (t) => (S(), u("a", {
156
+ key: t.id,
157
+ href: t.href,
158
+ "aria-current": t.id === e.project ? "page" : void 0
159
+ }, D(t.label), 9, U))), 128))])], 544), d("div", W, [e.links.length > 0 ? (S(), u("nav", G, [(S(!0), u(o, null, w(e.links, (e) => (S(), u("a", {
159
160
  key: e.href,
160
161
  href: e.href
161
- }, f(e.label), 9, M))), 128))])) : n("", !0), d(t.$slots, "default", {}, () => [v.value && p(_) ? (c(), r("div", N, [(c(), r(e, null, u(h, (t) => i("button", {
162
- key: t.value,
162
+ }, D(e.label), 9, K))), 128))])) : l("", !0), T(s.$slots, "default", {}, () => [i.value && O(r) ? (S(), u("div", q, [(S(), u(o, null, w(t, (e) => d("button", {
163
+ key: e.value,
163
164
  type: "button",
164
165
  class: "fg-site-appearance__choice",
165
- "aria-label": `${t.label} theme`,
166
- title: `${t.label} theme`,
167
- "aria-pressed": p(_).choice.value === t.value,
168
- onClick: (e) => p(_).chooseAppearance(t.value)
169
- }, [(c(), r("svg", F, [t.value === "system" ? (c(), r(e, { key: 0 }, [o[1] ||= i("rect", {
166
+ "aria-label": `${e.label} theme`,
167
+ title: `${e.label} theme`,
168
+ "aria-pressed": O(r).choice.value === e.value,
169
+ onClick: (t) => O(r).chooseAppearance(e.value)
170
+ }, [(S(), u("svg", Y, [e.value === "system" ? (S(), u(o, { key: 0 }, [f[1] ||= d("rect", {
170
171
  x: "3",
171
172
  y: "4",
172
173
  width: "18",
173
174
  height: "13",
174
175
  rx: "2"
175
- }, null, -1), o[2] ||= i("path", { d: "M8 21h8m-4-4v4" }, null, -1)], 64)) : t.value === "light" ? (c(), r(e, { key: 1 }, [o[3] ||= i("circle", {
176
+ }, null, -1), f[2] ||= d("path", { d: "M8 21h8m-4-4v4" }, null, -1)], 64)) : e.value === "light" ? (S(), u(o, { key: 1 }, [f[3] ||= d("circle", {
176
177
  cx: "12",
177
178
  cy: "12",
178
179
  r: "4"
179
- }, null, -1), o[4] ||= i("path", { d: "M12 2v2m0 16v2M2 12h2m16 0h2M5 5l1.5 1.5m11 11L19 19M5 19l1.5-1.5m11-11L19 5" }, null, -1)], 64)) : (c(), r("path", I))]))], 8, P)), 64))])) : n("", !0)])])])]));
180
+ }, null, -1), f[4] ||= d("path", { d: "M12 2v2m0 16v2M2 12h2m16 0h2M5 5l1.5 1.5m11 11L19 19M5 19l1.5-1.5m11-11L19 5" }, null, -1)], 64)) : (S(), u("path", X))]))], 8, J)), 64))])) : l("", !0)])])])]));
181
+ }
182
+ }), ae = ["id"], oe = ["role", "aria-labelledby"], se = ["id"], ce = [
183
+ "href",
184
+ "aria-current",
185
+ "onClick"
186
+ ], le = { key: 0 }, Z = /* @__PURE__ */ m({
187
+ __name: "SiteNavLinks",
188
+ props: {
189
+ contentId: {},
190
+ label: {},
191
+ groups: {},
192
+ activeId: {}
193
+ },
194
+ emits: ["navigate"],
195
+ setup(e, { emit: t }) {
196
+ let n = t, r = `${e.contentId}-label`, i = (t) => `${e.contentId}-group-${t}`, a = (t) => t.current ? "page" : e.activeId !== void 0 && t.href === `#${e.activeId}` ? "location" : void 0;
197
+ return (t, s) => (S(), u("div", {
198
+ id: e.contentId,
199
+ class: "fg-site-rail__content"
200
+ }, [d("nav", {
201
+ class: "fg-site-rail__nav fg-site-nav",
202
+ "aria-labelledby": r
203
+ }, [d("h2", {
204
+ id: r,
205
+ class: "fg-site-rail__label"
206
+ }, D(e.label), 1), (S(!0), u(o, null, w(e.groups, (e, t) => (S(), u("div", {
207
+ key: e.label ?? t,
208
+ class: "fg-site-rail__group",
209
+ role: e.label ? "group" : void 0,
210
+ "aria-labelledby": e.label ? i(t) : void 0
211
+ }, [e.label ? (S(), u("span", {
212
+ key: 0,
213
+ id: i(t),
214
+ class: "fg-site-rail__group-label"
215
+ }, D(e.label), 9, se)) : l("", !0), (S(!0), u(o, null, w(e.items, (e) => (S(), u("a", {
216
+ key: e.href,
217
+ href: e.href,
218
+ "aria-current": a(e),
219
+ onClick: (t) => n("navigate", e.href, t)
220
+ }, [e.code ? (S(), u("code", le, D(e.label), 1)) : (S(), u(o, { key: 1 }, [f(D(e.label), 1)], 64))], 8, ce))), 128))], 8, oe))), 128))])], 8, ae));
221
+ }
222
+ }), ue = ["data-enhanced"], de = ["open"], fe = ["aria-controls"], pe = "(max-width: 800px)", me = /* @__PURE__ */ m({
223
+ __name: "UiSiteNav",
224
+ props: {
225
+ label: {},
226
+ groups: {}
227
+ },
228
+ setup(e) {
229
+ let t = k(), n = C(), o = C(!1), s = C(!1), l = C(!1), m = a({ targetIds: e.groups.flatMap((e) => e.items).flatMap(({ href: e }) => e.startsWith("#") && e.length > 1 ? [e.slice(1)] : []) }), h, _ = null, v = () => n.value?.querySelector("button.fg-site-rail__toggle"), y = () => {
230
+ g(() => n.value?.querySelector(".fg-site-nav a")?.focus({ preventScroll: !0 }));
231
+ }, w = () => {
232
+ let e = h?.matches && !s.value && n.value?.contains(document.activeElement), t = h?.matches === !1 && s.value && !l.value && v() === document.activeElement;
233
+ s.value = h?.matches === !0, s.value || (l.value = !1), e ? g(() => v()?.focus({ preventScroll: !0 })) : t && y();
234
+ }, T = (e, t) => {
235
+ !l.value || t.button !== 0 || t.metaKey || t.ctrlKey || t.altKey || t.shiftKey || (_ = e.startsWith("#") ? document.getElementById(e.slice(1)) : null, l.value = !1);
236
+ }, E = (e) => {
237
+ _ ? (e.preventDefault(), _.tabIndex = -1, _.focus({ preventScroll: !0 }), _ = null) : s.value || (e.preventDefault(), y());
238
+ };
239
+ return b(() => {
240
+ h = matchMedia(pe), w(), o.value = !0, h.addEventListener("change", w);
241
+ }), x(() => h?.removeEventListener("change", w)), (a, h) => (S(), u("div", {
242
+ ref_key: "root",
243
+ ref: n,
244
+ class: "fg-site-rail",
245
+ "data-enhanced": o.value
246
+ }, [!o.value || !s.value ? (S(), u("details", {
247
+ key: 0,
248
+ class: "fg-site-rail__menu",
249
+ open: o.value && !s.value
250
+ }, [d("summary", {
251
+ class: "fg-site-rail__summary",
252
+ "aria-controls": O(t)
253
+ }, " Menu ", 8, fe), p(Z, {
254
+ "content-id": O(t),
255
+ label: e.label,
256
+ groups: e.groups,
257
+ "active-id": O(m)
258
+ }, null, 8, [
259
+ "content-id",
260
+ "label",
261
+ "groups",
262
+ "active-id"
263
+ ])], 8, de)) : (S(), c(i, {
264
+ key: 1,
265
+ open: l.value,
266
+ "onUpdate:open": h[0] ||= (e) => l.value = e,
267
+ title: "Navigation",
268
+ onCloseAutoFocus: E
269
+ }, {
270
+ trigger: M(() => [p(r, {
271
+ variant: "ghost",
272
+ size: "lg",
273
+ class: "fg-site-rail__toggle"
274
+ }, {
275
+ default: M(() => [...h[1] ||= [f(" Menu ", -1)]]),
276
+ _: 1
277
+ })]),
278
+ default: M(() => [p(Z, {
279
+ "content-id": O(t),
280
+ label: e.label,
281
+ groups: e.groups,
282
+ "active-id": O(m),
283
+ onNavigate: T
284
+ }, null, 8, [
285
+ "content-id",
286
+ "label",
287
+ "groups",
288
+ "active-id"
289
+ ])]),
290
+ _: 1
291
+ }, 8, ["open"]))], 8, ue));
292
+ }
293
+ }), he = [
294
+ "aria-label",
295
+ "tabindex",
296
+ "data-fit",
297
+ "innerHTML"
298
+ ], Q = /* @__PURE__ */ m({
299
+ __name: "CaptureScreen",
300
+ props: {
301
+ html: {},
302
+ label: {},
303
+ fit: { type: Boolean }
304
+ },
305
+ setup(e) {
306
+ let t = C(), n = C(1), r = C(), i, a = () => {
307
+ if (!e.fit) {
308
+ r.value = void 0, n.value = 1;
309
+ return;
310
+ }
311
+ let i = t.value, a = i?.firstElementChild;
312
+ !i?.clientWidth || !(a instanceof HTMLElement) || !a.offsetWidth || (n.value = Math.min(1, i.clientWidth / a.offsetWidth), r.value = Math.ceil(a.offsetHeight * n.value) + i.offsetHeight - i.clientHeight);
313
+ };
314
+ return j(() => [e.fit, e.html], a, { flush: "post" }), b(() => {
315
+ typeof ResizeObserver < "u" && (i = new ResizeObserver(a), t.value && i.observe(t.value)), a();
316
+ }), x(() => i?.disconnect()), (i, a) => (S(), u("div", {
317
+ ref_key: "container",
318
+ ref: t,
319
+ class: "fg-capture__screen",
320
+ role: "region",
321
+ "aria-label": e.label,
322
+ tabindex: e.fit ? void 0 : 0,
323
+ "data-fit": e.fit || void 0,
324
+ style: v({
325
+ height: r.value === void 0 ? void 0 : `${r.value}px`,
326
+ "--capture-scale": n.value
327
+ }),
328
+ innerHTML: e.html
329
+ }, null, 12, he));
330
+ }
331
+ }), ge = ["data-enhanced"], _e = ["id"], ve = { class: "fg-capture__preview" }, ye = [
332
+ "aria-label",
333
+ "title",
334
+ "onClick"
335
+ ], be = {
336
+ key: 0,
337
+ class: "fg-capture__caption"
338
+ }, xe = { key: 0 }, Se = /* @__PURE__ */ m({
339
+ __name: "UiCapture",
340
+ props: /*@__PURE__*/ h({
341
+ items: {},
342
+ label: {},
343
+ idPrefix: { default: "frame-" }
344
+ }, {
345
+ modelValue: {},
346
+ modelModifiers: {}
347
+ }),
348
+ emits: ["update:modelValue"],
349
+ setup(e) {
350
+ let i = ee(e, "modelValue"), a = C(!1), m = s(() => e.items.map(({ id: e, label: t }) => ({
351
+ value: e,
352
+ label: t
353
+ }))), h = s(() => i.value ?? e.items[0]?.id ?? ""), _ = C(!1), v = E(), y, O = 0, k = 0, A = (e, t) => {
354
+ t.currentTarget instanceof HTMLElement && (y = t.currentTarget), v.value = e, _.value = !0;
355
+ }, j = (e) => {
356
+ y?.isConnected && (e.preventDefault(), y.focus({ preventScroll: !0 }));
357
+ }, N = () => {
358
+ try {
359
+ return document.getElementById(decodeURIComponent(location.hash.slice(1)));
360
+ } catch {
361
+ return null;
362
+ }
363
+ }, P = async () => {
364
+ await g(), cancelAnimationFrame(O), cancelAnimationFrame(k), O = requestAnimationFrame(() => {
365
+ k = requestAnimationFrame(() => N()?.scrollIntoView({
366
+ behavior: "instant",
367
+ block: "start"
368
+ }));
369
+ });
370
+ }, F = () => {
371
+ let t = N();
372
+ if (!t) return !1;
373
+ let n = e.items.find(({ id: n }) => document.getElementById(`${e.idPrefix}${n}`)?.contains(t));
374
+ return !n || h.value === n.id ? !1 : (i.value = n.id, !0);
375
+ }, I = () => {
376
+ F() && P();
377
+ };
378
+ return b(() => {
379
+ a.value = !0, F(), location.hash && P(), window.addEventListener("hashchange", I), window.addEventListener("popstate", I);
380
+ }), x(() => {
381
+ cancelAnimationFrame(O), cancelAnimationFrame(k), window.removeEventListener("hashchange", I), window.removeEventListener("popstate", I);
382
+ }), (s, g) => (S(), u("div", {
383
+ class: "fg-capture",
384
+ "data-enhanced": a.value
385
+ }, [p(n, {
386
+ "model-value": h.value,
387
+ items: m.value,
388
+ label: e.label,
389
+ "onUpdate:modelValue": g[0] ||= (e) => i.value = e
390
+ }, {
391
+ panel: M(({ value: t }) => [(S(!0), u(o, null, w(e.items, (n) => (S(), u(o, { key: n.id }, [n.id === t ? (S(), u("figure", {
392
+ key: 0,
393
+ id: `${e.idPrefix}${n.id}`,
394
+ class: "fg-capture__figure"
395
+ }, [d("div", ve, [p(Q, {
396
+ html: n.html,
397
+ label: `Terminal capture: ${n.label}`,
398
+ fit: a.value
399
+ }, null, 8, [
400
+ "html",
401
+ "label",
402
+ "fit"
403
+ ]), a.value ? (S(), u("button", {
404
+ key: 0,
405
+ type: "button",
406
+ class: "fg-capture__expand",
407
+ "aria-label": `Expand ${n.label} capture`,
408
+ "aria-haspopup": "dialog",
409
+ title: `Open ${n.label} capture at full size`,
410
+ onClick: (e) => A(n, e)
411
+ }, null, 8, ye)) : l("", !0)]), n.command || s.$slots.caption ? (S(), u("figcaption", be, [n.command ? (S(), u("code", xe, D(n.command), 1)) : l("", !0), T(s.$slots, "caption", { item: n })])) : l("", !0)], 8, _e)) : l("", !0)], 64))), 128))]),
412
+ _: 3
413
+ }, 8, [
414
+ "model-value",
415
+ "items",
416
+ "label"
417
+ ]), p(t, {
418
+ open: _.value,
419
+ "onUpdate:open": g[2] ||= (e) => _.value = e,
420
+ title: `${v.value?.label ?? ""} capture`,
421
+ description: "Scroll to read the full capture.",
422
+ class: "fg-capture-viewer",
423
+ onCloseAutoFocus: j
424
+ }, {
425
+ footer: M(() => [p(r, {
426
+ variant: "secondary",
427
+ size: "lg",
428
+ onClick: g[1] ||= (e) => _.value = !1
429
+ }, {
430
+ default: M(() => [...g[3] ||= [f(" Close capture ", -1)]]),
431
+ _: 1
432
+ })]),
433
+ default: M(() => [v.value ? (S(), c(Q, {
434
+ key: 0,
435
+ html: v.value.html,
436
+ label: `${v.value.label} capture at full size`,
437
+ fit: !1
438
+ }, null, 8, ["html", "label"])) : l("", !0)]),
439
+ _: 1
440
+ }, 8, ["open", "title"])], 8, ge));
441
+ }
442
+ }), Ce = { class: "fg-command-list" }, we = { class: "fg-command-list__table" }, Te = { scope: "col" }, Ee = { scope: "col" }, De = { key: 0 }, $ = { class: "fg-command-list__command" }, Oe = { class: "fg-command-list__description" }, ke = {
443
+ key: 0,
444
+ class: "fg-command-list__action"
445
+ }, Ae = [
446
+ "disabled",
447
+ "aria-label",
448
+ "title",
449
+ "onClick"
450
+ ], je = {
451
+ viewBox: "0 0 24 24",
452
+ fill: "none",
453
+ stroke: "currentColor",
454
+ "stroke-width": "1.5",
455
+ "aria-hidden": "true"
456
+ }, Me = {
457
+ key: 0,
458
+ d: "m5 12 4 4L19 6"
459
+ }, Ne = /* @__PURE__ */ m({
460
+ __name: "UiCommandList",
461
+ props: {
462
+ items: {},
463
+ copyable: {
464
+ type: Boolean,
465
+ default: !0
466
+ },
467
+ commandHeader: { default: "Command" },
468
+ descriptionHeader: { default: "What it does" }
469
+ },
470
+ setup(t) {
471
+ let n = C(!1);
472
+ b(() => {
473
+ n.value = !0;
474
+ });
475
+ let { copied: r, pending: i, error: a, copy: c } = e({
476
+ unavailableMessage: "Clipboard unavailable. Select the command to copy it.",
477
+ failureMessage: "Could not copy. Select the command to copy it."
478
+ }), p = C(""), m = s(() => a.value || (r.value ? `${p.value} copied to clipboard.` : "")), h = (e) => (p.value = e, c(e));
479
+ return (e, s) => (S(), u("div", Ce, [d("table", we, [d("thead", null, [d("tr", null, [
480
+ d("th", Te, D(t.commandHeader), 1),
481
+ d("th", Ee, D(t.descriptionHeader), 1),
482
+ t.copyable ? (S(), u("td", De)) : l("", !0)
483
+ ])]), d("tbody", null, [(S(!0), u(o, null, w(t.items, (c) => (S(), u("tr", { key: c.command }, [
484
+ d("td", $, [d("code", null, D(c.command), 1)]),
485
+ d("td", Oe, [T(e.$slots, "description", { item: c }, () => [f(D(c.description), 1)])]),
486
+ t.copyable ? (S(), u("td", ke, [n.value ? (S(), u("button", {
487
+ key: 0,
488
+ type: "button",
489
+ class: "fg-command-list__copy",
490
+ disabled: O(i),
491
+ "aria-label": `Copy ${c.command}`,
492
+ title: `Copy ${c.command}`,
493
+ onClick: (e) => h(c.command)
494
+ }, [(S(), u("svg", je, [O(r) && !O(a) && p.value === c.command ? (S(), u("path", Me)) : (S(), u(o, { key: 1 }, [s[0] ||= d("rect", {
495
+ x: "8",
496
+ y: "8",
497
+ width: "12",
498
+ height: "13",
499
+ rx: "2"
500
+ }, null, -1), s[1] ||= d("path", { d: "M16 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3" }, null, -1)], 64))]))], 8, Ae)) : l("", !0)])) : l("", !0)
501
+ ]))), 128))])]), d("span", {
502
+ class: _(["fg-command-list__status", { "fg-site-sr-only": !O(a) }]),
503
+ role: "status"
504
+ }, D(m.value), 3)]));
180
505
  }
181
506
  });
182
507
  //#endregion
183
- export { y as SITE_APPEARANCE_KEY, w as SITE_PROJECTS, L as UiSiteHeader, S as applySiteAppearance, x as siteThemeBootScript, C as useSiteAppearance };
508
+ export { I as SITE_APPEARANCE_KEY, B as SITE_PROJECTS, Se as UiCapture, Ne as UiCommandList, ie as UiSiteHeader, me as UiSiteNav, R as applySiteAppearance, te as siteThemeBootScript, z as useSiteAppearance };