v1.1.3 — security, correctness & accessibility fixes
Patch release across all packages (1.1.2 → 1.1.3), resolving 32 issues (#150–#181) from a full-codebase audit. Every fix ships with regression tests; CI is green on Node 20 + 22 (typecheck, lint, format, build, test, bundle-size, tree-shaking).
🔒 Security
- CSS injection (core):
themeToCssBlocknow escapes custom-property values (not just the theme name) — a token value containing}/;/<, common when tokens come from imported design-token JSON, can no longer break out of the rule block or the<style>element. The sharedstringifyDeclarations(runtime + compiler +@keyframes) escapes identically, so runtime and compiler output stay byte-identical. (#150) @font-face(core):src/format/techand freeform descriptors are escaped, closing theurl('…')quote-breakout. (#151)- Release safety (scripts):
verify-version-bump.mjsnow fails closed whennpm viewcan't confirm the published version, instead of treating a transient error as "unpublished". (#178)
⚙️ Compiler
- Wrapper-stripping no longer drops
_before/_after,Textlines, orStackstagger(and leak them as invalid DOM attributes). (#172, #173, #174) - Native extraction no longer pins responsive props to their
basevalue at every breakpoint. (#175) - Dynamic
classNamemerges withfilter(Boolean)semantics, matching the runtime (no more"m-x undefined"). (#176) - Aggregated virtual CSS is deduplicated across modules. (#177)
⚛️ React & React Native
ZStackchildren overlap again. (#154)ImageforwardsobjectFit/objectPositionto the underlying<img>when a placeholder/fallback is set. (#155)Overlaycomposes a consumeronClickwith scrim-dismiss;FocusScopeonly restores focus on unmount. (#156, #157)- Native
Image/Avatarreset load state whensrcchanges; native FLIP teardown; spring seeds initial velocity once; nativeIconButtongains the gray-scale fallback. (#159, #160, #161, #162, #163)
♿ Accessibility (headless)
- A trigger can now dismiss its own Popover / Menu / Combobox / MultiSelect. (#164)
CommandPaletteis genuinely modal (focus trap + scrim + portal +aria-modal) and clamps its active-descendant during render. (#165, #169)NavigationMenusubmenu Escape/ArrowLeft restore focus to the parent;RangeSliderthumbs can't cross and swap identity. (#166, #167)Tooltipis non-interactive per the APG pattern;MultiSelect.SelectAllis keyboard-operable;Toastuses a single persistent live region;Fieldonly emitsaria-describedbyids that exist. (#168, #170, #171, #158)
🎨 Core, migrate & tooling
- Responsive DSL coerces numbers only when lossless; near-opaque alpha collapses to
rgb(). (#152, #153) - Markdown codemod parses 4+-backtick / longer-tilde fences correctly. (#179)
check-sizes.mjshandles empty budgets; test-utils matchers fail correctly under.not. (#181, #180)
Full diff: v1.1.2...v1.1.3