@nxgt/material-vue 0.26.1 → 0.28.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 (168) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/README.md +10 -7
  3. package/dist/Button-D1uzdbOJ.js +728 -0
  4. package/dist/{DropdownMenuTrigger-BHAhXGUO.js → DropdownMenuTrigger-BsuyNVzV.js} +48 -41
  5. package/dist/HoverCardTrigger-DaM5d4hE.js +510 -0
  6. package/dist/{camera-DvKuqT4L.js → camera-CxXijySa.js} +4 -4
  7. package/dist/components/base-content.css +139 -0
  8. package/dist/components/base.css +150 -0
  9. package/dist/components/components.css +2 -0
  10. package/dist/components/reduced-motion.css +56 -0
  11. package/dist/components/theme-tokens.css +116 -0
  12. package/dist/components/ui/actions/button-group/button-group.css +1 -1
  13. package/dist/components/ui/feedback/toast/toast.css +21 -0
  14. package/dist/components/ui/primitives/label/label.css +33 -0
  15. package/dist/{components-CCWod7cJ.js → components-Db9OdMfQ.js} +19053 -18364
  16. package/dist/components.js +7 -7
  17. package/dist/composables.js +3 -3
  18. package/dist/dnd.js +1 -1
  19. package/dist/field-name-attribute-Bl7LSVK0.js +4 -0
  20. package/dist/{form-scope-x-7TYn2s.js → form-scope-BILi3ke-.js} +1 -1
  21. package/dist/{i18n-provider-CaaZCmaR.js → i18n-provider-BPK68eqM.js} +1 -1
  22. package/dist/i18n.js +4 -4
  23. package/dist/icon-button-D60G5B_Z.js +262 -0
  24. package/dist/lib/components/ui/actions/button/Button.vue.d.ts +22 -4
  25. package/dist/lib/components/ui/actions/button/button-tones.d.ts +36 -0
  26. package/dist/lib/components/ui/actions/button/button.variants.d.ts +1 -1
  27. package/dist/lib/components/ui/actions/button/button.wrap.d.ts +8 -0
  28. package/dist/lib/components/ui/actions/button/label-text.d.ts +9 -0
  29. package/dist/lib/components/ui/actions/button/prepend-to-child.d.ts +18 -0
  30. package/dist/lib/components/ui/actions/button/use-click-lock.d.ts +14 -0
  31. package/dist/lib/components/ui/actions/copy-button/copy-button.vue.d.ts +6 -2
  32. package/dist/lib/components/ui/actions/icon-button/icon-button.compound-variants.d.ts +28 -0
  33. package/dist/lib/components/ui/actions/icon-button/icon-button.vue.d.ts +1 -1
  34. package/dist/lib/components/ui/actions/responsive-button/responsive-button.vue.d.ts +1 -3
  35. package/dist/lib/components/ui/collections/data-table/partials/data-table-empty.vue.d.ts +5 -1
  36. package/dist/lib/components/ui/collections/data-table/partials/data-table-scroll-region.vue.d.ts +28 -0
  37. package/dist/lib/components/ui/collections/data-table/partials/data-table-toolbar.d.ts +60 -0
  38. package/dist/lib/components/ui/collections/data-table/types.d.ts +9 -0
  39. package/dist/lib/components/ui/collections/data-table/use-scroll-edges.d.ts +22 -0
  40. package/dist/lib/components/ui/collections/pagination/PaginationFirst.vue.d.ts +1 -1
  41. package/dist/lib/components/ui/collections/pagination/PaginationItem.vue.d.ts +1 -1
  42. package/dist/lib/components/ui/collections/pagination/PaginationLast.vue.d.ts +1 -1
  43. package/dist/lib/components/ui/collections/pagination/PaginationNext.vue.d.ts +1 -1
  44. package/dist/lib/components/ui/collections/pagination/PaginationPrevious.vue.d.ts +1 -1
  45. package/dist/lib/components/ui/dates/calendar/Calendar.vue.d.ts +4 -4
  46. package/dist/lib/components/ui/dates/calendar/calendar-day-label.d.ts +17 -0
  47. package/dist/lib/components/ui/dates/calendar/calendar-years.d.ts +11 -0
  48. package/dist/lib/components/ui/dates/calendar/partials/calendar-month-select.vue.d.ts +18 -0
  49. package/dist/lib/components/ui/dates/calendar/partials/calendar-year-select.vue.d.ts +19 -0
  50. package/dist/lib/components/ui/dates/calendar/use-calendar-locale.d.ts +7 -0
  51. package/dist/lib/components/ui/dates/calendar/use-calendar-selected-hint.d.ts +17 -0
  52. package/dist/lib/components/ui/dates/date-range-field/partials/date-range-day.vue.d.ts +8 -0
  53. package/dist/lib/components/ui/display/cards/cards.gallery.d.ts +3 -3
  54. package/dist/lib/components/ui/display/list-tile/list-tile.vue.d.ts +10 -6
  55. package/dist/lib/components/ui/feedback/alert-dialog/AlertDialogContent.vue.d.ts +2 -2
  56. package/dist/lib/components/ui/feedback/sonner/index.d.ts +1 -0
  57. package/dist/lib/components/ui/feedback/toast/toast.d.ts +7 -0
  58. package/dist/lib/components/ui/feedback/toast/toast.vue.d.ts +18 -2
  59. package/dist/lib/components/ui/fields/contacts/consts.d.ts +1 -1
  60. package/dist/lib/components/ui/forms/use-field-blur.d.ts +3 -0
  61. package/dist/lib/components/ui/layout/app-shell/activity-content.vue.d.ts +9 -3
  62. package/dist/lib/components/ui/layout/app-shell/activity-layout.vue.d.ts +21 -4
  63. package/dist/lib/components/ui/layout/app-shell/app-header.vue.d.ts +7 -5
  64. package/dist/lib/components/ui/layout/app-shell/app-sidebar.vue.d.ts +4 -1
  65. package/dist/lib/components/ui/layout/app-shell/index.d.ts +2 -2
  66. package/dist/lib/components/ui/layout/app-shell/router-menu-link.d.ts +7 -0
  67. package/dist/lib/components/ui/layout/app-shell/types.d.ts +8 -0
  68. package/dist/lib/components/ui/layout/app-shell/use-content-scroll.d.ts +13 -0
  69. package/dist/lib/components/ui/layout/app-shell/use-navigation-sheet.d.ts +17 -0
  70. package/dist/lib/components/ui/layout/sidebar/sidebar-context.d.ts +15 -0
  71. package/dist/lib/components/ui/layout/sidebar/sidebar-menu-item.vue.d.ts +13 -4
  72. package/dist/lib/components/ui/media/carousel/carousel-next.vue.d.ts +1 -1
  73. package/dist/lib/components/ui/media/carousel/carousel-previous.vue.d.ts +1 -1
  74. package/dist/lib/components/ui/menu-item-variant.d.ts +4 -4
  75. package/dist/lib/components/ui/overlays/context-menu/ContextMenuContent.vue.d.ts +2 -2
  76. package/dist/lib/components/ui/overlays/dialog/DialogContent.vue.d.ts +2 -2
  77. package/dist/lib/components/ui/overlays/dialog/DialogScrollContent.vue.d.ts +2 -2
  78. package/dist/lib/components/ui/overlays/dialog/use-escape-forward.d.ts +17 -0
  79. package/dist/lib/components/ui/overlays/dialog/use-inert-others.d.ts +17 -0
  80. package/dist/lib/components/ui/overlays/dialog/use-modal-content.d.ts +32 -0
  81. package/dist/lib/components/ui/overlays/drawer/DrawerContent.vue.d.ts +2 -2
  82. package/dist/lib/components/ui/overlays/dropdown-menu/DropdownMenu.vue.d.ts +3 -1
  83. package/dist/lib/components/ui/overlays/dropdown-menu/DropdownMenuContent.vue.d.ts +2 -2
  84. package/dist/lib/components/ui/overlays/popover/PopoverContent.vue.d.ts +2 -2
  85. package/dist/lib/components/ui/overlays/sheet/SheetContent.vue.d.ts +2 -2
  86. package/dist/lib/components/ui/primitives/card/CardTitle.vue.d.ts +11 -4
  87. package/dist/lib/components/ui/primitives/card/index.d.ts +1 -0
  88. package/dist/lib/components/ui/primitives/tabs/Tabs.vue.d.ts +6 -2
  89. package/dist/lib/components/ui/primitives/tabs/TabsList.vue.d.ts +2 -2
  90. package/dist/lib/components/ui/primitives/tabs/TabsTrigger.vue.d.ts +6 -4
  91. package/dist/lib/components/ui/primitives/tabs/tabs-classes.d.ts +27 -0
  92. package/dist/lib/components/ui/primitives/tabs/tabs-indicator.vue.d.ts +25 -0
  93. package/dist/lib/components/ui/primitives/tabs/tabs-variant.d.ts +5 -8
  94. package/dist/lib/components/ui/primitives/toggle/Toggle.vue.d.ts +1 -1
  95. package/dist/lib/components/ui/primitives/toggle/index.d.ts +1 -1
  96. package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-box.vue.d.ts +2 -0
  97. package/dist/lib/components/ui/selection/select/SelectContent.vue.d.ts +2 -2
  98. package/dist/lib/components/ui/selection/select-chip-field/select-chip-field.vue.d.ts +1 -0
  99. package/dist/lib/components/ui/widgets/emoji/types.d.ts +1 -6
  100. package/dist/lib/i18n/resources/en/en.d.ts +23 -0
  101. package/dist/lib/i18n/resources/en/material.json.d.ts +28 -5
  102. package/dist/lib/i18n/resources/fr/fr.d.ts +23 -0
  103. package/dist/lib/i18n/resources/fr/material.json.d.ts +28 -5
  104. package/dist/lib/i18n/resources/resources.d.ts +46 -0
  105. package/dist/lib/i18n/translator.d.ts +1 -1
  106. package/dist/lib/lib/field-name-attribute.d.ts +7 -0
  107. package/dist/lib/lib/focus-field.d.ts +17 -0
  108. package/dist/lib/lib/index.d.ts +1 -0
  109. package/dist/lib.js +76 -74
  110. package/dist/main.js +13 -13
  111. package/dist/map.js +4 -4
  112. package/dist/material-vue.css +1 -1
  113. package/dist/{pdf-outline-sidebar-D3vq2qfS.js → pdf-outline-sidebar-BXGTDISI.js} +2 -2
  114. package/dist/{pdf-page-BrJbyjQj.js → pdf-page-BR4G03kN.js} +1 -1
  115. package/dist/{pdf-page-list-BCgYEszV.js → pdf-page-list-bjQm6_kf.js} +2 -2
  116. package/dist/{pdf-reader-BAzevSJU.js → pdf-reader-DGVEFNc0.js} +9 -9
  117. package/dist/{pdf-sidebar-DSh2Mend.js → pdf-sidebar-CiM6dwAm.js} +3 -3
  118. package/dist/{pdf-thumbnail-sidebar-D_EMcbKF.js → pdf-thumbnail-sidebar-fM3DGJzD.js} +3 -3
  119. package/dist/{pdf-toolbar-BcL7HlfS.js → pdf-toolbar-mWlGTWU1.js} +5 -5
  120. package/dist/pdf.js +2 -2
  121. package/dist/{sortable-provider-DMpmM7Ke.js → sortable-provider-Dml11nQY.js} +2 -2
  122. package/dist/{stored-language-Bxhsx4iB.js → stored-language-UnInBB6T.js} +56 -10
  123. package/dist/{stx-player-MldK_ZAZ.js → stx-player-BS7-CXFx.js} +2 -2
  124. package/dist/styles.css +10 -368
  125. package/dist/{translator-CLI_7Crg.js → translator-J3_vaV_A.js} +1 -1
  126. package/dist/{use-heading-spy-VPuFj2Gt.js → use-heading-spy-_dk8kGwL.js} +19 -19
  127. package/dist/use-inert-others-CtGqZKR8.js +22 -0
  128. package/dist/{use-material-translation-CONqD9wJ.js → use-material-translation-Do6ztdtV.js} +3 -3
  129. package/docs/components/buttons-and-actions.md +71 -16
  130. package/docs/components/data-display.md +13 -2
  131. package/docs/components/data-table-filter-and-lists.md +85 -5
  132. package/docs/components/date-and-time.md +25 -1
  133. package/docs/components/feedback-and-status.md +86 -11
  134. package/docs/components/form-fields.md +13 -4
  135. package/docs/components/media-and-files.md +7 -0
  136. package/docs/components/navigation-and-layout.md +19 -1
  137. package/docs/components/overlays-and-menus.md +20 -4
  138. package/docs/components/primitives.md +97 -20
  139. package/docs/components/rich-widgets.md +10 -0
  140. package/docs/components/selection-and-choice.md +12 -1
  141. package/docs/getting-started.md +2 -2
  142. package/docs/guides/app-shell.md +102 -6
  143. package/docs/guides/forms.md +58 -5
  144. package/docs/guides/helpers.md +2 -1
  145. package/docs/guides/i18n.md +24 -4
  146. package/docs/guides/ssr.md +1 -1
  147. package/docs/guides/theming.md +148 -6
  148. package/docs/previews/data-display-codegroup.webp +0 -0
  149. package/docs/previews/data-display-description.webp +0 -0
  150. package/docs/previews/feedback-status-toast.webp +0 -0
  151. package/docs/previews/primitives-tabs.webp +0 -0
  152. package/docs/previews/rich-widgets-emojipicker.webp +0 -0
  153. package/docs/roadmap.md +30 -1
  154. package/docs/troubleshooting.md +889 -12
  155. package/lib/components/base-content.css +139 -0
  156. package/lib/components/base.css +150 -0
  157. package/lib/components/components.css +2 -0
  158. package/lib/components/reduced-motion.css +56 -0
  159. package/lib/components/theme-tokens.css +116 -0
  160. package/lib/components/ui/actions/button-group/button-group.css +1 -1
  161. package/lib/components/ui/feedback/toast/toast.css +21 -0
  162. package/lib/components/ui/primitives/label/label.css +33 -0
  163. package/lib/styles.css +10 -368
  164. package/package.json +2 -2
  165. package/dist/Button-16J7vTpE.js +0 -665
  166. package/dist/HoverCardTrigger-C41002JS.js +0 -455
  167. package/dist/icon-button-CDdNsZuZ.js +0 -227
  168. package/dist/lib/components/ui/widgets/emoji/emoji.groups.d.ts +0 -6
@@ -32,8 +32,9 @@ build:
32
32
  (`RichTextEditor` code blocks), vue-sonner (`Toaster`),
33
33
  vue-advanced-cropper (`ImageCropper`), the `Spinner` animation, and the
34
34
  `nxgt-*` classes of `ButtonGroup`, `ContactItem`, `OpeningHoursItem`,
35
- `AttributeForm` and `AttributeValuesForm` (the packages are dependencies,
36
- the rest ship in `lib/components/`);
35
+ `AttributeForm` and `AttributeValuesForm`, and the required-field mark drawn
36
+ after a `Label` (the packages are dependencies, the rest ship in
37
+ `lib/components/`);
37
38
  - `@source "../dist"`, so your build scans the compiled components;
38
39
  - the **tokens**: CSS variables on `:root`, and their dark values on `.dark`
39
40
  and `[data-theme="dark"]`;
@@ -51,9 +52,11 @@ build:
51
52
  | `--primary`, `--primary-foreground` | `bg-primary`, `text-primary-foreground` | filled buttons, active states, focus |
52
53
  | `--secondary`, `--secondary-foreground` | `bg-secondary`, … | the secondary colour |
53
54
  | `--muted`, `--muted-foreground` | `bg-muted`, `text-muted-foreground` | quiet surfaces, hints, placeholders |
55
+ | `--track`, `--track-fill` | `bg-track`, `bg-track-fill`, `border-track-fill` | the empty part of a slider or meter, the drawer handle; the slider range and thumb |
54
56
  | `--accent`, `--accent-foreground` | `bg-accent`, … | hover surfaces |
55
- | `--error`, `--success`, `--info`, `--warning` (+ `-foreground`) | `bg-error`, `text-success`, … | the status colours of `Button`, `Alert`, `Badge`, toasts; `--error` also colours `variant="error"` menu items |
56
- | `--destructive` | `bg-destructive`, `text-destructive` | destructive actions (menu items use `--error`) |
57
+ | `--error`, `--success`, `--info`, `--warning` (+ `-foreground`) | `bg-error`, `text-success`, … | the status colours of `Button`, `Alert`, `Badge`, toasts |
58
+ | `--error-text` | `text-error-text` | error drawn as text: field messages, `HelperText` in its error state, form and dialog errors, `variant="error"` menu items |
59
+ | `--destructive` | `bg-destructive`, `text-destructive` | deprecated alias of `--error`: the light theme sets it to `var(--error)`, the dark theme keeps its own value; use `--error` |
57
60
  | `--card`, `--popover`, `--tooltip` (+ `-foreground`) | `bg-card`, `bg-popover`, `bg-tooltip` | surfaces |
58
61
  | `--border`, `--input`, `--ring` | `border-border`, `border-input`, `ring-ring` | outlines |
59
62
  | `--chart-1` … `--chart-5` | `bg-chart-1`, … | chart series (the charts read them at runtime) |
@@ -90,7 +93,9 @@ Redefine the variables **after** the import, for light and dark separately:
90
93
  Override the variable, not the `@theme` entry: `--color-primary` is defined as
91
94
  `var(--primary)`, so one change reaches both modes and every derived colour.
92
95
 
93
- For a single area of the page, set the variables on a wrapper:
96
+ For a single area of the page, set the `--color-*` variables on a wrapper
97
+ (the `@theme` entries are resolved on the root, so setting `--primary` on an
98
+ element below it changes nothing):
94
99
 
95
100
  ```vue
96
101
  <script setup lang="ts">
@@ -98,12 +103,149 @@ import { Button } from '@nxgt/material-vue/components';
98
103
  </script>
99
104
 
100
105
  <template>
101
- <section :style="{ '--primary': 'var(--error)' }">
106
+ <section :style="{ '--color-primary': 'var(--error)' }">
102
107
  <Button>Delete workspace</Button>
103
108
  </section>
104
109
  </template>
105
110
  ```
106
111
 
112
+ ## Contrast and reduced motion
113
+
114
+ **Contrast.** The shipped light palette keeps the text of every filled status
115
+ colour at 4.5:1 or more (WCAG 1.4.3): `--secondary` 5.7:1, `--success` 5.6:1,
116
+ `--info` 5.8:1 and `--warning` 5.3:1 against their `-foreground`, and
117
+ `--secondary` as text (a `tonal`, `outlined` or `link` `Button`) 6.0:1 on
118
+ `--background`, 4.8:1 on its own 15 % `tonal` tint.
119
+
120
+ The dark theme keeps brighter values, read as text on the dark surfaces: the
121
+ dark `--secondary` (`oklch(0.66 0.1135 245.65)`) is 6.5:1 on `--background`
122
+ and 5.8:1 on `--card` (a `tonal` secondary `Button` 5.4:1 and 4.6:1). Under
123
+ near-white text those brights are too light, so every filled surface built on
124
+ them is tinted in the dark theme: a filled `secondary` `Button`, `IconButton`
125
+ or `Badge` at 70 % (5.2:1 on `--background`, 4.9:1 on `--card`), a filled
126
+ `success`, `info` or `warning` one at 60 % (7.3:1, 5.7:1 and 7.5:1 on
127
+ `--background`; 6.7:1, 5.3:1 and 7.0:1 on `--card`). Their hover, focus and
128
+ pressed states are tinted further down, so they only gain contrast.
129
+
130
+ In the light theme the filled `primary`, `secondary`, `success`, `info`,
131
+ `warning` and `error` buttons darken when hovered, focused or pressed (mixed
132
+ with 10, 15 and 20 % black) rather than fading toward the page, so their
133
+ near-white text only gains contrast (the filled `default` variant's states are
134
+ unchanged); a `tonal` button's focus tint is 10 %
135
+ (lighter than its 15 % rest), an `outlined` one's 15 %, and its hover keeps the
136
+ text colour.
137
+
138
+ The `tonal`, `outlined` and `link` variants of `Button` and `IconButton` draw
139
+ their text and icon in one tone per colour, read on `--background`, on
140
+ `--card` and on the variant's own tint (15 % at most, at rest or focused). In
141
+ the light theme `primary`, `secondary`, `info` and `success` use the token
142
+ itself (5.8, 4.8, 4.9 and 4.7:1 at their lowest) and `warning` and `error` the
143
+ token mixed with 15 % black (6.0 and 5.4:1). In the dark theme `primary` is
144
+ mixed with 60 % white (8.1:1 on `--card`: the token itself is a dark indigo,
145
+ 2.2:1), `success` and `warning` with 15 % white (5.0 and 5.4:1), `error` with
146
+ 30 % white (5.9:1), and `secondary` and `info` use the token (4.6 and 5.3:1).
147
+ The tones are mixed from the tokens (`color-mix(in oklab, var(--color-error)
148
+ 85%, black)`), so an override of a token moves its tone with it; a text colour
149
+ of your own on one of those buttons (`class="text-primary"`) replaces the tone
150
+ and is yours to check.
151
+
152
+ A `Badge` used as a link (`as-child` around an `<a>`) darkens on hover like a filled
153
+ button (mixed with 10 % black; in the dark theme its tint drops by ten
154
+ points) rather than fading toward the page. A selected `ListTile` draws its
155
+ subtitle in `text-foreground/70` (7.0:1 on the selected tint, where the muted
156
+ colour gave 4.4:1). The light `--error` is `oklch(0.56 0.245 27.325)`, a shade
157
+ darker than the dark theme's: a filled `error` button's near-white text reaches
158
+ 4.8:1 (it was 4.6:1). The dark `--error` keeps `0.577`: a lighter value drops
159
+ the filled surface's near-white text below 4.5:1 (`0.62` gives 3.85:1).
160
+
161
+ **Error text has a token of its own**, `--error-text` (`text-error-text`), so
162
+ the fill can stay dark while the text is light enough to read. The light value
163
+ is `color-mix(in oklab, var(--error) 94%, black)` (5.7:1 on `--background`
164
+ and `--card`, 4.8:1 on the `bg-error/10` tint of a focused menu item, where
165
+ `--error` gives 5.0 and 4.2:1); the dark one is
166
+ `color-mix(in oklab, var(--error) 80%, white)`, 5.9:1 on `--background` and
167
+ 5.3:1 on `--card`, where `--error` itself gives 4.2 and 3.8:1. Field messages,
168
+ `HelperText` in its error state, form, dialog and upload errors, a textarea's
169
+ counter over its limit, the error lines of `Terminal`, a
170
+ `variant="error"` menu item and the falling values of the metric cards use it.
171
+
172
+ Which one to use:
173
+
174
+ - **`text-error-text`** for an error written as text on a page, card or
175
+ popover surface (your own validation message, a failed row, an inline
176
+ error), and for an icon drawn beside that text, so the two match.
177
+ - **`text-error`** (with `bg-error`, `border-error`, `ring-error`,
178
+ `stroke-error`) for fills, borders, rings and icons that stand alone: those
179
+ need 3:1 (WCAG 1.4.11), which `--error` reaches in both themes. Text on a
180
+ filled error surface is `text-error-foreground`.
181
+
182
+ `--error-text` is computed where it is declared, on the root, and `@theme`
183
+ resolves `--color-error-text` there too: an override of `--error` under `:root`
184
+ and `.dark, [data-theme="dark"]` moves it, but setting `--error-text` or
185
+ `--error` on an element below the root changes nothing. Below the root, set
186
+ `--color-error-text` (and `--color-error` for fills) on that element, or put
187
+ the override on the root.
188
+
189
+ Storybook's `Guides/Theming/Contrast` measures all of this in both themes:
190
+ the surfaces' text, the error text (`HelperText` and a field's message on
191
+ `--background` and `--card`), the `Alert`s and the `Timeline`, `Button` and
192
+ `IconButton` in every variant and colour, and a `Badge` link in every colour,
193
+ at rest, hovered, focused and pressed, the tracks and the tabs;
194
+ `Data display/ListTile` measures the selected tile. Run them against your own
195
+ tokens after an override.
196
+
197
+ **Tabs.** An `underline` tab's active label is `--primary` in the light
198
+ theme (7.3:1 on `--background` and `--card`, 6.7:1 on `--muted`) and
199
+ `--primary` mixed with 60 % white in the dark one (10.0:1, 9.0:1 and 7.4:1);
200
+ its bar and every tab's focus outline are `--primary` in the light theme and
201
+ `--track-fill` in the dark one (at least 6.7:1 and 9.0:1 on those surfaces).
202
+ An inactive label is `--muted-foreground`, and turns to `--foreground` when
203
+ hovered. A `segmented` tab's active label is `--foreground` on the raised
204
+ surface (19.9:1 light, 17.0:1 dark); that surface is only 1.1:1 to 1.2:1 on
205
+ the track, so it has a `--muted-foreground` border (5.0:1 light, 4.7:1 dark
206
+ on the track), and the label also changes colour and weight. Storybook's
207
+ `Guides/Theming/Contrast` story `Tabs` measures each label at rest, hovered
208
+ and focused, the outline, the bar and the border, on the three surfaces, in
209
+ both themes.
210
+
211
+ `--muted-foreground` is 5.5:1 on `--background` and `--card`, 5.1:1 on the
212
+ "paper" tint (`bg-background-paper`, 5 % primary) and 5.0:1 on `--muted` in
213
+ the light theme; in the dark theme it is 6.4:1 on `--background`, 5.7:1 on
214
+ `--card`, 6.3:1 on the paper tint and 4.7:1 on `--muted`. The dark `--muted`
215
+ is a dark surface (`oklch(0.279 0.041 260.031)`, it was the light value, a
216
+ near-white block on a dark page) and `--foreground` on it reaches 14.0:1.
217
+
218
+ **Tracks.** The empty part of a `Slider`, of the password strength meter and
219
+ the `Drawer` handle use `--track` (`bg-track`), and the `Slider`'s range and
220
+ thumb border `--track-fill` (`bg-track-fill`, `border-track-fill`). In the
221
+ dark theme the track reaches 3.6:1 on `--background` and 3.2:1 on `--card`
222
+ (WCAG 1.4.11; `bg-muted`, a dark surface now, gave 1.4:1 and 1.2:1), and the
223
+ fill 3.4:1 on the track. The light theme keeps a pale track (`--track` is the
224
+ light `--muted`) and `--track-fill` is `--primary`: the thumb, 7.3:1 on the
225
+ page, shows the value. A track, bar, handle or divider of your own drawn with
226
+ `bg-muted` is near invisible in the dark theme now that `--muted` is a dark
227
+ surface: draw it with `bg-track`.
228
+
229
+ When you override one of these tokens, keep its pair at 4.5:1 (3:1 for an
230
+ icon or a border), or the `Badge`, `Button`, `Alert` and toast text built on it fails
231
+ an accessibility audit. The muted text of a highlighted menu entry (a
232
+ `DropdownMenuShortcut`, the code in `LanguageSwitcher`) switches to
233
+ `--accent-foreground` while the entry is highlighted, so a `--muted-foreground`
234
+ of your own does not have to pass on the highlight colour.
235
+
236
+ **Reduced motion.** `styles.css` imports `components/reduced-motion.css`: one
237
+ `@media (prefers-reduced-motion: reduce)` rule that turns off the transitions
238
+ and animations of every catalogue component (everything under a `data-slot`,
239
+ and the toasts): dialogs, sheets and menus appear without sliding or fading,
240
+ buttons and toasts without transitions. The `Spinner` and any `animate-spin` element (a spinning
241
+ loading icon) keep turning: they are the only sign that something is loading.
242
+ The rule is `!important` but unlayered and with a specificity of 0, so a
243
+ component's own `duration-*` utility does not outrank it, and your own
244
+ `!important` rule on a class does; to keep one motion for everyone, override it
245
+ on that element with that rule inside `@media (prefers-reduced-motion: reduce)`.
246
+ Your own components outside a `data-slot` are yours: use Tailwind's
247
+ `motion-reduce:` variant on them.
248
+
107
249
  ## Dark mode
108
250
 
109
251
  Dark values apply under a `.dark` class **or** a `data-theme="dark"`
Binary file
package/docs/roadmap.md CHANGED
@@ -19,6 +19,9 @@ Nothing in progress right now; see Next.
19
19
 
20
20
  ## Later
21
21
 
22
+ - **Next major: `ListTile`'s `data-slot` becomes `list-tile`** — it is
23
+ `item-detail` today, so the name matches the component like every other
24
+ slot. Breaking for a selector or a test that looks for `item-detail`.
22
25
  - **1.0: the same amounts and dates on every machine** — `formatAmount` and
23
26
  `formatDate` stop falling back to the runtime's locale when you pass none, so
24
27
  a server and a browser always print the same string.
@@ -92,6 +95,31 @@ Nothing in progress right now; see Next.
92
95
 
93
96
  ## Shipped
94
97
 
98
+ - **Tabs in two looks** — `underline`, the new default, whose bar slides to
99
+ the active tab, and a neutral `segmented` pill; a list that scrolls
100
+ sideways on a phone instead of widening the page, right-to-left, a visible
101
+ focus ring, labels that read 4.5:1 in both themes, and an indicator that
102
+ stops sliding under `prefers-reduced-motion`. `bar` and `line` still work,
103
+ as deprecated aliases of `underline` and `segmented`. 0.28.0.
104
+
105
+ - **Accessible by default** — error text in its own `--error-text` colour that
106
+ reads 4.5:1 in both themes, the empty part of sliders and meters in a
107
+ `--track` colour that reads 3:1, buttons, badges and status colours that
108
+ reach WCAG contrast, animations that honour `prefers-reduced-motion`, the
109
+ page behind a modal layer made `inert`, the first invalid field focused
110
+ after a failed submit (`focusFirstInvalid`), Escape that reaches the layer
111
+ below while one closes, and a `Toaster` at the top of a phone whose toasts
112
+ a tap does not pause and whose actions work over a dialog. 0.27.0.
113
+ - **Fits a phone** — `DataTable` with no height cap by default (`max-height`
114
+ when it should scroll in a box), a header row at every width, and wide
115
+ columns that scroll sideways in one region a keyboard can reach; a `Button`
116
+ never wider than its container (a long label ends in "…", or wraps with
117
+ `wrap`); `OtpField` slots that shrink to fit a narrow card. 0.27.0.
118
+ - **App shell links, landmarks and scrolling** — menu entries that are real
119
+ links (middle-click, before hydration, `aria-current="page"`, your router's
120
+ link through `link-component`), one `<main>` landmark, and a shell
121
+ that lets the document scroll, with `scroll="container"` for a full-height
122
+ screen. 0.27.0.
95
123
  - **DataTable server-side data** — hand the table one page from your loader
96
124
  (`manual`): no client paging or sorting, `v-model:sorting` and
97
125
  `v-model:row-selection` by row id (`getRowId`), a footer with "41–60 of 133"
@@ -106,7 +134,8 @@ Nothing in progress right now; see Next.
106
134
  form, date fields that disable chosen days, `SliderField` ticks and
107
135
  leading/trailing content, a presence status on `Avatar`, a logo slot on the
108
136
  QR code, slots on `AccordionCard`, an option slot on `SelectField`, Monaco's
109
- own options on `CodeEditor` and a line variant for `Tabs`. 0.25.0.
137
+ own options on `CodeEditor` and a line variant for `Tabs` (`line` is now a
138
+ deprecated alias of `segmented`). 0.25.0.
110
139
  - **DateRangeField presets and time** — one-click ranges such as Today, Last 7
111
140
  days and This month, or your own, beside the calendar (`presets`), and a time
112
141
  of day on each end of the range (`with-time`), and `min-date` / `max-date`.