@a-vision-software/vue-input-components 1.2.11 → 1.2.13
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 +121 -102
- package/dist/vue-input-components.cjs.js +1 -561
- package/dist/vue-input-components.css +1 -1
- package/dist/vue-input-components.es.js +4906 -8034
- package/dist/vue-input-components.umd.js +1 -561
- package/package.json +82 -86
- package/src/assets/colors.css +2 -1
- package/src/components/Dropdown.vue +400 -0
- package/src/components/Navigation.vue +98 -163
- package/src/main.ts +1 -1
- package/src/router/index.ts +7 -0
- package/src/types/dropdown.ts +25 -0
- package/src/views/DashboardView.vue +7 -0
- package/src/views/DropdownTestView.vue +191 -0
- package/src/views/NavigationTestView.vue +13 -54
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<nav
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
]"
|
|
9
|
-
:style="{
|
|
2
|
+
<nav :class="[
|
|
3
|
+
'navigation',
|
|
4
|
+
`navigation--${type}`,
|
|
5
|
+
`navigation--${orientation}`,
|
|
6
|
+
{ 'navigation--large-icons': iconSize === 'large' },
|
|
7
|
+
]" :style="{
|
|
10
8
|
'--navigation-color': color,
|
|
11
9
|
'--navigation-hover-color': hoverColor,
|
|
12
10
|
'--navigation-active-color': activeColor,
|
|
@@ -23,101 +21,61 @@
|
|
|
23
21
|
: 'none',
|
|
24
22
|
'--navigation-tiles-grid': navigationGrid,
|
|
25
23
|
'max-height': height,
|
|
26
|
-
}"
|
|
27
|
-
>
|
|
24
|
+
}">
|
|
28
25
|
<template v-if="type === 'tiles'">
|
|
29
26
|
<div class="navigation__tiles">
|
|
30
|
-
<div
|
|
31
|
-
|
|
32
|
-
:
|
|
33
|
-
|
|
34
|
-
:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
|
|
47
|
-
}"
|
|
48
|
-
@click="(e) => !item.id.includes('spacer') && handleItemClick(item, e)"
|
|
49
|
-
>
|
|
50
|
-
<div
|
|
51
|
-
class="navigation__tile-content"
|
|
52
|
-
:class="{
|
|
53
|
-
'navigation__tile-content--icon-only': !item.label,
|
|
54
|
-
'navigation__tile-content--large-icon': iconSize === 'large' && item.icon,
|
|
55
|
-
}"
|
|
56
|
-
>
|
|
27
|
+
<div v-for="(item, index) in sortedItems" :key="item.id" class="navigation__tile" :class="[
|
|
28
|
+
{ 'navigation__tile--active': item.id === activeItem },
|
|
29
|
+
{ 'navigation__tile--disabled': item.disabled },
|
|
30
|
+
{ 'navigation__tile--right': item.alignment === 'right' },
|
|
31
|
+
{ 'navigation__tile--open': isDropdownOpen(item.id) },
|
|
32
|
+
{ 'navigation__tile--spacer': item.id.includes('spacer') },
|
|
33
|
+
]" :style="{
|
|
34
|
+
'--item-alignment': item.alignment || activeItemAlignment,
|
|
35
|
+
width: item.width || '150px',
|
|
36
|
+
'min-width': item.width || '150px',
|
|
37
|
+
'max-width': item.width || '150px',
|
|
38
|
+
'grid-column': item.alignment === 'right' ? `${index - items.length}` : `auto`,
|
|
39
|
+
}" @click="(e) => !item.id.includes('spacer') && handleItemClick(item, e)">
|
|
40
|
+
<div class="navigation__tile-content" :class="{
|
|
41
|
+
'navigation__tile-content--icon-only': !item.label,
|
|
42
|
+
'navigation__tile-content--large-icon': iconSize === 'large' && item.icon,
|
|
43
|
+
}">
|
|
57
44
|
<div v-if="item.icon" class="navigation__icon">
|
|
58
|
-
<img
|
|
59
|
-
|
|
60
|
-
:src="item.icon.substring(4)"
|
|
61
|
-
:alt="item.label || 'Icon'"
|
|
62
|
-
class="navigation__icon-image"
|
|
63
|
-
/>
|
|
45
|
+
<img v-if="item.icon.startsWith('img:')" :src="item.icon.substring(4)" :alt="item.label || 'Icon'"
|
|
46
|
+
class="navigation__icon-image" />
|
|
64
47
|
<font-awesome-icon v-else :icon="item.icon" />
|
|
65
48
|
</div>
|
|
66
|
-
<div
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
'navigation__label--small': item.labelSize === 'small',
|
|
71
|
-
'navigation__label--large': item.labelSize === 'large',
|
|
72
|
-
}"
|
|
73
|
-
>
|
|
49
|
+
<div v-if="item.label" class="navigation__label" :class="{
|
|
50
|
+
'navigation__label--small': item.labelSize === 'small',
|
|
51
|
+
'navigation__label--large': item.labelSize === 'large',
|
|
52
|
+
}">
|
|
74
53
|
<span>{{ item.label }}</span>
|
|
75
54
|
<div v-if="item.children" class="navigation__dropdown-arrow">
|
|
76
55
|
<font-awesome-icon icon="chevron-down" />
|
|
77
56
|
</div>
|
|
78
57
|
</div>
|
|
79
58
|
</div>
|
|
80
|
-
<div
|
|
81
|
-
|
|
82
|
-
class="navigation__external-link"
|
|
83
|
-
@click.stop="openUrl(item.url)"
|
|
84
|
-
>
|
|
59
|
+
<div v-if="item.url && parseInt(height || '0') >= 80 && !item.hideExternalOpen"
|
|
60
|
+
class="navigation__external-link" @click.stop="openUrl(item.url)">
|
|
85
61
|
<font-awesome-icon icon="square-up-right" />
|
|
86
62
|
</div>
|
|
87
|
-
<div
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'navigation__dropdown-
|
|
93
|
-
}"
|
|
94
|
-
>
|
|
95
|
-
<div
|
|
96
|
-
v-for="child in item.children"
|
|
97
|
-
:key="child.id"
|
|
98
|
-
class="navigation__dropdown-item"
|
|
99
|
-
:class="{
|
|
100
|
-
'navigation__dropdown-item--disabled': child.disabled,
|
|
101
|
-
}"
|
|
102
|
-
@click="(e) => handleItemClick(child, e)"
|
|
103
|
-
>
|
|
63
|
+
<div v-if="item.children && isDropdownOpen(item.id)" class="navigation__dropdown-content" :class="{
|
|
64
|
+
'navigation__dropdown-content--start': item.alignment === 'start',
|
|
65
|
+
'navigation__dropdown-content--end': item.alignment === 'end',
|
|
66
|
+
}">
|
|
67
|
+
<div v-for="child in item.children" :key="child.id" class="navigation__dropdown-item" :class="{
|
|
68
|
+
'navigation__dropdown-item--disabled': child.disabled,
|
|
69
|
+
}" @click="(e) => handleItemClick(child, e)">
|
|
104
70
|
<div v-if="child.icon" class="navigation__icon">
|
|
105
|
-
<img
|
|
106
|
-
|
|
107
|
-
:src="child.icon.substring(4)"
|
|
108
|
-
:alt="child.label || 'Icon'"
|
|
109
|
-
class="navigation__icon-image"
|
|
110
|
-
/>
|
|
71
|
+
<img v-if="child.icon.startsWith('img:')" :src="child.icon.substring(4)" :alt="child.label || 'Icon'"
|
|
72
|
+
class="navigation__icon-image" />
|
|
111
73
|
<font-awesome-icon v-else :icon="child.icon" />
|
|
112
74
|
</div>
|
|
113
|
-
<div
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
'navigation__label--small': child.labelSize === 'small',
|
|
118
|
-
'navigation__label--large': child.labelSize === 'large',
|
|
119
|
-
}"
|
|
120
|
-
>
|
|
75
|
+
<div v-if="child.label" class="navigation__label" :class="{
|
|
76
|
+
'navigation__label--small': child.labelSize === 'small',
|
|
77
|
+
'navigation__label--large': child.labelSize === 'large',
|
|
78
|
+
}">
|
|
121
79
|
{{ child.label }}
|
|
122
80
|
</div>
|
|
123
81
|
</div>
|
|
@@ -128,93 +86,54 @@
|
|
|
128
86
|
|
|
129
87
|
<template v-else>
|
|
130
88
|
<div class="navigation__dropdowns">
|
|
131
|
-
<div
|
|
132
|
-
|
|
133
|
-
:
|
|
134
|
-
|
|
135
|
-
:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}"
|
|
145
|
-
>
|
|
146
|
-
<div
|
|
147
|
-
class="navigation__dropdown-header"
|
|
148
|
-
:class="{
|
|
149
|
-
'navigation__dropdown-header--icon-only': !item.label,
|
|
150
|
-
'navigation__dropdown-header--large-icon': iconSize === 'large' && item.icon,
|
|
151
|
-
}"
|
|
152
|
-
@click="(e) => handleItemClick(item, e)"
|
|
153
|
-
>
|
|
89
|
+
<div v-for="item in items" :key="item.id" class="navigation__dropdown" :class="[
|
|
90
|
+
{ 'navigation__dropdown--active': item.id === activeItem },
|
|
91
|
+
{ 'navigation__dropdown--disabled': item.disabled },
|
|
92
|
+
{ 'navigation__dropdown--start': item.alignment === 'start' },
|
|
93
|
+
{ 'navigation__dropdown--end': item.alignment === 'end' },
|
|
94
|
+
{ 'navigation__dropdown--open': isDropdownOpen(item.id) },
|
|
95
|
+
]" :style="{
|
|
96
|
+
'--item-alignment': item.alignment || activeItemAlignment,
|
|
97
|
+
}">
|
|
98
|
+
<div class="navigation__dropdown-header" :class="{
|
|
99
|
+
'navigation__dropdown-header--icon-only': !item.label,
|
|
100
|
+
'navigation__dropdown-header--large-icon': iconSize === 'large' && item.icon,
|
|
101
|
+
}" @click="(e) => handleItemClick(item, e)">
|
|
154
102
|
<div v-if="item.icon" class="navigation__icon">
|
|
155
|
-
<img
|
|
156
|
-
|
|
157
|
-
:src="item.icon.substring(4)"
|
|
158
|
-
:alt="item.label || 'Icon'"
|
|
159
|
-
class="navigation__icon-image"
|
|
160
|
-
/>
|
|
103
|
+
<img v-if="item.icon.startsWith('img:')" :src="item.icon.substring(4)" :alt="item.label || 'Icon'"
|
|
104
|
+
class="navigation__icon-image" />
|
|
161
105
|
<font-awesome-icon v-else :icon="item.icon" />
|
|
162
106
|
</div>
|
|
163
|
-
<div
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
'navigation__label--small': item.labelSize === 'small',
|
|
168
|
-
'navigation__label--large': item.labelSize === 'large',
|
|
169
|
-
}"
|
|
170
|
-
>
|
|
107
|
+
<div v-if="item.label" class="navigation__label" :class="{
|
|
108
|
+
'navigation__label--small': item.labelSize === 'small',
|
|
109
|
+
'navigation__label--large': item.labelSize === 'large',
|
|
110
|
+
}">
|
|
171
111
|
<span>{{ item.label }}</span>
|
|
172
112
|
<div v-if="item.children" class="navigation__dropdown-arrow">
|
|
173
113
|
<font-awesome-icon icon="chevron-down" />
|
|
174
114
|
</div>
|
|
175
115
|
</div>
|
|
176
116
|
</div>
|
|
177
|
-
<div
|
|
178
|
-
|
|
179
|
-
class="navigation__external-link"
|
|
180
|
-
@click.stop="openUrl(item.url)"
|
|
181
|
-
>
|
|
117
|
+
<div v-if="item.url && parseInt(height || '0') >= 80 && !item.hideExternalOpen"
|
|
118
|
+
class="navigation__external-link" @click.stop="openUrl(item.url)">
|
|
182
119
|
<font-awesome-icon icon="square-up-right" />
|
|
183
120
|
</div>
|
|
184
|
-
<div
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
'navigation__dropdown-
|
|
190
|
-
}"
|
|
191
|
-
>
|
|
192
|
-
<div
|
|
193
|
-
v-for="child in item.children"
|
|
194
|
-
:key="child.id"
|
|
195
|
-
class="navigation__dropdown-item"
|
|
196
|
-
:class="{
|
|
197
|
-
'navigation__dropdown-item--disabled': child.disabled,
|
|
198
|
-
}"
|
|
199
|
-
@click="(e) => handleItemClick(child, e)"
|
|
200
|
-
>
|
|
121
|
+
<div v-if="item.children && isDropdownOpen(item.id)" class="navigation__dropdown-content" :class="{
|
|
122
|
+
'navigation__dropdown-content--start': item.alignment === 'start',
|
|
123
|
+
'navigation__dropdown-content--end': item.alignment === 'end',
|
|
124
|
+
}">
|
|
125
|
+
<div v-for="child in item.children" :key="child.id" class="navigation__dropdown-item" :class="{
|
|
126
|
+
'navigation__dropdown-item--disabled': child.disabled,
|
|
127
|
+
}" @click="(e) => handleItemClick(child, e)">
|
|
201
128
|
<div v-if="child.icon" class="navigation__icon">
|
|
202
|
-
<img
|
|
203
|
-
|
|
204
|
-
:src="child.icon.substring(4)"
|
|
205
|
-
:alt="child.label || 'Icon'"
|
|
206
|
-
class="navigation__icon-image"
|
|
207
|
-
/>
|
|
129
|
+
<img v-if="child.icon.startsWith('img:')" :src="child.icon.substring(4)" :alt="child.label || 'Icon'"
|
|
130
|
+
class="navigation__icon-image" />
|
|
208
131
|
<font-awesome-icon v-else :icon="child.icon" />
|
|
209
132
|
</div>
|
|
210
|
-
<div
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
'navigation__label--small': child.labelSize === 'small',
|
|
215
|
-
'navigation__label--large': child.labelSize === 'large',
|
|
216
|
-
}"
|
|
217
|
-
>
|
|
133
|
+
<div v-if="child.label" class="navigation__label" :class="{
|
|
134
|
+
'navigation__label--small': child.labelSize === 'small',
|
|
135
|
+
'navigation__label--large': child.labelSize === 'large',
|
|
136
|
+
}">
|
|
218
137
|
{{ child.label }}
|
|
219
138
|
</div>
|
|
220
139
|
</div>
|
|
@@ -227,8 +146,7 @@
|
|
|
227
146
|
|
|
228
147
|
<script setup lang="ts">
|
|
229
148
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
|
230
|
-
import {
|
|
231
|
-
import { NavigationProps, NavigationItem } from '../types/navigation'
|
|
149
|
+
import type { NavigationProps, NavigationItem } from '../types/navigation'
|
|
232
150
|
|
|
233
151
|
const props = defineProps<NavigationProps>()
|
|
234
152
|
const emit = defineEmits<{
|
|
@@ -334,11 +252,13 @@ onUnmounted(() => {
|
|
|
334
252
|
transition: all 0.2s ease;
|
|
335
253
|
background: transparent;
|
|
336
254
|
height: 100%;
|
|
255
|
+
overflow: hidden;
|
|
337
256
|
}
|
|
338
257
|
|
|
339
258
|
.navigation__tile:hover {
|
|
340
259
|
border-color: var(--navigation-hover-color);
|
|
341
260
|
color: var(--navigation-hover-color);
|
|
261
|
+
overflow: visible;
|
|
342
262
|
|
|
343
263
|
.navigation__tile-content {
|
|
344
264
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -347,6 +267,7 @@ onUnmounted(() => {
|
|
|
347
267
|
}
|
|
348
268
|
|
|
349
269
|
.navigation__tile--active {
|
|
270
|
+
overflow: visible;
|
|
350
271
|
border-color: var(--navigation-active-color);
|
|
351
272
|
color: var(--navigation-active-color);
|
|
352
273
|
background-color: var(--navigation-active-background-color);
|
|
@@ -584,10 +505,24 @@ onUnmounted(() => {
|
|
|
584
505
|
.navigation__label {
|
|
585
506
|
white-space: nowrap;
|
|
586
507
|
text-align: center;
|
|
587
|
-
display:
|
|
508
|
+
display: inline-block;
|
|
509
|
+
overflow: hidden;
|
|
510
|
+
text-overflow: ellipsis;
|
|
588
511
|
align-items: center;
|
|
589
512
|
justify-content: center;
|
|
590
513
|
font-size: 1rem;
|
|
514
|
+
max-width: 100%;
|
|
515
|
+
|
|
516
|
+
.navigation__dropdown-arrow {
|
|
517
|
+
display: inline-block;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.navigation__tile:hover .navigation__label,
|
|
522
|
+
.navigation__tile--active .navigation__label {
|
|
523
|
+
text-overflow: unset;
|
|
524
|
+
overflow: visible;
|
|
525
|
+
max-width: unset;
|
|
591
526
|
}
|
|
592
527
|
|
|
593
528
|
.navigation__label--small {
|
package/src/main.ts
CHANGED
package/src/router/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import FileUploadTestView from '../views/FileUploadTestView.vue'
|
|
|
4
4
|
import ActionTestView from '../views/ActionTestView.vue'
|
|
5
5
|
import DashboardView from '../views/DashboardView.vue'
|
|
6
6
|
import NavigationTestView from '../views/NavigationTestView.vue'
|
|
7
|
+
import DropdownTestView from '../views/DropdownTestView.vue'
|
|
7
8
|
|
|
8
9
|
const router = createRouter({
|
|
9
10
|
history: createWebHistory(import.meta.env.BASE_URL),
|
|
@@ -38,6 +39,12 @@ const router = createRouter({
|
|
|
38
39
|
component: NavigationTestView,
|
|
39
40
|
meta: { title: 'Navigation Test' },
|
|
40
41
|
},
|
|
42
|
+
{
|
|
43
|
+
path: '/dropdown',
|
|
44
|
+
name: 'dropdown',
|
|
45
|
+
component: DropdownTestView,
|
|
46
|
+
meta: { title: 'Dropdown Test' },
|
|
47
|
+
},
|
|
41
48
|
],
|
|
42
49
|
})
|
|
43
50
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DropdownOption {
|
|
2
|
+
id: string
|
|
3
|
+
label: string
|
|
4
|
+
disabled?: boolean
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface DropdownProps {
|
|
8
|
+
options: DropdownOption[]
|
|
9
|
+
modelValue: string | string[]
|
|
10
|
+
multiple?: boolean
|
|
11
|
+
placeholder?: string
|
|
12
|
+
filterable?: boolean
|
|
13
|
+
disabled?: boolean
|
|
14
|
+
maxHeight?: string
|
|
15
|
+
width?: string
|
|
16
|
+
color?: string
|
|
17
|
+
hoverColor?: string
|
|
18
|
+
activeColor?: string
|
|
19
|
+
disabledColor?: string
|
|
20
|
+
backgroundColor?: string
|
|
21
|
+
borderRadius?: string
|
|
22
|
+
padding?: string
|
|
23
|
+
icon?: string
|
|
24
|
+
iconSize?: 'normal' | 'large'
|
|
25
|
+
}
|
|
@@ -30,6 +30,13 @@
|
|
|
30
30
|
<p>Test the navigation component</p>
|
|
31
31
|
</div>
|
|
32
32
|
</router-link>
|
|
33
|
+
<router-link to="/dropdown" class="tile">
|
|
34
|
+
<div class="tile-content">
|
|
35
|
+
<font-awesome-icon icon="chevron-down" class="tile-icon" />
|
|
36
|
+
<h2>Dropdown</h2>
|
|
37
|
+
<p>Test the dropdown component with single/multiple selection and filtering</p>
|
|
38
|
+
</div>
|
|
39
|
+
</router-link>
|
|
33
40
|
</div>
|
|
34
41
|
</div>
|
|
35
42
|
</template>
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="dropdown-test">
|
|
3
|
+
<div class="dropdown-test__back">
|
|
4
|
+
<router-link to="/" class="back-link"> ← Back to Dashboard </router-link>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="dropdown-test__section">
|
|
8
|
+
<h2>Single Select Dropdown</h2>
|
|
9
|
+
<Dropdown v-model="selectedSingle" :options="options" placeholder="Select a color" filterable
|
|
10
|
+
@update:modelValue="handleSingleChange" />
|
|
11
|
+
<div v-if="selectedSingle" class="selection-info">
|
|
12
|
+
Selected: {{ getOptionLabel(selectedSingle) }}
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="dropdown-test__section">
|
|
17
|
+
<h2>Multiple Select Dropdown</h2>
|
|
18
|
+
<Dropdown v-model="selectedMultiple" :options="options" multiple filterable placeholder="Select colors"
|
|
19
|
+
icon="paintbrush" @update:modelValue="handleMultipleChange" color="#aa0000" />
|
|
20
|
+
<div v-if="selectedMultiple.length" class="selection-info">
|
|
21
|
+
Selected: {{ getSelectedLabels(selectedMultiple).join(', ') }}
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="dropdown-test__section">
|
|
26
|
+
<h2>Dropdown with Icon</h2>
|
|
27
|
+
<Dropdown v-model="selectedWithIcon" :options="options" placeholder="Select with icon" icon="house"
|
|
28
|
+
@update:modelValue="handleIconChange" />
|
|
29
|
+
<div v-if="selectedWithIcon" class="selection-info">
|
|
30
|
+
Selected: {{ getOptionLabel(selectedWithIcon) }}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div class="dropdown-test__section">
|
|
35
|
+
<h2>Dropdown with Large Icon</h2>
|
|
36
|
+
<Dropdown v-model="selectedWithLargeIcon" :options="options" placeholder="Select with large icon"
|
|
37
|
+
icon="gauge-high" iconSize="large" @update:modelValue="handleLargeIconChange" />
|
|
38
|
+
<div v-if="selectedWithLargeIcon" class="selection-info">
|
|
39
|
+
Selected: {{ getOptionLabel(selectedWithLargeIcon) }}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div class="dropdown-test__section">
|
|
44
|
+
<h2>Custom Styled Dropdown</h2>
|
|
45
|
+
<Dropdown v-model="selectedCustom" :options="options" placeholder="Select with custom style" color="#4a90e2"
|
|
46
|
+
hoverColor="#357abd" activeColor="#2c5a8c" borderRadius="1rem" padding="0.75rem 1rem"
|
|
47
|
+
@update:modelValue="handleCustomChange" />
|
|
48
|
+
<div v-if="selectedCustom" class="selection-info">
|
|
49
|
+
Selected: {{ getOptionLabel(selectedCustom) }}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div class="dropdown-test__section">
|
|
54
|
+
<h2>Disabled Dropdown</h2>
|
|
55
|
+
<Dropdown v-model="selectedDisabled" :options="options" disabled placeholder="This dropdown is disabled" />
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div class="dropdown-test__section">
|
|
59
|
+
<h2>Dropdown with Disabled Options</h2>
|
|
60
|
+
<Dropdown v-model="selectedWithDisabled" :options="optionsWithDisabled" placeholder="Some options are disabled"
|
|
61
|
+
@update:modelValue="handleDisabledChange" />
|
|
62
|
+
<div v-if="selectedWithDisabled" class="selection-info">
|
|
63
|
+
Selected: {{ getOptionLabel(selectedWithDisabled) }}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<script setup lang="ts">
|
|
70
|
+
import { ref } from 'vue'
|
|
71
|
+
import type { DropdownOption } from '../types/dropdown'
|
|
72
|
+
import Dropdown from '@/components/Dropdown.vue'
|
|
73
|
+
|
|
74
|
+
const options: DropdownOption[] = [
|
|
75
|
+
{ id: 'red', label: 'Red' },
|
|
76
|
+
{ id: 'blue', label: 'Blue' },
|
|
77
|
+
{ id: 'green', label: 'Green' },
|
|
78
|
+
{ id: 'yellow', label: 'Yellow' },
|
|
79
|
+
{ id: 'purple', label: 'Purple' },
|
|
80
|
+
{ id: 'orange', label: 'Orange' },
|
|
81
|
+
{ id: 'pink', label: 'Pink' },
|
|
82
|
+
{ id: 'brown', label: 'Brown' },
|
|
83
|
+
{ id: 'gray', label: 'Gray' },
|
|
84
|
+
{ id: 'black', label: 'Black' },
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
const optionsWithDisabled: DropdownOption[] = [
|
|
88
|
+
{ id: 'red', label: 'Red' },
|
|
89
|
+
{ id: 'blue', label: 'Blue', disabled: true },
|
|
90
|
+
{ id: 'green', label: 'Green' },
|
|
91
|
+
{ id: 'yellow', label: 'Yellow', disabled: true },
|
|
92
|
+
{ id: 'purple', label: 'Purple' },
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
const selectedSingle = ref('')
|
|
96
|
+
const selectedMultiple = ref<string[]>([])
|
|
97
|
+
const selectedCustom = ref('')
|
|
98
|
+
const selectedDisabled = ref('')
|
|
99
|
+
const selectedWithDisabled = ref('')
|
|
100
|
+
const selectedWithIcon = ref('')
|
|
101
|
+
const selectedWithLargeIcon = ref('')
|
|
102
|
+
|
|
103
|
+
const getOptionLabel = (id: string) => {
|
|
104
|
+
return options.find((option) => option.id === id)?.label || ''
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const getSelectedLabels = (ids: string[]) => {
|
|
108
|
+
return ids.map((id) => getOptionLabel(id)).filter(Boolean)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const handleSingleChange = (value: string | string[]) => {
|
|
112
|
+
if (typeof value === 'string') {
|
|
113
|
+
console.log('Single selection changed:', value)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const handleMultipleChange = (value: string | string[]) => {
|
|
118
|
+
if (Array.isArray(value)) {
|
|
119
|
+
console.log('Multiple selection changed:', value)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const handleCustomChange = (value: string | string[]) => {
|
|
124
|
+
if (typeof value === 'string') {
|
|
125
|
+
console.log('Custom selection changed:', value)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const handleDisabledChange = (value: string | string[]) => {
|
|
130
|
+
if (typeof value === 'string') {
|
|
131
|
+
console.log('Selection with disabled options changed:', value)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const handleIconChange = (value: string | string[]) => {
|
|
136
|
+
if (typeof value === 'string') {
|
|
137
|
+
console.log('Selection with icon changed:', value)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const handleLargeIconChange = (value: string | string[]) => {
|
|
142
|
+
if (typeof value === 'string') {
|
|
143
|
+
console.log('Selection with large icon changed:', value)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
</script>
|
|
147
|
+
|
|
148
|
+
<style scoped>
|
|
149
|
+
.dropdown-test {
|
|
150
|
+
max-width: 800px;
|
|
151
|
+
margin: 0 auto;
|
|
152
|
+
padding: 2rem;
|
|
153
|
+
margin-bottom: 5rem;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.dropdown-test__back {
|
|
157
|
+
margin-bottom: 2rem;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.back-link {
|
|
161
|
+
display: inline-flex;
|
|
162
|
+
align-items: center;
|
|
163
|
+
gap: 0.5rem;
|
|
164
|
+
color: #4a90e2;
|
|
165
|
+
text-decoration: none;
|
|
166
|
+
font-weight: 500;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.back-link:hover {
|
|
170
|
+
color: #357abd;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.dropdown-test__section {
|
|
174
|
+
margin-bottom: 3rem;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.dropdown-test__section h2 {
|
|
178
|
+
margin-bottom: 1rem;
|
|
179
|
+
color: #333;
|
|
180
|
+
font-size: 1.5rem;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.selection-info {
|
|
184
|
+
margin-top: 1rem;
|
|
185
|
+
padding: 0.5rem;
|
|
186
|
+
background-color: #f7fafc;
|
|
187
|
+
border-radius: 4px;
|
|
188
|
+
font-size: 0.9rem;
|
|
189
|
+
color: #4a5568;
|
|
190
|
+
}
|
|
191
|
+
</style>
|