Plate React resize components for making editor elements resizable through drag handles within the Plate rich text editor ecosystem.
npx @tessl/cli install tessl/npm-udecode--plate-resizable@49.0.0Plate Resizable provides React components for implementing resizable functionality within the Plate rich text editor ecosystem. It enables users to resize elements like images, tables, or other media through drag handles with proper state management and editor integration.
npm install @udecode/plate-resizableimport { Resizable, ResizeHandle } from "@udecode/plate-resizable";For CommonJS:
const { Resizable, ResizeHandle } = require("@udecode/plate-resizable");import React from 'react';
import { Resizable, ResizeHandle } from "@udecode/plate-resizable";
function MyResizableComponent() {
return (
<Resizable options={{ align: 'center', minWidth: 100, maxWidth: '80%' }}>
<div style={{ background: '#f0f0f0', padding: '20px' }}>
<p>This content can be resized!</p>
<ResizeHandle direction="right" />
<ResizeHandle direction="left" />
</div>
</Resizable>
);
}Plate Resizable is built around several key components:
The main component that wraps content to make it resizable with configurable constraints and alignment options.
interface ResizableOptions {
/** Node alignment. */
align?: 'center' | 'left' | 'right';
maxWidth?: ResizeLength;
minWidth?: ResizeLength;
readOnly?: boolean;
}
const Resizable: React.ForwardRefExoticComponent<{
options: ResizableOptions;
} & React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;Hooks for managing resizable state and behavior, typically used internally by the Resizable component.
function useResizableState(options?: ResizableOptions): {
align: 'center' | 'left' | 'right';
maxWidth: ResizeLength;
minWidth: ResizeLength;
setNodeWidth: (w: number) => void;
setWidth: (w: ResizeLength) => void;
width: ResizeLength;
};
function useResizable(state: ReturnType<typeof useResizableState>): {
context: {
onResize: (event: ResizeEvent) => void;
};
props: {
style: React.CSSProperties;
};
wrapperProps: {
style: React.CSSProperties;
};
wrapperRef: React.RefObject<HTMLDivElement>;
};Interactive handle component that users drag to resize elements, with support for different directions and touch events.
interface ResizeHandleOptions {
direction?: ResizeDirection;
initialSize?: number;
onHover?: () => void;
onHoverEnd?: () => void;
onMouseDown?: React.MouseEventHandler;
onResize?: (event: ResizeEvent) => void;
onTouchStart?: React.TouchEventHandler;
}
const ResizeHandle: React.ComponentType<
Omit<React.HTMLAttributes<HTMLDivElement>, 'onResize'> &
ResizeHandleOptions
>;
type ResizeHandleProps = React.ComponentPropsWithRef<typeof ResizeHandle>;Hooks for managing resize handle state and interactions.
function useResizeHandleState(options: ResizeHandleOptions): {
direction: ResizeDirection;
initialPosition: number;
initialSize: number;
isHorizontal: boolean;
isResizing: boolean;
readOnly: boolean;
setInitialPosition: (pos: number) => void;
setInitialSize: (size: number) => void;
setIsResizing: (resizing: boolean) => void;
onHover?: () => void;
onHoverEnd?: () => void;
onMouseDown?: React.MouseEventHandler;
onResize: (event: ResizeEvent) => void;
onTouchStart?: React.TouchEventHandler;
};
function useResizeHandle(state: ReturnType<typeof useResizeHandleState>): {
hidden: boolean;
props: {
onMouseDown: React.MouseEventHandler;
onMouseOut: () => void;
onMouseOver: () => void;
onTouchEnd: () => void;
onTouchMove: () => void;
onTouchStart: React.TouchEventHandler;
};
};Context providers and hooks for managing resizable state across components.
// Resizable store
const ResizableProvider: React.ComponentType<React.PropsWithChildren<{}>>;
const resizableStore: any; // Jotai atom store instance
function useResizableSet<K extends keyof ResizableStoreState>(field: K, value: ResizableStoreState[K]): void;
function useResizableStore(): ResizableStoreState;
function useResizableValue<K extends keyof ResizableStoreState>(field: K): ResizableStoreState[K];
interface ResizableStoreState {
width: React.CSSProperties['width'];
}
// ResizeHandle store
interface ResizeHandleStoreState {
onResize: ((event: ResizeEvent) => void) | null;
}
const ResizeHandleProvider: React.ComponentType<React.PropsWithChildren<ResizeHandleStoreState>>;
function useResizeHandleSet<K extends keyof ResizeHandleStoreState>(field: K, value: ResizeHandleStoreState[K]): void;
function useResizeHandleStore(): ResizeHandleStoreState;
function useResizeHandleValue<K extends keyof ResizeHandleStoreState>(field: K): ResizeHandleStoreState[K];Helper functions for converting between different length formats and applying constraints.
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent;
interface ResizeLengthClampOptions<T = ResizeLength> {
max?: T;
min?: T;
}
function resizeLengthClamp<T extends ResizeLength>(
length: T,
parentLength: number,
options: ResizeLengthClampOptions<ResizeLength>
): T;
function resizeLengthClampStatic(
length: ResizeLengthStatic,
options: ResizeLengthClampOptions<ResizeLengthStatic>
): ResizeLengthStatic;
function resizeLengthToRelative(
length: ResizeLength,
parentLength: number
): ResizeLengthRelative;
function resizeLengthToStatic(
length: ResizeLength,
parentLength: number
): ResizeLengthStatic;type ResizeDirection = 'bottom' | 'left' | 'right' | 'top';
interface ResizeEvent {
delta: ResizeLengthStatic;
direction: ResizeDirection;
finished: boolean;
initialSize: ResizeLengthStatic;
}
type ResizeLength = ResizeLengthRelative | ResizeLengthStatic;
type ResizeLengthRelative = string;
type ResizeLengthStatic = number;