github quasarframework/quasar quasar-v2.25.1

3 hours ago

Important

A few behavior changes worth checking before you upgrade:

  • lazy-rules now clears an error while you type: while an error is displayed, the field re-checks on each model change instead of waiting for the next blur. Rules that were only ever meant to run on blur will now also run on every keystroke for as long as the field is in error.
  • Async rules re-validate when the value changes or the field blurs mid-flight: a slow rule that settles after the user moved on no longer paints its verdict onto the newer value; a second validation run is triggered instead.
  • The field's hint/error/counter area sits in normal flow: a message taller than one line now grows the field instead of painting over the content below it. Geometry is unchanged for every one-line message, except item-aligned fields, which now reserve that one line (about 20px taller) instead of bleeding messages into the next item. Custom CSS leaning on .q-field--with-bottom's padding-bottom or on the absolutely positioned .q-field__bottom--animated needs a second look.
  • QLayout can emit one extra @scroll: a scroll update suppressed while the body scroll lock was held is now applied when the lock releases without restoring the position.

Fixes

  • fix(QField/QInput/QSelect/QFile): lazy-rules re-validates on model change while an error is displayed -> the error clears as soon as what you type becomes valid, instead of staying up until the next blur (#17456)
  • fix(QField/QInput/QSelect/QFile): re-validate when the model changes or the field blurs during a pending async validation -> a slow rule can no longer settle onto a value the user has already replaced, leaving the field showing a verdict for text that is no longer there
  • fix(QForm): report a child whose validate() throws synchronously -> that child now fails and gets focused, exactly as a rejected async rule already did, instead of the exception breaking the whole submit()
  • fix(QField): flow the hint/error/counter area in-layout -> a message longer than one line grows the field instead of painting over whatever follows it, and item-aligned fields no longer bleed their messages into the next item (#17807)
  • fix(QLayout): re-sync the scroll state when a scroll lock releases on a changed route -> navigating away from inside a Dialog or under the Loading plugin left the layout holding the pre-navigation scroll state, so a reveal QHeader never reappeared at the top of the new page (#12994)
  • fix(QMenu/QTooltip): re-anchor when the iOS visual viewport moves -> with the soft keyboard open or while pinch-zoomed, iOS scrolls only the visual viewport and no window scroll event fires, so an open popup ended up detached from its anchor by the scrolled amount (#16849)
  • fix(QSelect): keep the field width stable while loading with hide-dropdown-icon -> with no icon to swap for, the default spinner appended net-new width and the field jumped on every filter round-trip. The default spinner is now suppressed when the dropdown icon is hidden (an explicit loading slot still renders), and the clearable icon keeps its place while loading instead of vanishing (#17375)
  • fix(QTabs): show the overflow arrows when align="right" -> Blink and Gecko keep start-side overflow out of the scrollable overflow region, which collapsed the measurement and hid both arrows, leaving the overflowing tabs unreachable by pointer (#17847)
  • fix(QInfiniteScroll): stop polling while a Dialog or an overlay Drawer scroll-locks the page -> opening one over an infinite scroll fired @load in a loop until the whole list had been fetched (#13257)
  • fix(QInput): don't lose a typed char that equals a mask literal -> mask 11## swallowed a typed "1" and 04## ### ### a typed "0", because the char could not be told apart from the literal sitting at that position (#15624, #18051)
  • fix(QInput): soft-keyboard backspace over a mask literal deletes the data char before it -> on iOS the browser removed only the literal, the remask put it straight back, and the edit became a silent no-op that left the caret misplaced, so every digit typed next landed one slot early and scrambled the value (#17639)
  • fix(QInput): re-anchor the caret after a dynamic mask change -> with a mask computed from the value being typed, the caret could land inside the value after the layout shifted, so the next digits scrambled it and the last char read as never registering (#7777)
  • fix(QInput): drop a stale debounced emission when the mask restores the model's value -> cutting a whole masked value and pasting it back before the debounce fired emptied the model while the input showed the pasted text (#17568)
  • fix(ui): resolve a custom Dialog's show/hide through arbitrarily nested components -> a QDialog sitting behind two or more single-root wrapper components failed with "Incorrectly defined Dialog component" and never opened (#18159)

Other

  • Regression coverage for the two families reworked here: the validation composable (async races, the QForm submit flow, reset/unmount/disable, reactive rules) and the mask engine (chars equal to a literal, dynamic masks, backspace bursts, the multiple-masks pattern), plus cross-engine sweep scenarios that also run on the iOS Simulator, where the mask and QTabs bugs above behave differently than on any desktop engine

Donations

Quasar Framework is an open-source MIT-licensed project made possible due to the generous contributions by sponsors and backers. If Quasar is useful in your workflow and you want to support ongoing maintenance, please consider the following:

Don't miss a new quasar release

NewReleases is sending notifications on new releases.