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
128 changes: 128 additions & 0 deletions .storybook/components/StoryDocPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { useMemo } from 'react';
import { Controls, Markdown, Primary, Subtitle, Title, useOf } from '@storybook/addon-docs/blocks';
import LinkTo from '@storybook/addon-links/react';
import type { ResolvedModuleExportFromType } from 'storybook/internal/types';
import { Flex } from 'antd';
import { useStoryT } from '../locales';
import { processDescription } from '../utils/description';

function StoryDocPage() {
const t = useStoryT();
const currentStory = useMemo(() => {
const path = new URLSearchParams(top?.location.search).get('path');
const matches = path?.match(/\/docs\/(components|hooks|utils)-(\w+?)--api/);
if (matches && matches.length > 2) {
return `./stories/${matches[1]}/${matches[2]}/index.stories.tsx`.toLowerCase();
}
return null;
}, []);
const componentPaths = useMemo(() => Object.keys(import.meta.glob(`./stories/components/*/index.stories.tsx`)), []);
const hookPaths = useMemo(() => Object.keys(import.meta.glob(`./stories/hooks/*/index.stories.tsx`)), []);
const utilPaths = useMemo(() => Object.keys(import.meta.glob(`./stories/utils/*/index.stories.tsx`)), []);
const allStories = useMemo(
() =>
[...componentPaths, ...hookPaths, ...utilPaths].map((path) => {
const parts = path.split('/');
return {
path: path.toLowerCase(),
name: parts[3],
url: `${parts[2]}/${parts[3]}`,
};
}),
[componentPaths, hookPaths, utilPaths],
);
const index = useMemo(() => allStories.findIndex((story) => story.path === currentStory), [allStories, currentStory]);

return (
<>
<Title />
<Subtitle />
<CustomComponentDescription />
<h2>{t('storybook.stories.demo')}</h2>
<Primary />
<Controls />
<Flex justify="space-between">
<p>{t('storybook.stories.nav.previous')}</p>
<p>{t('storybook.stories.nav.next')}</p>
</Flex>
<Flex justify="space-between">
{index > 0 ? (
<LinkTo kind={allStories[index - 1].url} story="api">
<span style={{ fontSize: 18, fontWeight: 600 }}>← {allStories[index - 1].name}</span>
</LinkTo>
) : (
<LinkTo kind="get-started" story="api">
<span style={{ fontSize: 18, fontWeight: 600 }}>← {t('storybook.stories.nav.getStarted')}</span>
</LinkTo>
)}
{index < allStories.length - 1 ? (
<LinkTo kind={allStories[index + 1].url} story="api">
<span style={{ fontSize: 18, fontWeight: 600 }}>{allStories[index + 1].name} →</span>
</LinkTo>
) : (
<p style={{ margin: 0 }}>{t('storybook.stories.nav.nothing')}</p>
)}
</Flex>
</>
);
}

function CustomComponentDescription() {
const resolvedOfMeta = useOf<'meta'>('meta');
let resolvedOfComponent: ResolvedModuleExportFromType<'component'> | undefined;
try {
// eslint-disable-next-line @tiny-codes/react-hooks/rules-of-hooks
resolvedOfComponent = useOf<'component'>('component');
} catch {
// Ignore error
}
const descriptionOfMeta = getDescriptionFromResolvedOf(resolvedOfMeta);
const descriptionOfComponent = getDescriptionFromResolvedOf(resolvedOfComponent);
const next = useMemo(() => {
const description = descriptionOfMeta || descriptionOfComponent || '';
return processDescription(description);
}, [descriptionOfMeta, descriptionOfComponent]);

if (!next) return null;
return <Markdown>{next}</Markdown>;
}

function getDescriptionFromResolvedOf(resolvedOf: ReturnType<typeof useOf> | undefined): string | null {
if (!resolvedOf) return null;
switch (resolvedOf.type) {
case 'story': {
return resolvedOf.story.parameters.docs?.description?.story || null;
}
case 'meta': {
const { parameters, component } = resolvedOf.preparedMeta;
const metaDescription = parameters.docs?.description?.component;
if (metaDescription) {
return metaDescription;
}
return (
parameters.docs?.extractComponentDescription?.(component, {
component,
parameters,
}) || null
);
}
case 'component': {
const {
component,
projectAnnotations: { parameters },
} = resolvedOf;
return (
parameters?.docs?.extractComponentDescription?.(component, {
component,
parameters,
}) || null
);
}
default: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
throw new Error(`Unrecognized module type resolved from 'useOf', got: ${(resolvedOf as any).type}`);
}
}
}

export default StoryDocPage;
10 changes: 10 additions & 0 deletions .storybook/components/ThemedDocsContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { PropsWithChildren } from 'react';
import type { DocsContainerProps } from '@storybook/addon-docs/blocks';
import { DocsContainer } from '@storybook/addon-docs/blocks';
import { themes } from 'storybook/theming';

function ThemedDocsContainer({ isDark, ...props }: PropsWithChildren<DocsContainerProps> & { isDark: boolean }) {
return <DocsContainer {...props} theme={isDark ? themes.dark : themes.light} />;
}

export default ThemedDocsContainer;
8 changes: 8 additions & 0 deletions .storybook/docs-localized/GetStarted.en-US.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,11 @@ import { ConfigProvider } from '@tiny-codes/react-easy';
- Open the individual component stories to inspect props and live behavior.
- Use the `Controls` panel to understand default values and supported options.
- Switch the top toolbar language when you want to preview localized story content.

---

{/* docs-prev-next-nav */}

| Previous | Next |
| -------------------------------------------------------- | ------------------------------------------------------------------------- |
| [← Install](?path=/docs/install--api&globals=lang:en-US) | [BreakLines →](?path=/docs/components-breaklines--api&globals=lang:en-US) |
Comment on lines +61 to +63

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Link Get Started to Changelog.

Both next links bypass the final guide page and open the BreakLines component story. This breaks the declared sequence: Introduce, Install, Get Started, Changelog.

  • .storybook/docs-localized/GetStarted.en-US.mdx#L61-L63: replace the BreakLines target with ?path=/docs/changelog--api&globals=lang:en-US.
  • .storybook/docs-localized/GetStarted.zh-CN.mdx#L61-L63: replace the BreakLines target with ?path=/docs/changelog--api&globals=lang:zh-CN.
📍 Affects 2 files
  • .storybook/docs-localized/GetStarted.en-US.mdx#L61-L63 (this comment)
  • .storybook/docs-localized/GetStarted.zh-CN.mdx#L61-L63
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.storybook/docs-localized/GetStarted.en-US.mdx around lines 61 - 63, Update
the next-link target in .storybook/docs-localized/GetStarted.en-US.mdx lines
61-63 to the Changelog story with the en-US global. Apply the corresponding
change in .storybook/docs-localized/GetStarted.zh-CN.mdx lines 61-63, using the
zh-CN global instead of the BreakLines target.

8 changes: 8 additions & 0 deletions .storybook/docs-localized/GetStarted.zh-CN.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,11 @@ import { ConfigProvider } from '@tiny-codes/react-easy';
- 打开各个组件故事页查看参数与实际交互效果。
- 使用 `Controls` 面板了解默认值与支持的配置项。
- 通过顶部工具栏切换语言,预览本地化后的文档和故事内容。

---

{/* docs-prev-next-nav */}

| 上一篇 | 下一篇 |
| ----------------------------------------------------- | ------------------------------------------------------------------------- |
| [← 安装](?path=/docs/install--api&globals=lang:zh-CN) | [BreakLines →](?path=/docs/components-breaklines--api&globals=lang:zh-CN) |
8 changes: 8 additions & 0 deletions .storybook/docs-localized/Install.en-US.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,11 @@ npm run build
npm run build-storybook
npx tsc -p tsconfig.json --noEmit
```

---

{/* docs-prev-next-nav */}

| Previous | Next |
| ------------------------------------------------------------ | ---------------------------------------------------------------- |
| [← Introduce](?path=/docs/introduce--api&globals=lang:en-US) | [Get Started →](?path=/docs/get-started--api&globals=lang:en-US) |
8 changes: 8 additions & 0 deletions .storybook/docs-localized/Install.zh-CN.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,11 @@ npm run build
npm run build-storybook
npx tsc -p tsconfig.json --noEmit
```

---

{/* docs-prev-next-nav */}

| 上一篇 | 下一篇 |
| ------------------------------------------------------- | ------------------------------------------------------------- |
| [← 介绍](?path=/docs/introduce--api&globals=lang:zh-CN) | [快速开始 →](?path=/docs/get-started--api&globals=lang:zh-CN) |
8 changes: 8 additions & 0 deletions .storybook/docs-localized/Introduce.en-US.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,11 @@ Notes:
- The docs pages explain setup and common usage patterns.
- The component stories under `Components` show interactive examples and prop tables.
- Use the top toolbar to switch language and preview theme while browsing stories.

---

{/* docs-prev-next-nav */}

| | Next |
| --- | -------------------------------------------------------- |
| | [Install →](?path=/docs/install--api&globals=lang:en-US) |
8 changes: 8 additions & 0 deletions .storybook/docs-localized/Introduce.zh-CN.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,11 @@ npm install @tiny-codes/react-easy
- 文档页会说明接入方式与常见使用模式。
- `Components` 下的故事页提供可交互示例和参数表。
- 通过顶部工具栏可切换语言与预览主题。

---

{/* docs-prev-next-nav */}

| | 下一篇 |
| --- | ----------------------------------------------------- |
| | [安装 →](?path=/docs/install--api&globals=lang:zh-CN) |
14 changes: 11 additions & 3 deletions .storybook/docs/Changelog.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { Meta, Markdown } from '@storybook/addon-docs/blocks';
import { Markdown, Meta } from '@storybook/addon-docs/blocks';
import content from '../../CHANGELOG.md?raw';

<Meta title="Changelog" />

<Markdown>{content}</Markdown>

---

{/* docs-prev-next-nav */}

| Previous | Next |
| ---------------------------------------------------------------- | ----- |
| [← Get Started](?path=/docs/get-started--api&globals=lang:en-US) | \- \- |
89 changes: 0 additions & 89 deletions .storybook/lazy-docs.tsx

This file was deleted.

5 changes: 5 additions & 0 deletions .storybook/locales/langs/en-US.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
const enUS = {
'storybook.stories.demo': 'Demo',
'storybook.stories.nav.previous': 'Previous',
'storybook.stories.nav.next': 'Next',
'storybook.stories.nav.getStarted': 'Get Started',
'storybook.stories.nav.nothing': 'Nothing',
'storybook.stories.AudioPlayer.actions.backward': 'Back {{seconds}}s',
'storybook.stories.AudioPlayer.actions.forward': 'Forward {{seconds}}s',
'storybook.stories.AudioPlayer.actions.pause': 'Pause',
Expand Down
5 changes: 5 additions & 0 deletions .storybook/locales/langs/zh-CN.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
const zhCN = {
'storybook.stories.demo': '演示',
'storybook.stories.nav.previous': '上一篇',
'storybook.stories.nav.next': '下一篇',
'storybook.stories.nav.getStarted': '开始使用',
'storybook.stories.nav.nothing': '没有了',
'storybook.stories.AudioPlayer.actions.backward': '后退 {{seconds}} 秒',
'storybook.stories.AudioPlayer.actions.forward': '前进 {{seconds}} 秒',
'storybook.stories.AudioPlayer.actions.pause': '暂停',
Expand Down
15 changes: 14 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import type { StorybookConfig } from '@storybook/react-vite';
import remarkGfm from 'remark-gfm';
import type { RollupLog } from 'rollup';
import { mergeConfig } from 'vite';

const config: StorybookConfig = {
stories: ['./docs/**/*.mdx', './stories/**/*.stories.@(ts|tsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-docs'],
addons: [
'@storybook/addon-links',
{
name: '@storybook/addon-docs',
options: {
mdxPluginOptions: {
mdxCompileOptions: {
remarkPlugins: [remarkGfm],
},
},
},
},
],
docs: {
defaultName: 'API',
},
Expand Down
6 changes: 0 additions & 6 deletions .storybook/preview-head.html

This file was deleted.

Loading