Skip to content

Version Packages#7

Merged
Todari merged 1 commit into
mainfrom
changeset-release/main
Jun 12, 2026
Merged

Version Packages#7
Todari merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@react-pixel-ui/core@2.2.0

Minor Changes

  • #6 911fbb0 Thanks @Todari! - Core engine overhaul: real PNG compression, full CSS color support, gradient correctness, and graceful degradation.

    Performance

    • The PNG encoder now uses a built-in dependency-free DEFLATE (fixed Huffman + LZ77) instead of uncompressed stored blocks — generated data URLs are 30–100× smaller (e.g. a 600×400 card went from ~78 KB to ~2.4 KB), with a stored-block fallback for incompressible data.
    • generatePixelArt accepts options.want: 'styles' | 'composite' | 'both' so consumers skip generating the PNG they discard (~2× faster for gradient cases). Default 'both' keeps backward compatibility.
    • generatePixelArt results are cached in a small LRU keyed by inputs — hover/theme/re-render churn no longer regenerates identical art. Treat returned objects as immutable.

    Color parsing

    • All 148 CSS named colors are now supported (previously 14 — lime, navy, teal, tomato, gold, rebeccapurple, … no longer fail to parse).
    • New: color(srgb … ), color(srgb-linear …), and color(display-p3 …) — Chromium serializes computed color-mix() results as color(srgb …), so color-mix() now works end-to-end through <Pixel>/usePixelRef.
    • rgb()/rgba() patterns are anchored, so colors embedded in unsupported values (e.g. conic-gradient(rgb(255,0,0), …)) are no longer misparsed as a solid color.

    Gradients

    • Tailwind v4 interpolation hints are handled: linear-gradient(to right in oklab, …) no longer silently falls back to to bottom.
    • Angle units turn, rad, and grad are converted correctly (previously only deg worked).
    • Corner keywords (to top right, …) now resolve to the aspect-ratio-dependent "magic corner" angle per CSS spec via the new resolveGradientAngle(gradient, width, height) export, instead of a fixed 45° multiple.
    • Double-position stops (red 0% 50%) expand into two stops, preserving hard color edges.
    • Stops with px positions or one unparseable stop no longer corrupt the whole gradient (the -1 position sentinel can no longer leak into sampling).

    Correctness & safety

    • generatePixelShadow no longer forces zero offsets to pixelSizebox-shadow: 0 4px 0 stays a straight shadow instead of turning diagonal. Offsets snap to the nearest grid line; all-zero shadows are skipped entirely.
    • generateCompositePixelImage keeps the interior transparent for border-only elements (previously it filled the content area with the border color), and returns null when a background is present but unparseable (url(), conic-gradient(), …) so consumers can leave the original styling untouched.
    • parseComputedStyles resolves percentage border-radius (e.g. border-radius: 50% avatars) against the element size via a new optional size parameter, and handles elliptical two-value radii.
    • parseBoxShadow detects the inset keyword anywhere in the serialization — real browsers put it at the END in computed styles, so inset shadows were previously converted into outer drop-shadows. Multiple shadows are split correctly and the first non-inset one is used.
    • Every exported generator sanitizes pixelSizepixelSize: 0 no longer hangs the tab (infinite loop) or throws RangeError.

    Packaging

    • ESM consumers under moduleResolution: node16/nodenext now get the ESM declaration file (index.d.mts) via per-condition exports types — fixes the attw "Masquerading as CJS" failure and wrong CJS-interop type errors.

@react-pixel-ui/react@2.2.0

Minor Changes

  • #6 911fbb0 Thanks @Todari! - React layer fixes: stable DOM across re-measures, resize awareness, StrictMode-safe observers, working responsive mode, and API hardening.

    <Pixel>

    • The drop-shadow wrapper no longer remounts the child DOM node on every re-measure (theme toggle, style change). Once a shadow wrapper exists it stays in the tree (display: contents while measuring), so uncontrolled <input> values, focus, and selection survive.
    • A ResizeObserver now watches the child: responsive/percentage-width elements re-measure when their size changes (stale absolute-px clip-paths are regenerated), and elements that mount at zero size (inside display: none tabs/accordions) get pixel art as soon as they become visible — previously they never did.
    • Backgrounds the engine can't pixelate (url() images, conic-gradient()) are left untouched instead of being replaced with background: none + a transparent PNG (elements no longer go invisible or flash solid red).
    • Author box-shadow is only cleared when it is actually replaced by a pixel shadow — inset-only shadows are preserved.

    usePixelRef

    • The style observer is created inside an effect instead of the ref callback. Under React 18 StrictMode (the Vite/Next dev default) the simulated remount previously disconnected the observer permanently, freezing all hover/focus/resize updates in development.
    • Borderless elements with a box-shadow get their pixelated drop-shadow again — the hook only read wrapperStyle.filter, which the composer only sets when a border wrapper is needed, so shadows were silently deleted. When the element has no clip-path the filter now applies to the element itself instead of its parent.
    • Same graceful-degradation behavior as <Pixel> for unparseable backgrounds.

    <PixelBox>

    • responsive mode actually works now: the component no longer pins its own measured fallback (200×100) as inline px width/height, which made the ResizeObserver only ever read back the forced size. Size the box with your own CSS (style={{ width: '100%', height: 120 }}) and the pixel art follows it. Measurement uses the border box.
    • className, style, and other HTML props now consistently land on the root element (previously style landed on the inner content div when a border was used, so margin etc. silently did nothing).

    <PixelButton>

    • Unknown variant values fall back to primary with a dev warning instead of crashing with a TypeError.
    • The rendered <button> defaults to type="button" so dropping it into a form no longer submits the form; an explicit type prop still wins.

    Misc

    • PixelConfigProvider no longer crashes when rendered without a config prop (it is now optional).
    • usePixelArt memoizes by the radius values, so inline per-corner arrays (borderRadius={[8,8,0,0]}) no longer regenerate the art on every parent re-render; it also skips generating the unused composite PNG.
    • PixelBox/PixelButton expose proper displayNames in React DevTools (no more PixelBox2).
    • ESM consumers under moduleResolution: node16/nodenext get the ESM declaration file via per-condition exports types, and the "use client" banner no longer shifts source maps by one line.

Patch Changes

  • Updated dependencies [911fbb0]:
    • @react-pixel-ui/core@2.2.0

@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-pixel-ui Ready Ready Preview, Comment Jun 12, 2026 9:23am

@Todari Todari merged commit 537c64a into main Jun 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant