Back to Plate

Horizontal Rule

content/docs/(plugins)/(elements)/horizontal-rule.mdx

53.0.85.4 KB
Original Source

Horizontal Rule adds a void hr block for separating sections. The package owns the element type, HTML parser, default <hr> render tag, and Markdown-style input rules. The registry kit adds the Plate UI divider component, static renderer, and insert toolbar item.

<ComponentPreview name="basic-blocks-demo" /> <PackageInfo>

Features

  • Void block hr element.
  • HTML deserialization from <hr>.
  • Default render tag of <hr>.
  • --- and ___ input rules through HorizontalRuleRules.markdown().
  • Editable and static registry divider components.
  • Insert toolbar item labeled Divider.
</PackageInfo>

Fast Path

<Steps>

Add Basic Blocks

BasicBlocksKit installs HorizontalRulePlugin with the registry HrElement and both default input rules.

<ComponentSource name="basic-blocks-kit" />
tsx
import { createPlateEditor } from 'platejs/react';

import { BasicBlocksKit } from '@/components/editor/plugins/basic-blocks-kit';

export const editor = createPlateEditor({
  plugins: BasicBlocksKit,
});

Render The Divider

hr-node renders the editable divider with selected/focused ring styles and a static companion component.

<ComponentSource name="hr-node" />

Add Static Rendering

Use BaseBasicBlocksKit when rendering read-only content with platejs/static.

<ComponentSource name="basic-blocks-base-kit" /> </Steps>

Ownership

LayerOwnerWhat It Does
@platejs/basic-nodesPackageExports BaseHorizontalRulePlugin and HorizontalRuleRules.
@platejs/basic-nodes/reactPackageExports HorizontalRulePlugin.
basic-blocks-kitRegistryAdds HorizontalRulePlugin with dash and underscore input rules plus HrElement.
basic-blocks-base-kitRegistryAdds BaseHorizontalRulePlugin.withComponent(HrElementStatic).
hr-nodeRegistry UIRenders editable and static divider components.
Insert toolbarRegistry UIInserts KEYS.hr through the generic insertBlock path.

There is no package-specific insertHorizontalRule helper. App UI usually inserts KEYS.hr through the same block insertion helper used by other registry blocks.

Manual Setup

<Steps>

Install Package

bash
npm install @platejs/basic-nodes

Add The Plugin

Use the React plugin when the editor renders the divider UI.

tsx
import { HorizontalRuleRules } from '@platejs/basic-nodes';
import { HorizontalRulePlugin } from '@platejs/basic-nodes/react';
import { createPlateEditor } from 'platejs/react';

import { HrElement } from '@/components/ui/hr-node';

export const editor = createPlateEditor({
  plugins: [
    HorizontalRulePlugin.configure({
      inputRules: [
        HorizontalRuleRules.markdown({ variant: '-' }),
        HorizontalRuleRules.markdown({ variant: '_' }),
      ],
      node: { component: HrElement },
    }),
  ],
});

Add Static Rendering

Use the base plugin with the static component in static rendering paths.

tsx
import { BaseHorizontalRulePlugin } from '@platejs/basic-nodes';
import { createStaticEditor } from 'platejs';

import { HrElementStatic } from '@/components/ui/hr-node-static';

export const staticEditor = createStaticEditor({
  plugins: [BaseHorizontalRulePlugin.withComponent(HrElementStatic)],
});
</Steps>

Value Shape

Horizontal rules are void block elements. Keep the empty text child so the node remains a valid Slate element.

tsx
const value = [
  {
    children: [{ text: 'Before the divider' }],
    type: 'p',
  },
  {
    children: [{ text: '' }],
    type: 'hr',
  },
  {
    children: [{ text: 'After the divider' }],
    type: 'p',
  },
];
FieldTypeNotes
type'hr'Plugin key and node type from KEYS.hr.
children[{ text: '' }]Required child for the void element.

Input Rules

HorizontalRuleRules.markdown() converts a paragraph into an hr block and inserts an empty paragraph after it.

RuleTriggerBehavior
HorizontalRuleRules.markdown({ variant: '-' })type the third - after --Converts --- to hr, then inserts a paragraph.
HorizontalRuleRules.markdown({ variant: '_' })type a space after ___Converts ___ to hr, then inserts a paragraph.

The rule uses editor.tf.setNodes({ type: KEYS.hr }), so it transforms the current block instead of inserting a second divider elsewhere.

Registry UI

SurfaceBehavior
Editable elementRenders a non-editable padded wrapper with an <hr> inside it.
Selected + focusedAdds a focus ring around the divider.
Read-onlyRemoves the pointer cursor from the editable component.
Static elementRenders the same divider inside SlateElement.
Insert toolbarAdds a Divider item with MinusIcon and KEYS.hr.

The divider component renders {props.children} after the non-editable wrapper so Slate can still keep the void child mounted.

API Reference

APIPackageUse
BaseHorizontalRulePlugin@platejs/basic-nodesHeadless void hr block with HTML deserialization and default render tag.
HorizontalRulePlugin@platejs/basic-nodes/reactReact horizontal rule plugin.
HorizontalRuleRules.markdown({ variant: '-' })@platejs/basic-nodesCreates the dash input rule for ---.
HorizontalRuleRules.markdown({ variant: '_' })@platejs/basic-nodesCreates the underscore input rule for ___ .