
前端UI组件【免费下载链接】react-pageNext-gen, highly customizable content editor for the browser - based on React and written in TypeScript. WYSIWYG on steroids.项目地址https://gitcode.com/gh_mirrors/rea/react-page点击查看免费下载ReactPage曾用名 ORY Editor是一个基于 React、使用 TypeScript 编写的开源“所见即所得”WYSIWYG内容编辑器核心库。它以可插拔的CellPlugin插件体系替代了传统contenteditable的诸多限制并以可移植的 JSON 结构存储整页内容。通过阅读本文你将掌握 ReactPage 的安装方式、Editor /组件的核心用法、编辑/只读双模式、内置与自定义插件的完整配置以及多语言与界面本地化等实战方案。ReactPage 是什么ReactPage 的定位非常明确——官方 README 中的一句话概括了它的核心主张If you are fed up with the limitations ofcontenteditable, you are in the right place.换句话说它是一套**智能smart、可扩展extensible、现代化modern**的浏览器端内容编辑器方案而不是另一个基于contenteditable的富文本包装器。从仓库结构上看这是一个 Yarn Workspaces Lerna 管理的 monorepo见 package.json 与 lerna.json主要包含三大块packages/editor编辑器核心库最终以react-page/editor发布提供Editor /组件、类型定义、reducer、migrations、渲染器等packages/plugins/content与packages/plugins/layout官方维护的插件包Slate 富文本、Image、Spacer、Divider、Video、Background 等examples基于 Next.js 的示例应用覆盖几乎所有功能的可用示例。其整体架构可以用一句话概括编辑器核心Editor 一组单元格插件cellPlugins 一份 JSON 内容value。内容被拆分为一个个cell单元格每个 cell 由某个插件负责渲染与编辑这种设计让内容的增删、拖拽、嵌套、多语言都变得非常灵活。安装与依赖ReactPage 提供了稳定的stable与包含不稳定特性的beta两个 npm 发布频道。安装方式如下命令完整摘录自 README.md# 稳定版 yarn add react-page/editor # 或 npm install --save react-page/editor # beta 频道可能包含不稳定特性 yarn add react-page/editorbeta # 或 npm install --save react-page/editorbeta关键依赖说明根据 packages/editor/package.jsonreact-page/editor的peerDependencies为react 16.14与react-dom 16.14因此使用 React 16.14 及以上版本即可安装仓库本身的开发环境已使用 React 18。官方文档 docs/quick-start.md 还补充了以下实践要点富文本插件通常是必需的ReactPage 自带的富文本编辑能力来自 Slate 插件包通常需要一并安装yarn add react-page/plugins-slate # 或 npm i --save react-page/plugins-slate编辑器 UI 基于 MUIMaterial-UI 5它是懒加载lazy load的不会直接增加主包的 bundle 体积如果希望覆盖主题需要额外安装emotion/react与emotion/styledyarn add emotion/react emotion/styled # 或 npm i --save emotion/react emotion/styled记得在应用入口引入样式文件import react-page/editor/lib/index.css;快速上手从零搭建一个编辑器仓库中的 examples/pages/examples/simple.tsx 是一个最小可运行的示例其完整逻辑如下import React, { useState } from react; // 编辑器核心 import type { Value } from react-page/editor; import Editor from react-page/editor; // 富文本插件Slate import slate from react-page/plugins-slate; // 图片插件 import image from react-page/plugins-image; // 定义允许使用的插件列表 const cellPlugins [slate(), image]; export default function SimpleExample() { const [value, setValue] useStateValue | null(null); return ( Editor cellPlugins{cellPlugins} value{value} onChange{setValue} / ); }这段代码展示了 ReactPage 的核心使用模型cellPlugins一个插件数组决定了编辑器里能添加什么。上例中slate()提供富文本段落image提供图片value当前内容的 JSON 状态类型为Value | nullonChange内容变化时的回调与 React 的受控组件模式一致——把新的value存进 state再传回给编辑器。编辑器对外默认导出Editor组件同时从 packages/editor/src/index.tsx 还导出了createValue、getTextContents、objIsNode、migrateValue、deepEquals、makeUniformsSchema、Migration等工具与类型这些在序列化、迁移和文本提取场景中会用到。编辑与只读双模式一份内容两种用途ReactPage 的Editor /组件既可以用于编辑内容也可以用于展示内容切换开关就是readOnly属性。这在 README 中被强调为项目的关键设计之一用同一组件无缝衔接内容生产与内容消费两个场景。// 编辑模式 Editor cellPlugins{cellPlugins} value{value} onChange{setValue} / // 只读模式仅展示已保存内容无需 onChange Editor cellPlugins{cellPlugins} value{value} readOnly /对应地examples/pages/examples/readonly.tsx 展示了只读模式的完整写法——直接传入一份预置内容demoSimpleReadOnly即可渲染页面。背后的实现按需加载带来的体积优化只读模式并非简单的禁用编辑而是根本不会加载编辑相关的代码。查看 packages/editor/src/editor/Editor.tsx 的实现可以看到readOnly的默认值是falsevalue默认null编辑用的EditableEditor通过lazyLoad(() import(./EditableEditor))进行动态 import 懒加载组件挂载时总是先以只读方式渲染useState(true)待useEffect根据readOnly决定是否切换到编辑 UI——这避免了 SSR服务端渲染时直接加载编辑代码的问题因此当readOnly{true}时使用 webpack 等打包工具的应用可以显著减小首屏 bundle 体积。官方文档 docs/editor.md 还给出一个实用场景在对外公开的页面中默认只读展示当检测到当前用户具备发布权限时显示一个按钮把readOnly置为false并传入onChange即可直接在线上页面完成内容修改与保存。理解 value可移植的 JSON 数据结构ReactPage 的整页内容以一个JSON 对象Value表示它同时包含数据用户看到的正文与元数据渲染所需的信息id、版本、插件标识等。这份 JSON 是不透明的——官方明确建议不要依赖其内部结构直接修改但它有非常明显的优势不包含任何展示样式没有 CSS 被写进内容体积小、结构干净相比经典富文本编辑器产出的内容与样式混合的 HTML同一份 JSON 可以被不同的渲染组件以不同方式呈现可移植可以复制到新文档中用于版本管理或模板克隆。通过 packages/editor/src/core/utils/createValue.ts 可以一窥Value的基本骨架它由id、rows行数组和version当前可编辑版本号取自CURRENT_EDITABLE_VERSION组成每一行又包含若干cells每个 cell 记录size栅格宽度、plugin插件 id 与版本、dataI18n按语言存放的数据等信息。下面是一个包含图片单元格的实际 JSON 示例界面效果见下图{ id: obknih, version: 1, rows: [ { id: b27eia, cells: [ { id: e9htzt, size: 12, plugin: { id: ory/editor/core/content/slate, version: 1 }, dataI18n: { default: { slate: [ { type: HEADINGS/HEADING-TWO, children: [{ text: This is a heading }] }, { type: PARAGRAPH/PARAGRAPH, children: [{ text: This is some paragraph text }] } ] } }, rows: [], inline: null } ] }, { id: 5j8lyl, cells: [ { id: k0t2gk, size: 12, plugin: { id: ory/editor/core/content/image, version: 1 }, dataI18n: { default: { src: https://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/mars2020-sample-tubes.jpg?itokSiZDKmmG } }, rows: [], inline: null } ] } ] }值得注意的是内容数据被存放在dataI18n中并按语言分键——这正是多语言支持的数据基础见下文多语言章节。docs/editor.md中提供了更多Value结构的细节与示例。插件体系CellPlugin 深度解析插件是 ReactPage 的灵魂。cell plugin定义了用户可以向文档添加的每一种单元格——它由唯一的id、一个title和一个Renderer渲染该 cell 的 React 组件构成。完整类型定义见 packages/editor/src/core/types/plugins.ts。插件的基础属性一个典型的自定义插件长这样示例来自 docs/custom-cell-plugins.mdimport { CellPlugin } from react-page/editor; import React from react; // 注意请使用 type 而不是 interface 来声明数据类型 type Data { title: string; }; const myFirstCellPlugin: CellPluginData { Renderer: ({ data }) ( SomeCustomComponent title{data.title} / ), id: myFirstCellPlugin, title: My first cell plugin, description: My first cell plugin just displays a title, version: 1, controls: { type: autoform, schema: { properties: { title: { type: string, default: someDefaultValue, }, }, required: [title], }, }, };然后把它和其他插件一起传给Editor /Editor cellPlugins{[myFirstCellPlugin, ...otherPlugins]} value{value} onChange{onChange} /基础属性一览与源码中的CellPlugin类型字段一一对应属性类型说明idstring插件的唯一标识所有使用的插件 id 必须互不相同titlestring插件的展示名称descriptionstring附加说明会显示在插件抽屉Plugin Drawer中iconReactNode插件抽屉中显示的图标推荐使用 MUI iconsversionnumber当前数据版本号数据形状变化时需要递增并配套 migrationRendererComponent渲染 cell 内容的组件接收data、children、readOnly、onChange、focused、lang、isPreviewMode、isEditMode等 propscellStyleCSSProperties \| (data) CSSProperties应用到 cell 最外层 div 的样式而非Renderer本身常用于调整 cell 内边距controlsAutoformControlsDef \| CustomControlsDef \| ControlsDefList定义编辑该 cell 的表单控件见下文cellPluginsCellPlugin[] \| (cellPlugins, data) CellPlugin[]限定该 cell 内部允许嵌套的子插件既可以是数组也可以是接收父级插件列表与当前数据的函数createInitialData(cell) Data新增 cell 时生成初始数据createInitialChildren() PartialRow[]若Renderer渲染children可在此预置初始的行与子 cellmigrationsMigration[]数据形状变更时从旧版本迁移到新版本的迁移器数组需同时递增versionisInlinableboolean是否可作为浮动内联元素插入其他插件典型用途在富文本中插入浮动图片allowInlineNeighboursboolean该 cell 是否允许接收isInlinable的邻居allowClickInsideboolean编辑模式下 ReactPage 默认拦截 cell 的点击/事件以保证可选中、可缩放设为true可解除拦截富文本插件即如此hideInMenuboolean在插件抽屉中隐藏该插件ProviderComponent同时包裹Renderer与选中时的 BottomToolbar 的上下文组件用于在两者间共享状态Slate 插件用它高亮当前激活的格式childConstraints{ maxChildren: number }实验性当 cell 内行数达到上限后隐藏按钮三种 controlsautoform / custom / 多标签controls决定用户如何编辑这个 cell 的数据共有三种形态{ type: autoform }自动表单基于你提供的 JSON Schema 自动生成表单底层使用 uniforms。支持字符串、日期、整数、嵌套对象与数组也支持自定义字段组件例如上传图片到 S3 并返回 URL 的字段、用 GraphQL 查询选项的下拉框等。还可通过 schema 字段中的uniforms属性透传 propscontrols: { type: autoform, schema: { properties: { description: { type: string, uniforms: { label: My field, // 自定义 label placeholder: fill me, // 自定义占位符 component: MyCustomComponent, // 覆盖字段组件 showIf: (data) data.myOtherField something, // 条件显示 multiline: true, // 多行文本 rows: 4, }, }, }, }, }自定义字段组件通过 uniforms 的connectField实现例如一个图片上传字段import { connectField } from uniforms; const ImageUploadField connectField(({ value, onChange }) { return ( div {value ? img style{{ width: 150 }} src{value} / : null} input typefile onChange{async (e) { // 假设 uploadFile 会把文件上传如 S3并返回可访问 URL const url await uploadFile(e.target.files[0]); onChange(url); }} / /div ); });{ type: custom }自定义控件当自动表单不适合已有表单组件库、或有非常特殊的编辑需求时直接提供一个自定义组件它接收与Renderer相同的 props并通过onChange(data)回写数据。该组件会显示在选中 cell 时的底部工具栏BottomToolbar中。多控件数组传入[{ title, controls }, ...]选中该 cell 时工具栏会显示多个 Tab 以切换不同编辑面板典型场景是基础配置 / 高级配置分离controls: [ { title: Base config, controls: { type: autoform, schema: { properties: { title: { type: string } }, required: [], }, }, }, { title: Advanced, controls: { type: autoform, schema: { type: object, required: [], properties: { advancedProperty: { type: string } }, }, }, }, ],完整示例见 examples/plugins/customContentPlugin.tsx以及docs/custom-cell-plugins.md中更详尽的属性说明。官方内置插件ReactPage 将若干常用插件作为独立 npm 包随官方仓库维护见 docs/builtin_plugins.md。它们都遵循同一种接入模式作为cellPlugins数组的一员传入Editor /。Slate 富文本插件Slate 插件是 ReactPage 预置的富文本编辑方案本质上也是一个 cell plugin插件 id 形如ory/editor/core/content/slate。它支持标题、段落、列表、链接、引用、行内元素等丰富的排版能力详细配置见 docs/slate.md 与 docs/recipes.md。Image 图片插件图片插件支持两种图片来源已有 URL 直链或上传到任意目标S3、Backblaze 等。图片还可以链接到任意 URL并可设置在新窗口打开。export const cellPlugins [ // ... 其他插件 imagePlugin({ imageUpload: uploadImage(https://example.com/default.jpg), }), ];上传处理器是一个接收File、返回Promise{ url: string }的函数。官方文档给出了一个2 秒后返回默认 URL的 shim 示例实际场景中只需在 Promise 内真正执行上传function uploadImageShim(defaultUrl) { return function (file, reportProgress) { return new Promise((resolve) { setTimeout(() { resolve({ url: defaultUrl }); }, 2000); }); }; }安装包react-page/plugins-image。Spacer 间隔插件Spacer 用于在行与行、列与列之间创建可控的空白区域——插在行下方产生垂直间距插在列旁边产生水平间距。安装包react-page/plugins-spacer。Divider 分割线插件Divider 用于插入一条水平分隔线。安装包react-page/plugins-divider。Background 背景插件Background 是一个布局插件可以为某个区块设置背景图片和/或背景色且其他 cell 插件可以放在背景插件之上。它通过enabledModes按位组合控制三个模式标签页的显隐export const cellPlugins [ // ... 其他插件 background({ imageUpload: uploadImage(/images/default.svg), enabledModes: ModeEnum.COLOR_MODE_FLAG | ModeEnum.IMAGE_MODE_FLAG | ModeEnum.GRADIENT_MODE_FLAG, }), ];IMAGE_MODE_FLAG允许设置背景图片COLOR_MODE_FLAG允许设置背景颜色GRADIENT_MODE_FLAG允许创建多色渐变。安装包react-page/plugins-background。此外仓库还维护了 Video、HTML5 Video 等插件见 packages/plugins/content并支持 examples/plugins/cellPlugins.ts 中展示的多插件组合用法。多语言内容与界面本地化多语言内容langlanguagesReactPage 支持按 cell 级别的多语言内容。向Editor /传入languages语言列表与lang当前语言 idconst LANGUAGES [ { lang: en, label: English }, { lang: de, label: Deutsch }, ]; Editor cellPlugins{cellPlugins} value{value} langen onChange{setValue} languages{LANGUAGES} /工作机制是每个 cell 默认显示default语言的内容直到用户为特定语言单独创建了翻译版本。这样编辑者只需翻译需要翻译的 cell而不用复制整个页面到另一种语言——这正是很多 CMS 的多语言痛点。此外cell 还可以按语言单独隐藏。界面文本本地化uiTranslatoruiTranslator接收一个(label?: string) string函数所有编辑器界面文案都会经过它。仓库的 examples/pages/examples/i18n.tsx 给出了一个中文翻译示例const TRANSLATIONS: { [key: string]: string } { Edit blocks: 编辑, Add blocks: 添加, Move blocks: 移动, Resize blocks: 调整大小, Preview blocks: 预览模式, }; const uiTranslator useCallback((label?: string | null) { if (label TRANSLATIONS[label] ! undefined) { return TRANSLATIONS[label]; } return ${label}(to translate); }, []);未命中翻译的文案会以(to translate)后缀提示方便后续补齐翻译。布局控制与其他配置cellSpacing单元格间距控制 cell 之间的间距可传数字或{x, y}对象cellSpacing { x: 15, // 水平间距 y: 20, // 垂直间距 };childConstraints实验性限制整个编辑器可添加的最大行数超过后隐藏按钮childConstraints: { maxChildren: number, }注意它目前仅控制按钮显隐仍可通过拖拽添加新 cell属于实验性功能。components实验性覆盖编辑器 UI如果需要更细粒度的 UI 控制可以通过components覆盖内部组件目前主要是BottomToolbar即选中 cell 时显示插件控件与操作的底部工具栏。官方建议将其作为最后手段使用并优先通过 Issue 反馈自定义需求以便沉淀为通用特性。核心 Props 速查表综合 docs/editor.md 与源码 packages/editor/src/editor/Editor.tsxEditor /的核心 props 如下Prop类型说明valueValue \| null要显示的内容JSON来源可为文件、数据库、API 等onChange(newValue: Value) void内容变化回调readOnly时可不传readOnlybooleantrue时仅展示内容编辑代码不加载减少 bundle 体积cellPluginsCellPlugin[]该编辑器可用的插件数组langstring当前内容语言 id需与languages配合languages{ lang: string; label: string }[]可用语言列表cellSpacingnumber \| { x: number; y: number }单元格间距uiTranslator(label?: string) string界面文案翻译函数childConstraints{ maxChildren: number }实验性限制最大行数components对象实验性覆盖内部 UI 组件项目背景、现状与本地运行历史与现状ReactPage 前身为ORY Editor由aeneasrORY 团队创建如今以react-page/editor等 scoped 包名发布。需要特别说明的是仓库 README 顶部明确标注了LOOKING FOR MAINTAINERS正在寻找维护者——这意味着项目目前处于社区维护力量有限的状态评估是否在生产环境采用时需自行权衡。据 README 记载ReactPage 已被用于以下生产场景表述以仓库 README 为准GuestBell Hotel App用作酒店落地页的 CMSVeloplus 在线商店用于创建与展示任意内容页含落地页Bike2School用于骑行上学推广项目的内容编辑。本地运行示例应用仓库的examples目录是一个完整的 Next.js 应用见 examples/package.json。你可以克隆本仓库后在本地运行全部示例git clone https://gitcode.com/gh_mirrors/rea/react-page.git cd react-page yarn install yarn dev启动后浏览器访问本地 Next.js 服务端口默认 3000即可查看simple、readonly、i18n、multicontrols、cellSpacing、nestedPlugins、customToolbar等全部示例对应 examples/pages/examples 下的页面。此外仓库还提供了yarn build构建所有包yarn test运行 Jest 测试含覆盖率yarn docs在 3100 端口启动 docsify 文档站。社区渠道项目使用 GitHub Discussion 作为社区讨论板欢迎在react-page/react-page/discussions发起讨论。文档方面本仓库的docs目录提供了从快速上手docs/quick-start.md、编辑器配置docs/editor.md、自定义插件docs/custom-cell-plugins.md到内置插件docs/builtin_plugins.md、服务端渲染docs/server-side-rendering.md、React Admin 集成docs/integration-react-admin.md与实用技巧docs/recipes.md的完整指南可作为深入学习的入口。赞分享前端UI组件【免费下载链接】react-pageNext-gen, highly customizable content editor for the browser - based on React and written in TypeScript. WYSIWYG on steroids.项目地址https://gitcode.com/gh_mirrors/rea/react-page点击查看免费下载相关推荐猫抓浏览器扩展3步解锁网页资源捕获的终极指南猫抓浏览器扩展3步解锁网页资源捕获的终极指南 你是否曾经在浏览网页时遇到心仪的视频、音频或图片资源却苦于无法轻松下载或者面对复杂的流媒体加密内容束手无策音视频ReactPage下一代React内容编辑器深度解析ReactPage下一代React内容编辑器深度解析 ReactPage是一个基于React和TypeScript构建的下一代、高度可定制的内容编辑器专为现前端UI组件ReactPage 开发指南React TypeScript 可视化内容编辑器的安装、集成与生态全景ReactPage 开发指南React TypeScript 可视化内容编辑器的安装、集成与生态全景 ReactPage曾用名 ORY Editor是前端UI组件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。