Skip to content

fix(editor): Single-letter tags in Select/Multi-Select table cell#14808

Open
aisharoslan wants to merge 1 commit intotoeverything:canaryfrom
aisharoslan:fix-select-single-letter
Open

fix(editor): Single-letter tags in Select/Multi-Select table cell#14808
aisharoslan wants to merge 1 commit intotoeverything:canaryfrom
aisharoslan:fix-select-single-letter

Conversation

@aisharoslan
Copy link
Copy Markdown
Contributor

@aisharoslan aisharoslan commented Apr 8, 2026

Summary of Changes

Resolves #14715 and #14280.

When a user types into a Select/Multi-Select table cell to create/choose a tag, that character is stashed on the cell container (setTagDraft) instead of going through valueSetFromString. Opening the tag picker reads it via consumeTagDraftFromTableCellHost.

Verification

  • Added unit test to check that single-character input doesn't immediately call valueSetFromString.
Screen.Recording.2026-04-08.at.4.35.06.PM.mov

Summary by CodeRabbit

  • New Features

    • Tag selection popups now initialize with draft text from keypresses in tag columns, improving user experience when editing tags.
  • Tests

    • Added comprehensive hotkey tests for single-select and multi-select tag column behavior.

@aisharoslan aisharoslan requested a review from a team as a code owner April 8, 2026 20:29
@github-actions github-actions bot added the test Related to test cases label Apr 8, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

This PR fixes a bug where typing a character in multi-select/select fields creates a new option instead of filtering existing ones. The solution introduces tag draft management: character input is now captured and passed as initial draft text to the tag selection popup, enabling search/filter behavior instead of immediate option creation.

Changes

Cohort / File(s) Summary
Test Updates
blocksuite/affine/data-view/src/__tests__/hotkeys.unit.spec.ts
Added parameterized tests for TableHotkeysController and VirtualHotkeysController verifying that character input on select/multi-select columns calls setTagDraft() instead of valueSetFromString().
Draft State Infrastructure
blocksuite/affine/data-view/src/core/component/tags/multi-tag-select.ts
Added initialDraftText property to MultiTagSelect and TagManagerOptions; implemented connectedCallback() to initialize draft text on component connection; exported consumeTagDraftFromTableCellHost() helper for retrieving draft text from table cell hosts.
Cell Container Draft Management
blocksuite/affine/data-view/src/view-presets/table/pc/cell.ts, blocksuite/affine/data-view/src/view-presets/table/pc-virtual/row/cell.ts
Added private _tagDraft field and public setTagDraft() / consumeTagDraft() methods to both TableViewCellContainer and DatabaseCellContainer for managing single-use draft state.
Cell Renderer Draft Integration
blocksuite/affine/data-view/src/property-presets/multi-select/cell-renderer.ts, blocksuite/affine/data-view/src/property-presets/select/cell-renderer.ts
Modified popup creation to retrieve draft text via consumeTagDraftFromTableCellHost() and pass it to popTagSelect() via the new initialDraftText option.
Event Routing Logic
blocksuite/affine/data-view/src/view-presets/table/utils.ts
Modified handleCharStartEdit() to branch based on column type: for select/multi-select columns, routes character input to cell.setTagDraft() instead of column.valueSetFromString(). Updated ColumnAccessor return type to always include type$ readonly signal.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR successfully implements the fix for issue #14715 by stashing single-character input via setTagDraft instead of immediately calling valueSetFromString, enabling the tag picker to handle the character on popup open.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the single-letter tag draft feature: hotkey tests, tag draft storage, consumption helpers, and routing logic in table cells and utilities.
Title check ✅ Passed The PR title 'fix(editor): Single-letter tags in Select/Multi-Select table cell' directly and clearly describes the main change: addressing single-character input handling in tag selection cells by preventing immediate option creation.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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


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.

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.

🧹 Nitpick comments (2)
blocksuite/affine/data-view/src/__tests__/hotkeys.unit.spec.ts (1)

99-132: Nice coverage addition; consider asserting preventDefault in tag-column cases too.

You already verify preventDefault in the normal char-start tests. Adding it in these new parameterized tag-column tests would lock behavior parity and prevent regressions.

✅ Suggested test strengthening
       logic.keyDown({ get: () => ({ raw: evt }) });
       expect(cell.column.valueSetFromString).not.toHaveBeenCalled();
       expect(setTagDraft).toHaveBeenCalledWith('C');
       expect(selectionController.selection.isEditing).toBe(true);
+      expect(evt.preventDefault).toHaveBeenCalled();
       logic.keyDown({ get: () => ({ raw: evt }) });
       expect(cell.column$.value.valueSetFromString).not.toHaveBeenCalled();
       expect(setTagDraft).toHaveBeenCalledWith('C');
       expect(selectionController.selection.isEditing).toBe(true);
+      expect(evt.preventDefault).toHaveBeenCalled();

Also applies to: 171-206

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

In `@blocksuite/affine/data-view/src/__tests__/hotkeys.unit.spec.ts` around lines
99 - 132, The new parameterized test for tag columns currently omits asserting
that the keyboard event's preventDefault() was called; update the test in
hotkeys.unit.spec.ts (the case using TableHotkeysController,
selectionController.getCellContainer returning cell with setTagDraft, and
logic.keyDown({ get: () => ({ raw: evt }) })) to also expect evt.preventDefault
toHaveBeenCalled(), mirroring the normal char-start tests and ensuring
preventDefault behavior is locked for tag-column flows where setTagDraft is
used.
blocksuite/affine/data-view/src/view-presets/table/pc/cell.ts (1)

49-59: Optional: extract shared tag-draft host behavior to avoid drift.

This implementation is mirrored in blocksuite/affine/data-view/src/view-presets/table/pc-virtual/row/cell.ts (Line 185-195). Consider centralizing this tiny behavior (mixin/helper/interface utility) so both hosts stay consistent as the draft lifecycle evolves.

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

In `@blocksuite/affine/data-view/src/view-presets/table/pc/cell.ts` around lines
49 - 59, The tag-draft lifecycle (_tagDraft, setTagDraft, consumeTagDraft) is
duplicated between cell.ts and pc-virtual/row/cell.ts; extract this into a
shared utility (e.g., a TagDraftHost interface plus a TagDraftMixin or helper
functions) and replace the per-file fields/methods with calls to that shared
implementation so both hosts delegate to the same logic; ensure the shared API
exposes setTagDraft(value: string), consumeTagDraft(): string | undefined and an
internal storage name consistent with _tagDraft to avoid behavioral drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@blocksuite/affine/data-view/src/__tests__/hotkeys.unit.spec.ts`:
- Around line 99-132: The new parameterized test for tag columns currently omits
asserting that the keyboard event's preventDefault() was called; update the test
in hotkeys.unit.spec.ts (the case using TableHotkeysController,
selectionController.getCellContainer returning cell with setTagDraft, and
logic.keyDown({ get: () => ({ raw: evt }) })) to also expect evt.preventDefault
toHaveBeenCalled(), mirroring the normal char-start tests and ensuring
preventDefault behavior is locked for tag-column flows where setTagDraft is
used.

In `@blocksuite/affine/data-view/src/view-presets/table/pc/cell.ts`:
- Around line 49-59: The tag-draft lifecycle (_tagDraft, setTagDraft,
consumeTagDraft) is duplicated between cell.ts and pc-virtual/row/cell.ts;
extract this into a shared utility (e.g., a TagDraftHost interface plus a
TagDraftMixin or helper functions) and replace the per-file fields/methods with
calls to that shared implementation so both hosts delegate to the same logic;
ensure the shared API exposes setTagDraft(value: string), consumeTagDraft():
string | undefined and an internal storage name consistent with _tagDraft to
avoid behavioral drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5a25c76e-9738-43ec-8111-65097dde75dc

📥 Commits

Reviewing files that changed from the base of the PR and between 156cfc7 and ebe4397.

📒 Files selected for processing (7)
  • blocksuite/affine/data-view/src/__tests__/hotkeys.unit.spec.ts
  • blocksuite/affine/data-view/src/core/component/tags/multi-tag-select.ts
  • blocksuite/affine/data-view/src/property-presets/multi-select/cell-renderer.ts
  • blocksuite/affine/data-view/src/property-presets/select/cell-renderer.ts
  • blocksuite/affine/data-view/src/view-presets/table/pc-virtual/row/cell.ts
  • blocksuite/affine/data-view/src/view-presets/table/pc/cell.ts
  • blocksuite/affine/data-view/src/view-presets/table/utils.ts

@aisharoslan aisharoslan changed the title fix(editor): Single-letter option in Select/Multi-Select fix(editor): Single-letter tags in Select/Multi-Select Apr 8, 2026
@aisharoslan aisharoslan changed the title fix(editor): Single-letter tags in Select/Multi-Select fix(editor): Single-letter tags in Select/Multi-Select table cell Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test Related to test cases

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

[Bug]: When writing in multi-select field the first letter creates new option

1 participant