Skip to main content

WireKit v2.73.0

Minor release

Minor. More components follow a page that reads from right to left, a sidebar can take a width its reader drags, a notification center can stand in an app rail, and a price can read amounts in the minor unit of their currency. A spacing, size, type or alignment class given to a component now replaces the component's own of the same kind. Most of the other entries are fixes.

Added

  • Notification center: trigger="rail" draws it as an entry of an app rail. The center is drawn with the rail's own entry: the bell alone in a narrow rail with its name in a tooltip, the title under or beside it where the rail draws names, and the unread count on the bell, following the center as notifications arrive and are read. For that the app rail entry takes live-badge, an Alpine expression its counter follows.

  • Two design tokens for the spacing of a navigation row: --space-wk-nav-icon-gap and --space-wk-nav-indent. The space between a row's icon and its name in a sidebar.item, a sidebar.collapsible and an app-rail.item, and the indent of a section's entries, took a padding token. A row drawn in their image can now take the same token and stay in line when a theme retunes a scale. Both default to the value they had, so nothing moves.

  • Notification center: a read notification is marked, and delete-read clears the read ones. A read notification shows a check where the unread dot stands, and a screen reader hears "Read." as it hears "Unread." on the others; :read-marker="false" leaves that place empty, as before. delete-read adds Delete read to the head of the panel: it takes the read notifications out of the list and names their ids in a bubbling notification-delete-read, for the application to delete them.

  • App rail brand: hide-name. A wordmark in the expanded slot shows the name already, and the brand drew name a second time beside it in the wide rail. With hide-name the name stays the link's accessible name and out of sight at every width, and the description, drawn only beside the name, goes with it.

  • text, heading and code break an email address, a host or a URL at its seams, with break="address". break="anywhere" broke an address wherever the line ended, so a narrow column could show "example.or" over a lone "g". The new value breaks before the @ and before each full stop first, and in a URL before a slash, ?, #, & and = and after the // of the scheme; a part too wide for the line on its own still breaks inside. The break points are <wbr> elements, which add no character, so the text a reader copies is the address. A feature test that looks for the address in the HTML with assertSee() finds nothing once the mode is set; assertSeeText() reads it.

  • An input groups the digits of an amount while it is typed, with group-digits. The field shows the number the way the language of the page writes it, 1,500,000.5 in English and 1.500.000,5 in German, keeps the caret after the digit typed when a mark appears or goes, and takes the marks of an application's own number formatter. Its value stays the plain number, digits with a . before the decimals, for wire:model, x-model and a plain form alike, and a binding to an int or float property reads it as a number. Pasted text is read by its own marks, so 1,500,000 pasted on a German page stays one and a half million. The field is a text field with a decimal keyboard.

  • A badge takes href and is then the link itself. It renders an <a> with the badge's fill, the pointer, a dim on hover and the kit's focus ring, so a status that opens its record needs no ring or underline around a link that wraps it. wire:navigate and target go on the link, and with target="_blank" it says so and sets rel. A badge with href takes no dismissible.

  • Image hotspots show a crop of the same file on a phone, with phone-crop. x, y, w and h in percent of the image, the value the image editor gives, name the part a phone shows below 48rem: the box takes the part's ratio, the image is drawn into it, and the markers move to their place in the part. A marker outside the part leaves the image on the phone and stays in the strip. With srcset the browser picks a file for the larger drawn width, and phone-sizes names the width of the box on a phone.

  • A table search leaves the search to the application with server. A table that renders its first rows only holds rows a search in the browser cannot find. With server the field binds a property of the Livewire component with wire:model, the component filters every row, and the field says the counts it passes as matches and total once the answer is rendered, and shows empty-text when nothing matches. WireKit::foldForSearch() folds a query and a row on the server by the rule the field folds by in the browser, so munchen finds München there as well.

  • A tab of a bar the server drives opens an address with href. tabs.tab with href renders a link with the role, the selection and the keyboard model of a tab, so a reader can open a view in a new window and Back returns to the one before. With wire:navigate on the tag the focus goes back to the chosen tab after the visit, unless the new page focuses something itself. Space opens a link tab as Enter does, and a disabled one keeps its place in the arrow keys without an address.

  • An icon tile, an icon in a square or a circle tinted in the color of its intent. It marks the start of a notice, a step or a figure, in accent, neutral or the color of a state, at the sm, md or lg step of the size ladder. Without a label it is decoration and hidden from screen readers; with one it is an image with that name.

  • A tooltip takes the sides of the line as its placement, start and end, which follow the page: end opens on the right of a page that reads from the left and on the left of one that reads from the right, with -start and -end for the alignment as before. An app rail item opens its tooltip at end without a placement, so on a left-to-right page it opens on the right as before, and the rail's own tooltip does the same.

  • A price shows a recommended retail price with base-label. A recommended retail price is no previous price: base-label="UVP" or "RRP" writes the name in front of the base amount and shows it as a reference price, muted and not struck through, since a strike-through reads as a reduction of the seller's own price. A screen reader hears the name instead of the hidden "Previous price". The name and the amount stay together on a narrow line, and fit shrinks them with the price. Without base-label the compare-at price is struck through as before.

  • A link in the color of the running text, with variant="text". It keeps its underline, which inside a sentence is what tells a reader the words are a link. Where a link stands on its own, such as an order number in a table column, underline="hover" shows the underline under the pointer only.

  • A data list sets a row of a totals block apart with emphasis. strong sets label and value in the weight of a heading, total does the same and draws a rule above the row across both columns, and sub sets a breakdown such as "of which tax" one size smaller and muted. A class on an item could not do this in the summary layout, where the item has no box of its own.

  • A badge keeps a count whole beside a cut name, with the after slot. With truncate the ellipsis took the whole label, a count included. Markup in after stands after the label, outside the cut, and the tooltip shows the whole name while it is cut.

  • The glyphs the kit repeats in every instance can come from one icon sprite per page, with wirekit.icons.sprite. The question mark of a field's help, the check and the dash of a checkbox, the arrows of a select and a folding card and the spinner of a busy button each carried their whole drawing in every instance. With the switch on (WIREKIT_ICON_SPRITE=true), @wirekitScripts writes each once as a symbol and every instance points there, in forced colors as well. Off by default, since a page needs @wirekitScripts while it is on, and wirekit:verify names a page shell without it.

  • Tooltips of words alone can share one panel per page, with shared or components.tooltip.shared. Every tooltip carried its panel in its markup, and a form with help on every label carried one per field, its help text twice. A shared tooltip writes no panel: its words stand once, in an element its trigger is described by, and one panel in the overlay root shows them while it is open. The help on a field's label hands over the hidden text the field is described by, through the new text-from. A tooltip with a content slot, a shortcut or the words of a cut text keeps its own panel. Off by default.

  • An icon for sharing, share. Each of the four presets draws it as three linked nodes, so a share button no longer borrows the arrow of a link that leaves the page.

  • An alert that lands out of view shows as a toast as well, with toast-when-hidden. An alert a Livewire render adds wholly above or below the window, such as a success message at the top of a long page after a save far below, shows its title and message as a toast in the color of its intent, and stays where it stands. A screen reader hears it once, since the toast says nothing of what the alert says already. On for every alert through toast-when-hidden in the alert entry of the configuration. A toast takes announce: false in its event for the same reason.

  • A notification center takes its trigger from the configuration. trigger in the notification-center entry of config/wirekit.php sets how a center opens when its call names none, so a center that a starter kit bundle renders can stand as an entry of a sidebar (row) without a change to that bundle's view. A trigger on the call wins, and the default stays bell.

  • The question before leaving says what leaving does, with wirekit:unsaved-question. The scope dispatches the event just before the dialog of an unsaved hint opens, and a listener sets the question, a sentence under it that also describes the dialog, the label of Leave and whether ⌘↵ or Ctrl+Enter presses Leave, for that opening. An application that keeps unsaved work as a draft can say so, where the dialog only asked whether to leave. Without a listener the dialog asks as before, and the shortcut presses nothing in it.

  • A table search says what it counts and of how many, with found. A screen reader heard "3 results" in every table, so on a page with several searches it could not tell which table answered, nor how many rows that table holds. found takes a translated line with :count, the rows that match, and :total, the rows the field searches, such as "3 of 12 steps match the search.", its form following :count. Without it the field says what it said.

  • The − and + of a cart line's press stepper take a surface, with stepper-surface. They were outline buttons in every interface. soft, filled or ghost gives them the fill the other buttons of an interface carry, on one line or for every line through stepper-surface in the cart-item entry of the configuration. Without it they stay outline.

  • A button group becomes a column below a width named with stack-below, as button.group does: welded on the block axis there, its buttons stretched to one width, and on the inline axis from that width up.

  • Table cells and heads, the columns of a data table, and text align to start and end, which follow the direction of the page: a column of figures with align="end" stands at the right of an English page and at the left of an Arabic or Hebrew one. left and right keep naming a physical side. A cell, a head or a column without align starts its text where the line starts, so on a right-to-left page it stands at the right, where it stood at the left.

  • A drawer opens from position="start" or "end", the edges where the lines of the page begin and end: end is the right edge of an English page and the left edge of an Arabic or Hebrew one, and the panel slides in from that edge. left and right keep naming a physical edge, and right stays the default.

  • A reading spine stands at position="start" or "end", and a reading minimap at side="start" or "end", the edges where the lines of the page begin and end, the spine with its border, corners and edge gradient on the side that faces the article, the minimap with its anchors and tooltip on the side it stands on, in either direction.

  • A message, a message group and a typing indicator take side="start" and "end", the same two sides as left and right under names that follow the direction of the page, as their row always has: on a right-to-left page an incoming message stands at the right, where the line starts.

  • A sidebar's names can cut with an ellipsis instead of wrapping. truncate on the sidebar sets it for every entry, and a group, a section or a single entry can set its own. A cut name keeps its full text for a screen reader and shows it as a tooltip; a counter beside it keeps its width. Names still wrap by default.

  • A sidebar takes resizable, a handle on the edge that faces the content by which a reader sets its width. It is dragged, stepped with the arrow keys or with the two controls beside its grip, and holds the width between min-width and max-width; width is where it starts and where Enter returns it to. With persist the width is remembered with the same driver as the folded state, each sidebar under its own key, and the cookie driver renders the first paint at the reader's width. On a page that reads from the right the handle and its keys follow the page.

  • A resizable handle takes steps and grip, and the width handle of a sidebar takes them as handle-steps and handle-grip. :steps="false" leaves out the two step controls beside the grip. Without them a pointer that cannot drag has only the keyboard left, so they belong off only where the sizes can be set without a drag as well. grip="hover" shows the three dots only while the line is pointed at, focused from the keyboard or dragged; on a touch screen they show at rest either way.

  • A toast region and a scroll-to-top button take the corners of the line as their position, top-start, top-end, bottom-start and bottom-end, which follow the direction of the page, beside the corners of the screen, which stay as they are. The defaults are now top-end and bottom-end, the same corner on a page that reads from the left, and on one that reads from the right the corner at the end of its line. A position set in the configuration keeps its value.

  • A price takes currency-minor-units, which reads an amount in the minor unit ISO 4217 gives its currency, the way a payment provider hands amounts over: 1500 is ¥1,500, 2999 is $29.99, 1500 is BHD 1.500 and IQD 1.500. The digits come from the standard's own list, which the package carries, with the intl extension and without it, and the price shows as many decimals as the standard gives the currency. A currency without a minor unit, such as gold, is refused. minor-units keeps dividing by 100 for every currency.

  • @wirekitLast and @endwirekitLast: an @if for a conditional block at the end of an element. Inside a Livewire component, Livewire writes two HTML comments around every @if so that its DOM morph can tell the block from the elements after it. A block with nothing after it in its parent element needs neither: @wirekitLast takes the same condition and the same @elseif and @else branches as @if and writes no comments. Outside a Livewire component the two render the same. Where it may stand is on the custom components page.

  • Three house conventions, in the guidance for assistants and as hints of wirekit:doctor:props. Buttons are filled and take their rank from intent; the content of a screen stands in cards, a card of settings with a head; a date or a time a reader sees stays on one line. AGENTS.md and the Cursor rules carry them, so the MCP server's get_conventions hands them out. The linter reports an outlined button, a field of a settings page outside a card and a formatted date in text that may break, as hints that change the exit code only with the new --fail-on-convention.

  • wirekit:csp-audit lists every expression it checked with --json --expressions. The payload named only the expressions with a finding. The expressions key holds each one the run handed to the parser, the clean ones included, with its file, line and attribute, so a test of the application can put the same expressions to the Alpine its CSP build ships.

  • WireKit::compactClasses() answers with the names the kit writes a class list under. With compact classes on, a test that compares the classes of a component, or code that writes the kit's classes into a page itself, asks for the short names instead of reading the kit's table. Off, the list comes back as it was given; a second argument keeps the field classes of an input, a select or a textarea.

Changed

  • A spacing, a size, a type or an alignment in a component's class takes the place of the component's own of the same kind, as a display and a position already do. A padding, a margin or a gap, a width or a height with their minimum and maximum, a font size or a font weight, a text alignment, justify-*, items-*, self-*, a flex direction and whitespace-* lost beside the value the component takes from a token, because Tailwind writes a token value after a named one: an alert kept its padding beside p-2, a stack its gap beside gap-2, a badge its size beside text-xs. A class that did nothing so far takes effect after the update, so a page where one was left standing can change. A side or an axis replaces only what it covers, a value under a breakpoint leaves the component's own in place below it, and overflow, the layer and the border width stay with the component. See Customization.

  • A container's content is as wide as its max size, as a navbar's, a hero's, a brand bar's and a footer's is. Its padding stood inside the size, so on a screen wider than the size plus twice the padding its content started one padding further in than theirs. The container now grows by its own padding on both sides, so on a wide screen it is up to twice its padding wider than before, and with padding="lg" its content starts on the same line as theirs. Below that width nothing changes.

  • An app rail's toggle draws the same glyph as a sidebar's collapse control. It drew a double chevron, and beside a sidebar in one shell the two controls that fold a column looked like two different buttons. Both now draw a panel whose arrow points the way the column is about to move, and only the arrow turns. The arrow of a rail or a column that renders folded is turned in the markup as well, so it no longer spins round when the page's script starts.

  • A callout draws the same box as an alert. Its padding and corners are the alert's (--padding-wk-x-md, --radius-wk-md), its fill mixes 10% of the intent into the raised surface and its border 35%, and neutral sits on --color-wk-bg-muted. A page that showed both showed two boxes of one intent in two sizes and tones. The two differ where it means something: an alert is announced when a render adds it and can be dismissed, a callout stands with the page. A card with an intent draws the same border, 35% of the tone.

  • A pagination's numbered links carry none of Livewire's morph markers. Inside a Livewire component every page link, the current page and each gap wrote two HTML comments around itself, and the row two more, sent again with every turn of the page: 22 of the 32 comments on the first example of the pagination page. The row is written as one string of elements now, which Livewire matches by their keys. Paginations look and behave as before.

  • Inside a Livewire component, most conditional parts that stand last in their element write none of Livewire's morph markers. Livewire writes two HTML comments around every @if so that its DOM morph can tell the part from the elements after it, and a part with nothing after it on its level needs neither. Such parts now go without them in the components where they stand: the badge of a tab, the clear button of a time picker's panel, the hints and the description in the head of a card, and many more. Over the first example of every component page that is 1,050 comments fewer, 18 % of all. Components look and behave as before.

  • A button and the items of a dropdown or a context menu write fewer of Livewire's morph markers. Inside a Livewire component a button's label and every part after it, the right icon and the new-tab hint, and on a menu item the counter, the shortcut hint and the new-tab hint, wrote two HTML comments around themselves, on every use and with every update: ten on a button, up to eight on a menu item. They are written without them now, which leaves four on a button, four on a checkbox item, whose wrapper for an optimistic toggle keeps its own, and two on every other menu item; every badge writes two fewer as well, twelve instead of fourteen, and so does every other component that can link to a new tab, from a card and a stat to the items of a navbar, a navigation menu, a menubar and a sidebar. A stat drops two more: its citation, which stands last, is written without them, whether the tile has one or not. So does the error, success or hint message of a field where it stands last, two fewer on every checkbox, radio, select, multi-select, toggle, color picker, phone field, tags input and time picker, with a message and without one. A calendar, a combobox and a datetime picker drop two more for their required message, which stands last in them. An input, a textarea, an OTP input and a date picker drop two more for the live region of an optimistic field, which stands last in them, whether the field is optimistic or not. The help of a label, which stands last in it, carries none of them either, and neither does the part that stands last in an input, a checkbox, a radio, a toggle, a multi-select, a combobox, a number input, a password input, an OTP input, a tags input, a color picker and a field: two fewer for each, with the part and without it. The parts before the label, the spinner and an icon, keep theirs, so a part that comes in before the label still leaves the label and the state of an element in it as they were. A radio item's indicator writes none either: it stands before the label, but as the only element in a wrapper of its own. Buttons and menu items look and behave as before.

  • A radio and a swatch group draw the ring of a radio the arrow keys reached from the stylesheet. WebKit does not count that focus as :focus-visible, so each option wrote four more ring classes for it, about 250 characters on every radio and every swatch. The stylesheet now draws that ring once for the page, from the same tokens, on the circle of a radio, around a card and on a swatch. They look as before.

  • The package is about 3 MB smaller: the per-component Tailwind sources hold only the classes Tailwind reads. Each source under resources/tailwind/, which the integration guide declares one per component, carried every word of its templates, prose and PHP included, 4.9 MB in all. They now hold the candidates Tailwind's own scanner reads from those words, 1.9 MB, and a build compiles the same stylesheet from them.

  • wirekit:doctor:props also judges a component whose template picks between two elements. A badge with href is a link and without it a <span>, so an attribute neither of them uses, such as value, is reported as rendered "onto <a> or <span>", and an attribute one of them takes is not reported at all.

  • The question before leaving a form with unsaved changes groups them by their place. The fields of one tab, card or marked part stand in one box headed "Section: General", each entry reading "Unsaved content: Title", where the list named each field with its place in gray behind it and did not say which was which. A field without a place stands outside every box. The unsaved hint page shows the list, and the two labels are the translation keys wirekit::Section: and wirekit::Unsaved content:.

  • A step control of a resizable handle disappears at the bound it points toward, where a click on it moved nothing. It comes back as soon as the handle leaves the bound, and the other control stays. The width handle of a sidebar does the same.

Fixed

  • A folded sidebar stands the rows of its foot on the lines of an app rail beside it. An entry there took its height from its line of text and the control that unfolds the column from its glyph, so counted from the bottom they stood 2 and 3.5 pixels lower than the rail's rows. Both are now as tall as a row of the rail, and on a touch screen they keep the touch height.

  • The header checkbox of a data table in client mode leaves the rows a search hides as they were. Selecting through it replaced the selection with the visible rows, so a hidden row that had been chosen was dropped, and clearing through it cleared the hidden rows too. It now selects or clears the visible rows only, as it does with the page of a server table, and the bar counts every selected row.

  • An app rail entry rendered as a button looks and answers the pointer like the links beside it. The rule that takes a button's own chrome back also set its fill, its color and its font, and it beat the entry's own classes: the button stood in the rail's text color instead of the muted one of its neighbors, and its fill did not change under the pointer. The rule now leaves those to the entry.

  • An app rail that remembers being expanded paints its whole state before its script runs. The remembered width arrived with the page, but the expanded marker, the labeling mode and the names waited for the script, so for one frame an expanded rail showed its icons centered and no names, and then every entry moved. With persist-driver="cookie" the server now writes all of it, and with the default driver the small script before the first paint applies it together with the width. A sidebar remembered folded in the browser applies its folded state with its width the same way.

  • A sidebar's head and foot keep the column's padding toward the list. A row scrolled up under the head stopped right under the brand, with the edge shadow on the name, and a row scrolled down to the foot stopped right above it. Between each zone and the list now stands the padding the column keeps at its edges. A band that reaches the column's edges with bleed draws its rule there instead, and the list still runs up to the rule.

  • A sidebar.item in a sidebar's head or foot is as wide as the rows of the list and lines up with them. The zone indented the row on top of the row's own inset, so a sign-out row in the foot stood narrower than the rows above it and further in. The row now gives the zone's inset back, in a form as well, and a name beside it keeps the inset. zone-inset="false" is no longer needed for a row and stays for other content that pads itself.

  • A name under an app rail's icon that is too wide for its entry on its own breaks at a syllable, with a hyphen. Hyphenation took only a word of twelve letters or more, so a shorter one that did not fit broke wherever the line ended: Verwaltung stood as Verwaltun over a lone g. A word of eight letters or more now hyphenates, never closer than four letters to either end, which also keeps a word that fits on the next line whole, as before. The same holds for the labels of a horizontal stepper.

  • A tour step whose target is taller than the window stays in the window. The tour scrolls a step's target to the middle of the window, and a target such as a whole section on a phone left no room above or below it: the step stood past the bottom of the window, with Next out of reach behind the backdrop. It now lies over its target at the edge of the window, whole, and a step with room beside its target stays where it was.

  • A button whose label ends in a visually hidden addition stands with the same space before and after its label. A <span class="sr-only"> behind the label, the usual way to give same-named buttons of a list a name of their own for a screen reader, left 0.5rem more space after the label than before it. The button wrote white space between its parts, and a <button> lays such a run out as a flex item of its own, with the gap beside it; it writes none now. The items of a dropdown and a context menu that render as buttons write none either, so a label that opens with an element stands one gap from the item's icon, where it stood two.

  • Visually hidden text written into a badge stays inside the badge. A <span class="sr-only"> in the badge's content, as in "Priority P1" read out where "P1" is shown, is positioned absolutely, and with nothing around it positioned it stood where the badge stood: in a container that scrolls sideways it widened the page, which then scrolled sideways on a phone. The badge now holds such text the way components holding their own hidden text do.

  • The scrolling area of a main shows the kit's focus ring where a keyboard stops on it. Chromium lets Tab stop on a scroll container that holds nothing focusable, and on <x-wirekit::main> it then drew its own ring, which no preset reaches. The area draws the kit's ring along its inner edge, also with personalized classes.

  • A finished stepper says so in its compact form. With current past the last step no step is current, and the line under the row belonged to the current step, so a stepper whose columns were too narrow for its labels showed its check marks and not one word. The last step now carries a line that reads "All steps done", shown where the compact form shows its line, also for a stepper that follows a flow with follow.

  • With compact classes on, a utility the kit writes under its own name no longer wins over a later one written under a short name. A class that keeps its name comes from the application's stylesheet, which loads after the compact one, so on the same element hidden beat the short form of a breakpoint class that shows the element again, absolute the short form of one that makes it relative again, and sr-only a padding: the logo of a brand stayed hidden on wide screens, the sidebar of an app shell stood over the content on a desktop, and a label of an app rail lost its padding. A utility that Tailwind orders after such a class, with a property of the same kind, now keeps its name on that element as well, also where the class comes from another part of the class attribute or from a binding that sets it while the page runs, so both come from one stylesheet in Tailwind's order. The compact stylesheet is unchanged.

  • A static action bar continues on a second line where its container is narrower than its content. With mode="static" the bar was as wide as its summary and its actions side by side, and ran out of a narrow card or a phone's column. Now the actions continue below the summary when they do not fit beside it. A floating bar keeps one line.

  • A disabled tab of a tab bar the server drives is dimmed. A disabled tabs.tab carries aria-disabled, so the arrow keys still reach it, and its dimming answered only the native disabled: it looked like every other tab and brightened under the pointer. It now takes --opacity-wk-disabled and the not-allowed pointer, and keeps its color under the pointer.

  • A navigation with track-current follows an address the page writes itself. A sidebar, navbar, app rail, bottom navigation or navigation menu marked its current entry again only after a wire:navigate visit, so a tab kept in a #[Url] property moved the address while the entry the page loaded with stayed current. It now follows the address after each Livewire response and on Back and Forward, and a script that writes the address itself dispatches wirekit:address-changed on the window.

  • The copy button of a code block shows its icon from the first paint. Both icons of the button waited for Alpine, so until a block started the button was an empty square of eight pixels, and the header grew when the icon arrived. The clipboard icon is now part of the markup; only the check after a copy waits for Alpine.

  • A German time of day ends on "Uhr". The timestamp and the status time of a message and the deadline a countdown names to a screen reader wrote the hour in the format Carbon gives the language, which in German leaves out the word that follows it: "21:15" now reads "21:15 Uhr". The word comes from the kit's catalog, so a language without one writes the time alone, and an explicit time-format on a message is written as given.

  • Two alerts of one render that say the same are announced once. A page that confirms a save at the top and beside its button rendered two equal alerts, and a screen reader heard "Success: Saved." twice. Equal words of one render are said once now; different alerts of one render are all said, and the same words of a later render are said again.

  • The frozen first column of a hoverable table changes with its row. Under the pointer the rest of the row faded to its hover tint while the frozen cell switched at once, so the two parts of one row changed a moment apart, entering and leaving. The frozen cell fades over the same duration and easing as its row now.

  • A compact file upload with help keeps its label clear of the question mark. In variant="compact" the label ran to the end of the row, and the question mark in the end corner stood over its last words, such as "(optional)". The end of the row keeps room for it now; the default area, whose corner is free, is unchanged.

  • A field the browser holds invalid says why, under the red it turns. A form whose submit the browser stopped at an empty required field never reached Livewire, so no message of the server came, and the browser pointed its own bubble at one field for a moment: every other red field stood without a word. The browser's own message, in the reader's language, now stands under each input, textarea, select or checkbox it holds invalid, after a submit and once a red field is left; the field is described by it and marked invalid while it lasts, the first such field takes the focus, and the message goes once the value is valid. A field that shows an error of the server keeps that one alone.

  • The heading and numbered-list buttons of the editor toolbar draw their glyphs as pictures. They showed H1, H2, H3 and 1. as text, a visible label their names "Heading 1" and "Numbered list" did not contain (WCAG 2.5.3), which axe-core 4.14 reports as label-content-name-mismatch. The glyphs stand for their command as the link and the task list already do, and the names are unchanged.

  • x-wk-unsaved no longer counts a field as unsaved that holds its saved value in another form. A field the reader emptied over a property that holds null was framed, its label took the words of the hint, and .confirm asked before the page was left, although a save would have changed nothing. A number or a boolean the field holds as its text, such as "3" for 3, did the same until the next request. Both count as saved now, and a list or an object is compared entry by entry the same way.

  • The month and year pickers of a calendar, the lines of a stepper, a hero's text and a sidebar item's count follow a right-to-left page. There the pickers' arrows stood at the start of the box, a stepper's lines ran from the wrong side of each step, a hero's text aligned left on a wide screen, and a count stood at the start of its row or, in a collapsed rail, at the wrong corner of the icon. The column of dots of a vertical carousel, the button back to the top of a reading spine, the label of a collapsible sidebar section and the space beside an app shell's inset sidebar follow the page as well, and a left-to-right page looks as before.

  • Bars, stripes, rules, badges and indents follow a right-to-left page. On a page that reads from the right the bar of a blockquote, the stripe of a callout, the rule of a vertical divider and the border between a map and its list stood on the far side, the status badge of an avatar and the count on a notification center's bell at the wrong corner, and the indent of a tree view's branches and leaves, the actions of a brand bar, the shortcuts of a command palette, the links of a navbar and the caret of a stream on the wrong side. The trigger of an accordion and a collapsible, a profile's name and a notification row aligned their text to the left. All of them follow the page now, and a left-to-right page looks as before.

  • A floating action button and a scroll-to-top button above it keep clear of a landscape notch at the edge they stand at on a right-to-left page. Each side folded in the device's inset of the edge it has on a page that reads from the left, so at the start, which is the right edge on a page that reads from the right, the button kept clear of the left edge's notch and sat in the right one's.

  • Nothing on the page moves while a modal, drawer, alert dialog, command palette or lightbox is open. The scroll lock hides the document's classic scrollbar, and in every browser with scrollbar-gutter, which is every supported one but Safari before 18.2, it now keeps the scrollbar's gutter in its place, so the page keeps its width and a pinned surface stays where it was on a page that reads from either side. In Safari before 18.2 the lock still pads the body by the gutter and lends it to the pinned surfaces on a page that reads from the left; the theming guide says what that leaves on a page that reads from the right.

  • The circle of reading progress keeps clear of the home indicator and of the scrollbar's gutter. Its inline style set both offsets to the plain padding and overrode its classes, so on a phone with a home indicator the circle sat in the gesture strip, and beside an inner scroll container's scrollbar it touched the scrollbar. The style now carries the same offsets as the classes.

  • The circle of reading progress and the floating reading bookmark stand at the end of the line, as the floating action button does: on a page that reads from the right in the bottom left corner, where they stood at the start of the line.

  • A scroll-to-top button and a toast region in a corner of the screen keep clear of the scrollbar's gutter on a page that reads from the right. --wk-scrollbar-inset is a gutter at the end of the line, and the corners of the screen folded it in at the right in either reading direction, so on a page that reads from the right a button or a toast in a left corner stood against an inner scroll container's scrollbar, and one in a right corner kept its gap from a scrollbar that was not there.

  • A table's caption and the row actions of a data table follow a right-to-left page, as its cells do. The caption and the table's own text aligned to the left there and the row actions to the right; they align to the start and the end of the line now, and a left-to-right page looks as before.

  • An event calendar follows a right-to-left page. There the stripe of an event, the lines between its days and the clock beside the hours stood on the far side, the events' text aligned left, and events that share a time stood in left-to-right order. They follow the page now, and a left-to-right page looks as before.

  • A filter builder's pickers and chips and a status matrix's frozen first column follow a right-to-left page. The arrows of the builder's pickers stood at the start of each box and the room inside its chips on the far side; the matrix kept its row headers and their corner frozen at the left, with the line between them and the data on the wrong side. They follow the page now, and a left-to-right page looks as before.

  • The parts of a field stand at the start and the end of the line on a right-to-left page. The arrow of a select and the toggle of a password input stood at the start of the box there, and the room around the leading icon, prefix, suffix, trailing icon and buttons of an input, around the prefix and suffix of a number input and inside the chips of a multi-select lay on the far side of each part. They follow the page now, and a left-to-right page looks as before.

  • Chevrons that point along the line turn with a right-to-left page. The month arrows of a calendar, the arrows of a branch switcher and of a horizontal carousel, a sidebar item's submenu hint and the arrow of a collapsible sidebar section pointed the same way on a page read from the right, against the direction the layout already mirrored. They mirror there now, an open section's arrow still points down, and a carousel's arrows stand at the start and the end of its row.

  • On a right-to-left page the side keys move toward the side they name. A row there runs from the right, yet Right Arrow moved to the next item, which stands on the left: in tabs, a segmented control, a menubar, a navigation menu, the submenus of a dropdown and a context menu, the calendar, the views of an event calendar, a tree view, a rating, the editor's command bar, the lightbox, the filters of a notification center, a branch switcher, a lifted card on a kanban, the boxes of an OTP input, a status matrix and the handle of a resizable panel. Left Arrow now goes to the next item there, a submenu opens to the left with its chevron pointing there, and a left-to-right page behaves as before. A submenu given a placement keeps its side, its chevron and its keys on either page. A slider, a range slider, a color picker and an image comparison keep their sides, since they draw left to right on any page.

  • A blockquote with cite places the attribution outside the quotation. The name stood in a <footer> inside the <blockquote>, where HTML does not allow it and a screen reader reads it as part of the quote. The quote is now a <figure> with the attribution as its <figcaption>; it looks as before. With cite, class and style land on the figure and every other attribute on the quotation.

  • A chart with a data table, linked points or replayable takes one place in a grid. The table, the list of the points' links and the replay wrapper stood as elements of their own beside the drawing. In a grid the table took the cell beside the chart, the list took a cell of its own as soon as one of its links had the focus, and a class such as col-span-2 reached the drawing inside the replay wrapper rather than the cell. The chart now renders inside one element that holds every part, and that element takes the chart's class, wire:key and x-show; style, id and the ARIA attributes stay on the drawing. A chart without any of these parts renders as before.

  • A chart follows a class that sets its display or its position. The chart wrote display: block and position: relative inline, which win over every class, so class="hidden md:block" left the chart on a phone and class="absolute inset-0" left it in the flow. Where the chart's class sets a display or a position, the inline one now gives way to it, on the chart or on the element around its parts; the width stays with the parent.

  • A chart reads inline="false" and replayable="false" as off. The two switches took any text as on, so both rendered as if written bare. A wire-stream-cap that is no number, a prop bound to null such as :height="$height" with no height, and a text where the chart takes a list ended the page with a type error, and so did a bound cap of NAN or INF. Now the cap falls back to 100, and the other props render as if they were not written; the text is reported as an invalid prop. A value-decimals that no integer holds, such as 1e400, wrote values with no decimals, and on PHP 8.5 it ended the page, as a bound NAN did; it now reads as no decimals at all.

  • A switch bound to a float that is no number takes its default. PHP reads NAN as on, so a switch such as :open="$ratio" with a ratio over nothing switched on, and on PHP 8.5, which warns on that cast, the page ended. The switches of a chart and of a field took it the same way, and so did the fit of a heading, a text, a stat, a price, a hero and a cart line; on PHP 8.5 a NAN in a chart's table or value-grouping ended the page too. Each now renders as if the switch were not written.

  • A scroll area written with fade="false" shows no fade. The text named no edge, so it was refused and replaced by both edges. A switch spelled as text now reads as one: false, 0, off and no as no fade, true, 1, on and yes as both edges, as a bare fade does.

  • A switch written as a word reads as the switch on tabs, the character counter of an input and a textarea, and a countdown. wrap="off" wrapped the bar from the sm width up, counter="off" drew a counter that read "off", animate="off" kept the change animation, and fit="off" fitted the line of a heading, a text, a stat, a price, a hero and a cart line. off, no and false in any case now read as off and on and yes as on, as they do on the other switches of the kit.

  • Stats and a feature grid written with stagger="150" stagger by 150ms. The step was taken only from a bound number, so a step written as text staggered by the default 75ms. A switch word such as on still staggers by 75ms, and a text that holds no number, such as stagger="15O", is reported now, as on any numeric prop, and staggers by 75ms. A stagger bound to NAN staggers nothing now, as without the prop. A reveal written with delay="125" waits 125ms the same way, where the text was refused as an unknown token and the entrance began at once.

  • A toggle cell of a status matrix is on for every value a switch reads as on. It was on only for true and on, so 1 from a column without a cast, yes and On drew an empty dot and told a screen reader the cell was off, and the first click switched on a cell that already was. A cell is on for true, a number other than 0, and 1, true, on and yes in any case, on the server and in the browser alike. A switched cell writes true or false, and a cell nobody switched sends its value back as it came.

  • A switch field of an item reads the switch it names on a select, a combobox, an overflow nav and a data table. An option's disabled and an entry's current, pinned and divider were read by PHP's truth, so the text false, no or off from a JSON column disabled the option, or made the entry the current page, pinned it or drew a divider after it. A column's sortable turned sorting off for false alone, so the same text, and 0, left the column sortable. They read the words a switch prop reads now, as the disabled of a quick reply already did.

  • A data table reports a column's sortStart that is neither asc nor desc, and an intent in its intents that a badge does not take. Such a sortStart, DESC or descending among them, started the column ascending without a report, and an intent such as orange drew a neutral pill, which reads as no status. Both are reported under strict validation now, as a column's align and cellType are; where nothing throws, the column still starts ascending and the pill stays neutral.

  • A lightbox reports an item's type that is none of image, video and embed. Such an item, Embed or iframe among them, showed its address as an image without a report, a broken one for a video host. It is reported under strict validation now, and the item still shows as an image where nothing throws.

  • Status tiles report an intent that is none of the five words. Such a tile was drawn as neutral without a report, so Danger from a database or a typo showed an incident as a neutral tile in every mode. It is reported under strict validation now and still drawn as neutral; a tile without an intent is neutral without a report, as before.

  • An event calendar reads an event's allDay as a switch. It was read by its truth in JSON, so the text 0, false, no or off, as a JSON column holds it, made the event all-day, and its start and end were written as days: an event at 09:00 lost its time. allDay reads the words a switch prop reads now, and any other text is reported and reads as all day; the browser is handed the switch it names.

  • A tristate cell of a status matrix reads Allow as allow, and reports a value that names no state. The cell read its value only in the browser and only as written, so Allow or a word with spaces around it drew no glyph, its name ended in "undefined" for a screen reader, and the first click set it to inherit. One of the three words is read in any case and with spaces around it now; any other value, true or granted among them, is reported under strict validation and reads as inherit, as a cell that holds nothing. A cell nobody switches sends its value back as it came.

  • A heat cell of a status matrix that holds NAN or INF renders as an empty cell. NAN wrote NAN% into the cell's color, which a browser drops, and NAN into its label, and on PHP 8.5, which warns on writing NAN as text, the page ended. INF painted the top of the scale and read INF. Both read as no value now: the start of the scale and a dash, as a cell that holds null. A heat-min or heat-max bound to NAN ended the page the same way; a bound that holds no finite number takes its default now, and a text that holds none, such as heat-min="10%", which was already reported, starts the scale of the cells at that default as well, where they started it at 10.

  • A heat cell of a status matrix and its legend write their numbers in the application's language. The cell wrote its value as PHP writes a number, so 12.5 read 12.5% on a German page, and a legend's 1000 had no grouping. Both are written as WireKit writes its own numbers now, 12,5% and 1.000 in German, and through the formatter an application registers where it has one. A text that holds no number is written as it comes.

  • A filter builder reads a filter on a bool field from the server as the switch it names. A filter that came with 'false', '0', 'no' or 'off' said "Yes" on its chip, editing it opened a menu with neither option chosen, and applying '1', 'yes' or 'on' unchanged turned it off. The chip, the menu and the applied value read the value as a switch is read on the server, and a filter nobody edits sends its value back as it came.

  • The data table of a chart writes "No value" for a value that is NAN or INF, as for a missing one. Such a value reaches the browser as nothing and leaves a gap in the drawing, while the table wrote NaN or ∞ beside it. A linked point that holds one is named as a point that holds nothing.

  • The data table of a candlestick or a boxplot chart names the values of each point. A cell held four or five numbers joined by dashes, which a screen reader reads without a meaning; it names them now as the tooltip does, in the application's language: "Open price: 126.40; High: 130.50; Low: 124.10; Close price: 129.80". A range keeps its two ends.

  • button-group and button.group weld through the same rules. A hovered button of a button-group rises above the seam as a focused one does, and the field of an input in it gives up its seam-side border to the neighbor drawn over it. A dropdown trigger or a field inside a button.group gets its inner corners squared, and its buttons keep the height floor without a touch patch reaching into the neighbor. The seam of both is --border-wk-width wide.

  • wireStreamCap bounds a strict ApexCharts stream whose window xaxis.range bounds. Every point went through appendData(), and a series grew for as long as the page stayed open. Such a series now grows to half again the cap and is cut back to it from its start, in one update without animation, never dropping a point the window draws or the one the line enters it from. A chart without xaxis.range draws every point it holds and keeps them all, as before.

  • A Chart.js area chart on a stacked axis draws one band per series. Each area filled to the zero line, so on a stacked axis it lay over the areas of the series below it, and the lowest band carried every series' tint. type="area" now gives a dataset on a stacked value axis fill: 'stack', which fills to the series below. A fill set on a dataset still wins, and fill: true keeps the earlier drawing.

  • A Chart.js chart keeps the axis, legend and tooltip colors set in its options through a change of mode. A grid color, a tick color, a tooltip background or a font family set in options held until the first switch between light and dark and was then replaced by the theme's. The theme now recolors only the places the options leave open, as it already did for a dataset that names a color.

  • A Chart.js chart draws a color named by a token. A dataset or annotation color written as var(--color-wk-warning) reached the canvas as text, which a canvas ignores, so it drew in Chart.js's default color. The adapter resolves such a token before the chart draws, after a Livewire update and again when the mode or the theme changes, as the ApexCharts adapter already did.

  • An ApexCharts chart keeps every name of a short category axis on a narrow screen. ApexCharts dropped an x-axis label that would overlap its neighbor, and on a phone a funnel of four stages showed two bars without a name. A category axis of up to eight names now shortens a label that does not fit, and the tip on a shortened label shows it in full; a date axis, a longer axis and an axis that sets its own trim or its own rule for overlapping labels are unchanged.

  • An event calendar stays readable on a phone. Below sm a month event dropped its time, so a sighted reader saw it nowhere; it now stands on a second line under the title. The week view split seven days into columns of about 45px and an event beside two others into a sliver; each day now keeps 5.5rem, and where seven do not fit the grid scrolls across as well as down.

  • The responsive utility wk-stack-below-md lifts a max-height while it stacks. A two-pane container whose panes shared a capped height kept that cap below md, where the panes stand one above the other, so the lower pane was clipped where nothing could scroll to it.

  • An avatar with an empty alt keeps its initials from a screen reader, as an image with an empty alt is. Beside a visible name, alt="" now skips the letters and still reads the status, where hiding the avatar took the status with it. A testimonial without a portrait read the author's initials before the name; it reads the name once.

  • A table takes its width from its columns again in a parent that sizes itself to its content. Since 2.54.0 the table's frame was a size container on every table, and a size container takes no width from what it holds, so a table in a flex item without a width of its own collapsed: it scrolled sideways in the room a sibling left it, or stood at no width at all. The frame is now a size container only while something measures it: stack-below-container, a column, a details row or a stand-in on the container scale, a caption, a frozen column, or container units written into a cell. Such a table still takes its width from the page, as before.

  • The scroll shadows of a sidebar with a fixed head or foot reach the column's edges. They ended where the column's padding begins, above a foot band whose rule runs to the edge. The rows, the scroller and its scrollbar keep their place.

  • A link component without size takes the font family of the text around it, as it takes its size. It set the kit's sans on every link, so inside a monospaced or a serif sentence the linked words stood in sans. A link with a named size stands on its own and keeps the sans, and the words of plain-without-href follow the same rule.

  • An icon with a size it does not know falls back to md, its size without size. Outside strict validation it fell back to xs, so a typo drew a 12px icon beside 14px text.

  • The markers of a list keep their indent on a right-to-left page. The indent sat on the left side, while the markers of a right-to-left list stand at the right. Left to right the list looks as before.

  • A width class on a mockup sizes the frame. The default widths of the frames live in WireKit's stylesheet, which is unlayered and outranked w-full or max-w-2xl on the component, so only an inline style changed them. A frame with a width class of its own now leaves its default width out.

  • Prose on a right-to-left page indents its lists, draws the bar of a quote and aligns a table heading at the start of the line. All three sat on the left side, while a right-to-left article starts on the right. Left to right nothing changes.

  • A skip link on a right-to-left page appears at the start of the line, top right. It came out at the top left in either direction. Left to right nothing changes.

  • The knob of a theme controller's switch rests at the start of the track on a right-to-left page and travels toward its end. It stood at the left there and slid right, as on a page that reads from the left. Left to right nothing changes.

  • A lightbox on a right-to-left page puts Previous at the right and Next at the left, with their arrows pointing the way they lead. Close and the zoom and pan controls move to the matching corners, each still clear of the screen's notch on its own edge. The arrow keys already followed the page; the buttons stood where they stand from left to right. Left to right nothing changes.

  • The step controls of a resizable handle move the line the way their arrows point on a right-to-left page. There the first panel stands at the right, and the control pointing left shrank it, so the line moved right. Left to right nothing changes.

  • The values of a data list stand at the end of the line on a right-to-left page. In the default and the summary layout a value was aligned to the right in either direction, so on a page that reads from the right it stood against its label instead of at the far edge. Left to right nothing changes.

  • The dividers of a reading progress bar's segments count from where the bar fills, the right on a right-to-left page. The fill already grew from the right there, while the dividers stayed counted from the left, so a quarter read lit the bar up to the divider of three quarters. Left to right nothing changes.

  • The ramp in a status matrix's heat legend runs from its low value on a right-to-left page. The two values beside it trade sides there, the low one at the right, while the ramp still ran from the left, so its cold end stood beside the high value. Left to right nothing changes.

  • Code reads from the left on a right-to-left page. A code block and an inline code took the page's direction, so the lines of a block stood against the right edge and the punctuation closing a line or an inline piece, such as ; or ), could appear at its start. Both read from the left now, an inline piece isolated from the sentence around it, and a code block's filename stands at the start of the header line in either direction. Left to right nothing changes.

  • A stat reads a change written with the minus sign − as a fall. Number formatting writes that sign in Swedish, Finnish, Norwegian and several other languages, and the screen reader heard the word of trend instead, so a falling churn rate passed with trend="up" was announced as an increase. A dash on its own, standing in for a missing value, no longer announces a fall, and -0% is unchanged like +0%.

  • A ticker delta passed as text with the minus sign − is a fall. It turned green and was announced as a rise.

  • A ticker takes the direction of a text delta from the number it begins with. A text that was no number was compared with zero as characters, so +5% turned red and was announced as a fall, and n/a green as a rise. A text that begins with no number is now neutral and announces no direction.

  • wirekit:doctor no longer compares --shadow with --shadow-wk. No component reads a --shadow-wk, only --shadow-wk-sm, -md and -lg, so the line could not report a match or a mismatch that meant anything.

  • wirekit:install puts @wirekitStyles in front of the application's stylesheet. It went at the end of the <head>, behind @vite, so with compact classes on, a short class of the kit's won a tie with a utility the application set on the same element, against what the customization page promises. In the Livewire starter kit the directive now goes into partials/head.blade.php, in front of the kit's @vite. While compact classes are on, wirekit:doctor warns about a page shell that still loads the application's stylesheet first.

  • A breadcrumb names each step of its structured data by an absolute URL. A step whose href was relative went into the JSON-LD as "item": "/products"; it is resolved against the application's URL now, the only form Google's breadcrumb documentation shows. Schema::breadcrumbList() does the same, and the visible trail is unchanged.

  • The header checkbox of a bulk selection and of a data table shows its mixed state under the CSP bundle. Both set indeterminate from an expression that assigned the property, which the CSP build refuses when it runs: the box stayed empty while some of the page's rows were ticked, and each page with one reported an error as it loaded. The state is bound to an attribute now, and the kit's directive sets the property from it, in both bundles.

  • wirekit:csp-audit reports an expression that assigns a property of an element. The CSP build refuses such an assignment each time it runs, $el.value = '' or $refs.list.scrollTop = 0 for example, while the expression parses, so the audit read it as clean. It names the target now, for $el, $root, a $refs entry and the element of an event, their style, dataset and classList included; an assignment to the component's own state stays clean.

  • The French catalog writes protected spaces where French typography sets a space: inside « » and before a colon, a question mark and a percent sign. A plain space there let a line break part the mark from its word, in the sentence a wizard speaks for an unfinished step and in the labels, filters and figures of other components. The space keeps its width, so a line looks as before.

  • wirekit:csp-audit reads no attribute that a Blade comment between a tag's attributes spells. A comment renders to nothing, and the audit counted and checked what looked like an attribute in its text.

  • wirekit:csp-audit reports AlpinePayload only in the body of a <script> block. It read the attributes of the opening tag as part of the block, so a value a script reads back from dataset, written with AlpinePayload::json() in an attribute of that tag, was reported as a payload in a script context. Those attributes are escaped like any other, and the audit leaves them alone now.

Documentation

  • The documentation says what holds in v2, and nothing about a later version. Prop Naming Conventions, Progress, Overlay Events, Localization, Dependencies, AI Tooling and the CLI reference described what a future major version would remove or rename. They now say which spelling to write in new code and that the older one keeps working.

  • The component catalog says when an alert applies and when a callout does. Both draw a box with an intent, and the catalog's one-line descriptions, which the MCP server and /components.json hand to a tool, named neither the difference nor the other component. An alert answers what the reader did and is announced when a render adds it; a callout stands with the page and is never announced.

  • The flag page says that compression is the web server's job, and what nginx needs for it. A few flags with a coat of arms weigh more than a hundred kilobytes and shrink to about a third compressed. The route and the published files leave compression to the server, which compresses SVG and JavaScript once gzip_types names them.

  • The documentation reader recipe's title preview works under the CSP bundle. Its listener wrote the text of an element, which the CSP build refuses; it keeps the title as Alpine state now and shows it with x-text.

  • Strict validation explains a report about a field of a list's items. A data table column's cellType, a lightbox item's type and the other item fields that take one word from a fixed list are reported with the item in the name, such as columns[3].cellType, and the page says what that name means and what renders. It also says that a switch field of an item reads the words a switch prop reads.

  • The reading progress page no longer offers corners for its dot that the component does not take. It named position="bottom-left", "top-left" and "top-right", each of which was reported and left the dot where it was. position places the bar at the top or the bottom, and the dot stands in the bottom corner at the end of the line.

  • Localization says how a page that reads from the right sets its direction, what follows it, from the layout and the arrows to the side keys, the overlays and the props that take start and end, and what keeps its sides because it works over a picture or a scale.

  • The reduced-motion rule is described as far as it reaches. The animations and theming pages said an application's own animations were slowed with WireKit's anywhere on the page, which holds only where a wk- class sits on <body>; they now say the rule covers WireKit's elements and what is inside them, and that animations outside them need a reduced-motion rule of the application's own.

  • The design token reference sends a token override to :root, never to @theme. It placed the chart colors' override in @theme, where WireKit's unlayered defaults win; the override belongs in :root, with .dark beside it.

  • The variants and intents page lists the surfaces a badge takes: soft, solid and outline. It listed filled and ghost, which a badge rejects, and called six intents universal where badge and stat add accent and text has no primary.

  • The getting-started, theming, extending and CLI pages match the code, and their examples run as written. Among the corrections: the core bundle does not carry the combobox, the date picker or the overlays; the browser-test setup says what assertNoJavascriptErrors() sees in the installed plugin; the personalization examples no longer replace a whole class block with one class; the syntax-highlighter example hands the language over from data-language; and the theme presets cite WCAG 2.4.13 for the size of a focus ring.

  • The table page shows each width-dependent table at full width. The previews of stacking by the table's width, of a column that gives way and of details rows stood in narrow boxes, one of them blank. They fill the preview now, at thresholds the width switcher shows. Hiding a column below a window width is introduced first, with a stand-in that keeps the hidden values on a small screen, and the page says that a column hidden without one takes its values with it.

  • The data list page sends a key with markup to <x-slot:label>. It told the reader to put such a key in the item's slot, which holds the value, and said the item had no named slots.

  • Price says that an absolute delta is never divided. minor-units and currency-minor-units read the amount, the struck price and the unit price in the currency's minor unit, and the delta as it is given. The page and its props table now say so, and that the change goes in the major unit next to amounts in cents.

  • The integration guide says what a component's render costs without OPcache, and how to measure what production pays. Without OPcache, PHP compiles the view of every component again on every render, and the console, a test run and a queue worker have it off by default. A file younger than opcache.file_update_protection stays out as well. The section shows the two settings for a measurement in the console and the one a queue worker that renders mail or exports needs.

Components

Every component this release changes, each linked to its page: Accordion · Action Bar · Activity Row · Alert · Alert Dialog · Announcement Banner · App Rail · App Shell · Assistant Message · Attachment · Avatar · Badge · Blockquote · Bottom Nav · Branch Switcher · Brand · Brand Bar · Breadcrumb · Bulk Selection · Button · Button Group · Calendar · Callout · Card · Carousel · Cart List · Cart Summary · Chart · Chart Mixed · Chat Marker · Checkbox · Code · Code Block · Collapsible · Color Picker · Combobox · Command Palette · Container · Context Menu · Conversation · Countdown · CTA · Data List · Data Table · Date Picker · Datetime Picker · Divider · Drawer · Dropdown · Editor · Empty State · Energy Label · Event Calendar · FAB · FAQ · Feature · Feature Grid · Field · File Upload · Filter Builder · Fonts · Footer · Form · Grid · Header · Heading · Hero · Hover Card · Icon · Icon Tile · Image · Image Compare · Image Editor · Image Gallery · Image Hotspots · Image Hotspots Editor · Indicator · Inline Edit · Input · Kanban · Kbd · Label · Lightbox · Link component · Liquid Glass · List · Main · Map · Menubar · Message · Message Group · Message Typing · Mockup · Modal · Multi-Select · Navbar · Navigation Menu · Notification Center · Number Input · OTP Input · Overflow Nav · Page Header · Pagination · Password Input · Phone · Popover · Price · Pricing Table · Product Card · Profile · Progress · Progress Radial · Prose · Radio · Range Slider · Rating · Reaction · Reading · Replay Button · Resizable · Reveal · Review · Review Summary · Row · Scope Switcher · Scroll Area · Scroll to Top · Segmented Control · Select · Shell Bar · Shimmer · Shortcuts · Sidebar · Sign-in Button · Skeleton · Skip Link · Slider · Sparkline · Spinner · Stage Card · Stat · Stats · Status Matrix · Status Tiles · Stepper · Sticky Panel · Stream · Strength Meter · Swap · Swatch · Swatch Group · Table · Tabs · Tags Input · Team Section · Testimonial · Text · Textarea · Theme Controller · Ticker · Time Picker · Timeline · Tire Label · Toast · Toggle · Toggle Button · Tool Call · Toolbar · Tooltip · Tour · Translatable Input · Tree View · Unsaved Hint · Usage Meter · Video · Wizard