feat(CommandTextArea): add component#1222
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📦 NPM canary releaseDeployed canary version 0.0.0-canary-009d53f. |
🧪 Storybook is successfully deployed!
|
🏋️ Size limit report
Click here if you want to find out what is changed in this build |
| if (focused != null) { | ||
| e.preventDefault(); | ||
| commit(focused); | ||
| } |
There was a problem hiding this comment.
Stale focus commits wrong command
High Severity
While the popover stays open, narrowing the typed token does not update virtual focus when the highlighted key is no longer in the filtered list. Enter/Tab still commits that stale key via getItemTextValue, so the inserted command can disagree with the visible options (e.g. after / then adding h, Enter can insert /clear while only /help and /share match).
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 44be071. Configure here.
| const popoverRef = useCombinedRefs(propsPopoverRef); | ||
| const listBoxRef = useCombinedRefs(propsListBoxRef); | ||
| const listStateRef = (propsListStateRef ?? | ||
| useRef<ListStateLike | null>(null)) as RefObject<ListStateLike | null>; |
There was a problem hiding this comment.
Conditional useRef breaks hooks
High Severity
listStateRef is assigned with propsListStateRef ?? useRef(...), so useRef runs only when the optional listStateRef prop is omitted. If a parent later passes listStateRef (or removes it), the hook call order changes and React can throw or behave unpredictably.
Reviewed by Cursor Bugbot for commit 44be071. Configure here.
| // ---- trigger detection ------------------------------------------------ | ||
| const activeToken = useMemo( | ||
| () => parseActiveToken(effectiveValue, caret, triggers), | ||
| [effectiveValue, caret, triggers], |
There was a problem hiding this comment.
Caret stale after value updates
Medium Severity
Caret position lives in React state and is updated mainly via syncCaret on user events. When the textarea value is updated from outside (controlled mode or form reset), caret is not synced to the DOM selection, so parseActiveToken can use a stale index and open, hide, or parse the wrong command token.
Reviewed by Cursor Bugbot for commit 44be071. Configure here.
| return textFilterFn(node.textValue || '', term) ? node : null; | ||
| }) | ||
| .filter(Boolean); | ||
| return filterCollectionNodes(nodes, term, textFilterFn); |
There was a problem hiding this comment.
ComboBox filters non textValue fields
Medium Severity
ComboBox filtering now goes through filterCollectionNodes, which matches plain-text children and description as well as textValue. ComboBox documents filtering on textValue only, so options can appear or disappear based on description text that users cannot see in the input.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4fe7d81. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
There are 5 total unresolved issues (including 4 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 69b395f. Configure here.
| let { labelProps, inputProps } = useTextField( | ||
| { | ||
| ...otherProps, | ||
| value: effectiveValue, |
There was a problem hiding this comment.
defaultValue ignored on textarea
Medium Severity
Uncontrolled CommandTextArea always seeds and drives the field with effectiveValue starting at '', so a defaultValue from props (e.g. the Multiline story) never appears in the textarea or in trigger parsing until the user types.
Reviewed by Cursor Bugbot for commit 69b395f. Configure here.


Note
Medium Risk
ComboBox behavior is consolidated behind a shared popover module (regression surface), and CommandTextArea adds combobox ARIA and caret-positioning logic on a new public form control.
Overview
Adds
CommandTextArea, a multiline field that keeps focus in the textarea while showing aListBoxpopover when the caret sits on a configurable trigger token (default/at line start, or e.g.@after whitespace). Options filter ontextValue, plain-text children, and description; matches are highlighted in label and description. Picking an option replaces the active token with the item’stextValue(optional trailing space) and callsonCommand. The popover is caret-anchored viauseCaretAnchor/getCaretRect, with keyboard list navigation while open.Refactor: Extracts shared
ListBoxPopover(overlay, portal, virtual-focus list) pluslistNavigation/useCompositeFocusfromComboBox, which now consumes those modules instead of inline overlay code.Supporting tweaks:
Itemapplieshighlightto string descriptions;ListBoxgainsoptionHighlightwired through options and sections. Package export fromfields/index, plus Storybook docs, stories, and tests.Reviewed by Cursor Bugbot for commit 69b395f. Bugbot is set up for automated code reviews on this repo. Configure here.