Skip to content
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

[PE-304] feat: make floating link generic and use it for all editors #6552

Merged
merged 8 commits into from
Apr 2, 2025

Conversation

Palanikannan1437
Copy link
Collaborator

@Palanikannan1437 Palanikannan1437 commented Feb 5, 2025

Description

Floating links are now generic and can be used across all the editors, even to insert links.

Defining a protocol isn't necessary, defaults to https protocol if no protocol is specified.

Summary by CodeRabbit

  • New Features

    • Enhanced link management with a streamlined preview and editing experience.
    • Improved image handling with enforced file size limits and upload progress tracking.
    • Added new editor event tracking for improved interaction feedback.
  • Bug Fixes

    • Refined URL validation for more reliable link submissions.
    • Expanded bubble menu display to cover additional contexts.
  • Style

    • Updated text formatting labels for consistency, renaming “strike” to “strikethrough.”

Copy link
Contributor

coderabbitai bot commented Feb 5, 2025

Walkthrough

This pull request consolidates and refines editor behavior. It removes legacy link preview logic from the page renderer, replacing it with a dedicated LinkViewContainer integrated in the editor container. The changes include updated type definitions, refined URL validation via an enhanced helper, and standardized naming (e.g., renaming "strike" to "strikethrough") across menus and constants. Additionally, storage management improvements have been applied across various extensions, and editor components have been reorganized with minor import reordering.

Changes

Files Change Summary
.gitignore Added ignore rules for dev-editor and re-added *.rdb.gz.
packages/editor/src/core/components/editors/… (page-renderer.tsx, editor-container.tsx, editor-content.tsx, link-view-container.tsx) Removed link preview logic from page-renderer.tsx; updated editor-container.tsx to require a non-null editor and added a containerRef passed to a new LinkViewContainer; reordered imports in editor-content.tsx.
packages/editor/src/core/components/links/… (index.ts, link-edit-view.tsx, link-input-view.tsx, link-preview.tsx, link-view.tsx) Removed export and file for link-input-view; updated view handling and props in link-edit-view.tsx and link-preview.tsx, and consolidated view types in link-view.tsx using the new LinkViews alias.
packages/editor/src/core/components/menus/… & web/core/… (bubble-menu/link-selector.tsx, bubble-menu/root.tsx, menu-items.ts, toolbar.tsx, editor.ts) Modified URL validation and immutability in link-selector.tsx; enhanced bubble menu display conditions and state management in bubble-menu/root.tsx; renamed identifiers from "strike" to "strikethrough" in menu items and constants; removed debug console logs in the toolbar.
packages/editor/src/core/extensions/… Updated URL validation logic and storage types in extensions (custom-image, custom-link, read-only-custom-image, headers, image, and mentions), including new properties and methods for state management.
packages/editor/src/core/helpers/… & packages/editor/src/core/types/… Modified isValidHttpUrl to return an object; reordered imports in editor-commands.ts; added a new getExtensionStorage utility; updated editor command naming and introduced new editor event definitions.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant EC as EditorContainer
    participant LVC as LinkViewContainer
    participant FU as Floating UI
    participant LV as LinkView

    Note over EC,LVC: Editor initialized with containerRef and LinkViewContainer
    User->>EC: Hover over link in editor
    EC->>LVC: Dispatch link hover event
    LVC->>FU: Process positioning & interaction (useFloating)
    FU-->>LVC: Return position data
    LVC->>LV: Render LinkView with updated styles
Loading

Suggested labels

✨feature, 🌐frontend, 🛠️refactor, ✍️editor

Suggested reviewers

  • aaryan610

Poem

Hey there, I'm a happy bunny, hopping with delight,
New code flows in the editor, making everything bright!
No more clutter, links now shine with a graceful show,
From refactored previews to menus that glow.
With lines updated and features new,
My little paws dance—they're cheering for you! 🐇🌟

✨ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

@Palanikannan1437 Palanikannan1437 marked this pull request as ready for review April 2, 2025 07:00
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: 1

🧹 Nitpick comments (2)
packages/editor/src/core/extensions/headers.ts (1)

15-15: Consider improving type parameters.

While adding the storage type parameter is good, the first type parameter is still set to any. Consider defining a proper type for this parameter as well to further improve type safety.

-export const HeadingListExtension = Extension.create<any, HeadingExtensionStorage>({
+export const HeadingListExtension = Extension.create<Record<string, never>, HeadingExtensionStorage>({

Or if there are specific options that should be typed:

-export const HeadingListExtension = Extension.create<any, HeadingExtensionStorage>({
+export const HeadingListExtension = Extension.create<HeadingExtensionOptions, HeadingExtensionStorage>({
packages/editor/src/core/components/editors/editor-container.tsx (1)

15-15: Update type definition for consistency with implementation.

The editor prop type has been changed from Editor | null to just Editor, indicating it should never be null. However, the click handler on line 26 still has a null check if (!editor) return;. This check is now unnecessary according to the type definition.

-  if (!editor) return;
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 921dfe3 and 1a885c1.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (31)
  • .gitignore (1 hunks)
  • packages/editor/src/core/components/editors/document/page-renderer.tsx (2 hunks)
  • packages/editor/src/core/components/editors/editor-container.tsx (2 hunks)
  • packages/editor/src/core/components/editors/editor-content.tsx (1 hunks)
  • packages/editor/src/core/components/editors/link-view-container.tsx (1 hunks)
  • packages/editor/src/core/components/links/index.ts (0 hunks)
  • packages/editor/src/core/components/links/link-edit-view.tsx (1 hunks)
  • packages/editor/src/core/components/links/link-input-view.tsx (0 hunks)
  • packages/editor/src/core/components/links/link-preview.tsx (2 hunks)
  • packages/editor/src/core/components/links/link-view.tsx (2 hunks)
  • packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx (1 hunks)
  • packages/editor/src/core/components/menus/bubble-menu/root.tsx (2 hunks)
  • packages/editor/src/core/components/menus/menu-items.ts (1 hunks)
  • packages/editor/src/core/constants/common.ts (2 hunks)
  • packages/editor/src/core/extensions/core-without-props.ts (1 hunks)
  • packages/editor/src/core/extensions/custom-image/components/image-node.tsx (2 hunks)
  • packages/editor/src/core/extensions/custom-image/custom-image.ts (1 hunks)
  • packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (1 hunks)
  • packages/editor/src/core/extensions/custom-link/extension.tsx (2 hunks)
  • packages/editor/src/core/extensions/extensions.tsx (1 hunks)
  • packages/editor/src/core/extensions/headers.ts (1 hunks)
  • packages/editor/src/core/extensions/image/extension.tsx (1 hunks)
  • packages/editor/src/core/extensions/image/image-component-without-props.tsx (2 hunks)
  • packages/editor/src/core/extensions/mentions/extension-config.ts (1 hunks)
  • packages/editor/src/core/extensions/read-only-extensions.tsx (1 hunks)
  • packages/editor/src/core/helpers/common.ts (1 hunks)
  • packages/editor/src/core/helpers/editor-commands.ts (1 hunks)
  • packages/editor/src/core/helpers/get-extension-storage.ts (1 hunks)
  • packages/editor/src/core/types/editor.ts (3 hunks)
  • web/core/components/pages/editor/header/toolbar.tsx (0 hunks)
  • web/core/constants/editor.ts (2 hunks)
💤 Files with no reviewable changes (3)
  • web/core/components/pages/editor/header/toolbar.tsx
  • packages/editor/src/core/components/links/index.ts
  • packages/editor/src/core/components/links/link-input-view.tsx
🧰 Additional context used
🧬 Code Definitions (11)
packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx (1)
packages/editor/src/core/helpers/common.ts (1)
  • isValidHttpUrl (47-89)
packages/editor/src/core/extensions/custom-image/components/image-node.tsx (1)
packages/editor/src/core/helpers/get-extension-storage.ts (1)
  • getExtensionStorage (20-23)
packages/editor/src/core/components/links/link-preview.tsx (1)
packages/editor/src/core/components/links/link-view.tsx (2)
  • LinkViewProps (8-16)
  • LinkViews (6-6)
packages/editor/src/core/components/editors/editor-container.tsx (4)
packages/editor/src/core/types/config.ts (1)
  • TDisplayConfig (28-33)
packages/utils/src/common.ts (1)
  • cn (7-7)
packages/editor/src/core/constants/config.ts (1)
  • DEFAULT_DISPLAY_CONFIG (4-9)
packages/editor/src/core/components/editors/link-view-container.tsx (1)
  • LinkViewContainer (12-126)
packages/editor/src/core/helpers/get-extension-storage.ts (4)
packages/editor/src/core/extensions/custom-image/custom-image.ts (1)
  • UploadImageExtensionStorage (35-41)
packages/editor/src/core/extensions/custom-link/extension.tsx (1)
  • CustomLinkStorage (76-79)
packages/editor/src/core/extensions/headers.ts (1)
  • HeadingExtensionStorage (11-13)
packages/editor/src/core/extensions/mentions/extension-config.ts (1)
  • MentionExtensionStorage (15-17)
web/core/constants/editor.ts (1)
packages/editor/src/core/constants/common.ts (1)
  • ToolbarMenuItem (34-42)
packages/editor/src/core/components/editors/link-view-container.tsx (1)
packages/editor/src/core/components/links/link-view.tsx (2)
  • LinkViewProps (8-16)
  • LinkView (18-39)
packages/editor/src/core/components/links/link-edit-view.tsx (2)
packages/editor/src/core/components/links/link-view.tsx (2)
  • LinkViewProps (8-16)
  • LinkViews (6-6)
packages/editor/src/core/helpers/common.ts (1)
  • isValidHttpUrl (47-89)
packages/editor/src/core/components/links/link-view.tsx (2)
packages/editor/src/core/components/links/link-preview.tsx (1)
  • LinkPreview (5-56)
packages/editor/src/core/components/links/link-edit-view.tsx (1)
  • LinkEditView (36-149)
packages/editor/src/core/components/editors/document/page-renderer.tsx (2)
packages/editor/src/core/components/editors/editor-container.tsx (1)
  • EditorContainer (20-94)
packages/editor/src/core/components/menus/bubble-menu/root.tsx (1)
  • EditorBubbleMenu (48-216)
packages/editor/src/core/constants/common.ts (1)
web/core/constants/editor.ts (1)
  • ToolbarMenuItem (40-48)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (56)
packages/editor/src/core/components/menus/menu-items.ts (1)

145-146:

❓ Verification inconclusive

Potential inconsistency between key name and isActive check.

While you've updated the key and type parameter from "strike" to "strikethrough", the isActive method on line 148 still checks for editor?.isActive("strike"). This could lead to unexpected behavior if the underlying editor implementation also changes.


🏁 Script executed:

#!/bin/bash
# Check if "strike" is used consistently in the codebase
echo "Searching for 'isActive(\"strike\")' in the codebase:"
rg 'isActive\(.*\"strike\"' --type ts --type tsx -A 3 -B 3

echo -e "\nChecking if there are other instances of strikethrough vs strike naming:"
rg "strikethrough|strike" --type ts --type tsx --files-with-matches

Length of output: 539


#!/bin/bash
# Re-run search for isActive usage with corrected regex and file globbing for both TS and TSX files
echo "Searching for 'isActive(\"strike\")' usage in TS/TSX files:"
rg 'isActive\("strike"' --glob "*.ts" --glob "*.tsx" -A 3 -B 3

echo -e "\nSearching for 'isActive(\"strikethrough\")' usage in TS/TSX files:"
rg 'isActive\("strikethrough"' --glob "*.ts" --glob "*.tsx" -A 3 -B 3

Action: Update isActive parameter for consistency

It appears that the menu item key has been updated to "strikethrough" in
packages/editor/src/core/components/menus/menu-items.ts (line 145), but the
isActive check (line 148) still references "strike". This discrepancy could
cause unexpected behavior in the editor’s active state detection.

  • Recommendation: Change the parameter in the isActive call from "strike" to "strikethrough" if that change is intentional.
  • Next Step: Please run the above script and ensure there are no lingering references to "strike" where "strikethrough" is expected.
packages/editor/src/core/components/editors/editor-content.tsx (1)

2-2: LGTM! Simple import reordering.

This change just reorders the imports without affecting functionality.

packages/editor/src/core/extensions/read-only-extensions.tsx (1)

90-90:

✅ Verification successful

Updated URL validation to use new object return structure.

The change reflects an enhancement to the isValidHttpUrl function, which now returns an object with an isValid property instead of just a boolean. This change supports better URL validation and aligns with the PR's goal of improving link handling.


🏁 Script executed:

#!/bin/bash
# Check the implementation of isValidHttpUrl function
echo "Checking the implementation of isValidHttpUrl:"
rg "function isValidHttpUrl" -A 15 -B 5

# Verify if all instances of isValidHttpUrl usage have been updated
echo -e "\nChecking all usages of isValidHttpUrl:"
rg "isValidHttpUrl\(" -A 2 -B 2

Length of output: 2612


URL Validation Update Verified

The updated implementation of the isValidHttpUrl function now returning an object with an isValid property has been verified across the codebase. Specifically, in packages/editor/src/core/extensions/read-only-extensions.tsx, the code:

validate: (url: string) => isValidHttpUrl(url).isValid,

is implemented correctly. All usages—including those in link-selector.tsx, extensions.tsx, link-edit-view.tsx, and core-without-props.ts—consistently apply the new return structure, aligning well with the PR's objectives.

.gitignore (2)

91-91: LGTM! Added dev-editor directory to gitignore.

Adding the dev-editor directory to .gitignore is appropriate for excluding development-specific editor files from version control.


94-94: LGTM! Added Redis compressed database files to gitignore.

Adding compressed Redis database files (*.rdb.gz) to .gitignore is appropriate to prevent these large binary files from being committed.

packages/editor/src/core/extensions/core-without-props.ts (1)

69-69: Updated URL validation logic.

The validation logic now accesses the isValid property from the isValidHttpUrl function's return value, suggesting the function now returns an object with additional information rather than a simple boolean.

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

2-3: Reorganized import statements.

The import of InsertImageComponentProps has been moved to a dedicated types section, improving code organization.

packages/editor/src/core/extensions/image/extension.tsx (1)

3-4: Reorganized import statements.

The import of CustomImageNode has been moved to a dedicated extensions section, improving code organization.

packages/editor/src/core/extensions/extensions.tsx (1)

105-105: Updated URL validation logic.

The validation logic now accesses the isValid property from the isValidHttpUrl function's return value, consistent with the changes in core-without-props.ts. This ensures that link validation behavior is consistent across all editor variants.

packages/editor/src/core/extensions/custom-image/components/image-node.tsx (2)

5-5: Improved type safety with centralized extension storage access.

The addition of the getExtensionStorage helper function improves type safety and follows good coding practices by centralizing access to extension storage.


80-80: Good refactoring of extension storage access.

Replacing direct access to editor.storage.imageComponent.maxFileSize with getExtensionStorage(editor, "imageComponent").maxFileSize improves code organization and type safety while maintaining the same functionality.

packages/editor/src/core/extensions/custom-image/custom-image.ts (1)

38-40: Enhanced state management with additional storage properties.

The addition of these properties to the UploadImageExtensionStorage interface provides better state management capabilities:

  • deletedImageSet - Efficiently tracks deleted images
  • uploadInProgress - Tracks ongoing upload operations
  • maxFileSize - Sets upload size limits

These changes support the PR objective of making components more generic and reusable across editors.

packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx (1)

26-35: Improved link validation with automatic protocol handling.

The changes to the handleLinkSubmit function significantly improve link handling:

  1. Using isValidHttpUrl centralizes validation logic
  2. Making url constant improves immutability
  3. The new approach automatically adds HTTPS protocol when none is specified
  4. Security is enhanced by checking for potentially dangerous protocols

This directly supports the PR objective of making floating links generic and more user-friendly.

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

11-13: Enhanced type safety with explicit storage type definition.

Adding the HeadingExtensionStorage type improves code clarity and type safety by explicitly defining the structure of the extension's storage.

packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (1)

55-57: Storage properties extended for better image management

The additions to the storage object enhance image handling capabilities by adding tracking for deleted images, upload progress state, and file size limitations.

packages/editor/src/core/helpers/get-extension-storage.ts (1)

1-24: Great utility function for type-safe extension storage access

This helper function centralizes and type-checks extension storage access, which improves code maintainability and prevents type errors when accessing different extension storage objects.

The implementation uses TypeScript's type system effectively by:

  1. Defining a union type for valid extension names
  2. Creating a map between extension names and their storage types
  3. Using generics to ensure type safety when retrieving storage

This approach is much safer than directly accessing editor.storage[extensionName] without type checking.

web/core/constants/editor.ts (1)

96-96: Standardized command naming from "strike" to "strikethrough"

This change makes the type definition consistent with the semantic meaning of the command.

packages/editor/src/core/components/menus/bubble-menu/root.tsx (3)

94-94: Support for imageComponent in bubble menu visibility

This addition ensures the bubble menu correctly handles both standard images and custom image components.


110-110: Consistent cleanup of link state on menu hide

This change ensures the link state is properly reset when the bubble menu is hidden, preventing stale UI states.


106-108:

✅ Verification successful

Added link state management during bubble menu events

Setting the bubble menu state in link storage enables better coordination between link behavior and bubble menu visibility.


🏁 Script executed:

#!/bin/bash
# Verify that the link storage is properly initialized before being accessed

echo "Checking if CustomLinkStorage initializes isBubbleMenuOpen property..."
ast-grep --pattern $'export (type|interface) CustomLinkStorage = {
  $$$
  isBubbleMenuOpen: boolean;
  $$$
}'

# If not found directly, check for any initialization of the property
if [ $? -ne 0 ]; then
  echo "Searching for alternative initialization of isBubbleMenuOpen..."
  rg "isBubbleMenuOpen" --type ts --type tsx packages/editor/src/
fi

Length of output: 280


Link State Management Confirmed and Approved

The state update in the onShow handler is correctly implemented. Our verification confirms that the CustomLinkStorage interface/type initializes the isBubbleMenuOpen property, ensuring that this new link state management is safe and effective.

packages/editor/src/core/components/editors/editor-container.tsx (2)

22-22: LGTM! Reference needed for link view integration.

Adding a container reference is necessary to properly integrate with the LinkViewContainer component, which needs a reference to attach event listeners.


72-92: Good improvement: Extracted link preview functionality.

The restructuring of the component to wrap the div in fragments and include the LinkViewContainer improves the separation of concerns, moving the link preview functionality to a dedicated component.

This change allows for:

  • Better maintainability as link handling logic is now isolated
  • Consistent link preview behavior across editors
  • Cleaner component structure
packages/editor/src/core/helpers/common.ts (1)

47-89:

✅ Verification successful

Enhanced URL validation with protocol safety and automatic HTTPS.

This is a significant improvement to the URL validation function. Instead of just returning a boolean, it now returns both the validity status and a potentially modified URL.

Key improvements:

  1. Blocks potentially dangerous protocols (javascript:, data:, etc.)
  2. Automatically adds "https://" when a protocol is missing
  3. Provides more detailed feedback through the return object

Let's verify that the implementation correctly handles all edge cases:


🏁 Script executed:

#!/bin/bash
# Test the URL validation with various inputs

echo "Testing URL validation scenarios:"
echo "---------------------------------"

echo "1. Valid URLs with protocols:"
echo "https://example.com should be valid"
echo "http://subdomain.example.com should be valid"
echo "ftp://files.example.com should be valid"

echo "2. Valid domains without protocols:"
echo "example.com should be valid and prefixed with https://"
echo "subdomain.example.com should be valid and prefixed with https://"

echo "3. Blocked protocols:"
echo "javascript:alert(1) should be invalid"
echo "data:text/html,<script>alert(1)</script> should be invalid"
echo "vbscript:alert(1) should be invalid"
echo "file:///etc/passwd should be invalid"
echo "about:blank should be invalid"

echo "4. Invalid URLs:"
echo "not a url should be invalid"
echo "https:/example.com (missing slash) should be invalid"
echo "://example.com (missing protocol) should be invalid"

Length of output: 1662


Enhanced URL Validation: Implementation Approved

The updated isValidHttpUrl function in packages/editor/src/core/helpers/common.ts (lines 47–89) now correctly handles the edge cases:

  • Blocked Dangerous Protocols: The function reliably detects and rejects dangerous protocols such as javascript:, data:, vbscript:, file:, and about:.
  • Automatic HTTPS Handling: If the input string lacks a protocol or fails validation initially, the function automatically prepends https:// and returns the corrected URL.
  • Detailed Feedback: The return object provides both the validity status and the final URL, offering clearer insights into the URL processing.

Verification with the test scenarios confirms that all intended cases—from valid URLs and domain inputs to blocked and malformed strings—are properly managed.

packages/editor/src/core/extensions/mentions/extension-config.ts (2)

15-17: LGTM! Added storage type for managing mention state.

Adding a proper type definition for the extension storage helps with type safety and ensures proper integration with the editor.


19-19: Enhanced type parameters for better type safety.

Extending the Mention extension with proper type parameters for both options and storage improves type checking and makes the code more maintainable.

packages/editor/src/core/extensions/image/image-component-without-props.tsx (3)

4-4: LGTM! Updated import for consistent naming.

The rename from UploadImageExtensionStorage to ImageExtensionStorage improves naming consistency across the codebase.


7-7: Updated type parameter for extension storage.

The extension's type parameter now uses the renamed ImageExtensionStorage type, maintaining type safety after the import change.


51-52: Added tracking for upload state and size limits.

New storage properties improve the image upload experience:

  1. uploadInProgress - Allows tracking when an upload is happening
  2. maxFileSize - Enables validation of file size limits

These additions will help provide better feedback to users during the upload process and prevent oversized file uploads.

packages/editor/src/core/components/links/link-preview.tsx (6)

3-3: Good type update for better consistency

The import now uses the LinkViews type, matching the broader changes being made to standardize link functionality across editors.


10-10: Improved typing for better type safety

Changing from string literals to the LinkViews type enhances maintainability and ensures consistency with the type system.


25-31: Good animation enhancement

Adding animation effects to the link preview improves the user experience by providing visual feedback when previews appear. The cubic-bezier timing function creates a professional, smooth transition.


34-34: Improved null safety with optional chaining

Using optional chaining for URL length check prevents potential runtime errors if the URL is undefined or null.


36-36: Enhanced button styling with hover effects

Adding hover effects to the buttons provides better visual feedback to users, improving the overall interaction experience.

Also applies to: 43-44, 47-47


39-51: Good conditional rendering based on editor state

Only showing edit and remove buttons when the editor is editable is a logical improvement that prevents users from attempting to modify links in read-only mode.

packages/editor/src/core/extensions/custom-link/extension.tsx (3)

76-79: Good addition of storage type for state management

Creating a dedicated CustomLinkStorage type provides a well-structured way to manage link-related state, improving type safety and code organization.


81-81: Updated extension with proper generic type

Using the new CustomLinkStorage type as a generic parameter to Mark.create ensures type safety for the extension's storage.


251-257: Well-implemented storage initialization

The addStorage method properly initializes the extension's state with sensible defaults. This is crucial for the generic floating link functionality to work correctly across all editors.

packages/editor/src/core/constants/common.ts (1)

90-90: Improved naming consistency

Changing from "strike" to "strikethrough" standardizes terminology across the codebase, making it more consistent and intuitive. This naming better aligns with standard text formatting conventions.

Also applies to: 116-116

packages/editor/src/core/components/editors/document/page-renderer.tsx (2)

1-1: Simplified imports

Removing unnecessary imports makes the code cleaner and indicates better separation of concerns.


22-38: Good separation of link preview functionality

Removing the link preview logic from the PageRenderer component and moving it to a dedicated component (as mentioned in the PR summary) follows the Single Responsibility Principle. This makes the code more maintainable and reusable across different editors.

packages/editor/src/core/types/editor.ts (3)

35-35: Terminology correction enhances consistency

Changing from "strike" to "strikethrough" makes the naming more consistent with standard text formatting terminology, which improves code readability.


134-134: Good addition of bubble menu configuration

Adding bubbleMenuEnabled to the base IEditorProps makes this functionality configurable across all editor types, providing better flexibility.


200-210: Great addition of structured event interface

The new EditorEvents interface provides a clear contract for all editor lifecycle events. This typed approach improves code safety and developer experience when handling editor events.

packages/editor/src/core/components/links/link-view.tsx (4)

6-6: Good type alias for better type safety

Creating a dedicated LinkViews type alias improves code readability and type safety by explicitly defining the allowed view types.


14-14: Useful enhancement for link display

Adding the optional text property enables more flexibility for displaying link content, which will be helpful when editing links.


19-19: Improved default view selection

Defaulting to "LinkPreview" instead of "LinkInputView" provides a better user experience by showing the preview first before editing.


33-38: Simplified rendering with conditional logic

Replacing the switch statement with conditional rendering makes the code more concise and easier to understand. The removal of the "LinkInputView" case aligns with the new simplified approach.

packages/editor/src/core/components/links/link-edit-view.tsx (5)

9-15: Improved input component props

Converting from defaultValue to value changes this to a controlled component, giving you better control over the input state. The addition of autoFocus improves user experience.


22-26: Event propagation handled correctly

Adding stopPropagation() on the click event prevents unwanted interactions with underlying editor elements, which could cause unexpected behavior.


40-44: Well-structured state management

Using multiple state variables with clear purposes and a ref to track submission status improves the component's maintainability and predictability.


74-106: Robust link update implementation

The applyChanges function properly handles URL validation, text updates, and mark restoration. This implementation correctly preserves the editor state while making changes.

One improvement to note is the use of the isValidHttpUrl helper which will now automatically prefix URLs with "https://" if no protocol is specified, fulfilling the PR objective.


114-126: Good keyboard handling for form submission

Adding the Enter key handler improves user experience by providing a familiar way to submit the form. The implementation also correctly prevents event propagation and handles the editor state.

packages/editor/src/core/components/editors/link-view-container.tsx (4)

24-41: Excellent use of floating-ui for positioning

The implementation of floating UI with appropriate middleware (flip, shift, hide) ensures that the link preview is always visible within the viewport and positioned correctly relative to the link.


47-96: Well-implemented link hover detection

The handleLinkHover function correctly:

  1. Detects hovering over links
  2. Handles editor view state properly
  3. Extracts link information from the document
  4. Sets up the correct props for the link view
  5. Includes error handling for robustness

This implementation provides a seamless user experience for link interactions.


99-108: Proper event listener management

The event listeners are correctly added to the container and properly cleaned up when the component unmounts, preventing memory leaks.


110-115: Good coordination with bubble menu

Closing the link view when the bubble menu opens prevents UI conflicts and improves the user experience by avoiding overlapping interactive elements.

@pushya22 pushya22 changed the title feat: make floating link generic and use it for all editors [PE-304] feat: make floating link generic and use it for all editors Apr 2, 2025
Copy link

makeplane bot commented Apr 2, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

@sriramveeraghanta sriramveeraghanta merged commit a57c37c into preview Apr 2, 2025
5 of 6 checks passed
@sriramveeraghanta sriramveeraghanta deleted the feat/link-button branch April 2, 2025 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants