@necrolab/dashboard 0.5.15 → 0.5.17
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/backend/api.js +2 -3
- package/eslint.config.js +46 -0
- package/index.html +2 -1
- package/package.json +5 -2
- package/src/App.vue +70 -566
- package/src/assets/css/base/mixins.scss +72 -0
- package/src/assets/css/base/reset.scss +0 -2
- package/src/assets/css/base/scroll.scss +43 -36
- package/src/assets/css/base/typography.scss +9 -10
- package/src/assets/css/base/variables.scss +43 -0
- package/src/assets/css/components/accessibility.scss +37 -0
- package/src/assets/css/components/buttons.scss +61 -74
- package/src/assets/css/components/forms.scss +31 -32
- package/src/assets/css/components/headers.scss +13 -21
- package/src/assets/css/components/modals.scss +2 -2
- package/src/assets/css/components/search-groups.scss +28 -22
- package/src/assets/css/components/tables.scss +5 -7
- package/src/assets/css/components/toasts.scss +7 -7
- package/src/assets/css/components/utilities.scss +295 -0
- package/src/assets/css/main.scss +55 -139
- package/src/components/Auth/LoginForm.vue +7 -86
- package/src/components/Console/ConsoleToolbar.vue +123 -0
- package/src/components/Editors/Account/Account.vue +12 -12
- package/src/components/Editors/Account/AccountView.vue +38 -111
- package/src/components/Editors/Account/CreateAccount.vue +11 -61
- package/src/components/Editors/Account/{AccountCreator.vue → CreateAccountBatch.vue} +28 -59
- package/src/components/Editors/AdminFileEditor.vue +179 -0
- package/src/components/Editors/Profile/CreateProfile.vue +77 -150
- package/src/components/Editors/Profile/Profile.vue +20 -21
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +16 -60
- package/src/components/Editors/Profile/ProfileView.vue +41 -116
- package/src/components/Editors/ProxyFileEditor.vue +86 -0
- package/src/components/Editors/TagLabel.vue +16 -55
- package/src/components/Editors/TagToggle.vue +20 -8
- package/src/components/Filter/Filter.vue +66 -79
- package/src/components/Filter/FilterPreview.vue +153 -135
- package/src/components/Filter/PriceSortToggle.vue +36 -43
- package/src/components/Table/Header.vue +1 -1
- package/src/components/Table/Table.vue +45 -51
- package/src/components/Tasks/CheckStock.vue +7 -16
- package/src/components/Tasks/Controls/DesktopControls.vue +15 -60
- package/src/components/Tasks/Controls/MobileControls.vue +5 -20
- package/src/components/Tasks/CreateTaskAXS.vue +20 -118
- package/src/components/Tasks/CreateTaskTM.vue +33 -189
- package/src/components/Tasks/EventDetailRow.vue +21 -0
- package/src/components/Tasks/MassEdit.vue +6 -16
- package/src/components/Tasks/QuickSettings.vue +140 -216
- package/src/components/Tasks/ScrapeVenue.vue +4 -13
- package/src/components/Tasks/Stats.vue +20 -39
- package/src/components/Tasks/Task.vue +64 -270
- package/src/components/Tasks/TaskLabel.vue +9 -3
- package/src/components/Tasks/TaskView.vue +45 -64
- package/src/components/Tasks/Utilities.vue +10 -44
- package/src/components/Tasks/ViewTask.vue +23 -107
- package/src/components/icons/Close.vue +2 -8
- package/src/components/icons/Gear.vue +8 -8
- package/src/components/icons/Hash.vue +5 -0
- package/src/components/icons/Key.vue +2 -8
- package/src/components/icons/Pencil.vue +2 -8
- package/src/components/icons/Profile.vue +2 -8
- package/src/components/icons/Sell.vue +2 -8
- package/src/components/icons/Spinner.vue +4 -7
- package/src/components/icons/Wildcard.vue +2 -8
- package/src/components/icons/index.js +3 -5
- package/src/components/ui/ActionButtonGroup.vue +113 -52
- package/src/components/ui/BalanceIndicator.vue +60 -0
- package/src/components/ui/EmptyState.vue +24 -0
- package/src/components/ui/EnableDisableToggle.vue +23 -0
- package/src/components/ui/FormField.vue +49 -49
- package/src/components/ui/IconLabel.vue +23 -0
- package/src/components/ui/InfoRow.vue +21 -54
- package/src/components/ui/Modal.vue +161 -54
- package/src/components/ui/Navbar.vue +63 -44
- package/src/components/ui/ReadonlyFieldsSection.vue +31 -0
- package/src/components/ui/ReconnectIndicator.vue +111 -124
- package/src/components/ui/SectionCard.vue +6 -14
- package/src/components/ui/Splash.vue +2 -10
- package/src/components/ui/StatusBadge.vue +26 -28
- package/src/components/ui/TaskToggle.vue +54 -0
- package/src/components/ui/controls/CountryChooser.vue +29 -66
- package/src/components/ui/controls/EyeToggle.vue +1 -1
- package/src/components/ui/controls/atomic/Checkbox.vue +40 -121
- package/src/components/ui/controls/atomic/Dropdown.vue +103 -139
- package/src/components/ui/controls/atomic/MultiDropdown.vue +72 -120
- package/src/components/ui/controls/atomic/Switch.vue +21 -84
- package/src/composables/useCodeEditor.js +117 -0
- package/src/composables/useColorMapping.js +15 -0
- package/src/composables/useCopyToClipboard.js +1 -1
- package/src/composables/useDateFormatting.js +21 -0
- package/src/composables/useDeviceDetection.js +14 -0
- package/src/composables/useDropdownPosition.js +1 -4
- package/src/composables/useDynamicTableHeight.js +31 -0
- package/src/composables/useEnableDisable.js +6 -0
- package/src/composables/useFilterCSS.js +71 -0
- package/src/composables/useFormValidation.js +92 -0
- package/src/composables/useGetAllTags.js +9 -0
- package/src/composables/useIOSViewportHandling.js +76 -0
- package/src/composables/useNotchHandling.js +306 -0
- package/src/composables/useRowSelection.js +0 -3
- package/src/composables/useTableRender.js +23 -0
- package/src/composables/useTicketPricing.js +16 -0
- package/src/composables/useWindowDimensions.js +21 -0
- package/src/composables/useZoomPrevention.js +96 -0
- package/src/constants/tableLayout.js +14 -0
- package/src/libs/Filter.js +14 -20
- package/src/libs/panzoom.js +1 -5
- package/src/libs/utils/array.js +58 -0
- package/src/{stores/utils.js → libs/utils/dataGeneration.js} +2 -250
- package/src/libs/utils/eventUrl.js +40 -0
- package/src/libs/utils/string.js +3 -0
- package/src/libs/utils/time.js +20 -0
- package/src/libs/utils/validation.js +64 -0
- package/src/main.js +0 -2
- package/src/stores/connection.js +1 -29
- package/src/stores/logger.js +6 -12
- package/src/stores/sampleData.js +1 -2
- package/src/stores/ui.js +80 -71
- package/src/utils/tableHelpers.js +1 -0
- package/src/views/Accounts.vue +19 -38
- package/src/views/Console.vue +74 -253
- package/src/views/Editor.vue +47 -1114
- package/src/views/FilterBuilder.vue +190 -461
- package/src/views/Login.vue +3 -28
- package/src/views/Profiles.vue +17 -32
- package/src/views/Tasks.vue +51 -38
- package/tailwind.config.js +82 -71
- package/workbox-config.cjs +47 -5
- package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2438
- package/exit +0 -209
- package/run +0 -177
- package/src/assets/css/base/color-fallbacks.scss +0 -10
- package/src/assets/img/background.svg.backup +0 -11
- package/src/components/icons/SquareCheck.vue +0 -18
- package/src/components/icons/SquareUncheck.vue +0 -18
- package/src/components/ui/controls/atomic/LoadingButton.vue +0 -45
- package/switch-branch.sh +0 -41
- /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
@click="toggleOpened"
|
|
4
|
+
class="dropdown"
|
|
5
|
+
:class="[props.variant, { 'opened': opened }]"
|
|
6
|
+
ref="dropdownRef"
|
|
7
|
+
role="combobox"
|
|
8
|
+
:aria-expanded="opened"
|
|
9
|
+
:aria-label="props.default"
|
|
10
|
+
tabindex="0"
|
|
11
|
+
@keydown.enter="toggleOpened"
|
|
12
|
+
@keydown.space.prevent="toggleOpened"
|
|
13
|
+
@keydown.escape="opened && ui.setCurrentDropdown('')">
|
|
3
14
|
<span class="dropdown-display">
|
|
4
15
|
<span class="dropdown-value" :class="capitalize ? 'capitalize' : ''">
|
|
5
16
|
{{ currentValue ? currentValue : props.default }}
|
|
@@ -12,6 +23,7 @@
|
|
|
12
23
|
v-if="opened"
|
|
13
24
|
class="dropdown-menu-portal scrollable"
|
|
14
25
|
:style="menuStyle"
|
|
26
|
+
role="listbox"
|
|
15
27
|
@click.stop
|
|
16
28
|
@wheel.stop>
|
|
17
29
|
<button
|
|
@@ -19,11 +31,13 @@
|
|
|
19
31
|
class="dropdown-item"
|
|
20
32
|
:class="i !== 0 ? 'border-t border-dark-650' : ''"
|
|
21
33
|
v-for="(f, i) in !allowDefault ? props.options : ['', ...props.options]"
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
role="option"
|
|
35
|
+
:aria-selected="(f || props.default) === currentValue"
|
|
36
|
+
@click.stop="chose(f)">
|
|
24
37
|
<span class="dropdown-item-text" :class="capitalize ? 'capitalize' : ''">
|
|
25
38
|
{{ f ? f : props.default }}
|
|
26
39
|
</span>
|
|
40
|
+
<CheckmarkIcon v-if="(f || props.default) === currentValue" class="ml-2" />
|
|
27
41
|
</button>
|
|
28
42
|
</div>
|
|
29
43
|
</transition>
|
|
@@ -40,16 +54,47 @@ import { useDropdownPosition } from "@/composables/useDropdownPosition";
|
|
|
40
54
|
const ui = useUIStore();
|
|
41
55
|
|
|
42
56
|
const props = defineProps({
|
|
43
|
-
onClick: {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
onClick: {
|
|
58
|
+
type: Function,
|
|
59
|
+
default: null
|
|
60
|
+
},
|
|
61
|
+
default: {
|
|
62
|
+
type: String,
|
|
63
|
+
default: ''
|
|
64
|
+
},
|
|
65
|
+
value: {
|
|
66
|
+
type: String,
|
|
67
|
+
default: ''
|
|
68
|
+
},
|
|
69
|
+
options: {
|
|
70
|
+
type: Object,
|
|
71
|
+
required: true
|
|
72
|
+
},
|
|
73
|
+
allowDefault: {
|
|
74
|
+
type: Boolean,
|
|
75
|
+
default: false
|
|
76
|
+
},
|
|
77
|
+
rightAmount: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: ''
|
|
80
|
+
},
|
|
81
|
+
topPadding: {
|
|
82
|
+
type: String,
|
|
83
|
+
default: ''
|
|
84
|
+
},
|
|
85
|
+
capitalize: {
|
|
86
|
+
type: Boolean,
|
|
87
|
+
default: false
|
|
88
|
+
},
|
|
89
|
+
includeAdjacentButtons: {
|
|
90
|
+
type: Boolean,
|
|
91
|
+
default: false
|
|
92
|
+
},
|
|
93
|
+
variant: {
|
|
94
|
+
type: String,
|
|
95
|
+
default: 'default',
|
|
96
|
+
validator: (value) => ['default', 'transparent'].includes(value)
|
|
97
|
+
}
|
|
53
98
|
});
|
|
54
99
|
|
|
55
100
|
const currentValue = ref(props.value);
|
|
@@ -66,11 +111,11 @@ const id = Math.random();
|
|
|
66
111
|
const opened = computed(() => ui.currentDropdown === id);
|
|
67
112
|
|
|
68
113
|
const { menuStyle, updatePosition } = useDropdownPosition(dropdownRef, {
|
|
69
|
-
maxHeight:
|
|
114
|
+
maxHeight: 200,
|
|
70
115
|
includeAdjacentButtons: props.includeAdjacentButtons,
|
|
71
116
|
estimateHeight: () => {
|
|
72
117
|
const optionsCount = !props.allowDefault ? props.options?.length || 0 : (props.options?.length || 0) + 1;
|
|
73
|
-
return Math.min(optionsCount * 44,
|
|
118
|
+
return Math.min(optionsCount * 44, 200);
|
|
74
119
|
}
|
|
75
120
|
});
|
|
76
121
|
|
|
@@ -102,39 +147,6 @@ const toggleOpened = () => {
|
|
|
102
147
|
} else {
|
|
103
148
|
ui.setCurrentDropdown(id);
|
|
104
149
|
updatePosition();
|
|
105
|
-
// Set all items to same width only if horizontal scrolling is needed
|
|
106
|
-
setTimeout(() => {
|
|
107
|
-
const portal = document.querySelector('.dropdown-menu-portal');
|
|
108
|
-
const items = portal?.querySelectorAll('.dropdown-item');
|
|
109
|
-
if (items && items.length > 0) {
|
|
110
|
-
let maxWidth = 0;
|
|
111
|
-
// Reset styles first to get accurate measurements
|
|
112
|
-
items.forEach(item => {
|
|
113
|
-
item.style.width = '';
|
|
114
|
-
item.style.minWidth = '';
|
|
115
|
-
});
|
|
116
|
-
portal.style.overflowX = '';
|
|
117
|
-
|
|
118
|
-
// Measure actual content width
|
|
119
|
-
items.forEach(item => {
|
|
120
|
-
const contentWidth = item.scrollWidth;
|
|
121
|
-
maxWidth = Math.max(maxWidth, contentWidth);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// Only enable horizontal scrolling if content is truly wider than the max allowed width
|
|
125
|
-
const maxAllowedWidth = Math.min(400, window.innerWidth * 0.9);
|
|
126
|
-
if (maxWidth > maxAllowedWidth) {
|
|
127
|
-
// Enable horizontal scrolling for long items
|
|
128
|
-
portal.style.overflowX = 'auto';
|
|
129
|
-
items.forEach(item => {
|
|
130
|
-
item.style.minWidth = maxWidth + 'px';
|
|
131
|
-
});
|
|
132
|
-
} else {
|
|
133
|
-
// Normal display - no horizontal scrolling needed
|
|
134
|
-
portal.style.overflowX = 'hidden';
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}, 50);
|
|
138
150
|
}
|
|
139
151
|
};
|
|
140
152
|
|
|
@@ -151,34 +163,41 @@ const chose = (f) => {
|
|
|
151
163
|
|
|
152
164
|
<style scoped>
|
|
153
165
|
.dropdown {
|
|
154
|
-
@apply relative w-full text-white ml-auto rounded-lg ring-0 h-10 bg-
|
|
155
|
-
padding: 0.75rem;
|
|
166
|
+
@apply relative w-full text-white ml-auto rounded-lg ring-0 h-10 border-2 bg-bg-input border-border p-3;
|
|
156
167
|
}
|
|
157
168
|
|
|
158
169
|
.dropdown.transparent {
|
|
159
|
-
@apply bg-transparent border-
|
|
170
|
+
@apply !bg-transparent !border-none !shadow-none !p-0 !h-10;
|
|
160
171
|
}
|
|
161
172
|
|
|
162
173
|
.dropdown.transparent:hover,
|
|
163
174
|
.dropdown.transparent:focus-within,
|
|
164
175
|
.dropdown.transparent.opened {
|
|
165
|
-
@apply border-
|
|
176
|
+
@apply !border-none !bg-transparent !shadow-none !outline-none;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.unified-search-group .dropdown:hover {
|
|
180
|
+
@apply !border-transparent;
|
|
166
181
|
}
|
|
167
182
|
|
|
168
|
-
.dropdown:not(.transparent):hover {
|
|
169
|
-
border-
|
|
183
|
+
.dropdown:not(.transparent):not(.unified-search-group .dropdown):hover {
|
|
184
|
+
@apply border-dark-700;
|
|
170
185
|
}
|
|
171
186
|
|
|
172
|
-
.dropdown:
|
|
173
|
-
.dropdown
|
|
174
|
-
@apply border-
|
|
175
|
-
|
|
187
|
+
.unified-search-group .dropdown:focus-within,
|
|
188
|
+
.unified-search-group .dropdown.opened {
|
|
189
|
+
@apply !border-0 !outline-0 !border-transparent;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.dropdown:not(.transparent):not(.unified-search-group .dropdown):focus-within,
|
|
193
|
+
.dropdown:not(.transparent):not(.unified-search-group .dropdown).opened {
|
|
194
|
+
@apply !border-primary !outline !outline-1 !outline-primary;
|
|
195
|
+
outline-offset: 0 !important;
|
|
176
196
|
}
|
|
177
197
|
|
|
178
198
|
@media (min-width: 768px) {
|
|
179
199
|
.dropdown {
|
|
180
|
-
@apply h-10;
|
|
181
|
-
padding: 0.625rem;
|
|
200
|
+
@apply h-10 py-2.5 px-2.5;
|
|
182
201
|
}
|
|
183
202
|
}
|
|
184
203
|
|
|
@@ -187,44 +206,25 @@ const chose = (f) => {
|
|
|
187
206
|
}
|
|
188
207
|
|
|
189
208
|
.dropdown-value {
|
|
190
|
-
@apply overflow-hidden truncate min-w-0 flex-1
|
|
191
|
-
padding-right: 2rem; /* Extra space to prevent collision with arrow */
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
@media (min-width: 768px) {
|
|
195
|
-
.dropdown-value {
|
|
196
|
-
font-size: 12px;
|
|
197
|
-
}
|
|
209
|
+
@apply overflow-hidden truncate min-w-0 flex-1 text-sm md:text-xs;
|
|
198
210
|
}
|
|
199
211
|
|
|
200
212
|
.dropdown-arrow {
|
|
201
|
-
@apply w-4 h-4 transition-all duration-300;
|
|
202
|
-
position: absolute;
|
|
203
|
-
right: 0.75rem;
|
|
204
|
-
top: 50%;
|
|
205
|
-
transform: translateY(-50%);
|
|
206
|
-
display: flex;
|
|
207
|
-
align-items: center;
|
|
208
|
-
justify-content: center;
|
|
213
|
+
@apply w-4 h-4 transition-all duration-300 flex-shrink-0;
|
|
209
214
|
}
|
|
210
215
|
|
|
211
216
|
.dropdown-menu-portal {
|
|
212
|
-
@apply rounded-xl
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
overflow-x: hidden;
|
|
217
|
+
@apply rounded-xl z-modal border-2 border-dark-650 bg-dark-400 shadow-dropdown;
|
|
218
|
+
min-width: 200px;
|
|
219
|
+
max-width: min(90vw, 600px);
|
|
220
|
+
overflow-x: auto;
|
|
217
221
|
overflow-y: auto;
|
|
218
222
|
overscroll-behavior: contain;
|
|
223
|
+
touch-action: pan-x pan-y;
|
|
219
224
|
-webkit-overflow-scrolling: touch;
|
|
220
|
-
touch-action: pan-y;
|
|
221
225
|
scrollbar-width: thin;
|
|
222
|
-
scrollbar-color:
|
|
223
|
-
|
|
224
|
-
min-width: 200px;
|
|
225
|
-
max-width: min(400px, 90vw);
|
|
226
|
-
display: flex;
|
|
227
|
-
flex-direction: column;
|
|
226
|
+
scrollbar-color: theme('colors.dark.750') theme('colors.dark.350');
|
|
227
|
+
scrollbar-gutter: stable;
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
.dropdown-menu-portal::-webkit-scrollbar {
|
|
@@ -233,48 +233,40 @@ const chose = (f) => {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
.dropdown-menu-portal::-webkit-scrollbar-track {
|
|
236
|
-
|
|
236
|
+
@apply bg-transparent;
|
|
237
|
+
margin: 12px 0;
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
.dropdown-menu-portal::-webkit-scrollbar-thumb {
|
|
240
|
-
|
|
241
|
-
border
|
|
241
|
+
@apply bg-dark-750 rounded-full;
|
|
242
|
+
border: 2px solid transparent;
|
|
243
|
+
background-clip: padding-box;
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
.dropdown-menu-portal::-webkit-scrollbar-thumb:hover {
|
|
245
|
-
|
|
247
|
+
@apply bg-dark-800;
|
|
246
248
|
}
|
|
247
249
|
|
|
248
250
|
.dropdown-item {
|
|
249
|
-
@apply cursor-pointer text-left text-white transition-all duration-200;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
font-weight: 500;
|
|
253
|
-
border-bottom: 1px solid rgba(61, 62, 68, 0.3);
|
|
254
|
-
display: flex !important;
|
|
255
|
-
align-items: center;
|
|
256
|
-
gap: 1rem;
|
|
257
|
-
width: 100%;
|
|
258
|
-
flex-shrink: 0;
|
|
251
|
+
@apply cursor-pointer text-left text-white transition-all duration-200 flex items-center justify-between;
|
|
252
|
+
@apply px-4 py-3 text-sm font-medium border-b border-dark-625/30;
|
|
253
|
+
min-width: 100%;
|
|
259
254
|
}
|
|
260
255
|
|
|
261
256
|
.dropdown-item:last-child {
|
|
262
|
-
border-
|
|
257
|
+
@apply border-b-0;
|
|
263
258
|
}
|
|
264
259
|
|
|
265
260
|
.dropdown-item:hover {
|
|
266
|
-
|
|
267
|
-
color: oklch(1 0 0);
|
|
261
|
+
@apply bg-dark-550 text-white;
|
|
268
262
|
}
|
|
269
263
|
|
|
270
264
|
.dropdown-item:active {
|
|
271
|
-
@apply bg-dark-650;
|
|
272
|
-
box-shadow: inset 0 2px 4px oklch(0 0 0 / 0.4);
|
|
265
|
+
@apply bg-dark-650 shadow-input-inset;
|
|
273
266
|
}
|
|
274
267
|
|
|
275
268
|
.dropdown-item.selected {
|
|
276
|
-
|
|
277
|
-
color: oklch(0.72 0.15 145);
|
|
269
|
+
@apply bg-primary/15 text-primary;
|
|
278
270
|
}
|
|
279
271
|
|
|
280
272
|
.dropdown-item:first-child {
|
|
@@ -286,38 +278,10 @@ const chose = (f) => {
|
|
|
286
278
|
}
|
|
287
279
|
|
|
288
280
|
.dropdown-item-text {
|
|
289
|
-
@apply pr-2
|
|
290
|
-
white-space: nowrap;
|
|
291
|
-
overflow: hidden;
|
|
292
|
-
text-overflow: ellipsis;
|
|
281
|
+
@apply pr-2 whitespace-nowrap;
|
|
293
282
|
}
|
|
294
283
|
|
|
295
284
|
.dropdown-item svg {
|
|
296
|
-
@apply w-4 h-4;
|
|
297
|
-
color: oklch(0.72 0.15 145);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
.dropdown-fade-enter-active {
|
|
301
|
-
@apply transition-all duration-300;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
.dropdown-fade-leave-active {
|
|
305
|
-
@apply transition-all duration-200;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
.dropdown-fade-enter-from {
|
|
309
|
-
@apply opacity-0;
|
|
310
|
-
transform: translateY(-8px) scale(0.95);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.dropdown-fade-leave-to {
|
|
314
|
-
@apply opacity-0;
|
|
315
|
-
transform: translateY(-4px) scale(0.98);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
.dropdown-fade-enter-to,
|
|
319
|
-
.dropdown-fade-leave-from {
|
|
320
|
-
@apply opacity-100;
|
|
321
|
-
transform: translateY(0) scale(1);
|
|
285
|
+
@apply w-4 h-4 text-primary;
|
|
322
286
|
}
|
|
323
287
|
</style>
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
36
|
<div v-if="selectedOptions.length > 0" class="selected-summary">
|
|
37
|
-
<div class="flex items-center justify-between
|
|
37
|
+
<div class="flex-gap-2 items-center justify-between">
|
|
38
38
|
<div class="selected-count">
|
|
39
39
|
<span class="count-badge">
|
|
40
40
|
{{ selectedOptions.length }}
|
|
@@ -71,13 +71,34 @@ import { useClickOutside } from "@/composables/useClickOutside";
|
|
|
71
71
|
const ui = useUIStore();
|
|
72
72
|
|
|
73
73
|
const props = defineProps({
|
|
74
|
-
onSelect: {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
onSelect: {
|
|
75
|
+
type: Function,
|
|
76
|
+
default: null
|
|
77
|
+
},
|
|
78
|
+
default: {
|
|
79
|
+
type: String,
|
|
80
|
+
default: 'Select options...'
|
|
81
|
+
},
|
|
82
|
+
options: {
|
|
83
|
+
type: Array,
|
|
84
|
+
required: true
|
|
85
|
+
},
|
|
86
|
+
rightAmount: {
|
|
87
|
+
type: String,
|
|
88
|
+
default: ''
|
|
89
|
+
},
|
|
90
|
+
topPadding: {
|
|
91
|
+
type: String,
|
|
92
|
+
default: ''
|
|
93
|
+
},
|
|
94
|
+
capitalize: {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
default: false
|
|
97
|
+
},
|
|
98
|
+
includeAdjacentButtons: {
|
|
99
|
+
type: Boolean,
|
|
100
|
+
default: false
|
|
101
|
+
}
|
|
81
102
|
});
|
|
82
103
|
|
|
83
104
|
const selectedOptions = ref([]);
|
|
@@ -132,33 +153,6 @@ const toggleOpened = () => {
|
|
|
132
153
|
} else {
|
|
133
154
|
ui.setCurrentDropdown(id);
|
|
134
155
|
updatePosition();
|
|
135
|
-
// Set all items to same width only if horizontal scrolling is needed
|
|
136
|
-
setTimeout(() => {
|
|
137
|
-
const portal = document.querySelector('.dropdown-menu-portal');
|
|
138
|
-
const items = portal?.querySelectorAll('.dropdown-item');
|
|
139
|
-
if (items && items.length > 0) {
|
|
140
|
-
let maxWidth = 0;
|
|
141
|
-
items.forEach(item => {
|
|
142
|
-
item.style.width = 'max-content';
|
|
143
|
-
maxWidth = Math.max(maxWidth, item.scrollWidth);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Only set explicit widths if content is wider than container
|
|
147
|
-
if (maxWidth > portal.offsetWidth) {
|
|
148
|
-
// Enable horizontal scrolling for long items
|
|
149
|
-
portal.style.overflowX = 'auto';
|
|
150
|
-
items.forEach(item => {
|
|
151
|
-
item.style.width = maxWidth + 'px';
|
|
152
|
-
});
|
|
153
|
-
} else {
|
|
154
|
-
// Disable horizontal scrolling for short items
|
|
155
|
-
portal.style.overflowX = 'hidden';
|
|
156
|
-
items.forEach(item => {
|
|
157
|
-
item.style.width = '100%';
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}, 50);
|
|
162
156
|
}
|
|
163
157
|
};
|
|
164
158
|
|
|
@@ -218,24 +212,22 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
218
212
|
|
|
219
213
|
<style scoped>
|
|
220
214
|
.dropdown {
|
|
221
|
-
@apply relative w-full h-10 text-white ml-auto rounded-lg ring-0;
|
|
222
|
-
|
|
223
|
-
border: 1px solid oklch(0.26 0 0);
|
|
215
|
+
@apply relative w-full h-10 text-white ml-auto rounded-lg ring-0 border-2;
|
|
216
|
+
@apply bg-bg-input border-border;
|
|
224
217
|
padding: 0.75rem;
|
|
225
218
|
}
|
|
226
219
|
|
|
227
220
|
.dropdown:hover {
|
|
228
|
-
border-
|
|
221
|
+
@apply border-dark-650;
|
|
229
222
|
}
|
|
230
223
|
|
|
231
224
|
.dropdown:focus-within,
|
|
232
225
|
.dropdown.opened {
|
|
233
|
-
border-
|
|
234
|
-
outline:
|
|
235
|
-
outline-offset: 0;
|
|
226
|
+
@apply border-primary outline outline-1 outline-primary;
|
|
227
|
+
outline-offset: 0 !important;
|
|
236
228
|
}
|
|
237
229
|
|
|
238
|
-
@
|
|
230
|
+
@screen modal {
|
|
239
231
|
.dropdown {
|
|
240
232
|
@apply h-10;
|
|
241
233
|
padding: 0.625rem;
|
|
@@ -251,40 +243,30 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
251
243
|
}
|
|
252
244
|
|
|
253
245
|
.dropdown-counter {
|
|
254
|
-
@apply flex items-center gap-2 absolute;
|
|
255
|
-
right: 0.75rem;
|
|
256
|
-
top: 50%;
|
|
257
|
-
transform: translateY(-50%);
|
|
246
|
+
@apply flex items-center gap-2 absolute right-2;
|
|
258
247
|
}
|
|
259
248
|
|
|
260
249
|
.counter-badge {
|
|
261
|
-
@apply text-white text-xs font-semibold px-1.5 py-0.5 rounded-full text-center min-w-
|
|
262
|
-
|
|
250
|
+
@apply text-white text-xs font-semibold px-1.5 py-0.5 rounded-full text-center min-w-4.5 shadow-sm;
|
|
251
|
+
@apply bg-primary;
|
|
263
252
|
}
|
|
264
253
|
|
|
265
254
|
.dropdown-arrow {
|
|
266
255
|
@apply min-w-4 min-h-4 transition-all duration-300;
|
|
267
|
-
display: flex;
|
|
268
|
-
align-items: center;
|
|
269
|
-
justify-content: center;
|
|
270
256
|
}
|
|
271
257
|
|
|
272
258
|
.dropdown-menu-portal {
|
|
273
|
-
@apply rounded-xl shadow-
|
|
274
|
-
background: linear-gradient(135deg, oklch(0.18 0 0) 0%, oklch(0.20 0 0) 100%);
|
|
275
|
-
border: 1px solid oklch(0.26 0 0);
|
|
276
|
-
backdrop-filter: blur(12px);
|
|
277
|
-
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2),
|
|
278
|
-
0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
279
|
-
overflow-x: auto !important;
|
|
280
|
-
overflow-y: auto !important;
|
|
281
|
-
overscroll-behavior: contain !important;
|
|
282
|
-
touch-action: pan-x pan-y !important;
|
|
283
|
-
-webkit-overflow-scrolling: touch !important;
|
|
284
|
-
scrollbar-width: thin;
|
|
285
|
-
scrollbar-color: oklch(0.35 0 0) oklch(0.19 0 0);
|
|
259
|
+
@apply rounded-xl z-modal border-2 border-dark-650 bg-dark-400 shadow-dropdown;
|
|
286
260
|
min-width: 200px;
|
|
287
|
-
max-width: 90vw;
|
|
261
|
+
max-width: min(90vw, 600px);
|
|
262
|
+
overflow-x: auto;
|
|
263
|
+
overflow-y: auto;
|
|
264
|
+
overscroll-behavior: contain;
|
|
265
|
+
touch-action: pan-x pan-y;
|
|
266
|
+
-webkit-overflow-scrolling: touch;
|
|
267
|
+
scrollbar-width: thin;
|
|
268
|
+
scrollbar-color: theme('colors.dark.750') theme('colors.dark.350');
|
|
269
|
+
scrollbar-gutter: stable;
|
|
288
270
|
}
|
|
289
271
|
|
|
290
272
|
.dropdown-menu-portal::-webkit-scrollbar {
|
|
@@ -293,31 +275,37 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
293
275
|
}
|
|
294
276
|
|
|
295
277
|
.dropdown-menu-portal::-webkit-scrollbar-track {
|
|
296
|
-
|
|
278
|
+
@apply bg-transparent;
|
|
279
|
+
margin: 12px 0;
|
|
297
280
|
}
|
|
298
281
|
|
|
299
282
|
.dropdown-menu-portal::-webkit-scrollbar-thumb {
|
|
300
|
-
|
|
301
|
-
border
|
|
283
|
+
@apply bg-dark-750 rounded-full;
|
|
284
|
+
border: 2px solid transparent;
|
|
285
|
+
background-clip: padding-box;
|
|
302
286
|
}
|
|
303
287
|
|
|
304
288
|
.dropdown-menu-portal::-webkit-scrollbar-thumb:hover {
|
|
305
|
-
|
|
289
|
+
@apply bg-dark-800;
|
|
306
290
|
}
|
|
307
291
|
|
|
308
292
|
.dropdown-menu-portal.multi .option-list {
|
|
309
293
|
@apply max-h-48 overflow-y-auto;
|
|
310
|
-
overscroll-behavior: contain
|
|
311
|
-
|
|
312
|
-
-
|
|
294
|
+
overscroll-behavior: contain;
|
|
295
|
+
-webkit-overflow-scrolling: touch;
|
|
296
|
+
scrollbar-width: none;
|
|
297
|
+
-ms-overflow-style: none;
|
|
298
|
+
touch-action: pan-y;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.dropdown-menu-portal.multi .option-list::-webkit-scrollbar {
|
|
302
|
+
display: none;
|
|
313
303
|
}
|
|
314
304
|
|
|
315
305
|
.dropdown-item {
|
|
316
306
|
@apply cursor-pointer text-left w-full text-white transition-all duration-200 flex justify-between items-center;
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
font-weight: 500;
|
|
320
|
-
border-bottom: 1px solid rgba(61, 62, 68, 0.3);
|
|
307
|
+
@apply px-4 py-3 text-sm font-medium;
|
|
308
|
+
border-bottom: 1px solid theme('colors.dark.500 / 0.3');
|
|
321
309
|
}
|
|
322
310
|
|
|
323
311
|
.dropdown-item:last-child {
|
|
@@ -325,13 +313,11 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
325
313
|
}
|
|
326
314
|
|
|
327
315
|
.dropdown-item:hover {
|
|
328
|
-
@apply bg-dark-
|
|
329
|
-
color: oklch(1 0 0);
|
|
316
|
+
@apply bg-dark-550 text-white;
|
|
330
317
|
}
|
|
331
318
|
|
|
332
319
|
.dropdown-item:active {
|
|
333
|
-
@apply bg-dark-650;
|
|
334
|
-
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
|
|
320
|
+
@apply bg-dark-650 shadow-input-inset;
|
|
335
321
|
}
|
|
336
322
|
|
|
337
323
|
.dropdown-item:first-child {
|
|
@@ -349,13 +335,12 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
349
335
|
|
|
350
336
|
/* Checkmark styling */
|
|
351
337
|
.dropdown-item svg {
|
|
352
|
-
@apply w-4 h-4;
|
|
353
|
-
color: oklch(0.72 0.15 145);
|
|
338
|
+
@apply w-4 h-4 text-primary;
|
|
354
339
|
}
|
|
355
340
|
|
|
356
341
|
.selected-summary {
|
|
357
342
|
@apply border-t bg-dark-550 w-full px-4 py-3;
|
|
358
|
-
border-top: 1px solid
|
|
343
|
+
border-top: 1px solid theme('colors.dark.500 / 0.5');
|
|
359
344
|
}
|
|
360
345
|
|
|
361
346
|
.selected-count {
|
|
@@ -364,7 +349,7 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
364
349
|
|
|
365
350
|
.count-badge {
|
|
366
351
|
@apply text-white text-xs font-semibold px-2 py-1 rounded-full shadow-sm;
|
|
367
|
-
|
|
352
|
+
@apply bg-primary;
|
|
368
353
|
}
|
|
369
354
|
|
|
370
355
|
.count-label {
|
|
@@ -373,53 +358,20 @@ if (props.default && !selectedOptions.value.includes(props.default)) {
|
|
|
373
358
|
|
|
374
359
|
.clear-button {
|
|
375
360
|
@apply text-xs text-white transition-all duration-200 font-medium px-2 py-1.5 rounded-lg shadow-sm flex items-center justify-center;
|
|
376
|
-
|
|
361
|
+
@apply bg-red-400 hover:bg-red-300;
|
|
377
362
|
min-width: 32px;
|
|
378
363
|
}
|
|
379
364
|
|
|
380
|
-
.clear-button:hover {
|
|
381
|
-
background: oklch(0.60 0.22 25);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
365
|
.done-button {
|
|
385
366
|
@apply text-xs text-white transition-all duration-200 font-medium px-2 py-1.5 rounded-lg shadow-sm flex items-center justify-center;
|
|
386
|
-
|
|
367
|
+
@apply bg-primary hover:bg-green-400;
|
|
387
368
|
min-width: 32px;
|
|
388
369
|
}
|
|
389
370
|
|
|
390
|
-
.done-button:hover {
|
|
391
|
-
background: oklch(0.68 0.15 145);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
371
|
@media (min-width: 640px) {
|
|
395
372
|
.clear-button,
|
|
396
373
|
.done-button {
|
|
397
374
|
padding: 0.375rem 0.75rem;
|
|
398
375
|
}
|
|
399
376
|
}
|
|
400
|
-
|
|
401
|
-
/* Transition animations */
|
|
402
|
-
.dropdown-fade-enter-active {
|
|
403
|
-
@apply transition-all duration-300;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
.dropdown-fade-leave-active {
|
|
407
|
-
@apply transition-all duration-200;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
.dropdown-fade-enter-from {
|
|
411
|
-
@apply opacity-0;
|
|
412
|
-
transform: translateY(-8px) scale(0.95);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
.dropdown-fade-leave-to {
|
|
416
|
-
@apply opacity-0;
|
|
417
|
-
transform: translateY(-4px) scale(0.98);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
.dropdown-fade-enter-to,
|
|
421
|
-
.dropdown-fade-leave-from {
|
|
422
|
-
@apply opacity-100;
|
|
423
|
-
transform: translateY(0) scale(1);
|
|
424
|
-
}
|
|
425
377
|
</style>
|