**Minor.** A strength meter of its own, a row of links kept to a number of lines with the rest in a menu, rows a reader reorders by dragging or with two arrows, a row that lights up when the server says it changed, and server search in multi-select and combobox. A chart now follows the data its Livewire component renders, a pager offers a choice of page size, a tooltip can take the surface menus use, and an application can make the controls inside an element touch-sized on any pointer, or build its stylesheet from only the components it renders. `wirekit:theme` and the preset pages now agree on every token both of them set. Most of the fixes came from applications that build on the kit: dialogs, menus, drawers, tooltips and fields that went wrong in ways a reader could see and nothing reported.

### Added

- **[`<x-wirekit::overflow-nav>`](https://docs.wirekit.app/components/overflow-nav) — a wrapping row of links kept to a number of lines.** The links the rows have no room for move into a menu at the end of the last row, behind a button that shows their count, and the current link never leaves the rows. `lines` sets how many rows the links may take, two by default, and each item can carry attributes for its anchor, such as `wire:navigate`. Without JavaScript every link is shown, in as many rows as it takes.
- **`<x-wirekit::strength-meter>` — the display the password input draws, as a component of its own.** A step from 0 to `max` (4 by default), a `label` that names what is judged, `levels` for the words, `show-level` to put the word on screen and `announce` for a polite status region that speaks a change and not the starting value. It is a `role="meter"` rendered by the server, so it is complete before Alpine starts, and the step can come from a Livewire render or from `x-model`. With `show-level` the bars keep one length whatever the word beside them. See [strength meter](https://docs.wirekit.app/components/strength-meter).
- **Rows a reader reorders by dragging or with two arrows.** `<x-wirekit::table.reorder>` draws a drag handle for Livewire's `wire:sort` and two arrow buttons that call the method a drop calls, with the row and its new position, disabled where they lead nowhere and named after the row. After the round trip the focus is back on the arrow that was pressed, and `table.reorder-head` heads the column for a screen reader. See [reordering rows](https://docs.wirekit.app/components/table#reordering-rows).
- **`x-wk-flash` lights a row up in a tone when the server says it changed.** The server writes `data-wk-flash` (one of the intents) and a `data-wk-flash-key` that is new with every change, so the same tone twice flashes twice; with `data-wk-flash-leave` a removed row flashes once more and leaves the page when its flash has ended. A table row flashes through its cells, and under reduced motion the tint appears and holds without fading. The tints are tokens, `--color-wk-flash-{tone}`. See [flashing a row that changed](https://docs.wirekit.app/animations#flashing-a-row-that-changed).
- **Server search in [multi-select](https://docs.wirekit.app/components/multi-select#server-search) and [combobox](https://docs.wirekit.app/components/combobox#server-search).** With `server` the typed text reaches your component as `search-change` once it is long enough (`searchMinLength`, 2) and has settled (`searchDebounce`, 300ms), the event the data table's server mode already sends. The results come back through the render, a chosen option keeps its label after the list has moved on, and the list says when it is searching, when there are more results than it shows and when there are none.
- **A [chart](https://docs.wirekit.app/components/chart#livewire-integration) follows the labels and series its Livewire component renders.** A filter that changes the period updates the drawn chart in place, under both adapters, without rebuilding it or replaying its entrance; the chart type and its options stay as first rendered. The page said property-driven updates were unsupported, and it no longer does.
- **A [pager](https://docs.wirekit.app/components/pagination#choosing-the-page-size) offers a choice of page size.** `:per-page-options="[10, 25, 50, 100]"` draws a small select beside the summary. `wire:model` on the pager binds it and a change goes back to the first page; without Livewire it is a GET form that keeps the query your page links carry. With a choice on offer the pager also renders on a single page, so picking the largest size does not remove the control that picks a smaller one.
- **`data-wk-touch` gives the controls inside an element the touch sizes on any pointer.** A till or a kiosk reports a fine pointer once a mouse is plugged in, and its fields and buttons took the mouse sizes; inside `data-wk-touch` they take the 44px touch sizes whatever the pointer, and a dialog opened from inside the element keeps them. See [touch sizes on any pointer](https://docs.wirekit.app/theming#touch-sizes-on-any-pointer).
- **An application can build its stylesheet from only the components it renders.** The package ships one Tailwind source per component, `resources/tailwind/<name>.txt`, covering the component, its parts and everything it renders; declare one `@source` per component your views use instead of scanning every template. `wirekit:doctor` reads your views and names every component they render that no declared source covers. See [scanning only the components you use](https://docs.wirekit.app/getting-started/integration#scanning-only-the-components-you-use).
- **`<x-wirekit::sidebar.collapse-toggle>` — the sidebar's collapse control, wherever you put it.** In a rail's foot or a top bar it asks the [sidebar](https://docs.wirekit.app/components/sidebar) to fold and draws the state the sidebar reports, `for` addresses one sidebar by id, and below the shell's `lg` breakpoint it hides unless `always` is set.
- **A [modal](https://docs.wirekit.app/components/modal#when-the-reader-dismisses-it) and a [drawer](https://docs.wirekit.app/components/drawer) say when the reader dismisses them.** `wirekit:modal-dismissed` and `wirekit:drawer-dismissed` go out on the window with `{ name, via }` for a click beside the panel, Escape and the close button, so a dialog that cleans up on the server hears about it; a close your page asked for stays silent. Escape and the close button now hand the focus back to the opener, as a click beside the panel already did.
- **A [navbar](https://docs.wirekit.app/components/navbar#a-row-that-scrolls-instead-of-a-menu) row that scrolls instead of folding into a menu.** `mobile="scroll"` keeps the entries in one row at every width and keeps the current one in view, and `density="compact"` sets small entries with the ones you are not on muted.
- **A [page header](https://docs.wirekit.app/components/page-header#status-beside-the-title) takes a `meta` slot for a status or a count beside the title.** It is drawn in the title's row after the heading and outside it, so a screen reader does not read it as part of the title.
- **A link can open a new tab without announcing one.** `:announce-new-tab="false"` drops the arrow and the screen-reader hint and keeps the target and `rel="noopener noreferrer"`, for a link that script turns into something else, a dialog for example. See [when script turns the link into something else](https://docs.wirekit.app/components/link#when-script-turns-the-link-into-something-else).
- **A [stepper](https://docs.wirekit.app/components/stepper#following-a-flow-that-changes-step-in-the-browser) can follow a step that changes in the browser.** `follow` names the Alpine property that holds the current step, and the circles, `aria-current` and the compact form's line follow it. The wizard's indicator uses it.
- **A [brand](https://docs.wirekit.app/components/brand#inside-a-link) can sit inside a link, and takes a `size`.** `:href="false"` renders it without a link of its own, and `size` sets the logo's height: `xs`, `sm` (as before), `md` or `lg`, or a CSS length such as `1.75rem` for a height between those steps.
- **The [app shell](https://docs.wirekit.app/components/app-shell#a-height-other-than-the-windows)'s height has a name.** Set `--wk-shell-height` on the shell or an ancestor for a height other than the window's; unset, the shell is exactly as tall as before.
- **A [table](https://docs.wirekit.app/components/table) head can break only between its words, or turn on its side.** `wrap="words"` keeps a head's words whole and evens its lines, for heads over narrow columns of numbers; `sideways` turns a head to read from bottom to top on one line, for many short columns beside a wide one.
- **A table your Markdown pipeline rendered can freeze its first column below a breakpoint only.** `data-wk-sticky-column-below="md"` (or `sm`, `lg`, `xl`, `2xl`) does on your own `<table>` what the [table](https://docs.wirekit.app/components/table#only-below-a-breakpoint)'s `sticky-column-below` does for its own: below the breakpoint the first column stays in place while the rest scrolls, and from that width up the table wraps into its box like any other. The rules ship in the stylesheet, so they use Tailwind's default breakpoint widths. See [attribute hooks](https://docs.wirekit.app/extending/public-css-api#attribute-hooks-you-can-put-on-your-own-markup).
- **A [data table](https://docs.wirekit.app/components/data-table#keeping-the-readers-columns) says when the reader shows or hides a column.** `wirekit:data-table-columns-changed` carries `hidden` and `visible`, so an application can keep the choice with the reader's account, and a `hidden` list from a later render is followed without rebuilding the table.
- **A [slider](https://docs.wirekit.app/components/slider#value-below-the-track) can show its value on a line under the track.** `value-position="below"` gives every slider in a form the same track length, and `data-wk-slider-value` marks the value box for styling.
- **An [OTP input](https://docs.wirekit.app/components/otp-input#width-and-size) takes a `size`.** `sm` 32px, `md` 40px as before, `lg` 48px, which clears the touch target on any pointer. `dusk` and `data-*` attributes reach the group element.
- **A [button](https://docs.wirekit.app/components/button) takes `icon-only-below="xs"`,** a step below `sm` at 360px, for a bar that fits a phone but not the smallest ones.
- **[Text](https://docs.wirekit.app/components/text) takes `leading` and `wrap`.** `leading` sets `tight`, `normal` or `relaxed` on the leading tokens, and `:wrap="false"` keeps a line whole without cutting it.
- **A [tab](https://docs.wirekit.app/components/tabs)'s badge can carry a tone.** `badgeIntent` on `items` or on `tabs.tab` passes one of the badge's intents.
- **A [tooltip](https://docs.wirekit.app/components/tooltip#surface) takes `surface="elevated"`** for the surface menus and popovers use: the elevated background, the body text and the theme's border. The default stays the inverted tooltip. The example the page used to call "Inverted" was this surface, set through two custom properties, and it is now named for what it is.
- **A [callout](https://docs.wirekit.app/components/callout) takes `title` as a prop as well as a slot,** the way an alert does.
- **The labeled [app rail](https://docs.wirekit.app/components/app-rail)'s icon has its own size.** `--size-wk-rail-icon-labeled` sizes the glyph under a name and defaults to `--size-wk-rail-icon`, and a long name hyphenates at a syllable where the page's language allows.
- **`wirekit:doctor:props` reports a named slot passed as an attribute and names the slot to use.** Written as `:title="…"`, a slot's value landed on the wrapper as an HTML attribute and the heading was never drawn; the linter now reports it with `<x-slot:name>`. See the [CLI reference](https://docs.wirekit.app/cli-reference).

### Changed

- **A list of options with gaps is a map now, in [multi-select](https://docs.wirekit.app/components/multi-select) and [combobox](https://docs.wirekit.app/components/combobox).** Both decide between a list and a map by the whole array, as `select` does, so `pluck('name', 'id')` submits the ids. An array filtered without `array_values()` keeps its indexes as keys and now submits them; wrap it in `array_values()` to submit the values.
- **[`wirekit:theme`](https://docs.wirekit.app/cli-reference#wirekittheme-preset) and each preset's page agree on every token both of them set.** Where the command and the page gave one preset two different values, the page's value is now the one the command writes: Material takes indigo-600 as its accent where it wrote the darker indigo-700, and its easing is `cubic-bezier(0.2, 0, 0, 1)`; Cupertino eases with `cubic-bezier(0.25, 0.46, 0.45, 0.94)`; Retro Terminal uses `#00ff41` with a `#0d0d0d` label; and the accent label of Soft, Material and Cupertino is white. Minimal now writes its page's whole block, in light and dark: borders go away and fields take a neutral fill in their place, the text inside a field darkens to stay readable on that fill, panels get a surface of their own so an open menu stands off the page without a shadow, headings are lighter and motion is quicker, and pills and avatars stay round, as they do on the page. Most other pages still set more than the command writes, Retro Terminal's palette among them, so copy a page's block when you want its complete look. The command writes into your `app.css`, so a preset you applied before keeps its old values until you run it again.
- **A finger scrolls the page on a [reading minimap](https://docs.wirekit.app/components/reading) instead of dragging it.** Dragging the viewport box maps the pointer onto the scroll position like a scrollbar thumb, and under a finger that scrolled the page the wrong way round. On a touch screen a swipe now scrolls the page natively and a tap on a stripe still jumps to its section; a mouse and a pen drag as before.
- **A modal's and a drawer's body and footer pad all four sides alike.** The content starts where the title starts; the sides were wider than the top and the bottom.
- **A [tooltip](https://docs.wirekit.app/components/tooltip) opens on focus only when the focus is visible.** A dialog that focuses its first control when it opens no longer shows that control's tooltip; a keyboard focus and a hover still open it.
- **`text weight="normal"` reads `--font-wk-body-weight`,** so text follows a theme that sets its running text lighter or heavier.
- **A control bound with neither `id` nor `name` derives its id from what it is bound to.** `file-upload`, `slider` and `date-picker` drew a random id on every render, which Livewire's morph reads as a new element; the id now comes from `wire:model` (`wk-upload-photos`) or from the render order, and it is the same on every render. The nameless title ids of the modal, the drawer and the alert dialog follow the same rule.
- **Some class names changed in the rendered markup.** The shell drawer transitions `translate` as well, the modal's and the drawer's padding use one token, and a data table's hidden columns travel in its state carrier instead of `x-data`. Nothing changes on screen beyond the entries above; it matters only if a test of yours matches on these names.

### Fixed

- **An [editor](https://docs.wirekit.app/components/editor) bound with `wire:model` sends its last change when a form is submitted right after it.** The field follows the editor 200 ms late, and a submit inside that window sent the text from before the change. Leaving the editor now writes a pending change at once; leaving an editor that did not change still reports nothing.
- **A tooltip restyled on its wrapper keeps its colors when Livewire updates the page while it is open.** The update took away the colors the tooltip copies onto its panel, so a tooltip held open under the pointer or by focus came back in the default colors; before 2.54.0 it also lost its position and stood at the end of the page.
- **The arrow keys of a menu walk only the entries that are drawn.** In the [dropdown](https://docs.wirekit.app/components/dropdown), the [context menu](https://docs.wirekit.app/components/context-menu), the [menubar](https://docs.wirekit.app/components/menubar) and a submenu, an entry hidden with `x-show` stopped the arrow keys, and focus stayed where it was.
- **A panel opened inside a dialog stands above it.** A tooltip, a popover or a dropdown opened from inside a modal stood under the dialog's layer, and a click on a dropdown entry landed on that layer.
- **A dialog's action row wraps instead of pushing its first action off the panel.** The footers of the modal and the drawer and the actions of the [alert dialog](https://docs.wirekit.app/components/alert-dialog) cut an action off on a phone when the actions did not fit one line; on a desktop they stay one line.
- **A required field Livewire empties after a success no longer turns red.** The browser remembers that the reader touched a field when script empties it, so the add-another row painted its field red over a success message; a field the reader empties, or tries to submit empty, is red as before.
- **A [file upload](https://docs.wirekit.app/components/file-upload)'s list follows the property it is bound to.** A save that sets it back to empty clears the list, and so do a form reset and `wirekit:file-upload-reset`.
- **The [editor](https://docs.wirekit.app/components/editor) no longer reports loading a stored value as an edit.** It wrote its own serialization of the document back on load, and the next save stored that rewrite of a document nobody had touched.
- **Multi-select and combobox submit the key of a map with integer keys,** `pluck('name', 'id')` included; they submitted the labels.
- **A [lightbox](https://docs.wirekit.app/components/lightbox) opens from a trigger inside a tooltip, and its embed slide loads under the CSP build.** The trigger opened the tooltip instead of the gallery, and the embed frame stayed blank.
- **A horizontal [stepper](https://docs.wirekit.app/components/stepper#many-steps-in-a-narrow-column) with many steps keeps its words whole in a narrow column.** Below 5rem per step it draws the circles with one line naming the current step, instead of breaking every word; a [wizard](https://docs.wirekit.app/components/wizard)'s indicator follows Next and Back.
- **The app shell's drawer slides in** instead of standing at its open position in the first frame.
- **A collapsed sidebar shows its names in the phone drawer, and its collapse control leaves the drawer,** where it had nothing to fold; the desktop keeps the reader's choice.
- **The phone drawer with a labeled rail beside a menu fits a 320px screen,** and a name under a rail icon keeps to the width of its entry.
- **The columns that scroll beside a frozen [table](https://docs.wirekit.app/components/table#the-columns-beside-it) column each fit beside it.** A value wider than the room beside the frozen column could never be seen whole; a scrolling cell is now capped by `--size-wk-table-sticky-cell-max` and the frame.
- **An icon-only button stays square on a touch screen** and is hit across 44px.
- **An [input](https://docs.wirekit.app/components/input)'s clear and copy buttons take the touch target where a finger works them, and `readonly` paints the muted surface** on the input and the [textarea](https://docs.wirekit.app/components/textarea).
- **A button as a strip's action keeps to the strip's line** on a desktop and on a touch screen, where it stood 8px over each edge; see the [announcement banner](https://docs.wirekit.app/components/announcement-banner).
- **A slider's `error` or `hint` is a line of its own under the control.** It sat in the row beside the track and took the track's room.
- **Scroll shadows no longer flash when a hidden panel is revealed.**
- **The [page progress](https://docs.wirekit.app/components/page-progress) bar shows a request that begins while the previous bar is fading out.**
- **A [reveal](https://docs.wirekit.app/components/reveal) taller than the screen appears.** A section that could never reach the threshold stayed invisible.
- **A page header whose default slot holds only Livewire's markers renders its title.**
- **`<x-wirekit::fonts />` writes no font preload into the answer to a `wire:navigate`,** which made the browser fetch the body font again after every navigation.
- **`wirekit:csp-audit` reports what the CSP build refuses whatever the expression says:** `x-html`, and any expression on an `<iframe>` or a `<script>`, which parsed and passed.
- **`wirekit:verify` accepts a comparison with `null` as the guard before a `disconnect()`,** and `wirekit:doctor:props` reads `:attributes="$bag"` as Blade rather than as an unknown prop.
- **The public `components.json` and `api-map.json` leave out a component that is documented only on a page that is not public yet.**

### Components

Every component this release changes, each linked to its page: [Accordion](https://docs.wirekit.app/components/accordion) · [Alert Dialog](https://docs.wirekit.app/components/alert-dialog) · [Announcement Banner](https://docs.wirekit.app/components/announcement-banner) · [App Rail](https://docs.wirekit.app/components/app-rail) · [App Shell](https://docs.wirekit.app/components/app-shell) · [Assistant Message](https://docs.wirekit.app/components/assistant-message) · [Branch Switcher](https://docs.wirekit.app/components/branch-switcher) · [Brand](https://docs.wirekit.app/components/brand) · [Button](https://docs.wirekit.app/components/button) · [Button Group](https://docs.wirekit.app/components/button-group) · [Calendar](https://docs.wirekit.app/components/calendar) · [Callout](https://docs.wirekit.app/components/callout) · [Chart](https://docs.wirekit.app/components/chart) · [Checkbox](https://docs.wirekit.app/components/checkbox) · [Code Block](https://docs.wirekit.app/components/code-block) · [Color Picker](https://docs.wirekit.app/components/color-picker) · [Combobox](https://docs.wirekit.app/components/combobox) · [Command Palette](https://docs.wirekit.app/components/command-palette) · [Context Menu](https://docs.wirekit.app/components/context-menu) · [Data Table](https://docs.wirekit.app/components/data-table) · [Date Picker](https://docs.wirekit.app/components/date-picker) · [Drawer](https://docs.wirekit.app/components/drawer) · [Dropdown](https://docs.wirekit.app/components/dropdown) · [Editor](https://docs.wirekit.app/components/editor) · [Event Calendar](https://docs.wirekit.app/components/event-calendar) · [File Upload](https://docs.wirekit.app/components/file-upload) · [Filter Builder](https://docs.wirekit.app/components/filter-builder) · [Fonts](https://docs.wirekit.app/components/fonts) · [Hover Card](https://docs.wirekit.app/components/hover-card) · [Inline Edit](https://docs.wirekit.app/components/inline-edit) · [Input](https://docs.wirekit.app/components/input) · [Lightbox](https://docs.wirekit.app/components/lightbox) · [Link component](https://docs.wirekit.app/components/link) · [Menubar](https://docs.wirekit.app/components/menubar) · [Message](https://docs.wirekit.app/components/message) · [Modal](https://docs.wirekit.app/components/modal) · [Multi-Select](https://docs.wirekit.app/components/multi-select) · [Navbar](https://docs.wirekit.app/components/navbar) · [Navigation Menu](https://docs.wirekit.app/components/navigation-menu) · [Notification Center](https://docs.wirekit.app/components/notification-center) · [Number Input](https://docs.wirekit.app/components/number-input) · [OTP Input](https://docs.wirekit.app/components/otp-input) · [Overflow Nav](https://docs.wirekit.app/components/overflow-nav) · [Page Header](https://docs.wirekit.app/components/page-header) · [Page Progress](https://docs.wirekit.app/components/page-progress) · [Pagination](https://docs.wirekit.app/components/pagination) · [Password Input](https://docs.wirekit.app/components/password-input) · [Phone](https://docs.wirekit.app/components/phone) · [Popover](https://docs.wirekit.app/components/popover) · [Pricing Table](https://docs.wirekit.app/components/pricing-table) · [Radio](https://docs.wirekit.app/components/radio) · [Range Slider](https://docs.wirekit.app/components/range-slider) · [Rating](https://docs.wirekit.app/components/rating) · [Reading](https://docs.wirekit.app/components/reading) · [Reveal](https://docs.wirekit.app/components/reveal) · [Scope Switcher](https://docs.wirekit.app/components/scope-switcher) · [Scroll to Top](https://docs.wirekit.app/components/scroll-to-top) · [Segmented Control](https://docs.wirekit.app/components/segmented-control) · [Select](https://docs.wirekit.app/components/select) · [Shell Bar](https://docs.wirekit.app/components/shell-bar) · [Sidebar](https://docs.wirekit.app/components/sidebar) · [Slider](https://docs.wirekit.app/components/slider) · [Stepper](https://docs.wirekit.app/components/stepper) · [Sticky Panel](https://docs.wirekit.app/components/sticky-panel) · [Strength Meter](https://docs.wirekit.app/components/strength-meter) · [Table](https://docs.wirekit.app/components/table) · [Tabs](https://docs.wirekit.app/components/tabs) · [Tags Input](https://docs.wirekit.app/components/tags-input) · [Text](https://docs.wirekit.app/components/text) · [Textarea](https://docs.wirekit.app/components/textarea) · [Theme Controller](https://docs.wirekit.app/components/theme-controller) · [Time Picker](https://docs.wirekit.app/components/time-picker) · [Toggle](https://docs.wirekit.app/components/toggle) · [Tooltip](https://docs.wirekit.app/components/tooltip) · [Tour](https://docs.wirekit.app/components/tour) · [Wizard](https://docs.wirekit.app/components/wizard)