mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
Core & UI: Move Typescript integrations to fumadocs-typescript
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-typescript': major
|
||||
---
|
||||
|
||||
Support markdown in type description
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
'fumadocs-core': major
|
||||
'fumadocs-ui': major
|
||||
---
|
||||
|
||||
**Move Typescript integrations to `fumadocs-typescript`**
|
||||
|
||||
why: It is now a stable feature
|
||||
|
||||
migrate: Use `fumadocs-typescript` instead.
|
||||
|
||||
```diff
|
||||
- import { AutoTypeTable } from "fumadocs-ui/components/auto-type-table"
|
||||
+ import { AutoTypeTable } from "fumadocs-typescript/ui"
|
||||
```
|
||||
@@ -346,7 +346,6 @@ function Hero(): JSX.Element {
|
||||
baseFrequency="0.6"
|
||||
numOctaves="1"
|
||||
seed="15"
|
||||
stitchTiles="stitch"
|
||||
result="turbulence"
|
||||
/>
|
||||
<feComposite in="SourceGraphic" in2="turbulence" operator="in" />
|
||||
|
||||
@@ -12,7 +12,7 @@ Your `tsconfig.json` file in the current working directory will be loaded. You m
|
||||
It accepts a `path` prop which should be a typescript file, and `name` for the exported type name.
|
||||
|
||||
```mdx
|
||||
import { AutoTypeTable } from 'fumadocs-ui/components/auto-type-table';
|
||||
import { AutoTypeTable } from 'fumadocs-typescript/ui';
|
||||
|
||||
<AutoTypeTable path="./path/to/file.ts" name="MyInterface" />
|
||||
```
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { DocsLayoutProps } from 'fumadocs-ui/layout';
|
||||
import type { AnchorHTMLAttributes, ComponentPropsWithoutRef } from 'react';
|
||||
import type { DocsPageProps } from 'fumadocs-ui/page';
|
||||
import type { RootProviderProps } from 'fumadocs-ui/provider';
|
||||
import type { AutoTypeTable } from 'fumadocs-ui/components/auto-type-table';
|
||||
import type { AutoTypeTable } from 'fumadocs-typescript/ui';
|
||||
|
||||
export type AccordionsProps = Omit<
|
||||
ComponentPropsWithoutRef<typeof Accordions>,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from 'fumadocs-ui/components/codeblock';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Popup, PopupContent, PopupTrigger } from 'fumadocs-ui/twoslash/popup';
|
||||
import { AutoTypeTable } from 'fumadocs-ui/components/auto-type-table';
|
||||
import { AutoTypeTable } from 'fumadocs-typescript/ui';
|
||||
import { Wrapper } from '@/components/preview/wrapper';
|
||||
import { cn } from './utils/cn';
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-mdx": "workspace:*",
|
||||
"fumadocs-twoslash": "workspace:^",
|
||||
"fumadocs-typescript": "workspace:^",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"geist": "^1.2.0",
|
||||
"katex": "^0.16.8",
|
||||
|
||||
@@ -44,10 +44,6 @@
|
||||
"import": "./dist/link.js",
|
||||
"types": "./dist/link.d.ts"
|
||||
},
|
||||
"./typescript": {
|
||||
"import": "./dist/typescript.js",
|
||||
"types": "./dist/typescript.d.ts"
|
||||
},
|
||||
"./middleware": {
|
||||
"import": "./dist/middleware.js",
|
||||
"types": "./dist/middleware.d.ts"
|
||||
@@ -76,9 +72,6 @@
|
||||
"toc": [
|
||||
"./dist/toc.d.ts"
|
||||
],
|
||||
"typescript": [
|
||||
"./dist/typescript.d.ts"
|
||||
],
|
||||
"search/client": [
|
||||
"./dist/search/client.d.ts"
|
||||
],
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
external: [
|
||||
'@algolia/client-search',
|
||||
'algoliasearch',
|
||||
'unified',
|
||||
'typescript',
|
||||
],
|
||||
external: ['@algolia/client-search', 'algoliasearch', 'unified'],
|
||||
dts: true,
|
||||
target: 'es6',
|
||||
format: 'esm',
|
||||
@@ -16,6 +11,6 @@ export default defineConfig({
|
||||
'src/{search,search-algolia}/client.ts',
|
||||
'src/search/shared.ts',
|
||||
'src/{search,search-algolia}/server.ts',
|
||||
'src/{middleware,typescript}.ts',
|
||||
'src/middleware.ts',
|
||||
],
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ A CLI tool to create new Next.js documentation sites with Fumadocs.
|
||||
```bash
|
||||
npx create-fumadocs-app
|
||||
#or
|
||||
pnpx create-fumadocs-app
|
||||
pnpm create fumadocs-app
|
||||
#or
|
||||
yarn create fumadocs-app
|
||||
```
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
extends: ['custom/library'],
|
||||
ignorePatterns: ['*.test.ts'],
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
# Fumadocs Typescript
|
||||
|
||||
Typescript Integration for Fumadocs.
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "fumadocs-typescript",
|
||||
"version": "0.0.0",
|
||||
"description": "Typescript Integration for Fumadocs",
|
||||
"keywords": [
|
||||
"NextJs",
|
||||
"fumadocs",
|
||||
"Docs"
|
||||
],
|
||||
"homepage": "https://fumadocs.vercel.app",
|
||||
"repository": "github:fuma-nama/fumadocs",
|
||||
"license": "MIT",
|
||||
"author": "Fuma Nama",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./ui": {
|
||||
"import": "./dist/ui/index.js",
|
||||
"types": "./dist/ui/index.d.ts"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"ui": [
|
||||
"./dist/ui/index.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"clean": "rimraf dist",
|
||||
"dev": "tsup --watch",
|
||||
"lint": "eslint .",
|
||||
"types:check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"hast-util-to-jsx-runtime": "^2.3.0",
|
||||
"mdast-util-from-markdown": "^2.0.0",
|
||||
"mdast-util-gfm": "^3.0.0",
|
||||
"mdast-util-to-hast": "^13.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/mdast": "^4.0.3",
|
||||
"@types/react": "18.2.0",
|
||||
"@types/react-dom": "18.2.1",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"tsconfig": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
@@ -81,8 +81,9 @@ function getExportedSymbol({
|
||||
const fileSymbol = checker.getSymbolAtLocation(sourceFile);
|
||||
if (!fileSymbol) return;
|
||||
|
||||
const exports = checker.getExportsOfModule(fileSymbol);
|
||||
return exports.find((e) => e.getEscapedName().toString() === name);
|
||||
return checker
|
||||
.getExportsOfModule(fileSymbol)
|
||||
.find((e) => e.getEscapedName().toString() === name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -0,0 +1 @@
|
||||
export * from './generate';
|
||||
@@ -0,0 +1,31 @@
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown';
|
||||
import { gfmFromMarkdown } from 'mdast-util-gfm';
|
||||
import { toHast } from 'mdast-util-to-hast';
|
||||
import {
|
||||
type Jsx,
|
||||
type Fragment,
|
||||
toJsxRuntime,
|
||||
} from 'hast-util-to-jsx-runtime';
|
||||
import * as runtime from 'react/jsx-runtime';
|
||||
|
||||
declare module 'react/jsx-runtime' {
|
||||
export const Fragment: Fragment;
|
||||
export const jsx: Jsx;
|
||||
export const jsxs: Jsx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns html
|
||||
*/
|
||||
export function renderMarkdown(md: string): JSX.Element {
|
||||
const mdast = fromMarkdown(
|
||||
md.replace(/{@link (?<link>[^}]*)}/g, '$1'), // replace jsdoc links
|
||||
{ mdastExtensions: [gfmFromMarkdown()] },
|
||||
);
|
||||
|
||||
return toJsxRuntime(toHast(mdast), {
|
||||
Fragment: runtime.Fragment,
|
||||
jsx: runtime.jsx,
|
||||
jsxs: runtime.jsxs,
|
||||
});
|
||||
}
|
||||
+5
-4
@@ -1,8 +1,9 @@
|
||||
import { Options, generateDocumentation } from 'fumadocs-core/typescript';
|
||||
import { TypeTable } from 'fumadocs-ui/components/type-table';
|
||||
import { renderMarkdown } from '@/markdown';
|
||||
import type { Options } from '../generate';
|
||||
import { generateDocumentation } from '../generate';
|
||||
import 'server-only';
|
||||
|
||||
declare const { TypeTable }: typeof import('./type-table');
|
||||
|
||||
/**
|
||||
* **Server Component Only**
|
||||
*
|
||||
@@ -26,7 +27,7 @@ export function AutoTypeTable({
|
||||
entry.name,
|
||||
{
|
||||
type: entry.type,
|
||||
description: entry.description,
|
||||
description: renderMarkdown(entry.description),
|
||||
default: entry.default,
|
||||
},
|
||||
]),
|
||||
@@ -0,0 +1 @@
|
||||
export * from './auto-type-table';
|
||||
Vendored
+12
-2
@@ -31,15 +31,25 @@
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"name": "file",
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"name": "transform",
|
||||
"description": "Modify output property entry",
|
||||
"type": "(this: EntryContext, entry: DocEntry, propertyType: Type, propertySymbol: Symbol) => void"
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"description": "",
|
||||
"type": "string"
|
||||
"type": "Partial<{ files: string[]; tsconfigPath: string; basePath: string; }>"
|
||||
}
|
||||
]
|
||||
]
|
||||
+1
-1
@@ -10,7 +10,7 @@ export type Test2 = Test1 & {
|
||||
generic: GenericType<string, string, string>;
|
||||
};
|
||||
|
||||
export type { BreadcrumbItem as Test3 } from '@/breadcrumb';
|
||||
export type { Options as Test3 } from '../../src/generate';
|
||||
|
||||
interface GenericType<A, B, C> {
|
||||
A: A;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { generateDocumentation } from '../src/typescript';
|
||||
import { generateDocumentation } from '../src/generate';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import path from 'node:path';
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "tsconfig/react-library.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["./src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
external: ['server-only', 'fumadocs-ui', 'react'],
|
||||
dts: true,
|
||||
target: 'es6',
|
||||
format: 'esm',
|
||||
entry: ['src/index.ts', 'src/ui/index.ts'],
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineProject } from 'vitest/config';
|
||||
|
||||
export default defineProject({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@/': new URL('./src/', import.meta.url).pathname,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -3,6 +3,7 @@
|
||||
import { InfoIcon } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import type { ReactNode } from 'react';
|
||||
import { cva } from 'class-variance-authority';
|
||||
import { cn } from '@/utils/cn';
|
||||
import {
|
||||
Popover,
|
||||
@@ -16,7 +17,7 @@ export function Info({ children }: { children: ReactNode }): JSX.Element {
|
||||
<PopoverTrigger>
|
||||
<InfoIcon className="size-4" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="text-sm">{children}</PopoverContent>
|
||||
<PopoverContent className="prose text-sm">{children}</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
@@ -25,7 +26,7 @@ interface ObjectType {
|
||||
/**
|
||||
* Additional description of the field
|
||||
*/
|
||||
description?: string;
|
||||
description?: ReactNode;
|
||||
type: string;
|
||||
typeDescription?: string;
|
||||
/**
|
||||
@@ -35,40 +36,42 @@ interface ObjectType {
|
||||
default?: string;
|
||||
}
|
||||
|
||||
const th = cva('p-2 font-medium first:pl-0 last:pr-0');
|
||||
const td = cva('p-2 first:pl-0 last:pr-0');
|
||||
const field = cva('inline-flex flex-row items-center gap-1');
|
||||
const code = cva('rounded-md bg-secondary p-1 text-secondary-foreground', {
|
||||
variants: {
|
||||
color: { primary: 'bg-primary/10 text-primary' },
|
||||
},
|
||||
});
|
||||
|
||||
export function TypeTable({
|
||||
type,
|
||||
}: {
|
||||
type: Record<string, ObjectType>;
|
||||
}): JSX.Element {
|
||||
const th = cn('p-2 font-medium first:pl-0 last:pr-0');
|
||||
const td = cn('p-2 first:pl-0 last:pr-0');
|
||||
const field = cn('inline-flex flex-row items-center gap-1');
|
||||
const code = cn('rounded-md bg-secondary p-1 text-secondary-foreground');
|
||||
|
||||
return (
|
||||
<div className="not-prose overflow-auto whitespace-nowrap">
|
||||
<table className="my-4 w-full text-left text-sm text-muted-foreground">
|
||||
<thead className="border-b">
|
||||
<tr>
|
||||
<th className={cn(th, 'w-[45%]')}>Prop</th>
|
||||
<th className={cn(th, 'w-[30%]')}>Type</th>
|
||||
<th className={cn(th, 'w-[25%]')}>Default</th>
|
||||
<th className={cn(th(), 'w-[45%]')}>Prop</th>
|
||||
<th className={cn(th(), 'w-[30%]')}>Type</th>
|
||||
<th className={cn(th(), 'w-[25%]')}>Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="border-collapse divide-y divide-border">
|
||||
{Object.entries(type).map(([key, value]) => (
|
||||
<tr key={key}>
|
||||
<td className={td}>
|
||||
<div className={field}>
|
||||
<code className={cn(code, 'bg-primary/10 text-primary')}>
|
||||
{key}
|
||||
</code>
|
||||
<td className={td()}>
|
||||
<div className={field()}>
|
||||
<code className={cn(code({ color: 'primary' }))}>{key}</code>
|
||||
{value.description ? <Info>{value.description}</Info> : null}
|
||||
</div>
|
||||
</td>
|
||||
<td className={td}>
|
||||
<div className={field}>
|
||||
<code className={code}>{value.type}</code>
|
||||
<td className={td()}>
|
||||
<div className={field()}>
|
||||
<code className={code()}>{value.type}</code>
|
||||
{value.typeDescription ? (
|
||||
<Info>
|
||||
<pre className="overflow-auto bg-secondary text-secondary-foreground">
|
||||
@@ -83,9 +86,9 @@ export function TypeTable({
|
||||
) : null}
|
||||
</div>
|
||||
</td>
|
||||
<td className={td}>
|
||||
<td className={td()}>
|
||||
{value.default ? (
|
||||
<code className={code}>{value.default}</code>
|
||||
<code className={code()}>{value.default}</code>
|
||||
) : (
|
||||
<span>-</span>
|
||||
)}
|
||||
|
||||
@@ -17,14 +17,12 @@ const exportedComponents = [
|
||||
'card',
|
||||
'heading',
|
||||
'codeblock',
|
||||
'auto-type-table',
|
||||
'dialog/search',
|
||||
'dialog/search-default',
|
||||
'dialog/search-algolia',
|
||||
];
|
||||
|
||||
const injectImports = {
|
||||
'./src/components/auto-type-table.tsx': './src/components/type-table.tsx',
|
||||
'./src/page.tsx': './src/page.client.tsx',
|
||||
'./src/mdx.tsx': './src/mdx.client.tsx',
|
||||
'./src/layout.tsx': './src/layout.client.tsx',
|
||||
|
||||
Generated
+47
@@ -73,6 +73,9 @@ importers:
|
||||
fumadocs-twoslash:
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/twoslash
|
||||
fumadocs-typescript:
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/typescript
|
||||
fumadocs-ui:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/ui
|
||||
@@ -526,6 +529,46 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../tsconfig
|
||||
|
||||
packages/typescript:
|
||||
dependencies:
|
||||
hast-util-to-jsx-runtime:
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0
|
||||
mdast-util-from-markdown:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
mdast-util-gfm:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
mdast-util-to-hast:
|
||||
specifier: ^13.1.0
|
||||
version: 13.1.0
|
||||
typescript:
|
||||
specifier: '*'
|
||||
version: 5.3.3
|
||||
devDependencies:
|
||||
'@types/hast':
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4
|
||||
'@types/mdast':
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
'@types/react':
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
'@types/react-dom':
|
||||
specifier: 18.2.1
|
||||
version: 18.2.1
|
||||
eslint-config-custom:
|
||||
specifier: workspace:*
|
||||
version: link:../eslint-config-custom
|
||||
fumadocs-ui:
|
||||
specifier: workspace:*
|
||||
version: link:../ui
|
||||
tsconfig:
|
||||
specifier: workspace:*
|
||||
version: link:../tsconfig
|
||||
|
||||
packages/ui:
|
||||
dependencies:
|
||||
'@radix-ui/react-accordion':
|
||||
@@ -1251,6 +1294,10 @@ packages:
|
||||
peerDependencies:
|
||||
'@effect-ts/otel-node': '*'
|
||||
peerDependenciesMeta:
|
||||
'@effect-ts/core':
|
||||
optional: true
|
||||
'@effect-ts/otel':
|
||||
optional: true
|
||||
'@effect-ts/otel-node':
|
||||
optional: true
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user