.do
Mdxmdxui

mdxui

Type-aware components for rendering MDXLD documents

MDXUI: Components for MDXLD Types

MDXUI provides type-aware components that know how to render different MDXLD $type values - whether it's a LandingPage, Site, App, API docs, or Documentation.

What is MDXUI?

MDXUI maps MDXLD semantic types to appropriate UI components:

---
$type: LandingPage
title: Welcome to Our Product
---

{/* MDXUI automatically renders LandingPage with Hero, Features, etc. */}

The same content with a different $type renders differently:

---
$type: Documentation
title: Welcome to Our Product
---

{/* Same content, but renders as docs with navigation, search, etc. */}

Type-Aware Rendering:

  • LandingPage → Hero, Features, Pricing, Testimonials
  • Documentation → Sidebar, Search, TOC, Breadcrumbs
  • BlogPost → Article layout, Author info, Related posts
  • Product → Gallery, Specs, Reviews, Buy button
  • API → Endpoints, Parameters, Examples, Try-it
  • App → Full-page layout with routing and state
  • Site → Multi-page with navigation and footer

Also provides:

  • Layout Components: Container, Grid, Flex, Stack, Section
  • Primitive Components: Button, Card, Input, Badge
  • Semantic HTML: Proper HTML5 elements for each type
  • Accessibility: ARIA attributes and keyboard navigation
  • Themeable: Customize appearance per type

Installation

pnpm install mdxui

Quick Start

Automatic Type-Based Rendering

MDXUI automatically applies the right layout based on $type:

---
$type: LandingPage
title: My Product
features:
  - Fast Performance
  - Easy to Use
  - Secure
pricing:
  - name: Free
    price: $0
  - name: Pro
    price: $29
---

# {data.title}

The best product for your needs.

MDXUI sees $type: LandingPage and automatically:

  • Wraps content in landing page layout
  • Renders data.features as feature cards
  • Renders data.pricing as pricing table
  • Adds appropriate semantic HTML and meta tags

Manual Component Usage

You can also use components directly:

import { Button, Card, Grid } from 'mdxui'

<Grid cols={3}>
  <Card title="Feature 1">
    <Button>Learn More</Button>
  </Card>
  <Card title="Feature 2">
    <Button>Learn More</Button>
  </Card>
  <Card title="Feature 3">
    <Button>Learn More</Button>
  </Card>
</Grid>

Note: In MDX files, the markdown/content itself is automatically the default export - you don't need to explicitly export components or the page itself. Just write markdown and use components inline.

Type-Based Rendering

MDXUI provides specialized rendering for each MDXLD type:

$type: LandingPage

Renders with hero, features, pricing, testimonials:

---
$type: LandingPage
title: Welcome to Product
subtitle: The best solution for your needs
cta:
  text: Get Started
  url: /signup
features:
  - icon: 
    title: Fast
    description: Lightning-fast performance
  - icon: 🔒
    title: Secure
    description: Bank-level security
pricing:
  - name: Starter
    price: $0
    features: [10 projects, 100 GB]
  - name: Pro
    price: $29
    features: [Unlimited, 1 TB]
---

# {data.title}

{data.subtitle}

Renders as: Hero section + Features grid + Pricing table + CTA

$type: Documentation

Renders with sidebar, search, table of contents:

---
$type: Documentation
title: Getting Started
category: Guides
sidebar:
  - Installation
  - Configuration
  - Usage
---

# {data.title}

This guide will help you get started.

## Installation

Install the package...

Renders as: Sidebar navigation + Content area + Search + TOC

$type: BlogPost

Renders as article with metadata:

---
$type: BlogPost
title: Introduction to GraphQL
author: Jane Developer
date: 2025-10-27
tags: [graphql, api, tutorial]
---

# {data.title}

By {data.author} on {data.date}

Content here...

Renders as: Article header + Author info + Reading time + Related posts

$type: Product

Renders with gallery, specs, reviews:

---
$type: Product
name: Widget Pro
price: 99.99
images:
  - /products/widget-1.jpg
  - /products/widget-2.jpg
specs:
  - Dimensions: 10x5x3 inches
  - Weight: 2.5 lbs
reviews:
  - author: John
    rating: 5
    text: Amazing product!
---

# {data.name}

${data.price}

Premium widget with advanced features.

Renders as: Image gallery + Price + Specs table + Reviews + Buy button

$type: API

Renders with endpoint browser, try-it console:

---
$type: API
title: Users API
baseUrl: https://api.example.com
endpoints:
  - method: GET
    path: /users
    description: List all users
    params:
      - name: limit
        type: number
  - method: POST
    path: /users
    description: Create user
---

# {data.title}

Base URL: {data.baseUrl}

## Endpoints

API documentation here...

Renders as: Endpoint list + Parameters + Examples + Try-it console

$type: App

Renders as full application with routing:

---
$type: App
title: My Dashboard
routes:
  - path: /
    component: Home
  - path: /settings
    component: Settings
nav:
  - Dashboard
  - Analytics
  - Settings
---

# {data.title}

Full app content...

Renders as: App shell + Router + Navigation + Content area

$type: Site

Renders as multi-page website:

---
$type: Site
title: Company Website
pages:
  - Home
  - About
  - Contact
nav:
  logo: /logo.svg
  links:
    - Home: /
    - About: /about
footer:
  copyright: 2025 Company
  links:
    - Privacy: /privacy
---

# {data.title}

Site content...

Renders as: Header + Nav + Pages + Footer

Same Content, Different Types

The same MDX content can render multiple ways depending on $type:

---
$type: LandingPage  # or Documentation, BlogPost, Product, etc.
title: Welcome
description: Learn about our product
features:
  - Fast
  - Secure
  - Scalable
---

# {data.title}

{data.description}

Our product is amazing!

As LandingPage: Hero with CTA + Feature cards + Marketing layout As Documentation: Sidebar + Content + Search + Doc layout As BlogPost: Article format + Author + Date + Blog layout As Product: Product page + Images + Buy button + E-commerce layout

Layout Components

Container

Center and constrain content width:

<Container>
  <h1>Page Title</h1>
  <p>Content is centered with max width</p>
</Container>

<Container size="small">Narrow</Container>
<Container size="large">Wide</Container>

Grid

Responsive grid layouts:

<Grid cols={3}>
  <div>Column 1</div>
  <div>Column 2</div>
  <div>Column 3</div>
</Grid>

<Grid cols={2} gap="large">
  <Card>Item 1</Card>
  <Card>Item 2</Card>
</Grid>

Flex

Flexbox layouts:

<Flex direction="row" align="center" justify="space-between">
  <div>Left</div>
  <div>Right</div>
</Flex>

<Flex direction="column" gap="medium">
  <Card>Item 1</Card>
  <Card>Item 2</Card>
</Flex>

Stack

Vertical spacing:

<Stack spacing="large">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</Stack>

Primitive Components

Button

<Button>Default</Button>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="danger">Delete</Button>
<Button href="/docs">Link</Button>
<Button size="small">Small</Button>
<Button size="large">Large</Button>

Card

<Card title="Title">
  Card content goes here
</Card>

<Card title="With Icon" icon="📚">
  Content
</Card>

<Card variant="bordered">
  Bordered card
</Card>

Badge

<Badge>Default</Badge>
<Badge variant="success">New</Badge>
<Badge variant="warning">Beta</Badge>
<Badge variant="error">Deprecated</Badge>

Feature Components

Hero

<Hero
  title="Welcome to Our Platform"
  subtitle="Build amazing things faster"
  cta={<Button variant="primary" size="large">Get Started</Button>}
  image="/hero.png"
/>

Features

<Features
  items={[
    {
      icon: "⚡",
      title: "Fast",
      description: "Lightning-fast performance"
    },
    {
      icon: "🔒",
      title: "Secure",
      description: "Built-in security"
    },
    {
      icon: "🌍",
      title: "Global",
      description: "Worldwide CDN"
    }
  ]}
/>

Pricing

<Pricing
  plans={[
    {
      name: 'Free',
      price: '$0',
      features: ['10 projects', '100 GB storage'],
      cta: <Button>Start Free</Button>
    },
    {
      name: 'Pro',
      price: '$29',
      features: ['Unlimited projects', '1 TB storage'],
      cta: <Button variant="primary">Upgrade</Button>,
      highlighted: true
    }
  ]}
/>

Testimonials

<Testimonials
  items={[
    {
      quote: "Amazing product!",
      author: "Jane Developer",
      role: "CTO at TechCorp",
      avatar: "/avatars/jane.jpg"
    }
  ]}
/>

Stats

<Stats
  items={[
    { label: 'Users', value: '10,245', change: '+12%' },
    { label: 'Revenue', value: '$45.2K', change: '+23%' },
    { label: 'Conversion', value: '3.2%', change: '-2%' }
  ]}
/>

Content Components

Callout

<Callout type="info">
  This is an informational message
</Callout>

<Callout type="warning">
  Warning message
</Callout>

<Callout type="error">
  Error message
</Callout>

<Callout type="success">
  Success message
</Callout>

Tabs

<Tabs>
  <Tab title="Installation">
    ## Installation
    \`\`\`bash
    pnpm install mdxui
    \`\`\`
  </Tab>
  <Tab title="Usage">
    ## Usage
    Import components
  </Tab>
</Tabs>

Accordion

<Accordion>
  <AccordionItem title="What is MDX?">
    MDX combines Markdown with JSX
  </AccordionItem>
  <AccordionItem title="How to get started?">
    Install and import components
  </AccordionItem>
</Accordion>

Code Block

<CodeBlock
  language="typescript"
  code={\`
function greet(name: string) {
  return \`Hello, \${name}!\`
}
\`}
  showLineNumbers
  highlightLines={[2]}
/>

Form Components

Input

<Input
  label="Name"
  placeholder="Enter your name"
  required
/>

<Input
  type="email"
  label="Email"
  placeholder="[email protected]"
/>

Select

<Select
  label="Country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'ca', label: 'Canada' }
  ]}
/>

Textarea

<Textarea
  label="Message"
  rows={4}
  placeholder="Enter your message"
/>

Checkbox

<Checkbox label="I agree to terms" />
<Checkbox label="Subscribe to newsletter" defaultChecked />

Theming

Default Theme

import { ThemeProvider } from 'mdxui'

export default function Layout({ children }) {
  return (
    <ThemeProvider>
      {children}
    </ThemeProvider>
  )
}

Custom Theme

import { createTheme, ThemeProvider } from 'mdxui'

const theme = createTheme({
  colors: {
    primary: '#007bff',
    secondary: '#6c757d',
    success: '#28a745',
    warning: '#ffc107',
    error: '#dc3545',
    info: '#17a2b8',
  },
  fonts: {
    body: 'system-ui, sans-serif',
    heading: 'Georgia, serif',
    mono: 'Consolas, monospace',
  },
  spacing: {
    small: '0.5rem',
    medium: '1rem',
    large: '2rem',
  },
})

export default function Layout({ children }) {
  return (
    <ThemeProvider theme={theme}>
      {children}
    </ThemeProvider>
  )
}

Tailwind Integration

Use with Tailwind CSS:

// tailwind.config.js
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './node_modules/mdxui/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        primary: '#007bff',
      },
    },
  },
}

Components automatically use Tailwind classes:

<Button className="bg-primary text-white">
  Custom Styled Button
</Button>

Accessibility

All components include:

  • Semantic HTML: Proper HTML5 elements
  • ARIA Attributes: Labels, roles, and states
  • Keyboard Navigation: Tab, Enter, Escape, Arrow keys
  • Focus Management: Visible focus indicators
  • Screen Reader Support: Descriptive labels

Example:

<Button
  aria-label="Close dialog"
  aria-pressed={isPressed}
>
  Close
</Button>

<Tabs aria-label="Navigation tabs">
  <Tab title="Home">Home content</Tab>
  <Tab title="About">About content</Tab>
</Tabs>

Responsive Design

Components are mobile-first and responsive:

<Grid cols={1} md={2} lg={3}>
  <Card>Mobile: 1 col, Tablet: 2 cols, Desktop: 3 cols</Card>
</Grid>

<Flex direction="column" md="row">
  <div>Stacks on mobile, horizontal on tablet+</div>
</Flex>

Advanced Usage

Composition

Build complex UIs:

<Container>
  <Hero
    title="Welcome"
    cta={<Button>Get Started</Button>}
  />

  <Section>
    <Grid cols={3}>
      <Card><Features /></Card>
      <Card><Pricing /></Card>
      <Card><Testimonials /></Card>
    </Grid>
  </Section>

  <Section>
    <Tabs>
      <Tab title="Docs"><Documentation /></Tab>
      <Tab title="Examples"><Examples /></Tab>
    </Tabs>
  </Section>
</Container>

Custom Components

Extend MDXUI components:

import { Button as BaseButton } from 'mdxui'

export function CustomButton({ children, ...props }) {
  return (
    <BaseButton
      {...props}
      className="custom-styles"
    >
      {children}
    </BaseButton>
  )
}

Use Cases

Documentation Sites

<Container>
  <Tabs>
    <Tab title="Getting Started">
      <Callout type="info">Install the package</Callout>
      <CodeBlock language="bash" code="pnpm install" />
    </Tab>
    <Tab title="API Reference">
      <Accordion>
        <AccordionItem title="Functions">...</AccordionItem>
        <AccordionItem title="Types">...</AccordionItem>
      </Accordion>
    </Tab>
  </Tabs>
</Container>

Landing Pages

<Hero title="Product Name" cta={<Button>Sign Up</Button>} />
<Features items={features} />
<Pricing plans={plans} />
<Testimonials items={testimonials} />
<Footer />

Blogs

<Container size="small">
  <article>
    # Blog Post Title

    <Callout type="info">
      Published on {date}
    </Callout>

    Content here...

    <Grid cols={2}>
      <Card>Related Post 1</Card>
      <Card>Related Post 2</Card>
    </Grid>
  </article>
</Container>

Next Steps