Repository navigation
fix(deps): update dependency quasar to v2.30.0 - #708
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
2.22.0→2.30.0Release Notes
quasarframework/quasar (quasar)
v2.30.0Compare Source
New
useIntersection()composable -> observe any element's visibility fromsetup()with a plain object, a ref or a getter (target,root,rootMargin,threshold,once,disabled,onIntersect), getting back a reactiveisIntersectingand astop(). The observer pool behind it is now shared by the composable,v-intersectionand QIntersection (rebuilt on top of the composable), so a page mixing the three with the same options runs a single IntersectionObserversideprop, pull from any edge of the content to refresh -> the pull can start from thetop(the default, unchanged),bottom,leftorrightof the content, as an inward pan from that edge while the scroll target sits at it.bottomis the messenger case,left/rightserve horizontally scrolling content (#7599)cursor-positionprop, position the tooltip at the pointer -> on a large trigger a tooltip placed against the anchor's box ends up far from what the user is pointing at, which is why the nativetitleattribute opens at the cursor. The pointer becomes the anchor point (anchorno longer applies,selfandoffsetkeep working), after waiting for the pointer to settle so a tooltip opening mid-sweep can't freeze at a point already left behind; a touch or stylus press opens at the contact point without waiting, and a keyboard focus or a bare model toggle keeps the regular anchor-relative placement (#6019)overflow: hiddenon desktop, so the only way to reach offscreen tabs was the arrow icons and a horizontal trackpad swipe or a wheel tilt did nothing. It now scrolls on its own axis on every platform, the cross axis staying hidden, the scrollbar staying invisible and the arrows still tracking the position. Vertical wheel over horizontal tabs is deliberately not remapped, so a tab bar in a page never captures the page scroll (#7404)staggerprop -> each action fades and scales on its own, cascading outwards from the trigger when opening and back towards it when closing, which is the Material speed dial behavior.staggersets the milliseconds between consecutive actions (default 40; 0 animates them all at once); the delays are derived in CSS withsibling-index(), so no number of actions is special-cased and browsers predating those functions simply animate the actions together (#6413)ellipsisslot to replace the "..." buttons -> the ellipsis buttons were hard-wired to jump to the first hidden page on their side and there was no slot to attach anything else. The slot replaces the button entirely and hands over{ side, page, btnProps, onClick }(plustowhento-fnis set);btnPropsreplicates the default button but carries neither the click handler nor the router target, so spreading it onto a QBtn hosting a QPopupEdit does not also trigger the jump. Without the slot the rendered output is unchanged (#11341)dropdown-hover,dropdown-hover-delayanddropdown-hover-hide-delayprops are forwarded to the QBtnDropdown of every toolbar dropdown. Click, tap and keyboard interactions keep toggling as before, and touch devices fall back to themextractDate()parses ISO week dates -> the week (w/wo/ww), ISO week year (GG/GGGG) and day of week (d/do/E/ddd/dddd) tokens were emitted by the parser but never mapped, so aGGGG-[W]ww-Emask resolved to Jan 1st 1900 instead of the day it described and twelve formatting tokens could not survive aformatDate()round trip. A mask carrying a week number now resolves as an ISO week date, an explicit calendar day still winning. See the note at the top (#7732)v-intersection, QIntersection anduseIntersection, clipping through every scrollable ancestor up to the viewport, and takes the fraction of the element that must be visible as an argument (v-scroll-fire:0.5, default 0). See the note at the top.mouseon a device without touch) can be armed later. The notes are gone from the four pagesscroll-targetprop accepts a Vue component reference, standing for its root element -> QInfiniteScroll, QScrollObserver, QVirtualScroll, QParallax, QPullToRefresh, QTree and QTable share the prop, and the resolver behind it has always unwrapped a component instance to its root element, but the prop type rejected it: in production it worked, in development Vue's prop validation refused it and building the warning threw ("Cannot convert object to primitive value"), aborting the update. A value without a root element now falls back to auto detection with a warning naming the causequasar.configspinner of Loading and Notify is typed by name ->framework.config.loading.spinnerandframework.config.notify.spinnertake a spinner's name ('QSpinnerGears'), which the CLI imports for you, but the typing dropped both keys altogether, so naming a spinner there was a type error.quasarnow also exports theQuasarSpinnersunion of the spinner component namesFixes
rootBoundsfrom a cross-origin iframe for every entry of the viewport root, and a 2020 guard read that null as the element having been caught out of the DOM by a Vue transition, re-observing forever. So inside Codepen, jsFiddle and StackBlitz previews nov-intersectionor QIntersection handler ever ran, since 2020 (the docs advised therootprop as a workaround and Codepen was disabled on the examples). Firefox was unaffected. The guard is dropped, the docs' workaround paragraph with it, and the Intersection examples get their Codepen link backmousedownandtouchstartonly, so a page cancellingpointerdown(Cesium does it on every mouse press with a registered action) suppressed the compatibilitymousedownand the popup stayed open, in every engine. QSelect's dropdown got stuck along with it. A mouse or penpointerdownnow arms a 0ms fallback that themousedownof a normal press cancels in the same task, so every existing path is unchanged (#12575)top/left, so a popup with a bottom or right self origin kept its top edge frozen: content growing after the decision extended it over its own anchor until the next pass re-derived the position and it jumped. The engine now writes its inset from the edge the self origin anchors, like the native onemax-height/max-widthprops, the stylesheet ceilings ($menu-max-height, ...) and any app CSS at once. Before the amendment a flip towards a roomier side could widen the popup past those bounds (#18536, #18537)center/middlehad no viewport correction at all, and now shifts back inside the viewport, frozen at decision time. The offset was applied with a fixed positive sign whatever the self origin, so a popup growing up or left opened onto the coordinate instead of clearing it; it now carries the sign of the direction the popup grows. Visible today for a QMenu opened at a coordinate. See the note at the topdisable/readonlyin the toolbar, keep the fullscreen root opaque ->getBtn()overwrote the editor-wide disabled state with the per-button definition, so every plain toolbar button of a disabled or readonly editor stayed actionable (only the dropdowns behaved), which is how a disabled fullscreen editor's fullscreen button could be clicked.readonlykeeps the read-only commands (fullscreen, print, viewsource),disabletakes the whole toolbar out of play. The global.disabledrule also sat on the root, which in fullscreen is a viewport-sized fixed element, so the page composited straight through it. See the note at the top (#15486)disable/readonlytoggle, QTabPanels/QStepper/QCarousel destroyed every panel (KeepAlive state included) on aswipeabletoggle, QDrawer re-created its content on ano-swipe-closetoggle and QSplitter its separator slot ondisable. The directive now stays attached and is disarmed in place. QColor's spectrum, QSlider/QRange's track and QDrawer's backdrop got the same treatment internally (#12668, #18535)isFinalpayload never arrived: QSplitter kept its--activeclass and dropped theupdate:modelValue, QPullToRefresh stayed in its pulling state, QDrawer's close pan lost its end on a breakpoint crossingv-intersectionaccepted Booleanfalseonly and threw onundefined, andv-mutationtolerated a non-function value only by accident, keeping the observer connected and rebuilding it on every handler change (an inline arrow function on each render). Both now disarm cleanly,v-mutationdropping its observer and only swapping the callback target on a handler change (#18531)inject()fallback factory was never flagged as one, so the function itself landed in$faband a QFabAction rendered outside a QFab crashed instead of showing itself as an enabled, standalone button (#18538)v-morph.tween="{ name, group, model }"lost the tween. The directive modifiers are the base now and the object overrides only the keys it definesdeepEqual()compares binary data by content -> ArrayBuffers, DataViews and typed arrays were compared through the generic object path, and the typed-array branch was duck-typed on a.bufferproperty, so a plain{ buffer: ArrayBuffer }(and DataView) spun forever. Binary views are recognised throughArrayBuffer.isView(), which also covers views over a SharedArrayBuffer, and both sides'byteLengthis compared before anything is allocated (#18539)ComponentInstance, not aComponent-> QFile, QForm, QPopupProxy, QScrollArea, QSelect, QTable, QTree, QUploader, QVirtualScroll anduseVirtualScrollhand over mounted component instances that the generated typings declared with Vue's definition type.Componentstays where a definition really is passed: the plugins'spinneroptions and Dialog'scomponentOther
v-ripple,v-scroll,v-close-popup,v-intersection,v-morphand the four touch directives now share module-level listeners instead of allocating a set of closures per element,v-intersectionshares one IntersectionObserver per distinct config (per-scroll main-thread time on 3000 observed elements 4.1ms -> 2.5ms) andv-scrollone listener per target (2000 elements on window: mount 8.9ms -> 2.0ms, unmount 8.3ms -> 0.8ms, one scroll event 1.74ms -> 0.08ms). QInfiniteScroll and QPullToRefresh watch the content through the intersection pool rather than a scroll listener and render their indicator in a sub-component, so a load or a pull no longer re-renders the slot content, and QPullToRefresh arms TouchPan only while the pulled edge is on screen, keeping JS out of the touch path of every other scroll gesture. Every template ref in the ui package is ashallowRef()useFullscreen()relocation (#18513)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:
v2.29.0Compare Source
New
clickfrom the handler they bind whileclickable, so a@clickon an item or chip without that prop was dead code. See the note at the top (#16731)getClosestIsoName()maps a locale to the nearest language pack -> language packs carry a region subtag only when a language ships more than one translation, so a browser locale likees-MXorsr-Cyrl-RShas no pack of its own and every app hand-maintained a locale-to-pack map.Lang.getClosestIsoName(locale, isoNames)(also on$q.lang) picks the closest of the packs your app ships: exact match, then the RFC 4647 lookup chain with the script outranking the region (sr-Cyrl-RSreadssr-Cyrl,zh-Hant-TWreadszh-TW), then the CLDR likely subtags (zhreadszh-CN,ptreadspt-BR,de-ATreadsde-DEoverde-CH). Malformed entries are skipped, so alang/*.jsglob's deprecated files do no harm, andgetLocale()can be passed straight in. The docs' dynamic boot-file recipe now uses it (#12174)Fixes
blurand ran lazy validation (an empty date input went red just for opening the picker). QMenu and QDialog dispatch bubblingpopup-show/popup-hideDOM events again, the way Quasar v1 did, and QField holds its focused state, styling and lazy validation until the popup hides. Hover-shown menus and tooltips take no focus and stay silent (#9779)position: fixeddialog is attached to, and it reveals the focused field only for a user-initiated focus, so a field focused programmatically (autofocus or a.focus()call) opened the keyboard with a bottom-anchored dialog left entirely underneath it. QDialog now tracks the visual viewport while shown on iOS and insets its inner element to it. Verified on the iPhone 17 Pro simulator (#17594)100dvhnow and the platform override is goneoffsetWidth, which rounds each one up, so three justified tabs in a 440px container summed to 441,scrollableflipped on, the tabs collapsed to their natural width and nothing re-measured. It repeated at every third pixel of width, which is the on/off alternation of the report. Tabs are now measured withgetBoundingClientRect()and an overflow of a pixel or less is never treated as scrollable (#18532)offsetHeightas 29, so the paddings standing in for the items outside the slice put the content half a pixel per item off on every re-slice and the rows visibly jittered while scrolling, worse the deeper into the list. Both directions measure throughgetBoundingClientRect()now (#15754)$q.screenand the CSS breakpoints. A standard layout now reports$q.screen.width; containerized layouts are unchanged (#15506)disableis toggled -> all three baked!disableinto the root vnode key, so flipping the prop destroyed and rebuilt the whole subtree instead of leaving the content as it was. Disabling now travels through the directive value. One related change: with QIntersection'sonce, an observer that has already fired is no longer re-armed by togglingdisableoff and on, which was a side effect of the remount and contradictedonce(#12668, #18531)overflow: clip, which is not a scroll container; layout is unchanged (#17464)ssrContext-> Node (and Vitest) resolvequasarthrough thenodeexport condition to the SSR build, so a test setup that does not go through @quasar/vite-plugin installed it and crashed with "Cannot convert undefined or null to object". The error now explains what happened and how to fix it, and the Vite plugin docs gained a "Testing with Vitest" section (#15469)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:
v2.28.0Compare Source
Perf
New
position-anchor/anchor()insets, so the browser keeps it glued through any scroll, layout shift, resize or animation with zero listeners. Every other engine keeps the JS positioning engine, whose behavior was aligned with the native one so a flip in Chromium and a flip in Safari are the same flip by construction. Menus now follow ANY scrolling container on both paths, ending the long-standing "the menu only follows a container carrying thescrollclass" limitation (the #8343 family)hover,hover-delayandhover-hide-delayprops, the same contract QMenu, QBtnDropdown and QFab settled on. A hover-shown open never steals focus and never pretends to be focused, so a pointer merely passing over the select emits no focus/blur and cannot trip lazy validation;@filterselects still load their options on hover. A real click or Tab upgrades the show to a regular focused open (#11675)behavior="dialog"finally has a visible dismiss affordance, a labeled button in the in-dialog control row where the dropdown arrow would sit, so the software keyboard can never cover it. Follows thecolorprop, styleable throughq-select__dialog-close, opt out with the newhide-dialog-closeprop (#6858)no-chip-removeprop -> withuse-chips, drops the chips' remove icon and disarms the chip-armed Backspace removal, so a select that must always hold a value is possible with chips.clearable's own affordances stay intact when explicitly enabled alongside it (#17937)no-option-labelprop -> a plain no-options message without having to reach for theno-optionslot (#9463)q-select__selected-valueclass as an officially targetable hook, e.g.white-space: pre-lineto render embedded newlines (#17973)lazymodifier -> Vue implements it only on native elements and leaves the deferral to components, which QInput ignored. The emission now stays pending until the change event or blur, matching the modifier's native semantics; an external model change cancels it (#18023)onCancel/onDismiss-> the callbacks receive'cancel','backdrop','escape'or'programmatic'(which includes an app route change), so the Cancel button can finally be told apart from a backdrop click, ESC or ahide()call. Custom components built onuseDialogPluginComponentget it with no template changes. New exported TS type:DialogDismissReason(#17938)onCancel/onDismiss-> the same argument,'backdrop','escape'or'programmatic'scroll-targetprop stays with its other, narrower meaning: the box the scroll percentage is computed againstenginesfield (node >= 10!) move to Node 22Fixes
<KeepAlive>never received its transition-end, so it came back stuck half-faded (#18201, #18526)once+ssr-prerender, freshly hydrated content was destroyed and rebuilt on every page load (#17099)body-cell-<name>/header-cell-<name>slots were dropped unkeyed into the row, so changingvisible-columnsmade Vue diff one column's compiled slot output against another's, producing hybrid cells (one column's label with another's href) and worse after repeated toggles. Production-only, which is why it survived dev testing. Same treatment fortop-row/bottom-rowandtop-selection(#16047)sortOrder: 'da'showed an up arrow even though the first click sorts descending (#18009)td:first-child { position: sticky }also matched the hidden spacer cells, and mutating a sticky cell during a scrollbar thumb drag made Chromium ratchet the scroller to the end (#17107)scrollTo()-> a scroller with CSSscroll-behavior: smoothanimated the internal repositioning (#18168)hide-scrollbaron the root element -> since Chrome/Edge 121 honorscrollbar-width, and it only reaches the viewport scrollbar from the root element, the anti-flicker resize logic had quietly stopped working (#17122)naturalWidth/naturalHeightfrom the img's current laid-out box, so when the load event lost the race with layout the wrong ratio got locked in andobject-fit: covercropped the image (#15652)unmasked-value, the first re-render after a keystroke rewrote the field to the raw text and it never recovered; the same happened after an IME compositiontoolbarprop rendered fine but crashed on entering source view (#16940)validate()returns nullish instead of breaking (#17921)hide()-> thehide/before-hideevents carried no payload on ESC dismissal, so listeners could not tell a keyboard dismissal from a backdrop onearia-activedescendantwas never set there either, breaking the combobox pattern's active-descendant navigation (#16599)bodyinstead of returning it to the control (#6858)behavior="dialog"anduse-input, typing into the focused but closed control was a dead end: the text piled up while the filter early-returned (#15976)@filteroptions andmap-options, a preloaded model value displayed raw until a user interaction loaded the options. QSelect now fires that one filter call itself (#17983)@popup-show/@popup-hide-> both events always receivedundefined(#14678)no-optionslot) left the typed filter text behind in the input (#16135)coverwithtransition-show) for JSX/TSX consumers and the docs API card listed none of them.separate-close-popupis the one documented exception: the menu branch overrides it (#18530)q-focusable/q-hoverablehelpersbody.desktop, so the keyboard navigation QSelect just gained on mobile moved a focused state nothing painted (#16599)Other
escape-keyevent, and QVirtualScroll's entirely undocumented QList / QMarkupTable attrs forwarding is now declared. Both reach the generated TS types and the docs API cardserrorprop reserves the bottom space even whenfalse-> thefalsevsnulldistinction (reserve the error line vs no external validation at all) was undocumented and kept getting reported as a bug (#17662)<object>fallback, IE-era normalize rules), the hover engine shared by QMenu/QFab/QSelect moved into one composable, and the API builder gained mixin/extends features that let components pull pass-through definitions straight from their source component instead of hand-copying themDonations
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:
v2.27.0Compare Source
New
hover,hover-delayandhover-hide-delayprops, the same contract QMenu and QBtnDropdown got in v2.26. The pointer can cross the gap between the main button and the actions without closing them (150ms grace period by default), touch devices keep tap-toggling, keyboard interaction is untouched, and focus is never movedcol-nameprop -> a QTd or QTh wrapped in your own component inside QTable's#bodyslot can finally say which column it belongs to. The cells used to resolve their column from the vnodekey, which Vue never forwards through$attrs, so a wrapped cell rendered nothing. Existingkey="..."usage keeps working;col-nametakes precedence (#17830)quasar/lang/ckb,quasar/lang/myandquasar/lang/sr-Cyrlfor Central Kurdish, Burmese and Serbian Cyrillic.kur-CKB,mmandsr-CYRremain available as deprecated aliasesFixes
hovermenu's target and clicking it in one gesture closed the menu the hover had just opened. Also applies to QBtnDropdown (#18524)keyset on the griditemslot content -> the mapped rows reached Vue as keyless Fragments, so removing a row recreated every card after it instead of moving the surviving instances (#18045)rightinset could not be flipped by the RTL stylesheet (#17943).q-electron-dragregions in Electron -> menus, dialogs, notifications and tooltips overlapping a draggable title bar lost the overlapping area to window dragging. An explicit drag class on the content itself still wins, and dialogs keep letting you drag the window (#17285)fill-mask="0"and reverse filling, the unmasked value grew by one fill char per keystroke ("0.01" became "00.01", "000.10", ...), which is the docs' own "Price with 2 decimals" example (#18523)unmasked-valueand forward filling, a typed "1" over###-##withfill-mask="0"was reported as "10000"; with maskAA-AAandfill-mask="A", "X" became "XAAA" (#18523)reverse-fill-mask, every mask mixing letters and digits silently rendered nothing for ordinary values ("ab12" overAA-##), including values the control had just rendered itself (#18523)AA-##rendered "-57", which unmasked back to "57", so what the field displayed was not a value it could read again (#18523)srpack, Simplified characters insidezh-TW, untranslated English left in translated packs, and year-range plural/agreement errors in some 40 languages (#18522). Ukrainian was corrected first in PR #18522 by Ihor DiachenkoOther
offsetprop of the position engine does not translate the popup, it inflates the anchor box, somiddle/centerorigins are offset-invariant by construction. That is why QTooltip's horizontal offset reads as broken on its defaultanchor="bottom middle". Documented on the API of QMenu, QTooltip, QBtnDropdown, QPopupEdit and QSelect, with the direction each offset component expands in, plus the note that QMenu'scoverdrops the offset entirely (#18212)validateStringArraywas declared with four parameters and called with three, so its loop never ran. Every string, array entry and formatter result is now checked for padding, doubled spaces and control characters, and formatters are probed across the counts that select their plural branchesDonations
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:
v2.26.0Compare Source
New
hover,hover-delayandhover-hide-delayprops, also forwarded by QBtnDropdown (in split mode hovering either button opens it). A hover-open never steals focus from where you are typing, ESC still dismisses, submenus keep the chain open while the pointer travels between them, and touch devices keep tap-toggling. No effect whencontext-menuis set (#6776)min-rangeandmax-rangeprops -> constrain the width of the selection. Out-of-limits model values are coerced likeinner-min/inner-maxalready do, dragging and the keyboard clamp each thumb to what the other thumb allows, and a minimum width blocks thumb crossover (#18182, #2100). Based on PR #18182 by Teodor Atroshenko (thexeos)footerslot -> renders a real<tfoot>element, so a totals/summary row can be made sticky through CSS. Works in default and virtual-scroll moConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.