adata-ui 2.1.40 → 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.
Files changed (258) hide show
  1. package/-error.vue +2 -2
  2. package/.playground/app.vue +13 -13
  3. package/.playground/nuxt.config.ts +1 -1
  4. package/CLAUDE.md +63 -0
  5. package/assets/styles/main.css +12 -0
  6. package/assets/styles/theme.css +583 -0
  7. package/assets/styles/ui.css +247 -0
  8. package/components/elements/a-select-row/ASelectRowV2.vue +13 -17
  9. package/components/elements/a-select-row/index.vue +13 -12
  10. package/components/elements/accordion/AAccordion.vue +2 -2
  11. package/components/elements/accordion/AAccordionGroup/AAccordionGroup.vue +1 -1
  12. package/components/elements/accordion/AAccordionGroup/ui.config.ts +4 -4
  13. package/components/elements/accordion/ui.config.ts +4 -4
  14. package/components/elements/alert/AAlert.vue +5 -5
  15. package/components/elements/bg-block/ABgBlock.vue +1 -1
  16. package/components/elements/button/AButton.vue +48 -45
  17. package/components/elements/button/AButtonV2.vue +74 -30
  18. package/components/elements/button-login/index.vue +2 -1
  19. package/components/elements/carousel/config.ui.ts +2 -2
  20. package/components/elements/chip-wrapper/AChipWrapper.vue +4 -3
  21. package/components/elements/chips/AChips.vue +4 -3
  22. package/components/elements/companies/AOurClients.vue +1 -1
  23. package/components/elements/count-up/ACountUp.vue +54 -0
  24. package/components/elements/curve-block/ACurveBlock.vue +15 -48
  25. package/components/elements/curve-block-v2/ACurveBlockV2.vue +60 -25
  26. package/components/elements/digit-badge/ADigitBadge.vue +17 -16
  27. package/components/elements/empty-box/empty-box-V2.vue +92 -0
  28. package/components/elements/error-template/index.vue +99 -31
  29. package/components/elements/feature-description/AFeatureDescription.vue +8 -8
  30. package/components/elements/illustrations/noAccess.vue +1 -1
  31. package/components/elements/infinite-carousel/AInfiniteCarousel.vue +44 -16
  32. package/components/elements/leave-note/ALeaveNote.vue +2 -2
  33. package/components/elements/pagination/APagination.vue +8 -8
  34. package/components/elements/section-heading/ASectionHeading.vue +35 -0
  35. package/components/elements/segmented/ASegmentedV2.vue +24 -21
  36. package/components/elements/select/ASelect.vue +28 -27
  37. package/components/elements/select/ASelectMobile.vue +5 -5
  38. package/components/elements/select/ASelectV2.vue +20 -28
  39. package/components/elements/select/ui/select-button.vue +8 -8
  40. package/components/elements/select/ui/select-list.vue +2 -2
  41. package/components/elements/show-more/AShowMore.vue +2 -2
  42. package/components/elements/show-more/AShowMoreV2.vue +3 -3
  43. package/components/elements/skeleton/ASkeleton.vue +1 -1
  44. package/components/elements/slider/ASlider.vue +3 -2
  45. package/components/elements/slider/ASliderV2.vue +182 -0
  46. package/components/elements/star-rating/AStarRating.vue +2 -2
  47. package/components/elements/status-badge/AStatusBadge.vue +40 -36
  48. package/components/elements/step-slider/AStepSliderColCard.vue +77 -39
  49. package/components/elements/step-slider/AStepSliderColNumber.vue +74 -53
  50. package/components/elements/table/table.config.ts +8 -8
  51. package/components/elements/tree-select/components/ATreeSelectNode.vue +4 -4
  52. package/components/elements/tree-select-mobile/components/ATreeSelectNodesMobile.vue +3 -3
  53. package/components/elements/tree-select-modal/ATreeSelectModal.vue +4 -4
  54. package/components/features/color-mode/AColorMode.client.vue +2 -24
  55. package/components/features/dropdown/ADropdownV2.vue +1 -1
  56. package/components/features/lang-switcher/lang-switcher.vue +6 -6
  57. package/components/features/payment/banner/BasicPlusLimitBanner.vue +3 -23
  58. package/components/features/payment/banner/PaymentBanner.vue +3 -23
  59. package/components/features/payment/banner/UpSellBanner.vue +1 -21
  60. package/components/features/payment/process/PaymentKaspiQrSidePanel.vue +8 -7
  61. package/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue +5 -5
  62. package/components/features/payment/process/PaymentMethodSidePanel.vue +12 -12
  63. package/components/features/payment/process/PaymentTopUpSidePanel.vue +6 -6
  64. package/components/features/pk-mobile-services/APkMobileServices.vue +14 -43
  65. package/components/features//321/201hange-version/AChangeVersion.vue +1 -1
  66. package/components/forms/checkbox/ACheckbox.vue +8 -8
  67. package/components/forms/checkbox/ACheckboxV2.vue +8 -8
  68. package/components/forms/feedback-form/FeedbackForm.vue +8 -8
  69. package/components/forms/feedback-form/FeedbackFormV2.vue +9 -8
  70. package/components/forms/input/AInputV2.vue +39 -25
  71. package/components/forms/input/button/AInputButton.vue +1 -1
  72. package/components/forms/input/date/AInputDate.vue +13 -9
  73. package/components/forms/input/password/AInputPassword.vue +1 -1
  74. package/components/forms/input/standard/AInputStandard.vue +23 -14
  75. package/components/forms/input/textarea/ATextarea.vue +15 -11
  76. package/components/forms/input/textarea/ATextareaV2.vue +18 -13
  77. package/components/forms/radio-button/ARadioButton.vue +4 -4
  78. package/components/forms/request-demo/ARequestDemo.vue +5 -5
  79. package/components/forms/toggle/AToggle.vue +8 -7
  80. package/components/forms/toggle/AToggleV2.vue +7 -6
  81. package/components/modals/AConfirmationEmail.vue +3 -3
  82. package/components/modals/AboutTariffModal.vue +10 -9
  83. package/components/modals/AnotherDeviceModal.vue +11 -10
  84. package/components/modals/ApplicationAcceptedModal.vue +3 -2
  85. package/components/modals/ConnectingTariffModal.vue +1 -1
  86. package/components/modals/ContactsMobileModel.vue +5 -5
  87. package/components/modals/ContentNavigationModal.vue +8 -7
  88. package/components/modals/Insufficient-funds-modal.vue +4 -4
  89. package/components/modals/LimitReachedModal.vue +18 -7
  90. package/components/modals/NoAccessModal.vue +7 -3
  91. package/components/modals/PaymentMethodModal.vue +4 -4
  92. package/components/modals/RedirectsBanksModal.vue +4 -4
  93. package/components/modals/ReplenishModal.vue +2 -2
  94. package/components/modals/ReportBugConfirmModal.vue +2 -2
  95. package/components/modals/ReportBugModal.vue +2 -2
  96. package/components/modals/Resend.vue +4 -4
  97. package/components/modals/SubmitApplicationModal.vue +1 -5
  98. package/components/modals/id/AuthModal.vue +27 -47
  99. package/components/modals/id/IdAutoLogoutModal.vue +23 -24
  100. package/components/modals/id/IdBanner.vue +4 -24
  101. package/components/modals/id/IdConfirmAccountOtpModal.vue +5 -4
  102. package/components/modals/id/IdConfirmSuccessfulModal.vue +3 -3
  103. package/components/modals/id/IdLoginModal.vue +8 -8
  104. package/components/modals/id/IdModals.vue +1 -3
  105. package/components/modals/id/IdNewPasswordModal.vue +3 -3
  106. package/components/modals/id/IdOtpInput.vue +3 -3
  107. package/components/modals/id/IdPasswordSuccessfulModal.vue +3 -3
  108. package/components/modals/id/IdRecoveryModal.vue +3 -3
  109. package/components/modals/id/IdRegistrationModal.vue +4 -4
  110. package/components/modals/id/IdResetPasswordOtpModal.vue +5 -4
  111. package/components/modals/id/IdTwoFactorModal.vue +3 -2
  112. package/components/navigation/bottom-navigation/ABottomNavigation.vue +7 -7
  113. package/components/navigation/breadcrumbs/ABreadcrumbs.vue +4 -4
  114. package/components/navigation/footer/AFooter.vue +2 -2
  115. package/components/navigation/footer/ui/a-footer-accordion.vue +1 -1
  116. package/components/navigation/header/AHeader.vue +11 -11
  117. package/components/navigation/header/AlmatyContacts.vue +7 -7
  118. package/components/navigation/header/AstanaContacts.vue +4 -4
  119. package/components/navigation/header/CardGallery.vue +8 -7
  120. package/components/navigation/header/ContactMenu.vue +1 -1
  121. package/components/navigation/header/HeaderLink.vue +5 -5
  122. package/components/navigation/header/HeaderUsage.vue +14 -14
  123. package/components/navigation/header/ListItem.vue +4 -3
  124. package/components/navigation/header/NavCard.vue +6 -5
  125. package/components/navigation/header/NavList.vue +9 -8
  126. package/components/navigation/header/NotificationsMenu.vue +10 -10
  127. package/components/navigation/header/ProductMenu.vue +10 -9
  128. package/components/navigation/header/ProfileMenu.vue +13 -12
  129. package/components/navigation/header/SystemNotification.vue +4 -4
  130. package/components/navigation/line-tabs/ALineTabs.vue +10 -9
  131. package/components/navigation/pill-tabs/APillTabs.vue +18 -16
  132. package/components/navigation/pill-tabs/APillTabsV2.vue +40 -25
  133. package/components/navigation/side-navigation/ASideNavigation.vue +3 -3
  134. package/components/overlays/drawer/ADrawerV2.vue +12 -11
  135. package/components/overlays/modal/AModal.vue +4 -4
  136. package/components/overlays/modal/AModalV2.vue +17 -13
  137. package/components/overlays/side-panel/ASidePanel.vue +7 -7
  138. package/components/overlays/sideover/ASlideover.vue +4 -4
  139. package/components/overlays/tooltip/ATooltip.vue +3 -2
  140. package/components/overlays/tooltip/ATooltipV2.vue +2 -2
  141. package/composables/highlight.ts +2 -1
  142. package/eslint.config.mjs +14 -1
  143. package/icons/arrow/arrow-left.vue +14 -0
  144. package/icons/arrow-currency-gray.vue +1 -1
  145. package/icons/arrow-currency-green.vue +1 -1
  146. package/icons/arrow-currency-red.vue +1 -1
  147. package/icons/avatar.vue +1 -1
  148. package/icons/bar-chart-3.vue +3 -0
  149. package/icons/book-open.vue +3 -0
  150. package/icons/bookmark/bookmark-filled.vue +1 -0
  151. package/icons/braces.vue +3 -0
  152. package/icons/check/check-outline.vue +3 -0
  153. package/icons/chevron/chevron-down-outline.vue +3 -0
  154. package/icons/clipboard-list.vue +3 -0
  155. package/icons/clock-outline.vue +3 -0
  156. package/icons/company-egov-small.vue +1 -1
  157. package/icons/database.vue +3 -0
  158. package/icons/download-outline.vue +3 -0
  159. package/icons/download.vue +1 -1
  160. package/icons/egov.vue +1 -1
  161. package/icons/elicense.vue +1 -1
  162. package/icons/file-json.vue +3 -0
  163. package/icons/file-search.vue +3 -0
  164. package/icons/file-text.vue +3 -0
  165. package/icons/flask-conical.vue +3 -0
  166. package/icons/folder-open.vue +3 -0
  167. package/icons/gift-outline.vue +3 -0
  168. package/icons/globe-2.vue +3 -0
  169. package/icons/graph-loading.vue +2 -2
  170. package/icons/hand/hand-thumb-up-filled.vue +1 -1
  171. package/icons/home.vue +14 -0
  172. package/icons/invoice.vue +1 -0
  173. package/icons/key-round.vue +3 -0
  174. package/icons/letter/letter-a.vue +4 -2
  175. package/icons/letter/letter-b.vue +2 -2
  176. package/icons/letter/letter-c.vue +2 -2
  177. package/icons/letter/letter-d.vue +2 -2
  178. package/icons/letter/letter-e.vue +2 -2
  179. package/icons/logo.vue +1 -1
  180. package/icons/main-filter.vue +1 -1
  181. package/icons/menu.vue +4 -4
  182. package/icons/message/message.vue +1 -1
  183. package/icons/messages-square.vue +3 -0
  184. package/icons/more.vue +1 -1
  185. package/icons/payment/payment-card.vue +2 -2
  186. package/icons/radio/radio-check.vue +1 -1
  187. package/icons/robot-outline.vue +3 -0
  188. package/icons/scales/scale-outline.vue +3 -0
  189. package/icons/search-outline.vue +3 -0
  190. package/icons/send.vue +3 -0
  191. package/icons/star/star-filled.vue +1 -0
  192. package/icons/star/star-half-filled.vue +1 -0
  193. package/icons/sun.vue +1 -0
  194. package/icons/terminal.vue +3 -0
  195. package/icons/toasts/warning-triangle-toast.vue +1 -0
  196. package/icons/triangle-alert.vue +3 -0
  197. package/icons/users-outline.vue +3 -0
  198. package/icons/webhook.vue +3 -0
  199. package/icons/x-outline.vue +3 -0
  200. package/icons/yandex.vue +2 -1
  201. package/illustrations/address-location.vue +2 -2
  202. package/illustrations/award-badge.vue +105 -0
  203. package/illustrations/ball-with-chain.vue +7 -7
  204. package/illustrations/bill.vue +5 -5
  205. package/illustrations/buildings.vue +4 -4
  206. package/illustrations/calendar.vue +11 -11
  207. package/illustrations/chains.vue +12 -12
  208. package/illustrations/coin-percent.vue +3 -3
  209. package/illustrations/coins-stack.vue +4 -4
  210. package/illustrations/delete-dark.vue +1 -0
  211. package/illustrations/delete.vue +1 -0
  212. package/illustrations/doc-with-stamp.vue +5 -5
  213. package/illustrations/document.vue +3 -3
  214. package/illustrations/door.vue +79 -68
  215. package/illustrations/empty-badge-check.vue +20 -0
  216. package/illustrations/empty-ban.vue +18 -0
  217. package/illustrations/empty-box.vue +5 -5
  218. package/illustrations/empty-filter.vue +20 -0
  219. package/illustrations/empty-inbox.vue +19 -0
  220. package/illustrations/empty-scale.vue +22 -0
  221. package/illustrations/empty-search-x.vue +21 -0
  222. package/illustrations/empty-shopping-cart.vue +21 -0
  223. package/illustrations/empty-users-round.vue +20 -0
  224. package/illustrations/empty-wallet.vue +121 -155
  225. package/illustrations/graph-in-coin.vue +2 -2
  226. package/illustrations/hammer.vue +5 -5
  227. package/illustrations/hand-cash.vue +1 -1
  228. package/illustrations/info.vue +49 -36
  229. package/illustrations/mail-active.vue +86 -0
  230. package/illustrations/mail.vue +4 -4
  231. package/illustrations/no-access.vue +92 -0
  232. package/illustrations/ok.vue +86 -58
  233. package/illustrations/people-group.vue +1 -1
  234. package/illustrations/person-with-phone.vue +5 -5
  235. package/illustrations/person.vue +3 -3
  236. package/illustrations/phone-check.vue +104 -84
  237. package/illustrations/phone-payment-method.vue +1 -1
  238. package/illustrations/shield-user.vue +94 -0
  239. package/illustrations/stop-hand.vue +78 -71
  240. package/illustrations/stop-sign.vue +1 -1
  241. package/illustrations/suit.vue +93 -107
  242. package/illustrations/suitcase.vue +6 -6
  243. package/illustrations/terminal.vue +94 -228
  244. package/illustrations/trash-can.vue +60 -102
  245. package/illustrations/turn-on-tariff.vue +2 -2
  246. package/illustrations/two-persons.vue +2 -2
  247. package/lang/en.ts +25 -29
  248. package/lang/kk.ts +24 -28
  249. package/lang/ru.ts +24 -29
  250. package/nuxt.config.ts +11 -4
  251. package/package.json +7 -12
  252. package/assets/styles/index.scss +0 -166
  253. package/assets/styles/modules/_base.scss +0 -5
  254. package/assets/styles/modules/_typography.scss +0 -152
  255. package/components/elements/error-template/types.ts +0 -23
  256. package/illustrations/terminal-dark.vue +0 -48
  257. package/tailwind.config.ts +0 -194
  258. package/tests/AButton.test.ts +0 -81
@@ -126,6 +126,7 @@ defineExpose({ next, prev, goTo, index, count })
126
126
  class="absolute bottom-0 left-1/2 z-10 flex -translate-x-1/2 gap-2"
127
127
  role="tablist"
128
128
  >
129
+ <!-- пастельный бренд-трек: семантического токена нет, dark-компенсация вручную -->
129
130
  <button
130
131
  v-for="(_, i) in count"
131
132
  :key="i"
@@ -133,14 +134,14 @@ defineExpose({ next, prev, goTo, index, count })
133
134
  role="tab"
134
135
  :aria-selected="index === i"
135
136
  :aria-label="`Слайд ${i + 1}`"
136
- class="relative h-[6px] cursor-pointer overflow-hidden rounded-full bg-blue-200 transition-all duration-300 dark:bg-blue-900/40"
137
+ class="relative h-[6px] cursor-pointer overflow-hidden rounded-full bg-brand-200 dark:bg-brand-500/30 transition-all duration-300"
137
138
  :class="index === i ? 'w-[30px]' : 'w-[20px]'"
138
139
  @click="goTo(i)"
139
140
  >
140
141
  <span
141
142
  v-if="index === i && shouldRun"
142
143
  :key="tick"
143
- class="a-slider-progress absolute inset-0 rounded-full bg-blue-500 dark:bg-blue-400"
144
+ class="a-slider-progress absolute inset-0 rounded-full bg-brand"
144
145
  :style="timingStyle"
145
146
  />
146
147
  </button>
@@ -0,0 +1,182 @@
1
+ <script setup lang="ts" generic="T">
2
+ import { useElementHover } from '@vueuse/core'
3
+ import { computed, ref, watch } from 'vue'
4
+
5
+ interface Props {
6
+ /** Slides. The slider only uses their count and the current one. */
7
+ slides: readonly T[]
8
+ /** Time each slide stays active, in ms. Also the progress-bar duration. */
9
+ interval?: number
10
+ /** Advance automatically. */
11
+ autoplay?: boolean
12
+ /** Freeze autoplay while the cursor is over the slider. */
13
+ pauseOnHover?: boolean
14
+ /** Render the built-in progress indicators. */
15
+ indicators?: boolean
16
+ /**
17
+ * CSS transition name for the built-in slide swap, e.g. `"fade"`.
18
+ * The slider only passes the name through to `<transition>` — the CSS
19
+ * itself stays with the slide. Without it slides swap instantly.
20
+ * Ignored when the default slot is used: taking over the rendering means
21
+ * taking over the transition too.
22
+ */
23
+ transition?: string
24
+ /** Transition mode, as on Vue's `<transition>`. */
25
+ transitionMode?: 'out-in' | 'in-out' | 'default'
26
+ /** Explicit transition duration in ms, as on Vue's `<transition>`. */
27
+ transitionDuration?: number | { enter: number, leave: number }
28
+ }
29
+
30
+ const props = withDefaults(defineProps<Props>(), {
31
+ interval: 5000,
32
+ autoplay: true,
33
+ pauseOnHover: true,
34
+ indicators: true,
35
+ transition: undefined,
36
+ transitionMode: 'out-in',
37
+ transitionDuration: undefined,
38
+ })
39
+
40
+ /** Active slide index — usable as `v-model:index`. */
41
+ const index = defineModel<number>('index', { default: 0 })
42
+
43
+ const root = ref<HTMLElement>()
44
+ const count = computed(() => props.slides.length)
45
+
46
+ /* ---- navigation (always wraps around) ---- */
47
+ function goTo(to: number) {
48
+ if (count.value === 0)
49
+ return
50
+ index.value = ((to % count.value) + count.value) % count.value
51
+ }
52
+ function next() {
53
+ goTo(index.value + 1)
54
+ }
55
+ function prev() {
56
+ goTo(index.value - 1)
57
+ }
58
+
59
+ /* ---- autoplay ----
60
+ * Timing is driven by an invisible "clock" element's CSS animation.
61
+ * `animation-play-state: paused` freezes both the clock and the visible
62
+ * progress bar in one place, so the pause stays perfectly in sync and
63
+ * resumes from where it stopped — no JS timers to keep aligned. */
64
+
65
+ // Bumping this key remounts the clock/progress element, restarting the timing.
66
+ // Watched rather than bumped inside `goTo`, so writing to `v-model:index`
67
+ // from the outside restarts the timing too.
68
+ const tick = ref(0)
69
+ watch(index, () => {
70
+ tick.value++
71
+ })
72
+
73
+ // The slide list may have shrunk under the current index.
74
+ watch(count, (n) => {
75
+ if (index.value >= n)
76
+ goTo(0)
77
+ })
78
+
79
+ const hovered = useElementHover(root)
80
+
81
+ const running = computed(() => props.autoplay && count.value > 1)
82
+ const timingStyle = computed(() => ({
83
+ animationDuration: `${props.interval}ms`,
84
+ animationPlayState: props.pauseOnHover && hovered.value ? 'paused' : 'running',
85
+ }))
86
+
87
+ defineExpose({ next, prev, goTo })
88
+ </script>
89
+
90
+ <template>
91
+ <div
92
+ ref="root"
93
+ class="relative overflow-hidden"
94
+ role="group"
95
+ aria-roledescription="carousel"
96
+ >
97
+ <!-- Invisible clock: fires `next` when a slide's time elapses. -->
98
+ <div
99
+ v-if="running"
100
+ :key="tick"
101
+ class="a-slider-clock"
102
+ :style="timingStyle"
103
+ @animationend="next"
104
+ />
105
+
106
+ <!-- Rendered once, for the active slide. Markup and animations are the
107
+ consumer's job — the slider only says which slide is active.
108
+ Without a slot the slider still works on its own: it renders the
109
+ active slide as-is, optionally wrapped in a named transition. -->
110
+ <slot
111
+ v-if="$slots.default"
112
+ :slide="slides[index]"
113
+ :index="index"
114
+ :count="count"
115
+ :go-to="goTo"
116
+ />
117
+
118
+ <!-- БЕЗ `appear` — это принципиально. Под SSR `<transition appear>`
119
+ сериализует содержимое в литеральный `<template>`: браузер такой узел
120
+ не рендерит, слайдер стоит пустым до гидратации, а сама гидратация
121
+ падает с mismatch (проверено на Nuxt 3.18 / Vue 3.5).
122
+ Вход первого слайда всё равно задаётся обычной CSS-анимацией на
123
+ монтировании — `appear` при SSR-гидратации Vue и так не проигрывает. -->
124
+ <transition
125
+ v-else-if="transition && slides[index]"
126
+ :name="transition"
127
+ :mode="transitionMode"
128
+ :duration="transitionDuration"
129
+ >
130
+ <component :is="slides[index]" :key="index" />
131
+ </transition>
132
+
133
+ <component
134
+ :is="slides[index]"
135
+ v-else-if="slides[index]"
136
+ :key="index"
137
+ />
138
+
139
+ <div
140
+ v-if="indicators && count > 1"
141
+ class="absolute bottom-0 left-1/2 z-10 flex -translate-x-1/2 gap-2"
142
+ >
143
+ <!-- пастельный бренд-трек: семантического токена нет, dark-компенсация вручную -->
144
+ <button
145
+ v-for="(_, i) in count"
146
+ :key="i"
147
+ type="button"
148
+ :aria-label="`Слайд ${i + 1}`"
149
+ :aria-current="index === i"
150
+ class="relative h-[6px] cursor-pointer overflow-hidden rounded-full bg-brand-200 transition-all duration-300 dark:bg-brand-500/30"
151
+ :class="index === i ? 'w-[30px]' : 'w-[20px]'"
152
+ @click="goTo(i)"
153
+ >
154
+ <span
155
+ v-if="index === i && running"
156
+ :key="tick"
157
+ class="a-slider-progress absolute inset-0 rounded-full bg-brand"
158
+ :style="timingStyle"
159
+ />
160
+ </button>
161
+ </div>
162
+ </div>
163
+ </template>
164
+
165
+ <style scoped>
166
+ .a-slider-clock {
167
+ position: absolute;
168
+ height: 1px;
169
+ opacity: 0;
170
+ pointer-events: none;
171
+ }
172
+
173
+ .a-slider-clock,
174
+ .a-slider-progress {
175
+ animation: a-slider-run linear forwards;
176
+ }
177
+
178
+ @keyframes a-slider-run {
179
+ from { width: 0; }
180
+ to { width: 100%; }
181
+ }
182
+ </style>
@@ -114,7 +114,7 @@ createStars(shouldRound.value)
114
114
  <div class="w-full flex items-center gap-2">
115
115
  <span
116
116
  v-if="ratingPlacement === 'left' && !hideValue"
117
- class="text-gray-600 dark:text-gray-300 mt-px"
117
+ class="text-quaternary mt-px"
118
118
  :style="{fontSize: `${fontSize}px`}"
119
119
  >
120
120
  {{ modelValue }}
@@ -136,7 +136,7 @@ createStars(shouldRound.value)
136
136
  </div>
137
137
  <span
138
138
  v-if="ratingPlacement === 'right' && !hideValue"
139
- class="text-sm text-gray-600 dark:text-gray-300 mt-px"
139
+ class="text-body-md text-quaternary mt-px"
140
140
  >
141
141
  {{ modelValue }}
142
142
  </span>
@@ -34,37 +34,41 @@ const props = withDefaults(defineProps<Props>(), {
34
34
 
35
35
  const typeSwitchValues: ViewType = {
36
36
  default: {
37
- primary: 'bg-[#068DFF] text-white border-transparent dark:bg-[#068DFF]/30 dark:text-blue-100',
38
- success: 'bg-[#00A63E] text-white border-transparent dark:bg-[#00A63E]/30 dark:text-green-100',
39
- danger: 'bg-[#E7000B] text-white border-transparent dark:bg-[#E7000B]/30 dark:text-red-100',
40
- warning: 'bg-[#E17100] text-white border-transparent dark:bg-[#E17100]/30 dark:text-orange-100',
41
- gray: 'bg-[#4A5565] text-white border-transparent dark:bg-[#4A5565]/30 dark:text-gray-100',
37
+ primary: 'bg-brand text-white border-transparent',
38
+ success: 'bg-success text-white border-transparent',
39
+ danger: 'bg-danger text-white border-transparent',
40
+ warning: 'bg-warning text-white border-transparent',
41
+ /* solid-серый бейдж: токена нет, константный примитив */
42
+ gray: 'bg-gray-600 text-white border-transparent',
42
43
  },
43
44
  inverted: {
44
- primary: 'bg-[#F0F8FF] text-[#068DFF] border-transparent dark:bg-[#068DFF]/10 dark:text-blue-400',
45
- success: 'bg-[#DCFCE7] text-[#008236] border-transparent dark:bg-[#00A63E]/10 dark:text-green-400',
46
- danger: 'bg-[#FFE2E2] text-[#C10007] border-transparent dark:bg-[#E7000B]/10 dark:text-red-400',
47
- warning: 'bg-[#FEF3C6] text-[#9A5800] border-transparent dark:bg-[#E17100]/10 dark:text-orange-400',
48
- gray: 'bg-[#F3F4F6] text-[#364153] border-transparent dark:bg-[#4A5565]/10 dark:text-gray-300',
45
+ primary: 'bg-brand-subtle text-brand border-transparent',
46
+ success: 'bg-success-subtle text-success border-transparent',
47
+ danger: 'bg-danger-subtle text-danger border-transparent',
48
+ warning: 'bg-warning-subtle text-warning border-transparent',
49
+ gray: 'bg-muted text-quaternary border-transparent',
49
50
  },
51
+ /* бордеры: для brand/green/yellow пастельных токенов нет — примитивы осознанно */
50
52
  transparent: {
51
- primary: 'bg-white border-[#B3DCFF] text-[#0066BD] dark:bg-transparent dark:border-[#068DFF]/50 dark:text-blue-400',
52
- success: 'bg-white border-[#7BF1A8] text-[#008236] dark:bg-transparent dark:border-[#00A63E]/50 dark:text-green-400',
53
- danger: 'bg-white border-[#FFA2A2] text-[#C10007] dark:bg-transparent dark:border-[#E7000B]/50 dark:text-red-400',
54
- warning: 'bg-white border-[#FFD230] text-[#9A5800] dark:bg-transparent dark:border-[#E17100]/50 dark:text-orange-400',
55
- gray: 'bg-white border-[#D1D5DC] text-[#364153] dark:bg-transparent dark:border-[#4A5565]/50 dark:text-gray-300',
53
+ primary: 'bg-main border-brand-200 text-brand dark:bg-transparent',
54
+ success: 'bg-main border-green-300 text-success dark:bg-transparent',
55
+ danger: 'bg-main border-red text-danger dark:bg-transparent',
56
+ warning: 'bg-main border-yellow-300 text-warning dark:bg-transparent',
57
+ gray: 'bg-main border-strong text-quaternary dark:bg-transparent',
56
58
  },
59
+ /* тинты и пастельные бордеры subtle-вью: токенов нет — примитивы + dark:-пары осознанно */
57
60
  subtle: {
58
- primary: 'bg-[#068DFF]/5 border-[#B3DCFF] text-[#068DFF] dark:bg-blue-500/10 dark:border-[#068DFF]/40 dark:text-blue-400',
59
- success: 'bg-[#00A63E]/5 border-[#7BF1A8] text-[#00A63E] dark:bg-green-500/10 dark:border-[#00A63E]/40 dark:text-green-400',
60
- danger: 'bg-[#E7000B]/5 border-[#FFA2A2] text-[#E7000B] dark:bg-red-500/10 dark:border-[#E7000B]/40 dark:text-red-400',
61
- warning: 'bg-[#E17100]/5 border-[#FFD230] text-[#E17100] dark:bg-yellow-500/10 dark:border-[#E17100]/40 dark:text-orange-400',
62
- gray: 'bg-[#4A5565]/5 border-[#D1D5DC] text-[#4A5565] dark:bg-gray-500/10 dark:border-[#4A5565]/40 dark:text-gray-300',
61
+ primary: 'bg-brand-500/5 border-brand-200 text-brand dark:bg-brand-500/10 dark:border-brand-500/40',
62
+ success: 'bg-green-600/5 border-green-300 text-success dark:bg-green-500/10 dark:border-green-600/40',
63
+ danger: 'bg-red-600/5 border-red text-danger dark:bg-red-500/10 dark:border-red-600/40',
64
+ warning: 'bg-amber-600/5 border-yellow-300 text-warning dark:bg-yellow-500/10 dark:border-amber-600/40',
65
+ gray: 'bg-gray-600/5 border-strong text-quaternary dark:bg-gray-500/10 dark:border-gray-600/40',
63
66
  },
64
67
  }
65
68
 
66
69
  const pointSwitchValues: ViewType = {
67
70
  default: {
71
+ /* белая точка на цветной плашке — осознанно константный white */
68
72
  primary: 'bg-white',
69
73
  success: 'bg-white',
70
74
  danger: 'bg-white',
@@ -72,25 +76,25 @@ const pointSwitchValues: ViewType = {
72
76
  gray: 'bg-white',
73
77
  },
74
78
  inverted: {
75
- primary: 'bg-[#068DFF] dark:bg-blue-400',
76
- success: 'bg-[#00A63E] dark:bg-green-400',
77
- danger: 'bg-[#E7000B] dark:bg-red-400',
78
- warning: 'bg-[#E17100] dark:bg-orange-400',
79
- gray: 'bg-[#6A7282] dark:bg-gray-300',
79
+ primary: 'bg-brand',
80
+ success: 'bg-success',
81
+ danger: 'bg-danger',
82
+ warning: 'bg-warning',
83
+ gray: 'bg-icon-default',
80
84
  },
81
85
  transparent: {
82
- primary: 'bg-[#068DFF] dark:bg-blue-400',
83
- success: 'bg-[#00A63E] dark:bg-green-400',
84
- danger: 'bg-[#E7000B] dark:bg-red-400',
85
- warning: 'bg-[#E17100] dark:bg-orange-400',
86
- gray: 'bg-[#6A7282] dark:bg-gray-300',
86
+ primary: 'bg-brand',
87
+ success: 'bg-success',
88
+ danger: 'bg-danger',
89
+ warning: 'bg-warning',
90
+ gray: 'bg-icon-default',
87
91
  },
88
92
  subtle: {
89
- primary: 'bg-[#068DFF] dark:bg-blue-400',
90
- success: 'bg-[#00A63E] dark:bg-green-400',
91
- danger: 'bg-[#E7000B] dark:bg-red-400',
92
- warning: 'bg-[#E17100] dark:bg-orange-400',
93
- gray: 'bg-[#6A7282] dark:bg-gray-300',
93
+ primary: 'bg-brand',
94
+ success: 'bg-success',
95
+ danger: 'bg-danger',
96
+ warning: 'bg-warning',
97
+ gray: 'bg-icon-default',
94
98
  },
95
99
  }
96
100
 
@@ -100,7 +104,7 @@ const classes = computed(() =>
100
104
  typeSwitchValues[props.view][props.type],
101
105
  props.size === 'xs' ? 'px-2 py-[2px] text-body-sm font-bold' : '',
102
106
  props.size === 'sm' ? 'px-[10px] py-1 text-body-sm font-semibold h-6' : '',
103
- props.size === 'md' ? 'px-3 py-[6x] text-body-sm font-semibold h-7' : '',
107
+ props.size === 'md' ? 'px-3 py-[6px] text-body-sm font-semibold h-7' : '',
104
108
  props.size === 'lg' ? 'px-4 py-[6px] font-semibold' : '',
105
109
  ])
106
110
 
@@ -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
- stopTicker()
93
+ if (!props.pauseOnHover) return
94
+ isPaused.value = true
95
+ stopTicker()
93
96
  }
94
97
 
95
98
  function onMouseLeave() {
96
- if (props.pauseOnHover)
97
- startTicker()
99
+ if (!props.pauseOnHover) return
100
+ isPaused.value = false
101
+ startTicker()
98
102
  }
99
103
 
100
104
  onMounted(startTicker)
@@ -106,43 +110,55 @@ 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-4 lg:gap-10"
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-3">
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-2xl border bg-white transition-all duration-300"
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-blue-200'
120
- : 'border-gray-200 hover:border-blue-100'"
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-4"
135
+ class="flex gap-[13px]"
126
136
  :class="expandable ? 'items-center' : 'items-start'"
127
137
  >
128
138
  <span
129
- class="flex size-11 shrink-0 items-center justify-center rounded-xl"
130
- :class="step.iconBg || 'bg-blue-50'"
139
+ class="flex size-10 shrink-0 items-center justify-center rounded-[12px]"
140
+ :class="step.iconBg || 'bg-brand-subtle'"
131
141
  >
132
142
  <component
133
143
  :is="step.icon"
134
144
  v-if="step.icon"
135
145
  class="size-5"
136
- :class="step.iconColor || 'text-blue-600'"
146
+ :class="step.iconColor || 'text-brand'"
137
147
  />
138
148
  </span>
139
149
  <div class="min-w-0 flex-1">
140
- <p class="text-body-md-strong md:text-body-lg-strong text-gray-900">
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 class="mt-1 text-body-sm text-gray-500">
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-gray-500">
191
+ <p class="text-body-sm text-quaternary">
176
192
  {{ step.description }}
177
193
  </p>
178
194
  <div
@@ -194,39 +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
- class="absolute inset-x-0 bottom-0 h-1 bg-gray-100"
200
- >
201
- <span
202
- class="block h-full rounded-r-full bg-gradient-to-r from-blue-600 to-blue-400 transition-[width] duration-100 ease-linear"
203
- :style="{ width: fillWidth }"
204
- />
205
- </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
+ />
206
224
  </li>
207
225
  </ol>
208
226
 
209
- <div
210
- @mouseenter="onMouseEnter"
211
- @mouseleave="onMouseLeave"
212
- >
213
- <div class="flex justify-center">
214
- <slot
215
- name="panel"
216
- :active="active"
217
- :step="steps[active]"
218
- :progress="progress"
219
- :count="steps.length"
220
- :fill-width="fillWidth"
221
- :go-to="goTo"
222
- />
223
- </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
+ />
224
237
  </div>
225
238
  </div>
226
239
  </template>
227
240
 
228
241
  <style scoped>
229
242
  .ss-card-active {
230
- box-shadow: 0 22px 60px -18px rgb(6 141 255 / 22%);
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
+ }
231
269
  }
232
270
  </style>