mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-15 04:40:40 -07:00
- Updated `.gitignore` to include new build and generated content directories. - Removed outdated Mintlify configuration files and documentation. - Introduced new `MIGRATION.md` to outline the transition from Mintlify to Fumadocs. - Added `mdx-components.tsx` for MDX component configuration and compatibility. - Updated `package.json` and `next.config.mjs` for new dependencies and Next.js configuration. - Created `source.config.ts` for content source configuration. - Added OpenAPI specification in `openapi.json` for API documentation. - Removed legacy files and adjusted project structure to align with Fumadocs conventions.
125 lines
3.4 KiB
TypeScript
125 lines
3.4 KiB
TypeScript
/**
|
|
* Compatibility components for Mintlify -> Fumadocs migration
|
|
* Maps Mintlify components to Fumadocs equivalents
|
|
*/
|
|
|
|
import { Card, Cards } from 'fumadocs-ui/components/card';
|
|
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
|
import { Callout } from 'fumadocs-ui/components/callout';
|
|
import type { ReactNode } from 'react';
|
|
import * as Icons from 'lucide-react';
|
|
|
|
// Icon name to Lucide icon mapping
|
|
const iconMap: Record<string, typeof Icons.Mic> = {
|
|
microphone: Icons.Mic,
|
|
film: Icons.Film,
|
|
code: Icons.Code,
|
|
shield: Icons.Shield,
|
|
download: Icons.Download,
|
|
rocket: Icons.Rocket,
|
|
apple: Icons.Apple,
|
|
windows: Icons.Monitor, // Windows doesn't exist, using Monitor instead
|
|
server: Icons.Server,
|
|
user: Icons.User,
|
|
waveform: Icons.Waves, // Waveform doesn't exist, using Waves instead
|
|
};
|
|
|
|
function getIcon(iconName?: string) {
|
|
if (!iconName) return undefined;
|
|
const IconComponent = iconMap[iconName.toLowerCase()];
|
|
return IconComponent ? <IconComponent className="w-5 h-5" /> : undefined;
|
|
}
|
|
|
|
// Frame -> Simple image wrapper (Fumadocs images are zoomable by default)
|
|
export function Frame({ children }: { children: ReactNode }) {
|
|
return <div className="my-6">{children}</div>;
|
|
}
|
|
|
|
// CardGroup -> Cards (Fumadocs component)
|
|
export function CardGroup({
|
|
cols,
|
|
children
|
|
}: {
|
|
cols?: number;
|
|
children: ReactNode;
|
|
}) {
|
|
return <Cards style={{ gridTemplateColumns: cols ? `repeat(${cols}, 1fr)` : undefined }}>{children}</Cards>;
|
|
}
|
|
|
|
// Card -> Card (maps icon string to Lucide icon)
|
|
export function MintlifyCard({
|
|
title,
|
|
icon,
|
|
href,
|
|
children
|
|
}: {
|
|
title?: string;
|
|
icon?: string;
|
|
href?: string;
|
|
children: ReactNode;
|
|
}) {
|
|
const iconElement = getIcon(icon);
|
|
|
|
// Extract text content from children to avoid nested <p> tags
|
|
// fumadocs Card component wraps description in a <p>, so we need plain content
|
|
const description = typeof children === 'string'
|
|
? children
|
|
: undefined;
|
|
|
|
return (
|
|
<Card
|
|
title={title || ''}
|
|
href={href}
|
|
icon={iconElement}
|
|
description={description}
|
|
/>
|
|
);
|
|
}
|
|
|
|
// Steps and Step are direct mappings
|
|
export { Steps, Step };
|
|
|
|
// Callout variants - Note: Fumadocs doesn't have "note" type, using "info"
|
|
export function Tip({ children }: { children: ReactNode }) {
|
|
return <Callout type="info">{children}</Callout>;
|
|
}
|
|
|
|
export function Note({ children }: { children: ReactNode }) {
|
|
return <Callout type="info">{children}</Callout>;
|
|
}
|
|
|
|
export function Warning({ children }: { children: ReactNode }) {
|
|
return <Callout type="warn">{children}</Callout>;
|
|
}
|
|
|
|
export function Info({ children }: { children: ReactNode }) {
|
|
return <Callout type="info">{children}</Callout>;
|
|
}
|
|
|
|
export function Danger({ children }: { children: ReactNode }) {
|
|
return <Callout type="error">{children}</Callout>;
|
|
}
|
|
|
|
// Accordion -> HTML details/summary (Fumadocs doesn't have built-in accordion)
|
|
export function AccordionGroup({ children }: { children: ReactNode }) {
|
|
return <div className="my-6 space-y-2">{children}</div>;
|
|
}
|
|
|
|
export function Accordion({
|
|
title,
|
|
children
|
|
}: {
|
|
title: string;
|
|
children: ReactNode;
|
|
}) {
|
|
return (
|
|
<details className="group border rounded-lg p-4">
|
|
<summary className="cursor-pointer font-semibold list-none">
|
|
<span className="group-open:rotate-90 transition-transform inline-block mr-2">▶</span>
|
|
{title}
|
|
</summary>
|
|
<div className="mt-4 pl-6">{children}</div>
|
|
</details>
|
|
);
|
|
}
|