Skip to content

patch: general improvements and fixes#993

Merged
davedbase merged 4 commits into
solidjs-community:nextfrom
davedbase:patch/kobalte-primitive-improvements
Jul 20, 2026
Merged

patch: general improvements and fixes#993
davedbase merged 4 commits into
solidjs-community:nextfrom
davedbase:patch/kobalte-primitive-improvements

Conversation

@davedbase

@davedbase davedbase commented Jul 18, 2026

Copy link
Copy Markdown
Member

This PR is derived from some research and comments that came out of a HopeUI document I stumbled on: https://github.com/hope-ui/hope-ui/blob/main/docs/solid-primitives-eval.md. These were not reported but to be proactive in fixing details I've attempted exploring the issues and correcting them.

Responds to hope-ui's solid-primitives-eval.md, which flagged a suspected "transform-boundary hydration hazard" in createSignal(fn)/createMemo-backed primitives. Traced actual solid-js@2.0.0-beta.20/@solidjs/signals internals and built a real server-render→hydrate round-trip test harness (spawns a genuine node subprocess so the package under test resolves its published dist build, not workspace src) to prove/disprove it empirically rather than by inspection alone. Result: the pattern hydrates cleanly across controlled-signal, a11y, pagination, and state-machine — evidence points at hope-ui's own non-standard SSR harness, not a general solid-primitives/solid-js defect.

Along the way, found and fixed real bugs via an 8-angle self-review of the diff:

  • interaction: opt-in inert option on createHideOutside/ariaHideOutside, ref-counted alongside aria-hidden. Fixed a bug where inert was applied even to nodes deliberately left alone because they already carry an author-managed aria-hidden — broke that "not ours to manage" invariant.
  • focus: new standalone createFocusRestore primitive (restore focus without trapping, for non-modal Popover/Tooltip). Fixed a stale-closure race shared with createFocusTrap — a fast reactivate-before-restore-fires cycle could restore focus to the wrong element — via one shared scheduleFocusRestore helper instead of two copies of the same bug.
  • scroll + interaction: module-scope ref-count/observer state hardened against duplicate installed package copies via a new shared globalRegistry() helper in @solid-primitives/utils (also fixed an instance-id collision the extraction would otherwise have introduced).
  • a11y: createFormControl's dataset converted from createMemo to a plain getter — removes a hydration-id-consuming call for a value cheap enough that memoizing it buys nothing.
  • Hydration harness: dead import removed, console-patch timing fixed so it no longer misses async/deferred hydration-mismatch warnings (this surfaced a real stale-dist-build false positive during development, now documented as a known footgun), reentrancy guard, and caching so repeated fixtures don't re-spawn subprocesses.
  • Removed a duplicate contains() helper in scroll in favor of the existing one in @solid-primitives/utils.

The only new public export across all of this is globalRegistry in @solid-primitives/utils — everything else is internal refactoring or bug fixes with no signature changes.

Some additional adjustments were added:

notification**'s createNotificationPermission.requestPermissiongainedaffects(permission)soisPending(permission)now works for callers who want the standard idiom, alongside the existingpending` accessor (kept for backward compatibility — pure addition, no breaking change).

clipboard — I initially added the same pattern, but discovered through direct experimentation that affects() only holds its pending mark for a single flush cycle unless it's called inside a real action() generator. Clipboard's write is a plain async function, so the fix would have looked adopted but silently done nothing across the real async gap. I reverted it rather than ship something ineffective. This constraint isn't clearly documented anywhere, so I wrote it up in project memory.

controlled-props**'s BoolProp/NumberProp/RangeProp/StringPropretyped fromComponent

toVoidComponent

`, since none of them accept or render children.

All four packages pass their full test suites and typecheck cleanly, each fix verified by reverting it and confirming the corresponding test fails, then restoring.

Also a number of banner comments were removed

@davedbase davedbase added this to the Solid 2.0 Migration milestone Jul 18, 2026
@davedbase davedbase added bug Something isn't working enhancement New feature or request labels Jul 18, 2026
@changeset-bot

changeset-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b7ef2f3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@solid-primitives/a11y Patch
@solid-primitives/controlled-props Patch
@solid-primitives/focus Minor
@solid-primitives/interaction Minor
@solid-primitives/intersection-observer Patch
@solid-primitives/notification Patch
@solid-primitives/scroll Patch
@solid-primitives/utils Minor
@solid-primitives/spring Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@davedbase
davedbase changed the base branch from main to next July 18, 2026 19:35
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0124ec9-54f2-41e9-bcbf-b5e759d59e94

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@davedbase davedbase changed the title patch: hydration improvements and fixes patch: general improvements and fixes Jul 20, 2026
@davedbase
davedbase merged commit 4069e23 into solidjs-community:next Jul 20, 2026
2 of 3 checks passed
@davedbase
davedbase deleted the patch/kobalte-primitive-improvements branch July 20, 2026 01:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant