Skip to main content
WireKit

WireKit v2.30.0

Minor release

Minor — a personalization that keeps inheriting, an error message that finally names its own cause, and asset replies that are safe to cache where they claim to be.

Nothing here changes what an unchanged call site renders. The asset routes change which middleware they run; see the entry below if your application relies on web applying to them.

Added

  • A mistyped prop now tells you, on nearly every component instead of a handful. Blade folds a name a component does not declare into the attribute bag, where it renders as a literal HTML attribute nothing reads — the page looks finished and nothing fails. WireKit has warned about that in development since v2.6, with a did-you-mean hint, but only a handful of components asked for the check. It now covers essentially the whole catalog. The warning is development-only and silent in production, and the list of accepted names is read from the component itself, so it cannot fall behind the component it describes.

    Two things it deliberately does not flag: any valid HTML attribute, and framework wiring (aria-*, data-*, wire:, x-/@/:, v-, and the on* event family). A name a component reads through @awareannounce-errors on any form control, for instance — counts as known too. That last part is also a fix: those calls were reported as typos before, on the components that already had the check.

    ComponentRegistry::extractAwareProps() exposes the @aware half for tooling that needs it. It stays separate from extractProps(), which continues to mean "the props this component declares". Customization

  • A class block can state its delta instead of taking the block over. Personalizing a block has always meant restating it in full, and from that moment your application owns it — every later improvement WireKit makes to that block stops arriving, silently, because nothing is broken. A block value may now be a closure, and it receives the class string WireKit ships:

    WireKit::personalize('sidebar.item', [
        'base' => fn (string $vendor): string => $vendor.' rounded-none',
    ]);
    

    You are not limited to appending — the point is that you can see what you are overriding, so you can swap or drop one utility and keep the rest. Works on personalize() and scope(). A plain string still replaces the block outright, unchanged, and is still the right choice when you do mean to own the slot. Not available for class overrides written in config/wirekit.php: a closure there cannot survive config:cache, so it would work in development and vanish on the first cached deploy. Customization

Fixed

  • The scroll-area edge fade pointed the wrong way in right-to-left layouts. fade="start" and fade="end" name the reading start and end, but the horizontal mask was emitted with physical directions, so in an Arabic or Hebrew document the two were inverted: the fade sat on the edge the reader had already passed while the edge that actually scrolls stayed hard. Nothing failed and nothing logged — the hint simply pointed backwards. fade="both" is symmetric and was never affected, which is why the most-viewed example could not show it. Scroll Area

  • The asset routes no longer set a cookie on a response they ask a cache to keep for a year. The routes serving WireKit's own CSS, JS and fonts were registered inside the web middleware group. Their handlers read a file from the package directory — no session, no CSRF token, no authentication, no route-model binding — so the group gave them nothing, while StartSession added the session cookie to every reply. Those replies declare public, max-age=31536000, immutable: a shared cache is invited to keep them for a year and may hand one to the next visitor with the cookie still attached. That most shared caches refuse a response carrying Set-Cookie is a per-vendor default you do not control, not a property of what is sent. The practical cost was the reverse of what the header was written for — a CDN could not cache the files the year-long directive exists to let it cache, and every stylesheet hit paid for a session read and write.

    The group is now taken from wirekit.assets.middleware, which defaults to none. If your application applies its own middleware everywhere — a security-header layer, HTTPS enforcement — name it there; anything that starts a session brings the cookie back with it. Published assets served from public/vendor/wirekit/ never used these routes and are unaffected. Integration

  • A bundle that loads too late now says so, instead of leaving you with someone else's error. If the WireKit bundle is loaded after Alpine has already started, every component already on the page never receives its Alpine data. Those elements cannot be revived by registering afterwards, and what reached you instead was the browser complaining about the bindings inside themstartShadow is not defined, a property of a component you never wrote, from a file you did not author. Because tables are responsive by default, one ordinary <x-wirekit::table> was enough to produce it on a page whose author had never heard of a sticky panel. Every bundle now reports the real cause once, with the remedy, and only when there is actually affected markup on the page. Integration

Documentation

  • Design Tokens is now actually complete. The page opens by calling itself the complete CSS-variable surface, and 69 of the 237 declared tokens were not on it — among them --space-wk-md, the whole --size-wk-container-* ladder, both halves of the inverse color pair, every --shimmer-wk-*, and 26 tokens of the reading family. Looking one up returned nothing, with no way to tell "not a token" from "not written down". All of them now have a row, and a check keeps the claim honest as tokens are added.

  • Customization explains when to adjust a block rather than replace it, and why the choice affects whether you keep receiving upstream changes to that block.