{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "api-resizable-docs",
  "title": "Resizable",
  "description": "API reference for @platejs/resizable.",
  "files": [
    {
      "path": "../../content/docs/api/resizable.mdx",
      "content": "---\ntitle: Resizable\ndescription: API reference for @platejs/resizable.\n---\n\n`@platejs/resizable` provides the headless resize wrapper, resize handle primitive,\nshared resize stores, and length utilities used by Plate media components. It\nowns behavior; registry components own styling.\n\n## Installation\n\n```bash\nnpm install @platejs/resizable\n```\n\n## Ownership\n\n| Surface | Owner | Use |\n| --- | --- | --- |\n| `Resizable` | `@platejs/resizable` | Wraps a Plate element, tracks width, clamps resize values, and writes the final width to the node. |\n| `ResizeHandle` | `@platejs/resizable` | Primitive handle that starts mouse/touch resizing and emits `ResizeEvent` values. |\n| `ResizableProvider` | `@platejs/resizable` | Stores the active width for the current resizable subtree. |\n| `ResizeHandleProvider` | `@platejs/resizable` | Shares the wrapper `onResize` callback with nested handles. |\n| Resize hooks | `@platejs/resizable` | Split state from DOM props for custom wrappers and handles. |\n| Length utilities | `@platejs/resizable` | Convert and clamp static pixel widths and relative percent widths. |\n\n## Media Pattern\n\nWrap each resizable element with `ResizableProvider`. Media components use the\nprovider width for captions and use `Resizable` plus left/right handles around\nthe media body.\n\n```tsx title=\"Resizable media element\"\nimport type { TImageElement } from 'platejs';\nimport type { PlateElementProps } from 'platejs/react';\n\nimport {\n  Resizable,\n  ResizableProvider,\n  ResizeHandle,\n  useResizableValue,\n} from '@platejs/resizable';\nimport { PlateElement, withHOC } from 'platejs/react';\n\nexport const ImageElement = withHOC(\n  ResizableProvider,\n  function ImageElement(props: PlateElementProps<TImageElement>) {\n    const width = useResizableValue('width');\n\n    return (\n      <PlateElement {...props}>\n        <figure contentEditable={false}>\n          <Resizable\n            options={{\n              align: 'center',\n              maxWidth: '100%',\n              minWidth: 120,\n            }}\n          >\n            <ResizeHandle options={{ direction: 'left' }} />\n            <img alt=\"\" src={props.element.url as string} />\n            <ResizeHandle options={{ direction: 'right' }} />\n          </Resizable>\n\n          <figcaption style={{ width }}>Caption</figcaption>\n        </figure>\n\n        {props.children}\n      </PlateElement>\n    );\n  }\n);\n```\n\nThe registry `resize-handle` component imports these primitives and adds the absolute positioning, hover affordance, and alignment classes.\n\n## Resizable Wrapper\n\n`Resizable` composes `useResizableState` and `useResizable`. It renders a\nrelative outer wrapper and a relative inner wrapper, then provides its resize\ncallback to descendants through `ResizeHandleProvider`.\n\n<API name=\"Resizable\">\n<APIOptions type=\"{ options: ResizableOptions } & React.HTMLAttributes<HTMLDivElement>\">\n  <APIItem name=\"options\" type=\"ResizableOptions\" required>\n    Width constraints and alignment used by the resize calculation.\n  </APIItem>\n  <APIItem name=\"children\" type=\"React.ReactNode\" optional>\n    Media body, resize handles, or custom controls.\n  </APIItem>\n</APIOptions>\n</API>\n\n<API name=\"useResizableState\">\n<APIOptions type=\"ResizableOptions\">\n  <APIItem name=\"align\" type=\"'center' | 'left' | 'right'\" optional>\n    Alignment used to calculate resize delta. Defaults to `center`.\n  </APIItem>\n  <APIItem name=\"maxWidth\" type=\"ResizeLength\" optional>\n    Maximum width. Defaults to `100%`.\n  </APIItem>\n  <APIItem name=\"minWidth\" type=\"ResizeLength\" optional>\n    Minimum width. Defaults to `92`.\n  </APIItem>\n  <APIItem name=\"readOnly\" type=\"boolean\" optional>\n    Reserved in the options type. `Resizable` itself does not read this value.\n  </APIItem>\n</APIOptions>\n<APIReturns type=\"ReturnType<typeof useResizableState>\">\n  <APIItem name=\"align\" type=\"'center' | 'left' | 'right'\">\n    Alignment used by resize math.\n  </APIItem>\n  <APIItem name=\"maxWidth\" type=\"ResizeLength\">\n    Maximum width passed to the wrapper style and clamp utility.\n  </APIItem>\n  <APIItem name=\"minWidth\" type=\"ResizeLength\">\n    Minimum width passed to the wrapper style and clamp utility.\n  </APIItem>\n  <APIItem name=\"setNodeWidth\" type=\"(width: number) => void\">\n    Writes the finished width to the current `TResizableElement`. If the width is unchanged, it selects the node.\n  </APIItem>\n  <APIItem name=\"setWidth\" type=\"(width: React.CSSProperties['width']) => void\">\n    Updates the transient provider width while dragging.\n  </APIItem>\n  <APIItem name=\"width\" type=\"React.CSSProperties['width']\">\n    Current provider width. It is synced from `element.width ?? '100%'`.\n  </APIItem>\n</APIReturns>\n</API>\n\n<API name=\"useResizable\">\n<APIParameters>\n  <APIItem name=\"state\" type=\"ReturnType<typeof useResizableState>\">\n    State returned by `useResizableState`.\n  </APIItem>\n</APIParameters>\n<APIReturns type=\"object\">\n  <APIItem name=\"context.onResize\" type=\"(event: ResizeEvent) => void\">\n    Converts a handle delta into a new width, clamps it, stores it while dragging, and writes it to the node when `finished` is true.\n  </APIItem>\n  <APIItem name=\"props\" type=\"{ style: React.CSSProperties }\">\n    Inner wrapper props with `position: 'relative'`, `width`, `minWidth`, and `maxWidth`.\n  </APIItem>\n  <APIItem name=\"wrapperProps\" type=\"{ style: React.CSSProperties }\">\n    Outer wrapper props with `position: 'relative'`.\n  </APIItem>\n  <APIItem name=\"wrapperRef\" type=\"React.RefObject<HTMLDivElement>\">\n    Measures the static wrapper width for percent-to-pixel conversion.\n  </APIItem>\n</APIReturns>\n</API>\n\nFor centered elements, left and right handles double the delta so the element grows from both sides. Left handles invert the delta before clamping.\n\n## Resize Handles\n\n`ResizeHandle` is a primitive `div` created with `createPrimitiveComponent`. It\nreturns `null` in read-only mode because `useResizeHandle` sets `hidden` from\n`useReadOnly()`.\n\n<API name=\"ResizeHandle\">\n<APIOptions type=\"ResizeHandleProps\">\n  <APIItem name=\"options\" type=\"ResizeHandleOptions\" optional>\n    Direction, initial size, and lifecycle callbacks for the handle.\n  </APIItem>\n  <APIItem name=\"state\" type=\"ReturnType<typeof useResizeHandleState>\" optional>\n    Precomputed state when composing your own handle pipeline.\n  </APIItem>\n</APIOptions>\n</API>\n\n<API name=\"useResizeHandleState\">\n<APIOptions type=\"ResizeHandleOptions\">\n  <APIItem name=\"direction\" type=\"ResizeDirection\" optional>\n    Resize edge. Defaults to `left`.\n  </APIItem>\n  <APIItem name=\"initialSize\" type=\"number\" optional>\n    Starting width or height. If omitted, the handle reads its parent element on pointer start.\n  </APIItem>\n  <APIItem name=\"onHover\" type=\"() => void\" optional>\n    Called on mouse over and touch move.\n  </APIItem>\n  <APIItem name=\"onHoverEnd\" type=\"() => void\" optional>\n    Called after hover ends or resizing finishes.\n  </APIItem>\n  <APIItem name=\"onMouseDown\" type=\"React.MouseEventHandler\" optional>\n    Called after the hook records the starting pointer position and size.\n  </APIItem>\n  <APIItem name=\"onResize\" type=\"(event: ResizeEvent) => void\" optional>\n    Resize callback. Defaults to the nearest `ResizeHandleProvider` value.\n  </APIItem>\n  <APIItem name=\"onTouchStart\" type=\"React.TouchEventHandler\" optional>\n    Called after the hook records the starting touch position and size.\n  </APIItem>\n</APIOptions>\n<APIReturns type=\"ReturnType<typeof useResizeHandleState>\">\n  Direction, pointer state, horizontal/vertical mode, read-only state, setters, and callbacks consumed by `useResizeHandle`.\n</APIReturns>\n</API>\n\n<API name=\"useResizeHandle\">\n<APIParameters>\n  <APIItem name=\"state\" type=\"ReturnType<typeof useResizeHandleState>\">\n    State returned by `useResizeHandleState`.\n  </APIItem>\n</APIParameters>\n<APIReturns type=\"object\">\n  <APIItem name=\"hidden\" type=\"boolean\">\n    `true` while the editor is read-only.\n  </APIItem>\n  <APIItem name=\"props\" type=\"React.HTMLAttributes<HTMLDivElement>\">\n    Mouse and touch handlers for starting resize, tracking hover, and finishing resize.\n  </APIItem>\n</APIReturns>\n</API>\n\nResize handles listen on `window` while dragging. Mouse and touch move events emit `finished: false`; mouse up and touch end emit `finished: true`.\n\n## Stores\n\n| API | State | Use |\n| --- | --- | --- |\n| `ResizableProvider` | `{ width: React.CSSProperties['width'] }` | Wrap a resizable node and expose the active width to captions or overlays. |\n| `useResizableValue('width')` | `React.CSSProperties['width']` | Read the current width. |\n| `useResizableSet('width')` | setter | Set the current width. |\n| `useResizableStore` / `resizableStore` | atom store | Advanced access to the resizable store. |\n| `ResizeHandleProvider` | `{ onResize: (event: ResizeEvent) => void }` | Provides the wrapper resize callback to nested handles. |\n| `useResizeHandleValue('onResize')` | callback | Read the current resize callback. |\n| `useResizeHandleSet('onResize')` | setter | Replace the current resize callback. |\n| `useResizeHandleStore` | atom store | Advanced access to the handle store. |\n\n## Types\n\n| Type | Value |\n| --- | --- |\n| `ResizeDirection` | `'bottom' \\| 'left' \\| 'right' \\| 'top'` |\n| `ResizeLength` | `number \\| string` |\n| `ResizeLengthStatic` | `number` |\n| `ResizeLengthRelative` | `string` |\n| `ResizeEvent` | `{ delta: number; direction: ResizeDirection; finished: boolean; initialSize: number }` |\n\n## Length Utilities\n\n<API name=\"Length utilities\">\n<APIMethods>\n  <APIItem name=\"resizeLengthClampStatic\" type=\"(length: number, options: { min?: number; max?: number }) => number\">\n    Clamps a pixel length to pixel min/max values.\n  </APIItem>\n  <APIItem name=\"resizeLengthClamp\" type=\"<T extends ResizeLength>(length: T, parentLength: number, options: { min?: ResizeLength; max?: ResizeLength }) => T\">\n    Converts length and constraints to pixels, clamps the value, then returns the same length kind as the input.\n  </APIItem>\n  <APIItem name=\"resizeLengthToRelative\" type=\"(length: ResizeLength, parentLength: number) => string\">\n    Converts a pixel length to a percent string. Percent strings pass through unchanged.\n  </APIItem>\n  <APIItem name=\"resizeLengthToStatic\" type=\"(length: ResizeLength, parentLength: number) => number\">\n    Converts a percent string to pixels. Numbers pass through unchanged.\n  </APIItem>\n  <APIItem name=\"isTouchEvent\" type=\"(event: MouseEvent | TouchEvent) => event is TouchEvent\">\n    Narrows pointer events by checking for `touches`.\n  </APIItem>\n</APIMethods>\n</API>\n\n`resizeLengthToStatic` parses strings as percentages. Use numeric pixel lengths when the source value is not a percentage.\n\n## Related Components\n\n- [Media](/docs/media) covers the image, video, audio, and embed elements that consume the resizable primitives.\n- [Resize Handle](/docs/components/resize-handle) covers the styled registry wrapper.\n",
      "type": "registry:file",
      "target": "content/docs/plate/api/resizable.mdx"
    }
  ],
  "type": "registry:file"
}