Skip to content

fix(editor): single-letter tags in select/multi-select table cell#14808

Merged
darkskygit merged 3 commits intotoeverything:canaryfrom
aisharoslan:fix-select-single-letter
May 3, 2026
Merged

fix(editor): single-letter tags in select/multi-select table cell#14808
darkskygit merged 3 commits 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately and concisely describes the main change: fixing single-letter tag creation in select/multi-select table cells, which directly addresses the core issue resolved by this changeset.

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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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
@aisharoslan
Copy link
Copy Markdown
Contributor Author

aisharoslan commented Apr 22, 2026

Hi @darkskygit, would appreciate your review on this when you have a moment, as it's a highly-requested fix. Thanks!

@darkskygit darkskygit force-pushed the canary branch 5 times, most recently from 3403237 to 78a9942 Compare April 29, 2026 11:31
@aisharoslan aisharoslan changed the title fix(editor): Single-letter tags in Select/Multi-Select table cell fix(editor): single-letter tags in select/multi-select table cell May 3, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 3, 2026

Codecov Report

❌ Patch coverage is 27.58621% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.36%. Comparing base (7046ad7) to head (74d251e).
⚠️ Report is 9 commits behind head on canary.

Files with missing lines Patch % Lines
...a-view/src/core/component/tags/multi-tag-select.ts 16.66% 10 Missing ⚠️
...view/src/view-presets/table/pc-virtual/row/cell.ts 0.00% 5 Missing ⚠️
...affine/data-view/src/view-presets/table/pc/cell.ts 40.00% 3 Missing ⚠️
...src/property-presets/multi-select/cell-renderer.ts 0.00% 1 Missing ⚠️
...-view/src/property-presets/select/cell-renderer.ts 0.00% 1 Missing ⚠️
...e/affine/data-view/src/view-presets/table/utils.ts 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           canary   #14808      +/-   ##
==========================================
+ Coverage   47.43%   57.36%   +9.92%     
==========================================
  Files        3162     3166       +4     
  Lines      171118   172217    +1099     
  Branches    22694    25340    +2646     
==========================================
+ Hits        81176    98787   +17611     
+ Misses      86506    69964   -16542     
- Partials     3436     3466      +30     
Flag Coverage Δ
server-test 78.18% <ø> (+19.81%) ⬆️
unittest 34.45% <27.58%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@darkskygit darkskygit merged commit 5d234ad into toeverything:canary May 3, 2026
59 of 63 checks passed
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

2 participants