Skip to content

[WIKI-491] [WIKI-496] [WIKI-499] refactor: tables width and selection UI #7274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 2, 2025

Conversation

aaryan610
Copy link
Member

@aaryan610 aaryan610 commented Jun 26, 2025

Description

  • Tables now use a consistent default column width.
  • Selected tables and cells receive enhanced visual feedback.
  • Tables now expand to full editor width for better layout flexibility.

Type of Change

  • Improvement (change that would cause existing functionality to not work as expected)

Media

Before After
Screen.Recording.2025-06-26.at.18.07.20.mov
Screen.Recording.2025-06-26.at.18.04.49.mov

Summary by CodeRabbit

  • New Features

    • Added visual outlines for selected table cells, improving clarity when selecting multiple cells in tables.
  • Improvements

    • Tables now use a consistent default column width.
    • Table controls and resizing handles have refined positioning and styling.
    • Selected tables and cells receive enhanced visual feedback.
    • Certain table elements now expand to full editor width for better layout flexibility.
  • Bug Fixes

    • Improved detection and handling of table elements for side menus and drag handles.
  • Style

    • Restructured and updated table-related CSS for better maintainability and visual consistency.

Copy link

makeplane bot commented Jun 26, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

Copy link
Contributor

coderabbitai bot commented Jun 26, 2025

Walkthrough

This update refactors table-related logic and styling in the editor. It introduces a default column width constant, adjusts table and cell selection handling, restructures CSS for tables and drag-drop, and adds a ProseMirror plugin for outlining selected table cells. Several selectors and command signatures are updated to streamline table management and visual consistency.

Changes

File(s) Change Summary
.../extensions/side-menu.ts, .../plugins/drag-handle.ts Changed table detection logic from .table-wrapper class selector to table element selector.
.../extensions/table/table/index.ts Added export of DEFAULT_COLUMN_WIDTH constant (value: 150).
.../extensions/table/table-cell.ts, .../extensions/table/table-header.ts Updated default colwidth attribute to use [DEFAULT_COLUMN_WIDTH]; added ProseMirror plugin for cell selection outline in table-cell.ts.
.../extensions/table/table.ts, .../helpers/editor-commands.ts Simplified insertTable command signature; removed explicit columnWidth parameter.
.../extensions/table/table/utilities/create-table.ts Refactored createTable to accept a single props object; removed default for columnWidth.
.../extensions/table/plugins/table-selection-outline/plugin.ts, .../utils.ts Added plugin and utilities to visually outline selected table cells based on selection adjacency.
.../extensions/table/table/table-view.tsx Updated root container CSS classes to add full-width and adjust scrollbar size.
.../styles/table.css Restructured and nested table-related CSS; introduced .selectedCell styles and adjusted border colors.
.../styles/drag-drop.css Updated selectors to exclude .table-wrapper from certain styles and apply others to it.
.../styles/variables.css Differentiated styling between full-width and constrained editor blocks using .editor-full-width-block.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Editor
    participant TableCellSelectionOutlinePlugin
    participant TableView

    User->>Editor: Selects table cells
    Editor->>TableCellSelectionOutlinePlugin: Updates selection state
    TableCellSelectionOutlinePlugin->>Editor: Applies border classes to selected cells
    Editor->>TableView: Renders table with outlined cell selections
Loading

Suggested labels

🎨UI / UX, 🛠️refactor, ready_to_merge

Suggested reviewers

  • Palanikannan1437
  • sriramveeraghanta

Poem

Oh tables, how you now align,
With borders crisp and cells that shine!
Selection glows with outlined grace,
As rabbits hop from place to place.
Full width blocks and scrollbars small—
This editor now delights us all!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
packages/editor/src/core/extensions/table/table/utilities/create-table.ts (1)

22-42: Every row currently re-uses the same cell nodes

headerCells and cells are created once and inserted into all
rows. ProseMirror expects each node instance to appear only once in
the document tree; re-using them can lead to
“Node may not be reused” errors and unexpected mutations when one cell
is edited.

A minimal fix is to copy the nodes per row:

-  for (let index = 0; index < rowsCount; index += 1) {
-    rows.push(types.row.createChecked(null, withHeaderRow && index === 0 ? headerCells : cells));
-  }
+  for (let rowIndex = 0; rowIndex < rowsCount; rowIndex += 1) {
+    const source = withHeaderRow && rowIndex === 0 ? headerCells : cells;
+
+    // copy() produces a structurally identical node with a new identity
+    const rowCells = source.map((cell) => cell.copy());
+
+    rows.push(types.row.createChecked(null, rowCells));
+  }
🧹 Nitpick comments (5)
packages/editor/src/styles/variables.css (1)

189-193: Consider consistent padding for full-width blocks.

The full-width block styling uses different padding values for start and end (padding-inline-end uses --wide-content-margin which is 96px). This might create asymmetric layouts. Consider using the same calculation for both sides:

    & > .editor-full-width-block {
      max-width: 100%;
      padding-inline-start: calc((100% - var(--editor-content-width)) / 2);
-     padding-inline-end: var(--wide-content-margin);
+     padding-inline-end: calc((100% - var(--editor-content-width)) / 2);
    }
packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (2)

5-5: Remove React dependency for better modularity.

The import of CSSProperties from React seems unnecessary since this is a ProseMirror plugin that doesn't use React. Consider defining the styles inline or creating a local type:

-import type { CSSProperties } from "react";
+type CSSProperties = Record<string, string | number>;

This improves modularity and removes an unnecessary dependency.

Also applies to: 35-80


118-138: Consider performance optimization for DOM element creation.

Creating DOM elements on every selection change could impact performance with large tables or frequent selections. Consider:

  1. Reusing DOM elements where possible
  2. Using CSS classes instead of inline styles
  3. Implementing a caching mechanism for border elements

This would reduce garbage collection pressure and improve performance.

packages/editor/src/core/extensions/table/table/utilities/create-table.ts (1)

25-27: Unnecessary null-checks

createCell always returns a ProsemirrorNode, so the surrounding
if (cell) { … } blocks can be removed to simplify the loop.

packages/editor/src/styles/table.css (1)

43-47: Visual contrast check for selection background

rgba(var(--color-primary-100), 0.2) applies a 20 % alpha overlay to
the whole table. On light themes this can be very subtle; on dark
themes it may be too strong. Consider using color-mix() with the
surface background or adjusting the alpha via design tokens so that
contrast meets WCAG AA across themes.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 25a6cd4 and fdd4f80.

📒 Files selected for processing (12)
  • packages/editor/src/core/extensions/side-menu.ts (1 hunks)
  • packages/editor/src/core/extensions/table/table-cell.ts (2 hunks)
  • packages/editor/src/core/extensions/table/table/index.ts (1 hunks)
  • packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (1 hunks)
  • packages/editor/src/core/extensions/table/table/table-view.tsx (1 hunks)
  • packages/editor/src/core/extensions/table/table/table.ts (3 hunks)
  • packages/editor/src/core/extensions/table/table/utilities/create-table.ts (2 hunks)
  • packages/editor/src/core/helpers/editor-commands.ts (1 hunks)
  • packages/editor/src/core/plugins/drag-handle.ts (3 hunks)
  • packages/editor/src/styles/drag-drop.css (2 hunks)
  • packages/editor/src/styles/table.css (2 hunks)
  • packages/editor/src/styles/variables.css (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
packages/editor/src/core/extensions/table/table/table-view.tsx (1)
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.
packages/editor/src/styles/drag-drop.css (2)
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.
Learnt from: vineetk13
PR: makeplane/plane#6391
File: web/styles/react-day-picker.css:249-282
Timestamp: 2025-01-17T05:17:51.953Z
Learning: In the date range picker's CSS, left/right positioning for cell background effects (like in `.rdp-range_start::before`, `.rdp-range_middle::before`, `.rdp-range_end::before`) should use physical properties instead of logical properties, as these create visual effects that should remain consistent regardless of text direction.
packages/editor/src/styles/variables.css (1)
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.
packages/editor/src/styles/table.css (2)
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.
Learnt from: vineetk13
PR: makeplane/plane#6391
File: web/styles/react-day-picker.css:249-282
Timestamp: 2025-01-17T05:17:51.953Z
Learning: In the date range picker's CSS, left/right positioning for cell background effects (like in `.rdp-range_start::before`, `.rdp-range_middle::before`, `.rdp-range_end::before`) should use physical properties instead of logical properties, as these create visual effects that should remain consistent regardless of text direction.
🧬 Code Graph Analysis (2)
packages/editor/src/core/extensions/table/table-cell.ts (1)
packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (1)
  • TableCellSelectionOutlinePlugin (88-150)
packages/editor/src/core/extensions/table/table/table.ts (2)
packages/editor/src/core/extensions/table/table/utilities/create-table.ts (1)
  • createTable (15-45)
packages/editor/src/core/extensions/table/table/index.ts (1)
  • DEFAULT_COLUMN_WIDTH (3-3)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (10)
packages/editor/src/core/extensions/table/table/index.ts (1)

3-3: LGTM! Good centralization of default values.

The DEFAULT_COLUMN_WIDTH constant provides a single source of truth for table column widths, making the codebase more maintainable and consistent.

packages/editor/src/core/extensions/side-menu.ts (1)

134-134: Improved DOM targeting precision.

The change from .table-wrapper to table provides more precise element targeting, which aligns with the broader table refactoring effort. This approach is more semantically correct and reduces dependency on CSS class names.

packages/editor/src/core/extensions/table/table/table-view.tsx (1)

390-390: Good styling improvements for table layout.

The addition of editor-full-width-block class supports the full-width table layout design, and the scrollbar size change from scrollbar-md to scrollbar-sm provides a more refined visual appearance.

packages/editor/src/core/helpers/editor-commands.ts (1)

112-113: Good refactoring to remove hardcoded values.

Removing the explicit columnWidth: 150 parameter improves maintainability by allowing the table extension to handle default column width internally via the DEFAULT_COLUMN_WIDTH constant. This decouples the command from implementation details.

packages/editor/src/core/extensions/table/table-cell.ts (2)

4-5: Good import organization for the new plugin.

The import is properly placed in the local imports section with clear commenting.


52-54: Excellent UX enhancement with proper plugin integration.

The TableCellSelectionOutlinePlugin integration provides visual feedback for table cell selections, improving the editing experience. The plugin is properly registered through the addProseMirrorPlugins method and correctly passes the editor instance.

packages/editor/src/styles/drag-drop.css (1)

38-71: CSS changes look good and align with table UI improvements.

The exclusion of .table-wrapper from the general selected node styles and its specific inclusion with image-related nodes for offset and background styling is consistent with the PR objectives to improve table selection UI.

packages/editor/src/core/extensions/table/table/table.ts (1)

32-32: Good refactoring to simplify the table insertion API.

The removal of the columnWidth parameter from the command signature and the use of DEFAULT_COLUMN_WIDTH constant promotes consistency across the codebase. The switch to an options object for createTable improves maintainability.

Also applies to: 46-46, 115-123

packages/editor/src/core/plugins/drag-handle.ts (1)

19-19: Improved semantic targeting by using table element selector.

The consistent change from .table-wrapper to table across all three locations improves reliability by targeting the actual table element rather than relying on a wrapper class. This is a more robust approach for table detection.

Also applies to: 93-93, 102-102

packages/editor/src/styles/table.css (1)

1-41: Confirm that the build pipeline supports native / PostCSS nesting

The file now relies heavily on nested selectors (table { … },
&.ProseMirror-selectednode { … }, etc.) which plain CSS does not
yet support in all target browsers.
If the repository isn’t already using postcss-nesting or the new CSS
Nesting spec behind a compiler step, this change will break the style
sheet at runtime.

Please double-check the tooling or move the rules to a pre-processed
.scss/.pcss file.

Copy link
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.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (1)

38-38: Good fix: Plugin key is now appropriately specific.

The plugin key has been updated from the generic "selection" to "table-cell-selection-outline", addressing the previous review feedback.

🧹 Nitpick comments (2)
packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (2)

18-19: Improve variable naming for better readability.

The variable names testRight and testBottom don't clearly convey their purpose as cell span offsets.

-  const testRight = cellW;
-  const testBottom = width * cellH;
+  const rightOffset = cellW;
+  const bottomOffset = width * cellH;

And update their usage accordingly in lines 22 and 24.


21-24: Consider adding comments for complex cell adjacency logic.

The cell adjacency calculations handle spanning cells correctly but are complex to understand without context.

+  // Calculate adjacent cell positions accounting for cell spans
   const topCell = cellIndex >= width ? tableMap.map[cellIndex - width] : undefined;
-  const bottomCell = cellIndex < width * height - testBottom ? tableMap.map[cellIndex + testBottom] : undefined;
+  const bottomCell = cellIndex < width * height - bottomOffset ? tableMap.map[cellIndex + bottomOffset] : undefined;
   const leftCell = cellIndex % width > 0 ? tableMap.map[cellIndex - 1] : undefined;
-  const rightCell = cellIndex % width < width - testRight ? tableMap.map[cellIndex + testRight] : undefined;
+  const rightCell = cellIndex % width < width - rightOffset ? tableMap.map[cellIndex + rightOffset] : undefined;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fdd4f80 and a0d6fa0.

📒 Files selected for processing (2)
  • packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (1 hunks)
  • packages/editor/src/styles/table.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/editor/src/styles/table.css
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
packages/editor/src/core/extensions/table/table/plugins/selection-outline.plugin.ts (5)

1-5: LGTM: Clean imports and dependencies.

The imports are well-organized and include all necessary ProseMirror and TipTap dependencies for the plugin functionality.


45-51: Efficient early returns prevent unnecessary processing.

The plugin correctly handles non-editable states, missing tables, and unchanged states to avoid unnecessary decoration recalculation.


76-76: Decoration implementation follows ProseMirror best practices.

The node decoration with CSS classes is properly implemented and will integrate well with the corresponding CSS styles.


84-88: Plugin structure follows ProseMirror conventions correctly.

The plugin properly exposes decorations through the props.decorations method and maintains state through the plugin key.


60-63: Consider performance impact for large tables.

The plugin recalculates all decorations on every selection change within a table. For very large tables with many selected cells, this could impact performance.

#!/bin/bash
# Description: Check if there are any performance optimizations or throttling mechanisms in similar table plugins

# Search for performance-related patterns in table extensions
rg -A 5 -B 5 "performance|throttle|debounce|optimize" --type ts packages/editor/src/core/extensions/table/

Copy link
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.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/plugin.ts (1)

41-46: Consider performance optimization for large table selections.

The current implementation creates decorations for every selected cell individually. For large table selections, consider batching decoration creation or using range-based decorations to improve performance.

-        // Then, add decorations with appropriate border classes
-        selection.forEachCell((node, pos) => {
-          const start = pos - table.pos - 1;
-          const classes = getCellBorderClasses(start, selectedCells, tableMap);
-
-          decorations.push(Decoration.node(pos, pos + node.nodeSize, { class: classes.join(" ") }));
-        });
+        // Then, add decorations with appropriate border classes
+        const cellDecorations = [];
+        selection.forEachCell((node, pos) => {
+          const start = pos - table.pos - 1;
+          const classes = getCellBorderClasses(start, selectedCells, tableMap);
+          
+          if (classes.length > 0) {
+            cellDecorations.push(Decoration.node(pos, pos + node.nodeSize, { class: classes.join(" ") }));
+          }
+        });
+        decorations.push(...cellDecorations);
packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/utils.ts (2)

20-23: Add error handling for edge case.

The indexOf operation could return -1 for malformed table structures. Consider adding a more descriptive error or logging to help debug issues when cell positions are not found in the table map.

  // Find the index of our cell in the flat tableMap.map array
  // tableMap.map contains start positions of all cells in row-by-row order
  const cellIndex = tableMap.map.indexOf(cellStart);

  // Safety check: if cell position not found in table map, return empty object
- if (cellIndex === -1) return {};
+ if (cellIndex === -1) {
+   console.warn(`Cell position ${cellStart} not found in table map`);
+   return {};
+ }

9-11: Export the utility function for potential reuse.

The getAdjacentCellPositions function could be useful in other table-related features. Consider exporting it for broader use within the table extension.

- const getAdjacentCellPositions = (
+ export const getAdjacentCellPositions = (
    cellStart: number,
    tableMap: TableMap
  ): { top?: number; bottom?: number; left?: number; right?: number } => {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec7cbd4 and 167e53f.

📒 Files selected for processing (3)
  • packages/editor/src/core/extensions/table/table-cell.ts (2 hunks)
  • packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/plugin.ts (1 hunks)
  • packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/utils.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/editor/src/core/extensions/table/table-cell.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/plugin.ts (1)
packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/utils.ts (1)
  • getCellBorderClasses (50-75)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/plugin.ts (2)

19-25: Good optimization with early returns and state preservation.

The plugin correctly handles non-editable states and unchanged documents, with proper state preservation when no table is found.


35-38: Verify position calculation consistency.

The position calculation pos - table.pos - 1 converts absolute document positions to table-relative positions. Ensure this calculation is consistent with how TableMap expects positions.

#!/bin/bash
# Description: Verify how ProseMirror TableMap handles position calculations
# Expected: Confirm that table-relative positions are calculated correctly

rg -A 10 -B 5 "table\.pos" --type ts
rg -A 10 -B 5 "TableMap\.get" --type ts
packages/editor/src/core/extensions/table/table/plugins/table-selection-outline/utils.ts (3)

28-29: Mathematical calculations are correct.

The coordinate conversion from flat array index to 2D grid coordinates using integer division and modulo operations is mathematically sound and well-documented.


31-47: Boundary checks are comprehensive and correct.

The boundary checks for each direction (top, bottom, left, right) properly handle table edges by checking row and column bounds before calculating adjacent positions.


50-75: Border class logic is sound and efficient.

The function correctly determines which borders to show by checking if adjacent cells are selected or don't exist. The logic ensures that selection outlines only appear at the boundary of the selection.

Copy link
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.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/editor/src/core/extensions/table/plugins/table-selection-outline/utils.ts (1)

50-75: Consider optimizing array membership checks for better performance.

The function logic is correct for determining border classes, but the repeated selectedCells.includes() calls could be expensive for large selections since includes() has O(n) complexity.

Consider converting the selectedCells array to a Set for O(1) membership checks:

-export const getCellBorderClasses = (cellStart: number, selectedCells: number[], tableMap: TableMap): string[] => {
+export const getCellBorderClasses = (cellStart: number, selectedCells: number[] | Set<number>, tableMap: TableMap): string[] => {
   const adjacent = getAdjacentCellPositions(cellStart, tableMap);
   const classes: string[] = [];
+  const selectedSet = selectedCells instanceof Set ? selectedCells : new Set(selectedCells);

   // Add border-right if right cell is not selected or doesn't exist
-  if (adjacent.right === undefined || !selectedCells.includes(adjacent.right)) {
+  if (adjacent.right === undefined || !selectedSet.has(adjacent.right)) {
     classes.push("selectedCell-border-right");
   }

   // Apply similar changes to other border checks...
packages/editor/src/core/extensions/table/plugins/table-selection-outline/plugin.ts (2)

14-58: Well-structured plugin implementation with room for performance optimization.

The plugin correctly implements the ProseMirror plugin pattern and handles table cell selection outlining. The logic is sound and follows best practices for state management and decoration application.

Consider these optimizations for better performance:

  1. Optimize selectedCells collection: Convert to Set for faster lookups:
-        const selectedCells: number[] = [];
+        const selectedCells = new Set<number>();

         // First, collect all selected cell positions
         selection.forEachCell((_node, pos) => {
           const start = pos - table.pos - 1;
-          selectedCells.push(start);
+          selectedCells.add(start);
         });
  1. Add early return for single cell selections: Single cells don't need border outlining:
         // First, collect all selected cell positions
         selection.forEachCell((_node, pos) => {
           const start = pos - table.pos - 1;
           selectedCells.add(start);
         });

+        // Skip decoration for single cell selections
+        if (selectedCells.size === 1) return {};
  1. Consider caching decorations: If the same selection persists across multiple state changes, you could cache the decoration set to avoid recalculation.

20-25: Consider clarifying the conditional logic for better readability.

The nested conditional logic works correctly but could be more explicit about the different scenarios.

Consider restructuring for better clarity:

-        if (!table || !hasDocChanged) {
-          return table === undefined ? {} : prev;
-        }
+        // No table context - clear decorations
+        if (!table) return {};
+        
+        // No changes - keep previous decorations
+        if (!hasDocChanged) return prev;

This makes the two distinct scenarios more explicit: clearing decorations vs. preserving them.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13c7ac8 and e32807d.

📒 Files selected for processing (3)
  • packages/editor/src/core/extensions/table/plugins/table-selection-outline/plugin.ts (1 hunks)
  • packages/editor/src/core/extensions/table/plugins/table-selection-outline/utils.ts (1 hunks)
  • packages/editor/src/core/extensions/table/table-cell.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/editor/src/core/extensions/table/table-cell.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/editor/src/core/extensions/table/plugins/table-selection-outline/plugin.ts (1)
packages/editor/src/core/extensions/table/plugins/table-selection-outline/utils.ts (1)
  • getCellBorderClasses (50-75)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
packages/editor/src/core/extensions/table/plugins/table-selection-outline/utils.ts (1)

9-48: LGTM! Well-implemented adjacency calculation with proper edge handling.

The getAdjacentCellPositions function correctly:

  • Converts flat table map indices to 2D coordinates using division and modulo
  • Handles table edges by returning undefined for non-existent adjacent cells
  • Includes comprehensive inline documentation explaining the coordinate system

The bounds checking logic is sound and prevents accessing cells outside the table boundaries.

@aaryan610 aaryan610 changed the title [WIKI-491] [WIKI-496] refactor: tables width and selection UI [WIKI-491] [WIKI-496] [WIKI-499] refactor: tables width and selection UI Jun 30, 2025
@sriramveeraghanta sriramveeraghanta merged commit 1fcffad into preview Jul 2, 2025
5 of 6 checks passed
@sriramveeraghanta sriramveeraghanta deleted the refactor/tables branch July 2, 2025 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants