@filipgutica/ui 1.1.1 → 1.3.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/UiCodeBlock.vue.d.ts +1 -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 +290 -133
- 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 +51 -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 S, toDisplayString as C, unref as w, useId as T, useModel as E, useSlots as ee, watch as te, withCtx as D } from "vue";
|
|
2
|
+
import { CheckboxIndicator as O, CheckboxRoot as k, DialogClose as A, DialogContent as j, DialogDescription as ne, 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(w(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,65 @@ 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 = ee();
|
|
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(C(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 = [
|
|
74
|
+
"data-wrap",
|
|
75
|
+
"data-line-numbers",
|
|
76
|
+
"data-variant"
|
|
77
|
+
], oe = {
|
|
74
78
|
key: 0,
|
|
79
|
+
class: "fg-code-block__header"
|
|
80
|
+
}, se = {
|
|
81
|
+
key: 0,
|
|
82
|
+
class: "fg-code-block__title"
|
|
83
|
+
}, ce = {
|
|
84
|
+
key: 1,
|
|
75
85
|
class: "fg-code-block__language"
|
|
76
|
-
},
|
|
86
|
+
}, le = { class: "fg-code-block__actions" }, ue = ["disabled", "title"], de = {
|
|
87
|
+
viewBox: "0 0 24 24",
|
|
88
|
+
fill: "none",
|
|
89
|
+
stroke: "currentColor",
|
|
90
|
+
"stroke-width": "1.5",
|
|
91
|
+
"aria-hidden": "true"
|
|
92
|
+
}, fe = {
|
|
93
|
+
key: 0,
|
|
94
|
+
d: "m5 12 4 4L19 6"
|
|
95
|
+
}, pe = { key: 0 }, me = ["aria-label"], he = {
|
|
77
96
|
key: 0,
|
|
78
97
|
class: "fg-code-block__number",
|
|
79
98
|
"aria-hidden": "true"
|
|
80
|
-
},
|
|
81
|
-
class: "fg-code-block__status",
|
|
82
|
-
role: "status"
|
|
83
|
-
}, ue = /* @__PURE__ */ c({
|
|
99
|
+
}, ge = { class: "fg-code-block__text" }, _e = ["data-state"], ve = /* @__PURE__ */ c({
|
|
84
100
|
__name: "UiCodeBlock",
|
|
85
101
|
props: {
|
|
86
102
|
code: {},
|
|
@@ -97,10 +113,11 @@ var U = /* @__PURE__ */ c({
|
|
|
97
113
|
wrap: {
|
|
98
114
|
type: Boolean,
|
|
99
115
|
default: !1
|
|
100
|
-
}
|
|
116
|
+
},
|
|
117
|
+
variant: { default: "default" }
|
|
101
118
|
},
|
|
102
119
|
setup(n) {
|
|
103
|
-
let s =
|
|
120
|
+
let s = S(), c = v(""), l = t(() => s.value ?? n.code.split("\n").map((e) => [{ content: e }])), u = {
|
|
104
121
|
vue: "vue",
|
|
105
122
|
ts: "typescript",
|
|
106
123
|
typescript: "typescript",
|
|
@@ -136,93 +153,93 @@ var U = /* @__PURE__ */ c({
|
|
|
136
153
|
i || (c.value = "Syntax highlighting unavailable. Showing plain text.");
|
|
137
154
|
}
|
|
138
155
|
}, { immediate: !0 });
|
|
139
|
-
let d =
|
|
156
|
+
let d = v(!1), { start: p } = K(() => {
|
|
140
157
|
d.value = !1;
|
|
141
|
-
}, 1500, { immediate: !1 }),
|
|
142
|
-
if (
|
|
143
|
-
|
|
158
|
+
}, 1500, { immediate: !1 }), m = v(!1), g = v(""), _ = t(() => d.value && !g.value), x = t(() => n.variant === "compact" && _.value && !c.value), w = t(() => g.value ? g.value : n.variant === "compact" && c.value ? d.value ? `Code copied to clipboard. ${c.value}` : c.value : d.value ? "Code copied to clipboard." : c.value), T = async () => {
|
|
159
|
+
if (g.value = "", d.value = !1, typeof navigator > "u" || !navigator.clipboard?.writeText) {
|
|
160
|
+
g.value = "Clipboard unavailable. Select the code to copy it.";
|
|
144
161
|
return;
|
|
145
162
|
}
|
|
146
|
-
|
|
163
|
+
m.value = !0;
|
|
147
164
|
try {
|
|
148
|
-
await navigator.clipboard.writeText(n.code), d.value = !0,
|
|
165
|
+
await navigator.clipboard.writeText(n.code), d.value = !0, p();
|
|
149
166
|
} catch {
|
|
150
|
-
|
|
167
|
+
g.value = "Could not copy. Select the code to copy it.";
|
|
151
168
|
} finally {
|
|
152
|
-
|
|
169
|
+
m.value = !1;
|
|
153
170
|
}
|
|
154
171
|
};
|
|
155
|
-
return (t, s) => (
|
|
172
|
+
return (t, s) => (h(), i("div", {
|
|
156
173
|
class: "fg-code-block",
|
|
157
174
|
"data-wrap": n.wrap,
|
|
158
|
-
"data-line-numbers": n.lineNumbers
|
|
175
|
+
"data-line-numbers": n.lineNumbers,
|
|
176
|
+
"data-variant": n.variant
|
|
159
177
|
}, [
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
n.title ? (
|
|
163
|
-
a("div",
|
|
178
|
+
n.variant === "default" || n.copyable || t.$slots.actions ? (h(), i("div", oe, [
|
|
179
|
+
n.variant === "default" ? (h(), i("span", se, C(n.title || n.language), 1)) : r("", !0),
|
|
180
|
+
n.title && n.variant === "default" ? (h(), i("span", ce, C(n.language), 1)) : r("", !0),
|
|
181
|
+
a("div", le, [b(t.$slots, "actions"), n.copyable ? (h(), i("button", {
|
|
164
182
|
key: 0,
|
|
165
183
|
type: "button",
|
|
166
184
|
class: "fg-code-block__copy",
|
|
167
|
-
disabled:
|
|
185
|
+
disabled: m.value,
|
|
168
186
|
"aria-label": "Copy code",
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
fill: "none",
|
|
173
|
-
stroke: "currentColor",
|
|
174
|
-
"stroke-width": "1.5",
|
|
175
|
-
"aria-hidden": "true"
|
|
176
|
-
}, [a("rect", {
|
|
187
|
+
title: n.variant === "compact" ? _.value ? "Copied" : "Copy code" : void 0,
|
|
188
|
+
onClick: T
|
|
189
|
+
}, [(h(), i("svg", de, [n.variant === "compact" && _.value ? (h(), i("path", fe)) : (h(), i(e, { key: 1 }, [s[0] ||= a("rect", {
|
|
177
190
|
x: "8",
|
|
178
191
|
y: "8",
|
|
179
192
|
width: "12",
|
|
180
193
|
height: "13",
|
|
181
194
|
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" }
|
|
183
|
-
]),
|
|
195
|
+
}, null, -1), s[1] ||= a("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))])), n.variant === "default" ? (h(), i("span", pe, C(_.value ? "Copied" : "Copy"), 1)) : r("", !0)], 8, ue)) : r("", !0)])
|
|
196
|
+
])) : r("", !0),
|
|
184
197
|
a("pre", {
|
|
185
198
|
class: "fg-code-block__pre",
|
|
186
199
|
tabindex: "0",
|
|
187
200
|
"aria-label": n.title || `${n.language} code`
|
|
188
|
-
}, [a("code", null, [(
|
|
201
|
+
}, [a("code", null, [(h(!0), i(e, null, y(l.value, (t, s) => (h(), i("span", {
|
|
189
202
|
key: s,
|
|
190
203
|
class: "fg-code-block__line"
|
|
191
|
-
}, [n.lineNumbers ? (
|
|
204
|
+
}, [n.lineNumbers ? (h(), i("span", he, C(s + 1), 1)) : r("", !0), a("span", ge, [(h(!0), i(e, null, y(t, (e, t) => (h(), i("span", {
|
|
192
205
|
key: t,
|
|
193
206
|
style: f({ color: e.color })
|
|
194
|
-
},
|
|
195
|
-
a("span",
|
|
196
|
-
|
|
207
|
+
}, C(e.content), 5))), 128)), o(C(s < l.value.length - 1 ? "\n" : ""), 1)])]))), 128))])], 8, me),
|
|
208
|
+
a("span", {
|
|
209
|
+
class: "fg-code-block__status",
|
|
210
|
+
role: "status",
|
|
211
|
+
"data-state": x.value ? "success" : void 0
|
|
212
|
+
}, C(w.value), 9, _e)
|
|
213
|
+
], 8, ae));
|
|
197
214
|
}
|
|
198
|
-
}),
|
|
215
|
+
}), ye = /* @__PURE__ */ c({
|
|
199
216
|
__name: "UiAlert",
|
|
200
217
|
props: { tone: { default: "neutral" } },
|
|
201
218
|
setup(e) {
|
|
202
|
-
return (t, r) => (
|
|
219
|
+
return (t, r) => (h(), n(w(L), {
|
|
203
220
|
as: "div",
|
|
204
221
|
class: "fg-alert",
|
|
205
222
|
"data-tone": e.tone,
|
|
206
223
|
role: e.tone === "danger" || e.tone === "error" ? "alert" : "status"
|
|
207
224
|
}, {
|
|
208
|
-
default:
|
|
225
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
209
226
|
_: 3
|
|
210
227
|
}, 8, ["data-tone", "role"]));
|
|
211
228
|
}
|
|
212
|
-
}),
|
|
229
|
+
}), be = /* @__PURE__ */ c({
|
|
213
230
|
__name: "UiBadge",
|
|
214
231
|
props: { tone: { default: "neutral" } },
|
|
215
232
|
setup(e) {
|
|
216
|
-
return (t, r) => (
|
|
233
|
+
return (t, r) => (h(), n(w(L), {
|
|
217
234
|
as: "span",
|
|
218
235
|
class: "fg-badge",
|
|
219
236
|
"data-tone": e.tone
|
|
220
237
|
}, {
|
|
221
|
-
default:
|
|
238
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
222
239
|
_: 3
|
|
223
240
|
}, 8, ["data-tone"]));
|
|
224
241
|
}
|
|
225
|
-
}),
|
|
242
|
+
}), xe = ["data-size", "data-disabled"], Se = { class: "fg-checkbox__label" }, Ce = /* @__PURE__ */ c({
|
|
226
243
|
__name: "UiCheckbox",
|
|
227
244
|
props: {
|
|
228
245
|
disabled: {
|
|
@@ -240,27 +257,28 @@ var U = /* @__PURE__ */ c({
|
|
|
240
257
|
let n = t, r = (e) => {
|
|
241
258
|
n("update:modelValue", e === !0);
|
|
242
259
|
};
|
|
243
|
-
return (t, n) => (
|
|
260
|
+
return (t, n) => (h(), i("label", {
|
|
244
261
|
class: "fg-checkbox",
|
|
245
262
|
"data-size": e.size,
|
|
246
263
|
"data-disabled": e.disabled ? "true" : void 0
|
|
247
|
-
}, [s(
|
|
264
|
+
}, [s(w(k), {
|
|
248
265
|
class: "fg-checkbox__control",
|
|
249
266
|
disabled: e.disabled,
|
|
250
267
|
"model-value": e.modelValue,
|
|
251
268
|
"onUpdate:modelValue": r
|
|
252
269
|
}, {
|
|
253
|
-
default:
|
|
254
|
-
default:
|
|
270
|
+
default: D(() => [s(w(O), { class: "fg-checkbox__indicator" }, {
|
|
271
|
+
default: D(() => [...n[0] ||= [o("✓", -1)]]),
|
|
255
272
|
_: 1
|
|
256
273
|
})]),
|
|
257
274
|
_: 1
|
|
258
|
-
}, 8, ["disabled", "model-value"]), a("span",
|
|
275
|
+
}, 8, ["disabled", "model-value"]), a("span", Se, [b(t.$slots, "default")])], 8, xe));
|
|
259
276
|
}
|
|
260
|
-
}),
|
|
277
|
+
}), we = { class: "fg-dialog__header" }, Te = { class: "fg-dialog__body" }, Ee = {
|
|
261
278
|
key: 0,
|
|
262
279
|
class: "fg-dialog__footer"
|
|
263
|
-
},
|
|
280
|
+
}, De = /* @__PURE__ */ c({
|
|
281
|
+
inheritAttrs: !1,
|
|
264
282
|
__name: "UiDialog",
|
|
265
283
|
props: {
|
|
266
284
|
description: { default: () => void 0 },
|
|
@@ -270,43 +288,86 @@ var U = /* @__PURE__ */ c({
|
|
|
270
288
|
emits: ["update:open"],
|
|
271
289
|
setup(e, { emit: t }) {
|
|
272
290
|
let c = t;
|
|
273
|
-
return (t, l) => (
|
|
291
|
+
return (t, l) => (h(), n(w(P), {
|
|
274
292
|
open: e.open,
|
|
275
293
|
"onUpdate:open": l[0] ||= (e) => c("update:open", e)
|
|
276
294
|
}, {
|
|
277
|
-
default:
|
|
278
|
-
default:
|
|
295
|
+
default: D(() => [s(w(N), null, {
|
|
296
|
+
default: D(() => [s(w(M), { class: "fg-dialog__overlay" }), s(w(j), d({
|
|
279
297
|
class: "fg-dialog__content",
|
|
280
298
|
"aria-modal": "true"
|
|
281
|
-
}, {
|
|
282
|
-
default:
|
|
283
|
-
a("div",
|
|
284
|
-
default:
|
|
299
|
+
}, t.$attrs), {
|
|
300
|
+
default: D(() => [
|
|
301
|
+
a("div", we, [a("div", null, [s(w(F), { class: "fg-dialog__title" }, {
|
|
302
|
+
default: D(() => [o(C(e.title), 1)]),
|
|
285
303
|
_: 1
|
|
286
|
-
}), e.description ? (
|
|
304
|
+
}), e.description ? (h(), n(w(ne), {
|
|
287
305
|
key: 0,
|
|
288
306
|
class: "fg-dialog__description"
|
|
289
307
|
}, {
|
|
290
|
-
default:
|
|
308
|
+
default: D(() => [o(C(e.description), 1)]),
|
|
291
309
|
_: 1
|
|
292
|
-
})) : r("", !0)]), s(
|
|
310
|
+
})) : r("", !0)]), s(w(A), {
|
|
293
311
|
class: "fg-dialog__close",
|
|
294
312
|
"aria-label": "Close dialog"
|
|
295
313
|
}, {
|
|
296
|
-
default:
|
|
314
|
+
default: D(() => [...l[1] ||= [o(" × ", -1)]]),
|
|
297
315
|
_: 1
|
|
298
316
|
})]),
|
|
299
|
-
a("div",
|
|
300
|
-
t.$slots.footer ? (
|
|
317
|
+
a("div", Te, [b(t.$slots, "default")]),
|
|
318
|
+
t.$slots.footer ? (h(), i("div", Ee, [b(t.$slots, "footer")])) : r("", !0)
|
|
301
319
|
]),
|
|
302
320
|
_: 3
|
|
303
|
-
})]),
|
|
321
|
+
}, 16)]),
|
|
304
322
|
_: 3
|
|
305
323
|
})]),
|
|
306
324
|
_: 3
|
|
307
325
|
}, 8, ["open"]));
|
|
308
326
|
}
|
|
309
|
-
}),
|
|
327
|
+
}), Oe = { class: "fg-drawer__header" }, ke = { class: "fg-drawer__body" }, Ae = /* @__PURE__ */ c({
|
|
328
|
+
inheritAttrs: !1,
|
|
329
|
+
__name: "UiDrawer",
|
|
330
|
+
props: {
|
|
331
|
+
open: { type: Boolean },
|
|
332
|
+
title: {}
|
|
333
|
+
},
|
|
334
|
+
emits: ["update:open", "closeAutoFocus"],
|
|
335
|
+
setup(e, { emit: t }) {
|
|
336
|
+
let i = t;
|
|
337
|
+
return (t, c) => (h(), n(w(P), {
|
|
338
|
+
open: e.open,
|
|
339
|
+
"onUpdate:open": c[1] ||= (e) => i("update:open", e)
|
|
340
|
+
}, {
|
|
341
|
+
default: D(() => [t.$slots.trigger ? (h(), n(w(I), {
|
|
342
|
+
key: 0,
|
|
343
|
+
"as-child": ""
|
|
344
|
+
}, {
|
|
345
|
+
default: D(() => [b(t.$slots, "trigger")]),
|
|
346
|
+
_: 3
|
|
347
|
+
})) : r("", !0), s(w(N), null, {
|
|
348
|
+
default: D(() => [s(w(M), { class: "fg-drawer__overlay" }), s(w(j), d({
|
|
349
|
+
class: "fg-drawer__content",
|
|
350
|
+
"aria-modal": "true",
|
|
351
|
+
"aria-describedby": void 0
|
|
352
|
+
}, t.$attrs, { onCloseAutoFocus: c[0] ||= (e) => i("closeAutoFocus", e) }), {
|
|
353
|
+
default: D(() => [a("div", Oe, [s(w(F), { class: "fg-drawer__title" }, {
|
|
354
|
+
default: D(() => [o(C(e.title), 1)]),
|
|
355
|
+
_: 1
|
|
356
|
+
}), s(w(A), {
|
|
357
|
+
class: "fg-drawer__close",
|
|
358
|
+
"aria-label": "Close drawer"
|
|
359
|
+
}, {
|
|
360
|
+
default: D(() => [...c[2] ||= [o(" × ", -1)]]),
|
|
361
|
+
_: 1
|
|
362
|
+
})]), a("div", ke, [b(t.$slots, "default")])]),
|
|
363
|
+
_: 3
|
|
364
|
+
}, 16)]),
|
|
365
|
+
_: 3
|
|
366
|
+
})]),
|
|
367
|
+
_: 3
|
|
368
|
+
}, 8, ["open"]));
|
|
369
|
+
}
|
|
370
|
+
}), Q = Symbol("UiFieldContext"), je = ["data-invalid"], Me = ["for"], Ne = ["id"], Pe = ["id"], Fe = /* @__PURE__ */ c({
|
|
310
371
|
__name: "UiField",
|
|
311
372
|
props: {
|
|
312
373
|
controlId: {},
|
|
@@ -316,38 +377,38 @@ var U = /* @__PURE__ */ c({
|
|
|
316
377
|
},
|
|
317
378
|
setup(e) {
|
|
318
379
|
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
|
|
380
|
+
return g(Q, {
|
|
320
381
|
controlId: t(() => e.controlId),
|
|
321
382
|
descriptionId: n,
|
|
322
383
|
errorId: o,
|
|
323
384
|
invalid: s
|
|
324
|
-
}), (t, s) => (
|
|
385
|
+
}), (t, s) => (h(), i("div", {
|
|
325
386
|
class: "fg-field",
|
|
326
387
|
"data-invalid": e.error ? "true" : void 0
|
|
327
388
|
}, [
|
|
328
389
|
a("label", {
|
|
329
390
|
class: "fg-field__label",
|
|
330
391
|
for: e.controlId
|
|
331
|
-
},
|
|
332
|
-
|
|
392
|
+
}, C(e.label), 9, Me),
|
|
393
|
+
b(t.$slots, "default", {
|
|
333
394
|
descriptionId: n.value,
|
|
334
395
|
errorId: o.value
|
|
335
396
|
}),
|
|
336
|
-
e.description && !e.error ? (
|
|
397
|
+
e.description && !e.error ? (h(), i("p", {
|
|
337
398
|
key: 0,
|
|
338
399
|
id: n.value,
|
|
339
400
|
class: "fg-field__description",
|
|
340
401
|
"data-field-description": ""
|
|
341
|
-
},
|
|
342
|
-
e.error ? (
|
|
402
|
+
}, C(e.description), 9, Ne)) : r("", !0),
|
|
403
|
+
e.error ? (h(), i("p", {
|
|
343
404
|
key: 1,
|
|
344
405
|
id: o.value,
|
|
345
406
|
class: "fg-field__error",
|
|
346
407
|
"data-field-error": ""
|
|
347
|
-
},
|
|
348
|
-
], 8,
|
|
408
|
+
}, C(e.error), 9, Pe)) : r("", !0)
|
|
409
|
+
], 8, je));
|
|
349
410
|
}
|
|
350
|
-
}),
|
|
411
|
+
}), Ie = /* @__PURE__ */ c({
|
|
351
412
|
__name: "UiInput",
|
|
352
413
|
props: {
|
|
353
414
|
disabled: {
|
|
@@ -368,13 +429,13 @@ var U = /* @__PURE__ */ c({
|
|
|
368
429
|
let r = l(Q, void 0), i = t, a = (e) => {
|
|
369
430
|
e.currentTarget instanceof HTMLInputElement && i("update:modelValue", e.currentTarget.value);
|
|
370
431
|
};
|
|
371
|
-
return (t, i) => (
|
|
372
|
-
id:
|
|
432
|
+
return (t, i) => (h(), n(w(L), {
|
|
433
|
+
id: w(r)?.controlId.value ?? e.id,
|
|
373
434
|
as: "input",
|
|
374
435
|
class: "fg-input",
|
|
375
|
-
"aria-describedby":
|
|
376
|
-
"aria-errormessage":
|
|
377
|
-
"aria-invalid": e.invalid ||
|
|
436
|
+
"aria-describedby": w(r)?.descriptionId.value,
|
|
437
|
+
"aria-errormessage": w(r)?.errorId.value,
|
|
438
|
+
"aria-invalid": e.invalid || w(r)?.invalid.value ? "true" : void 0,
|
|
378
439
|
"data-size": e.size,
|
|
379
440
|
disabled: e.disabled,
|
|
380
441
|
type: e.type,
|
|
@@ -391,7 +452,7 @@ var U = /* @__PURE__ */ c({
|
|
|
391
452
|
"value"
|
|
392
453
|
]));
|
|
393
454
|
}
|
|
394
|
-
}),
|
|
455
|
+
}), Le = 100, Re = /* @__PURE__ */ c({
|
|
395
456
|
__name: "UiProgress",
|
|
396
457
|
props: {
|
|
397
458
|
label: {},
|
|
@@ -400,19 +461,19 @@ var U = /* @__PURE__ */ c({
|
|
|
400
461
|
},
|
|
401
462
|
setup(e) {
|
|
402
463
|
let r = t(() => {
|
|
403
|
-
let t = Number.isFinite(e.max) && e.max > 0 ? e.max :
|
|
464
|
+
let t = Number.isFinite(e.max) && e.max > 0 ? e.max : Le;
|
|
404
465
|
return {
|
|
405
466
|
max: t,
|
|
406
467
|
value: e.value === null || !Number.isFinite(e.value) ? null : Math.min(t, Math.max(0, e.value))
|
|
407
468
|
};
|
|
408
469
|
}), i = t(() => r.value.value === null ? 0 : r.value.value / r.value.max * 100);
|
|
409
|
-
return (t, a) => (
|
|
470
|
+
return (t, a) => (h(), n(w(z), {
|
|
410
471
|
class: "fg-progress",
|
|
411
472
|
"aria-label": e.label,
|
|
412
473
|
max: r.value.max,
|
|
413
474
|
"model-value": r.value.value
|
|
414
475
|
}, {
|
|
415
|
-
default:
|
|
476
|
+
default: D(() => [s(w(R), {
|
|
416
477
|
class: "fg-progress__indicator",
|
|
417
478
|
style: f({ transform: `translateX(-${100 - i.value}%)` })
|
|
418
479
|
}, null, 8, ["style"])]),
|
|
@@ -423,7 +484,7 @@ var U = /* @__PURE__ */ c({
|
|
|
423
484
|
"model-value"
|
|
424
485
|
]));
|
|
425
486
|
}
|
|
426
|
-
}),
|
|
487
|
+
}), ze = { class: "fg-radio-card__content" }, Be = /* @__PURE__ */ c({
|
|
427
488
|
__name: "UiRadioCard",
|
|
428
489
|
props: {
|
|
429
490
|
disabled: {
|
|
@@ -433,19 +494,19 @@ var U = /* @__PURE__ */ c({
|
|
|
433
494
|
value: {}
|
|
434
495
|
},
|
|
435
496
|
setup(e) {
|
|
436
|
-
return (t, r) => (
|
|
497
|
+
return (t, r) => (h(), n(w(B), {
|
|
437
498
|
class: "fg-radio-card",
|
|
438
499
|
disabled: e.disabled,
|
|
439
500
|
value: e.value
|
|
440
501
|
}, {
|
|
441
|
-
default:
|
|
502
|
+
default: D(() => [r[0] ||= a("span", {
|
|
442
503
|
class: "fg-radio-card__indicator",
|
|
443
504
|
"aria-hidden": "true"
|
|
444
|
-
}, null, -1), a("span",
|
|
505
|
+
}, null, -1), a("span", ze, [b(t.$slots, "default")])]),
|
|
445
506
|
_: 3
|
|
446
507
|
}, 8, ["disabled", "value"]));
|
|
447
508
|
}
|
|
448
|
-
}),
|
|
509
|
+
}), Ve = /* @__PURE__ */ c({
|
|
449
510
|
__name: "UiRadioCardGroup",
|
|
450
511
|
props: /*@__PURE__*/ u({
|
|
451
512
|
disabled: {
|
|
@@ -463,7 +524,7 @@ var U = /* @__PURE__ */ c({
|
|
|
463
524
|
}),
|
|
464
525
|
emits: ["update:modelValue"],
|
|
465
526
|
setup(e) {
|
|
466
|
-
let t =
|
|
527
|
+
let t = E(e, "modelValue"), r = (t) => {
|
|
467
528
|
if (t.altKey || t.ctrlKey || t.metaKey || t.shiftKey) return;
|
|
468
529
|
let n = t.currentTarget, r = t.target;
|
|
469
530
|
if (!(n instanceof HTMLElement) || !(r instanceof HTMLElement)) return;
|
|
@@ -479,14 +540,14 @@ var U = /* @__PURE__ */ c({
|
|
|
479
540
|
let d = o[u];
|
|
480
541
|
!d || d === r || (t.preventDefault(), d.focus(), d.click());
|
|
481
542
|
};
|
|
482
|
-
return (i, a) => (
|
|
543
|
+
return (i, a) => (h(), n(w(V), d({
|
|
483
544
|
modelValue: t.value,
|
|
484
545
|
"onUpdate:modelValue": a[0] ||= (e) => t.value = e,
|
|
485
546
|
class: "fg-radio-card-group",
|
|
486
547
|
disabled: e.disabled,
|
|
487
548
|
loop: e.loop
|
|
488
549
|
}, e.orientation === void 0 ? {} : { orientation: e.orientation }, { onKeydown: r }), {
|
|
489
|
-
default:
|
|
550
|
+
default: D(() => [b(i.$slots, "default")]),
|
|
490
551
|
_: 3
|
|
491
552
|
}, 16, [
|
|
492
553
|
"modelValue",
|
|
@@ -494,7 +555,7 @@ var U = /* @__PURE__ */ c({
|
|
|
494
555
|
"loop"
|
|
495
556
|
]));
|
|
496
557
|
}
|
|
497
|
-
}),
|
|
558
|
+
}), $ = /* @__PURE__ */ c({
|
|
498
559
|
__name: "UiSelect",
|
|
499
560
|
props: {
|
|
500
561
|
disabled: {
|
|
@@ -514,19 +575,19 @@ var U = /* @__PURE__ */ c({
|
|
|
514
575
|
let r = l(Q, void 0), i = t, a = (e) => {
|
|
515
576
|
e.currentTarget instanceof HTMLSelectElement && i("update:modelValue", e.currentTarget.value);
|
|
516
577
|
};
|
|
517
|
-
return (t, i) => (
|
|
518
|
-
id:
|
|
578
|
+
return (t, i) => (h(), n(w(L), {
|
|
579
|
+
id: w(r)?.controlId.value ?? e.id,
|
|
519
580
|
as: "select",
|
|
520
581
|
class: "fg-select",
|
|
521
|
-
"aria-describedby":
|
|
522
|
-
"aria-errormessage":
|
|
523
|
-
"aria-invalid": e.invalid ||
|
|
582
|
+
"aria-describedby": w(r)?.descriptionId.value,
|
|
583
|
+
"aria-errormessage": w(r)?.errorId.value,
|
|
584
|
+
"aria-invalid": e.invalid || w(r)?.invalid.value ? "true" : void 0,
|
|
524
585
|
"data-size": e.size,
|
|
525
586
|
disabled: e.disabled,
|
|
526
587
|
value: e.modelValue,
|
|
527
588
|
onChange: a
|
|
528
589
|
}, {
|
|
529
|
-
default:
|
|
590
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
530
591
|
_: 3
|
|
531
592
|
}, 8, [
|
|
532
593
|
"id",
|
|
@@ -538,7 +599,7 @@ var U = /* @__PURE__ */ c({
|
|
|
538
599
|
"value"
|
|
539
600
|
]));
|
|
540
601
|
}
|
|
541
|
-
}),
|
|
602
|
+
}), He = /* @__PURE__ */ c({
|
|
542
603
|
__name: "UiSlider",
|
|
543
604
|
props: {
|
|
544
605
|
disabled: {
|
|
@@ -571,7 +632,7 @@ var U = /* @__PURE__ */ c({
|
|
|
571
632
|
e !== void 0 && o("update:modelValue", e);
|
|
572
633
|
}
|
|
573
634
|
});
|
|
574
|
-
return (t, r) => (
|
|
635
|
+
return (t, r) => (h(), n(w(U), {
|
|
575
636
|
modelValue: c.value,
|
|
576
637
|
"onUpdate:modelValue": r[0] ||= (e) => c.value = e,
|
|
577
638
|
class: "fg-slider",
|
|
@@ -581,15 +642,15 @@ var U = /* @__PURE__ */ c({
|
|
|
581
642
|
min: a.value.min,
|
|
582
643
|
step: a.value.step
|
|
583
644
|
}, {
|
|
584
|
-
default:
|
|
585
|
-
default:
|
|
645
|
+
default: D(() => [s(w(G), { class: "fg-slider__track" }, {
|
|
646
|
+
default: D(() => [s(w(H), { class: "fg-slider__range" })]),
|
|
586
647
|
_: 1
|
|
587
|
-
}), s(
|
|
588
|
-
id:
|
|
648
|
+
}), s(w(W), {
|
|
649
|
+
id: w(i)?.controlId.value ?? e.id,
|
|
589
650
|
class: "fg-slider__thumb",
|
|
590
|
-
"aria-describedby":
|
|
591
|
-
"aria-errormessage":
|
|
592
|
-
"aria-invalid":
|
|
651
|
+
"aria-describedby": w(i)?.descriptionId.value,
|
|
652
|
+
"aria-errormessage": w(i)?.errorId.value,
|
|
653
|
+
"aria-invalid": w(i)?.invalid.value ? "true" : void 0,
|
|
593
654
|
"aria-label": e.label
|
|
594
655
|
}, null, 8, [
|
|
595
656
|
"id",
|
|
@@ -608,22 +669,118 @@ var U = /* @__PURE__ */ c({
|
|
|
608
669
|
"step"
|
|
609
670
|
]));
|
|
610
671
|
}
|
|
611
|
-
}),
|
|
672
|
+
}), Ue = { class: "fg-tabs" }, We = ["aria-label"], Ge = [
|
|
673
|
+
"id",
|
|
674
|
+
"aria-controls",
|
|
675
|
+
"aria-selected",
|
|
676
|
+
"tabindex",
|
|
677
|
+
"onClick",
|
|
678
|
+
"onFocus"
|
|
679
|
+
], Ke = [
|
|
680
|
+
"id",
|
|
681
|
+
"role",
|
|
682
|
+
"aria-labelledby",
|
|
683
|
+
"hidden",
|
|
684
|
+
"tabindex"
|
|
685
|
+
], qe = ["id", "hidden"], Je = /* @__PURE__ */ c({
|
|
686
|
+
__name: "UiTabs",
|
|
687
|
+
props: {
|
|
688
|
+
items: {},
|
|
689
|
+
label: {},
|
|
690
|
+
modelValue: {}
|
|
691
|
+
},
|
|
692
|
+
emits: ["update:modelValue"],
|
|
693
|
+
setup(n, { emit: o }) {
|
|
694
|
+
let s = o, c = T(), 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)}`;
|
|
695
|
+
p(() => {
|
|
696
|
+
l.value = !0;
|
|
697
|
+
});
|
|
698
|
+
let g = (e) => {
|
|
699
|
+
e !== u.value && s("update:modelValue", e);
|
|
700
|
+
}, _ = (e) => {
|
|
701
|
+
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || ![
|
|
702
|
+
"ArrowLeft",
|
|
703
|
+
"ArrowRight",
|
|
704
|
+
"Home",
|
|
705
|
+
"End"
|
|
706
|
+
].includes(e.key)) return;
|
|
707
|
+
let t = e.currentTarget, n = e.target;
|
|
708
|
+
if (!(t instanceof HTMLElement) || !(n instanceof HTMLButtonElement)) return;
|
|
709
|
+
let r = [...t.querySelectorAll("[role=\"tab\"]")], i = r.indexOf(n);
|
|
710
|
+
if (i < 0 || r.length === 0) return;
|
|
711
|
+
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];
|
|
712
|
+
s && (e.preventDefault(), s.focus());
|
|
713
|
+
};
|
|
714
|
+
return (t, o) => (h(), i("div", Ue, [l.value ? (h(), i("div", {
|
|
715
|
+
key: 0,
|
|
716
|
+
class: "fg-tabs__list",
|
|
717
|
+
role: "tablist",
|
|
718
|
+
"aria-label": n.label,
|
|
719
|
+
onKeydown: _
|
|
720
|
+
}, [(h(!0), i(e, null, y(n.items, (e) => (h(), i("button", {
|
|
721
|
+
id: d(e.value),
|
|
722
|
+
key: e.value,
|
|
723
|
+
type: "button",
|
|
724
|
+
class: "fg-tabs__tab",
|
|
725
|
+
role: "tab",
|
|
726
|
+
"aria-controls": f(e.value),
|
|
727
|
+
"aria-selected": e.value === u.value,
|
|
728
|
+
tabindex: e.value === u.value ? 0 : -1,
|
|
729
|
+
onClick: (t) => g(e.value),
|
|
730
|
+
onFocus: (t) => g(e.value)
|
|
731
|
+
}, C(e.label), 41, Ge))), 128))], 40, We)) : r("", !0), (h(!0), i(e, null, y(n.items, (e) => (h(), i("section", {
|
|
732
|
+
id: f(e.value),
|
|
733
|
+
key: e.value,
|
|
734
|
+
class: "fg-tabs__panel",
|
|
735
|
+
role: l.value ? "tabpanel" : void 0,
|
|
736
|
+
"aria-labelledby": l.value ? d(e.value) : m(e.value),
|
|
737
|
+
hidden: l.value && e.value !== u.value,
|
|
738
|
+
tabindex: l.value ? 0 : void 0
|
|
739
|
+
}, [a("h3", {
|
|
740
|
+
id: m(e.value),
|
|
741
|
+
class: "fg-tabs__heading",
|
|
742
|
+
hidden: l.value
|
|
743
|
+
}, C(e.label), 9, qe), b(t.$slots, "panel", { value: e.value })], 8, Ke))), 128))]));
|
|
744
|
+
}
|
|
745
|
+
}), Ye = /* @__PURE__ */ c({
|
|
612
746
|
__name: "UiSurface",
|
|
613
747
|
props: {
|
|
614
748
|
as: { default: "section" },
|
|
615
749
|
padding: { default: "default" }
|
|
616
750
|
},
|
|
617
751
|
setup(e) {
|
|
618
|
-
return (t, r) => (
|
|
752
|
+
return (t, r) => (h(), n(w(L), {
|
|
619
753
|
as: e.as,
|
|
620
754
|
class: "fg-surface",
|
|
621
755
|
"data-padding": e.padding
|
|
622
756
|
}, {
|
|
623
|
-
default:
|
|
757
|
+
default: D(() => [b(t.$slots, "default")]),
|
|
624
758
|
_: 3
|
|
625
759
|
}, 8, ["as", "data-padding"]));
|
|
626
760
|
}
|
|
627
|
-
})
|
|
761
|
+
}), Xe = ({ targetIds: e }) => {
|
|
762
|
+
let t = v(e[0]), n, r, i;
|
|
763
|
+
return p(() => {
|
|
764
|
+
let a = e.flatMap((e) => {
|
|
765
|
+
let t = document.getElementById(e);
|
|
766
|
+
return t ? [{
|
|
767
|
+
id: e,
|
|
768
|
+
element: t
|
|
769
|
+
}] : [];
|
|
770
|
+
}), o = () => {
|
|
771
|
+
n = void 0;
|
|
772
|
+
let e = document.documentElement, r = Number.parseFloat(getComputedStyle(e).scrollPaddingTop) || 0, i = a[0]?.id;
|
|
773
|
+
for (let e of a) e.element.getBoundingClientRect().top <= r + 1 && (i = e.id);
|
|
774
|
+
window.scrollY > 0 && window.scrollY + window.innerHeight >= e.scrollHeight - 2 && (i = a.at(-1)?.id), t.value = i;
|
|
775
|
+
}, s = () => {
|
|
776
|
+
n === void 0 && (n = requestAnimationFrame(o));
|
|
777
|
+
};
|
|
778
|
+
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 = () => {
|
|
779
|
+
window.removeEventListener("scroll", s), window.removeEventListener("resize", s), window.removeEventListener("pageshow", s), document.body.removeEventListener("transitionend", s);
|
|
780
|
+
}, o();
|
|
781
|
+
}), m(() => {
|
|
782
|
+
i?.(), r?.disconnect(), n !== void 0 && cancelAnimationFrame(n);
|
|
783
|
+
}), _(t);
|
|
784
|
+
};
|
|
628
785
|
//#endregion
|
|
629
|
-
export {
|
|
786
|
+
export { ye as UiAlert, be as UiBadge, q as UiButton, ie as UiCard, Ce as UiCheckbox, ve as UiCodeBlock, De as UiDialog, Ae as UiDrawer, Fe as UiField, Ie as UiInput, Re as UiProgress, Be as UiRadioCard, Ve as UiRadioCardGroup, $ as UiSelect, He as UiSlider, Ye as UiSurface, Je as UiTabs, Xe 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.3.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;
|
|
@@ -55,6 +61,51 @@
|
|
|
55
61
|
.fg-code-block[data-wrap="true"] .fg-code-block__text { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
56
62
|
.fg-code-block__status:empty { display: none; }
|
|
57
63
|
.fg-code-block__status:not(:empty) { display: block; padding: 0.5rem 0.75rem; font-size: 0.75rem; }
|
|
64
|
+
.fg-code-block[data-variant="compact"] {
|
|
65
|
+
position: relative;
|
|
66
|
+
display: grid;
|
|
67
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
68
|
+
align-items: center;
|
|
69
|
+
}
|
|
70
|
+
.fg-code-block[data-variant="compact"] .fg-code-block__header {
|
|
71
|
+
grid-column: 2;
|
|
72
|
+
grid-row: 1;
|
|
73
|
+
min-height: 0;
|
|
74
|
+
padding: var(--space-1);
|
|
75
|
+
border: 0;
|
|
76
|
+
background: transparent;
|
|
77
|
+
}
|
|
78
|
+
.fg-code-block[data-variant="compact"] .fg-code-block__actions {
|
|
79
|
+
gap: var(--space-1);
|
|
80
|
+
margin-left: 0;
|
|
81
|
+
}
|
|
82
|
+
.fg-code-block[data-variant="compact"] .fg-code-block__copy {
|
|
83
|
+
padding: 0;
|
|
84
|
+
border-radius: var(--radius-control);
|
|
85
|
+
}
|
|
86
|
+
.fg-code-block[data-variant="compact"] .fg-code-block__pre {
|
|
87
|
+
grid-column: 1;
|
|
88
|
+
grid-row: 1;
|
|
89
|
+
min-width: 0;
|
|
90
|
+
padding: var(--space-2) var(--space-3);
|
|
91
|
+
}
|
|
92
|
+
.fg-code-block[data-variant="compact"] .fg-code-block__status:not(:empty) {
|
|
93
|
+
grid-column: 1 / -1;
|
|
94
|
+
padding: var(--space-2) var(--space-3);
|
|
95
|
+
font-size: var(--text-sm);
|
|
96
|
+
overflow-wrap: anywhere;
|
|
97
|
+
}
|
|
98
|
+
.fg-code-block[data-variant="compact"] .fg-code-block__status[data-state="success"] {
|
|
99
|
+
position: absolute;
|
|
100
|
+
top: 0;
|
|
101
|
+
left: 0;
|
|
102
|
+
width: 1px;
|
|
103
|
+
height: 1px;
|
|
104
|
+
padding: 0;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
clip-path: inset(50%);
|
|
107
|
+
white-space: nowrap;
|
|
108
|
+
}
|
|
58
109
|
.fg-button,
|
|
59
110
|
.fg-input,
|
|
60
111
|
.fg-select,
|