Markdown Parts

Stable MarkdownHeading, MarkdownParagraph, and related parts from raft-ui. The complete Markdown renderer shown here is a docs-local composition, not a raft-ui export.

Preview#

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Inline: bold, italic, strikethrough, inline code, plus escaped *literal* asterisks.

First line
hard-break second line.

Labeled link and an autolink https://github.com/botiverse/slock, plus email contact@raft.build.

部署成功 🎉 完成 — emoji and CJK render as plain body text.

Raw user HTML is escaped as text: <span>not message markup</span>.

  • Unordered item
  • Nested list
    • child bullet
  1. Ordered one
  2. Ordered two
  • completed task-list item
  • open task-list item

Blockquote wraps at the same line height.


TokenSurface
layer-panelpanel
line-strongborder

markdown embed

Here is the loader I landed — no highlighting, just the mono block.

ts
const tokens = load();
console.log(tokens.layerPanel);
import {
  MarkdownBlockquote,
  MarkdownCell,
  MarkdownCheckbox,
  MarkdownHeaderCell,
  MarkdownHeading,
  MarkdownImage,
  MarkdownInlineCode,
  MarkdownLink,
  MarkdownList,
  MarkdownListItem,
  MarkdownMark,
  MarkdownOrderedList,
  MarkdownParagraph,
  MarkdownRule,
  MarkdownTable,
  MarkdownTableRow,
  MarkdownTableScroll,
} from "raft-ui";

<MarkdownHeading level={2} />
<MarkdownParagraph>
  <MarkdownLink />
  <MarkdownInlineCode />
  <MarkdownMark />
</MarkdownParagraph>
<MarkdownList>
  <MarkdownListItem>
    <MarkdownCheckbox />
  </MarkdownListItem>
</MarkdownList>
<MarkdownOrderedList>
  <MarkdownListItem />
</MarkdownOrderedList>
<MarkdownBlockquote />
<MarkdownRule />
<MarkdownImage />
<MarkdownTableScroll>
  <MarkdownTable>
    <MarkdownTableRow>
      <MarkdownHeaderCell />
      <MarkdownCell />
    </MarkdownTableRow>
  </MarkdownTable>
</MarkdownTableScroll>

Docs-local renderer#

/**
 * Default node mapping. Every entry renders a Markdown part, so consumer overrides never
 * inherit descendant styling meant for parser output. Override any entry through
 * `Markdown`'s `components` prop. Fenced code is not mapped here: override `pre` with a
 * renderer of your own.
 */
export const MARKDOWN_COMPONENTS: Components = {
  a: ({ node: _node, ...props }) => (
    <MarkdownLink {...props} target="_blank" rel="noopener noreferrer" />
  ),
  blockquote: ({ node: _node, ...props }) => <MarkdownBlockquote {...props} />,
  code: ({ node: _node, ...props }) => <MarkdownInlineCode {...props} />,
  h1: ({ node: _node, ...props }) => <MarkdownHeading level={1} {...props} />,
  h2: ({ node: _node, ...props }) => <MarkdownHeading level={2} {...props} />,
  h3: ({ node: _node, ...props }) => <MarkdownHeading level={3} {...props} />,
  h4: ({ node: _node, ...props }) => <MarkdownHeading level={4} {...props} />,
  h5: ({ node: _node, ...props }) => <MarkdownHeading level={5} {...props} />,
  h6: ({ node: _node, ...props }) => <MarkdownHeading level={6} {...props} />,
  hr: ({ node: _node, ...props }) => <MarkdownRule {...props} />,
  img: ({ node: _node, ...props }) => <MarkdownImage {...props} />,
  input: ({ node: _node, checked, disabled: _disabled, type, ...props }) => {
    if (type !== "checkbox") return <input {...props} type={type} checked={checked} />;

    return <MarkdownCheckbox checked={checked === true} />;
  },
  li: ({ node: _node, ...props }) => <MarkdownListItem {...props} />,
  mark: ({ node: _node, ...props }) => <MarkdownMark {...props} />,
  ol: ({ node: _node, ...props }) => <MarkdownOrderedList {...props} />,
  p: ({ node: _node, ...props }) => <MarkdownParagraph {...props} />,
  table: ({ node: _node, ...props }) => (
    <MarkdownTableScroll>
      <MarkdownTable {...props} />
    </MarkdownTableScroll>
  ),
  td: ({ node: _node, ...props }) => <MarkdownCell {...props} />,
  th: ({ node: _node, ...props }) => <MarkdownHeaderCell {...props} />,
  tr: ({ node: _node, ...props }) => <MarkdownTableRow {...props} />,
  ul: ({ node: _node, ...props }) => <MarkdownList {...props} />,
};

API#WIP

PropTypeDefaultDescription
level1 | 2 | 3 | 4 | 5 | 6Heading level; selects both the element and its scale.
...propsComponentPropsWithRef<"h1">Heading. The level selects both the element and its scale.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"p">Paragraph. Drops its bottom margin when it is the last child.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"mark">Highlighted run, for search matches and emphasis.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"ul">Bulleted list.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"ol">Numbered list. Shares the list slot and only switches the marker.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"li">List item.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"blockquote">Quote block.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"hr">Thematic break.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"div">Horizontal scroll container. Wrap the table in it so wide tables never overflow.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"table">Table. Borders live on the cells, not here.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"tr">Table row. The last one drops its cells' bottom border.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"th">Header cell. Carries the header surface and the column divider.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"td">Body cell. Carries the row and column dividers.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"img">Embedded image on a transparency checkerboard.
PropTypeDefaultDescription
...propsInlineCodePropsInline code, sized for body density.
PropTypeDefaultDescription
...propsCheckboxPropsTask-list checkbox. Read-only by default, since task items are display-only.