Skip to content

[lexical-table] Bug Fix: Cover a tapped empty table cell on iOS so a double tap cannot select past it - #9350

Open
SujinKim1127 wants to merge 19 commits into
meta:mainfrom
SujinKim1127:fix/ios-table-cell-editing-host
Open

SujinKim1127 wants to merge 19 commits into
meta:mainfrom
SujinKim1127:fix/ios-table-cell-editing-host

Conversation

@SujinKim1127

@SujinKim1127 SujinKim1127 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Description

On iOS, double tapping an empty table cell makes WebKit select back to the nearest preceding word, which lies outside the table. #9267 restores the caret after selectionchange, but iOS paints the native highlight before the page is notified, so the preceding content still flashes on every double tap (#9347). The second tap dispatches no cancelable event, and page CSS does not affect the highlight.

This PR first gave every cell its own editing host. Following review, it now uses a much smaller overlay instead; the wrapper, the empty-cell Backspace guard, and the window blur / touch marker changes are reverted.

Empty cell overlay (LexicalTableIOSEmptyCellOverlay.ts)

  • A touch tap in an empty cell covers that cell for 500ms with an unmanaged contenteditable="false" overlay. A second tap in that window lands on the overlay instead of editable text, so iOS does not start a word selection, and the overlay places the caret in the cell.
  • The cell is covered on the tap's pointerup, after a short, still touch. When the cell already holds the caret, iOS withholds that tap's pointerup until it knows whether a second tap follows, so that cell is covered on pointerdown instead.
  • Outside the window nothing covers the cell, so long press and long press drag keep working. A drag or long press elsewhere, and a touch iOS takes over (pointercancel), never adds it.
  • The overlay goes away when the window ends, another cell is tapped, or the cell gets content, and the cell's inline position is restored with it.
  • TableCellNode.getDOMSlot keeps the cell's children before the overlay with withBefore, so DOM child offsets still match the node's children. The overlay is never part of createDOM, so exported HTML is unchanged.

Drag caret (LexicalTableIOSDragCaret.ts)

  • During a long press drag across cells, iOS keeps moving the native caret while the table selection keeps clearing it, so it flickers.
  • The root's caret-color is made transparent while a finger is down on a cell, and restored (to any previous inline value) when the last finger lifts.
  • This reduces the flicker but does not remove it: the caret iOS draws around its magnifier is not affected by caret-color. I'm happy to split this into its own PR if you'd prefer.

Both are registered from registerTableSelectionObserver on iOS only. In LexicalTableSelectionHelpers, the #9267 repair now uses the shared $isCellEmpty (LexicalTableUtils) for its empty cell check, and TAP_SLOP moved to constants so the overlay can share it; neither changes behavior. Non-iOS behavior and DOM are unchanged.

Closes #9347

Test plan

IosEmptyCellOverlay.test.ts and IosTableDragCaret.test.ts mock IS_IOS.

Before

ScreenRecording_10-12-2026.16-51-09_1.mov

On an iPhone (iOS Safari) with the playground: double tapping an empty cell flashes the cells above and the end of the paragraph above the table. A long press drag across cells starting from an empty cell paints the cells with the caret flickering throughout.

With the lexical-table sources at main:

$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts packages/lexical-table/src/__tests__/unit/IosTableDragCaret.test.ts
     × hides the caret while a finger is down on a cell
     × keeps hiding until the last finger lifts
     × restores a caret-color that was already set
     × a touch tap in an empty cell covers it for the double-tap window
     × restores the cell position when the overlay goes away
     × a touch on the cell holding the caret covers it on pointerdown
     × only the most recently tapped cell is covered
     × a second tap on the overlay places the caret in its cell
     × keeps managed children before the overlay and drops it once the cell has text
      Tests  9 failed | 9 passed (18)

After

ScreenRecording_10-23-2026.15-34-02_1.mov

On the same iPhone with the playground:

  • Double tapping an empty cell, repeated at varying speeds, shows no highlight, including when the cell already holds the caret. An on-device event log confirmed the second tap lands on the overlay.
  • A single tap places the caret and opens the keyboard. Typing, including Korean, works.
  • A long press in an empty cell still shows the native menu, and the caret is visible again once the menu closes.
  • A long press drag starting from an empty cell paints the cells, with the caret flicker reduced but not gone.
  • Tapping the start cell right after a drag places the caret normally.
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts packages/lexical-table/src/__tests__/unit/IosTableDragCaret.test.ts
      Tests  18 passed (18)
$ pnpm exec vitest run packages/lexical-table
 Test Files  30 passed (30)
      Tests  289 passed (289)
$ pnpm exec vitest run --project browser packages/lexical-table/src/__tests__/browser
 Test Files  7 passed (7)
      Tests  58 passed (58)
$ pnpm exec vitest run scripts/__tests__/unit/treeShakingSource.test.ts
      Tests  342 passed (342)
$ pnpm run tsc     # 0 errors
$ pnpm run flow    # Found 0 errors

Not exercised: iPadOS, Android (the code is iOS-only), and hardware keyboard navigation.

🤖 Generated with Claude Code

… host on iOS

## Description

On iOS, double tapping an empty table cell makes WebKit select back to the
nearest preceding word, which lies outside the table when the cell is empty.
meta#9267 restores the caret after `selectionchange`, which prevents the data
loss, but iOS paints the native selection highlight before the page is
notified, so the preceding content still flashes blue on every double tap
(meta#9347). Nothing dispatched to the page can cancel that gesture: the second
tap produces no cancelable event, and `::selection` / `user-select` do not
affect the UIKit highlight.

This change gives each table cell its own editing host on iOS so the word
search never leaves the cell. `TableCellNode.createDOM` renders
`<td contenteditable="false"><div data-lexical-table-cell-content
contenteditable="true">` and `getDOMSlot` returns `slot.withElement(wrapper)`,
so the reconciler places the cell's children inside the wrapper without any
model change. `exportDOM` strips the wrapper and the `contenteditable`
attribute, so copied and exported HTML keeps the existing `<td><p>` shape.
Non-iOS DOM is unchanged.

Two side effects of the nested host are handled in
`LexicalTableSelectionHelpers`:

- Backspace at the start of an empty cell would let WebKit move the caret
  into the previous editing host (the cell to the left). It is consumed for
  `deleteContentBackward` / `DELETE_CHARACTER_COMMAND` when the cell is empty
  and the caret is at its start.
- The iOS selection UI fires `window.blur` before `selectionchange`, which
  cleared the `touchTapCellKey` marker from meta#9267 before it could be used.
  The marker is now kept for up to 500ms across that blur when the tapped
  cell is an empty wrapper cell, and a native range touching that cell is
  collapsed back to the cell start.

Closes meta#9347

## Test plan

`IosTableCellEditingHost.test.ts` mocks `IS_IOS` (and `CAN_USE_BEFORE_INPUT`,
which jsdom lacks) and pins the wrapper DOM shape, wrapper identity across
added paragraphs, the editable toggle, the exported HTML, and the Backspace
guard in both the empty and the non-empty cell.

### Before

```
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosTableCellEditingHost.test.ts
     × renders the cell content inside a nested editing host
     × keeps the same editing host as paragraphs are added
     × follows the editable state of the editor
     × consumes Backspace at the start of an empty cell
     × leaves Backspace alone in a cell with text
      Tests  5 failed | 1 passed (6)
```

On an iPhone (iOS Safari and iOS Chrome) with the playground: insert a table
below a paragraph, double tap an empty cell. The cells above and the end of
the paragraph above the table are highlighted blue for one frame, then the
caret returns to the cell.

### After

```
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosTableCellEditingHost.test.ts
      Tests  6 passed (6)
$ pnpm exec vitest run packages/lexical-table
 Test Files  26 passed (26)
      Tests  265 passed (265)
$ pnpm exec vitest run --project browser packages/lexical-table/src/__tests__/browser/EmptyCellTouchSelection.test.ts
 Test Files  1 passed (1)
      Tests  30 passed (30)
$ pnpm run tsc        # 0 errors
$ pnpm exec eslint <changed files>   # ok
$ pnpm exec prettier --check <changed files>   # All matched files use Prettier code style!
```

Same device steps: nothing is highlighted and the caret stays in the cell.
Also verified on device: typing in a previously empty cell (English with
autocorrect, Korean IME), Enter creating several paragraphs, Backspace at an
empty cell start staying in the cell, double tap on a cell with text
selecting the word, selection-handle drag from the paragraph above into the
table and from a cell out of the table, long-press drag across cells
producing a table selection, tapping another cell moving the caret, table
scrolling.

Not exercised: arrow-key and Shift+arrow navigation across cells on iOS (no
hardware keyboard available), and Android.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
lexical Ready Ready Preview Oct 30, 2026 12:40am UTC
lexical-playground Ready Ready Preview Oct 30, 2026 12:40am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 13, 2026
@pkg-pr-new

pkg-pr-new Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
lexical

npm i https://pkg.pr.new/lexical@9350

@lexical/a11y

npm i https://pkg.pr.new/@lexical/a11y@9350

@lexical/clipboard

npm i https://pkg.pr.new/@lexical/clipboard@9350

@lexical/code

npm i https://pkg.pr.new/@lexical/code@9350

@lexical/code-core

npm i https://pkg.pr.new/@lexical/code-core@9350

@lexical/code-prism

npm i https://pkg.pr.new/@lexical/code-prism@9350

@lexical/code-shiki

npm i https://pkg.pr.new/@lexical/code-shiki@9350

@lexical/compiler

npm i https://pkg.pr.new/@lexical/compiler@9350

@lexical/devtools-core

npm i https://pkg.pr.new/@lexical/devtools-core@9350

@lexical/dragon

npm i https://pkg.pr.new/@lexical/dragon@9350

@lexical/eslint-plugin

npm i https://pkg.pr.new/@lexical/eslint-plugin@9350

@lexical/extension

npm i https://pkg.pr.new/@lexical/extension@9350

@lexical/fast-check

npm i https://pkg.pr.new/@lexical/fast-check@9350

@lexical/file

npm i https://pkg.pr.new/@lexical/file@9350

@lexical/hashtag

npm i https://pkg.pr.new/@lexical/hashtag@9350

@lexical/headless

npm i https://pkg.pr.new/@lexical/headless@9350

@lexical/history

npm i https://pkg.pr.new/@lexical/history@9350

@lexical/html

npm i https://pkg.pr.new/@lexical/html@9350

@lexical/internal

npm i https://pkg.pr.new/@lexical/internal@9350

@lexical/link

npm i https://pkg.pr.new/@lexical/link@9350

@lexical/list

npm i https://pkg.pr.new/@lexical/list@9350

@lexical/mark

npm i https://pkg.pr.new/@lexical/mark@9350

@lexical/markdown

npm i https://pkg.pr.new/@lexical/markdown@9350

@lexical/mdast

npm i https://pkg.pr.new/@lexical/mdast@9350

@lexical/offset

npm i https://pkg.pr.new/@lexical/offset@9350

@lexical/overflow

npm i https://pkg.pr.new/@lexical/overflow@9350

@lexical/plain-text

npm i https://pkg.pr.new/@lexical/plain-text@9350

@lexical/react

npm i https://pkg.pr.new/@lexical/react@9350

@lexical/rich-text

npm i https://pkg.pr.new/@lexical/rich-text@9350

@lexical/selection

npm i https://pkg.pr.new/@lexical/selection@9350

@lexical/table

npm i https://pkg.pr.new/@lexical/table@9350

@lexical/tailwind

npm i https://pkg.pr.new/@lexical/tailwind@9350

@lexical/text

npm i https://pkg.pr.new/@lexical/text@9350

@lexical/utils

npm i https://pkg.pr.new/@lexical/utils@9350

@lexical/y

npm i https://pkg.pr.new/@lexical/y@9350

@lexical/yjs

npm i https://pkg.pr.new/@lexical/yjs@9350

commit: cdfd198

SujinKim1127 and others added 3 commits October 23, 2026 14:15
…double tap cannot select past it

## Description

On iOS, double tapping an empty table cell makes WebKit select back to the
nearest preceding word, which lies outside the table. meta#9267 restores the
caret after `selectionchange`, but iOS paints the native highlight before the
page is notified, so the preceding content still flashes on every double tap
(meta#9347). The second tap dispatches no cancelable event, and page CSS does not
affect the highlight.

As suggested in review, this replaces the per-cell editing host from the
previous commit with a much smaller change and reverts its other parts (the
cell wrapper, the empty-cell Backspace guard, and the window blur / touch
marker changes); `LexicalTableSelectionHelpers` is back to `main`.

- Empty cell overlay (`LexicalTableIOSEmptyCellOverlay`): after a short, still
  touch tap in an empty cell, that cell is covered for 500ms by an unmanaged
  `contenteditable="false"` overlay. A second tap in that window lands on the
  overlay instead of editable text, so iOS does not start a word selection,
  and the overlay places the caret in the cell. Outside the window nothing
  covers the cell, so long press and long press drag keep working. Drags,
  long presses, and touches iOS takes over (`pointercancel`) never add it.
  The overlay goes away when the window ends, another cell is tapped, or the
  cell gets content, and the cell's inline `position` is restored with it.
  `TableCellNode.getDOMSlot` keeps the cell's children before the overlay
  with `withBefore`, so DOM child offsets still match the node's children.
  The overlay is never part of `createDOM`, so exported HTML is unchanged.
- Drag caret (`LexicalTableIOSDragCaret`): during a long press drag across
  cells, iOS keeps moving the native caret while the table selection keeps
  clearing it, so it flickers. The root's `caret-color` is made transparent
  while a finger is down on a cell and restored (to any previous inline
  value) when the last finger lifts. This reduces the flicker; the caret iOS
  draws around its magnifier is not affected by `caret-color`.

Both are registered from `registerTableSelectionObserver` on iOS only.
Non-iOS behavior and DOM are unchanged.

Closes meta#9347

## Test plan

`IosEmptyCellOverlay.test.ts` and `IosTableDragCaret.test.ts` mock `IS_IOS`.

### Before

With the sources at `main`:

```
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts packages/lexical-table/src/__tests__/unit/IosTableDragCaret.test.ts
     × hides the caret while a finger is down on a cell
     × keeps hiding until the last finger lifts
     × restores a caret-color that was already set
     × a touch tap in an empty cell covers it for the double-tap window
     × restores the cell position when the overlay goes away
     × only the most recently tapped cell is covered
     × a second tap on the overlay places the caret in its cell
     × keeps managed children before the overlay and drops it once the cell has text
      Tests  8 failed | 8 passed (16)
```

On an iPhone (iOS Safari) with the playground: double tapping an empty cell
flashes the cells above and the end of the paragraph above the table; a long
press drag across cells starting from an empty cell paints the cells with the
caret flickering throughout.

### After

```
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts packages/lexical-table/src/__tests__/unit/IosTableDragCaret.test.ts
      Tests  16 passed (16)
$ pnpm exec vitest run packages/lexical-table
 Test Files  30 passed (30)
      Tests  287 passed (287)
$ pnpm exec vitest run --project browser packages/lexical-table/src/__tests__/browser
 Test Files  7 passed (7)
      Tests  58 passed (58)
$ pnpm exec vitest run scripts/__tests__/unit/treeShakingSource.test.ts
      Tests  342 passed (342)
$ pnpm run tsc     # 0 errors
$ pnpm run flow    # Found 0 errors
```

On the same iPhone with the playground: double tapping an empty cell
(repeated, at varying speeds) shows no highlight; a single tap places the
caret and opens the keyboard; typing (including Korean) works; a long press
in an empty cell keeps the native behavior; a long press drag starting from
an empty cell paints the cells, with the caret flicker reduced but not gone;
tapping the start cell right after a drag places the caret normally. An
on-device event log confirmed the second tap of a double tap lands on the
overlay. Not exercised: iPadOS, Android (code is iOS-only), and hardware
keyboard navigation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…it already holds the caret

## Description

Double tapping an empty table cell on iOS still selected past the table,
back to the text above it, when the caret was already in that cell. In that
case iOS sends no pointerup for the first tap until the second tap has
started (its touchend arrives 1ms before the next touchstart), so the
overlay that the previous commit adds on pointerup came too late. Whether a
double tap worked depended on whether the cell had been tapped before.

A touch pointerdown on the cell that holds a collapsed DOM selection now
covers it right away. Other taps still cover the cell on pointerup, so long
press and drag behavior elsewhere is unchanged.

Cleanup in the same files, with no behavior change:

- The overlay's update listener and state live in the root listener and
  only check the covered cell, instead of scanning every dirty element on
  every update. The saved inline `position` is kept in that state rather
  than in the overlay's dataset.
- The empty cell check is shared as `$isCellEmpty` in `LexicalTableUtils`
  with the existing double tap repair in `LexicalTableSelectionHelpers`,
  and the tap slop is the existing `TAP_SLOP`, moved to `constants`.
- `createEmptyCellOverlay` moved into the overlay module; `TableCellNode`
  keeps only what `getDOMSlot` needs.
- The drag caret touch listeners are passive.

## Test plan

### Before

The new test with the pointerdown branch disabled:

```
$ npx vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts
     × a touch on the cell holding the caret covers it on pointerdown 7ms
AssertionError: expected null not to be null // Object.is equality
      Tests  1 failed | 12 passed (13)
```

### After

```
$ npx vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts
 Test Files  1 passed (1)
      Tests  13 passed (13)
$ npx vitest run packages/lexical-table
 Test Files  30 passed (30)
      Tests  289 passed (289)
```

The 5 unhandled errors in the `packages/lexical-table` run
(`LexicalEvents.ts:792`) also occur without this change.

Checked by hand on an iPhone against the playground: double tapping an
empty cell that already holds the caret keeps the caret in the cell; long
pressing an empty cell still shows the Paste menu, and the caret is visible
again once the menu closes. Other browsers were not exercised; the change
only runs on iOS.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… changedTouches list

## Description

The synthetic `touchend` events in `IosTableDragCaret.test.ts` and
`IosEmptyCellOverlay.test.ts` had no `changedTouches`, so Lexical's own iOS
`touchend` listener (`LexicalEvents.ts:792`) threw on them. The tests still
passed, but the `packages/lexical-table` run reported 5 unhandled errors that
`main` does not have. The events now carry an empty `changedTouches` list.

## Test plan

### Before

```
$ pnpm exec vitest run packages/lexical-table
 ❯ HTMLDivElement.<anonymous> packages/lexical/src/LexicalEvents.ts:792:29   (x5)
 Test Files  30 passed (30)
      Tests  289 passed (289)
```

### After

```
$ pnpm exec vitest run packages/lexical-table
 Test Files  30 passed (30)
      Tests  289 passed (289)
```

No unhandled errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SujinKim1127 SujinKim1127 changed the title [lexical-table] Bug Fix: Render table cell content in its own editing host on iOS [lexical-table] Bug Fix: Cover a tapped empty table cell on iOS so a double tap cannot select past it Oct 23, 2026
… tests

## Description

No intended behavior change, apart from one tap no longer building the
overlay twice.

- A tap on the cell that holds the caret covered it on `pointerdown`, then
  its own `pointerup` removed and rebuilt the overlay (and the cell
  `position` around it). That `pointerup` now only restarts the window.
- The cell lookup from an event target is shared by `pointerdown` and
  `pointerup`; the overlay state drops the cell, which is the overlay's
  parent.
- Listeners are registered with `registerEventListeners` /
  `registerEventListener` and `mergeRegister`, so the drag caret listeners
  are removed with the same options they were added with.
- `TableCellNode.getDOMSlot` inlines its single-use overlay lookup.
- Comments are shorter, and the one claiming a positioned cell stops a long
  press drag is corrected: the playground theme already positions cells.
- The overlay tests are consolidated (same behaviors, fewer near-duplicate
  cases), use the existing `PointerEvent` mock, and find cells from the DOM
  instead of tracking keys. A check that one tap keeps a single overlay is
  added.

## Test plan

### Before

```
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts -t "holding the caret"   # with the restart branch removed
     × the cell holding the caret is covered on pointerdown
      Tests  1 failed | 9 skipped (10)
```

### After

```
$ pnpm exec vitest run packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts packages/lexical-table/src/__tests__/unit/IosTableDragCaret.test.ts
      Tests  15 passed (15)
$ pnpm exec vitest run packages/lexical-table
 Test Files  30 passed (30)
      Tests  286 passed (286)
$ pnpm exec vitest run --project browser packages/lexical-table/src/__tests__/browser
      Tests  58 passed (58)
$ pnpm exec vitest run scripts/__tests__/unit/treeShakingSource.test.ts
      Tests  342 passed (342)
$ pnpm run tsc     # 0 errors
$ pnpm run flow    # Found 0 errors
```

Not re-checked on a device; the only runtime difference is the overlay no
longer being rebuilt on the same tap's pointerup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SujinKim1127

Copy link
Copy Markdown
Contributor Author

@etrepum

I think this workaround causes more problems than it solves, I suspect we can come to a simper solution either by overlaying some DOM over empty table cells or by having some unmanaged DOM in empty table cells (still a DOMSlot related change but not an additional wrapper)

Thanks for the suggestion, I've reworked the PR along those lines. The per-cell wrapper and the other changes to the selection helpers are gone; the #9267 repair is unchanged apart from sharing an empty-cell helper.

  • A tap in an empty cell covers that cell for 500ms with an unmanaged contenteditable="false" overlay, kept out of the managed children with getDOMSlot(...).withBefore(overlay). The second tap of a double tap lands on the overlay, so iOS never starts the word selection, and the overlay places the caret in the cell.
  • It is added on the tap's pointerup, or on pointerdown when the cell already holds the caret, since iOS holds back that tap's pointerup until it knows whether a second tap follows.
  • An overlay that stays on every empty cell gets in the way of a long press in that cell, so it only lives for the double-tap window.
  • While testing that drag I also noticed the caret flickering throughout, so there is a small separate module that hides the caret (caret-color) while a finger is down on a cell, which reduces the flicker.

Verified on an iPhone with the playground: no highlight on repeated double taps, single tap still places the caret and opens the keyboard, typing (including Korean) works, and long press and long press drag behave as before.

SujinKim1127 and others added 3 commits October 29, 2026 09:16
…overlay test

## Description

`main` removed the deprecated unchecked type arguments on node getters
(meta#9479), so `getFirstChildOrThrow<ElementNode>()` in
`IosEmptyCellOverlay.test.ts` no longer type-checks and the `integrity` CI
job failed on this PR. The test now gets a cell's paragraph through a small
`$paragraph()` helper that narrows with `$isElementNode` and `assert`.

## Test plan

### Before

With `main` merged into the branch:

```
$ pnpm run tsc
packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts(72,33): error TS2558: Expected 0 type arguments, but got 1.
packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts(73,12): error TS2339: Property 'append' does not exist on type 'LexicalNode'.
packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts(199,39): error TS2558: Expected 0 type arguments, but got 1.
packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts(199,54): error TS2339: Property 'clear' does not exist on type 'LexicalNode'.
packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts(246,33): error TS2558: Expected 0 type arguments, but got 1.
packages/lexical-table/src/__tests__/unit/IosEmptyCellOverlay.test.ts(247,12): error TS2339: Property 'append' does not exist on type 'LexicalNode'.
```

### After

Each `ci-check` step run on its own (`tsc`, `tsc-test`, `tsc-scripts`,
`tsc-extension`, `tsc-website`, `flow`, `prettier`, `lint`,
`check-changesets`): all exit 0.

```
$ pnpm exec vitest run packages/lexical-table
 Test Files  31 passed (31)
      Tests  298 passed (298)
$ pnpm exec vitest run --project browser packages/lexical-table/src/__tests__/browser
      Tests  58 passed (58)
$ pnpm exec vitest run scripts/__tests__/unit/treeShakingSource.test.ts
      Tests  374 passed (374)
```

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

2 active deployments
Preview – lexical — cdfd1982 Deployed Oct 30, 2026 by vercel[bot]
Preview – lexical-playground — cdfd1982 Deployed Oct 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Double tap in an empty table cell on iOS briefly highlights the preceding content

2 participants