@necrolab/dashboard 0.4.48 → 0.4.50
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/.claude/settings.local.json +2 -1
- package/.prettierrc +12 -1
- package/exit +209 -0
- package/index.html +1 -1
- package/package.json +1 -1
- package/public/manifest.json +8 -3
- package/src/assets/css/_input.scss +104 -111
- package/src/assets/css/_utilities.scss +441 -0
- package/src/assets/css/main.scss +228 -154
- package/src/components/Auth/LoginForm.vue +49 -6
- package/src/components/Editors/Account/Account.vue +156 -146
- package/src/components/Editors/Account/AccountCreator.vue +1 -1
- package/src/components/Editors/Account/AccountView.vue +13 -13
- package/src/components/Editors/Account/CreateAccount.vue +25 -16
- package/src/components/Editors/Profile/CreateProfile.vue +1 -1
- package/src/components/Editors/Profile/Profile.vue +1 -1
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +83 -19
- package/src/components/Editors/Profile/ProfileView.vue +11 -11
- package/src/components/Tasks/CreateTaskAXS.vue +3 -3
- package/src/components/Tasks/CreateTaskTM.vue +7 -35
- package/src/components/Tasks/QuickSettings.vue +112 -9
- package/src/components/Tasks/Stats.vue +29 -26
- package/src/components/Tasks/Task.vue +499 -365
- package/src/components/Tasks/TaskView.vue +187 -127
- package/src/components/icons/Sandclock.vue +2 -2
- package/src/components/icons/Stadium.vue +1 -1
- package/src/components/ui/Modal.vue +37 -35
- package/src/components/ui/controls/CountryChooser.vue +200 -62
- package/src/components/ui/controls/atomic/Dropdown.vue +177 -91
- package/src/components/ui/controls/atomic/MultiDropdown.vue +247 -168
- package/src/composables/useClickOutside.js +21 -0
- package/src/composables/useDropdownPosition.js +174 -0
- package/src/stores/sampleData.js +4 -2
- package/src/stores/ui.js +8 -6
- package/src/views/Accounts.vue +12 -19
- package/src/views/Console.vue +34 -47
- package/src/views/Editor.vue +1194 -730
- package/src/views/Login.vue +65 -119
- package/src/views/Profiles.vue +2 -2
- package/src/views/Tasks.vue +170 -137
- package/static/offline.html +192 -50
- package/tailwind.config.js +47 -21
|
@@ -1,87 +1,225 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<div class="snap-start pt-2 text-sm font-bold text-center">TM</div>
|
|
15
|
-
<div
|
|
16
|
-
v-bind:key="country.id"
|
|
17
|
-
v-for="(country, i) in countries.TM"
|
|
18
|
-
:class="`cursor-pointer snap-start w-12 ${i === 0 ? 'pt-2' : 'my-2'}`"
|
|
19
|
-
@click="ui.setCurrentCountry(country, true, 'TM')"
|
|
20
|
-
>
|
|
21
|
-
<div class="flex justify-between smooth-hover">
|
|
22
|
-
<span class="text-sm">{{ country.siteId.split("_")[1] }} </span>
|
|
23
|
-
<img class="w-5" :src="`/flags/${country.siteId.split('_')[1].toLowerCase()}.svg`" />
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="snap-start pt-2 text-sm font-bold text-center">AXS</div>
|
|
27
|
-
<div
|
|
28
|
-
v-bind:key="country.id"
|
|
29
|
-
v-for="(country, i) in countries.AXS"
|
|
30
|
-
:class="`cursor-pointer snap-start w-12 ${i === 0 ? 'pt-2' : 'my-2'}`"
|
|
31
|
-
@click="ui.setCurrentCountry(country, true, 'AXS')"
|
|
32
|
-
>
|
|
33
|
-
<div class="flex gap-3 justify-between smooth-hover">
|
|
34
|
-
<span class="text-sm">{{ country.siteId.split("_")[1] }} </span>
|
|
35
|
-
<img class="w-5" :src="`/flags/${country.siteId.split('_')[1].toLowerCase()}.svg`" />
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</transition>
|
|
2
|
+
<div>
|
|
3
|
+
<div
|
|
4
|
+
class="dropdown input-default p-4 w-16 bg-dark-550 small-dropdown"
|
|
5
|
+
ref="dropdownRef"
|
|
6
|
+
@click="toggleOpen"
|
|
7
|
+
>
|
|
8
|
+
<span class="flex justify-between items-center z-50 text-white">
|
|
9
|
+
<div class="flex gap-3 justify-center">
|
|
10
|
+
<img
|
|
11
|
+
class="w-5"
|
|
12
|
+
:src="`/flags/${ui.currentCountry.siteId.split('_')[1].toLowerCase()}.svg`"
|
|
13
|
+
/>
|
|
40
14
|
</div>
|
|
15
|
+
</span>
|
|
16
|
+
<Teleport to="body">
|
|
17
|
+
<transition name="fade">
|
|
18
|
+
<div
|
|
19
|
+
v-if="open"
|
|
20
|
+
class="dropdown-content-portal special-dropdown"
|
|
21
|
+
:style="menuStyle"
|
|
22
|
+
@click.stop
|
|
23
|
+
@wheel.stop
|
|
24
|
+
@touchmove.stop
|
|
25
|
+
>
|
|
26
|
+
<div class="header-item">TM</div>
|
|
27
|
+
<div
|
|
28
|
+
v-bind:key="country.id"
|
|
29
|
+
v-for="country in countries.TM"
|
|
30
|
+
class="country-item"
|
|
31
|
+
@click="selectCountry(country, 'TM')"
|
|
32
|
+
>
|
|
33
|
+
<div class="flex items-center justify-center gap-2">
|
|
34
|
+
<span class="text-xs font-medium">{{
|
|
35
|
+
country.siteId.split("_")[1]
|
|
36
|
+
}}</span>
|
|
37
|
+
<img
|
|
38
|
+
class="w-5 h-4"
|
|
39
|
+
:src="`/flags/${country.siteId.split('_')[1].toLowerCase()}.svg`"
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="header-item">AXS</div>
|
|
44
|
+
<div
|
|
45
|
+
v-bind:key="country.id"
|
|
46
|
+
v-for="country in countries.AXS"
|
|
47
|
+
class="country-item"
|
|
48
|
+
@click="selectCountry(country, 'AXS')"
|
|
49
|
+
>
|
|
50
|
+
<div class="flex items-center justify-center gap-2">
|
|
51
|
+
<span class="text-xs font-medium">{{
|
|
52
|
+
country.siteId.split("_")[1]
|
|
53
|
+
}}</span>
|
|
54
|
+
<img
|
|
55
|
+
class="w-5 h-4"
|
|
56
|
+
:src="`/flags/${country.siteId.split('_')[1].toLowerCase()}.svg`"
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</transition>
|
|
62
|
+
</Teleport>
|
|
41
63
|
</div>
|
|
64
|
+
</div>
|
|
42
65
|
</template>
|
|
43
66
|
|
|
44
67
|
<script setup>
|
|
45
68
|
import { ref } from "vue";
|
|
46
69
|
import { useUIStore } from "@/stores/ui";
|
|
47
70
|
import { countries } from "@/stores/countries";
|
|
71
|
+
import { useDropdownPosition } from "@/composables/useDropdownPosition";
|
|
72
|
+
import { useClickOutside } from "@/composables/useClickOutside";
|
|
73
|
+
|
|
48
74
|
const ui = useUIStore();
|
|
49
75
|
const open = ref(false);
|
|
76
|
+
const dropdownRef = ref(null);
|
|
77
|
+
|
|
78
|
+
// Use composables for positioning and click outside
|
|
79
|
+
const { menuStyle, updatePosition } = useDropdownPosition(dropdownRef, {
|
|
80
|
+
offset: { x: -26, y: 4 },
|
|
81
|
+
minWidth: 100,
|
|
82
|
+
maxHeight: 208,
|
|
83
|
+
estimateHeight: () => {
|
|
84
|
+
const tmCount = countries.TM?.length || 0;
|
|
85
|
+
const axsCount = countries.AXS?.length || 0;
|
|
86
|
+
const totalItems = tmCount + axsCount + 2; // +2 for headers
|
|
87
|
+
return Math.min(totalItems * 32, 208);
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
useClickOutside(dropdownRef, () => {
|
|
92
|
+
if (open.value) {
|
|
93
|
+
open.value = false;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const toggleOpen = () => {
|
|
98
|
+
open.value = !open.value;
|
|
99
|
+
if (open.value) {
|
|
100
|
+
updatePosition();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const selectCountry = (country, module) => {
|
|
105
|
+
ui.setCurrentCountry(country, true, module);
|
|
106
|
+
open.value = false;
|
|
107
|
+
};
|
|
50
108
|
</script>
|
|
51
109
|
|
|
52
110
|
<style scoped>
|
|
53
111
|
.special-dropdown {
|
|
54
|
-
|
|
112
|
+
@apply min-w-20;
|
|
55
113
|
}
|
|
56
114
|
|
|
57
115
|
.small-dropdown {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
116
|
+
background-clip: border-box !important;
|
|
117
|
+
border-radius: 100% !important;
|
|
118
|
+
padding: 0;
|
|
119
|
+
width: 3em !important;
|
|
120
|
+
height: 3em !important;
|
|
121
|
+
display: flex;
|
|
122
|
+
justify-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.dropdown-content-portal {
|
|
127
|
+
@apply bg-dark-400 border border-dark-650 rounded-lg shadow-2xl z-50;
|
|
128
|
+
padding: 0.5rem;
|
|
129
|
+
max-height: 208px !important;
|
|
130
|
+
overflow-y: auto !important;
|
|
131
|
+
overscroll-behavior: contain !important;
|
|
132
|
+
touch-action: pan-y !important;
|
|
133
|
+
-webkit-overflow-scrolling: touch !important;
|
|
134
|
+
scrollbar-width: none;
|
|
135
|
+
-ms-overflow-style: none;
|
|
136
|
+
min-width: 100px;
|
|
137
|
+
width: 100px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.dropdown-content-portal::-webkit-scrollbar {
|
|
141
|
+
display: none;
|
|
66
142
|
}
|
|
67
143
|
|
|
68
|
-
.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
144
|
+
.header-item {
|
|
145
|
+
text-align: center !important;
|
|
146
|
+
font-size: 0.75rem;
|
|
147
|
+
font-weight: 700;
|
|
148
|
+
color: white;
|
|
149
|
+
padding: 8px 4px;
|
|
150
|
+
cursor: default;
|
|
151
|
+
pointer-events: none;
|
|
152
|
+
margin: 4px 2px;
|
|
153
|
+
position: relative;
|
|
154
|
+
background: linear-gradient(
|
|
155
|
+
135deg,
|
|
156
|
+
rgba(255, 255, 255, 0.08) 0%,
|
|
157
|
+
rgba(255, 255, 255, 0.04) 100%
|
|
158
|
+
);
|
|
159
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
160
|
+
border-radius: 6px;
|
|
161
|
+
letter-spacing: 0.5px;
|
|
162
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
163
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
164
|
+
display: flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
justify-content: center;
|
|
76
167
|
}
|
|
77
168
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
169
|
+
.header-item:first-child {
|
|
170
|
+
margin-top: 2px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.header-item::before {
|
|
174
|
+
content: "";
|
|
175
|
+
position: absolute;
|
|
176
|
+
top: 0;
|
|
177
|
+
left: 0;
|
|
178
|
+
right: 0;
|
|
179
|
+
height: 1px;
|
|
180
|
+
background: linear-gradient(
|
|
181
|
+
90deg,
|
|
182
|
+
transparent 0%,
|
|
183
|
+
rgba(255, 255, 255, 0.2) 50%,
|
|
184
|
+
transparent 100%
|
|
185
|
+
);
|
|
186
|
+
border-radius: 6px 6px 0 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.country-item {
|
|
190
|
+
padding: 8px 4px;
|
|
191
|
+
font-size: 0.875rem;
|
|
192
|
+
color: white;
|
|
193
|
+
cursor: pointer;
|
|
194
|
+
border-radius: 6px;
|
|
195
|
+
margin: 1px 2px;
|
|
196
|
+
transition: all 0.15s ease;
|
|
197
|
+
display: flex;
|
|
198
|
+
align-items: center;
|
|
199
|
+
justify-content: center;
|
|
200
|
+
min-height: 32px;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.country-item .flex {
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
justify-content: center;
|
|
207
|
+
gap: 6px;
|
|
208
|
+
width: 100%;
|
|
209
|
+
flex-wrap: nowrap;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.country-item .flex span {
|
|
213
|
+
font-size: 0.75rem;
|
|
214
|
+
font-weight: 500;
|
|
215
|
+
white-space: nowrap;
|
|
216
|
+
flex-shrink: 0;
|
|
217
|
+
text-align: center;
|
|
218
|
+
}
|
|
82
219
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
220
|
+
.country-item .flex img {
|
|
221
|
+
width: 18px;
|
|
222
|
+
height: 14px;
|
|
223
|
+
flex-shrink: 0;
|
|
86
224
|
}
|
|
87
225
|
</style>
|
|
@@ -1,164 +1,250 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<div @click="toggleOpened" class="dropdown" :class="props.variant" ref="dropdownRef">
|
|
3
|
+
<span class="dropdown-display">
|
|
4
|
+
<span class="dropdown-value" :class="capitalize ? 'capitalize' : ''">
|
|
5
|
+
{{ currentValue ? currentValue : props.default }}
|
|
6
|
+
</span>
|
|
7
|
+
<DownIcon class="dropdown-arrow" :class="opened ? 'rotate-180' : ''" />
|
|
8
|
+
</span>
|
|
9
|
+
<Teleport to="body">
|
|
10
|
+
<transition name="dropdown-fade">
|
|
11
|
+
<div
|
|
12
|
+
v-if="opened"
|
|
13
|
+
class="dropdown-menu-portal scrollable"
|
|
14
|
+
:style="menuStyle"
|
|
15
|
+
@click.stop
|
|
16
|
+
@wheel.stop
|
|
17
|
+
@touchmove.stop
|
|
18
|
+
>
|
|
19
|
+
<button
|
|
20
|
+
v-bind:key="f"
|
|
21
|
+
class="dropdown-item"
|
|
22
|
+
:class="i !== 0 ? 'border-t border-dark-650' : ''"
|
|
23
|
+
v-for="(f, i) in !allowDefault ? props.options : ['', ...props.options]"
|
|
24
|
+
@click.stop="chose(f)"
|
|
25
|
+
>
|
|
26
|
+
<span class="dropdown-item-text" :class="capitalize ? 'capitalize' : ''">
|
|
27
|
+
{{ f ? f : props.default }}
|
|
6
28
|
</span>
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@click.stop
|
|
14
|
-
@wheel.stop
|
|
15
|
-
@touchmove.stop
|
|
16
|
-
>
|
|
17
|
-
<button
|
|
18
|
-
v-bind:key="f"
|
|
19
|
-
class="dropdown-item"
|
|
20
|
-
:class="i !== 0 ? 'border-t border-dark-650' : ''"
|
|
21
|
-
v-for="(f, i) in !allowDefault ? props.options : ['', ...props.options]"
|
|
22
|
-
@click.stop="chose(f)"
|
|
23
|
-
>
|
|
24
|
-
<span class="dropdown-item-text" :class="capitalize ? 'capitalize' : ''">
|
|
25
|
-
{{f ? f : props.default}}
|
|
26
|
-
</span>
|
|
27
|
-
<CheckmarkIcon v-if="(f || props.default) === currentValue" class="ml-2" />
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
</transition>
|
|
31
|
-
</div>
|
|
29
|
+
<CheckmarkIcon v-if="(f || props.default) === currentValue" class="ml-2" />
|
|
30
|
+
</button>
|
|
31
|
+
</div>
|
|
32
|
+
</transition>
|
|
33
|
+
</Teleport>
|
|
34
|
+
</div>
|
|
32
35
|
</template>
|
|
33
36
|
|
|
34
37
|
<script setup>
|
|
35
38
|
import { ref, computed, watch } from "vue";
|
|
36
39
|
import { DownIcon, CheckmarkIcon } from "@/components/icons";
|
|
37
40
|
import { useUIStore } from "@/stores/ui";
|
|
41
|
+
import { useDropdownPosition } from "@/composables/useDropdownPosition";
|
|
42
|
+
import { useClickOutside } from "@/composables/useClickOutside";
|
|
43
|
+
|
|
38
44
|
const ui = useUIStore();
|
|
39
45
|
|
|
40
46
|
const props = defineProps({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
onClick: { type: Function },
|
|
48
|
+
default: { type: String },
|
|
49
|
+
value: { type: String },
|
|
50
|
+
options: { type: Object },
|
|
51
|
+
allowDefault: { type: Boolean },
|
|
52
|
+
rightAmount: { type: String },
|
|
53
|
+
topPadding: { type: String },
|
|
54
|
+
capitalize: { type: Boolean },
|
|
55
|
+
includeAdjacentButtons: { type: Boolean, default: false },
|
|
56
|
+
variant: { type: String, default: 'default' }
|
|
49
57
|
});
|
|
50
58
|
|
|
51
59
|
const currentValue = ref(props.value);
|
|
60
|
+
const dropdownRef = ref(null);
|
|
52
61
|
|
|
53
62
|
// Watch for changes to the value prop and update currentValue
|
|
54
|
-
watch(
|
|
63
|
+
watch(
|
|
64
|
+
() => props.value,
|
|
65
|
+
(newValue) => {
|
|
55
66
|
currentValue.value = newValue;
|
|
56
|
-
}
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
57
70
|
const id = Math.random();
|
|
58
71
|
const opened = computed(() => ui.currentDropdown === id);
|
|
59
72
|
|
|
73
|
+
// Use composables for positioning and click outside
|
|
74
|
+
const { menuStyle, updatePosition } = useDropdownPosition(dropdownRef, {
|
|
75
|
+
maxHeight: 200,
|
|
76
|
+
includeAdjacentButtons: props.includeAdjacentButtons,
|
|
77
|
+
estimateHeight: () => {
|
|
78
|
+
const optionsCount = !props.allowDefault
|
|
79
|
+
? props.options?.length || 0
|
|
80
|
+
: (props.options?.length || 0) + 1;
|
|
81
|
+
return Math.min(optionsCount * 44, 200);
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
useClickOutside(dropdownRef, () => {
|
|
86
|
+
if (opened.value) {
|
|
87
|
+
ui.setCurrentDropdown("");
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
60
91
|
const toggleOpened = () => {
|
|
61
|
-
|
|
62
|
-
|
|
92
|
+
if (opened.value) {
|
|
93
|
+
ui.setCurrentDropdown("");
|
|
94
|
+
} else {
|
|
95
|
+
ui.setCurrentDropdown(id);
|
|
96
|
+
updatePosition();
|
|
97
|
+
}
|
|
63
98
|
};
|
|
64
99
|
|
|
65
100
|
const chose = (f) => {
|
|
66
|
-
|
|
67
|
-
|
|
101
|
+
ui.logger.Info("Dropdown: chosen", f, "hiding...");
|
|
102
|
+
currentValue.value = f;
|
|
103
|
+
ui.setCurrentDropdown("");
|
|
104
|
+
if (props.onClick) props.onClick(f);
|
|
105
|
+
// Ensure dropdown closes
|
|
106
|
+
setTimeout(() => {
|
|
68
107
|
ui.setCurrentDropdown("");
|
|
69
|
-
|
|
70
|
-
// Ensure dropdown closes
|
|
71
|
-
setTimeout(() => {
|
|
72
|
-
ui.setCurrentDropdown("");
|
|
73
|
-
}, 50);
|
|
108
|
+
}, 50);
|
|
74
109
|
};
|
|
75
|
-
|
|
76
110
|
</script>
|
|
77
111
|
|
|
78
112
|
<style scoped>
|
|
79
113
|
.dropdown {
|
|
80
|
-
|
|
114
|
+
@apply relative w-full text-white ml-auto rounded-lg ring-0;
|
|
115
|
+
background: linear-gradient(135deg, #2a2b30 0%, #2e2f34 100%);
|
|
116
|
+
border: 1px solid #3d3e44;
|
|
117
|
+
padding: 0.75rem;
|
|
118
|
+
height: 3.45em;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.dropdown.transparent {
|
|
122
|
+
background: transparent !important;
|
|
123
|
+
border: none !important;
|
|
124
|
+
box-shadow: none !important;
|
|
125
|
+
padding: 0 !important;
|
|
126
|
+
height: 40px !important;
|
|
81
127
|
}
|
|
82
128
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
129
|
+
.dropdown.transparent:hover,
|
|
130
|
+
.dropdown.transparent:focus-within {
|
|
131
|
+
border: none !important;
|
|
132
|
+
background: transparent !important;
|
|
133
|
+
box-shadow: none !important;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.dropdown:not(.transparent):hover {
|
|
137
|
+
@apply border-dark-400;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.dropdown:not(.transparent):focus-within {
|
|
141
|
+
@apply border-blue-500;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@media (min-width: 768px) {
|
|
145
|
+
.dropdown {
|
|
146
|
+
height: 40px;
|
|
147
|
+
padding: 0.625rem;
|
|
148
|
+
}
|
|
87
149
|
}
|
|
88
150
|
|
|
89
151
|
.dropdown-display {
|
|
90
|
-
|
|
152
|
+
@apply flex items-center justify-between z-10 w-full h-full;
|
|
91
153
|
}
|
|
92
154
|
|
|
93
155
|
.dropdown-value {
|
|
94
|
-
|
|
156
|
+
@apply overflow-hidden truncate min-w-0 flex-1 mr-2 text-sm;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@media (min-width: 768px) {
|
|
160
|
+
.dropdown-value {
|
|
161
|
+
font-size: 12px;
|
|
162
|
+
}
|
|
95
163
|
}
|
|
96
164
|
|
|
97
165
|
.dropdown-arrow {
|
|
98
|
-
|
|
166
|
+
@apply w-4 h-4 transition-all duration-300 flex-shrink-0;
|
|
99
167
|
}
|
|
100
168
|
|
|
101
|
-
.dropdown-menu {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
169
|
+
.dropdown-menu-portal {
|
|
170
|
+
@apply rounded-xl shadow-2xl overflow-hidden;
|
|
171
|
+
background: linear-gradient(135deg, #2a2b30 0%, #2e2f34 100%);
|
|
172
|
+
border: 1px solid #3d3e44;
|
|
173
|
+
backdrop-filter: blur(12px);
|
|
174
|
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2),
|
|
175
|
+
0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
176
|
+
overflow-y: auto !important;
|
|
177
|
+
overscroll-behavior: contain !important;
|
|
178
|
+
touch-action: pan-y !important;
|
|
179
|
+
-webkit-overflow-scrolling: touch !important;
|
|
180
|
+
scrollbar-width: none;
|
|
181
|
+
-ms-overflow-style: none;
|
|
114
182
|
}
|
|
115
183
|
|
|
116
|
-
.dropdown-menu::-webkit-scrollbar {
|
|
117
|
-
|
|
184
|
+
.dropdown-menu-portal::-webkit-scrollbar {
|
|
185
|
+
display: none;
|
|
118
186
|
}
|
|
119
187
|
|
|
120
|
-
.dropdown-
|
|
121
|
-
|
|
188
|
+
.dropdown-item {
|
|
189
|
+
@apply cursor-pointer text-left w-full text-white transition-all duration-200 flex items-center justify-between;
|
|
190
|
+
padding: 0.75rem 1rem;
|
|
191
|
+
font-size: 0.875rem;
|
|
192
|
+
font-weight: 500;
|
|
193
|
+
border-bottom: 1px solid rgba(61, 62, 68, 0.3);
|
|
122
194
|
}
|
|
123
195
|
|
|
124
|
-
.dropdown-
|
|
125
|
-
|
|
126
|
-
border-radius: 4px;
|
|
196
|
+
.dropdown-item:last-child {
|
|
197
|
+
border-bottom: none;
|
|
127
198
|
}
|
|
128
199
|
|
|
129
|
-
.dropdown-
|
|
130
|
-
|
|
200
|
+
.dropdown-item:hover {
|
|
201
|
+
@apply bg-dark-600;
|
|
202
|
+
color: #ffffff;
|
|
131
203
|
}
|
|
132
204
|
|
|
133
|
-
.dropdown-item {
|
|
134
|
-
|
|
205
|
+
.dropdown-item:active {
|
|
206
|
+
@apply bg-dark-650;
|
|
207
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
|
|
135
208
|
}
|
|
136
209
|
|
|
137
210
|
.dropdown-item:first-child {
|
|
138
|
-
|
|
211
|
+
@apply rounded-t-xl;
|
|
139
212
|
}
|
|
140
213
|
|
|
141
214
|
.dropdown-item:last-child {
|
|
142
|
-
|
|
215
|
+
@apply rounded-b-xl;
|
|
143
216
|
}
|
|
144
217
|
|
|
145
218
|
.dropdown-item-text {
|
|
146
|
-
|
|
219
|
+
@apply overflow-hidden truncate pr-2;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.dropdown-item svg {
|
|
223
|
+
@apply w-4 h-4;
|
|
224
|
+
color: #10b981;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.dropdown-fade-enter-active {
|
|
228
|
+
@apply transition-all duration-300;
|
|
147
229
|
}
|
|
148
230
|
|
|
149
|
-
/* Transition animations */
|
|
150
|
-
.dropdown-fade-enter-active,
|
|
151
231
|
.dropdown-fade-leave-active {
|
|
152
|
-
|
|
232
|
+
@apply transition-all duration-200;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.dropdown-fade-enter-from {
|
|
236
|
+
@apply opacity-0;
|
|
237
|
+
transform: translateY(-8px) scale(0.95);
|
|
153
238
|
}
|
|
154
239
|
|
|
155
|
-
.dropdown-fade-enter-from,
|
|
156
240
|
.dropdown-fade-leave-to {
|
|
157
|
-
|
|
241
|
+
@apply opacity-0;
|
|
242
|
+
transform: translateY(-4px) scale(0.98);
|
|
158
243
|
}
|
|
159
244
|
|
|
160
245
|
.dropdown-fade-enter-to,
|
|
161
246
|
.dropdown-fade-leave-from {
|
|
162
|
-
|
|
247
|
+
@apply opacity-100;
|
|
248
|
+
transform: translateY(0) scale(1);
|
|
163
249
|
}
|
|
164
|
-
</style>
|
|
250
|
+
</style>
|