Hoist `findAllTables(memo.content)` into a shared `useMemo` so the
markdown AST is parsed exactly once per `memo.content` change.
Both `resolveTableIndex` and `handleEditClick` now reference the same
cached `tables` array, keeping the lookup and edit paths in sync and
eliminating the duplicate parse that previously occurred on every edit
click.
- escapeCell() replaces unescaped | with \| before writing each cell,
applied in both width calculation and formatRow so padding is accurate
- parseRow unescapes \| back to | after splitting on unescaped pipes
- Adds round-trip regression test for cells containing pipe characters
Addresses coderabbitai review comment on PR #5680.
- Replace regex-based TABLE_LINE scan in findAllTables with a proper
GFM markdown AST lookup using mdast-util-from-markdown + mdast-util-gfm
+ micromark-extension-gfm + unist-util-visit (all already in deps).
Tables without leading/trailing pipes (e.g. 'A | B\n--- | ---\n1 | 2')
are now correctly detected via node.position.start/end.offset.
- Add regression test asserting pipe-less GFM table is found with correct
start/end offsets.
- Fix parseMarkdownTable to split on unescaped pipes only (lookbehind).
- Fix import order in Table.tsx (Biome organizeImports).
- Fix useless escape \- → - in TableEditorDialog.tsx sort regex.
- Reformat long normalize/compareFn lines to satisfy Biome formatter.
Bugs:
- Fix replaceNthTable off-by-one: findAllTables now uses truly exclusive
end index (start + text.length) so content.slice(start, end) === text
- Replace fragile DOM-based table index resolution with AST-based approach
using node.position.start.offset from hast ReactMarkdownProps
Architecture:
- Unify TableEditorDialog instances: InsertMenu no longer manages its own
dialog, instead calls onOpenTableEditor from parent MemoEditor which
owns the single shared dialog instance
- Remove onInsertText prop chain (InsertMenu → EditorToolbar → MemoEditor)
replaced by onOpenTableEditor
Other improvements:
- Add i18n: all hardcoded English strings now use useTranslate()/t() with
new editor.table.* keys in en.json
- Fix useCallback [props] dependency that defeated memoization (removed
with dialog unification)
- Use stable row IDs (monotonic counter) as React keys instead of array
indices in TableEditorDialog
- Replace hardcoded MONO_FONT constant with Tailwind font-mono class
(maps to project's --font-mono CSS variable)
- Add 28 vitest tests for markdown-table.ts covering parse, serialize,
findAllTables, replaceNthTable, createEmptyTable with edge cases
- Add vitest dev dependency with test/test:watch scripts
Add a dialog-based table editor to create and edit markdown tables via a
visual grid instead of raw pipe-delimited text.
Features:
- Visual grid with inputs for headers and cells; add/remove rows and columns
- Sort columns (asc/desc, text and numeric); tab navigation (new row at end)
- Insert column/row between columns/rows via hover zones and + buttons with
blue highlight lines clipped to table bounds
- Sticky header with solid background; square headers; monospace cell font
- Row numbers with insert zones; delete row at row end; delete column with
spacing from insert button; Add row/Add column in footer and below table
- Delete table button on rendered tables (with confirm); edit pencil opens
dialog with parsed data; always-visible sort/delete at 40% opacity
- Fixed-size dialog (56rem x 44rem); /table slash command and Table in
InsertMenu open dialog; Command.action support for dialog-based commands
New: TableEditorDialog.tsx, utils/markdown-table.ts. Integration in
SlashCommands, EditorContent, InsertMenu, MemoContent Table.
Made-with: Cursor
The failed-to-load key was only used for non-ConnectError exceptions, which
are unreachable in practice since the Connect RPC client always wraps errors
as ConnectError. Use (error as Error).message as a plain fallback instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
30 locale files were missing the two keys added in the auth redirect PR.
Added English fallback strings so all locales render properly until
community translations are contributed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>