adata-ui 2.1.40-beta.18 → 2.1.40-beta.19

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 (211) hide show
  1. package/.playground/app.vue +102 -0
  2. package/assets/styles/index.scss +67 -5
  3. package/components/elements/a-select-row/ASelectRowV2.vue +214 -0
  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 +133 -0
  11. package/components/elements/button-login/index.vue +6 -10
  12. package/components/elements/chip-wrapper/AChipWrapper.vue +1 -1
  13. package/components/elements/chips/AChips.vue +2 -2
  14. package/components/elements/companies/AOurClients.vue +3 -1
  15. package/components/elements/curve-block-v2/ACurveBlockV2.vue +85 -0
  16. package/components/elements/digit-badge/ADigitBadge.vue +24 -22
  17. package/components/elements/feature-description/AFeatureDescription.vue +1 -1
  18. package/components/elements/leave-note/ALeaveNote.vue +39 -18
  19. package/components/elements/pagination/APagination.vue +7 -7
  20. package/components/elements/segmented/ASegmentedV2.vue +151 -0
  21. package/components/elements/select/ASelect.vue +4 -4
  22. package/components/elements/select/ASelectMobile.vue +2 -2
  23. package/components/elements/select/ASelectV2.vue +588 -0
  24. package/components/elements/select/ui/select-button.vue +1 -1
  25. package/components/elements/show-more/AShowMoreV2.vue +26 -0
  26. package/components/elements/slider/ASlider.vue +174 -0
  27. package/components/elements/slider/ASliderItem.vue +31 -0
  28. package/components/elements/slider/types.ts +21 -0
  29. package/components/elements/star-rating/AStarRating.vue +12 -4
  30. package/components/elements/status-badge/AStatusBadge.vue +91 -44
  31. package/components/elements/step-slider/AStepSliderColCard.vue +232 -0
  32. package/components/elements/step-slider/AStepSliderColNumber.vue +178 -0
  33. package/components/elements/table/ATable.vue +1 -1
  34. package/components/elements/table/table.config.ts +2 -2
  35. package/components/elements/tree-select/ATreeSelect.vue +97 -113
  36. package/components/elements/tree-select/TreeService.ts +142 -207
  37. package/components/elements/tree-select/components/ATreeSelectNode.vue +104 -0
  38. package/components/elements/tree-select/types.ts +40 -11
  39. package/components/elements/tree-select/utils.ts +30 -0
  40. package/components/elements/tree-select-modal/ATreeSelectModal.vue +217 -0
  41. package/components/features/color-mode/AColorMode.client.vue +74 -32
  42. package/components/features/dropdown/ADropdownV2.vue +140 -0
  43. package/components/features/lang-switcher/lang-switcher.vue +125 -40
  44. package/components/features/payment/banner/BasicPlusLimitBanner.vue +3 -3
  45. package/components/features/payment/banner/PaymentBanner.vue +3 -3
  46. package/components/features/payment/banner/UpSellBanner.vue +3 -3
  47. package/components/features/payment/process/PaymentKaspiQrSidePanel.vue +45 -27
  48. package/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue +34 -23
  49. package/components/features/payment/process/PaymentMethodSidePanel.vue +66 -49
  50. package/components/features/payment/process/PaymentProcess.vue +6 -6
  51. package/components/features/payment/process/PaymentTopUpSidePanel.vue +49 -63
  52. package/components/features/pk-mobile-services/APkMobileServices.vue +6 -28
  53. package/components/features//321/201hange-version/AChangeVersion.vue +2 -2
  54. package/components/forms/checkbox/ACheckbox.vue +1 -1
  55. package/components/forms/checkbox/ACheckboxV2.vue +229 -0
  56. package/components/forms/feedback-form/FeedbackForm.vue +8 -8
  57. package/components/forms/feedback-form/FeedbackFormV2.vue +182 -0
  58. package/components/forms/input/AInputV2.vue +542 -0
  59. package/components/forms/input/date/AInputDate.vue +2 -2
  60. package/components/forms/input/password/AInputPassword.vue +8 -2
  61. package/components/forms/input/standard/AInputStandard.vue +3 -3
  62. package/components/forms/input/textarea/ATextarea.vue +2 -2
  63. package/components/forms/input/textarea/ATextareaV2.vue +248 -0
  64. package/components/forms/toggle/AToggle.vue +2 -3
  65. package/components/forms/toggle/AToggleV2.vue +71 -0
  66. package/components/modals/AnotherDeviceModal.vue +22 -18
  67. package/components/modals/ApplicationAcceptedModal.vue +12 -15
  68. package/components/modals/ConnectingTariffModal.vue +13 -20
  69. package/components/modals/ContactsMobileModel.vue +1 -1
  70. package/components/modals/ContentNavigationModal.vue +77 -333
  71. package/components/modals/Insufficient-funds-modal.vue +18 -33
  72. package/components/modals/LimitReachedModal.vue +17 -14
  73. package/components/modals/NoAccessModal.vue +9 -11
  74. package/components/modals/PaymentMethodModal.vue +1 -1
  75. package/components/modals/ReportBugConfirmModal.vue +12 -10
  76. package/components/modals/ReportBugModal.vue +46 -38
  77. package/components/modals/Resend.vue +9 -10
  78. package/components/modals/SubmitApplicationModal.vue +27 -24
  79. package/components/modals/id/IdBanner.vue +3 -3
  80. package/components/modals/id/IdConfirmAccountOtpModal.vue +4 -9
  81. package/components/modals/id/IdLoginModal.vue +3 -8
  82. package/components/modals/id/IdModals.vue +23 -10
  83. package/components/modals/id/IdRecoveryModal.vue +1 -1
  84. package/components/modals/id/IdTwoFactorModal.vue +3 -8
  85. package/components/navigation/bottom-navigation/ABottomNavigation.vue +1 -1
  86. package/components/navigation/breadcrumbs/ABreadcrumbs.vue +106 -45
  87. package/components/navigation/breadcrumbs/types.ts +3 -0
  88. package/components/navigation/footer/AFooter.vue +39 -40
  89. package/components/navigation/footer/ui/a-footer-accordion.vue +9 -9
  90. package/components/navigation/header/AHeader.vue +68 -51
  91. package/components/navigation/header/AlmatyContacts.vue +78 -78
  92. package/components/navigation/header/CardGallery.vue +9 -7
  93. package/components/navigation/header/ContactMenu.vue +26 -92
  94. package/components/navigation/header/HeaderLink.vue +181 -213
  95. package/components/navigation/header/HeaderUsage.vue +139 -0
  96. package/components/navigation/header/ListItem.vue +2 -2
  97. package/components/navigation/header/NavCard.vue +1 -1
  98. package/components/navigation/header/NavList.vue +33 -92
  99. package/components/navigation/header/NotificationsMenu.vue +2 -3
  100. package/components/navigation/header/ProductMenu.vue +81 -127
  101. package/components/navigation/header/ProfileMenu.vue +122 -151
  102. package/components/navigation/header/SystemNotification.vue +108 -0
  103. package/components/navigation/mobile-navigation/AMobileNavigation.vue +23 -15
  104. package/components/navigation/pill-tabs/APillTabs.vue +2 -2
  105. package/components/navigation/pill-tabs/APillTabsV2.vue +226 -0
  106. package/components/overlays/drawer/ADrawerV2.vue +335 -0
  107. package/components/overlays/modal/AModal.vue +4 -4
  108. package/components/overlays/modal/AModalV2.vue +397 -0
  109. package/components/overlays/side-panel/ASidePanel.vue +10 -7
  110. package/components/overlays/sideover/ASlideover.vue +6 -6
  111. package/components/overlays/tooltip/ATooltip.vue +1 -1
  112. package/components/overlays/tooltip/ATooltipV2.vue +223 -0
  113. package/components/overlays/tooltip/types.ts +26 -0
  114. package/components/overlays/tooltip/useTooltipTrigger.ts +101 -0
  115. package/components/transitions/ATransitionHeight.vue +1 -1
  116. package/composables/useAccessTokenCookie.ts +25 -0
  117. package/composables/useActiveNavigation.ts +84 -0
  118. package/composables/useChipOverflow.ts +92 -0
  119. package/composables/useHeaderNavigationLinks.ts +140 -98
  120. package/icons/archive.vue +16 -0
  121. package/icons/arrow/arrow-left-right.vue +8 -0
  122. package/icons/arrow/arrow-right.vue +14 -0
  123. package/icons/arrow/arrows-in.vue +11 -0
  124. package/icons/arrow/arrows-out.vue +11 -0
  125. package/icons/arrow/arrows-resize-in.vue +38 -0
  126. package/icons/arrow/arrows-resize-out.vue +17 -0
  127. package/icons/bill.vue +3 -0
  128. package/icons/bot.vue +52 -0
  129. package/icons/briefcase.vue +14 -0
  130. package/icons/building.vue +9 -0
  131. package/icons/car-side.vue +16 -0
  132. package/icons/cart.vue +15 -0
  133. package/icons/chart-no-axes-column.vue +3 -0
  134. package/icons/clock-time.vue +24 -0
  135. package/icons/cloud/cloud-upload.vue +3 -0
  136. package/icons/code.vue +9 -0
  137. package/icons/compare-outlined.vue +8 -0
  138. package/icons/dots-horizontal.vue +31 -0
  139. package/icons/download-line.vue +13 -0
  140. package/icons/download-rounded.vue +15 -0
  141. package/icons/egov.vue +41 -0
  142. package/icons/elicense.vue +38 -0
  143. package/icons/favourite-bookmark-outline.vue +17 -0
  144. package/icons/file/file-check-corner.vue +3 -0
  145. package/icons/file/file-spreadsheet.vue +3 -0
  146. package/icons/file-pen.vue +31 -0
  147. package/icons/file-stack.vue +31 -0
  148. package/icons/file-types/excel.vue +131 -0
  149. package/icons/file-types/html.vue +13 -0
  150. package/icons/file-types/jpeg.vue +16 -0
  151. package/icons/file-types/pdf.vue +11 -0
  152. package/icons/file-types/png.vue +11 -0
  153. package/icons/file-types/rar.vue +11 -0
  154. package/icons/file-types/word.vue +50 -0
  155. package/icons/file-types/zip.vue +11 -0
  156. package/icons/gauge.vue +17 -0
  157. package/icons/git-compare.vue +38 -0
  158. package/icons/git-fork.vue +3 -0
  159. package/icons/graduation-cap.vue +31 -0
  160. package/icons/graph-loading.vue +34 -0
  161. package/icons/headset.vue +6 -0
  162. package/icons/help-question-circle.vue +26 -0
  163. package/icons/in-row-type.vue +46 -0
  164. package/icons/in-table-type.vue +29 -0
  165. package/icons/landmark.vue +3 -0
  166. package/icons/layers.vue +3 -0
  167. package/icons/letter/letter-a.vue +6 -0
  168. package/icons/letter/letter-b.vue +6 -0
  169. package/icons/letter/letter-c.vue +6 -0
  170. package/icons/letter/letter-d.vue +6 -0
  171. package/icons/letter/letter-e.vue +6 -0
  172. package/icons/link-url.vue +3 -0
  173. package/icons/list-tree.vue +3 -0
  174. package/icons/mail-question-mark.vue +8 -0
  175. package/icons/message/message-square.vue +3 -0
  176. package/icons/message-dotted.vue +30 -0
  177. package/icons/network.vue +3 -0
  178. package/icons/newspaper.vue +3 -0
  179. package/icons/notification-error.vue +17 -0
  180. package/icons/person.vue +22 -0
  181. package/icons/phone-call.vue +6 -0
  182. package/icons/phone-reversed.vue +3 -0
  183. package/icons/route.vue +7 -0
  184. package/icons/scan-search.vue +3 -0
  185. package/icons/settings.vue +26 -0
  186. package/icons/shield-alert.vue +31 -0
  187. package/icons/shield-verified.vue +14 -0
  188. package/icons/socials/facebook-color.vue +16 -0
  189. package/icons/socials/globe-color.vue +16 -0
  190. package/icons/socials/instagram-color.vue +46 -0
  191. package/icons/socials/linkedin-color.vue +14 -0
  192. package/icons/socials/telegram-color.vue +16 -0
  193. package/icons/socials/tiktok-color.vue +14 -0
  194. package/icons/socials/vk-color.vue +16 -0
  195. package/icons/socials/youtube-color.vue +16 -0
  196. package/icons/sparkles.vue +3 -0
  197. package/icons/sun.vue +13 -3
  198. package/icons/users-round.vue +3 -0
  199. package/icons/view-eye-open.vue +13 -0
  200. package/icons/workflow.vue +3 -0
  201. package/icons/zap.vue +3 -0
  202. package/lang/en.ts +49 -5
  203. package/lang/kk.ts +50 -6
  204. package/lang/ru.ts +51 -7
  205. package/package.json +1 -1
  206. package/plugins/toast.client.ts +38 -55
  207. package/shared/constans/pages.ts +8 -2
  208. package/tailwind.config.ts +147 -116
  209. package/utils/twMerge.ts +34 -0
  210. package/components/elements/tree-select/components/tree-select-nodes.vue +0 -91
  211. package/components/navigation/header/TopHeader.vue +0 -196
@@ -0,0 +1,102 @@
1
+ <script setup lang="ts">
2
+ const manualOpen = ref(false)
3
+ const placements = ['top', 'top-start', 'bottom', 'bottom-end', 'left', 'right'] as const
4
+ </script>
5
+
6
+ <template>
7
+ <div class="min-h-screen bg-gray-50 p-10 dark:bg-gray-950">
8
+ <div class="mx-auto flex max-w-3xl flex-col gap-10">
9
+ <div class="flex items-center justify-between">
10
+ <h1 class="text-xl font-bold text-deepblue-900 dark:text-gray-100">
11
+ ATooltipV2
12
+ </h1>
13
+ <a-color-mode />
14
+ </div>
15
+
16
+ <!-- Placements + arrow (hover/focus) -->
17
+ <section class="flex flex-wrap gap-6">
18
+ <a-tooltip-v2
19
+ v-for="p in placements"
20
+ :key="p"
21
+ :placement="p"
22
+ arrow
23
+ :open-delay="80"
24
+ >
25
+ <button class="rounded-lg bg-blue-700 px-3 py-2 text-sm text-white dark:bg-blue-500 dark:text-gray-900">
26
+ {{ p }}
27
+ </button>
28
+ <template #content>
29
+ <div class="text-[11px] text-deepblue-900 dark:text-gray-100">
30
+ Placement <b>{{ p }}</b>
31
+ </div>
32
+ </template>
33
+ </a-tooltip-v2>
34
+ </section>
35
+
36
+ <!-- Click trigger, interactive content -->
37
+ <section>
38
+ <a-tooltip-v2
39
+ trigger="click"
40
+ placement="bottom-start"
41
+ arrow
42
+ content-class="w-56"
43
+ >
44
+ <button class="rounded-lg px-3 py-2 text-sm text-deepblue-900 ring-1 ring-gray-200 dark:text-gray-100 dark:ring-gray-700">
45
+ Click me
46
+ </button>
47
+ <template #content="{ close }">
48
+ <div class="flex flex-col gap-2 text-[11px] text-deepblue-900 dark:text-gray-100">
49
+ <p>Interactive — outside-click &amp; Esc close.</p>
50
+ <button
51
+ class="self-start text-blue-700 dark:text-blue-400"
52
+ @click="close"
53
+ >
54
+ Close
55
+ </button>
56
+ </div>
57
+ </template>
58
+ </a-tooltip-v2>
59
+ </section>
60
+
61
+ <!-- Manual via v-model:open -->
62
+ <section class="flex items-center gap-4">
63
+ <button
64
+ class="rounded-lg bg-deepblue-900 px-3 py-2 text-sm text-white dark:bg-gray-100 dark:text-gray-900"
65
+ @click="manualOpen = !manualOpen"
66
+ >
67
+ Toggle manual ({{ manualOpen }})
68
+ </button>
69
+ <a-tooltip-v2
70
+ v-model:open="manualOpen"
71
+ trigger="manual"
72
+ placement="right"
73
+ arrow
74
+ >
75
+ <span class="text-sm text-gray-500 dark:text-gray-400">anchor</span>
76
+ <template #content>
77
+ <div class="text-[11px] text-deepblue-900 dark:text-gray-100">
78
+ Manually controlled
79
+ </div>
80
+ </template>
81
+ </a-tooltip-v2>
82
+ </section>
83
+
84
+ <!-- Teleport out of an overflow-hidden container -->
85
+ <section class="h-24 overflow-hidden rounded-lg p-3 ring-1 ring-gray-200 dark:ring-gray-700">
86
+ <a-tooltip-v2
87
+ placement="top"
88
+ arrow
89
+ >
90
+ <button class="rounded-lg bg-green-500 px-3 py-2 text-sm text-white dark:text-gray-900">
91
+ Inside overflow-hidden (teleported)
92
+ </button>
93
+ <template #content>
94
+ <div class="text-[11px] text-deepblue-900 dark:text-gray-100">
95
+ Not clipped
96
+ </div>
97
+ </template>
98
+ </a-tooltip-v2>
99
+ </section>
100
+ </div>
101
+ </div>
102
+ </template>
@@ -68,18 +68,80 @@ input::-webkit-inner-spin-button {
68
68
  -webkit-appearance: none;
69
69
  margin: 0;
70
70
  }
71
- .toast__body{
72
- padding:0 16px 0 0 !important;
73
- margin:0 !important;
74
- align-items: stretch !important;
75
- }
76
71
  .Toastify__toast-container {
77
72
  z-index: 10002 !important;
78
73
  }
74
+
75
+ @media (min-width: 481px) {
76
+ .Toastify__toast-container {
77
+ width: 600px;
78
+ }
79
+ }
80
+
81
+ .Toastify__toast-container .Toastify__toast {
82
+ min-height: 71px;
83
+ padding: 14px 16px;
84
+ border: 1px solid transparent;
85
+ border-left-width: 4px; /* акцентная полоса слева */
86
+ border-radius: 12px;
87
+ box-shadow: none;
88
+ }
89
+
90
+ .Toastify__toast-container .Toastify__toast-body {
91
+ margin: 0;
92
+ padding: 0;
93
+ gap: 12px;
94
+ align-items: center;
95
+ font-size: 16px;
96
+ font-weight: 500;
97
+ line-height: 24px;
98
+ }
99
+
100
+ .Toastify__toast-container .Toastify__toast-icon {
101
+ width: 24px;
102
+ height: 24px;
103
+ margin-inline-end: 0;
104
+ }
105
+
106
+ .Toastify__toast-container .Toastify__toast-icon svg {
107
+ width: 24px;
108
+ height: 24px;
109
+ }
110
+
111
+ .Toastify__toast-container .Toastify__close-button {
112
+ align-self: center;
113
+ color: #2c3e50;
114
+ opacity: 0.6;
115
+ }
116
+
117
+ .Toastify__toast-container .Toastify__close-button:hover {
118
+ opacity: 1;
119
+ }
120
+
121
+ .Toastify__toast-container .Toastify__toast--info { background: #eff6ff; border-color: #068dff; color: #068dff; }
122
+ .Toastify__toast-container .Toastify__toast--success { background: #f0fdf4; border-color: #00a63e; color: #00a63e; }
123
+ .Toastify__toast-container .Toastify__toast--warning { background: #fffbeb; border-color: #e17100; color: #e17100; }
124
+ .Toastify__toast-container .Toastify__toast--error { background: #fef2f2; border-color: #e7000b; color: #e7000b; }
125
+
126
+ .Toastify__toast-container .Toastify__toast--info .Toastify__progress-bar { background: #068dff; }
127
+ .Toastify__toast-container .Toastify__toast--success .Toastify__progress-bar { background: #00a63e; }
128
+ .Toastify__toast-container .Toastify__toast--warning .Toastify__progress-bar { background: #e17100; }
129
+ .Toastify__toast-container .Toastify__toast--error .Toastify__progress-bar { background: #e7000b; }
130
+
131
+ /* Тёмная тема (нежная): фон = тинт solid-хекса тона /10, но непрозрачный (тост плавает
132
+ над контентом) — композит поверх #161617; бордер rgba(solid,0.4); текст/иконка -400. */
133
+ .dark .Toastify__toast-container .Toastify__close-button { color: #e3e5e8; }
134
+
135
+ .dark .Toastify__toast-container .Toastify__toast--info { background: #14222e; border-color: rgba(6, 141, 255, 0.4); color: #43afed; }
136
+ .dark .Toastify__toast-container .Toastify__toast--success { background: #14241b; border-color: rgba(0, 166, 62, 0.4); color: #6bbd6e; }
137
+ .dark .Toastify__toast-container .Toastify__toast--warning { background: #2a1f15; border-color: rgba(225, 113, 0, 0.4); color: #ffc31e; }
138
+ .dark .Toastify__toast-container .Toastify__toast--error { background: #2b1416; border-color: rgba(231, 0, 11, 0.4); color: #f47e75; }
139
+
79
140
  input[type="search"]::-webkit-search-cancel-button {
80
141
  -webkit-appearance: none;
81
142
  appearance: none;
82
143
  }
144
+
83
145
  input[type="search"]::-ms-clear {
84
146
  display: none;
85
147
  width: 0;
@@ -0,0 +1,214 @@
1
+ <script setup lang="ts">
2
+ import { useChipOverflow } from '#adata-ui/composables/useChipOverflow'
3
+
4
+ interface Item {
5
+ id: number | string
6
+ name: string
7
+ }
8
+
9
+ interface Props {
10
+ label: string
11
+ selectedItems: Item[]
12
+ clearable?: boolean
13
+ disabled?: boolean
14
+ deletable?: boolean
15
+ btnClass?: string
16
+ size?: 'sm' | 'md'
17
+ required?: boolean
18
+ }
19
+
20
+ const props = withDefaults(defineProps<Props>(), {
21
+ clearable: true,
22
+ disabled: false,
23
+ deletable: false,
24
+ btnClass: '',
25
+ size: 'md',
26
+ required: false,
27
+ })
28
+
29
+ const emit = defineEmits<{
30
+ (e: 'delete', item: Item): void
31
+ (e: 'clear'): void
32
+ }>()
33
+
34
+ const isOpen = defineModel<boolean>('isOpen', { default: false })
35
+
36
+ const chipsRow = ref<HTMLElement | null>(null)
37
+ const measureRow = ref<HTMLElement | null>(null)
38
+
39
+ const itemCount = computed(() => props.selectedItems?.length ?? 0)
40
+
41
+ const { visibleCount, hiddenCount } = useChipOverflow({
42
+ container: chipsRow,
43
+ measure: measureRow,
44
+ count: itemCount,
45
+ contentKey: computed(() => props.selectedItems?.map(item => item.name).join(' ') ?? ''),
46
+ gap: 6,
47
+ })
48
+
49
+ const visibleItems = computed(() => props.selectedItems.slice(0, visibleCount.value))
50
+
51
+ const showFloatingLabel = computed(() => !!props.label && !visibleItems.value?.length)
52
+
53
+ const hasValue = computed(() => itemCount.value > 0)
54
+
55
+ const isLabelFloated = computed(() => hasValue.value || isOpen.value)
56
+
57
+ function deleteItem(item: Item) {
58
+ emit('delete', item)
59
+ }
60
+
61
+ function onClear() {
62
+ emit('clear')
63
+ }
64
+
65
+ const triggerLayoutClass = computed(() => {
66
+ if (hasValue.value || !props.label) {
67
+ return props.size === 'md' ? 'h-10 py-1.5' : 'h-9 py-1.5'
68
+ }
69
+ return props.size === 'md' ? 'h-10 pt-3.5 pb-1' : 'h-9 pt-[14px] pb-1'
70
+ })
71
+
72
+ defineExpose({ onClear })
73
+ </script>
74
+
75
+ <template>
76
+ <div class="select-row-v2 relative w-full text-body-md">
77
+ <button
78
+ type="button"
79
+ :disabled="disabled"
80
+ :class="[
81
+ triggerLayoutClass,
82
+ clearable ? 'pr-16' : 'pr-9',
83
+ disabled
84
+ ? 'border-gray-200 bg-gray-100/70 dark:border-gray-700 dark:bg-white/[0.03]'
85
+ : (btnClass || 'border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900'),
86
+ { 'select-row-v2__trigger--open': isOpen },
87
+ ]"
88
+ class="select-row-v2__trigger text-deepblue-900 relative flex w-full items-center gap-2 rounded-[10px] border border-solid pl-4 transition-colors duration-200 hover:border-blue-500 focus-visible:border-blue-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600/20 dark:text-gray-200 dark:hover:border-blue-400 dark:focus-visible:border-blue-400 dark:focus-visible:ring-blue-400/20"
89
+ @click="isOpen = !isOpen"
90
+ >
91
+ <span
92
+ v-if="showFloatingLabel"
93
+ :data-size="size"
94
+ class="select-row-v2__label pointer-events-none absolute left-4 top-1/2 max-w-[calc(100%-48px)] truncate text-gray-500 dark:text-gray-400"
95
+ :class="{ 'select-row-v2__label--floated': isLabelFloated }"
96
+ >
97
+ {{ label }}<span v-if="required" class="text-red-500 dark:text-red-400">&nbsp;*</span>
98
+ </span>
99
+
100
+ <span ref="chipsRow" class="relative flex w-full min-w-0 items-center gap-1.5 overflow-hidden text-start leading-none">
101
+ <template v-if="hasValue">
102
+ <span
103
+ v-for="item in visibleItems"
104
+ :key="item.id"
105
+ class="select-row-v2__chip inline-flex min-w-0 items-center gap-1 rounded-sm bg-[#F0F8FF] px-2 py-0.5 text-body-sm text-blue-600 dark:bg-blue-600/15 dark:text-blue-400"
106
+ @click.stop="deletable ? deleteItem(item) : (isOpen = true)"
107
+ >
108
+ <span class="truncate">{{ item.name }}</span>
109
+ <button
110
+ v-if="deletable"
111
+ type="button"
112
+ class="flex shrink-0 items-center justify-center rounded-full p-0.5 transition-colors hover:bg-blue-100 dark:hover:bg-blue-500/20"
113
+ >
114
+ <a-icon-x-mark class="size-2.5" />
115
+ </button>
116
+ </span>
117
+ <span
118
+ v-if="hiddenCount > 0"
119
+ class="inline-flex shrink-0 items-center whitespace-nowrap rounded-sm bg-[#DBEFFF] px-2 py-0.5 text-body-sm-medium text-[#0066BD] dark:bg-blue-600/25 dark:text-blue-300"
120
+ >
121
+ +{{ hiddenCount }}
122
+ </span>
123
+
124
+ <span
125
+ ref="measureRow"
126
+ aria-hidden="true"
127
+ class="pointer-events-none invisible absolute left-0 top-0 flex h-0 w-max items-center gap-1.5"
128
+ >
129
+ <span
130
+ v-for="item in selectedItems"
131
+ :key="`measure-${item.id}`"
132
+ class="inline-flex items-center gap-1 whitespace-nowrap rounded-sm bg-gray-50 px-2 py-0.5 text-body-sm"
133
+ >
134
+ <span>{{ item.name }}</span>
135
+ <span
136
+ v-if="deletable"
137
+ class="flex shrink-0 items-center justify-center rounded-full p-0.5"
138
+ >
139
+ <a-icon-x-mark class="size-2.5" />
140
+ </span>
141
+ </span>
142
+ <span class="inline-flex shrink-0 items-center whitespace-nowrap rounded-sm px-2 py-0.5 text-body-sm-medium">
143
+ +{{ itemCount }}
144
+ </span>
145
+ </span>
146
+ </template>
147
+ <span v-else class="text-gray-500 dark:text-gray-400">&#8203;</span>
148
+ </span>
149
+
150
+ <button
151
+ v-if="clearable && hasValue && !disabled"
152
+ type="button"
153
+ class="absolute right-9 top-1/2 flex -translate-y-1/2 items-center justify-center rounded-full p-0.5 transition-colors hover:bg-gray-100 dark:hover:bg-white/[0.08] dark:hover:text-gray-300"
154
+ @click.stop="onClear"
155
+ >
156
+ <a-icon-x-mark class="!m-0 size-3.5" />
157
+ </button>
158
+
159
+ <span
160
+ :class="{ 'rotate-180': isOpen }"
161
+ class="absolute right-3 top-1/2 -translate-y-1/2 transition-transform duration-200"
162
+ >
163
+ <a-icon-chevron-down class="!m-0 size-4 text-gray-400 dark:text-gray-500" />
164
+ </span>
165
+ </button>
166
+ </div>
167
+ </template>
168
+
169
+ <style scoped>
170
+ .select-row-v2__trigger:disabled {
171
+ pointer-events: none;
172
+ cursor: not-allowed;
173
+ opacity: 0.7;
174
+ }
175
+
176
+ .select-row-v2__chip {
177
+ cursor: pointer;
178
+ transition: background-color 150ms;
179
+ }
180
+
181
+ .select-row-v2__chip:hover {
182
+ background-color: theme('colors.blue.100');
183
+ }
184
+
185
+ :is(.dark) .select-row-v2__chip:hover {
186
+ background-color: rgb(6 141 255 / 0.25);
187
+ }
188
+
189
+ .select-row-v2__label {
190
+ font-size: 14px;
191
+ line-height: 1.3;
192
+ transform: translateY(-50%);
193
+ transition:
194
+ transform 300ms cubic-bezier(0.22, 1, 0.36, 1),
195
+ font-size 300ms cubic-bezier(0.22, 1, 0.36, 1),
196
+ color 300ms ease-out;
197
+ }
198
+
199
+ .select-row-v2__label--floated {
200
+ font-size: 10px;
201
+ transform: translateY(-17px);
202
+ }
203
+
204
+ .select-row-v2__label--floated[data-size="sm"] {
205
+ transform: translateY(-14px);
206
+ }
207
+
208
+ @media (prefers-reduced-motion: reduce) {
209
+ .select-row-v2__label,
210
+ .select-row-v2__trigger {
211
+ transition: none;
212
+ }
213
+ }
214
+ </style>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
- import AChips from '~/components/elements/chips/AChips.vue'
2
+ import { twMerge } from '#adata-ui/utils/twMerge'
3
3
  import {isEqual} from 'lodash-es'
4
- import { twMerge } from 'tailwind-merge'
4
+ import AChips from '~/components/elements/chips/AChips.vue'
5
5
 
6
6
  type Item = {
7
7
  id: number | string
@@ -17,8 +17,6 @@ interface Props {
17
17
  btnClass?: string
18
18
  }
19
19
 
20
- // const items = defineModel<Item[]>('selectedItems', {required: true})
21
-
22
20
  type Emits = {
23
21
  (e: 'delete', item: Item): void
24
22
  }
@@ -83,7 +81,7 @@ const onClear = () => {
83
81
  <button
84
82
  ref="buttonElement"
85
83
  class="hover:border-blue focus-visible:outline-blue
86
- relative flex w-full items-center justify-between gap-2 rounded-md
84
+ relative flex w-full items-center justify-between gap-2 rounded-sm
87
85
  border border-solid border-deepblue-50 bg-deepblue-50 min-h-[40px] text-gray-500 body-400 px-4 py-1.5
88
86
  focus-visible:shadow-[0_0_0_4px#1B64B3] dark:border-gray-900 dark:bg-gray-200/5
89
87
  dark:hover:border-blue-700"
@@ -1,9 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  // REFACTOR @Iskander
3
- import ui from './ui.config'
4
- import {Disclosure, DisclosureButton, DisclosurePanel} from '@headlessui/vue'
5
- import {twJoin, twMerge} from 'tailwind-merge'
6
3
  import type {Color, Size} from "#adata-ui/components/elements/accordion/types";
4
+ import {twJoin, twMerge} from '#adata-ui/utils/twMerge'
5
+ import {Disclosure, DisclosureButton, DisclosurePanel} from '@headlessui/vue'
6
+ import ui from './ui.config'
7
7
 
8
8
  export interface Props {
9
9
  label: string
@@ -16,6 +16,7 @@ export interface Props {
16
16
  contentClass?: string
17
17
  bodyClass?: string
18
18
  activateOpenBg?: boolean
19
+ iconChevronTestId?: string
19
20
  }
20
21
 
21
22
  interface Emits {
@@ -160,6 +161,7 @@ defineExpose({
160
161
  <a-icon-chevron-down
161
162
  :arrow-attrs="{ class: 'stroke-deepblue-900' }"
162
163
  :class="[{ 'rotate-180': open }, 'max-h-[16px] min-h-[16px] min-w-[16px] max-w-[16px]', ui.item.icon]"
164
+ :data-test-id="iconChevronTestId"
163
165
  />
164
166
  </button>
165
167
  </slot>
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
- import ui from './ui.config'
2
+ import type {Props, Size} from "./types";
3
+ import {twJoin, twMerge} from '#adata-ui/utils/twMerge';
3
4
  import {
4
5
  Disclosure,
5
6
  DisclosureButton,
6
7
  DisclosurePanel
7
8
  } from '@headlessui/vue'
8
- import type {Size, Props} from "./types";
9
- import {twJoin, twMerge} from "tailwind-merge";
9
+ import ui from './ui.config'
10
10
 
11
11
  defineOptions({
12
12
  inheritAttrs: false
@@ -1,65 +1,52 @@
1
- <template>
2
- <div
3
- class="inline-flex w-full rounded-md"
4
- :class="twMerge(colorOptions.description[color])"
5
- >
6
- <div
7
- class="flex items-center justify-center rounded-l-md"
8
- :class="twMerge([colorOptions.icon[color], sizeOptions[size]])"
9
- >
10
- <slot name="icon">
11
- <a-icon-info-circle v-if="iconType == 'circle'" :class="`w-[${iconSize}] h-[${iconSize}]`" />
12
- <a-icon-warning-triangle v-if="iconType == 'triangle'" :class="`w-[${iconSize}] h-[${iconSize}]`" />
13
- </slot>
14
- </div>
15
- <div
16
- :class="sizeOptions[size]"
17
- class="rounded-r-md flex items-center"
18
- >
19
- <slot name="default" />
20
- </div>
21
- </div>
22
- </template>
23
-
24
1
  <script setup lang="ts">
25
- import {twMerge} from "tailwind-merge";
26
-
27
- defineOptions({ name: 'AAlert' })
28
-
29
2
  interface Props {
30
3
  size?: 'lg' | 'sm' | 'xs'
31
4
  color?: 'blue' | 'green' | 'red' | 'deepblue' | 'orange'
32
- iconType?:'triangle' |'circle'
5
+ iconType?: 'triangle' | 'circle'
33
6
  iconSize?: string
34
7
  }
35
- withDefaults(defineProps<Props>(), {
8
+ defineOptions({ name: 'AAlert' })
9
+
10
+ const props = withDefaults(defineProps<Props>(), {
36
11
  size: 'sm',
37
12
  color: 'blue',
38
- iconType:'circle',
13
+ iconType: 'circle',
39
14
  iconSize: '16px',
40
15
  })
16
+
41
17
  const sizeOptions = {
42
- lg: 'text-base p-2',
43
- sm: 'text-sm px-2 py-[3.5px]',
44
- xs: 'text-xs px-2 py-[3.5px]'
18
+ lg: 'text-body-lg',
19
+ sm: 'text-body-md',
20
+ xs: 'text-body-sm',
45
21
  }
46
22
 
47
23
  const colorOptions = {
48
- icon: {
49
- blue: 'bg-blue-700 text-white dark:bg-blue-500 dark:text-gray-900',
50
- green: 'bg-green-500 text-white dark:text-gray-900',
51
- orange: 'bg-[#FCA204] text-white dark:text-gray-900',
52
- deepblue: 'bg-deepblue-900 text-white dark:text-gray-900',
53
- red: 'bg-red-500 text-white dark:bg-red-400 dark:text-gray-900'
54
- },
55
- description: {
56
- blue: 'bg-blue-100 dark:bg-gray-200/10 text-blue-700 dark:text-blue-500',
57
- green: 'bg-green-100 text-green-500',
58
- orange: 'bg-[#FFF5E6] dark:bg-[#FCA2041A] text-[#FCA204]',
59
- deepblue: 'bg-deepblue-100 text-deepblue-900',
60
- red: 'bg-red-100 text-red-500 dark:bg-[#3A3133] dark:text-red-400'
61
- }
24
+ blue: 'bg-[#EFF6FF] border-[#068DFF] text-[#068DFF] dark:bg-[#068DFF]/10 dark:border-[#068DFF]/40 dark:text-blue-400',
25
+ green: 'bg-[#F0FDF4] border-[#00A63E] text-[#00A63E] dark:bg-[#00A63E]/10 dark:border-[#00A63E]/40 dark:text-green-400',
26
+ orange: 'bg-[#FFFBEB] border-[#E17100] text-[#E17100] dark:bg-[#E17100]/10 dark:border-[#E17100]/40 dark:text-orange-400',
27
+ red: 'bg-[#FEF2F2] border-[#E7000B] text-[#E7000B] dark:bg-[#E7000B]/10 dark:border-[#E7000B]/40 dark:text-red-400',
28
+ deepblue: 'bg-deepblue-100 border-deepblue-900 text-deepblue-900 dark:bg-gray-500/10 dark:border-gray-500/40 dark:text-gray-300',
62
29
  }
30
+
31
+ const rootClass = computed(() => [colorOptions[props.color], sizeOptions[props.size]])
32
+ const iconStyle = computed(() => ({ width: props.iconSize, height: props.iconSize }))
63
33
  </script>
64
34
 
35
+ <template>
36
+ <div
37
+ class="flex w-full items-center gap-2 rounded-lg border border-l-4 p-2"
38
+ :class="rootClass"
39
+ >
40
+ <span class="flex shrink-0 items-center justify-center">
41
+ <slot name="icon">
42
+ <a-icon-info-circle v-if="iconType === 'circle'" :style="iconStyle" />
43
+ <a-icon-warning-triangle v-else :style="iconStyle" />
44
+ </slot>
45
+ </span>
46
+ <div class="min-w-0 flex-1">
47
+ <slot name="default" />
48
+ </div>
49
+ </div>
50
+ </template>
51
+
65
52
  <style scoped></style>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts"></script>
2
2
 
3
3
  <template>
4
- <div class="md:rounded-lg p-4 bg-white dark:bg-gray-900">
4
+ <div class="md:rounded-md p-4 bg-white dark:bg-gray-900">
5
5
  <slot />
6
6
  </div>
7
7
  </template>
@@ -1,8 +1,8 @@
1
1
  <script lang="ts" setup>
2
2
  // TODO: refactor Ilkham
3
- import { twJoin, twMerge } from 'tailwind-merge'
4
3
  import type { Component } from 'vue'
5
4
  import type { DisabledViewSwitchValues, SizeSwitchValues, ViewSwitchValues } from './types'
5
+ import { twJoin, twMerge } from '#adata-ui/utils/twMerge'
6
6
  import { NuxtLinkLocale} from '#components'
7
7
 
8
8
  defineOptions({ name: 'AButton' })
@@ -35,13 +35,13 @@ const props = withDefaults(defineProps<Props>(), {
35
35
  })
36
36
 
37
37
  const classes = computed(() => [
38
- 'body-600 rounded-md cursor-pointer outline-none transition duration-200 select-none',
38
+ 'text-body-md-strong rounded-sm cursor-pointer outline-none transition duration-200 select-none',
39
39
  props.block ? 'w-full' : '',
40
40
  typeSwitchValues[props.view][props.variant],
41
41
  sizeSwitchValues[props.form][props.size]
42
42
  ])
43
43
  const disabledClasses = computed(() => [
44
- 'body-600 rounded-md outline-none transition duration-200 select-none',
44
+ 'text-body-md-strong rounded-sm outline-none transition duration-200 select-none',
45
45
  props.block ? 'w-full' : '',
46
46
  disabledTypeSwitchValues[props.view],
47
47
  sizeSwitchValues[props.form][props.size]