Browse Source

docs: add guidelines for using useId() with reactstrap target prop

Yuki Takei 1 day ago
parent
commit
cbe5efcf2d
1 changed files with 23 additions and 0 deletions
  1. 23 0
      apps/app/.claude/rules/ui-pitfalls.md

+ 23 - 0
apps/app/.claude/rules/ui-pitfalls.md

@@ -0,0 +1,23 @@
+# UI Pitfalls
+
+## useId() must not be passed to reactstrap `target` prop
+
+React's `useId()` generates IDs containing colons (`:r0:`, `:r1:`, `:r2:`). These are valid HTML `id` attributes but **invalid CSS selectors**.
+
+reactstrap's `findDOMElements()` resolves string targets via `document.querySelectorAll(target)`, which throws `DOMException: is not a valid selector` when the string contains colons.
+
+```tsx
+// ❌ WRONG: useId() output passed as string target
+const popoverTargetId = useId();
+<button id={popoverTargetId}>...</button>
+<Popover target={popoverTargetId} />  // → DOMException at componentDidMount
+
+// ✅ CORRECT: use ref — reactstrap resolves refs via .current, bypassing querySelectorAll
+const popoverTargetRef = useRef<HTMLButtonElement>(null);
+<button ref={popoverTargetRef}>...</button>
+<Popover target={popoverTargetRef} />
+```
+
+**Applies to all reactstrap components with a `target` prop**: `Popover`, `Tooltip`, `UncontrolledPopover`, `UncontrolledTooltip`, etc.
+
+**Safe uses of `useId()`**: `id=`, `htmlFor=`, `aria-labelledby=`, `aria-describedby=` — these use `getElementById` internally, which does not parse CSS.