vunor 0.3.1 → 0.4.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 +8 -1
- package/dist/AppLayout.mjs +17 -68
- package/dist/AppToasts.d.mts +3 -0
- package/dist/AppToasts.mjs +59 -76
- package/dist/Button.d.mts +26 -10
- package/dist/Button.mjs +95 -60
- package/dist/ButtonBase.mjs +26 -40
- package/dist/Calendar.d.mts +14 -2
- package/dist/Calendar.mjs +37 -85
- package/dist/Card.mjs +6 -25
- package/dist/CardHeader.mjs +3 -12
- package/dist/Checkbox.d.mts +7 -2
- package/dist/Checkbox.mjs +37 -45
- package/dist/Combobox.d.mts +24 -8
- package/dist/Combobox.mjs +274 -350
- package/dist/DatePicker.d.mts +18 -4
- package/dist/DatePicker.mjs +93 -216
- package/dist/DatePickerBase.d.mts +21 -8
- package/dist/DatePickerBase.mjs +108 -257
- package/dist/DatePickerPopup.d.mts +27 -2
- package/dist/DatePickerPopup.mjs +62 -13
- package/dist/DelayedSwitch.mjs +3 -14
- package/dist/DevTools.mjs +377 -388
- package/dist/Dialog.d.mts +8 -3
- package/dist/Dialog.mjs +77 -107
- package/dist/Icon.mjs +1 -4
- package/dist/InnerLoading.mjs +1 -4
- package/dist/Input.mjs +35 -126
- package/dist/InputBase.mjs +28 -93
- package/dist/LoadingIndicator.mjs +1 -5
- package/dist/Menu.mjs +44 -65
- package/dist/MenuItem.mjs +4 -16
- package/dist/OverflowContainer.mjs +9 -11
- package/dist/Pagination.mjs +11 -29
- package/dist/Popover.d.mts +39 -11
- package/dist/Popover.mjs +80 -99
- package/dist/ProgressBar.d.mts +9 -2
- package/dist/ProgressBar.mjs +11 -27
- package/dist/RadioGroup.d.mts +2 -1
- package/dist/RadioGroup.mjs +33 -47
- package/dist/Select.d.mts +24 -7
- package/dist/Select.mjs +94 -186
- package/dist/SelectBase.d.mts +26 -11
- package/dist/SelectBase.mjs +59 -83
- package/dist/Slider.d.mts +6 -1
- package/dist/Slider.mjs +34 -103
- package/dist/Tabs.mjs +13 -49
- package/dist/forward-root-DPGTBptG.js +125 -0
- package/dist/nuxt.mjs +36 -1
- package/dist/theme.d.mts +1 -1
- package/dist/theme.mjs +22 -5
- package/dist/{utils-6bTTIoaw.js → utils-BCBGEM10.js} +30 -1
- package/dist/utils.mjs +1 -1
- package/dist/vite.d.mts +13 -4
- package/dist/vite.mjs +5 -0
- package/package.json +24 -9
- package/dist/utils-Z0nPSAzb.js +0 -42
package/README.md
CHANGED
|
@@ -287,6 +287,8 @@ Each includes hover, active, and focus states. Hover and press do not paint on a
|
|
|
287
287
|
<button class="scope-error c8-flat">Cancel</button>
|
|
288
288
|
```
|
|
289
289
|
|
|
290
|
+
The `btn` layout primitive fades a disabled element to opacity 0.8. That is a default: `disabled-soft` (0.4) or a `disabled:opacity-*` utility replaces it, whether written on the element or composed with `btn` in your own shortcut (`'my-btn': 'btn disabled-soft'`).
|
|
291
|
+
|
|
290
292
|
### Inputable Styles (`i8`)
|
|
291
293
|
|
|
292
294
|
Input field design variants:
|
|
@@ -377,9 +379,14 @@ export default defineConfig({
|
|
|
377
379
|
### Vue 3 + Vite
|
|
378
380
|
|
|
379
381
|
```bash
|
|
380
|
-
pnpm add vunor
|
|
382
|
+
pnpm add vunor vue unocss reka-ui
|
|
381
383
|
```
|
|
382
384
|
|
|
385
|
+
`vue`, `unocss` and `reka-ui` are peer dependencies: your app provides them, so it has a
|
|
386
|
+
single copy of each (two copies of Vue or Reka break reactivity and SSR). npm and pnpm
|
|
387
|
+
install missing peers automatically, but listing them pins the versions you use.
|
|
388
|
+
`vue-router` is optional: `<VuButton :to>` uses the `RouterLink` your app registers.
|
|
389
|
+
|
|
383
390
|
**vite.config.ts**
|
|
384
391
|
|
|
385
392
|
```ts
|
package/dist/AppLayout.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderSlot } from "vue";
|
|
2
|
-
import "\0stub:/Users/mavrik/code/vunor/packages/vunor/src/components/AppLayout/AppLayout.vue?vue&type=style&index=0&lang.css";
|
|
3
2
|
//#region src/components/AppLayout/AppLayout.vue?vue&type=script&setup=true&lang.ts
|
|
4
3
|
const _hoisted_1 = { class: "mx-auto max-w-[var(--app-max-w)] flex items-center justify-between w-full" };
|
|
5
4
|
const _hoisted_2 = { class: "max-w-[var(--app-max-w)] w-full mx-auto flex" };
|
|
@@ -16,71 +15,21 @@ const _hoisted_4 = {
|
|
|
16
15
|
var AppLayout_default = /* @__PURE__ */ defineComponent({
|
|
17
16
|
__name: "AppLayout",
|
|
18
17
|
props: {
|
|
19
|
-
maxW: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
leftW: {
|
|
35
|
-
type: String,
|
|
36
|
-
required: false,
|
|
37
|
-
default: "14rem"
|
|
38
|
-
},
|
|
39
|
-
rightW: {
|
|
40
|
-
type: String,
|
|
41
|
-
required: false,
|
|
42
|
-
default: "14rem"
|
|
43
|
-
},
|
|
44
|
-
footer: {
|
|
45
|
-
type: Boolean,
|
|
46
|
-
required: false
|
|
47
|
-
},
|
|
48
|
-
header: {
|
|
49
|
-
type: Boolean,
|
|
50
|
-
required: false
|
|
51
|
-
},
|
|
52
|
-
left: {
|
|
53
|
-
type: Boolean,
|
|
54
|
-
required: false
|
|
55
|
-
},
|
|
56
|
-
right: {
|
|
57
|
-
type: Boolean,
|
|
58
|
-
required: false
|
|
59
|
-
},
|
|
60
|
-
headerClass: {
|
|
61
|
-
type: [String, Object],
|
|
62
|
-
required: false
|
|
63
|
-
},
|
|
64
|
-
footerClass: {
|
|
65
|
-
type: [String, Object],
|
|
66
|
-
required: false
|
|
67
|
-
},
|
|
68
|
-
leftClass: {
|
|
69
|
-
type: [String, Object],
|
|
70
|
-
required: false
|
|
71
|
-
},
|
|
72
|
-
rightClass: {
|
|
73
|
-
type: [String, Object],
|
|
74
|
-
required: false
|
|
75
|
-
},
|
|
76
|
-
mainClass: {
|
|
77
|
-
type: [String, Object],
|
|
78
|
-
required: false
|
|
79
|
-
},
|
|
80
|
-
scrollTopOnChangeView: {
|
|
81
|
-
type: Boolean,
|
|
82
|
-
required: false
|
|
83
|
-
}
|
|
18
|
+
maxW: { default: "90rem" },
|
|
19
|
+
headerH: { default: "3rem" },
|
|
20
|
+
footerH: { default: "3rem" },
|
|
21
|
+
leftW: { default: "14rem" },
|
|
22
|
+
rightW: { default: "14rem" },
|
|
23
|
+
footer: { type: Boolean },
|
|
24
|
+
header: { type: Boolean },
|
|
25
|
+
left: { type: Boolean },
|
|
26
|
+
right: { type: Boolean },
|
|
27
|
+
headerClass: {},
|
|
28
|
+
footerClass: {},
|
|
29
|
+
leftClass: {},
|
|
30
|
+
rightClass: {},
|
|
31
|
+
mainClass: {},
|
|
32
|
+
scrollTopOnChangeView: { type: Boolean }
|
|
84
33
|
},
|
|
85
34
|
setup(__props) {
|
|
86
35
|
const props = __props;
|
|
@@ -123,7 +72,7 @@ var AppLayout_default = /* @__PURE__ */ defineComponent({
|
|
|
123
72
|
}, [__props.header ? (openBlock(), createElementBlock("header", {
|
|
124
73
|
key: 0,
|
|
125
74
|
class: normalizeClass(["sticky top-0 flex-shrink-0 h-[var(--app-header-h)] w-full flex", __props.headerClass])
|
|
126
|
-
}, [createElementVNode("div", _hoisted_1, [renderSlot(_ctx.$slots, "header")])], 2)) : createCommentVNode("
|
|
75
|
+
}, [createElementVNode("div", _hoisted_1, [renderSlot(_ctx.$slots, "header")])], 2)) : createCommentVNode("", true), createElementVNode("div", _hoisted_2, [
|
|
127
76
|
createElementVNode("aside", _hoisted_3, [createElementVNode("div", { class: normalizeClass(["min-h-full", __props.leftClass]) }, [renderSlot(_ctx.$slots, "left")], 2)]),
|
|
128
77
|
createElementVNode("main", {
|
|
129
78
|
class: normalizeClass(["flex-1 overflow-auto lg:pl-[var(--app-left-w)] lg:pr-[var(--app-right-w)]", __props.mainClass]),
|
|
@@ -134,7 +83,7 @@ var AppLayout_default = /* @__PURE__ */ defineComponent({
|
|
|
134
83
|
class: normalizeClass(["hidden xl:block w-[var(--app-right-w)] top-[var(--app-header-h)] overflow-auto fixed", __props.rightClass]),
|
|
135
84
|
style: "height: calc(100vh - var(--app-header-h) - var(--app-footer-h)); left: calc(50% - var(--app-right-w) + min(var(--app-max-w), 100vw) / 2);"
|
|
136
85
|
}, [renderSlot(_ctx.$slots, "right")], 2)
|
|
137
|
-
])], 512), __props.footer ? (openBlock(), createElementBlock("footer", _hoisted_4, [..._cache[0] || (_cache[0] = [createElementVNode("div", { class: "mx-auto max-w-[var(--app-max-w)] flex items-center justify-between w-full" }, " footer ", -1)])])) : createCommentVNode("
|
|
86
|
+
])], 512), __props.footer ? (openBlock(), createElementBlock("footer", _hoisted_4, [..._cache[0] || (_cache[0] = [createElementVNode("div", { class: "mx-auto max-w-[var(--app-max-w)] flex items-center justify-between w-full" }, " footer ", -1)])])) : createCommentVNode("", true)], 4);
|
|
138
87
|
};
|
|
139
88
|
}
|
|
140
89
|
});
|
package/dist/AppToasts.d.mts
CHANGED
|
@@ -2,8 +2,11 @@ import type { ToastProviderProps } from 'reka-ui';
|
|
|
2
2
|
import type { TVueCssClass } from 'vunor/utils';
|
|
3
3
|
type __VLS_Props = ToastProviderProps & {
|
|
4
4
|
class?: TVueCssClass;
|
|
5
|
+
/** Keys that focus the toast viewport (Reka `ToastViewport`), default F8 */
|
|
6
|
+
hotkey?: string[];
|
|
5
7
|
};
|
|
6
8
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
9
|
+
disableSwipe: boolean;
|
|
7
10
|
swipeDirection: "left" | "right" | "up" | "down";
|
|
8
11
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
12
|
declare const _default: typeof __VLS_export;
|
package/dist/AppToasts.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as useForwardToRoot } from "./forward-root-DPGTBptG.js";
|
|
2
|
+
import { Fragment, createBlock, createElementBlock, createElementVNode, createVNode, defineComponent, guardReactiveProps, mergeProps, normalizeClass, normalizeProps, openBlock, renderList, toDisplayString, unref, withCtx } from "vue";
|
|
2
3
|
import { ToastAction, ToastDescription, ToastProvider, ToastRoot, ToastTitle, ToastViewport } from "reka-ui";
|
|
3
4
|
import { useAppToasts } from "vunor";
|
|
4
5
|
import VuButton from "vunor/Button";
|
|
@@ -7,41 +8,24 @@ const _hoisted_1 = { class: "text-body-s" };
|
|
|
7
8
|
//#endregion
|
|
8
9
|
//#region src/components/AppToasts/AppToasts.vue
|
|
9
10
|
var AppToasts_default = /* @__PURE__ */ defineComponent({
|
|
11
|
+
inheritAttrs: false,
|
|
10
12
|
__name: "AppToasts",
|
|
11
13
|
props: {
|
|
12
|
-
label: {
|
|
13
|
-
|
|
14
|
-
required: false
|
|
15
|
-
},
|
|
16
|
-
duration: {
|
|
17
|
-
type: Number,
|
|
18
|
-
required: false
|
|
19
|
-
},
|
|
14
|
+
label: {},
|
|
15
|
+
duration: {},
|
|
20
16
|
disableSwipe: {
|
|
21
17
|
type: Boolean,
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
swipeDirection: {
|
|
25
|
-
type: String,
|
|
26
|
-
required: false,
|
|
27
|
-
default: "left"
|
|
18
|
+
default: void 0
|
|
28
19
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
class: {
|
|
34
|
-
type: [
|
|
35
|
-
String,
|
|
36
|
-
Array,
|
|
37
|
-
Object
|
|
38
|
-
],
|
|
39
|
-
required: false
|
|
40
|
-
}
|
|
20
|
+
swipeDirection: { default: "left" },
|
|
21
|
+
swipeThreshold: {},
|
|
22
|
+
class: {},
|
|
23
|
+
hotkey: {}
|
|
41
24
|
},
|
|
42
25
|
setup(__props) {
|
|
43
26
|
const { toasts, close } = useAppToasts();
|
|
44
27
|
const props = __props;
|
|
28
|
+
const providerProps = useForwardToRoot(ToastProvider, props);
|
|
45
29
|
const defaultActions = (toast) => [{
|
|
46
30
|
text: "Dismiss",
|
|
47
31
|
action: () => {
|
|
@@ -49,56 +33,55 @@ var AppToasts_default = /* @__PURE__ */ defineComponent({
|
|
|
49
33
|
}
|
|
50
34
|
}];
|
|
51
35
|
return (_ctx, _cache) => {
|
|
52
|
-
return openBlock(), createBlock(unref(ToastProvider),
|
|
53
|
-
default: withCtx(() => [
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
open
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
36
|
+
return openBlock(), createBlock(unref(ToastProvider), normalizeProps(guardReactiveProps(unref(providerProps))), {
|
|
37
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(toasts), (toast) => {
|
|
38
|
+
return openBlock(), createBlock(unref(ToastRoot), {
|
|
39
|
+
key: toast.id,
|
|
40
|
+
duration: toast.duration,
|
|
41
|
+
open: toast.open,
|
|
42
|
+
"onUpdate:open": [($event) => toast.open = $event, (open) => {
|
|
43
|
+
if (!open) unref(close)(toast.id);
|
|
44
|
+
}],
|
|
45
|
+
"data-swipe": __props.swipeDirection,
|
|
46
|
+
class: normalizeClass([toast.class, "toast-root"])
|
|
47
|
+
}, {
|
|
48
|
+
default: withCtx(() => [
|
|
49
|
+
createVNode(unref(ToastTitle), { class: "[grid-area:_title] mb-$s fw-$bold" }, {
|
|
50
|
+
default: withCtx(() => [createElementVNode("span", null, toDisplayString(toast.title), 1)]),
|
|
51
|
+
_: 2
|
|
52
|
+
}, 1024),
|
|
53
|
+
createVNode(unref(ToastDescription), { "as-child": "" }, {
|
|
54
|
+
default: withCtx(() => [createElementVNode("span", _hoisted_1, toDisplayString(toast.message), 1)]),
|
|
55
|
+
_: 2
|
|
56
|
+
}, 1024),
|
|
57
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(toast.actions || defaultActions(toast), (action) => {
|
|
58
|
+
return openBlock(), createBlock(unref(ToastAction), {
|
|
59
|
+
class: "[grid-area:_action]",
|
|
60
|
+
"as-child": "",
|
|
61
|
+
"alt-text": action.text,
|
|
62
|
+
key: action.text
|
|
63
|
+
}, {
|
|
64
|
+
default: withCtx(() => [createVNode(VuButton, {
|
|
65
|
+
onClick: ($event) => action.action(),
|
|
66
|
+
class: "c8-flat text-body-s",
|
|
67
|
+
label: action.text
|
|
68
|
+
}, null, 8, ["onClick", "label"])]),
|
|
73
69
|
_: 2
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}), 128))
|
|
90
|
-
]),
|
|
91
|
-
_: 2
|
|
92
|
-
}, 1032, [
|
|
93
|
-
"duration",
|
|
94
|
-
"open",
|
|
95
|
-
"onUpdate:open",
|
|
96
|
-
"data-swipe",
|
|
97
|
-
"class"
|
|
98
|
-
]);
|
|
99
|
-
}), 128)),
|
|
100
|
-
createVNode(unref(ToastViewport), { class: normalizeClass([props.class, "toasts-viewport"]) }, null, 8, ["class"])
|
|
101
|
-
]),
|
|
70
|
+
}, 1032, ["alt-text"]);
|
|
71
|
+
}), 128))
|
|
72
|
+
]),
|
|
73
|
+
_: 2
|
|
74
|
+
}, 1032, [
|
|
75
|
+
"duration",
|
|
76
|
+
"open",
|
|
77
|
+
"onUpdate:open",
|
|
78
|
+
"data-swipe",
|
|
79
|
+
"class"
|
|
80
|
+
]);
|
|
81
|
+
}), 128)), createVNode(unref(ToastViewport), mergeProps(_ctx.$attrs, {
|
|
82
|
+
hotkey: props.hotkey,
|
|
83
|
+
class: [props.class, "toasts-viewport"]
|
|
84
|
+
}), null, 16, ["hotkey", "class"])]),
|
|
102
85
|
_: 1
|
|
103
86
|
}, 16);
|
|
104
87
|
};
|
package/dist/Button.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type RouteLocationRaw } from 'vue-router';
|
|
2
1
|
type __VLS_Props = {
|
|
3
2
|
label?: string;
|
|
4
3
|
icon?: string;
|
|
@@ -8,26 +7,43 @@ type __VLS_Props = {
|
|
|
8
7
|
active?: boolean;
|
|
9
8
|
pressed?: boolean;
|
|
10
9
|
selected?: boolean;
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Router location: renders a router link through the app's RouterLink. Typed
|
|
12
|
+
* structurally (compatible with vue-router's `RouteLocationRaw`), so vunor needs no
|
|
13
|
+
* vue-router types. Without a router, a string (or `{ path }`) renders `<a href>`.
|
|
14
|
+
*/
|
|
15
|
+
to?: string | {
|
|
16
|
+
path?: string;
|
|
17
|
+
name?: string | symbol;
|
|
18
|
+
params?: Record<string, unknown>;
|
|
19
|
+
query?: Record<string, unknown>;
|
|
20
|
+
hash?: string;
|
|
21
|
+
replace?: boolean;
|
|
22
|
+
force?: boolean;
|
|
23
|
+
state?: unknown;
|
|
24
|
+
};
|
|
12
25
|
class?: string | Record<string, boolean>;
|
|
13
26
|
style?: string | Record<string, string>;
|
|
14
27
|
asLink?: boolean;
|
|
15
28
|
};
|
|
16
|
-
declare var
|
|
29
|
+
declare var __VLS_17: {}, __VLS_19: {}, __VLS_22: {}, __VLS_32: {}, __VLS_34: {}, __VLS_37: {};
|
|
17
30
|
type __VLS_Slots = {} & {
|
|
18
|
-
'icon-left'?: (props: typeof
|
|
31
|
+
'icon-left'?: (props: typeof __VLS_17) => any;
|
|
19
32
|
} & {
|
|
20
|
-
default?: (props: typeof
|
|
33
|
+
default?: (props: typeof __VLS_19) => any;
|
|
21
34
|
} & {
|
|
22
|
-
'icon-right'?: (props: typeof
|
|
35
|
+
'icon-right'?: (props: typeof __VLS_22) => any;
|
|
23
36
|
} & {
|
|
24
|
-
'icon-left'?: (props: typeof
|
|
37
|
+
'icon-left'?: (props: typeof __VLS_32) => any;
|
|
25
38
|
} & {
|
|
26
|
-
default?: (props: typeof
|
|
39
|
+
default?: (props: typeof __VLS_34) => any;
|
|
27
40
|
} & {
|
|
28
|
-
'icon-right'?: (props: typeof
|
|
41
|
+
'icon-right'?: (props: typeof __VLS_37) => any;
|
|
29
42
|
};
|
|
30
|
-
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
43
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
44
|
+
pressed: boolean;
|
|
45
|
+
selected: boolean;
|
|
46
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
31
47
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
32
48
|
declare const _default: typeof __VLS_export;
|
|
33
49
|
export default _default;
|
package/dist/Button.mjs
CHANGED
|
@@ -1,73 +1,107 @@
|
|
|
1
|
-
import { createBlock, createSlots, createVNode, defineComponent, mergeProps, openBlock, renderSlot, unref, withCtx } from "vue";
|
|
2
|
-
import { RouterLink } from "vue-router";
|
|
1
|
+
import { computed, createBlock, createSlots, createVNode, defineComponent, getCurrentInstance, mergeProps, openBlock, renderSlot, resolveDynamicComponent, unref, useAttrs, warn, withCtx } from "vue";
|
|
3
2
|
import VuButtonBase from "vunor/ButtonBase";
|
|
4
3
|
//#endregion
|
|
5
4
|
//#region src/components/Button/Button.vue
|
|
6
5
|
var Button_default = /* @__PURE__ */ defineComponent({
|
|
6
|
+
inheritAttrs: false,
|
|
7
7
|
__name: "Button",
|
|
8
8
|
props: {
|
|
9
|
-
label: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
required: false
|
|
16
|
-
},
|
|
17
|
-
iconSide: {
|
|
18
|
-
type: String,
|
|
19
|
-
required: false
|
|
20
|
-
},
|
|
21
|
-
loading: {
|
|
22
|
-
type: Boolean,
|
|
23
|
-
required: false
|
|
24
|
-
},
|
|
25
|
-
disabled: {
|
|
26
|
-
type: Boolean,
|
|
27
|
-
required: false
|
|
28
|
-
},
|
|
29
|
-
active: {
|
|
30
|
-
type: Boolean,
|
|
31
|
-
required: false
|
|
32
|
-
},
|
|
9
|
+
label: {},
|
|
10
|
+
icon: {},
|
|
11
|
+
iconSide: {},
|
|
12
|
+
loading: { type: Boolean },
|
|
13
|
+
disabled: { type: Boolean },
|
|
14
|
+
active: { type: Boolean },
|
|
33
15
|
pressed: {
|
|
34
16
|
type: Boolean,
|
|
35
|
-
|
|
17
|
+
default: void 0
|
|
36
18
|
},
|
|
37
19
|
selected: {
|
|
38
20
|
type: Boolean,
|
|
39
|
-
|
|
21
|
+
default: void 0
|
|
40
22
|
},
|
|
41
|
-
to: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
class: {
|
|
46
|
-
type: [String, Object],
|
|
47
|
-
required: false
|
|
48
|
-
},
|
|
49
|
-
style: {
|
|
50
|
-
type: [String, Object],
|
|
51
|
-
required: false
|
|
52
|
-
},
|
|
53
|
-
asLink: {
|
|
54
|
-
type: Boolean,
|
|
55
|
-
required: false
|
|
56
|
-
}
|
|
23
|
+
to: {},
|
|
24
|
+
class: {},
|
|
25
|
+
style: {},
|
|
26
|
+
asLink: { type: Boolean }
|
|
57
27
|
},
|
|
58
28
|
setup(__props) {
|
|
29
|
+
const SELECTABLE_ROLES = new Set([
|
|
30
|
+
"option",
|
|
31
|
+
"tab",
|
|
32
|
+
"gridcell",
|
|
33
|
+
"row",
|
|
34
|
+
"columnheader",
|
|
35
|
+
"rowheader",
|
|
36
|
+
"treeitem"
|
|
37
|
+
]);
|
|
38
|
+
/** the defined entries only: an `undefined` binding would still override or render */
|
|
39
|
+
function defined(values) {
|
|
40
|
+
const result = {};
|
|
41
|
+
for (const key in values) if (values[key] !== void 0) result[key] = values[key];
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
/** `@click` with any modifiers Vue keeps in the key (`.once`, `.capture`, `.passive`) */
|
|
45
|
+
const CLICK_LISTENER = /^onClick(?:Once|Passive|Capture)*$/;
|
|
59
46
|
const props = __props;
|
|
47
|
+
const RouterLink = getCurrentInstance()?.appContext.components.RouterLink;
|
|
48
|
+
const baseProps = computed(() => defined({
|
|
49
|
+
label: props.label,
|
|
50
|
+
icon: props.icon,
|
|
51
|
+
iconSide: props.iconSide,
|
|
52
|
+
loading: props.loading,
|
|
53
|
+
disabled: props.disabled,
|
|
54
|
+
class: props.class,
|
|
55
|
+
style: props.style
|
|
56
|
+
}));
|
|
57
|
+
const attrs = useAttrs();
|
|
58
|
+
const ariaSelected = computed(() => props.selected !== void 0 && SELECTABLE_ROLES.has(String(attrs.role)) ? props.selected : void 0);
|
|
59
|
+
const stateAttrs = computed(() => defined({
|
|
60
|
+
"data-active": props.active ? "" : void 0,
|
|
61
|
+
"aria-pressed": props.pressed,
|
|
62
|
+
"data-selected": props.selected === void 0 ? void 0 : String(props.selected),
|
|
63
|
+
"aria-selected": ariaSelected.value
|
|
64
|
+
}));
|
|
65
|
+
const inactive = computed(() => !!(props.disabled || props.loading));
|
|
66
|
+
function linkAttrs() {
|
|
67
|
+
const rest = {};
|
|
68
|
+
for (const key in attrs) {
|
|
69
|
+
if (key === "onClick" || inactive.value && CLICK_LISTENER.test(key)) continue;
|
|
70
|
+
rest[key] = attrs[key];
|
|
71
|
+
}
|
|
72
|
+
return rest;
|
|
73
|
+
}
|
|
74
|
+
function onLinkClick(event, navigate) {
|
|
75
|
+
if (inactive.value) {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const handlers = attrs.onClick;
|
|
80
|
+
for (const handler of [handlers ?? []].flat()) handler(event);
|
|
81
|
+
navigate?.(event);
|
|
82
|
+
}
|
|
83
|
+
const fallbackHref = computed(() => {
|
|
84
|
+
const to = props.to;
|
|
85
|
+
return typeof to === "string" ? to : to?.path;
|
|
86
|
+
});
|
|
87
|
+
const isLink = computed(() => props.asLink || fallbackHref.value !== void 0);
|
|
88
|
+
if (props.to !== void 0 && !RouterLink) warn("VuButton: `to` is set but the app has no router (app.use(router)); rendering a plain link without client-side navigation.");
|
|
60
89
|
return (_ctx, _cache) => {
|
|
61
|
-
return !!__props.to ? (openBlock(), createBlock(unref(RouterLink), {
|
|
90
|
+
return !!__props.to && unref(RouterLink) ? (openBlock(), createBlock(resolveDynamicComponent(unref(RouterLink)), {
|
|
62
91
|
key: 0,
|
|
63
92
|
custom: "",
|
|
64
93
|
to: __props.to
|
|
65
94
|
}, {
|
|
66
|
-
default: withCtx(({ isActive, href }) => [createVNode(VuButtonBase, mergeProps({
|
|
95
|
+
default: withCtx(({ isActive, isExactActive, href, navigate }) => [createVNode(VuButtonBase, mergeProps({
|
|
96
|
+
...isExactActive ? { "aria-current": "page" } : {},
|
|
97
|
+
...isActive ? { "data-selected": "true" } : {},
|
|
98
|
+
...linkAttrs(),
|
|
99
|
+
...baseProps.value
|
|
100
|
+
}, {
|
|
67
101
|
as: "a",
|
|
68
102
|
href,
|
|
69
|
-
|
|
70
|
-
}
|
|
103
|
+
onClick: ($event) => onLinkClick($event, navigate)
|
|
104
|
+
}), createSlots({
|
|
71
105
|
default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
|
|
72
106
|
_: 2
|
|
73
107
|
}, [_ctx.$slots["icon-left"] ? {
|
|
@@ -78,15 +112,21 @@ var Button_default = /* @__PURE__ */ defineComponent({
|
|
|
78
112
|
name: "icon-right",
|
|
79
113
|
fn: withCtx(() => [renderSlot(_ctx.$slots, "icon-right")]),
|
|
80
114
|
key: "1"
|
|
81
|
-
} : void 0]), 1040, ["href", "
|
|
115
|
+
} : void 0]), 1040, ["href", "onClick"])]),
|
|
82
116
|
_: 3
|
|
83
117
|
}, 8, ["to"])) : (openBlock(), createBlock(VuButtonBase, mergeProps({
|
|
84
118
|
key: 1,
|
|
85
|
-
as:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
119
|
+
as: isLink.value ? "a" : "button",
|
|
120
|
+
href: fallbackHref.value
|
|
121
|
+
}, isLink.value ? {
|
|
122
|
+
...stateAttrs.value,
|
|
123
|
+
...linkAttrs(),
|
|
124
|
+
...baseProps.value,
|
|
125
|
+
onClick: onLinkClick
|
|
126
|
+
} : {
|
|
127
|
+
...stateAttrs.value,
|
|
128
|
+
..._ctx.$attrs,
|
|
129
|
+
...baseProps.value
|
|
90
130
|
}), createSlots({
|
|
91
131
|
default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
|
|
92
132
|
_: 2
|
|
@@ -98,12 +138,7 @@ var Button_default = /* @__PURE__ */ defineComponent({
|
|
|
98
138
|
name: "icon-right",
|
|
99
139
|
fn: withCtx(() => [renderSlot(_ctx.$slots, "icon-right")]),
|
|
100
140
|
key: "1"
|
|
101
|
-
} : void 0]), 1040, [
|
|
102
|
-
"as",
|
|
103
|
-
"data-active",
|
|
104
|
-
"aria-pressed",
|
|
105
|
-
"aria-selected"
|
|
106
|
-
]));
|
|
141
|
+
} : void 0]), 1040, ["as", "href"]));
|
|
107
142
|
};
|
|
108
143
|
}
|
|
109
144
|
});
|
package/dist/ButtonBase.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeProps, openBlock, renderSlot, toDisplayString, unref, withCtx } from "vue";
|
|
2
2
|
import { Primitive } from "reka-ui";
|
|
3
3
|
import VuIcon from "vunor/Icon";
|
|
4
4
|
import VuLoadingIndicator from "vunor/LoadingIndicator";
|
|
@@ -13,71 +13,57 @@ const _hoisted_2 = { class: "btn-label" };
|
|
|
13
13
|
var ButtonBase_default = /* @__PURE__ */ defineComponent({
|
|
14
14
|
__name: "ButtonBase",
|
|
15
15
|
props: {
|
|
16
|
-
label: {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
iconSide: {
|
|
25
|
-
type: String,
|
|
26
|
-
required: false,
|
|
27
|
-
default: "left"
|
|
28
|
-
},
|
|
29
|
-
loading: {
|
|
30
|
-
type: Boolean,
|
|
31
|
-
required: false
|
|
32
|
-
},
|
|
33
|
-
disabled: {
|
|
34
|
-
type: Boolean,
|
|
35
|
-
required: false
|
|
36
|
-
},
|
|
37
|
-
as: {
|
|
38
|
-
type: String,
|
|
39
|
-
required: false,
|
|
40
|
-
default: "button"
|
|
41
|
-
},
|
|
42
|
-
href: {
|
|
43
|
-
type: String,
|
|
44
|
-
required: false
|
|
45
|
-
}
|
|
16
|
+
label: {},
|
|
17
|
+
icon: {},
|
|
18
|
+
iconSide: { default: "left" },
|
|
19
|
+
loading: { type: Boolean },
|
|
20
|
+
disabled: { type: Boolean },
|
|
21
|
+
as: { default: "button" },
|
|
22
|
+
href: {}
|
|
46
23
|
},
|
|
47
24
|
setup(__props) {
|
|
25
|
+
const INACTIVE_LINK_ATTRS = Object.freeze({
|
|
26
|
+
"role": "link",
|
|
27
|
+
"aria-disabled": "true",
|
|
28
|
+
"tabindex": 0
|
|
29
|
+
});
|
|
30
|
+
const NO_ATTRS = Object.freeze({});
|
|
31
|
+
const props = __props;
|
|
32
|
+
const inactiveLink = computed(() => props.as === "a" && !!(props.loading || props.disabled));
|
|
48
33
|
return (_ctx, _cache) => {
|
|
49
|
-
return openBlock(),
|
|
34
|
+
return openBlock(), createBlock(unref(Primitive), mergeProps({
|
|
50
35
|
class: "btn group/btn",
|
|
51
36
|
as: __props.as,
|
|
52
|
-
href: __props.href
|
|
37
|
+
href: inactiveLink.value ? void 0 : __props.href
|
|
38
|
+
}, inactiveLink.value ? unref(INACTIVE_LINK_ATTRS) : unref(NO_ATTRS), {
|
|
53
39
|
"data-has-label": !!__props.label || !!_ctx.$slots.default,
|
|
54
40
|
"data-has-icon": !!__props.icon,
|
|
55
41
|
"data-loading": __props.loading ? "" : void 0,
|
|
56
|
-
disabled: __props.loading || __props.disabled || void 0
|
|
57
|
-
}, {
|
|
42
|
+
disabled: __props.as === "button" ? __props.loading || __props.disabled || void 0 : void 0
|
|
43
|
+
}), {
|
|
58
44
|
default: withCtx(() => [
|
|
59
|
-
__props.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [createVNode(VuLoadingIndicator)])) : createCommentVNode("
|
|
45
|
+
__props.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [createVNode(VuLoadingIndicator)])) : createCommentVNode("", true),
|
|
60
46
|
renderSlot(_ctx.$slots, "icon-left", {}, () => [__props.icon && __props.iconSide === "left" ? (openBlock(), createBlock(VuIcon, {
|
|
61
47
|
key: 0,
|
|
62
48
|
name: __props.icon,
|
|
63
49
|
class: "btn-icon btn-icon-left"
|
|
64
|
-
}, null, 8, ["name"])) : createCommentVNode("
|
|
50
|
+
}, null, 8, ["name"])) : createCommentVNode("", true)]),
|
|
65
51
|
renderSlot(_ctx.$slots, "default", {}, () => [createElementVNode("span", _hoisted_2, toDisplayString(__props.label), 1)]),
|
|
66
52
|
renderSlot(_ctx.$slots, "icon-right", {}, () => [__props.icon && __props.iconSide === "right" ? (openBlock(), createBlock(VuIcon, {
|
|
67
53
|
key: 0,
|
|
68
54
|
name: __props.icon,
|
|
69
55
|
class: "btn-icon btn-icon-right"
|
|
70
|
-
}, null, 8, ["name"])) : createCommentVNode("
|
|
56
|
+
}, null, 8, ["name"])) : createCommentVNode("", true)])
|
|
71
57
|
]),
|
|
72
58
|
_: 3
|
|
73
|
-
},
|
|
59
|
+
}, 16, [
|
|
74
60
|
"as",
|
|
75
61
|
"href",
|
|
76
62
|
"data-has-label",
|
|
77
63
|
"data-has-icon",
|
|
78
64
|
"data-loading",
|
|
79
65
|
"disabled"
|
|
80
|
-
])
|
|
66
|
+
]);
|
|
81
67
|
};
|
|
82
68
|
}
|
|
83
69
|
});
|