ui@0.5.0
Breaking Changes📦 remixView on GitHub →
⚠ 1 breaking✨ 9 features🐛 9 fixes🔧 29 symbols
Summary
This release introduces enhanced frame navigation capabilities for same-origin forms and allows browser frame resolvers to return `Response` objects. It also includes several bug fixes for component updates, navigation stability, and DOM preservation.
⚠️ Breaking Changes
- Browser `resolveFrame` callbacks now receive a single options object instead of positional signal and target arguments. Update `resolveFrame(src, signal, target)` implementations to use `resolveFrame(src, options)` and read `options?.signal` and `options?.target`.
Migration Steps
- Update `resolveFrame(src, signal, target)` implementations to use `resolveFrame(src, options)` and read `options?.signal` and `options?.target`.
✨ New Features
- Added `frames` to the `app` object returned from `run()`, mirroring the existing `handle.frames` API.
- Added `@remix-run/ui/dev/refresh` for development tooling that needs to reconcile mounted roots after component modules update.
- Same-origin forms now progressively enhance into frame navigations when `run({ resolveFrame })` is configured. Native constraint validation runs before interception, submissions target the top frame by default, `rmx-target` selects a named frame, and `rmx-document` opts back into document navigation.
- Browser frame resolvers may now return a `Response`. Its body is streamed into the frame, and when a top-frame navigation follows a redirect, the final response URL replaces the current navigation entry and becomes the frame's canonical `src` without loading the frame a second time.
- Add an `rmx-history="push|replace"` attribute for anchors and forms that overrides the history behavior of enhanced frame navigations. Native anchors using `link(href, { history })` emit the corresponding attribute value automatically.
- Add an `rmx-preserve-dom` attribute that tells the DOM reconciler to preserve a matching element's current attributes and children during reloads, allowing client-owned subtrees such as custom elements to manage their own DOM.
- Allow element-wide mixins such as `css()` to be used on subtype hosts like `<select>` without TypeScript assignability errors.
- Built-in styled components now use adaptive `light-dark(...)` colors for their internal surfaces, text, borders, focus rings, and control states so they render correctly in dark color schemes.
- Escape less-than characters in server-rendered `css()` output so style values cannot terminate the generated `<style>` element.
🐛 Bug Fixes
- Fix hydrated component updates that could lose content when adding elements before existing content in a fragment.
- Prevent navigation and reloads from hanging when a nested `Frame` marker moves outside a frame region while the DOM is being updated.
- Preserve client entry and frame state only for live boundaries with matching semantic identities, while replacing pending client entry SSR during reloads and releasing temporary response metadata after hydration or cancellation.
- Prevent client-side document navigation and `Frame` updates from stalling after navigating between pages with different `Frame` layouts. A frame's end marker could be reused as the start marker of an incoming frame, which left the frame's region bounds and instance pointing at the wrong nodes.
- Preserve resolved client-created frame content when its parent rerenders while the frame is still pending (see #11659).
- Prevent document and frame reloads from dropping newly rendered sibling elements when client entries from the previous content are disposed.
- Reload frames rendered within preserved client entries during ancestor frame reloads.
- Show complete destination server-rendered client entry content during document and frame reloads while replacement modules load, instead of retaining only positionally matched source content.
- Fix top frame reloads using the previous URL after navigation targets a named frame.
Affected Symbols
`resolveFrame``app` object`handle.frames` API`@remix-run/ui/dev/refresh``run()``rmx-target``rmx-document``FormData``_method` conventions`rmx-history` attribute`link(href, { history })``rmx-preserve-dom` attribute`css()``<select>``light-dark(...)``<style>` element`Frame` markerclient entryframe statelive boundariesSSRhydrationresponse metadataFramesemantic identitiesclient-created frame contentancestor frame reloadsreplacement modulessource content