adata-ui 2.1.40-beta.11 → 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 (133) hide show
  1. package/assets/styles/index.scss +67 -5
  2. package/components/elements/a-select-row/ASelectRowV2.vue +8 -8
  3. package/components/elements/a-select-row/index.vue +3 -5
  4. package/components/elements/accordion/AAccordion.vue +5 -3
  5. package/components/elements/accordion/AAccordionGroup/AAccordionGroup.vue +3 -3
  6. package/components/elements/alert/AAlert.vue +34 -47
  7. package/components/elements/bg-block/ABgBlock.vue +1 -1
  8. package/components/elements/button/AButton.vue +3 -3
  9. package/components/elements/button/AButtonV2.vue +7 -5
  10. package/components/elements/button-login/index.vue +1 -1
  11. package/components/elements/chip-wrapper/AChipWrapper.vue +1 -1
  12. package/components/elements/chips/AChips.vue +2 -2
  13. package/components/elements/digit-badge/ADigitBadge.vue +21 -19
  14. package/components/elements/feature-description/AFeatureDescription.vue +1 -1
  15. package/components/elements/leave-note/ALeaveNote.vue +1 -1
  16. package/components/elements/pagination/APagination.vue +7 -7
  17. package/components/elements/segmented/ASegmentedV2.vue +103 -10
  18. package/components/elements/select/ASelect.vue +4 -4
  19. package/components/elements/select/ASelectMobile.vue +2 -2
  20. package/components/elements/select/ASelectV2.vue +10 -11
  21. package/components/elements/select/ui/select-button.vue +1 -1
  22. package/components/elements/status-badge/AStatusBadge.vue +22 -19
  23. package/components/elements/status-badge-v2/StatusBadgeV2.vue +1 -3
  24. package/components/elements/table/ATable.vue +1 -1
  25. package/components/elements/table/table.config.ts +2 -2
  26. package/components/elements/tree-select/ATreeSelect.vue +97 -113
  27. package/components/elements/tree-select/TreeService.ts +142 -207
  28. package/components/elements/tree-select/components/ATreeSelectNode.vue +104 -0
  29. package/components/elements/tree-select/types.ts +40 -11
  30. package/components/elements/tree-select/utils.ts +30 -0
  31. package/components/elements/tree-select-modal/ATreeSelectModal.vue +217 -0
  32. package/components/features/color-mode/AColorMode.client.vue +1 -1
  33. package/components/features/dropdown/ADropdownV2.vue +1 -2
  34. package/components/features/lang-switcher/lang-switcher.vue +9 -4
  35. package/components/features/payment/banner/BasicPlusLimitBanner.vue +3 -3
  36. package/components/features/payment/banner/PaymentBanner.vue +3 -3
  37. package/components/features/payment/banner/UpSellBanner.vue +3 -3
  38. package/components/features/payment/process/PaymentKaspiQrSidePanel.vue +3 -3
  39. package/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue +1 -1
  40. package/components/features/payment/process/PaymentMethodSidePanel.vue +3 -3
  41. package/components/features/payment/process/PaymentTopUpSidePanel.vue +2 -2
  42. package/components/features/pk-mobile-services/APkMobileServices.vue +1 -1
  43. package/components/features//321/201hange-version/AChangeVersion.vue +2 -2
  44. package/components/forms/checkbox/ACheckbox.vue +1 -1
  45. package/components/forms/checkbox/ACheckboxV2.vue +5 -5
  46. package/components/forms/input/AInputV2.vue +4 -4
  47. package/components/forms/input/date/AInputDate.vue +2 -2
  48. package/components/forms/input/password/AInputPassword.vue +8 -2
  49. package/components/forms/input/standard/AInputStandard.vue +3 -3
  50. package/components/forms/input/textarea/ATextarea.vue +2 -2
  51. package/components/forms/toggle/AToggle.vue +2 -3
  52. package/components/forms/toggle/AToggleV2.vue +3 -3
  53. package/components/modals/AnotherDeviceModal.vue +1 -1
  54. package/components/modals/ContactsMobileModel.vue +1 -1
  55. package/components/modals/ContentNavigationModal.vue +3 -3
  56. package/components/modals/Insufficient-funds-modal.vue +1 -1
  57. package/components/modals/PaymentMethodModal.vue +1 -1
  58. package/components/modals/id/IdBanner.vue +3 -3
  59. package/components/modals/id/IdRecoveryModal.vue +1 -1
  60. package/components/navigation/breadcrumbs/ABreadcrumbs.vue +106 -45
  61. package/components/navigation/breadcrumbs/types.ts +3 -0
  62. package/components/navigation/footer/AFooter.vue +39 -40
  63. package/components/navigation/footer/ui/a-footer-accordion.vue +9 -9
  64. package/components/navigation/header/AHeader.vue +2 -4
  65. package/components/navigation/header/AlmatyContacts.vue +78 -78
  66. package/components/navigation/header/CardGallery.vue +4 -4
  67. package/components/navigation/header/HeaderUsage.vue +4 -6
  68. package/components/navigation/header/ListItem.vue +2 -2
  69. package/components/navigation/header/NavCard.vue +1 -1
  70. package/components/navigation/header/NavList.vue +2 -2
  71. package/components/navigation/header/NotificationsMenu.vue +2 -3
  72. package/components/navigation/header/ProductMenu.vue +1 -1
  73. package/components/navigation/header/ProfileMenu.vue +26 -35
  74. package/components/navigation/header/SystemNotification.vue +1 -3
  75. package/components/navigation/pill-tabs/APillTabs.vue +2 -2
  76. package/components/navigation/pill-tabs/APillTabsV2.vue +5 -5
  77. package/components/overlays/drawer/ADrawerV2.vue +335 -0
  78. package/components/overlays/modal/AModal.vue +4 -4
  79. package/components/overlays/modal/AModalV2.vue +4 -4
  80. package/components/overlays/side-panel/ASidePanel.vue +6 -6
  81. package/components/overlays/sideover/ASlideover.vue +6 -6
  82. package/components/overlays/tooltip/ATooltip.vue +1 -1
  83. package/components/overlays/tooltip/ATooltipV2.vue +2 -12
  84. package/components/transitions/ATransitionHeight.vue +1 -1
  85. package/composables/useHeaderNavigationLinks.ts +100 -94
  86. package/icons/archive.vue +16 -0
  87. package/icons/arrow/arrows-in.vue +11 -0
  88. package/icons/arrow/arrows-out.vue +11 -0
  89. package/icons/arrow/arrows-resize-in.vue +38 -0
  90. package/icons/arrow/arrows-resize-out.vue +17 -0
  91. package/icons/bot.vue +52 -0
  92. package/icons/clock-time.vue +24 -0
  93. package/icons/compare-outlined.vue +8 -0
  94. package/icons/dots-horizontal.vue +31 -0
  95. package/icons/download-line.vue +13 -0
  96. package/icons/egov.vue +41 -0
  97. package/icons/elicense.vue +38 -0
  98. package/icons/favourite-bookmark-outline.vue +17 -0
  99. package/icons/file-pen.vue +31 -0
  100. package/icons/file-stack.vue +31 -0
  101. package/icons/file-types/excel.vue +131 -0
  102. package/icons/file-types/html.vue +13 -0
  103. package/icons/file-types/jpeg.vue +16 -0
  104. package/icons/file-types/pdf.vue +11 -0
  105. package/icons/file-types/png.vue +11 -0
  106. package/icons/file-types/rar.vue +11 -0
  107. package/icons/file-types/word.vue +50 -0
  108. package/icons/file-types/zip.vue +11 -0
  109. package/icons/git-compare.vue +38 -0
  110. package/icons/graduation-cap.vue +31 -0
  111. package/icons/graph-loading.vue +34 -0
  112. package/icons/help-question-circle.vue +26 -0
  113. package/icons/in-row-type.vue +46 -0
  114. package/icons/in-table-type.vue +29 -0
  115. package/icons/message-dotted.vue +30 -0
  116. package/icons/notification-error.vue +17 -0
  117. package/icons/person.vue +22 -0
  118. package/icons/settings.vue +26 -0
  119. package/icons/shield-alert.vue +31 -0
  120. package/icons/socials/facebook-color.vue +16 -0
  121. package/icons/socials/globe-color.vue +16 -0
  122. package/icons/socials/instagram-color.vue +46 -0
  123. package/icons/socials/linkedin-color.vue +14 -0
  124. package/icons/socials/telegram-color.vue +16 -0
  125. package/icons/socials/tiktok-color.vue +14 -0
  126. package/icons/socials/vk-color.vue +16 -0
  127. package/icons/socials/youtube-color.vue +16 -0
  128. package/icons/view-eye-open.vue +13 -0
  129. package/package.json +1 -1
  130. package/plugins/toast.client.ts +38 -55
  131. package/tailwind.config.ts +147 -116
  132. package/utils/twMerge.ts +34 -0
  133. package/components/elements/tree-select/components/tree-select-nodes.vue +0 -91
@@ -64,9 +64,9 @@ const gapClass = computed(() => {
64
64
 
65
65
  const textClass = computed(() => {
66
66
  switch (props.size) {
67
- case 'sm': return 'text-xs'
68
- case 'lg': return 'text-base'
69
- default: return 'text-sm'
67
+ case 'sm': return 'text-body-sm'
68
+ case 'lg': return 'text-body-lg'
69
+ default: return 'text-body-md'
70
70
  }
71
71
  })
72
72
 
@@ -82,7 +82,7 @@ const isActive = computed(() => isChecked.value || props.intermediate)
82
82
 
83
83
  const squareClass = computed(() => {
84
84
  const base = [
85
- 'checkbox-square inline-flex shrink-0 items-center justify-center rounded-md border transition-colors duration-150',
85
+ 'checkbox-square inline-flex shrink-0 items-center justify-center rounded-sm border transition-colors duration-150',
86
86
  squareSizeClass.value,
87
87
  ]
88
88
 
@@ -101,7 +101,7 @@ const squareClass = computed(() => {
101
101
 
102
102
  const chipClass = computed(() => {
103
103
  const base = [
104
- 'inline-flex items-center rounded-full border px-3 py-1 text-xs transition-colors duration-150',
104
+ 'inline-flex items-center rounded-full border px-3 py-1 text-body-sm transition-colors duration-150',
105
105
  ]
106
106
 
107
107
  if (isActive.value) {
@@ -303,7 +303,7 @@ function rowDisplay(item: T): unknown {
303
303
  <template>
304
304
  <div
305
305
  ref="wrapperRef"
306
- class="input-v2 relative w-full text-sm"
306
+ class="input-v2 relative w-full text-body-md"
307
307
  v-bind="wrapperAttrs"
308
308
  >
309
309
  <div
@@ -395,7 +395,7 @@ function rowDisplay(item: T): unknown {
395
395
  <div
396
396
  v-if="isDropdownOpen"
397
397
  ref="floatingRef"
398
- class="input-v2__dropdown z-[10000] flex flex-col gap-2 rounded-xl border border-gray-200 bg-white p-1.5 shadow-lg shadow-gray-900/10 dark:border-gray-700 dark:bg-gray-900 dark:shadow-black/30"
398
+ class="input-v2__dropdown z-[10000] flex flex-col gap-2 rounded-lg border border-gray-200 bg-white p-1.5 shadow-lg shadow-gray-900/10 dark:border-gray-700 dark:bg-gray-900 dark:shadow-black/30"
399
399
  :style="{
400
400
  position: strategy,
401
401
  left: x != null ? `${x}px` : '',
@@ -406,7 +406,7 @@ function rowDisplay(item: T): unknown {
406
406
  <li
407
407
  v-for="(item, idx) in autocompleteList"
408
408
  :key="idx"
409
- class="cursor-pointer rounded-lg px-3 py-2 text-sm transition-colors duration-100 hover:bg-gray-50 dark:hover:bg-gray-800/60"
409
+ class="cursor-pointer rounded-md px-3 py-2 text-body-md transition-colors duration-100 hover:bg-gray-50 dark:hover:bg-gray-800/60"
410
410
  :class="{ 'input-v2__option--active': currentItemIndex === idx }"
411
411
  @mousedown.prevent="onSelectOption(item)"
412
412
  @touchend.prevent="onTouchEndOption(item)"
@@ -430,7 +430,7 @@ function rowDisplay(item: T): unknown {
430
430
  leave-from-class="input-v2__error-leave-from"
431
431
  leave-to-class="input-v2__error-leave-to"
432
432
  >
433
- <p v-if="hasError" class="mt-1 flex flex-col text-xs text-red-500 dark:text-red-400">
433
+ <p v-if="hasError" class="mt-1 flex flex-col text-body-sm text-red-500 dark:text-red-400">
434
434
  <span v-for="(err, idx) in errorMessages" :key="idx">{{ err }}</span>
435
435
  </p>
436
436
  </transition>
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
- import { twJoin, twMerge } from 'tailwind-merge'
3
2
  import ACalendar from "#adata-ui/components/elements/calendar/ACalendar.vue";
3
+ import { twJoin, twMerge } from '#adata-ui/utils/twMerge'
4
4
 
5
5
 
6
6
  interface Props {
@@ -48,7 +48,7 @@ const uiConfig = {
48
48
  "input-wrapper": {
49
49
  base: 'relative inline-block w-full text-sm sm:min-w-full'
50
50
  },
51
- base: 'w-full border-0 rounded-md text-deepblue-900 dark:text-gray-200 hover:outline hover:outline-1 hover:outline-blue-700 hover:dark:outline-blue-500 focus:outline focus:outline-blue-700 focus:dark:outline-blue-500 mt-0',
51
+ base: 'w-full border-0 rounded-sm text-deepblue-900 dark:text-gray-200 hover:outline hover:outline-1 hover:outline-blue-700 hover:dark:outline-blue-500 focus:outline focus:outline-blue-700 focus:dark:outline-blue-500 mt-0',
52
52
  size: {
53
53
  sm: 'h-8 px-4 py-1.5 sm',
54
54
  md: 'h-10 px-4 pb-1.5 pt-[18px] md'
@@ -1,13 +1,13 @@
1
1
  <script lang="ts" setup>
2
2
  import AInputStandard from "#adata-ui/components/forms/input/standard/AInputStandard.vue";
3
3
 
4
-
5
4
  interface Props {
6
5
  disabled?: boolean
7
6
  label?: string
8
7
  size?: 'sm' | 'md'
9
8
  error?: string
10
9
  required?: boolean
10
+ iconEyeTestId?: string
11
11
  }
12
12
 
13
13
  const props = withDefaults(defineProps<Props>(), {
@@ -19,19 +19,25 @@ const props = withDefaults(defineProps<Props>(), {
19
19
  })
20
20
 
21
21
  const isOpened = ref<boolean>(false)
22
+
23
+ const inputProps = computed(() => {
24
+ const { iconEyeTestId, ...rest } = props
25
+ return rest
26
+ })
22
27
  </script>
23
28
 
24
29
  <template>
25
30
  <a-input-standard
26
31
  v-bind="$attrs"
27
32
  :type="isOpened ? 'text' : 'password'"
28
- v-bind.prop="props"
33
+ v-bind.prop="inputProps"
29
34
  >
30
35
  <template #endButton>
31
36
  <button
32
37
  class="absolute top-1/2 right-4 text-gray-500 fill-gray-500 pointer-events-click text-2xl transform translate-y-[-50%] hover:opacity-80 disabled:pointer-events-none"
33
38
  :disabled="disabled"
34
39
  type="button"
40
+ :data-test-id="iconEyeTestId"
35
41
  @click="isOpened = !isOpened"
36
42
  >
37
43
  <a-icon-eye-closed
@@ -1,6 +1,6 @@
1
1
  <script generic="T, K extends keyof T" lang="ts" setup>
2
- import {twMerge, twJoin} from 'tailwind-merge'
3
2
  import AAlert from '#adata-ui/components/elements/alert/AAlert.vue'
3
+ import {twJoin, twMerge} from '#adata-ui/utils/twMerge'
4
4
 
5
5
  interface Props {
6
6
  disabled?: boolean
@@ -44,11 +44,11 @@ const {t} = useI18n()
44
44
  const uiConfig = {
45
45
  wrapper: 'transition duration-500 w-full',
46
46
  'input-wrapper': {
47
- base: 'relative inline-block w-full text-sm sm:min-w-full',
47
+ base: 'relative inline-block w-full text-body-md sm:min-w-full',
48
48
  readonly: 'pointer-events-none user-select-none',
49
49
  disabled: 'pointer-events-none user-select-none opacity-40'
50
50
  },
51
- base: 'w-full border-0 rounded-md text-deepblue-900 dark:text-gray-200 hover:outline outline-offset-[-1px] hover:outline-1 hover:outline-blue-700 hover:dark:outline-blue-500 focus:outline focus:outline-blue-700 focus:dark:outline-blue-500 mt-0',
51
+ base: 'w-full border-0 rounded-sm text-deepblue-900 dark:text-gray-200 hover:outline outline-offset-[-1px] hover:outline-1 hover:outline-blue-700 hover:dark:outline-blue-500 focus:outline focus:outline-blue-700 focus:dark:outline-blue-500 mt-0',
52
52
  size: {
53
53
  sm: 'h-8 px-4 py-1.5 sm',
54
54
  md: 'h-10 px-4 pb-1.5 pt-[18px] md',
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
- import { twMerge, twJoin } from 'tailwind-merge'
3
2
  import AAlert from '#adata-ui/components/elements/alert/AAlert.vue'
3
+ import { twJoin, twMerge } from '#adata-ui/utils/twMerge'
4
4
 
5
5
  interface Props {
6
6
  disabled?: boolean
@@ -38,7 +38,7 @@ const uiConfig = {
38
38
  disabled: 'pointer-events-none user-select-none opacity-40',
39
39
  color: 'bg-deepblue-900/5 dark:bg-gray-200/5'
40
40
  },
41
- base: 'w-full border-0 rounded-md text-deepblue-900 dark:text-gray-200 outline-none mt-0',
41
+ base: 'w-full border-0 rounded-sm text-deepblue-900 dark:text-gray-200 outline-none mt-0',
42
42
  size: {
43
43
  sm: 'h-8 px-4 py-1.5 sm',
44
44
  md: 'h-10 px-4 pb-1.5 pt-[8px] md'
@@ -1,8 +1,7 @@
1
1
  <script setup lang="ts">
2
- import {Switch} from "@headlessui/vue";
3
- import {twMerge, twJoin} from "tailwind-merge";
4
-
5
2
  import type {Props} from "./types";
3
+ import {twJoin, twMerge} from '#adata-ui/utils/twMerge';
4
+ import {Switch} from "@headlessui/vue";
6
5
 
7
6
  const props = withDefaults(defineProps<Props>(), {
8
7
  disabled: false,
@@ -15,8 +15,8 @@ const props = withDefaults(defineProps<{
15
15
  const model = defineModel<boolean>({ default: false })
16
16
 
17
17
  const SIZE: Record<Size, { track: string, knob: string, on: string, off: string, text: string }> = {
18
- sm: { track: 'h-5 w-9', knob: 'size-4', on: 'translate-x-4', off: 'translate-x-0.5', text: 'text-xs' },
19
- md: { track: 'h-6 w-11', knob: 'size-5', on: 'translate-x-5', off: 'translate-x-0.5', text: 'text-sm' },
18
+ sm: { track: 'h-5 w-9', knob: 'size-4', on: 'translate-x-4', off: 'translate-x-0.5', text: 'text-body-sm-medium' },
19
+ md: { track: 'h-6 w-11', knob: 'size-5', on: 'translate-x-5', off: 'translate-x-0.5', text: 'text-body-md-medium' },
20
20
  }
21
21
  const s = computed(() => SIZE[props.size])
22
22
 
@@ -39,7 +39,7 @@ function toggle() {
39
39
  >
40
40
  <span
41
41
  v-if="label"
42
- class="font-medium text-gray-600 transition-colors group-hover:text-gray-800 dark:text-gray-300 dark:group-hover:text-gray-100"
42
+ class="text-gray-600 transition-colors group-hover:text-gray-800 dark:text-gray-300 dark:group-hover:text-gray-100"
43
43
  :class="s.text"
44
44
  >
45
45
  {{ label }}
@@ -30,7 +30,7 @@ function onToMain() {
30
30
  {{ t('modals.another_device_modal.info') }}
31
31
  </p>
32
32
  <div
33
- class="body-400 flex gap-2 rounded-lg border border-red-500 bg-[#FDECEB] p-3 text-red-500 dark:border-red-400 dark:bg-red-400/10 dark:text-red-400"
33
+ class="body-400 flex gap-2 rounded-md border border-red-500 bg-[#FDECEB] p-3 text-red-500 dark:border-red-400 dark:bg-red-400/10 dark:text-red-400"
34
34
  >
35
35
  <a-icon-warning-triangle
36
36
  class="size-4 shrink-0"
@@ -170,7 +170,7 @@ watch(tab, (e) => {
170
170
  <nuxt-link
171
171
  to="/"
172
172
  @click="emits('pushMain')"
173
- class="flex items-center gap-4 rounded-md bg-gray-50 px-4 py-3 dark:bg-gray-800"
173
+ class="flex items-center gap-4 rounded-sm bg-gray-50 px-4 py-3 dark:bg-gray-800"
174
174
  >
175
175
  <a-icon-menu />
176
176
  {{ t('modals.mobile_navigation.return_button') }}
@@ -66,9 +66,9 @@ function onReturn() {
66
66
  v-for="item in currentLinks"
67
67
  :key="item.to"
68
68
  :to="item.to"
69
- class="group flex items-center gap-3 rounded-2xl border border-gray-100 bg-white px-3 py-2.5 transition-colors hover:border-blue-200 hover:bg-blue-50/50 dark:border-gray-800 dark:bg-gray-900 dark:hover:border-blue-500/30 dark:hover:bg-gray-800"
69
+ class="group flex items-center gap-3 rounded-xl border border-gray-100 bg-white px-3 py-2.5 transition-colors hover:border-blue-200 hover:bg-blue-50/50 dark:border-gray-800 dark:bg-gray-900 dark:hover:border-blue-500/30 dark:hover:bg-gray-800"
70
70
  >
71
- <span class="flex size-10 shrink-0 items-center justify-center rounded-xl bg-blue-50 text-blue-500 transition-colors group-hover:bg-blue-700 group-hover:text-white dark:bg-blue-500/10 dark:text-blue-500 dark:group-hover:bg-blue-500 dark:group-hover:text-white">
71
+ <span class="flex size-10 shrink-0 items-center justify-center rounded-lg bg-blue-50 text-blue-500 transition-colors group-hover:bg-blue-700 group-hover:text-white dark:bg-blue-500/10 dark:text-blue-500 dark:group-hover:bg-blue-500 dark:group-hover:text-white">
72
72
  <component
73
73
  :is="item.icon"
74
74
  class="size-5"
@@ -86,7 +86,7 @@ function onReturn() {
86
86
  <template #footer>
87
87
  <nuxt-link
88
88
  to="/"
89
- class="flex items-center justify-center gap-2 rounded-2xl bg-gray-100 px-4 py-3 text-sm font-semibold text-deepblue-900 transition-colors hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700"
89
+ class="flex items-center justify-center gap-2 rounded-xl bg-gray-100 px-4 py-3 text-sm font-semibold text-deepblue-900 transition-colors hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700"
90
90
  @click="onReturn"
91
91
  >
92
92
  <a-icon-menu class="size-5" />
@@ -30,7 +30,7 @@ function cancel() {
30
30
  <p class="text-center">
31
31
  {{ t('modals.low_balance.questions') }}
32
32
  </p>
33
- <div class="flex flex-col rounded-xl border border-blue-500 bg-blue-50 px-4 py-2 dark:border-blue-500 dark:bg-blue-950/40">
33
+ <div class="flex flex-col rounded-lg border border-blue-500 bg-blue-50 px-4 py-2 dark:border-blue-500 dark:bg-blue-950/40">
34
34
  <p class="body-600 text-center text-blue-700 dark:text-blue-300">
35
35
  {{ t('modals.low_balance.current_balance') }}
36
36
  </p>
@@ -66,7 +66,7 @@ if (props.deleteFromDom) {
66
66
  :name="`${item.name}`"
67
67
  side="right"
68
68
  :value="item.id"
69
- class="flex items-center justify-between gap-2 rounded-md bg-gray-50 p-[10px_16px] dark:bg-[#393D40]"
69
+ class="flex items-center justify-between gap-2 rounded-sm bg-gray-50 p-[10px_16px] dark:bg-[#393D40]"
70
70
  >
71
71
  <div class="flex w-full items-center gap-2">
72
72
  <component :is="item.img" />
@@ -9,15 +9,15 @@ function onRegister() {
9
9
  </script>
10
10
 
11
11
  <template>
12
- <div class="gradient flex flex-col gap-2 lg:gap-0 lg:flex-row justify-between rounded-lg p-4 ring-1 ring-inset ring-blue-700/80 dark:bg-gray-800">
12
+ <div class="gradient flex flex-col gap-2 lg:gap-0 lg:flex-row justify-between rounded-md p-4 ring-1 ring-inset ring-blue-700/80 dark:bg-gray-800">
13
13
  <div>
14
- <p class="mb-2 font-semibold">
14
+ <p class="mb-2 text-h5">
15
15
  {{ t('modals.id.banners.auth.title') }}
16
16
  </p>
17
17
  <i18n-t
18
18
  keypath="modals.id.banners.auth.subtitle"
19
19
  tag="p"
20
- class="text-sm text-gray-600 dark:text-gray-200"
20
+ class="text-body-md text-gray-600 dark:text-gray-200"
21
21
  >
22
22
  <template #register>
23
23
  <button class="font-semibold text-blue-700 dark:text-blue-500" @click="onRegister">
@@ -83,7 +83,7 @@ onBeforeUnmount(() => {
83
83
 
84
84
  <template>
85
85
  <form
86
- class="flex flex-col items-stretch gap-5 rounded-lg text-center"
86
+ class="flex flex-col items-stretch gap-5 rounded-md text-center"
87
87
  novalidate
88
88
  @submit.prevent="onSubmit"
89
89
  >
@@ -1,67 +1,128 @@
1
1
  <script lang="ts" setup>
2
2
  import type { Crumb } from './types'
3
- import { twMerge } from 'tailwind-merge'
3
+ import { twMerge } from '#adata-ui/utils/twMerge'
4
4
 
5
- defineProps<{
5
+ const props = defineProps<{
6
6
  links: Crumb[]
7
7
  customClasses?: string
8
+ collapsible?: boolean
8
9
  }>()
9
10
 
10
11
  const { t } = useI18n()
12
+
13
+ const expanded = ref(false)
14
+
15
+ type Item = { kind: 'crumb', crumb: Crumb, position: number } | { kind: 'ellipsis' }
16
+
17
+ const items = computed<Item[]>(() => {
18
+ const toItem = (crumb: Crumb, position: number): Item => ({ kind: 'crumb', crumb, position })
19
+
20
+ if (!props.collapsible || expanded.value || props.links.length <= 3) {
21
+ return props.links.map(toItem)
22
+ }
23
+
24
+ const last = props.links.length
25
+ return [
26
+ toItem(props.links[0], 0),
27
+ { kind: 'ellipsis' },
28
+ toItem(props.links[last - 2], last - 2),
29
+ toItem(props.links[last - 1], last - 1),
30
+ ]
31
+ })
11
32
  </script>
33
+
12
34
  <template>
13
- <div class="">
35
+ <div>
14
36
  <ul
15
- class="flex gap-1"
37
+ class="flex items-center gap-2"
16
38
  itemscope
17
39
  itemtype="https://schema.org/BreadcrumbList"
18
40
  >
19
- <li
20
- v-for="(breadcrumbItem, idx) in links"
21
- :key="idx"
22
- :class="
23
- twMerge(
24
- 'flex items-center text-xs text-gray-500 underline-offset-2 last-of-type:text-deepblue-900 hover:underline dark:last-of-type:text-gray-200',
25
- customClasses
26
- )
27
- "
28
- itemprop="itemListElement"
29
- itemscope
30
- itemtype="https://schema.org/ListItem"
41
+ <template
42
+ v-for="(item, idx) in items"
43
+ :key="item.kind === 'crumb' ? item.position : 'ellipsis'"
31
44
  >
32
- <meta
33
- itemprop="position"
34
- :content="`${idx}`"
35
- >
36
- <slot
37
- name="icon"
38
- :breadcrumb-item="breadcrumbItem"
39
- :index="idx"
45
+ <li
46
+ v-if="item.kind === 'ellipsis'"
47
+ class="flex items-center gap-2"
40
48
  >
41
- <span v-if="idx !== 0">
42
- <a-icon-chevron-right />
49
+ <span class="text-[#CAD5E2] dark:text-gray-600">
50
+ <a-icon-chevron-right class="size-4" />
43
51
  </span>
44
- </slot>
45
- <nuxt-link-locale
46
- v-if="breadcrumbItem.to"
47
- class="pl-1"
48
- :to="breadcrumbItem.to"
49
- rel="noopener noreferrer"
50
- itemprop="item"
51
- :data-test-id="breadcrumbItem?.dataTestId"
52
- >
53
- <span itemprop="name">
54
- {{ t(breadcrumbItem.label) }}
55
- </span>
56
- </nuxt-link-locale>
57
- <span
52
+ <button
53
+ type="button"
54
+ class="flex size-[18px] items-center justify-center rounded text-[#62748E] transition-colors hover:text-deepblue-900 dark:text-gray-400 dark:hover:text-gray-200"
55
+ :aria-label="t('actions.showMore')"
56
+ @click="expanded = true"
57
+ >
58
+ <a-icon-horizontal-more class="size-4" />
59
+ </button>
60
+ </li>
61
+ <li
58
62
  v-else
59
- class="pl-1"
60
- itemprop="name"
63
+ :class="
64
+ twMerge(
65
+ 'flex items-center gap-2 text-body-md text-[#62748E] underline-offset-2 last-of-type:font-semibold last-of-type:text-deepblue-900 hover:underline dark:text-gray-400 dark:last-of-type:text-gray-200',
66
+ customClasses,
67
+ )
68
+ "
69
+ itemprop="itemListElement"
70
+ itemscope
71
+ itemtype="https://schema.org/ListItem"
61
72
  >
62
- {{ t(breadcrumbItem.label) }}
63
- </span>
64
- </li>
73
+ <meta
74
+ itemprop="position"
75
+ :content="`${item.position}`"
76
+ >
77
+ <slot
78
+ name="icon"
79
+ :breadcrumb-item="item.crumb"
80
+ :index="idx"
81
+ >
82
+ <span
83
+ v-if="idx !== 0"
84
+ class="text-[#CAD5E2] dark:text-gray-600"
85
+ >
86
+ <a-icon-chevron-right class="size-4" />
87
+ </span>
88
+ </slot>
89
+ <nuxt-link-locale
90
+ v-if="item.crumb.to"
91
+ class="flex items-center"
92
+ :to="item.crumb.to"
93
+ rel="noopener noreferrer"
94
+ itemprop="item"
95
+ :data-test-id="item.crumb?.dataTestId"
96
+ :aria-label="item.crumb.icon ? t(item.crumb.label) : undefined"
97
+ >
98
+ <component
99
+ :is="item.crumb.icon"
100
+ v-if="item.crumb.icon"
101
+ class="size-[18px]"
102
+ />
103
+ <span
104
+ itemprop="name"
105
+ :class="item.crumb.icon ? 'sr-only' : ''"
106
+ >
107
+ {{ t(item.crumb.label) }}
108
+ </span>
109
+ </nuxt-link-locale>
110
+ <span
111
+ v-else
112
+ class="flex items-center"
113
+ itemprop="name"
114
+ >
115
+ <component
116
+ :is="item.crumb.icon"
117
+ v-if="item.crumb.icon"
118
+ class="size-[18px]"
119
+ />
120
+ <span :class="item.crumb.icon ? 'sr-only' : ''">
121
+ {{ t(item.crumb.label) }}
122
+ </span>
123
+ </span>
124
+ </li>
125
+ </template>
65
126
  </ul>
66
127
  </div>
67
128
  </template>
@@ -1,5 +1,8 @@
1
+ import type { Component } from 'vue'
2
+
1
3
  export interface Crumb {
2
4
  label: string
3
5
  to: string
4
6
  dataTestId?: string
7
+ icon?: Component
5
8
  }