A SolidJS library for transforming MDS (Markdown Steps) HAST to Solid components
npm install solid-mdsA SolidJS library for transforming MDS (Markdown Steps) HAST to Solid components.
This package works with hast-mds to render step-based Markdown content in SolidJS applications.
``bash`
npm install solid-mds hast-mdsor
pnpm add solid-mds hast-mds
Peer dependencies:
- solid-js ^1.9.0hast-mds
- ^0.1.0
`tsx
import { parse } from "hast-mds";
import { transform } from "solid-mds";
const markdown =
This is bold and italic text.;
function App() {
const parsed = parse(markdown);
const result = transform(parsed);
return
Architecture
solid-mds is designed as a thin transformation layer:
1. hast-mds parses your MDS content into HAST (Hypertext Abstract Syntax Tree)
2. solid-mds transforms HAST into renderable Solid components
This separation allows:
- Framework-agnostic parsing (use hast-mds with React, Vue, etc.)
- Optimized Solid rendering with SSR support
MDS Format
MDS (Markdown Steps) extends Markdown with step-based structure.
$3
`markdown
+++intro
Welcome
This is the introduction.
+++main
Main Content
+++conclusion
Summary
`$3
#### Global Metadata
`markdown
\\\yaml @@\\+++intro
Content
`Access via
result.global.title.#### Global Markdown Blocks
`markdown
\\\md @@/footer\\+++intro
Content
`Access via
result.global.footer (returns Solid component).#### Local Metadata (per step)
`markdown
+++slide1
\\\yaml @\\Slide Content
`Access via
result.steps.slide1.local.layout.#### Local Markdown Blocks
`markdown
+++slide1
\\\md @/notes\\Main Content
`Access via
result.steps.slide1.local.notes (returns Solid component).Custom Components
$3
`tsx
import { parse } from "hast-mds";
import { transform, ComponentMap, StandardComponentProps } from "solid-mds";const CustomHeading = (props: StandardComponentProps) => (
{props.children}
);const components: ComponentMap = {
h1: CustomHeading,
};
const parsed = parse(markdown);
const result = transform(parsed, components);
`$3
Create custom components using
yaml componentName or md componentName/path syntax:`tsx
import { parse } from "hast-mds";
import { transform, ComponentMap, CustomBlockProps } from "solid-mds";const Alert = (props: CustomBlockProps) => (
alert alert-${props.payload[0] || "info"}}>
{props.children}
);const components: ComponentMap = {
alert: Alert,
};
const markdown =
\\md alert/warning
This is a warning message!
\\\;// Register component names when parsing
const parsed = parse(markdown, new Set(["alert"]));
const result = transform(parsed, components);
`$3
`tsx
const Card = (props: CustomBlockProps) => (
{props.data?.title}
{props.data?.description}
);const components: ComponentMap = { card: Card };
const markdown =
\\yaml card
title: My Card
description: Card content here
\\\;const parsed = parse(markdown, new Set(["card"]));
const result = transform(parsed, components);
`Complete Example
`tsx
import { createSignal, Show } from "solid-js";
import { parse } from "hast-mds";
import { transform, ComponentMap, CustomBlockProps, StandardComponentProps } from "solid-mds";// Custom components
const Slide = (props: CustomBlockProps) => (
);const Code = (props: StandardComponentProps) => (
{props.children}
);const components: ComponentMap = {
slide: Slide,
code: Code,
};
const content =
\\yaml @@
title: My Presentation
author: Developer
\\\+++intro
\\\yaml @\
transition: fade
\\
Introduction slide content.
+++demo
\\\md slide/centeredDemo Time
Check out this code!
\\\
+++end
;function Presentation() {
const parsed = parse(content, new Set(["slide"]));
const result = transform(parsed, components);
const [currentId, setCurrentId] = createSignal(result.first);
const currentStep = () => result.steps[currentId()!];
const goNext = () => {
const next = currentStep()?.next;
if (next) setCurrentId(next);
};
const goPrev = () => {
const prev = currentStep()?.prev;
if (prev) setCurrentId(prev);
};
return (
{result.global?.title}
by {result.global?.author}
{currentStep().Body()}
);
}
`API Reference
$3
Transforms parsed MDS content (HAST) into Solid components.
Parameters:
-
parsed — Result from hast-mds parse() function
- components — Optional map of custom Solid componentsReturns:
`ts
interface ParseResult {
first: string | null; // First step ID
steps: Record>; // All steps by ID
count: number; // Total number of steps
global: TGlobal | null; // Global metadata
}interface Step {
id: string;
local: TLocal;
Body: Component; // Call as Body() to render
prev: string | null;
next: string | null;
current: number;
}
`$3
`ts
import type {
ComponentMap,
CustomBlockProps,
StandardComponentProps,
ParseResult,
Step,
// Re-exported from hast-mds
HastParseResult,
HastStep,
HastBody,
CustomComponents,
} from "solid-mds";
`Migration from v0.3.x
$3
1. New API:
parse() is replaced by transform()
2. Requires hast-mds: Install and use hast-mds for parsing
3. Syntax changes: Old block syntax is no longer supported$3
`tsx
import { parse } from "solid-mds";const result = parse(markdown, components);
`$3
`tsx
import { parse } from "hast-mds";
import { transform } from "solid-mds";const parsed = parse(markdown, new Set(Object.keys(components)));
const result = transform(parsed, components);
`$3
| Old Syntax | New Syntax |
|------------|------------|
|
``@@\| | `yaml @@ | `@\| | `yaml @ | `@@/name | `md @@/name | `@/name | `md @/name | `componentName\| | `yaml componentName | `componentName/path | `md componentName/path |solid-mds (via hast-mds) supports:
- Standard Markdown: Headings, bold, italic, links, images, lists, blockquotes, code
- GFM: Tables, task lists, strikethrough, autolinks
- Math: LaTeX via KaTeX ($inline$ and $$block$$)
For math rendering, include KaTeX CSS:
``html``
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"
/>
MIT