adata-ui 2.1.40-beta.10 → 2.1.40-beta.12

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 (139) hide show
  1. package/.claude/settings.local.json +19 -0
  2. package/assets/styles/index.scss +67 -5
  3. package/components/elements/a-select-row/ASelectRowV2.vue +8 -8
  4. package/components/elements/a-select-row/index.vue +3 -5
  5. package/components/elements/accordion/AAccordion.vue +5 -3
  6. package/components/elements/accordion/AAccordionGroup/AAccordionGroup.vue +3 -3
  7. package/components/elements/alert/AAlert.vue +34 -47
  8. package/components/elements/bg-block/ABgBlock.vue +1 -1
  9. package/components/elements/button/AButton.vue +3 -3
  10. package/components/elements/button/AButtonV2.vue +7 -5
  11. package/components/elements/button-login/index.vue +1 -1
  12. package/components/elements/chip-wrapper/AChipWrapper.vue +1 -1
  13. package/components/elements/chips/AChips.vue +2 -2
  14. package/components/elements/digit-badge/ADigitBadge.vue +21 -19
  15. package/components/elements/feature-description/AFeatureDescription.vue +1 -1
  16. package/components/elements/leave-note/ALeaveNote.vue +1 -1
  17. package/components/elements/pagination/APagination.vue +7 -7
  18. package/components/elements/segmented/ASegmentedV2.vue +103 -10
  19. package/components/elements/select/ASelect.vue +4 -4
  20. package/components/elements/select/ASelectMobile.vue +2 -2
  21. package/components/elements/select/ASelectV2.vue +10 -11
  22. package/components/elements/select/ui/select-button.vue +1 -1
  23. package/components/elements/status-badge/AStatusBadge.vue +22 -19
  24. package/components/elements/status-badge-v2/StatusBadgeV2.vue +1 -3
  25. package/components/elements/table/ATable.vue +1 -1
  26. package/components/elements/table/table.config.ts +2 -2
  27. package/components/elements/tree-select/ATreeSelect.vue +97 -113
  28. package/components/elements/tree-select/TreeService.ts +142 -207
  29. package/components/elements/tree-select/components/ATreeSelectNode.vue +104 -0
  30. package/components/elements/tree-select/types.ts +40 -11
  31. package/components/elements/tree-select/utils.ts +30 -0
  32. package/components/elements/tree-select-modal/ATreeSelectModal.vue +217 -0
  33. package/components/features/color-mode/AColorMode.client.vue +1 -1
  34. package/components/features/dropdown/ADropdownV2.vue +1 -2
  35. package/components/features/lang-switcher/lang-switcher.vue +9 -4
  36. package/components/features/payment/banner/BasicPlusLimitBanner.vue +3 -3
  37. package/components/features/payment/banner/PaymentBanner.vue +3 -3
  38. package/components/features/payment/banner/UpSellBanner.vue +3 -3
  39. package/components/features/payment/process/PaymentKaspiQrSidePanel.vue +43 -27
  40. package/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue +34 -23
  41. package/components/features/payment/process/PaymentMethodSidePanel.vue +61 -49
  42. package/components/features/payment/process/PaymentProcess.vue +6 -6
  43. package/components/features/payment/process/PaymentTopUpSidePanel.vue +44 -63
  44. package/components/features/pk-mobile-services/APkMobileServices.vue +1 -1
  45. package/components/features//321/201hange-version/AChangeVersion.vue +2 -2
  46. package/components/forms/checkbox/ACheckbox.vue +1 -1
  47. package/components/forms/checkbox/ACheckboxV2.vue +5 -5
  48. package/components/forms/input/AInputV2.vue +4 -4
  49. package/components/forms/input/date/AInputDate.vue +2 -2
  50. package/components/forms/input/password/AInputPassword.vue +8 -2
  51. package/components/forms/input/standard/AInputStandard.vue +3 -3
  52. package/components/forms/input/textarea/ATextarea.vue +2 -2
  53. package/components/forms/toggle/AToggle.vue +2 -3
  54. package/components/forms/toggle/AToggleV2.vue +3 -3
  55. package/components/modals/AnotherDeviceModal.vue +1 -1
  56. package/components/modals/ContactsMobileModel.vue +1 -1
  57. package/components/modals/ContentNavigationModal.vue +77 -333
  58. package/components/modals/Insufficient-funds-modal.vue +1 -1
  59. package/components/modals/PaymentMethodModal.vue +1 -1
  60. package/components/modals/id/IdBanner.vue +3 -3
  61. package/components/modals/id/IdRecoveryModal.vue +1 -1
  62. package/components/navigation/bottom-navigation/ABottomNavigation.vue +1 -1
  63. package/components/navigation/breadcrumbs/ABreadcrumbs.vue +106 -45
  64. package/components/navigation/breadcrumbs/types.ts +3 -0
  65. package/components/navigation/footer/AFooter.vue +39 -40
  66. package/components/navigation/footer/ui/a-footer-accordion.vue +9 -9
  67. package/components/navigation/header/AHeader.vue +13 -19
  68. package/components/navigation/header/AlmatyContacts.vue +78 -78
  69. package/components/navigation/header/CardGallery.vue +4 -4
  70. package/components/navigation/header/HeaderUsage.vue +4 -6
  71. package/components/navigation/header/ListItem.vue +2 -2
  72. package/components/navigation/header/NavCard.vue +1 -1
  73. package/components/navigation/header/NavList.vue +2 -2
  74. package/components/navigation/header/NotificationsMenu.vue +2 -3
  75. package/components/navigation/header/ProductMenu.vue +7 -7
  76. package/components/navigation/header/ProfileMenu.vue +26 -35
  77. package/components/navigation/header/SystemNotification.vue +1 -3
  78. package/components/navigation/pill-tabs/APillTabs.vue +2 -2
  79. package/components/navigation/pill-tabs/APillTabsV2.vue +22 -6
  80. package/components/overlays/drawer/ADrawerV2.vue +335 -0
  81. package/components/overlays/modal/AModal.vue +4 -4
  82. package/components/overlays/modal/AModalV2.vue +7 -4
  83. package/components/overlays/side-panel/ASidePanel.vue +6 -6
  84. package/components/overlays/sideover/ASlideover.vue +6 -6
  85. package/components/overlays/tooltip/ATooltip.vue +1 -1
  86. package/components/overlays/tooltip/ATooltipV2.vue +2 -12
  87. package/components/transitions/ATransitionHeight.vue +1 -1
  88. package/composables/useHeaderNavigationLinks.ts +100 -94
  89. package/icons/archive.vue +16 -0
  90. package/icons/arrow/arrows-in.vue +11 -0
  91. package/icons/arrow/arrows-out.vue +11 -0
  92. package/icons/arrow/arrows-resize-in.vue +38 -0
  93. package/icons/arrow/arrows-resize-out.vue +17 -0
  94. package/icons/bot.vue +52 -0
  95. package/icons/clock-time.vue +24 -0
  96. package/icons/compare-outlined.vue +8 -0
  97. package/icons/dots-horizontal.vue +31 -0
  98. package/icons/download-line.vue +13 -0
  99. package/icons/egov.vue +41 -0
  100. package/icons/elicense.vue +38 -0
  101. package/icons/favourite-bookmark-outline.vue +17 -0
  102. package/icons/file-pen.vue +31 -0
  103. package/icons/file-stack.vue +31 -0
  104. package/icons/file-types/excel.vue +131 -0
  105. package/icons/file-types/html.vue +13 -0
  106. package/icons/file-types/jpeg.vue +16 -0
  107. package/icons/file-types/pdf.vue +11 -0
  108. package/icons/file-types/png.vue +11 -0
  109. package/icons/file-types/rar.vue +11 -0
  110. package/icons/file-types/word.vue +50 -0
  111. package/icons/file-types/zip.vue +11 -0
  112. package/icons/git-compare.vue +38 -0
  113. package/icons/graduation-cap.vue +31 -0
  114. package/icons/graph-loading.vue +34 -0
  115. package/icons/help-question-circle.vue +26 -0
  116. package/icons/in-row-type.vue +46 -0
  117. package/icons/in-table-type.vue +29 -0
  118. package/icons/message-dotted.vue +30 -0
  119. package/icons/notification-error.vue +17 -0
  120. package/icons/person.vue +22 -0
  121. package/icons/settings.vue +26 -0
  122. package/icons/shield-alert.vue +31 -0
  123. package/icons/socials/facebook-color.vue +16 -0
  124. package/icons/socials/globe-color.vue +16 -0
  125. package/icons/socials/instagram-color.vue +46 -0
  126. package/icons/socials/linkedin-color.vue +14 -0
  127. package/icons/socials/telegram-color.vue +16 -0
  128. package/icons/socials/tiktok-color.vue +14 -0
  129. package/icons/socials/vk-color.vue +16 -0
  130. package/icons/socials/youtube-color.vue +16 -0
  131. package/icons/view-eye-open.vue +13 -0
  132. package/lang/en.ts +1 -0
  133. package/lang/kk.ts +1 -0
  134. package/lang/ru.ts +1 -0
  135. package/package.json +1 -1
  136. package/plugins/toast.client.ts +38 -55
  137. package/tailwind.config.ts +147 -116
  138. package/utils/twMerge.ts +34 -0
  139. package/components/elements/tree-select/components/tree-select-nodes.vue +0 -91
@@ -18,18 +18,22 @@ const props = withDefaults(defineProps<{
18
18
  block?: boolean
19
19
  disabled?: boolean
20
20
  size?: 'sm' | 'md'
21
+ scrollIntoView?: boolean
21
22
  }>(), {
22
23
  showCount: false,
23
24
  block: false,
24
25
  disabled: false,
25
26
  size: 'sm',
27
+ scrollIntoView: false,
26
28
  })
27
29
 
28
30
  const emit = defineEmits<{ (e: 'update:modelValue', value: string): void }>()
29
31
 
32
+ const listRef = ref<HTMLElement | null>(null)
33
+
30
34
  const SIZE_CLASS: Record<'sm' | 'md', string> = {
31
- sm: 'text-xs',
32
- md: 'text-sm',
35
+ sm: 'text-body-sm',
36
+ md: 'text-body-md',
33
37
  }
34
38
 
35
39
  const COUNT_COLOR_CLASS: Record<CountColor, string> = {
@@ -55,11 +59,22 @@ function select(option: PillTab) {
55
59
  if (isDisabled(option)) return
56
60
  emit('update:modelValue', option.key)
57
61
  }
62
+
63
+ function scrollActiveIntoView() {
64
+ if (!props.scrollIntoView) return
65
+ nextTick(() => {
66
+ const active = listRef.value?.querySelector<HTMLElement>('[aria-selected="true"]')
67
+ active?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' })
68
+ })
69
+ }
70
+
71
+ watch(() => props.modelValue, scrollActiveIntoView)
72
+ onMounted(scrollActiveIntoView)
58
73
  </script>
59
74
 
60
75
  <template>
61
76
  <div
62
- class="pill-tabs-v2 min-w-0 max-w-full rounded-xl border border-gray-200 bg-gray-50 p-1 dark:border-white/10 dark:bg-white/[0.03]"
77
+ class="pill-tabs-v2 min-w-0 max-w-full rounded-lg border border-gray-200 bg-gray-50 p-1 dark:border-white/10 dark:bg-white/[0.03]"
63
78
  :class="[
64
79
  block ? 'w-full' : 'w-fit',
65
80
  disabled ? 'pill-tabs-v2--disabled opacity-60' : '',
@@ -67,6 +82,7 @@ function select(option: PillTab) {
67
82
  :aria-disabled="disabled || undefined"
68
83
  >
69
84
  <div
85
+ ref="listRef"
70
86
  role="tablist"
71
87
  :aria-label="ariaLabel"
72
88
  class="pill-tabs-v2__list flex w-full flex-nowrap items-center gap-1 overflow-x-auto"
@@ -80,13 +96,13 @@ function select(option: PillTab) {
80
96
  :aria-disabled="isDisabled(option) || undefined"
81
97
  :disabled="isDisabled(option)"
82
98
  :tabindex="modelValue === option.key ? 0 : -1"
83
- class="inline-flex items-center gap-1.5 whitespace-nowrap rounded-lg px-3 py-1.5 font-medium transition-colors duration-150"
99
+ class="inline-flex items-center gap-1.5 whitespace-nowrap rounded-md px-3 py-1.5 font-medium transition-colors duration-150"
84
100
  :class="[
85
101
  SIZE_CLASS[size],
86
102
  isDisabled(option)
87
103
  ? 'cursor-not-allowed text-gray-300 dark:text-gray-600'
88
104
  : modelValue === option.key
89
- ? 'text-deepblue-900 bg-white shadow-sm dark:bg-gray-700 dark:text-gray-100 dark:shadow-none dark:ring-1 dark:ring-inset dark:ring-white/10'
105
+ ? 'bg-white text-deepblue-900 shadow-sm dark:bg-gray-700 dark:text-gray-100 dark:shadow-none dark:ring-1 dark:ring-inset dark:ring-white/10'
90
106
  : 'text-gray-700 hover:bg-white/70 hover:text-gray-900 dark:text-gray-200 dark:hover:bg-white/[0.06] dark:hover:text-gray-100',
91
107
  block ? 'flex-1 basis-0 justify-center' : 'shrink-0',
92
108
  ]"
@@ -97,7 +113,7 @@ function select(option: PillTab) {
97
113
 
98
114
  <span
99
115
  v-if="showCount && !option.hideCount"
100
- class="inline-flex min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-xs font-semibold leading-5"
116
+ class="inline-flex min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-body-sm font-semibold leading-5"
101
117
  :class="COUNT_COLOR_CLASS[option.countColor ?? 'gray']"
102
118
  >
103
119
  {{ option.count }}
@@ -0,0 +1,335 @@
1
+ <script setup lang="ts">
2
+ import { onKeyStroke, useScrollLock } from '@vueuse/core'
3
+
4
+ const props = withDefaults(defineProps<{
5
+ title?: string
6
+ closeOnOverlay?: boolean
7
+ closeOnEsc?: boolean
8
+ lockScroll?: boolean
9
+ persistent?: boolean
10
+ transition?: boolean
11
+ contentClass?: string
12
+ hideHeader?: boolean
13
+ blur?: boolean | 'sm' | 'md' | 'lg' | 'xl'
14
+ swipeToClose?: boolean
15
+ swipeThreshold?: number
16
+ showDragHandle?: boolean
17
+ maxHeight?: string
18
+ }>(), {
19
+ closeOnOverlay: true,
20
+ closeOnEsc: true,
21
+ lockScroll: true,
22
+ persistent: false,
23
+ transition: true,
24
+ hideHeader: false,
25
+ blur: false,
26
+ swipeToClose: true,
27
+ swipeThreshold: 65,
28
+ showDragHandle: true,
29
+ maxHeight: '100dvh',
30
+ })
31
+
32
+ const emit = defineEmits<{
33
+ (e: 'close'): void
34
+ (e: 'open'): void
35
+ }>()
36
+
37
+ const open = defineModel<boolean>({ required: true })
38
+
39
+ const contentRef = ref<HTMLElement | null>(null)
40
+ const overlayRef = ref<HTMLElement | null>(null)
41
+ const swipeClosing = ref(false)
42
+ const bodyScrollLocked = useScrollLock(import.meta.client ? document.body : null)
43
+
44
+ const blurClass = computed(() => {
45
+ if (!props.blur) return ''
46
+
47
+ switch (props.blur) {
48
+ case 'sm': return 'backdrop-blur-sm'
49
+ case 'md': return 'backdrop-blur-md'
50
+ case 'lg': return 'backdrop-blur-lg'
51
+ case 'xl': return 'backdrop-blur-xl'
52
+ default: return 'backdrop-blur'
53
+ }
54
+ })
55
+
56
+ const overlayClass = computed(() => {
57
+ const base = ['drawer-v2-overlay fixed inset-0 z-[10000] flex items-end justify-stretch bg-black/40 dark:bg-black/60']
58
+ if (blurClass.value) base.push(blurClass.value)
59
+ return base.join(' ')
60
+ })
61
+
62
+ const contentStyle = computed(() => ({ maxHeight: props.maxHeight }))
63
+
64
+ const overlayTransitionName = computed(() => {
65
+ if (swipeClosing.value) return ''
66
+ return props.transition ? 'drawer-v2-overlay' : ''
67
+ })
68
+ const contentTransitionName = computed(() => {
69
+ if (swipeClosing.value || !props.transition) return ''
70
+ return 'drawer-v2-sheet'
71
+ })
72
+
73
+ function closeIfAllowed() {
74
+ if (props.persistent) return
75
+ open.value = false
76
+ }
77
+
78
+ function onOverlayClick(event: MouseEvent) {
79
+ if (!props.closeOnOverlay || props.persistent) return
80
+ if (event.target === event.currentTarget) {
81
+ open.value = false
82
+ }
83
+ }
84
+
85
+ onKeyStroke('Escape', () => {
86
+ if (!open.value) return
87
+ if (!props.closeOnEsc || props.persistent) return
88
+ open.value = false
89
+ })
90
+
91
+ function setScrollbarCompensation(active: boolean) {
92
+ if (!import.meta.client) return
93
+
94
+ if (active) {
95
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth
96
+ document.body.style.paddingRight = scrollbarWidth > 0 ? `${scrollbarWidth}px` : ''
97
+ }
98
+ else {
99
+ document.body.style.paddingRight = ''
100
+ }
101
+ }
102
+
103
+ watch(open, (value) => {
104
+ if (props.lockScroll) {
105
+ if (value) setScrollbarCompensation(true)
106
+ bodyScrollLocked.value = value
107
+ if (!value) setScrollbarCompensation(false)
108
+ }
109
+
110
+ if (value) emit('open')
111
+ else emit('close')
112
+ })
113
+
114
+ onBeforeUnmount(() => {
115
+ if (bodyScrollLocked.value) {
116
+ bodyScrollLocked.value = false
117
+ }
118
+ setScrollbarCompensation(false)
119
+ })
120
+
121
+ const dragging = ref(false)
122
+ const dragStartY = ref(0)
123
+ const dragDelta = ref(0)
124
+
125
+ function canSwipe() {
126
+ return props.swipeToClose && !props.persistent
127
+ }
128
+
129
+ function setTransform(value: string) {
130
+ if (contentRef.value) {
131
+ contentRef.value.style.transform = value
132
+ }
133
+ }
134
+
135
+ function onTouchStart(event: TouchEvent) {
136
+ if (!canSwipe()) return
137
+ dragging.value = true
138
+ dragStartY.value = event.touches[0].clientY
139
+ dragDelta.value = 0
140
+
141
+ if (contentRef.value) {
142
+ contentRef.value.style.transition = 'none'
143
+ }
144
+ }
145
+
146
+ function onTouchMove(event: TouchEvent) {
147
+ if (!dragging.value || !canSwipe()) return
148
+
149
+ const delta = event.touches[0].clientY - dragStartY.value
150
+ if (delta < 0) {
151
+ dragDelta.value = 0
152
+ setTransform('')
153
+ return
154
+ }
155
+
156
+ dragDelta.value = delta
157
+ setTransform(`translateY(${delta}px)`)
158
+ }
159
+
160
+ function prefersReducedMotion() {
161
+ return import.meta.client && window.matchMedia('(prefers-reduced-motion: reduce)').matches
162
+ }
163
+
164
+ function animateClose() {
165
+ const content = contentRef.value
166
+
167
+ if (!content || prefersReducedMotion()) {
168
+ open.value = false
169
+ return
170
+ }
171
+
172
+ swipeClosing.value = true
173
+
174
+ let done = false
175
+ const finish = () => {
176
+ if (done) return
177
+ done = true
178
+ content.removeEventListener('transitionend', onTransitionEnd)
179
+ open.value = false
180
+ swipeClosing.value = false
181
+ }
182
+
183
+ function onTransitionEnd(event: TransitionEvent) {
184
+ if (event.target === content && event.propertyName === 'transform') {
185
+ finish()
186
+ }
187
+ }
188
+
189
+ content.addEventListener('transitionend', onTransitionEnd)
190
+ setTimeout(finish, 320)
191
+
192
+ requestAnimationFrame(() => {
193
+ content.style.transition = 'transform 260ms cubic-bezier(0.22, 1, 0.36, 1)'
194
+ content.style.transform = 'translateY(100%)'
195
+
196
+ if (overlayRef.value) {
197
+ overlayRef.value.style.transition = 'opacity 260ms ease'
198
+ overlayRef.value.style.opacity = '0'
199
+ }
200
+ })
201
+ }
202
+
203
+ function onTouchEnd() {
204
+ if (!dragging.value) return
205
+ dragging.value = false
206
+
207
+ const shouldClose = dragDelta.value > props.swipeThreshold && canSwipe()
208
+
209
+ if (shouldClose) {
210
+ animateClose()
211
+ }
212
+ else if (contentRef.value) {
213
+ contentRef.value.style.transition = 'transform 220ms cubic-bezier(0.22, 1, 0.36, 1)'
214
+ contentRef.value.style.transform = ''
215
+ }
216
+
217
+ dragDelta.value = 0
218
+ }
219
+ </script>
220
+
221
+ <template>
222
+ <client-only>
223
+ <teleport to="body">
224
+ <transition :name="overlayTransitionName">
225
+ <div
226
+ v-if="open"
227
+ ref="overlayRef"
228
+ :class="overlayClass"
229
+ @mousedown="onOverlayClick"
230
+ >
231
+ <transition :name="contentTransitionName" appear>
232
+ <div
233
+ v-if="open"
234
+ ref="contentRef"
235
+ class="drawer-v2-content flex w-full max-w-none flex-col overflow-hidden rounded-t-xl border-t border-gray-200 bg-white shadow-2xl dark:border-gray-800 dark:bg-gray-900"
236
+ :style="contentStyle"
237
+ @mousedown.stop
238
+ >
239
+ <div
240
+ v-if="showDragHandle"
241
+ class="flex shrink-0 cursor-grab touch-none justify-center py-2"
242
+ @touchstart.passive="onTouchStart"
243
+ @touchmove="onTouchMove"
244
+ @touchend="onTouchEnd"
245
+ @touchcancel="onTouchEnd"
246
+ >
247
+ <div class="h-1 w-10 rounded-full bg-gray-300 dark:bg-gray-600" />
248
+ </div>
249
+
250
+ <header
251
+ v-if="!hideHeader && (title || $slots.header)"
252
+ class="flex shrink-0 items-center justify-between gap-3 border-b border-gray-200 px-5 py-4 dark:border-gray-800"
253
+ @touchstart.passive="onTouchStart"
254
+ @touchmove="onTouchMove"
255
+ @touchend="onTouchEnd"
256
+ @touchcancel="onTouchEnd"
257
+ >
258
+ <slot name="header">
259
+ <h2 class="text-base font-semibold text-gray-900 dark:text-gray-100">
260
+ {{ title }}
261
+ </h2>
262
+ <button
263
+ type="button"
264
+ class="rounded-sm p-1 text-gray-500 transition hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-800 dark:hover:text-gray-200"
265
+ @click="closeIfAllowed"
266
+ >
267
+ <a-icon-x-mark class="size-4" />
268
+ </button>
269
+ </slot>
270
+ </header>
271
+
272
+ <div class="min-h-0 flex-1 overflow-auto" :class="contentClass">
273
+ <slot :close="closeIfAllowed" />
274
+ </div>
275
+
276
+ <footer
277
+ v-if="$slots.footer"
278
+ class="shrink-0 border-t border-gray-200 px-5 py-4 dark:border-gray-800"
279
+ >
280
+ <slot name="footer" :close="closeIfAllowed" />
281
+ </footer>
282
+ </div>
283
+ </transition>
284
+ </div>
285
+ </transition>
286
+ </teleport>
287
+ </client-only>
288
+ </template>
289
+
290
+ <style scoped lang="scss">
291
+ .drawer-v2-overlay {
292
+ will-change: opacity;
293
+ }
294
+
295
+ .drawer-v2-content {
296
+ will-change: transform;
297
+ transform: translateZ(0);
298
+ backface-visibility: hidden;
299
+ }
300
+
301
+ .drawer-v2-overlay-enter-active {
302
+ transition: opacity 240ms ease-out;
303
+ }
304
+
305
+ .drawer-v2-overlay-leave-active {
306
+ transition: opacity 220ms ease-in;
307
+ }
308
+
309
+ .drawer-v2-overlay-enter-from,
310
+ .drawer-v2-overlay-leave-to {
311
+ opacity: 0;
312
+ }
313
+
314
+ .drawer-v2-sheet-enter-active {
315
+ transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
316
+ }
317
+
318
+ .drawer-v2-sheet-leave-active {
319
+ transition: transform 240ms cubic-bezier(0.4, 0, 1, 1);
320
+ }
321
+
322
+ .drawer-v2-sheet-enter-from,
323
+ .drawer-v2-sheet-leave-to {
324
+ transform: translate3d(0, 100%, 0);
325
+ }
326
+
327
+ @media (prefers-reduced-motion: reduce) {
328
+ .drawer-v2-overlay-enter-active,
329
+ .drawer-v2-overlay-leave-active,
330
+ .drawer-v2-sheet-enter-active,
331
+ .drawer-v2-sheet-leave-active {
332
+ transition: none;
333
+ }
334
+ }
335
+ </style>
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
 
3
- import { twJoin, twMerge } from 'tailwind-merge'
3
+ import { twJoin, twMerge } from '#adata-ui/utils/twMerge'
4
4
  import { onClickOutside, useWindowSize } from '@vueuse/core'
5
5
  import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'
6
6
 
@@ -22,13 +22,13 @@ const uiConfig = {
22
22
  position: 'top-1/2 left-1/2 translate-y-[-50%] translate-x-[-50%]',
23
23
  padding: "p-8",
24
24
  background: "bg-white dark:bg-gray-900",
25
- rounded: "rounded-lg",
25
+ rounded: "rounded-md",
26
26
  fullscreen: "w-screen h-screen rounded-none",
27
27
  mobile: {
28
28
  width: "w-screen",
29
29
  position: "bottom-0 left-0 transition-transform",
30
30
  padding: 'px-4 sm:pb-8 pb-4 pt-3',
31
- rounded: "rounded-t-2xl"
31
+ rounded: "rounded-t-xl"
32
32
  },
33
33
  transition: {
34
34
  desktop: {
@@ -297,7 +297,7 @@ watch(modelValue, async (newValue) => {
297
297
  >
298
298
  <h4
299
299
  v-if="title"
300
- class="heading-02 text-center"
300
+ class="text-h2 text-center"
301
301
  @touchmove="touchmove"
302
302
  @touchstart="touchstart"
303
303
  @touchend="touchend"
@@ -14,6 +14,7 @@ const props = withDefaults(defineProps<{
14
14
  transition?: boolean
15
15
  contentClass?: string
16
16
  hideHeader?: boolean
17
+ hideClose?: boolean
17
18
  blur?: boolean | 'sm' | 'md' | 'lg' | 'xl'
18
19
  mobileSheet?: boolean
19
20
  swipeToClose?: boolean
@@ -27,6 +28,7 @@ const props = withDefaults(defineProps<{
27
28
  persistent: false,
28
29
  transition: true,
29
30
  hideHeader: false,
31
+ hideClose: false,
30
32
  blur: false,
31
33
  mobileSheet: true,
32
34
  swipeToClose: true,
@@ -96,10 +98,10 @@ const contentBaseClass = computed(() => {
96
98
  const base = ['modal-v2-content flex flex-col overflow-hidden border bg-white shadow-2xl dark:bg-gray-900']
97
99
 
98
100
  if (isSheet.value) {
99
- base.push('w-full max-w-none max-h-[100dvh] rounded-t-2xl rounded-b-none border-x-0 border-b-0 border-t border-gray-200 dark:border-gray-800')
101
+ base.push('w-full max-w-none max-h-[100dvh] rounded-t-xl rounded-b-none border-x-0 border-b-0 border-t border-gray-200 dark:border-gray-800')
100
102
  }
101
103
  else {
102
- const radius = props.size === 'fullscreen' ? 'rounded-none' : 'rounded-2xl'
104
+ const radius = props.size === 'fullscreen' ? 'rounded-none' : 'rounded-xl'
103
105
  const widthCls = props.size === 'container'
104
106
  ? ' w-full max-w-screen-sm md:max-w-screen-md lg:max-w-screen-lg xl:max-w-screen-xl 2xl:max-w-screen-2xl'
105
107
  : ''
@@ -306,13 +308,14 @@ function onTouchEnd() {
306
308
  @touchcancel="onTouchEnd"
307
309
  >
308
310
  <slot name="header">
309
- <h2 v-if="title" class="text-base font-semibold text-gray-900 dark:text-gray-100">
311
+ <h2 v-if="title" class="text-h5 text-gray-900 dark:text-gray-100">
310
312
  {{ title }}
311
313
  </h2>
312
314
  </slot>
313
315
  <button
316
+ v-if="!hideClose"
314
317
  type="button"
315
- class="ml-auto rounded-md p-1 transition hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-gray-200"
318
+ class="ml-auto rounded-sm p-1 transition hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-gray-200"
316
319
  @click="closeIfAllowed"
317
320
  >
318
321
  <a-icon-x-mark class="size-4" />
@@ -128,10 +128,10 @@ watch(() => [modelValue.value, panel.value], (newP, oldP) => {
128
128
 
129
129
  const roundedClass = computed(() => {
130
130
  const classes = {
131
- left: "rounded-r-xl",
132
- right: "rounded-l-xl",
133
- top: "rounded-b-xl",
134
- bottom: "rounded-t-xl",
131
+ left: "rounded-r-lg",
132
+ right: "rounded-l-lg",
133
+ top: "rounded-b-lg",
134
+ bottom: "rounded-t-lg",
135
135
  }
136
136
 
137
137
  return classes[panelSide.value]
@@ -170,7 +170,7 @@ const modalHeight = ref(0)
170
170
  const touchstart = (event: TouchEvent) => {
171
171
  isClose.value = false
172
172
  positionStart.value = event.touches[0].clientY
173
- modalHeight.value = panel.value?.offsetHeight || 0 // Запоминаем текущую высоту модалки
173
+ modalHeight.value = panel.value?.offsetHeight || 0
174
174
  }
175
175
 
176
176
  const touchmove = (event: TouchEvent) => {
@@ -179,7 +179,7 @@ const touchmove = (event: TouchEvent) => {
179
179
  const touchPosition = event.touches[0].clientY
180
180
  const step = touchPosition - positionStart.value
181
181
 
182
- if (step < 0) return // предотвратить движение вверх
182
+ if (step < 0) return
183
183
 
184
184
  const newHeight = modalHeight.value - step
185
185
  panel.value.style.height = `${newHeight}px`
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
 
3
- import { twJoin, twMerge } from 'tailwind-merge'
3
+ import { twJoin, twMerge } from '#adata-ui/utils/twMerge'
4
4
  import { onClickOutside, useWindowSize } from '@vueuse/core'
5
5
  import {disableBodyScroll, enableBodyScroll} from "body-scroll-lock";
6
6
 
@@ -37,10 +37,10 @@ const uiConfig = {
37
37
  bottom: 'bottom-0 left-0 w-full'
38
38
  },
39
39
  rounded: {
40
- top: 'rounded-b-lg',
41
- bottom: 'rounded-t-lg',
42
- left: 'rounded-r-lg',
43
- right: 'rounded-l-lg'
40
+ top: 'rounded-b-md',
41
+ bottom: 'rounded-t-md',
42
+ left: 'rounded-r-md',
43
+ right: 'rounded-l-md'
44
44
  },
45
45
  fullscreen: 'w-screen h-screen rounded-none',
46
46
  transition: {
@@ -219,7 +219,7 @@ const modalHeight = ref(0)
219
219
  const touchstart = (event: TouchEvent) => {
220
220
  isClose.value = false
221
221
  positionStart.value = event.touches[0].clientY
222
- modalHeight.value = slideover.value?.offsetHeight || 0 // Запоминаем текущую высоту модалки
222
+ modalHeight.value = slideover.value?.offsetHeight || 0
223
223
  }
224
224
 
225
225
  const touchmove = (event: TouchEvent) => {
@@ -56,7 +56,7 @@ const baseClass = computed(() => {
56
56
  const color = props.errorParsing ? 'text-[#E74135] dark:text-[#F47E75]' : 'text-white dark:text-deepblue-900'
57
57
  const pad = props.size === 'sm' ? 'px-4 py-2' : 'px-4 py-4'
58
58
  const truncated = props.truncate ? 'truncate' : 'max-w-[530px] w-max'
59
- return ['text-xs font-normal absolute', bg, color, 'rounded-md', pad, truncated].join(' ')
59
+ return ['text-body-sm font-normal absolute', bg, color, 'rounded-sm', pad, truncated].join(' ')
60
60
  })
61
61
 
62
62
  /* --- positioning logic --- */
@@ -9,27 +9,20 @@ import {
9
9
  useFloating,
10
10
  } from '@floating-ui/vue'
11
11
  import { onClickOutside, onKeyStroke } from '@vueuse/core'
12
- import { twMerge } from 'tailwind-merge'
12
+ import { twMerge } from '#adata-ui/utils/twMerge'
13
13
  import { useTooltipTrigger } from './useTooltipTrigger'
14
14
 
15
15
  interface Props {
16
- /** Preferred side; auto-flips when there isn't room. */
17
16
  placement?: TooltipPlacement
18
- /** How the tooltip opens. `manual` is fully driven by `v-model:open`. */
19
17
  trigger?: TooltipTrigger
20
- /** Show a pointer arrow aimed at the trigger. */
21
18
  arrow?: boolean
22
- /** Gap between trigger and tooltip, in px. */
23
19
  offset?: number
24
20
  openDelay?: number
25
21
  closeDelay?: number
26
- /** Render through `<Teleport to="body">` to escape overflow/stacking contexts. */
27
22
  teleport?: boolean
28
23
  disabled?: boolean
29
24
  zIndex?: number
30
- /** Plain-text fallback used when the `content` slot is empty. */
31
25
  text?: string
32
- /** Extra classes merged onto the tooltip box (e.g. width/padding overrides). */
33
26
  contentClass?: string
34
27
  }
35
28
 
@@ -80,7 +73,6 @@ const { x, y, strategy, middlewareData, placement: resolvedPlacement } = useFloa
80
73
  const side = computed(() => resolvedPlacement.value.split('-')[0])
81
74
  const opposite: Record<string, string> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' }
82
75
 
83
- // Grow the panel out of the edge nearest the trigger.
84
76
  const transformOrigin = computed(() => {
85
77
  const [main, align] = resolvedPlacement.value.split('-')
86
78
  const anchor = opposite[main] ?? 'center'
@@ -92,7 +84,6 @@ const transformOrigin = computed(() => {
92
84
  return `${h} ${anchor}`
93
85
  })
94
86
 
95
- // The two outer edges of the rotated square form the visible point.
96
87
  const arrowBorderClass = computed(() => {
97
88
  switch (side.value) {
98
89
  case 'top': return 'border-b border-r'
@@ -117,12 +108,11 @@ const interactive = computed(() => props.trigger !== 'hover')
117
108
 
118
109
  const boxClass = computed(() =>
119
110
  twMerge(
120
- 'rounded-lg bg-white px-2.5 py-1.5 shadow-lg ring-1 ring-gray-200 dark:bg-gray-900 dark:ring-gray-700',
111
+ 'rounded-md bg-white px-2.5 py-1.5 shadow-lg ring-1 ring-gray-200 dark:bg-gray-900 dark:ring-gray-700',
121
112
  props.contentClass,
122
113
  ),
123
114
  )
124
115
 
125
- // Click mode dismisses on outside-click / Escape; hover leaves on its own; manual is parent-driven.
126
116
  onClickOutside(
127
117
  floating,
128
118
  () => {
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import ui from "#adata-ui/components/elements/accordion/AAccordionGroup/ui.config";
3
- import { twMerge } from 'tailwind-merge'
3
+ import { twMerge } from '#adata-ui/utils/twMerge'
4
4
 
5
5
  const props = defineProps<{
6
6
  transition?: {