@feugene/granularity 0.42.0 → 0.44.0

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 (193) hide show
  1. package/README.md +2 -2
  2. package/dist/chunks/config-BXRmsn3t.js +172 -0
  3. package/dist/chunks/config-BXRmsn3t.js.map +1 -0
  4. package/dist/chunks/config-BkQ2jvXv.js +49 -0
  5. package/dist/chunks/config-BkQ2jvXv.js.map +1 -0
  6. package/dist/chunks/config-Dg0bSoGw.js +81 -0
  7. package/dist/chunks/config-Dg0bSoGw.js.map +1 -0
  8. package/dist/chunks/config-DmED6aJV.js +237 -0
  9. package/dist/chunks/config-DmED6aJV.js.map +1 -0
  10. package/dist/chunks/{config-DWL81-aM.js → config-hnoZvcIM.js} +2 -20
  11. package/dist/chunks/config-hnoZvcIM.js.map +1 -0
  12. package/dist/chunks/dragSortGeometry-CY-llfrQ.js +87 -0
  13. package/dist/chunks/dragSortGeometry-CY-llfrQ.js.map +1 -0
  14. package/dist/chunks/{en-B9E3jO6m.js → en-DiHzFact.js} +34 -1
  15. package/dist/chunks/en-DiHzFact.js.map +1 -0
  16. package/dist/chunks/{es-QpzdIEut.js → es-1ZL6NtkB.js} +34 -1
  17. package/dist/chunks/es-1ZL6NtkB.js.map +1 -0
  18. package/dist/chunks/{es-DCkqHTlU.js → es-CeKkMxZ_.js} +3 -3
  19. package/dist/chunks/{es-DCkqHTlU.js.map → es-CeKkMxZ_.js.map} +1 -1
  20. package/dist/chunks/{generated-B95IBXs6.js → generated-Hxu_sWPs.js} +238 -0
  21. package/dist/chunks/generated-Hxu_sWPs.js.map +1 -0
  22. package/dist/chunks/{granular-provider-BG_2XqkS.js → granular-provider-CCNbQa5U.js} +9 -1
  23. package/dist/chunks/granular-provider-CCNbQa5U.js.map +1 -0
  24. package/dist/chunks/{ru-D_1Ya489.js → ru-Dr2RYn0P.js} +34 -1
  25. package/dist/chunks/ru-Dr2RYn0P.js.map +1 -0
  26. package/dist/chunks/scrollOverflow-B_kEdcol.js +31 -0
  27. package/dist/chunks/scrollOverflow-B_kEdcol.js.map +1 -0
  28. package/dist/chunks/tones-CRJAaYyg.js +21 -0
  29. package/dist/chunks/tones-CRJAaYyg.js.map +1 -0
  30. package/dist/chunks/useScrollSpy-CIJpw0RI.js +360 -0
  31. package/dist/chunks/useScrollSpy-CIJpw0RI.js.map +1 -0
  32. package/dist/components/GrAffix/chunks/GrAffix-CWtC7yi8.js +272 -0
  33. package/dist/components/GrAffix/chunks/GrAffix-CWtC7yi8.js.map +1 -0
  34. package/dist/components/GrAffix/index.js +3 -0
  35. package/dist/components/GrCarousel/chunks/GrCarousel-ByuughtI.js +761 -0
  36. package/dist/components/GrCarousel/chunks/GrCarousel-ByuughtI.js.map +1 -0
  37. package/dist/components/GrCarousel/index.js +3 -0
  38. package/dist/components/GrCarousel/styles.css +1 -0
  39. package/dist/components/GrColorPicker/chunks/{GrColorPicker-BwzRLs-i.js → GrColorPicker-9mTR-YZ_.js} +1 -1
  40. package/dist/components/GrColorPicker/chunks/{GrColorPicker-BwzRLs-i.js.map → GrColorPicker-9mTR-YZ_.js.map} +1 -1
  41. package/dist/components/GrColorPicker/index.js +1 -1
  42. package/dist/components/GrDataTable/chunks/{GrDataTable-BBe7-uUe.js → GrDataTable-xNSmO_I-.js} +4 -3
  43. package/dist/components/GrDataTable/chunks/{GrDataTable-BBe7-uUe.js.map → GrDataTable-xNSmO_I-.js.map} +1 -1
  44. package/dist/components/GrDataTable/index.js +1 -1
  45. package/dist/components/GrImageViewer/chunks/{GrImageViewer-Dd2gJ-j_.js.map → GrImageViewer-DK-iVHHC.js.map} +1 -1
  46. package/dist/components/GrImageViewer/index.js +1 -1
  47. package/dist/components/GrInputTag/chunks/{GrInputTag-BKzm1PKw.js.map → GrInputTag-Ci8AO1ze.js.map} +1 -1
  48. package/dist/components/GrInputTag/index.js +1 -1
  49. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BLCEWlwg.js → GrJsonViewer-CwCBMh4h.js} +2 -2
  50. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BLCEWlwg.js.map → GrJsonViewer-CwCBMh4h.js.map} +1 -1
  51. package/dist/components/GrJsonViewer/index.js +1 -1
  52. package/dist/components/GrNumberInput/chunks/{GrNumberInput-Bm-V59TG.js.map → GrNumberInput-CL5QhOmx.js.map} +1 -1
  53. package/dist/components/GrNumberInput/index.js +1 -1
  54. package/dist/components/GrProgressBar/index.js +1 -1
  55. package/dist/components/GrScrollSpy/chunks/GrScrollSpy-CQCH3zLC.js +207 -0
  56. package/dist/components/GrScrollSpy/chunks/GrScrollSpy-CQCH3zLC.js.map +1 -0
  57. package/dist/components/GrScrollSpy/index.js +3 -0
  58. package/dist/components/GrSlider/chunks/{GrSlider-Db-jACXz.js.map → GrSlider-CO8N9SF6.js.map} +1 -1
  59. package/dist/components/GrSlider/index.js +1 -1
  60. package/dist/components/GrSortableList/chunks/{GrSortableList-ce1psLL0.js → GrSortableList-NKriuGm_.js} +2 -1
  61. package/dist/components/GrSortableList/chunks/{GrSortableList-ce1psLL0.js.map → GrSortableList-NKriuGm_.js.map} +1 -1
  62. package/dist/components/GrSortableList/index.js +1 -1
  63. package/dist/components/GrTabs/chunks/{GrTabs-BArefUFv.js → GrTabs-s9RzC1WX.js} +2 -31
  64. package/dist/components/GrTabs/chunks/GrTabs-s9RzC1WX.js.map +1 -0
  65. package/dist/components/GrTabs/index.js +1 -1
  66. package/dist/components/GrTransfer/chunks/GrTransfer-8FA78ny6.js +1368 -0
  67. package/dist/components/GrTransfer/chunks/GrTransfer-8FA78ny6.js.map +1 -0
  68. package/dist/components/GrTransfer/index.js +3 -0
  69. package/dist/components/GrTransfer/styles.css +1 -0
  70. package/dist/components/GrTree/chunks/{GrTree-BFWFc0Bm.js → GrTree-CkHzgYg1.js} +3 -3
  71. package/dist/components/GrTree/chunks/{GrTree-BFWFc0Bm.js.map → GrTree-CkHzgYg1.js.map} +1 -1
  72. package/dist/components/GrTree/index.js +1 -1
  73. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DJa2lYGe.js → GrTreeSelect-DUsv3_mF.js} +1 -1
  74. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DJa2lYGe.js.map → GrTreeSelect-DUsv3_mF.js.map} +1 -1
  75. package/dist/components/GrTreeSelect/index.js +1 -1
  76. package/dist/composables/useDragSort.js +179 -1
  77. package/dist/composables/useDragSort.js.map +1 -0
  78. package/dist/composables/useScrollSpy.js +2 -0
  79. package/dist/granular-provider-node.js +1 -1
  80. package/dist/granular-provider.js +1 -1
  81. package/dist/i18n/all.js +1 -1
  82. package/dist/i18n/index.js +1 -1
  83. package/dist/index.js +26 -19
  84. package/dist/theme.js +1 -1
  85. package/dist/tokens.js +1 -1
  86. package/dist/types/components/GrAffix/GrAffix.vue.d.ts +91 -0
  87. package/dist/types/components/GrAffix/affixState.d.ts +81 -0
  88. package/dist/types/components/GrAffix/config.d.ts +1 -0
  89. package/dist/types/components/GrAffix/grAffixStyles.d.ts +46 -0
  90. package/dist/types/components/GrAffix/index.d.ts +9 -0
  91. package/dist/types/components/GrAffix/safelist.d.ts +1 -0
  92. package/dist/types/components/GrAlert/GrAlert.vue.d.ts +1 -1
  93. package/dist/types/components/GrBadgeWrap/GrBadgeWrap.vue.d.ts +2 -2
  94. package/dist/types/components/GrButton/GrButton.vue.d.ts +2 -2
  95. package/dist/types/components/GrCard/GrCard.vue.d.ts +1 -1
  96. package/dist/types/components/GrCarousel/GrCarousel.vue.d.ts +151 -0
  97. package/dist/types/components/GrCarousel/GrCarouselSlide.vue.d.ts +53 -0
  98. package/dist/types/components/GrCarousel/carouselNavigation.d.ts +57 -0
  99. package/dist/types/components/GrCarousel/composables/useCarouselAutoplay.d.ts +33 -0
  100. package/dist/types/components/GrCarousel/composables/useCarouselSwipe.d.ts +20 -0
  101. package/dist/types/components/GrCarousel/config.d.ts +7 -0
  102. package/dist/types/components/GrCarousel/defaults.d.ts +13 -0
  103. package/dist/types/components/GrCarousel/grCarouselContext.d.ts +46 -0
  104. package/dist/types/components/GrCarousel/grCarouselStyles.d.ts +80 -0
  105. package/dist/types/components/GrCarousel/index.d.ts +12 -0
  106. package/dist/types/components/GrCarousel/safelist.d.ts +1 -0
  107. package/dist/types/components/GrCheckbox/GrCheckbox.vue.d.ts +3 -3
  108. package/dist/types/components/GrCheckboxGroup/GrCheckboxGroup.vue.d.ts +2 -2
  109. package/dist/types/components/GrChip/GrChip.vue.d.ts +2 -2
  110. package/dist/types/components/GrChipGroup/GrChipGroup.vue.d.ts +2 -2
  111. package/dist/types/components/GrCollapse/GrCollapse.vue.d.ts +1 -1
  112. package/dist/types/components/GrCollapse/GrCollapseItem.vue.d.ts +1 -1
  113. package/dist/types/components/GrColorPicker/GrColorPicker.vue.d.ts +3 -3
  114. package/dist/types/components/GrCommandPalette/GrCommandPalette.vue.d.ts +1 -1
  115. package/dist/types/components/GrConfirmDialog/GrConfirmDialog.vue.d.ts +1 -1
  116. package/dist/types/components/GrContextMenu/GrContextMenu.vue.d.ts +2 -2
  117. package/dist/types/components/GrDialog/GrDialog.vue.d.ts +1 -1
  118. package/dist/types/components/GrDivider/GrDivider.vue.d.ts +2 -2
  119. package/dist/types/components/GrDrawer/GrDrawer.vue.d.ts +1 -1
  120. package/dist/types/components/GrDropdown/GrDropdown.vue.d.ts +3 -3
  121. package/dist/types/components/GrDropdownMenu/GrDropdownMenu.vue.d.ts +3 -3
  122. package/dist/types/components/GrDropdownMenu/GrDropdownMenuItem.vue.d.ts +1 -1
  123. package/dist/types/components/GrEmptyState/GrEmptyState.vue.d.ts +1 -1
  124. package/dist/types/components/GrFileUpload/GrFileUpload.vue.d.ts +1 -1
  125. package/dist/types/components/GrFormField/GrFormField.vue.d.ts +3 -3
  126. package/dist/types/components/GrFormFile/GrFormFile.vue.d.ts +2 -2
  127. package/dist/types/components/GrFormSection/GrFormSection.vue.d.ts +1 -1
  128. package/dist/types/components/GrIcon/GrIcon.vue.d.ts +1 -1
  129. package/dist/types/components/GrImageViewer/GrImageViewer.vue.d.ts +3 -3
  130. package/dist/types/components/GrInput/GrInput.vue.d.ts +4 -4
  131. package/dist/types/components/GrInputTag/GrInputTag.vue.d.ts +3 -3
  132. package/dist/types/components/GrKbd/GrKbd.vue.d.ts +1 -1
  133. package/dist/types/components/GrLink/GrLink.vue.d.ts +1 -1
  134. package/dist/types/components/GrList/GrListItem.vue.d.ts +2 -2
  135. package/dist/types/components/GrNavbar/GrNavbar.vue.d.ts +2 -2
  136. package/dist/types/components/GrNumberInput/GrNumberInput.vue.d.ts +3 -3
  137. package/dist/types/components/GrPagination/GrPagination.vue.d.ts +1 -1
  138. package/dist/types/components/GrPopover/GrPopover.vue.d.ts +3 -3
  139. package/dist/types/components/GrPromptDialog/GrPromptDialog.vue.d.ts +3 -3
  140. package/dist/types/components/GrRadio/GrRadio.vue.d.ts +2 -2
  141. package/dist/types/components/GrRadioGroup/GrRadioGroup.vue.d.ts +2 -2
  142. package/dist/types/components/GrRating/GrRating.vue.d.ts +2 -2
  143. package/dist/types/components/GrScrollSpy/GrScrollSpy.vue.d.ts +105 -0
  144. package/dist/types/components/GrScrollSpy/config.d.ts +1 -0
  145. package/dist/types/components/GrScrollSpy/grScrollSpyStyles.d.ts +26 -0
  146. package/dist/types/components/GrScrollSpy/index.d.ts +9 -0
  147. package/dist/types/components/GrScrollSpy/safelist.d.ts +1 -0
  148. package/dist/types/components/GrScrollSpy/scrollSpyItems.d.ts +44 -0
  149. package/dist/types/components/GrSegmented/GrSegmented.vue.d.ts +2 -2
  150. package/dist/types/components/GrSidebar/GrSidebarItem.vue.d.ts +1 -1
  151. package/dist/types/components/GrSkeleton/GrSkeleton.vue.d.ts +1 -1
  152. package/dist/types/components/GrSlider/GrSlider.vue.d.ts +3 -3
  153. package/dist/types/components/GrSplitter/GrSplitter.vue.d.ts +1 -1
  154. package/dist/types/components/GrStatistic/GrStatistic.vue.d.ts +2 -2
  155. package/dist/types/components/GrSwitch/GrSwitch.vue.d.ts +3 -3
  156. package/dist/types/components/GrTable/GrTable.vue.d.ts +1 -1
  157. package/dist/types/components/GrTabs/GrTabs.vue.d.ts +1 -1
  158. package/dist/types/components/GrTextarea/GrTextarea.vue.d.ts +2 -2
  159. package/dist/types/components/GrTimeline/GrTimelineItem.vue.d.ts +2 -2
  160. package/dist/types/components/GrToaster/GrToaster.vue.d.ts +1 -1
  161. package/dist/types/components/GrTooltip/GrTooltip.vue.d.ts +3 -3
  162. package/dist/types/components/GrTransfer/GrTransfer.vue.d.ts +103 -0
  163. package/dist/types/components/GrTransfer/config.d.ts +1 -0
  164. package/dist/types/components/GrTransfer/defaults.d.ts +15 -0
  165. package/dist/types/components/GrTransfer/grTransferStyles.d.ts +127 -0
  166. package/dist/types/components/GrTransfer/index.d.ts +11 -0
  167. package/dist/types/components/GrTransfer/safelist.d.ts +1 -0
  168. package/dist/types/components/GrTransfer/transferGeometry.d.ts +44 -0
  169. package/dist/types/components/GrTransfer/transferModel.d.ts +68 -0
  170. package/dist/types/components/GrTransfer/transferSelection.d.ts +36 -0
  171. package/dist/types/components/GrTransfer/useTransferDrag.d.ts +48 -0
  172. package/dist/types/composables/internal/scrollSpyGeometry.d.ts +67 -0
  173. package/dist/types/composables/useScrollSpy.d.ts +59 -0
  174. package/dist/types/granular-provider/shared.d.ts +4 -0
  175. package/dist/types/i18n/messages/en.d.ts +64 -0
  176. package/dist/types/i18n/messages/es.d.ts +64 -0
  177. package/dist/types/i18n/messages/ru.d.ts +64 -0
  178. package/dist/types/index.d.ts +6 -0
  179. package/dist/web-types.json +809 -284
  180. package/package.json +25 -1
  181. package/dist/chunks/config-DWL81-aM.js.map +0 -1
  182. package/dist/chunks/en-B9E3jO6m.js.map +0 -1
  183. package/dist/chunks/es-QpzdIEut.js.map +0 -1
  184. package/dist/chunks/generated-B95IBXs6.js.map +0 -1
  185. package/dist/chunks/granular-provider-BG_2XqkS.js.map +0 -1
  186. package/dist/chunks/ru-D_1Ya489.js.map +0 -1
  187. package/dist/chunks/useDragSort-0l47h4yb.js +0 -265
  188. package/dist/chunks/useDragSort-0l47h4yb.js.map +0 -1
  189. package/dist/components/GrTabs/chunks/GrTabs-BArefUFv.js.map +0 -1
  190. package/dist/components/GrImageViewer/chunks/{GrImageViewer-Dd2gJ-j_.js → GrImageViewer-DK-iVHHC.js} +3 -3
  191. package/dist/components/GrInputTag/chunks/{GrInputTag-BKzm1PKw.js → GrInputTag-Ci8AO1ze.js} +1 -1
  192. package/dist/components/GrNumberInput/chunks/{GrNumberInput-Bm-V59TG.js → GrNumberInput-CL5QhOmx.js} +1 -1
  193. package/dist/components/GrSlider/chunks/{GrSlider-Db-jACXz.js → GrSlider-CO8N9SF6.js} +1 -1
@@ -0,0 +1,761 @@
1
+ import { i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
2
+ import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
3
+ import { t as useFocusWithin } from "../../../chunks/useFocusWithin-BwHE0rzm.js";
4
+ import { useRovingFocus } from "../../../composables/useRovingFocus.js";
5
+ import { useAnnouncer } from "../../../composables/useAnnouncer.js";
6
+ import { t as resolveScrollOverflow } from "../../../chunks/scrollOverflow-B_kEdcol.js";
7
+ import { useDragGesture } from "../../../composables/useDragGesture.js";
8
+ import { a as carouselSlideBase, c as carouselToggleClass, d as carouselViewportSwipeClass, f as grCarouselControlClass, i as carouselRootBase, l as carouselTrackBase, m as grCarouselIndicatorsClass, o as carouselThumbFallbackClass, p as grCarouselIndicatorClass, r as carouselIconClass, s as carouselThumbImageClass, u as carouselViewportBase } from "../../../chunks/config-BXRmsn3t.js";
9
+ import { t as chevron_left_default } from "../../../chunks/chevron-left-D8AUBAM7.js";
10
+ import { t as chevron_right_default } from "../../../chunks/chevron-right-C6Z01h0X.js";
11
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, markRaw, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, openBlock, provide, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useId, useSlots, watch, watchEffect } from "vue";
12
+ import '../styles.css';/**
13
+ * Доля ширины вьюпорта, начиная с которой жест засчитывается. Работает вместе
14
+ * с {@link SWIPE_THRESHOLD_PX} по максимуму: 60px на герое шириной 1200px —
15
+ * это нервно, а на узкой карточке доля выродилась бы в пару пикселей.
16
+ */
17
+ var SWIPE_THRESHOLD_RATIO = .15;
18
+ /**
19
+ * Логическое направление жеста: `1` — вперёд, `-1` — назад, `0` — не свайп.
20
+ *
21
+ * `dx` физический, в пикселях экрана; разворот под RTL — забота вызывающего,
22
+ * модуль про направление письма не знает. Палец, ушедший влево, листает вперёд:
23
+ * содержимое едет за пальцем, как в нативной прокрутке.
24
+ *
25
+ * Отдельным модулем, потому что в jsdom раскладки нет и через смонтированный
26
+ * компонент ни одна ветка не проверяется — тот же довод, что у
27
+ * {@link resolveScrollOverflow}.
28
+ */
29
+ function resolveSwipeDirection(dx, dy, threshold = 60) {
30
+ if (Math.abs(dx) < threshold) return 0;
31
+ if (Math.abs(dx) < Math.abs(dy) * 1.5) return 0;
32
+ return dx < 0 ? 1 : -1;
33
+ }
34
+ /**
35
+ * Порог жеста для ленты шириной `width`. При нулевой ширине — а в jsdom она
36
+ * всегда нулевая — вырождается в пиксельный минимум, и жест остаётся
37
+ * проверяемым.
38
+ */
39
+ function swipeThresholdFor(width) {
40
+ return Math.max(60, width * SWIPE_THRESHOLD_RATIO);
41
+ }
42
+ /** Смещение ленты за пальцем: за краем — вязкое, иначе один в один. */
43
+ function resistOffset(delta, atEdge) {
44
+ return atEdge ? delta / 4 : delta;
45
+ }
46
+ /**
47
+ * Индекс, зажатый в границы ленты. Пустая лента даёт `0`: слайда с таким
48
+ * номером нет, но отрицательный индекс уехал бы в CSS-переменную трека.
49
+ */
50
+ function clampIndex(index, count) {
51
+ if (count <= 0) return 0;
52
+ if (!Number.isFinite(index)) return 0;
53
+ return Math.min(Math.max(Math.trunc(index), 0), count - 1);
54
+ }
55
+ /**
56
+ * Шаг по ленте. Без `loop` на краю возвращает тот же индекс — вызывающий по
57
+ * этому признаку и гасит стрелку, отдельного предиката не нужно.
58
+ */
59
+ function stepIndex(index, delta, count, loop) {
60
+ if (count <= 0) return 0;
61
+ const next = clampIndex(index, count) + delta;
62
+ if (loop) return (next % count + count) % count;
63
+ return clampIndex(next, count);
64
+ }
65
+ /**
66
+ * Насколько прокрутить полосу переключателей, чтобы кадр был виден.
67
+ *
68
+ * Считается своей арифметикой, а не `scrollIntoView`: тот прокручивает **всех**
69
+ * предков, включая документ, — и карусель, уехавшая под сгиб, на каждом шаге
70
+ * автопрокрутки утаскивала бы страницу обратно к себе. Здесь двигается только
71
+ * сама полоса.
72
+ *
73
+ * Движение минимальное: элемент уже виден — `scrollLeft` не меняется вовсе.
74
+ */
75
+ function stripScrollLeft(scrollLeft, viewport, itemStart, itemEnd, padding = 0) {
76
+ if (viewport <= 0) return scrollLeft;
77
+ if (itemStart - padding < scrollLeft) return Math.max(0, itemStart - padding);
78
+ if (itemEnd + padding > scrollLeft + viewport) return itemEnd + padding - viewport;
79
+ return scrollLeft;
80
+ }
81
+ //#endregion
82
+ //#region src/components/GrCarousel/composables/useCarouselAutoplay.ts
83
+ /**
84
+ * Таймер автопрокрутки с паузой по остатку.
85
+ *
86
+ * Модель взята у `useToast` (`{ handle, remaining, startedAt }`), и `setInterval`
87
+ * здесь не годится принципиально: паузу, сохраняющую остаток, на нём не
88
+ * выразить — курсор, снятый за полсекунды до шага, откладывал бы шаг на полный
89
+ * интервал.
90
+ *
91
+ * Композабл локальный: публичный потребовал бы записей в трёх реестрах пакета,
92
+ * а переиспользовать его сегодня некому.
93
+ */
94
+ function useCarouselAutoplay(options) {
95
+ let handle = null;
96
+ let remaining = 0;
97
+ let startedAt = 0;
98
+ const armed = ref(false);
99
+ function clear() {
100
+ if (handle !== null) {
101
+ clearTimeout(handle);
102
+ handle = null;
103
+ }
104
+ armed.value = false;
105
+ }
106
+ function arm() {
107
+ if (typeof window === "undefined" || remaining <= 0) return;
108
+ startedAt = Date.now();
109
+ armed.value = true;
110
+ handle = window.setTimeout(() => {
111
+ handle = null;
112
+ remaining = options.interval();
113
+ options.advance();
114
+ if (options.enabled() && !options.paused()) arm();
115
+ else clear();
116
+ }, remaining);
117
+ }
118
+ function pause() {
119
+ if (handle === null) {
120
+ armed.value = false;
121
+ return;
122
+ }
123
+ clearTimeout(handle);
124
+ handle = null;
125
+ armed.value = false;
126
+ remaining = Math.max(0, remaining - (Date.now() - startedAt));
127
+ }
128
+ function restart() {
129
+ clear();
130
+ remaining = options.interval();
131
+ if (options.enabled() && !options.paused()) arm();
132
+ }
133
+ watchEffect(() => {
134
+ const ms = options.interval();
135
+ if (!options.enabled() || options.paused() || ms <= 0) {
136
+ pause();
137
+ return;
138
+ }
139
+ if (handle !== null) return;
140
+ if (remaining <= 0) remaining = ms;
141
+ arm();
142
+ });
143
+ onScopeDispose(clear);
144
+ return {
145
+ running: computed(() => armed.value),
146
+ restart
147
+ };
148
+ }
149
+ //#endregion
150
+ //#region src/components/GrCarousel/composables/useCarouselSwipe.ts
151
+ /**
152
+ * Что внутри слайда остаётся нажатием, а не превращается в протяжку. Ссылка и
153
+ * кнопка в онбординг-слайде — обычный интерактив, и жест их перехватывать
154
+ * не вправе (приём `GrToaster`).
155
+ */
156
+ var INTERACTIVE_SELECTOR = "a[href], button, input, textarea, select, summary, [role=\"button\"], [contenteditable]";
157
+ function useCarouselSwipe(options) {
158
+ const offset = ref(0);
159
+ let startX = 0;
160
+ let startY = 0;
161
+ let threshold = 0;
162
+ let rtl = false;
163
+ function reset() {
164
+ offset.value = 0;
165
+ }
166
+ const drag = useDragGesture({
167
+ disabled: options.disabled,
168
+ onStart: (event) => {
169
+ if (event.target?.closest(INTERACTIVE_SELECTOR)) return false;
170
+ const viewport = options.viewport();
171
+ if (!viewport) return false;
172
+ startX = event.clientX;
173
+ startY = event.clientY;
174
+ offset.value = 0;
175
+ threshold = swipeThresholdFor(viewport.getBoundingClientRect().width);
176
+ rtl = getComputedStyle(viewport).direction === "rtl";
177
+ options.onStart?.();
178
+ },
179
+ onMove: (event) => {
180
+ event.preventDefault();
181
+ const dx = event.clientX - startX;
182
+ const dy = event.clientY - startY;
183
+ if (Math.abs(dx) < Math.abs(dy) * 1.5) {
184
+ offset.value = 0;
185
+ return;
186
+ }
187
+ const logical = physicalToLogical(dx < 0 ? 1 : -1);
188
+ offset.value = resistOffset(dx, options.atEdge(logical));
189
+ },
190
+ onEnd: (event) => {
191
+ const direction = event ? resolveSwipeDirection(event.clientX - startX, event.clientY - startY, threshold) : 0;
192
+ reset();
193
+ if (direction !== 0) options.onSwipe(physicalToLogical(direction));
194
+ },
195
+ onCancel: reset
196
+ });
197
+ /** В RTL содержимое течёт справа налево, и палец влево листает назад. */
198
+ function physicalToLogical(direction) {
199
+ return rtl ? direction === 1 ? -1 : 1 : direction;
200
+ }
201
+ return {
202
+ isDragging: drag.isDragging,
203
+ offset,
204
+ start: drag.start
205
+ };
206
+ }
207
+ //#endregion
208
+ //#region src/components/GrCarousel/grCarouselContext.ts
209
+ var GR_CAROUSEL_CONTEXT = Symbol("GR_CAROUSEL_CONTEXT");
210
+ //#endregion
211
+ //#region ~icons/lucide/pause
212
+ var _hoisted_1$3 = {
213
+ viewBox: "0 0 24 24",
214
+ width: "1.2em",
215
+ height: "1.2em"
216
+ };
217
+ function render$2(_ctx, _cache) {
218
+ return openBlock(), createElementBlock("svg", _hoisted_1$3, [..._cache[0] || (_cache[0] = [createElementVNode("g", {
219
+ fill: "none",
220
+ stroke: "currentColor",
221
+ "stroke-linecap": "round",
222
+ "stroke-linejoin": "round",
223
+ "stroke-width": "2"
224
+ }, [createElementVNode("rect", {
225
+ width: "5",
226
+ height: "18",
227
+ x: "14",
228
+ y: "3",
229
+ rx: "1"
230
+ }), createElementVNode("rect", {
231
+ width: "5",
232
+ height: "18",
233
+ x: "5",
234
+ y: "3",
235
+ rx: "1"
236
+ })], -1)])]);
237
+ }
238
+ var pause_default = markRaw({
239
+ name: "lucide-pause",
240
+ render: render$2
241
+ });
242
+ //#endregion
243
+ //#region ~icons/lucide/play
244
+ var _hoisted_1$2 = {
245
+ viewBox: "0 0 24 24",
246
+ width: "1.2em",
247
+ height: "1.2em"
248
+ };
249
+ function render$1(_ctx, _cache) {
250
+ return openBlock(), createElementBlock("svg", _hoisted_1$2, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
251
+ fill: "none",
252
+ stroke: "currentColor",
253
+ "stroke-linecap": "round",
254
+ "stroke-linejoin": "round",
255
+ "stroke-width": "2",
256
+ d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z"
257
+ }, null, -1)])]);
258
+ }
259
+ var play_default = markRaw({
260
+ name: "lucide-play",
261
+ render: render$1
262
+ });
263
+ //#endregion
264
+ //#region src/components/GrCarousel/GrCarousel.vue?vue&type=script&setup=true&lang.ts
265
+ var _hoisted_1$1 = [
266
+ "role",
267
+ "aria-roledescription",
268
+ "aria-label",
269
+ "aria-labelledby"
270
+ ];
271
+ var _hoisted_2 = ["aria-live"];
272
+ var _hoisted_3 = ["aria-label"];
273
+ var _hoisted_4 = ["aria-disabled", "aria-label"];
274
+ var _hoisted_5 = ["aria-disabled", "aria-label"];
275
+ var _hoisted_6 = [
276
+ "data-variant",
277
+ "data-overflow",
278
+ "aria-label"
279
+ ];
280
+ var _hoisted_7 = [
281
+ "id",
282
+ "aria-selected",
283
+ "aria-controls",
284
+ "aria-label",
285
+ "tabindex",
286
+ "onClick"
287
+ ];
288
+ var _hoisted_8 = ["src"];
289
+ //#endregion
290
+ //#region src/components/GrCarousel/GrCarousel.vue
291
+ var GrCarousel_default = /* @__PURE__ */ defineComponent({
292
+ __name: "GrCarousel",
293
+ props: {
294
+ modelValue: { default: void 0 },
295
+ autoplay: {
296
+ type: Boolean,
297
+ default: false
298
+ },
299
+ autoplayInterval: { default: 5e3 },
300
+ loop: {
301
+ type: Boolean,
302
+ default: true
303
+ },
304
+ indicators: { default: void 0 },
305
+ tone: { default: void 0 },
306
+ activationMode: { default: void 0 },
307
+ arrows: {
308
+ type: Boolean,
309
+ default: true
310
+ },
311
+ swipe: {
312
+ type: Boolean,
313
+ default: true
314
+ },
315
+ landmark: {
316
+ type: Boolean,
317
+ default: false
318
+ },
319
+ ariaLabel: { default: void 0 },
320
+ ariaLabelledby: { default: void 0 },
321
+ prevLabel: { default: void 0 },
322
+ nextLabel: { default: void 0 },
323
+ playLabel: { default: void 0 },
324
+ pauseLabel: { default: void 0 },
325
+ indicatorsLabel: { default: void 0 }
326
+ },
327
+ emits: ["update:modelValue"],
328
+ setup(__props, { expose: __expose, emit: __emit }) {
329
+ const props = __props;
330
+ const emit = __emit;
331
+ const { t } = useGranularityTranslations();
332
+ const { announce } = useAnnouncer();
333
+ const resolvedIndicators = useGrComponentProp("GrCarousel", "indicators", () => props.indicators, "dots");
334
+ const resolvedActivation = useGrComponentProp("GrCarousel", "activationMode", () => props.activationMode, "automatic");
335
+ const resolvedTone = useGrComponentProp("GrCarousel", "tone", () => props.tone, "primary");
336
+ const rootEl = ref(null);
337
+ const viewportEl = ref(null);
338
+ const indicatorsEl = ref(null);
339
+ const tabRefs = ref([]);
340
+ const entries = ref([]);
341
+ const total = computed(() => entries.value.length);
342
+ let reorderScheduled = false;
343
+ /**
344
+ * Порядок регистрации совпадает с документом только при первом монтировании:
345
+ * кадр, появившийся посреди ленты позже, встал бы в конец, и переключатели
346
+ * разъехались бы с лентой. Пересортировка откладывается на такт — к этому
347
+ * моменту узлы уже в DOM.
348
+ */
349
+ function scheduleReorder() {
350
+ if (reorderScheduled || typeof document === "undefined") return;
351
+ reorderScheduled = true;
352
+ nextTick(() => {
353
+ reorderScheduled = false;
354
+ entries.value = [...entries.value].sort((left, right) => {
355
+ const a = left.el();
356
+ const b = right.el();
357
+ if (!a || !b) return 0;
358
+ return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
359
+ });
360
+ });
361
+ }
362
+ function register(entry) {
363
+ entries.value.push(entry);
364
+ scheduleReorder();
365
+ return () => {
366
+ const index = entries.value.findIndex((item) => item.id === entry.id);
367
+ if (index >= 0) entries.value.splice(index, 1);
368
+ scheduleReorder();
369
+ };
370
+ }
371
+ const internalIndex = ref(0);
372
+ const currentIndex = computed(() => clampIndex(props.modelValue ?? internalIndex.value, total.value));
373
+ function setIndex(next) {
374
+ const value = clampIndex(next, total.value);
375
+ if (value === currentIndex.value) return;
376
+ internalIndex.value = value;
377
+ emit("update:modelValue", value);
378
+ }
379
+ const showIndicators = computed(() => resolvedIndicators.value !== "none" && total.value > 1);
380
+ const showArrows = computed(() => props.arrows && total.value > 1);
381
+ const isThumbnails = computed(() => resolvedIndicators.value === "thumbnails");
382
+ const atStart = computed(() => !props.loop && currentIndex.value <= 0);
383
+ const atEnd = computed(() => !props.loop && currentIndex.value >= total.value - 1);
384
+ const reducedMotion = ref(false);
385
+ const hovered = ref(false);
386
+ const documentHidden = ref(false);
387
+ /** `null` — тумблер не трогали, и решает проп. */
388
+ const userIntent = ref(null);
389
+ const playing = computed(() => total.value > 1 && (userIntent.value ?? (props.autoplay && !reducedMotion.value)));
390
+ /**
391
+ * Живой регион читает кадр, только когда лента стоит: у движущейся карусели
392
+ * объявление каждого кадра превратило бы страницу в неработающую.
393
+ */
394
+ const liveMode = computed(() => playing.value ? "off" : "polite");
395
+ const swipeGesture = useCarouselSwipe({
396
+ disabled: () => !props.swipe || total.value <= 1,
397
+ viewport: () => viewportEl.value,
398
+ atEdge: (direction) => direction === 1 ? atEnd.value : atStart.value,
399
+ onStart: stopAutoplay,
400
+ onSwipe: (direction) => {
401
+ commitUserNavigation(stepIndex(currentIndex.value, direction, total.value, props.loop));
402
+ }
403
+ });
404
+ const autoplayTimer = useCarouselAutoplay({
405
+ interval: () => props.autoplayInterval,
406
+ enabled: () => playing.value,
407
+ paused: () => hovered.value || documentHidden.value || swipeGesture.isDragging.value,
408
+ advance: () => {
409
+ const next = stepIndex(currentIndex.value, 1, total.value, props.loop);
410
+ if (next === currentIndex.value) {
411
+ userIntent.value = false;
412
+ return;
413
+ }
414
+ setIndex(next);
415
+ }
416
+ });
417
+ function stopAutoplay() {
418
+ if (!playing.value) return;
419
+ userIntent.value = false;
420
+ announce(t("gr.carousel.autoplayStopped", "Automatic slide show stopped"));
421
+ }
422
+ /**
423
+ * `aria-live` обязан стать `polite` **раньше**, чем поменяется содержимое:
424
+ * иначе мутация случится, пока регион ещё `off`, и не прозвучит вовсе.
425
+ */
426
+ async function commitUserNavigation(next) {
427
+ if (playing.value) {
428
+ stopAutoplay();
429
+ await nextTick();
430
+ }
431
+ setIndex(next);
432
+ }
433
+ function toggleAutoplay() {
434
+ if (playing.value) {
435
+ stopAutoplay();
436
+ return;
437
+ }
438
+ userIntent.value = true;
439
+ autoplayTimer.restart();
440
+ }
441
+ function goTo(index) {
442
+ commitUserNavigation(clampIndex(index, total.value));
443
+ }
444
+ function step(delta) {
445
+ commitUserNavigation(stepIndex(currentIndex.value, delta, total.value, props.loop));
446
+ }
447
+ const roving = useRovingFocus({
448
+ items: () => entries.value.map((_, index) => index),
449
+ elementFor: (index) => tabRefs.value[index],
450
+ orientation: () => "horizontal",
451
+ wrap: () => true,
452
+ initialKey: () => total.value > 0 ? currentIndex.value : void 0,
453
+ beforeFocus: (index) => scrollTabIntoView(index)
454
+ });
455
+ watch(total, (count) => {
456
+ if (count === 0) {
457
+ roving.reset();
458
+ return;
459
+ }
460
+ const requested = props.modelValue ?? internalIndex.value;
461
+ const clamped = clampIndex(requested, count);
462
+ if (clamped !== requested) {
463
+ internalIndex.value = clamped;
464
+ emit("update:modelValue", clamped);
465
+ }
466
+ });
467
+ /**
468
+ * Прокрутка **полосы**, а не страницы.
469
+ *
470
+ * `scrollIntoView` двигает всех предков, включая документ: карусель, уехавшая
471
+ * под сгиб, на каждом шаге автопрокрутки утаскивала бы страницу обратно к себе.
472
+ * Поэтому позиция считается сама и присваивается `scrollLeft` полосы.
473
+ */
474
+ function scrollTabIntoView(index) {
475
+ const strip = indicatorsEl.value;
476
+ const tab = tabRefs.value[index];
477
+ if (!strip || !tab) return;
478
+ const next = stripScrollLeft(strip.scrollLeft, strip.clientWidth, tab.offsetLeft, tab.offsetLeft + tab.offsetWidth);
479
+ if (next !== strip.scrollLeft) strip.scrollLeft = next;
480
+ }
481
+ function setTabRef(el, index) {
482
+ tabRefs.value[index] = el;
483
+ }
484
+ function onIndicatorKeydown(event) {
485
+ if (total.value === 0) return;
486
+ const current = roving.rovingKey.value ?? 0;
487
+ if ((event.key === "Enter" || event.key === " ") && resolvedActivation.value === "manual") {
488
+ event.preventDefault();
489
+ commitUserNavigation(current);
490
+ return;
491
+ }
492
+ if (!roving.handleNavigationKeys(event)) return;
493
+ if (resolvedActivation.value !== "manual") commitUserNavigation(roving.rovingKey.value ?? current);
494
+ }
495
+ function onIndicatorClick(index) {
496
+ roving.setActive(index);
497
+ commitUserNavigation(index);
498
+ }
499
+ const { onFocusIn, onFocusOut } = useFocusWithin(rootEl, { enter: stopAutoplay });
500
+ const stripOverflow = ref("none");
501
+ let resizeObserver = null;
502
+ let measureScheduled = false;
503
+ function measureOverflow() {
504
+ const el = indicatorsEl.value;
505
+ if (!el || !isThumbnails.value) {
506
+ stripOverflow.value = "none";
507
+ return;
508
+ }
509
+ stripOverflow.value = resolveScrollOverflow(el.scrollLeft, el.scrollWidth, el.clientWidth);
510
+ }
511
+ function scheduleMeasure() {
512
+ if (measureScheduled) return;
513
+ measureScheduled = true;
514
+ nextTick(() => {
515
+ measureScheduled = false;
516
+ measureOverflow();
517
+ });
518
+ }
519
+ function onVisibilityChange() {
520
+ documentHidden.value = document.hidden;
521
+ }
522
+ onMounted(() => {
523
+ reducedMotion.value = typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches === true;
524
+ document.addEventListener("visibilitychange", onVisibilityChange);
525
+ scheduleMeasure();
526
+ if (typeof ResizeObserver === "undefined") return;
527
+ resizeObserver = new ResizeObserver(scheduleMeasure);
528
+ if (indicatorsEl.value) resizeObserver.observe(indicatorsEl.value);
529
+ });
530
+ onBeforeUnmount(() => {
531
+ document.removeEventListener("visibilitychange", onVisibilityChange);
532
+ resizeObserver?.disconnect();
533
+ resizeObserver = null;
534
+ });
535
+ watch([total, isThumbnails], scheduleMeasure);
536
+ watch(currentIndex, async (index) => {
537
+ await nextTick();
538
+ scrollTabIntoView(index);
539
+ });
540
+ function entryAt(index) {
541
+ return entries.value[index];
542
+ }
543
+ function positionLabelAt(index) {
544
+ return t("gr.carousel.slidePosition", "{index} of {total}", {
545
+ index: index + 1,
546
+ total: total.value
547
+ });
548
+ }
549
+ function indicatorName(index) {
550
+ return entryAt(index)?.label() ?? positionLabelAt(index);
551
+ }
552
+ function tabDomId(index) {
553
+ return `${entryAt(index)?.id ?? index}-tab`;
554
+ }
555
+ const trackStyle = computed(() => {
556
+ const style = {
557
+ "--gr-carousel-index": String(currentIndex.value),
558
+ "--gr-carousel-drag": `${swipeGesture.offset.value}px`
559
+ };
560
+ if (swipeGesture.isDragging.value) style.transition = "none";
561
+ return style;
562
+ });
563
+ provide(GR_CAROUSEL_CONTEXT, {
564
+ register,
565
+ indexOf: (id) => entries.value.findIndex((entry) => entry.id === id),
566
+ isCurrent: (id) => entries.value[currentIndex.value]?.id === id,
567
+ total,
568
+ slideRole: computed(() => showIndicators.value ? "tabpanel" : "group"),
569
+ slideRoledescription: computed(() => t("gr.carousel.slideRoledescription", "slide")),
570
+ tabIdFor: (id) => {
571
+ if (!showIndicators.value) return void 0;
572
+ const index = entries.value.findIndex((entry) => entry.id === id);
573
+ return index >= 0 ? tabDomId(index) : void 0;
574
+ },
575
+ positionLabel: (id) => {
576
+ const index = entries.value.findIndex((entry) => entry.id === id);
577
+ return positionLabelAt(index >= 0 ? index : 0);
578
+ }
579
+ });
580
+ if (process.env.NODE_ENV !== "production") watchEffect(() => {
581
+ if (!props.ariaLabel && !props.ariaLabelledby) console.warn("[granularity] GrCarousel: у карусели нет доступного имени — передайте `ariaLabel` или `ariaLabelledby`. `aria-roledescription` именем не является.");
582
+ if (!props.arrows && resolvedIndicators.value === "none" && total.value > 1) console.warn("[granularity] GrCarousel: `arrows: false` вместе с `indicators: \"none\"` не оставляет ни одного способа сменить кадр с клавиатуры.");
583
+ if (isThumbnails.value && total.value > 0 && entries.value.every((entry) => !entry.hasThumbnail() && !entry.thumbnailSrc())) console.warn("[granularity] GrCarousel: `indicators=\"thumbnails\"`, но ни один слайд не дал миниатюру — задайте проп `thumbnail` или слот `#thumbnail` у `GrCarouselSlide`.");
584
+ });
585
+ __expose({
586
+ /** Текущий кадр — единственный способ прочитать позицию без `v-model`. */
587
+ index: computed(() => currentIndex.value),
588
+ /** Число кадров: состав живёт в слоте, снаружи его посчитать нечем. */
589
+ count: total,
590
+ /** Идёт ли показ. Пауза под курсором его не выключает. */
591
+ playing: computed(() => playing.value),
592
+ next: () => step(1),
593
+ prev: () => step(-1),
594
+ goTo,
595
+ play: () => {
596
+ if (!playing.value) toggleAutoplay();
597
+ },
598
+ pause: stopAutoplay
599
+ });
600
+ return (_ctx, _cache) => {
601
+ return openBlock(), createElementBlock("div", {
602
+ ref_key: "rootEl",
603
+ ref: rootEl,
604
+ "data-gr-carousel": "",
605
+ class: normalizeClass(unref(carouselRootBase)),
606
+ role: __props.landmark ? "region" : "group",
607
+ "aria-roledescription": unref(t)("gr.carousel.roledescription", "carousel"),
608
+ "aria-label": __props.ariaLabelledby ? void 0 : __props.ariaLabel,
609
+ "aria-labelledby": __props.ariaLabelledby,
610
+ onMouseenter: _cache[3] || (_cache[3] = ($event) => hovered.value = true),
611
+ onMouseleave: _cache[4] || (_cache[4] = ($event) => hovered.value = false),
612
+ onFocusin: _cache[5] || (_cache[5] = (...args) => unref(onFocusIn) && unref(onFocusIn)(...args)),
613
+ onFocusout: _cache[6] || (_cache[6] = (...args) => unref(onFocusOut) && unref(onFocusOut)(...args))
614
+ }, [createElementVNode("div", {
615
+ ref_key: "viewportEl",
616
+ ref: viewportEl,
617
+ "data-gr-carousel-viewport": "",
618
+ class: normalizeClass([unref(carouselViewportBase), props.swipe ? unref(carouselViewportSwipeClass) : ""]),
619
+ "aria-live": liveMode.value,
620
+ "aria-atomic": "true",
621
+ onPointerdown: _cache[2] || (_cache[2] = (...args) => unref(swipeGesture).start && unref(swipeGesture).start(...args))
622
+ }, [
623
+ createElementVNode("div", {
624
+ "data-gr-carousel-track": "",
625
+ class: normalizeClass(unref(carouselTrackBase)),
626
+ style: normalizeStyle(trackStyle.value)
627
+ }, [renderSlot(_ctx.$slots, "default")], 6),
628
+ props.autoplay && total.value > 1 ? (openBlock(), createElementBlock("button", {
629
+ key: 0,
630
+ type: "button",
631
+ "data-gr-carousel-toggle": "",
632
+ class: normalizeClass(unref(carouselToggleClass)),
633
+ "aria-label": playing.value ? __props.pauseLabel ?? unref(t)("gr.carousel.pause", "Stop automatic slide show") : __props.playLabel ?? unref(t)("gr.carousel.play", "Start automatic slide show"),
634
+ onClick: toggleAutoplay
635
+ }, [(openBlock(), createBlock(resolveDynamicComponent(playing.value ? unref(pause_default) : unref(play_default)), {
636
+ class: normalizeClass(unref(carouselIconClass)),
637
+ "aria-hidden": "true"
638
+ }, null, 8, ["class"]))], 10, _hoisted_3)) : createCommentVNode("", true),
639
+ showArrows.value ? (openBlock(), createElementBlock("button", {
640
+ key: 1,
641
+ type: "button",
642
+ "data-gr-carousel-prev": "",
643
+ class: normalizeClass(unref(grCarouselControlClass)("prev", atStart.value)),
644
+ "aria-disabled": atStart.value ? "true" : void 0,
645
+ "aria-label": __props.prevLabel ?? unref(t)("gr.carousel.previous", "Previous slide"),
646
+ onClick: _cache[0] || (_cache[0] = ($event) => atStart.value ? void 0 : step(-1))
647
+ }, [renderSlot(_ctx.$slots, "prev", { disabled: atStart.value }, () => [createVNode(unref(chevron_left_default), {
648
+ class: normalizeClass(unref(carouselIconClass)),
649
+ "aria-hidden": "true"
650
+ }, null, 8, ["class"])])], 10, _hoisted_4)) : createCommentVNode("", true),
651
+ showArrows.value ? (openBlock(), createElementBlock("button", {
652
+ key: 2,
653
+ type: "button",
654
+ "data-gr-carousel-next": "",
655
+ class: normalizeClass(unref(grCarouselControlClass)("next", atEnd.value)),
656
+ "aria-disabled": atEnd.value ? "true" : void 0,
657
+ "aria-label": __props.nextLabel ?? unref(t)("gr.carousel.next", "Next slide"),
658
+ onClick: _cache[1] || (_cache[1] = ($event) => atEnd.value ? void 0 : step(1))
659
+ }, [renderSlot(_ctx.$slots, "next", { disabled: atEnd.value }, () => [createVNode(unref(chevron_right_default), {
660
+ class: normalizeClass(unref(carouselIconClass)),
661
+ "aria-hidden": "true"
662
+ }, null, 8, ["class"])])], 10, _hoisted_5)) : createCommentVNode("", true)
663
+ ], 42, _hoisted_2), showIndicators.value ? (openBlock(), createElementBlock("div", {
664
+ key: 0,
665
+ ref_key: "indicatorsEl",
666
+ ref: indicatorsEl,
667
+ role: "tablist",
668
+ "data-gr-carousel-indicators": "",
669
+ "data-variant": unref(resolvedIndicators),
670
+ "data-overflow": stripOverflow.value,
671
+ class: normalizeClass(unref(grCarouselIndicatorsClass)(unref(resolvedIndicators))),
672
+ "aria-label": __props.indicatorsLabel ?? unref(t)("gr.carousel.indicators", "Slides"),
673
+ onKeydown: onIndicatorKeydown,
674
+ onScrollPassive: scheduleMeasure
675
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(entries.value, (entry, index) => {
676
+ return openBlock(), createElementBlock("button", {
677
+ id: tabDomId(index),
678
+ key: entry.id,
679
+ ref_for: true,
680
+ ref: (el) => setTabRef(el, index),
681
+ type: "button",
682
+ role: "tab",
683
+ "data-gr-carousel-indicator": "",
684
+ "aria-selected": index === currentIndex.value ? "true" : "false",
685
+ "aria-controls": entry.id,
686
+ "aria-label": indicatorName(index),
687
+ tabindex: unref(roving).tabindexFor(index),
688
+ class: normalizeClass(unref(grCarouselIndicatorClass)(unref(resolvedIndicators), index === currentIndex.value, unref(resolvedTone))),
689
+ onClick: ($event) => onIndicatorClick(index)
690
+ }, [isThumbnails.value && entry.hasThumbnail() ? (openBlock(), createBlock(resolveDynamicComponent(entry.thumbnail), { key: 0 })) : isThumbnails.value && entry.thumbnailSrc() ? (openBlock(), createElementBlock("img", {
691
+ key: 1,
692
+ src: entry.thumbnailSrc(),
693
+ alt: "",
694
+ loading: "lazy",
695
+ decoding: "async",
696
+ class: normalizeClass(unref(carouselThumbImageClass))
697
+ }, null, 10, _hoisted_8)) : isThumbnails.value ? (openBlock(), createElementBlock("span", {
698
+ key: 2,
699
+ class: normalizeClass(unref(carouselThumbFallbackClass))
700
+ }, toDisplayString(index + 1), 3)) : createCommentVNode("", true)], 10, _hoisted_7);
701
+ }), 128))], 42, _hoisted_6)) : createCommentVNode("", true)], 42, _hoisted_1$1);
702
+ };
703
+ }
704
+ });
705
+ //#endregion
706
+ //#region src/components/GrCarousel/GrCarouselSlide.vue?vue&type=script&setup=true&lang.ts
707
+ var _hoisted_1 = [
708
+ "id",
709
+ "role",
710
+ "aria-roledescription",
711
+ "aria-labelledby",
712
+ "aria-label",
713
+ "inert"
714
+ ];
715
+ //#endregion
716
+ //#region src/components/GrCarousel/GrCarouselSlide.vue
717
+ var GrCarouselSlide_default = /* @__PURE__ */ defineComponent({
718
+ __name: "GrCarouselSlide",
719
+ props: {
720
+ label: { default: void 0 },
721
+ thumbnail: { default: void 0 }
722
+ },
723
+ setup(__props) {
724
+ const props = __props;
725
+ const carousel = inject(GR_CAROUSEL_CONTEXT);
726
+ if (!carousel) throw new Error("GrCarouselSlide must be used inside GrCarousel");
727
+ const slots = useSlots();
728
+ const slideId = useId();
729
+ const rootEl = ref(null);
730
+ function renderThumbnail() {
731
+ return slots.thumbnail?.();
732
+ }
733
+ onBeforeUnmount(carousel.register({
734
+ id: slideId,
735
+ label: () => props.label,
736
+ thumbnailSrc: () => props.thumbnail,
737
+ hasThumbnail: () => Boolean(slots.thumbnail),
738
+ thumbnail: renderThumbnail,
739
+ el: () => rootEl.value
740
+ }));
741
+ const isCurrent = computed(() => carousel.isCurrent(slideId));
742
+ const labelledBy = computed(() => carousel.tabIdFor(slideId));
743
+ const accessibleName = computed(() => props.label ?? carousel.positionLabel(slideId));
744
+ return (_ctx, _cache) => {
745
+ return openBlock(), createElementBlock("div", {
746
+ id: unref(slideId),
747
+ ref_key: "rootEl",
748
+ ref: rootEl,
749
+ "data-gr-carousel-slide": "",
750
+ class: normalizeClass(unref(carouselSlideBase)),
751
+ role: unref(carousel).slideRole.value,
752
+ "aria-roledescription": unref(carousel).slideRoledescription.value,
753
+ "aria-labelledby": labelledBy.value,
754
+ "aria-label": labelledBy.value ? void 0 : accessibleName.value,
755
+ inert: isCurrent.value ? void 0 : true
756
+ }, [renderSlot(_ctx.$slots, "default")], 10, _hoisted_1);
757
+ };
758
+ }
759
+ });
760
+ //#endregion
761
+ export { GrCarousel_default as n, GrCarouselSlide_default as t };