WireKit v2.35.0
Minor. The stylesheet you serve is a fifth of the size it was, the ES module can finally be tree-shaken, and a handful of controls now do what they always said they did — a rich-text editor that stops zooming iOS, a checkbox whose third state survives a server round trip, a sidebar rail that no longer shifts the page when it collapses.
Added
--z-wk-chrome— a layer for page chrome that must stay above overlays opened in page content.<x-wirekit::andheader sticky> <x-wirekit::sit on it, so a popover in an article no longer paints over the site header. It stays belownavbar sticky> --z-wk-modal, and a panel anchored inside the header is unaffected: top chrome opens downward and never overlaps the bar it hangs from.--reading-progress-segment— retint the chapter dividers<x-wirekit::draws, independently of the bar itself.reading-progress :segments="…"> previous-labelandnext-labelon<x-wirekit::— name the two direction controls. "Previous" and "Next" are misleading on a reverse-chronological list, where moving "next" goes backward in time; on a changelog or an activity feed,pagination> previous-label="Newer"says what the button does. Unset keeps the translated defaults.labelon<x-wirekit::anddrawer> <x-wirekit::— name the dialog without a header slot. A drawer built from body content alone previously had no accessible name and no way to give it one.alert-dialog> - The
undoicon alias — a real undo glyph in all four presets, so the name keeps meaning the same thing when a project changes preset. - Per-component ES module exports. Every Alpine factory is exported by name and
register()takes a chosen subset, so a bundler can drop what you never render. Measured with esbuild: one component 26 KB raw / 10 KB gzip against 235 KB / 66 KB for the whole library. The default export is unchanged.
Changed
@wirekitStyleslinks a minified stylesheet. The readable, fully commenteddist/is still published beside it — it is the source of truth for what every token means — but two thirds of it is comments, and it is render-blocking. The linked file is now 12 KB gzip instead of 74 KB, verified to contain every token, component class and at-rule the readable one does.wirekit. css wirekit:install --font=<key>publishes that family only. It copied the whole 5.8 MB font tree for a single flag, once per--font*flag, and again on everycomposer installwhere the publish is wired intopost-autoload-dump.<x-wirekit::wraps long lines in aprose> <pre>instead of scrolling them. A horizontal scroll region has to be reachable by keyboard, and Prose styles markup it did not author, so it cannot put a tab stop on your<pre>. Author one yourself —<pre tabindex="0" role="region" aria-label="…">— and Prose gives that block its horizontal scrolling back.wirekit:doctorchecks the stylesheet the page actually links. It reported the readable copy as published while the linked one was missing, which is a green tick over an unstyled page.- Sidebar rows keep one height whether the rail is expanded or collapsed. They were sized by the label when it showed and by the icon when it did not — 2.75px per row on the shipped type ramp, so a three-item rail moved everything below it by 8.25px on every toggle.
Fixed
<x-wirekit::no longer makes iOS zoom on focus. Its typing surface computed to 14px: the 16px floor was written for form controls, and a rich-text editor types into aeditor> contenteditable, which noinput/textareaselector reaches.- A caller's
aria-labelreaches the control oninline-edit,editor,command-palette,drawerandalert-dialog. It was landing on a wrapper with no role, so the element the user operates had no accessible name at all. - Every labeled
<x-wirekit::had a control with no accessible name — the label'sinline-edit> forand the control'sidwere two different strings. <x-wirekit::follows a change made after the first render. The third state is a DOM property with no HTML attribute, and it was applied once; a Livewire round trip left the box reading "none selected" while something was selected.checkbox indeterminate> <x-wirekit::andcollapsible> <x-wirekit::keep their content across a Livewire round trip. Both built ids that changed on every render, so the morph replaced the region: focus left the slot, anything typed into an unbound input was discarded, and an open panel flashed hidden.tabs> <x-wirekit::andmenubar. menu> <x-wirekit::keep the classes you pass them. They emittednavigation-menu. item> classtwice, and the browser discards the second.<x-wirekit::andcode-block> <x-wirekit::scroll regions are reachable by keyboard. The shell bar's wiring depended on its optionalshell-bar> label, so the common usage shipped an unreachable scroller.<x-wirekit::reveals its actions on touch. The default reveal used hover and focus, and a phone has neither in a discoverable form — reply, react and delete were invisible with no way to summon them.message> - Bottom-anchored floating controls clear the iOS home indicator.
action-bar,scroll-to-top,reading-bookmarkand the<x-wirekit::badge sat inside the gesture strip, which swallows taps.reading-progress indicator="dot"> <x-wirekit::measures against the dynamic viewport, so the strip it reserves is not consumed by the mobile browser's own chrome.drawer> - Reveals no longer flash before they animate, and a click-triggered one is visible enough
to click. The rule that pre-hides an element until its animation runs was spelled for one
authoring form in its anchor and for the other in its exclusions, so each was half-covered
in opposite directions: a
<x-wirekit::painted at full opacity before sliding in, while areveal> wirekitwritten by hand was hidden into a target nobody could aim at. Measured across all seven combinations.Animate('…', { trigger: 'click' }) - A
<x-wirekit::counter can be started again. It fires once when the stat scrolls into view — correctly, since a stat that re-counts on every pass would be distracting — but nothing could ask for a restart: the observer disconnects itself after the first intersection, and the page said to scroll the stat out of view and back, which for that reason could never have worked. Dispatchstat animate> wirekit:stat-replayon the stat's root. Underprefers-reduced-motion: reducethe value is already settled and the event does nothing. <x-wirekit::renders its themed background again.mark> reading-progresschapter dividers are visible in dark mode — they were a fixed near-black on a transparent strip.- The sliders shrink with a narrow parent instead of overflowing it. Their minimum width was a hard floor, against a comment promising the opposite.
<x-wirekit::is documented for the start of the body, not the head. It emits anglass /> <svg>, and an SVG in the head ends head parsing — every metadata tag after it is reparented into the body, where a crawler does not look.- Config defaults that nothing read are wired or removed —
stat.animate,editor.format,editor.toolbarandeditor.sizeare read from config now;date-picker.is gone, since a native date input renders in the viewer's locale and cannot be told otherwise.format asis validated before it becomes a tag name. A value containing a space or an=was rendered into the opening tag as an attribute.wirekit:install --rollbackno longer runs out of memory on a large install log, and a second run reports that the session is already undone instead of silently replaying it.<x-wirekit::documents its one prop.fonts> noncewas explained in prose but never listed as a prop, so it was absent from the one place a developer looks for the component's surface.- The
wirekit:doctorpage shows the glyphs the command prints. Five of its six output examples used⚠for a warning, which the command has never emitted — it prints!— and the page asserted the wrong glyph in its own legend. Four of the quoted lines also carried labels and a shape the command does not produce. A developer comparing their terminal against the page was matching it to output that does not exist. wirekit:glass installtells you to put the component in the body, where it belongs. The command and both pages that show the placement still put it in the<head>— the placement this release announced as corrected. An SVG there ends head parsing, so every metadata tag after it is reparented into the body.wirekit:icons --auditsays what it looked at when it finds nothing. It reads two surfaces — the<x-wirekit::tag and theicon> iconprop on every component that takes one — but both of its refusals named only the tag, so a project whose icons are props was told no icon tags were found and sent looking for a scanning path that was not the problem. The bound-value line said:name="…"where a prop binds as:icon.wirekit:class-by-arealooks for your application's own compiled CSS, and says so when it finds none.
Documentation
- The ES module page explains how to import a subset, with measured sizes.
wirekit:doctor's example output is transcribed once, on the command's own page.- Fifty-seven blueprint code blocks that name a destination
.phpfile now open with<?php. - Thirteen page-to-page links that pointed at a fragment no heading generates are corrected.
- Every publicly served page has an authored meta description within the serving cap, and no two share a title.