简体中文
Tiptap Editor Demo Source
约 1082 字大约 4 分钟
Tiptap Editor Demo Source
This directory is the single source of truth for the checked-in demo page. When the page is copied into pages/avaui-sub/tiptap-editor, keep the content in sync from here instead of maintaining a second implementation.
What this demo is for
The demo is a business reference for how to use the public avaui-sub/tiptap-editor component in a real mini-program page:
- load the shared SDK through
src - pass editor extensions through
extensions - configure the built-in block image through
extensionConfigs.image - load the optional Markdown adapter through a versioned
pluginUrlsURL - enable HTTPS/origin policy and SRI metadata for production plugin delivery
- use
styleVarsfor theme overrides - use the
Heading 1-6action to verify the platform heading defaults - pass instance classes and FXUI icon classes through
customBlocks - use
autoGrowfor content-driven mini-program height synchronization - use
viewportStyleonly when the business chooses a fixed internal viewport - keep business composer UI, slash menu, and debug UI outside the public editor
Current business demo nodes:
businessChipbusinessBadgebusinessIconBlockbusinessIconInline
They are configuration-only customBlocks and do not require a plugin package. Business pages should keep only the node definitions they use.
Files in this demo
index.js— page state, editor events, command wiring, demo slash sheetindex.wxml— page structure and the editor component usageindex.wxss— page layout, composer card, and demo sheet stylesindex.json— page component registration
How to build a business demo
- Start from this directory.
- Keep the public editor wrapper as the only editor entry.
- Put business composer UI in the page, not in the editor component.
- Pass
extensionsandpluginUrlsonly for the nodes you really need. - Use
styleVarsfor font size, line height, spacing, and color tokens. - Choose
autoGrowor host-controlledviewportStyle; never combine both. - If a node is still experimental, keep it in the demo source instead of promoting it into
fe-dev-libs/packages/.
For plugin delivery, pass absolute HTTPS URLs and pair them with pluginPolicy and pluginIntegrity from the release manifest. The checked-in page uses the versioned enterprise test CDN; Ava mobile production must replace it with the published //a9.fspage.com/FSR/... URL.
Built-in extension reference
When the business does not pass extensions, or passes an empty array, the public component uses ['starter-kit']. The current StarterKit is based on @tiptap/starter-kit@3.30.0 and includes:
| Category | Default capabilities |
|---|---|
| Document structure | doc, paragraph, text |
| Headings | heading, supporting h1 through h6 |
| Block nodes | blockquote, codeBlock, horizontalRule |
| Lists | bulletList, orderedList, listItem |
| Text marks | bold, italic, strike, code, underline |
| Links | link |
| Editing behavior | hardBreak, dropcursor, gapcursor, trailingNode |
| History and keymaps | undoRedo, listKeymap |
The core also exposes link, underline, image, and placeholder as standalone names. link and underline are already included in StarterKit, so do not add them again when using the default configuration. Use extensionConfigs.starter-kit.link to configure the Link extension inside StarterKit. image and placeholder are not included by default:
extensions: ['starter-kit', 'image'],
extensionConfigs: {
image: {
inline: false,
allowBase64: false,
},
},The built-in image node is block-level by default and does not provide file selection, upload, compression, authentication, preview, or retry behavior. table, mention, file preview, and complex NodeViews are L2 capabilities and must be loaded through pluginUrls.
Minimal business page pattern
Page({
data: {
sdkUrl: 'https://www.ceshi112.com/fsh5/fe-dev-libs/tiptap-hera/0.1.0/tiptap-hera.iife.js',
extensions: ['starter-kit', 'markdown'],
pluginUrls: [
'https://www.ceshi112.com/fsh5/fe-dev-libs/tiptap-markdown/0.1.0/tiptap-markdown.iife.js',
],
styleVars: {
'--tt-font-size-body': '15px',
},
autoGrow: {
minHeight: 140,
maxHeight: 480,
},
},
})The checked-in demo intentionally does not override the heading line-height tokens. Tap Heading 1-6 to replace the editor content with all six heading levels. Their expected defaults are:
| Level | Font size | Line height |
|---|---|---|
| h1 | 22px | 1.6 |
| h2 | 20px | 1.6 |
| h3 | 18px | 1.6 |
| h4 | 16px | 1.6 |
| h5 | 15px | 1.6 |
| h6 | 14px | 1.6 |
The built-in image demo does not require a plugin package:
extensions: ['starter-kit', 'image'],
extensionConfigs: {
image: {
inline: false,
allowBase64: false,
},
},Block image simulates the result of a completed business upload and inserts the returned HTTPS URL with insertContent. File selection, compression, authentication, upload, retry, and error UI remain business responsibilities. The demo intentionally keeps inline: false; changing between block and inline images changes the editor schema and is not a per-image runtime switch.
For a simple static business block, prefer customBlocks. This keeps the business definition in the page and does not require a new package in fe-dev-libs:
extensions: ['starter-kit'],
customBlocks: [
{
type: 'businessIconBlock',
template: '<div class="{{class}}"><span class="{{icon}}"></span><span>{{label}}</span></div>',
schema: { class: 'string', icon: 'string', label: 'string' },
className: 'business-icon-block',
},
{
type: 'businessIconInline',
inline: true,
template: '<span class="{{class}}"><span class="{{icon}}"></span><span>{{label}}</span></span>',
schema: { class: 'string', icon: 'string', label: 'string' },
className: 'business-icon-inline',
},
],Insert it with JSON content from the business page:
{
type: 'businessIconBlock',
attrs: {
class: 'business-icon-block--sortable',
icon: 'fxui_all tuodongpaixu',
label: 'Sortable block',
},
}className is the fixed root class shared by every node instance. A schema field such as class or icon can be interpolated into a template class. The core merges root template classes with className and removes duplicates. The public mini-program component enables addGlobalClass, so an existing FXUI class such as fxui_all tuodongpaixu can be passed as node data without adding the icon font to the SDK or creating a plugin package.
Use an L2 plugin only when the block needs commands, interaction, async behavior, complex serialization, or a custom NodeView.
This demo page loads only one L2 bundle: tiptap-markdown.iife.js, the optional Markdown format adapter. The business blocks above remain configuration-only customBlocks.
The page provides these integration buttons:
Config blockappendsbusinessBadgethroughcustomBlocksandsetContent.Class blockappends a block node whose root and icon classes come from attrs.Class inlineinserts the same class-driven pattern as an inline atom node.Code blockinserts the built-incodeBlocknode fromstarter-kitwith a small JavaScript sample; it does not load a plugin package.Block imageinserts the built-in block image after a simulated upload.Markdown importcallssetContentwithcontentType: 'markdown'. The page bindscontentTypeandemitMarkdownon the public component, so the update event includesmarkdownwhen the Markdown adapter is loaded.
When not to change the demo
- Do not move this page logic into
avaui-sub/tiptap-editor/index.js. - Do not copy the same demo into another
avaui-subcomponent. - Do not promote a demo-only node into
fe-dev-libs/packages/before it has a stable cross-business contract.
