This is early WIP!
写组件 demo

写组件 demo

Pressify 支持两种写组件 demo 的方式,适用于不同的场景。

代码块 demo

对于简单的组件 demo,我们可以直接在 Markdown 代码块中写 demo。 当在代码块的 ``` 后加上 demo 标记,这个代码块就会变成一个 demo。例如:

```ts demo
export default function Foo() {
  return (
    <button
      className="px-3 py-1 rounded text-white bg-c-brand hover:bg-c-brand-light"
      onClick={() => alert('Hi')}
    >
      Hello World
    </button>
  );
}
```
```ts demo
export default function Foo() {
  return (
    <button
      className="px-3 py-1 rounded text-white bg-c-brand hover:bg-c-brand-light"
      onClick={() => alert('Hi')}
    >
      Hello World
    </button>
  );
}
```

会渲染成 ↓↓↓:

外部 demo

对于比较复杂的 demo,如果还是“内联”在 Markdown 代码块中,就享受不到编辑器提供的类型提示、ESLint、Prettier 等功能的好处了,体验会有点糟糕。 建议把复杂的 demo 写在外部 JS/TS 文件中,然后在 Markdown 中通过 <Demo src="xxx" /> 的形式引入这个 demo 组件。

例如我们在 <root>/.pressify/demo/Button.tsx 有这样的组件 demo:

export default function Button() {
  return (
    <button
      className="px-3 py-1 rounded text-white bg-sky-500 hover:bg-sky-400"
      onClick={() => alert('Hi')}
    >
      外部 demo
    </button>
  );
}
export default function Button() {
  return (
    <button
      className="px-3 py-1 rounded text-white bg-sky-500 hover:bg-sky-400"
      onClick={() => alert('Hi')}
    >
      外部 demo
    </button>
  );
}

然后在 Markdown 中把该组件路径传给 Demo 组件的 src 属性:

<Demo src="/.pressify/demo/Button.tsx" />
<Demo src="/.pressify/demo/Button.tsx" />

就能实现这样的 demo 效果啦:

TIP

其实代码块 demo 底层也是基于 <Demo /> 组件来实现的。

自定义 Demo 组件

如果要自定义 Demo 组件,可以考虑自定义主题或者扩展主题, 然后在主题的 mdxComponents 中传入自定义的 Demo 组件。

举个例子,可以通过下面的方法替换默认主题的 Demo 组件:

// .pressify/theme/index.js

import theme from 'pressify/theme';

function CustomDemo({ children, code }) {
  return (
    <>
      <div>渲染结果:{children}</div>
      <div>源代码:{code}</div>
    </>
  );
}

export default {
  ...theme,
  mdxComponents: {
    ...theme.mdxComponents,
    Demo: CustomDemo,
  },
};
// .pressify/theme/index.js

import theme from 'pressify/theme';

function CustomDemo({ children, code }) {
  return (
    <>
      <div>渲染结果:{children}</div>
      <div>源代码:{code}</div>
    </>
  );
}

export default {
  ...theme,
  mdxComponents: {
    ...theme.mdxComponents,
    Demo: CustomDemo,
  },
};

Demo 组件接收的 props 类型为:

interface DemoProps {
  /* demo 源代码 */
  code: string;
  /* 经过 shiki 高亮的代码 html */
  codeHtml: string;
  /* demo meta 信息 */
  meta?: Record<string, any>;
  /* 组件的渲染结果 */
  children: React.ReactNode;
}
interface DemoProps {
  /* demo 源代码 */
  code: string;
  /* 经过 shiki 高亮的代码 html */
  codeHtml: string;
  /* demo meta 信息 */
  meta?: Record<string, any>;
  /* 组件的渲染结果 */
  children: React.ReactNode;
}