@veritree/ui 0.19.2-21 → 0.19.2-22
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/package.json +1 -1
- package/src/components/Alert/VTAlert.vue +55 -14
- package/src/components/Dialog/VTDialog.vue +13 -11
- package/src/components/Dialog/VTDialogClose.vue +13 -19
- package/src/components/Dialog/VTDialogContent.vue +19 -14
- package/src/components/Dialog/VTDialogFooter.vue +9 -14
- package/src/components/Dialog/VTDialogHeader.vue +11 -13
- package/src/components/Dialog/VTDialogMain.vue +6 -13
- package/src/components/Dialog/VTDialogOverlay.vue +9 -13
- package/src/components/Dialog/VTDialogTitle.vue +8 -5
- package/src/components/Disclosure/VTDisclosureHeader.vue +1 -1
- package/src/components/DropdownMenu/VTDropdownMenu.vue +19 -0
- package/src/components/DropdownMenu/VTDropdownMenuContent.vue +14 -6
- package/src/components/DropdownMenu/VTDropdownMenuDivider.vue +7 -16
- package/src/components/DropdownMenu/VTDropdownMenuItem.vue +3 -7
- package/src/components/DropdownMenu/VTDropdownMenuLabel.vue +1 -10
- package/src/components/DropdownMenu/VTDropdownMenuTrigger.vue +4 -9
- package/src/components/Listbox/VTListboxItem.vue +0 -1
- package/src/components/Popover/VTPopover.vue +19 -0
- package/src/components/ProgressBar/VTProgressBar.vue +21 -3
- package/src/components/Skeleton/VTSkeleton.vue +11 -0
- package/src/components/Skeleton/VTSkeletonItem.vue +9 -0
- package/src/components/Tabs/VTTab.vue +13 -11
- package/src/components/Tooltip/VTTooltip.vue +65 -0
- package/src/components/Tooltip/VTTooltipContent.vue +59 -0
- package/src/components/Tooltip/VTTooltipTrigger.vue +98 -0
- package/src/components/Utils/FloatingUi.vue +6 -0
- package/src/components/Input/VTInput.vue +0 -82
- package/src/components/Input/VTInputDate.vue +0 -36
- package/src/components/Input/VTInputFile.vue +0 -60
- package/src/components/Input/VTInputUpload.vue +0 -54
package/package.json
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
v-if="
|
|
3
|
+
v-if="modelValue"
|
|
4
4
|
:class="[
|
|
5
5
|
// default styles
|
|
6
|
-
headless
|
|
7
|
-
? 'alert'
|
|
8
|
-
: 'flex items-start gap-3 rounded border border-solid p-3',
|
|
6
|
+
headless ? 'alert' : 'flex items-start gap-3 rounded border border-solid',
|
|
9
7
|
// variant styles
|
|
10
8
|
headless
|
|
11
9
|
? `alert--${variant}`
|
|
@@ -16,6 +14,14 @@
|
|
|
16
14
|
: isWarning
|
|
17
15
|
? 'border-warning-300 bg-warning-200 text-warning-700'
|
|
18
16
|
: null,
|
|
17
|
+
// sizes styles
|
|
18
|
+
headless
|
|
19
|
+
? `alert--${size}`
|
|
20
|
+
: isLarge
|
|
21
|
+
? 'p-3'
|
|
22
|
+
: isSmall
|
|
23
|
+
? 'py-1 px-2 text-sm'
|
|
24
|
+
: null,
|
|
19
25
|
]"
|
|
20
26
|
role="alert"
|
|
21
27
|
>
|
|
@@ -23,9 +29,15 @@
|
|
|
23
29
|
<button
|
|
24
30
|
v-if="dismissable"
|
|
25
31
|
:class="[
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
// default styles
|
|
33
|
+
headless ? 'alert-close' : 'ml-auto h-4 w-4 shrink-0 text-current',
|
|
34
|
+
headless
|
|
35
|
+
? `alert-close--${variant}`
|
|
36
|
+
: isLarge
|
|
37
|
+
? 'mt-1'
|
|
38
|
+
: isSmall
|
|
39
|
+
? 'mt-0.5'
|
|
40
|
+
: null,
|
|
29
41
|
]"
|
|
30
42
|
@click="hide"
|
|
31
43
|
>
|
|
@@ -35,14 +47,30 @@
|
|
|
35
47
|
</template>
|
|
36
48
|
|
|
37
49
|
<script>
|
|
50
|
+
import IconClose from '@veritree/icons/src/components/IconClose.vue';
|
|
51
|
+
|
|
38
52
|
export default {
|
|
39
53
|
name: 'VTAlert',
|
|
40
54
|
|
|
55
|
+
components: {
|
|
56
|
+
IconClose,
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
data() {
|
|
60
|
+
return {
|
|
61
|
+
modelValueLocal: true,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
|
|
41
65
|
props: {
|
|
42
66
|
variant: {
|
|
43
67
|
type: String,
|
|
44
68
|
default: 'success',
|
|
45
69
|
},
|
|
70
|
+
size: {
|
|
71
|
+
type: String,
|
|
72
|
+
default: 'large',
|
|
73
|
+
},
|
|
46
74
|
headless: {
|
|
47
75
|
type: Boolean,
|
|
48
76
|
default: false,
|
|
@@ -51,12 +79,10 @@ export default {
|
|
|
51
79
|
type: Boolean,
|
|
52
80
|
default: false,
|
|
53
81
|
},
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
show: true,
|
|
59
|
-
};
|
|
82
|
+
modelValue: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: null,
|
|
85
|
+
},
|
|
60
86
|
},
|
|
61
87
|
|
|
62
88
|
computed: {
|
|
@@ -71,12 +97,27 @@ export default {
|
|
|
71
97
|
isWarning() {
|
|
72
98
|
return this.variant === 'warning';
|
|
73
99
|
},
|
|
100
|
+
|
|
101
|
+
isLarge() {
|
|
102
|
+
return this.size === 'large';
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
isSmall() {
|
|
106
|
+
return this.size === 'small';
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
isVisible() {
|
|
110
|
+
return this.modelValue !== null ? this.modelValue : this.modelValueLocal;
|
|
111
|
+
},
|
|
74
112
|
},
|
|
75
113
|
|
|
76
114
|
methods: {
|
|
77
115
|
hide() {
|
|
116
|
+
this.modelValue !== null
|
|
117
|
+
? this.$emit('update:modelValue', false)
|
|
118
|
+
: (this.modelValueLocal = false);
|
|
119
|
+
|
|
78
120
|
this.$emit('dismiss');
|
|
79
|
-
this.show = false;
|
|
80
121
|
},
|
|
81
122
|
},
|
|
82
123
|
};
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
<div
|
|
4
4
|
v-if="modelValue"
|
|
5
5
|
:id="id"
|
|
6
|
-
:class="
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
:class="
|
|
7
|
+
headless
|
|
8
|
+
? 'dialog'
|
|
9
|
+
: `fixed inset-0 z-50 grid grid-cols-1 grid-rows-1 ${classes}`
|
|
10
|
+
"
|
|
10
11
|
aria-modal="true"
|
|
11
12
|
v-bind="$attrs"
|
|
12
13
|
@click="onClick"
|
|
@@ -27,10 +28,7 @@ export default {
|
|
|
27
28
|
provide() {
|
|
28
29
|
return {
|
|
29
30
|
apiDialog: () => {
|
|
30
|
-
const id = this.id;
|
|
31
31
|
const componentId = this.componentId;
|
|
32
|
-
const isDark = this.dark;
|
|
33
|
-
const isHeadless = this.headless;
|
|
34
32
|
|
|
35
33
|
const registerContent = (content) => {
|
|
36
34
|
if (!content) return;
|
|
@@ -46,15 +44,15 @@ export default {
|
|
|
46
44
|
|
|
47
45
|
const emit = () => this.emit();
|
|
48
46
|
|
|
47
|
+
const full = this.full;
|
|
48
|
+
|
|
49
49
|
return {
|
|
50
|
-
id,
|
|
51
50
|
componentId,
|
|
52
|
-
isDark,
|
|
53
|
-
isHeadless,
|
|
54
51
|
hide,
|
|
55
52
|
emit,
|
|
56
53
|
registerContent,
|
|
57
54
|
registerOverlay,
|
|
55
|
+
full,
|
|
58
56
|
};
|
|
59
57
|
},
|
|
60
58
|
};
|
|
@@ -69,7 +67,7 @@ export default {
|
|
|
69
67
|
type: Boolean,
|
|
70
68
|
default: false,
|
|
71
69
|
},
|
|
72
|
-
|
|
70
|
+
full: {
|
|
73
71
|
type: Boolean,
|
|
74
72
|
default: false,
|
|
75
73
|
},
|
|
@@ -88,6 +86,10 @@ export default {
|
|
|
88
86
|
return `dialog-${this.componentId}`;
|
|
89
87
|
},
|
|
90
88
|
|
|
89
|
+
classes() {
|
|
90
|
+
return !this.full ? 'p-4 md:p-6' : '';
|
|
91
|
+
},
|
|
92
|
+
|
|
91
93
|
hasContent() {
|
|
92
94
|
return this.content !== null;
|
|
93
95
|
},
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
<VTButton
|
|
3
3
|
variant="icon"
|
|
4
4
|
:id="id"
|
|
5
|
-
:class="
|
|
6
|
-
'Dialog-close': headless,
|
|
7
|
-
}"
|
|
8
|
-
:theme="theme"
|
|
5
|
+
:class="[headless ? 'dialog-close' : null]"
|
|
9
6
|
@click.prevent="hide"
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
>
|
|
8
|
+
<slot>
|
|
9
|
+
<IconClose class="h-4 w-4" />
|
|
10
|
+
</slot>
|
|
11
|
+
</VTButton>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
14
|
<script>
|
|
@@ -22,23 +22,17 @@ export default {
|
|
|
22
22
|
|
|
23
23
|
inject: ['apiDialog'],
|
|
24
24
|
|
|
25
|
+
props: {
|
|
26
|
+
headless: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
|
|
25
32
|
computed: {
|
|
26
33
|
id() {
|
|
27
34
|
return `dialog-close-${this.apiDialog().componentId}`;
|
|
28
35
|
},
|
|
29
|
-
|
|
30
|
-
dark() {
|
|
31
|
-
return this.apiDialog().isDark;
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
headless() {
|
|
35
|
-
return this.apiDialog().isHeadless;
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
// temporary till button theme is implemented
|
|
39
|
-
theme() {
|
|
40
|
-
return this.dark ? 'dark' : null;
|
|
41
|
-
},
|
|
42
36
|
},
|
|
43
37
|
|
|
44
38
|
methods: {
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<transition
|
|
3
3
|
enter-active-class="duration-300 ease-out"
|
|
4
|
-
enter-
|
|
4
|
+
enter-class="translate-y-[50px] opacity-0"
|
|
5
5
|
enter-to-class="translate-y-0 opacity-100"
|
|
6
6
|
leave-active-class="duration-300 ease-out"
|
|
7
|
-
leave-
|
|
7
|
+
leave-class="translate-y-0 opacity-100"
|
|
8
8
|
leave-to-class="translate-y-[50px] opacity-0"
|
|
9
9
|
@after-leave="hideDialog"
|
|
10
10
|
>
|
|
11
11
|
<div
|
|
12
12
|
v-show="visible"
|
|
13
13
|
:id="id"
|
|
14
|
-
:class="
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'bg-fd-600': dark,
|
|
20
|
-
}"
|
|
14
|
+
:class="
|
|
15
|
+
headless
|
|
16
|
+
? 'dialog-content'
|
|
17
|
+
: `relative m-auto flex flex-col overflow-auto rounded bg-white p-4 focus:outline-none lg:p-6 ${classes}`
|
|
18
|
+
"
|
|
21
19
|
tabindex="-1"
|
|
22
|
-
@
|
|
20
|
+
@keydown.esc.stop="hide"
|
|
23
21
|
>
|
|
24
22
|
<slot></slot>
|
|
25
23
|
</div>
|
|
@@ -32,6 +30,13 @@ export default {
|
|
|
32
30
|
|
|
33
31
|
inject: ['apiDialog'],
|
|
34
32
|
|
|
33
|
+
props: {
|
|
34
|
+
headless: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
|
|
35
40
|
data() {
|
|
36
41
|
return {
|
|
37
42
|
visible: false,
|
|
@@ -43,12 +48,12 @@ export default {
|
|
|
43
48
|
return `dialog-content-${this.apiDialog().componentId}`;
|
|
44
49
|
},
|
|
45
50
|
|
|
46
|
-
|
|
47
|
-
return this.
|
|
51
|
+
classes() {
|
|
52
|
+
return this.full ? 'h-screen w-screen' : 'max-h-full max-w-full';
|
|
48
53
|
},
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
return this.apiDialog().
|
|
55
|
+
full() {
|
|
56
|
+
return this.apiDialog().full;
|
|
52
57
|
},
|
|
53
58
|
},
|
|
54
59
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="as"
|
|
4
|
-
:class="
|
|
4
|
+
:class="[
|
|
5
|
+
headless
|
|
6
|
+
? 'dialog-footer'
|
|
7
|
+
: '-mx-4 -mb-4 flex items-center justify-between gap-x-3 p-4 md:-mx-6 md:-mb-6 md:p-6',
|
|
8
|
+
]"
|
|
5
9
|
>
|
|
6
10
|
<slot></slot>
|
|
7
11
|
</component>
|
|
@@ -10,24 +14,15 @@
|
|
|
10
14
|
<script>
|
|
11
15
|
export default {
|
|
12
16
|
name: 'VTDialogFooter',
|
|
13
|
-
|
|
14
|
-
inject: ['apiDialog'],
|
|
15
|
-
|
|
16
17
|
props: {
|
|
18
|
+
headless: {
|
|
19
|
+
type: Boolean,
|
|
20
|
+
default: false,
|
|
21
|
+
},
|
|
17
22
|
as: {
|
|
18
23
|
type: String,
|
|
19
24
|
default: 'footer',
|
|
20
25
|
},
|
|
21
26
|
},
|
|
22
|
-
|
|
23
|
-
computed: {
|
|
24
|
-
dark() {
|
|
25
|
-
return this.apiDialog().isDark;
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
headless() {
|
|
29
|
-
return this.apiDialog().isHeadless;
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
27
|
};
|
|
33
28
|
</script>
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
<component
|
|
3
3
|
:is="as"
|
|
4
4
|
:id="id"
|
|
5
|
-
:class="
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
:class="[
|
|
6
|
+
headless
|
|
7
|
+
? 'dialog-header'
|
|
8
|
+
: '-mx-4 -mt-4 flex items-center justify-between gap-x-3 p-4 md:-mx-6 md:-mt-6 md:p-6',
|
|
9
|
+
]"
|
|
10
|
+
@click.stop
|
|
9
11
|
>
|
|
10
12
|
<slot></slot>
|
|
11
13
|
</component>
|
|
@@ -18,6 +20,10 @@ export default {
|
|
|
18
20
|
inject: ['apiDialog'],
|
|
19
21
|
|
|
20
22
|
props: {
|
|
23
|
+
headless: {
|
|
24
|
+
type: Boolean,
|
|
25
|
+
default: false,
|
|
26
|
+
},
|
|
21
27
|
as: {
|
|
22
28
|
type: String,
|
|
23
29
|
default: 'header',
|
|
@@ -25,16 +31,8 @@ export default {
|
|
|
25
31
|
},
|
|
26
32
|
|
|
27
33
|
computed: {
|
|
28
|
-
dark() {
|
|
29
|
-
return this.apiDialog().isDark;
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
headless() {
|
|
33
|
-
return this.apiDialog().isHeadless;
|
|
34
|
-
},
|
|
35
|
-
|
|
36
34
|
id() {
|
|
37
|
-
return
|
|
35
|
+
return `dialog-header-${this.apiDialog().componentId}`;
|
|
38
36
|
},
|
|
39
37
|
},
|
|
40
38
|
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
<component
|
|
3
3
|
:is="as"
|
|
4
4
|
:id="id"
|
|
5
|
-
:class="
|
|
6
|
-
'Dialog-body': headless,
|
|
7
|
-
'flex-1 w-full h-full overflow-y-auto': !headless,
|
|
8
|
-
}"
|
|
5
|
+
:class="[headless ? 'dialog-body' : 'h-full flex-1 overflow-y-auto']"
|
|
9
6
|
>
|
|
10
7
|
<slot></slot>
|
|
11
8
|
</component>
|
|
@@ -18,6 +15,10 @@ export default {
|
|
|
18
15
|
inject: ['apiDialog'],
|
|
19
16
|
|
|
20
17
|
props: {
|
|
18
|
+
headless: {
|
|
19
|
+
type: Boolean,
|
|
20
|
+
default: false,
|
|
21
|
+
},
|
|
21
22
|
as: {
|
|
22
23
|
type: String,
|
|
23
24
|
default: 'main',
|
|
@@ -25,16 +26,8 @@ export default {
|
|
|
25
26
|
},
|
|
26
27
|
|
|
27
28
|
computed: {
|
|
28
|
-
dark() {
|
|
29
|
-
return this.apiDialog().isDark;
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
headless() {
|
|
33
|
-
return this.apiDialog().isHeadless;
|
|
34
|
-
},
|
|
35
|
-
|
|
36
29
|
id() {
|
|
37
|
-
return
|
|
30
|
+
return `dialog-main-${this.apiDialog().componentId}`;
|
|
38
31
|
},
|
|
39
32
|
},
|
|
40
33
|
|
|
@@ -3,11 +3,8 @@
|
|
|
3
3
|
<div
|
|
4
4
|
v-if="visible"
|
|
5
5
|
:id="id"
|
|
6
|
-
:class="
|
|
7
|
-
|
|
8
|
-
'bg-primary-200/80 fixed inset-0': !headless,
|
|
9
|
-
}"
|
|
10
|
-
></div>
|
|
6
|
+
:class="[headless ? 'dialog-overlay' : 'bg-primary-200/80 fixed inset-0']"
|
|
7
|
+
/>
|
|
11
8
|
</FadeInOut>
|
|
12
9
|
</template>
|
|
13
10
|
|
|
@@ -23,6 +20,13 @@ export default {
|
|
|
23
20
|
|
|
24
21
|
inject: ['apiDialog'],
|
|
25
22
|
|
|
23
|
+
props: {
|
|
24
|
+
headless: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: false,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
|
|
26
30
|
data() {
|
|
27
31
|
return {
|
|
28
32
|
visible: false,
|
|
@@ -33,14 +37,6 @@ export default {
|
|
|
33
37
|
id() {
|
|
34
38
|
return `dialog-overlay-${this.apiDialog().componentId}`;
|
|
35
39
|
},
|
|
36
|
-
|
|
37
|
-
dark() {
|
|
38
|
-
return this.apiDialog().isDark;
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
headless() {
|
|
42
|
-
return this.apiDialog().isHeadless;
|
|
43
|
-
},
|
|
44
40
|
},
|
|
45
41
|
|
|
46
42
|
mounted() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span
|
|
3
3
|
:id="id"
|
|
4
|
-
:class="
|
|
4
|
+
:class="[headless ? 'dialog-header' : 'text-2xl font-semibold']"
|
|
5
5
|
>
|
|
6
6
|
<slot></slot
|
|
7
7
|
></span>
|
|
@@ -13,13 +13,16 @@ export default {
|
|
|
13
13
|
|
|
14
14
|
inject: ['apiDialog'],
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
headless
|
|
18
|
-
|
|
16
|
+
props: {
|
|
17
|
+
headless: {
|
|
18
|
+
type: Boolean,
|
|
19
|
+
default: false,
|
|
19
20
|
},
|
|
21
|
+
},
|
|
20
22
|
|
|
23
|
+
computed: {
|
|
21
24
|
id() {
|
|
22
|
-
return
|
|
25
|
+
return `dialog-overlay-${this.apiDialog().componentId}`;
|
|
23
26
|
},
|
|
24
27
|
},
|
|
25
28
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:class="[
|
|
5
5
|
headless
|
|
6
6
|
? 'details-header'
|
|
7
|
-
: 'flex cursor-pointer justify-between gap-3
|
|
7
|
+
: 'text-body flex cursor-pointer justify-between gap-3 font-semibold',
|
|
8
8
|
]"
|
|
9
9
|
:aria-controls="ariaControls"
|
|
10
10
|
:aria-expanded="String(ariaExpanded)"
|
|
@@ -56,12 +56,31 @@ export default {
|
|
|
56
56
|
type: Boolean,
|
|
57
57
|
default: false,
|
|
58
58
|
},
|
|
59
|
+
placement: {
|
|
60
|
+
type: String,
|
|
61
|
+
default: 'bottom-start',
|
|
62
|
+
},
|
|
59
63
|
},
|
|
60
64
|
|
|
61
65
|
data() {
|
|
62
66
|
return {
|
|
63
67
|
componentId: genId(),
|
|
64
68
|
items: [],
|
|
69
|
+
/**
|
|
70
|
+
* Explaining the need for the floatingUiMinWidth data
|
|
71
|
+
*
|
|
72
|
+
* The floating ui is a result of two items:
|
|
73
|
+
*
|
|
74
|
+
* 1. Trigger: the action button
|
|
75
|
+
* 2. Content: the popper/wrapper that appears after triggering the action button
|
|
76
|
+
*
|
|
77
|
+
* By default, the content will match the triggers width.
|
|
78
|
+
* The problem with this is that the trigger width
|
|
79
|
+
* might be too small causing the content to not fit
|
|
80
|
+
* what is inside it properly. So, to avoid this,
|
|
81
|
+
* a min width is needed.
|
|
82
|
+
*/
|
|
83
|
+
floatingUiMinWidth: 200,
|
|
65
84
|
};
|
|
66
85
|
},
|
|
67
86
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<FloatingUi
|
|
3
|
-
:visible="visible"
|
|
4
3
|
:id="id"
|
|
4
|
+
:visible="visible"
|
|
5
5
|
:headless="headless"
|
|
6
|
-
|
|
7
|
-
:floating-ui-class="floatingUiClass"
|
|
6
|
+
component="dropdown"
|
|
8
7
|
>
|
|
9
8
|
<slot></slot>
|
|
10
9
|
</FloatingUi>
|
|
@@ -16,6 +15,8 @@ import { floatingUiContentMixin } from '../../../mixins/floating-ui-content';
|
|
|
16
15
|
export default {
|
|
17
16
|
name: 'VTDropdownMenuContent',
|
|
18
17
|
|
|
18
|
+
inheritAttrs: false,
|
|
19
|
+
|
|
19
20
|
mixins: [floatingUiContentMixin],
|
|
20
21
|
|
|
21
22
|
inject: ['apiDropdownMenu'],
|
|
@@ -39,13 +40,20 @@ export default {
|
|
|
39
40
|
id: this.id,
|
|
40
41
|
hide: this.hide,
|
|
41
42
|
show: this.show,
|
|
42
|
-
getMousemove: this.getMousemove,
|
|
43
|
-
setMousemove: this.setMousemove,
|
|
44
|
-
unsetMousemove: this.unsetMousemove,
|
|
45
43
|
setActiveDescedant: this.setActiveDescedant,
|
|
46
44
|
};
|
|
47
45
|
|
|
48
46
|
this.apiDropdownMenu().registerContent(content);
|
|
49
47
|
},
|
|
48
|
+
|
|
49
|
+
methods: {
|
|
50
|
+
hidden() {
|
|
51
|
+
this.$emit('hidden');
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
shown() {
|
|
55
|
+
this.$emit('shown');
|
|
56
|
+
},
|
|
57
|
+
},
|
|
50
58
|
};
|
|
51
59
|
</script>
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
:class="
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}"
|
|
3
|
+
:class="[
|
|
4
|
+
headless ? 'dropdown-menu-divider' : '-mx-3 my-2 h-[1px] bg-gray-200',
|
|
5
|
+
]"
|
|
7
6
|
></div>
|
|
8
7
|
</template>
|
|
9
8
|
|
|
@@ -13,18 +12,10 @@ export default {
|
|
|
13
12
|
|
|
14
13
|
inject: ['apiDropdownMenu'],
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
computed: {
|
|
22
|
-
dark() {
|
|
23
|
-
return this.apiDropdownMenu().isDark;
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
headless() {
|
|
27
|
-
return this.apiDropdownMenu().isHeadless;
|
|
15
|
+
props: {
|
|
16
|
+
headless: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: false,
|
|
28
19
|
},
|
|
29
20
|
},
|
|
30
21
|
};
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
class="-mx-3"
|
|
10
10
|
role="menuitem"
|
|
11
11
|
@click.stop.prevent="onClick"
|
|
12
|
-
@keydown.down.prevent="
|
|
13
|
-
@keydown.up.prevent="
|
|
12
|
+
@keydown.down.prevent="focusNextItem"
|
|
13
|
+
@keydown.up.prevent="focusPreviousItem"
|
|
14
14
|
@keydown.home.prevent="focusFirstItem"
|
|
15
15
|
@keydown.end.prevent="focusLastItem"
|
|
16
16
|
@keydown.esc.prevent="onKeyEsc"
|
|
@@ -51,11 +51,7 @@ export default {
|
|
|
51
51
|
|
|
52
52
|
computed: {
|
|
53
53
|
as() {
|
|
54
|
-
return this.href
|
|
55
|
-
? 'a'
|
|
56
|
-
: this.to
|
|
57
|
-
? resolveComponent('NuxtLink')
|
|
58
|
-
: 'button';
|
|
54
|
+
return this.href ? 'a' : this.to ? 'NuxtLink' : 'button';
|
|
59
55
|
},
|
|
60
56
|
},
|
|
61
57
|
};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span
|
|
3
|
-
:class="
|
|
4
|
-
MenuLabel: headless,
|
|
5
|
-
'mb-2 block text-xs uppercase': !headless,
|
|
6
|
-
'text-inherit': !dark,
|
|
7
|
-
'text-white': dark,
|
|
8
|
-
}"
|
|
3
|
+
:class="[headless ? 'dropdown-menu-label' : 'mb-2 block text-xs uppercase']"
|
|
9
4
|
>
|
|
10
5
|
<slot></slot>
|
|
11
6
|
</span>
|
|
@@ -18,10 +13,6 @@ export default {
|
|
|
18
13
|
inject: ['apiDropdownMenu'],
|
|
19
14
|
|
|
20
15
|
computed: {
|
|
21
|
-
dark() {
|
|
22
|
-
return this.apiDropdownMenu().isDark;
|
|
23
|
-
},
|
|
24
|
-
|
|
25
16
|
headless() {
|
|
26
17
|
return this.apiDropdownMenu().isHeadless;
|
|
27
18
|
},
|