Skip to content

Queryselector to refs#1737

Merged
kotAPI merged 8 commits intomainfrom
queryselector-to-refs
Apr 4, 2026
Merged

Queryselector to refs#1737
kotAPI merged 8 commits intomainfrom
queryselector-to-refs

Conversation

@GoldGroove06
Copy link
Copy Markdown
Collaborator

@GoldGroove06 GoldGroove06 commented Apr 4, 2026

closes #1727

Summary by CodeRabbit

  • Refactor

    • Replaced fragile DOM-query patterns with instance-scoped refs across tree, slider, roving-focus, and navigation components for more reliable keyboard navigation, focus behavior, and drag interactions.
    • Improved lifecycle registration/unregistration to reduce cross-component interference, hydration/test fragility, and stale-element issues.
  • Documentation

    • Added a comprehensive guide with failure modes, priority recommendations, ref-based solutions, examples, and refactoring guidance.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 4, 2026

🦋 Changeset detected

Latest commit: 1020489

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

This PR includes changesets to release 1 package
Name Type
@radui/ui Minor

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 851fdeaf-9f2c-456b-aa45-66be096c1fe8

📥 Commits

Reviewing files that changed from the base of the PR and between e14d33c and ff6dd2c.

📒 Files selected for processing (1)
  • knowledge/good_practices/index.md
✅ Files skipped from review due to trivial changes (1)
  • knowledge/good_practices/index.md

📝 Walkthrough

Walkthrough

Migrates imperative DOM lookups (querySelector*/querySelectorAll) to React ref registries across RovingFocusGroup, Tree, Slider, and NavigationMenu; components now register element refs in context and resolve focus/interaction targets from those registries instead of global selectors.

Changes

Cohort / File(s) Summary
Documentation & Metadata
knowledge/querySelector-to-refs/components-analysis.md, .changeset/chatty-showers-repeat.md
Added a detailed migration guide and a changeset marking the minor release describing querySelector→refs migration.
Navigation Menu
src/components/ui/NavigationMenu/fragments/NavigationMenuContent.tsx
Removed an imperative effect that queried/focused the first focusable element; now relies on RovingFocusGroup for focus.
Slider Context & Fragments
src/components/ui/Slider/context/SliderContext.tsx, src/components/ui/Slider/fragments/SliderRoot.tsx, src/components/ui/Slider/fragments/SliderThumb.tsx, src/components/ui/Slider/fragments/SliderRangeSlider.tsx
Added rootRef, thumbRefs, and registerThumbRef to SliderContext; SliderRoot manages thumb registry and focuses registered thumbs; SliderRangeSlider uses rootRef instead of document.querySelector; SliderThumb registers its ref and merges forwarded refs.
Tree Context & Fragments
src/components/ui/Tree/contexts/TreeContext.tsx, src/components/ui/Tree/fragments/TreeRoot.tsx, src/components/ui/Tree/fragments/TreeItem.tsx
Introduced itemRefs Map and register/unregister callbacks in TreeContext; TreeRoot exposes registry; TreeItem registers its button ref, removes DOM-traversal lookups, and uses context refs for parent/child focus (adds onChildRefReady prop).
RovingFocusGroup Context & Fragments
src/core/utils/RovingFocusGroup/context/RovingFocusGroupContext.tsx, src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx, src/core/utils/RovingFocusGroup/fragments/RovingFocusItem.tsx
Extended context with itemRefs and register/unregister functions; RovingFocusGroup computes focusable items from the registry (tree mode) sorted by document order; RovingFocusItem registers per-item refs and resolves navigation targets via the registry instead of groupRef DOM queries.
Best-practice Guidance
knowledge/good_practices/index.md
Added guidance advising against querySelector usage in components and recommending refs for instance-scoped DOM access.

Sequence Diagram(s)

sequenceDiagram
  participant TreeItem as "TreeItem\n(creates ref)"
  participant TreeRoot as "TreeRoot\n(context)"
  participant Roving as "RovingFocusGroup\n(context)"
  participant User as "User\n(key/navigation)"
  rect rgba(200,230,255,0.5)
    TreeItem->>TreeRoot: registerItemRef(id, ref)
    TreeRoot->>Roving: expose itemRefs via context
    Roving->>Roving: recompute focusItems from itemRefs (sort by document order)
  end
  rect rgba(220,255,220,0.5)
    User->>Roving: key navigation (e.g., ArrowDown)
    Roving->>Roving: determine target id from focusItems
    Roving->>TreeItem: itemRefs.get(id).current.focus()
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related issues

  • #1727: [New Feature] Use refs globally, without querySelectors — This PR implements replacing querySelector-based lookups with ref-based registries as requested.
  • #1315: Migrating Tree/RovingFocusGroup to ref-based focus management — changes here match the refactor suggested in that issue.

Possibly related PRs

  • rad-ui/ui#1720: Adds/uses mergeRefs utility referenced by SliderThumb and RovingFocusItem ref-forwarding changes.
  • rad-ui/ui#1675: Similar Slider ref/thumb wiring and multi-thumb support modifications that align with this PR's slider changes.
  • rad-ui/ui#1108: Moves DOM access into context-provided refs in other components — same pattern used here.

Suggested labels

automerge

Suggested reviewers

  • kotAPI

Poem

🐰 I hopped from queries old and gray,
Left global selectors far away,
Now refs are nested, neat, and bright,
Each item knows its own true light,
Focus hops home — a rabbit's delight. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main change: converting querySelector calls to refs throughout the codebase, which is the primary objective of the pull request.
Linked Issues check ✅ Passed The PR fully addresses issue #1727 by systematically replacing querySelector with refs in multiple components (NavigationMenu, Slider, Tree, RovingFocusGroup) and documenting the patterns.
Out of Scope Changes check ✅ Passed All changes directly support the querySelector-to-refs migration: component refactoring, context updates, documentation, and a changeset entry. No out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch queryselector-to-refs

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 and usage tips.

@@ -0,0 +1,264 @@
# Components Using querySelector That Can Be Replaced with Refs
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let this file just be a rule of why we should use refs instead of dom queries, these will go out of date and don't really help us in the long run

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -0,0 +1,161 @@
# querySelector to Refs Refactoring - Complete

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just use one file, we can delete this

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/ui/Tree/fragments/TreeItem.tsx (1)

145-160: ⚠️ Potential issue | 🟠 Major

Don't use item.label as the React key for children — provide a persistent unique identifier.

Line 155 keys children by subItem.label, but labels are not reliable React keys if they're non-unique or mutable. With the ref registry keyed by instance identity (useId), a label collision or change will cause React to reuse the wrong TreeItem component, breaking the ref lookups in focus management (e.g., line 79 when collapsing to find the parent ref). If tree items don't have a built-in unique ID, add one to the data model or construct a stable key from multiple fields.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/ui/Tree/fragments/TreeItem.tsx` around lines 145 - 160, The
children are keyed by mutable/non-unique subItem.label which breaks component
identity and ref lookups (affecting TreeItem, handleFirstChildRef and
collapse/focus logic); change the key on the mapped TreeItem to a stable unique
identifier (prefer an explicit id property like subItem.id) and fall back to a
deterministic composite key if no id exists (for example combine the parent's id
and the child index or another immutable field) so React preserves instance
identity for the ref registry and focus management.
🧹 Nitpick comments (1)
src/components/ui/Slider/fragments/SliderThumb.tsx (1)

22-36: Register the thumb ref during commit instead of in useEffect.

SliderRoot accesses thumbRefsArray.current[0] synchronously on the initial pointerdown event to focus the first thumb in single-value mode. With the current code, this registry is populated only after useEffect runs (post-paint). Moving the registration into the mergedRef callback ensures the thumb is available during the commit phase, before any user interaction can occur.

♻️ Suggested change
     const mergedRef = React.useMemo(() => {
         return (node: HTMLDivElement | null) => {
             (thumbRef as any).current = node;
+            if (registerThumbRef && node) {
+                registerThumbRef(index, thumbRef);
+            }
             if (typeof ref === 'function') ref(node);
             else if (ref) (ref as any).current = node;
         };
-    }, [ref]);
-    
-    // Register this thumb ref with the slider root
-    React.useEffect(() => {
-        if (registerThumbRef && thumbRef.current) {
-            registerThumbRef(index, thumbRef);
-        }
-    }, [index, registerThumbRef]);
+    }, [index, ref, registerThumbRef]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/ui/Slider/fragments/SliderThumb.tsx` around lines 22 - 36, The
thumb registration must happen during commit, not in useEffect: move the
registerThumbRef(index, thumbRef) call into the mergedRef callback so the slider
root sees thumbRefsArray synchronously; update the mergedRef function (currently
setting (thumbRef as any).current and forwarding ref) to also call
registerThumbRef(index, thumbRef) when thumbRef becomes non-null, and remove the
separate React.useEffect that registers the thumb; keep references to mergedRef,
thumbRef, registerThumbRef and index when making this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@knowledge/querySelector-to-refs/refactoring-summary.md`:
- Around line 126-159: Update the "Remaining Work" and "Known Issues" sections
in refactoring-summary.md to match the completed refactor: remove or mark
resolved the entries for RovingFocusItem.tsx, RovingFocusGroup.tsx, and
NavigationMenuContent.tsx (or explicitly scope the doc to the earlier
tree/slider phase if you want to keep historical notes), change the Portal
Components note to reflect that theme container lookup now uses ThemeContext
refs only, and resolve the "Vertical Slider Visual Inversion" entry by adding
the investigation outcome (tested on main branch and whether it was
pre-existing, CSS-related, or a calculation bug) plus any follow-up action.

In `@src/components/ui/NavigationMenu/fragments/NavigationMenuContent.tsx`:
- Around line 21-22: Restore an explicit "focus-on-open" step that runs when the
menu's open state becomes true, but drive it through the roving-focus registry
instead of using querySelector; in practice, add an effect that watches the menu
open prop and the RovingFocusGroup's focusedItemId and calls the
RovingFocusGroup/RovingFocusItem registry focus helper (use the component ref or
registry API exposed by RovingFocusGroup — e.g.,
rovingGroupRef.focus(focusedItemId) or a focusFirst() helper) to move DOM focus
into the content when opened, rather than invoking element.querySelector(...).
Ensure the effect uses the existing RovingFocusGroup ref/registry and cleans up
appropriately.

In `@src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx`:
- Around line 62-75: The tree-mode focus list currently uses
Array.from(itemRefsMap.current.keys()) which preserves registration order and
causes focus order to drift; update addFocusItem (and unregisterItemRef) so that
when SHOULD_RECOMPUTE_FOCUS_ITEMS is true you derive focusItems from the current
visible DOM order instead of insertion order: iterate over the rendered
container (e.g., querySelectorAll for focusable item elements or map
itemRefsMap.current to existing DOM nodes and sort by compareDocumentPosition)
to build the ordered array, call setFocusItems with that ordered list, and
ensure unregisterItemRef also removes the id from focusItems via setFocusItems
to avoid leaving stale IDs. Use the existing symbols itemRefsMap, addFocusItem,
unregisterItemRef, setFocusItems, and SHOULD_RECOMPUTE_FOCUS_ITEMS to locate
where to apply these changes.

---

Outside diff comments:
In `@src/components/ui/Tree/fragments/TreeItem.tsx`:
- Around line 145-160: The children are keyed by mutable/non-unique
subItem.label which breaks component identity and ref lookups (affecting
TreeItem, handleFirstChildRef and collapse/focus logic); change the key on the
mapped TreeItem to a stable unique identifier (prefer an explicit id property
like subItem.id) and fall back to a deterministic composite key if no id exists
(for example combine the parent's id and the child index or another immutable
field) so React preserves instance identity for the ref registry and focus
management.

---

Nitpick comments:
In `@src/components/ui/Slider/fragments/SliderThumb.tsx`:
- Around line 22-36: The thumb registration must happen during commit, not in
useEffect: move the registerThumbRef(index, thumbRef) call into the mergedRef
callback so the slider root sees thumbRefsArray synchronously; update the
mergedRef function (currently setting (thumbRef as any).current and forwarding
ref) to also call registerThumbRef(index, thumbRef) when thumbRef becomes
non-null, and remove the separate React.useEffect that registers the thumb; keep
references to mergedRef, thumbRef, registerThumbRef and index when making this
change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ad6f4be-6543-4011-a675-c3bccb6a3153

📥 Commits

Reviewing files that changed from the base of the PR and between 6a8df80 and 580294f.

📒 Files selected for processing (14)
  • knowledge/querySelector-to-refs/components-analysis.md
  • knowledge/querySelector-to-refs/refactoring-complete.md
  • knowledge/querySelector-to-refs/refactoring-summary.md
  • src/components/ui/NavigationMenu/fragments/NavigationMenuContent.tsx
  • src/components/ui/Slider/context/SliderContext.tsx
  • src/components/ui/Slider/fragments/SliderRangeSlider.tsx
  • src/components/ui/Slider/fragments/SliderRoot.tsx
  • src/components/ui/Slider/fragments/SliderThumb.tsx
  • src/components/ui/Tree/contexts/TreeContext.tsx
  • src/components/ui/Tree/fragments/TreeItem.tsx
  • src/components/ui/Tree/fragments/TreeRoot.tsx
  • src/core/utils/RovingFocusGroup/context/RovingFocusGroupContext.tsx
  • src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx
  • src/core/utils/RovingFocusGroup/fragments/RovingFocusItem.tsx

Comment thread knowledge/querySelector-to-refs/refactoring-summary.md Outdated
Comment on lines +21 to +22
// RovingFocusGroup automatically handles focus management
// No need for manual querySelector and focus
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Opening the menu no longer moves DOM focus into the content.

RovingFocusGroup only initializes focusedItemId; the actual .focus() call still happens later from RovingFocusItem navigation helpers. After removing the old effect, opening the menu leaves focus on the trigger/body, so keyboard users can’t start interacting with the content immediately. Keep an explicit focus-on-open step, but drive it through the roving-focus ref registry instead of querySelector.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/ui/NavigationMenu/fragments/NavigationMenuContent.tsx` around
lines 21 - 22, Restore an explicit "focus-on-open" step that runs when the
menu's open state becomes true, but drive it through the roving-focus registry
instead of using querySelector; in practice, add an effect that watches the menu
open prop and the RovingFocusGroup's focusedItemId and calls the
RovingFocusGroup/RovingFocusItem registry focus helper (use the component ref or
registry API exposed by RovingFocusGroup — e.g.,
rovingGroupRef.focus(focusedItemId) or a focusFirst() helper) to move DOM focus
into the content when opened, rather than invoking element.querySelector(...).
Ensure the effect uses the existing RovingFocusGroup ref/registry and cleans up
appropriately.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIP very early comp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GoldGroove06, understood — thanks for the heads-up! I'll leave this comment open as a reminder. When you're ready to finalize this component, the key thing to address is restoring an explicit focus-on-open step (without reverting to querySelector) — for example, by exposing a focusFirst() helper or similar API from RovingFocusGroup and calling it in an effect that watches itemOpen. Happy to help work through the implementation when you get there. 🐇


🧠 Learnings used
Learnt from: GoldGroove06
Repo: rad-ui/ui PR: 1215
File: src/core/primitives/CheckboxGroup/fragments/CheckboxGroupPrimitiveTrigger.tsx:25-27
Timestamp: 2025-07-18T16:43:26.175Z
Learning: In the CheckboxGroupPrimitiveTrigger component (`src/core/primitives/CheckboxGroup/fragments/CheckboxGroupPrimitiveTrigger.tsx`), the component uses two separate useEffect hooks with different purposes: the first useEffect (lines 25-27) with empty dependency array `[]` is meant to set the initial state only once on mount by syncing with the group's checked values, while the second useEffect (lines 28-34) handles ongoing state updates by propagating local `isChecked` changes back to the group's `checkedValues`. This pattern prevents infinite loops while maintaining proper synchronization.

Learnt from: decipher-cs
Repo: rad-ui/ui PR: 417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.

Comment thread src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx Outdated
Comment thread src/core/utils/RovingFocusGroup/fragments/RovingFocusItem.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx`:
- Around line 62-69: unregisterItemRef currently removes the id from itemRefsMap
and focusItems but doesn't clear the provider's focusedItemId, leaving a
dangling focus target; update the unregisterItemRef callback to also check the
current focusedItemId and, if it equals the unregistered id, call the focused-id
setter (e.g. setFocusedItemId(null) or setFocusedItemId(undefined) as used in
this module) to clear it, while retaining the existing removal of focusItems and
respecting SHOULD_RECOMPUTE_FOCUS_ITEMS.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 19f0a632-65dc-4004-97ce-69a98fab80a3

📥 Commits

Reviewing files that changed from the base of the PR and between 580294f and e14d33c.

📒 Files selected for processing (5)
  • .changeset/chatty-showers-repeat.md
  • knowledge/querySelector-to-refs/components-analysis.md
  • src/components/ui/Slider/fragments/SliderThumb.tsx
  • src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx
  • src/core/utils/RovingFocusGroup/fragments/RovingFocusItem.tsx
✅ Files skipped from review due to trivial changes (3)
  • .changeset/chatty-showers-repeat.md
  • src/core/utils/RovingFocusGroup/fragments/RovingFocusItem.tsx
  • knowledge/querySelector-to-refs/components-analysis.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/ui/Slider/fragments/SliderThumb.tsx

Comment on lines +62 to +69
const unregisterItemRef = React.useCallback((id: string) => {
itemRefsMap.current.delete(id);

// Remove from focusItems to avoid stale IDs
if (SHOULD_RECOMPUTE_FOCUS_ITEMS) {
setFocusItems((prev) => prev.filter((itemId) => itemId !== id));
}
}, [SHOULD_RECOMPUTE_FOCUS_ITEMS]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Clear focusedItemId when the active item unregisters.

Lines 65-68 prune focusItems, but the provider can still point at the removed id. That leaves the group without a valid roving target after a focused item is collapsed or unmounted.

💡 Proposed fix
 const unregisterItemRef = React.useCallback((id: string) => {
     itemRefsMap.current.delete(id);
+    setFocusedItemId((prev) => (prev === id ? null : prev));
         
     // Remove from focusItems to avoid stale IDs
     if (SHOULD_RECOMPUTE_FOCUS_ITEMS) {
         setFocusItems((prev) => prev.filter((itemId) => itemId !== id));
     }
 }, [SHOULD_RECOMPUTE_FOCUS_ITEMS]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx` around lines
62 - 69, unregisterItemRef currently removes the id from itemRefsMap and
focusItems but doesn't clear the provider's focusedItemId, leaving a dangling
focus target; update the unregisterItemRef callback to also check the current
focusedItemId and, if it equals the unregistered id, call the focused-id setter
(e.g. setFocusedItemId(null) or setFocusedItemId(undefined) as used in this
module) to clear it, while retaining the existing removal of focusItems and
respecting SHOULD_RECOMPUTE_FOCUS_ITEMS.

@kotAPI kotAPI requested a review from Copilot April 4, 2026 15:26
@kotAPI kotAPI review requested due to automatic review settings April 4, 2026 15:27
@kotAPI kotAPI added the automerge A tag that tells kodiak bot to automerge PRs for us when tests and approval conditions are met label Apr 4, 2026
@kotAPI kotAPI merged commit d2c5395 into main Apr 4, 2026
8 checks passed
@kotAPI kotAPI deleted the queryselector-to-refs branch April 4, 2026 16:01
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 4, 2026

Coverage

This report compares the PR with the base branch. "Δ" shows how the PR affects each metric.

Metric PR Δ
Statements 81.46% +0.18%
Branches 64.2% -0.04%
Functions 69.65% +0.11%
Lines 82.82% +0.20%

Coverage decreased for at least one metric. Please add or update tests to improve coverage.

Run npm run coverage locally for detailed reports and target untested areas to raise these numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge A tag that tells kodiak bot to automerge PRs for us when tests and approval conditions are met

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[New Feature] Use refs globally, without querySelectors

2 participants