Link plugin for Plate rich text editor providing hyperlink functionality with URL validation, keyboard shortcuts, and UI 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.
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 encodingtarget: Target attribute (if specified)rel: Security attributes for external linksonClick: Click handler for editor integrationonMouseDown: Mouse event handlingHook 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-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>
);
}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>
);
}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;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>
);
}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