CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-udecode--plate-link

Link plugin for Plate rich text editor providing hyperlink functionality with URL validation, keyboard shortcuts, and UI components

Pending
Overview
Eval results
Files

react-components.mddocs/

React Components

Pre-built React components and hooks for creating link editing interfaces, toolbar buttons, and form inputs with full integration into the Plate editor ecosystem.

Capabilities

Link Element Hook

useLink

React hook for rendering link elements with proper event handling and attributes.

/**
 * React hook for link element rendering with event handling
 * @param props - Hook configuration with link element
 * @returns Props object for anchor element
 */
function useLink({ element }: { element: TLinkElement }): {
  props: React.AnchorHTMLAttributes<HTMLAnchorElement>;
};

Usage Examples:

import React from 'react';
import { useLink } from "@udecode/plate-link/react";

function LinkElement({ element, children }) {
  const { props } = useLink({ element });
  
  return (
    <a {...props}>
      {children}
    </a>
  );
}

// Usage in PlateContent rendering
function CustomLinkElement({ element, children, ...props }) {
  const { props: linkProps } = useLink({ element });
  
  return (
    <a 
      {...linkProps} 
      className="custom-link-style"
      onContextMenu={(e) => {
        // Custom context menu logic
        console.log('Right-clicked link:', element.url);
      }}
    >
      {children}
    </a>
  );
}

Generated Props:

  • href: Processed URL with encoding
  • target: Target attribute (if specified)
  • rel: Security attributes for external links
  • onClick: Click handler for editor integration
  • onMouseDown: Mouse event handling

Toolbar Integration

useLinkToolbarButton

Hook pair providing state and behavior for link toolbar buttons.

/**
 * Get toolbar button state based on current selection
 * @returns State object with pressed status
 */
function useLinkToolbarButtonState(): { pressed: boolean };

/**
 * Get toolbar button behavior and event handlers
 * @param state - State from useLinkToolbarButtonState
 * @returns Props object with click handlers
 */
function useLinkToolbarButton(
  state: ReturnType<typeof useLinkToolbarButtonState>
): {
  props: {
    pressed: boolean;
    onClick: () => void;
    onMouseDown: (e: React.MouseEvent) => void;
  };
};

Usage Examples:

import React from 'react';
import { 
  useLinkToolbarButtonState, 
  useLinkToolbarButton 
} from "@udecode/plate-link/react";

function LinkToolbarButton() {
  const state = useLinkToolbarButtonState();
  const { props } = useLinkToolbarButton(state);
  
  return (
    <button
      {...props}
      className={`toolbar-button ${props.pressed ? 'active' : ''}`}
      title="Add Link (Ctrl+K)"
    >
      🔗
    </button>
  );
}

// With custom styling and icons
function CustomLinkButton() {
  const state = useLinkToolbarButtonState();
  const { props } = useLinkToolbarButton(state);
  
  return (
    <button
      {...props}
      className={`btn ${props.pressed ? 'btn-active' : 'btn-default'}`}
    >
      <LinkIcon />
      {props.pressed ? 'Edit Link' : 'Add Link'}
    </button>
  );
}

Pre-built Form Components

FloatingLinkUrlInput

Pre-configured input component for URL entry with validation and state management.

/**
 * Get state for URL input component
 * @returns State object with input ref
 */
function useFloatingLinkUrlInputState(): { 
  ref: RefObject<HTMLInputElement> 
};

/**
 * Get props and behavior for URL input
 * @param state - State from useFloatingLinkUrlInputState
 * @returns Input props and ref
 */
function useFloatingLinkUrlInput(state: ReturnType<typeof useFloatingLinkUrlInputState>): {
  props: {
    defaultValue: string;
    onChange: ChangeEventHandler<HTMLInputElement>;
  };
  ref: RefObject<HTMLInputElement>;
};

/**
 * Pre-built URL input component
 */
const FloatingLinkUrlInput: React.FC;

Usage Examples:

import React from 'react';
import { 
  FloatingLinkUrlInput,
  useFloatingLinkUrlInputState,
  useFloatingLinkUrlInput
} from "@udecode/plate-link/react";

// Using pre-built component
function SimpleFloatingForm() {
  return (
    <div className="floating-link-form">
      <FloatingLinkUrlInput />
      <button type="submit">Save</button>
    </div>
  );
}

// Using hooks for custom component
function CustomUrlInput() {
  const state = useFloatingLinkUrlInputState();
  const { props, ref } = useFloatingLinkUrlInput(state);
  
  return (
    <div className="url-input-wrapper">
      <label htmlFor="url-input">URL:</label>
      <input
        {...props}
        ref={ref}
        id="url-input"
        className="url-input"
        placeholder="https://example.com"
        autoFocus
      />
    </div>
  );
}

FloatingLinkNewTabInput

Pre-configured checkbox component for new tab option.

/**
 * Get state for new tab checkbox component
 * @returns State object with checkbox state and ref
 */
function useFloatingLinkNewTabInputState(): {
  checked: boolean;
  ref: RefObject<HTMLInputElement>;
  setChecked: Dispatch<SetStateAction<boolean>>;
};

/**
 * Get props and behavior for new tab checkbox
 * @param state - State from useFloatingLinkNewTabInputState
 * @returns Checkbox props and ref
 */
function useFloatingLinkNewTabInput(
  state: ReturnType<typeof useFloatingLinkNewTabInputState>
): {
  props: {
    checked: boolean;
    type: 'checkbox';
    onChange: ChangeEventHandler<HTMLInputElement>;
  };
  ref: RefObject<HTMLInputElement>;
};

/**
 * Pre-built new tab checkbox component
 */
const FloatingLinkNewTabInput: React.FC;

Usage Examples:

import React from 'react';
import { 
  FloatingLinkNewTabInput,
  useFloatingLinkNewTabInputState,
  useFloatingLinkNewTabInput
} from "@udecode/plate-link/react";

// Using pre-built component
function FloatingFormWithNewTab() {
  return (
    <div className="floating-link-form">
      <FloatingLinkUrlInput />
      <label>
        <FloatingLinkNewTabInput />
        Open in new tab
      </label>
      <button type="submit">Save</button>
    </div>
  );
}

// Using hooks for custom component
function CustomNewTabCheckbox() {
  const state = useFloatingLinkNewTabInputState();
  const { props, ref } = useFloatingLinkNewTabInput(state);
  
  return (
    <div className="checkbox-wrapper">
      <input
        {...props}
        ref={ref}
        id="new-tab-checkbox"
        className="new-tab-checkbox"
      />
      <label htmlFor="new-tab-checkbox">
        Open link in new tab
      </label>
    </div>
  );
}

Deprecated Components

LinkOpenButton

Legacy component for opening links (deprecated in favor of direct link interaction).

/**
 * @deprecated Use direct link interaction instead
 * Get state for link open button
 */
function useLinkOpenButtonState(): { element?: TLinkElement };

/**
 * @deprecated Use direct link interaction instead
 * Get props for link open button
 */
function useLinkOpenButton({ element }: { element?: TLinkElement }): {
  props: React.AnchorHTMLAttributes<HTMLAnchorElement>;
};

/**
 * @deprecated Use direct link interaction instead
 * Pre-built link open button component
 */
const LinkOpenButton: React.FC;

Advanced Component Patterns

Custom Form Components

import React from 'react';
import { 
  useFloatingLinkUrlInputState,
  useFloatingLinkUrlInput,
  useFloatingLinkNewTabInputState,
  useFloatingLinkNewTabInput,
  submitFloatingLink
} from "@udecode/plate-link/react";
import { useEditorPlugin } from '@udecode/plate/react';
import { LinkPlugin } from '@udecode/plate-link/react';

function CustomFloatingLinkForm() {
  const { editor } = useEditorPlugin(LinkPlugin);
  
  const urlState = useFloatingLinkUrlInputState();
  const { props: urlProps, ref: urlRef } = useFloatingLinkUrlInput(urlState);
  
  const newTabState = useFloatingLinkNewTabInputState();
  const { props: newTabProps, ref: newTabRef } = useFloatingLinkNewTabInput(newTabState);
  
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const success = submitFloatingLink(editor);
    if (success) {
      console.log('Link submitted successfully');
    }
  };
  
  return (
    <form onSubmit={handleSubmit} className="floating-link-form">
      <div className="form-group">
        <label htmlFor="url">URL</label>
        <input
          {...urlProps}
          ref={urlRef}
          id="url"
          className="form-control"
          placeholder="Enter URL..."
        />
      </div>
      
      <div className="form-group">
        <label className="checkbox-label">
          <input
            {...newTabProps}
            ref={newTabRef}
            className="checkbox"
          />
          Open in new tab
        </label>
      </div>
      
      <div className="form-actions">
        <button type="submit" className="btn-primary">
          Save Link
        </button>
        <button 
          type="button" 
          onClick={() => editor.api.floatingLink.hide()}
          className="btn-secondary"
        >
          Cancel
        </button>
      </div>
    </form>
  );
}

Toolbar Integration

import React from 'react';
import { 
  useLinkToolbarButtonState,
  useLinkToolbarButton
} from "@udecode/plate-link/react";

function LinkToolbar() {
  const linkState = useLinkToolbarButtonState();
  const { props: linkProps } = useLinkToolbarButton(linkState);
  
  return (
    <div className="toolbar">
      <button
        {...linkProps}
        className={`toolbar-btn ${linkProps.pressed ? 'active' : ''}`}
        title="Link (Ctrl+K)"
      >
        <LinkIcon />
      </button>
    </div>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-udecode--plate-link

docs

core-plugin.md

floating-interface.md

index.md

react-components.md

react-integration.md

transforms.md

url-utils.md

tile.json