@quasar/app-vite-v3.6.1
- fix(app-vite): ext add/remove, mode add -> the flow no longer aborts half-way on pnpm v11+. pnpm v11 turned "Ignored build scripts" into a fatal error (v10 only warned), so any dependency with an unapproved build script anywhere in your project made the CLI's
pnpm add/pnpm installexit non-zero even though the packages did install --quasar ext addthen stopped with the App Extension package installed and registered as a devDependency but its install script (prompts, rendered templates,quasar.extensions.jsonentry) never run, leaving the project in a half-applied state. Same forquasar mode add capacitor/electronand the Vue DevTools / store-provider installs. Nothing is silently built -- pnpm still prints its "Ignored build scripts" notice and still refuses to run those scripts, so you can approve them withpnpm approve-buildswhenever you want to - fix(app-vite): a failing command now reports what actually went wrong when the CLI's output is piped (test harness, shell script, IDE task runner) instead of replacing the real error with a
TypeError: stdin.setRawMode is not a functioncrash -- which also skipped the failure banner and left the terminal switched to the alternate screen buffer. As a bonus, the alternate-screen escape sequences are no longer written into piped logs
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:
@quasar/icongenie-v6.1.6
- fix(icongenie): generate -> the Capacitor mount step no longer reports "Failed to install @capacitor/splash-screen. Please do it manually." on pnpm v11+ for a package it actually installed. pnpm v11 turned "Ignored build scripts" into a fatal error (v10 only warned), so any dependency with an unapproved build script anywhere in /src-capacitor made the install exit non-zero even after the package landed. Nothing is silently built -- pnpm still prints its "Ignored build scripts" notice and still refuses to run those scripts, so you can approve them with
pnpm approve-buildswhenever you want to - fix(icongenie): a failing command now reports what actually went wrong when Icon Genie's output is piped (shell script, CI-less task runner, IDE task) instead of replacing the real error with a
TypeError: stdin.setRawMode is not a functioncrash, which also left the terminal switched to the alternate screen buffer. As a bonus, the alternate-screen escape sequences are no longer written into piped logs
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:
@quasar/cli-v5.0.7
This is the optional globally-installed part of the Quasar CLI
- fix(cli): upgrade ->
quasar upgrade --installno longer stops half-way on pnpm v11+. pnpm v11 turned "Ignored build scripts" into a fatal error (v10 only warned), so any dependency with an unapproved build script anywhere in the project made the install step exit non-zero even though the packages did install -- leaving package.json with the new versions and nothing installed to match. The install now runs to completion; pnpm still prints its "Ignored build scripts" notice and still refuses to run those scripts, so nothing is silently built -- approve them withpnpm approve-buildswhenever you want to - fix(cli): a failing command now reports what actually went wrong when the CLI's output is piped (test harness, shell script, IDE task runner) instead of replacing the real error with a
TypeError: stdin.setRawMode is not a functioncrash -- which also skipped the failure banner and left the terminal switched to the alternate screen buffer. As a bonus, the alternate-screen escape sequences are no longer written into piped logs - chore(cli): upgraded deps ->
hono^4.13.0 and@hono/node-server^2.1.0 (the web server behindquasar serve)
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:
@quasar/app-vite-v3.6.0
- feat(app-vite): capacitor -> new
iosBuildSchemeconfig for iOS builds. The CLI used to hardcode the default "App" Xcode scheme andApp.xcworkspace, so building failed for anyone who renamed the project in Xcode. It now passes your scheme toxcodebuildand looks for<scheme>.xcworkspace(defaults toApp, so nothing changes unless you set it) (#7947)
- fix(app-vite): dev -> Vite's
devServer.host: true("listen on all addresses") is now accepted. Everything downstream expected a string, so address verification,APP_URLand external-IP detection all misbehaved; it is normalized to0.0.0.0(#16601) - fix(app-vite): build -> the build summary is now displayed when building with
--ide. The handoff to the external tool short-circuited the run before the summary was ever printed (#17422)
- Now bundles
@quasar/render-ssr-errorv2.2.6 -> the SSR error page can be pinch-zoomed; it previously shipped auser-scalable=no, maximum-scale=1viewport, failing WCAG 2.1 AA 1.4.4
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:
quasar-v2.25.0
[!IMPORTANT] A few behavior changes worth checking before you upgrade:
- QMenu no longer claims
role="menu"and QBtnDropdown's toggle no longer emitsaria-haspopup— a menu may only containmenuitem*children, so the old markup was invalid. Declarerole="menu"on the wrapped QList (its actionable QItems then expose themselves as menuitems automatically) and use the newtoggle-aria-haspopupprop on QBtnDropdown.- SSR'd virtual lists now render their first slice on the server, so item templates of a server-rendered QVirtualScroll/QTable run on the server too and must be SSR-safe.
- QSlideTransition starts animating immediately instead of 100ms later, which shifts the timing of every QTree / QExpansionItem / QStep slide.
- Third-party language packs: this release adds
colorPickeranduploadersections plus several keys. All are optional in the types and read with optional chaining, so existing packs keep working and compiling — but they will announce nothing for those internals until updated.
- feat(QTree): opt-in virtual scroll mode -> new
virtual-scrollprop family,@virtual-scrollevent and key-basedscrollTo(key, edge). Only the rows around the viewport exist in the DOM, so cost stays flat however much of the tree is expanded (22.6k nodes, dev mode: expand-all 2.2s -> 23ms, filter keystroke on a fully expanded tree 560ms -> 29ms, ~600 DOM elements at any scale) - feat(QTree): methods for the state v1 exposed through its per-node meta map ->
getIndeterminateNodes(),isIndeterminate(key),getParentNode(key)and tri-stategetTickState(key)(returns thetrue/null/falsea QCheckbox takes as its model); the header and body slot scopes gain anindeterminateboolean next toticked(#17298) (#12762) - feat(ui): SSR renders the virtual scroll initial window -> server-rendered virtual lists emit their first slice instead of zero items, so crawlers and first paint finally see content. QTable's virtual-scroll mode inherits it; QSelect is unaffected
- feat(QDate): roving-tabindex keyboard navigation for the day grid -> the calendar is a single Tab stop instead of up to 31. Arrows move by day/week, Home/End to the week edges, PageUp/PageDown by month (Shift for year), all crossing month boundaries and honoring RTL, the
optionsprop and the navigation-min/max limits - feat(QTime): direct numeric keyboard entry on the time units -> typing digits on a focused hour/minute/second sets it directly, accumulating multi-digit values within 1.5s (#12467)
- feat(QSplitter): Enter collapses the primary panel to its minimum limit and restores the pre-collapse position on the next press (#12466)
- feat(QSlider/QRange): the
sliderrole now sits on the focusable element, and the whole family gains Home/End - feat(QRange): WAI-ARIA multi-thumb slider semantics -> new
left-thumb-aria-labelandright-thumb-aria-labelprops - feat(QBtnDropdown): new
toggleslot -> renders next to the dropdown arrow, so content like a QTooltip can finally attach to the toggle button in split mode (#16955) - feat(QBtnDropdown): new
toggle-aria-haspopupprop -> names the popup's role on the control that actually opens it, in both the regular and the split design - feat(QList/QItem): new
roleprop -> the documented override path (e.g.menuitemcheckbox, orrole="menu"on a QList) - feat(QLayout): new
$layout-marginal-backgroundand$layout-marginal-colorSass variables for the marginal sections (#10476) - feat(QDrawer): new
escape-keyevent - feat(QField): the
controlslot scope gainsariaInvalid,ariaDescribedbyandariaErrormessage - feat(a11y): the component internals consumers cannot reach now carry accessible names -> QColor's view tabs, header value field and hue/opacity sliders, QUploader's icon-only buttons and hidden file input, QTable's selection checkboxes plus their empty column header, and QPagination's navigation landmark. Adds the
colorPickeranduploaderlang sections plustable.selectAllRows,table.selectRowandpagination.label, translated across all 72 language packs
- fix(QTime): implement the WAI-ARIA spinbutton pattern -> the hour/minute/second controls are localized spinbuttons instead of mislabeled toggle buttons; arrows adjust the focused unit (key-repeat works, the page no longer scrolls) and Home/End jump to the first/last valid value (#12467)
- fix(QDate): give the calendar controls real accessible semantics -> days announce their full localized date instead of a bare number, expose selection through
aria-pressedand mark today witharia-current="date"; the view switcher becomes a real button that Space activates - fix(QOptionGroup): implement the WAI-ARIA radiogroup keyboard pattern -> a radio group is a single Tab stop with arrow-key navigation, wrapping, skipping disabled radios and mirrored in RTL (#17638)
- fix(QOptionGroup): announce a disabled group whatever its type ->
aria-disabledwas set only for radios - fix(QSplitter): implement the WAI-ARIA window splitter keyboard pattern -> the separator is a focusable, value-carrying
separator; arrows move it by 1% (10px inpxunit) and Home/End jump to the limits (#12466) - fix(QSplitter): give the separator bar an accessible name -> new
separator-aria-labelprop - fix(QTabPanels/QTabs): complete the WAI-ARIA tabs pattern -> QTabPanel is focusable so keyboard and screen reader users can reach panel content with nothing focusable inside, and the
tabpanelrole lives solely on the panel components (#6560) - fix(QStepper/QCarousel): correct the ARIA semantics of their panel patterns -> QStep drops the orphaned
tabpanelrole and becomes a group labeled with its title, conveyingaria-current="step"even with header navigation off; QCarousel's navigation is exposed as the tabs pattern it actually is (#6560) - fix(QEditor): complete the WAI-ARIA toolbar/textbox contract ->
role=toolbarwith a localized name, a single Tab stop with roving tabindex, arrow navigation (wrapping, RTL-mirrored) and Home/End (#15675) - fix(QEditor,QTable): name the internals that reuse existing lang keys -> QEditor's toolbar toggles convey their state with
aria-pressedinstead of color alone, and the hyperlink editor's URL field gets a name - fix(QMenu/QList/QItem): derive valid ARIA roles instead of claiming
role=menu(#17162) - fix(QMenu): close the popup when TAB moves focus out of it -> focus no longer drops onto the browser UI leaving the menu open (#15675)
- fix(QMenu): mark its anchor as the popup's trigger ->
aria-expanded/aria-controlsstay in sync without apps mirroring the open state by hand - fix(QMenu,QDialog): render menu portals inside their
aria-modaldialog -> menus anchored in a modal QDialog (a QSelect's listbox included) were pruned from the accessibility tree and never announced (#17078) - fix(QSelect): align the popup with the ARIA combobox pattern -> the
listboxrole wraps only the options, which now carryaria-setsize/aria-posinset(#17344) - fix(QSelect): keep a readonly select focusable and announced -> it used to emit no focusable element at all
- fix(QSelect): expose a disabled select instead of dropping its control
- fix(QSelect,QTable): give the rows-per-page selection an accessible name (#9689)
- fix(QInput,QSelect,QField): expose error state to assistive tech (#18323)
- fix(QFile): expose error state to assistive tech (#17306)
- fix(use-field): drop the error ARIA references when no message renders ->
<q-input error hide-bottom-space>pointedaria-errormessage/aria-describedbyat a missing id - fix(QTree): tickable nodes trapped the keyboard -> tickboxes leave the Tab order and Space toggles them from the node header (#17603)
- fix(QTree): make every visible node keyboard-reachable, disabled ones included -> arrow navigation used to skip every leaf in a tree without selection
- fix(QTree): don't hijack keys typed into interactive header content (#17790)
- fix(QTree): demote a stale roving Tab stop -> re-expanding could leave two Tab stops
- fix(QTree,useRefocusTarget): never let focus land in an
aria-hiddencontrol (#17810) - fix(QCarousel): give the prev/next arrows an accessible name -> new
carousellang-pack section, translated across all packs (#7423) - fix(QDrawer): let ESCAPE dismiss the drawer in its modal states, under exactly the conditions the backdrop accepts a click (#7423)
- fix(QItem): attach pointer listeners only on interactive items -> WCAG checkers flagged the no-op handlers on a non-clickable QItem (#7423)
- fix(QStepper): announce a disabled step header as an unavailable button instead of inert text
- fix(QRating): ArrowDown/ArrowUp move focus in the documented radio-group direction
- fix(QSlider,QRange): say "no value" instead of announcing a limit as one -> a null QSlider announced the minimum, an untouched QRange the whole range as selected
- fix(QSlider,QRange,QImg): emit valid ARIA in three edge cases
- fix(QIcon): keep the ligature text out of the accessibility tree (#18084)
- fix(a11y): give the scrollable regions keyboard access -> QMarkupTable and QTable's horizontally scrolling middle are Tab stops, so a table wider than its container is no longer pointer-only
- fix(ui): drop spec-invalid ARIA from QToggle, QPagination, QChip, QFab, QImg, QLinearProgress, QTimeline and QBtn
- fix(types): keep the screen-reader lang keys optional -> a third-party language pack written before them kept compiling
- perf(QTree): the tree was rebuilt around lazy rendering, per-node render isolation and incremental state -> collapsed subtrees mount on first expansion instead of being pre-rendered behind
v-show(22.6k-node tree, dev mode: 2196ms/299,713 DOM elements -> 31ms/169), a state change re-renders only the affected nodes, and the monolithic O(N) meta rebuild became layered derivation that recomputes only on its own triggers. Per-key state of keys that left the model is pruned, andgetTickedNodes()/getExpandedNodes()use keyed lookups - perf(QSlideTransition): start animating immediately instead of 100ms later -> every QTree, QExpansionItem and QStep slide loses 100ms of idle latency, and
duration <= 0short-circuits to an immediate settle - perf(ui): a broad mount-cost sweep ->
useQuasar()resolves through the instance's global properties (~0.6ns/read vs ~37ns), size styles are module-cached, and trivial computeds were flattened out of the render path across ~70 files (QBtn, QItem family, the checkbox family, QChip, QTab/QRouteTab, QList, spinners and 12 bulk-mounted leaves, plus use-dark/use-align/use-form/use-transition/use-router-link/use-split-attrs) - perf(ui): every component of that sweep was then re-benchmarked in a real browser, and the computeds whose removal cost more than it saved were restored
- perf(QIcon): module-level parse cache, no per-instance computeds
- perf(date): compile
formatDatemasks once and cache per mask - perf(QScrollArea): allocation-free
@scrollpayload assembly - perf(ui): allocation-free
isKeyCode, loop-basedsumSize, regex-freehexToRgband allocation-free mask token testers - perf(QInput/QSelect/QTab): test the cheap event flags before
shouldIgnoreKey()
- fix(QSelect): allow cancelling keyboard actions (#18507)
- fix(QInput): allow cancelling mask keyboard actions (#18515)
- fix(QEditor): allow cancelling the CTRL keyboard shortcuts ->
@keydown.ctrl.b.preventcould observe the key but not stop QEditor toggling bold - fix(QTab/QRouteTab): allow cancelling the keyboard actions -> the event was emitted after the tab had already acted on it
- fix(QEditor): commit a link only when the user asks for it -> opening the link toolbar used to wrap the selection in an
<a href="https://">straight away, leaving a broken link behind if you walked away (#18289) - fix(QEditor): keep the link editor open when the command sits in a toolbar dropdown (#17920)
- fix(ui): add validation for the q-editor link
- fix(QMenu): keep popups open on clicks inside a fullscreen-detached child (#18512)
- fix(QMenu): follow the anchor through a fullscreen detach -> the menu stayed open at stale coordinates, painted over by the fullscreen element (#18513)
- fix(useFullscreen): keep focus and caret through the detach/restore moves -> a caret placed in a QEditor before entering fullscreen was lost (#17843)
- fix(QMenu/QTooltip): follow an anchor still moving during the enter transition -> the popup no longer lands at a stale spot and snaps into place at transition end
- fix(QDialog/QMenu): don't throw on focus when the inner ref holds a non-Element stub (#12780)
- fix(QDialog/QTooltip): resolve fall-through attrs on the render path -> a dynamic
:classon an open QDialog never reached the portal root, and a dynamicidwent stale on QTooltip - fix(QDialog): stop fighting the iOS scroll position while the viewport is zoomed
- fix(QScrollArea): stop trapping fixed-positioned children -> a
position: fixeddescendant anchored itself to the scroll area and was clipped there (#12109) - fix(QSelect): display falsy (non-null) selected values with
fill-input(#17763) - fix(QInput): restore the textarea inline styles when
autogrowis toggled off (#17535) - fix(QFab): stop forwarding the FAB's own props to the trigger button -> every FAB shipped an anchor carrying invalid DOM attributes like
direction="up"andlabelposition="right" - fix(ui): QFab/QFabAction internal top/bottom label was never stacked -> an internal
label-position="top"/"bottom"laid icon and label out in a row instead of a column - fix(QColor): drop the dead
hideSelectionprop from the alpha slider - fix(QTree): align dense virtual scroll root leaves with the nested layout
- fix(ui): QVirtualScroll SSR-rendered padding mismatching the client's -> no more "Hydration style mismatch" warning in every SSR app rendering a QVirtualScroll
- fix(ui): Morph SSR hydration class false-positive
- fix(ui): Screen plugin -> honor the documented
config > screen > bodyClasseskey on SSR, which never emitted its body class into server-rendered HTML - fix(ui): widen
useQuasar()'sinject()fallback past the no-instance case - fix(ui): actually print the UMD missing-Vue guidance error -> it was dead code behind a cryptic "Cannot read properties of undefined" throw
- Test infrastructure: SSR hydration coverage for every component and directive (with a Quasar-config and icon-set install axis), a hydration sweep over the playground, a UMD suite running the built bundles under both global Vue builds, a cross-engine regression sweep page, and an
[Accessibility]category in the Specs workflow
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:
@quasar/icongenie-v6.1.5
- fix(icongenie): running a command outside a Quasar CLI project folder no longer aborts with "This command must be executed inside a Quasar project folder." Quasar is also used as a plain library in custom Vite/Electron setups, so Icon Genie now prints a warning and falls back to the current folder as the target — assets are generated for whichever modes actually have their target folders there (#16836)
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:
2.17.1
- Fix overrides lost after switching component variant #10588 (PR: #10619)
- Fix malformed get-font-variants request when team-id is missing from dashboard URL #10644 (PR: #10645)
- Fix malformed get-profiles-for-file-comments request when file-id is missing from workspace URL #10652 (PR: #10655)
- Fix internal error when dragging inner layout with Boolean operations #10647 (PR: #10778)
- Fix frontend throwing raw TypeError on undefined .getData receivers across import, paste, drag, and text editor paths #10709 (PR: #10718)
- Fix workspace crash with 'can't access dead object' in Firefox when navigating between pages #10719 (PR: #10721)
- Fix workspace crash when holding an arrow key on a selection due to excessive re-renders #10726 (PR: #10736)
- Fix dashboard sidebar throwing removeChild NotFoundError during rapid keyboard navigation #10714 (PR: #10715)
- Fix asset download failing with S3 auth conflict when using access token #10776 (PR: #10777)
- Fix import worker crashing when importing non-Penpot zip files #10781 (PR: #10782)
- Fix viewer crash with WASM panic when opening URL with page-id #10800 (PR: #10805)
- Fix backend returning 500 when JSON request body has unrecognized escape sequence #10804 (PR: #10808)
- Fix color picker eyedropper crashing when viewport is unmounted during pointer move #10811 (PR: #10812)
- Fix flex layout crash when dragging shapes with missing bounds #10843 (PR: #10845)
- Fix export failing when shape has blank layer name #10849 (PR: #10852)
- Fix area selection (marquee) being aborted by select-shapes interrupt #10872 (PR: #10870)
- Fix gradient editor sending invalid stop offset when clicking outside gradient line #10879 (PR: #10881)
- Fix audit event validation failing when error reports contain string profile-id and missing token context #10897 (PR: #10898)
- Fix MCP tool call timeout being too low for some operations #10953 (PR: #10967)
- Fix MCP requests running into timeouts after leaving a file in Penpot #10958 (PR: #10967)
- Fix duplicate WebSocket MCP connection attempts deregistering the original connection's routing entries #10961 (PR: #10967)