@xleddyl/443-components-vue 0.5.0 → 0.6.2

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 (315) hide show
  1. package/README.md +25 -6
  2. package/dist/chart/BarChart.vue +11 -4
  3. package/dist/chart/BarChart.vue.d.ts +2 -0
  4. package/dist/chart/ChartLegend.vue +43 -4
  5. package/dist/chart/ChartLegend.vue.d.ts +4 -2
  6. package/dist/chart/ChartPanel.vue +10 -10
  7. package/dist/chart/ChartPanel.vue.d.ts +11 -8
  8. package/dist/chart/ChartSummary.vue +8 -3
  9. package/dist/chart/ChartSummary.vue.d.ts +3 -1
  10. package/dist/chart/DoughnutChart.vue +11 -4
  11. package/dist/chart/LineChart.vue +8 -2
  12. package/dist/chart/LineChart.vue.d.ts +2 -0
  13. package/dist/chart/chart.css +19 -0
  14. package/dist/chart/patterns.d.ts +6 -0
  15. package/dist/chart/patterns.mjs +79 -0
  16. package/dist/chart/types.d.ts +5 -0
  17. package/dist/chart/useChartColors.mjs +1 -1
  18. package/dist/components/core/Button.vue +11 -1
  19. package/dist/components/core/Button.vue.d.ts +1 -1
  20. package/dist/components/core/FieldMessage.vue +6 -0
  21. package/dist/components/core/FieldMessage.vue.d.ts +1 -1
  22. package/dist/components/core/Form.vue +18 -1
  23. package/dist/components/core/FormAlerts.vue +41 -3
  24. package/dist/components/core/FormField.vue +43 -24
  25. package/dist/components/core/Input.vue.d.ts +6 -6
  26. package/dist/components/core/Root.vue +6 -1
  27. package/dist/components/core/Root.vue.d.ts +2 -2
  28. package/dist/components/core/Spinner.vue +6 -11
  29. package/dist/components/core/Spinner.vue.d.ts +2 -2
  30. package/dist/components/core/Textarea.vue.d.ts +2 -2
  31. package/dist/components/core/VisuallyHidden.vue.d.ts +2 -2
  32. package/dist/components/data/Avatar.vue +8 -5
  33. package/dist/components/data/AvatarGroup.vue +6 -3
  34. package/dist/components/data/Badge.vue.d.ts +1 -1
  35. package/dist/components/data/FilterPills.vue +18 -2
  36. package/dist/components/data/Pagination.vue +24 -18
  37. package/dist/components/data/Pagination.vue.d.ts +2 -2
  38. package/dist/components/data/SelectionBar.vue +32 -3
  39. package/dist/components/data/Stat.vue +7 -1
  40. package/dist/components/data/Stat.vue.d.ts +2 -2
  41. package/dist/components/data/Table.vue +62 -14
  42. package/dist/components/data/Tag.vue +24 -4
  43. package/dist/components/data/Tag.vue.d.ts +3 -3
  44. package/dist/components/data/Timeline.vue +12 -1
  45. package/dist/components/data/Tree.vue +137 -36
  46. package/dist/components/data/Tree.vue.d.ts +13 -14
  47. package/dist/components/data/types.d.ts +2 -1
  48. package/dist/components/feedback/Alert.vue +18 -9
  49. package/dist/components/feedback/Alert.vue.d.ts +2 -2
  50. package/dist/components/feedback/LoadingOverlay.vue +35 -3
  51. package/dist/components/feedback/Meter.vue +28 -3
  52. package/dist/components/feedback/Progress.vue +2 -7
  53. package/dist/components/feedback/Progress.vue.d.ts +1 -1
  54. package/dist/components/feedback/ProgressRing.vue +2 -6
  55. package/dist/components/feedback/ProgressRing.vue.d.ts +1 -1
  56. package/dist/components/forms/Calendar.vue +49 -26
  57. package/dist/components/forms/Calendar.vue.d.ts +9 -5
  58. package/dist/components/forms/CheckboxGroup.vue +14 -4
  59. package/dist/components/forms/CheckboxGroup.vue.d.ts +1 -0
  60. package/dist/components/forms/ColorInput.vue +68 -15
  61. package/dist/components/forms/ColorInput.vue.d.ts +16 -13
  62. package/dist/components/forms/Combobox.vue +18 -4
  63. package/dist/components/forms/DateInput.vue.d.ts +6 -6
  64. package/dist/components/forms/DatePicker.vue +23 -7
  65. package/dist/components/forms/DatePicker.vue.d.ts +4 -2
  66. package/dist/components/forms/FileInput.vue +31 -13
  67. package/dist/components/forms/FileInput.vue.d.ts +2 -2
  68. package/dist/components/forms/InputAddon.vue +18 -2
  69. package/dist/components/forms/InputGroup.vue +27 -0
  70. package/dist/components/forms/InputGroup.vue.d.ts +2 -0
  71. package/dist/components/forms/NumberInput.vue +6 -7
  72. package/dist/components/forms/NumberInput.vue.d.ts +6 -6
  73. package/dist/components/forms/PasswordInput.vue +12 -6
  74. package/dist/components/forms/PasswordInput.vue.d.ts +6 -7
  75. package/dist/components/forms/PinInput.vue +11 -1
  76. package/dist/components/forms/PinInput.vue.d.ts +8 -6
  77. package/dist/components/forms/RadioGroup.vue +15 -5
  78. package/dist/components/forms/RadioGroup.vue.d.ts +1 -0
  79. package/dist/components/forms/SegmentedControl.vue +15 -10
  80. package/dist/components/forms/SegmentedControl.vue.d.ts +1 -0
  81. package/dist/components/forms/Slider.vue +9 -0
  82. package/dist/components/forms/Slider.vue.d.ts +8 -6
  83. package/dist/components/forms/Switch.vue +7 -0
  84. package/dist/components/forms/Switch.vue.d.ts +2 -2
  85. package/dist/components/forms/TimeInput.vue.d.ts +6 -6
  86. package/dist/components/forms/types.d.ts +4 -0
  87. package/dist/components/layout/Accordion.vue.d.ts +2 -2
  88. package/dist/components/layout/AppShell.vue +40 -18
  89. package/dist/components/layout/AppShell.vue.d.ts +11 -9
  90. package/dist/components/layout/Card.vue +50 -16
  91. package/dist/components/layout/Card.vue.d.ts +13 -11
  92. package/dist/components/layout/CopyButton.vue +13 -5
  93. package/dist/components/layout/CopyButton.vue.d.ts +3 -3
  94. package/dist/components/layout/NavLink.vue +10 -1
  95. package/dist/components/layout/NavLink.vue.d.ts +2 -2
  96. package/dist/components/layout/PageHeader.vue +2 -2
  97. package/dist/components/layout/Separator.vue +6 -3
  98. package/dist/components/layout/Sidebar.vue +14 -7
  99. package/dist/components/layout/Sidebar.vue.d.ts +0 -2
  100. package/dist/components/layout/SidebarNav.vue +16 -44
  101. package/dist/components/layout/Stack.vue.d.ts +2 -2
  102. package/dist/components/layout/Tabs.vue +10 -18
  103. package/dist/components/layout/Tabs.vue.d.ts +2 -2
  104. package/dist/components/layout/Toolbar.vue +10 -4
  105. package/dist/components/layout/Toolbar.vue.d.ts +1 -0
  106. package/dist/components/layout/types.d.ts +1 -0
  107. package/dist/components/overlays/CommandPalette.vue +8 -4
  108. package/dist/components/overlays/CommandPalette.vue.d.ts +3 -8
  109. package/dist/components/overlays/ConfirmDialog.vue +7 -5
  110. package/dist/components/overlays/ConfirmDialog.vue.d.ts +12 -8
  111. package/dist/components/overlays/ConfirmHost.vue +22 -19
  112. package/dist/components/overlays/ConfirmHost.vue.d.ts +8 -6
  113. package/dist/components/overlays/ContextMenu.vue +9 -11
  114. package/dist/components/overlays/ContextMenu.vue.d.ts +2 -2
  115. package/dist/components/overlays/Drawer.vue +2 -0
  116. package/dist/components/overlays/Drawer.vue.d.ts +4 -2
  117. package/dist/components/overlays/DropdownMenu.vue +13 -21
  118. package/dist/components/overlays/DropdownMenu.vue.d.ts +2 -2
  119. package/dist/components/overlays/HoverCard.vue +8 -2
  120. package/dist/components/overlays/HoverCard.vue.d.ts +2 -2
  121. package/dist/components/overlays/Modal.vue +2 -0
  122. package/dist/components/overlays/Modal.vue.d.ts +4 -2
  123. package/dist/components/overlays/Popover.vue +19 -4
  124. package/dist/components/overlays/Popover.vue.d.ts +2 -2
  125. package/dist/components/overlays/Toaster.vue +39 -7
  126. package/dist/components/overlays/Tooltip.vue +39 -14
  127. package/dist/components/overlays/types.d.ts +6 -0
  128. package/dist/components/templates/AccountMenu.vue.d.ts +2 -2
  129. package/dist/components/templates/AppearanceSettings.vue +83 -77
  130. package/dist/components/templates/AppearanceSettings.vue.d.ts +2 -2
  131. package/dist/components/templates/AuthLayout.vue +2 -2
  132. package/dist/components/templates/Brand.vue.d.ts +2 -2
  133. package/dist/components/templates/DashboardLayout.vue +3 -7
  134. package/dist/components/templates/DashboardLayout.vue.d.ts +8 -18
  135. package/dist/components/templates/DetailPage.vue +3 -1
  136. package/dist/components/templates/DetailPage.vue.d.ts +2 -2
  137. package/dist/components/templates/ErrorPage.vue +11 -5
  138. package/dist/components/templates/ErrorPage.vue.d.ts +10 -6
  139. package/dist/components/templates/FormPage.vue +16 -3
  140. package/dist/components/templates/ListPage.vue +19 -6
  141. package/dist/components/templates/ListPage.vue.d.ts +1 -0
  142. package/dist/components/templates/NotFoundPage.vue +2 -0
  143. package/dist/components/templates/NotFoundPage.vue.d.ts +4 -0
  144. package/dist/components/templates/SaveBar.vue +18 -3
  145. package/dist/components/templates/SaveBar.vue.d.ts +5 -5
  146. package/dist/components/templates/SettingsGroup.vue +1 -1
  147. package/dist/components/templates/SettingsGroup.vue.d.ts +3 -1
  148. package/dist/components/templates/SettingsModal.vue +73 -46
  149. package/dist/components/templates/SettingsModal.vue.d.ts +9 -11
  150. package/dist/components/templates/SettingsPage.vue.d.ts +2 -2
  151. package/dist/components/templates/SettingsSection.vue.d.ts +4 -2
  152. package/dist/components/templates/types.d.ts +4 -0
  153. package/dist/composables/useAlert.mjs +5 -10
  154. package/dist/composables/useConfirm.mjs +5 -5
  155. package/dist/composables/useField.d.ts +4 -0
  156. package/dist/composables/useField.mjs +16 -5
  157. package/dist/composables/useFileDrop.mjs +2 -1
  158. package/dist/composables/useOverlay.mjs +2 -1
  159. package/dist/composables/usePreset.mjs +4 -10
  160. package/dist/composables/usePrompt.mjs +6 -13
  161. package/dist/composables/useScrollLock.mjs +4 -3
  162. package/dist/composables/useTheme.mjs +3 -11
  163. package/dist/composables/useToast.mjs +2 -1
  164. package/dist/editor/RichTextEditor.vue +31 -6
  165. package/dist/editor/RichTextEditor.vue.d.ts +2 -2
  166. package/dist/editor/rich-text-editor.css +9 -4
  167. package/dist/grid/DataGrid.vue +72 -12
  168. package/dist/grid/GridToolbar.vue +1 -1
  169. package/dist/grid/GridToolbar.vue.d.ts +2 -2
  170. package/dist/grid/cells/BadgeCell.vue +3 -1
  171. package/dist/grid/cells/BadgeCell.vue.d.ts +17 -3
  172. package/dist/grid/cells/DateCell.vue +3 -1
  173. package/dist/grid/cells/DateCell.vue.d.ts +17 -3
  174. package/dist/grid/cells/EmptyCell.vue +15 -0
  175. package/dist/grid/cells/EmptyCell.vue.d.ts +392 -0
  176. package/dist/grid/cells/LinkCell.vue +9 -2
  177. package/dist/grid/cells/LinkCell.vue.d.ts +17 -3
  178. package/dist/grid/data-grid.css +5 -5
  179. package/dist/grid/types.d.ts +2 -0
  180. package/dist/internal/core/ButtonContent.vue +3 -0
  181. package/dist/internal/core/LiveRegion.vue +26 -0
  182. package/dist/internal/core/LiveRegion.vue.d.ts +393 -0
  183. package/dist/internal/core/copy.d.ts +6 -0
  184. package/dist/internal/core/copy.mjs +14 -0
  185. package/dist/internal/core/focus.d.ts +6 -0
  186. package/dist/internal/core/focus.mjs +46 -0
  187. package/dist/internal/core/intl.d.ts +4 -2
  188. package/dist/internal/core/intl.mjs +23 -22
  189. package/dist/internal/core/live.d.ts +6 -0
  190. package/dist/internal/core/live.mjs +22 -0
  191. package/dist/internal/core/preset.d.ts +0 -1
  192. package/dist/internal/core/preset.mjs +4 -14
  193. package/dist/internal/core/resize.d.ts +1 -0
  194. package/dist/internal/core/resize.mjs +11 -0
  195. package/dist/internal/core/roving.d.ts +7 -0
  196. package/dist/internal/core/roving.mjs +19 -1
  197. package/dist/internal/core/scroll-edges.d.ts +5 -0
  198. package/dist/internal/core/scroll-edges.mjs +63 -0
  199. package/dist/internal/core/storage.d.ts +2 -0
  200. package/dist/internal/core/storage.mjs +8 -0
  201. package/dist/internal/core/theme.d.ts +0 -1
  202. package/dist/internal/core/theme.mjs +4 -13
  203. package/dist/internal/core/tone.d.ts +1 -0
  204. package/dist/internal/core/tone.mjs +4 -0
  205. package/dist/internal/core/transition.d.ts +1 -0
  206. package/dist/internal/core/transition.mjs +20 -0
  207. package/dist/internal/data/rows.mjs +6 -5
  208. package/dist/internal/data/tree.d.ts +2 -3
  209. package/dist/internal/feedback/LoadingHost.vue +16 -6
  210. package/dist/internal/feedback/loading.mjs +2 -1
  211. package/dist/internal/feedback/progress.d.ts +12 -0
  212. package/dist/internal/feedback/progress.mjs +13 -0
  213. package/dist/internal/floating/layer.d.ts +1 -1
  214. package/dist/internal/floating/layer.mjs +17 -10
  215. package/dist/internal/forms/keys.d.ts +4 -0
  216. package/dist/internal/forms/keys.mjs +1 -0
  217. package/dist/internal/forms/name.d.ts +2 -0
  218. package/dist/internal/forms/name.mjs +12 -0
  219. package/dist/internal/forms/standard-schema.d.ts +0 -2
  220. package/dist/internal/forms/standard-schema.mjs +0 -18
  221. package/dist/internal/layout/NavGroup.vue +104 -0
  222. package/dist/internal/layout/NavGroup.vue.d.ts +412 -0
  223. package/dist/internal/overlays/DialogFrame.vue +53 -6
  224. package/dist/internal/overlays/DialogFrame.vue.d.ts +5 -2
  225. package/dist/internal/overlays/MenuList.vue +4 -11
  226. package/dist/internal/overlays/MenuList.vue.d.ts +6 -6
  227. package/dist/internal/overlays/OverlayView.vue +2 -0
  228. package/dist/internal/overlays/OverlayView.vue.d.ts +8 -6
  229. package/dist/internal/overlays/confirm.d.ts +6 -1
  230. package/dist/internal/overlays/confirm.mjs +5 -2
  231. package/dist/internal/overlays/dialog.d.ts +1 -0
  232. package/dist/internal/overlays/dialog.mjs +9 -9
  233. package/dist/internal/overlays/hover.d.ts +1 -0
  234. package/dist/internal/overlays/hover.mjs +20 -3
  235. package/dist/internal/overlays/menu.d.ts +9 -0
  236. package/dist/internal/overlays/menu.mjs +15 -0
  237. package/dist/internal/overlays/stack.d.ts +1 -0
  238. package/dist/locale/en.mjs +70 -18
  239. package/dist/locale/index.d.ts +1 -1
  240. package/dist/locale/index.mjs +5 -11
  241. package/dist/locale/it.mjs +70 -18
  242. package/dist/locale/types.d.ts +54 -2
  243. package/dist/nuxt/runtime/RouteAnnouncer.vue +21 -0
  244. package/dist/nuxt/runtime/RouteAnnouncer.vue.d.ts +3 -0
  245. package/dist/nuxt/runtime/layout-head.d.ts +2 -0
  246. package/dist/nuxt/runtime/layout-head.mjs +13 -0
  247. package/dist/nuxt/runtime/layouts/auth.vue +4 -0
  248. package/dist/nuxt/runtime/layouts/auth.vue.d.ts +2 -2
  249. package/dist/nuxt/runtime/layouts/dashboard.vue +4 -0
  250. package/dist/nuxt/runtime/layouts/dashboard.vue.d.ts +2 -2
  251. package/dist/nuxt/runtime/locale.mjs +9 -1
  252. package/dist/nuxt/runtime/theme.mjs +17 -12
  253. package/dist/styles/base.css +0 -13
  254. package/dist/styles/core/button.css +8 -8
  255. package/dist/styles/core/field-message.css +2 -2
  256. package/dist/styles/core/form-field.css +11 -2
  257. package/dist/styles/core/input.css +4 -7
  258. package/dist/styles/core/kbd.css +0 -1
  259. package/dist/styles/data/badge.css +8 -4
  260. package/dist/styles/data/description-list.css +2 -2
  261. package/dist/styles/data/filter-pills.css +5 -8
  262. package/dist/styles/data/pagination.css +2 -2
  263. package/dist/styles/data/stat.css +3 -3
  264. package/dist/styles/data/table.css +2 -2
  265. package/dist/styles/data/tag.css +1 -2
  266. package/dist/styles/data/timeline.css +1 -1
  267. package/dist/styles/data/tree.css +31 -10
  268. package/dist/styles/feedback/alert.css +0 -3
  269. package/dist/styles/feedback/loading-host.css +4 -0
  270. package/dist/styles/feedback/loading-overlay.css +4 -0
  271. package/dist/styles/forced-colors.css +215 -0
  272. package/dist/styles/forms/calendar.css +2 -2
  273. package/dist/styles/forms/choice.css +2 -2
  274. package/dist/styles/forms/color-input.css +1 -1
  275. package/dist/styles/forms/combobox.css +2 -24
  276. package/dist/styles/forms/date-input.css +2 -2
  277. package/dist/styles/forms/date-picker.css +3 -7
  278. package/dist/styles/forms/file-input.css +4 -3
  279. package/dist/styles/forms/input-group.css +6 -0
  280. package/dist/styles/forms/number-input.css +2 -2
  281. package/dist/styles/forms/password-input.css +5 -2
  282. package/dist/styles/forms/pin-input.css +4 -2
  283. package/dist/styles/forms/segmented.css +2 -2
  284. package/dist/styles/forms/select.css +6 -6
  285. package/dist/styles/forms/slider.css +5 -4
  286. package/dist/styles/forms/switch.css +5 -1
  287. package/dist/styles/index.css +1 -0
  288. package/dist/styles/layout/app-shell.css +15 -3
  289. package/dist/styles/layout/copy-button.css +1 -1
  290. package/dist/styles/layout/nav-link.css +1 -33
  291. package/dist/styles/layout/separator.css +1 -1
  292. package/dist/styles/layout/sidebar-nav.css +15 -4
  293. package/dist/styles/layout/sidebar.css +20 -6
  294. package/dist/styles/layout/tabs.css +9 -4
  295. package/dist/styles/layout/theme-switch.css +0 -6
  296. package/dist/styles/overlays/command.css +9 -15
  297. package/dist/styles/overlays/confirm.css +1 -1
  298. package/dist/styles/overlays/drawer.css +0 -1
  299. package/dist/styles/overlays/menu.css +2 -17
  300. package/dist/styles/overlays/modal.css +29 -6
  301. package/dist/styles/overlays/toast.css +1 -2
  302. package/dist/styles/presets.css +4 -4
  303. package/dist/styles/shared.css +96 -3
  304. package/dist/styles/templates/account-menu.css +3 -3
  305. package/dist/styles/templates/auth-layout.css +1 -1
  306. package/dist/styles/templates/brand.css +3 -3
  307. package/dist/styles/templates/empty-page.css +1 -1
  308. package/dist/styles/templates/form-page.css +10 -0
  309. package/dist/styles/templates/save-bar.css +10 -0
  310. package/dist/styles/templates/settings-modal.css +42 -44
  311. package/dist/styles/templates/settings-page.css +3 -3
  312. package/dist/styles/tokens.css +12 -2
  313. package/package.json +1 -1
  314. package/dist/internal/overlays/focus.d.ts +0 -1
  315. package/dist/internal/overlays/focus.mjs +0 -24
@@ -6,49 +6,54 @@
6
6
  :description="themeDescription"
7
7
  :level="level"
8
8
  >
9
- <fieldset class="k-appearance-cards">
10
- <legend class="k-visually-hidden">{{ themeLabelText }}</legend>
11
- <label
12
- v-for="option in themeOptions"
13
- :key="option.value"
14
- class="k-appearance-card"
15
- :class="{ 'is-active': theme.preference.value === option.value }"
16
- >
17
- <input
18
- type="radio"
19
- class="k-visually-hidden"
20
- :name="themeName"
21
- :value="option.value"
22
- :checked="theme.preference.value === option.value"
23
- @change="theme.set(option.value)"
24
- />
25
- <span class="k-appearance-preview" :class="`is-${option.value}`" aria-hidden="true">
9
+ <template #default="{ headingId: themeHeadingId }">
10
+ <div class="k-appearance-cards" role="radiogroup" :aria-labelledby="themeHeadingId">
11
+ <label
12
+ v-for="option in themeOptions"
13
+ :key="option.value"
14
+ class="k-appearance-card"
15
+ :class="{ 'is-active': theme.preference.value === option.value }"
16
+ >
17
+ <input
18
+ type="radio"
19
+ class="k-visually-hidden"
20
+ :name="themeName"
21
+ :value="option.value"
22
+ :checked="theme.preference.value === option.value"
23
+ @change="theme.set(option.value)"
24
+ />
26
25
  <span
27
- v-for="half in themeHalves(option.value)"
28
- :key="half"
29
- class="k-root k-appearance-app"
30
- :class="`is-${half}`"
31
- :data-theme="half"
26
+ class="k-appearance-preview"
27
+ :class="`is-${option.value}`"
28
+ aria-hidden="true"
32
29
  >
33
- <span class="k-appearance-side" />
34
- <span class="k-appearance-panel">
35
- <span class="k-appearance-line is-accent" />
36
- <span class="k-appearance-line" />
37
- <span class="k-appearance-line is-short" />
30
+ <span
31
+ v-for="half in themeHalves(option.value)"
32
+ :key="half"
33
+ class="k-root k-appearance-app"
34
+ :class="`is-${half}`"
35
+ :data-theme="half"
36
+ >
37
+ <span class="k-appearance-side" />
38
+ <span class="k-appearance-panel">
39
+ <span class="k-appearance-line is-accent" />
40
+ <span class="k-appearance-line" />
41
+ <span class="k-appearance-line is-short" />
42
+ </span>
38
43
  </span>
39
44
  </span>
40
- </span>
41
- <span class="k-appearance-card-label">
42
- <Icon :name="option.icon" />
43
- {{ t(`theme.${option.value}`) }}
44
- <Icon
45
- v-if="theme.preference.value === option.value"
46
- name="check"
47
- class="k-appearance-card-check"
48
- />
49
- </span>
50
- </label>
51
- </fieldset>
45
+ <span class="k-appearance-card-label">
46
+ <Icon :name="option.icon" />
47
+ {{ t(`theme.${option.value}`) }}
48
+ <Icon
49
+ v-if="theme.preference.value === option.value"
50
+ name="check"
51
+ class="k-appearance-card-check"
52
+ />
53
+ </span>
54
+ </label>
55
+ </div>
56
+ </template>
52
57
  </SettingsGroup>
53
58
 
54
59
  <SettingsGroup
@@ -57,46 +62,47 @@
57
62
  :description="presetDescription"
58
63
  :level="level"
59
64
  >
60
- <fieldset class="k-appearance-cards">
61
- <legend class="k-visually-hidden">{{ presetLabelText }}</legend>
62
- <label
63
- v-for="option in presetList"
64
- :key="option.value"
65
- class="k-appearance-card"
66
- :class="{ 'is-active': preset.preset.value === option.value }"
67
- >
68
- <input
69
- type="radio"
70
- class="k-visually-hidden"
71
- :name="presetName"
72
- :value="option.value"
73
- :checked="preset.preset.value === option.value"
74
- :aria-describedby="`${presetName}-${option.value}`"
75
- @change="preset.set(option.value)"
76
- />
77
- <span class="k-appearance-preview" aria-hidden="true">
78
- <span class="k-root k-appearance-app" :data-preset="option.value">
79
- <span class="k-appearance-side" />
80
- <span class="k-appearance-panel">
81
- <span class="k-appearance-sample">Aa</span>
82
- <span class="k-appearance-line is-accent" />
83
- <span class="k-appearance-line is-short" />
65
+ <template #default="{ headingId: presetHeadingId }">
66
+ <div class="k-appearance-cards" role="radiogroup" :aria-labelledby="presetHeadingId">
67
+ <label
68
+ v-for="option in presetList"
69
+ :key="option.value"
70
+ class="k-appearance-card"
71
+ :class="{ 'is-active': preset.preset.value === option.value }"
72
+ >
73
+ <input
74
+ type="radio"
75
+ class="k-visually-hidden"
76
+ :name="presetName"
77
+ :value="option.value"
78
+ :checked="preset.preset.value === option.value"
79
+ :aria-describedby="`${presetName}-${option.value}`"
80
+ @change="preset.set(option.value)"
81
+ />
82
+ <span class="k-appearance-preview" aria-hidden="true">
83
+ <span class="k-root k-appearance-app" :data-preset="option.value">
84
+ <span class="k-appearance-side" />
85
+ <span class="k-appearance-panel">
86
+ <span class="k-appearance-sample">Aa</span>
87
+ <span class="k-appearance-line is-accent" />
88
+ <span class="k-appearance-line is-short" />
89
+ </span>
84
90
  </span>
85
91
  </span>
86
- </span>
87
- <span class="k-appearance-card-label">
88
- {{ presetTitle(option) }}
89
- <Icon
90
- v-if="preset.preset.value === option.value"
91
- name="check"
92
- class="k-appearance-card-check"
93
- />
94
- </span>
95
- <span :id="`${presetName}-${option.value}`" class="k-appearance-card-description">
96
- {{ t(`preset.${option.value}Description`) }}
97
- </span>
98
- </label>
99
- </fieldset>
92
+ <span class="k-appearance-card-label">
93
+ {{ presetTitle(option) }}
94
+ <Icon
95
+ v-if="preset.preset.value === option.value"
96
+ name="check"
97
+ class="k-appearance-card-check"
98
+ />
99
+ </span>
100
+ <span :id="`${presetName}-${option.value}`" class="k-appearance-card-description">
101
+ {{ t(`preset.${option.value}Description`) }}
102
+ </span>
103
+ </label>
104
+ </div>
105
+ </template>
100
106
  </SettingsGroup>
101
107
  <slot />
102
108
  </div>
@@ -1,7 +1,7 @@
1
1
  import type { ThemePreset } from '../../composables/usePreset';
2
- declare var __VLS_31: {};
2
+ declare var __VLS_33: {};
3
3
  type __VLS_Slots = {} & {
4
- default?: (props: typeof __VLS_31) => any;
4
+ default?: (props: typeof __VLS_33) => any;
5
5
  };
6
6
  declare const __VLS_base: import("vue").DefineComponent<{
7
7
  presets?: readonly ThemePreset[] | false;
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <div class="k-auth" :class="`k-auth-${variant}`">
3
3
  <a class="k-auth-skip k-visually-hidden-focusable" :href="`#${mainId}`">{{ skipText }}</a>
4
- <div v-if="themeSwitch || $slots.corner" class="k-auth-corner">
4
+ <header v-if="themeSwitch || $slots.corner" class="k-auth-corner">
5
5
  <slot name="corner" />
6
6
  <ThemeSwitch v-if="themeSwitch" variant="icon" :label="themeLabel" />
7
- </div>
7
+ </header>
8
8
  <main :id="mainId" class="k-auth-main" tabindex="-1">
9
9
  <div class="k-auth-panel">
10
10
  <header class="k-auth-header">
@@ -32,6 +32,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
32
32
  results?: (string | number) | undefined;
33
33
  placeholder?: string | undefined;
34
34
  bind?: Record<string, unknown>;
35
+ dir?: string | undefined;
35
36
  class?: import("vue").ClassValue;
36
37
  role?: string | undefined;
37
38
  'aria-label'?: string | undefined;
@@ -190,7 +191,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
190
191
  accesskey?: string | undefined;
191
192
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
192
193
  contextmenu?: string | undefined;
193
- dir?: string | undefined;
194
194
  draggable?: (boolean | "true" | "false") | undefined;
195
195
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
196
196
  enterKeyHint?: import("vue").HTMLAttributes["enterkeyhint"];
@@ -251,6 +251,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
251
251
  results?: (string | number) | undefined;
252
252
  placeholder?: string | undefined;
253
253
  bind?: Record<string, unknown>;
254
+ dir?: string | undefined;
254
255
  class?: import("vue").ClassValue;
255
256
  role?: string | undefined;
256
257
  'aria-label'?: string | undefined;
@@ -409,7 +410,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
409
410
  accesskey?: string | undefined;
410
411
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
411
412
  contextmenu?: string | undefined;
412
- dir?: string | undefined;
413
413
  draggable?: (boolean | "true" | "false") | undefined;
414
414
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
415
415
  enterKeyHint?: import("vue").HTMLAttributes["enterkeyhint"];
@@ -7,6 +7,7 @@
7
7
  :variant="variant"
8
8
  :sidebar-label="sidebarLabel"
9
9
  :menu-label="menuLabel"
10
+ :close-label="closeLabel"
10
11
  :skip-label="skipLabel"
11
12
  :fluid="fluid"
12
13
  :topbar="hasDesktopTopbar"
@@ -15,12 +16,7 @@
15
16
  :view-transition="viewTransition"
16
17
  >
17
18
  <template #sidebar="{ collapsed: isCollapsed }">
18
- <Sidebar
19
- :label="navLabel"
20
- :collapsible="collapsible"
21
- :collapse-label="collapseLabel"
22
- :expand-label="expandLabel"
23
- >
19
+ <Sidebar :label="navLabel" :collapsible="collapsible" :collapse-label="collapseLabel">
24
20
  <template #header>
25
21
  <slot name="brand" :collapsed="isCollapsed">
26
22
  <Brand
@@ -203,7 +199,7 @@ const props = defineProps({
203
199
  menuLabel: { type: String, required: false },
204
200
  skipLabel: { type: String, required: false },
205
201
  collapseLabel: { type: String, required: false },
206
- expandLabel: { type: String, required: false },
202
+ closeLabel: { type: String, required: false },
207
203
  accountLabel: { type: String, required: false },
208
204
  themeLabel: { type: String, required: false }
209
205
  });
@@ -1,9 +1,9 @@
1
1
  import type { IconName } from '../../composables/useIcons';
2
2
  import type { BreadcrumbItem } from '../layout/types';
3
- import type { CommandGroup, CommandItem, MenuItem } from '../overlays/types';
3
+ import type { CommandGroupLabelSlotProps, CommandItem, MenuItem } from '../overlays/types';
4
4
  import type { ThemePreset } from '../../composables/usePreset';
5
5
  import type { LinkTarget } from '../core/types';
6
- import type { AccountAction, BrandLogo, DashboardAccount, DashboardNavigation, DashboardSearch, DashboardSearchProps, DashboardVariant, SettingsModalAccount, SettingsModalSection, ThemeSwitchPlacement } from './types';
6
+ import type { AccountAction, BrandLogo, DashboardAccount, DashboardNavigation, DashboardSearch, DashboardSearchProps, DashboardVariant, SettingsModalAccount, SettingsModalSection, SettingsSectionSlotProps, ThemeSwitchPlacement } from './types';
7
7
  declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
8
8
  props: import("vue").PublicProps & __VLS_PrettifyLocal<({
9
9
  variant?: DashboardVariant;
@@ -40,7 +40,7 @@ declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeo
40
40
  menuLabel?: string;
41
41
  skipLabel?: string;
42
42
  collapseLabel?: string;
43
- expandLabel?: string;
43
+ closeLabel?: string;
44
44
  accountLabel?: string;
45
45
  themeLabel?: string;
46
46
  } & {
@@ -58,6 +58,7 @@ declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeo
58
58
  readonly variant?: import("../layout/types").AppShellVariant | undefined;
59
59
  readonly sidebarLabel?: string | undefined;
60
60
  readonly menuLabel?: string | undefined;
61
+ readonly closeLabel?: string | undefined;
61
62
  readonly skipLabel?: string | undefined;
62
63
  readonly fluid?: boolean | undefined;
63
64
  readonly topbar?: boolean | undefined;
@@ -72,6 +73,7 @@ declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeo
72
73
  readonly style?: import("vue").StyleValue;
73
74
  readonly results?: (string | number) | undefined;
74
75
  readonly placeholder?: string | undefined | undefined;
76
+ readonly dir?: string | undefined | undefined;
75
77
  readonly class?: import("vue").ClassValue;
76
78
  readonly role?: string | undefined | undefined;
77
79
  readonly 'aria-label'?: string | undefined | undefined;
@@ -227,7 +229,6 @@ declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeo
227
229
  readonly accesskey?: string | undefined | undefined;
228
230
  readonly contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
229
231
  readonly contextmenu?: string | undefined | undefined;
230
- readonly dir?: string | undefined | undefined;
231
232
  readonly draggable?: (boolean | "true" | "false") | undefined;
232
233
  readonly enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
233
234
  readonly enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -302,12 +303,7 @@ declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeo
302
303
  'search-empty'?: (props: {
303
304
  query: string;
304
305
  }) => unknown;
305
- 'search-group-label'?: (props: {
306
- group?: CommandGroup<T>;
307
- label?: string;
308
- description?: string;
309
- recent: boolean;
310
- }) => unknown;
306
+ 'search-group-label'?: (props: CommandGroupLabelSlotProps<T>) => unknown;
311
307
  'search-after-results'?: (props: {
312
308
  query: string;
313
309
  count: number;
@@ -317,14 +313,8 @@ declare const __VLS_export: <T = unknown>(__VLS_props: NonNullable<Awaited<typeo
317
313
  close: () => void;
318
314
  }) => unknown;
319
315
  } & {
320
- [key: `settings-section-${string}`]: ((props: {
321
- section: SettingsModalSection;
322
- close: () => void;
323
- }) => unknown) | undefined;
324
- [key: `settings-actions-${string}`]: ((props: {
325
- section: SettingsModalSection;
326
- close: () => void;
327
- }) => unknown) | undefined;
316
+ [key: `settings-section-${string}`]: ((props: SettingsSectionSlotProps) => unknown) | undefined;
317
+ [key: `settings-actions-${string}`]: ((props: SettingsSectionSlotProps) => unknown) | undefined;
328
318
  };
329
319
  emit: ((evt: "accountSelect", item: MenuItem, event: Event) => void) & (((event: "update:open", value: boolean) => void) & ((event: "update:collapsed", value: boolean) => void) & ((event: "update:settingsOpen", value: boolean) => void) & ((event: "update:settingsSection", value: string | undefined) => void));
330
320
  }>) => import("vue").VNode & {
@@ -20,6 +20,7 @@
20
20
  >
21
21
  <template v-if="loading && !title" #title>
22
22
  <Skeleton width="14rem" height="1.5rem" />
23
+ <span class="k-visually-hidden">{{ t("common.loading") }}</span>
23
24
  </template>
24
25
  <template v-if="status || $slots.badge" #badge>
25
26
  <slot name="badge">
@@ -73,7 +74,7 @@
73
74
  :key="section.title ?? index"
74
75
  :title="section.title"
75
76
  :description="section.description"
76
- :level="2"
77
+ :level="childLevel"
77
78
  class="k-detail-section"
78
79
  >
79
80
  <DescriptionList :items="section.items" layout="stacked" />
@@ -120,6 +121,7 @@ const backText = computed(() => props.backLabel ?? t("common.back"));
120
121
  const tabsText = computed(() => props.tabsLabel ?? t("detailPage.sections"));
121
122
  const asideText = computed(() => props.asideLabel ?? t("detailPage.details"));
122
123
  const errorText = computed(() => props.errorTitle ?? t("detailPage.error"));
124
+ const childLevel = computed(() => Math.min(props.level + 1, 6));
123
125
  const tab = defineModel("tab", { type: [String, Number] });
124
126
  const slots = useSlots();
125
127
  const panelSlots = computed(
@@ -39,6 +39,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
39
39
  style?: import("vue").StyleValue;
40
40
  results?: (string | number) | undefined;
41
41
  placeholder?: string | undefined | undefined;
42
+ dir?: string | undefined | undefined;
42
43
  class?: import("vue").ClassValue;
43
44
  role?: string | undefined | undefined;
44
45
  'aria-label'?: string | undefined | undefined;
@@ -194,7 +195,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
194
195
  accesskey?: string | undefined | undefined;
195
196
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
196
197
  contextmenu?: string | undefined | undefined;
197
- dir?: string | undefined | undefined;
198
198
  draggable?: (boolean | "true" | "false") | undefined;
199
199
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
200
200
  enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -250,6 +250,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
250
250
  style?: import("vue").StyleValue;
251
251
  results?: (string | number) | undefined;
252
252
  placeholder?: string | undefined | undefined;
253
+ dir?: string | undefined | undefined;
253
254
  class?: import("vue").ClassValue;
254
255
  role?: string | undefined | undefined;
255
256
  'aria-label'?: string | undefined | undefined;
@@ -405,7 +406,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
405
406
  accesskey?: string | undefined | undefined;
406
407
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
407
408
  contextmenu?: string | undefined | undefined;
408
- dir?: string | undefined | undefined;
409
409
  draggable?: (boolean | "true" | "false") | undefined;
410
410
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
411
411
  enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -1,16 +1,20 @@
1
1
  <template>
2
2
  <div class="k-error-page" :class="{ 'is-fill': fill }">
3
- <div v-if="brandName || brandIcon || brandLogo || $slots.brand" class="k-error-brand">
3
+ <component
4
+ :is="fill ? 'header' : 'div'"
5
+ v-if="brandName || brandIcon || brandLogo || $slots.brand"
6
+ class="k-error-brand"
7
+ >
4
8
  <slot name="brand">
5
9
  <Brand :name="brandName" :icon="brandIcon" :logo="brandLogo" :to="homeTo" size="sm" />
6
10
  </slot>
7
- </div>
11
+ </component>
8
12
  <component :is="fill ? 'main' : 'div'" class="k-error-body">
9
13
  <div class="k-error-panel">
10
14
  <p class="k-error-code" aria-hidden="true">{{ code }}</p>
11
- <h1 class="k-error-title">
15
+ <component :is="`h${level}`" class="k-error-title">
12
16
  <slot name="title">{{ resolvedTitle }}</slot>
13
- </h1>
17
+ </component>
14
18
  <p v-if="resolvedMessage || $slots.message" class="k-error-message">
15
19
  <slot name="message">{{ resolvedMessage }}</slot>
16
20
  </p>
@@ -47,6 +51,7 @@ import { computed } from "vue";
47
51
  import { useLocale } from "../../composables/useLocale";
48
52
  import Button from "../core/Button.vue";
49
53
  import Brand from "./Brand.vue";
54
+ import { isClient } from "../../internal/core/env";
50
55
  const props = defineProps({
51
56
  error: { type: [Object, null], required: false },
52
57
  statusCode: { type: Number, required: false },
@@ -60,6 +65,7 @@ const props = defineProps({
60
65
  brandIcon: { type: null, required: false },
61
66
  brandLogo: { type: String, required: false },
62
67
  fill: { type: Boolean, required: false, default: true },
68
+ level: { type: Number, required: false, default: 1 },
63
69
  onHome: { type: Function, required: false },
64
70
  onRetry: { type: Function, required: false }
65
71
  });
@@ -97,7 +103,7 @@ const resolvedMessage = computed(() => {
97
103
  return preset.value.message;
98
104
  });
99
105
  function goBack() {
100
- if (typeof window === "undefined") return;
106
+ if (!isClient()) return;
101
107
  window.history.back();
102
108
  }
103
109
  </script>
@@ -1,17 +1,18 @@
1
1
  import type { IconName } from '../../composables/useIcons';
2
2
  import type { ErrorLike } from './types';
3
3
  import type { LinkTarget } from '../core/types';
4
- declare var __VLS_1: {}, __VLS_14: {}, __VLS_16: {}, __VLS_18: {}, __VLS_44: {};
4
+ import type { HeadingLevel } from '../layout/types';
5
+ declare var __VLS_7: {}, __VLS_26: {}, __VLS_28: {}, __VLS_30: {}, __VLS_56: {};
5
6
  type __VLS_Slots = {} & {
6
- brand?: (props: typeof __VLS_1) => any;
7
+ brand?: (props: typeof __VLS_7) => any;
7
8
  } & {
8
- title?: (props: typeof __VLS_14) => any;
9
+ title?: (props: typeof __VLS_26) => any;
9
10
  } & {
10
- message?: (props: typeof __VLS_16) => any;
11
+ message?: (props: typeof __VLS_28) => any;
11
12
  } & {
12
- actions?: (props: typeof __VLS_18) => any;
13
+ actions?: (props: typeof __VLS_30) => any;
13
14
  } & {
14
- default?: (props: typeof __VLS_44) => any;
15
+ default?: (props: typeof __VLS_56) => any;
15
16
  };
16
17
  declare const __VLS_base: import("vue").DefineComponent<{
17
18
  error?: ErrorLike | null;
@@ -26,6 +27,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
26
27
  brandIcon?: IconName;
27
28
  brandLogo?: string;
28
29
  fill?: boolean;
30
+ level?: HeadingLevel;
29
31
  onHome?: () => void;
30
32
  onRetry?: () => void;
31
33
  innerHTML?: string | undefined | undefined;
@@ -232,6 +234,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
232
234
  brandIcon?: IconName;
233
235
  brandLogo?: string;
234
236
  fill?: boolean;
237
+ level?: HeadingLevel;
235
238
  onHome?: () => void;
236
239
  onRetry?: () => void;
237
240
  innerHTML?: string | undefined | undefined;
@@ -427,6 +430,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
427
430
  ref_key?: string | undefined | undefined;
428
431
  }> & Readonly<{}>, {
429
432
  fill: boolean;
433
+ level: HeadingLevel;
430
434
  backLabel: string | false;
431
435
  homeTo: LinkTarget;
432
436
  homeLabel: string | false;
@@ -44,7 +44,7 @@
44
44
  </form>
45
45
 
46
46
  <div class="k-form-page-footer" :class="{ 'is-sticky': sticky, 'is-dirty': isDirty }">
47
- <p class="k-form-page-status" aria-live="polite">
47
+ <p class="k-form-page-status">
48
48
  <span v-if="isDirty" class="k-form-page-dot" aria-hidden="true" />
49
49
  <slot name="status" :dirty="isDirty">{{ isDirty ? dirtyText : "" }}</slot>
50
50
  </p>
@@ -60,10 +60,11 @@
60
60
  >{{ cancelText }}</Button
61
61
  >
62
62
  <Button
63
+ ref="submitButton"
63
64
  type="submit"
64
65
  :form="formId"
65
66
  :loading="isSaving"
66
- :disabled="requireDirty && !isDirty"
67
+ :disabled="submitDisabled"
67
68
  :icon="submitIcon"
68
69
  >{{ submitText }}</Button
69
70
  >
@@ -74,8 +75,9 @@
74
75
  </template>
75
76
 
76
77
  <script setup>
77
- import { computed, useId } from "vue";
78
+ import { computed, useId, useTemplateRef, watch } from "vue";
78
79
  import { useDirtyGuard } from "../../composables/useDirtyGuard";
80
+ import { focusStable, hasFocusWithin } from "../../internal/core/focus";
79
81
  import { useLocale } from "../../composables/useLocale";
80
82
  import Button from "../core/Button.vue";
81
83
  import Form from "../core/Form.vue";
@@ -115,6 +117,17 @@ const dirtyText = computed(() => props.dirtyMessage ?? t("common.unsavedChanges"
115
117
  const formId = useId();
116
118
  const isDirty = computed(() => props.dirty ?? Boolean(props.form?.dirty.value));
117
119
  const isSaving = computed(() => props.saving || Boolean(props.form?.submitting.value));
120
+ const submitDisabled = computed(() => props.requireDirty && !isDirty.value);
121
+ const submitButton = useTemplateRef("submitButton");
122
+ watch(
123
+ submitDisabled,
124
+ (disabled) => {
125
+ if (!disabled || !hasFocusWithin(submitButton.value?.$el)) return;
126
+ const form = document.getElementById(formId);
127
+ if (form) focusStable(form);
128
+ },
129
+ { flush: "pre" }
130
+ );
118
131
  const guard = useDirtyGuard(isDirty, {
119
132
  enabled: () => props.guard && !isSaving.value,
120
133
  title: props.guardTitle,
@@ -12,14 +12,14 @@
12
12
 
13
13
  <slot name="before" />
14
14
 
15
- <Card v-if="error" class="k-list-state" padding="lg">
15
+ <Card v-if="error" class="k-list-state" padding="lg" role="alert">
16
16
  <slot name="error" :retry="() => emit('retry')">
17
17
  <EmptyState
18
18
  variant="plain"
19
19
  icon="exclamation-triangle"
20
20
  :title="errorText"
21
21
  :description="typeof error === 'string' ? error : void 0"
22
- :level="2"
22
+ :level="childLevel"
23
23
  >
24
24
  <template #actions>
25
25
  <Button
@@ -41,7 +41,7 @@
41
41
  :icon="emptyIcon"
42
42
  :title="emptyTitleText"
43
43
  :description="emptyDescription"
44
- :level="2"
44
+ :level="childLevel"
45
45
  >
46
46
  <template v-if="$slots['empty-actions']" #actions>
47
47
  <slot name="empty-actions" />
@@ -123,7 +123,7 @@
123
123
  icon="magnifying-glass"
124
124
  :title="noResultsTitleText"
125
125
  :description="isFiltered ? noResultsDescriptionText : void 0"
126
- :level="2"
126
+ :level="childLevel"
127
127
  >
128
128
  <template v-if="isFiltered" #actions>
129
129
  <Button size="sm" variant="soft" tone="neutral" @click="clearFilters">{{
@@ -153,12 +153,14 @@
153
153
  </template>
154
154
  </Card>
155
155
 
156
+ <LiveRegion :message="resultsMessage" />
157
+
156
158
  <slot />
157
159
  </div>
158
160
  </template>
159
161
 
160
162
  <script setup>
161
- import { computed, useSlots, watch } from "vue";
163
+ import { computed, ref, useSlots, watch } from "vue";
162
164
  import { useLocale } from "../../composables/useLocale";
163
165
  import Button from "../core/Button.vue";
164
166
  import { createCollator, readCell, sortRows } from "../../internal/data/rows";
@@ -171,6 +173,7 @@ import Table from "../data/Table.vue";
171
173
  import EmptyState from "../feedback/EmptyState.vue";
172
174
  import Card from "../layout/Card.vue";
173
175
  import PageHeader from "../layout/PageHeader.vue";
176
+ import LiveRegion from "../../internal/core/LiveRegion.vue";
174
177
  const props = defineProps({
175
178
  title: { type: String, required: false },
176
179
  description: { type: String, required: false },
@@ -208,7 +211,8 @@ const props = defineProps({
208
211
  clearLabel: { type: String, required: false },
209
212
  errorTitle: { type: String, required: false },
210
213
  retryLabel: { type: String, required: false },
211
- selectedText: { type: Function, required: false }
214
+ selectedText: { type: Function, required: false },
215
+ resultsText: { type: Function, required: false }
212
216
  });
213
217
  const { locale, t } = useLocale();
214
218
  const searchPlaceholderText = computed(() => props.searchPlaceholder ?? t("common.search"));
@@ -222,6 +226,7 @@ const noResultsDescriptionText = computed(
222
226
  const clearText = computed(() => props.clearLabel ?? t("listPage.clearFilters"));
223
227
  const errorText = computed(() => props.errorTitle ?? t("common.somethingWentWrong"));
224
228
  const retryText = computed(() => props.retryLabel ?? t("common.retry"));
229
+ const childLevel = computed(() => Math.min(props.level + 1, 6));
225
230
  function selectedLabel(count) {
226
231
  return props.selectedText ? props.selectedText(count) : t("common.selected", { count });
227
232
  }
@@ -294,9 +299,17 @@ function clearFilters() {
294
299
  filter.value = Array.isArray(filter.value) ? [] : null;
295
300
  emit("clear");
296
301
  }
302
+ const interacted = ref(false);
297
303
  watch([search, filterValues], () => {
304
+ interacted.value = true;
298
305
  if (page.value !== 1) page.value = 1;
299
306
  });
307
+ const resultsMessage = computed(() => {
308
+ if (props.loading || props.error || isFirstRun.value) return "";
309
+ const total = resultTotal.value;
310
+ if (!interacted.value && total > 0) return "";
311
+ return props.resultsText ? props.resultsText(total) : t("listPage.results", { count: total });
312
+ });
300
313
  watch(resultTotal, (total) => {
301
314
  if (props.loading) return;
302
315
  const last = Math.max(1, Math.ceil(total / pageSize.value));