Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export default defineAppConfig({
description: 'Markdown with Components',
url: 'https://mdc-syntax.vercel.app',

ui: {
colors: {
primary: 'yellow',
neutral: 'neutral',
},
},

docus: {
footer: {
credits: {
Expand Down
11 changes: 11 additions & 0 deletions docs/app/components/AppHeaderCTA.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<UButton
v-if="$route.path === '/'"
label="Get Started"
to="/getting-started/introduction"
size="sm"
color="neutral"
variant="solid"
trailing-icon="i-lucide-arrow-right"
/>
</template>
17 changes: 8 additions & 9 deletions docs/app/components/landing/LandingGetStarted.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ import { ref } from 'vue'
const activeTab = ref('vue')

const tabs = [
{ id: 'vue', label: 'Vue' },
{ id: 'react', label: 'React' },
{ id: 'vue', label: 'Vue', icon: 'i-logos-vue' },
{ id: 'react', label: 'React', icon: 'i-logos-react' },
]

const codeSnippets = {
vue: `\`\`\`vue [pages/index.vue]\n<script setup>
import { MDC } from 'mdc-syntax/vue'

const markdown = \`# Hello **World**\`\n<`
+ `/script>
vue: `\`\`\`vue [src/App.vue]\n<script setup lang="ts">\nimport { MDC } from 'mdc-syntax/vue'\nimport Alert from './components/Alert.vue'\n\nconst md = \`\n# [Hello *World*]{.text-5xl}\n\n::alert{type="info"}\nThis is an alert!\n::\n<` + `/script>

<template>
<MDC :markdown="markdown" />
<Suspense>
<MDC :markdown="md" :components="{ Alert }" />
</Suspense>
</template>\n\`\`\``,
react: `\`\`\`tsx [src/App.tsx]\nimport { MDC } from 'mdc-syntax/react'

Expand Down Expand Up @@ -72,7 +70,8 @@ export default function App() {
v-for="tab in tabs"
:key="tab.id"
:variant="activeTab === tab.id ? 'solid' : 'soft'"
:color="activeTab === tab.id ? 'primary' : 'neutral'"
color="neutral"
:icon="tab.icon"
@click="activeTab = tab.id"
>
{{ tab.label }}
Expand Down
104 changes: 29 additions & 75 deletions examples/react-vite/README.md
Original file line number Diff line number Diff line change
@@ -1,102 +1,56 @@
---
title: React
description: A minimal example showing how to use MDC Syntax with React and Vite.
icon: i-logos-react
---

::code-tree{defaultValue="src/main.tsx" expandAll}
::code-tree{defaultValue="src/App.tsx" expandAll}

```tsx [src/main.tsx]
import { createRoot } from 'react-dom/client'
import App from './App'

createRoot(document.getElementById('root')!).render(<App />)
```

```tsx [src/App.tsx]
import { MDC } from 'mdc-syntax/react'
import Alert from './components/Alert'

const el = document.getElementById('root')!
const markdown = `
# Hello *World*]

createRoot(el)
.render(<MDC markdown={`# Hello *World*`} />)
::alert{type="info"}
This is an alert!
::
`

export default function App() {
return (
<MDC
markdown={markdown}
components={{ Alert }}
/>
)
}
```

```ts [vite.config.ts]
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
plugins: [
react(),
tailwindcss(),
],
})
...
```

```json [package.json]
{
"name": "mdc-syntax-react-example",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"mdc-syntax": "workspace:*",
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/react": "^19.2.10",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.3",
"typescript": "^5.9.3",
"vite": "^7.3.1"
}
}
...
```

```html [index.html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MDC Syntax - React Example</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
...
```

```json [tsconfig.json]
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}
...
```

::


This example demonstrates the simplest way to use MDC Syntax with React - just import the `MDC` component and pass it markdown content. The component handles parsing and rendering automatically.
This example demonstrates the simplest way to use MDC Syntax with React - use the `MDC` component and pass it markdown content. The component handles parsing and rendering automatically.
1 change: 1 addition & 0 deletions examples/react-vite/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MDC Syntax - React Example</title>
<link href="/src/index.css" rel="stylesheet">
</head>
<body>
<div id="root"></div>
Expand Down
19 changes: 19 additions & 0 deletions examples/react-vite/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MDC } from 'mdc-syntax/react'
import Alert from './components/Alert'

const markdown = `
# Hello *World*

::alert{type="info"}
This is an alert!
::
`

export default function App() {
return (
<MDC
markdown={markdown}
components={{ Alert }}
/>
)
}
19 changes: 19 additions & 0 deletions examples/react-vite/src/components/Alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { ReactNode } from 'react'

const config = {
info: 'bg-blue-50 border-blue-400 text-blue-900 dark:bg-blue-950/50 dark:border-blue-500/50 dark:text-blue-200',
warning: 'bg-amber-50 border-amber-400 text-amber-900 dark:bg-amber-950/50 dark:border-amber-500/50 dark:text-amber-200',
success: 'bg-emerald-50 border-emerald-400 text-emerald-900 dark:bg-emerald-950/50 dark:border-emerald-500/50 dark:text-emerald-200',
danger: 'bg-red-50 border-red-400 text-red-900 dark:bg-red-950/50 dark:border-red-500/50 dark:text-red-200',
}

export default function Alert({ type = 'info', children }: { type?: 'info' | 'warning' | 'success' | 'danger', children?: ReactNode }) {
return (
<div
className={`my-4 rounded-lg border-l-4 px-4 py-3 text-sm leading-relaxed ${config[type]}`}
role="alert"
>
{children}
</div>
)
}
6 changes: 6 additions & 0 deletions examples/react-vite/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@import "tailwindcss";
@source "../node_modules/mdc-syntax";

body {
@apply bg-neutral-50 dark:bg-neutral-950 p-4 text-neutral-900 dark:text-neutral-50;
}
6 changes: 2 additions & 4 deletions examples/react-vite/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { createRoot } from 'react-dom/client'
import { MDC } from 'mdc-syntax/react'
import App from './App'

const el = document.getElementById('root')!

createRoot(el).render(<MDC markdown="# Hello *World*" />)
createRoot(document.getElementById('root')!).render(<App />)
1 change: 1 addition & 0 deletions examples/vue-vite/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Vue
description: A minimal example showing how to use MDC Syntax with Vue 3 and Vite.
icon: i-logos-vue
---

::code-tree{defaultValue="src/App.vue" expandAll}
Expand Down
16 changes: 15 additions & 1 deletion examples/vue-vite/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
<script setup lang="ts">
import { MDC } from 'mdc-syntax/vue'
import Alert from './components/Alert.vue'

const markdown = `
# Hello *World*

::alert{type="info"}
This is an alert!
::
`
</script>

<template>
<MDC markdown="# Hello *World*" />
<Suspense>
<MDC
:markdown="markdown"
:components="{ Alert }"
/>
</Suspense>
</template>
24 changes: 24 additions & 0 deletions examples/vue-vite/src/components/Alert.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
const props = withDefaults(defineProps<{
type?: 'info' | 'warning' | 'success' | 'danger'
}>(), {
type: 'info',
})

const config = {
info: 'bg-blue-50 border-blue-400 text-blue-900 dark:bg-blue-950/50 dark:border-blue-500/50 dark:text-blue-200',
warning: 'bg-amber-50 border-amber-400 text-amber-900 dark:bg-amber-950/50 dark:border-amber-500/50 dark:text-amber-200',
success: 'bg-emerald-50 border-emerald-400 text-emerald-900 dark:bg-emerald-950/50 dark:border-emerald-500/50 dark:text-emerald-200',
danger: 'bg-red-50 border-red-400 text-red-900 dark:bg-red-950/50 dark:border-red-500/50 dark:text-red-200',
}
</script>

<template>
<div
:class="config[props.type]"
class="my-4 rounded-lg border-l-4 px-4 py-3 text-sm leading-relaxed"
role="alert"
>
<slot />
</div>
</template>
7 changes: 7 additions & 0 deletions examples/vue-vite/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import "tailwindcss";
@source "./**/*.vue";
@source "../node_modules/mdc-syntax";

body {
@apply bg-neutral-50 dark:bg-neutral-950 p-4 text-neutral-900 dark:text-neutral-50;
}
2 changes: 1 addition & 1 deletion packages/mdc-syntax/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import { Math } from '@mdc-syntax/math/react'

function App() {
const chatMessage = ...
return <MDC markdown={chatMessage} components={{ Math }} options={{ plugind: [cjkPlugin, mathPlugin] }} />
return <MDC markdown={chatMessage} components={{ Math }} options={{ plugins: [cjkPlugin, mathPlugin] }} />
}
```

Expand Down
6 changes: 3 additions & 3 deletions packages/mdc-syntax/src/react/components/MDCRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MinimarkElement, MinimarkNode, MinimarkTree } from 'minimark'
import React, { lazy, Suspense, useMemo } from 'react'
import { standardProseComponents } from '.'
import { camelCase } from 'scule'
import { camelCase, pascalCase } from 'scule'
import { findLastTextNodeAndAppendNode, getCaret } from '../../utils/caret'

/**
Expand Down Expand Up @@ -125,8 +125,8 @@ function renderNode(
const nodeProps = getProps(node)
const children = getChildren(node)

// Check if there's a custom component for this tag
let customComponent = components[tag]
// Check if there's a custom component for this tag (exact match or PascalCase)
let customComponent = components[tag] || components[pascalCase(tag)]

// If not in components map and manifest is provided, try dynamic resolution
if (!customComponent && componentsManifest && !defaultTagMap[tag]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const ProsePre: React.FC<ProsePreProps> = ({
{/* Header with language label and copy button */}
<div className="rounded-t-lg border border-b-0 border-neutral-300 dark:border-neutral-700 top-[-1.5rem] right-0 left-0 flex items-center justify-between px-4 py-2 z-10">
{/* Language label */}
<span className="font-mono font-semibold tracking-wider text-neutral-600 dark:text-neutral-400 bg-neutral-200/80 dark:bg-neutral-800/80 px-2.5 py-1 rounded backdrop-blur-sm">
<span className="font-mono text-sm font-semibold tracking-wider text-neutral-600 dark:text-neutral-400 bg-neutral-200/80 dark:bg-neutral-800/80 px-2.5 py-1 rounded backdrop-blur-sm">
{filename || language}
</span>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export const ShikiCodeBlock: React.FC<ShikiCodeBlockProps> = ({
{/* Fallback with header padding */}
{!isLoading && !stream && (
<pre className={fallbackWithHeaderClass}>
<code className="font-mono text-sm leading-relaxed block whitespace-pre">
<code className="font-mono text-sm leading-tight block whitespace-pre">
{codeContent}
</code>
</pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

const props = withDefaults(defineProps<{
// @eslint-disable-next-line vue/prop-name-casing
__node: any

Check warning on line 7 in packages/mdc-syntax/src/vue/components/prose/ProsePre.vue

View workflow job for this annotation

GitHub Actions / test

Prop "__node" is not in camelCase
language?: string
theme?: string
filename?: string
Expand Down Expand Up @@ -66,7 +66,7 @@
<div class="rounded-t-lg border border-b-0 border-neutral-300 dark:border-neutral-700 top-[-1.5rem] right-0 left-0 flex items-center justify-between px-4 py-2 z-10">
<!-- Language label -->
<span
class="font-mono font-semibold tracking-wider text-neutral-600 dark:text-neutral-400 bg-neutral-200/80 dark:bg-neutral-800/80 px-2.5 py-1 rounded backdrop-blur-sm"
class="font-mono text-sm font-semibold tracking-wider text-neutral-600 dark:text-neutral-400 bg-neutral-200/80 dark:bg-neutral-800/80 px-2.5 py-1 rounded backdrop-blur-sm"
>
{{ filename || language }}
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

const props = withDefaults(defineProps<{
// @eslint-disable-next-line vue/prop-name-casing
__node: any

Check warning on line 9 in packages/mdc-syntax/src/vue/components/prose/ProsePreShiki.vue

View workflow job for this annotation

GitHub Actions / test

Prop "__node" is not in camelCase
language?: string
theme?: string
filename?: string
Expand Down Expand Up @@ -101,7 +101,7 @@
<div class="absolute top-0 right-0 left-0 flex items-center justify-between px-4 py-2 z-10">
<!-- Language label -->
<span
class="font-mono font-semibold tracking-wider text-neutral-600 dark:text-neutral-400 bg-neutral-200/80 dark:bg-neutral-800/80 px-2.5 py-1 rounded backdrop-blur-sm"
class="font-mono text-sm font-semibold tracking-wider text-neutral-600 dark:text-neutral-400 bg-neutral-200/80 dark:bg-neutral-800/80 px-2.5 py-1 rounded backdrop-blur-sm"
>
{{ filename || language }}
</span>
Expand Down Expand Up @@ -177,7 +177,7 @@
:class="fallbackWithHeaderClass"
>
sas
<code class="font-mono text-sm leading-relaxed block whitespace-pre">{{ codeContent }}</code>
<code class="font-mono text-sm leading-tight block whitespace-pre">{{ codeContent }}</code>
</pre>
</div>
</template>
Expand Down
Loading