From d7f01cd903ae35601e5fe75ea45f04958636662c Mon Sep 17 00:00:00 2001 From: Fengbao Li Date: Sat, 8 Aug 2026 00:29:23 +0800 Subject: [PATCH 1/6] docs: add prev/next navigation to guide docs pages Follow enum-plus convention: append a static markdown table (Previous | Next) at the bottom of each guide doc page (Introduce/Install/Get Started/Changelog), linking via ?path=/docs/--api with lang:zh-CN globals for CN docs. - Introduce: prev placeholder (- -), next -> Install - Install: prev -> Introduce, next -> Get Started - Get Started: prev -> Install, next -> Changelog - Changelog: prev -> Get Started, next placeholder (- -) --- .storybook/docs-localized/GetStarted.en-US.mdx | 8 ++++++++ .storybook/docs-localized/GetStarted.zh-CN.mdx | 8 ++++++++ .storybook/docs-localized/Install.en-US.mdx | 8 ++++++++ .storybook/docs-localized/Install.zh-CN.mdx | 8 ++++++++ .storybook/docs-localized/Introduce.en-US.mdx | 8 ++++++++ .storybook/docs-localized/Introduce.zh-CN.mdx | 8 ++++++++ .storybook/docs/Changelog.mdx | 14 +++++++++++--- 7 files changed, 59 insertions(+), 3 deletions(-) diff --git a/.storybook/docs-localized/GetStarted.en-US.mdx b/.storybook/docs-localized/GetStarted.en-US.mdx index 6e4d6bc..0202c09 100644 --- a/.storybook/docs-localized/GetStarted.en-US.mdx +++ b/.storybook/docs-localized/GetStarted.en-US.mdx @@ -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) | [Changelog →](?path=/docs/changelog--api) | diff --git a/.storybook/docs-localized/GetStarted.zh-CN.mdx b/.storybook/docs-localized/GetStarted.zh-CN.mdx index e12d122..a54ac4c 100644 --- a/.storybook/docs-localized/GetStarted.zh-CN.mdx +++ b/.storybook/docs-localized/GetStarted.zh-CN.mdx @@ -53,3 +53,11 @@ import { ConfigProvider } from '@tiny-codes/react-easy'; - 打开各个组件故事页查看参数与实际交互效果。 - 使用 `Controls` 面板了解默认值与支持的配置项。 - 通过顶部工具栏切换语言,预览本地化后的文档和故事内容。 + +--- + +{/* docs-prev-next-nav */} + +| 上一篇 | 下一篇 | +| ----------------------------------------------------- | ----------------------------------------------------------- | +| [← 安装](?path=/docs/install--api&globals=lang:zh-CN) | [更新日志 →](?path=/docs/changelog--api&globals=lang:zh-CN) | diff --git a/.storybook/docs-localized/Install.en-US.mdx b/.storybook/docs-localized/Install.en-US.mdx index 540e6cd..f6580a7 100644 --- a/.storybook/docs-localized/Install.en-US.mdx +++ b/.storybook/docs-localized/Install.en-US.mdx @@ -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) | [Get Started →](?path=/docs/get-started--api) | diff --git a/.storybook/docs-localized/Install.zh-CN.mdx b/.storybook/docs-localized/Install.zh-CN.mdx index 80aa4de..f6841b3 100644 --- a/.storybook/docs-localized/Install.zh-CN.mdx +++ b/.storybook/docs-localized/Install.zh-CN.mdx @@ -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) | diff --git a/.storybook/docs-localized/Introduce.en-US.mdx b/.storybook/docs-localized/Introduce.en-US.mdx index 5215ba7..9a0998b 100644 --- a/.storybook/docs-localized/Introduce.en-US.mdx +++ b/.storybook/docs-localized/Introduce.en-US.mdx @@ -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 */} + +| Previous | Next | +| -------- | ------------------------------------- | +| \- \- | [Install →](?path=/docs/install--api) | diff --git a/.storybook/docs-localized/Introduce.zh-CN.mdx b/.storybook/docs-localized/Introduce.zh-CN.mdx index de57ef8..179392f 100644 --- a/.storybook/docs-localized/Introduce.zh-CN.mdx +++ b/.storybook/docs-localized/Introduce.zh-CN.mdx @@ -58,3 +58,11 @@ npm install @tiny-codes/react-easy - 文档页会说明接入方式与常见使用模式。 - `Components` 下的故事页提供可交互示例和参数表。 - 通过顶部工具栏可切换语言与预览主题。 + +--- + +{/* docs-prev-next-nav */} + +| 上一篇 | 下一篇 | +| ------ | ----------------------------------------------------- | +| \- \- | [安装 →](?path=/docs/install--api&globals=lang:zh-CN) | diff --git a/.storybook/docs/Changelog.mdx b/.storybook/docs/Changelog.mdx index 6b14ea6..c28b5bd 100644 --- a/.storybook/docs/Changelog.mdx +++ b/.storybook/docs/Changelog.mdx @@ -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'; - + - + {content} + +--- + +{/* docs-prev-next-nav */} + +| Previous | Next | +| --------------------------------------------- | ----- | +| [← Get Started](?path=/docs/get-started--api) | \- \- | From cc7fbd7d51f073ed471aec5ee5d334e9e38cdf30 Mon Sep 17 00:00:00 2001 From: Fengbao Li Date: Sat, 8 Aug 2026 10:47:25 +0800 Subject: [PATCH 2/6] docs: add bottom previous/next navigator --- .storybook/docs-localized/Introduce.en-US.mdx | 6 +- .storybook/docs-localized/Introduce.zh-CN.mdx | 6 +- .storybook/main.ts | 15 +- .storybook/preview-head.html | 6 - .storybook/preview.css | 35 ++ .storybook/preview.tsx | 3 +- package-lock.json | 527 +++++++++++++++++- package.json | 1 + 8 files changed, 582 insertions(+), 17 deletions(-) delete mode 100644 .storybook/preview-head.html create mode 100644 .storybook/preview.css diff --git a/.storybook/docs-localized/Introduce.en-US.mdx b/.storybook/docs-localized/Introduce.en-US.mdx index 9a0998b..fed90c7 100644 --- a/.storybook/docs-localized/Introduce.en-US.mdx +++ b/.storybook/docs-localized/Introduce.en-US.mdx @@ -63,6 +63,6 @@ Notes: {/* docs-prev-next-nav */} -| Previous | Next | -| -------- | ------------------------------------- | -| \- \- | [Install →](?path=/docs/install--api) | +| | Next | +| --- | ------------------------------------- | +| | [Install →](?path=/docs/install--api) | diff --git a/.storybook/docs-localized/Introduce.zh-CN.mdx b/.storybook/docs-localized/Introduce.zh-CN.mdx index 179392f..9126f55 100644 --- a/.storybook/docs-localized/Introduce.zh-CN.mdx +++ b/.storybook/docs-localized/Introduce.zh-CN.mdx @@ -63,6 +63,6 @@ npm install @tiny-codes/react-easy {/* docs-prev-next-nav */} -| 上一篇 | 下一篇 | -| ------ | ----------------------------------------------------- | -| \- \- | [安装 →](?path=/docs/install--api&globals=lang:zh-CN) | +| | 下一篇 | +| --- | ----------------------------------------------------- | +| | [安装 →](?path=/docs/install--api&globals=lang:zh-CN) | diff --git a/.storybook/main.ts b/.storybook/main.ts index f71ba50..403242b 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -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', }, diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index 3eabab6..0000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/.storybook/preview.css b/.storybook/preview.css new file mode 100644 index 0000000..bd37cb9 --- /dev/null +++ b/.storybook/preview.css @@ -0,0 +1,35 @@ +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper { + padding-top: 3rem; + padding-bottom: 3rem; +} + +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-of-type { + width: 100%; +} + +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child * { + border: none; +} + +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child th:first-child, +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child td:first-child { + width: 50%; + text-align: left; +} + +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child th:last-child, +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child td:last-child { + width: 50%; + text-align: right; +} + +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child td { + font-weight: 600; + font-size: 18px; +} diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 7136817..3e3838b 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -9,8 +9,7 @@ import { stripExampleBlock } from './utils/description'; import { pickLangDoc } from './utils/doc'; import { getGlobalValueFromUrl } from './utils/global'; import { inferControlFromDocgenType, standardizeJsDocDefaultValue } from './utils/jsdoc'; - -// import './preview.css'; +import './preview.css'; // Loading them lazily keeps them out of the story-view critical path. const ThemedDocsContainer = lazy(() => import('./lazy-docs').then((m) => ({ default: m.ThemedDocsContainer }))); diff --git a/package-lock.json b/package-lock.json index b29ee8e..db9ea43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tiny-codes/react-easy", - "version": "2.0.0", + "version": "2.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tiny-codes/react-easy", - "version": "2.0.0", + "version": "2.2.0", "license": "MIT", "dependencies": { "crypto-js": "^4.2.0" @@ -49,6 +49,7 @@ "react-dom": "^19.0.0", "react-is": "^19.0.0", "react-resize-detector": "^12.3.0", + "remark-gfm": "^4.0.1", "sockjs-client": "^1.6.1", "storybook": "^10.2.12", "streamsaver": "^2.0.6", @@ -11235,6 +11236,17 @@ "@babel/core": "^7.0.0" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -11774,6 +11786,17 @@ ], "license": "CC-BY-4.0" }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chai": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", @@ -15638,6 +15661,13 @@ "node": ">=12.0.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -21008,6 +21038,17 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -21117,6 +21158,17 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -21150,6 +21202,36 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", @@ -21175,6 +21257,150 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", @@ -21319,6 +21545,134 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -24805,6 +25159,58 @@ "jsesc": "bin/jsesc" } }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -27776,6 +28182,17 @@ "dev": true, "license": "MIT" }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", @@ -28657,6 +29074,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -28671,6 +29122,37 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -28901,6 +29383,36 @@ "node": ">= 0.8" } }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "7.3.6", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", @@ -30001,6 +30513,17 @@ "engines": { "node": "^12.20.0 || >=14" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index b000618..177500e 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "react-dom": "^19.0.0", "react-is": "^19.0.0", "react-resize-detector": "^12.3.0", + "remark-gfm": "^4.0.1", "sockjs-client": "^1.6.1", "storybook": "^10.2.12", "streamsaver": "^2.0.6", From 5cf8d49b1df8a808c21cec9ea5662f5d2f332ae9 Mon Sep 17 00:00:00 2001 From: Fengbao Li Date: Sat, 8 Aug 2026 20:46:56 +0800 Subject: [PATCH 3/6] docs: update navigation links and translations for documentation --- .../docs-localized/GetStarted.en-US.mdx | 6 +- .../docs-localized/GetStarted.zh-CN.mdx | 6 +- .storybook/docs-localized/Install.en-US.mdx | 6 +- .storybook/docs-localized/Introduce.en-US.mdx | 6 +- .storybook/lazy-docs.tsx | 60 ++++++++++++++++++- .storybook/locales/langs/en-US.ts | 5 ++ .storybook/locales/langs/zh-CN.ts | 5 ++ .storybook/preview.tsx | 2 +- 8 files changed, 80 insertions(+), 16 deletions(-) diff --git a/.storybook/docs-localized/GetStarted.en-US.mdx b/.storybook/docs-localized/GetStarted.en-US.mdx index 0202c09..38b52f2 100644 --- a/.storybook/docs-localized/GetStarted.en-US.mdx +++ b/.storybook/docs-localized/GetStarted.en-US.mdx @@ -58,6 +58,6 @@ import { ConfigProvider } from '@tiny-codes/react-easy'; {/* docs-prev-next-nav */} -| Previous | Next | -| ------------------------------------- | ----------------------------------------- | -| [← Install](?path=/docs/install--api) | [Changelog →](?path=/docs/changelog--api) | +| Previous | Next | +| -------------------------------------------------------- | ------------------------------------------------------------------------- | +| [← Install](?path=/docs/install--api&globals=lang:en-US) | [BreakLines →](?path=/docs/components-breaklines--api&globals=lang:en-US) | diff --git a/.storybook/docs-localized/GetStarted.zh-CN.mdx b/.storybook/docs-localized/GetStarted.zh-CN.mdx index a54ac4c..aca81be 100644 --- a/.storybook/docs-localized/GetStarted.zh-CN.mdx +++ b/.storybook/docs-localized/GetStarted.zh-CN.mdx @@ -58,6 +58,6 @@ import { ConfigProvider } from '@tiny-codes/react-easy'; {/* docs-prev-next-nav */} -| 上一篇 | 下一篇 | -| ----------------------------------------------------- | ----------------------------------------------------------- | -| [← 安装](?path=/docs/install--api&globals=lang:zh-CN) | [更新日志 →](?path=/docs/changelog--api&globals=lang:zh-CN) | +| 上一篇 | 下一篇 | +| ----------------------------------------------------- | ------------------------------------------------------------------------- | +| [← 安装](?path=/docs/install--api&globals=lang:zh-CN) | [BreakLines →](?path=/docs/components-breaklines--api&globals=lang:zh-CN) | diff --git a/.storybook/docs-localized/Install.en-US.mdx b/.storybook/docs-localized/Install.en-US.mdx index f6580a7..f4ca99f 100644 --- a/.storybook/docs-localized/Install.en-US.mdx +++ b/.storybook/docs-localized/Install.en-US.mdx @@ -62,6 +62,6 @@ npx tsc -p tsconfig.json --noEmit {/* docs-prev-next-nav */} -| Previous | Next | -| ----------------------------------------- | --------------------------------------------- | -| [← Introduce](?path=/docs/introduce--api) | [Get Started →](?path=/docs/get-started--api) | +| Previous | Next | +| ------------------------------------------------------------ | ---------------------------------------------------------------- | +| [← Introduce](?path=/docs/introduce--api&globals=lang:en-US) | [Get Started →](?path=/docs/get-started--api&globals=lang:en-US) | diff --git a/.storybook/docs-localized/Introduce.en-US.mdx b/.storybook/docs-localized/Introduce.en-US.mdx index fed90c7..22763d2 100644 --- a/.storybook/docs-localized/Introduce.en-US.mdx +++ b/.storybook/docs-localized/Introduce.en-US.mdx @@ -63,6 +63,6 @@ Notes: {/* docs-prev-next-nav */} -| | Next | -| --- | ------------------------------------- | -| | [Install →](?path=/docs/install--api) | +| | Next | +| --- | -------------------------------------------------------- | +| | [Install →](?path=/docs/install--api&globals=lang:en-US) | diff --git a/.storybook/lazy-docs.tsx b/.storybook/lazy-docs.tsx index f84a2a4..b710a69 100644 --- a/.storybook/lazy-docs.tsx +++ b/.storybook/lazy-docs.tsx @@ -2,10 +2,12 @@ import type { PropsWithChildren } from 'react'; import { useMemo } from 'react'; import type { DocsContainerProps } from '@storybook/addon-docs/blocks'; import { Controls, DocsContainer, 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 { themes } from 'storybook/theming'; +import { Flex } from 'antd'; +import { useStoryT } from './locales'; import { processDescription } from './utils/description'; -import { getGlobalValueFromUrl } from './utils/global'; /** * All `@storybook/addon-docs/blocks` and `storybook/theming` imports live in this module so that @@ -17,15 +19,67 @@ export function ThemedDocsContainer({ isDark, ...props }: PropsWithChildren { + 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`; + } + return null; + }, []); + const componentPaths = Object.keys(import.meta.glob(`./stories/components/*/index.stories.tsx`)); + const hookPaths = Object.keys(import.meta.glob(`./stories/hooks/*/index.stories.tsx`)); + const utilPaths = Object.keys(import.meta.glob(`./stories/utils/*/index.stories.tsx`)); + const allStories = [...componentPaths, ...hookPaths, ...utilPaths].map((path) => { + const parts = path.split('/'); + return { + path: path.toLowerCase(), + name: parts[3], + url: `${parts[2]}/${parts[3]}`, + }; + }); + const index = allStories.findIndex((story) => story.path === currentStory); + if (index === -1) { + throw new Error(`Current story not found: ${currentStory}`); + } + return ( <> <Subtitle /> <CustomComponentDescription /> - <h2>{langFromUrl === 'zh-CN' ? '演示' : 'Demo'}</h2> + <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 ? ( + // <a href={allStories[index - 1].url} style={{ fontSize: 18, fontWeight: 600 }}> + // ← {allStories[index - 1].name} + // </a> + // @ts-expect-error: because style props exists but not exposed + <LinkTo kind={allStories[index - 1].url} story="api" style={{ fontSize: 18, fontWeight: 600 }}> + ← {allStories[index - 1].name} + </LinkTo> + ) : ( + // @ts-expect-error: because style props exists but not exposed + <LinkTo kind="get-started" story="api" style={{ fontSize: 18, fontWeight: 600 }}> + ← {t('storybook.stories.nav.getStarted')} + </LinkTo> + )} + {index < allStories.length - 1 ? ( + // @ts-expect-error: because style props exists but not exposed + <LinkTo kind={allStories[index + 1].url} story="api" style={{ fontSize: 18, fontWeight: 600 }}> + {allStories[index + 1].name} → + </LinkTo> + ) : ( + <p style={{ margin: 0 }}>{t('storybook.stories.nav.nothing')}</p> + )} + </Flex> </> ); } diff --git a/.storybook/locales/langs/en-US.ts b/.storybook/locales/langs/en-US.ts index 9e8d982..e5a1cfe 100644 --- a/.storybook/locales/langs/en-US.ts +++ b/.storybook/locales/langs/en-US.ts @@ -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', diff --git a/.storybook/locales/langs/zh-CN.ts b/.storybook/locales/langs/zh-CN.ts index 98c1938..89fd7d3 100644 --- a/.storybook/locales/langs/zh-CN.ts +++ b/.storybook/locales/langs/zh-CN.ts @@ -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': '暂停', diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 3e3838b..5cda614 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -34,7 +34,7 @@ const preview: Preview = { icon: 'globe', items: [ { value: 'en-US', right: '🇺🇸', title: 'English' }, - { value: 'zh-CN', right: '🇨🇳', title: '中文' }, + { value: 'zh-CN', right: '🇨🇳', title: '简体中文' }, ], }, }, From 359b4dfe6d367c513a5c0c0f64104f2cbde3fb3c Mon Sep 17 00:00:00 2001 From: Fengbao Li <shijistar@gmail.com> Date: Sat, 8 Aug 2026 20:59:10 +0800 Subject: [PATCH 4/6] docs: optimize story paths retrieval with useMemo for performance --- .storybook/lazy-docs.tsx | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/.storybook/lazy-docs.tsx b/.storybook/lazy-docs.tsx index b710a69..d2e22d4 100644 --- a/.storybook/lazy-docs.tsx +++ b/.storybook/lazy-docs.tsx @@ -28,21 +28,22 @@ export function DocsPage() { } return null; }, []); - const componentPaths = Object.keys(import.meta.glob(`./stories/components/*/index.stories.tsx`)); - const hookPaths = Object.keys(import.meta.glob(`./stories/hooks/*/index.stories.tsx`)); - const utilPaths = Object.keys(import.meta.glob(`./stories/utils/*/index.stories.tsx`)); - const allStories = [...componentPaths, ...hookPaths, ...utilPaths].map((path) => { - const parts = path.split('/'); - return { - path: path.toLowerCase(), - name: parts[3], - url: `${parts[2]}/${parts[3]}`, - }; - }); - const index = allStories.findIndex((story) => story.path === currentStory); - if (index === -1) { - throw new Error(`Current story not found: ${currentStory}`); - } + 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 ( <> From 5a748ab02db32302813c6ba0ef553cd94d0514e8 Mon Sep 17 00:00:00 2001 From: Fengbao Li <shijistar@gmail.com> Date: Sat, 8 Aug 2026 21:01:49 +0800 Subject: [PATCH 5/6] docs: adjust table cell styles for improved readability --- .storybook/preview.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.storybook/preview.css b/.storybook/preview.css index bd37cb9..59164f5 100644 --- a/.storybook/preview.css +++ b/.storybook/preview.css @@ -14,6 +14,12 @@ border: none; } +/* stylelint-disable-next-line selector-disallowed-list */ +#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child td { + font-weight: 600; + font-size: 18px; +} + /* stylelint-disable-next-line selector-disallowed-list */ #storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child th:first-child, #storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child td:first-child { @@ -27,9 +33,3 @@ width: 50%; text-align: right; } - -/* stylelint-disable-next-line selector-disallowed-list */ -#storybook-docs > .sbdocs-wrapper > .sbdocs-content > table:last-child td { - font-weight: 600; - font-size: 18px; -} From 4be89db14afee9cca366fbb53c8315986ccc36a7 Mon Sep 17 00:00:00 2001 From: Fengbao Li <shijistar@gmail.com> Date: Sat, 8 Aug 2026 21:13:38 +0800 Subject: [PATCH 6/6] docs: update changelog navigation link with language parameter --- .../StoryDocPage.tsx} | 42 ++++++------------- .storybook/components/ThemedDocsContainer.tsx | 10 +++++ .storybook/docs/Changelog.mdx | 6 +-- .storybook/preview.tsx | 7 ++-- 4 files changed, 29 insertions(+), 36 deletions(-) rename .storybook/{lazy-docs.tsx => components/StoryDocPage.tsx} (70%) create mode 100644 .storybook/components/ThemedDocsContainer.tsx diff --git a/.storybook/lazy-docs.tsx b/.storybook/components/StoryDocPage.tsx similarity index 70% rename from .storybook/lazy-docs.tsx rename to .storybook/components/StoryDocPage.tsx index d2e22d4..12baecd 100644 --- a/.storybook/lazy-docs.tsx +++ b/.storybook/components/StoryDocPage.tsx @@ -1,30 +1,18 @@ -import type { PropsWithChildren } from 'react'; import { useMemo } from 'react'; -import type { DocsContainerProps } from '@storybook/addon-docs/blocks'; -import { Controls, DocsContainer, Markdown, Primary, Subtitle, Title, useOf } from '@storybook/addon-docs/blocks'; +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 { themes } from 'storybook/theming'; import { Flex } from 'antd'; -import { useStoryT } from './locales'; -import { processDescription } from './utils/description'; +import { useStoryT } from '../locales'; +import { processDescription } from '../utils/description'; -/** - * All `@storybook/addon-docs/blocks` and `storybook/theming` imports live in this module so that - * they can be code-split away from the preview entry chunk. Only docs view mode pays for them. - */ - -export function ThemedDocsContainer({ isDark, ...props }: PropsWithChildren<DocsContainerProps> & { isDark: boolean }) { - return <DocsContainer {...props} theme={isDark ? themes.dark : themes.light} />; -} - -export function DocsPage() { +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`; + return `./stories/${matches[1]}/${matches[2]}/index.stories.tsx`.toLowerCase(); } return null; }, []); @@ -59,23 +47,17 @@ export function DocsPage() { </Flex> <Flex justify="space-between"> {index > 0 ? ( - // <a href={allStories[index - 1].url} style={{ fontSize: 18, fontWeight: 600 }}> - // ← {allStories[index - 1].name} - // </a> - // @ts-expect-error: because style props exists but not exposed - <LinkTo kind={allStories[index - 1].url} story="api" style={{ fontSize: 18, fontWeight: 600 }}> - ← {allStories[index - 1].name} + <LinkTo kind={allStories[index - 1].url} story="api"> + <span style={{ fontSize: 18, fontWeight: 600 }}>← {allStories[index - 1].name}</span> </LinkTo> ) : ( - // @ts-expect-error: because style props exists but not exposed - <LinkTo kind="get-started" story="api" style={{ fontSize: 18, fontWeight: 600 }}> - ← {t('storybook.stories.nav.getStarted')} + <LinkTo kind="get-started" story="api"> + <span style={{ fontSize: 18, fontWeight: 600 }}>← {t('storybook.stories.nav.getStarted')}</span> </LinkTo> )} {index < allStories.length - 1 ? ( - // @ts-expect-error: because style props exists but not exposed - <LinkTo kind={allStories[index + 1].url} story="api" style={{ fontSize: 18, fontWeight: 600 }}> - {allStories[index + 1].name} → + <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> @@ -142,3 +124,5 @@ function getDescriptionFromResolvedOf(resolvedOf: ReturnType<typeof useOf> | und } } } + +export default StoryDocPage; diff --git a/.storybook/components/ThemedDocsContainer.tsx b/.storybook/components/ThemedDocsContainer.tsx new file mode 100644 index 0000000..2139883 --- /dev/null +++ b/.storybook/components/ThemedDocsContainer.tsx @@ -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; diff --git a/.storybook/docs/Changelog.mdx b/.storybook/docs/Changelog.mdx index c28b5bd..669996c 100644 --- a/.storybook/docs/Changelog.mdx +++ b/.storybook/docs/Changelog.mdx @@ -9,6 +9,6 @@ import content from '../../CHANGELOG.md?raw'; {/* docs-prev-next-nav */} -| Previous | Next | -| --------------------------------------------- | ----- | -| [← Get Started](?path=/docs/get-started--api) | \- \- | +| Previous | Next | +| ---------------------------------------------------------------- | ----- | +| [← Get Started](?path=/docs/get-started--api&globals=lang:en-US) | \- \- | diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 5cda614..ae01c02 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -12,9 +12,8 @@ import { inferControlFromDocgenType, standardizeJsDocDefaultValue } from './util import './preview.css'; // Loading them lazily keeps them out of the story-view critical path. -const ThemedDocsContainer = lazy(() => import('./lazy-docs').then((m) => ({ default: m.ThemedDocsContainer }))); -const DocsPage = lazy(() => import('./lazy-docs').then((m) => ({ default: m.DocsPage }))); -// const PreviewDecorator = lazy(() => import('./components/PreviewDecorator')); +const ThemedDocsContainer = lazy(() => import('./components/ThemedDocsContainer')); +const StoryDocPage = lazy(() => import('./components/StoryDocPage')); const themeFromUrl = getGlobalValueFromUrl('backgrounds.value'); const isPreferDark = window.matchMedia('(prefers-color-scheme: dark)').matches; @@ -84,7 +83,7 @@ const preview: Preview = { }, page: () => ( <Suspense fallback={null}> - <DocsPage /> + <StoryDocPage /> </Suspense> ), },