vectis-ui 0.15.0 → 0.17.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 (216) 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/context.js.map +1 -1
  7. package/dist/components/VAvatar/VAvatar.d.ts +0 -3
  8. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  9. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +21 -27
  10. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/VAvatar/VAvatarGroup.d.ts +0 -6
  12. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  13. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +5 -19
  14. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/VAvatar/context.d.ts +0 -1
  16. package/dist/components/VAvatar/context.js.map +1 -1
  17. package/dist/components/VButton/VButton.d.ts +0 -6
  18. package/dist/components/VButton/VButton.js.map +1 -1
  19. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +11 -17
  20. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/VButton/VButtonGroup.d.ts +0 -6
  22. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  23. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +0 -7
  24. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/VButton/context.d.ts +0 -2
  26. package/dist/components/VButton/context.js.map +1 -1
  27. package/dist/components/VChip/VChip.d.ts +0 -3
  28. package/dist/components/VChip/VChip.js.map +1 -1
  29. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +0 -6
  30. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  31. package/dist/components/VColorInput/VColorInput.d.ts +0 -3
  32. package/dist/components/VColorInput/VColorInput.js.map +1 -1
  33. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js +60 -66
  34. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/VColorPicker/color.js +2 -2
  36. package/dist/components/VColorPicker/color.js.map +1 -1
  37. package/dist/components/VCombobox/VCombobox.d.ts +10 -3
  38. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  39. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +170 -163
  40. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/VContextMenu/VContextMenu.d.ts +0 -3
  42. package/dist/components/VContextMenu/VContextMenu.js.map +1 -1
  43. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js +0 -6
  44. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/VDataTable/VDataTable.css +1 -1
  46. package/dist/components/VDataTable/VDataTable.d.ts +0 -2
  47. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  48. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +69 -84
  49. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/VDateInput/VDateInput.d.ts +0 -3
  51. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  52. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +32 -37
  53. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  54. package/dist/components/VDatePicker/VDatePicker.css +1 -1
  55. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  56. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +3 -2
  57. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/VDialog/VDialog.css +1 -1
  59. package/dist/components/VDialog/VDialog.js.map +1 -1
  60. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +4 -2
  61. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/VDrawer/VDrawer.css +1 -1
  63. package/dist/components/VDrawer/VDrawer.js.map +1 -1
  64. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js +4 -2
  65. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/VFileInput/VFileInput.d.ts +0 -5
  67. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  68. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +75 -86
  69. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/VHotkeys/VHotkeys.d.ts +0 -3
  71. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  72. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +0 -6
  73. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/VIconButton/VIconButton.d.ts +0 -3
  75. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  76. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +0 -6
  77. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components/VInput/VInput.css +1 -1
  79. package/dist/components/VInput/VInput.d.ts +0 -3
  80. package/dist/components/VInput/VInput.js.map +1 -1
  81. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +18 -24
  82. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  83. package/dist/components/VInput/VInputGroup.d.ts +0 -3
  84. package/dist/components/VInput/VInputGroup.js.map +1 -1
  85. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +0 -7
  86. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  87. package/dist/components/VInput/context.d.ts +0 -2
  88. package/dist/components/VInput/context.js.map +1 -1
  89. package/dist/components/VInputOTP/VInputOTP.d.ts +0 -3
  90. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  91. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +0 -6
  92. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/VListbox/VListboxPanel.d.ts +0 -3
  94. package/dist/components/VListbox/VListboxPanel.js.map +1 -1
  95. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js +0 -6
  96. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/dist/components/VListbox/VListboxValues.js.map +1 -1
  98. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js +4 -14
  99. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/components/VMenu/VMenu.d.ts +0 -3
  101. package/dist/components/VMenu/VMenu.js.map +1 -1
  102. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +0 -6
  103. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/components/VMenu/VMenuPanel.d.ts +0 -3
  105. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  106. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +0 -6
  107. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/components/VMeter/VMeter.css +1 -1
  109. package/dist/components/VMeter/VMeter.d.ts +24 -8
  110. package/dist/components/VMeter/VMeter.js.map +1 -1
  111. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js +65 -48
  112. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  113. package/dist/components/VMeterGroup/VMeterGroup.css +2 -0
  114. package/dist/components/VMeterGroup/VMeterGroup.d.ts +101 -0
  115. package/dist/components/VMeterGroup/VMeterGroup.js +9 -0
  116. package/dist/components/VMeterGroup/VMeterGroup.js.map +1 -0
  117. package/dist/components/VMeterGroup/VMeterGroup.vue_vue_type_script_setup_true_lang.js +117 -0
  118. package/dist/components/VMeterGroup/VMeterGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  119. package/dist/components/VNumberInput/VNumberInput.d.ts +0 -3
  120. package/dist/components/VNumberInput/VNumberInput.js.map +1 -1
  121. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js +0 -6
  122. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  123. package/dist/components/VNumberInput/number.js +2 -2
  124. package/dist/components/VNumberInput/number.js.map +1 -1
  125. package/dist/components/VPagination/VPagination.d.ts +0 -3
  126. package/dist/components/VPagination/VPagination.js.map +1 -1
  127. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +0 -6
  128. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  129. package/dist/components/VProgressCircular/VProgressCircular.d.ts +1 -1
  130. package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
  131. package/dist/components/VProgressLinear/VProgressLinear.d.ts +12 -13
  132. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  133. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +65 -48
  134. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  135. package/dist/components/VSelect/VSelect.d.ts +0 -3
  136. package/dist/components/VSelect/VSelect.js.map +1 -1
  137. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js +114 -123
  138. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  139. package/dist/components/VSeparator/VSeparator.css +1 -1
  140. package/dist/components/VSeparator/VSeparator.d.ts +42 -2
  141. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  142. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js +50 -9
  143. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  144. package/dist/components/VSideNavigation/VSideNavigation.d.ts +6 -6
  145. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  146. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +7 -7
  147. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  148. package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
  149. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  150. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  151. package/dist/components/VSideNavigation/context.js.map +1 -1
  152. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +0 -3
  153. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  154. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +0 -6
  155. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  156. package/dist/components/VSlider/VSlider.js.map +1 -1
  157. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +115 -120
  158. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  159. package/dist/components/VSnackbar/state.js +2 -3
  160. package/dist/components/VSnackbar/state.js.map +1 -1
  161. package/dist/components/VSplitButton/VSplitButton.d.ts +0 -3
  162. package/dist/components/VSplitButton/VSplitButton.js.map +1 -1
  163. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js +0 -6
  164. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/components/VTabs/VTab.js.map +1 -1
  166. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +0 -2
  167. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  168. package/dist/components/VTabs/VTabs.css +1 -1
  169. package/dist/components/VTabs/VTabs.d.ts +0 -3
  170. package/dist/components/VTabs/VTabs.js.map +1 -1
  171. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +2 -15
  172. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  173. package/dist/components/VTabs/context.d.ts +0 -2
  174. package/dist/components/VTabs/context.js.map +1 -1
  175. package/dist/components/VTextarea/VTextarea.d.ts +0 -6
  176. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  177. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +0 -6
  178. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  179. package/dist/components/VTimeInput/VTimeInput.d.ts +0 -3
  180. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  181. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +211 -218
  182. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  183. package/dist/components/VToast/state.js +2 -3
  184. package/dist/components/VToast/state.js.map +1 -1
  185. package/dist/components/VToggle/VToggle.d.ts +0 -3
  186. package/dist/components/VToggle/VToggle.js.map +1 -1
  187. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +0 -6
  188. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  189. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  190. package/dist/composables/useAriaLabel.d.ts +5 -0
  191. package/dist/composables/useAriaLabel.js +5 -1
  192. package/dist/composables/useAriaLabel.js.map +1 -1
  193. package/dist/composables/useControlShape.d.ts +1 -5
  194. package/dist/composables/useControlShape.js +0 -1
  195. package/dist/composables/useControlShape.js.map +1 -1
  196. package/dist/composables/useListbox.d.ts +2 -1
  197. package/dist/composables/useListbox.js +72 -69
  198. package/dist/composables/useListbox.js.map +1 -1
  199. package/dist/i18n/en.js +3 -1
  200. package/dist/i18n/en.js.map +1 -1
  201. package/dist/i18n/fr.js +3 -1
  202. package/dist/i18n/fr.js.map +1 -1
  203. package/dist/i18n/types.d.ts +6 -0
  204. package/dist/index.d.ts +5 -3
  205. package/dist/index.js +21 -20
  206. package/dist/styles.css +1 -1
  207. package/dist/tokens/index.d.ts +13 -5
  208. package/dist/tokens/semantic.d.ts +13 -5
  209. package/dist/tokens/semantic.js +16 -10
  210. package/dist/tokens/semantic.js.map +1 -1
  211. package/dist/tokens.json +51 -19
  212. package/dist/types.d.ts +0 -2
  213. package/dist/utils/chip.d.ts +4 -6
  214. package/dist/utils/chip.js +8 -5
  215. package/dist/utils/chip.js.map +1 -1
  216. package/package.json +3 -3
@@ -1,2 +1,2 @@
1
1
  @layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
2
- @layer vectis.components{.v-separator{border:0 solid var(--vectis-color-border);flex:none;margin:0}.v-separator[data-orientation=horizontal]{border-block-start-width:1px}.v-separator[data-orientation=vertical]{border-inline-start-width:1px;align-self:stretch}}
2
+ @layer vectis.components{.v-separator{--separator-color:var(--vectis-color-border);--separator-thickness:var(--vectis-control-size-separator-sm);border:0 solid var(--separator-color);flex:none;margin:0}.v-separator[data-size=md]{--separator-thickness:var(--vectis-control-size-separator-md)}.v-separator[data-size=lg]{--separator-thickness:var(--vectis-control-size-separator-lg)}.v-separator[data-variant=dashed]{border-style:dashed}.v-separator[data-variant=dotted]{border-style:dotted}.v-separator[data-orientation=vertical]{align-self:stretch}hr.v-separator[data-orientation=horizontal]{border-block-start-width:var(--separator-thickness)}hr.v-separator[data-orientation=vertical]{border-inline-start-width:var(--separator-thickness)}div.v-separator{align-items:center;gap:var(--vectis-space-3);color:var(--vectis-color-text-muted);font-family:var(--vectis-text-family);font-size:var(--vectis-text-caption-size);font-weight:var(--vectis-text-caption-weight);line-height:var(--vectis-text-caption-leading);display:flex}div.v-separator:before,div.v-separator:after{content:"";border-width:0;border-color:inherit;border-style:inherit;flex:1}div.v-separator[data-orientation=horizontal]:before,div.v-separator[data-orientation=horizontal]:after{border-block-start-width:var(--separator-thickness)}div.v-separator[data-orientation=vertical]{flex-direction:column}div.v-separator[data-orientation=vertical]:before,div.v-separator[data-orientation=vertical]:after{border-inline-start-width:var(--separator-thickness)}div.v-separator[data-content-position=start]:before,div.v-separator[data-content-position=end]:after{display:none}.v-separator-content{--vectis-icon-size:var(--vectis-icon-size-sm);align-items:center;gap:var(--vectis-space-2);display:inline-flex}}
@@ -1,12 +1,52 @@
1
- /** Use a native hr for separator semantics and borders for visibility in forced colours. */
1
+ import { IconSource } from '../VIcon/types.js';
2
2
  /** Which way the rule runs. */
3
3
  export type SeparatorOrientation = 'horizontal' | 'vertical';
4
+ /** How the rule is stroked. */
5
+ export type SeparatorVariant = 'solid' | 'dashed' | 'dotted';
6
+ /** Where the content sits along the rule. */
7
+ export type SeparatorContentPosition = 'start' | 'center' | 'end';
8
+ /** How thick the rule is. */
9
+ export type SeparatorSize = 'sm' | 'md' | 'lg';
4
10
  interface SeparatorProps {
5
11
  /** The direction the rule runs in: across by default, or down the page under `vertical`. */
6
12
  orientation?: SeparatorOrientation;
13
+ /** How the rule is stroked: a continuous line, dashes or dots. */
14
+ variant?: SeparatorVariant;
15
+ /**
16
+ * How thick the rule is: a 1px hairline (`sm`, the default), 2px or 4px. A thicker rule marks
17
+ * a stronger break, and makes `dotted` read as dots.
18
+ */
19
+ size?: SeparatorSize;
20
+ /**
21
+ * A colour of your own (hex, CSS name or `oklch()`) for the rule. The label and icon keep the
22
+ * muted text colour, so their contrast stays the design system's.
23
+ */
24
+ color?: string;
25
+ /** Visible text breaking the rule. It also becomes the separator's accessible name. */
26
+ label?: string;
27
+ /** An icon breaking the rule, before the label when both are set (the VIcon contract). */
28
+ icon?: IconSource;
29
+ /** Where the label and icon sit along the rule: its start, centre or end. */
30
+ contentPosition?: SeparatorContentPosition;
7
31
  }
8
- declare const __VLS_export: import('vue').DefineComponent<SeparatorProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SeparatorProps> & Readonly<{}>, {
32
+ type __VLS_Slots = {
33
+ /** Rich content breaking the rule, after the icon and in place of the label. */
34
+ default?(): unknown;
35
+ };
36
+ declare const __VLS_base: import('vue').DefineComponent<SeparatorProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SeparatorProps> & Readonly<{}>, {
37
+ label: string;
38
+ size: SeparatorSize;
39
+ variant: SeparatorVariant;
40
+ color: string;
41
+ icon: IconSource;
9
42
  orientation: SeparatorOrientation;
43
+ contentPosition: SeparatorContentPosition;
10
44
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
45
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
11
46
  declare const _default: typeof __VLS_export;
12
47
  export default _default;
48
+ type __VLS_WithSlots<T, S> = T & {
49
+ new (): {
50
+ $slots: S;
51
+ };
52
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"VSeparator.js","names":["_sfc_main","VSeparator_vue_vue_type_script_setup_true_lang_default","VSeparator_default"],"sources":["../../../src/components/VSeparator/VSeparator.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Use a native hr for separator semantics and borders for visibility in forced colours. */\n/** Which way the rule runs. */\nexport type SeparatorOrientation = 'horizontal' | 'vertical'\n\ninterface SeparatorProps {\n /** The direction the rule runs in: across by default, or down the page under `vertical`. */\n orientation?: SeparatorOrientation\n}\n\nwithDefaults(defineProps<SeparatorProps>(), {\n orientation: 'horizontal',\n})\n</script>\n\n<template>\n <!--\n Aria-orientation is emitted only when it CONTRADICTS what the role already implies: a\n separator is horizontal by default, so stating it would merely restate the role. This is the\n same convention the VTabs tablist follows.\n -->\n <hr\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n />\n</template>\n\n<style>\n@layer vectis.components {\n .v-separator {\n flex: none;\n /*\n * `.v-menu-separator` and `.v-listbox-separator` override that margin from THEIR own\n * sheet, and which of the two sheets the consumer's bundler puts last is not ours to\n * decide. Both are therefore written as the compound `.v-separator.v-x-separator`, and\n * every declaration added here falls under the same obligation.\n */\n margin: 0;\n border: 0 solid var(--vectis-color-border);\n }\n\n .v-separator[data-orientation='horizontal'] {\n border-block-start-width: 1px;\n }\n\n /*\n * In ordinary flow it collapses to nothing, silently and with no error; there it is up to the\n * consumer to give it a block-size.\n */\n .v-separator[data-orientation='vertical'] {\n align-self: stretch;\n border-inline-start-width: 1px;\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VSeparator.js","names":["_sfc_main","VSeparator_vue_vue_type_script_setup_true_lang_default","VSeparator_default"],"sources":["../../../src/components/VSeparator/VSeparator.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Use a native hr for separator semantics and borders for visibility in forced colours. */\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\n/** Which way the rule runs. */\nexport type SeparatorOrientation = 'horizontal' | 'vertical'\n/** How the rule is stroked. */\nexport type SeparatorVariant = 'solid' | 'dashed' | 'dotted'\n/** Where the content sits along the rule. */\nexport type SeparatorContentPosition = 'start' | 'center' | 'end'\n/** How thick the rule is. */\nexport type SeparatorSize = 'sm' | 'md' | 'lg'\n\ninterface SeparatorProps {\n /** The direction the rule runs in: across by default, or down the page under `vertical`. */\n orientation?: SeparatorOrientation\n /** How the rule is stroked: a continuous line, dashes or dots. */\n variant?: SeparatorVariant\n /**\n * How thick the rule is: a 1px hairline (`sm`, the default), 2px or 4px. A thicker rule marks\n * a stronger break, and makes `dotted` read as dots.\n */\n size?: SeparatorSize\n /**\n * A colour of your own (hex, CSS name or `oklch()`) for the rule. The label and icon keep the\n * muted text colour, so their contrast stays the design system's.\n */\n color?: string\n /** Visible text breaking the rule. It also becomes the separator's accessible name. */\n label?: string\n /** An icon breaking the rule, before the label when both are set (the VIcon contract). */\n icon?: IconSource\n /** Where the label and icon sit along the rule: its start, centre or end. */\n contentPosition?: SeparatorContentPosition\n}\n\nwithDefaults(defineProps<SeparatorProps>(), {\n orientation: 'horizontal',\n variant: 'solid',\n size: 'sm',\n color: undefined,\n label: undefined,\n icon: undefined,\n contentPosition: 'center',\n})\n\nconst slots = defineSlots<{\n /** Rich content breaking the rule, after the icon and in place of the label. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive.\nfunction hasSlot() {\n return slots.default !== undefined\n}\n</script>\n\n<template>\n <!--\n Aria-orientation is emitted only when it CONTRADICTS what the role already implies: a\n separator is horizontal by default, so stating it would merely restate the role. This is the\n same convention the VTabs tablist follows.\n -->\n <hr\n v-if=\"!label && !icon && !hasSlot()\"\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :data-variant=\"variant\"\n :data-size=\"size\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n :style=\"color !== undefined ? { '--separator-color': color } : undefined\"\n />\n <!--\n An <hr> cannot hold content. A separator's children are presentational, so the label is\n repeated as its accessible name; slot-only content is named by the consumer's aria-label.\n -->\n <div\n v-else\n role=\"separator\"\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :data-variant=\"variant\"\n :data-size=\"size\"\n :data-content-position=\"contentPosition\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n :aria-label=\"label\"\n :style=\"color !== undefined ? { '--separator-color': color } : undefined\"\n >\n <span class=\"v-separator-content\">\n <VIcon v-if=\"icon\" v-bind=\"iconProps(icon)\" />\n <slot>{{ label }}</slot>\n </span>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-separator {\n --separator-color: var(--vectis-color-border);\n --separator-thickness: var(--vectis-control-size-separator-sm);\n\n flex: none;\n /*\n * `.v-menu-separator` and `.v-listbox-separator` override that margin from THEIR own\n * sheet, and which of the two sheets the consumer's bundler puts last is not ours to\n * decide. Both are therefore written as the compound `.v-separator.v-x-separator`, and\n * every declaration added here falls under the same obligation.\n */\n margin: 0;\n border: 0 solid var(--separator-color);\n }\n\n .v-separator[data-size='md'] {\n --separator-thickness: var(--vectis-control-size-separator-md);\n }\n\n .v-separator[data-size='lg'] {\n --separator-thickness: var(--vectis-control-size-separator-lg);\n }\n\n .v-separator[data-variant='dashed'] {\n border-style: dashed;\n }\n\n .v-separator[data-variant='dotted'] {\n border-style: dotted;\n }\n\n /*\n * In ordinary flow it collapses to nothing, silently and with no error; there it is up to the\n * consumer to give it a block-size.\n */\n .v-separator[data-orientation='vertical'] {\n align-self: stretch;\n }\n\n hr.v-separator[data-orientation='horizontal'] {\n border-block-start-width: var(--separator-thickness);\n }\n\n hr.v-separator[data-orientation='vertical'] {\n border-inline-start-width: var(--separator-thickness);\n }\n\n /* With content, the root only lays out; its two pseudo-elements are the strokes. */\n div.v-separator {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-3);\n color: var(--vectis-color-text-muted);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n }\n\n div.v-separator::before,\n div.v-separator::after {\n content: '';\n flex: 1;\n /* The initial width is `medium` (3px): every side but the stroke's must be zeroed. */\n border-width: 0;\n border-color: inherit;\n border-style: inherit;\n }\n\n div.v-separator[data-orientation='horizontal']::before,\n div.v-separator[data-orientation='horizontal']::after {\n border-block-start-width: var(--separator-thickness);\n }\n\n div.v-separator[data-orientation='vertical'] {\n flex-direction: column;\n }\n\n div.v-separator[data-orientation='vertical']::before,\n div.v-separator[data-orientation='vertical']::after {\n border-inline-start-width: var(--separator-thickness);\n }\n\n div.v-separator[data-content-position='start']::before,\n div.v-separator[data-content-position='end']::after {\n display: none;\n }\n\n .v-separator-content {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n}\n</style>\n"],"mappings":""}
@@ -1,17 +1,58 @@
1
- import { createElementBlock as e, defineComponent as t, openBlock as n } from "vue";
1
+ import { iconProps as e } from "../VIcon/iconProps.js";
2
+ import t from "../VIcon/VIcon.js";
3
+ import { createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, defineComponent as s, mergeProps as c, normalizeProps as l, normalizeStyle as u, openBlock as d, renderSlot as f, toDisplayString as p, unref as m, useSlots as h } from "vue";
2
4
  //#region src/components/VSeparator/VSeparator.vue?vue&type=script&setup=true&lang.ts
3
- var r = ["data-orientation", "aria-orientation"], i = /*@__PURE__*/ t({
5
+ var g = [
6
+ "data-orientation",
7
+ "data-variant",
8
+ "data-size",
9
+ "aria-orientation"
10
+ ], _ = [
11
+ "data-orientation",
12
+ "data-variant",
13
+ "data-size",
14
+ "data-content-position",
15
+ "aria-orientation",
16
+ "aria-label"
17
+ ], v = { class: "v-separator-content" }, y = /*@__PURE__*/ s({
4
18
  __name: "VSeparator",
5
- props: { orientation: { default: "horizontal" } },
6
- setup(t) {
7
- return (i, a) => (n(), e("hr", {
19
+ props: {
20
+ orientation: { default: "horizontal" },
21
+ variant: { default: "solid" },
22
+ size: { default: "sm" },
23
+ color: { default: void 0 },
24
+ label: { default: void 0 },
25
+ icon: { default: void 0 },
26
+ contentPosition: { default: "center" }
27
+ },
28
+ setup(s) {
29
+ let y = h();
30
+ function b() {
31
+ return y.default !== void 0;
32
+ }
33
+ return (h, y) => !s.label && !s.icon && !b() ? (d(), i("hr", {
34
+ key: 0,
8
35
  class: "v-separator",
9
- "data-orientation": t.orientation,
10
- "aria-orientation": t.orientation === "vertical" ? "vertical" : void 0
11
- }, null, 8, r));
36
+ "data-orientation": s.orientation,
37
+ "data-variant": s.variant,
38
+ "data-size": s.size,
39
+ "aria-orientation": s.orientation === "vertical" ? "vertical" : void 0,
40
+ style: u(s.color === void 0 ? void 0 : { "--separator-color": s.color })
41
+ }, null, 12, g)) : (d(), i("div", {
42
+ key: 1,
43
+ role: "separator",
44
+ class: "v-separator",
45
+ "data-orientation": s.orientation,
46
+ "data-variant": s.variant,
47
+ "data-size": s.size,
48
+ "data-content-position": s.contentPosition,
49
+ "aria-orientation": s.orientation === "vertical" ? "vertical" : void 0,
50
+ "aria-label": s.label,
51
+ style: u(s.color === void 0 ? void 0 : { "--separator-color": s.color })
52
+ }, [a("span", v, [s.icon ? (d(), n(t, l(c({ key: 0 }, m(e)(s.icon))), null, 16)) : r("", !0), f(h.$slots, "default", {}, () => [o(p(s.label), 1)])])], 12, _));
12
53
  }
13
54
  });
14
55
  //#endregion
15
- export { i as default };
56
+ export { y as default };
16
57
 
17
58
  //# sourceMappingURL=VSeparator.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VSeparator.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_hoisted_1","VSeparator_vue_vue_type_script_setup_true_lang_default","openBlock","createElementBlock","__props"],"sources":["../../../src/components/VSeparator/VSeparator.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Use a native hr for separator semantics and borders for visibility in forced colours. */\n/** Which way the rule runs. */\nexport type SeparatorOrientation = 'horizontal' | 'vertical'\n\ninterface SeparatorProps {\n /** The direction the rule runs in: across by default, or down the page under `vertical`. */\n orientation?: SeparatorOrientation\n}\n\nwithDefaults(defineProps<SeparatorProps>(), {\n orientation: 'horizontal',\n})\n</script>\n\n<template>\n <!--\n Aria-orientation is emitted only when it CONTRADICTS what the role already implies: a\n separator is horizontal by default, so stating it would merely restate the role. This is the\n same convention the VTabs tablist follows.\n -->\n <hr\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n />\n</template>\n\n<style>\n@layer vectis.components {\n .v-separator {\n flex: none;\n /*\n * `.v-menu-separator` and `.v-listbox-separator` override that margin from THEIR own\n * sheet, and which of the two sheets the consumer's bundler puts last is not ours to\n * decide. Both are therefore written as the compound `.v-separator.v-x-separator`, and\n * every declaration added here falls under the same obligation.\n */\n margin: 0;\n border: 0 solid var(--vectis-color-border);\n }\n\n .v-separator[data-orientation='horizontal'] {\n border-block-start-width: 1px;\n }\n\n /*\n * In ordinary flow it collapses to nothing, silently and with no error; there it is up to the\n * consumer to give it a block-size.\n */\n .v-separator[data-orientation='vertical'] {\n align-self: stretch;\n border-inline-start-width: 1px;\n }\n}\n</style>\n"],"mappings":";;;;;;oBAqBEA,EAAA,GAAAC,EAIE,MAAA;GAHA,OAAM;GACL,oBAAkBK,EAAA;GAClB,oBAAkBA,EAAA,gBAAW,aAAA,aAA+B,KAAA"}
1
+ {"version":3,"file":"VSeparator.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeStyle","_createElementVNode","_createBlock","VIcon","_normalizeProps","_mergeProps","_unref","_createCommentVNode","_renderSlot","_createTextVNode","_toDisplayString","VIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","VSeparator_vue_vue_type_script_setup_true_lang_default","slots","useSlots","hasSlot","__props","openBlock","createElementBlock","normalizeStyle","createElementVNode","createBlock","normalizeProps","mergeProps","unref","iconProps","createCommentVNode","renderSlot","_ctx","createTextVNode","toDisplayString"],"sources":["../../../src/components/VSeparator/VSeparator.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Use a native hr for separator semantics and borders for visibility in forced colours. */\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\n/** Which way the rule runs. */\nexport type SeparatorOrientation = 'horizontal' | 'vertical'\n/** How the rule is stroked. */\nexport type SeparatorVariant = 'solid' | 'dashed' | 'dotted'\n/** Where the content sits along the rule. */\nexport type SeparatorContentPosition = 'start' | 'center' | 'end'\n/** How thick the rule is. */\nexport type SeparatorSize = 'sm' | 'md' | 'lg'\n\ninterface SeparatorProps {\n /** The direction the rule runs in: across by default, or down the page under `vertical`. */\n orientation?: SeparatorOrientation\n /** How the rule is stroked: a continuous line, dashes or dots. */\n variant?: SeparatorVariant\n /**\n * How thick the rule is: a 1px hairline (`sm`, the default), 2px or 4px. A thicker rule marks\n * a stronger break, and makes `dotted` read as dots.\n */\n size?: SeparatorSize\n /**\n * A colour of your own (hex, CSS name or `oklch()`) for the rule. The label and icon keep the\n * muted text colour, so their contrast stays the design system's.\n */\n color?: string\n /** Visible text breaking the rule. It also becomes the separator's accessible name. */\n label?: string\n /** An icon breaking the rule, before the label when both are set (the VIcon contract). */\n icon?: IconSource\n /** Where the label and icon sit along the rule: its start, centre or end. */\n contentPosition?: SeparatorContentPosition\n}\n\nwithDefaults(defineProps<SeparatorProps>(), {\n orientation: 'horizontal',\n variant: 'solid',\n size: 'sm',\n color: undefined,\n label: undefined,\n icon: undefined,\n contentPosition: 'center',\n})\n\nconst slots = defineSlots<{\n /** Rich content breaking the rule, after the icon and in place of the label. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive.\nfunction hasSlot() {\n return slots.default !== undefined\n}\n</script>\n\n<template>\n <!--\n Aria-orientation is emitted only when it CONTRADICTS what the role already implies: a\n separator is horizontal by default, so stating it would merely restate the role. This is the\n same convention the VTabs tablist follows.\n -->\n <hr\n v-if=\"!label && !icon && !hasSlot()\"\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :data-variant=\"variant\"\n :data-size=\"size\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n :style=\"color !== undefined ? { '--separator-color': color } : undefined\"\n />\n <!--\n An <hr> cannot hold content. A separator's children are presentational, so the label is\n repeated as its accessible name; slot-only content is named by the consumer's aria-label.\n -->\n <div\n v-else\n role=\"separator\"\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :data-variant=\"variant\"\n :data-size=\"size\"\n :data-content-position=\"contentPosition\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n :aria-label=\"label\"\n :style=\"color !== undefined ? { '--separator-color': color } : undefined\"\n >\n <span class=\"v-separator-content\">\n <VIcon v-if=\"icon\" v-bind=\"iconProps(icon)\" />\n <slot>{{ label }}</slot>\n </span>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-separator {\n --separator-color: var(--vectis-color-border);\n --separator-thickness: var(--vectis-control-size-separator-sm);\n\n flex: none;\n /*\n * `.v-menu-separator` and `.v-listbox-separator` override that margin from THEIR own\n * sheet, and which of the two sheets the consumer's bundler puts last is not ours to\n * decide. Both are therefore written as the compound `.v-separator.v-x-separator`, and\n * every declaration added here falls under the same obligation.\n */\n margin: 0;\n border: 0 solid var(--separator-color);\n }\n\n .v-separator[data-size='md'] {\n --separator-thickness: var(--vectis-control-size-separator-md);\n }\n\n .v-separator[data-size='lg'] {\n --separator-thickness: var(--vectis-control-size-separator-lg);\n }\n\n .v-separator[data-variant='dashed'] {\n border-style: dashed;\n }\n\n .v-separator[data-variant='dotted'] {\n border-style: dotted;\n }\n\n /*\n * In ordinary flow it collapses to nothing, silently and with no error; there it is up to the\n * consumer to give it a block-size.\n */\n .v-separator[data-orientation='vertical'] {\n align-self: stretch;\n }\n\n hr.v-separator[data-orientation='horizontal'] {\n border-block-start-width: var(--separator-thickness);\n }\n\n hr.v-separator[data-orientation='vertical'] {\n border-inline-start-width: var(--separator-thickness);\n }\n\n /* With content, the root only lays out; its two pseudo-elements are the strokes. */\n div.v-separator {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-3);\n color: var(--vectis-color-text-muted);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n }\n\n div.v-separator::before,\n div.v-separator::after {\n content: '';\n flex: 1;\n /* The initial width is `medium` (3px): every side but the stroke's must be zeroed. */\n border-width: 0;\n border-color: inherit;\n border-style: inherit;\n }\n\n div.v-separator[data-orientation='horizontal']::before,\n div.v-separator[data-orientation='horizontal']::after {\n border-block-start-width: var(--separator-thickness);\n }\n\n div.v-separator[data-orientation='vertical'] {\n flex-direction: column;\n }\n\n div.v-separator[data-orientation='vertical']::before,\n div.v-separator[data-orientation='vertical']::after {\n border-inline-start-width: var(--separator-thickness);\n }\n\n div.v-separator[data-content-position='start']::before,\n div.v-separator[data-content-position='end']::after {\n display: none;\n }\n\n .v-separator-content {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDA,IAAMmB,IAAQnB,EAAA;EAMd,SAASqB,IAAU;GACjB,OAAOF,EAAM,YAAY,KAAA;EAC3B;mBAUW,CAAAG,EAAA,SAAK,CAAKA,EAAA,QAAI,CAAKD,EAAO,KADnCpB,EAAA,GAAAC,EAQE,MAAA;;GANA,OAAM;GACL,oBAAkBoB,EAAA;GAClB,gBAAcA,EAAA;GACd,aAAWA,EAAA;GACX,oBAAkBA,EAAA,gBAAW,aAAA,aAA+B,KAAA;GAC5D,OAAKnB,EAAEmB,EAAA,UAAU,KAAA,IAA6C,KAAA,IAApC,EAAA,qBAA0BA,EAAA,MAAK,CAAc;EAM1ErB,GAAAA,MAAAA,IAAAA,CAAAA,MAAAA,EAAA,GAAAC,EAgBM,OAAA;;GAdJ,MAAK;GACL,OAAM;GACL,oBAAkBoB,EAAA;GAClB,gBAAcA,EAAA;GACd,aAAWA,EAAA;GACX,yBAAuBA,EAAA;GACvB,oBAAkBA,EAAA,gBAAW,aAAA,aAA+B,KAAA;GAC5D,cAAYA,EAAA;GACZ,OAAKnB,EAAEmB,EAAA,UAAU,KAAA,IAA6C,KAAA,IAApC,EAAA,qBAA0BA,EAAA,MAAK,CAAc;EAExElB,GAAAA,CAAAA,EAGO,QAHPa,GAGO,CAFQK,EAAA,QAAbrB,EAAA,GAAAI,EAA8CC,GAAAC,EAAAC,EAAA,EAAA,KAAA,EAAA,GAAnBC,EAAAsB,CAAA,CAAS,CAACT,EAAA,IAAI,CAAA,CAAA,GAAA,MAAA,EAAA,KAAAU,EAAA,IAAA,EAAA,GACzCrB,EAAwBuB,EAAA,QAAA,WAAA,CAAA,SAAA,CAAftB,EAAAC,EAAAS,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,IAAAN,CAAA"}
@@ -10,11 +10,6 @@ interface SideNavigationProps {
10
10
  label?: string;
11
11
  /** The height of the rows, 32 or 40 pixels, inherited by every level. */
12
12
  size?: SideNavigationSize;
13
- /**
14
- * Takes 4px off the height of every row. It is a density setting and not a collapsed
15
- * icon-only rail, which this component does not offer.
16
- */
17
- compact?: boolean;
18
13
  /**
19
14
  * Keeps a single section open at a time WITHIN EACH LEVEL, which the browser does on
20
15
  * its own. It is off by default: a sidebar normally lets several sections stay open.
@@ -27,6 +22,11 @@ interface SideNavigationProps {
27
22
  * by 180°.
28
23
  */
29
24
  collapseIcon?: IconSource;
25
+ /**
26
+ * Draws a vertical line beside the subitems of each branch, under the middle of the
27
+ * parent's icon, to show which row they belong to.
28
+ */
29
+ guides?: boolean;
30
30
  }
31
31
  type __VLS_Slots = {
32
32
  /** The first level of the tree: items, groups and separators. */
@@ -35,10 +35,10 @@ type __VLS_Slots = {
35
35
  declare const __VLS_base: import('vue').DefineComponent<SideNavigationProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SideNavigationProps> & Readonly<{}>, {
36
36
  label: string;
37
37
  size: SideNavigationSize;
38
- compact: boolean;
39
38
  expandIcon: IconSource;
40
39
  collapseIcon: IconSource;
41
40
  exclusive: boolean;
41
+ guides: boolean;
42
42
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
43
43
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
44
44
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
1
- {"version":3,"file":"VSideNavigation.js","names":["_sfc_main","VSideNavigation_vue_vue_type_script_setup_true_lang_default","VSideNavigation_default"],"sources":["../../../src/components/VSideNavigation/VSideNavigation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @keyboard @core\n/**\n * Native details folds branches; JavaScript bridges open models and adds arrow navigation\n * without replacing native links or buttons.\n */\n\nimport { provide, ref, useId } from 'vue'\n\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { arrowNavigate } from '../../utils/arrowNav'\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\n/** The height of the rows: 32 or 40 pixels. */\nexport type SideNavigationSize = 'sm' | 'md'\n\ninterface SideNavigationProps {\n /**\n * What screen readers announce for this navigation. A page often has several (a\n * main one, a sidebar, a footer) and this is what tells them apart. It falls back\n * to the design system dictionary.\n */\n label?: string\n /** The height of the rows, 32 or 40 pixels, inherited by every level. */\n size?: SideNavigationSize\n /**\n * Takes 4px off the height of every row. It is a density setting and not a collapsed\n * icon-only rail, which this component does not offer.\n */\n compact?: boolean\n /**\n * Keeps a single section open at a time WITHIN EACH LEVEL, which the browser does on\n * its own. It is off by default: a sidebar normally lets several sections stay open.\n */\n exclusive?: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon?: IconSource\n /**\n * The chevron of an open section. Leave it out and the closed one is simply rotated\n * by 180°.\n */\n collapseIcon?: IconSource\n}\n\nconst props = withDefaults(defineProps<SideNavigationProps>(), {\n label: undefined,\n size: 'md',\n compact: false,\n exclusive: false,\n expandIcon: () => expandMoreIcon,\n collapseIcon: undefined,\n})\n\ndefineSlots<{\n /** The first level of the tree: items, groups and separators. */\n default(): unknown\n}>()\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.sideNavigation.label)\n\n// The name shared by the first level's sections. Each item mints another for its own children,\n// which keeps the exclusivity local to a level (see context.ts).\nconst rootName = useId()\n\nprovide(sideNavigationKey, {\n get name() {\n return props.exclusive ? rootName : undefined\n },\n get exclusive() {\n return props.exclusive\n },\n get expandIcon() {\n return props.expandIcon\n },\n get collapseIcon() {\n return props.collapseIcon\n },\n})\n\nconst rootEl = ref<HTMLElement | null>(null)\n\n// @keyboard @a11y\n/**\n * What the arrow keys may move to: the header of a branch, and the link of a leaf. Both forms\n * of disabling have to be excluded, since `:disabled` only ever matches a button; an inert link\n * and a disabled branch header are marked with `aria-disabled` instead, exactly as in VMenu's\n * panel.\n */\nconst ROW_SELECTOR = ':is(summary, .v-side-nav-action):not(:disabled):not([aria-disabled=\"true\"])'\n\n// @keyboard @a11y\n/**\n * This cannot be left to the shared helper, which skips whatever is not displayed. The content\n * of a closed disclosure element is not hidden that way: the browser passes over it by a rule\n * of its own, and it still reports itself as displayed.\n */\nfunction reachable(el: HTMLElement, root: HTMLElement): boolean {\n for (\n let child: HTMLElement = el, parent = el.parentElement;\n parent && child !== root;\n child = parent, parent = parent.parentElement\n ) {\n if (parent.tagName === 'DETAILS' && !(parent as HTMLDetailsElement).open) {\n if (child.tagName !== 'SUMMARY') return false\n }\n }\n return true\n}\n\n// @keyboard @a11y\n/*\n * The component's only behavioural JavaScript, and it exists because nothing native moves the\n * focus from one link to the next. It follows the design system's contract: the arrows MOVE the\n * focus and never activate anything.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const root = rootEl.value\n if (!root || event.defaultPrevented) return\n // Only a key pressed on a row: a field or a menu in a row's `#end` slot is a descendant too,\n // and its caret or its own list must keep the arrows and Home/End.\n if (!(event.target as Element | null)?.matches(ROW_SELECTOR)) return\n arrowNavigate(\n event,\n root,\n () => [...root.querySelectorAll<HTMLElement>(ROW_SELECTOR)].filter((el) => reachable(el, root)),\n { vertical: true },\n )\n}\n</script>\n\n<template>\n <nav\n ref=\"rootEl\"\n class=\"v-side-nav v-control\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :aria-label=\"ariaLabel\"\n @keydown=\"onKeydown\"\n >\n <ul class=\"v-side-nav-list\">\n <slot />\n </ul>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n .v-side-nav {\n /* Every level inherits it. */\n --side-nav-indent: calc(var(--vectis-icon-size) + var(--control-gap));\n\n font-family: var(--vectis-text-family);\n }\n\n /*\n * They are laid out as flex columns and not as ordinary blocks, which removes margin\n * collapsing entirely; otherwise a group's margin could escape a branch that is closed, and\n * therefore of zero height, and push the rows apart under it.\n */\n .v-side-nav-list,\n .v-side-nav-children,\n .v-side-nav-group-list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VSideNavigation.js","names":["_sfc_main","VSideNavigation_vue_vue_type_script_setup_true_lang_default","VSideNavigation_default"],"sources":["../../../src/components/VSideNavigation/VSideNavigation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @keyboard @core\n/**\n * Native details folds branches; JavaScript bridges open models and adds arrow navigation\n * without replacing native links or buttons.\n */\n\nimport { provide, ref, useId } from 'vue'\n\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { arrowNavigate } from '../../utils/arrowNav'\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\n/** The height of the rows: 32 or 40 pixels. */\nexport type SideNavigationSize = 'sm' | 'md'\n\ninterface SideNavigationProps {\n /**\n * What screen readers announce for this navigation. A page often has several (a\n * main one, a sidebar, a footer) and this is what tells them apart. It falls back\n * to the design system dictionary.\n */\n label?: string\n /** The height of the rows, 32 or 40 pixels, inherited by every level. */\n size?: SideNavigationSize\n /**\n * Keeps a single section open at a time WITHIN EACH LEVEL, which the browser does on\n * its own. It is off by default: a sidebar normally lets several sections stay open.\n */\n exclusive?: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon?: IconSource\n /**\n * The chevron of an open section. Leave it out and the closed one is simply rotated\n * by 180°.\n */\n collapseIcon?: IconSource\n /**\n * Draws a vertical line beside the subitems of each branch, under the middle of the\n * parent's icon, to show which row they belong to.\n */\n guides?: boolean\n}\n\nconst props = withDefaults(defineProps<SideNavigationProps>(), {\n label: undefined,\n size: 'md',\n exclusive: false,\n expandIcon: () => expandMoreIcon,\n collapseIcon: undefined,\n guides: false,\n})\n\ndefineSlots<{\n /** The first level of the tree: items, groups and separators. */\n default(): unknown\n}>()\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.sideNavigation.label)\n\n// The name shared by the first level's sections. Each item mints another for its own children,\n// which keeps the exclusivity local to a level (see context.ts).\nconst rootName = useId()\n\nprovide(sideNavigationKey, {\n get name() {\n return props.exclusive ? rootName : undefined\n },\n get exclusive() {\n return props.exclusive\n },\n get expandIcon() {\n return props.expandIcon\n },\n get collapseIcon() {\n return props.collapseIcon\n },\n})\n\nconst rootEl = ref<HTMLElement | null>(null)\n\n// @keyboard @a11y\n/**\n * What the arrow keys may move to: the header of a branch, and the link of a leaf. Both forms\n * of disabling have to be excluded, since `:disabled` only ever matches a button; an inert link\n * and a disabled branch header are marked with `aria-disabled` instead, exactly as in VMenu's\n * panel.\n */\nconst ROW_SELECTOR = ':is(summary, .v-side-nav-action):not(:disabled):not([aria-disabled=\"true\"])'\n\n// @keyboard @a11y\n/**\n * This cannot be left to the shared helper, which skips whatever is not displayed. The content\n * of a closed disclosure element is not hidden that way: the browser passes over it by a rule\n * of its own, and it still reports itself as displayed.\n */\nfunction reachable(el: HTMLElement, root: HTMLElement): boolean {\n for (\n let child: HTMLElement = el, parent = el.parentElement;\n parent && child !== root;\n child = parent, parent = parent.parentElement\n ) {\n if (parent.tagName === 'DETAILS' && !(parent as HTMLDetailsElement).open) {\n if (child.tagName !== 'SUMMARY') return false\n }\n }\n return true\n}\n\n// @keyboard @a11y\n/*\n * The component's only behavioural JavaScript, and it exists because nothing native moves the\n * focus from one link to the next. It follows the design system's contract: the arrows MOVE the\n * focus and never activate anything.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const root = rootEl.value\n if (!root || event.defaultPrevented) return\n // Only a key pressed on a row: a field or a menu in a row's `#end` slot is a descendant too,\n // and its caret or its own list must keep the arrows and Home/End.\n if (!(event.target as Element | null)?.matches(ROW_SELECTOR)) return\n arrowNavigate(\n event,\n root,\n () => [...root.querySelectorAll<HTMLElement>(ROW_SELECTOR)].filter((el) => reachable(el, root)),\n { vertical: true },\n )\n}\n</script>\n\n<template>\n <nav\n ref=\"rootEl\"\n class=\"v-side-nav v-control\"\n :data-size=\"size\"\n :data-guides=\"guides ? '' : undefined\"\n :aria-label=\"ariaLabel\"\n @keydown=\"onKeydown\"\n >\n <ul class=\"v-side-nav-list\">\n <slot />\n </ul>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n .v-side-nav {\n /* Every level inherits it. */\n --side-nav-indent: calc(var(--vectis-icon-size) + var(--control-gap));\n\n font-family: var(--vectis-text-family);\n }\n\n /*\n * They are laid out as flex columns and not as ordinary blocks, which removes margin\n * collapsing entirely; otherwise a group's margin could escape a branch that is closed, and\n * therefore of zero height, and push the rows apart under it.\n */\n .v-side-nav-list,\n .v-side-nav-children,\n .v-side-nav-group-list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n}\n</style>\n"],"mappings":""}
@@ -7,23 +7,23 @@ import { createElementBlock as a, createElementVNode as o, defineComponent as s,
7
7
  //#region src/components/VSideNavigation/VSideNavigation.vue?vue&type=script&setup=true&lang.ts
8
8
  var m = [
9
9
  "data-size",
10
- "data-compact",
10
+ "data-guides",
11
11
  "aria-label"
12
12
  ], h = { class: "v-side-nav-list" }, g = ":is(summary, .v-side-nav-action):not(:disabled):not([aria-disabled=\"true\"])", _ = /*@__PURE__*/ s({
13
13
  __name: "VSideNavigation",
14
14
  props: {
15
15
  label: { default: void 0 },
16
16
  size: { default: "md" },
17
- compact: {
18
- type: Boolean,
19
- default: !1
20
- },
21
17
  exclusive: {
22
18
  type: Boolean,
23
19
  default: !1
24
20
  },
25
21
  expandIcon: { default: () => n },
26
- collapseIcon: { default: void 0 }
22
+ collapseIcon: { default: void 0 },
23
+ guides: {
24
+ type: Boolean,
25
+ default: !1
26
+ }
27
27
  },
28
28
  setup(n) {
29
29
  let s = n, _ = e(), v = t(() => s.label ?? _.value.sideNavigation.label), y = p();
@@ -55,7 +55,7 @@ var m = [
55
55
  ref: b,
56
56
  class: "v-side-nav v-control",
57
57
  "data-size": n.size,
58
- "data-compact": n.compact ? "" : void 0,
58
+ "data-guides": n.guides ? "" : void 0,
59
59
  "aria-label": f(v),
60
60
  onKeydown: S
61
61
  }, [o("ul", h, [d(e.$slots, "default")])], 40, m));
@@ -1 +1 @@
1
- {"version":3,"file":"VSideNavigation.vue_vue_type_script_setup_true_lang.js","names":["expandMoreIcon","_openBlock","_createElementBlock","_unref","_createElementVNode","_renderSlot","_hoisted_1","_hoisted_2","ROW_SELECTOR","VSideNavigation_vue_vue_type_script_setup_true_lang_default","expand_more","props","__props","m","useMessages","ariaLabel","useAriaLabel","rootName","useId","sideNavigationKey","rootEl","ref","reachable","child","el","parent","root","onKeydown","event","arrowNavigate","openBlock","createElementBlock","unref","createElementVNode","renderSlot","_ctx"],"sources":["../../../src/components/VSideNavigation/VSideNavigation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @keyboard @core\n/**\n * Native details folds branches; JavaScript bridges open models and adds arrow navigation\n * without replacing native links or buttons.\n */\n\nimport { provide, ref, useId } from 'vue'\n\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { arrowNavigate } from '../../utils/arrowNav'\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\n/** The height of the rows: 32 or 40 pixels. */\nexport type SideNavigationSize = 'sm' | 'md'\n\ninterface SideNavigationProps {\n /**\n * What screen readers announce for this navigation. A page often has several (a\n * main one, a sidebar, a footer) and this is what tells them apart. It falls back\n * to the design system dictionary.\n */\n label?: string\n /** The height of the rows, 32 or 40 pixels, inherited by every level. */\n size?: SideNavigationSize\n /**\n * Takes 4px off the height of every row. It is a density setting and not a collapsed\n * icon-only rail, which this component does not offer.\n */\n compact?: boolean\n /**\n * Keeps a single section open at a time WITHIN EACH LEVEL, which the browser does on\n * its own. It is off by default: a sidebar normally lets several sections stay open.\n */\n exclusive?: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon?: IconSource\n /**\n * The chevron of an open section. Leave it out and the closed one is simply rotated\n * by 180°.\n */\n collapseIcon?: IconSource\n}\n\nconst props = withDefaults(defineProps<SideNavigationProps>(), {\n label: undefined,\n size: 'md',\n compact: false,\n exclusive: false,\n expandIcon: () => expandMoreIcon,\n collapseIcon: undefined,\n})\n\ndefineSlots<{\n /** The first level of the tree: items, groups and separators. */\n default(): unknown\n}>()\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.sideNavigation.label)\n\n// The name shared by the first level's sections. Each item mints another for its own children,\n// which keeps the exclusivity local to a level (see context.ts).\nconst rootName = useId()\n\nprovide(sideNavigationKey, {\n get name() {\n return props.exclusive ? rootName : undefined\n },\n get exclusive() {\n return props.exclusive\n },\n get expandIcon() {\n return props.expandIcon\n },\n get collapseIcon() {\n return props.collapseIcon\n },\n})\n\nconst rootEl = ref<HTMLElement | null>(null)\n\n// @keyboard @a11y\n/**\n * What the arrow keys may move to: the header of a branch, and the link of a leaf. Both forms\n * of disabling have to be excluded, since `:disabled` only ever matches a button; an inert link\n * and a disabled branch header are marked with `aria-disabled` instead, exactly as in VMenu's\n * panel.\n */\nconst ROW_SELECTOR = ':is(summary, .v-side-nav-action):not(:disabled):not([aria-disabled=\"true\"])'\n\n// @keyboard @a11y\n/**\n * This cannot be left to the shared helper, which skips whatever is not displayed. The content\n * of a closed disclosure element is not hidden that way: the browser passes over it by a rule\n * of its own, and it still reports itself as displayed.\n */\nfunction reachable(el: HTMLElement, root: HTMLElement): boolean {\n for (\n let child: HTMLElement = el, parent = el.parentElement;\n parent && child !== root;\n child = parent, parent = parent.parentElement\n ) {\n if (parent.tagName === 'DETAILS' && !(parent as HTMLDetailsElement).open) {\n if (child.tagName !== 'SUMMARY') return false\n }\n }\n return true\n}\n\n// @keyboard @a11y\n/*\n * The component's only behavioural JavaScript, and it exists because nothing native moves the\n * focus from one link to the next. It follows the design system's contract: the arrows MOVE the\n * focus and never activate anything.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const root = rootEl.value\n if (!root || event.defaultPrevented) return\n // Only a key pressed on a row: a field or a menu in a row's `#end` slot is a descendant too,\n // and its caret or its own list must keep the arrows and Home/End.\n if (!(event.target as Element | null)?.matches(ROW_SELECTOR)) return\n arrowNavigate(\n event,\n root,\n () => [...root.querySelectorAll<HTMLElement>(ROW_SELECTOR)].filter((el) => reachable(el, root)),\n { vertical: true },\n )\n}\n</script>\n\n<template>\n <nav\n ref=\"rootEl\"\n class=\"v-side-nav v-control\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :aria-label=\"ariaLabel\"\n @keydown=\"onKeydown\"\n >\n <ul class=\"v-side-nav-list\">\n <slot />\n </ul>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n .v-side-nav {\n /* Every level inherits it. */\n --side-nav-indent: calc(var(--vectis-icon-size) + var(--control-gap));\n\n font-family: var(--vectis-text-family);\n }\n\n /*\n * They are laid out as flex columns and not as ordinary blocks, which removes margin\n * collapsing entirely; otherwise a group's margin could escape a branch that is closed, and\n * therefore of zero height, and push the rows apart under it.\n */\n .v-side-nav-list,\n .v-side-nav-children,\n .v-side-nav-group-list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;qCA6FMQ,IAAe;;;;;;;;;;;;;;;;;EA7CrB,IAAMG,IAAQC,GAcRC,IAAIC,EAAY,GAChBC,IAAYC,QAAmBL,EAAM,SAASE,EAAE,MAAM,eAAe,KAAK,GAI1EI,IAAWC,EAAM;EAEvB,EAAQC,GAAmB;GACzB,IAAI,OAAO;IACT,OAAOR,EAAM,YAAYM,IAAW,KAAA;GACtC;GACA,IAAI,YAAY;IACd,OAAON,EAAM;GACf;GACA,IAAI,aAAa;IACf,OAAOA,EAAM;GACf;GACA,IAAI,eAAe;IACjB,OAAOA,EAAM;GACf;EACF,CAAC;EAED,IAAMS,IAASC,EAAwB,IAAI;EAiB3C,SAASC,EAAU,GAAiB,GAA4B;GAC9D,KACE,IAAIC,IAAqBC,GAAIC,IAASD,EAAG,eACzCC,KAAUF,MAAUG,GACpB,IAAQD,GAAQ,IAASA,EAAO,eAEhC,IAAIA,EAAO,YAAY,aAAa,CAAEA,EAA8B,QAC9DF,EAAM,YAAY,WAAW,OAAO;GAG5C,OAAO;EACT;EAQA,SAASI,EAAU,GAAsB;GACvC,IAAMD,IAAON,EAAO;GACpB,AAAKM,KAAQ,GAAM,oBAGbE,EAAM,QAA2B,QAAQpB,CAAY,KAC3DqB,EACED,GACAF,SACM,CAAC,GAAGA,EAAK,iBAA8BlB,CAAY,CAAC,CAAC,CAAC,QAAQ,MAAOc,EAAUE,GAAIE,CAAI,CAAC,GAC9F,EAAE,UAAU,GAAK,CACnB;EACF;oBAIEzB,EAAA,GAAAC,EAWM,OAAA;GAVA,SAAA;GAAJ,KAAIkB;GACJ,OAAM;GACL,aAAWR,EAAA;GACX,gBAAcA,EAAA,UAAO,KAAQ,KAAA;GAC7B,cAAYT,EAAAY,CAAA;GACH;EAEVX,GAAAA,CAAAA,EAEK,MAFLG,GAEK,CADHF,EAAQ8B,EAAA,QAAA,SAAA,CAAA,CAAA,CAAA,GAAA,IAAA7B,CAAA"}
1
+ {"version":3,"file":"VSideNavigation.vue_vue_type_script_setup_true_lang.js","names":["expandMoreIcon","_openBlock","_createElementBlock","_unref","_createElementVNode","_renderSlot","_hoisted_1","_hoisted_2","ROW_SELECTOR","VSideNavigation_vue_vue_type_script_setup_true_lang_default","expand_more","props","__props","m","useMessages","ariaLabel","useAriaLabel","rootName","useId","sideNavigationKey","rootEl","ref","reachable","child","el","parent","root","onKeydown","event","arrowNavigate","openBlock","createElementBlock","unref","createElementVNode","renderSlot","_ctx"],"sources":["../../../src/components/VSideNavigation/VSideNavigation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @keyboard @core\n/**\n * Native details folds branches; JavaScript bridges open models and adds arrow navigation\n * without replacing native links or buttons.\n */\n\nimport { provide, ref, useId } from 'vue'\n\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { arrowNavigate } from '../../utils/arrowNav'\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages } from '../../i18n/state'\n\n/** The height of the rows: 32 or 40 pixels. */\nexport type SideNavigationSize = 'sm' | 'md'\n\ninterface SideNavigationProps {\n /**\n * What screen readers announce for this navigation. A page often has several (a\n * main one, a sidebar, a footer) and this is what tells them apart. It falls back\n * to the design system dictionary.\n */\n label?: string\n /** The height of the rows, 32 or 40 pixels, inherited by every level. */\n size?: SideNavigationSize\n /**\n * Keeps a single section open at a time WITHIN EACH LEVEL, which the browser does on\n * its own. It is off by default: a sidebar normally lets several sections stay open.\n */\n exclusive?: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon?: IconSource\n /**\n * The chevron of an open section. Leave it out and the closed one is simply rotated\n * by 180°.\n */\n collapseIcon?: IconSource\n /**\n * Draws a vertical line beside the subitems of each branch, under the middle of the\n * parent's icon, to show which row they belong to.\n */\n guides?: boolean\n}\n\nconst props = withDefaults(defineProps<SideNavigationProps>(), {\n label: undefined,\n size: 'md',\n exclusive: false,\n expandIcon: () => expandMoreIcon,\n collapseIcon: undefined,\n guides: false,\n})\n\ndefineSlots<{\n /** The first level of the tree: items, groups and separators. */\n default(): unknown\n}>()\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.sideNavigation.label)\n\n// The name shared by the first level's sections. Each item mints another for its own children,\n// which keeps the exclusivity local to a level (see context.ts).\nconst rootName = useId()\n\nprovide(sideNavigationKey, {\n get name() {\n return props.exclusive ? rootName : undefined\n },\n get exclusive() {\n return props.exclusive\n },\n get expandIcon() {\n return props.expandIcon\n },\n get collapseIcon() {\n return props.collapseIcon\n },\n})\n\nconst rootEl = ref<HTMLElement | null>(null)\n\n// @keyboard @a11y\n/**\n * What the arrow keys may move to: the header of a branch, and the link of a leaf. Both forms\n * of disabling have to be excluded, since `:disabled` only ever matches a button; an inert link\n * and a disabled branch header are marked with `aria-disabled` instead, exactly as in VMenu's\n * panel.\n */\nconst ROW_SELECTOR = ':is(summary, .v-side-nav-action):not(:disabled):not([aria-disabled=\"true\"])'\n\n// @keyboard @a11y\n/**\n * This cannot be left to the shared helper, which skips whatever is not displayed. The content\n * of a closed disclosure element is not hidden that way: the browser passes over it by a rule\n * of its own, and it still reports itself as displayed.\n */\nfunction reachable(el: HTMLElement, root: HTMLElement): boolean {\n for (\n let child: HTMLElement = el, parent = el.parentElement;\n parent && child !== root;\n child = parent, parent = parent.parentElement\n ) {\n if (parent.tagName === 'DETAILS' && !(parent as HTMLDetailsElement).open) {\n if (child.tagName !== 'SUMMARY') return false\n }\n }\n return true\n}\n\n// @keyboard @a11y\n/*\n * The component's only behavioural JavaScript, and it exists because nothing native moves the\n * focus from one link to the next. It follows the design system's contract: the arrows MOVE the\n * focus and never activate anything.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const root = rootEl.value\n if (!root || event.defaultPrevented) return\n // Only a key pressed on a row: a field or a menu in a row's `#end` slot is a descendant too,\n // and its caret or its own list must keep the arrows and Home/End.\n if (!(event.target as Element | null)?.matches(ROW_SELECTOR)) return\n arrowNavigate(\n event,\n root,\n () => [...root.querySelectorAll<HTMLElement>(ROW_SELECTOR)].filter((el) => reachable(el, root)),\n { vertical: true },\n )\n}\n</script>\n\n<template>\n <nav\n ref=\"rootEl\"\n class=\"v-side-nav v-control\"\n :data-size=\"size\"\n :data-guides=\"guides ? '' : undefined\"\n :aria-label=\"ariaLabel\"\n @keydown=\"onKeydown\"\n >\n <ul class=\"v-side-nav-list\">\n <slot />\n </ul>\n </nav>\n</template>\n\n<style>\n@layer vectis.components {\n .v-side-nav {\n /* Every level inherits it. */\n --side-nav-indent: calc(var(--vectis-icon-size) + var(--control-gap));\n\n font-family: var(--vectis-text-family);\n }\n\n /*\n * They are laid out as flex columns and not as ordinary blocks, which removes margin\n * collapsing entirely; otherwise a group's margin could escape a branch that is closed, and\n * therefore of zero height, and push the rows apart under it.\n */\n .v-side-nav-list,\n .v-side-nav-children,\n .v-side-nav-group-list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;qCA6FMQ,IAAe;;;;;;;;;;;;;;;;;EA7CrB,IAAMG,IAAQC,GAcRC,IAAIC,EAAY,GAChBC,IAAYC,QAAmBL,EAAM,SAASE,EAAE,MAAM,eAAe,KAAK,GAI1EI,IAAWC,EAAM;EAEvB,EAAQC,GAAmB;GACzB,IAAI,OAAO;IACT,OAAOR,EAAM,YAAYM,IAAW,KAAA;GACtC;GACA,IAAI,YAAY;IACd,OAAON,EAAM;GACf;GACA,IAAI,aAAa;IACf,OAAOA,EAAM;GACf;GACA,IAAI,eAAe;IACjB,OAAOA,EAAM;GACf;EACF,CAAC;EAED,IAAMS,IAASC,EAAwB,IAAI;EAiB3C,SAASC,EAAU,GAAiB,GAA4B;GAC9D,KACE,IAAIC,IAAqBC,GAAIC,IAASD,EAAG,eACzCC,KAAUF,MAAUG,GACpB,IAAQD,GAAQ,IAASA,EAAO,eAEhC,IAAIA,EAAO,YAAY,aAAa,CAAEA,EAA8B,QAC9DF,EAAM,YAAY,WAAW,OAAO;GAG5C,OAAO;EACT;EAQA,SAASI,EAAU,GAAsB;GACvC,IAAMD,IAAON,EAAO;GACpB,AAAKM,KAAQ,GAAM,oBAGbE,EAAM,QAA2B,QAAQpB,CAAY,KAC3DqB,EACED,GACAF,SACM,CAAC,GAAGA,EAAK,iBAA8BlB,CAAY,CAAC,CAAC,CAAC,QAAQ,MAAOc,EAAUE,GAAIE,CAAI,CAAC,GAC9F,EAAE,UAAU,GAAK,CACnB;EACF;oBAIEzB,EAAA,GAAAC,EAWM,OAAA;GAVA,SAAA;GAAJ,KAAIkB;GACJ,OAAM;GACL,aAAWR,EAAA;GACX,eAAaA,EAAA,SAAM,KAAQ,KAAA;GAC3B,cAAYT,EAAAY,CAAA;GACH;EAEVX,GAAAA,CAAAA,EAEK,MAFLG,GAEK,CADHF,EAAQ8B,EAAA,QAAA,SAAA,CAAA,CAAA,CAAA,GAAA,IAAA7B,CAAA"}
@@ -1,2 +1,2 @@
1
1
  @layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
2
- @layer vectis.components{.v-side-nav-item{--side-nav-parent-level:var(--side-nav-level,0)}.v-side-nav-children{--side-nav-level:calc(var(--side-nav-parent-level) + 1)}.v-side-nav-row{--side-nav-row-radius:min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));align-items:center;gap:var(--control-gap);min-block-size:var(--control-height);padding-block:var(--vectis-space-1);padding-inline:calc(var(--control-padding-inline) + var(--side-nav-level,0) * var(--side-nav-indent)) var(--control-padding-inline);border-radius:var(--side-nav-row-radius);color:var(--vectis-color-text);font-size:var(--control-font-size);line-height:var(--vectis-text-body-md-leading);cursor:pointer;display:flex;position:relative}.v-side-nav-action{align-items:center;gap:var(--control-gap);min-inline-size:0;color:inherit;font-family:inherit;font-size:inherit;line-height:inherit;text-align:start;cursor:inherit;background:0 0;border:none;flex:1;padding:0;text-decoration:none;display:flex}.v-side-nav-action:after{content:"";border-radius:var(--side-nav-row-radius);position:absolute;inset:0}.v-side-nav-content{flex-direction:column;flex:1;min-inline-size:0;display:flex}.v-side-nav-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.v-side-nav-sublabel{font-size:var(--vectis-text-caption-size);color:var(--vectis-color-text-muted);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.v-side-nav-icon{color:var(--vectis-color-text-muted);flex:none}.v-side-nav-end{align-items:center;gap:var(--vectis-space-1);flex:none;display:flex;position:relative}.v-side-nav-row:hover:not([data-disabled]){background:var(--vectis-color-surface-muted)}.v-side-nav-row:focus-visible,.v-side-nav-action:focus-visible:after{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:calc(-1 * var(--vectis-focus-ring-width))}.v-side-nav-action:focus-visible{outline:none}.v-side-nav-row[data-current]{background:var(--vectis-color-accent-surface);color:var(--vectis-color-accent-text)}.v-side-nav-row[data-current] .v-side-nav-label{font-weight:var(--vectis-text-label-weight)}.v-side-nav-row[data-current] .v-side-nav-icon,.v-side-nav-row[data-current] .v-side-nav-sublabel,.v-side-nav-row[data-current] .v-side-nav-chevron{color:inherit}.v-side-nav-row[data-current]:not([data-disabled]):hover{background:color-mix(in oklab, var(--vectis-color-accent-surface), var(--vectis-color-accent-text) 8%)}.v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])>.v-side-nav-row:not([data-current],[data-disabled]){color:var(--vectis-color-accent-text)}.v-side-nav-row[data-disabled]{color:var(--vectis-color-text-subtle);cursor:not-allowed}.v-side-nav-row[data-disabled] .v-side-nav-icon,.v-side-nav-row[data-disabled] .v-side-nav-sublabel{color:inherit}@media (forced-colors:active){.v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current]{forced-color-adjust:none;color:highlighttext;background:highlight}.v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current][data-disabled]{color:graytext;background:canvas}.v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])>.v-side-nav-row:not([data-current],[data-disabled]) .v-side-nav-label{text-decoration:underline}}}
2
+ @layer vectis.components{.v-side-nav-item{--side-nav-parent-level:var(--side-nav-level,0)}.v-side-nav-children{--side-nav-level:calc(var(--side-nav-parent-level) + 1)}.v-side-nav-row{--side-nav-row-radius:min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));align-items:center;gap:var(--control-gap);min-block-size:var(--control-height);padding-block:var(--vectis-space-1);padding-inline:calc(var(--control-padding-inline) + var(--side-nav-level,0) * var(--side-nav-indent)) var(--control-padding-inline);border-radius:var(--side-nav-row-radius);color:var(--vectis-color-text);font-size:var(--control-font-size);line-height:var(--vectis-text-body-md-leading);cursor:pointer;display:flex;position:relative}.v-side-nav-action{align-items:center;gap:var(--control-gap);min-inline-size:0;color:inherit;font-family:inherit;font-size:inherit;line-height:inherit;text-align:start;cursor:inherit;background:0 0;border:none;flex:1;padding:0;text-decoration:none;display:flex}.v-side-nav-action:after{content:"";border-radius:var(--side-nav-row-radius);position:absolute;inset:0}.v-side-nav-content{flex-direction:column;flex:1;min-inline-size:0;display:flex}.v-side-nav-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.v-side-nav-sublabel{font-size:var(--vectis-text-caption-size);color:var(--vectis-color-text-muted);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.v-side-nav-icon{color:var(--vectis-color-text-muted);flex:none}.v-side-nav-end{align-items:center;gap:var(--vectis-space-1);flex:none;display:flex;position:relative}.v-side-nav-row:hover:not([data-disabled]){background:var(--vectis-color-surface-muted)}.v-side-nav-row:focus-visible,.v-side-nav-action:focus-visible:after{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:calc(-1 * var(--vectis-focus-ring-width))}.v-side-nav-action:focus-visible{outline:none}.v-side-nav-row[data-current]{background:var(--vectis-color-accent-surface);color:var(--vectis-color-accent-text)}.v-side-nav-row[data-current] .v-side-nav-label{font-weight:var(--vectis-text-label-weight)}.v-side-nav-row[data-current] .v-side-nav-icon,.v-side-nav-row[data-current] .v-side-nav-sublabel,.v-side-nav-row[data-current] .v-side-nav-chevron{color:inherit}.v-side-nav-row[data-current]:not([data-disabled]):hover{background:color-mix(in oklab, var(--vectis-color-accent-surface), var(--vectis-color-accent-text) 8%)}.v-side-nav[data-guides] .v-side-nav-children{position:relative}.v-side-nav[data-guides] .v-side-nav-children:before{content:"";border-inline-start:1px solid var(--vectis-color-border);position:absolute;inset-block:0;inset-inline-start:calc(var(--control-padding-inline) + var(--side-nav-parent-level) * var(--side-nav-indent) + var(--vectis-icon-size) / 2)}.v-side-nav[data-guides] .v-side-nav-children .v-side-nav-row{margin-inline-start:calc(var(--control-padding-inline) + (var(--side-nav-level) - 1) * var(--side-nav-indent) + var(--vectis-icon-size) / 2 + var(--control-gap));padding-inline-start:calc(var(--vectis-icon-size) / 2)}.v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])>.v-side-nav-row:not([data-current],[data-disabled]){color:var(--vectis-color-accent-text)}.v-side-nav-row[data-disabled]{color:var(--vectis-color-text-subtle);cursor:not-allowed}.v-side-nav-row[data-disabled] .v-side-nav-icon,.v-side-nav-row[data-disabled] .v-side-nav-sublabel{color:inherit}@media (forced-colors:active){.v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current]{forced-color-adjust:none;color:highlighttext;background:highlight}.v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current][data-disabled]{color:graytext;background:canvas}.v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])>.v-side-nav-row:not([data-current],[data-disabled]) .v-side-nav-label{text-decoration:underline}}}
@@ -1 +1 @@
1
- {"version":3,"file":"VSideNavigationItem.js","names":["_sfc_main","VSideNavigationItem_vue_vue_type_script_setup_true_lang_default","VSideNavigationItem_default"],"sources":["../../../src/components/VSideNavigation/VSideNavigationItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Branches use native details and leaves use links or buttons. JavaScript synchronizes open\n * state, disables summaries and makes disabled links inert.\n */\n\nimport { computed, inject, provide, ref, useId, useSlots } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { useDetailsOpen } from '../../composables/useDetailsOpen'\nimport { useInertLink } from '../../composables/useInertLink'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\ninterface SideNavigationItemProps {\n /** What the row says, and where it goes. The default slot replaces it. */\n label?: string\n /** A second line under the label, for a status or a short explanation. */\n sublabel?: string\n /**\n * An icon before the label: an icon name, or an explicit render. The `#icon` slot\n * replaces it.\n */\n icon?: IconSource\n /**\n * Where this row leads, which makes it a link. It is IGNORED on a row that has\n * subitems: such a row opens and closes rather than navigating.\n */\n href?: string\n /**\n * Marks this row as the page currently being viewed. It is highlighted, and\n * announced as the current page (`aria-current`).\n */\n current?: boolean\n /**\n * Makes the row unusable: it greys out through the colour tokens and leaves the\n * keyboard path.\n */\n disabled?: boolean\n /** Renders a branch already open. Bind `v-model:open` to drive it instead. */\n defaultOpen?: boolean\n}\n\n// Without redirecting them, `target`, `rel`, `download` and the aria-* would land on that list\n// item instead of on the link or the branch header.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SideNavigationItemProps>(), {\n label: undefined,\n sublabel: undefined,\n icon: undefined,\n href: undefined,\n current: false,\n disabled: false,\n defaultOpen: false,\n})\n\n// \"not bound\" is written as `null` and not `undefined`. A model typed as a plain boolean is\n// declared as such at runtime, and Vue casts an ABSENT boolean prop to `false`, which would\n// silently overwrite `defaultOpen` on every branch.\n/**\n * Whether the branch is open, when the consumer wants to drive or observe it. Left\n * unbound, the browser keeps that state to itself, `defaultOpen` giving only the initial\n * value. `null` means unbound.\n */\nconst open = defineModel<boolean | null>('open', { default: null })\n\nconst emit = defineEmits<{\n // Never declare a `click` emit alongside it. Vue removes a declared event from the forwarded\n // attributes, and a consumer's own `@click` would then stop reaching the link entirely.\n /** A row WITHOUT subitems was activated, by click or by keyboard. */\n select: []\n}>()\n\ndefineSlots<{\n /**\n * The label of the row, replacing the `label` prop. One of the two is REQUIRED: a\n * navigation row must say where it goes.\n */\n default?(): unknown\n /** A second line made of markup, replacing the `sublabel` prop. */\n sublabel?(): unknown\n /** Free content before the label, which takes the place of `icon`. */\n icon?(): unknown\n /**\n * Free content at the end of the row, before the chevron: a counter, a badge. On a\n * BRANCH it must not be focusable, a control inside the header being a control nested\n * inside another.\n */\n end?(): unknown\n /**\n * The subitems, which turn this row into a branch. Nesting is not limited. The slot\n * must be statically present or absent: whether a row is a branch is decided when it\n * is created.\n */\n children?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst slots = useSlots()\nconst tag = computed(() => (props.href !== undefined ? 'a' : 'button'))\n\nconst parent = inject(sideNavigationKey, null)\n\n/**\n * Both chevrons are chosen on the navigation as a whole. The fallback is what keeps an\n * item rendering correctly when it is used outside one.\n */\nconst expandIcon = computed(() => parent?.expandIcon ?? expandMoreIcon)\nconst collapseIcon = computed(() => parent?.collapseIcon)\n\n// @ssr\n// Each level owns its exclusive group, including children supplied after the first render.\nconst childrenName = useId()\nprovide(sideNavigationKey, {\n get name() {\n return parent?.exclusive ? childrenName : undefined\n },\n get exclusive() {\n return parent?.exclusive ?? false\n },\n get expandIcon() {\n return expandIcon.value\n },\n get collapseIcon() {\n return collapseIcon.value\n },\n})\n\nconst { openAttr, onToggle, onSummaryClick } = useDetailsOpen(open, {\n defaultOpen: () => props.defaultOpen,\n disabled: () => props.disabled,\n})\n\n/*\n * Stopping the event from travelling would not help: folding is not a listener anyone\n * registered, it is the click's default action, and only cancelling that prevents it. The\n * exception is a click that already landed on something activable.\n */\n// @core\nfunction onEndClick(event: MouseEvent) {\n const target = event.target as Element | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n}\n\n// A template ref on the item reaches the list item, a layout box; what is focused and\n// named is its row: the branch header, or the leaf's link or button.\nconst rowEl = ref<HTMLElement | null>(null)\nconst actionEl = ref<HTMLElement | null>(null)\nconst control = () => (slots.children ? rowEl.value : actionEl.value)\ndefineExpose({\n /** Moves the focus to the row: the branch header, or the leaf's link or button. */\n focus: (options?: FocusOptions) => control()?.focus(options),\n /** The row, which is also where the consumer's attributes land. */\n get el() {\n return control()\n },\n})\n\n// @a11y\n// A leaf link has no `disabled`: the address, the consumer's click listeners and the\n// generic role of an `<a>` without `href` are handled by the shared inert link.\nconst link = useInertLink({\n href: () => (tag.value === 'a' ? props.href : undefined),\n inert: () => props.disabled,\n attrs: () => forwardedAttrs.value,\n})\n\n// @core\nfunction onActionClick(event: MouseEvent) {\n // A disabled button never receives the click at all; an inert link does, so it is\n // cancelled here.\n if (props.disabled) {\n event.preventDefault()\n return\n }\n emit('select')\n}\n</script>\n\n<template>\n <li class=\"v-side-nav-item\" :class=\"rootClass\" :style=\"rootStyle\">\n <details\n v-if=\"$slots.children\"\n class=\"v-side-nav-branch v-disclosure\"\n :name=\"parent?.name\"\n :open=\"openAttr\"\n :data-swap=\"collapseIcon ? '' : undefined\"\n @toggle=\"onToggle\"\n >\n <summary\n ref=\"rowEl\"\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :aria-current=\"current ? 'true' : undefined\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n v-bind=\"forwardedAttrs\"\n @click=\"onSummaryClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n <!-- This slot sits INSIDE the branch header, where ANY click folds the\n branch: without the handler, clicking a badge would close the section\n under it -->\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\" @click=\"onEndClick\"\n ><slot name=\"end\"\n /></span>\n <VIcon class=\"v-side-nav-chevron v-disclosure-chevron\" v-bind=\"iconProps(expandIcon)\" />\n <VIcon\n v-if=\"collapseIcon\"\n class=\"v-side-nav-chevron v-side-nav-chevron-open v-disclosure-chevron v-disclosure-chevron-open\"\n v-bind=\"iconProps(collapseIcon)\"\n />\n </summary>\n <ul class=\"v-side-nav-children\">\n <slot name=\"children\" />\n </ul>\n </details>\n\n <div\n v-else\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <component\n :is=\"tag\"\n ref=\"actionEl\"\n class=\"v-side-nav-action\"\n :type=\"tag === 'button' ? 'button' : undefined\"\n :disabled=\"tag === 'button' ? disabled : undefined\"\n :aria-disabled=\"link.isInertLink.value ? 'true' : undefined\"\n :aria-current=\"current ? (tag === 'a' ? 'page' : 'true') : undefined\"\n v-bind=\"link.attrs.value\"\n :href=\"link.linkHref.value\"\n @click=\"onActionClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n </component>\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\"><slot name=\"end\" /></span>\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The obvious one-name form, incrementing a variable by reading itself, is a CYCLE as far as\n * CSS is concerned, even though the value being read is the inherited one. The property then\n * falls to invalid, every read falls back to zero, and the whole tree renders FLAT; with\n * nothing in the console to say why.\n */\n .v-side-nav-item {\n --side-nav-parent-level: var(--side-nav-level, 0);\n }\n\n .v-side-nav-children {\n --side-nav-level: calc(var(--side-nav-parent-level) + 1);\n }\n\n .v-side-nav-row {\n /*\n * The indent is computed here and not stored in a variable set higher up. A custom property\n * is substituted on the element that DECLARES it, so a padding computed on the nav would be\n * frozen at level zero for the whole tree.\n */\n\n /*\n * The cap has to stay derived from --control-height. A browser scales down any radius it\n * cannot fit, so a row exactly one control tall already paints half that height under a\n * pill override; min() applies the same reduction to a row that grew past it.\n */\n --side-nav-row-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n min-block-size: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline: calc(\n var(--control-padding-inline) + var(--side-nav-level, 0) * var(--side-nav-indent)\n )\n var(--control-padding-inline);\n border-radius: var(--side-nav-row-radius);\n color: var(--vectis-color-text);\n font-size: var(--control-font-size);\n line-height: var(--vectis-text-body-md-leading);\n cursor: pointer;\n }\n\n .v-side-nav-action {\n /* On a leaf the link is a CHILD of the row, and the indent deliberately stays on\n the row itself: what has to run the full width is the hover background, not the\n link inside it. */\n flex: 1;\n min-inline-size: 0;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n cursor: inherit;\n }\n\n /*\n * This is what stretches the link over the whole row without having to wrap the end slot\n * inside it. It is an invisible box, positioned, so it is painted above the chevron; which is\n * not positioned; while passing UNDER the end slot, which is positioned too and comes later\n * in the document.\n */\n .v-side-nav-action::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--side-nav-row-radius);\n }\n\n .v-side-nav-content {\n flex: 1;\n min-inline-size: 0;\n display: flex;\n flex-direction: column;\n }\n\n .v-side-nav-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-sublabel {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-icon {\n flex: none;\n color: var(--vectis-color-text-muted);\n }\n\n /* Positioned on purpose: that is what paints it above the stretched link, and\n therefore what keeps whatever it holds clickable. */\n .v-side-nav-end {\n position: relative;\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-side-nav-row:hover:not([data-disabled]) {\n background: var(--vectis-color-surface-muted);\n }\n\n /*\n * A branch header takes focus itself; a leaf only takes it through its link, and the\n * ring is then drawn on the stretched box so that it frames the whole row rather than\n * just the text.\n *\n * The ring is pulled INWARDS in both cases: the content of a branch is clipped so it\n * can be animated open, and a ring drawn outside the row would be cut off there.\n */\n .v-side-nav-row:focus-visible,\n .v-side-nav-action:focus-visible::after {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-side-nav-action:focus-visible {\n outline: none;\n }\n\n .v-side-nav-row[data-current] {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-label {\n font-weight: var(--vectis-text-label-weight);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-icon,\n .v-side-nav-row[data-current] .v-side-nav-sublabel,\n .v-side-nav-row[data-current] .v-side-nav-chevron {\n color: inherit;\n }\n\n .v-side-nav-row[data-current]:not([data-disabled]):hover {\n /*\n * The current row is already tinted, so its hover deepens that tint rather than replacing\n * it with the neutral highlight; the VMenuItem idiom.\n */\n background: color-mix(\n in oklab,\n var(--vectis-color-accent-surface),\n var(--vectis-color-accent-text) 8%\n );\n }\n\n /* A CLOSED branch holding the current page keeps a mark of it, so the reader can see\n where they are without opening every section. The lookup is deliberately a\n descendant one: the page may be several levels down. */\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled]) {\n color: var(--vectis-color-accent-text);\n }\n\n /* A disabled row greys out through the colour tokens, never through opacity. */\n .v-side-nav-row[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n /* The icon and the second line default to a colour DARKER than the one a disabled\n label takes: left alone they would come out stronger than the label itself, so they\n inherit it instead. The chevron gets the same treatment from `styles/disclosure.css`. */\n .v-side-nav-row[data-disabled] .v-side-nav-icon,\n .v-side-nav-row[data-disabled] .v-side-nav-sublabel {\n color: inherit;\n }\n\n /* Forced colours flatten the current row's tint to `Canvas` and its accent text to\n `CanvasText`, leaving a slightly bolder label as the only cue, and the mark on a closed\n branch is a colour alone. The current row takes the system selection pair, repeated to\n (0,4,0) above its own hover, and the closed branch underlines its label, a decoration\n the mode keeps. */\n @media (forced-colors: active) {\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current][data-disabled] {\n background: Canvas;\n color: GrayText;\n }\n\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled])\n .v-side-nav-label {\n text-decoration: underline;\n }\n }\n\n /* The disclosure animation, the chevron's rotation or swap and the WebKit marker come\n from `styles/disclosure.css`, reduced-motion block included. */\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VSideNavigationItem.js","names":["_sfc_main","VSideNavigationItem_vue_vue_type_script_setup_true_lang_default","VSideNavigationItem_default"],"sources":["../../../src/components/VSideNavigation/VSideNavigationItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Branches use native details and leaves use links or buttons. JavaScript synchronizes open\n * state, disables summaries and makes disabled links inert.\n */\n\nimport { computed, inject, provide, ref, useId, useSlots } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { useDetailsOpen } from '../../composables/useDetailsOpen'\nimport { useInertLink } from '../../composables/useInertLink'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\ninterface SideNavigationItemProps {\n /** What the row says, and where it goes. The default slot replaces it. */\n label?: string\n /** A second line under the label, for a status or a short explanation. */\n sublabel?: string\n /**\n * An icon before the label: an icon name, or an explicit render. The `#icon` slot\n * replaces it.\n */\n icon?: IconSource\n /**\n * Where this row leads, which makes it a link. It is IGNORED on a row that has\n * subitems: such a row opens and closes rather than navigating.\n */\n href?: string\n /**\n * Marks this row as the page currently being viewed. It is highlighted, and\n * announced as the current page (`aria-current`).\n */\n current?: boolean\n /**\n * Makes the row unusable: it greys out through the colour tokens and leaves the\n * keyboard path.\n */\n disabled?: boolean\n /** Renders a branch already open. Bind `v-model:open` to drive it instead. */\n defaultOpen?: boolean\n}\n\n// Without redirecting them, `target`, `rel`, `download` and the aria-* would land on that list\n// item instead of on the link or the branch header.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SideNavigationItemProps>(), {\n label: undefined,\n sublabel: undefined,\n icon: undefined,\n href: undefined,\n current: false,\n disabled: false,\n defaultOpen: false,\n})\n\n// \"not bound\" is written as `null` and not `undefined`. A model typed as a plain boolean is\n// declared as such at runtime, and Vue casts an ABSENT boolean prop to `false`, which would\n// silently overwrite `defaultOpen` on every branch.\n/**\n * Whether the branch is open, when the consumer wants to drive or observe it. Left\n * unbound, the browser keeps that state to itself, `defaultOpen` giving only the initial\n * value. `null` means unbound.\n */\nconst open = defineModel<boolean | null>('open', { default: null })\n\nconst emit = defineEmits<{\n // Never declare a `click` emit alongside it. Vue removes a declared event from the forwarded\n // attributes, and a consumer's own `@click` would then stop reaching the link entirely.\n /** A row WITHOUT subitems was activated, by click or by keyboard. */\n select: []\n}>()\n\ndefineSlots<{\n /**\n * The label of the row, replacing the `label` prop. One of the two is REQUIRED: a\n * navigation row must say where it goes.\n */\n default?(): unknown\n /** A second line made of markup, replacing the `sublabel` prop. */\n sublabel?(): unknown\n /** Free content before the label, which takes the place of `icon`. */\n icon?(): unknown\n /**\n * Free content at the end of the row, before the chevron: a counter, a badge. On a\n * BRANCH it must not be focusable, a control inside the header being a control nested\n * inside another.\n */\n end?(): unknown\n /**\n * The subitems, which turn this row into a branch. Nesting is not limited. The slot\n * must be statically present or absent: whether a row is a branch is decided when it\n * is created.\n */\n children?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst slots = useSlots()\nconst tag = computed(() => (props.href !== undefined ? 'a' : 'button'))\n\nconst parent = inject(sideNavigationKey, null)\n\n/**\n * Both chevrons are chosen on the navigation as a whole. The fallback is what keeps an\n * item rendering correctly when it is used outside one.\n */\nconst expandIcon = computed(() => parent?.expandIcon ?? expandMoreIcon)\nconst collapseIcon = computed(() => parent?.collapseIcon)\n\n// @ssr\n// Each level owns its exclusive group, including children supplied after the first render.\nconst childrenName = useId()\nprovide(sideNavigationKey, {\n get name() {\n return parent?.exclusive ? childrenName : undefined\n },\n get exclusive() {\n return parent?.exclusive ?? false\n },\n get expandIcon() {\n return expandIcon.value\n },\n get collapseIcon() {\n return collapseIcon.value\n },\n})\n\nconst { openAttr, onToggle, onSummaryClick } = useDetailsOpen(open, {\n defaultOpen: () => props.defaultOpen,\n disabled: () => props.disabled,\n})\n\n/*\n * Stopping the event from travelling would not help: folding is not a listener anyone\n * registered, it is the click's default action, and only cancelling that prevents it. The\n * exception is a click that already landed on something activable.\n */\n// @core\nfunction onEndClick(event: MouseEvent) {\n const target = event.target as Element | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n}\n\n// A template ref on the item reaches the list item, a layout box; what is focused and\n// named is its row: the branch header, or the leaf's link or button.\nconst rowEl = ref<HTMLElement | null>(null)\nconst actionEl = ref<HTMLElement | null>(null)\nconst control = () => (slots.children ? rowEl.value : actionEl.value)\ndefineExpose({\n /** Moves the focus to the row: the branch header, or the leaf's link or button. */\n focus: (options?: FocusOptions) => control()?.focus(options),\n /** The row, which is also where the consumer's attributes land. */\n get el() {\n return control()\n },\n})\n\n// @a11y\n// A leaf link has no `disabled`: the address, the consumer's click listeners and the\n// generic role of an `<a>` without `href` are handled by the shared inert link.\nconst link = useInertLink({\n href: () => (tag.value === 'a' ? props.href : undefined),\n inert: () => props.disabled,\n attrs: () => forwardedAttrs.value,\n})\n\n// @core\nfunction onActionClick(event: MouseEvent) {\n // A disabled button never receives the click at all; an inert link does, so it is\n // cancelled here.\n if (props.disabled) {\n event.preventDefault()\n return\n }\n emit('select')\n}\n</script>\n\n<template>\n <li class=\"v-side-nav-item\" :class=\"rootClass\" :style=\"rootStyle\">\n <details\n v-if=\"$slots.children\"\n class=\"v-side-nav-branch v-disclosure\"\n :name=\"parent?.name\"\n :open=\"openAttr\"\n :data-swap=\"collapseIcon ? '' : undefined\"\n @toggle=\"onToggle\"\n >\n <summary\n ref=\"rowEl\"\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :aria-current=\"current ? 'true' : undefined\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n v-bind=\"forwardedAttrs\"\n @click=\"onSummaryClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n <!-- This slot sits INSIDE the branch header, where ANY click folds the\n branch: without the handler, clicking a badge would close the section\n under it -->\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\" @click=\"onEndClick\"\n ><slot name=\"end\"\n /></span>\n <VIcon class=\"v-side-nav-chevron v-disclosure-chevron\" v-bind=\"iconProps(expandIcon)\" />\n <VIcon\n v-if=\"collapseIcon\"\n class=\"v-side-nav-chevron v-side-nav-chevron-open v-disclosure-chevron v-disclosure-chevron-open\"\n v-bind=\"iconProps(collapseIcon)\"\n />\n </summary>\n <ul class=\"v-side-nav-children\">\n <slot name=\"children\" />\n </ul>\n </details>\n\n <div\n v-else\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <component\n :is=\"tag\"\n ref=\"actionEl\"\n class=\"v-side-nav-action\"\n :type=\"tag === 'button' ? 'button' : undefined\"\n :disabled=\"tag === 'button' ? disabled : undefined\"\n :aria-disabled=\"link.isInertLink.value ? 'true' : undefined\"\n :aria-current=\"current ? (tag === 'a' ? 'page' : 'true') : undefined\"\n v-bind=\"link.attrs.value\"\n :href=\"link.linkHref.value\"\n @click=\"onActionClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n </component>\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\"><slot name=\"end\" /></span>\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The obvious one-name form, incrementing a variable by reading itself, is a CYCLE as far as\n * CSS is concerned, even though the value being read is the inherited one. The property then\n * falls to invalid, every read falls back to zero, and the whole tree renders FLAT; with\n * nothing in the console to say why.\n */\n .v-side-nav-item {\n --side-nav-parent-level: var(--side-nav-level, 0);\n }\n\n .v-side-nav-children {\n --side-nav-level: calc(var(--side-nav-parent-level) + 1);\n }\n\n .v-side-nav-row {\n /*\n * The indent is computed here and not stored in a variable set higher up. A custom property\n * is substituted on the element that DECLARES it, so a padding computed on the nav would be\n * frozen at level zero for the whole tree.\n */\n\n /*\n * The cap has to stay derived from --control-height. A browser scales down any radius it\n * cannot fit, so a row exactly one control tall already paints half that height under a\n * pill override; min() applies the same reduction to a row that grew past it.\n */\n --side-nav-row-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n min-block-size: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline: calc(\n var(--control-padding-inline) + var(--side-nav-level, 0) * var(--side-nav-indent)\n )\n var(--control-padding-inline);\n border-radius: var(--side-nav-row-radius);\n color: var(--vectis-color-text);\n font-size: var(--control-font-size);\n line-height: var(--vectis-text-body-md-leading);\n cursor: pointer;\n }\n\n .v-side-nav-action {\n /* On a leaf the link is a CHILD of the row, and the indent deliberately stays on\n the row itself: what has to run the full width is the hover background, not the\n link inside it. */\n flex: 1;\n min-inline-size: 0;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n cursor: inherit;\n }\n\n /*\n * This is what stretches the link over the whole row without having to wrap the end slot\n * inside it. It is an invisible box, positioned, so it is painted above the chevron; which is\n * not positioned; while passing UNDER the end slot, which is positioned too and comes later\n * in the document.\n */\n .v-side-nav-action::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--side-nav-row-radius);\n }\n\n .v-side-nav-content {\n flex: 1;\n min-inline-size: 0;\n display: flex;\n flex-direction: column;\n }\n\n .v-side-nav-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-sublabel {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-icon {\n flex: none;\n color: var(--vectis-color-text-muted);\n }\n\n /* Positioned on purpose: that is what paints it above the stretched link, and\n therefore what keeps whatever it holds clickable. */\n .v-side-nav-end {\n position: relative;\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-side-nav-row:hover:not([data-disabled]) {\n background: var(--vectis-color-surface-muted);\n }\n\n /*\n * A branch header takes focus itself; a leaf only takes it through its link, and the\n * ring is then drawn on the stretched box so that it frames the whole row rather than\n * just the text.\n *\n * The ring is pulled INWARDS in both cases: the content of a branch is clipped so it\n * can be animated open, and a ring drawn outside the row would be cut off there.\n */\n .v-side-nav-row:focus-visible,\n .v-side-nav-action:focus-visible::after {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-side-nav-action:focus-visible {\n outline: none;\n }\n\n .v-side-nav-row[data-current] {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-label {\n font-weight: var(--vectis-text-label-weight);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-icon,\n .v-side-nav-row[data-current] .v-side-nav-sublabel,\n .v-side-nav-row[data-current] .v-side-nav-chevron {\n color: inherit;\n }\n\n .v-side-nav-row[data-current]:not([data-disabled]):hover {\n /*\n * The current row is already tinted, so its hover deepens that tint rather than replacing\n * it with the neutral highlight; the VMenuItem idiom.\n */\n background: color-mix(\n in oklab,\n var(--vectis-color-accent-surface),\n var(--vectis-color-accent-text) 8%\n );\n }\n\n /*\n * The line sits under the middle of the parent's icon, whether or not it has one. A row\n * of the sublist then starts a gutter after the line, so its highlight never covers it, and\n * its padding takes up the rest: the label stays where the indent puts it.\n *\n * Painted with a border and not a background, which forced colours would turn to Canvas.\n */\n .v-side-nav[data-guides] .v-side-nav-children {\n position: relative;\n }\n\n .v-side-nav[data-guides] .v-side-nav-children::before {\n content: '';\n position: absolute;\n inset-block: 0;\n inset-inline-start: calc(\n var(--control-padding-inline) + var(--side-nav-parent-level) * var(--side-nav-indent) +\n var(--vectis-icon-size) / 2\n );\n border-inline-start: 1px solid var(--vectis-color-border);\n }\n\n .v-side-nav[data-guides] .v-side-nav-children .v-side-nav-row {\n margin-inline-start: calc(\n var(--control-padding-inline) + (var(--side-nav-level) - 1) * var(--side-nav-indent) +\n var(--vectis-icon-size) / 2 + var(--control-gap)\n );\n padding-inline-start: calc(var(--vectis-icon-size) / 2);\n }\n\n /* A CLOSED branch holding the current page keeps a mark of it, so the reader can see\n where they are without opening every section. The lookup is deliberately a\n descendant one: the page may be several levels down. */\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled]) {\n color: var(--vectis-color-accent-text);\n }\n\n /* A disabled row greys out through the colour tokens, never through opacity. */\n .v-side-nav-row[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n /* The icon and the second line default to a colour DARKER than the one a disabled\n label takes: left alone they would come out stronger than the label itself, so they\n inherit it instead. The chevron gets the same treatment from `styles/disclosure.css`. */\n .v-side-nav-row[data-disabled] .v-side-nav-icon,\n .v-side-nav-row[data-disabled] .v-side-nav-sublabel {\n color: inherit;\n }\n\n /* Forced colours flatten the current row's tint to `Canvas` and its accent text to\n `CanvasText`, leaving a slightly bolder label as the only cue, and the mark on a closed\n branch is a colour alone. The current row takes the system selection pair, repeated to\n (0,4,0) above its own hover, and the closed branch underlines its label, a decoration\n the mode keeps. */\n @media (forced-colors: active) {\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current][data-disabled] {\n background: Canvas;\n color: GrayText;\n }\n\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled])\n .v-side-nav-label {\n text-decoration: underline;\n }\n }\n\n /* The disclosure animation, the chevron's rotation or swap and the WebKit marker come\n from `styles/disclosure.css`, reduced-motion block included. */\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"VSideNavigationItem.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","expandMoreIcon","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_createElementVNode","_mergeProps","_renderSlot","_createBlock","VIcon","_createCommentVNode","_createTextVNode","_toDisplayString","_createVNode","_resolveDynamicComponent","_withCtx","VIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","VSideNavigationItem_vue_vue_type_script_setup_true_lang_default","\"open\"","\"openModifiers\"","__expose","__emit","props","__props","open","useModel","emit","useRootAttrs","slots","useSlots","tag","computed","parent","inject","sideNavigationKey","expandIcon","expand_more","collapseIcon","childrenName","useId","useDetailsOpen","onEndClick","event","rowEl","ref","actionEl","control","options","link","useInertLink","forwardedAttrs","onActionClick","openBlock","createElementBlock","normalizeClass","unref","rootClass","normalizeStyle","rootStyle","_ctx","openAttr","_cache","args","onToggle","createElementVNode","mergeProps","onSummaryClick","renderSlot","createBlock","iconProps","createCommentVNode","createTextVNode","toDisplayString","createVNode","resolveDynamicComponent","withCtx"],"sources":["../../../src/components/VSideNavigation/VSideNavigationItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Branches use native details and leaves use links or buttons. JavaScript synchronizes open\n * state, disables summaries and makes disabled links inert.\n */\n\nimport { computed, inject, provide, ref, useId, useSlots } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { useDetailsOpen } from '../../composables/useDetailsOpen'\nimport { useInertLink } from '../../composables/useInertLink'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\ninterface SideNavigationItemProps {\n /** What the row says, and where it goes. The default slot replaces it. */\n label?: string\n /** A second line under the label, for a status or a short explanation. */\n sublabel?: string\n /**\n * An icon before the label: an icon name, or an explicit render. The `#icon` slot\n * replaces it.\n */\n icon?: IconSource\n /**\n * Where this row leads, which makes it a link. It is IGNORED on a row that has\n * subitems: such a row opens and closes rather than navigating.\n */\n href?: string\n /**\n * Marks this row as the page currently being viewed. It is highlighted, and\n * announced as the current page (`aria-current`).\n */\n current?: boolean\n /**\n * Makes the row unusable: it greys out through the colour tokens and leaves the\n * keyboard path.\n */\n disabled?: boolean\n /** Renders a branch already open. Bind `v-model:open` to drive it instead. */\n defaultOpen?: boolean\n}\n\n// Without redirecting them, `target`, `rel`, `download` and the aria-* would land on that list\n// item instead of on the link or the branch header.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SideNavigationItemProps>(), {\n label: undefined,\n sublabel: undefined,\n icon: undefined,\n href: undefined,\n current: false,\n disabled: false,\n defaultOpen: false,\n})\n\n// \"not bound\" is written as `null` and not `undefined`. A model typed as a plain boolean is\n// declared as such at runtime, and Vue casts an ABSENT boolean prop to `false`, which would\n// silently overwrite `defaultOpen` on every branch.\n/**\n * Whether the branch is open, when the consumer wants to drive or observe it. Left\n * unbound, the browser keeps that state to itself, `defaultOpen` giving only the initial\n * value. `null` means unbound.\n */\nconst open = defineModel<boolean | null>('open', { default: null })\n\nconst emit = defineEmits<{\n // Never declare a `click` emit alongside it. Vue removes a declared event from the forwarded\n // attributes, and a consumer's own `@click` would then stop reaching the link entirely.\n /** A row WITHOUT subitems was activated, by click or by keyboard. */\n select: []\n}>()\n\ndefineSlots<{\n /**\n * The label of the row, replacing the `label` prop. One of the two is REQUIRED: a\n * navigation row must say where it goes.\n */\n default?(): unknown\n /** A second line made of markup, replacing the `sublabel` prop. */\n sublabel?(): unknown\n /** Free content before the label, which takes the place of `icon`. */\n icon?(): unknown\n /**\n * Free content at the end of the row, before the chevron: a counter, a badge. On a\n * BRANCH it must not be focusable, a control inside the header being a control nested\n * inside another.\n */\n end?(): unknown\n /**\n * The subitems, which turn this row into a branch. Nesting is not limited. The slot\n * must be statically present or absent: whether a row is a branch is decided when it\n * is created.\n */\n children?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst slots = useSlots()\nconst tag = computed(() => (props.href !== undefined ? 'a' : 'button'))\n\nconst parent = inject(sideNavigationKey, null)\n\n/**\n * Both chevrons are chosen on the navigation as a whole. The fallback is what keeps an\n * item rendering correctly when it is used outside one.\n */\nconst expandIcon = computed(() => parent?.expandIcon ?? expandMoreIcon)\nconst collapseIcon = computed(() => parent?.collapseIcon)\n\n// @ssr\n// Each level owns its exclusive group, including children supplied after the first render.\nconst childrenName = useId()\nprovide(sideNavigationKey, {\n get name() {\n return parent?.exclusive ? childrenName : undefined\n },\n get exclusive() {\n return parent?.exclusive ?? false\n },\n get expandIcon() {\n return expandIcon.value\n },\n get collapseIcon() {\n return collapseIcon.value\n },\n})\n\nconst { openAttr, onToggle, onSummaryClick } = useDetailsOpen(open, {\n defaultOpen: () => props.defaultOpen,\n disabled: () => props.disabled,\n})\n\n/*\n * Stopping the event from travelling would not help: folding is not a listener anyone\n * registered, it is the click's default action, and only cancelling that prevents it. The\n * exception is a click that already landed on something activable.\n */\n// @core\nfunction onEndClick(event: MouseEvent) {\n const target = event.target as Element | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n}\n\n// A template ref on the item reaches the list item, a layout box; what is focused and\n// named is its row: the branch header, or the leaf's link or button.\nconst rowEl = ref<HTMLElement | null>(null)\nconst actionEl = ref<HTMLElement | null>(null)\nconst control = () => (slots.children ? rowEl.value : actionEl.value)\ndefineExpose({\n /** Moves the focus to the row: the branch header, or the leaf's link or button. */\n focus: (options?: FocusOptions) => control()?.focus(options),\n /** The row, which is also where the consumer's attributes land. */\n get el() {\n return control()\n },\n})\n\n// @a11y\n// A leaf link has no `disabled`: the address, the consumer's click listeners and the\n// generic role of an `<a>` without `href` are handled by the shared inert link.\nconst link = useInertLink({\n href: () => (tag.value === 'a' ? props.href : undefined),\n inert: () => props.disabled,\n attrs: () => forwardedAttrs.value,\n})\n\n// @core\nfunction onActionClick(event: MouseEvent) {\n // A disabled button never receives the click at all; an inert link does, so it is\n // cancelled here.\n if (props.disabled) {\n event.preventDefault()\n return\n }\n emit('select')\n}\n</script>\n\n<template>\n <li class=\"v-side-nav-item\" :class=\"rootClass\" :style=\"rootStyle\">\n <details\n v-if=\"$slots.children\"\n class=\"v-side-nav-branch v-disclosure\"\n :name=\"parent?.name\"\n :open=\"openAttr\"\n :data-swap=\"collapseIcon ? '' : undefined\"\n @toggle=\"onToggle\"\n >\n <summary\n ref=\"rowEl\"\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :aria-current=\"current ? 'true' : undefined\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n v-bind=\"forwardedAttrs\"\n @click=\"onSummaryClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n <!-- This slot sits INSIDE the branch header, where ANY click folds the\n branch: without the handler, clicking a badge would close the section\n under it -->\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\" @click=\"onEndClick\"\n ><slot name=\"end\"\n /></span>\n <VIcon class=\"v-side-nav-chevron v-disclosure-chevron\" v-bind=\"iconProps(expandIcon)\" />\n <VIcon\n v-if=\"collapseIcon\"\n class=\"v-side-nav-chevron v-side-nav-chevron-open v-disclosure-chevron v-disclosure-chevron-open\"\n v-bind=\"iconProps(collapseIcon)\"\n />\n </summary>\n <ul class=\"v-side-nav-children\">\n <slot name=\"children\" />\n </ul>\n </details>\n\n <div\n v-else\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <component\n :is=\"tag\"\n ref=\"actionEl\"\n class=\"v-side-nav-action\"\n :type=\"tag === 'button' ? 'button' : undefined\"\n :disabled=\"tag === 'button' ? disabled : undefined\"\n :aria-disabled=\"link.isInertLink.value ? 'true' : undefined\"\n :aria-current=\"current ? (tag === 'a' ? 'page' : 'true') : undefined\"\n v-bind=\"link.attrs.value\"\n :href=\"link.linkHref.value\"\n @click=\"onActionClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n </component>\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\"><slot name=\"end\" /></span>\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The obvious one-name form, incrementing a variable by reading itself, is a CYCLE as far as\n * CSS is concerned, even though the value being read is the inherited one. The property then\n * falls to invalid, every read falls back to zero, and the whole tree renders FLAT; with\n * nothing in the console to say why.\n */\n .v-side-nav-item {\n --side-nav-parent-level: var(--side-nav-level, 0);\n }\n\n .v-side-nav-children {\n --side-nav-level: calc(var(--side-nav-parent-level) + 1);\n }\n\n .v-side-nav-row {\n /*\n * The indent is computed here and not stored in a variable set higher up. A custom property\n * is substituted on the element that DECLARES it, so a padding computed on the nav would be\n * frozen at level zero for the whole tree.\n */\n\n /*\n * The cap has to stay derived from --control-height. A browser scales down any radius it\n * cannot fit, so a row exactly one control tall already paints half that height under a\n * pill override; min() applies the same reduction to a row that grew past it.\n */\n --side-nav-row-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n min-block-size: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline: calc(\n var(--control-padding-inline) + var(--side-nav-level, 0) * var(--side-nav-indent)\n )\n var(--control-padding-inline);\n border-radius: var(--side-nav-row-radius);\n color: var(--vectis-color-text);\n font-size: var(--control-font-size);\n line-height: var(--vectis-text-body-md-leading);\n cursor: pointer;\n }\n\n .v-side-nav-action {\n /* On a leaf the link is a CHILD of the row, and the indent deliberately stays on\n the row itself: what has to run the full width is the hover background, not the\n link inside it. */\n flex: 1;\n min-inline-size: 0;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n cursor: inherit;\n }\n\n /*\n * This is what stretches the link over the whole row without having to wrap the end slot\n * inside it. It is an invisible box, positioned, so it is painted above the chevron; which is\n * not positioned; while passing UNDER the end slot, which is positioned too and comes later\n * in the document.\n */\n .v-side-nav-action::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--side-nav-row-radius);\n }\n\n .v-side-nav-content {\n flex: 1;\n min-inline-size: 0;\n display: flex;\n flex-direction: column;\n }\n\n .v-side-nav-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-sublabel {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-icon {\n flex: none;\n color: var(--vectis-color-text-muted);\n }\n\n /* Positioned on purpose: that is what paints it above the stretched link, and\n therefore what keeps whatever it holds clickable. */\n .v-side-nav-end {\n position: relative;\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-side-nav-row:hover:not([data-disabled]) {\n background: var(--vectis-color-surface-muted);\n }\n\n /*\n * A branch header takes focus itself; a leaf only takes it through its link, and the\n * ring is then drawn on the stretched box so that it frames the whole row rather than\n * just the text.\n *\n * The ring is pulled INWARDS in both cases: the content of a branch is clipped so it\n * can be animated open, and a ring drawn outside the row would be cut off there.\n */\n .v-side-nav-row:focus-visible,\n .v-side-nav-action:focus-visible::after {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-side-nav-action:focus-visible {\n outline: none;\n }\n\n .v-side-nav-row[data-current] {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-label {\n font-weight: var(--vectis-text-label-weight);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-icon,\n .v-side-nav-row[data-current] .v-side-nav-sublabel,\n .v-side-nav-row[data-current] .v-side-nav-chevron {\n color: inherit;\n }\n\n .v-side-nav-row[data-current]:not([data-disabled]):hover {\n /*\n * The current row is already tinted, so its hover deepens that tint rather than replacing\n * it with the neutral highlight; the VMenuItem idiom.\n */\n background: color-mix(\n in oklab,\n var(--vectis-color-accent-surface),\n var(--vectis-color-accent-text) 8%\n );\n }\n\n /* A CLOSED branch holding the current page keeps a mark of it, so the reader can see\n where they are without opening every section. The lookup is deliberately a\n descendant one: the page may be several levels down. */\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled]) {\n color: var(--vectis-color-accent-text);\n }\n\n /* A disabled row greys out through the colour tokens, never through opacity. */\n .v-side-nav-row[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n /* The icon and the second line default to a colour DARKER than the one a disabled\n label takes: left alone they would come out stronger than the label itself, so they\n inherit it instead. The chevron gets the same treatment from `styles/disclosure.css`. */\n .v-side-nav-row[data-disabled] .v-side-nav-icon,\n .v-side-nav-row[data-disabled] .v-side-nav-sublabel {\n color: inherit;\n }\n\n /* Forced colours flatten the current row's tint to `Canvas` and its accent text to\n `CanvasText`, leaving a slightly bolder label as the only cue, and the mark on a closed\n branch is a colour alone. The current row takes the system selection pair, repeated to\n (0,4,0) above its own hover, and the closed branch underlines its label, a decoration\n the mode keeps. */\n @media (forced-colors: active) {\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current][data-disabled] {\n background: Canvas;\n color: GrayText;\n }\n\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled])\n .v-side-nav-label {\n text-decoration: underline;\n }\n }\n\n /* The disclosure animation, the chevron's rotation or swap and the WebKit marker come\n from `styles/disclosure.css`, reduced-motion block included. */\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"VSideNavigationItem.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","expandMoreIcon","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_createElementVNode","_mergeProps","_renderSlot","_createBlock","VIcon","_createCommentVNode","_createTextVNode","_toDisplayString","_createVNode","_resolveDynamicComponent","_withCtx","VIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","VSideNavigationItem_vue_vue_type_script_setup_true_lang_default","\"open\"","\"openModifiers\"","__expose","__emit","props","__props","open","useModel","emit","useRootAttrs","slots","useSlots","tag","computed","parent","inject","sideNavigationKey","expandIcon","expand_more","collapseIcon","childrenName","useId","useDetailsOpen","onEndClick","event","rowEl","ref","actionEl","control","options","link","useInertLink","forwardedAttrs","onActionClick","openBlock","createElementBlock","normalizeClass","unref","rootClass","normalizeStyle","rootStyle","_ctx","openAttr","_cache","args","onToggle","createElementVNode","mergeProps","onSummaryClick","renderSlot","createBlock","iconProps","createCommentVNode","createTextVNode","toDisplayString","createVNode","resolveDynamicComponent","withCtx"],"sources":["../../../src/components/VSideNavigation/VSideNavigationItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Branches use native details and leaves use links or buttons. JavaScript synchronizes open\n * state, disables summaries and makes disabled links inert.\n */\n\nimport { computed, inject, provide, ref, useId, useSlots } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { useDetailsOpen } from '../../composables/useDetailsOpen'\nimport { useInertLink } from '../../composables/useInertLink'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\ninterface SideNavigationItemProps {\n /** What the row says, and where it goes. The default slot replaces it. */\n label?: string\n /** A second line under the label, for a status or a short explanation. */\n sublabel?: string\n /**\n * An icon before the label: an icon name, or an explicit render. The `#icon` slot\n * replaces it.\n */\n icon?: IconSource\n /**\n * Where this row leads, which makes it a link. It is IGNORED on a row that has\n * subitems: such a row opens and closes rather than navigating.\n */\n href?: string\n /**\n * Marks this row as the page currently being viewed. It is highlighted, and\n * announced as the current page (`aria-current`).\n */\n current?: boolean\n /**\n * Makes the row unusable: it greys out through the colour tokens and leaves the\n * keyboard path.\n */\n disabled?: boolean\n /** Renders a branch already open. Bind `v-model:open` to drive it instead. */\n defaultOpen?: boolean\n}\n\n// Without redirecting them, `target`, `rel`, `download` and the aria-* would land on that list\n// item instead of on the link or the branch header.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SideNavigationItemProps>(), {\n label: undefined,\n sublabel: undefined,\n icon: undefined,\n href: undefined,\n current: false,\n disabled: false,\n defaultOpen: false,\n})\n\n// \"not bound\" is written as `null` and not `undefined`. A model typed as a plain boolean is\n// declared as such at runtime, and Vue casts an ABSENT boolean prop to `false`, which would\n// silently overwrite `defaultOpen` on every branch.\n/**\n * Whether the branch is open, when the consumer wants to drive or observe it. Left\n * unbound, the browser keeps that state to itself, `defaultOpen` giving only the initial\n * value. `null` means unbound.\n */\nconst open = defineModel<boolean | null>('open', { default: null })\n\nconst emit = defineEmits<{\n // Never declare a `click` emit alongside it. Vue removes a declared event from the forwarded\n // attributes, and a consumer's own `@click` would then stop reaching the link entirely.\n /** A row WITHOUT subitems was activated, by click or by keyboard. */\n select: []\n}>()\n\ndefineSlots<{\n /**\n * The label of the row, replacing the `label` prop. One of the two is REQUIRED: a\n * navigation row must say where it goes.\n */\n default?(): unknown\n /** A second line made of markup, replacing the `sublabel` prop. */\n sublabel?(): unknown\n /** Free content before the label, which takes the place of `icon`. */\n icon?(): unknown\n /**\n * Free content at the end of the row, before the chevron: a counter, a badge. On a\n * BRANCH it must not be focusable, a control inside the header being a control nested\n * inside another.\n */\n end?(): unknown\n /**\n * The subitems, which turn this row into a branch. Nesting is not limited. The slot\n * must be statically present or absent: whether a row is a branch is decided when it\n * is created.\n */\n children?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst slots = useSlots()\nconst tag = computed(() => (props.href !== undefined ? 'a' : 'button'))\n\nconst parent = inject(sideNavigationKey, null)\n\n/**\n * Both chevrons are chosen on the navigation as a whole. The fallback is what keeps an\n * item rendering correctly when it is used outside one.\n */\nconst expandIcon = computed(() => parent?.expandIcon ?? expandMoreIcon)\nconst collapseIcon = computed(() => parent?.collapseIcon)\n\n// @ssr\n// Each level owns its exclusive group, including children supplied after the first render.\nconst childrenName = useId()\nprovide(sideNavigationKey, {\n get name() {\n return parent?.exclusive ? childrenName : undefined\n },\n get exclusive() {\n return parent?.exclusive ?? false\n },\n get expandIcon() {\n return expandIcon.value\n },\n get collapseIcon() {\n return collapseIcon.value\n },\n})\n\nconst { openAttr, onToggle, onSummaryClick } = useDetailsOpen(open, {\n defaultOpen: () => props.defaultOpen,\n disabled: () => props.disabled,\n})\n\n/*\n * Stopping the event from travelling would not help: folding is not a listener anyone\n * registered, it is the click's default action, and only cancelling that prevents it. The\n * exception is a click that already landed on something activable.\n */\n// @core\nfunction onEndClick(event: MouseEvent) {\n const target = event.target as Element | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n}\n\n// A template ref on the item reaches the list item, a layout box; what is focused and\n// named is its row: the branch header, or the leaf's link or button.\nconst rowEl = ref<HTMLElement | null>(null)\nconst actionEl = ref<HTMLElement | null>(null)\nconst control = () => (slots.children ? rowEl.value : actionEl.value)\ndefineExpose({\n /** Moves the focus to the row: the branch header, or the leaf's link or button. */\n focus: (options?: FocusOptions) => control()?.focus(options),\n /** The row, which is also where the consumer's attributes land. */\n get el() {\n return control()\n },\n})\n\n// @a11y\n// A leaf link has no `disabled`: the address, the consumer's click listeners and the\n// generic role of an `<a>` without `href` are handled by the shared inert link.\nconst link = useInertLink({\n href: () => (tag.value === 'a' ? props.href : undefined),\n inert: () => props.disabled,\n attrs: () => forwardedAttrs.value,\n})\n\n// @core\nfunction onActionClick(event: MouseEvent) {\n // A disabled button never receives the click at all; an inert link does, so it is\n // cancelled here.\n if (props.disabled) {\n event.preventDefault()\n return\n }\n emit('select')\n}\n</script>\n\n<template>\n <li class=\"v-side-nav-item\" :class=\"rootClass\" :style=\"rootStyle\">\n <details\n v-if=\"$slots.children\"\n class=\"v-side-nav-branch v-disclosure\"\n :name=\"parent?.name\"\n :open=\"openAttr\"\n :data-swap=\"collapseIcon ? '' : undefined\"\n @toggle=\"onToggle\"\n >\n <summary\n ref=\"rowEl\"\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :aria-current=\"current ? 'true' : undefined\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n v-bind=\"forwardedAttrs\"\n @click=\"onSummaryClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n <!-- This slot sits INSIDE the branch header, where ANY click folds the\n branch: without the handler, clicking a badge would close the section\n under it -->\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\" @click=\"onEndClick\"\n ><slot name=\"end\"\n /></span>\n <VIcon class=\"v-side-nav-chevron v-disclosure-chevron\" v-bind=\"iconProps(expandIcon)\" />\n <VIcon\n v-if=\"collapseIcon\"\n class=\"v-side-nav-chevron v-side-nav-chevron-open v-disclosure-chevron v-disclosure-chevron-open\"\n v-bind=\"iconProps(collapseIcon)\"\n />\n </summary>\n <ul class=\"v-side-nav-children\">\n <slot name=\"children\" />\n </ul>\n </details>\n\n <div\n v-else\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <component\n :is=\"tag\"\n ref=\"actionEl\"\n class=\"v-side-nav-action\"\n :type=\"tag === 'button' ? 'button' : undefined\"\n :disabled=\"tag === 'button' ? disabled : undefined\"\n :aria-disabled=\"link.isInertLink.value ? 'true' : undefined\"\n :aria-current=\"current ? (tag === 'a' ? 'page' : 'true') : undefined\"\n v-bind=\"link.attrs.value\"\n :href=\"link.linkHref.value\"\n @click=\"onActionClick\"\n >\n <slot name=\"icon\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"\n ><slot>{{ label }}</slot></span\n >\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n </component>\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\"><slot name=\"end\" /></span>\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The obvious one-name form, incrementing a variable by reading itself, is a CYCLE as far as\n * CSS is concerned, even though the value being read is the inherited one. The property then\n * falls to invalid, every read falls back to zero, and the whole tree renders FLAT; with\n * nothing in the console to say why.\n */\n .v-side-nav-item {\n --side-nav-parent-level: var(--side-nav-level, 0);\n }\n\n .v-side-nav-children {\n --side-nav-level: calc(var(--side-nav-parent-level) + 1);\n }\n\n .v-side-nav-row {\n /*\n * The indent is computed here and not stored in a variable set higher up. A custom property\n * is substituted on the element that DECLARES it, so a padding computed on the nav would be\n * frozen at level zero for the whole tree.\n */\n\n /*\n * The cap has to stay derived from --control-height. A browser scales down any radius it\n * cannot fit, so a row exactly one control tall already paints half that height under a\n * pill override; min() applies the same reduction to a row that grew past it.\n */\n --side-nav-row-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n min-block-size: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline: calc(\n var(--control-padding-inline) + var(--side-nav-level, 0) * var(--side-nav-indent)\n )\n var(--control-padding-inline);\n border-radius: var(--side-nav-row-radius);\n color: var(--vectis-color-text);\n font-size: var(--control-font-size);\n line-height: var(--vectis-text-body-md-leading);\n cursor: pointer;\n }\n\n .v-side-nav-action {\n /* On a leaf the link is a CHILD of the row, and the indent deliberately stays on\n the row itself: what has to run the full width is the hover background, not the\n link inside it. */\n flex: 1;\n min-inline-size: 0;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n cursor: inherit;\n }\n\n /*\n * This is what stretches the link over the whole row without having to wrap the end slot\n * inside it. It is an invisible box, positioned, so it is painted above the chevron; which is\n * not positioned; while passing UNDER the end slot, which is positioned too and comes later\n * in the document.\n */\n .v-side-nav-action::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--side-nav-row-radius);\n }\n\n .v-side-nav-content {\n flex: 1;\n min-inline-size: 0;\n display: flex;\n flex-direction: column;\n }\n\n .v-side-nav-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-sublabel {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-icon {\n flex: none;\n color: var(--vectis-color-text-muted);\n }\n\n /* Positioned on purpose: that is what paints it above the stretched link, and\n therefore what keeps whatever it holds clickable. */\n .v-side-nav-end {\n position: relative;\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-side-nav-row:hover:not([data-disabled]) {\n background: var(--vectis-color-surface-muted);\n }\n\n /*\n * A branch header takes focus itself; a leaf only takes it through its link, and the\n * ring is then drawn on the stretched box so that it frames the whole row rather than\n * just the text.\n *\n * The ring is pulled INWARDS in both cases: the content of a branch is clipped so it\n * can be animated open, and a ring drawn outside the row would be cut off there.\n */\n .v-side-nav-row:focus-visible,\n .v-side-nav-action:focus-visible::after {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-side-nav-action:focus-visible {\n outline: none;\n }\n\n .v-side-nav-row[data-current] {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-label {\n font-weight: var(--vectis-text-label-weight);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-icon,\n .v-side-nav-row[data-current] .v-side-nav-sublabel,\n .v-side-nav-row[data-current] .v-side-nav-chevron {\n color: inherit;\n }\n\n .v-side-nav-row[data-current]:not([data-disabled]):hover {\n /*\n * The current row is already tinted, so its hover deepens that tint rather than replacing\n * it with the neutral highlight; the VMenuItem idiom.\n */\n background: color-mix(\n in oklab,\n var(--vectis-color-accent-surface),\n var(--vectis-color-accent-text) 8%\n );\n }\n\n /*\n * The line sits under the middle of the parent's icon, whether or not it has one. A row\n * of the sublist then starts a gutter after the line, so its highlight never covers it, and\n * its padding takes up the rest: the label stays where the indent puts it.\n *\n * Painted with a border and not a background, which forced colours would turn to Canvas.\n */\n .v-side-nav[data-guides] .v-side-nav-children {\n position: relative;\n }\n\n .v-side-nav[data-guides] .v-side-nav-children::before {\n content: '';\n position: absolute;\n inset-block: 0;\n inset-inline-start: calc(\n var(--control-padding-inline) + var(--side-nav-parent-level) * var(--side-nav-indent) +\n var(--vectis-icon-size) / 2\n );\n border-inline-start: 1px solid var(--vectis-color-border);\n }\n\n .v-side-nav[data-guides] .v-side-nav-children .v-side-nav-row {\n margin-inline-start: calc(\n var(--control-padding-inline) + (var(--side-nav-level) - 1) * var(--side-nav-indent) +\n var(--vectis-icon-size) / 2 + var(--control-gap)\n );\n padding-inline-start: calc(var(--vectis-icon-size) / 2);\n }\n\n /* A CLOSED branch holding the current page keeps a mark of it, so the reader can see\n where they are without opening every section. The lookup is deliberately a\n descendant one: the page may be several levels down. */\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled]) {\n color: var(--vectis-color-accent-text);\n }\n\n /* A disabled row greys out through the colour tokens, never through opacity. */\n .v-side-nav-row[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n /* The icon and the second line default to a colour DARKER than the one a disabled\n label takes: left alone they would come out stronger than the label itself, so they\n inherit it instead. The chevron gets the same treatment from `styles/disclosure.css`. */\n .v-side-nav-row[data-disabled] .v-side-nav-icon,\n .v-side-nav-row[data-disabled] .v-side-nav-sublabel {\n color: inherit;\n }\n\n /* Forced colours flatten the current row's tint to `Canvas` and its accent text to\n `CanvasText`, leaving a slightly bolder label as the only cue, and the mark on a closed\n branch is a colour alone. The current row takes the system selection pair, repeated to\n (0,4,0) above its own hover, and the closed branch underlines its label, a decoration\n the mode keeps. */\n @media (forced-colors: active) {\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-side-nav-row.v-side-nav-row.v-side-nav-row[data-current][data-disabled] {\n background: Canvas;\n color: GrayText;\n }\n\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current], [data-disabled])\n .v-side-nav-label {\n text-decoration: underline;\n }\n }\n\n /* The disclosure animation, the chevron's rotation or swap and the WebKit marker come\n from `styles/disclosure.css`, reduced-motion block included. */\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":["sideNavigationKey"],"sources":["../../../src/components/VSideNavigation/context.ts"],"sourcesContent":["/** Share navigation behaviour only; CSS inheritance carries size, compact and branch depth. */\n\nimport type { InjectionKey } from 'vue'\n\nimport type { IconSource } from '../VIcon/types'\n\nexport interface SideNavigationContext {\n /**\n * The name shared by the collapsible sections of this level. Sections that share one\n * close each other, which the browser does entirely on its own. Nothing here means\n * several may stay open at once.\n */\n name: string | undefined\n /**\n * Whether the sidebar was asked for one-at-a-time behaviour. It is passed down so\n * that each level can mint a name of its own.\n */\n exclusive: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon: IconSource\n /**\n * The chevron of an open section. Nothing here means the closed one is simply\n * rotated.\n */\n collapseIcon: IconSource | undefined\n}\n\nexport const sideNavigationKey: InjectionKey<SideNavigationContext> = Symbol('v-side-navigation')\n"],"mappings":";AA2BA,IAAaA,IAAyD,OAAO,mBAAmB"}
1
+ {"version":3,"file":"context.js","names":["sideNavigationKey"],"sources":["../../../src/components/VSideNavigation/context.ts"],"sourcesContent":["/** Share navigation behaviour only; CSS inheritance carries size, density and branch depth. */\n\nimport type { InjectionKey } from 'vue'\n\nimport type { IconSource } from '../VIcon/types'\n\nexport interface SideNavigationContext {\n /**\n * The name shared by the collapsible sections of this level. Sections that share one\n * close each other, which the browser does entirely on its own. Nothing here means\n * several may stay open at once.\n */\n name: string | undefined\n /**\n * Whether the sidebar was asked for one-at-a-time behaviour. It is passed down so\n * that each level can mint a name of its own.\n */\n exclusive: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon: IconSource\n /**\n * The chevron of an open section. Nothing here means the closed one is simply\n * rotated.\n */\n collapseIcon: IconSource | undefined\n}\n\nexport const sideNavigationKey: InjectionKey<SideNavigationContext> = Symbol('v-side-navigation')\n"],"mappings":";AA2BA,IAAaA,IAAyD,OAAO,mBAAmB"}