WireKit v2.47.0
Minor. Most of this release is WireKit correcting things it told you that were not true. wirekit:verify asked Composer whether an icon package was installed and then asserted a runtime it had never measured — over a tree where every icon renders. Two of its translation warnings contradicted each other, and following the first one's advice failed the gate on the second; a third kept explaining a mechanism the developer had switched off. The dropdown warned that mixing its two forms nests a panel inside a panel, which stopped being the case when the wrap became conditional. A warning is believed, and that is what makes a stale one expensive rather than untidy: it aims the next investigation, and the reader arrives looking for a symptom that is not there. Alongside those, seven components stop guessing where in your document they sit — a hero, a feature card and five more take the heading level from you — and twelve form components can finally shrink inside a caller's grid instead of pushing it sideways.
Added
-
Seven components let you choose their heading level instead of writing the tag for you. Hero, Feature, CTA, Product Card, Event Calendar, Tour's step and the alert dialog's title each take a
levelprop, defaulting to exactly what they rendered before — so nothing moves unless you set it. A marketing page built from a hero and five feature cards renderedh1followed by fiveh3, and those cards are that page's first-order sections: the level was not merely a formal mistake, it described the page's structure wrongly. A component cannot know where in a document it sits, so the level is yours to choose rather than something to guess. Reported by a developer whose accessibility sweep was green while the score that publishes was not — the rule that catches this sits in axe's best-practice group rather than the WCAG groups most suites run, and in Lighthouse's accessibility category. -
Button can stay enabled while its action is in flight. It disables itself for the duration of a
wire:loadingwindow, which is right for a submit and wrong for a control you want pressable again — a filter that re-runs, a refresh.disable-on-loading="false"keeps it focusable and in the tab order and marks itaria-busy="true"instead, so assistive technology still hears that something is happening. The default is unchanged, and the trade is yours to make: a control that stays enabled can be pressed twice. -
Dropdown can fill the width it is given.
blockmakes its wrapper a full-width block, so a trigger that spans its column gets a panel that reaches past it instead of one sized to a shrink-wrapped shell. A class from the call site cannot do this: the wrapper's owndisplaywould have to be overridden, and two conflicting utilities resolve by stylesheet order rather than by which one you wrote. -
Profile takes a
toneand apadding.tone="muted"renders the name in muted text that brightens with the row on hover — for the entry that closes a navigation list rather than heading it — andpaddingsets the row's own inset. Neither was reachable from a call site without giving up thenameprop for the slot and re-writing the collapse handling by hand, and a component whose most common use needs an incantation gets rebuilt instead of adopted. -
Reading Spine takes the distance from the edge it sits on.
positionpicks which edge;edge-offsetpicks how far in — and0, a spine flush against the window, was unreachable before because both arms carried1remas a literal. It is a theme token too (--reading-spine-edge-offset), so one declaration moves every spine in an application. Reported from a developer who had reached for a stylesheet override instead: that reaches every spine rather than the one call that wants it, and it only wins at all because Tailwind emits its utilities into a layer. -
Shell Bar has an
xspadding rung. The gap betweennoneandsmwas the width a dense toolbar wanted, and closing it by hand meant a class that fights the component's own.
Changed
- The Event Calendar's focused date is exposed as
focusedDatein its Alpine scope, notfocus. A scope property that shares its name with a browser global is resolved againstwindowwhenever a scope is lost — so instead of the error that would name the component, the expression quietly hits something else entirely. The old name was never documented and nothing in the component reads it, so the rename is invisible unless you reached for it yourself.
Fixed
- The dropdown's mixed-form warning described a consequence the same template prevents. A call site naming both
<x-slot:trigger>and an explicit<x-wirekit::dropdown.panel>was told it had nested a panel inside a panel and given the two the same id. That was true once and has not been since the wrap became conditional — the explicit panel is passed through untouched, and rendering the same call site with and without it produces identical markup. A warning is believed, so the sentence sent the reader looking for a duplicate id that was not there. It now says what is actually the case: the explicit panel repeats work the component already does, and dropping it is a simplification rather than a repair. Reported by a developer who measured it after the text sent them the wrong way, with 208 occurrences of the line in one log window. wirekit:verifyasked Composer whether an icon package was installed, and then asserted a runtime it had never measured. The question that decides whether a page renders is whether the identifiers resolve — and an application may ship the glyphs itself under the preset's prefix, registering its own set and deliberately not depending on the upstream package. Composer answers "not installed" over a tree where every icon renders. The remedy the warning printed made it worse: installing the package brings a second set claiming the same prefix, which Blade Icons refuses. The check now resolves one real identifier per configured preset, through the supported API.- Twelve form components could not shrink inside a caller's grid or flex layout. The wrapper each of them puts into your layout lacked
min-w-0, so a long unbreakable value drove its track wider than its share and the page scrolled sideways — visible at narrow viewports and not at the one the page was written on. The class changes nothing in normal flow, where a block already takes its width from its container. wirekit:verifyreported two translation warnings that contradicted each other, and neither could be silenced. The first says a shared key means something different in your catalog than in WireKit, and tells you to translate the namespaced key while keeping your own — the second then reported exactly that catalog as a fork. Following the first one's advice failed the gate on the second, and there was no third state satisfying both. A fork is now only reported when the two spellings hold the same wording, which is the case that check was written for: one string in two places, free to drift with nothing to notice. Two different wordings is the split the first message asks for, and it reads as an informational line.- The same check ignored
translations.legacy_key_bridgeentirely. With the bridge off, your catalog's unprefixed key does not reach the component at all — WireKit renders its own string — so a wording difference has no effect on anything shown. The warning stayed anyway, and its closing sentence ("the legacy-key bridge keeps applying your wording inside the component") had become untrue. It now reads the setting, and reports an informational line instead. Reported by a developer whose upgrade turned fourteen of these into a red gate with no documented way out.