Skip to content

v1.1.3 — security, correctness & accessibility fixes

Choose a tag to compare

@0xNeit 0xNeit released this 02 Jun 17:25
· 9 commits to main since this release
84a9121

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): themeToCssBlock now 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 shared stringifyDeclarations (runtime + compiler + @keyframes) escapes identically, so runtime and compiler output stay byte-identical. (#150)
  • @font-face (core): src/format/tech and freeform descriptors are escaped, closing the url('…') quote-breakout. (#151)
  • Release safety (scripts): verify-version-bump.mjs now fails closed when npm view can't confirm the published version, instead of treating a transient error as "unpublished". (#178)

⚙️ Compiler

  • Wrapper-stripping no longer drops _before/_after, Text lines, or Stack stagger (and leak them as invalid DOM attributes). (#172, #173, #174)
  • Native extraction no longer pins responsive props to their base value at every breakpoint. (#175)
  • Dynamic className merges with filter(Boolean) semantics, matching the runtime (no more "m-x undefined"). (#176)
  • Aggregated virtual CSS is deduplicated across modules. (#177)

⚛️ React & React Native

  • ZStack children overlap again. (#154)
  • Image forwards objectFit/objectPosition to the underlying <img> when a placeholder/fallback is set. (#155)
  • Overlay composes a consumer onClick with scrim-dismiss; FocusScope only restores focus on unmount. (#156, #157)
  • Native Image/Avatar reset load state when src changes; native FLIP teardown; spring seeds initial velocity once; native IconButton gains the gray-scale fallback. (#159, #160, #161, #162, #163)

♿ Accessibility (headless)

  • A trigger can now dismiss its own Popover / Menu / Combobox / MultiSelect. (#164)
  • CommandPalette is genuinely modal (focus trap + scrim + portal + aria-modal) and clamps its active-descendant during render. (#165, #169)
  • NavigationMenu submenu Escape/ArrowLeft restore focus to the parent; RangeSlider thumbs can't cross and swap identity. (#166, #167)
  • Tooltip is non-interactive per the APG pattern; MultiSelect.SelectAll is keyboard-operable; Toast uses a single persistent live region; Field only emits aria-describedby ids 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.mjs handles empty budgets; test-utils matchers fail correctly under .not. (#181, #180)

Full diff: v1.1.2...v1.1.3