@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
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div
3
+ ref="root"
3
4
  class="k-filter-pills"
4
5
  :class="`k-filter-pills-${size}`"
5
6
  role="group"
@@ -31,8 +32,9 @@
31
32
  </template>
32
33
 
33
34
  <script setup>
34
- import { computed, h, ref, watch } from "vue";
35
+ import { computed, h, nextTick, ref, useTemplateRef, watch } from "vue";
35
36
  import { useLocale } from "../../composables/useLocale";
37
+ import { hasFocusWithin } from "../../internal/core/focus";
36
38
  import Button from "../core/Button.vue";
37
39
  import DropdownMenu from "../overlays/DropdownMenu.vue";
38
40
  import Popover from "../overlays/Popover.vue";
@@ -79,8 +81,22 @@ function toggle(value) {
79
81
  if (active && props.required) return;
80
82
  setModel(active ? null : value);
81
83
  }
82
- function clear() {
84
+ const root = useTemplateRef("root");
85
+ async function clear() {
86
+ const group = root.value;
87
+ const hadFocus = hasFocusWithin(group);
83
88
  setModel(props.multiple ? [] : null);
89
+ if (!hadFocus || !group) return;
90
+ await nextTick();
91
+ if (hasFocusWithin(group)) return;
92
+ const pill = Array.from(group.querySelectorAll("button, [href]")).find(
93
+ (element) => !element.classList.contains("k-filter-pills-clear") && !element.hasAttribute("disabled") && element.getAttribute("aria-disabled") !== "true"
94
+ );
95
+ if (pill) pill.focus({ preventScroll: true });
96
+ else {
97
+ group.tabIndex = -1;
98
+ group.focus({ preventScroll: true });
99
+ }
84
100
  }
85
101
  function setPanel(value, open) {
86
102
  if (open) openPanel.value = value;
@@ -28,15 +28,17 @@
28
28
  </span>
29
29
  </div>
30
30
  <nav class="k-pagination-nav" :aria-label="navLabel">
31
- <Button
32
- variant="ghost"
33
- tone="neutral"
34
- :size="buttonSize"
35
- icon="chevron-left"
36
- :disabled="disabled || page <= 1"
31
+ <button
32
+ type="button"
33
+ class="k-btn k-btn-neutral k-btn-ghost is-icon"
34
+ :class="`k-btn-${buttonSize}`"
35
+ :disabled="disabled"
36
+ :aria-disabled="!disabled && page <= 1 ? 'true' : void 0"
37
37
  :aria-label="previousText"
38
38
  @click="go(page - 1)"
39
- />
39
+ >
40
+ <Icon name="chevron-left" />
41
+ </button>
40
42
  <ul v-if="!compact" role="list" class="k-pagination-list">
41
43
  <li v-for="item in items" :key="item.key">
42
44
  <span
@@ -51,7 +53,7 @@
51
53
  type="button"
52
54
  class="k-pagination-page"
53
55
  :aria-current="item.value === page ? 'page' : void 0"
54
- :aria-label="`${pageText} ${item.value}`"
56
+ :aria-label="pageText(item.value)"
55
57
  :disabled="disabled"
56
58
  @click="go(item.value)"
57
59
  >
@@ -60,15 +62,17 @@
60
62
  </li>
61
63
  </ul>
62
64
  <span v-else class="k-pagination-compact"> {{ page }} / {{ pageCount }} </span>
63
- <Button
64
- variant="ghost"
65
- tone="neutral"
66
- :size="buttonSize"
67
- icon="chevron-right"
68
- :disabled="disabled || page >= pageCount"
65
+ <button
66
+ type="button"
67
+ class="k-btn k-btn-neutral k-btn-ghost is-icon"
68
+ :class="`k-btn-${buttonSize}`"
69
+ :disabled="disabled"
70
+ :aria-disabled="!disabled && page >= pageCount ? 'true' : void 0"
69
71
  :aria-label="nextText"
70
72
  @click="go(page + 1)"
71
- />
73
+ >
74
+ <Icon name="chevron-right" />
75
+ </button>
72
76
  </nav>
73
77
  </div>
74
78
  </template>
@@ -77,7 +81,7 @@
77
81
  import { computed, useId, watch } from "vue";
78
82
  import { paginationItems } from "../../internal/data/pagination";
79
83
  import { useLocale } from "../../composables/useLocale";
80
- import Button from "../core/Button.vue";
84
+ import { translateOr } from "../../locale";
81
85
  import Icon from "../core/Icon.vue";
82
86
  const props = defineProps({
83
87
  total: { type: Number, required: true },
@@ -95,9 +99,11 @@ const props = defineProps({
95
99
  ofText: { type: String, required: false },
96
100
  emptyText: { type: String, required: false }
97
101
  });
98
- const { t } = useLocale();
102
+ const { t, locale } = useLocale();
99
103
  const navLabel = computed(() => props.label ?? t("pagination.label"));
100
- const pageText = computed(() => props.pageLabel ?? t("pagination.page"));
104
+ function pageText(value) {
105
+ return translateOr(locale.value, props.pageLabel, "pagination.page", { page: value });
106
+ }
101
107
  const previousText = computed(() => props.previousLabel ?? t("pagination.previous"));
102
108
  const nextText = computed(() => props.nextLabel ?? t("pagination.next"));
103
109
  const pageSizeText = computed(() => props.pageSizeLabel ?? t("pagination.pageSize"));
@@ -29,6 +29,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
29
29
  style?: import("vue").StyleValue;
30
30
  results?: (string | number) | undefined;
31
31
  placeholder?: string | undefined | undefined;
32
+ dir?: string | undefined | undefined;
32
33
  class?: import("vue").ClassValue;
33
34
  role?: string | undefined | undefined;
34
35
  'aria-label'?: string | undefined | undefined;
@@ -184,7 +185,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
184
185
  accesskey?: string | undefined | undefined;
185
186
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
186
187
  contextmenu?: string | undefined | undefined;
187
- dir?: string | undefined | undefined;
188
188
  draggable?: (boolean | "true" | "false") | undefined;
189
189
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
190
190
  enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -241,6 +241,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
241
241
  style?: import("vue").StyleValue;
242
242
  results?: (string | number) | undefined;
243
243
  placeholder?: string | undefined | undefined;
244
+ dir?: string | undefined | undefined;
244
245
  class?: import("vue").ClassValue;
245
246
  role?: string | undefined | undefined;
246
247
  'aria-label'?: string | undefined | undefined;
@@ -396,7 +397,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
396
397
  accesskey?: string | undefined | undefined;
397
398
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
398
399
  contextmenu?: string | undefined | undefined;
399
- dir?: string | undefined | undefined;
400
400
  draggable?: (boolean | "true" | "false") | undefined;
401
401
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
402
402
  enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -3,8 +3,17 @@
3
3
  class="k-selection-bar"
4
4
  :class="[`k-selection-bar-${placement}`, { 'is-visible': visible }]"
5
5
  >
6
- <span class="k-visually-hidden" role="status">{{ announcement }}</span>
7
- <div v-if="visible" class="k-selection-bar-panel" role="group" :aria-label="labelText">
6
+ <span ref="status" class="k-visually-hidden" role="status" tabindex="-1">{{
7
+ announcement
8
+ }}</span>
9
+ <div
10
+ v-if="visible"
11
+ ref="panel"
12
+ class="k-selection-bar-panel"
13
+ role="group"
14
+ :aria-label="labelText"
15
+ @focusin="onFocusIn"
16
+ >
8
17
  <span class="k-selection-bar-count">
9
18
  <span class="k-selection-bar-dot" aria-hidden="true" />
10
19
  <slot name="count" :count="count" :total="total">{{ countText }}</slot>
@@ -37,8 +46,9 @@
37
46
  </template>
38
47
 
39
48
  <script setup>
40
- import { computed, onMounted, ref, watch } from "vue";
49
+ import { computed, nextTick, onMounted, ref, useTemplateRef, watch } from "vue";
41
50
  import { useLocale } from "../../composables/useLocale";
51
+ import { hasFocusWithin } from "../../internal/core/focus";
42
52
  import Button from "../core/Button.vue";
43
53
  const props = defineProps({
44
54
  count: { type: Number, required: true },
@@ -78,4 +88,23 @@ watch(
78
88
  }
79
89
  );
80
90
  onMounted(() => mounted.value = true);
91
+ const panel = useTemplateRef("panel");
92
+ const status = useTemplateRef("status");
93
+ let origin = null;
94
+ function onFocusIn(event) {
95
+ const from = event.relatedTarget;
96
+ if (from instanceof HTMLElement && !panel.value?.contains(from)) origin = from;
97
+ }
98
+ watch(
99
+ visible,
100
+ async (isVisible) => {
101
+ if (isVisible) return;
102
+ if (!hasFocusWithin(panel.value)) return;
103
+ const target = origin;
104
+ await nextTick();
105
+ if (target?.isConnected && !target.closest("[inert]")) target.focus({ preventScroll: true });
106
+ else status.value?.focus({ preventScroll: true });
107
+ },
108
+ { flush: "pre" }
109
+ );
81
110
  </script>
@@ -38,7 +38,8 @@
38
38
  >
39
39
  <Icon v-if="trend !== 'flat'" name="arrow-right" class="k-stat-delta-icon" />
40
40
  <span class="k-visually-hidden">{{ trendText }}</span>
41
- {{ deltaText }}
41
+ {{ deltaText
42
+ }}<span v-if="favorText" class="k-visually-hidden">, {{ favorText }}</span>
42
43
  </span>
43
44
  <span v-if="hint" class="k-stat-hint">{{ hint }}</span>
44
45
  <slot name="footer" />
@@ -103,6 +104,11 @@ const deltaText = computed(() => {
103
104
  const sign = trend.value === "up" ? "+" : trend.value === "down" ? "-" : "";
104
105
  return `${sign}${absolute}${props.deltaSuffix}`;
105
106
  });
107
+ const favorText = computed(() => {
108
+ if (resolvedTone.value === "positive") return t("stat.favorable");
109
+ if (resolvedTone.value === "negative") return t("stat.unfavorable");
110
+ return "";
111
+ });
106
112
  const trendText = computed(() => {
107
113
  if (trend.value === "up") return props.increaseLabel ?? t("stat.increased");
108
114
  if (trend.value === "down") return props.decreaseLabel ?? t("stat.decreased");
@@ -40,6 +40,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
40
40
  results?: (string | number) | undefined;
41
41
  placeholder?: string | undefined;
42
42
  bind?: Record<string, unknown>;
43
+ dir?: string | undefined;
43
44
  class?: import("vue").ClassValue;
44
45
  role?: string | undefined;
45
46
  'aria-label'?: string | undefined;
@@ -198,7 +199,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
198
199
  accesskey?: string | undefined;
199
200
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
200
201
  contextmenu?: string | undefined;
201
- dir?: string | undefined;
202
202
  draggable?: (boolean | "true" | "false") | undefined;
203
203
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
204
204
  enterKeyHint?: import("vue").HTMLAttributes["enterkeyhint"];
@@ -266,6 +266,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
266
266
  results?: (string | number) | undefined;
267
267
  placeholder?: string | undefined;
268
268
  bind?: Record<string, unknown>;
269
+ dir?: string | undefined;
269
270
  class?: import("vue").ClassValue;
270
271
  role?: string | undefined;
271
272
  'aria-label'?: string | undefined;
@@ -424,7 +425,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
424
425
  accesskey?: string | undefined;
425
426
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
426
427
  contextmenu?: string | undefined;
427
- dir?: string | undefined;
428
428
  draggable?: (boolean | "true" | "false") | undefined;
429
429
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
430
430
  enterKeyHint?: import("vue").HTMLAttributes["enterkeyhint"];
@@ -13,11 +13,12 @@
13
13
  :style="maxHeight ? { '--k-table-max-height': maxHeight } : void 0"
14
14
  >
15
15
  <div
16
+ ref="scroller"
16
17
  class="k-table-scroll"
17
- :tabindex="regionLabelled ? 0 : void 0"
18
- :role="regionLabelled ? 'region' : void 0"
19
- :aria-labelledby="caption ? captionId : void 0"
20
- :aria-label="caption ? void 0 : label"
18
+ :tabindex="scrollable ? 0 : void 0"
19
+ :role="isRegion ? 'region' : void 0"
20
+ :aria-labelledby="isRegion && caption ? captionId : void 0"
21
+ :aria-label="isRegion && !caption ? regionLabel : void 0"
21
22
  >
22
23
  <table class="k-table-el" :aria-busy="loading ? 'true' : void 0">
23
24
  <caption v-if="caption" :id="captionId" :class="{ 'k-visually-hidden': captionHidden }">
@@ -127,9 +128,24 @@
127
128
  </label>
128
129
  </td>
129
130
  <td v-for="column in columns" :key="column.key" :class="cellClass(column)">
131
+ <button
132
+ v-if="column.key === linkColumnKey && clickOnly"
133
+ type="button"
134
+ class="k-table-link"
135
+ @click.stop="emit('rowClick', row, index, $event)"
136
+ >
137
+ <slot
138
+ :name="`cell-${column.key}`"
139
+ :row="row"
140
+ :value="cellValue(column, row)"
141
+ :index="index"
142
+ :column="column"
143
+ >{{ cellText(column, row) }}</slot
144
+ >
145
+ </button>
130
146
  <component
131
147
  :is="rowLinks.get(row).is"
132
- v-if="column.key === linkColumnKey && rowLinks.has(row)"
148
+ v-else-if="column.key === linkColumnKey && rowLinks.has(row)"
133
149
  v-bind="rowLinks.get(row).attrs"
134
150
  class="k-table-link"
135
151
  @click.stop
@@ -158,12 +174,23 @@
158
174
  </tbody>
159
175
  </table>
160
176
  </div>
161
- <span v-if="loading" role="status" class="k-visually-hidden">{{ loadingLabel }}</span>
177
+ <LiveRegion :message="loading ? loadingLabel : live.message.value" />
162
178
  </div>
163
179
  </template>
164
180
 
165
181
  <script setup>
166
- import { computed, getCurrentInstance, useId, useTemplateRef, watchEffect } from "vue";
182
+ import {
183
+ computed,
184
+ getCurrentInstance,
185
+ onMounted,
186
+ ref,
187
+ useId,
188
+ useTemplateRef,
189
+ watchEffect
190
+ } from "vue";
191
+ import { useResizeObserver } from "../../internal/core/resize";
192
+ import LiveRegion from "../../internal/core/LiveRegion.vue";
193
+ import { useLiveMessage } from "../../internal/core/live";
167
194
  import { useLinkResolver } from "../../internal/core/link";
168
195
  import { readColumn } from "../../internal/data/rows";
169
196
  import { rowDelay } from "../../internal/data/stagger";
@@ -203,15 +230,26 @@ const captionId = useId();
203
230
  const { resolveLink } = useLinkResolver();
204
231
  const instance = getCurrentInstance();
205
232
  const headCheck = useTemplateRef("headCheck");
206
- const regionLabelled = computed(() => Boolean(props.caption || props.label));
233
+ const live = useLiveMessage();
234
+ const scroller = useTemplateRef("scroller");
235
+ const scrollable = ref(false);
236
+ const isRegion = computed(() => scrollable.value || Boolean(props.label));
237
+ const regionLabel = computed(() => props.label ?? t("table.label"));
238
+ function measure() {
239
+ const element = scroller.value;
240
+ if (!element) return;
241
+ scrollable.value = element.scrollWidth > element.clientWidth + 1 || element.scrollHeight > element.clientHeight + 1;
242
+ }
243
+ onMounted(measure);
244
+ useResizeObserver(() => [scroller.value, scroller.value?.firstElementChild], measure);
207
245
  const hasWidths = computed(() => props.columns.some((column) => column.width));
208
246
  const colspan = computed(() => props.columns.length + (props.selectable ? 1 : 0));
209
247
  const linkColumnKey = computed(() => props.linkKey ?? props.columns[0]?.key);
210
- const rowsInteractive = computed(
211
- () => Boolean(
212
- props.rowTo || instance?.vnode.props?.onRowClick || instance?.vnode.props?.["onRow-click"]
213
- )
248
+ const hasRowClick = computed(
249
+ () => Boolean(instance?.vnode.props?.onRowClick || instance?.vnode.props?.["onRow-click"])
214
250
  );
251
+ const rowsInteractive = computed(() => Boolean(props.rowTo || hasRowClick.value));
252
+ const clickOnly = computed(() => !props.rowTo && hasRowClick.value);
215
253
  function keyOf(row, index) {
216
254
  if (typeof props.rowKey === "function") return props.rowKey(row, index);
217
255
  const value = row[props.rowKey];
@@ -247,8 +285,7 @@ function cellClass(column) {
247
285
  ];
248
286
  }
249
287
  function ariaSort(column) {
250
- if (!column.sortable) return void 0;
251
- if (sort.value?.key !== column.key) return "none";
288
+ if (!column.sortable || sort.value?.key !== column.key) return void 0;
252
289
  return sort.value.direction === "asc" ? "ascending" : "descending";
253
290
  }
254
291
  function sortIcon(column) {
@@ -259,6 +296,17 @@ function toggleSort(column) {
259
296
  if (sort.value?.key !== column.key) sort.value = { key: column.key, direction: "asc" };
260
297
  else if (sort.value.direction === "asc") sort.value = { key: column.key, direction: "desc" };
261
298
  else sort.value = null;
299
+ const current = sort.value;
300
+ if (!current) {
301
+ live.announce(t("table.sortCleared"));
302
+ return;
303
+ }
304
+ live.announce(
305
+ t("table.sortedBy", {
306
+ column: column.label ?? column.key,
307
+ direction: t(current.direction === "asc" ? "table.ascending" : "table.descending")
308
+ })
309
+ );
262
310
  }
263
311
  const selectedSet = computed(() => new Set(selected.value));
264
312
  function isSelected(row, index) {
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <span
3
+ ref="root"
3
4
  class="k-tag"
4
5
  :class="[
5
6
  `k-tag-${tone}`,
@@ -27,8 +28,10 @@
27
28
  </template>
28
29
 
29
30
  <script setup>
30
- import { computed } from "vue";
31
+ import { computed, useTemplateRef } from "vue";
32
+ import { hasFocusWithin, neighborFocusTarget } from "../../internal/core/focus";
31
33
  import { useLocale } from "../../composables/useLocale";
34
+ import { formatLocaleMessage } from "../../locale";
32
35
  import Icon from "../core/Icon.vue";
33
36
  const props = defineProps({
34
37
  label: { type: String, required: false },
@@ -39,9 +42,24 @@ const props = defineProps({
39
42
  removeLabel: { type: String, required: false },
40
43
  disabled: { type: Boolean, required: false }
41
44
  });
42
- const { t } = useLocale();
45
+ const { t, locale } = useLocale();
46
+ const root = useTemplateRef("root");
43
47
  const emit = defineEmits(["remove"]);
48
+ function focusTarget(element) {
49
+ const parent = element.parentElement;
50
+ const buttons = parent ? Array.from(
51
+ parent.querySelectorAll(
52
+ ":scope > .k-tag > .k-tag-remove:not(:disabled)"
53
+ )
54
+ ).filter((button) => !element.contains(button)) : [];
55
+ const after = buttons.find(
56
+ (button) => element.compareDocumentPosition(button) & Node.DOCUMENT_POSITION_FOLLOWING
57
+ );
58
+ return after ?? buttons[buttons.length - 1] ?? neighborFocusTarget(element);
59
+ }
44
60
  function onRemove() {
61
+ const element = root.value;
62
+ if (element && hasFocusWithin(element)) focusTarget(element)?.focus({ preventScroll: true });
45
63
  emit("remove");
46
64
  }
47
65
  function onKeydown(event) {
@@ -50,7 +68,9 @@ function onKeydown(event) {
50
68
  onRemove();
51
69
  }
52
70
  const removeText = computed(() => {
53
- const action = props.removeLabel ?? t("common.remove");
54
- return props.label ? `${action} ${props.label}` : action;
71
+ const label = props.label ?? "";
72
+ if (props.removeLabel)
73
+ return formatLocaleMessage(locale.value.code, props.removeLabel, { label });
74
+ return label ? t("common.removeItem", { label }) : t("common.remove");
55
75
  });
56
76
  </script>
@@ -19,6 +19,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
19
19
  style?: import("vue").StyleValue;
20
20
  results?: (string | number) | undefined;
21
21
  placeholder?: string | undefined | undefined;
22
+ dir?: string | undefined | undefined;
22
23
  class?: import("vue").ClassValue;
23
24
  role?: string | undefined | undefined;
24
25
  'aria-label'?: string | undefined | undefined;
@@ -174,7 +175,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
174
175
  accesskey?: string | undefined | undefined;
175
176
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
176
177
  contextmenu?: string | undefined | undefined;
177
- dir?: string | undefined | undefined;
178
178
  draggable?: (boolean | "true" | "false") | undefined;
179
179
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
180
180
  enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -221,6 +221,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
221
221
  style?: import("vue").StyleValue;
222
222
  results?: (string | number) | undefined;
223
223
  placeholder?: string | undefined | undefined;
224
+ dir?: string | undefined | undefined;
224
225
  class?: import("vue").ClassValue;
225
226
  role?: string | undefined | undefined;
226
227
  'aria-label'?: string | undefined | undefined;
@@ -376,7 +377,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
376
377
  accesskey?: string | undefined | undefined;
377
378
  contenteditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
378
379
  contextmenu?: string | undefined | undefined;
379
- dir?: string | undefined | undefined;
380
380
  draggable?: (boolean | "true" | "false") | undefined;
381
381
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
382
382
  enterKeyHint?: "search" | "done" | "previous" | "next" | "enter" | "go" | "send" | undefined;
@@ -410,8 +410,8 @@ declare const __VLS_base: import("vue").DefineComponent<{
410
410
  }> & Readonly<{
411
411
  onRemove?: (() => any) | undefined;
412
412
  }>, {
413
- size: BadgeSize;
414
413
  tone: Tone;
414
+ size: BadgeSize;
415
415
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
416
416
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
417
417
  declare const _default: typeof __VLS_export;
@@ -14,7 +14,11 @@
14
14
  <div class="k-timeline-content">
15
15
  <slot name="item" :item="item" :index="index">
16
16
  <div class="k-timeline-head">
17
- <span class="k-timeline-title">{{ item.title }}</span>
17
+ <span class="k-timeline-title"
18
+ ><span v-if="toneText(item.tone)" class="k-visually-hidden"
19
+ >{{ toneText(item.tone) }}: </span
20
+ >{{ item.title }}</span
21
+ >
18
22
  <time v-if="item.time" class="k-timeline-time" :datetime="item.datetime">{{
19
23
  item.time
20
24
  }}</time>
@@ -29,10 +33,17 @@
29
33
  </template>
30
34
 
31
35
  <script setup>
36
+ import { useLocale } from "../../composables/useLocale";
32
37
  import Icon from "../core/Icon.vue";
33
38
  import { rowDelay } from "../../internal/data/stagger";
34
39
  defineProps({
35
40
  items: { type: Array, required: true },
36
41
  compact: { type: Boolean, required: false }
37
42
  });
43
+ const { t } = useLocale();
44
+ function toneText(tone) {
45
+ if (tone === "danger" || tone === "warning" || tone === "info" || tone === "success")
46
+ return t(`tone.${tone}`);
47
+ return "";
48
+ }
38
49
  </script>