@veritree/ui 0.19.2 → 0.20.0-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/index.js +64 -68
- package/mixins/floating-ui-content.js +81 -0
- package/mixins/floating-ui-item.js +266 -0
- package/mixins/floating-ui.js +67 -0
- package/mixins/form-control-icon.js +53 -0
- package/mixins/form-control.js +71 -0
- package/nuxt.js +30 -23
- package/package.json +9 -4
- package/src/components/Alert/VTAlert.vue +55 -14
- package/src/components/Avatar/VTAvatar.vue +32 -29
- package/src/components/Button/VTButton.vue +9 -6
- package/src/components/Checkbox/VTCheckbox.vue +134 -0
- package/src/components/Checkbox/VTCheckboxLabel.vue +3 -0
- package/src/components/Checkbox/VTCheckboxText.vue +20 -0
- package/src/components/Dialog/VTDialog.vue +22 -32
- package/src/components/Dialog/VTDialogClose.vue +19 -25
- package/src/components/Dialog/VTDialogContent.vue +24 -19
- package/src/components/Dialog/VTDialogFooter.vue +11 -16
- package/src/components/Dialog/VTDialogHeader.vue +16 -18
- package/src/components/Dialog/VTDialogMain.vue +11 -18
- package/src/components/Dialog/VTDialogOverlay.vue +14 -18
- package/src/components/Dialog/VTDialogTitle.vue +10 -7
- package/src/components/Disclosure/VTDisclosureContent.vue +1 -1
- package/src/components/Disclosure/VTDisclosureDetails.vue +1 -1
- package/src/components/Disclosure/VTDisclosureHeader.vue +2 -2
- package/src/components/Disclosure/VTDisclosureIcon.vue +1 -1
- package/src/components/Drawer/VTDrawer.vue +14 -16
- package/src/components/Drawer/VTDrawerClose.vue +9 -9
- package/src/components/Drawer/VTDrawerContent.vue +8 -8
- package/src/components/Drawer/VTDrawerFooter.vue +3 -3
- package/src/components/Drawer/VTDrawerHeader.vue +4 -4
- package/src/components/Drawer/VTDrawerMain.vue +5 -5
- package/src/components/Drawer/VTDrawerOverlay.vue +6 -6
- package/src/components/Drawer/VTDrawerTitle.vue +5 -5
- package/src/components/DropdownMenu/VTDropdownMenu.vue +45 -28
- package/src/components/DropdownMenu/VTDropdownMenuContent.vue +29 -64
- package/src/components/DropdownMenu/VTDropdownMenuDivider.vue +8 -14
- package/src/components/DropdownMenu/VTDropdownMenuItem.vue +11 -124
- package/src/components/DropdownMenu/VTDropdownMenuLabel.vue +3 -12
- package/src/components/DropdownMenu/VTDropdownMenuTrigger.vue +91 -121
- package/src/components/Form/VTFormFeedback.vue +39 -22
- package/src/components/Form/VTFormGroup.vue +5 -7
- package/src/components/Form/VTFormLabel.vue +22 -0
- package/src/components/Form/VTFormRow.vue +5 -0
- package/src/components/Form/VTInput.vue +40 -0
- package/src/components/Form/VTInputIcon.vue +35 -0
- package/src/components/Form/VTInputPassword.vue +55 -0
- package/src/components/Form/VTTextarea.vue +22 -0
- package/src/components/Listbox/VTListbox.vue +122 -50
- package/src/components/Listbox/VTListboxContent.vue +20 -116
- package/src/components/Listbox/VTListboxItem.vue +115 -166
- package/src/components/Listbox/VTListboxLabel.vue +3 -14
- package/src/components/Listbox/VTListboxList.vue +10 -40
- package/src/components/Listbox/VTListboxSearch.vue +76 -68
- package/src/components/Listbox/VTListboxTrigger.vue +75 -86
- package/src/components/Popover/VTPopover.vue +42 -29
- package/src/components/Popover/VTPopoverContent.vue +24 -59
- package/src/components/Popover/VTPopoverDivider.vue +4 -11
- package/src/components/Popover/VTPopoverItem.vue +21 -14
- package/src/components/Popover/VTPopoverTrigger.vue +126 -21
- 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 +4 -3
- package/src/components/Tabs/VTTabGroup.vue +9 -7
- package/src/components/Tabs/VTTabPanel.vue +4 -5
- 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/Transitions/FadeInOut.vue +2 -2
- package/src/components/Utils/FloatingUi.vue +93 -0
- package/package-lock.json +0 -13
- 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/src/components/Modal/VTModal.vue +0 -69
- package/src/utils/genId.js +0 -13
|
@@ -1,34 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
|
+
:id="id"
|
|
4
|
+
:class="classComputed"
|
|
5
|
+
:disabled="disabled"
|
|
3
6
|
:aria-expanded="expanded"
|
|
4
7
|
:aria-haspopup="hasPopup"
|
|
5
|
-
:class="{
|
|
6
|
-
'Listbox-button': headless,
|
|
7
|
-
'flex w-full justify-between rounded-md border border-solid py-2 px-3':
|
|
8
|
-
!headless,
|
|
9
|
-
'border-gray-300 text-gray-500': !dark && !headless,
|
|
10
|
-
'border-white/70 text-white focus-visible:ring-2 focus-visible:ring-white':
|
|
11
|
-
dark && !headless,
|
|
12
|
-
}"
|
|
13
8
|
type="button"
|
|
14
|
-
@click.
|
|
15
|
-
@keydown.down.prevent="
|
|
16
|
-
@keydown.up.prevent="
|
|
9
|
+
@click.prevent="onClick"
|
|
10
|
+
@keydown.down.prevent="onKeyDownOrUp"
|
|
11
|
+
@keydown.up.prevent="onKeyDownOrUp"
|
|
17
12
|
@keydown.esc.stop="onKeyEsc"
|
|
18
13
|
>
|
|
19
|
-
<span
|
|
20
|
-
:class="{
|
|
21
|
-
'Listbox-button__text': headless,
|
|
22
|
-
'text-left': !headless,
|
|
23
|
-
}"
|
|
24
|
-
>
|
|
14
|
+
<span :class="[headless ? 'listbox-button__text' : 'truncate text-left']">
|
|
25
15
|
<slot></slot>
|
|
26
16
|
</span>
|
|
27
|
-
<span
|
|
28
|
-
:class="{
|
|
29
|
-
'Listbox-button__icon': headless,
|
|
30
|
-
}"
|
|
31
|
-
>
|
|
17
|
+
<span :class="[headless ? 'listbox-button__icon' : 'shrink-0']">
|
|
32
18
|
<IconChevronDown
|
|
33
19
|
class="transition-transform"
|
|
34
20
|
:class="{ 'rotate-180': expanded }"
|
|
@@ -38,6 +24,10 @@
|
|
|
38
24
|
</template>
|
|
39
25
|
|
|
40
26
|
<script>
|
|
27
|
+
import {
|
|
28
|
+
formControlMixin,
|
|
29
|
+
formControlStyleMixin,
|
|
30
|
+
} from '../../../mixins/form-control';
|
|
41
31
|
import { IconChevronDown } from '@veritree/icons';
|
|
42
32
|
|
|
43
33
|
export default {
|
|
@@ -45,33 +35,29 @@ export default {
|
|
|
45
35
|
|
|
46
36
|
components: { IconChevronDown },
|
|
47
37
|
|
|
48
|
-
|
|
38
|
+
mixins: [formControlMixin, formControlStyleMixin],
|
|
49
39
|
|
|
50
|
-
|
|
51
|
-
headless: {
|
|
52
|
-
type: Boolean,
|
|
53
|
-
default: false,
|
|
54
|
-
},
|
|
55
|
-
},
|
|
40
|
+
inject: ['apiListbox'],
|
|
56
41
|
|
|
57
42
|
data() {
|
|
58
43
|
return {
|
|
44
|
+
name: 'listbox-trigger',
|
|
59
45
|
expanded: false,
|
|
60
46
|
hasPopup: false,
|
|
61
47
|
};
|
|
62
48
|
},
|
|
63
49
|
|
|
64
50
|
computed: {
|
|
65
|
-
|
|
66
|
-
return this.
|
|
51
|
+
id() {
|
|
52
|
+
return `listbox-trigger-${this.apiListbox().id}`;
|
|
67
53
|
},
|
|
68
54
|
|
|
69
|
-
|
|
70
|
-
return this.
|
|
55
|
+
componentContent() {
|
|
56
|
+
return this.apiListbox().componentContent;
|
|
71
57
|
},
|
|
72
58
|
|
|
73
59
|
items() {
|
|
74
|
-
return this.
|
|
60
|
+
return this.apiListbox().items;
|
|
75
61
|
},
|
|
76
62
|
|
|
77
63
|
firstMenuItem() {
|
|
@@ -86,83 +72,86 @@ export default {
|
|
|
86
72
|
mounted() {
|
|
87
73
|
const trigger = {
|
|
88
74
|
el: this.$el,
|
|
75
|
+
cancel: this.cancel,
|
|
89
76
|
focus: this.focus,
|
|
90
|
-
|
|
91
|
-
contract: this.contract,
|
|
77
|
+
id: this.id,
|
|
92
78
|
};
|
|
93
79
|
|
|
94
|
-
this.
|
|
80
|
+
this.apiListbox().registerTrigger(trigger);
|
|
95
81
|
},
|
|
96
82
|
|
|
97
83
|
methods: {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
84
|
+
init(e) {
|
|
85
|
+
if (!this.componentContent) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (this.expanded) {
|
|
90
|
+
this.cancel();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
102
94
|
this.expanded = true;
|
|
103
|
-
this.content.show();
|
|
104
|
-
},
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
96
|
+
// delay stop propagation to close other visible
|
|
97
|
+
// dropdowns and delay click event to control
|
|
98
|
+
// this dropdown visibility
|
|
99
|
+
setTimeout(() => e.stopImmediatePropagation(), 50);
|
|
100
|
+
setTimeout(() => this.showComponentContent(), 100);
|
|
108
101
|
},
|
|
109
102
|
|
|
110
|
-
|
|
111
|
-
if (!this.
|
|
103
|
+
cancel() {
|
|
104
|
+
if (!this.componentContent) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
112
108
|
this.expanded = false;
|
|
113
|
-
},
|
|
114
109
|
|
|
115
|
-
|
|
116
|
-
* On click, do the following:
|
|
117
|
-
*
|
|
118
|
-
* 1. Toggle aria expanded attribute/state
|
|
119
|
-
* 2. Open the menu if it's closed
|
|
120
|
-
* 3. Close the menu if it's open
|
|
121
|
-
*/
|
|
122
|
-
onClick() {
|
|
123
|
-
if (!this.content) return;
|
|
124
|
-
this.expanded ? this.content.hide() : this.showContent();
|
|
110
|
+
this.hideComponentContent();
|
|
125
111
|
},
|
|
126
112
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
* 1. if the menu is not expanded, expand it and focus the first menu item
|
|
131
|
-
* 2. if the menu is expanded, focus the first menu item
|
|
132
|
-
*/
|
|
133
|
-
onKeyArrowDown() {
|
|
134
|
-
if (!this.content) return;
|
|
113
|
+
focus() {
|
|
114
|
+
this.$el.focus();
|
|
115
|
+
},
|
|
135
116
|
|
|
136
|
-
|
|
117
|
+
showComponentContent() {
|
|
118
|
+
this.componentContent.show();
|
|
119
|
+
},
|
|
137
120
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
});
|
|
121
|
+
hideComponentContent() {
|
|
122
|
+
this.componentContent.hide();
|
|
141
123
|
},
|
|
142
124
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
* 2. if the menu is expanded, focus the last menu item
|
|
148
|
-
*/
|
|
149
|
-
onKeyArrowUp() {
|
|
150
|
-
if (!this.content) return;
|
|
125
|
+
onClick(e) {
|
|
126
|
+
this.init(e);
|
|
127
|
+
this.$emit('click');
|
|
128
|
+
},
|
|
151
129
|
|
|
152
|
-
|
|
130
|
+
onKeyDownOrUp(e) {
|
|
131
|
+
if (!this.expanded) {
|
|
132
|
+
this.$el.click(e);
|
|
133
|
+
}
|
|
153
134
|
|
|
135
|
+
const keyCode = e.code;
|
|
136
|
+
const listItemPosition =
|
|
137
|
+
keyCode === 'ArrowDown'
|
|
138
|
+
? 'firstMenuItem'
|
|
139
|
+
: keyCode === 'ArrowUp'
|
|
140
|
+
? 'lastMenuItem'
|
|
141
|
+
: null;
|
|
142
|
+
|
|
143
|
+
// settimeout here is delaying the focusing the element
|
|
144
|
+
// since it is not rendered yet. All items will only
|
|
145
|
+
// be available when the content is fully visible.
|
|
154
146
|
this.$nextTick(() => {
|
|
155
|
-
this.
|
|
147
|
+
setTimeout(() => this[listItemPosition].focus(), 100);
|
|
156
148
|
});
|
|
157
149
|
},
|
|
158
150
|
|
|
151
|
+
// change it to a better name or move the methods inside to another function
|
|
159
152
|
onKeyEsc() {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (this.expanded) {
|
|
163
|
-
this.toggleExpanded();
|
|
164
|
-
this.content.hide();
|
|
165
|
-
}
|
|
153
|
+
this.cancel();
|
|
154
|
+
this.focus();
|
|
166
155
|
},
|
|
167
156
|
},
|
|
168
157
|
};
|
|
@@ -2,43 +2,41 @@
|
|
|
2
2
|
<div
|
|
3
3
|
:id="id"
|
|
4
4
|
class="relative"
|
|
5
|
-
:aria-haspopup="
|
|
6
|
-
:aria-controls="
|
|
5
|
+
:aria-haspopup="componentContent ? 'true' : null"
|
|
6
|
+
:aria-controls="componentContent ? componentContent.id : null"
|
|
7
7
|
>
|
|
8
8
|
<slot></slot>
|
|
9
9
|
</div>
|
|
10
10
|
</template>
|
|
11
11
|
|
|
12
12
|
<script>
|
|
13
|
-
import {
|
|
13
|
+
import { floatingUiMixin } from '../../../mixins/floating-ui';
|
|
14
|
+
import { genId } from '../../utils/ids';
|
|
14
15
|
|
|
15
16
|
export default {
|
|
16
|
-
name:
|
|
17
|
+
name: 'VTPopover',
|
|
18
|
+
|
|
19
|
+
mixins: [floatingUiMixin],
|
|
17
20
|
|
|
18
21
|
provide() {
|
|
19
22
|
return {
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const registerButton = (button) => {
|
|
25
|
-
if (!button) return;
|
|
26
|
-
this.button = button;
|
|
23
|
+
apiPopover: () => {
|
|
24
|
+
const registerTrigger = (trigger) => {
|
|
25
|
+
if (!trigger) return;
|
|
26
|
+
this.componentTrigger = trigger;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const registerContent = (content) => {
|
|
30
30
|
if (!content) return;
|
|
31
|
-
this.
|
|
31
|
+
this.componentContent = content;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
return {
|
|
35
|
-
id,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
content,
|
|
41
|
-
registerButton,
|
|
35
|
+
id: this.componentId,
|
|
36
|
+
component: this.component,
|
|
37
|
+
componentTrigger: this.componentTrigger,
|
|
38
|
+
componentContent: this.componentContent,
|
|
39
|
+
registerTrigger,
|
|
42
40
|
registerContent,
|
|
43
41
|
};
|
|
44
42
|
},
|
|
@@ -50,22 +48,37 @@ export default {
|
|
|
50
48
|
type: Boolean,
|
|
51
49
|
default: false,
|
|
52
50
|
},
|
|
53
|
-
|
|
54
|
-
type:
|
|
55
|
-
default:
|
|
56
|
-
},
|
|
57
|
-
right: {
|
|
58
|
-
type: Boolean,
|
|
59
|
-
default: false,
|
|
51
|
+
placement: {
|
|
52
|
+
type: String,
|
|
53
|
+
default: 'bottom-start',
|
|
60
54
|
},
|
|
61
55
|
},
|
|
62
56
|
|
|
63
57
|
data() {
|
|
64
58
|
return {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
componentId: genId(),
|
|
60
|
+
/**
|
|
61
|
+
* Explaining the need for the floatingUiMinWidth data
|
|
62
|
+
*
|
|
63
|
+
* The floating ui is a result of two items:
|
|
64
|
+
*
|
|
65
|
+
* 1. Trigger: the action button
|
|
66
|
+
* 2. Content: the popper/wrapper that appears after triggering the action button
|
|
67
|
+
*
|
|
68
|
+
* By default, the content will match the triggers width.
|
|
69
|
+
* The problem with this is that the trigger width
|
|
70
|
+
* might be too small causing the content to not fit
|
|
71
|
+
* what is inside it properly. So, to avoid this,
|
|
72
|
+
* a min width is needed.
|
|
73
|
+
*/
|
|
74
|
+
floatingUiMinWidth: 200,
|
|
68
75
|
};
|
|
69
76
|
},
|
|
77
|
+
|
|
78
|
+
computed: {
|
|
79
|
+
id() {
|
|
80
|
+
return `popover-${this.componentId}`;
|
|
81
|
+
},
|
|
82
|
+
},
|
|
70
83
|
};
|
|
71
84
|
</script>
|
|
@@ -1,82 +1,47 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
leave-to-class="translate-y-[15px] opacity-0"
|
|
9
|
-
@after-leave="hide"
|
|
2
|
+
<FloatingUi
|
|
3
|
+
:visible="visible"
|
|
4
|
+
:id="id"
|
|
5
|
+
:headless="headless"
|
|
6
|
+
:class="{ 'popover-content': headless }"
|
|
7
|
+
:floating-ui-class="floatingUiClass"
|
|
10
8
|
>
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
:id="id"
|
|
14
|
-
:class="{
|
|
15
|
-
PopoverPanel: headless,
|
|
16
|
-
'absolute top-full mt-3 rounded-md shadow-300 ': !headless,
|
|
17
|
-
'bg-white': !dark,
|
|
18
|
-
'border-gray-700 bg-forest-default shadow-gray-700': dark,
|
|
19
|
-
'left-0': !right,
|
|
20
|
-
'right-0': right,
|
|
21
|
-
}"
|
|
22
|
-
>
|
|
23
|
-
<slot></slot>
|
|
24
|
-
</div>
|
|
25
|
-
</transition>
|
|
9
|
+
<slot></slot>
|
|
10
|
+
</FloatingUi>
|
|
26
11
|
</template>
|
|
27
12
|
|
|
28
13
|
<script>
|
|
29
|
-
import {
|
|
14
|
+
import { floatingUiContentMixin } from '../../../mixins/floating-ui-content';
|
|
30
15
|
|
|
31
16
|
export default {
|
|
32
|
-
name:
|
|
17
|
+
name: 'VTPopoverContent',
|
|
33
18
|
|
|
34
|
-
|
|
19
|
+
mixins: [floatingUiContentMixin],
|
|
35
20
|
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
id: `popover-panel-${genId()}`,
|
|
39
|
-
visible: false,
|
|
40
|
-
};
|
|
41
|
-
},
|
|
21
|
+
inject: ['apiPopover'],
|
|
42
22
|
|
|
43
23
|
computed: {
|
|
44
|
-
|
|
45
|
-
return this.
|
|
24
|
+
id() {
|
|
25
|
+
return `popover-content-${this.apiPopover().id}`;
|
|
46
26
|
},
|
|
47
27
|
|
|
48
|
-
|
|
49
|
-
return this.
|
|
28
|
+
component() {
|
|
29
|
+
return this.apiPopover().component;
|
|
50
30
|
},
|
|
51
31
|
|
|
52
|
-
|
|
53
|
-
return this.
|
|
32
|
+
componentTrigger() {
|
|
33
|
+
return this.apiPopover().componentTrigger;
|
|
54
34
|
},
|
|
55
35
|
},
|
|
56
36
|
|
|
57
37
|
mounted() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (this.visible && !this.$el.contains(e.target)) this.hide();
|
|
64
|
-
});
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
destroyed() {
|
|
68
|
-
// TODO: Create a directive or mixin for this
|
|
69
|
-
document.removeEventListener("click", this.hide());
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
methods: {
|
|
73
|
-
show() {
|
|
74
|
-
this.visible = true;
|
|
75
|
-
},
|
|
38
|
+
const content = {
|
|
39
|
+
id: this.id,
|
|
40
|
+
show: this.show,
|
|
41
|
+
hide: this.hide,
|
|
42
|
+
};
|
|
76
43
|
|
|
77
|
-
|
|
78
|
-
this.visible = false;
|
|
79
|
-
},
|
|
44
|
+
this.apiPopover().registerContent(content);
|
|
80
45
|
},
|
|
81
46
|
};
|
|
82
47
|
</script>
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
:class="{
|
|
4
4
|
PopoverDivider: headless,
|
|
5
5
|
'h-[1px]': !headless,
|
|
6
|
-
'bg-white': !dark,
|
|
7
|
-
'bg-fd-500': dark,
|
|
8
6
|
}"
|
|
9
7
|
></div>
|
|
10
8
|
</template>
|
|
@@ -13,15 +11,10 @@
|
|
|
13
11
|
export default {
|
|
14
12
|
name: 'VTPopoverDivider',
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return this.api().isDark;
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
headless() {
|
|
24
|
-
return this.api().isHeadless;
|
|
14
|
+
props: {
|
|
15
|
+
headless: {
|
|
16
|
+
type: Boolean,
|
|
17
|
+
default: false,
|
|
25
18
|
},
|
|
26
19
|
},
|
|
27
20
|
};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="as"
|
|
4
|
-
:class="
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}"
|
|
4
|
+
:class="[
|
|
5
|
+
// default styles
|
|
6
|
+
headless
|
|
7
|
+
? 'popover-item'
|
|
8
|
+
: 'hover:bg-secondary-200/10 relative z-10 -mx-3 flex items-center gap-2 px-3 py-2 text-inherit no-underline',
|
|
9
|
+
]"
|
|
11
10
|
@click="onClick"
|
|
12
11
|
>
|
|
13
12
|
<slot></slot>
|
|
@@ -18,30 +17,38 @@
|
|
|
18
17
|
export default {
|
|
19
18
|
name: 'VTPopoverItem',
|
|
20
19
|
|
|
21
|
-
inject: ['
|
|
20
|
+
inject: ['apiPopover'],
|
|
22
21
|
|
|
23
22
|
props: {
|
|
24
|
-
|
|
25
|
-
type:
|
|
26
|
-
default:
|
|
23
|
+
headless: {
|
|
24
|
+
type: Boolean,
|
|
25
|
+
default: false,
|
|
27
26
|
},
|
|
28
27
|
href: {
|
|
29
28
|
type: String,
|
|
30
29
|
default: null,
|
|
31
30
|
},
|
|
31
|
+
to: {
|
|
32
|
+
type: [String, Object],
|
|
33
|
+
default: null,
|
|
34
|
+
},
|
|
32
35
|
},
|
|
33
36
|
|
|
34
37
|
computed: {
|
|
35
38
|
dark() {
|
|
36
|
-
return this.
|
|
39
|
+
return this.apiPopover().isDark;
|
|
37
40
|
},
|
|
38
41
|
|
|
39
42
|
headless() {
|
|
40
|
-
return this.
|
|
43
|
+
return this.apiPopover().isHeadless;
|
|
41
44
|
},
|
|
42
45
|
|
|
43
46
|
as() {
|
|
44
|
-
return this.href
|
|
47
|
+
return this.href
|
|
48
|
+
? 'a'
|
|
49
|
+
: this.to
|
|
50
|
+
? resolveComponent('NuxtLink')
|
|
51
|
+
: 'button';
|
|
45
52
|
},
|
|
46
53
|
},
|
|
47
54
|
|