vectis-ui 0.14.0 → 0.16.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 (442) hide show
  1. package/dist/components/VAccordion/VAccordion.css +1 -1
  2. package/dist/components/VAccordion/VAccordion.d.ts +0 -6
  3. package/dist/components/VAccordion/VAccordion.js.map +1 -1
  4. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +3 -8
  5. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  7. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  8. package/dist/components/VAccordion/context.js.map +1 -1
  9. package/dist/components/VAlert/VAlert.js.map +1 -1
  10. package/dist/components/VAlert/VAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/VAvatar/VAvatar.d.ts +0 -3
  12. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  13. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +21 -27
  14. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/VAvatar/VAvatarGroup.d.ts +0 -6
  16. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  17. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +5 -19
  18. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/VAvatar/context.d.ts +0 -1
  20. package/dist/components/VAvatar/context.js.map +1 -1
  21. package/dist/components/VBadge/VBadge.js.map +1 -1
  22. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  23. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  25. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/VButton/VButton.d.ts +0 -6
  27. package/dist/components/VButton/VButton.js.map +1 -1
  28. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +11 -17
  29. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/VButton/VButtonGroup.d.ts +0 -6
  31. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  32. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +0 -7
  33. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/VButton/context.d.ts +0 -2
  35. package/dist/components/VButton/context.js.map +1 -1
  36. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  37. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  39. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  41. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +5 -17
  42. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  44. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +19 -31
  45. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  47. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/VCalendar/color.js.map +1 -1
  49. package/dist/components/VCalendar/edgeStep.js +1 -5
  50. package/dist/components/VCalendar/edgeStep.js.map +1 -1
  51. package/dist/components/VCalendar/gesture.js +4 -12
  52. package/dist/components/VCalendar/gesture.js.map +1 -1
  53. package/dist/components/VCalendar/keyboard.js.map +1 -1
  54. package/dist/components/VCalendar/layout.js +8 -12
  55. package/dist/components/VCalendar/layout.js.map +1 -1
  56. package/dist/components/VCalendar/timeGrid.js +5 -5
  57. package/dist/components/VCalendar/timeGrid.js.map +1 -1
  58. package/dist/components/VCard/VCard.js.map +1 -1
  59. package/dist/components/VCard/VCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  60. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  61. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  63. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  64. package/dist/components/VCarousel/context.js.map +1 -1
  65. package/dist/components/VCheckbox/VCheckMark.js.map +1 -1
  66. package/dist/components/VCheckbox/VCheckMark.vue_vue_type_script_setup_true_lang.js.map +1 -1
  67. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  68. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/VChip/VChip.d.ts +0 -3
  70. package/dist/components/VChip/VChip.js.map +1 -1
  71. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +0 -6
  72. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/VColorInput/VColorInput.d.ts +0 -3
  74. package/dist/components/VColorInput/VColorInput.js.map +1 -1
  75. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js +3 -9
  76. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  77. package/dist/components/VColorPicker/VColorPicker.js.map +1 -1
  78. package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js +1 -5
  79. package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/VColorPicker/color.js.map +1 -1
  81. package/dist/components/VCombobox/VCombobox.d.ts +0 -3
  82. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  83. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +100 -119
  84. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/VCommandPalette/VCommandPalette.js.map +1 -1
  86. package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js +0 -1
  87. package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/VCommandPalette/VCommandPaletteItem.js.map +1 -1
  89. package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js +1 -5
  90. package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/VContextMenu/VContextMenu.d.ts +0 -3
  92. package/dist/components/VContextMenu/VContextMenu.js.map +1 -1
  93. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js +3 -11
  94. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/VDataTable/VDataTable.css +1 -1
  96. package/dist/components/VDataTable/VDataTable.d.ts +0 -2
  97. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  98. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +69 -88
  99. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/components/VDateInput/VDateInput.d.ts +0 -3
  101. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  102. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +5 -10
  103. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/components/VDateInput/mask.js.map +1 -1
  105. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  106. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +2 -1
  107. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/components/VDatePicker/keyboard.js.map +1 -1
  109. package/dist/components/VDatePicker/names.js.map +1 -1
  110. package/dist/components/VDialog/VDialog.js.map +1 -1
  111. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/VDialog/VDialogAlert.js.map +1 -1
  113. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  114. package/dist/components/VDrawer/VDrawer.js.map +1 -1
  115. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  116. package/dist/components/VEmptyState/VEmptyState.js.map +1 -1
  117. package/dist/components/VEmptyState/VEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/VField/VField.js.map +1 -1
  119. package/dist/components/VField/VField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/VField/VFieldAnnouncer.js.map +1 -1
  121. package/dist/components/VField/VFieldAnnouncer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/VField/VFieldMessage.js.map +1 -1
  123. package/dist/components/VField/VFieldMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  124. package/dist/components/VFieldset/VFieldset.js.map +1 -1
  125. package/dist/components/VFieldset/VFieldset.vue_vue_type_script_setup_true_lang.js.map +1 -1
  126. package/dist/components/VFileInput/VFileInput.d.ts +0 -5
  127. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  128. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +54 -65
  129. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/VFileInput/truncate.js.map +1 -1
  131. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  132. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  133. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  134. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  135. package/dist/components/VHotkeys/VHotkeys.d.ts +0 -3
  136. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  137. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +0 -6
  138. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  139. package/dist/components/VHotkeys/platform.js +1 -1
  140. package/dist/components/VHotkeys/platform.js.map +1 -1
  141. package/dist/components/VHoverCard/VHoverCard.js.map +1 -1
  142. package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js +2 -12
  143. package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  144. package/dist/components/VIcon/VIcon.js.map +1 -1
  145. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/VIcon/iconProps.js.map +1 -1
  147. package/dist/components/VIcon/icons/add.js.map +1 -1
  148. package/dist/components/VIcon/icons/arrow_downward.js.map +1 -1
  149. package/dist/components/VIcon/icons/arrow_downward_alt.js.map +1 -1
  150. package/dist/components/VIcon/icons/arrow_drop_down.js.map +1 -1
  151. package/dist/components/VIcon/icons/arrow_drop_up.js.map +1 -1
  152. package/dist/components/VIcon/icons/arrow_left_alt.js.map +1 -1
  153. package/dist/components/VIcon/icons/arrow_right_alt.js.map +1 -1
  154. package/dist/components/VIcon/icons/arrow_upward.js.map +1 -1
  155. package/dist/components/VIcon/icons/arrow_upward_alt.js.map +1 -1
  156. package/dist/components/VIcon/icons/attach_file.js.map +1 -1
  157. package/dist/components/VIcon/icons/audio_file.js.map +1 -1
  158. package/dist/components/VIcon/icons/calendar_today.js.map +1 -1
  159. package/dist/components/VIcon/icons/check.js.map +1 -1
  160. package/dist/components/VIcon/icons/check_circle.js.map +1 -1
  161. package/dist/components/VIcon/icons/chevron_left.js.map +1 -1
  162. package/dist/components/VIcon/icons/chevron_right.js.map +1 -1
  163. package/dist/components/VIcon/icons/close.js.map +1 -1
  164. package/dist/components/VIcon/icons/cloud_upload.js.map +1 -1
  165. package/dist/components/VIcon/icons/code.js.map +1 -1
  166. package/dist/components/VIcon/icons/colorize.js.map +1 -1
  167. package/dist/components/VIcon/icons/description.js.map +1 -1
  168. package/dist/components/VIcon/icons/error.js.map +1 -1
  169. package/dist/components/VIcon/icons/expand_less.js.map +1 -1
  170. package/dist/components/VIcon/icons/expand_more.js.map +1 -1
  171. package/dist/components/VIcon/icons/first_page.js.map +1 -1
  172. package/dist/components/VIcon/icons/folder_zip.js.map +1 -1
  173. package/dist/components/VIcon/icons/image.js.map +1 -1
  174. package/dist/components/VIcon/icons/inbox.js.map +1 -1
  175. package/dist/components/VIcon/icons/index.js.map +1 -1
  176. package/dist/components/VIcon/icons/info.js.map +1 -1
  177. package/dist/components/VIcon/icons/last_page.js.map +1 -1
  178. package/dist/components/VIcon/icons/more_horiz.js.map +1 -1
  179. package/dist/components/VIcon/icons/names.js.map +1 -1
  180. package/dist/components/VIcon/icons/notifications.js.map +1 -1
  181. package/dist/components/VIcon/icons/open_in_new.js.map +1 -1
  182. package/dist/components/VIcon/icons/picture_as_pdf.js.map +1 -1
  183. package/dist/components/VIcon/icons/priority_high.js.map +1 -1
  184. package/dist/components/VIcon/icons/remove.js.map +1 -1
  185. package/dist/components/VIcon/icons/schedule.js.map +1 -1
  186. package/dist/components/VIcon/icons/search.js.map +1 -1
  187. package/dist/components/VIcon/icons/search_off.js.map +1 -1
  188. package/dist/components/VIcon/icons/star.js.map +1 -1
  189. package/dist/components/VIcon/icons/swap_vert.js.map +1 -1
  190. package/dist/components/VIcon/icons/table_chart.js.map +1 -1
  191. package/dist/components/VIcon/icons/video_file.js.map +1 -1
  192. package/dist/components/VIcon/icons/viewBox.js.map +1 -1
  193. package/dist/components/VIcon/icons/warning.js.map +1 -1
  194. package/dist/components/VIcon/resolver.js.map +1 -1
  195. package/dist/components/VIconButton/VIconButton.d.ts +0 -3
  196. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  197. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +0 -6
  198. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  199. package/dist/components/VInput/VInput.css +1 -1
  200. package/dist/components/VInput/VInput.d.ts +0 -3
  201. package/dist/components/VInput/VInput.js.map +1 -1
  202. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +2 -8
  203. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  204. package/dist/components/VInput/VInputGroup.d.ts +0 -3
  205. package/dist/components/VInput/VInputGroup.js.map +1 -1
  206. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +0 -7
  207. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  208. package/dist/components/VInput/context.d.ts +0 -2
  209. package/dist/components/VInput/context.js.map +1 -1
  210. package/dist/components/VInputOTP/VInputOTP.d.ts +0 -3
  211. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  212. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +2 -14
  213. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/components/VLink/VLink.js.map +1 -1
  215. package/dist/components/VLink/VLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
  216. package/dist/components/VListbox/VListboxChevron.js.map +1 -1
  217. package/dist/components/VListbox/VListboxChevron.vue_vue_type_script_setup_true_lang.js.map +1 -1
  218. package/dist/components/VListbox/VListboxGroup.js.map +1 -1
  219. package/dist/components/VListbox/VListboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/components/VListbox/VListboxOption.js.map +1 -1
  221. package/dist/components/VListbox/VListboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  222. package/dist/components/VListbox/VListboxPanel.d.ts +0 -3
  223. package/dist/components/VListbox/VListboxPanel.js.map +1 -1
  224. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js +0 -6
  225. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  226. package/dist/components/VListbox/VListboxSeparator.js.map +1 -1
  227. package/dist/components/VListbox/VListboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  228. package/dist/components/VListbox/VListboxValues.js.map +1 -1
  229. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js +4 -14
  230. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js.map +1 -1
  231. package/dist/components/VMenu/VMenu.d.ts +0 -3
  232. package/dist/components/VMenu/VMenu.js.map +1 -1
  233. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +0 -6
  234. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  235. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  236. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  237. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  238. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +6 -12
  239. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  240. package/dist/components/VMenu/VMenuPanel.d.ts +0 -3
  241. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  242. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +9 -16
  243. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/VMenu/VMenuSeparator.js.map +1 -1
  245. package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  246. package/dist/components/VMenu/context.js.map +1 -1
  247. package/dist/components/VMeter/VMeter.js.map +1 -1
  248. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  249. package/dist/components/VNumberInput/VNumberInput.d.ts +0 -3
  250. package/dist/components/VNumberInput/VNumberInput.js.map +1 -1
  251. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js +85 -90
  252. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  253. package/dist/components/VNumberInput/number.js.map +1 -1
  254. package/dist/components/VPagination/VPagination.d.ts +0 -3
  255. package/dist/components/VPagination/VPagination.js.map +1 -1
  256. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +0 -6
  257. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  258. package/dist/components/VPopover/VPopover.js.map +1 -1
  259. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  260. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  261. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  262. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  263. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  264. package/dist/components/VRadio/VRadio.js.map +1 -1
  265. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  266. package/dist/components/VRating/VRating.js.map +1 -1
  267. package/dist/components/VRating/VRating.vue_vue_type_script_setup_true_lang.js.map +1 -1
  268. package/dist/components/VResizable/VResizable.js.map +1 -1
  269. package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js +8 -6
  270. package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  271. package/dist/components/VResizable/VResizablePanel.js.map +1 -1
  272. package/dist/components/VResizable/VResizablePanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  273. package/dist/components/VResizable/context.js.map +1 -1
  274. package/dist/components/VResizable/layout.js.map +1 -1
  275. package/dist/components/VSelect/VSelect.d.ts +0 -3
  276. package/dist/components/VSelect/VSelect.js.map +1 -1
  277. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js +80 -90
  278. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  279. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  280. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  281. package/dist/components/VSideNavigation/VSideNavigation.d.ts +0 -6
  282. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  283. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +2 -11
  284. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  285. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  286. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  287. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  288. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +1 -5
  289. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  290. package/dist/components/VSideNavigation/VSideNavigationSeparator.js.map +1 -1
  291. package/dist/components/VSideNavigation/context.js.map +1 -1
  292. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +0 -3
  293. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  294. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +0 -6
  295. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  296. package/dist/components/VSlider/VSlider.js.map +1 -1
  297. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +107 -112
  298. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  299. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  300. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  301. package/dist/components/VSnackbar/state.js.map +1 -1
  302. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  303. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  304. package/dist/components/VSplitButton/VSplitButton.d.ts +0 -3
  305. package/dist/components/VSplitButton/VSplitButton.js.map +1 -1
  306. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js +0 -6
  307. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  308. package/dist/components/VStepper/VStepper.js.map +1 -1
  309. package/dist/components/VStepper/VStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  310. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  311. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  312. package/dist/components/VTabs/VTab.js.map +1 -1
  313. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +0 -2
  314. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  315. package/dist/components/VTabs/VTabPanel.js.map +1 -1
  316. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  317. package/dist/components/VTabs/VTabs.css +1 -1
  318. package/dist/components/VTabs/VTabs.d.ts +0 -3
  319. package/dist/components/VTabs/VTabs.js.map +1 -1
  320. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +2 -15
  321. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  322. package/dist/components/VTabs/context.d.ts +0 -2
  323. package/dist/components/VTabs/context.js.map +1 -1
  324. package/dist/components/VTextarea/VTextarea.d.ts +0 -6
  325. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  326. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +0 -6
  327. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  328. package/dist/components/VTimeInput/VTimeInput.d.ts +0 -3
  329. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  330. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +197 -204
  331. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  332. package/dist/components/VTimeInput/search.js.map +1 -1
  333. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  334. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +9 -9
  335. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  336. package/dist/components/VTimePicker/limits.js.map +1 -1
  337. package/dist/components/VTimeline/VTimeline.js.map +1 -1
  338. package/dist/components/VTimeline/VTimeline.vue_vue_type_script_setup_true_lang.js.map +1 -1
  339. package/dist/components/VTimeline/VTimelineItem.js.map +1 -1
  340. package/dist/components/VTimeline/VTimelineItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  341. package/dist/components/VTimeline/context.js.map +1 -1
  342. package/dist/components/VTimeline/datetime.js.map +1 -1
  343. package/dist/components/VToast/VToast.js.map +1 -1
  344. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  345. package/dist/components/VToast/VToaster.js.map +1 -1
  346. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +1 -1
  347. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  348. package/dist/components/VToast/state.js.map +1 -1
  349. package/dist/components/VToggle/VToggle.d.ts +0 -3
  350. package/dist/components/VToggle/VToggle.js.map +1 -1
  351. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +1 -13
  352. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  353. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  354. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  355. package/dist/components/VToggle/context.js.map +1 -1
  356. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  357. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  358. package/dist/components/VTreeView/VTreeView.js.map +1 -1
  359. package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js +1 -5
  360. package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  361. package/dist/components/VTypography/VTypography.js.map +1 -1
  362. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  363. package/dist/components/VVirtualList/VVirtualList.js.map +1 -1
  364. package/dist/components/VVirtualList/VVirtualList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  365. package/dist/composables/useAriaLabel.js.map +1 -1
  366. package/dist/composables/useChoice.js.map +1 -1
  367. package/dist/composables/useClearable.js.map +1 -1
  368. package/dist/composables/useControlShape.d.ts +1 -5
  369. package/dist/composables/useControlShape.js +0 -1
  370. package/dist/composables/useControlShape.js.map +1 -1
  371. package/dist/composables/useDebouncedSearch.js.map +1 -1
  372. package/dist/composables/useDetailsOpen.js.map +1 -1
  373. package/dist/composables/useEscapeDismiss.js.map +1 -1
  374. package/dist/composables/useFieldIds.js.map +1 -1
  375. package/dist/composables/useFieldPanel.js +3 -7
  376. package/dist/composables/useFieldPanel.js.map +1 -1
  377. package/dist/composables/useFileDrop.js.map +1 -1
  378. package/dist/composables/useFileField.js +2 -2
  379. package/dist/composables/useFileField.js.map +1 -1
  380. package/dist/composables/useFocusoutDismiss.js.map +1 -1
  381. package/dist/composables/useHotkeyListener.js.map +1 -1
  382. package/dist/composables/useIconClickHandlers.js.map +1 -1
  383. package/dist/composables/useInertLink.js.map +1 -1
  384. package/dist/composables/useInfiniteScroll.js +2 -2
  385. package/dist/composables/useInfiniteScroll.js.map +1 -1
  386. package/dist/composables/useListbox.d.ts +0 -1
  387. package/dist/composables/useListbox.js +4 -10
  388. package/dist/composables/useListbox.js.map +1 -1
  389. package/dist/composables/useLiveAnnouncer.js.map +1 -1
  390. package/dist/composables/useMaskedField.js +28 -48
  391. package/dist/composables/useMaskedField.js.map +1 -1
  392. package/dist/composables/useModalDialog.js +1 -1
  393. package/dist/composables/useModalDialog.js.map +1 -1
  394. package/dist/composables/usePopover.js +1 -1
  395. package/dist/composables/usePopover.js.map +1 -1
  396. package/dist/composables/useProgressValue.js.map +1 -1
  397. package/dist/composables/useRootAttrs.js.map +1 -1
  398. package/dist/composables/useSlotNodes.js.map +1 -1
  399. package/dist/composables/useTextLimit.js.map +1 -1
  400. package/dist/composables/useTimer.js.map +1 -1
  401. package/dist/composables/useTypeahead.js.map +1 -1
  402. package/dist/composables/useVirtualList.js.map +1 -1
  403. package/dist/i18n/en.js.map +1 -1
  404. package/dist/i18n/fr.js.map +1 -1
  405. package/dist/i18n/state.js.map +1 -1
  406. package/dist/styles.css +1 -1
  407. package/dist/tokens/css.js.map +1 -1
  408. package/dist/tokens/index.d.ts +3 -0
  409. package/dist/tokens/index.js.map +1 -1
  410. package/dist/tokens/primitives.js.map +1 -1
  411. package/dist/tokens/semantic.d.ts +3 -0
  412. package/dist/tokens/semantic.js +6 -5
  413. package/dist/tokens/semantic.js.map +1 -1
  414. package/dist/tokens/themes/dark.js.map +1 -1
  415. package/dist/tokens/types.js.map +1 -1
  416. package/dist/tokens.json +12 -5
  417. package/dist/types.d.ts +0 -2
  418. package/dist/utils/array.js.map +1 -1
  419. package/dist/utils/arrowNav.js.map +1 -1
  420. package/dist/utils/attrs.js.map +1 -1
  421. package/dist/utils/chip.d.ts +4 -6
  422. package/dist/utils/chip.js +8 -5
  423. package/dist/utils/chip.js.map +1 -1
  424. package/dist/utils/clock.js +3 -1
  425. package/dist/utils/clock.js.map +1 -1
  426. package/dist/utils/css.js +1 -1
  427. package/dist/utils/css.js.map +1 -1
  428. package/dist/utils/date.js.map +1 -1
  429. package/dist/utils/direction.js.map +1 -1
  430. package/dist/utils/env.js.map +1 -1
  431. package/dist/utils/file.js +13 -31
  432. package/dist/utils/file.js.map +1 -1
  433. package/dist/utils/focus.js.map +1 -1
  434. package/dist/utils/hostWarns.js.map +1 -1
  435. package/dist/utils/ids.js.map +1 -1
  436. package/dist/utils/matcher.js.map +1 -1
  437. package/dist/utils/memo.js.map +1 -1
  438. package/dist/utils/number.js.map +1 -1
  439. package/dist/utils/text.js.map +1 -1
  440. package/dist/utils/time.js.map +1 -1
  441. package/dist/utils/vnode.js.map +1 -1
  442. package/package.json +19 -19
@@ -15,11 +15,6 @@ interface AvatarGroupProps {
15
15
  * of its own keeps it.
16
16
  */
17
17
  size?: AvatarSize;
18
- /**
19
- * Applies the reduced density to every avatar inside. Unlike `size` it is cumulative: an
20
- * avatar cannot opt back out of a compact group.
21
- */
22
- compact?: boolean;
23
18
  /**
24
19
  * The colour of the ring drawn around each disc. It defaults to the page background, which
25
20
  * makes the ring read as a gap between two avatars.
@@ -43,7 +38,6 @@ type __VLS_Slots = {
43
38
  declare const __VLS_base: import('vue').DefineComponent<AvatarGroupProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<AvatarGroupProps> & Readonly<{}>, {
44
39
  label: string;
45
40
  size: AvatarSize;
46
- compact: boolean;
47
41
  max: number;
48
42
  ringColor: string;
49
43
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"VAvatarGroup.js","names":[],"sources":["../../../src/components/VAvatar/VAvatarGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Count avatars through slot VNodes for SSR-consistent overflow; useSlotNodes keeps that count\n * reactive when the parent replaces its slot.\n */\n\nimport { computed, provide } from 'vue'\nimport type { StyleValue } from 'vue'\n\nimport VAvatar from './VAvatar.vue'\nimport type { AvatarSize } from './VAvatar.vue'\nimport { AVATAR_DEFAULT_SIZE, avatarGroupKey } from './context'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useSlotNodes } from '../../composables/useSlotNodes'\n\n/** What the `#overflow` slot receives. */\nexport interface AvatarGroupOverflowSlotProps {\n /** How many avatars are hidden beyond `max`. */\n count: number\n}\n\ninterface AvatarGroupProps {\n /**\n * How many avatars to show before the remaining ones are summed up as a single\n * \"+X\" disc. Left out, or set to 0, every avatar is shown.\n */\n max?: number\n /**\n * The size given to the avatars inside the group. An avatar that sets a `size`\n * of its own keeps it.\n */\n size?: AvatarSize\n /**\n * Applies the reduced density to every avatar inside. Unlike `size` it is cumulative: an\n * avatar cannot opt back out of a compact group.\n */\n compact?: boolean\n /**\n * The colour of the ring drawn around each disc. It defaults to the page background, which\n * makes the ring read as a gap between two avatars.\n */\n ringColor?: string\n /**\n * The accessible name of the group, e.g. \"Project members\". A row of faces does not say on\n * its own who these people are. A consumer `aria-label` or `aria-labelledby` wins over it.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<AvatarGroupProps>(), {\n max: undefined,\n size: undefined,\n compact: false,\n ringColor: undefined,\n label: undefined,\n})\n\nconst ariaLabel = useAriaLabel(() => props.label)\n\ndefineSlots<{\n /** The VAvatars to stack. */\n default?(): unknown\n /**\n * Replaces the \"+X\" disc that stands for the avatars beyond `max`. It receives\n * `count`, the number of avatars being hidden.\n */\n overflow?(props: AvatarGroupOverflowSlotProps): unknown\n}>()\n\nprovide(avatarGroupKey, {\n get size() {\n return props.size\n },\n get compact() {\n return props.compact\n },\n})\n\nconst items = useSlotNodes()\n// `max: 0` means \"no limit\", as documented, and so does a negative one: `slice(0, -1)` would\n// drop the last avatar and sum it into a \"+1\" disc.\nconst visibleItems = computed(() =>\n props.max !== undefined && props.max > 0 ? items.value.slice(0, props.max) : items.value,\n)\nconst overflowCount = computed(() => items.value.length - visibleItems.value.length)\n\n// A functional component is the only way to render VNodes that have already been\n// captured: <component :is> expects a component definition, not a vnode.\nconst VisibleAvatars = () => visibleItems.value\n\nconst rootStyle = computed<StyleValue>(() =>\n props.ringColor !== undefined ? { '--avatar-ring-color': props.ringColor } : undefined,\n)\n\n// The group carries v-control so that --control-height is defined at ITS level, which keeps the\n// overlap computable even when a child is wrapped; a VTooltip, for instance, inserts a <span>\n// between the group and the VAvatar. An avatar given a size of its own redefines\n// --control-height on itself, so its own overlap follows that size rather than the group's.\nconst resolvedGroupSize = computed<AvatarSize>(() => props.size ?? AVATAR_DEFAULT_SIZE)\n</script>\n\n<template>\n <div\n class=\"v-avatar-group v-control\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :style=\"rootStyle\"\n :data-size=\"resolvedGroupSize\"\n :data-compact=\"compact ? '' : undefined\"\n >\n <component :is=\"VisibleAvatars\" />\n <slot v-if=\"overflowCount > 0\" name=\"overflow\" :count=\"overflowCount\">\n <VAvatar>+{{ overflowCount }}</VAvatar>\n </slot>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-avatar-group {\n /* The separation ring, declared here so that every child .v-avatar inherits it. */\n --avatar-ring-color: var(--vectis-color-surface);\n display: inline-flex;\n align-items: center;\n }\n\n /*\n * Take overlap height from the group so wrappers and differently sized avatars share one row\n * contract.\n */\n .v-avatar-group > * + * {\n margin-inline-start: calc(var(--control-height) * -0.3);\n }\n\n /* On hover, or as soon as something inside it takes focus, a disc rises above its\n neighbours so it is seen whole rather than clipped by the next one. */\n .v-avatar-group > *:hover,\n .v-avatar-group > *:focus-within {\n z-index: 1;\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VAvatarGroup.js","names":["_sfc_main","VAvatarGroup_vue_vue_type_script_setup_true_lang_default","VAvatarGroup_default"],"sources":["../../../src/components/VAvatar/VAvatarGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Count avatars through slot VNodes for SSR-consistent overflow; useSlotNodes keeps that count\n * reactive when the parent replaces its slot.\n */\n\nimport { computed, provide } from 'vue'\nimport type { StyleValue } from 'vue'\n\nimport VAvatar from './VAvatar.vue'\nimport type { AvatarSize } from './VAvatar.vue'\nimport { AVATAR_DEFAULT_SIZE, avatarGroupKey } from './context'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useSlotNodes } from '../../composables/useSlotNodes'\n\n/** What the `#overflow` slot receives. */\nexport interface AvatarGroupOverflowSlotProps {\n /** How many avatars are hidden beyond `max`. */\n count: number\n}\n\ninterface AvatarGroupProps {\n /**\n * How many avatars to show before the remaining ones are summed up as a single\n * \"+X\" disc. Left out, or set to 0, every avatar is shown.\n */\n max?: number\n /**\n * The size given to the avatars inside the group. An avatar that sets a `size`\n * of its own keeps it.\n */\n size?: AvatarSize\n /**\n * The colour of the ring drawn around each disc. It defaults to the page background, which\n * makes the ring read as a gap between two avatars.\n */\n ringColor?: string\n /**\n * The accessible name of the group, e.g. \"Project members\". A row of faces does not say on\n * its own who these people are. A consumer `aria-label` or `aria-labelledby` wins over it.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<AvatarGroupProps>(), {\n max: undefined,\n size: undefined,\n ringColor: undefined,\n label: undefined,\n})\n\nconst ariaLabel = useAriaLabel(() => props.label)\n\ndefineSlots<{\n /** The VAvatars to stack. */\n default?(): unknown\n /**\n * Replaces the \"+X\" disc that stands for the avatars beyond `max`. It receives\n * `count`, the number of avatars being hidden.\n */\n overflow?(props: AvatarGroupOverflowSlotProps): unknown\n}>()\n\nprovide(avatarGroupKey, {\n get size() {\n return props.size\n },\n})\n\nconst items = useSlotNodes()\n// `max: 0` means \"no limit\", as documented, and so does a negative one: `slice(0, -1)` would\n// drop the last avatar and sum it into a \"+1\" disc.\nconst visibleItems = computed(() =>\n props.max !== undefined && props.max > 0 ? items.value.slice(0, props.max) : items.value,\n)\nconst overflowCount = computed(() => items.value.length - visibleItems.value.length)\n\n// A functional component is the only way to render VNodes that have already been\n// captured: <component :is> expects a component definition, not a vnode.\nconst VisibleAvatars = () => visibleItems.value\n\nconst rootStyle = computed<StyleValue>(() =>\n props.ringColor !== undefined ? { '--avatar-ring-color': props.ringColor } : undefined,\n)\n\n// The group carries v-control so that --control-height is defined at ITS level, which keeps the\n// overlap computable even when a child is wrapped; a VTooltip, for instance, inserts a <span>\n// between the group and the VAvatar. An avatar given a size of its own redefines\n// --control-height on itself, so its own overlap follows that size rather than the group's.\nconst resolvedGroupSize = computed<AvatarSize>(() => props.size ?? AVATAR_DEFAULT_SIZE)\n</script>\n\n<template>\n <div\n class=\"v-avatar-group v-control\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :style=\"rootStyle\"\n :data-size=\"resolvedGroupSize\"\n >\n <component :is=\"VisibleAvatars\" />\n <slot v-if=\"overflowCount > 0\" name=\"overflow\" :count=\"overflowCount\">\n <VAvatar>+{{ overflowCount }}</VAvatar>\n </slot>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-avatar-group {\n /* The separation ring, declared here so that every child .v-avatar inherits it. */\n --avatar-ring-color: var(--vectis-color-surface);\n display: inline-flex;\n align-items: center;\n }\n\n /*\n * Take overlap height from the group so wrappers and differently sized avatars share one row\n * contract.\n */\n .v-avatar-group > * + * {\n margin-inline-start: calc(var(--control-height) * -0.3);\n }\n\n /* On hover, or as soon as something inside it takes focus, a disc rises above its\n neighbours so it is seen whole rather than clipped by the next one. */\n .v-avatar-group > *:hover,\n .v-avatar-group > *:focus-within {\n z-index: 1;\n }\n}\n</style>\n"],"mappings":""}
@@ -4,40 +4,26 @@ import { avatarGroupKey as n } from "./context.js";
4
4
  import r from "./VAvatar.js";
5
5
  import { computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createTextVNode as c, createVNode as l, defineComponent as u, normalizeStyle as d, openBlock as f, provide as p, renderSlot as m, resolveDynamicComponent as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
6
6
  //#region src/components/VAvatar/VAvatarGroup.vue?vue&type=script&setup=true&lang.ts
7
- var y = [
8
- "aria-label",
9
- "data-size",
10
- "data-compact"
11
- ], b = /*@__PURE__*/ u({
7
+ var y = ["aria-label", "data-size"], b = /*@__PURE__*/ u({
12
8
  __name: "VAvatarGroup",
13
9
  props: {
14
10
  max: { default: void 0 },
15
11
  size: { default: void 0 },
16
- compact: {
17
- type: Boolean,
18
- default: !1
19
- },
20
12
  ringColor: { default: void 0 },
21
13
  label: { default: void 0 }
22
14
  },
23
15
  setup(u) {
24
16
  let b = u, x = t(() => b.label);
25
- p(n, {
26
- get size() {
27
- return b.size;
28
- },
29
- get compact() {
30
- return b.compact;
31
- }
32
- });
17
+ p(n, { get size() {
18
+ return b.size;
19
+ } });
33
20
  let S = e(), C = i(() => b.max !== void 0 && b.max > 0 ? S.value.slice(0, b.max) : S.value), w = i(() => S.value.length - C.value.length), T = () => C.value, E = i(() => b.ringColor === void 0 ? void 0 : { "--avatar-ring-color": b.ringColor }), D = i(() => b.size ?? "md");
34
21
  return (e, t) => (f(), s("div", {
35
22
  class: "v-avatar-group v-control",
36
23
  role: "group",
37
24
  "aria-label": _(x),
38
25
  style: d(E.value),
39
- "data-size": D.value,
40
- "data-compact": u.compact ? "" : void 0
26
+ "data-size": D.value
41
27
  }, [(f(), a(h(T))), w.value > 0 ? m(e.$slots, "overflow", { count: w.value }, () => [l(r, null, {
42
28
  default: v(() => [c("+" + g(w.value), 1)]),
43
29
  _: 1
@@ -1 +1 @@
1
- {"version":3,"file":"VAvatarGroup.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VAvatar/VAvatarGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Count avatars through slot VNodes for SSR-consistent overflow; useSlotNodes keeps that count\n * reactive when the parent replaces its slot.\n */\n\nimport { computed, provide } from 'vue'\nimport type { StyleValue } from 'vue'\n\nimport VAvatar from './VAvatar.vue'\nimport type { AvatarSize } from './VAvatar.vue'\nimport { AVATAR_DEFAULT_SIZE, avatarGroupKey } from './context'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useSlotNodes } from '../../composables/useSlotNodes'\n\n/** What the `#overflow` slot receives. */\nexport interface AvatarGroupOverflowSlotProps {\n /** How many avatars are hidden beyond `max`. */\n count: number\n}\n\ninterface AvatarGroupProps {\n /**\n * How many avatars to show before the remaining ones are summed up as a single\n * \"+X\" disc. Left out, or set to 0, every avatar is shown.\n */\n max?: number\n /**\n * The size given to the avatars inside the group. An avatar that sets a `size`\n * of its own keeps it.\n */\n size?: AvatarSize\n /**\n * Applies the reduced density to every avatar inside. Unlike `size` it is cumulative: an\n * avatar cannot opt back out of a compact group.\n */\n compact?: boolean\n /**\n * The colour of the ring drawn around each disc. It defaults to the page background, which\n * makes the ring read as a gap between two avatars.\n */\n ringColor?: string\n /**\n * The accessible name of the group, e.g. \"Project members\". A row of faces does not say on\n * its own who these people are. A consumer `aria-label` or `aria-labelledby` wins over it.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<AvatarGroupProps>(), {\n max: undefined,\n size: undefined,\n compact: false,\n ringColor: undefined,\n label: undefined,\n})\n\nconst ariaLabel = useAriaLabel(() => props.label)\n\ndefineSlots<{\n /** The VAvatars to stack. */\n default?(): unknown\n /**\n * Replaces the \"+X\" disc that stands for the avatars beyond `max`. It receives\n * `count`, the number of avatars being hidden.\n */\n overflow?(props: AvatarGroupOverflowSlotProps): unknown\n}>()\n\nprovide(avatarGroupKey, {\n get size() {\n return props.size\n },\n get compact() {\n return props.compact\n },\n})\n\nconst items = useSlotNodes()\n// `max: 0` means \"no limit\", as documented, and so does a negative one: `slice(0, -1)` would\n// drop the last avatar and sum it into a \"+1\" disc.\nconst visibleItems = computed(() =>\n props.max !== undefined && props.max > 0 ? items.value.slice(0, props.max) : items.value,\n)\nconst overflowCount = computed(() => items.value.length - visibleItems.value.length)\n\n// A functional component is the only way to render VNodes that have already been\n// captured: <component :is> expects a component definition, not a vnode.\nconst VisibleAvatars = () => visibleItems.value\n\nconst rootStyle = computed<StyleValue>(() =>\n props.ringColor !== undefined ? { '--avatar-ring-color': props.ringColor } : undefined,\n)\n\n// The group carries v-control so that --control-height is defined at ITS level, which keeps the\n// overlap computable even when a child is wrapped; a VTooltip, for instance, inserts a <span>\n// between the group and the VAvatar. An avatar given a size of its own redefines\n// --control-height on itself, so its own overlap follows that size rather than the group's.\nconst resolvedGroupSize = computed<AvatarSize>(() => props.size ?? AVATAR_DEFAULT_SIZE)\n</script>\n\n<template>\n <div\n class=\"v-avatar-group v-control\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :style=\"rootStyle\"\n :data-size=\"resolvedGroupSize\"\n :data-compact=\"compact ? '' : undefined\"\n >\n <component :is=\"VisibleAvatars\" />\n <slot v-if=\"overflowCount > 0\" name=\"overflow\" :count=\"overflowCount\">\n <VAvatar>+{{ overflowCount }}</VAvatar>\n </slot>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-avatar-group {\n /* The separation ring, declared here so that every child .v-avatar inherits it. */\n --avatar-ring-color: var(--vectis-color-surface);\n display: inline-flex;\n align-items: center;\n }\n\n /*\n * Take overlap height from the group so wrappers and differently sized avatars share one row\n * contract.\n */\n .v-avatar-group > * + * {\n margin-inline-start: calc(var(--control-height) * -0.3);\n }\n\n /* On hover, or as soon as something inside it takes focus, a disc rises above its\n neighbours so it is seen whole rather than clipped by the next one. */\n .v-avatar-group > *:hover,\n .v-avatar-group > *:focus-within {\n z-index: 1;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EAmDA,IAAM,IAAQ,GAQR,IAAY,QAAmB,EAAM,KAAK;EAYhD,EAAQ,GAAgB;GACtB,IAAI,OAAO;IACT,OAAO,EAAM;GACf;GACA,IAAI,UAAU;IACZ,OAAO,EAAM;GACf;EACF,CAAC;EAED,IAAM,IAAQ,EAAa,GAGrB,IAAe,QACnB,EAAM,QAAQ,KAAA,KAAa,EAAM,MAAM,IAAI,EAAM,MAAM,MAAM,GAAG,EAAM,GAAG,IAAI,EAAM,KACrF,GACM,IAAgB,QAAe,EAAM,MAAM,SAAS,EAAa,MAAM,MAAM,GAI7E,UAAuB,EAAa,OAEpC,IAAY,QAChB,EAAM,cAAc,KAAA,IAAyD,KAAA,IAA7C,EAAE,uBAAuB,EAAM,UAAU,CAC3E,GAMM,IAAoB,QAA2B,EAAM,QAAA,IAA2B;yBAIpF,EAYM,OAAA;GAXJ,OAAM;GACN,MAAK;GACJ,cAAY,EAAA,CAAA;GACZ,OAAK,EAAE,EAAA,KAAS;GAChB,aAAW,EAAA;GACX,gBAAc,EAAA,UAAO,KAAQ,KAAA;YAE9B,EAAkC,EAAlB,CAAc,CAAA,IAClB,EAAA,QAAa,IAAzB,EAEO,EAAA,QAAA,YAAA,EAFyC,OAAO,EAAA,MAAa,SAE7D,CADL,EAAuC,GAAA,MAAA;oBAA7B,CAAA,EAAD,MAAC,EAAG,EAAA,KAAa,GAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"VAvatarGroup.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_unref","_normalizeStyle","_createBlock","_resolveDynamicComponent","_renderSlot","_createVNode","VAvatar","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","VAvatar_default","_hoisted_1","VAvatarGroup_vue_vue_type_script_setup_true_lang_default","props","__props","ariaLabel","useAriaLabel","avatarGroupKey","items","useSlotNodes","visibleItems","computed","overflowCount","VisibleAvatars","rootStyle","resolvedGroupSize","openBlock","createElementBlock","unref","normalizeStyle","createBlock","resolveDynamicComponent","renderSlot","_ctx","createVNode","withCtx","createTextVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/VAvatar/VAvatarGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Count avatars through slot VNodes for SSR-consistent overflow; useSlotNodes keeps that count\n * reactive when the parent replaces its slot.\n */\n\nimport { computed, provide } from 'vue'\nimport type { StyleValue } from 'vue'\n\nimport VAvatar from './VAvatar.vue'\nimport type { AvatarSize } from './VAvatar.vue'\nimport { AVATAR_DEFAULT_SIZE, avatarGroupKey } from './context'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useSlotNodes } from '../../composables/useSlotNodes'\n\n/** What the `#overflow` slot receives. */\nexport interface AvatarGroupOverflowSlotProps {\n /** How many avatars are hidden beyond `max`. */\n count: number\n}\n\ninterface AvatarGroupProps {\n /**\n * How many avatars to show before the remaining ones are summed up as a single\n * \"+X\" disc. Left out, or set to 0, every avatar is shown.\n */\n max?: number\n /**\n * The size given to the avatars inside the group. An avatar that sets a `size`\n * of its own keeps it.\n */\n size?: AvatarSize\n /**\n * The colour of the ring drawn around each disc. It defaults to the page background, which\n * makes the ring read as a gap between two avatars.\n */\n ringColor?: string\n /**\n * The accessible name of the group, e.g. \"Project members\". A row of faces does not say on\n * its own who these people are. A consumer `aria-label` or `aria-labelledby` wins over it.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<AvatarGroupProps>(), {\n max: undefined,\n size: undefined,\n ringColor: undefined,\n label: undefined,\n})\n\nconst ariaLabel = useAriaLabel(() => props.label)\n\ndefineSlots<{\n /** The VAvatars to stack. */\n default?(): unknown\n /**\n * Replaces the \"+X\" disc that stands for the avatars beyond `max`. It receives\n * `count`, the number of avatars being hidden.\n */\n overflow?(props: AvatarGroupOverflowSlotProps): unknown\n}>()\n\nprovide(avatarGroupKey, {\n get size() {\n return props.size\n },\n})\n\nconst items = useSlotNodes()\n// `max: 0` means \"no limit\", as documented, and so does a negative one: `slice(0, -1)` would\n// drop the last avatar and sum it into a \"+1\" disc.\nconst visibleItems = computed(() =>\n props.max !== undefined && props.max > 0 ? items.value.slice(0, props.max) : items.value,\n)\nconst overflowCount = computed(() => items.value.length - visibleItems.value.length)\n\n// A functional component is the only way to render VNodes that have already been\n// captured: <component :is> expects a component definition, not a vnode.\nconst VisibleAvatars = () => visibleItems.value\n\nconst rootStyle = computed<StyleValue>(() =>\n props.ringColor !== undefined ? { '--avatar-ring-color': props.ringColor } : undefined,\n)\n\n// The group carries v-control so that --control-height is defined at ITS level, which keeps the\n// overlap computable even when a child is wrapped; a VTooltip, for instance, inserts a <span>\n// between the group and the VAvatar. An avatar given a size of its own redefines\n// --control-height on itself, so its own overlap follows that size rather than the group's.\nconst resolvedGroupSize = computed<AvatarSize>(() => props.size ?? AVATAR_DEFAULT_SIZE)\n</script>\n\n<template>\n <div\n class=\"v-avatar-group v-control\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :style=\"rootStyle\"\n :data-size=\"resolvedGroupSize\"\n >\n <component :is=\"VisibleAvatars\" />\n <slot v-if=\"overflowCount > 0\" name=\"overflow\" :count=\"overflowCount\">\n <VAvatar>+{{ overflowCount }}</VAvatar>\n </slot>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-avatar-group {\n /* The separation ring, declared here so that every child .v-avatar inherits it. */\n --avatar-ring-color: var(--vectis-color-surface);\n display: inline-flex;\n align-items: center;\n }\n\n /*\n * Take overlap height from the group so wrappers and differently sized avatars share one row\n * contract.\n */\n .v-avatar-group > * + * {\n margin-inline-start: calc(var(--control-height) * -0.3);\n }\n\n /* On hover, or as soon as something inside it takes focus, a disc rises above its\n neighbours so it is seen whole rather than clipped by the next one. */\n .v-avatar-group > *:hover,\n .v-avatar-group > *:focus-within {\n z-index: 1;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;EA8CA,IAAMgB,IAAQC,GAORC,IAAYC,QAAmBH,EAAM,KAAK;EAYhD,EAAQI,GAAgB,EACtB,IAAI,OAAO;GACT,OAAOJ,EAAM;EACf,EACF,CAAC;EAED,IAAMK,IAAQC,EAAa,GAGrBC,IAAeC,QACnBR,EAAM,QAAQ,KAAA,KAAaA,EAAM,MAAM,IAAIK,EAAM,MAAM,MAAM,GAAGL,EAAM,GAAG,IAAIK,EAAM,KACrF,GACMI,IAAgBD,QAAeH,EAAM,MAAM,SAASE,EAAa,MAAM,MAAM,GAI7EG,UAAuBH,EAAa,OAEpCI,IAAYH,QAChBR,EAAM,cAAc,KAAA,IAAyD,KAAA,IAA7C,EAAE,uBAAuBA,EAAM,UAAU,CAC3E,GAMMY,IAAoBJ,QAA2BR,EAAM,QAAA,IAA2B;oBAIpFhB,EAAA,GAAAC,EAWM,OAAA;GAVJ,OAAM;GACN,MAAK;GACJ,cAAYC,EAAAgB,CAAA;GACZ,OAAKf,EAAEwB,EAAA,KAAS;GAChB,aAAWC,EAAA;EAEZ5B,GAAAA,EAAAA,EAAA,GAAAI,EAAkCC,EAAlBqB,CAAc,CAAA,IAClBD,EAAA,QAAa,IAAzBnB,EAEO8B,EAAA,QAAA,YAAA,EAFyC,OAAOX,EAAA,MAAa,SAE7D,CADLlB,EAAuCC,GAAA,MAAA;GAA9B,SAAAC,QAAC,CAADC,EAAA,MAACC,EAAGc,EAAA,KAAa,GAAA,CAAA,CAAA,CAAA"}
@@ -2,7 +2,6 @@ import { InjectionKey } from 'vue';
2
2
  import { AvatarSize } from './VAvatar.js';
3
3
  export interface AvatarGroupContext {
4
4
  size?: AvatarSize;
5
- compact?: boolean;
6
5
  }
7
6
  /** The size of an avatar that neither names one nor sits in a group that does. */
8
7
  export declare const AVATAR_DEFAULT_SIZE: AvatarSize;
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../src/components/VAvatar/context.ts"],"sourcesContent":["/**\n * Explicit avatar size overrides the group fallback. Compact is cumulative, so a compact group\n * cannot have an expanded child.\n */\n\nimport type { InjectionKey } from 'vue'\n\nimport type { AvatarSize } from './VAvatar.vue'\n\nexport interface AvatarGroupContext {\n size?: AvatarSize\n compact?: boolean\n}\n\n/** The size of an avatar that neither names one nor sits in a group that does. */\nexport const AVATAR_DEFAULT_SIZE: AvatarSize = 'md'\n\nexport const avatarGroupKey: InjectionKey<AvatarGroupContext> = Symbol('v-avatar-group')\n"],"mappings":";AAiBA,IAAa,IAAmD,OAAO,gBAAgB"}
1
+ {"version":3,"file":"context.js","names":["avatarGroupKey"],"sources":["../../../src/components/VAvatar/context.ts"],"sourcesContent":["/** Explicit avatar size overrides the group fallback. */\n\nimport type { InjectionKey } from 'vue'\n\nimport type { AvatarSize } from './VAvatar.vue'\n\nexport interface AvatarGroupContext {\n size?: AvatarSize\n}\n\n/** The size of an avatar that neither names one nor sits in a group that does. */\nexport const AVATAR_DEFAULT_SIZE: AvatarSize = 'md'\n\nexport const avatarGroupKey: InjectionKey<AvatarGroupContext> = Symbol('v-avatar-group')\n"],"mappings":";AAaA,IAAaA,IAAmD,OAAO,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"VBadge.js","names":[],"sources":["../../../src/components/VBadge/VBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Render the default slot once: inspect its VNodes to decide whether a noninteractive badge has\n * content.\n */\nimport { computed, h } from 'vue'\nimport type { FunctionalComponent } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\nimport { customColorStyle } from '../../utils/css'\n\n/** How strongly the badge is painted: the full colour, or a tint of it. */\nexport type BadgeVariant = 'solid' | 'soft'\n/** What the badge means, in colour. */\nexport type BadgeTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n/** The corner an overlaid badge is pinned to. */\nexport type BadgeOverlayPosition = 'top' | 'bottom'\n\ninterface BadgeProps {\n /**\n * How strongly the badge is painted: filled with the full colour (`solid`, the default), or a\n * tinted background with the text in the colour (`soft`), for a count that should not draw\n * the eye.\n */\n variant?: BadgeVariant\n /**\n * The meaning the badge carries, expressed as a colour. A solid badge is filled\n * with it and its text adapts to stay readable; a soft one is tinted with it and\n * writes its text in it.\n */\n tone?: BadgeTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. On a solid\n * badge, browsers that support `contrast-color()` turn the text black or white by themselves;\n * everywhere else it falls back to white, so with a light colour the contrast is yours to\n * check.\n */\n color?: string\n /**\n * The number to display. Anything above 99 is shown as \"99+\", so that a busy\n * counter cannot stretch the pill indefinitely.\n */\n count?: number\n /**\n * A single icon shown instead of a number: an icon name, or an explicit render\n * (the VIcon contract). It takes precedence over `count`, and is ignored when the\n * badge is a `dot`.\n */\n icon?: IconSource\n /**\n * Reduces the badge to a 10px dot with no content, the discreet way to signal\n * that something is new without saying how much.\n */\n dot?: boolean\n /**\n * Pins the badge to a corner of the target element instead of placing it beside\n * it. It does nothing when the badge has no target.\n */\n overlay?: boolean\n /**\n * Which corner an `overlay` badge is pinned to: the top one by default, the bottom one for a\n * marker that belongs at the foot of its target, such as a presence dot under an avatar.\n */\n overlayPosition?: BadgeOverlayPosition\n /**\n * Draws a 2px ring around the badge, in the colour of the surface behind it, which detaches\n * it from a busy target such as a picture.\n */\n bordered?: boolean\n /** The colour of the ring drawn by `bordered`. */\n ringColor?: string\n}\n\nconst props = withDefaults(defineProps<BadgeProps>(), {\n variant: 'solid',\n tone: 'accent',\n color: undefined,\n count: undefined,\n icon: undefined,\n overlayPosition: 'top',\n ringColor: undefined,\n // Written out although Vue casts an absent boolean to `false` on its own: left out,\n // `vue-component-meta` reports no default at all and the docs table's cell goes blank.\n dot: false,\n overlay: false,\n bordered: false,\n})\n\nconst slots = defineSlots<{\n /** The element the badge belongs to. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive, so a computed\n// would keep its first answer while a slot behind a `v-if` comes and goes.\nfunction hasTarget() {\n return slots.default !== undefined\n}\n\n/**\n * The counter as it is actually displayed: a whole number, zero or more, and anything past 99\n * becomes \"99+\".\n */\nconst displayCount = computed(() => {\n const count = props.count\n if (count === undefined || !Number.isFinite(count)) return undefined\n return count > 99 ? '99+' : Math.max(0, Math.trunc(count))\n})\n\n/*\n * The template has two roots; one wrapping a target, one standing alone; and both render the\n * same badge; a functional component is the one way to put the same markup in two places of a\n * template without writing it twice.\n */\nconst Pill: FunctionalComponent = () =>\n h(\n 'span',\n {\n class: 'v-badge v-tone v-variant',\n 'data-variant': props.variant,\n 'data-tone': props.tone,\n 'data-custom': props.color !== undefined ? '' : undefined,\n 'data-dot': props.dot ? '' : undefined,\n 'data-icon-only': !props.dot && props.icon ? '' : undefined,\n 'data-bordered': props.bordered ? '' : undefined,\n style: [\n customColorStyle(props.color),\n props.ringColor !== undefined ? { '--badge-ring-color': props.ringColor } : undefined,\n ],\n },\n props.dot\n ? undefined\n : props.icon\n ? [h(VIcon, iconProps(props.icon))]\n : displayCount.value === undefined\n ? undefined\n : String(displayCount.value),\n )\n// The empty list is not decoration. A functional component that declares no props lets only\n// `class`, `style` and listeners fall through, so a standalone badge, whose root this is, would\n// silently drop every other attribute a consumer set on VBadge (an `id`, a `data-*`).\nPill.props = []\n</script>\n\n<template>\n <span\n v-if=\"hasTarget()\"\n class=\"v-badge-host\"\n :data-overlay=\"overlay ? '' : undefined\"\n :data-overlay-position=\"overlayPosition\"\n >\n <slot />\n <Pill aria-hidden=\"true\" />\n </span>\n <Pill v-else />\n</template>\n\n<style>\n@layer vectis.components {\n .v-badge-host {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n\n /* The pill is painted by the shared `.v-variant` rules (styles/variants.css) over the\n tone table (`.v-tone`), both set in the template: `solid` is the tone's full colour,\n `soft` its tint with the text in the tone's own colour. A custom colour is the table's\n `[data-custom]` row, in styles/tones.css. */\n .v-badge {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n /* The colour of the `bordered` ring: a bet on the page background, the only one a\n component can make since CSS cannot read what its parent paints. The `ringColor`\n prop overrides it inline for a badge sitting on anything else. */\n --badge-ring-color: var(--vectis-color-surface);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--vectis-control-size-badge-h);\n /* A minimum width equal to the height, with a small padding on top, is what\n makes a one- or two-digit counter come out round rather than oval. */\n min-width: var(--vectis-control-size-badge-h);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n /*\n * The class is compounded to (0,3,0): `.v-variant[data-variant='solid']` sets `color` at\n * (0,2,0) from another sheet, and a tie would be settled by sheet order. The soft pill keeps\n * the tone's own text colour, which says the tone where black or white would not.\n */\n @supports (color: contrast-color(red)) {\n .v-badge.v-variant[data-variant='solid'] {\n color: contrast-color(var(--tone-bg-solid));\n }\n }\n\n /* A dot is always solid: with no content, a soft dot is a pale disc on the page, which a\n presence marker cannot afford. (0,3,0), above the soft variant's background. */\n .v-badge.v-variant[data-dot] {\n background: var(--tone-bg-solid);\n }\n\n .v-badge[data-icon-only] {\n padding: 0;\n }\n\n .v-badge[data-dot] {\n width: var(--vectis-control-size-badge-dot);\n height: var(--vectis-control-size-badge-dot);\n min-width: 0;\n padding: 0;\n }\n\n .v-badge[data-bordered] {\n box-shadow: 0 0 0 var(--vectis-control-size-badge-ring) var(--badge-ring-color);\n }\n\n /*\n * The tuck-in offset is a ratio of the badge's own size, so it stays proportionate across the\n * pill, the dot and the icon. Each half of it is held in its own variable: the corner and the\n * reading direction each flip ONE axis, and writing the whole `translate` again in each\n * branch would make the two multiply; four rules to keep in step by hand for two independent\n * decisions.\n */\n .v-badge-host[data-overlay] > .v-badge {\n --badge-overlay-x: 25%;\n --badge-overlay-y: -25%;\n\n position: absolute;\n inset-block: 0 auto;\n inset-inline-end: 0;\n translate: var(--badge-overlay-x) var(--badge-overlay-y);\n /*\n * Raise overlaid badges above later positioned siblings; tree order alone lets neighbouring\n * segments cover them.\n */\n z-index: 1;\n }\n\n .v-badge-host[data-overlay][data-overlay-position='bottom'] > .v-badge {\n --badge-overlay-y: 25%;\n\n inset-block: auto 0;\n }\n\n /*\n * In a right-to-left direction the logical corner moves to the left, so the horizontal half\n * of the translation has to flip with it; `translate` is a physical property and knows\n * nothing about direction.\n */\n .v-badge-host[data-overlay]:dir(rtl) > .v-badge {\n --badge-overlay-x: -25%;\n }\n\n /* Forced colours repaint the background as Canvas and drop the ring, a shadow: the pill\n loses its shape, and a dot, which has nothing else, disappears altogether. The pill\n gets an edge, and the dot is filled in the text colour. */\n @media (forced-colors: active) {\n .v-badge {\n outline: var(--vectis-control-border-width) solid CanvasText;\n outline-offset: calc(-1 * var(--vectis-control-border-width));\n }\n\n .v-badge.v-variant[data-dot] {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VBadge.js","names":["_sfc_main","VBadge_vue_vue_type_script_setup_true_lang_default","VBadge_default"],"sources":["../../../src/components/VBadge/VBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Render the default slot once: inspect its VNodes to decide whether a noninteractive badge has\n * content.\n */\nimport { computed, h } from 'vue'\nimport type { FunctionalComponent } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\nimport { customColorStyle } from '../../utils/css'\n\n/** How strongly the badge is painted: the full colour, or a tint of it. */\nexport type BadgeVariant = 'solid' | 'soft'\n/** What the badge means, in colour. */\nexport type BadgeTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n/** The corner an overlaid badge is pinned to. */\nexport type BadgeOverlayPosition = 'top' | 'bottom'\n\ninterface BadgeProps {\n /**\n * How strongly the badge is painted: filled with the full colour (`solid`, the default), or a\n * tinted background with the text in the colour (`soft`), for a count that should not draw\n * the eye.\n */\n variant?: BadgeVariant\n /**\n * The meaning the badge carries, expressed as a colour. A solid badge is filled\n * with it and its text adapts to stay readable; a soft one is tinted with it and\n * writes its text in it.\n */\n tone?: BadgeTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. On a solid\n * badge, browsers that support `contrast-color()` turn the text black or white by themselves;\n * everywhere else it falls back to white, so with a light colour the contrast is yours to\n * check.\n */\n color?: string\n /**\n * The number to display. Anything above 99 is shown as \"99+\", so that a busy\n * counter cannot stretch the pill indefinitely.\n */\n count?: number\n /**\n * A single icon shown instead of a number: an icon name, or an explicit render\n * (the VIcon contract). It takes precedence over `count`, and is ignored when the\n * badge is a `dot`.\n */\n icon?: IconSource\n /**\n * Reduces the badge to a 10px dot with no content, the discreet way to signal\n * that something is new without saying how much.\n */\n dot?: boolean\n /**\n * Pins the badge to a corner of the target element instead of placing it beside\n * it. It does nothing when the badge has no target.\n */\n overlay?: boolean\n /**\n * Which corner an `overlay` badge is pinned to: the top one by default, the bottom one for a\n * marker that belongs at the foot of its target, such as a presence dot under an avatar.\n */\n overlayPosition?: BadgeOverlayPosition\n /**\n * Draws a 2px ring around the badge, in the colour of the surface behind it, which detaches\n * it from a busy target such as a picture.\n */\n bordered?: boolean\n /** The colour of the ring drawn by `bordered`. */\n ringColor?: string\n}\n\nconst props = withDefaults(defineProps<BadgeProps>(), {\n variant: 'solid',\n tone: 'accent',\n color: undefined,\n count: undefined,\n icon: undefined,\n overlayPosition: 'top',\n ringColor: undefined,\n // Written out although Vue casts an absent boolean to `false` on its own: left out,\n // `vue-component-meta` reports no default at all and the docs table's cell goes blank.\n dot: false,\n overlay: false,\n bordered: false,\n})\n\nconst slots = defineSlots<{\n /** The element the badge belongs to. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive, so a computed\n// would keep its first answer while a slot behind a `v-if` comes and goes.\nfunction hasTarget() {\n return slots.default !== undefined\n}\n\n/**\n * The counter as it is actually displayed: a whole number, zero or more, and anything past 99\n * becomes \"99+\".\n */\nconst displayCount = computed(() => {\n const count = props.count\n if (count === undefined || !Number.isFinite(count)) return undefined\n return count > 99 ? '99+' : Math.max(0, Math.trunc(count))\n})\n\n/*\n * The template has two roots; one wrapping a target, one standing alone; and both render the\n * same badge; a functional component is the one way to put the same markup in two places of a\n * template without writing it twice.\n */\nconst Pill: FunctionalComponent = () =>\n h(\n 'span',\n {\n class: 'v-badge v-tone v-variant',\n 'data-variant': props.variant,\n 'data-tone': props.tone,\n 'data-custom': props.color !== undefined ? '' : undefined,\n 'data-dot': props.dot ? '' : undefined,\n 'data-icon-only': !props.dot && props.icon ? '' : undefined,\n 'data-bordered': props.bordered ? '' : undefined,\n style: [\n customColorStyle(props.color),\n props.ringColor !== undefined ? { '--badge-ring-color': props.ringColor } : undefined,\n ],\n },\n props.dot\n ? undefined\n : props.icon\n ? [h(VIcon, iconProps(props.icon))]\n : displayCount.value === undefined\n ? undefined\n : String(displayCount.value),\n )\n// The empty list is not decoration. A functional component that declares no props lets only\n// `class`, `style` and listeners fall through, so a standalone badge, whose root this is, would\n// silently drop every other attribute a consumer set on VBadge (an `id`, a `data-*`).\nPill.props = []\n</script>\n\n<template>\n <span\n v-if=\"hasTarget()\"\n class=\"v-badge-host\"\n :data-overlay=\"overlay ? '' : undefined\"\n :data-overlay-position=\"overlayPosition\"\n >\n <slot />\n <Pill aria-hidden=\"true\" />\n </span>\n <Pill v-else />\n</template>\n\n<style>\n@layer vectis.components {\n .v-badge-host {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n\n /* The pill is painted by the shared `.v-variant` rules (styles/variants.css) over the\n tone table (`.v-tone`), both set in the template: `solid` is the tone's full colour,\n `soft` its tint with the text in the tone's own colour. A custom colour is the table's\n `[data-custom]` row, in styles/tones.css. */\n .v-badge {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n /* The colour of the `bordered` ring: a bet on the page background, the only one a\n component can make since CSS cannot read what its parent paints. The `ringColor`\n prop overrides it inline for a badge sitting on anything else. */\n --badge-ring-color: var(--vectis-color-surface);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--vectis-control-size-badge-h);\n /* A minimum width equal to the height, with a small padding on top, is what\n makes a one- or two-digit counter come out round rather than oval. */\n min-width: var(--vectis-control-size-badge-h);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n /*\n * The class is compounded to (0,3,0): `.v-variant[data-variant='solid']` sets `color` at\n * (0,2,0) from another sheet, and a tie would be settled by sheet order. The soft pill keeps\n * the tone's own text colour, which says the tone where black or white would not.\n */\n @supports (color: contrast-color(red)) {\n .v-badge.v-variant[data-variant='solid'] {\n color: contrast-color(var(--tone-bg-solid));\n }\n }\n\n /* A dot is always solid: with no content, a soft dot is a pale disc on the page, which a\n presence marker cannot afford. (0,3,0), above the soft variant's background. */\n .v-badge.v-variant[data-dot] {\n background: var(--tone-bg-solid);\n }\n\n .v-badge[data-icon-only] {\n padding: 0;\n }\n\n .v-badge[data-dot] {\n width: var(--vectis-control-size-badge-dot);\n height: var(--vectis-control-size-badge-dot);\n min-width: 0;\n padding: 0;\n }\n\n .v-badge[data-bordered] {\n box-shadow: 0 0 0 var(--vectis-control-size-badge-ring) var(--badge-ring-color);\n }\n\n /*\n * The tuck-in offset is a ratio of the badge's own size, so it stays proportionate across the\n * pill, the dot and the icon. Each half of it is held in its own variable: the corner and the\n * reading direction each flip ONE axis, and writing the whole `translate` again in each\n * branch would make the two multiply; four rules to keep in step by hand for two independent\n * decisions.\n */\n .v-badge-host[data-overlay] > .v-badge {\n --badge-overlay-x: 25%;\n --badge-overlay-y: -25%;\n\n position: absolute;\n inset-block: 0 auto;\n inset-inline-end: 0;\n translate: var(--badge-overlay-x) var(--badge-overlay-y);\n /*\n * Raise overlaid badges above later positioned siblings; tree order alone lets neighbouring\n * segments cover them.\n */\n z-index: 1;\n }\n\n .v-badge-host[data-overlay][data-overlay-position='bottom'] > .v-badge {\n --badge-overlay-y: 25%;\n\n inset-block: auto 0;\n }\n\n /*\n * In a right-to-left direction the logical corner moves to the left, so the horizontal half\n * of the translation has to flip with it; `translate` is a physical property and knows\n * nothing about direction.\n */\n .v-badge-host[data-overlay]:dir(rtl) > .v-badge {\n --badge-overlay-x: -25%;\n }\n\n /* Forced colours repaint the background as Canvas and drop the ring, a shadow: the pill\n loses its shape, and a dot, which has nothing else, disappears altogether. The pill\n gets an edge, and the dot is filled in the text colour. */\n @media (forced-colors: active) {\n .v-badge {\n outline: var(--vectis-control-border-width) solid CanvasText;\n outline-offset: calc(-1 * var(--vectis-control-border-width));\n }\n\n .v-badge.v-variant[data-dot] {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -33,7 +33,7 @@ var f = ["data-overlay", "data-overlay-position"], p = /*@__PURE__*/ s({
33
33
  }
34
34
  let g = r(() => {
35
35
  let e = p.count;
36
- if (!(e === void 0 || !Number.isFinite(e))) return e > 99 ? "99+" : Math.max(0, Math.trunc(e));
36
+ if (e !== void 0 && Number.isFinite(e)) return e > 99 ? "99+" : Math.max(0, Math.trunc(e));
37
37
  }), _ = () => c("span", {
38
38
  class: "v-badge v-tone v-variant",
39
39
  "data-variant": p.variant,
@@ -1 +1 @@
1
- {"version":3,"file":"VBadge.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VBadge/VBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Render the default slot once: inspect its VNodes to decide whether a noninteractive badge has\n * content.\n */\nimport { computed, h } from 'vue'\nimport type { FunctionalComponent } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\nimport { customColorStyle } from '../../utils/css'\n\n/** How strongly the badge is painted: the full colour, or a tint of it. */\nexport type BadgeVariant = 'solid' | 'soft'\n/** What the badge means, in colour. */\nexport type BadgeTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n/** The corner an overlaid badge is pinned to. */\nexport type BadgeOverlayPosition = 'top' | 'bottom'\n\ninterface BadgeProps {\n /**\n * How strongly the badge is painted: filled with the full colour (`solid`, the default), or a\n * tinted background with the text in the colour (`soft`), for a count that should not draw\n * the eye.\n */\n variant?: BadgeVariant\n /**\n * The meaning the badge carries, expressed as a colour. A solid badge is filled\n * with it and its text adapts to stay readable; a soft one is tinted with it and\n * writes its text in it.\n */\n tone?: BadgeTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. On a solid\n * badge, browsers that support `contrast-color()` turn the text black or white by themselves;\n * everywhere else it falls back to white, so with a light colour the contrast is yours to\n * check.\n */\n color?: string\n /**\n * The number to display. Anything above 99 is shown as \"99+\", so that a busy\n * counter cannot stretch the pill indefinitely.\n */\n count?: number\n /**\n * A single icon shown instead of a number: an icon name, or an explicit render\n * (the VIcon contract). It takes precedence over `count`, and is ignored when the\n * badge is a `dot`.\n */\n icon?: IconSource\n /**\n * Reduces the badge to a 10px dot with no content, the discreet way to signal\n * that something is new without saying how much.\n */\n dot?: boolean\n /**\n * Pins the badge to a corner of the target element instead of placing it beside\n * it. It does nothing when the badge has no target.\n */\n overlay?: boolean\n /**\n * Which corner an `overlay` badge is pinned to: the top one by default, the bottom one for a\n * marker that belongs at the foot of its target, such as a presence dot under an avatar.\n */\n overlayPosition?: BadgeOverlayPosition\n /**\n * Draws a 2px ring around the badge, in the colour of the surface behind it, which detaches\n * it from a busy target such as a picture.\n */\n bordered?: boolean\n /** The colour of the ring drawn by `bordered`. */\n ringColor?: string\n}\n\nconst props = withDefaults(defineProps<BadgeProps>(), {\n variant: 'solid',\n tone: 'accent',\n color: undefined,\n count: undefined,\n icon: undefined,\n overlayPosition: 'top',\n ringColor: undefined,\n // Written out although Vue casts an absent boolean to `false` on its own: left out,\n // `vue-component-meta` reports no default at all and the docs table's cell goes blank.\n dot: false,\n overlay: false,\n bordered: false,\n})\n\nconst slots = defineSlots<{\n /** The element the badge belongs to. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive, so a computed\n// would keep its first answer while a slot behind a `v-if` comes and goes.\nfunction hasTarget() {\n return slots.default !== undefined\n}\n\n/**\n * The counter as it is actually displayed: a whole number, zero or more, and anything past 99\n * becomes \"99+\".\n */\nconst displayCount = computed(() => {\n const count = props.count\n if (count === undefined || !Number.isFinite(count)) return undefined\n return count > 99 ? '99+' : Math.max(0, Math.trunc(count))\n})\n\n/*\n * The template has two roots; one wrapping a target, one standing alone; and both render the\n * same badge; a functional component is the one way to put the same markup in two places of a\n * template without writing it twice.\n */\nconst Pill: FunctionalComponent = () =>\n h(\n 'span',\n {\n class: 'v-badge v-tone v-variant',\n 'data-variant': props.variant,\n 'data-tone': props.tone,\n 'data-custom': props.color !== undefined ? '' : undefined,\n 'data-dot': props.dot ? '' : undefined,\n 'data-icon-only': !props.dot && props.icon ? '' : undefined,\n 'data-bordered': props.bordered ? '' : undefined,\n style: [\n customColorStyle(props.color),\n props.ringColor !== undefined ? { '--badge-ring-color': props.ringColor } : undefined,\n ],\n },\n props.dot\n ? undefined\n : props.icon\n ? [h(VIcon, iconProps(props.icon))]\n : displayCount.value === undefined\n ? undefined\n : String(displayCount.value),\n )\n// The empty list is not decoration. A functional component that declares no props lets only\n// `class`, `style` and listeners fall through, so a standalone badge, whose root this is, would\n// silently drop every other attribute a consumer set on VBadge (an `id`, a `data-*`).\nPill.props = []\n</script>\n\n<template>\n <span\n v-if=\"hasTarget()\"\n class=\"v-badge-host\"\n :data-overlay=\"overlay ? '' : undefined\"\n :data-overlay-position=\"overlayPosition\"\n >\n <slot />\n <Pill aria-hidden=\"true\" />\n </span>\n <Pill v-else />\n</template>\n\n<style>\n@layer vectis.components {\n .v-badge-host {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n\n /* The pill is painted by the shared `.v-variant` rules (styles/variants.css) over the\n tone table (`.v-tone`), both set in the template: `solid` is the tone's full colour,\n `soft` its tint with the text in the tone's own colour. A custom colour is the table's\n `[data-custom]` row, in styles/tones.css. */\n .v-badge {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n /* The colour of the `bordered` ring: a bet on the page background, the only one a\n component can make since CSS cannot read what its parent paints. The `ringColor`\n prop overrides it inline for a badge sitting on anything else. */\n --badge-ring-color: var(--vectis-color-surface);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--vectis-control-size-badge-h);\n /* A minimum width equal to the height, with a small padding on top, is what\n makes a one- or two-digit counter come out round rather than oval. */\n min-width: var(--vectis-control-size-badge-h);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n /*\n * The class is compounded to (0,3,0): `.v-variant[data-variant='solid']` sets `color` at\n * (0,2,0) from another sheet, and a tie would be settled by sheet order. The soft pill keeps\n * the tone's own text colour, which says the tone where black or white would not.\n */\n @supports (color: contrast-color(red)) {\n .v-badge.v-variant[data-variant='solid'] {\n color: contrast-color(var(--tone-bg-solid));\n }\n }\n\n /* A dot is always solid: with no content, a soft dot is a pale disc on the page, which a\n presence marker cannot afford. (0,3,0), above the soft variant's background. */\n .v-badge.v-variant[data-dot] {\n background: var(--tone-bg-solid);\n }\n\n .v-badge[data-icon-only] {\n padding: 0;\n }\n\n .v-badge[data-dot] {\n width: var(--vectis-control-size-badge-dot);\n height: var(--vectis-control-size-badge-dot);\n min-width: 0;\n padding: 0;\n }\n\n .v-badge[data-bordered] {\n box-shadow: 0 0 0 var(--vectis-control-size-badge-ring) var(--badge-ring-color);\n }\n\n /*\n * The tuck-in offset is a ratio of the badge's own size, so it stays proportionate across the\n * pill, the dot and the icon. Each half of it is held in its own variable: the corner and the\n * reading direction each flip ONE axis, and writing the whole `translate` again in each\n * branch would make the two multiply; four rules to keep in step by hand for two independent\n * decisions.\n */\n .v-badge-host[data-overlay] > .v-badge {\n --badge-overlay-x: 25%;\n --badge-overlay-y: -25%;\n\n position: absolute;\n inset-block: 0 auto;\n inset-inline-end: 0;\n translate: var(--badge-overlay-x) var(--badge-overlay-y);\n /*\n * Raise overlaid badges above later positioned siblings; tree order alone lets neighbouring\n * segments cover them.\n */\n z-index: 1;\n }\n\n .v-badge-host[data-overlay][data-overlay-position='bottom'] > .v-badge {\n --badge-overlay-y: 25%;\n\n inset-block: auto 0;\n }\n\n /*\n * In a right-to-left direction the logical corner moves to the left, so the horizontal half\n * of the translation has to flip with it; `translate` is a physical property and knows\n * nothing about direction.\n */\n .v-badge-host[data-overlay]:dir(rtl) > .v-badge {\n --badge-overlay-x: -25%;\n }\n\n /* Forced colours repaint the background as Canvas and drop the ring, a shadow: the pill\n loses its shape, and a dot, which has nothing else, disappears altogether. The pill\n gets an edge, and the dot is filled in the text colour. */\n @media (forced-colors: active) {\n .v-badge {\n outline: var(--vectis-control-border-width) solid CanvasText;\n outline-offset: calc(-1 * var(--vectis-control-border-width));\n }\n\n .v-badge.v-variant[data-dot] {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6EA,IAAM,IAAQ,GAeR,IAAQ,EAAA;EAOd,SAAS,IAAY;GACnB,OAAO,EAAM,YAAY,KAAA;EAC3B;EAMA,IAAM,IAAe,QAAe;GAClC,IAAM,IAAQ,EAAM;GAChB,YAAU,KAAA,KAAa,CAAC,OAAO,SAAS,CAAK,IACjD,OAAO,IAAQ,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,CAAK,CAAC;EAC3D,CAAC,GAOK,UACJ,EACE,QACA;GACE,OAAO;GACP,gBAAgB,EAAM;GACtB,aAAa,EAAM;GACnB,eAAe,EAAM,UAAU,KAAA,IAAiB,KAAA,IAAL;GAC3C,YAAY,EAAM,MAAM,KAAK,KAAA;GAC7B,kBAAkB,CAAC,EAAM,OAAO,EAAM,OAAO,KAAK,KAAA;GAClD,iBAAiB,EAAM,WAAW,KAAK,KAAA;GACvC,OAAO,CACL,EAAiB,EAAM,KAAK,GAC5B,EAAM,cAAc,KAAA,IAAwD,KAAA,IAA5C,EAAE,sBAAsB,EAAM,UAAU,CAC1E;EACF,GACA,EAAM,MACF,KAAA,IACA,EAAM,OACJ,CAAC,EAAE,GAAO,EAAU,EAAM,IAAI,CAAC,CAAC,IAChC,EAAa,UAAU,KAAA,IACrB,KAAA,IACA,OAAO,EAAa,KAAK,CACnC;SAIF,EAAK,QAAQ,CAAC,aAKJ,EAAS,KAAA,EAAA,GADjB,EAQO,QAAA;;GANL,OAAM;GACL,gBAAc,EAAA,UAAO,KAAQ,KAAA;GAC7B,yBAAuB,EAAA;MAExB,EAAQ,EAAA,QAAA,SAAA,GACR,EAA2B,GAAA,EAArB,eAAY,OAAM,CAAA,CAAA,GAAA,GAAA,CAAA,MAAA,EAAA,GAE1B,EAAe,GAAA,EAAA,KAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"VBadge.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","VIcon","_openBlock","_createElementBlock","_renderSlot","_createVNode","_createBlock","VIcon_default","_hoisted_1","VBadge_vue_vue_type_script_setup_true_lang_default","props","__props","slots","useSlots","hasTarget","displayCount","computed","count","Pill","h","customColorStyle","iconProps","openBlock","createElementBlock","renderSlot","_ctx","createVNode","createBlock"],"sources":["../../../src/components/VBadge/VBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Render the default slot once: inspect its VNodes to decide whether a noninteractive badge has\n * content.\n */\nimport { computed, h } from 'vue'\nimport type { FunctionalComponent } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\nimport { customColorStyle } from '../../utils/css'\n\n/** How strongly the badge is painted: the full colour, or a tint of it. */\nexport type BadgeVariant = 'solid' | 'soft'\n/** What the badge means, in colour. */\nexport type BadgeTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n/** The corner an overlaid badge is pinned to. */\nexport type BadgeOverlayPosition = 'top' | 'bottom'\n\ninterface BadgeProps {\n /**\n * How strongly the badge is painted: filled with the full colour (`solid`, the default), or a\n * tinted background with the text in the colour (`soft`), for a count that should not draw\n * the eye.\n */\n variant?: BadgeVariant\n /**\n * The meaning the badge carries, expressed as a colour. A solid badge is filled\n * with it and its text adapts to stay readable; a soft one is tinted with it and\n * writes its text in it.\n */\n tone?: BadgeTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. On a solid\n * badge, browsers that support `contrast-color()` turn the text black or white by themselves;\n * everywhere else it falls back to white, so with a light colour the contrast is yours to\n * check.\n */\n color?: string\n /**\n * The number to display. Anything above 99 is shown as \"99+\", so that a busy\n * counter cannot stretch the pill indefinitely.\n */\n count?: number\n /**\n * A single icon shown instead of a number: an icon name, or an explicit render\n * (the VIcon contract). It takes precedence over `count`, and is ignored when the\n * badge is a `dot`.\n */\n icon?: IconSource\n /**\n * Reduces the badge to a 10px dot with no content, the discreet way to signal\n * that something is new without saying how much.\n */\n dot?: boolean\n /**\n * Pins the badge to a corner of the target element instead of placing it beside\n * it. It does nothing when the badge has no target.\n */\n overlay?: boolean\n /**\n * Which corner an `overlay` badge is pinned to: the top one by default, the bottom one for a\n * marker that belongs at the foot of its target, such as a presence dot under an avatar.\n */\n overlayPosition?: BadgeOverlayPosition\n /**\n * Draws a 2px ring around the badge, in the colour of the surface behind it, which detaches\n * it from a busy target such as a picture.\n */\n bordered?: boolean\n /** The colour of the ring drawn by `bordered`. */\n ringColor?: string\n}\n\nconst props = withDefaults(defineProps<BadgeProps>(), {\n variant: 'solid',\n tone: 'accent',\n color: undefined,\n count: undefined,\n icon: undefined,\n overlayPosition: 'top',\n ringColor: undefined,\n // Written out although Vue casts an absent boolean to `false` on its own: left out,\n // `vue-component-meta` reports no default at all and the docs table's cell goes blank.\n dot: false,\n overlay: false,\n bordered: false,\n})\n\nconst slots = defineSlots<{\n /** The element the badge belongs to. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive, so a computed\n// would keep its first answer while a slot behind a `v-if` comes and goes.\nfunction hasTarget() {\n return slots.default !== undefined\n}\n\n/**\n * The counter as it is actually displayed: a whole number, zero or more, and anything past 99\n * becomes \"99+\".\n */\nconst displayCount = computed(() => {\n const count = props.count\n if (count === undefined || !Number.isFinite(count)) return undefined\n return count > 99 ? '99+' : Math.max(0, Math.trunc(count))\n})\n\n/*\n * The template has two roots; one wrapping a target, one standing alone; and both render the\n * same badge; a functional component is the one way to put the same markup in two places of a\n * template without writing it twice.\n */\nconst Pill: FunctionalComponent = () =>\n h(\n 'span',\n {\n class: 'v-badge v-tone v-variant',\n 'data-variant': props.variant,\n 'data-tone': props.tone,\n 'data-custom': props.color !== undefined ? '' : undefined,\n 'data-dot': props.dot ? '' : undefined,\n 'data-icon-only': !props.dot && props.icon ? '' : undefined,\n 'data-bordered': props.bordered ? '' : undefined,\n style: [\n customColorStyle(props.color),\n props.ringColor !== undefined ? { '--badge-ring-color': props.ringColor } : undefined,\n ],\n },\n props.dot\n ? undefined\n : props.icon\n ? [h(VIcon, iconProps(props.icon))]\n : displayCount.value === undefined\n ? undefined\n : String(displayCount.value),\n )\n// The empty list is not decoration. A functional component that declares no props lets only\n// `class`, `style` and listeners fall through, so a standalone badge, whose root this is, would\n// silently drop every other attribute a consumer set on VBadge (an `id`, a `data-*`).\nPill.props = []\n</script>\n\n<template>\n <span\n v-if=\"hasTarget()\"\n class=\"v-badge-host\"\n :data-overlay=\"overlay ? '' : undefined\"\n :data-overlay-position=\"overlayPosition\"\n >\n <slot />\n <Pill aria-hidden=\"true\" />\n </span>\n <Pill v-else />\n</template>\n\n<style>\n@layer vectis.components {\n .v-badge-host {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n\n /* The pill is painted by the shared `.v-variant` rules (styles/variants.css) over the\n tone table (`.v-tone`), both set in the template: `solid` is the tone's full colour,\n `soft` its tint with the text in the tone's own colour. A custom colour is the table's\n `[data-custom]` row, in styles/tones.css. */\n .v-badge {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n /* The colour of the `bordered` ring: a bet on the page background, the only one a\n component can make since CSS cannot read what its parent paints. The `ringColor`\n prop overrides it inline for a badge sitting on anything else. */\n --badge-ring-color: var(--vectis-color-surface);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--vectis-control-size-badge-h);\n /* A minimum width equal to the height, with a small padding on top, is what\n makes a one- or two-digit counter come out round rather than oval. */\n min-width: var(--vectis-control-size-badge-h);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n /*\n * The class is compounded to (0,3,0): `.v-variant[data-variant='solid']` sets `color` at\n * (0,2,0) from another sheet, and a tie would be settled by sheet order. The soft pill keeps\n * the tone's own text colour, which says the tone where black or white would not.\n */\n @supports (color: contrast-color(red)) {\n .v-badge.v-variant[data-variant='solid'] {\n color: contrast-color(var(--tone-bg-solid));\n }\n }\n\n /* A dot is always solid: with no content, a soft dot is a pale disc on the page, which a\n presence marker cannot afford. (0,3,0), above the soft variant's background. */\n .v-badge.v-variant[data-dot] {\n background: var(--tone-bg-solid);\n }\n\n .v-badge[data-icon-only] {\n padding: 0;\n }\n\n .v-badge[data-dot] {\n width: var(--vectis-control-size-badge-dot);\n height: var(--vectis-control-size-badge-dot);\n min-width: 0;\n padding: 0;\n }\n\n .v-badge[data-bordered] {\n box-shadow: 0 0 0 var(--vectis-control-size-badge-ring) var(--badge-ring-color);\n }\n\n /*\n * The tuck-in offset is a ratio of the badge's own size, so it stays proportionate across the\n * pill, the dot and the icon. Each half of it is held in its own variable: the corner and the\n * reading direction each flip ONE axis, and writing the whole `translate` again in each\n * branch would make the two multiply; four rules to keep in step by hand for two independent\n * decisions.\n */\n .v-badge-host[data-overlay] > .v-badge {\n --badge-overlay-x: 25%;\n --badge-overlay-y: -25%;\n\n position: absolute;\n inset-block: 0 auto;\n inset-inline-end: 0;\n translate: var(--badge-overlay-x) var(--badge-overlay-y);\n /*\n * Raise overlaid badges above later positioned siblings; tree order alone lets neighbouring\n * segments cover them.\n */\n z-index: 1;\n }\n\n .v-badge-host[data-overlay][data-overlay-position='bottom'] > .v-badge {\n --badge-overlay-y: 25%;\n\n inset-block: auto 0;\n }\n\n /*\n * In a right-to-left direction the logical corner moves to the left, so the horizontal half\n * of the translation has to flip with it; `translate` is a physical property and knows\n * nothing about direction.\n */\n .v-badge-host[data-overlay]:dir(rtl) > .v-badge {\n --badge-overlay-x: -25%;\n }\n\n /* Forced colours repaint the background as Canvas and drop the ring, a shadow: the pill\n loses its shape, and a dot, which has nothing else, disappears altogether. The pill\n gets an edge, and the dot is filled in the text colour. */\n @media (forced-colors: active) {\n .v-badge {\n outline: var(--vectis-control-border-width) solid CanvasText;\n outline-offset: calc(-1 * var(--vectis-control-border-width));\n }\n\n .v-badge.v-variant[data-dot] {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6EA,IAAMU,IAAQC,GAeRC,IAAQZ,EAAA;EAOd,SAASc,IAAY;GACnB,OAAOF,EAAM,YAAY,KAAA;EAC3B;EAMA,IAAMG,IAAeC,QAAe;GAClC,IAAMC,IAAQP,EAAM;GACpB,IAAIO,MAAU,KAAA,KAAc,OAAO,SAASA,CAAK,GACjD,OAAOA,IAAQ,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAMA,CAAK,CAAC;EAC3D,CAAC,GAOKC,UACJC,EACE,QACA;GACE,OAAO;GACP,gBAAgBT,EAAM;GACtB,aAAaA,EAAM;GACnB,eAAeA,EAAM,UAAU,KAAA,IAAiB,KAAA,IAAL;GAC3C,YAAYA,EAAM,MAAM,KAAK,KAAA;GAC7B,kBAAkB,CAACA,EAAM,OAAOA,EAAM,OAAO,KAAK,KAAA;GAClD,iBAAiBA,EAAM,WAAW,KAAK,KAAA;GACvC,OAAO,CACLU,EAAiBV,EAAM,KAAK,GAC5BA,EAAM,cAAc,KAAA,IAAwD,KAAA,IAA5C,EAAE,sBAAsBA,EAAM,UAAU,CAC1E;EACF,GACAA,EAAM,MACF,KAAA,IACAA,EAAM,OACJ,CAACS,EAAElB,GAAOoB,EAAUX,EAAM,IAAI,CAAC,CAAC,IAChCK,EAAa,UAAU,KAAA,IACrB,KAAA,IACA,OAAOA,EAAa,KAAK,CACnC;SAIF,EAAK,QAAQ,CAAC,aAKJD,EAAS,KADjBZ,EAAA,GAAAC,EAQO,QAAA;;GANL,OAAM;GACL,gBAAcQ,EAAA,UAAO,KAAQ,KAAA;GAC7B,yBAAuBA,EAAA;EAExBP,GAAAA,CAAAA,EAAQqB,EAAA,QAAA,SAAA,GACRpB,EAA2Ba,GAAA,EAArB,eAAY,OAAM,CAAA,CAAA,GAAA,GAAAV,CAAA,MAE1BN,EAAA,GAAAI,EAAeY,GAAA,EAAA,KAAA,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"VBreadcrumb.js","names":[],"sources":["../../../src/components/VBreadcrumb/VBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Mark the matching link aria-current without disabling it. CSS hides the first separator so\n * SSR needs no child registry.\n */\n\nimport { computed } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport { more_horiz as moreHorizIcon } from '../VIcon/icons/more_horiz'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\nexport interface BreadcrumbItem {\n /** The text shown for this segment. */\n label: string\n /**\n * Where the segment leads. It is also the value compared with `currentPath` to\n * decide which segment is the current page.\n */\n href: string\n /**\n * An icon placed before the label: an icon name, or an explicit render\n * (`{ src: '/logo.svg' }`, `{ component }`…). A string is always a name.\n */\n icon?: IconSource\n}\n\ninterface BreadcrumbProps {\n /** The segments of the trail, ordered from the most general down to the deepest. */\n items: BreadcrumbItem[]\n /**\n * The name screen readers announce for this navigation. It falls back to the\n * wording of the DS dictionary, in the current language.\n */\n label?: string\n /** The address of the page being displayed. */\n currentPath?: string\n /**\n * The icon drawn between two segments: an icon name, or an explicit render,\n * exactly like an item's `icon`. It is mirrored in a right-to-left page.\n */\n separatorIcon?: IconSource\n /**\n * The length past which the trail folds: only the first segment, an \"…\" button and the last\n * two remain, the button opening a menu that lists the hidden segments alone.\n */\n maxItems?: number\n /**\n * The name screen readers announce for the \"…\" button. It falls back to the\n * wording of the DS dictionary.\n */\n ellipsisLabel?: string\n}\n\nconst props = withDefaults(defineProps<BreadcrumbProps>(), {\n label: undefined,\n currentPath: undefined,\n separatorIcon: () => chevronRightIcon,\n maxItems: undefined,\n ellipsisLabel: undefined,\n})\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.breadcrumb.label)\nconst resolvedEllipsisLabel = computed(() => props.ellipsisLabel ?? m.value.breadcrumb.ellipsis)\n\n/**\n * Drops the query, the hash and a trailing slash, so that `/docs`, `/docs/` and a router's full\n * path `/docs?tab=2#intro` compare as the same page; the root `/` is left alone.\n */\nfunction normalize(path: string): string {\n const bare = path.replace(/[?#].*$/, '')\n return bare.length > 1 && bare.endsWith('/') ? bare.slice(0, -1) : bare\n}\n\nconst normalizedCurrent = computed(() =>\n props.currentPath === undefined ? undefined : normalize(props.currentPath),\n)\n\n// @a11y\n// This is what feeds `aria-current=\"page\"`, the only marker telling assistive technology\n// where the trail ends, the folded segments of the menu included.\nfunction isCurrent(item: BreadcrumbItem): boolean {\n return normalizedCurrent.value !== undefined && normalize(item.href) === normalizedCurrent.value\n}\n\nconst truncated = computed(\n () => props.maxItems !== undefined && props.items.length > Math.max(props.maxItems, 3),\n)\n/** The segments folded into the menu: everything between the first and the last two. */\nconst hiddenItems = computed(() => (truncated.value ? props.items.slice(1, -2) : []))\n/**\n * The segments actually rendered in the list; when the trail is folded, the first one followed\n * by the last two.\n */\nconst visibleItems = computed(() =>\n truncated.value ? [props.items[0] as BreadcrumbItem, ...props.items.slice(-2)] : props.items,\n)\n</script>\n\n<template>\n <nav class=\"v-breadcrumb\" :aria-label=\"ariaLabel\">\n <ol class=\"v-breadcrumb-list\">\n <template v-for=\"(item, index) in visibleItems\" :key=\"item.href\">\n <li v-if=\"truncated && index === 1\" class=\"v-breadcrumb-item v-breadcrumb-ellipsis\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <VMenu>\n <template #trigger=\"{ triggerProps }\">\n <VIconButton\n size=\"sm\"\n :label=\"resolvedEllipsisLabel\"\n :icon=\"moreHorizIcon\"\n v-bind=\"triggerProps\"\n />\n </template>\n <VMenuItem\n v-for=\"hidden in hiddenItems\"\n :key=\"hidden.href\"\n :href=\"hidden.href\"\n :label=\"hidden.label\"\n :icon-start=\"hidden.icon\"\n :selected=\"isCurrent(hidden)\"\n :aria-current=\"isCurrent(hidden) ? 'page' : undefined\"\n />\n </VMenu>\n </li>\n <li class=\"v-breadcrumb-item\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <a\n class=\"v-breadcrumb-link\"\n :href=\"item.href\"\n :aria-current=\"isCurrent(item) ? 'page' : undefined\"\n >\n <VIcon v-if=\"item.icon\" v-bind=\"iconProps(item.icon)\" />\n {{ item.label }}\n </a>\n </li>\n </template>\n </ol>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n /* The icon context is set here rather than through `.v-control`, which is the usual\n route: a trail has no `size` prop and no height to speak of, so the size scale would\n bring a table of five steps to pick one value from. */\n .v-breadcrumb {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n }\n\n .v-breadcrumb-list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--vectis-space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-body-md-size);\n }\n\n .v-breadcrumb-item {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n }\n\n /*\n * Every item renders its own leading separator and the first one is hidden here, which keeps\n * the template free of an index test. Delete this rule and the trail opens on a stray\n * chevron; both child combinators are load-bearing too, so wrapping an item or the list in\n * anything puts that chevron straight back.\n */\n .v-breadcrumb-list > .v-breadcrumb-item:first-child > .v-breadcrumb-separator {\n display: none;\n }\n\n .v-breadcrumb-separator {\n color: var(--vectis-color-text-subtle);\n }\n\n /* The corner is only ever seen on the focus ring, which follows it. It is the control\n radius capped at half a line, the row recipe of VSideNavigationItem with the line\n standing in for a control height the link does not have: a label that wraps keeps\n the corner of a one-line one under a pill override. */\n .v-breadcrumb-link {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-1);\n color: var(--vectis-color-text-muted);\n text-decoration: none;\n border-radius: min(var(--vectis-radius-interactive), 0.5lh);\n transition: color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-breadcrumb-link:hover {\n color: var(--vectis-color-text);\n text-decoration: underline;\n }\n\n .v-breadcrumb-link:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-breadcrumb-link[aria-current='page'] {\n color: var(--vectis-color-text);\n font-weight: var(--vectis-text-label-weight);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-breadcrumb-link {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VBreadcrumb.js","names":["_sfc_main","VBreadcrumb_vue_vue_type_script_setup_true_lang_default","VBreadcrumb_default"],"sources":["../../../src/components/VBreadcrumb/VBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Mark the matching link aria-current without disabling it. CSS hides the first separator so\n * SSR needs no child registry.\n */\n\nimport { computed } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport { more_horiz as moreHorizIcon } from '../VIcon/icons/more_horiz'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\nexport interface BreadcrumbItem {\n /** The text shown for this segment. */\n label: string\n /**\n * Where the segment leads. It is also the value compared with `currentPath` to\n * decide which segment is the current page.\n */\n href: string\n /**\n * An icon placed before the label: an icon name, or an explicit render\n * (`{ src: '/logo.svg' }`, `{ component }`…). A string is always a name.\n */\n icon?: IconSource\n}\n\ninterface BreadcrumbProps {\n /** The segments of the trail, ordered from the most general down to the deepest. */\n items: BreadcrumbItem[]\n /**\n * The name screen readers announce for this navigation. It falls back to the\n * wording of the DS dictionary, in the current language.\n */\n label?: string\n /** The address of the page being displayed. */\n currentPath?: string\n /**\n * The icon drawn between two segments: an icon name, or an explicit render,\n * exactly like an item's `icon`. It is mirrored in a right-to-left page.\n */\n separatorIcon?: IconSource\n /**\n * The length past which the trail folds: only the first segment, an \"…\" button and the last\n * two remain, the button opening a menu that lists the hidden segments alone.\n */\n maxItems?: number\n /**\n * The name screen readers announce for the \"…\" button. It falls back to the\n * wording of the DS dictionary.\n */\n ellipsisLabel?: string\n}\n\nconst props = withDefaults(defineProps<BreadcrumbProps>(), {\n label: undefined,\n currentPath: undefined,\n separatorIcon: () => chevronRightIcon,\n maxItems: undefined,\n ellipsisLabel: undefined,\n})\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.breadcrumb.label)\nconst resolvedEllipsisLabel = computed(() => props.ellipsisLabel ?? m.value.breadcrumb.ellipsis)\n\n/**\n * Drops the query, the hash and a trailing slash, so that `/docs`, `/docs/` and a router's full\n * path `/docs?tab=2#intro` compare as the same page; the root `/` is left alone.\n */\nfunction normalize(path: string): string {\n const bare = path.replace(/[?#].*$/, '')\n return bare.length > 1 && bare.endsWith('/') ? bare.slice(0, -1) : bare\n}\n\nconst normalizedCurrent = computed(() =>\n props.currentPath === undefined ? undefined : normalize(props.currentPath),\n)\n\n// @a11y\n// This is what feeds `aria-current=\"page\"`, the only marker telling assistive technology\n// where the trail ends, the folded segments of the menu included.\nfunction isCurrent(item: BreadcrumbItem): boolean {\n return normalizedCurrent.value !== undefined && normalize(item.href) === normalizedCurrent.value\n}\n\nconst truncated = computed(\n () => props.maxItems !== undefined && props.items.length > Math.max(props.maxItems, 3),\n)\n/** The segments folded into the menu: everything between the first and the last two. */\nconst hiddenItems = computed(() => (truncated.value ? props.items.slice(1, -2) : []))\n/**\n * The segments actually rendered in the list; when the trail is folded, the first one followed\n * by the last two.\n */\nconst visibleItems = computed(() =>\n truncated.value ? [props.items[0] as BreadcrumbItem, ...props.items.slice(-2)] : props.items,\n)\n</script>\n\n<template>\n <nav class=\"v-breadcrumb\" :aria-label=\"ariaLabel\">\n <ol class=\"v-breadcrumb-list\">\n <template v-for=\"(item, index) in visibleItems\" :key=\"item.href\">\n <li v-if=\"truncated && index === 1\" class=\"v-breadcrumb-item v-breadcrumb-ellipsis\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <VMenu>\n <template #trigger=\"{ triggerProps }\">\n <VIconButton\n size=\"sm\"\n :label=\"resolvedEllipsisLabel\"\n :icon=\"moreHorizIcon\"\n v-bind=\"triggerProps\"\n />\n </template>\n <VMenuItem\n v-for=\"hidden in hiddenItems\"\n :key=\"hidden.href\"\n :href=\"hidden.href\"\n :label=\"hidden.label\"\n :icon-start=\"hidden.icon\"\n :selected=\"isCurrent(hidden)\"\n :aria-current=\"isCurrent(hidden) ? 'page' : undefined\"\n />\n </VMenu>\n </li>\n <li class=\"v-breadcrumb-item\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <a\n class=\"v-breadcrumb-link\"\n :href=\"item.href\"\n :aria-current=\"isCurrent(item) ? 'page' : undefined\"\n >\n <VIcon v-if=\"item.icon\" v-bind=\"iconProps(item.icon)\" />\n {{ item.label }}\n </a>\n </li>\n </template>\n </ol>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n /* The icon context is set here rather than through `.v-control`, which is the usual\n route: a trail has no `size` prop and no height to speak of, so the size scale would\n bring a table of five steps to pick one value from. */\n .v-breadcrumb {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n }\n\n .v-breadcrumb-list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--vectis-space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-body-md-size);\n }\n\n .v-breadcrumb-item {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n }\n\n /*\n * Every item renders its own leading separator and the first one is hidden here, which keeps\n * the template free of an index test. Delete this rule and the trail opens on a stray\n * chevron; both child combinators are load-bearing too, so wrapping an item or the list in\n * anything puts that chevron straight back.\n */\n .v-breadcrumb-list > .v-breadcrumb-item:first-child > .v-breadcrumb-separator {\n display: none;\n }\n\n .v-breadcrumb-separator {\n color: var(--vectis-color-text-subtle);\n }\n\n /* The corner is only ever seen on the focus ring, which follows it. It is the control\n radius capped at half a line, the row recipe of VSideNavigationItem with the line\n standing in for a control height the link does not have: a label that wraps keeps\n the corner of a one-line one under a pill override. */\n .v-breadcrumb-link {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-1);\n color: var(--vectis-color-text-muted);\n text-decoration: none;\n border-radius: min(var(--vectis-radius-interactive), 0.5lh);\n transition: color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-breadcrumb-link:hover {\n color: var(--vectis-color-text);\n text-decoration: underline;\n }\n\n .v-breadcrumb-link:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-breadcrumb-link[aria-current='page'] {\n color: var(--vectis-color-text);\n font-weight: var(--vectis-text-label-weight);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-breadcrumb-link {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"VBreadcrumb.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VBreadcrumb/VBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Mark the matching link aria-current without disabling it. CSS hides the first separator so\n * SSR needs no child registry.\n */\n\nimport { computed } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport { more_horiz as moreHorizIcon } from '../VIcon/icons/more_horiz'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\nexport interface BreadcrumbItem {\n /** The text shown for this segment. */\n label: string\n /**\n * Where the segment leads. It is also the value compared with `currentPath` to\n * decide which segment is the current page.\n */\n href: string\n /**\n * An icon placed before the label: an icon name, or an explicit render\n * (`{ src: '/logo.svg' }`, `{ component }`…). A string is always a name.\n */\n icon?: IconSource\n}\n\ninterface BreadcrumbProps {\n /** The segments of the trail, ordered from the most general down to the deepest. */\n items: BreadcrumbItem[]\n /**\n * The name screen readers announce for this navigation. It falls back to the\n * wording of the DS dictionary, in the current language.\n */\n label?: string\n /** The address of the page being displayed. */\n currentPath?: string\n /**\n * The icon drawn between two segments: an icon name, or an explicit render,\n * exactly like an item's `icon`. It is mirrored in a right-to-left page.\n */\n separatorIcon?: IconSource\n /**\n * The length past which the trail folds: only the first segment, an \"…\" button and the last\n * two remain, the button opening a menu that lists the hidden segments alone.\n */\n maxItems?: number\n /**\n * The name screen readers announce for the \"…\" button. It falls back to the\n * wording of the DS dictionary.\n */\n ellipsisLabel?: string\n}\n\nconst props = withDefaults(defineProps<BreadcrumbProps>(), {\n label: undefined,\n currentPath: undefined,\n separatorIcon: () => chevronRightIcon,\n maxItems: undefined,\n ellipsisLabel: undefined,\n})\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.breadcrumb.label)\nconst resolvedEllipsisLabel = computed(() => props.ellipsisLabel ?? m.value.breadcrumb.ellipsis)\n\n/**\n * Drops the query, the hash and a trailing slash, so that `/docs`, `/docs/` and a router's full\n * path `/docs?tab=2#intro` compare as the same page; the root `/` is left alone.\n */\nfunction normalize(path: string): string {\n const bare = path.replace(/[?#].*$/, '')\n return bare.length > 1 && bare.endsWith('/') ? bare.slice(0, -1) : bare\n}\n\nconst normalizedCurrent = computed(() =>\n props.currentPath === undefined ? undefined : normalize(props.currentPath),\n)\n\n// @a11y\n// This is what feeds `aria-current=\"page\"`, the only marker telling assistive technology\n// where the trail ends, the folded segments of the menu included.\nfunction isCurrent(item: BreadcrumbItem): boolean {\n return normalizedCurrent.value !== undefined && normalize(item.href) === normalizedCurrent.value\n}\n\nconst truncated = computed(\n () => props.maxItems !== undefined && props.items.length > Math.max(props.maxItems, 3),\n)\n/** The segments folded into the menu: everything between the first and the last two. */\nconst hiddenItems = computed(() => (truncated.value ? props.items.slice(1, -2) : []))\n/**\n * The segments actually rendered in the list; when the trail is folded, the first one followed\n * by the last two.\n */\nconst visibleItems = computed(() =>\n truncated.value ? [props.items[0] as BreadcrumbItem, ...props.items.slice(-2)] : props.items,\n)\n</script>\n\n<template>\n <nav class=\"v-breadcrumb\" :aria-label=\"ariaLabel\">\n <ol class=\"v-breadcrumb-list\">\n <template v-for=\"(item, index) in visibleItems\" :key=\"item.href\">\n <li v-if=\"truncated && index === 1\" class=\"v-breadcrumb-item v-breadcrumb-ellipsis\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <VMenu>\n <template #trigger=\"{ triggerProps }\">\n <VIconButton\n size=\"sm\"\n :label=\"resolvedEllipsisLabel\"\n :icon=\"moreHorizIcon\"\n v-bind=\"triggerProps\"\n />\n </template>\n <VMenuItem\n v-for=\"hidden in hiddenItems\"\n :key=\"hidden.href\"\n :href=\"hidden.href\"\n :label=\"hidden.label\"\n :icon-start=\"hidden.icon\"\n :selected=\"isCurrent(hidden)\"\n :aria-current=\"isCurrent(hidden) ? 'page' : undefined\"\n />\n </VMenu>\n </li>\n <li class=\"v-breadcrumb-item\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <a\n class=\"v-breadcrumb-link\"\n :href=\"item.href\"\n :aria-current=\"isCurrent(item) ? 'page' : undefined\"\n >\n <VIcon v-if=\"item.icon\" v-bind=\"iconProps(item.icon)\" />\n {{ item.label }}\n </a>\n </li>\n </template>\n </ol>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n /* The icon context is set here rather than through `.v-control`, which is the usual\n route: a trail has no `size` prop and no height to speak of, so the size scale would\n bring a table of five steps to pick one value from. */\n .v-breadcrumb {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n }\n\n .v-breadcrumb-list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--vectis-space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-body-md-size);\n }\n\n .v-breadcrumb-item {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n }\n\n /*\n * Every item renders its own leading separator and the first one is hidden here, which keeps\n * the template free of an index test. Delete this rule and the trail opens on a stray\n * chevron; both child combinators are load-bearing too, so wrapping an item or the list in\n * anything puts that chevron straight back.\n */\n .v-breadcrumb-list > .v-breadcrumb-item:first-child > .v-breadcrumb-separator {\n display: none;\n }\n\n .v-breadcrumb-separator {\n color: var(--vectis-color-text-subtle);\n }\n\n /* The corner is only ever seen on the focus ring, which follows it. It is the control\n radius capped at half a line, the row recipe of VSideNavigationItem with the line\n standing in for a control height the link does not have: a label that wraps keeps\n the corner of a one-line one under a pill override. */\n .v-breadcrumb-link {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-1);\n color: var(--vectis-color-text-muted);\n text-decoration: none;\n border-radius: min(var(--vectis-radius-interactive), 0.5lh);\n transition: color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-breadcrumb-link:hover {\n color: var(--vectis-color-text);\n text-decoration: underline;\n }\n\n .v-breadcrumb-link:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-breadcrumb-link[aria-current='page'] {\n color: var(--vectis-color-text);\n font-weight: var(--vectis-text-label-weight);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-breadcrumb-link {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EA+DA,IAAM,IAAQ,GAQR,IAAI,EAAY,GAChB,IAAY,QAAmB,EAAM,SAAS,EAAE,MAAM,WAAW,KAAK,GACtE,IAAwB,QAAe,EAAM,iBAAiB,EAAE,MAAM,WAAW,QAAQ;EAM/F,SAAS,EAAU,GAAsB;GACvC,IAAM,IAAO,EAAK,QAAQ,WAAW,EAAE;GACvC,OAAO,EAAK,SAAS,KAAK,EAAK,SAAS,GAAG,IAAI,EAAK,MAAM,GAAG,EAAE,IAAI;EACrE;EAEA,IAAM,IAAoB,QACxB,EAAM,gBAAgB,KAAA,IAAY,KAAA,IAAY,EAAU,EAAM,WAAW,CAC3E;EAKA,SAAS,EAAU,GAA+B;GAChD,OAAO,EAAkB,UAAU,KAAA,KAAa,EAAU,EAAK,IAAI,MAAM,EAAkB;EAC7F;EAEA,IAAM,IAAY,QACV,EAAM,aAAa,KAAA,KAAa,EAAM,MAAM,SAAS,KAAK,IAAI,EAAM,UAAU,CAAC,CACvF,GAEM,IAAc,QAAgB,EAAU,QAAQ,EAAM,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,CAAE,GAK9E,IAAe,QACnB,EAAU,QAAQ,CAAC,EAAM,MAAM,IAAsB,GAAG,EAAM,MAAM,MAAM,EAAE,CAAC,IAAI,EAAM,KACzF;yBAIE,EAsCM,OAAA;GAtCD,OAAM;GAAgB,cAAY,EAAA,CAAA;MACrC,EAoCK,MApCL,GAoCK,EAAA,EAAA,EAAA,GAnCH,EAkCW,GAAA,MAAA,EAlCuB,EAAA,QAAhB,GAAM,wBAA8B,EAAK,KAAA,GAAA,CAC/C,EAAA,SAAa,MAAK,KAAA,EAAA,GAA5B,EAqBK,MArBL,GAqBK,CApBH,EAAmF,GAAnF,EAAmF,EAA5E,OAAM,yBAAwB,GAAA,EAAA,SAAA,GAAA,GAAS,EAAA,CAAA,CAAS,CAAC,EAAA,aAAa,GAAA,EAAG,UAAA,GAAQ,CAAA,GAAA,MAAA,EAAA,GAChF,EAkBQ,GAAA,MAAA;GAjBK,SAAO,GAMd,EANkB,sBAAY,CAChC,EAKE,GALF,EAKE;IAJA,MAAK;IACJ,OAAO,EAAA;IACP,MAAM,EAAA,CAAA;uBACC,CAAY,GAAA,MAAA,IAAA,CAAA,SAAA,MAAA,CAAA,CAAA,CAAA;oBAIO,EAAA,EAAA,EAAA,GAD/B,EAQE,GAAA,MAAA,EAPiB,EAAA,QAAV,YADT,EAQE,GAAA;IANC,KAAK,EAAO;IACZ,MAAM,EAAO;IACb,OAAO,EAAO;IACd,cAAY,EAAO;IACnB,UAAU,EAAU,CAAM;IAC1B,gBAAc,EAAU,CAAM,IAAA,SAAa,KAAA;;;;;;;;;qBAIlD,EAUK,MAVL,GAUK,CATH,EAAmF,GAAnF,EAAmF,EAA5E,OAAM,yBAAwB,GAAA,EAAA,SAAA,GAAA,GAAS,EAAA,CAAA,CAAS,CAAC,EAAA,aAAa,GAAA,EAAG,UAAA,GAAQ,CAAA,GAAA,MAAA,EAAA,GAChF,EAOI,KAAA;GANF,OAAM;GACL,MAAM,EAAK;GACX,gBAAc,EAAU,CAAI,IAAA,SAAa,KAAA;MAE7B,EAAK,QAAA,EAAA,GAAlB,EAAwD,GAAxD,EAAwD;;;KAAxB,EAAA,CAAA,CAAS,CAAC,EAAK,IAAI,CAAA,GAAA,MAAA,EAAA,KAAA,EAAA,IAAA,EAAA,GAAA,EAAK,MACxD,EAAG,EAAK,KAAK,GAAA,CAAA,CAAA,GAAA,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA"}
1
+ {"version":3,"file":"VBreadcrumb.vue_vue_type_script_setup_true_lang.js","names":["chevronRightIcon","_openBlock","_createElementBlock","_unref","_createElementVNode","_Fragment","_renderList","_createVNode","VIcon","_mergeProps","VMenu","_withCtx","VIconButton","moreHorizIcon","_createBlock","VMenuItem","_createCommentVNode","_createTextVNode","_toDisplayString","VIcon_default","VIconButton_default","VMenu_default","VMenuItem_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","VBreadcrumb_vue_vue_type_script_setup_true_lang_default","chevron_right","props","__props","m","useMessages","ariaLabel","useAriaLabel","resolvedEllipsisLabel","computed","normalize","bare","path","normalizedCurrent","isCurrent","item","truncated","hiddenItems","visibleItems","openBlock","createElementBlock","unref","createElementVNode","Fragment","renderList","index","createVNode","mergeProps","iconProps","withCtx","more_horiz","triggerProps","createBlock","hidden","createCommentVNode","createTextVNode","toDisplayString"],"sources":["../../../src/components/VBreadcrumb/VBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @ssr @core\n/**\n * Mark the matching link aria-current without disabling it. CSS hides the first separator so\n * SSR needs no child registry.\n */\n\nimport { computed } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport { more_horiz as moreHorizIcon } from '../VIcon/icons/more_horiz'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\nexport interface BreadcrumbItem {\n /** The text shown for this segment. */\n label: string\n /**\n * Where the segment leads. It is also the value compared with `currentPath` to\n * decide which segment is the current page.\n */\n href: string\n /**\n * An icon placed before the label: an icon name, or an explicit render\n * (`{ src: '/logo.svg' }`, `{ component }`…). A string is always a name.\n */\n icon?: IconSource\n}\n\ninterface BreadcrumbProps {\n /** The segments of the trail, ordered from the most general down to the deepest. */\n items: BreadcrumbItem[]\n /**\n * The name screen readers announce for this navigation. It falls back to the\n * wording of the DS dictionary, in the current language.\n */\n label?: string\n /** The address of the page being displayed. */\n currentPath?: string\n /**\n * The icon drawn between two segments: an icon name, or an explicit render,\n * exactly like an item's `icon`. It is mirrored in a right-to-left page.\n */\n separatorIcon?: IconSource\n /**\n * The length past which the trail folds: only the first segment, an \"…\" button and the last\n * two remain, the button opening a menu that lists the hidden segments alone.\n */\n maxItems?: number\n /**\n * The name screen readers announce for the \"…\" button. It falls back to the\n * wording of the DS dictionary.\n */\n ellipsisLabel?: string\n}\n\nconst props = withDefaults(defineProps<BreadcrumbProps>(), {\n label: undefined,\n currentPath: undefined,\n separatorIcon: () => chevronRightIcon,\n maxItems: undefined,\n ellipsisLabel: undefined,\n})\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.breadcrumb.label)\nconst resolvedEllipsisLabel = computed(() => props.ellipsisLabel ?? m.value.breadcrumb.ellipsis)\n\n/**\n * Drops the query, the hash and a trailing slash, so that `/docs`, `/docs/` and a router's full\n * path `/docs?tab=2#intro` compare as the same page; the root `/` is left alone.\n */\nfunction normalize(path: string): string {\n const bare = path.replace(/[?#].*$/, '')\n return bare.length > 1 && bare.endsWith('/') ? bare.slice(0, -1) : bare\n}\n\nconst normalizedCurrent = computed(() =>\n props.currentPath === undefined ? undefined : normalize(props.currentPath),\n)\n\n// @a11y\n// This is what feeds `aria-current=\"page\"`, the only marker telling assistive technology\n// where the trail ends, the folded segments of the menu included.\nfunction isCurrent(item: BreadcrumbItem): boolean {\n return normalizedCurrent.value !== undefined && normalize(item.href) === normalizedCurrent.value\n}\n\nconst truncated = computed(\n () => props.maxItems !== undefined && props.items.length > Math.max(props.maxItems, 3),\n)\n/** The segments folded into the menu: everything between the first and the last two. */\nconst hiddenItems = computed(() => (truncated.value ? props.items.slice(1, -2) : []))\n/**\n * The segments actually rendered in the list; when the trail is folded, the first one followed\n * by the last two.\n */\nconst visibleItems = computed(() =>\n truncated.value ? [props.items[0] as BreadcrumbItem, ...props.items.slice(-2)] : props.items,\n)\n</script>\n\n<template>\n <nav class=\"v-breadcrumb\" :aria-label=\"ariaLabel\">\n <ol class=\"v-breadcrumb-list\">\n <template v-for=\"(item, index) in visibleItems\" :key=\"item.href\">\n <li v-if=\"truncated && index === 1\" class=\"v-breadcrumb-item v-breadcrumb-ellipsis\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <VMenu>\n <template #trigger=\"{ triggerProps }\">\n <VIconButton\n size=\"sm\"\n :label=\"resolvedEllipsisLabel\"\n :icon=\"moreHorizIcon\"\n v-bind=\"triggerProps\"\n />\n </template>\n <VMenuItem\n v-for=\"hidden in hiddenItems\"\n :key=\"hidden.href\"\n :href=\"hidden.href\"\n :label=\"hidden.label\"\n :icon-start=\"hidden.icon\"\n :selected=\"isCurrent(hidden)\"\n :aria-current=\"isCurrent(hidden) ? 'page' : undefined\"\n />\n </VMenu>\n </li>\n <li class=\"v-breadcrumb-item\">\n <VIcon class=\"v-breadcrumb-separator\" v-bind=\"iconProps(separatorIcon)\" mirrored />\n <a\n class=\"v-breadcrumb-link\"\n :href=\"item.href\"\n :aria-current=\"isCurrent(item) ? 'page' : undefined\"\n >\n <VIcon v-if=\"item.icon\" v-bind=\"iconProps(item.icon)\" />\n {{ item.label }}\n </a>\n </li>\n </template>\n </ol>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n /* The icon context is set here rather than through `.v-control`, which is the usual\n route: a trail has no `size` prop and no height to speak of, so the size scale would\n bring a table of five steps to pick one value from. */\n .v-breadcrumb {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n --vectis-icon-opsz: 20;\n }\n\n .v-breadcrumb-list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--vectis-space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-body-md-size);\n }\n\n .v-breadcrumb-item {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n }\n\n /*\n * Every item renders its own leading separator and the first one is hidden here, which keeps\n * the template free of an index test. Delete this rule and the trail opens on a stray\n * chevron; both child combinators are load-bearing too, so wrapping an item or the list in\n * anything puts that chevron straight back.\n */\n .v-breadcrumb-list > .v-breadcrumb-item:first-child > .v-breadcrumb-separator {\n display: none;\n }\n\n .v-breadcrumb-separator {\n color: var(--vectis-color-text-subtle);\n }\n\n /* The corner is only ever seen on the focus ring, which follows it. It is the control\n radius capped at half a line, the row recipe of VSideNavigationItem with the line\n standing in for a control height the link does not have: a label that wraps keeps\n the corner of a one-line one under a pill override. */\n .v-breadcrumb-link {\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-1);\n color: var(--vectis-color-text-muted);\n text-decoration: none;\n border-radius: min(var(--vectis-radius-interactive), 0.5lh);\n transition: color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-breadcrumb-link:hover {\n color: var(--vectis-color-text);\n text-decoration: underline;\n }\n\n .v-breadcrumb-link:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-breadcrumb-link[aria-current='page'] {\n color: var(--vectis-color-text);\n font-weight: var(--vectis-text-label-weight);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-breadcrumb-link {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EA+DA,IAAM8B,IAAQC,GAQRC,IAAIC,EAAY,GAChBC,IAAYC,QAAmBL,EAAM,SAASE,EAAE,MAAM,WAAW,KAAK,GACtEI,IAAwBC,QAAeP,EAAM,iBAAiBE,EAAE,MAAM,WAAW,QAAQ;EAM/F,SAASM,EAAU,GAAsB;GACvC,IAAMC,IAAOC,EAAK,QAAQ,WAAW,EAAE;GACvC,OAAOD,EAAK,SAAS,KAAKA,EAAK,SAAS,GAAG,IAAIA,EAAK,MAAM,GAAG,EAAE,IAAIA;EACrE;EAEA,IAAME,IAAoBJ,QACxBP,EAAM,gBAAgB,KAAA,IAAY,KAAA,IAAYQ,EAAUR,EAAM,WAAW,CAC3E;EAKA,SAASY,EAAU,GAA+B;GAChD,OAAOD,EAAkB,UAAU,KAAA,KAAaH,EAAUK,EAAK,IAAI,MAAMF,EAAkB;EAC7F;EAEA,IAAMG,IAAYP,QACVP,EAAM,aAAa,KAAA,KAAaA,EAAM,MAAM,SAAS,KAAK,IAAIA,EAAM,UAAU,CAAC,CACvF,GAEMe,IAAcR,QAAgBO,EAAU,QAAQd,EAAM,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,CAAE,GAK9EgB,IAAeT,QACnBO,EAAU,QAAQ,CAACd,EAAM,MAAM,IAAsB,GAAGA,EAAM,MAAM,MAAM,EAAE,CAAC,IAAIA,EAAM,KACzF;oBAIE7B,EAAA,GAAAC,EAsCM,OAAA;GAtCD,OAAM;GAAgB,cAAYC,EAAA+B,CAAA;EACrC9B,GAAAA,CAAAA,EAoCK,MApCLoB,GAoCK,EAnCHvB,EAAA,EAAA,GAAAC,EAkCWG,GAAA,MAAAC,EAlCuBwC,EAAA,QAAhB,GAAM,OAA8BC,EAAA,GAAAC,EAAAG,GAAA,EAAA,KAAAR,EAAK,KAAA,GAAA,CAC/CC,EAAA,SAAaS,MAAK,KAA5BpD,EAAA,GAAAC,EAqBK,MArBLuB,GAqBK,CApBHlB,EAAmFC,GAAnFC,EAAmF,EAA5E,OAAM,yBAAwB,GAAA,EAAA,SAAA,GAAA,GAASN,EAAAqD,CAAA,CAAS,CAACzB,EAAA,aAAa,GAAA,EAAG,UAAA,GAAQ,CAAA,GAAA,MAAA,EAAA,GAChFxB,EAkBQG,GAAA,MAAA;GAjBK,SAAOC,GAMd,EANkB,sBAAY,CAChCJ,EAKEK,GALFH,EAKE;IAJA,MAAK;IACJ,OAAO2B,EAAA;IACP,MAAMjC,EAAAU,CAAA;GACC,GAAA,EAAA,SAAA,GAAA,GAAA8C,CAAY,GAAA,MAAA,IAAA,CAAA,SAAA,MAAA,CAAA,CAAA,CAAA;GAItB,SAAAhD,QAA6B,EAD/BV,EAAA,EAAA,GAAAC,EAQEG,GAAA,MAAAC,EAPiBuC,EAAA,QAAV,OADT5C,EAAA,GAAAa,EAQEC,GAAA;IANC,KAAK8C,EAAO;IACZ,MAAMA,EAAO;IACb,OAAOA,EAAO;IACd,cAAYA,EAAO;IACnB,UAAUnB,EAAUmB,CAAM;IAC1B,gBAAcnB,EAAUmB,CAAM,IAAA,SAAa,KAAA;;;;;;;;;EAIlDzD,CAAAA,CAAAA,CAAAA,KAAAA,EAAAA,IAAAA,EAAAA,GAAAA,EAUK,MAVLsB,GAUK,CATHnB,EAAmFC,GAAnFC,EAAmF,EAA5E,OAAM,yBAAwB,GAAA,EAAA,SAAA,GAAA,GAASN,EAAAqD,CAAA,CAAS,CAACzB,EAAA,aAAa,GAAA,EAAG,UAAA,GAAQ,CAAA,GAAA,MAAA,EAAA,GAChF3B,EAOI,KAAA;GANF,OAAM;GACL,MAAMuC,EAAK;GACX,gBAAcD,EAAUC,CAAI,IAAA,SAAa,KAAA;EAE7B,GAAA,CAAAA,EAAK,QAAlB1C,EAAA,GAAAa,EAAwDN,GAAxDC,EAAwD;;;EAAxB,GAAAN,EAAAqD,CAAA,CAAS,CAACb,EAAK,IAAI,CAAA,GAAA,MAAA,EAAA,KAAAmB,EAAA,IAAA,EAAA,GAAK7C,EAAA,MACxDC,EAAGyB,EAAK,KAAK,GAAA,CAAA,CAAA,GAAA,GAAAhB,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA"}
@@ -29,11 +29,6 @@ interface ButtonProps {
29
29
  * Inside a VButtonGroup the group's own size wins over this one.
30
30
  */
31
31
  size?: ButtonSize;
32
- /**
33
- * Takes 4px off the height, leaving the padding, the text and the icons as they
34
- * are. Inside a VButtonGroup the group's own value wins over this one.
35
- */
36
- compact?: boolean;
37
32
  /**
38
33
  * Stretches the button to the whole inline size of its parent, instead of leaving it only as
39
34
  * wide as its content.
@@ -85,7 +80,6 @@ declare const __VLS_base: import('vue').DefineComponent<ButtonProps, {}, {}, {},
85
80
  type: "button" | "reset" | "submit";
86
81
  variant: ButtonVariant;
87
82
  tone: ButtonTone;
88
- compact: boolean;
89
83
  href: string;
90
84
  iconStart: IconSource;
91
85
  iconEnd: IconSource;
@@ -1 +1 @@
1
- {"version":3,"file":"VButton.js","names":[],"sources":["../../../src/components/VButton/VButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * Native buttons own activation and disabling. Links use useInertLink because anchors have no\n * disabled state; group shape overrides preserve individual tones.\n */\nimport { computed, inject, useAttrs } from 'vue'\nimport type { ButtonHTMLAttributes } from 'vue'\n\nimport { buttonGroupKey } from './context'\n\nimport { useControlShape } from '../../composables/useControlShape'\nimport { useInertLink } from '../../composables/useInertLink'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\nimport VSpinner from '../VSpinner/VSpinner.vue'\n\n/** How much visual weight the button carries. */\nexport type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'soft'\n/** What the action means, in colour. */\nexport type ButtonTone = 'accent' | 'neutral' | 'danger'\n/** The height of the button, from the scale every control shares. */\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\ninterface ButtonProps {\n /**\n * How much visual weight the button carries: `solid` is filled with the tone, `soft` uses a\n * tinted background, `outline` keeps only a border, and `ghost` shows nothing until it is\n * hovered.\n */\n variant?: ButtonVariant\n /**\n * What the action means: `accent` for the ordinary one, `neutral` for a secondary one,\n * `danger` for one that destroys something. Left out inside a VButtonGroup it takes the\n * group's tone, which is the point of not defaulting it here; on its own it is `accent`.\n */\n tone?: ButtonTone\n /**\n * Raises the button off the page: a shadow that grows on hover and settles back when pressed,\n * whatever the variant. Inside a VButtonGroup the group's own value wins over this one.\n */\n elevated?: boolean\n /**\n * The height of the button, taken from the size scale shared by every control.\n * Inside a VButtonGroup the group's own size wins over this one.\n */\n size?: ButtonSize\n /**\n * Takes 4px off the height, leaving the padding, the text and the icons as they\n * are. Inside a VButtonGroup the group's own value wins over this one.\n */\n compact?: boolean\n /**\n * Stretches the button to the whole inline size of its parent, instead of leaving it only as\n * wide as its content.\n */\n fullWidth?: boolean\n /**\n * Turns the button into an `<a>` pointing at this address. A disabled or loading\n * link becomes inert: the address is dropped, so it can be neither focused nor\n * followed.\n */\n href?: string\n /** The native type of the button. It is ignored as soon as `href` makes it a link. */\n type?: ButtonHTMLAttributes['type']\n /**\n * Makes the button unusable: it stops responding, leaves the tab order and greys\n * out through the colour tokens.\n */\n disabled?: boolean\n /**\n * Shows a spinner, disables the button and announces it as busy. The spinner takes\n * the place of the start slot (`iconStart` / `#start`), so an icon and a spinner\n * are never displayed side by side.\n */\n loading?: boolean\n /** An icon before the label. The `#start` slot replaces it when both are given. */\n iconStart?: IconSource\n /** An icon after the label. The `#end` slot replaces it when both are given. */\n iconEnd?: IconSource\n /**\n * Renders `iconStart` and `iconEnd` in their filled form (the font's `FILL` axis).\n * It has no effect on the `#start`/`#end` slots, whose icons the consumer builds.\n */\n iconFilled?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n variant: 'solid',\n // The only one of the five with no default. `tone` is the prop a button keeps against its\n // group, so `undefined` has to stay distinguishable from an explicit `accent`, which would\n // otherwise silence the group for every button in the row.\n tone: undefined,\n elevated: false,\n size: 'md',\n compact: false,\n fullWidth: false,\n href: undefined,\n type: 'button',\n disabled: false,\n loading: false,\n iconStart: undefined,\n iconEnd: undefined,\n iconFilled: false,\n})\n\ndefineSlots<{\n /** The label of the button. */\n default(): unknown\n /**\n * Content placed before the label, usually an icon. Mark it `aria-hidden` when it\n * only repeats what the label already says.\n */\n start?(): unknown\n /** Content placed after the label. */\n end?(): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst attrs = useAttrs()\nconst group = inject(buttonGroupKey, null)\n\n// The shape of the segmented control belongs to the row: the group is read first, and a\n// group that named nothing hands the prop straight back. The tone goes the other way,\n// the button's own answer first (see context.ts).\nconst {\n size: resolvedSize,\n compact: resolvedCompact,\n disabled: resolvedDisabled,\n} = useControlShape<ButtonSize>(props, group)\nconst resolvedVariant = computed<ButtonVariant>(() => group?.variant ?? props.variant)\nconst resolvedElevated = computed(() => group?.elevated ?? props.elevated)\n// The tone goes the OTHER way, the button's own answer first: one action in a row can be\n// the destructive one, and the row has to be able to say so (see context.ts).\nconst resolvedTone = computed<ButtonTone>(() => props.tone ?? group?.tone ?? 'accent')\n\nconst isInert = computed(() => resolvedDisabled.value || props.loading)\nconst {\n isLink,\n isInertLink,\n linkHref,\n attrs: passedAttrs,\n} = useInertLink({\n href: () => props.href,\n inert: () => isInert.value,\n attrs: () => attrs,\n})\n</script>\n\n<template>\n <component\n :is=\"isLink ? 'a' : 'button'\"\n :aria-disabled=\"isInertLink ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"passedAttrs\"\n class=\"v-button v-control v-tone v-variant\"\n :href=\"linkHref\"\n :type=\"isLink ? undefined : type\"\n :disabled=\"isLink ? undefined : isInert\"\n :data-variant=\"resolvedVariant\"\n :data-tone=\"resolvedTone\"\n :data-elevated=\"resolvedElevated ? '' : undefined\"\n :data-size=\"resolvedSize\"\n :data-compact=\"resolvedCompact ? '' : undefined\"\n :data-full-width=\"fullWidth ? '' : undefined\"\n :data-loading=\"loading ? '' : undefined\"\n >\n <!-- The button already carries aria-busy, so the spinner is hidden from\n assistive technology: its own role=\"status\" would announce the same state a\n second time -->\n <span v-if=\"loading\" class=\"v-button-spinner\" aria-hidden=\"true\">\n <VSpinner />\n </span>\n <slot v-else name=\"start\">\n <VIcon v-if=\"iconStart\" v-bind=\"iconProps(iconStart)\" :filled=\"iconFilled\" />\n </slot>\n <slot />\n <slot name=\"end\">\n <VIcon v-if=\"iconEnd\" v-bind=\"iconProps(iconEnd)\" :filled=\"iconFilled\" />\n </slot>\n </component>\n</template>\n\n<style>\n@layer vectis.components {\n .v-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--control-gap);\n block-size: var(--control-height);\n padding-inline: var(--control-padding-inline);\n border: 1px solid transparent;\n border-radius: var(--vectis-radius-interactive);\n font-family: var(--vectis-text-family);\n font-size: var(--control-font-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n text-decoration: none;\n cursor: pointer;\n transition:\n background-color var(--vectis-duration-fast) var(--vectis-ease-default),\n border-color var(--vectis-duration-fast) var(--vectis-ease-default),\n color var(--vectis-duration-fast) var(--vectis-ease-default),\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /* An explicit display, rather than a width alone: an inline-level box sits on a line\n box, which would add the strut's descender under a button the consumer asked to\n fill its parent. Block-level, it measures the parent's content box exactly. */\n .v-button[data-full-width] {\n display: flex;\n inline-size: 100%;\n }\n\n /*\n * At (0,2,0) it beats this sheet's own padding by weight, and it is the only rule that may\n * touch that padding on an icon-only button. A consumer of VButton restyling the padding of\n * its own buttons at (0,2,0) from another sheet would tie with it, and the bundler would\n * decide: such a rule has to exclude `[data-icon-only]`.\n */\n .v-button[data-icon-only] {\n min-inline-size: var(--control-height);\n padding-inline: 0;\n }\n\n .v-button:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n /* Tone and variant recipes are shared; component-specific interaction states remain here. */\n\n .v-button[data-variant='solid']:hover:not(:disabled, [aria-disabled='true']) {\n background: var(--tone-bg-solid-hover);\n }\n\n .v-button[data-variant='solid']:active:not(:disabled, [aria-disabled='true']) {\n background: var(--tone-bg-solid-active);\n }\n\n /*\n * Nothing then arbitrates the background of a raised ghost by a one-step specificity margin,\n * so a declaration added to either set later cannot silently leak into the other case.\n */\n .v-button:is([data-variant='outline'], [data-variant='ghost']):not([data-elevated]):hover:not(\n :disabled,\n [aria-disabled='true']\n ) {\n background: var(--tone-bg-soft);\n }\n\n /* One step of tint, reached two ways: pressing a ghost or an outline, which already sit on\n the soft surface while hovered, and hovering a soft one. A selector list keeps each\n member's own weight, so merging them moves no arbitration: the outline/ghost half is\n still (0,5,0) after its hover, the soft half still (0,4,0) before its active. */\n .v-button:is([data-variant='outline'], [data-variant='ghost']):not([data-elevated]):active:not(\n :disabled,\n [aria-disabled='true']\n ),\n .v-button[data-variant='soft']:hover:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in oklab, var(--tone-bg-soft), var(--tone-text-tinted) 8%);\n }\n\n .v-button[data-variant='soft']:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in oklab, var(--tone-bg-soft), var(--tone-text-tinted) 14%);\n }\n\n /*\n * The `:is()` here is not decoration; it is what gives these rules a specificity of (0,3,0),\n * beating the (0,2,0) of the ghost and outline bases without depending on the order the rules\n * end up in.\n */\n .v-button[data-elevated] {\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-button[data-elevated]:is([data-variant='ghost'], [data-variant='outline']) {\n background: var(--vectis-color-surface-raised);\n }\n\n .v-button[data-elevated]:hover:not(:disabled, [aria-disabled='true']) {\n box-shadow: var(--vectis-shadow-md);\n }\n\n .v-button[data-elevated]:is([data-variant='ghost'], [data-variant='outline']):hover:not(\n :disabled,\n [aria-disabled='true']\n ) {\n background: color-mix(in oklab, var(--vectis-color-surface-raised), var(--tone-text-tinted) 8%);\n }\n\n .v-button[data-elevated]:active:not(:disabled, [aria-disabled='true']) {\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-button[data-elevated]:is([data-variant='ghost'], [data-variant='outline']):active:not(\n :disabled,\n [aria-disabled='true']\n ) {\n background: color-mix(\n in oklab,\n var(--vectis-color-surface-raised),\n var(--tone-text-tinted) 12%\n );\n }\n\n .v-button:is(:disabled, [aria-disabled='true']) {\n cursor: not-allowed;\n }\n\n .v-button[data-loading] {\n opacity: 0.5;\n }\n\n /* A disabled button that is not loading greys out through the colour tokens and\n never through opacity. These three rules are (0,4,0), so they already beat the\n (0,3,0) of the raised background whatever the order they are read in. */\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading]):is(\n [data-variant='solid'],\n [data-variant='soft']\n ) {\n background: var(--vectis-color-surface-muted);\n color: var(--vectis-color-text-subtle);\n }\n\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading])[data-variant='outline'] {\n background: transparent;\n color: var(--vectis-color-text-subtle);\n border-color: var(--vectis-color-border);\n }\n\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading])[data-variant='ghost'] {\n background: transparent;\n color: var(--vectis-color-text-subtle);\n }\n\n /*\n * The shadow needs a rule of its own. No variant declares a shadow, so none of the three\n * rules above cancels one, and a disabled raised ghost would otherwise go on casting its\n * shadow-sm.\n */\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading])[data-elevated] {\n box-shadow: none;\n }\n\n .v-button-spinner {\n /*\n * Match the spinner box and font size to the icon it replaces so loading preserves button\n * width and visual scale.\n */\n font-size: var(--vectis-icon-size);\n /* 1em of the line above rather than the variable again: a relative icon size would\n otherwise be resolved twice, once against the button's text and once against this\n box's own enlarged font-size. */\n inline-size: 1em;\n block-size: 1em;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-button {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VButton.js","names":["_sfc_main","VButton_vue_vue_type_script_setup_true_lang_default","VButton_default"],"sources":["../../../src/components/VButton/VButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * Native buttons own activation and disabling. Links use useInertLink because anchors have no\n * disabled state; group shape overrides preserve individual tones.\n */\nimport { computed, inject, useAttrs } from 'vue'\nimport type { ButtonHTMLAttributes } from 'vue'\n\nimport { buttonGroupKey } from './context'\n\nimport { useControlShape } from '../../composables/useControlShape'\nimport { useInertLink } from '../../composables/useInertLink'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\nimport VSpinner from '../VSpinner/VSpinner.vue'\n\n/** How much visual weight the button carries. */\nexport type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'soft'\n/** What the action means, in colour. */\nexport type ButtonTone = 'accent' | 'neutral' | 'danger'\n/** The height of the button, from the scale every control shares. */\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\ninterface ButtonProps {\n /**\n * How much visual weight the button carries: `solid` is filled with the tone, `soft` uses a\n * tinted background, `outline` keeps only a border, and `ghost` shows nothing until it is\n * hovered.\n */\n variant?: ButtonVariant\n /**\n * What the action means: `accent` for the ordinary one, `neutral` for a secondary one,\n * `danger` for one that destroys something. Left out inside a VButtonGroup it takes the\n * group's tone, which is the point of not defaulting it here; on its own it is `accent`.\n */\n tone?: ButtonTone\n /**\n * Raises the button off the page: a shadow that grows on hover and settles back when pressed,\n * whatever the variant. Inside a VButtonGroup the group's own value wins over this one.\n */\n elevated?: boolean\n /**\n * The height of the button, taken from the size scale shared by every control.\n * Inside a VButtonGroup the group's own size wins over this one.\n */\n size?: ButtonSize\n /**\n * Stretches the button to the whole inline size of its parent, instead of leaving it only as\n * wide as its content.\n */\n fullWidth?: boolean\n /**\n * Turns the button into an `<a>` pointing at this address. A disabled or loading\n * link becomes inert: the address is dropped, so it can be neither focused nor\n * followed.\n */\n href?: string\n /** The native type of the button. It is ignored as soon as `href` makes it a link. */\n type?: ButtonHTMLAttributes['type']\n /**\n * Makes the button unusable: it stops responding, leaves the tab order and greys\n * out through the colour tokens.\n */\n disabled?: boolean\n /**\n * Shows a spinner, disables the button and announces it as busy. The spinner takes\n * the place of the start slot (`iconStart` / `#start`), so an icon and a spinner\n * are never displayed side by side.\n */\n loading?: boolean\n /** An icon before the label. The `#start` slot replaces it when both are given. */\n iconStart?: IconSource\n /** An icon after the label. The `#end` slot replaces it when both are given. */\n iconEnd?: IconSource\n /**\n * Renders `iconStart` and `iconEnd` in their filled form (the font's `FILL` axis).\n * It has no effect on the `#start`/`#end` slots, whose icons the consumer builds.\n */\n iconFilled?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n variant: 'solid',\n // The only one of the five with no default. `tone` is the prop a button keeps against its\n // group, so `undefined` has to stay distinguishable from an explicit `accent`, which would\n // otherwise silence the group for every button in the row.\n tone: undefined,\n elevated: false,\n size: 'md',\n fullWidth: false,\n href: undefined,\n type: 'button',\n disabled: false,\n loading: false,\n iconStart: undefined,\n iconEnd: undefined,\n iconFilled: false,\n})\n\ndefineSlots<{\n /** The label of the button. */\n default(): unknown\n /**\n * Content placed before the label, usually an icon. Mark it `aria-hidden` when it\n * only repeats what the label already says.\n */\n start?(): unknown\n /** Content placed after the label. */\n end?(): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst attrs = useAttrs()\nconst group = inject(buttonGroupKey, null)\n\n// The shape of the segmented control belongs to the row: the group is read first, and a\n// group that named nothing hands the prop straight back. The tone goes the other way,\n// the button's own answer first (see context.ts).\nconst { size: resolvedSize, disabled: resolvedDisabled } = useControlShape<ButtonSize>(props, group)\nconst resolvedVariant = computed<ButtonVariant>(() => group?.variant ?? props.variant)\nconst resolvedElevated = computed(() => group?.elevated ?? props.elevated)\n// The tone goes the OTHER way, the button's own answer first: one action in a row can be\n// the destructive one, and the row has to be able to say so (see context.ts).\nconst resolvedTone = computed<ButtonTone>(() => props.tone ?? group?.tone ?? 'accent')\n\nconst isInert = computed(() => resolvedDisabled.value || props.loading)\nconst {\n isLink,\n isInertLink,\n linkHref,\n attrs: passedAttrs,\n} = useInertLink({\n href: () => props.href,\n inert: () => isInert.value,\n attrs: () => attrs,\n})\n</script>\n\n<template>\n <component\n :is=\"isLink ? 'a' : 'button'\"\n :aria-disabled=\"isInertLink ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"passedAttrs\"\n class=\"v-button v-control v-tone v-variant\"\n :href=\"linkHref\"\n :type=\"isLink ? undefined : type\"\n :disabled=\"isLink ? undefined : isInert\"\n :data-variant=\"resolvedVariant\"\n :data-tone=\"resolvedTone\"\n :data-elevated=\"resolvedElevated ? '' : undefined\"\n :data-size=\"resolvedSize\"\n :data-full-width=\"fullWidth ? '' : undefined\"\n :data-loading=\"loading ? '' : undefined\"\n >\n <!-- The button already carries aria-busy, so the spinner is hidden from\n assistive technology: its own role=\"status\" would announce the same state a\n second time -->\n <span v-if=\"loading\" class=\"v-button-spinner\" aria-hidden=\"true\">\n <VSpinner />\n </span>\n <slot v-else name=\"start\">\n <VIcon v-if=\"iconStart\" v-bind=\"iconProps(iconStart)\" :filled=\"iconFilled\" />\n </slot>\n <slot />\n <slot name=\"end\">\n <VIcon v-if=\"iconEnd\" v-bind=\"iconProps(iconEnd)\" :filled=\"iconFilled\" />\n </slot>\n </component>\n</template>\n\n<style>\n@layer vectis.components {\n .v-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--control-gap);\n block-size: var(--control-height);\n padding-inline: var(--control-padding-inline);\n border: 1px solid transparent;\n border-radius: var(--vectis-radius-interactive);\n font-family: var(--vectis-text-family);\n font-size: var(--control-font-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n text-decoration: none;\n cursor: pointer;\n transition:\n background-color var(--vectis-duration-fast) var(--vectis-ease-default),\n border-color var(--vectis-duration-fast) var(--vectis-ease-default),\n color var(--vectis-duration-fast) var(--vectis-ease-default),\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /* An explicit display, rather than a width alone: an inline-level box sits on a line\n box, which would add the strut's descender under a button the consumer asked to\n fill its parent. Block-level, it measures the parent's content box exactly. */\n .v-button[data-full-width] {\n display: flex;\n inline-size: 100%;\n }\n\n /*\n * At (0,2,0) it beats this sheet's own padding by weight, and it is the only rule that may\n * touch that padding on an icon-only button. A consumer of VButton restyling the padding of\n * its own buttons at (0,2,0) from another sheet would tie with it, and the bundler would\n * decide: such a rule has to exclude `[data-icon-only]`.\n */\n .v-button[data-icon-only] {\n min-inline-size: var(--control-height);\n padding-inline: 0;\n }\n\n .v-button:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n /* Tone and variant recipes are shared; component-specific interaction states remain here. */\n\n .v-button[data-variant='solid']:hover:not(:disabled, [aria-disabled='true']) {\n background: var(--tone-bg-solid-hover);\n }\n\n .v-button[data-variant='solid']:active:not(:disabled, [aria-disabled='true']) {\n background: var(--tone-bg-solid-active);\n }\n\n /*\n * Nothing then arbitrates the background of a raised ghost by a one-step specificity margin,\n * so a declaration added to either set later cannot silently leak into the other case.\n */\n .v-button:is([data-variant='outline'], [data-variant='ghost']):not([data-elevated]):hover:not(\n :disabled,\n [aria-disabled='true']\n ) {\n background: var(--tone-bg-soft);\n }\n\n /* One step of tint, reached two ways: pressing a ghost or an outline, which already sit on\n the soft surface while hovered, and hovering a soft one. A selector list keeps each\n member's own weight, so merging them moves no arbitration: the outline/ghost half is\n still (0,5,0) after its hover, the soft half still (0,4,0) before its active. */\n .v-button:is([data-variant='outline'], [data-variant='ghost']):not([data-elevated]):active:not(\n :disabled,\n [aria-disabled='true']\n ),\n .v-button[data-variant='soft']:hover:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in oklab, var(--tone-bg-soft), var(--tone-text-tinted) 8%);\n }\n\n .v-button[data-variant='soft']:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in oklab, var(--tone-bg-soft), var(--tone-text-tinted) 14%);\n }\n\n /*\n * The `:is()` here is not decoration; it is what gives these rules a specificity of (0,3,0),\n * beating the (0,2,0) of the ghost and outline bases without depending on the order the rules\n * end up in.\n */\n .v-button[data-elevated] {\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-button[data-elevated]:is([data-variant='ghost'], [data-variant='outline']) {\n background: var(--vectis-color-surface-raised);\n }\n\n .v-button[data-elevated]:hover:not(:disabled, [aria-disabled='true']) {\n box-shadow: var(--vectis-shadow-md);\n }\n\n .v-button[data-elevated]:is([data-variant='ghost'], [data-variant='outline']):hover:not(\n :disabled,\n [aria-disabled='true']\n ) {\n background: color-mix(in oklab, var(--vectis-color-surface-raised), var(--tone-text-tinted) 8%);\n }\n\n .v-button[data-elevated]:active:not(:disabled, [aria-disabled='true']) {\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-button[data-elevated]:is([data-variant='ghost'], [data-variant='outline']):active:not(\n :disabled,\n [aria-disabled='true']\n ) {\n background: color-mix(\n in oklab,\n var(--vectis-color-surface-raised),\n var(--tone-text-tinted) 12%\n );\n }\n\n .v-button:is(:disabled, [aria-disabled='true']) {\n cursor: not-allowed;\n }\n\n .v-button[data-loading] {\n opacity: 0.5;\n }\n\n /* A disabled button that is not loading greys out through the colour tokens and\n never through opacity. These three rules are (0,4,0), so they already beat the\n (0,3,0) of the raised background whatever the order they are read in. */\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading]):is(\n [data-variant='solid'],\n [data-variant='soft']\n ) {\n background: var(--vectis-color-surface-muted);\n color: var(--vectis-color-text-subtle);\n }\n\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading])[data-variant='outline'] {\n background: transparent;\n color: var(--vectis-color-text-subtle);\n border-color: var(--vectis-color-border);\n }\n\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading])[data-variant='ghost'] {\n background: transparent;\n color: var(--vectis-color-text-subtle);\n }\n\n /*\n * The shadow needs a rule of its own. No variant declares a shadow, so none of the three\n * rules above cancels one, and a disabled raised ghost would otherwise go on casting its\n * shadow-sm.\n */\n .v-button:is(:disabled, [aria-disabled='true']):not([data-loading])[data-elevated] {\n box-shadow: none;\n }\n\n .v-button-spinner {\n /*\n * Match the spinner box and font size to the icon it replaces so loading preserves button\n * width and visual scale.\n */\n font-size: var(--vectis-icon-size);\n /* 1em of the line above rather than the variable again: a relative icon size would\n otherwise be resolved twice, once against the button's text and once against this\n box's own enlarged font-size. */\n inline-size: 1em;\n block-size: 1em;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-button {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -21,10 +21,6 @@ var b = {
21
21
  default: !1
22
22
  },
23
23
  size: { default: "md" },
24
- compact: {
25
- type: Boolean,
26
- default: !1
27
- },
28
24
  fullWidth: {
29
25
  type: Boolean,
30
26
  default: !1
@@ -47,24 +43,23 @@ var b = {
47
43
  }
48
44
  },
49
45
  setup(d) {
50
- let x = d, S = v(), C = f(n, null), { size: w, compact: T, disabled: E } = r(x, C), D = o(() => C?.variant ?? x.variant), O = o(() => C?.elevated ?? x.elevated), k = o(() => x.tone ?? C?.tone ?? "accent"), A = o(() => E.value || x.loading), { isLink: j, isInertLink: M, linkHref: N, attrs: P } = i({
46
+ let x = d, S = v(), C = f(n, null), { size: w, disabled: T } = r(x, C), E = o(() => C?.variant ?? x.variant), D = o(() => C?.elevated ?? x.elevated), O = o(() => x.tone ?? C?.tone ?? "accent"), k = o(() => T.value || x.loading), { isLink: A, isInertLink: j, linkHref: M, attrs: N } = i({
51
47
  href: () => x.href,
52
- inert: () => A.value,
48
+ inert: () => k.value,
53
49
  attrs: () => S
54
50
  });
55
- return (n, r) => (m(), s(g(_(j) ? "a" : "button"), p({
56
- "aria-disabled": _(M) ? "true" : void 0,
51
+ return (n, r) => (m(), s(g(_(A) ? "a" : "button"), p({
52
+ "aria-disabled": _(j) ? "true" : void 0,
57
53
  "aria-busy": d.loading || void 0
58
- }, _(P), {
54
+ }, _(N), {
59
55
  class: "v-button v-control v-tone v-variant",
60
- href: _(N),
61
- type: _(j) ? void 0 : d.type,
62
- disabled: _(j) ? void 0 : A.value,
63
- "data-variant": D.value,
64
- "data-tone": k.value,
65
- "data-elevated": O.value ? "" : void 0,
56
+ href: _(M),
57
+ type: _(A) ? void 0 : d.type,
58
+ disabled: _(A) ? void 0 : k.value,
59
+ "data-variant": E.value,
60
+ "data-tone": O.value,
61
+ "data-elevated": D.value ? "" : void 0,
66
62
  "data-size": _(w),
67
- "data-compact": _(T) ? "" : void 0,
68
63
  "data-full-width": d.fullWidth ? "" : void 0,
69
64
  "data-loading": d.loading ? "" : void 0
70
65
  }), {
@@ -84,7 +79,6 @@ var b = {
84
79
  "data-tone",
85
80
  "data-elevated",
86
81
  "data-size",
87
- "data-compact",
88
82
  "data-full-width",
89
83
  "data-loading"
90
84
  ]));