编号格式下拉菜单

Available in Start plan

一个用于有序列表的编号样式选择器。它会渲染一个 ListButton 来切换有序列表,并附带一个编号样式下拉菜单——包括十进制、括号样式、嵌套十进制、大小写字母、大小写罗马数字以及前导零格式——每种样式都以一个小型嵌套列表预览的形式显示。

当前激活的格式通过 orderedListNumbering 扩展(属于 @tiptap-pro/extension-convert-kit)读取并应用,因此屏幕上的标记始终与已注册的格式保持一致。所有编辑器逻辑都通过 useNumberingFormatDropdownMenu 钩子暴露,因此你可以在其基础上构建完全自定义的 UI。

Requires the orderedListNumbering extension

这个组件会在最外层有序列表上读取并写入一个 numberingFormat id。对应的 级别定义(即每个 id 在屏幕上和导出时的显示方式)由扩展配置提供——见下方的 Setup。如果没有它,选择某种格式不会产生任何可见效果。

安装

通过 Tiptap CLI 添加该组件:

npx @tiptap/cli@latest add numbering-format-dropdown-menu

设置

该组件只在列表上存储一个格式 id;实际的标记渲染由扩展负责。请通过 ConvertKit 配置 orderedListNumbering,为你想提供的每个格式 id 提供一个层级定义,并且同样的定义也可以传递给 ExportDocx,以实现无损往返。

import { ConvertKit } from '@tiptap-pro/extension-convert-kit'

const NUMBERING_FORMATS = [
  {
    id: 'decimal',
    levels: Array.from({ length: 9 }, (_v, depth) => ({
      baseStyle: ['decimal', 'lowerLetter', 'lowerRoman'][depth % 3],
      textTemplate: `%${depth + 1}.`,
    })),
  },
  // …你提供的每个 id 对应一个条目(见 NUMBERING_FORMAT_IDS)
]

const editor = useEditor({
  extensions: [
    ConvertKit.configure({
      orderedListNumbering: {
        formats: NUMBERING_FORMATS,
        defaultFormat: 'decimal',
      },
    }),
    // …
  ],
})

组件

<NumberingFormatDropdownMenu />

一个预构建组件,将有序列表切换按钮与编号样式下拉菜单组合在一起。

用法

export default function MyEditor() {
  return (
    <NumberingFormatDropdownMenu
      editor={editor}
      hideWhenUnavailable={true}
      modal={false}
      onOpenChange={(isOpen) => console.log('Dropdown', isOpen ? 'opened' : 'closed')}
    />
  )
}

属性

该组件还会将任何额外的 Button 属性(除 type 外)转发给下拉触发器。

名称类型默认值描述
editorEditor | nullundefinedTiptap 编辑器实例。
formatsNumberingFormat[]DEFAULT_FORMATS在下拉菜单中提供的编号格式 id。
hideWhenUnavailablebooleanfalse当有序列表不可用时隐藏下拉菜单。
modalbooleantrue下拉菜单是否以模态方式捕获焦点。
onOpenChange(boolean) => voidundefined下拉菜单打开或关闭时的回调。

<NumberingFormatButton />

单个格式选项,以小型嵌套列表预览的形式渲染。可用于构建下拉菜单网格,也可单独使用。

属性

名称类型默认值描述
editorEditor | nullundefinedTiptap 编辑器实例。
formatNumberingFormat此按钮应用的编号格式。必填。
hideWhenUnavailablebooleanfalse当有序列表不可用时隐藏按钮。
onFormatSet() => voidundefined格式成功应用后调用。

钩子

useNumberingFormatDropdownMenu()

一个无头钩子,提供构建自定义编号下拉菜单所需的完整状态和操作。

用法

function MyNumberingDropdown() {
  const {
    isVisible,
    currentFormat,
    canToggle,
    formats,
    setFormat,
    isFormatActive,
    getFormatLabel,
  } = useNumberingFormatDropdownMenu({ editor, hideWhenUnavailable: true })

  if (!isVisible) return null

  return (
    <DropdownMenu>
      <DropdownMenuTrigger disabled={!canToggle}>编号</DropdownMenuTrigger>
      <DropdownMenuContent>
        {formats.map((format) => (
          <DropdownMenuItem
            key={format}
            data-active-state={isFormatActive(format) ? 'on' : 'off'}
            onClick={() => setFormat(format)}
          >
            {getFormatLabel(format)}
          </DropdownMenuItem>
        ))}
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

属性

名称类型默认值描述
editorEditor | nullundefinedTiptap 编辑器实例。
formatsNumberingFormat[]DEFAULT_FORMATS提供的编号格式 ID。
hideWhenUnavailablebooleanfalse当有序列表不可用时隐藏下拉菜单。

返回值

名称类型描述
isVisibleboolean下拉菜单是否应当渲染。
currentFormatstring当前应用的格式 ID(如果未设置,则为 "decimal")。
isActiveboolean提供的格式中是否有任意一个当前处于激活状态。
canToggleboolean当前状态下是否可以设置编号格式。
formatsNumberingFormat[]提供的格式 ID。
setFormat(format: NumberingFormat) => boolean应用某个格式;成功时返回 true
isFormatActive(format: NumberingFormat) => boolean某个给定格式是否为当前激活格式(用于激活标记)。
getFormatLabel(format: NumberingFormat) => string格式的可读预览标签,例如 "1. 2. 3."

useNumberingFormatButton()

单个格式选项的状态和处理器。

属性

名称类型默认值描述
editorEditor | nullundefinedTiptap 编辑器实例。
formatNumberingFormat此按钮应用的格式。必填。
hideWhenUnavailablebooleanfalse当不可用时隐藏按钮。
onFormatSet() => voidundefined格式设置后调用。

返回值

名称类型描述
isVisibleboolean按钮是否应当渲染。
isActiveboolean此格式当前是否处于激活状态。
handleSetFormat() => boolean应用该格式;成功时返回 true
canSetboolean当前状态下是否可以设置该格式。
labelstring该格式的预览标签,例如 "1. 2. 3."

工具

格式化 id 和标签

import {
  NUMBERING_FORMAT_IDS,
  NUMBERING_FORMAT_LABELS,
  DEFAULT_FORMATS,
} from '@/components/tiptap-ui/numbering-format-dropdown-menu'

NumberingFormat 是以下之一:decimaldecimal-parendecimal-nestedupper-alphalower-alphaupper-romanlower-romandecimal-zeroNUMBERING_FORMAT_IDS 按下拉菜单顺序列出它们;DEFAULT_FORMATS 是默认提供的集合;NUMBERING_FORMAT_LABELS 将每个 id 映射到其预览字符串(例如 "A. B. C.")。

编辑器辅助函数

import {
  setNumberingFormat,
  isNumberingFormatActive,
  getCurrentNumberingFormat,
  canSetNumberingFormat,
  getFormatLabel,
} from '@/components/tiptap-ui/numbering-format-dropdown-menu'

setNumberingFormat(editor, 'upper-roman') // 应用该格式,返回布尔值
getCurrentNumberingFormat(editor) // 当前激活的格式 id,若不在列表中则为 null
isNumberingFormatActive(editor, 'decimal') // 布尔值
canSetNumberingFormat(editor) // 布尔值
getFormatLabel('lower-alpha') // "a. b. c."

需求

依赖项

  • @tiptap/react — Tiptap React 核心集成
  • @tiptap-pro/extension-convert-kit — 提供 orderedListNumbering 扩展,用于存储和渲染该格式

引用的组件

  • use-tiptap-editor(hook)
  • list-button(组件)
  • button(原始组件)
  • button-group(原始组件)
  • dropdown-menu(原始组件)
  • tiptap-utils(库)
  • chevron-down-icon(图标)