@nxgt/material-vue 0.36.0 → 0.37.1
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.
- package/CHANGELOG.md +28 -0
- package/dist/{HoverCardTrigger-C3r0oc5d.js → HoverCardTrigger-jCXl6TrX.js} +1 -1
- package/dist/{camera-CaQlF4JJ.js → camera-CYwiFuGE.js} +1 -1
- package/dist/{components-D56FEfTa.js → components--v_k8diD.js} +25 -16
- package/dist/components.js +2 -2
- package/dist/{form-scope-DOL9MJL3.js → form-scope-B2oJ5fHr.js} +1 -1
- package/dist/lib/components/ui/selection/autocomplete/autocomplete-items.d.ts +2 -0
- package/dist/lib/components/ui/selection/autocomplete/autocomplete-keyboard.d.ts +1 -0
- package/dist/lib/components/ui/selection/autocomplete/autocomplete.vue.d.ts +2 -0
- package/dist/lib/components/ui/selection/autocomplete/search-types.d.ts +4 -1
- package/dist/main.js +2 -2
- package/dist/map.js +1 -1
- package/dist/material-vue.css +1 -1
- package/dist/{pdf-outline-sidebar-Gmdd3RNG.js → pdf-outline-sidebar-DJJ-ARco.js} +1 -1
- package/dist/{pdf-page-C3XhLcrp.js → pdf-page-CRt6KXdJ.js} +1 -1
- package/dist/{pdf-page-list-BTIb5Y-Y.js → pdf-page-list-BgCp5Asx.js} +2 -2
- package/dist/{pdf-reader-CX2owreo.js → pdf-reader-BGxqEx8O.js} +6 -6
- package/dist/{pdf-sidebar-BmAJ8Q_m.js → pdf-sidebar-Cvtuomgp.js} +2 -2
- package/dist/{pdf-thumbnail-sidebar-C04OeZ9M.js → pdf-thumbnail-sidebar-CeWPs7o7.js} +2 -2
- package/dist/{pdf-toolbar-zI0_eNXV.js → pdf-toolbar-BtXcyEpd.js} +1 -1
- package/dist/{stx-player-BUo2Vs0j.js → stx-player-nDsDyvc-.js} +1 -1
- package/docs/components/feedback-and-status.md +2 -0
- package/docs/components/overlays-and-menus.md +18 -0
- package/docs/components/selection-and-choice.md +14 -6
- package/docs/troubleshooting.md +80 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
|
-
import { Bf as n } from "./components
|
|
3
|
+
import { Bf as n } from "./components--v_k8diD.js";
|
|
4
4
|
import { t as r } from "./use-material-translation-DRB6oPdF.js";
|
|
5
5
|
import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, defineComponent as u, normalizeClass as d, normalizeStyle as f, openBlock as p, ref as m, renderList as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
|
|
6
6
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-outline-row.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import { Up as t } from "./components
|
|
2
|
+
import { Up as t } from "./components--v_k8diD.js";
|
|
3
3
|
import { computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, defineComponent as s, nextTick as c, normalizeClass as l, normalizeStyle as u, onBeforeUnmount as d, openBlock as f, ref as p, shallowRef as m, unref as h, watch as g } from "vue";
|
|
4
4
|
import { DEFAULT_PAGE_SIZE as _, escapeHtml as v, findTextMatches as y, highlightItemHtml as b, placeholderSize as x, rotatedSize as S } from "@nxgt/material-core/pdf-viewer";
|
|
5
5
|
//#region lib/components/ui/media/pdf-viewer/pdf-note-icons.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
|
-
import { Bf as t } from "./components
|
|
3
|
-
import { t as n } from "./pdf-page-
|
|
2
|
+
import { Bf as t } from "./components--v_k8diD.js";
|
|
3
|
+
import { t as n } from "./pdf-page-CRt6KXdJ.js";
|
|
4
4
|
import { Fragment as r, createBlock as i, createElementBlock as a, createElementVNode as o, defineComponent as s, openBlock as c, renderList as l, withCtx as u } from "vue";
|
|
5
5
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-page-list.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var d = { class: "flex flex-col items-center gap-4 px-4 py-4" }, f = /*@__PURE__*/ s({
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import { kn as t } from "./components
|
|
2
|
+
import { kn as t } from "./components--v_k8diD.js";
|
|
3
3
|
import { t as n } from "./use-material-translation-DRB6oPdF.js";
|
|
4
4
|
import { t as r } from "./Button-CurFF4Zt.js";
|
|
5
|
-
import { o as i } from "./HoverCardTrigger-
|
|
6
|
-
import { n as a } from "./pdf-page-
|
|
7
|
-
import { t as o } from "./pdf-page-list-
|
|
8
|
-
import { t as s } from "./pdf-sidebar-
|
|
9
|
-
import { t as c } from "./pdf-toolbar-
|
|
5
|
+
import { o as i } from "./HoverCardTrigger-jCXl6TrX.js";
|
|
6
|
+
import { n as a } from "./pdf-page-CRt6KXdJ.js";
|
|
7
|
+
import { t as o } from "./pdf-page-list-BgCp5Asx.js";
|
|
8
|
+
import { t as s } from "./pdf-sidebar-Cvtuomgp.js";
|
|
9
|
+
import { t as c } from "./pdf-toolbar-BtXcyEpd.js";
|
|
10
10
|
import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, nextTick as _, normalizeClass as v, onBeforeUnmount as y, onMounted as b, openBlock as x, reactive as S, ref as C, shallowRef as w, toDisplayString as T, toRef as E, unref as D, useId as O, watch as k, withCtx as A } from "vue";
|
|
11
11
|
import { AlertCircle as j, FileX2 as M, KeyRound as N, Loader2 as P } from "@lucide/vue";
|
|
12
12
|
import { pdfSourceKey as F, toPdfjsParams as I } from "@nxgt/material-core/pdf-source";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
3
|
import { t as n } from "./use-material-translation-DRB6oPdF.js";
|
|
4
|
-
import { t as r } from "./pdf-outline-sidebar-
|
|
5
|
-
import { t as i } from "./pdf-thumbnail-sidebar-
|
|
4
|
+
import { t as r } from "./pdf-outline-sidebar-DJJ-ARco.js";
|
|
5
|
+
import { t as i } from "./pdf-thumbnail-sidebar-CeWPs7o7.js";
|
|
6
6
|
import { createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, normalizeClass as l, openBlock as u, toDisplayString as d, unref as f, useId as p, useTemplateRef as m } from "vue";
|
|
7
7
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-sidebar.vue?vue&type=script&setup=true&lang.ts
|
|
8
8
|
var h = ["aria-label"], g = ["aria-label"], _ = [
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
|
-
import { Bf as n } from "./components
|
|
3
|
+
import { Bf as n } from "./components--v_k8diD.js";
|
|
4
4
|
import { t as r } from "./use-material-translation-DRB6oPdF.js";
|
|
5
|
-
import { t as i } from "./pdf-page-
|
|
5
|
+
import { t as i } from "./pdf-page-CRt6KXdJ.js";
|
|
6
6
|
import { Fragment as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createVNode as l, defineComponent as u, normalizeClass as d, openBlock as f, renderList as p, toDisplayString as m, unref as h, withCtx as g } from "vue";
|
|
7
7
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-thumbnail-sidebar.vue?vue&type=script&setup=true&lang.ts
|
|
8
8
|
var _ = ["aria-label"], v = {
|
|
@@ -4,7 +4,7 @@ import { t as n } from "./use-material-translation-DRB6oPdF.js";
|
|
|
4
4
|
import { d as r } from "./Button-CurFF4Zt.js";
|
|
5
5
|
import { t as i } from "./icon-button-CIUc1bEp.js";
|
|
6
6
|
import { a, i as o, n as s, o as c, r as l, t as u } from "./DropdownMenuTrigger-BsuyNVzV.js";
|
|
7
|
-
import { o as d } from "./HoverCardTrigger-
|
|
7
|
+
import { o as d } from "./HoverCardTrigger-jCXl6TrX.js";
|
|
8
8
|
import { Fragment as f, computed as p, createBlock as m, createCommentVNode as h, createElementBlock as g, createElementVNode as _, createTextVNode as v, createVNode as y, defineComponent as b, nextTick as x, normalizeClass as S, openBlock as C, ref as w, renderList as T, toDisplayString as E, unref as D, useTemplateRef as O, watch as k, withCtx as A } from "vue";
|
|
9
9
|
import { ChevronDown as j, ChevronLeft as M, ChevronRight as N, ChevronUp as P, Download as F, Maximize2 as I, Minimize2 as L, Moon as R, Printer as z, RotateCw as B, Search as V, Sidebar as H, ZoomIn as U, ZoomOut as W } from "@lucide/vue";
|
|
10
10
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-toolbar-search.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import { $t as t, Jt as n, Kp as r, Qt as i, Xt as a, Yt as o, en as s, tn as c } from "./components
|
|
2
|
+
import { $t as t, Jt as n, Kp as r, Qt as i, Xt as a, Yt as o, en as s, tn as c } from "./components--v_k8diD.js";
|
|
3
3
|
import { t as l } from "./use-material-translation-DRB6oPdF.js";
|
|
4
4
|
import { createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, normalizeClass as _, openBlock as v, toDisplayString as y, unref as b, withCtx as x } from "vue";
|
|
5
5
|
//#region lib/components/ui/media/stx-player/partials/stx-player-frame.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -173,6 +173,8 @@ keeps focus off the Cancel, on the content: the page behind an alert dialog is
|
|
|
173
173
|
task: focus it from a `setTimeout`, not in the handler.
|
|
174
174
|
|
|
175
175
|
**Emits:** `update:open` on `AlertDialog` — `boolean`.
|
|
176
|
+
`AlertDialogContent` is capped to the viewport height and scrolls inside itself, like `DialogContent` ([Dialog](overlays-and-menus.md#dialog)).
|
|
177
|
+
|
|
176
178
|
**Storybook:** `Feedback & status/AlertDialog` · **React:** `AlertDialog` (same parts)
|
|
177
179
|
|
|
178
180
|
---
|
|
@@ -96,6 +96,21 @@ overlay, for a dialog taller than the screen).
|
|
|
96
96
|
Unlike React, `DialogContent` renders the X by itself (turn it off with
|
|
97
97
|
`:show-close-button="false"`), and `DialogTrigger` is not `as-child` by default.
|
|
98
98
|
|
|
99
|
+
`DialogContent` and `AlertDialogContent` are capped at `100dvh - 2rem` (`100vh`
|
|
100
|
+
where `dvh` is unsupported) and scroll inside themselves, so a long body never
|
|
101
|
+
pushes the title off-screen on a phone. The built-in X scrolls with the content. On
|
|
102
|
+
browsers with `dvh` support, your own `max-h-*` through `class` wins over the
|
|
103
|
+
cap. To remove the cap and the scroll, pass `class="max-h-none overflow-visible"`:
|
|
104
|
+
|
|
105
|
+
```vue
|
|
106
|
+
<DialogContent class="max-h-none overflow-visible">
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Content wider than the dialog now scrolls horizontally or is clipped
|
|
110
|
+
(`overflow-visible` restores the old behaviour). `DialogScrollContent` is for a
|
|
111
|
+
dialog that should grow taller than the screen and scroll inside the overlay
|
|
112
|
+
instead of capping; it does not pin the header or footer.
|
|
113
|
+
|
|
99
114
|
On open, `DialogContent` moves focus into the dialog: to its first control
|
|
100
115
|
(the built-in X when there is nothing before it), or to the content itself
|
|
101
116
|
when it has none. An `@open-auto-focus` that calls `event.preventDefault()`
|
|
@@ -165,6 +180,9 @@ Parts: `Sheet`, `SheetTrigger`, `SheetContent`, `SheetHeader`, `SheetTitle`,
|
|
|
165
180
|
| `side` (`SheetContent`) | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` | the edge it slides from; left / right are ¾ wide, capped at 384 px |
|
|
166
181
|
| `default-open` / `v-model:open`, `modal` (`Sheet`) | as `Dialog` | — | a sheet is a Reka dialog |
|
|
167
182
|
|
|
183
|
+
`SheetContent` scrolls inside itself, and a top or bottom sheet is capped at
|
|
184
|
+
`100dvh`. Override the cap with `max-h-*` through `class`.
|
|
185
|
+
|
|
168
186
|
`SheetContent` always renders a top-right X, named "Close"
|
|
169
187
|
(`material.buttons.close`, translated); there is no `withCloseButton` prop in
|
|
170
188
|
Vue.
|
|
@@ -263,19 +263,19 @@ const picked = ref<string[]>(['nuxt']);
|
|
|
263
263
|
| --- | --- | --- | --- |
|
|
264
264
|
| `mode` | `'single' \| 'multiple'` | `'single'` | decides the `v-model` type |
|
|
265
265
|
| `v-model` | `string \| string[] \| null` | `null` | per `mode` |
|
|
266
|
-
| `options` | `T[]`, `T extends { value: string; label: string }` | `[]` | the items, typed by your own option type; with `on-search`, the list before a search and the selected options' labels |
|
|
266
|
+
| `options` | `T[]`, `T extends { value: string; label: string; disabled?: boolean }` | `[]` | the items (`disabled` on one: listed, announced as disabled, never picked), typed by your own option type; with `on-search`, the list before a search and the selected options' labels |
|
|
267
267
|
| `get-option-value` | `(option: T) => string` | `option.value` | the value an option stands for |
|
|
268
268
|
| `get-option-label` | `(option: T) => string` | `option.label` | the text it shows and is searched by |
|
|
269
269
|
| `filter` | `'accent-insensitive' \| 'none' \| (option: T, query: string) => boolean` | `'accent-insensitive'`, `'none'` with `on-search` | how the list is filtered as the user types: label or value, ignoring case and accents (`e` finds "École") in the provider's language; `'none'` shows `options` as given; a function gets the trimmed query, never an empty one |
|
|
270
270
|
| `free-solo` | `boolean` | `false` | accept a typed value that is not an option ("Add …") |
|
|
271
271
|
| `free-solo-label` | `(query: string) => string` | `Add "{query}"`, translated | the free-solo button's text |
|
|
272
272
|
| `@search` (prop `on-search`) | `(query: string, { signal }: { signal: AbortSignal }) => Promise<T[]>` | — | server search: called once typing pauses; its results become the list. Each search aborts the previous one, and a response that lands after a newer one is dropped |
|
|
273
|
-
| `@search-error` | `(error: unknown) => void` | — | `on-search` rejected (an abort is not a rejection) |
|
|
273
|
+
| `@search-error` | `(error: unknown) => void` | — | `on-search` rejected (an abort is not a rejection); pass the reason back as `search-error` |
|
|
274
274
|
| `min-query-length` | `number` | `1` | `on-search` waits for this many characters; below it the list says "Type at least N characters to search." |
|
|
275
|
-
| `debounce-ms` | `number` | `250` | the pause before `on-search` and `@query-change` run |
|
|
276
|
-
| `@query-change` | `(query: string) => void` | — | the typed text once typing pauses — fetch `options` yourself here |
|
|
275
|
+
| `debounce-ms` | `number` | `250` | the pause before `on-search` and `@query-change` run on typed text; an emptied query is reported to `@query-change` at once, and `on-search` never runs on it unless `min-query-length` is `0` (then it follows the pause) |
|
|
276
|
+
| `@query-change` | `(query: string) => void` | — | the typed text once typing pauses, and `''` at once when it empties (a pick, a clear) — fetch `options` yourself here |
|
|
277
277
|
| `loading` | `boolean` | — | with `@query-change`: "Loading…" in the list, `aria-busy` on it, announced |
|
|
278
|
-
| `search-error` | `string` | — |
|
|
278
|
+
| `search-error` | `string` | — | shown and announced in place of the options; with `on-search` it replaces the generic "The search failed. Try again." |
|
|
279
279
|
| `empty` | `string` | "No option found." | text when nothing matches |
|
|
280
280
|
| `required` | `boolean` | — | the asterisk, and `aria-required` on the input, which the label names |
|
|
281
281
|
| `error` | `boolean` | — | red border on the box, error helper text, `aria-invalid` on the input |
|
|
@@ -321,7 +321,10 @@ const person = ref<string | null>(null);
|
|
|
321
321
|
With `on-search`, `min-query-length` defaults to 1, `debounce-ms` to 250 and `filter` to `'none'`
|
|
322
322
|
(the server filters). A rejected search shows and announces "The search
|
|
323
323
|
failed. Try again." by itself and hands the error to `@search-error`; an abort is
|
|
324
|
-
never an error.
|
|
324
|
+
never an error. To say why instead (the API's own refusal, "the service is
|
|
325
|
+
unreachable"), keep the reason in your state from `@search-error` and pass it as
|
|
326
|
+
`search-error`: it takes precedence over the generic text, in the list and in the
|
|
327
|
+
live region. Type your search with `AutocompleteSearch<T>` (its second
|
|
325
328
|
argument is `AutocompleteSearchContext`, `{ signal }`); `AutocompleteFilter<T>`
|
|
326
329
|
and `AutocompleteSearchProps<T>` are exported from `@nxgt/material-vue/components` too.
|
|
327
330
|
`filterAutocompleteOptions(options, query, locale?)`, exported beside the
|
|
@@ -332,6 +335,11 @@ To fetch it yourself instead, keep `options` and `loading` in your state,
|
|
|
332
335
|
update them on `@query-change`, and pass `filter="none"` when the server
|
|
333
336
|
already filtered.
|
|
334
337
|
|
|
338
|
+
A disabled option (`disabled: true` on it, in `options` or in what `on-search`
|
|
339
|
+
returns) is greyed out, carries `aria-disabled` and a native `disabled`, so Tab
|
|
340
|
+
skips it, and is never picked, by click or by Enter (which picks the first
|
|
341
|
+
enabled option), in `single` and `multiple` mode.
|
|
342
|
+
|
|
335
343
|
**Accessibility.** A polite live region (`role="status"`) says "Loading…",
|
|
336
344
|
then "3 results" or "No results" (or the failure) once the search answers or
|
|
337
345
|
typing pauses — never on every keystroke. The list is `aria-busy` while
|
package/docs/troubleshooting.md
CHANGED
|
@@ -26,6 +26,7 @@ words in your error.
|
|
|
26
26
|
- [Dialogs, toasts or buttons no longer animate](#dialogs-toasts-or-buttons-no-longer-animate)
|
|
27
27
|
- [A Content-Security-Policy reports a `data:` image on every form with a required field](#a-content-security-policy-reports-a-data-image-on-every-form-with-a-required-field)
|
|
28
28
|
- [A Button's label overflows a card on a phone](#a-buttons-label-overflows-a-card-on-a-phone)
|
|
29
|
+
- [A dialog or sheet scrolls, or clips a child, after upgrading](#a-dialog-or-sheet-scrolls-or-clips-a-child-after-upgrading)
|
|
29
30
|
- [`JsBarcode is not a function`](#jsbarcode-is-not-a-function)
|
|
30
31
|
- [A `LinkButton` selected as a `button` stops matching](#a-linkbutton-selected-as-a-button-stops-matching)
|
|
31
32
|
- [A `Toc`, `Pager`, `SeeAlso` or `ScrollProgress` inside `Doc` selected by `data-slot` stops matching](#a-toc-pager-seealso-or-scrollprogress-inside-doc-selected-by-data-slot-stops-matching)
|
|
@@ -39,7 +40,10 @@ words in your error.
|
|
|
39
40
|
- [A test no longer finds `aria-invalid` on a `Switch` row or an `Autocomplete` box](#a-test-no-longer-finds-aria-invalid-on-a-switch-row-or-an-autocomplete-box)
|
|
40
41
|
- [An `Autocomplete` lists more options than before, or "ecole" finds "École"](#an-autocomplete-lists-more-options-than-before-or-ecole-finds-école)
|
|
41
42
|
- [`@query-change` runs more often after upgrading](#query-change-runs-more-often-after-upgrading)
|
|
43
|
+
- [A click on the next field right after an `Autocomplete` pick is lost](#a-click-on-the-next-field-right-after-an-autocomplete-pick-is-lost)
|
|
42
44
|
- [An older search's results replace the newer ones in an `Autocomplete`](#an-older-searchs-results-replace-the-newer-ones-in-an-autocomplete)
|
|
45
|
+
- [An `Autocomplete` option does nothing on click or Enter](#an-autocomplete-option-does-nothing-on-click-or-enter)
|
|
46
|
+
- ["The search failed. Try again." no longer shows in an `Autocomplete`](#the-search-failed-try-again-no-longer-shows-in-an-autocomplete)
|
|
43
47
|
- [A test no longer finds `aria-invalid` on an `OtpField` slot](#a-test-no-longer-finds-aria-invalid-on-an-otpfield-slot)
|
|
44
48
|
- [A test no longer finds the breadcrumb's home button](#a-test-no-longer-finds-the-breadcrumbs-home-button)
|
|
45
49
|
- [A test no longer finds a sidebar entry by the `button` role](#a-test-no-longer-finds-a-sidebar-entry-by-the-button-role)
|
|
@@ -642,6 +646,20 @@ was a fixed 300 ms.
|
|
|
642
646
|
**Fix:** set the pause you had, `:debounce-ms="300"`, or move the fetch to `on-search`, which
|
|
643
647
|
also aborts the previous request and drops a stale response.
|
|
644
648
|
|
|
649
|
+
### A click on the next field right after an `Autocomplete` pick is lost
|
|
650
|
+
|
|
651
|
+
**When:** before 0.37.1, in a dialog, a `Select` (or any field) right below an
|
|
652
|
+
`Autocomplete` whose `@query-change` shows or hides something (a line naming
|
|
653
|
+
who is already linked, a result count): a click on that field's option just
|
|
654
|
+
after a pick does nothing, now and then (more often in Firefox and on a slow
|
|
655
|
+
machine; an end-to-end test flakes).
|
|
656
|
+
**Why:** a pick empties the query, and `@query-change` with `''` came only
|
|
657
|
+
after `debounceMs`. The line it removed then shrank the centred dialog, which
|
|
658
|
+
moved the open list by half that height between the pointer's press and its
|
|
659
|
+
release: the release landed on another option, and nothing was chosen.
|
|
660
|
+
**Fix:** upgrade: an emptied query is reported at once, with the pick, before
|
|
661
|
+
the next click. Waiting in a test until no `listbox` is left only hid it.
|
|
662
|
+
|
|
645
663
|
### An older search's results replace the newer ones in an `Autocomplete`
|
|
646
664
|
|
|
647
665
|
**When:** you fetch `options` yourself from `@query-change`, and a slow response
|
|
@@ -661,6 +679,47 @@ an older query, even from an API that ignores the signal:
|
|
|
661
679
|
/>
|
|
662
680
|
```
|
|
663
681
|
|
|
682
|
+
### An `Autocomplete` option does nothing on click or Enter
|
|
683
|
+
|
|
684
|
+
**When:** one option of an `Autocomplete` is greyed out and clicking it, or
|
|
685
|
+
pressing Enter on it, changes nothing, with no error.
|
|
686
|
+
**Why:** that option has `disabled: true` (in the local `options` or in what
|
|
687
|
+
`on-search` returns). It is listed and announced with `aria-disabled`, and never
|
|
688
|
+
picked, in `single` and `multiple` mode; Enter picks the first enabled option, and Tab skips a disabled one.
|
|
689
|
+
**Fix:** drop `disabled` from the option, or build it only for the options that
|
|
690
|
+
may be chosen:
|
|
691
|
+
|
|
692
|
+
```vue
|
|
693
|
+
<Autocomplete
|
|
694
|
+
v-model="value"
|
|
695
|
+
:options="[
|
|
696
|
+
{ value: 'a', label: 'Alpha', disabled: true }, // listed, never picked
|
|
697
|
+
{ value: 'b', label: 'Beta' },
|
|
698
|
+
]"
|
|
699
|
+
/>
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
### "The search failed. Try again." no longer shows in an `Autocomplete`
|
|
703
|
+
|
|
704
|
+
**When:** after upgrading, an `Autocomplete` whose `on-search` rejects shows
|
|
705
|
+
your own text, or nothing generic, where it used to say "The search failed. Try
|
|
706
|
+
again."
|
|
707
|
+
**Why:** `search-error` now takes precedence over the generic text with `on-search`
|
|
708
|
+
too, in the list and in the live announcement. The generic text only shows
|
|
709
|
+
while `search-error` is unset.
|
|
710
|
+
**Fix:** nothing, if the reason is what you want. To get the generic text back,
|
|
711
|
+
leave `search-error` unset or empty; to show a reason, keep it from `@search-error` and pass it
|
|
712
|
+
back:
|
|
713
|
+
|
|
714
|
+
```vue
|
|
715
|
+
<Autocomplete
|
|
716
|
+
v-model="value"
|
|
717
|
+
:on-search="search"
|
|
718
|
+
:search-error="reason"
|
|
719
|
+
@search-error="reason = 'Directory unreachable'"
|
|
720
|
+
/>
|
|
721
|
+
```
|
|
722
|
+
|
|
664
723
|
### A test no longer finds `aria-invalid` on an `OtpField` slot
|
|
665
724
|
|
|
666
725
|
**When:** `[data-slot="input-otp-slot"][aria-invalid]` (or
|
|
@@ -1182,6 +1241,27 @@ your own through `class`. With `as-child`, put the label in a `<span>`:
|
|
|
1182
1241
|
</template>
|
|
1183
1242
|
```
|
|
1184
1243
|
|
|
1244
|
+
### A dialog or sheet scrolls, or clips a child, after upgrading
|
|
1245
|
+
|
|
1246
|
+
**When:** after upgrading, a tall `DialogContent`, `AlertDialogContent` or
|
|
1247
|
+
`SheetContent` shows a scrollbar, or a child that stuck out of it (a popover, a
|
|
1248
|
+
focus ring, a wide table) is clipped.
|
|
1249
|
+
**Why:** these contents are now capped to the viewport (`max-h-[calc(100dvh-2rem)]`,
|
|
1250
|
+
`100vh` where `dvh` is unsupported; a top or bottom sheet is capped at `100dvh`)
|
|
1251
|
+
and carry `overflow-y-auto`, so a long body scrolls inside them instead of
|
|
1252
|
+
leaving the title off-screen. Setting `overflow-y` makes `overflow-x` clip or
|
|
1253
|
+
scroll too.
|
|
1254
|
+
**Fix:** to keep the old behaviour on one dialog, remove the cap and the scroll
|
|
1255
|
+
with `class="max-h-none overflow-visible"`; to change the cap, pass your own
|
|
1256
|
+
`max-h-*` (it wins on browsers with `dvh` support):
|
|
1257
|
+
|
|
1258
|
+
```vue
|
|
1259
|
+
<DialogContent class="max-h-none overflow-visible">
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
For a dialog that should grow taller than the screen and scroll inside the
|
|
1263
|
+
overlay instead of capping, use `DialogScrollContent`.
|
|
1264
|
+
|
|
1185
1265
|
## Feedback
|
|
1186
1266
|
|
|
1187
1267
|
### A toast with an action never goes away
|