A syntax test page for the site, used for later feature testing
Note
Use this for key background, scope, or prerequisites; it's an optional Callout (Note) node.
Lexical syntax coverage · Local article
This is a real test article written to the local Core: it takes the full syntax coverage of the original Lexical showcase and drops it back into a production article shell for future page regression checks.
“
Note This fixture covers the Lexical nodes currently registered on the site — basic nodes, rich media nodes, and interactive nodes. Polls, dynamic components, and external media still go through the page's normal adapters, so real loading states can be checked.
1. Inline formatting
Inline text can be bold, italic, strikethrough, <u>underlined</u>,inline code, or carry links like innei.in, or an autolink: https://github.com/Innei/Yohaku.
A Japanese ruby annotation example: 紅葉(もみじ), 東京(とうきょう).
A quotation: Heaven and earth have great beauty and say nothing.
— Zhuangzi, "Knowledge Rambling in the North"
3. Lists and tasks
First unordered item
Nested:
Child item A
Child item B
Last item
First ordered item
Second ordered item
Last ordered item
Done: write the fixture
Done: hook up the mock adapter
To do: cover edge cases
4. Code
TSX
import type { LexicalContentProps } from '~/components/ui/rich-content/LexicalContent'
export function renderArticle(props: LexicalContentProps) {
return <LexicalContent {...props} />
}
Code snippet:counter.tsx
TSX
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount((c) => c + 1)}>{count}</button>
}
Code snippet:main.ts
TS
import { createRoot } from 'react-dom/client'
import { Counter } from './counter'
createRoot(document.getElementById('root')!).render(<Counter />)
5. Quotes and callouts
Tip
Before installing dependencies or running scripts, check your Node version and lockfile. This block is the editor's Tip node.
“
Important Important: you must sign in before you can use this feature.
Banner (note): shown purely as a bold decoration. Banner (tip): same type as alert, different layout. Banner (important): reserved for important matters. Banner (warning): for warnings. Banner (caution): for cautions.
Collapsible node test (collapsed by default on the original page):
“
Click to expand: inside this node
The collapsible node hides secondary content and starts with open=false. Any block-level node can go inside.
8. Diagrams and Turing machines
Mermaid flowchart:
Mermaid sequence diagram:
Excalidraw whiteboard (a Lexical-only node; in Markdown the interactive canvas is replaced with a text description):
“
The frame "01 · Syntax coverage (article)" contains one blue rectangle and one orange ellipse.
9. Chat and polls
User · Agent conversation:
“
Innei: What's the difference between Lexical's DecoratorNode and ElementNode?
Claude:ElementNode holds other nodes (paragraphs, headings, lists); DecoratorNode renders a React component as a leaf (poll, embed, chart). Use a decorator when the content isn't text-editable.
Single-choice poll:
Which cat do you like best?
Ragdoll
American Shorthair
Orange tabby
Multiple-choice poll:
Which pets have you kept? (multiple choices allowed)
Cat
Dog
Hamster
Fish
10. Nested documents
A nested doc is a block holding its own SerializedEditorState. Click to expand and read the whole thing.
Nested child doc
This child doc is itself a Lexical state, containing paragraphs, code, images and more.
A left-floated image takes up 40% of the line width, with body text wrapping down its right side. The wrapping paragraph needs enough length to show how lines break: once the text runs past the image's height, subsequent lines return to full width. In the leftover space, image and text play off each other and the layout comes alive.
This is a second wrapping paragraph, to check the spacing and alignment when several paragraphs wrap in a row. The horizontal gap between the floated image and the body text is built into the haklex styles (1.5rem) and shouldn't be overridden by site styles.
The right float has no displayWidth set, so it falls back to the default 50%. Body text wraps down its left side. On narrow screens (≤640px) both floats are released and the image returns to full width, centered, so mobile text isn't squeezed into a thin column.
One more paragraph at the end, to confirm the container contains the float with flow-root: content after this block shouldn't be intruded on by the floated image.
afilmory photo node — the schema holds only id + baseUrl; at runtime it fetches /api/manifest to parse EXIF. See /dev-demos/lexical/afilmory for the full set of cases.
Below is a multi-turn conversation, to test typography and underline handling:
User: Give a quick rundown of the main differences between Lexical and ProseMirror, with three typical use cases.
Yohaku: Lexical is more component-driven, with every node derived through DecoratorNode and ElementNode derived; ProseMirror describes structure through a schema, with nodes as immutable data.
Social content editors (Meta, Threads, etc.) mostly use Lexical, valuing React integration
AI streaming (chat UIs, for example) works with either, but Lexical's update cycle is closer to React, making integration a bit simpler
See the docs for lexical.dev and prosemirror.net.
User: So what is a Lexical DecoratorNode good for rendering?
Yohaku: DecoratorNode suits non-text leaf nodes — React manages their content itself, and the editor never enters their DOM:
Images, video, embedded iframes
Complex components like polls and tables
Custom widgets (like this chat node)
decorate() returns is exactly the React element it renders.
User: Got it, thanks.
The chat content above should render in sans, even though the parent note variant uses serif.
Local Markdown footnote margin-note layout test (dev only)
Markdown footnote margin-note layout check
Start with two adjacent references, "reading progress rail"1 and "rich-format margin notes"2, and watch whether they offset naturally when they sit close together. There's also a fixed reading progress rail on the left, and the margin notes need to keep clear of it.
A few ordinary paragraphs next, to give the page a real reading rhythm. Footnotes should stay beside their referencing paragraph, not pile up at the end of the article, and the body text order shouldn't be broken by margin notes.
The reading progress rail updates as you scroll; it's a reading tool that lives at the page edge. When it's collapsed, the margin notes keep their distance from it. When it expands on hover, the margin notes stay pinned to the left, and the rail may cover part of them without shifting the body layout.
Some paragraphs are short, others run on across several lines. Here's another longer block, to check whether the margin notes still line up with their referencing paragraph. If a note is longer than the body text, it shouldn't squeeze the body or cover the next note either.
The article's table of contents stays on the right, so this test only looks at the blank area on the left. When the margin sidebar is open, margin notes should step aside and return to the body flow; when the reading progress rail expands, they stay put and don't jostle the body.
This block stands in for the middle of the article, specifically to confirm that margin notes still follow their own reference position after longer content3. As you keep reading, a note shouldn't push back up into the earlier group of footnotes or cover the table of contents; when the rail is expanded it can overlay the notes as a floating layer.
Ordinary paragraphs can hold more text, lists, or images in between. Here's a slightly longer test passage: margin notes are reading aids that run parallel to the body, sitting in the left blank area on desktop and dropping below the current paragraph on narrow screens.
A few more paragraphs, to confirm numbering increments in the order references first appear, not by where the footnotes are defined. Definitions still live together at the end of the Markdown file, but once rendered they return to sit near their references.
As the window narrows, margin notes stop using the blank space on the left and continue in smaller type below the referencing paragraph. This fallback layout also needs to keep paragraph spacing, so a note doesn't end up crammed against the next paragraph.
One more reference near the end4, to confirm it shows up close to the bottom of the article and still uses numbering generated in order of first appearance.
Here we'll break up the flow with a few more paragraphs of ordinary content, mimicking the examples, explanations, and asides that appear in a real article. That way you can see whether the margin notes stay with their own references instead of gradually piling up in one place because of how positions are calculated.
If the reader opens the table of contents on the right or the margin sidebar on the left, the margin notes should temporarily fall back to the body layout so they don't compete with the sidebar for space. While the reading progress bar is expanded on hover, the margin notes stay pinned to the left, and the progress bar overlay is allowed to cover them; once the sidebar is closed, they can return to the left margin.
The last paragraph holds a back-to-reference note5, to check whether the back arrow returns to the right reference; it shouldn't drag all the margin notes down to the end of the article.
The reading progress track stays fixed at the far-left edge of the viewport; the sidenote should leave clear spacing from it.↩
Sidenote body text also supports **emphasis**, `inline code`, [Google](https://google.com), and multi-line content:↩
This is a sidenote placed mid-article to check larger vertical spacing.↩
A sidenote can also appear later in the article, and its number still increases in order of first reference.↩
Clicking the back arrow here should return you to the corresponding reference.↩
Neither the image nor the code should stretch the margin notes past their width, and neither should change the reading order of the original paragraph.
Use this for key background, scope, or prerequisites; it's an optional Callout (Note) node.
Lexical syntax coverage · Local article
This is a real test article written to the local Core: it takes the full syntax coverage of the original Lexical showcase and drops it back into a production article shell for future page regression checks.
1. Inline formatting
Inline text can be bold, italic, strikethrough, <u>underlined</u>,inline code, or carry links like
innei.in, or an autolink:
https://github.com/Innei/Yohaku.
A Japanese ruby annotation example: 紅葉(もみじ), 東京(とうきょう).
Social platform mentions:
innei and
@innei.
2. Headings and paragraphs
h3 subheading
A paragraph scattered over several lines.
3. Lists and tasks
4. Code
Code snippet:counter.tsx
Code snippet:main.ts
5. Quotes and callouts
Before installing dependencies or running scripts, check your Node version and lockfile. This block is the editor's Tip node.
Banner (note): shown purely as a bold decoration.
Banner (tip): same type as alert, different layout.
Banner (important): reserved for important matters.
Banner (warning): for warnings.
Banner (caution): for cautions.
6. Media
Single image:
!
random illustration
Image gallery (grid):
!
One
!
Two
!
Three
!
Four
Video cover and video file:
!
video cover
Embed (YouTube):
https://www.youtube.com/watch?v=dQw4w9WgXcQ
Link card:
https://github.com/Innei/Shiro
7. Tables and collapsibles
Node
Category
Notes
mermaid
block / decorator
wired up to the photo-viewer zoom
excalidraw
block / decorator
expand goes through PeekModal
nested-doc
block / decorator
embeds a SerializedEditorState
Collapsible node test (collapsed by default on the original page):
8. Diagrams and Turing machines
Mermaid flowchart:
Mermaid sequence diagram:
Excalidraw whiteboard (a Lexical-only node; in Markdown the interactive canvas is replaced with a text description):
9. Chat and polls
User · Agent conversation:
Single-choice poll:
Which cat do you like best?
Multiple-choice poll:
Which pets have you kept? (multiple choices allowed)
10. Nested documents
A nested doc is a block holding its own SerializedEditorState. Click to expand and read the whole thing.
Nested child doc
This child doc is itself a Lexical state, containing paragraphs, code, images and more.
Nesting can go further, but rendering stops at 6 nodes by default.
11. Extra layouts and extension nodes
The following cases round out the layouts, media, and interactive variants from the standalone Lexical demo that don't recur in the long-form article.
Image (display width)
displayWidth 60% / 35%, centered (default layout).
!
Mountain 60%
displayWidth: 60
!
Mountain 35%
displayWidth: 35
Image (align)
layout = align-left / align-right, displayWidth 40%.
!
Lake left-aligned
align-left
!
Lake right-aligned
align-right
Image (float)
layout = float-left / float-right, with text wrapping around the image; below 640px the float is released automatically.
!
Forest float-left
float-left · displayWidth: 40
A left-floated image takes up 40% of the line width, with body text wrapping down its right side. The wrapping paragraph needs enough length to show how lines break: once the text runs past the image's height, subsequent lines return to full width. In the leftover space, image and text play off each other and the layout comes alive.
This is a second wrapping paragraph, to check the spacing and alignment when several paragraphs wrap in a row. The horizontal gap between the floated image and the body text is built into the haklex styles (1.5rem) and shouldn't be overridden by site styles.
!
Coast float-right
float-right · default width (50%)
The right float has no displayWidth set, so it falls back to the default 50%. Body text wraps down its left side. On narrow screens (≤640px) both floats are released and the image returns to full width, centered, so mobile text isn't squeezed into a thin column.
One more paragraph at the end, to confirm the container contains the float with flow-root: content after this block shouldn't be intruded on by the floated image.
Gallery (carousel)
gallery layout = carousel
!
Slide 1
!
Slide 2
!
Slide 3
Afilmory Photo
afilmory photo node — the schema holds only id + baseUrl; at runtime it fetches /api/manifest to parse EXIF. See /dev-demos/lexical/afilmory for the full set of cases.
File
file attachment: block row + inline chip; md / code files expand into a preview (512KB range).
Attachments can be inline too:
vite.config.ts, right there in the body text.
Embed - Tweet
embed (Tweet) — verify that TweetRenderer renders a card, not a fallback link
Embed (Tweet):
Dynamic - remote quiz
dynamic node: a remote ESM widget (asset on S3), import(url) into a shadow root; the URL must appear in the /s/dynamic-widgets-catalog manifest.
Component question: where is this quiz component actually loaded from?
The original component lists "A standalone ESM module on object storage" as the correct answer. Its remote module URL:
Chat - user · user
Alice: Still up for tonight?
Bob: Yep.
Chat - user · agent (long markdown)
Below is a multi-turn conversation, to test typography and underline handling:
User: Give a quick rundown of the main differences between Lexical and ProseMirror, with three typical use cases.
Yohaku: Lexical is more component-driven, with every node derived through DecoratorNode and ElementNode derived; ProseMirror describes structure through a schema, with nodes as immutable data.
Three typical use cases:
See the docs for lexical.dev and prosemirror.net.
User: So what is a Lexical DecoratorNode good for rendering?
Yohaku: DecoratorNode suits non-text leaf nodes — React manages their content itself, and the editor never enters their DOM:
decorate() returns is exactly the React element it renders.
User: Got it, thanks.
The chat content above should render in sans, even though the parent note variant uses serif.
Local Markdown footnote margin-note layout test (dev only)
Markdown footnote margin-note layout check
Start with two adjacent references, "reading progress rail"1 and "rich-format margin notes"2, and watch whether they offset naturally when they sit close together. There's also a fixed reading progress rail on the left, and the margin notes need to keep clear of it.
A few ordinary paragraphs next, to give the page a real reading rhythm. Footnotes should stay beside their referencing paragraph, not pile up at the end of the article, and the body text order shouldn't be broken by margin notes.
The reading progress rail updates as you scroll; it's a reading tool that lives at the page edge. When it's collapsed, the margin notes keep their distance from it. When it expands on hover, the margin notes stay pinned to the left, and the rail may cover part of them without shifting the body layout.
Some paragraphs are short, others run on across several lines. Here's another longer block, to check whether the margin notes still line up with their referencing paragraph. If a note is longer than the body text, it shouldn't squeeze the body or cover the next note either.
The article's table of contents stays on the right, so this test only looks at the blank area on the left. When the margin sidebar is open, margin notes should step aside and return to the body flow; when the reading progress rail expands, they stay put and don't jostle the body.
This block stands in for the middle of the article, specifically to confirm that margin notes still follow their own reference position after longer content3. As you keep reading, a note shouldn't push back up into the earlier group of footnotes or cover the table of contents; when the rail is expanded it can overlay the notes as a floating layer.
Ordinary paragraphs can hold more text, lists, or images in between. Here's a slightly longer test passage: margin notes are reading aids that run parallel to the body, sitting in the left blank area on desktop and dropping below the current paragraph on narrow screens.
A few more paragraphs, to confirm numbering increments in the order references first appear, not by where the footnotes are defined. Definitions still live together at the end of the Markdown file, but once rendered they return to sit near their references.
As the window narrows, margin notes stop using the blank space on the left and continue in smaller type below the referencing paragraph. This fallback layout also needs to keep paragraph spacing, so a note doesn't end up crammed against the next paragraph.
One more reference near the end4, to confirm it shows up close to the bottom of the article and still uses numbering generated in order of first appearance.
Here we'll break up the flow with a few more paragraphs of ordinary content, mimicking the examples, explanations, and asides that appear in a real article. That way you can see whether the margin notes stay with their own references instead of gradually piling up in one place because of how positions are calculated.
If the reader opens the table of contents on the right or the margin sidebar on the left, the margin notes should temporarily fall back to the body layout so they don't compete with the sidebar for space. While the reading progress bar is expanded on hover, the margin notes stay pinned to the left, and the progress bar overlay is allowed to cover them; once the sidebar is closed, they can return to the left margin.
The last paragraph holds a back-to-reference note5, to check whether the back arrow returns to the right reference; it shouldn't drag all the margin notes down to the end of the article.

Neither the image nor the code should stretch the margin notes past their width, and neither should change the reading order of the original paragraph.