@apptegy/nuxt-navigation 0.1.3 → 0.1.5
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 +5 -70
- package/dist/module.json +2 -2
- package/dist/runtime/assets/icons/24/Metadata.svg +4 -0
- package/dist/runtime/components/Nav/Avatar.vue +1 -1
- package/dist/runtime/components/Nav/Header.vue +15 -158
- package/dist/runtime/components/Nav/HelpArticles.vue +14 -17
- package/dist/runtime/components/Nav/Icons/SidebarToggle.vue +6 -0
- package/dist/runtime/components/Nav/Icons/UserDropdownMenu.vue +5 -0
- package/dist/runtime/components/Nav/ImpersonateInfoPanel.vue +14 -14
- package/dist/runtime/components/Nav/OrgSelect.vue +96 -90
- package/dist/runtime/components/Nav/Sidebar.vue +9 -9
- package/dist/runtime/components/Nav/SidebarToggle.vue +32 -0
- package/dist/runtime/components/Nav/UserDropdown/index.vue +147 -0
- package/dist/runtime/composables/useDropdown.d.ts +16 -0
- package/dist/runtime/composables/useDropdown.js +204 -0
- package/package.json +15 -17
- package/dist/runtime/composables/accessibleActions.d.ts +0 -33
- package/dist/runtime/composables/accessibleActions.js +0 -195
package/README.md
CHANGED
|
@@ -2,83 +2,18 @@
|
|
|
2
2
|
Get your module up and running quickly.
|
|
3
3
|
|
|
4
4
|
Find and replace all on all files (CMD+SHIFT+F):
|
|
5
|
-
- Name:
|
|
6
|
-
- Package name:
|
|
7
|
-
- Description:
|
|
5
|
+
- Name: Navigation
|
|
6
|
+
- Package name: @apptegy/nuxt-navigation
|
|
7
|
+
- Description:Apptegy navigation components and patterns module.
|
|
8
8
|
-->
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Navigation
|
|
11
11
|
|
|
12
12
|
[![npm version][npm-version-src]][npm-version-href]
|
|
13
13
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
14
14
|
[![License][license-src]][license-href]
|
|
15
15
|
[![Nuxt][nuxt-src]][nuxt-href]
|
|
16
16
|
|
|
17
|
-
My new Nuxt module for doing amazing things.
|
|
18
17
|
|
|
19
|
-
- [
|
|
20
|
-
<!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
|
|
18
|
+
<!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/@apptegy/nuxt-navigation?file=playground%2Fapp.vue) -->
|
|
21
19
|
<!-- - [📖 Documentation](https://example.com) -->
|
|
22
|
-
|
|
23
|
-
## Features
|
|
24
|
-
|
|
25
|
-
<!-- Highlight some of the features your module provide here -->
|
|
26
|
-
- ⛰ Foo
|
|
27
|
-
- 🚠 Bar
|
|
28
|
-
- 🌲 Baz
|
|
29
|
-
|
|
30
|
-
## Quick Setup
|
|
31
|
-
|
|
32
|
-
Install the module to your Nuxt application with one command:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npx nuxi module add my-module
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
That's it! You can now use My Module in your Nuxt app ✨
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
## Contribution
|
|
42
|
-
|
|
43
|
-
<details>
|
|
44
|
-
<summary>Local development</summary>
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Install dependencies
|
|
48
|
-
npm install
|
|
49
|
-
|
|
50
|
-
# Generate type stubs
|
|
51
|
-
npm run dev:prepare
|
|
52
|
-
|
|
53
|
-
# Develop with the playground
|
|
54
|
-
npm run dev
|
|
55
|
-
|
|
56
|
-
# Build the playground
|
|
57
|
-
npm run dev:build
|
|
58
|
-
|
|
59
|
-
# Run ESLint
|
|
60
|
-
npm run lint
|
|
61
|
-
|
|
62
|
-
# Run Vitest
|
|
63
|
-
npm run test
|
|
64
|
-
npm run test:watch
|
|
65
|
-
|
|
66
|
-
# Release new version
|
|
67
|
-
npm run release
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
</details>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
<!-- Badges -->
|
|
74
|
-
[npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=020420&colorB=00DC82
|
|
75
|
-
[npm-version-href]: https://npmjs.com/package/my-module
|
|
76
|
-
|
|
77
|
-
[npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=020420&colorB=00DC82
|
|
78
|
-
[npm-downloads-href]: https://npmjs.com/package/my-module
|
|
79
|
-
|
|
80
|
-
[license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=020420&colorB=00DC82
|
|
81
|
-
[license-href]: https://npmjs.com/package/my-module
|
|
82
|
-
|
|
83
|
-
[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
|
|
84
|
-
[nuxt-href]: https://nuxt.com
|
package/dist/module.json
CHANGED
|
@@ -1,203 +1,60 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<header
|
|
3
|
+
class="header"
|
|
3
4
|
:class="{ sticky }"
|
|
4
5
|
role="banner"
|
|
5
6
|
>
|
|
6
|
-
<
|
|
7
|
-
class="sidebar-toggle"
|
|
8
|
-
@click="toggleSidebar">
|
|
9
|
-
<a-icon
|
|
10
|
-
class="icon"
|
|
11
|
-
icon="16:apptegy"
|
|
12
|
-
/>
|
|
13
|
-
<span>Menu</span>
|
|
14
|
-
</button >
|
|
7
|
+
<NavSidebarToggle @toggle-sidebar="$emit('toggle-sidebar')"/>
|
|
15
8
|
<div class="header__breadcrumbs">
|
|
16
9
|
<slot name="breadcrumbs" />
|
|
17
10
|
</div>
|
|
18
11
|
<slot name="org-select" />
|
|
19
12
|
<slot name="user-controls" />
|
|
20
|
-
<
|
|
21
|
-
ref="settingsTriggerRef"
|
|
22
|
-
aria-controls="settings-dropdown"
|
|
23
|
-
:aria-expanded="active"
|
|
24
|
-
aria-haspopup="listbox"
|
|
25
|
-
role="combobox"
|
|
26
|
-
tabindex="0"
|
|
27
|
-
class="header__dropdown"
|
|
28
|
-
@keydown="keydownActionsOnTrigger($event, userSettingsOptions, settingsOptionsRef, settingsTriggerRef, false, '')"
|
|
29
|
-
@click.prevent="toggleDropdown($event, settingsOptionsRef)">
|
|
30
|
-
<NavAvatar
|
|
31
|
-
:name="user.name"
|
|
32
|
-
:src="user.avatar"
|
|
33
|
-
/>
|
|
34
|
-
<a-icon
|
|
35
|
-
class="icon"
|
|
36
|
-
icon="24:hamburger"
|
|
37
|
-
/>
|
|
38
|
-
<span class="sr-only">Account Settings</span>
|
|
39
|
-
</div>
|
|
40
|
-
<div
|
|
41
|
-
v-show="active"
|
|
42
|
-
id="settings-dropdown"
|
|
43
|
-
class="options-dropdown"
|
|
44
|
-
role="listbox"
|
|
45
|
-
>
|
|
46
|
-
<div
|
|
47
|
-
v-for ="(option, idx) in userSettingsOptions"
|
|
48
|
-
v-on-click-outside="onClickOutsideHandler"
|
|
49
|
-
ref="settingsOptionsRef"
|
|
50
|
-
:key="option.label"
|
|
51
|
-
role="option"
|
|
52
|
-
class="option"
|
|
53
|
-
tabindex="-1"
|
|
54
|
-
@keydown="handleKeydownAction(userSettingsOptions, idx, $event, settingsOptionsRef, settingsTriggerRef)"
|
|
55
|
-
@click="handleSelectedClick(idx)"
|
|
56
|
-
>
|
|
57
|
-
<NuxtLink :to="option.url">
|
|
58
|
-
{{ option.label }}
|
|
59
|
-
<a-icon
|
|
60
|
-
:icon="option.icon"
|
|
61
|
-
color="black"
|
|
62
|
-
font-size="32px"
|
|
63
|
-
/>
|
|
64
|
-
</NuxtLink>
|
|
65
|
-
</div>
|
|
66
|
-
</div>
|
|
13
|
+
<NavUserDropdown :user="user" :user-dropdown-options="userDropdownOptions" :selected-option="selectedOptions" @select-option="$emit('selectedOption')"/>
|
|
67
14
|
</header>
|
|
68
15
|
</template>
|
|
69
16
|
|
|
70
17
|
<script setup lang="ts">
|
|
71
|
-
import { ref } from 'vue';
|
|
72
|
-
import { useDropdown } from '../../composables/accessibleActions.js';
|
|
73
|
-
import { vOnClickOutside } from '@vueuse/components';
|
|
74
|
-
|
|
75
|
-
const {
|
|
76
|
-
active,
|
|
77
|
-
toggleDropdown,
|
|
78
|
-
closeDropdown,
|
|
79
|
-
keydownActionsOnTrigger,
|
|
80
|
-
handleKeydown,
|
|
81
|
-
onClickOutsideHandler,
|
|
82
|
-
} = useDropdown();
|
|
83
18
|
|
|
84
19
|
interface IHeaderProps {
|
|
20
|
+
sticky?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface IUserDropdown {
|
|
85
24
|
user: {
|
|
86
25
|
name: string;
|
|
87
26
|
avatar?: string;
|
|
88
27
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
selectedSetting?: {}
|
|
28
|
+
userDropdownOptions: Array<unknown>;
|
|
29
|
+
selectedOption?: unknown
|
|
92
30
|
}
|
|
93
31
|
|
|
94
|
-
const props = defineProps<IHeaderProps>();
|
|
95
32
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const emit = defineEmits(['toggle-sidebar', 'select-setting']);
|
|
100
|
-
|
|
101
|
-
function handleSelectedClick(index: number) {
|
|
102
|
-
emit('select-setting', index);
|
|
103
|
-
closeDropdown();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function handleKeydownAction(userSettingsOptions: any[], idx: number, $event: { key: string | boolean; }, optionRef: { focus: () => void; }[], dropdownTriggerRef: { focus: () => void; }) {
|
|
107
|
-
if ($event.key === 'Enter' || $event.key === ' ') {
|
|
108
|
-
emit('select-setting', idx);
|
|
109
|
-
} else {
|
|
110
|
-
handleKeydown(userSettingsOptions, idx, $event, optionRef, dropdownTriggerRef);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
33
|
+
defineProps<IHeaderProps & IUserDropdown>();
|
|
34
|
+
defineEmits(['toggle-sidebar', 'selectedOption']);
|
|
113
35
|
|
|
114
|
-
function toggleSidebar() {
|
|
115
|
-
emit('toggle-sidebar');
|
|
116
|
-
}
|
|
117
36
|
</script>
|
|
118
37
|
|
|
119
38
|
<style scoped>
|
|
120
|
-
header {
|
|
39
|
+
header.header {
|
|
121
40
|
grid-area: navheader;
|
|
122
41
|
display: grid;
|
|
123
42
|
grid-auto-flow: column;
|
|
124
43
|
grid-template-columns: auto 1fr auto;
|
|
125
44
|
gap: 16px;
|
|
126
45
|
align-items: center;
|
|
127
|
-
padding: 24px 64px
|
|
46
|
+
padding: 24px 64px;
|
|
128
47
|
width: 100%;
|
|
129
48
|
background-color: var(--primary-white);
|
|
130
49
|
font: var(--font-regular);
|
|
131
50
|
}
|
|
132
51
|
@media only screen and (max-width: 960px) {
|
|
133
|
-
header {
|
|
52
|
+
header.header {
|
|
134
53
|
padding-left: 32px;
|
|
135
54
|
padding-right: 32px;
|
|
136
55
|
}
|
|
137
56
|
}
|
|
138
|
-
header.sticky {
|
|
57
|
+
header.header.sticky {
|
|
139
58
|
position: sticky;
|
|
140
59
|
}
|
|
141
|
-
header .sidebar-toggle {
|
|
142
|
-
display: flex;
|
|
143
|
-
align-items: center;
|
|
144
|
-
gap: 4px;
|
|
145
|
-
background: var(--purple-20);
|
|
146
|
-
border: none;
|
|
147
|
-
border-radius: 4px;
|
|
148
|
-
padding: 8px 16px;
|
|
149
|
-
color: var(--purple);
|
|
150
|
-
cursor: pointer;
|
|
151
|
-
}
|
|
152
|
-
header .sidebar-toggle:focus {
|
|
153
|
-
outline: none;
|
|
154
|
-
box-shadow: 0 0 0 2px var(--primary-white), 0 0 0 3px var(--purple);
|
|
155
|
-
}
|
|
156
|
-
header .header__dropdown {
|
|
157
|
-
font-size: 24px;
|
|
158
|
-
min-width: 64px;
|
|
159
|
-
width: 64px;
|
|
160
|
-
max-width: 64px;
|
|
161
|
-
border: none;
|
|
162
|
-
padding: 0;
|
|
163
|
-
outline: none;
|
|
164
|
-
color: var(--purple);
|
|
165
|
-
background: var(--purple-20);
|
|
166
|
-
border-radius: 16px;
|
|
167
|
-
overflow: hidden;
|
|
168
|
-
text-align: left;
|
|
169
|
-
position: relative;
|
|
170
|
-
display: flex;
|
|
171
|
-
align-items: center;
|
|
172
|
-
cursor: pointer;
|
|
173
|
-
}
|
|
174
|
-
header .header__dropdown:focus {
|
|
175
|
-
box-shadow: 0 0 0 2px var(--primary-white), 0 0 0 3px var(--purple);
|
|
176
|
-
}
|
|
177
|
-
header .header__dropdown .avatar-container:focus {
|
|
178
|
-
outline: none;
|
|
179
|
-
}
|
|
180
|
-
header .options-dropdown {
|
|
181
|
-
min-height: 100px;
|
|
182
|
-
position: absolute;
|
|
183
|
-
width: 198px;
|
|
184
|
-
right: 65px;
|
|
185
|
-
top: 80px;
|
|
186
|
-
background-color: #FFFFFF;
|
|
187
|
-
border-radius: 4px;
|
|
188
|
-
box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.06);
|
|
189
|
-
padding: 12px 0;
|
|
190
|
-
z-index: 10;
|
|
191
|
-
}
|
|
192
|
-
header .options-dropdown .option {
|
|
193
|
-
padding: 12px 16px;
|
|
194
|
-
cursor: pointer;
|
|
195
|
-
}
|
|
196
|
-
header .options-dropdown .option a {
|
|
197
|
-
color: #333;
|
|
198
|
-
text-decoration: none;
|
|
199
|
-
}
|
|
200
|
-
header .options-dropdown .option:focus-visible, header .options-dropdown .option:hover {
|
|
201
|
-
background-color: #F8F6FC;
|
|
202
|
-
}
|
|
203
60
|
</style>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="help-btn-wrapper">
|
|
3
3
|
<div
|
|
4
|
-
class="help-btn-actions"
|
|
5
4
|
ref="helpBtnActions"
|
|
6
|
-
|
|
7
|
-
:
|
|
5
|
+
class="help-btn-actions"
|
|
6
|
+
:class="{ expanded: expanded }"
|
|
7
|
+
:style="{ 'max-height': `${expanded ? dropdownScrollHeight : 0}px` }"
|
|
8
8
|
>
|
|
9
9
|
<button
|
|
10
10
|
v-for="(option, idx) in helpArticleOptions"
|
|
11
|
-
:key="idx"
|
|
12
11
|
:id="`help-btn-${option.id}`"
|
|
12
|
+
:key="idx"
|
|
13
13
|
class="help-btn-action"
|
|
14
14
|
>
|
|
15
15
|
{{ option.text }}
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
:class="['help-articles-btn', !isDropdown && 'help-btn']"
|
|
21
21
|
@click="expandDropdown"
|
|
22
22
|
>
|
|
23
|
-
<img v-if="isDropdown" src="../../assets/img/help-toggle.svg" alt="" class="help-center-btn-icon"
|
|
24
|
-
<img v-else src="../../assets/img/help.svg" alt="" class="help-center-btn-icon"
|
|
25
|
-
<span
|
|
23
|
+
<img v-if="isDropdown" src="../../assets/img/help-toggle.svg" alt="" class="help-center-btn-icon">
|
|
24
|
+
<img v-else src="../../assets/img/help.svg" alt="" class="help-center-btn-icon">
|
|
25
|
+
<span>
|
|
26
26
|
{{ isDropdown ? $t('navigation.helpCenter') : $t('navigation.helpArticles') }}
|
|
27
27
|
</span>
|
|
28
28
|
<img
|
|
29
|
-
v-if="isDropdown &&
|
|
29
|
+
v-if="isDropdown && !hasArticles"
|
|
30
30
|
class="caret-icon"
|
|
31
31
|
:class="{ collapse: !expanded }"
|
|
32
32
|
src="../../assets/img/navbar-up.svg"
|
|
33
33
|
alt=""
|
|
34
|
-
|
|
34
|
+
>
|
|
35
35
|
</button>
|
|
36
36
|
</div>
|
|
37
37
|
</template>
|
|
@@ -40,8 +40,7 @@
|
|
|
40
40
|
import { ref, computed, onMounted } from 'vue'
|
|
41
41
|
|
|
42
42
|
interface IHelpArticlesProps {
|
|
43
|
-
|
|
44
|
-
helpArticleOptions: Array<any>;
|
|
43
|
+
helpArticleOptions: Array<unknown>;
|
|
45
44
|
};
|
|
46
45
|
|
|
47
46
|
const props = withDefaults(defineProps<IHelpArticlesProps>(), {
|
|
@@ -53,9 +52,7 @@ const helpBtnActions = ref();
|
|
|
53
52
|
const dropdownScrollHeight = ref(0);
|
|
54
53
|
const isDropdown = ref(false);
|
|
55
54
|
|
|
56
|
-
const hasArticles = computed(() =>
|
|
57
|
-
return !!props.helpArticleOptions?.values?.length
|
|
58
|
-
})
|
|
55
|
+
const hasArticles = computed(() => !!props.helpArticleOptions?.values?.length)
|
|
59
56
|
|
|
60
57
|
onMounted(() => {
|
|
61
58
|
isDropdown.value = !!props.helpArticleOptions?.values?.length;
|
|
@@ -63,9 +60,7 @@ onMounted(() => {
|
|
|
63
60
|
});
|
|
64
61
|
|
|
65
62
|
function expandDropdown() {
|
|
66
|
-
if (!isDropdown)
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
63
|
+
if (!isDropdown.value) return;
|
|
69
64
|
expanded.value = !expanded.value;
|
|
70
65
|
};
|
|
71
66
|
|
|
@@ -78,6 +73,7 @@ function expandDropdown() {
|
|
|
78
73
|
flex-direction: column;
|
|
79
74
|
align-items: center;
|
|
80
75
|
width: 100%;
|
|
76
|
+
text-transform: uppercase;
|
|
81
77
|
}
|
|
82
78
|
.help-btn-wrapper .help-articles-btn {
|
|
83
79
|
cursor: pointer;
|
|
@@ -87,6 +83,7 @@ function expandDropdown() {
|
|
|
87
83
|
background: none;
|
|
88
84
|
padding: 8px 10px 8px 16px;
|
|
89
85
|
border: none;
|
|
86
|
+
text-transform: inherit;
|
|
90
87
|
}
|
|
91
88
|
.help-btn-wrapper .help-articles-btn:focus-visible {
|
|
92
89
|
outline: var(--orange) solid 2px;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden>
|
|
3
|
+
<rect x="4.3335" y="5.5" width="15.3333" height="13" rx="0.666667" stroke="currentColor"/>
|
|
4
|
+
<path d="M10 6L10 18" stroke="currentColor" stroke-linecap="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="a-nav-section animated"
|
|
3
|
-
<button
|
|
2
|
+
<div id="impersonate-info" class="a-nav-section animated">
|
|
3
|
+
<button class="a-nav-section--title" @click="expanded = !expanded">
|
|
4
4
|
<div class="a-nav-section-title-wrapper">
|
|
5
5
|
<div class="user-grid">
|
|
6
|
-
<img src="../../assets/img/impersonate-user.svg" alt="" class="user-icon"
|
|
6
|
+
<img src="../../assets/img/impersonate-user.svg" alt="" class="user-icon" >
|
|
7
7
|
<p class="info">{{ impersonatedUser.client }}</p>
|
|
8
8
|
<p class="info email">{{ impersonatedUser.email }}</p>
|
|
9
|
-
<img v-if="!expanded " class="panel-icon" src="../../assets/icons/24/Plus.svg" alt=""
|
|
10
|
-
<img v-else class="panel-icon" src="../../assets/icons/24/Minus.svg" alt=""
|
|
9
|
+
<img v-if="!expanded " class="panel-icon" src="../../assets/icons/24/Plus.svg" alt="" >
|
|
10
|
+
<img v-else class="panel-icon" src="../../assets/icons/24/Minus.svg" alt="" >
|
|
11
11
|
</div>
|
|
12
12
|
<div
|
|
13
13
|
ref="dropdownWrapper"
|
|
14
|
-
:style="{ 'max-height': `${expanded
|
|
14
|
+
:style="{ 'max-height': `${expanded ? dropdownScrollHeight : 0}px` }"
|
|
15
15
|
class="a-nav-section-title-dropdown-wrapper"
|
|
16
16
|
>
|
|
17
17
|
<div class="user-grid">
|
|
18
|
-
<img src="../../assets/img/user.svg" alt="" class="user-icon"
|
|
18
|
+
<img src="../../assets/img/user.svg" alt="" class="user-icon" >
|
|
19
19
|
<p class="info">{{ impersonatedUser.client }}</p>
|
|
20
20
|
<p class="info email">{{ impersonatedUser.admin_email }}</p>
|
|
21
21
|
</div>
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
import { ref, onMounted } from '#imports';
|
|
30
30
|
|
|
31
31
|
interface IPanelProps {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
client: ''
|
|
32
|
+
impersonatedUser: {
|
|
33
|
+
name: string,
|
|
34
|
+
email: string,
|
|
35
|
+
admin_email: string,
|
|
36
|
+
client: string,
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
|
-
|
|
39
|
+
|
|
40
|
+
defineProps<IPanelProps>();
|
|
41
41
|
|
|
42
42
|
const expanded = ref(false);
|
|
43
43
|
const dropdownScrollHeight = ref(0);
|