@filipgutica/ui 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/components/UiDrawer.vue.d.ts +23 -0
- package/dist/components/UiTabs.vue.d.ts +27 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +262 -122
- package/dist/use-active-section.d.ts +7 -0
- package/package.json +2 -1
- package/src/components/drawer.css +100 -0
- package/src/components/tabs.css +52 -0
- package/src/components.css +6 -0
package/README.md
CHANGED
|
@@ -39,6 +39,39 @@ The [component docs](https://filipgutica.github.io/ui/#/components/button)
|
|
|
39
39
|
cover examples, props, slots, and events. Place inputs and selects inside
|
|
40
40
|
`UiField` to connect labels, descriptions, and errors automatically.
|
|
41
41
|
|
|
42
|
+
## Page navigation
|
|
43
|
+
|
|
44
|
+
`UiDrawer` provides modal focus containment, Escape dismissal, and trigger focus
|
|
45
|
+
restoration. Keep native navigation in the server-rendered page until hydration;
|
|
46
|
+
the application decides when to replace it and when to close the drawer at a
|
|
47
|
+
desktop breakpoint. To focus a link destination after closing, prevent the
|
|
48
|
+
cancelable `closeAutoFocus` event and focus that heading.
|
|
49
|
+
|
|
50
|
+
`UiTabs` renders every labelled panel during SSR and initial hydration. After
|
|
51
|
+
mounting, it adds keyboard-accessible tabs and hides inactive panels without
|
|
52
|
+
unmounting them. Use unique item values and keep page anchor headings outside
|
|
53
|
+
the panels. Re-align an initial hash after layout settles if enhancement changes
|
|
54
|
+
the page height.
|
|
55
|
+
|
|
56
|
+
Track page sections from a component's setup function:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { useActiveSection } from '@filipgutica/ui'
|
|
60
|
+
|
|
61
|
+
const activeSection = useActiveSection({
|
|
62
|
+
targetIds: ['overview', 'install', 'commands'],
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The returned readonly ref contains the last supplied heading above the root's
|
|
67
|
+
CSS `scroll-padding-top` inset, or the final section at the document bottom.
|
|
68
|
+
IDs must remain stable and in page order; missing elements are ignored after
|
|
69
|
+
mounting. Bind matching links to `aria-current="location"`. Scrolling, resizing,
|
|
70
|
+
layout changes, completed transitions, and restored pages update the value.
|
|
71
|
+
The composable does not change focus, the URL, or browser history, and removes
|
|
72
|
+
its listeners and observer when the component unmounts. During SSR it returns
|
|
73
|
+
the first supplied ID without accessing browser globals.
|
|
74
|
+
|
|
42
75
|
## Themes
|
|
43
76
|
|
|
44
77
|
Import a VS Code JSON or JSONC theme in the browser:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface UiDrawerProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
title: string;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Slots = {
|
|
6
|
+
default(): unknown;
|
|
7
|
+
trigger?(): unknown;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_base: import("vue").DefineComponent<UiDrawerProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
10
|
+
"update:open": (value: boolean) => any;
|
|
11
|
+
closeAutoFocus: (value: Event) => any;
|
|
12
|
+
}, string, import("vue").PublicProps, Readonly<UiDrawerProps> & Readonly<{
|
|
13
|
+
"onUpdate:open"?: (value: boolean) => any;
|
|
14
|
+
onCloseAutoFocus?: (value: Event) => any;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
20
|
+
new (): {
|
|
21
|
+
$slots: S;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface UiTabItem {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
export interface UiTabsProps {
|
|
6
|
+
items: readonly UiTabItem[];
|
|
7
|
+
label: string;
|
|
8
|
+
modelValue: string;
|
|
9
|
+
}
|
|
10
|
+
type __VLS_Slots = {
|
|
11
|
+
panel(props: {
|
|
12
|
+
value: string;
|
|
13
|
+
}): unknown;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_base: import("vue").DefineComponent<UiTabsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
16
|
+
"update:modelValue": (value: string) => any;
|
|
17
|
+
}, string, import("vue").PublicProps, Readonly<UiTabsProps> & Readonly<{
|
|
18
|
+
"onUpdate:modelValue"?: (value: string) => any;
|
|
19
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
23
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
24
|
+
new (): {
|
|
25
|
+
$slots: S;
|
|
26
|
+
};
|
|
27
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export { default as UiCheckbox } from './components/UiCheckbox.vue';
|
|
|
12
12
|
export type { UiCheckboxProps } from './components/UiCheckbox.vue';
|
|
13
13
|
export { default as UiDialog } from './components/UiDialog.vue';
|
|
14
14
|
export type { UiDialogProps } from './components/UiDialog.vue';
|
|
15
|
+
export { default as UiDrawer } from './components/UiDrawer.vue';
|
|
16
|
+
export type { UiDrawerProps } from './components/UiDrawer.vue';
|
|
15
17
|
export { default as UiField } from './components/UiField.vue';
|
|
16
18
|
export type { UiFieldProps } from './components/UiField.vue';
|
|
17
19
|
export { default as UiInput } from './components/UiInput.vue';
|
|
@@ -26,7 +28,11 @@ export { default as UiSelect } from './components/UiSelect.vue';
|
|
|
26
28
|
export type { UiSelectProps } from './components/UiSelect.vue';
|
|
27
29
|
export { default as UiSlider } from './components/UiSlider.vue';
|
|
28
30
|
export type { UiSliderProps } from './components/UiSlider.vue';
|
|
31
|
+
export { default as UiTabs } from './components/UiTabs.vue';
|
|
32
|
+
export type { UiTabItem, UiTabsProps } from './components/UiTabs.vue';
|
|
29
33
|
/** @deprecated Use UiCard for structured content. */
|
|
30
34
|
export { default as UiSurface } from './components/UiSurface.vue';
|
|
31
35
|
export type { UiSurfaceProps } from './components/UiSurface.vue';
|
|
32
36
|
export type { UiControlSize } from './control.js';
|
|
37
|
+
export { useActiveSection } from './use-active-section.js';
|
|
38
|
+
export type { ActiveSectionOptions } from './use-active-section.js';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, defineComponent as c, inject as l, mergeModels as u, mergeProps as d, normalizeStyle as f,
|
|
2
|
-
import { CheckboxIndicator as
|
|
3
|
-
import { useTimeoutFn as
|
|
1
|
+
import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, defineComponent as c, inject as l, mergeModels as u, mergeProps as d, normalizeStyle as f, onMounted as p, onUnmounted as m, openBlock as h, provide as g, readonly as _, ref as v, renderList as y, renderSlot as b, resolveDynamicComponent as x, shallowRef as ee, toDisplayString as S, unref as C, useId as te, useModel as w, useSlots as T, watch as E, withCtx as D } from "vue";
|
|
2
|
+
import { CheckboxIndicator as O, CheckboxRoot as ne, DialogClose as k, DialogContent as A, DialogDescription as j, DialogOverlay as M, DialogPortal as N, DialogRoot as P, DialogTitle as F, DialogTrigger as I, Primitive as L, ProgressIndicator as R, ProgressRoot as z, RadioGroupItem as B, RadioGroupRoot as V, SliderRange as H, SliderRoot as U, SliderThumb as W, SliderTrack as G } from "reka-ui";
|
|
3
|
+
import { useTimeoutFn as K } from "@vueuse/core";
|
|
4
4
|
//#endregion
|
|
5
5
|
//#region src/components/UiButton.vue
|
|
6
|
-
var
|
|
6
|
+
var q = /* @__PURE__ */ c({
|
|
7
7
|
__name: "UiButton",
|
|
8
8
|
props: {
|
|
9
9
|
disabled: {
|
|
@@ -19,7 +19,7 @@ var U = /* @__PURE__ */ c({
|
|
|
19
19
|
variant: { default: "primary" }
|
|
20
20
|
},
|
|
21
21
|
setup(e) {
|
|
22
|
-
return (t, r) => (
|
|
22
|
+
return (t, r) => (h(), n(C(L), {
|
|
23
23
|
as: "button",
|
|
24
24
|
class: "fg-button",
|
|
25
25
|
"data-size": e.size,
|
|
@@ -28,7 +28,7 @@ var U = /* @__PURE__ */ c({
|
|
|
28
28
|
disabled: e.disabled || e.loading,
|
|
29
29
|
type: e.type
|
|
30
30
|
}, {
|
|
31
|
-
default:
|
|
31
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
32
32
|
_: 3
|
|
33
33
|
}, 8, [
|
|
34
34
|
"data-size",
|
|
@@ -38,49 +38,49 @@ var U = /* @__PURE__ */ c({
|
|
|
38
38
|
"type"
|
|
39
39
|
]));
|
|
40
40
|
}
|
|
41
|
-
}),
|
|
41
|
+
}), J = { class: "fg-card" }, Y = {
|
|
42
42
|
key: 0,
|
|
43
43
|
class: "fg-card__header"
|
|
44
|
-
},
|
|
44
|
+
}, X = {
|
|
45
45
|
key: 1,
|
|
46
46
|
class: "fg-card__actions"
|
|
47
|
-
},
|
|
47
|
+
}, Z = {
|
|
48
48
|
key: 1,
|
|
49
49
|
class: "fg-card__body"
|
|
50
|
-
},
|
|
50
|
+
}, re = {
|
|
51
51
|
key: 2,
|
|
52
52
|
class: "fg-card__footer"
|
|
53
|
-
},
|
|
53
|
+
}, ie = /* @__PURE__ */ c({
|
|
54
54
|
__name: "UiCard",
|
|
55
55
|
props: {
|
|
56
56
|
title: { default: () => void 0 },
|
|
57
57
|
titleTag: { default: "h3" }
|
|
58
58
|
},
|
|
59
59
|
setup(e) {
|
|
60
|
-
let t =
|
|
61
|
-
return (a, s) => (
|
|
62
|
-
e.title || t.title || t.actions ? (
|
|
60
|
+
let t = T();
|
|
61
|
+
return (a, s) => (h(), i("div", J, [
|
|
62
|
+
e.title || t.title || t.actions ? (h(), i("header", Y, [e.title || t.title ? (h(), n(x(e.titleTag), {
|
|
63
63
|
key: 0,
|
|
64
64
|
class: "fg-card__title"
|
|
65
65
|
}, {
|
|
66
|
-
default:
|
|
66
|
+
default: D(() => [b(a.$slots, "title", {}, () => [o(S(e.title), 1)])]),
|
|
67
67
|
_: 3
|
|
68
|
-
})) : r("", !0), t.actions ? (
|
|
69
|
-
t.default ? (
|
|
70
|
-
t.footer ? (
|
|
68
|
+
})) : r("", !0), t.actions ? (h(), i("div", X, [b(a.$slots, "actions")])) : r("", !0)])) : r("", !0),
|
|
69
|
+
t.default ? (h(), i("div", Z, [b(a.$slots, "default")])) : r("", !0),
|
|
70
|
+
t.footer ? (h(), i("footer", re, [b(a.$slots, "footer")])) : r("", !0)
|
|
71
71
|
]));
|
|
72
72
|
}
|
|
73
|
-
}),
|
|
73
|
+
}), ae = ["data-wrap", "data-line-numbers"], oe = { class: "fg-code-block__header" }, se = { class: "fg-code-block__title" }, ce = {
|
|
74
74
|
key: 0,
|
|
75
75
|
class: "fg-code-block__language"
|
|
76
|
-
},
|
|
76
|
+
}, le = { class: "fg-code-block__actions" }, ue = ["disabled"], de = ["aria-label"], fe = {
|
|
77
77
|
key: 0,
|
|
78
78
|
class: "fg-code-block__number",
|
|
79
79
|
"aria-hidden": "true"
|
|
80
|
-
},
|
|
80
|
+
}, pe = { class: "fg-code-block__text" }, me = {
|
|
81
81
|
class: "fg-code-block__status",
|
|
82
82
|
role: "status"
|
|
83
|
-
},
|
|
83
|
+
}, he = /* @__PURE__ */ c({
|
|
84
84
|
__name: "UiCodeBlock",
|
|
85
85
|
props: {
|
|
86
86
|
code: {},
|
|
@@ -100,7 +100,7 @@ var U = /* @__PURE__ */ c({
|
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
setup(n) {
|
|
103
|
-
let s = ee(), c =
|
|
103
|
+
let s = ee(), c = v(""), l = t(() => s.value ?? n.code.split("\n").map((e) => [{ content: e }])), u = {
|
|
104
104
|
vue: "vue",
|
|
105
105
|
ts: "typescript",
|
|
106
106
|
typescript: "typescript",
|
|
@@ -113,7 +113,7 @@ var U = /* @__PURE__ */ c({
|
|
|
113
113
|
sh: "bash",
|
|
114
114
|
shell: "bash"
|
|
115
115
|
};
|
|
116
|
-
|
|
116
|
+
E(() => [n.code, n.language], async ([e, t], n, r) => {
|
|
117
117
|
let i = !1;
|
|
118
118
|
r(() => {
|
|
119
119
|
i = !0;
|
|
@@ -136,37 +136,37 @@ var U = /* @__PURE__ */ c({
|
|
|
136
136
|
i || (c.value = "Syntax highlighting unavailable. Showing plain text.");
|
|
137
137
|
}
|
|
138
138
|
}, { immediate: !0 });
|
|
139
|
-
let d =
|
|
139
|
+
let d = v(!1), { start: p } = K(() => {
|
|
140
140
|
d.value = !1;
|
|
141
|
-
}, 1500, { immediate: !1 }),
|
|
142
|
-
if (
|
|
143
|
-
|
|
141
|
+
}, 1500, { immediate: !1 }), m = v(!1), g = v(""), _ = async () => {
|
|
142
|
+
if (g.value = "", d.value = !1, typeof navigator > "u" || !navigator.clipboard?.writeText) {
|
|
143
|
+
g.value = "Clipboard unavailable. Select the code to copy it.";
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
|
-
|
|
146
|
+
m.value = !0;
|
|
147
147
|
try {
|
|
148
|
-
await navigator.clipboard.writeText(n.code), d.value = !0,
|
|
148
|
+
await navigator.clipboard.writeText(n.code), d.value = !0, p();
|
|
149
149
|
} catch {
|
|
150
|
-
|
|
150
|
+
g.value = "Could not copy. Select the code to copy it.";
|
|
151
151
|
} finally {
|
|
152
|
-
|
|
152
|
+
m.value = !1;
|
|
153
153
|
}
|
|
154
154
|
};
|
|
155
|
-
return (t, s) => (
|
|
155
|
+
return (t, s) => (h(), i("div", {
|
|
156
156
|
class: "fg-code-block",
|
|
157
157
|
"data-wrap": n.wrap,
|
|
158
158
|
"data-line-numbers": n.lineNumbers
|
|
159
159
|
}, [
|
|
160
|
-
a("div",
|
|
161
|
-
a("span",
|
|
162
|
-
n.title ? (
|
|
163
|
-
a("div",
|
|
160
|
+
a("div", oe, [
|
|
161
|
+
a("span", se, S(n.title || n.language), 1),
|
|
162
|
+
n.title ? (h(), i("span", ce, S(n.language), 1)) : r("", !0),
|
|
163
|
+
a("div", le, [b(t.$slots, "actions"), n.copyable ? (h(), i("button", {
|
|
164
164
|
key: 0,
|
|
165
165
|
type: "button",
|
|
166
166
|
class: "fg-code-block__copy",
|
|
167
|
-
disabled:
|
|
167
|
+
disabled: m.value,
|
|
168
168
|
"aria-label": "Copy code",
|
|
169
|
-
onClick:
|
|
169
|
+
onClick: _
|
|
170
170
|
}, [s[0] ||= a("svg", {
|
|
171
171
|
viewBox: "0 0 24 24",
|
|
172
172
|
fill: "none",
|
|
@@ -179,50 +179,50 @@ var U = /* @__PURE__ */ c({
|
|
|
179
179
|
width: "12",
|
|
180
180
|
height: "13",
|
|
181
181
|
rx: "2"
|
|
182
|
-
}), a("path", { d: "M16 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3" })], -1), o(" " +
|
|
182
|
+
}), a("path", { d: "M16 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3" })], -1), o(" " + S(d.value && !g.value ? "Copied" : "Copy"), 1)], 8, ue)) : r("", !0)])
|
|
183
183
|
]),
|
|
184
184
|
a("pre", {
|
|
185
185
|
class: "fg-code-block__pre",
|
|
186
186
|
tabindex: "0",
|
|
187
187
|
"aria-label": n.title || `${n.language} code`
|
|
188
|
-
}, [a("code", null, [(
|
|
188
|
+
}, [a("code", null, [(h(!0), i(e, null, y(l.value, (t, s) => (h(), i("span", {
|
|
189
189
|
key: s,
|
|
190
190
|
class: "fg-code-block__line"
|
|
191
|
-
}, [n.lineNumbers ? (
|
|
191
|
+
}, [n.lineNumbers ? (h(), i("span", fe, S(s + 1), 1)) : r("", !0), a("span", pe, [(h(!0), i(e, null, y(t, (e, t) => (h(), i("span", {
|
|
192
192
|
key: t,
|
|
193
193
|
style: f({ color: e.color })
|
|
194
|
-
},
|
|
195
|
-
a("span",
|
|
196
|
-
], 8,
|
|
194
|
+
}, S(e.content), 5))), 128)), o(S(s < l.value.length - 1 ? "\n" : ""), 1)])]))), 128))])], 8, de),
|
|
195
|
+
a("span", me, S(g.value || (d.value ? "Code copied to clipboard." : c.value)), 1)
|
|
196
|
+
], 8, ae));
|
|
197
197
|
}
|
|
198
|
-
}),
|
|
198
|
+
}), ge = /* @__PURE__ */ c({
|
|
199
199
|
__name: "UiAlert",
|
|
200
200
|
props: { tone: { default: "neutral" } },
|
|
201
201
|
setup(e) {
|
|
202
|
-
return (t, r) => (
|
|
202
|
+
return (t, r) => (h(), n(C(L), {
|
|
203
203
|
as: "div",
|
|
204
204
|
class: "fg-alert",
|
|
205
205
|
"data-tone": e.tone,
|
|
206
206
|
role: e.tone === "danger" || e.tone === "error" ? "alert" : "status"
|
|
207
207
|
}, {
|
|
208
|
-
default:
|
|
208
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
209
209
|
_: 3
|
|
210
210
|
}, 8, ["data-tone", "role"]));
|
|
211
211
|
}
|
|
212
|
-
}),
|
|
212
|
+
}), _e = /* @__PURE__ */ c({
|
|
213
213
|
__name: "UiBadge",
|
|
214
214
|
props: { tone: { default: "neutral" } },
|
|
215
215
|
setup(e) {
|
|
216
|
-
return (t, r) => (
|
|
216
|
+
return (t, r) => (h(), n(C(L), {
|
|
217
217
|
as: "span",
|
|
218
218
|
class: "fg-badge",
|
|
219
219
|
"data-tone": e.tone
|
|
220
220
|
}, {
|
|
221
|
-
default:
|
|
221
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
222
222
|
_: 3
|
|
223
223
|
}, 8, ["data-tone"]));
|
|
224
224
|
}
|
|
225
|
-
}),
|
|
225
|
+
}), ve = ["data-size", "data-disabled"], ye = { class: "fg-checkbox__label" }, be = /* @__PURE__ */ c({
|
|
226
226
|
__name: "UiCheckbox",
|
|
227
227
|
props: {
|
|
228
228
|
disabled: {
|
|
@@ -240,27 +240,28 @@ var U = /* @__PURE__ */ c({
|
|
|
240
240
|
let n = t, r = (e) => {
|
|
241
241
|
n("update:modelValue", e === !0);
|
|
242
242
|
};
|
|
243
|
-
return (t, n) => (
|
|
243
|
+
return (t, n) => (h(), i("label", {
|
|
244
244
|
class: "fg-checkbox",
|
|
245
245
|
"data-size": e.size,
|
|
246
246
|
"data-disabled": e.disabled ? "true" : void 0
|
|
247
|
-
}, [s(
|
|
247
|
+
}, [s(C(ne), {
|
|
248
248
|
class: "fg-checkbox__control",
|
|
249
249
|
disabled: e.disabled,
|
|
250
250
|
"model-value": e.modelValue,
|
|
251
251
|
"onUpdate:modelValue": r
|
|
252
252
|
}, {
|
|
253
|
-
default:
|
|
254
|
-
default:
|
|
253
|
+
default: D(() => [s(C(O), { class: "fg-checkbox__indicator" }, {
|
|
254
|
+
default: D(() => [...n[0] ||= [o("✓", -1)]]),
|
|
255
255
|
_: 1
|
|
256
256
|
})]),
|
|
257
257
|
_: 1
|
|
258
|
-
}, 8, ["disabled", "model-value"]), a("span",
|
|
258
|
+
}, 8, ["disabled", "model-value"]), a("span", ye, [b(t.$slots, "default")])], 8, ve));
|
|
259
259
|
}
|
|
260
|
-
}),
|
|
260
|
+
}), xe = { class: "fg-dialog__header" }, Se = { class: "fg-dialog__body" }, Ce = {
|
|
261
261
|
key: 0,
|
|
262
262
|
class: "fg-dialog__footer"
|
|
263
|
-
},
|
|
263
|
+
}, we = /* @__PURE__ */ c({
|
|
264
|
+
inheritAttrs: !1,
|
|
264
265
|
__name: "UiDialog",
|
|
265
266
|
props: {
|
|
266
267
|
description: { default: () => void 0 },
|
|
@@ -270,43 +271,86 @@ var U = /* @__PURE__ */ c({
|
|
|
270
271
|
emits: ["update:open"],
|
|
271
272
|
setup(e, { emit: t }) {
|
|
272
273
|
let c = t;
|
|
273
|
-
return (t, l) => (
|
|
274
|
+
return (t, l) => (h(), n(C(P), {
|
|
274
275
|
open: e.open,
|
|
275
276
|
"onUpdate:open": l[0] ||= (e) => c("update:open", e)
|
|
276
277
|
}, {
|
|
277
|
-
default:
|
|
278
|
-
default:
|
|
278
|
+
default: D(() => [s(C(N), null, {
|
|
279
|
+
default: D(() => [s(C(M), { class: "fg-dialog__overlay" }), s(C(A), d({
|
|
279
280
|
class: "fg-dialog__content",
|
|
280
281
|
"aria-modal": "true"
|
|
281
|
-
}, {
|
|
282
|
-
default:
|
|
283
|
-
a("div",
|
|
284
|
-
default:
|
|
282
|
+
}, t.$attrs), {
|
|
283
|
+
default: D(() => [
|
|
284
|
+
a("div", xe, [a("div", null, [s(C(F), { class: "fg-dialog__title" }, {
|
|
285
|
+
default: D(() => [o(S(e.title), 1)]),
|
|
285
286
|
_: 1
|
|
286
|
-
}), e.description ? (
|
|
287
|
+
}), e.description ? (h(), n(C(j), {
|
|
287
288
|
key: 0,
|
|
288
289
|
class: "fg-dialog__description"
|
|
289
290
|
}, {
|
|
290
|
-
default:
|
|
291
|
+
default: D(() => [o(S(e.description), 1)]),
|
|
291
292
|
_: 1
|
|
292
|
-
})) : r("", !0)]), s(
|
|
293
|
+
})) : r("", !0)]), s(C(k), {
|
|
293
294
|
class: "fg-dialog__close",
|
|
294
295
|
"aria-label": "Close dialog"
|
|
295
296
|
}, {
|
|
296
|
-
default:
|
|
297
|
+
default: D(() => [...l[1] ||= [o(" × ", -1)]]),
|
|
297
298
|
_: 1
|
|
298
299
|
})]),
|
|
299
|
-
a("div",
|
|
300
|
-
t.$slots.footer ? (
|
|
300
|
+
a("div", Se, [b(t.$slots, "default")]),
|
|
301
|
+
t.$slots.footer ? (h(), i("div", Ce, [b(t.$slots, "footer")])) : r("", !0)
|
|
301
302
|
]),
|
|
302
303
|
_: 3
|
|
303
|
-
})]),
|
|
304
|
+
}, 16)]),
|
|
304
305
|
_: 3
|
|
305
306
|
})]),
|
|
306
307
|
_: 3
|
|
307
308
|
}, 8, ["open"]));
|
|
308
309
|
}
|
|
309
|
-
}),
|
|
310
|
+
}), Te = { class: "fg-drawer__header" }, Ee = { class: "fg-drawer__body" }, De = /* @__PURE__ */ c({
|
|
311
|
+
inheritAttrs: !1,
|
|
312
|
+
__name: "UiDrawer",
|
|
313
|
+
props: {
|
|
314
|
+
open: { type: Boolean },
|
|
315
|
+
title: {}
|
|
316
|
+
},
|
|
317
|
+
emits: ["update:open", "closeAutoFocus"],
|
|
318
|
+
setup(e, { emit: t }) {
|
|
319
|
+
let i = t;
|
|
320
|
+
return (t, c) => (h(), n(C(P), {
|
|
321
|
+
open: e.open,
|
|
322
|
+
"onUpdate:open": c[1] ||= (e) => i("update:open", e)
|
|
323
|
+
}, {
|
|
324
|
+
default: D(() => [t.$slots.trigger ? (h(), n(C(I), {
|
|
325
|
+
key: 0,
|
|
326
|
+
"as-child": ""
|
|
327
|
+
}, {
|
|
328
|
+
default: D(() => [b(t.$slots, "trigger")]),
|
|
329
|
+
_: 3
|
|
330
|
+
})) : r("", !0), s(C(N), null, {
|
|
331
|
+
default: D(() => [s(C(M), { class: "fg-drawer__overlay" }), s(C(A), d({
|
|
332
|
+
class: "fg-drawer__content",
|
|
333
|
+
"aria-modal": "true",
|
|
334
|
+
"aria-describedby": void 0
|
|
335
|
+
}, t.$attrs, { onCloseAutoFocus: c[0] ||= (e) => i("closeAutoFocus", e) }), {
|
|
336
|
+
default: D(() => [a("div", Te, [s(C(F), { class: "fg-drawer__title" }, {
|
|
337
|
+
default: D(() => [o(S(e.title), 1)]),
|
|
338
|
+
_: 1
|
|
339
|
+
}), s(C(k), {
|
|
340
|
+
class: "fg-drawer__close",
|
|
341
|
+
"aria-label": "Close drawer"
|
|
342
|
+
}, {
|
|
343
|
+
default: D(() => [...c[2] ||= [o(" × ", -1)]]),
|
|
344
|
+
_: 1
|
|
345
|
+
})]), a("div", Ee, [b(t.$slots, "default")])]),
|
|
346
|
+
_: 3
|
|
347
|
+
}, 16)]),
|
|
348
|
+
_: 3
|
|
349
|
+
})]),
|
|
350
|
+
_: 3
|
|
351
|
+
}, 8, ["open"]));
|
|
352
|
+
}
|
|
353
|
+
}), Q = Symbol("UiFieldContext"), Oe = ["data-invalid"], ke = ["for"], Ae = ["id"], je = ["id"], Me = /* @__PURE__ */ c({
|
|
310
354
|
__name: "UiField",
|
|
311
355
|
props: {
|
|
312
356
|
controlId: {},
|
|
@@ -316,38 +360,38 @@ var U = /* @__PURE__ */ c({
|
|
|
316
360
|
},
|
|
317
361
|
setup(e) {
|
|
318
362
|
let n = t(() => e.description && !e.error ? `${e.controlId}-description` : void 0), o = t(() => e.error ? `${e.controlId}-error` : void 0), s = t(() => !!e.error);
|
|
319
|
-
return
|
|
363
|
+
return g(Q, {
|
|
320
364
|
controlId: t(() => e.controlId),
|
|
321
365
|
descriptionId: n,
|
|
322
366
|
errorId: o,
|
|
323
367
|
invalid: s
|
|
324
|
-
}), (t, s) => (
|
|
368
|
+
}), (t, s) => (h(), i("div", {
|
|
325
369
|
class: "fg-field",
|
|
326
370
|
"data-invalid": e.error ? "true" : void 0
|
|
327
371
|
}, [
|
|
328
372
|
a("label", {
|
|
329
373
|
class: "fg-field__label",
|
|
330
374
|
for: e.controlId
|
|
331
|
-
},
|
|
332
|
-
|
|
375
|
+
}, S(e.label), 9, ke),
|
|
376
|
+
b(t.$slots, "default", {
|
|
333
377
|
descriptionId: n.value,
|
|
334
378
|
errorId: o.value
|
|
335
379
|
}),
|
|
336
|
-
e.description && !e.error ? (
|
|
380
|
+
e.description && !e.error ? (h(), i("p", {
|
|
337
381
|
key: 0,
|
|
338
382
|
id: n.value,
|
|
339
383
|
class: "fg-field__description",
|
|
340
384
|
"data-field-description": ""
|
|
341
|
-
},
|
|
342
|
-
e.error ? (
|
|
385
|
+
}, S(e.description), 9, Ae)) : r("", !0),
|
|
386
|
+
e.error ? (h(), i("p", {
|
|
343
387
|
key: 1,
|
|
344
388
|
id: o.value,
|
|
345
389
|
class: "fg-field__error",
|
|
346
390
|
"data-field-error": ""
|
|
347
|
-
},
|
|
348
|
-
], 8,
|
|
391
|
+
}, S(e.error), 9, je)) : r("", !0)
|
|
392
|
+
], 8, Oe));
|
|
349
393
|
}
|
|
350
|
-
}),
|
|
394
|
+
}), Ne = /* @__PURE__ */ c({
|
|
351
395
|
__name: "UiInput",
|
|
352
396
|
props: {
|
|
353
397
|
disabled: {
|
|
@@ -368,13 +412,13 @@ var U = /* @__PURE__ */ c({
|
|
|
368
412
|
let r = l(Q, void 0), i = t, a = (e) => {
|
|
369
413
|
e.currentTarget instanceof HTMLInputElement && i("update:modelValue", e.currentTarget.value);
|
|
370
414
|
};
|
|
371
|
-
return (t, i) => (
|
|
372
|
-
id:
|
|
415
|
+
return (t, i) => (h(), n(C(L), {
|
|
416
|
+
id: C(r)?.controlId.value ?? e.id,
|
|
373
417
|
as: "input",
|
|
374
418
|
class: "fg-input",
|
|
375
|
-
"aria-describedby":
|
|
376
|
-
"aria-errormessage":
|
|
377
|
-
"aria-invalid": e.invalid ||
|
|
419
|
+
"aria-describedby": C(r)?.descriptionId.value,
|
|
420
|
+
"aria-errormessage": C(r)?.errorId.value,
|
|
421
|
+
"aria-invalid": e.invalid || C(r)?.invalid.value ? "true" : void 0,
|
|
378
422
|
"data-size": e.size,
|
|
379
423
|
disabled: e.disabled,
|
|
380
424
|
type: e.type,
|
|
@@ -391,7 +435,7 @@ var U = /* @__PURE__ */ c({
|
|
|
391
435
|
"value"
|
|
392
436
|
]));
|
|
393
437
|
}
|
|
394
|
-
}),
|
|
438
|
+
}), Pe = 100, $ = /* @__PURE__ */ c({
|
|
395
439
|
__name: "UiProgress",
|
|
396
440
|
props: {
|
|
397
441
|
label: {},
|
|
@@ -400,19 +444,19 @@ var U = /* @__PURE__ */ c({
|
|
|
400
444
|
},
|
|
401
445
|
setup(e) {
|
|
402
446
|
let r = t(() => {
|
|
403
|
-
let t = Number.isFinite(e.max) && e.max > 0 ? e.max :
|
|
447
|
+
let t = Number.isFinite(e.max) && e.max > 0 ? e.max : Pe;
|
|
404
448
|
return {
|
|
405
449
|
max: t,
|
|
406
450
|
value: e.value === null || !Number.isFinite(e.value) ? null : Math.min(t, Math.max(0, e.value))
|
|
407
451
|
};
|
|
408
452
|
}), i = t(() => r.value.value === null ? 0 : r.value.value / r.value.max * 100);
|
|
409
|
-
return (t, a) => (
|
|
453
|
+
return (t, a) => (h(), n(C(z), {
|
|
410
454
|
class: "fg-progress",
|
|
411
455
|
"aria-label": e.label,
|
|
412
456
|
max: r.value.max,
|
|
413
457
|
"model-value": r.value.value
|
|
414
458
|
}, {
|
|
415
|
-
default:
|
|
459
|
+
default: D(() => [s(C(R), {
|
|
416
460
|
class: "fg-progress__indicator",
|
|
417
461
|
style: f({ transform: `translateX(-${100 - i.value}%)` })
|
|
418
462
|
}, null, 8, ["style"])]),
|
|
@@ -423,7 +467,7 @@ var U = /* @__PURE__ */ c({
|
|
|
423
467
|
"model-value"
|
|
424
468
|
]));
|
|
425
469
|
}
|
|
426
|
-
}),
|
|
470
|
+
}), Fe = { class: "fg-radio-card__content" }, Ie = /* @__PURE__ */ c({
|
|
427
471
|
__name: "UiRadioCard",
|
|
428
472
|
props: {
|
|
429
473
|
disabled: {
|
|
@@ -433,19 +477,19 @@ var U = /* @__PURE__ */ c({
|
|
|
433
477
|
value: {}
|
|
434
478
|
},
|
|
435
479
|
setup(e) {
|
|
436
|
-
return (t, r) => (
|
|
480
|
+
return (t, r) => (h(), n(C(B), {
|
|
437
481
|
class: "fg-radio-card",
|
|
438
482
|
disabled: e.disabled,
|
|
439
483
|
value: e.value
|
|
440
484
|
}, {
|
|
441
|
-
default:
|
|
485
|
+
default: D(() => [r[0] ||= a("span", {
|
|
442
486
|
class: "fg-radio-card__indicator",
|
|
443
487
|
"aria-hidden": "true"
|
|
444
|
-
}, null, -1), a("span",
|
|
488
|
+
}, null, -1), a("span", Fe, [b(t.$slots, "default")])]),
|
|
445
489
|
_: 3
|
|
446
490
|
}, 8, ["disabled", "value"]));
|
|
447
491
|
}
|
|
448
|
-
}),
|
|
492
|
+
}), Le = /* @__PURE__ */ c({
|
|
449
493
|
__name: "UiRadioCardGroup",
|
|
450
494
|
props: /*@__PURE__*/ u({
|
|
451
495
|
disabled: {
|
|
@@ -463,7 +507,7 @@ var U = /* @__PURE__ */ c({
|
|
|
463
507
|
}),
|
|
464
508
|
emits: ["update:modelValue"],
|
|
465
509
|
setup(e) {
|
|
466
|
-
let t =
|
|
510
|
+
let t = w(e, "modelValue"), r = (t) => {
|
|
467
511
|
if (t.altKey || t.ctrlKey || t.metaKey || t.shiftKey) return;
|
|
468
512
|
let n = t.currentTarget, r = t.target;
|
|
469
513
|
if (!(n instanceof HTMLElement) || !(r instanceof HTMLElement)) return;
|
|
@@ -479,14 +523,14 @@ var U = /* @__PURE__ */ c({
|
|
|
479
523
|
let d = o[u];
|
|
480
524
|
!d || d === r || (t.preventDefault(), d.focus(), d.click());
|
|
481
525
|
};
|
|
482
|
-
return (i, a) => (
|
|
526
|
+
return (i, a) => (h(), n(C(V), d({
|
|
483
527
|
modelValue: t.value,
|
|
484
528
|
"onUpdate:modelValue": a[0] ||= (e) => t.value = e,
|
|
485
529
|
class: "fg-radio-card-group",
|
|
486
530
|
disabled: e.disabled,
|
|
487
531
|
loop: e.loop
|
|
488
532
|
}, e.orientation === void 0 ? {} : { orientation: e.orientation }, { onKeydown: r }), {
|
|
489
|
-
default:
|
|
533
|
+
default: D(() => [b(i.$slots, "default")]),
|
|
490
534
|
_: 3
|
|
491
535
|
}, 16, [
|
|
492
536
|
"modelValue",
|
|
@@ -494,7 +538,7 @@ var U = /* @__PURE__ */ c({
|
|
|
494
538
|
"loop"
|
|
495
539
|
]));
|
|
496
540
|
}
|
|
497
|
-
}),
|
|
541
|
+
}), Re = /* @__PURE__ */ c({
|
|
498
542
|
__name: "UiSelect",
|
|
499
543
|
props: {
|
|
500
544
|
disabled: {
|
|
@@ -514,19 +558,19 @@ var U = /* @__PURE__ */ c({
|
|
|
514
558
|
let r = l(Q, void 0), i = t, a = (e) => {
|
|
515
559
|
e.currentTarget instanceof HTMLSelectElement && i("update:modelValue", e.currentTarget.value);
|
|
516
560
|
};
|
|
517
|
-
return (t, i) => (
|
|
518
|
-
id:
|
|
561
|
+
return (t, i) => (h(), n(C(L), {
|
|
562
|
+
id: C(r)?.controlId.value ?? e.id,
|
|
519
563
|
as: "select",
|
|
520
564
|
class: "fg-select",
|
|
521
|
-
"aria-describedby":
|
|
522
|
-
"aria-errormessage":
|
|
523
|
-
"aria-invalid": e.invalid ||
|
|
565
|
+
"aria-describedby": C(r)?.descriptionId.value,
|
|
566
|
+
"aria-errormessage": C(r)?.errorId.value,
|
|
567
|
+
"aria-invalid": e.invalid || C(r)?.invalid.value ? "true" : void 0,
|
|
524
568
|
"data-size": e.size,
|
|
525
569
|
disabled: e.disabled,
|
|
526
570
|
value: e.modelValue,
|
|
527
571
|
onChange: a
|
|
528
572
|
}, {
|
|
529
|
-
default:
|
|
573
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
530
574
|
_: 3
|
|
531
575
|
}, 8, [
|
|
532
576
|
"id",
|
|
@@ -538,7 +582,7 @@ var U = /* @__PURE__ */ c({
|
|
|
538
582
|
"value"
|
|
539
583
|
]));
|
|
540
584
|
}
|
|
541
|
-
}),
|
|
585
|
+
}), ze = /* @__PURE__ */ c({
|
|
542
586
|
__name: "UiSlider",
|
|
543
587
|
props: {
|
|
544
588
|
disabled: {
|
|
@@ -571,7 +615,7 @@ var U = /* @__PURE__ */ c({
|
|
|
571
615
|
e !== void 0 && o("update:modelValue", e);
|
|
572
616
|
}
|
|
573
617
|
});
|
|
574
|
-
return (t, r) => (
|
|
618
|
+
return (t, r) => (h(), n(C(U), {
|
|
575
619
|
modelValue: c.value,
|
|
576
620
|
"onUpdate:modelValue": r[0] ||= (e) => c.value = e,
|
|
577
621
|
class: "fg-slider",
|
|
@@ -581,15 +625,15 @@ var U = /* @__PURE__ */ c({
|
|
|
581
625
|
min: a.value.min,
|
|
582
626
|
step: a.value.step
|
|
583
627
|
}, {
|
|
584
|
-
default:
|
|
585
|
-
default:
|
|
628
|
+
default: D(() => [s(C(G), { class: "fg-slider__track" }, {
|
|
629
|
+
default: D(() => [s(C(H), { class: "fg-slider__range" })]),
|
|
586
630
|
_: 1
|
|
587
|
-
}), s(
|
|
588
|
-
id:
|
|
631
|
+
}), s(C(W), {
|
|
632
|
+
id: C(i)?.controlId.value ?? e.id,
|
|
589
633
|
class: "fg-slider__thumb",
|
|
590
|
-
"aria-describedby":
|
|
591
|
-
"aria-errormessage":
|
|
592
|
-
"aria-invalid":
|
|
634
|
+
"aria-describedby": C(i)?.descriptionId.value,
|
|
635
|
+
"aria-errormessage": C(i)?.errorId.value,
|
|
636
|
+
"aria-invalid": C(i)?.invalid.value ? "true" : void 0,
|
|
593
637
|
"aria-label": e.label
|
|
594
638
|
}, null, 8, [
|
|
595
639
|
"id",
|
|
@@ -608,22 +652,118 @@ var U = /* @__PURE__ */ c({
|
|
|
608
652
|
"step"
|
|
609
653
|
]));
|
|
610
654
|
}
|
|
611
|
-
}),
|
|
655
|
+
}), Be = { class: "fg-tabs" }, Ve = ["aria-label"], He = [
|
|
656
|
+
"id",
|
|
657
|
+
"aria-controls",
|
|
658
|
+
"aria-selected",
|
|
659
|
+
"tabindex",
|
|
660
|
+
"onClick",
|
|
661
|
+
"onFocus"
|
|
662
|
+
], Ue = [
|
|
663
|
+
"id",
|
|
664
|
+
"role",
|
|
665
|
+
"aria-labelledby",
|
|
666
|
+
"hidden",
|
|
667
|
+
"tabindex"
|
|
668
|
+
], We = ["id", "hidden"], Ge = /* @__PURE__ */ c({
|
|
669
|
+
__name: "UiTabs",
|
|
670
|
+
props: {
|
|
671
|
+
items: {},
|
|
672
|
+
label: {},
|
|
673
|
+
modelValue: {}
|
|
674
|
+
},
|
|
675
|
+
emits: ["update:modelValue"],
|
|
676
|
+
setup(n, { emit: o }) {
|
|
677
|
+
let s = o, c = te(), l = v(!1), u = t(() => n.items.some((e) => e.value === n.modelValue) ? n.modelValue : n.items[0]?.value), d = (e) => `${c}-tab-${encodeURIComponent(e)}`, f = (e) => `${c}-panel-${encodeURIComponent(e)}`, m = (e) => `${c}-heading-${encodeURIComponent(e)}`;
|
|
678
|
+
p(() => {
|
|
679
|
+
l.value = !0;
|
|
680
|
+
});
|
|
681
|
+
let g = (e) => {
|
|
682
|
+
e !== u.value && s("update:modelValue", e);
|
|
683
|
+
}, _ = (e) => {
|
|
684
|
+
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || ![
|
|
685
|
+
"ArrowLeft",
|
|
686
|
+
"ArrowRight",
|
|
687
|
+
"Home",
|
|
688
|
+
"End"
|
|
689
|
+
].includes(e.key)) return;
|
|
690
|
+
let t = e.currentTarget, n = e.target;
|
|
691
|
+
if (!(t instanceof HTMLElement) || !(n instanceof HTMLButtonElement)) return;
|
|
692
|
+
let r = [...t.querySelectorAll("[role=\"tab\"]")], i = r.indexOf(n);
|
|
693
|
+
if (i < 0 || r.length === 0) return;
|
|
694
|
+
let a = getComputedStyle(t).direction === "rtl", o = e.key === (a ? "ArrowRight" : "ArrowLeft"), s = r[e.key === "Home" ? 0 : e.key === "End" ? r.length - 1 : (i + (o ? -1 : 1) + r.length) % r.length];
|
|
695
|
+
s && (e.preventDefault(), s.focus());
|
|
696
|
+
};
|
|
697
|
+
return (t, o) => (h(), i("div", Be, [l.value ? (h(), i("div", {
|
|
698
|
+
key: 0,
|
|
699
|
+
class: "fg-tabs__list",
|
|
700
|
+
role: "tablist",
|
|
701
|
+
"aria-label": n.label,
|
|
702
|
+
onKeydown: _
|
|
703
|
+
}, [(h(!0), i(e, null, y(n.items, (e) => (h(), i("button", {
|
|
704
|
+
id: d(e.value),
|
|
705
|
+
key: e.value,
|
|
706
|
+
type: "button",
|
|
707
|
+
class: "fg-tabs__tab",
|
|
708
|
+
role: "tab",
|
|
709
|
+
"aria-controls": f(e.value),
|
|
710
|
+
"aria-selected": e.value === u.value,
|
|
711
|
+
tabindex: e.value === u.value ? 0 : -1,
|
|
712
|
+
onClick: (t) => g(e.value),
|
|
713
|
+
onFocus: (t) => g(e.value)
|
|
714
|
+
}, S(e.label), 41, He))), 128))], 40, Ve)) : r("", !0), (h(!0), i(e, null, y(n.items, (e) => (h(), i("section", {
|
|
715
|
+
id: f(e.value),
|
|
716
|
+
key: e.value,
|
|
717
|
+
class: "fg-tabs__panel",
|
|
718
|
+
role: l.value ? "tabpanel" : void 0,
|
|
719
|
+
"aria-labelledby": l.value ? d(e.value) : m(e.value),
|
|
720
|
+
hidden: l.value && e.value !== u.value,
|
|
721
|
+
tabindex: l.value ? 0 : void 0
|
|
722
|
+
}, [a("h3", {
|
|
723
|
+
id: m(e.value),
|
|
724
|
+
class: "fg-tabs__heading",
|
|
725
|
+
hidden: l.value
|
|
726
|
+
}, S(e.label), 9, We), b(t.$slots, "panel", { value: e.value })], 8, Ue))), 128))]));
|
|
727
|
+
}
|
|
728
|
+
}), Ke = /* @__PURE__ */ c({
|
|
612
729
|
__name: "UiSurface",
|
|
613
730
|
props: {
|
|
614
731
|
as: { default: "section" },
|
|
615
732
|
padding: { default: "default" }
|
|
616
733
|
},
|
|
617
734
|
setup(e) {
|
|
618
|
-
return (t, r) => (
|
|
735
|
+
return (t, r) => (h(), n(C(L), {
|
|
619
736
|
as: e.as,
|
|
620
737
|
class: "fg-surface",
|
|
621
738
|
"data-padding": e.padding
|
|
622
739
|
}, {
|
|
623
|
-
default:
|
|
740
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
624
741
|
_: 3
|
|
625
742
|
}, 8, ["as", "data-padding"]));
|
|
626
743
|
}
|
|
627
|
-
})
|
|
744
|
+
}), qe = ({ targetIds: e }) => {
|
|
745
|
+
let t = v(e[0]), n, r, i;
|
|
746
|
+
return p(() => {
|
|
747
|
+
let a = e.flatMap((e) => {
|
|
748
|
+
let t = document.getElementById(e);
|
|
749
|
+
return t ? [{
|
|
750
|
+
id: e,
|
|
751
|
+
element: t
|
|
752
|
+
}] : [];
|
|
753
|
+
}), o = () => {
|
|
754
|
+
n = void 0;
|
|
755
|
+
let e = document.documentElement, r = Number.parseFloat(getComputedStyle(e).scrollPaddingTop) || 0, i = a[0]?.id;
|
|
756
|
+
for (let e of a) e.element.getBoundingClientRect().top <= r + 1 && (i = e.id);
|
|
757
|
+
window.scrollY > 0 && window.scrollY + window.innerHeight >= e.scrollHeight - 2 && (i = a.at(-1)?.id), t.value = i;
|
|
758
|
+
}, s = () => {
|
|
759
|
+
n === void 0 && (n = requestAnimationFrame(o));
|
|
760
|
+
};
|
|
761
|
+
window.addEventListener("scroll", s, { passive: !0 }), window.addEventListener("resize", s), window.addEventListener("pageshow", s), document.body.addEventListener("transitionend", s), typeof ResizeObserver < "u" && (r = new ResizeObserver(s), r.observe(document.body)), i = () => {
|
|
762
|
+
window.removeEventListener("scroll", s), window.removeEventListener("resize", s), window.removeEventListener("pageshow", s), document.body.removeEventListener("transitionend", s);
|
|
763
|
+
}, o();
|
|
764
|
+
}), m(() => {
|
|
765
|
+
i?.(), r?.disconnect(), n !== void 0 && cancelAnimationFrame(n);
|
|
766
|
+
}), _(t);
|
|
767
|
+
};
|
|
628
768
|
//#endregion
|
|
629
|
-
export {
|
|
769
|
+
export { ge as UiAlert, _e as UiBadge, q as UiButton, ie as UiCard, be as UiCheckbox, he as UiCodeBlock, we as UiDialog, De as UiDrawer, Me as UiField, Ne as UiInput, $ as UiProgress, Ie as UiRadioCard, Le as UiRadioCardGroup, Re as UiSelect, ze as UiSlider, Ke as UiSurface, Ge as UiTabs, qe as useActiveSection };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
export interface ActiveSectionOptions {
|
|
3
|
+
/** Section IDs in page order. Missing elements are ignored after mounting. */
|
|
4
|
+
targetIds: readonly string[];
|
|
5
|
+
}
|
|
6
|
+
/** Tracks the last section heading above the document's scroll-padding inset. */
|
|
7
|
+
export declare const useActiveSection: ({ targetIds }: ActiveSectionOptions) => Readonly<Ref<string | undefined>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@filipgutica/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A compact Vue design system with Tailwind CSS and VS Code theme support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"dist",
|
|
11
11
|
"src/theme.css",
|
|
12
12
|
"src/components.css",
|
|
13
|
+
"src/components/*.css",
|
|
13
14
|
"README.md",
|
|
14
15
|
"LICENSE"
|
|
15
16
|
],
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.fg-drawer__overlay {
|
|
3
|
+
position: fixed;
|
|
4
|
+
inset: 0;
|
|
5
|
+
z-index: 50;
|
|
6
|
+
background: var(--color-overlay);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.fg-drawer__content {
|
|
10
|
+
position: fixed;
|
|
11
|
+
inset-block: 0;
|
|
12
|
+
left: 0;
|
|
13
|
+
z-index: 51;
|
|
14
|
+
display: grid;
|
|
15
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
16
|
+
width: min(calc(var(--sidebar) + var(--space-12)), calc(100vw - var(--space-12)));
|
|
17
|
+
height: 100vh;
|
|
18
|
+
height: 100dvh;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
border-right: 1px solid var(--color-border-subtle);
|
|
21
|
+
color: var(--color-text);
|
|
22
|
+
background: var(--color-surface-raised);
|
|
23
|
+
box-shadow: var(--shadow-dialog);
|
|
24
|
+
font-family: var(--font-ui);
|
|
25
|
+
font-size: var(--text-md);
|
|
26
|
+
font-weight: var(--weight-regular);
|
|
27
|
+
line-height: var(--leading);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.fg-drawer__header {
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: space-between;
|
|
34
|
+
gap: var(--space-3);
|
|
35
|
+
padding: var(--space-3) var(--space-4);
|
|
36
|
+
border-bottom: 1px solid var(--color-border-subtle);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.fg-drawer__title {
|
|
40
|
+
min-width: 0;
|
|
41
|
+
margin: 0;
|
|
42
|
+
font-size: var(--text-md);
|
|
43
|
+
font-weight: var(--weight-medium);
|
|
44
|
+
overflow-wrap: anywhere;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.fg-drawer__close {
|
|
48
|
+
display: inline-grid;
|
|
49
|
+
flex: none;
|
|
50
|
+
min-width: var(--control-lg);
|
|
51
|
+
min-height: var(--control-lg);
|
|
52
|
+
padding: 0;
|
|
53
|
+
place-items: center;
|
|
54
|
+
border: 0;
|
|
55
|
+
border-radius: var(--radius-control);
|
|
56
|
+
color: var(--color-muted);
|
|
57
|
+
background: transparent;
|
|
58
|
+
font: inherit;
|
|
59
|
+
font-size: var(--text-xl);
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.fg-drawer__close:hover {
|
|
64
|
+
color: var(--color-text);
|
|
65
|
+
background: var(--color-row-hover);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.fg-drawer__body {
|
|
69
|
+
min-height: 0;
|
|
70
|
+
overflow: auto;
|
|
71
|
+
overscroll-behavior: contain;
|
|
72
|
+
padding: var(--space-4);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.fg-drawer__close:focus-visible,
|
|
76
|
+
.fg-drawer__content:focus-visible {
|
|
77
|
+
outline: 2px solid var(--color-focus);
|
|
78
|
+
outline-offset: 2px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.fg-drawer__overlay[data-state="open"] { animation: fg-drawer-fade-in var(--duration) var(--ease-out); }
|
|
82
|
+
.fg-drawer__overlay[data-state="closed"] { animation: fg-drawer-fade-out var(--duration-fast) var(--ease-out); }
|
|
83
|
+
.fg-drawer__content[data-state="open"] { animation: fg-drawer-slide-in var(--duration) var(--ease-out); }
|
|
84
|
+
.fg-drawer__content[data-state="closed"] { animation: fg-drawer-slide-out var(--duration-fast) var(--ease-out); }
|
|
85
|
+
|
|
86
|
+
@keyframes fg-drawer-fade-in { from { opacity: 0; } to { opacity: 1; } }
|
|
87
|
+
@keyframes fg-drawer-fade-out { from { opacity: 1; } to { opacity: 0; } }
|
|
88
|
+
@keyframes fg-drawer-slide-in { from { transform: translateX(-100%); } to { transform: translateX(0); } }
|
|
89
|
+
@keyframes fg-drawer-slide-out { from { transform: translateX(0); } to { transform: translateX(-100%); } }
|
|
90
|
+
|
|
91
|
+
:root.high-contrast .fg-drawer__content {
|
|
92
|
+
border-width: 2px;
|
|
93
|
+
border-color: var(--color-border);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media (prefers-reduced-motion: reduce) {
|
|
97
|
+
.fg-drawer__overlay,
|
|
98
|
+
.fg-drawer__content { animation: none; }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.fg-tabs {
|
|
3
|
+
min-width: 0;
|
|
4
|
+
font-family: var(--font-ui);
|
|
5
|
+
font-size: var(--text-md);
|
|
6
|
+
line-height: var(--leading);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.fg-tabs__list {
|
|
10
|
+
display: flex;
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
overflow-x: auto;
|
|
13
|
+
border-bottom: 1px solid var(--color-border-subtle);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.fg-tabs__tab {
|
|
17
|
+
flex: none;
|
|
18
|
+
min-height: var(--control-md);
|
|
19
|
+
padding: var(--space-2) var(--space-3);
|
|
20
|
+
border: 0;
|
|
21
|
+
border-bottom: 2px solid transparent;
|
|
22
|
+
color: var(--color-muted);
|
|
23
|
+
background: transparent;
|
|
24
|
+
font: inherit;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.fg-tabs__tab:hover { color: var(--color-text); }
|
|
30
|
+
.fg-tabs__tab[aria-selected="true"] {
|
|
31
|
+
border-bottom-color: var(--color-link);
|
|
32
|
+
color: var(--color-text);
|
|
33
|
+
font-weight: var(--weight-medium);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.fg-tabs__panel { min-width: 0; }
|
|
37
|
+
.fg-tabs__panel[hidden], .fg-tabs__heading[hidden] { display: none; }
|
|
38
|
+
.fg-tabs__heading {
|
|
39
|
+
margin-block: var(--space-4) var(--space-2);
|
|
40
|
+
font-size: var(--text-md);
|
|
41
|
+
font-weight: var(--weight-medium);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.fg-tabs__tab:focus-visible, .fg-tabs__panel:focus-visible {
|
|
45
|
+
outline: 2px solid var(--color-focus);
|
|
46
|
+
outline-offset: -2px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@media (max-width: 640px) {
|
|
50
|
+
.fg-tabs__tab { min-height: var(--control-lg); }
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/components.css
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
@import './components/drawer.css';
|
|
2
|
+
@import './components/tabs.css';
|
|
3
|
+
|
|
1
4
|
@layer components {
|
|
2
5
|
/* Package-owned typography keeps controls consistent across consuming apps. */
|
|
3
6
|
.fg-button, .fg-input, .fg-select, .fg-checkbox, .fg-field,
|
|
@@ -34,7 +37,10 @@
|
|
|
34
37
|
.fg-code-block__copy {
|
|
35
38
|
display: inline-flex;
|
|
36
39
|
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
37
41
|
gap: 0.4rem;
|
|
42
|
+
min-width: var(--control-lg);
|
|
43
|
+
min-height: var(--control-lg);
|
|
38
44
|
padding: 0.25rem 0.4rem;
|
|
39
45
|
border: 0;
|
|
40
46
|
border-radius: 0.25rem;
|