adata-ui 2.1.41-beta.0 → 2.1.41-beta.1
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.md +2 -1
- package/assets/styles/main.css +4 -3
- package/assets/styles/theme.css +9 -2
- package/assets/styles/ui.css +77 -0
- package/components/elements/button/AButtonV2.vue +58 -15
- package/components/elements/count-up/ACountUp.vue +54 -0
- package/components/elements/curve-block-v2/ACurveBlockV2.vue +54 -18
- package/components/elements/infinite-carousel/AInfiniteCarousel.vue +46 -8
- package/components/elements/section-heading/ASectionHeading.vue +35 -0
- package/components/elements/step-slider/AStepSliderColCard.vue +75 -38
- package/components/elements/step-slider/AStepSliderColNumber.vue +74 -53
- package/components/features/color-mode/AColorMode.client.vue +1 -23
- package/components/forms/feedback-form/FeedbackFormV2.vue +3 -3
- package/components/forms/input/AInputV2.vue +28 -10
- package/components/forms/input/textarea/ATextareaV2.vue +10 -5
- package/components/navigation/footer/AFooter.vue +2 -2
- package/components/navigation/header/AHeader.vue +3 -3
- package/components/navigation/pill-tabs/APillTabsV2.vue +29 -14
- package/icons/letter/letter-a.vue +4 -2
- package/icons/letter/letter-b.vue +2 -2
- package/icons/letter/letter-c.vue +2 -2
- package/icons/letter/letter-d.vue +2 -2
- package/icons/letter/letter-e.vue +2 -2
- package/nuxt.config.ts +7 -4
- package/package.json +2 -2
|
@@ -87,14 +87,18 @@ function goTo(index: number) {
|
|
|
87
87
|
startTicker()
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
const isPaused = ref(false)
|
|
91
|
+
|
|
90
92
|
function onMouseEnter() {
|
|
91
|
-
if (props.pauseOnHover)
|
|
92
|
-
|
|
93
|
+
if (!props.pauseOnHover) return
|
|
94
|
+
isPaused.value = true
|
|
95
|
+
stopTicker()
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
function onMouseLeave() {
|
|
96
|
-
if (props.pauseOnHover)
|
|
97
|
-
|
|
99
|
+
if (!props.pauseOnHover) return
|
|
100
|
+
isPaused.value = false
|
|
101
|
+
startTicker()
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
onMounted(startTicker)
|
|
@@ -106,27 +110,33 @@ watch(() => [props.interval, props.autoplay, props.steps.length], () => {
|
|
|
106
110
|
</script>
|
|
107
111
|
|
|
108
112
|
<template>
|
|
113
|
+
<!-- eslint-disable tailwindcss/no-unnecessary-arbitrary-value --
|
|
114
|
+
Размеры и типографика скопированы из макета литералами (см. предупреждения
|
|
115
|
+
правила). Токены здесь не использовать: подсказка leading-1.4 в v4 значит
|
|
116
|
+
0.35rem, а не line-height 1.4. -->
|
|
109
117
|
<div
|
|
110
|
-
class="grid grid-cols-1 gap-
|
|
118
|
+
class="grid grid-cols-1 gap-8"
|
|
111
119
|
:class="colsClass"
|
|
120
|
+
@mouseenter="onMouseEnter"
|
|
121
|
+
@mouseleave="onMouseLeave"
|
|
112
122
|
>
|
|
113
|
-
<ol class="flex flex-col gap-
|
|
123
|
+
<ol class="flex flex-col gap-2">
|
|
114
124
|
<li
|
|
115
125
|
v-for="(step, i) in steps"
|
|
116
126
|
:key="i"
|
|
117
|
-
class="ss-card group relative cursor-pointer overflow-hidden rounded-
|
|
127
|
+
class="ss-card group relative cursor-pointer overflow-hidden rounded-14 border bg-main transition-[background-color,box-shadow,border-color,opacity] duration-300"
|
|
118
128
|
:class="i === active
|
|
119
|
-
? 'ss-card-active border-
|
|
120
|
-
: 'border-default hover:
|
|
129
|
+
? 'ss-card-active border-strong'
|
|
130
|
+
: 'border-default opacity-60 hover:bg-brand-subtle hover:opacity-100'"
|
|
121
131
|
@click="goTo(i)"
|
|
122
132
|
>
|
|
123
133
|
<div class="p-4">
|
|
124
134
|
<div
|
|
125
|
-
class="flex gap-
|
|
135
|
+
class="flex gap-[13px]"
|
|
126
136
|
:class="expandable ? 'items-center' : 'items-start'"
|
|
127
137
|
>
|
|
128
138
|
<span
|
|
129
|
-
class="flex size-
|
|
139
|
+
class="flex size-10 shrink-0 items-center justify-center rounded-[12px]"
|
|
130
140
|
:class="step.iconBg || 'bg-brand-subtle'"
|
|
131
141
|
>
|
|
132
142
|
<component
|
|
@@ -137,12 +147,18 @@ watch(() => [props.interval, props.autoplay, props.steps.length], () => {
|
|
|
137
147
|
/>
|
|
138
148
|
</span>
|
|
139
149
|
<div class="min-w-0 flex-1">
|
|
140
|
-
<p
|
|
150
|
+
<p
|
|
151
|
+
class="block text-[14px] font-bold transition-colors"
|
|
152
|
+
:class="i === active ? 'text-primary' : 'text-quaternary'"
|
|
153
|
+
>
|
|
141
154
|
{{ step.title }}
|
|
142
155
|
</p>
|
|
143
156
|
|
|
144
157
|
<div v-if="!expandable">
|
|
145
|
-
<p
|
|
158
|
+
<p
|
|
159
|
+
class="mt-0.5 block text-[12px] leading-[1.4] transition-colors"
|
|
160
|
+
:class="i === active ? 'text-quaternary' : 'text-secondary'"
|
|
161
|
+
>
|
|
146
162
|
{{ step.description }}
|
|
147
163
|
</p>
|
|
148
164
|
<div
|
|
@@ -172,7 +188,7 @@ watch(() => [props.interval, props.autoplay, props.steps.length], () => {
|
|
|
172
188
|
: 'grid-rows-[0fr] opacity-0'"
|
|
173
189
|
>
|
|
174
190
|
<div class="overflow-hidden">
|
|
175
|
-
<p class="text-body-sm text-
|
|
191
|
+
<p class="text-body-sm text-quaternary">
|
|
176
192
|
{{ step.description }}
|
|
177
193
|
</p>
|
|
178
194
|
<div
|
|
@@ -194,40 +210,61 @@ watch(() => [props.interval, props.autoplay, props.steps.length], () => {
|
|
|
194
210
|
</div>
|
|
195
211
|
</div>
|
|
196
212
|
|
|
213
|
+
<!-- Прогресс — CSS-анимация scaleX, как в макете (не JS-ширина);
|
|
214
|
+
длительность приходит переменной: scoped-стили переименовывают
|
|
215
|
+
@keyframes, поэтому inline-строку animation здесь использовать нельзя.
|
|
216
|
+
Константный бренд-градиент — одинаков в темах. -->
|
|
197
217
|
<span
|
|
198
218
|
v-if="i === active && autoplay && steps.length > 1"
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
:style="{ width: fillWidth }"
|
|
205
|
-
/>
|
|
206
|
-
</span>
|
|
219
|
+
:key="active"
|
|
220
|
+
class="cap-prog absolute inset-x-0 bottom-0 h-[3px] bg-linear-to-r from-brand to-[#4da8ff]"
|
|
221
|
+
:class="{ 'is-paused': isPaused }"
|
|
222
|
+
:style="{ '--cap-dur': `${interval}ms` }"
|
|
223
|
+
/>
|
|
207
224
|
</li>
|
|
208
225
|
</ol>
|
|
209
226
|
|
|
210
|
-
<div
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
:count="steps.length"
|
|
221
|
-
:fill-width="fillWidth"
|
|
222
|
-
:go-to="goTo"
|
|
223
|
-
/>
|
|
224
|
-
</div>
|
|
227
|
+
<div class="flex justify-center">
|
|
228
|
+
<slot
|
|
229
|
+
name="panel"
|
|
230
|
+
:active="active"
|
|
231
|
+
:step="steps[active]"
|
|
232
|
+
:progress="progress"
|
|
233
|
+
:count="steps.length"
|
|
234
|
+
:fill-width="fillWidth"
|
|
235
|
+
:go-to="goTo"
|
|
236
|
+
/>
|
|
225
237
|
</div>
|
|
226
238
|
</div>
|
|
227
239
|
</template>
|
|
228
240
|
|
|
229
241
|
<style scoped>
|
|
230
242
|
.ss-card-active {
|
|
231
|
-
box-shadow: 0
|
|
243
|
+
box-shadow: 0 14px 34px -18px color-mix(in srgb, var(--color-brand-500) 32%, transparent);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@keyframes cap-prog {
|
|
247
|
+
from {
|
|
248
|
+
transform: scaleX(0);
|
|
249
|
+
}
|
|
250
|
+
to {
|
|
251
|
+
transform: scaleX(1);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.cap-prog {
|
|
256
|
+
transform-origin: left;
|
|
257
|
+
animation: cap-prog var(--cap-dur, 4600ms) linear;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.cap-prog.is-paused {
|
|
261
|
+
animation-play-state: paused;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@media (prefers-reduced-motion: reduce) {
|
|
265
|
+
.cap-prog {
|
|
266
|
+
animation: none;
|
|
267
|
+
transform: none;
|
|
268
|
+
}
|
|
232
269
|
}
|
|
233
270
|
</style>
|
|
@@ -99,80 +99,101 @@ watch(() => [props.interval, props.autoplay, props.steps.length], () => {
|
|
|
99
99
|
|
|
100
100
|
<template>
|
|
101
101
|
<div
|
|
102
|
-
class="grid grid-cols-1 items-
|
|
102
|
+
class="grid grid-cols-1 items-start gap-[34px] lg:gap-13"
|
|
103
103
|
:class="colsClass"
|
|
104
104
|
>
|
|
105
|
-
<
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
@click="goTo(i)"
|
|
111
|
-
>
|
|
105
|
+
<div class="flex flex-col">
|
|
106
|
+
<ol class="relative flex flex-col gap-1.5">
|
|
107
|
+
<!-- Одна непрерывная линия с прогрессивной заливкой (как в макете),
|
|
108
|
+
а не дискретные сегменты между шагами. Линия проходит ЗА кружками,
|
|
109
|
+
поэтому их фон обязан быть непрозрачным (см. ниже). -->
|
|
112
110
|
<span
|
|
113
|
-
v-if="
|
|
114
|
-
class="
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
111
|
+
v-if="steps.length > 1"
|
|
112
|
+
class="absolute inset-y-9 left-[31px] z-0 w-0.5 overflow-hidden rounded bg-badge"
|
|
113
|
+
aria-hidden="true"
|
|
114
|
+
>
|
|
115
|
+
<span
|
|
116
|
+
class="ss-line-fill absolute inset-x-0 top-0 rounded bg-brand"
|
|
117
|
+
:style="{ height: `${(active / (steps.length - 1)) * 100}%` }"
|
|
118
|
+
/>
|
|
119
|
+
</span>
|
|
120
|
+
|
|
121
|
+
<li
|
|
122
|
+
v-for="(step, i) in steps"
|
|
123
|
+
:key="i"
|
|
124
|
+
class="ss-step relative z-10 flex cursor-pointer gap-[15px] rounded-14 px-4 py-3.5"
|
|
125
|
+
:class="i === active ? 'ss-step-on bg-main' : ''"
|
|
126
|
+
@click="goTo(i)"
|
|
127
|
+
>
|
|
128
|
+
<!-- Фон кружка только НЕПРОЗРАЧНЫМИ токенами: bg-brand-subtle в тёмной
|
|
129
|
+
теме = #068DFF1A (10% альфы), и линия прогресса просвечивала
|
|
130
|
+
сквозь пройденный шаг. Для дарка берём непрозрачный brand-900. -->
|
|
122
131
|
<span
|
|
123
|
-
class="
|
|
132
|
+
class="relative z-10 flex size-[34px] shrink-0 items-center justify-center rounded-full text-body-md font-bold transition-all duration-300"
|
|
124
133
|
:class="i === active
|
|
125
|
-
? 'ss-num-glow
|
|
134
|
+
? 'ss-num-glow scale-[1.08] bg-brand text-inverted'
|
|
126
135
|
: i < active
|
|
127
|
-
? '
|
|
128
|
-
: '
|
|
136
|
+
? 'bg-brand-100 text-brand dark:bg-brand-900 dark:text-brand-300'
|
|
137
|
+
: 'bg-canvas text-secondary'"
|
|
129
138
|
>
|
|
130
139
|
{{ i + 1 }}
|
|
131
140
|
</span>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
</li>
|
|
149
|
-
</ol>
|
|
141
|
+
<div>
|
|
142
|
+
<p
|
|
143
|
+
class="text-body-md-strong transition-colors"
|
|
144
|
+
:class="i === active ? 'text-primary' : 'text-secondary'"
|
|
145
|
+
>
|
|
146
|
+
{{ step.title }}
|
|
147
|
+
</p>
|
|
148
|
+
<p class="mt-[3px] text-body-sm leading-normal text-secondary">
|
|
149
|
+
{{ step.description }}
|
|
150
|
+
</p>
|
|
151
|
+
</div>
|
|
152
|
+
</li>
|
|
153
|
+
</ol>
|
|
154
|
+
|
|
155
|
+
<slot name="steps-footer" />
|
|
156
|
+
</div>
|
|
150
157
|
|
|
151
158
|
<div
|
|
152
159
|
@mouseenter="onMouseEnter"
|
|
153
160
|
@mouseleave="onMouseLeave"
|
|
154
161
|
>
|
|
155
|
-
<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/>
|
|
165
|
-
</div>
|
|
162
|
+
<slot
|
|
163
|
+
name="panel"
|
|
164
|
+
:active="active"
|
|
165
|
+
:step="steps[active]"
|
|
166
|
+
:progress="progress"
|
|
167
|
+
:count="steps.length"
|
|
168
|
+
:fill-width="fillWidth"
|
|
169
|
+
:go-to="goTo"
|
|
170
|
+
/>
|
|
166
171
|
</div>
|
|
167
172
|
</div>
|
|
168
173
|
</template>
|
|
169
174
|
|
|
170
175
|
<style scoped>
|
|
176
|
+
.ss-line-fill {
|
|
177
|
+
transition: height .6s cubic-bezier(.4, 0, .2, 1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.ss-step {
|
|
181
|
+
background: transparent;
|
|
182
|
+
transition: background .4s, box-shadow .4s;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.ss-step-on {
|
|
186
|
+
box-shadow: 0 14px 34px -18px color-mix(in srgb, var(--color-brand-500) 30%, transparent);
|
|
187
|
+
}
|
|
188
|
+
|
|
171
189
|
.ss-num-glow {
|
|
172
|
-
box-shadow: 0 4px
|
|
190
|
+
box-shadow: 0 6px 16px -4px color-mix(in srgb, var(--color-brand-500) 55%, transparent);
|
|
173
191
|
}
|
|
174
192
|
|
|
175
|
-
|
|
176
|
-
|
|
193
|
+
@media (prefers-reduced-motion: reduce) {
|
|
194
|
+
.ss-line-fill,
|
|
195
|
+
.ss-step {
|
|
196
|
+
transition: none;
|
|
197
|
+
}
|
|
177
198
|
}
|
|
178
199
|
</style>
|
|
@@ -1,36 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import Moon from '#adata-ui/icons/moon.vue'
|
|
3
3
|
import Sun from '#adata-ui/icons/sun.vue'
|
|
4
|
-
import { useEventListener } from '@vueuse/core'
|
|
5
4
|
|
|
6
5
|
const colorMode = useColorMode()
|
|
7
|
-
const setColorMode = useCookie('colorMode')
|
|
8
|
-
|
|
9
|
-
if (setColorMode.value) {
|
|
10
|
-
colorMode.preference = setColorMode.value
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const ONE_YEAR_SECONDS = 60 * 60 * 24 * 365
|
|
14
|
-
|
|
15
|
-
function cookieDomainAttr(): string {
|
|
16
|
-
const parts = location.hostname.split('.').reverse()
|
|
17
|
-
if (parts.length < 2) return ''
|
|
18
|
-
return `; domain=.${parts[1]}.${parts[0]}`
|
|
19
|
-
}
|
|
20
6
|
|
|
21
7
|
const isDark = computed(() => colorMode.value === 'dark')
|
|
22
8
|
|
|
23
9
|
function toggle() {
|
|
24
|
-
|
|
25
|
-
colorMode.preference = value
|
|
26
|
-
document.cookie = `colorMode=${value}; max-age=${ONE_YEAR_SECONDS}${cookieDomainAttr()}; path=/`
|
|
10
|
+
colorMode.preference = isDark.value ? 'light' : 'dark'
|
|
27
11
|
}
|
|
28
|
-
|
|
29
|
-
useEventListener(window, 'storage', (event: StorageEvent) => {
|
|
30
|
-
if (event.key === 'nuxt-color-mode' && event.newValue) {
|
|
31
|
-
colorMode.preference = event.newValue
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
12
|
</script>
|
|
35
13
|
|
|
36
14
|
<template>
|
|
@@ -70,10 +70,10 @@ onMounted(() => {
|
|
|
70
70
|
|
|
71
71
|
<template>
|
|
72
72
|
<section class="feedback-v2">
|
|
73
|
-
<!--
|
|
74
|
-
<div class="grid grid-cols-1 items-center gap-8 rounded-[28px] border border-
|
|
73
|
+
<!-- градиент промо-карточки — осознанный литерал (§05 аудита), но флипается в тёмной теме -->
|
|
74
|
+
<div class="grid grid-cols-1 items-center gap-8 rounded-[28px] border border-default bg-linear-to-br from-[#f0f8ff] via-[#eef4ff] to-[#f0f8ff] p-4 md:gap-10 md:p-12 lg:grid-cols-2 dark:from-[#1a2231] dark:via-[#15191f] dark:to-[#121316]">
|
|
75
75
|
<div>
|
|
76
|
-
<div class="mb-4 inline-flex items-center gap-2 rounded-full border border-
|
|
76
|
+
<div class="mb-4 inline-flex items-center gap-2 rounded-full border border-default bg-main px-3 py-1.5 text-body-md text-brand">
|
|
77
77
|
<message-square class="size-3.5" />
|
|
78
78
|
{{ t('forms.feedback.value') }}
|
|
79
79
|
</div>
|
|
@@ -43,12 +43,13 @@ interface Props {
|
|
|
43
43
|
disabled?: boolean
|
|
44
44
|
readonly?: boolean
|
|
45
45
|
clearable?: boolean
|
|
46
|
-
size?: 'sm' | 'md'
|
|
46
|
+
size?: 'sm' | 'md' | 'lg'
|
|
47
47
|
error?: string | string[]
|
|
48
48
|
startIcon?: Component
|
|
49
|
+
startIconClass?: string
|
|
49
50
|
endIcon?: Component
|
|
50
51
|
loading?: boolean
|
|
51
|
-
variant?: 'default' | 'gray' | 'blue'
|
|
52
|
+
variant?: 'default' | 'gray' | 'blue' | 'canvas'
|
|
52
53
|
mask?: string
|
|
53
54
|
inputId?: string
|
|
54
55
|
autocomplete?: string
|
|
@@ -255,13 +256,19 @@ defineExpose({ focus, blur, inputRef })
|
|
|
255
256
|
|
|
256
257
|
const layoutClass = computed(() => {
|
|
257
258
|
if (!props.label) {
|
|
259
|
+
if (props.size === 'lg') return 'h-11 py-2'
|
|
258
260
|
return props.size === 'md' ? 'h-10 py-1.5' : 'h-9 py-1.5'
|
|
259
261
|
}
|
|
262
|
+
if (props.size === 'lg') return 'h-11 pt-4 pb-1'
|
|
260
263
|
return props.size === 'md' ? 'h-10 pt-4 pb-0.5' : 'h-9 pt-3 pb-0.5'
|
|
261
264
|
})
|
|
262
265
|
|
|
266
|
+
/* Компенсация асимметричных паддингов поля с label: иконки возвращаются к
|
|
267
|
+
визуальному центру. Величина = (pt + контент/2) - h/2:
|
|
268
|
+
sm 12+11-18=5, md 16+11-20=7, lg 16+12-22=6. */
|
|
263
269
|
const iconOffsetClass = computed(() => {
|
|
264
270
|
if (!props.label) return ''
|
|
271
|
+
if (props.size === 'lg') return '-translate-y-[6px]'
|
|
265
272
|
return props.size === 'md' ? '-translate-y-[7px]' : '-translate-y-[5px]'
|
|
266
273
|
})
|
|
267
274
|
|
|
@@ -286,11 +293,16 @@ const fieldClass = computed(() => {
|
|
|
286
293
|
return 'border-default bg-badge/70'
|
|
287
294
|
}
|
|
288
295
|
if (props.variant === 'gray') {
|
|
289
|
-
|
|
296
|
+
/* по макету ДС-2026 у залитого поля бордер видимый, а не прозрачный */
|
|
297
|
+
return 'border-default bg-muted'
|
|
290
298
|
}
|
|
291
299
|
if (props.variant === 'blue') {
|
|
292
300
|
return 'border-brand-200 bg-brand-subtle'
|
|
293
301
|
}
|
|
302
|
+
if (props.variant === 'canvas') {
|
|
303
|
+
/* «утопленная» зона ДС + hero-поиск лендинга: bg-canvas глубже bg-muted в дарке */
|
|
304
|
+
return 'border-default bg-canvas'
|
|
305
|
+
}
|
|
294
306
|
return 'border-default bg-main'
|
|
295
307
|
})
|
|
296
308
|
|
|
@@ -308,7 +320,7 @@ function rowDisplay(item: T): unknown {
|
|
|
308
320
|
>
|
|
309
321
|
<div
|
|
310
322
|
ref="fieldRef"
|
|
311
|
-
class="input-v2__field
|
|
323
|
+
class="input-v2__field relative flex w-full cursor-text items-center gap-2 rounded-10 border border-solid text-primary transition-colors duration-200 focus-within:border-focus focus-within:ring-2 focus-within:ring-brand-500/20 hover:border-brand"
|
|
312
324
|
:class="[
|
|
313
325
|
layoutClass,
|
|
314
326
|
fieldClass,
|
|
@@ -331,11 +343,13 @@ function rowDisplay(item: T): unknown {
|
|
|
331
343
|
{{ label }}<span v-if="required" class="text-danger"> *</span>
|
|
332
344
|
</label>
|
|
333
345
|
|
|
346
|
+
<!-- startIconClass ЗАМЕНЯЕТ дефолтные размер+цвет, а не дописывается:
|
|
347
|
+
конфликт одинаковых утилит решается порядком в stylesheet, не в class -->
|
|
334
348
|
<component
|
|
335
349
|
:is="startIcon"
|
|
336
350
|
v-if="startIcon"
|
|
337
|
-
class="
|
|
338
|
-
:class="iconOffsetClass"
|
|
351
|
+
class="shrink-0"
|
|
352
|
+
:class="[startIconClass || 'size-4 text-icon-disabled', iconOffsetClass]"
|
|
339
353
|
/>
|
|
340
354
|
|
|
341
355
|
<input
|
|
@@ -348,7 +362,7 @@ function rowDisplay(item: T): unknown {
|
|
|
348
362
|
:readonly="readonly"
|
|
349
363
|
:autocomplete="autocomplete"
|
|
350
364
|
:tabindex="disabled ? -1 : 0"
|
|
351
|
-
class="input-v2__input
|
|
365
|
+
class="input-v2__input w-full min-w-0 bg-transparent leading-tight text-primary outline-hidden placeholder:text-secondary disabled:cursor-not-allowed"
|
|
352
366
|
v-bind="inputAttrs"
|
|
353
367
|
@input="onInput"
|
|
354
368
|
@focus="onFocus"
|
|
@@ -371,7 +385,7 @@ function rowDisplay(item: T): unknown {
|
|
|
371
385
|
@mousedown.prevent
|
|
372
386
|
@click.stop="onClear"
|
|
373
387
|
>
|
|
374
|
-
<a-icon-x-mark class="
|
|
388
|
+
<a-icon-x-mark class="m-0! size-3.5" />
|
|
375
389
|
</button>
|
|
376
390
|
|
|
377
391
|
<component
|
|
@@ -395,7 +409,7 @@ function rowDisplay(item: T): unknown {
|
|
|
395
409
|
<div
|
|
396
410
|
v-if="isDropdownOpen"
|
|
397
411
|
ref="floatingRef"
|
|
398
|
-
class="input-v2__dropdown z-
|
|
412
|
+
class="input-v2__dropdown z-10000 flex flex-col gap-2 rounded-xl border border-default bg-main p-1.5 shadow-[0_24px_50px_-24px] shadow-brand-500/50"
|
|
399
413
|
:style="{
|
|
400
414
|
position: strategy,
|
|
401
415
|
left: x != null ? `${x}px` : '',
|
|
@@ -406,7 +420,7 @@ function rowDisplay(item: T): unknown {
|
|
|
406
420
|
<li
|
|
407
421
|
v-for="(item, idx) in autocompleteList"
|
|
408
422
|
:key="idx"
|
|
409
|
-
class="cursor-pointer rounded-
|
|
423
|
+
class="cursor-pointer rounded-lg px-3.5 py-2.5 text-body-md transition-colors duration-100 hover:bg-brand-subtle"
|
|
410
424
|
:class="{ 'input-v2__option--active': currentItemIndex === idx }"
|
|
411
425
|
@mousedown.prevent="onSelectOption(item)"
|
|
412
426
|
@touchend.prevent="onTouchEndOption(item)"
|
|
@@ -471,6 +485,10 @@ function rowDisplay(item: T): unknown {
|
|
|
471
485
|
transform: translateY(-14px);
|
|
472
486
|
}
|
|
473
487
|
|
|
488
|
+
.input-v2__label--floated[data-size="lg"] {
|
|
489
|
+
transform: translateY(-19px);
|
|
490
|
+
}
|
|
491
|
+
|
|
474
492
|
.input-v2__dropdown-enter-active,
|
|
475
493
|
.input-v2__dropdown-leave-active {
|
|
476
494
|
transition:
|
|
@@ -30,7 +30,7 @@ interface Props {
|
|
|
30
30
|
readonly?: boolean
|
|
31
31
|
error?: string | string[]
|
|
32
32
|
size?: 'sm' | 'md'
|
|
33
|
-
variant?: 'default' | 'gray' | 'blue'
|
|
33
|
+
variant?: 'default' | 'gray' | 'blue' | 'canvas'
|
|
34
34
|
rows?: number
|
|
35
35
|
resize?: 'none' | 'vertical' | 'both'
|
|
36
36
|
maxlength?: number
|
|
@@ -60,11 +60,16 @@ const fieldClass = computed(() => {
|
|
|
60
60
|
return 'border-default bg-badge/70'
|
|
61
61
|
}
|
|
62
62
|
if (props.variant === 'gray') {
|
|
63
|
-
|
|
63
|
+
/* по макету ДС-2026 у залитого поля бордер видимый, а не прозрачный */
|
|
64
|
+
return 'border-default bg-muted'
|
|
64
65
|
}
|
|
65
66
|
if (props.variant === 'blue') {
|
|
66
67
|
return 'border-brand-200 bg-brand-subtle'
|
|
67
68
|
}
|
|
69
|
+
if (props.variant === 'canvas') {
|
|
70
|
+
/* «утопленная» зона ДС: bg-canvas глубже bg-muted в дарке (парно с AInputV2) */
|
|
71
|
+
return 'border-default bg-canvas'
|
|
72
|
+
}
|
|
68
73
|
return 'border-default bg-main'
|
|
69
74
|
})
|
|
70
75
|
|
|
@@ -124,7 +129,7 @@ defineExpose({ focus, blur, textareaRef })
|
|
|
124
129
|
<template>
|
|
125
130
|
<div class="textarea-v2 relative w-full text-body-md" v-bind="wrapperAttrs">
|
|
126
131
|
<div
|
|
127
|
-
class="textarea-v2__field relative rounded-
|
|
132
|
+
class="textarea-v2__field relative rounded-10 border border-solid transition-colors duration-200 focus-within:border-focus focus-within:ring-2 focus-within:ring-brand-500/20 hover:border-brand"
|
|
128
133
|
:class="[fieldClass, { 'textarea-v2__field--error': hasError, 'textarea-v2__field--disabled': disabled }]"
|
|
129
134
|
>
|
|
130
135
|
<label
|
|
@@ -147,7 +152,7 @@ defineExpose({ focus, blur, textareaRef })
|
|
|
147
152
|
:disabled="disabled"
|
|
148
153
|
:readonly="readonly"
|
|
149
154
|
:tabindex="disabled ? -1 : 0"
|
|
150
|
-
class="textarea-v2__input
|
|
155
|
+
class="textarea-v2__input block w-full bg-transparent leading-snug text-primary outline-hidden placeholder:text-secondary disabled:cursor-not-allowed"
|
|
151
156
|
:class="[resizeClass, paddingClass]"
|
|
152
157
|
v-bind="inputAttrs"
|
|
153
158
|
@focus="onFocus"
|
|
@@ -156,7 +161,7 @@ defineExpose({ focus, blur, textareaRef })
|
|
|
156
161
|
|
|
157
162
|
<span
|
|
158
163
|
v-if="maxlength"
|
|
159
|
-
class="textarea-v2__counter pointer-events-none absolute bottom-1.5
|
|
164
|
+
class="textarea-v2__counter pointer-events-none absolute right-3 bottom-1.5 text-body-sm text-icon-disabled"
|
|
160
165
|
>
|
|
161
166
|
{{ modelValue?.length ?? 0 }}/{{ maxlength }}
|
|
162
167
|
</span>
|
|
@@ -166,7 +166,7 @@ const contactLinks = computed(() => ({
|
|
|
166
166
|
<template>
|
|
167
167
|
<footer
|
|
168
168
|
id="footer"
|
|
169
|
-
class="rounded-t-
|
|
169
|
+
class="rounded-t-[32px] bg-secondary-500 py-4 lg:py-5 dark:bg-black"
|
|
170
170
|
>
|
|
171
171
|
<div class="a-container mobile-padding flex flex-col justify-between gap-8 py-5 text-white lg:flex-row">
|
|
172
172
|
<div class="flex flex-col justify-between gap-8">
|
|
@@ -221,7 +221,7 @@ const contactLinks = computed(() => ({
|
|
|
221
221
|
<!-- noindex -->
|
|
222
222
|
<div class="flex flex-col items-start gap-2" data-nosnippet>
|
|
223
223
|
<nuxt-link
|
|
224
|
-
class="cursor-pointer border-b-[0.5px] border-current pb-3
|
|
224
|
+
class="cursor-pointer border-b-[0.5px] border-current pr-4 pb-3 text-body-md-strong"
|
|
225
225
|
:to="contactLinks.link?.replace(/\/$/, '')"
|
|
226
226
|
>
|
|
227
227
|
{{ contactLinks.title }}
|
|
@@ -107,7 +107,7 @@ onMounted(() => {
|
|
|
107
107
|
<system-notification />
|
|
108
108
|
<header
|
|
109
109
|
ref="headerRef"
|
|
110
|
-
class="relative h-16 border-b border-default bg-
|
|
110
|
+
class="relative h-16 border-b border-default bg-main/72 backdrop-blur-[14px] backdrop-saturate-140"
|
|
111
111
|
>
|
|
112
112
|
<div class="a-container mobile-padding flex h-full items-center justify-between gap-2">
|
|
113
113
|
<!-- Desktop hidden -->
|
|
@@ -136,7 +136,7 @@ onMounted(() => {
|
|
|
136
136
|
@click="goToAnotherModule"
|
|
137
137
|
/>
|
|
138
138
|
<button
|
|
139
|
-
class="flex w-full items-center gap-2 rounded-full border border-strong/50 bg-
|
|
139
|
+
class="flex w-full items-center gap-2 rounded-full border border-strong/50 bg-main/30 px-4 py-1.5 backdrop-blur-sm"
|
|
140
140
|
@click="$emit('search')"
|
|
141
141
|
>
|
|
142
142
|
<a-icon-search class="text-icon-disabled" />
|
|
@@ -197,7 +197,7 @@ onMounted(() => {
|
|
|
197
197
|
<template #default="{ toggle, isOpen }">
|
|
198
198
|
<button
|
|
199
199
|
type="button"
|
|
200
|
-
class="hidden h-8 cursor-pointer items-center gap-1.5 rounded-full px-3 text-body-md-medium transition-colors duration-150 hover:bg-action-secondary-hover focus-visible:
|
|
200
|
+
class="hidden h-8 cursor-pointer items-center gap-1.5 rounded-full px-3 text-body-md-medium transition-colors duration-150 hover:bg-action-secondary-hover focus-visible:ring-2 focus-visible:ring-brand-500/50 focus-visible:ring-offset-1 focus-visible:outline-hidden lg:inline-flex"
|
|
201
201
|
:class="isOpen
|
|
202
202
|
? 'bg-action-secondary-hover text-primary'
|
|
203
203
|
: 'text-primary'"
|