diff --git a/README.md b/README.md index d5512309..01482117 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,61 @@ -# Cocos Creator Service Pack +# Cocos Service Pack -这是一个对 Cocos Creator 引擎进行特性新增、修复与优化的**开源非官方服务包**。 +![logo](/docs/static/img/logo2.png) -我们的发展方向是尽量以最符合引擎架构设计的方式加入新的特性、修复引擎已知问题以及性能优化。 +这是一个对 Cocos Creator 引擎进行特性增强、修复与优化的**开源非官方服务包**。 + +我们尽量以最符合引擎架构设计的方式加入新的特性、修复引擎已知问题以及性能优化。 > 项目的起源 > -> 2021 年 2 月,Cocos 发布 Cocos Creator 3.0,并在 3.x 发布之后不会再继续开发 2.x 版本的新特性。 +>2021 年 2 月,Cocos 发布 Cocos Creator 3.0,并在 3.x 发布之后不会再继续开发 2.x 版本的新特性,所有维护工作也会在 2023 年完全停止。 > -> 问题修复等所有维护工作也会在 2023 年完全停止。而 2.x 以及 3.x 在一些方面都并不完善,所以我们发布了这个非官方的引擎“魔改”集合。 +>但是 2.x 在一些方面还并不完善,所以我们发布了这个非官方的引擎“魔改”合集。 > -> 相似的事情发生在 2014 年 4 月,官方停止了对 Windows XP 的维护,之后 Harkaz 发布了一个非官方服务包 Service Pack 4 (SP4)。 +>相似的事情发生在 2014 年 4 月,官方停止了对 Windows XP 的维护,之后 Harkaz 发布了一个非官方服务包 Service Pack 4 (SP4)。 > -> 所以我们将这个“魔改”集合取名为 Service Pack。 +>受到 Windows XP 的启发,我们将这个非官方的引擎“魔改”合集取名为 Service Pack。 > -> 我们暂时只专注于 Cocos Creator 2.x 版本的适配,虽然当前服务包新增的一些特性在 Cocos Creator 3.5 版本中甚至依然还大部分缺失,但因为它还在蒸蒸日上中(还有希望),并且其引擎架构还在不断地迭代(不稳定),对其进行修改的维护工作会很大。 +>我们暂时只专注于 Cocos Creator 2.x 版本的适配,Cocos Creator 3.x 正在蒸蒸日上,其引擎架构还在不断地迭代(不稳定),对其进行修改的维护工作会很大。 -- [重要改进](#重要改进) -- [如何使用](#如何使用) -- [实现原理](#实现原理) +- [全部改动](#全部改动) +- [使用方法](#使用方法) + - [引擎扩展](#引擎扩展) + - [Git Patch](#git-patch) + - [直接动手](#直接动手) - [更新日志](#更新日志) - [贡献指南](#贡献指南) +- [常见问题](#常见问题) + - [为什么要直接修改引擎?](#为什么要直接修改引擎) -## 重要改进 +## 全部改动 + +服务包对引擎的所有改动都是开源的,并且每个改动都会附上一篇原理说明的文档,当你发现问题时请进行反馈,或者直接默默地帅气地提交一个 PR,帮助我们一起完善这个项目。 - 待补充。 -## 如何使用 +## 使用方法 + +我们推荐两种方式来使用这个服务包: + +### 引擎扩展 待补充。 -## 实现原理 +### Git Patch -每个改动的原理都会进行公示,我们没做过官方那样完善的测试,但是尽量保持改动的透明。 +待补充。 + +### 直接动手 + +阅读源码和原理文章来自行提取你想要的部分。 ## 更新日志 @@ -47,11 +63,34 @@ ## 贡献指南 -非常欢迎您能和我们一起来完善,所有的一切都通过 Github 进行: +非常欢迎你能和我们一起来完善这个项目,所有的一切都通过 Github 进行: -- 如果您有问题或者好的想法,请使用 `Issues` 或 `Discussions` 。 -- 如果您有新的代码提交,请使用 `Pull requests`。 +- 如果你有问题或者好的想法,请建立 `Issues` 或进入 `Discussions` 。 +- 如果你有新的代码提交,请建立 `Pull requests`。 -原则上我们接受任何新增与修改,但是**任何修改都必须兼容引擎原有的特性**,并且**不允许删除引擎原有的特性**。 +原则上我们接受任何增强与修改,但是**任何修改都必须兼容引擎原有的特性,不允许删除引擎原有的特性**,并且请认真思考功能的设计。 -在开发新特性时,请站在引擎的角度思考该如何设计。 +## 常见问题 + +### 为什么要直接修改引擎? + +直接修改引擎可能是大部分人认为的下下策,我们能听到的声音有: + +- 可以通过 “修改对象的原型” 等一些编程技巧做成一个插件脚本 +- 为什么要改?不改,因为 xxxx 原则说过,不要动旧的代码,我们造新的! +- 我都没接触过自定义引擎呢,不知道该怎么用 +- 如果我本来就改过引擎,不就很麻烦了吗? + +以上问题我们都思考过, + +首先,现在引擎的 2.x 版本已经停止了更新(仅做一些维护工作),也就是说我们的修改基本不会遇到在下个版本需要完全重构的情况。 + +其次,服务包中的大部分改动虽然可以做成一个插件脚本,但是原生平台就无法兼容,并且包体会增大,可维护性也不见得会提升。 + +最后,造新的或多或少会增加学习和使用的成本,并且我们希望它是 “原生” 的使用体验。 + +对于没有接触过自定义引擎的人,我们提供的引擎扩展可以一键帮助你设置好自定义引擎。 + +对于已经修改过引擎的人,我们提供 Git Patch 可以让你在已有修改的基础上轻松应用我们的更改,可能会产生一些冲突,但我相信你能解决。 + +**最后的最后,希望这个项目能够在你想学习相关知识或者做类似修改时可以帮助到你,享受吧!** diff --git a/docs/docs/installation-guide/_category_.json b/docs/docs/installation-guide/_category_.json new file mode 100644 index 00000000..af2c1ac7 --- /dev/null +++ b/docs/docs/installation-guide/_category_.json @@ -0,0 +1,9 @@ +{ + "label": "安装指南", + "position": 2, + "collapsed": false, + "link": { + "type": "doc", + "id": "installation-intro" + } +} diff --git a/docs/docs/installation-guide/assets/assetbundle-settings.png b/docs/docs/installation-guide/assets/assetbundle-settings.png new file mode 100644 index 00000000..1c21c9f5 Binary files /dev/null and b/docs/docs/installation-guide/assets/assetbundle-settings.png differ diff --git a/docs/docs/installation-guide/assets/dts.png b/docs/docs/installation-guide/assets/dts.png new file mode 100644 index 00000000..d5d0755d Binary files /dev/null and b/docs/docs/installation-guide/assets/dts.png differ diff --git a/docs/docs/installation-guide/installation-engine-plugin.md b/docs/docs/installation-guide/installation-engine-plugin.md new file mode 100644 index 00000000..a367ad74 --- /dev/null +++ b/docs/docs/installation-guide/installation-engine-plugin.md @@ -0,0 +1 @@ +# 使用引擎扩展安装 diff --git a/docs/docs/installation-guide/installation-intro.mdx b/docs/docs/installation-guide/installation-intro.mdx new file mode 100644 index 00000000..8a122dd9 --- /dev/null +++ b/docs/docs/installation-guide/installation-intro.mdx @@ -0,0 +1,17 @@ +--- +sidebar_position: 1 +hide_title: true +title: 安装指南 +--- +import DocCardList from '@theme/DocCardList'; +import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; + +服务包对引擎的改动主要使用 [自定义引擎](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/engine-customization.html) 的方式实现。 + +但由于没有找到方法添加内置资源,所以除此之外还需要您手动往项目里添加一些资源文件。 + +对于使用 TypeScript 的项目我们还提供 `creator-sp.d.ts` 类型提示文件。 + +以下是我们提供的两种安装方法,**推荐使用引擎扩展一键安装**: + + diff --git a/docs/docs/installation-guide/installation-manual.md b/docs/docs/installation-guide/installation-manual.md new file mode 100644 index 00000000..66077ed4 --- /dev/null +++ b/docs/docs/installation-guide/installation-manual.md @@ -0,0 +1,75 @@ +# 手动安装 + +:::caution 提示 + +手动安装需要掌握一定的 [Git](https://git-scm.com/doc) 和 [自定义引擎](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/engine-customization.html) 知识,建议使用我们发布的 [引擎扩展](./installation-engine-plugin) 一键安装。 + +::: + +## 引擎要求 + +请将 Cocos Creator 至少升级到 **v2.4.x** 版本。 +推荐直接升级到最新版本,2.x 版本只会进行维护性更新,所以不用担心其稳定性问题。 + +## 标准安装 + +当您项目所使用的引擎版本与服务包适配的引擎版本一致,并且您自己未对引擎有任何改动时,可参照以下步骤安装: + +### 1.替换自定义引擎 + +压缩包内的 `engine` `cocos2d-x` `jsb-adapter` 这三个目录分别就是我们已经修改好的 **JavaScript 引擎**、**Cocos2d-x 引擎** 和 **jsb-adpater**。 + +参照官方的 [自定义引擎](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/engine-customization.html) 文档分别配置或替换这三个部分即可。 + +:::tip 提示 + +**官方文档中的一些步骤我们已经帮你做好了**: + +**定制 JavaScript 引擎:**参考官方文档的 `1.2 修改 JS 引擎路径` 设置路径即可,无需安装编译依赖或者编译。 + +**定制 Cocos2d-x 引擎:** + +**替换 jsb-adapter:**这一步只需要替换目录即可,但请一定不要忘记! + +并且如果您**不需要支持原生平台,可以只配置 JavaScript 引擎**,不需要配置 Cocos2d-x 和 jsb-adapter。 +::: + +### 2.往项目放入资源 + +由于我们无法为引擎新增内置资源,所以需要您手动操作这一步,将压缩包内 `project` 目录的 `sp` 目录拷贝到项目的 `assets` 目录中,并设置 `sp` 目录为 **Asset Bundle**。 + +![assetbundlesettings](assets/assetbundle-settings.png) + +:::caution 注意 + +请勿随意放置,路径必须是 `assets/sp`,在编辑器环境中引擎只能通过路径读取资源。 + +请勿随意修改 Asset Bundle 的名称,名称必须是 `sp`,在实际运行中会通过加载这个 Asset Bundle 读取资源。 + +没有必要将这个 Asset Bundle 设为远程包或者 Zip 压缩,里面只是两个 Effect 着色器资源。 + +::: + +### 3.TypeScript 类型提示(可选) + +如果您的项目使用 TypeScript,请将压缩包内 `project` 目录的 `creator-sp.d.ts` 拷贝到项目根目录中,更新 API 接口类型提示。 + +![dts](assets/dts.png) + +部分 IDE 可能需要重启才会生效。 + +## 下载链接 + +### Service Pack v1.0 + +[下载压缩包](http://www.baidu.com) + +:::note + +**Service Pack v1.0** 适配 **Cocos Creator v2.4.9** 版本,请确认您项目的引擎版本一致。 + +::: + +### 历史版本 + +[存档页面](test) diff --git a/docs/docs/intro.md b/docs/docs/intro.md index 64f3020b..3cdd3ff8 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -1,36 +1,48 @@ --- sidebar_position: 1 +title: 介绍 +hide_title: true --- -# 介绍 +![logo](/img/logo2.png) -这是一个对 Cocos Creator 引擎进行特性新增、修复与优化的**开源非官方服务包**。 +这是一个对 Cocos Creator 引擎进行特性增强、修复与优化的**开源非官方服务包**。 -我们的发展方向是尽量以最符合引擎架构设计的方式加入新的特性、修复引擎已知问题以及性能优化。 +我们尽量以最符合引擎架构设计的方式加入新的特性、修复引擎已知问题以及性能优化。 :::info 项目的起源 -2021 年 2 月,Cocos 发布 Cocos Creator 3.0,并在 3.x 发布之后不会再继续开发 2.x 版本的新特性。 +2021 年 2 月,Cocos 发布 Cocos Creator 3.0,并在 3.x 发布之后不会再继续开发 2.x 版本的新特性,所有维护工作也会在 2023 年完全停止。 -问题修复等所有维护工作也会在 2023 年完全停止。而 2.x 以及 3.x 在一些方面都并不完善,所以我们发布了这个非官方的引擎“魔改”集合。 +但是 2.x 在一些方面还并不完善,所以我们发布了这个非官方的引擎“魔改”合集。 相似的事情发生在 2014 年 4 月,官方停止了对 Windows XP 的维护,之后 Harkaz 发布了一个非官方服务包 Service Pack 4 (SP4)。 -所以我们将这个“魔改”集合取名为 Service Pack。 +受到 Windows XP 的启发,我们将这个非官方的引擎“魔改”合集取名为 Service Pack。 -我们暂时只专注于 Cocos Creator 2.x 版本的适配,虽然当前服务包新增的一些特性在 Cocos Creator 3.5 版本中甚至依然还大部分缺失,但因为它还在蒸蒸日上中(还有希望),并且其引擎架构还在不断地迭代(不稳定),对其进行修改的维护工作会很大。 +我们暂时只专注于 Cocos Creator 2.x 版本的适配,Cocos Creator 3.x 正在蒸蒸日上,其引擎架构还在不断地迭代(不稳定),对其进行修改的维护工作会很大。 ::: -## 重要改进 +## 全部改动 + +服务包对引擎的所有改动都是开源的,并且每个改动都会附上一篇原理说明的文档,当你发现问题时请进行反馈,或者直接默默地帅气地提交一个 PR,帮助我们一起完善这个项目。 - 待补充。 -## 如何使用 +## 使用方法 + +我们推荐两种方式来使用这个服务包: + +### 引擎扩展 待补充。 -## 实现原理 +### Git Patch -每个改动的原理都会进行公示,我们没做过官方那样完善的测试,但是尽量保持改动的透明。 +待补充。 + +### 直接动手 + +阅读源码和原理文章来自行提取你想要的部分。 ## 更新日志 @@ -38,11 +50,34 @@ sidebar_position: 1 ## 贡献指南 -非常欢迎您能和我们一起来完善,所有的一切都通过 Github 进行: +非常欢迎你能和我们一起来完善这个项目,所有的一切都通过 Github 进行: -- 如果您有问题或者好的想法,请使用 `Issues` 或 `Discussions` 。 -- 如果您有新的代码提交,请使用 `Pull requests`。 +- 如果你有问题或者好的想法,请建立 `Issues` 或进入 `Discussions` 。 +- 如果你有新的代码提交,请建立 `Pull requests`。 -原则上我们接受任何新增与修改,但是**任何修改都必须兼容引擎原有的特性**,并且**不允许删除引擎原有的特性**。 +原则上我们接受任何增强与修改,但是**任何修改都必须兼容引擎原有的特性,不允许删除引擎原有的特性**,并且请认真思考功能的设计。 -在开发新特性时,请站在引擎的角度思考该如何设计。 +## 常见问题 + +### 为什么要直接修改引擎? + +直接修改引擎可能是大部分人认为的下下策,我们能听到的声音有: + +- 可以通过 “修改对象的原型” 等一些编程技巧做成一个插件脚本 +- 为什么要改?不改,因为 xxxx 原则说过,不要动旧的代码,我们造新的! +- 我都没接触过自定义引擎呢,不知道该怎么用 +- 如果我本来就改过引擎,不就很麻烦了吗? + +以上问题我们都思考过, + +首先,现在引擎的 2.x 版本已经停止了更新(仅做一些维护工作),也就是说我们的修改基本不会遇到在下个版本需要完全重构的情况。 + +其次,服务包中的大部分改动虽然可以做成一个插件脚本,但是原生平台就无法兼容,并且包体会增大,可维护性也不见得会提升。 + +最后,造新的或多或少会增加学习和使用的成本,并且我们希望它是 “原生” 的使用体验。 + +对于没有接触过自定义引擎的人,我们提供的引擎扩展可以一键帮助你设置好自定义引擎。 + +对于已经修改过引擎的人,我们提供 Git Patch 可以让你在已有修改的基础上轻松应用我们的更改,可能会产生一些冲突,但我相信你能解决。 + +**最后的最后,希望这个项目能够在你想学习相关知识或者做类似修改时可以帮助到你,享受吧!** diff --git a/docs/docs/tutorial-extras/_category_.json b/docs/docs/tutorial-extras/_category_.json deleted file mode 100644 index a8ffcc19..00000000 --- a/docs/docs/tutorial-extras/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Tutorial - Extras", - "position": 3, - "link": { - "type": "generated-index" - } -} diff --git a/docs/docs/tutorial-extras/img/docsVersionDropdown.png b/docs/docs/tutorial-extras/img/docsVersionDropdown.png deleted file mode 100644 index 97e41646..00000000 Binary files a/docs/docs/tutorial-extras/img/docsVersionDropdown.png and /dev/null differ diff --git a/docs/docs/tutorial-extras/img/localeDropdown.png b/docs/docs/tutorial-extras/img/localeDropdown.png deleted file mode 100644 index e257edc1..00000000 Binary files a/docs/docs/tutorial-extras/img/localeDropdown.png and /dev/null differ diff --git a/docs/docs/tutorial-extras/manage-docs-versions.md b/docs/docs/tutorial-extras/manage-docs-versions.md deleted file mode 100644 index e12c3f34..00000000 --- a/docs/docs/tutorial-extras/manage-docs-versions.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Manage Docs Versions - -Docusaurus can manage multiple versions of your docs. - -## Create a docs version - -Release a version 1.0 of your project: - -```bash -npm run docusaurus docs:version 1.0 -``` - -The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created. - -Your docs now have 2 versions: - -- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs -- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs** - -## Add a Version Dropdown - -To navigate seamlessly across versions, add a version dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -module.exports = { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'docsVersionDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The docs version dropdown appears in your navbar: - -![Docs Version Dropdown](./img/docsVersionDropdown.png) - -## Update an existing version - -It is possible to edit versioned docs in their respective folder: - -- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello` -- `docs/hello.md` updates `http://localhost:3000/docs/next/hello` diff --git a/docs/docs/tutorial-extras/translate-your-site.md b/docs/docs/tutorial-extras/translate-your-site.md deleted file mode 100644 index da2b8a36..00000000 --- a/docs/docs/tutorial-extras/translate-your-site.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Translate your site - -Let's translate `docs/intro.md` to French. - -## Configure i18n - -Modify `docusaurus.config.js` to add support for the `fr` locale: - -```js title="docusaurus.config.js" -module.exports = { - i18n: { - defaultLocale: 'en', - locales: ['en', 'fr'], - }, -}; -``` - -## Translate a doc - -Copy the `docs/intro.md` file to the `i18n/fr` folder: - -```bash -mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/ - -cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md -``` - -Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French. - -## Start your localized site - -Start your site on the French locale: - -```bash -npm run start -- --locale fr -``` - -Your localized site is accessible at `http://localhost:3000/fr/` and the `Getting Started` page is translated. - -:::caution - -In development, you can only use one locale at a same time. - -::: - -## Add a Locale Dropdown - -To navigate seamlessly across languages, add a locale dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -module.exports = { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'localeDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The locale dropdown now appears in your navbar: - -![Locale Dropdown](./img/localeDropdown.png) - -## Build your localized site - -Build your site for a specific locale: - -```bash -npm run build -- --locale fr -``` - -Or build your site to include all the locales at once: - -```bash -npm run build -``` diff --git a/docs/docs/tutorial-basics/_category_.json b/docs/docs/user-guide/_category_.json similarity index 66% rename from docs/docs/tutorial-basics/_category_.json rename to docs/docs/user-guide/_category_.json index 2e6db55b..b65ca9c4 100644 --- a/docs/docs/tutorial-basics/_category_.json +++ b/docs/docs/user-guide/_category_.json @@ -1,6 +1,7 @@ { - "label": "Tutorial - Basics", - "position": 2, + "label": "使用指南", + "position": 3, + "collapsed": false, "link": { "type": "generated-index", "description": "5 minutes to learn the most important Docusaurus concepts." diff --git a/docs/docs/tutorial-basics/congratulations.md b/docs/docs/user-guide/congratulations.md similarity index 100% rename from docs/docs/tutorial-basics/congratulations.md rename to docs/docs/user-guide/congratulations.md diff --git a/docs/docs/tutorial-basics/create-a-blog-post.md b/docs/docs/user-guide/create-a-blog-post.md similarity index 100% rename from docs/docs/tutorial-basics/create-a-blog-post.md rename to docs/docs/user-guide/create-a-blog-post.md diff --git a/docs/docs/tutorial-basics/create-a-document.md b/docs/docs/user-guide/create-a-document.md similarity index 100% rename from docs/docs/tutorial-basics/create-a-document.md rename to docs/docs/user-guide/create-a-document.md diff --git a/docs/docs/tutorial-basics/create-a-page.md b/docs/docs/user-guide/create-a-page.md similarity index 100% rename from docs/docs/tutorial-basics/create-a-page.md rename to docs/docs/user-guide/create-a-page.md diff --git a/docs/docs/tutorial-basics/deploy-your-site.md b/docs/docs/user-guide/deploy-your-site.md similarity index 100% rename from docs/docs/tutorial-basics/deploy-your-site.md rename to docs/docs/user-guide/deploy-your-site.md diff --git a/docs/docs/tutorial-basics/markdown-features.mdx b/docs/docs/user-guide/markdown-features.mdx similarity index 100% rename from docs/docs/tutorial-basics/markdown-features.mdx rename to docs/docs/user-guide/markdown-features.mdx diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index ce2ea285..e47beef2 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -7,8 +7,8 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula'); /** @type {import('@docusaurus/types').Config} */ const config = { title: 'Cocos Service Pack', - tagline: '对 Cocos Creator 引擎进行特性新增、修复与优化的开源非官方服务包', - url: 'https://smallmain.github.io/cocos-service-pack/', + tagline: '给 Cocos Creator 加点料', + url: 'https://smallmain.github.io', baseUrl: '/cocos-service-pack/', onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', @@ -78,8 +78,9 @@ const config = { // { to: '/blog', label: 'Blog', position: 'left' }, { href: 'https://github.com/smallmain/cocos-service-pack', - label: 'GitHub', + label: '加星鼓励', position: 'right', + className: 'header-github-link', }, { type: 'search', diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 6215cd04..a2a34970 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -15,6 +15,7 @@ --ifm-color-primary-lightest: #7b59c3; --ifm-code-font-size: 90%; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); + --ifm-h1-font-size: 2.5rem; } /* For readability concerns, you should choose a lighter palette in dark mode. */ @@ -31,12 +32,46 @@ @media screen and (max-width: 996px) { :root { - --ifm-font-size-base: 15px; + --ifm-font-size-base: 16px; } } @media screen and (min-width: 997px) { :root { - --ifm-font-size-base: 15px; + --ifm-font-size-base: 18px; } } + +html[data-theme=light] .navbar__item.header-github-link { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgiIGhlaWdodD0iMjciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMy42MDEgMGExMy41OTcgMTMuNTk3IDAgMCAwLTQuMjk4IDI2LjQ5OGMuNjc2LjEyNi45MjgtLjI5NS45MjgtLjY1NSAwLS4zMjUtLjAxMS0xLjM5NC0uMDE4LTIuNTMxLTMuNzgzLjgyMi00LjU4LTEuNjAzLTQuNTgtMS42MDMtLjYxOS0xLjU3Ni0xLjUxLTEuOTktMS41MS0xLjk5LTEuMjM0LS44NDUuMDkyLS44MjcuMDkyLS44MjcgMS4zNjYuMDk3IDIuMDg1IDEuNCAyLjA4NSAxLjQgMS4yMTMgMi4wNzkgMy4xODEgMS40OCAzLjk1NiAxLjEyNi4xMjMtLjg3OC40NzUtMS40NzcuODY0LTEuODE3LTMuMDEtLjM0LTYuMTk2LTEuNTA2LTYuMTk2LTYuNzE2YTUuMjU3IDUuMjU3IDAgMCAxIDEuNDAzLTMuNjU0Yy0uMTQyLS4zNDItLjYwOC0xLjcyNS4xMy0zLjYwMiAwIDAgMS4xNDItLjM2NSAzLjc0IDEuMzkzYTEyLjkyIDEyLjkyIDAgMCAxIDYuODEgMGMyLjU4NS0xLjc0OSAzLjczNi0xLjM5MyAzLjczNi0xLjM5My43MzkgMS44NzMuMjc1IDMuMjU1LjEzMyAzLjYwMmE1LjI1NSA1LjI1NSAwIDAgMSAxLjM5OCAzLjY1YzAgNS4yMjMtMy4xOCA2LjM3MS02LjIwNyA2LjcxLjQ4Ni40Mi45MiAxLjI0OS45MiAyLjUxNiAwIDEuODItLjAxMyAzLjI4NS0uMDEzIDMuNzMxIDAgLjM2My4yNDMuNzg2LjkzMi42NTNBMTMuNTk2IDEzLjU5NiAwIDAgMCAxMy42MDEgMHoiIGZpbGw9IiMyMTIyMkMiLz48cGF0aCBkPSJNNS4xNTQgMTkuNTJjLS4wMy4wNjgtLjEzNS4wODgtLjIyNS4wNDNzLS4xNTYtLjEzNy0uMTI0LS4yMDVjLjAzMS0uMDY3LjEzNy0uMDg3LjIyNS0uMDQyLjA4OC4wNDUuMTU1LjEzNy4xMjIuMjA0aC4wMDJ6bS41NTEuNjE1Yy0uMDY1LjA2LS4xOTEuMDMyLS4yNzktLjA2M2EuMjA3LjIwNyAwIDAgMS0uMDM4LS4yODFjLjA2Ny0uMDYxLjE4OS0uMDMyLjI3OS4wNjMuMDkuMDk0LjEwNi4yMjUuMDM4LjI4MXptLjUzNi43ODNjLS4wODMuMDU5LS4yMjUgMC0uMzA0LS4xMTctLjA3OS0uMTE3LS4wODMtLjI2NSAwLS4zMjQuMDg0LS4wNTguMjI1IDAgLjMwNC4xMTUuMDc5LjExNS4wODQuMjY4IDAgLjMyNnptLjc0My43NTdhLjI1NS4yNTUgMCAwIDEtLjM1OC0uMDZjLS4xMi0uMTExLS4xNTMtLjI2Ni0uMDc2LS4zNDguMDc2LS4wOC4yMjUtLjA2LjM1LjA1Mi4xMjcuMTEzLjE1NC4yNjYuMDc1LjM0N2wuMDEuMDA5em0xLjAwNC40MzljLS4wMzMuMTA2LS4xODQuMTU1LS4zNC4xMS0uMTU1LS4wNDUtLjI1NC0uMTctLjIyNS0uMjc5LjAzLS4xMDguMTg1LS4xNTcuMzQtLjExLjE1Ni4wNDcuMjU1LjE3LjIyNS4yNzl6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTkuMSAyMi4xOTVjMCAuMTEzLS4xMjYuMjA1LS4yODguMjA3LS4xNjIuMDAyLS4yOTItLjA4NS0uMjk1LS4xOTgtLjAwMi0uMTEzLjEyNi0uMjA1LjI5LS4yMDcuMTY1LS4wMDIuMjkzLjA4OC4yOTMuMTk4em0xLjAzNi0uMTc1Yy4wMi4xMS0uMDkyLjIyNS0uMjUyLjI1Mi0uMTYuMDI3LS4zMDQtLjAzOS0uMzI0LS4xNDktLjAyLS4xMS4wOTQtLjIyNS4yNTItLjI1Mi4xNTgtLjAyNy4zMDQuMDM4LjMyNC4xNDh6IiBmaWxsPSIjMUUxRjI3Ii8+PC9zdmc+) 0/20px 20px no-repeat; +} + +.navbar__item.header-github-link { + padding-left: 1.6rem; + padding-bottom: 0.2rem; + margin-left: 0.6rem; + margin-right: -1rem; + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgiIGhlaWdodD0iMjciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMy42MDEgMGExMy41OTcgMTMuNTk3IDAgMCAwLTQuMjk4IDI2LjQ5OGMuNjc2LjEyNi45MjgtLjI5NS45MjgtLjY1NSAwLS4zMjUtLjAxMS0xLjM5NC0uMDE4LTIuNTMxLTMuNzgzLjgyMi00LjU4LTEuNjAzLTQuNTgtMS42MDMtLjYxOS0xLjU3Ni0xLjUxLTEuOTktMS41MS0xLjk5LTEuMjM0LS44NDUuMDkyLS44MjcuMDkyLS44MjcgMS4zNjYuMDk3IDIuMDg1IDEuNCAyLjA4NSAxLjQgMS4yMTMgMi4wNzkgMy4xODEgMS40OCAzLjk1NiAxLjEyNi4xMjMtLjg3OC40NzUtMS40NzcuODY0LTEuODE3LTMuMDEtLjM0LTYuMTk2LTEuNTA2LTYuMTk2LTYuNzE2YTUuMjU3IDUuMjU3IDAgMCAxIDEuNDAzLTMuNjU0Yy0uMTQyLS4zNDItLjYwOC0xLjcyNS4xMy0zLjYwMiAwIDAgMS4xNDItLjM2NSAzLjc0IDEuMzkzYTEyLjkyIDEyLjkyIDAgMCAxIDYuODEgMGMyLjU4NS0xLjc0OSAzLjczNi0xLjM5MyAzLjczNi0xLjM5My43MzkgMS44NzMuMjc1IDMuMjU1LjEzMyAzLjYwMmE1LjI1NSA1LjI1NSAwIDAgMSAxLjM5OCAzLjY1YzAgNS4yMjMtMy4xOCA2LjM3MS02LjIwNyA2LjcxLjQ4Ni40Mi45MiAxLjI0OS45MiAyLjUxNiAwIDEuODItLjAxMyAzLjI4NS0uMDEzIDMuNzMxIDAgLjM2My4yNDMuNzg2LjkzMi42NTNBMTMuNTk2IDEzLjU5NiAwIDAgMCAxMy42MDEgMHoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNS4xNTQgMTkuNTJjLS4wMy4wNjgtLjEzNS4wODgtLjIyNS4wNDNzLS4xNTYtLjEzNy0uMTI0LS4yMDVjLjAzMS0uMDY3LjEzNy0uMDg3LjIyNS0uMDQyLjA4OC4wNDUuMTU1LjEzNy4xMjIuMjA0aC4wMDJ6bS41NTEuNjE1Yy0uMDY1LjA2LS4xOTEuMDMyLS4yNzktLjA2M2EuMjA3LjIwNyAwIDAgMS0uMDM4LS4yODFjLjA2Ny0uMDYxLjE4OS0uMDMyLjI3OS4wNjMuMDkuMDk0LjEwNi4yMjUuMDM4LjI4MXptLjUzNi43ODNjLS4wODMuMDU5LS4yMjUgMC0uMzA0LS4xMTctLjA3OS0uMTE3LS4wODMtLjI2NSAwLS4zMjQuMDg0LS4wNTguMjI1IDAgLjMwNC4xMTUuMDc5LjExNS4wODQuMjY4IDAgLjMyNnptLjc0My43NTdhLjI1NS4yNTUgMCAwIDEtLjM1OC0uMDZjLS4xMi0uMTExLS4xNTMtLjI2Ni0uMDc2LS4zNDguMDc2LS4wOC4yMjUtLjA2LjM1LjA1Mi4xMjcuMTEzLjE1NC4yNjYuMDc1LjM0N2wuMDEuMDA5em0xLjAwNC40MzljLS4wMzMuMTA2LS4xODQuMTU1LS4zNC4xMS0uMTU1LS4wNDUtLjI1NC0uMTctLjIyNS0uMjc5LjAzLS4xMDguMTg1LS4xNTcuMzQtLjExLjE1Ni4wNDcuMjU1LjE3LjIyNS4yNzl6bTEuMTEyLjA4MWMwIC4xMTMtLjEyNi4yMDUtLjI4OC4yMDctLjE2Mi4wMDItLjI5Mi0uMDg1LS4yOTUtLjE5OC0uMDAyLS4xMTMuMTI2LS4yMDUuMjktLjIwNy4xNjUtLjAwMi4yOTMuMDg4LjI5My4xOTh6bTEuMDM2LS4xNzVjLjAyLjExLS4wOTIuMjI1LS4yNTIuMjUyLS4xNi4wMjctLjMwNC0uMDM5LS4zMjQtLjE0OS0uMDItLjExLjA5NC0uMjI1LjI1Mi0uMjUyLjE1OC0uMDI3LjMwNC4wMzguMzI0LjE0OHoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=) 0/20px 20px no-repeat; +} + +.hero__subtitle { + margin-top: 2rem; +} + +.hero__title { + font-size: 4rem; +} + +@media screen and (max-width: 996px) { + .banner-img { + display: none; + } +} + +.markdown h1:first-child { + --ifm-h1-font-size: 2.5rem; +} + +.title_node_modules-\@docusaurus-theme-classic-lib-next-theme-DocCategoryGeneratedIndexPage-styles-module { + --ifm-h1-font-size: 2.5rem !important; +} diff --git a/docs/src/pages/index.module.css b/docs/src/pages/index.module.css index 9f71a5da..c4f77e8d 100644 --- a/docs/src/pages/index.module.css +++ b/docs/src/pages/index.module.css @@ -5,7 +5,7 @@ .heroBanner { padding: 4rem 0; - text-align: center; + /* text-align: center; */ position: relative; overflow: hidden; } @@ -19,5 +19,6 @@ .buttons { display: flex; align-items: center; - justify-content: center; + margin-top: 60px; + /* justify-content: center; */ } diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx index afed24b6..d5828d26 100644 --- a/docs/src/pages/index.tsx +++ b/docs/src/pages/index.tsx @@ -5,20 +5,59 @@ import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import styles from './index.module.css'; import HomepageFeatures from '@site/src/components/HomepageFeatures'; +import Rocket from '../../static/img/rocket.svg'; function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return ( -
+ // +
-

{siteConfig.title}

-

{siteConfig.tagline}

-
- - Docusaurus Tutorial - 5min ⏱️ - +
+
+

{siteConfig.title}

+

{siteConfig.tagline + ":"}

+
+

+ 2D 渲染 + 支持多纹理材质,新增多纹理合批管理器与静态合批组件 +

+

+ 动态图集 + 完全重构,进行了多方面提升,并支持自动多纹理合批 +

+

+ Label 组件 + 支持高 DPI 渲染,BITMAP 与 CHAR 缓存模式的实用性提升 +

+

+ RichText 组件 + 支持使用自定义材质 +

+

+ Spine 组件 + 支持 Region 换装,支持参与动态合图 +

+
+
+ + 开始使用 + + + + GitHub + +
+
+
+ +
@@ -26,7 +65,7 @@ function HomepageHeader() { } export default function Home(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return ( + {label} + {/* {href && !isInternalUrl(href) && } */} + + ); +} diff --git a/docs/src/theme/Footer/index.js b/docs/src/theme/Footer/index.js new file mode 100644 index 00000000..816eb392 --- /dev/null +++ b/docs/src/theme/Footer/index.js @@ -0,0 +1,26 @@ +import React from 'react'; +import {useThemeConfig} from '@docusaurus/theme-common'; +import FooterLinks from '@theme/Footer/Links'; +import FooterLogo from '@theme/Footer/Logo'; +import FooterCopyright from '@theme/Footer/Copyright'; +import FooterLayout from '@theme/Footer/Layout'; + +function Footer() { + const {footer} = useThemeConfig(); + + if (!footer) { + return null; + } + + const {copyright, links, logo, style} = footer; + return ( + 0 && } + logo={logo && } + copyright={copyright && } + /> + ); +} + +export default React.memo(Footer); diff --git a/docs/src/theme/NavbarItem/ComponentTypes.js b/docs/src/theme/NavbarItem/ComponentTypes.js new file mode 100644 index 00000000..8a432e7c --- /dev/null +++ b/docs/src/theme/NavbarItem/ComponentTypes.js @@ -0,0 +1,21 @@ +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; +import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem'; +import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem'; +import HtmlNavbarItem from '@theme/NavbarItem/HtmlNavbarItem'; +import DocNavbarItem from '@theme/NavbarItem/DocNavbarItem'; +import DocSidebarNavbarItem from '@theme/NavbarItem/DocSidebarNavbarItem'; +import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem'; +import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; +const ComponentTypes = { + default: DefaultNavbarItem, + localeDropdown: LocaleDropdownNavbarItem, + search: SearchNavbarItem, + dropdown: DropdownNavbarItem, + html: HtmlNavbarItem, + doc: DocNavbarItem, + docSidebar: DocSidebarNavbarItem, + docsVersion: DocsVersionNavbarItem, + docsVersionDropdown: DocsVersionDropdownNavbarItem, +}; +export default ComponentTypes; diff --git a/docs/src/theme/NavbarItem/DefaultNavbarItem.js b/docs/src/theme/NavbarItem/DefaultNavbarItem.js new file mode 100644 index 00000000..01eb5275 --- /dev/null +++ b/docs/src/theme/NavbarItem/DefaultNavbarItem.js @@ -0,0 +1,51 @@ +import React from 'react'; +import clsx from 'clsx'; +import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink'; +import {getInfimaActiveClassName} from '@theme/NavbarItem/utils'; + +function DefaultNavbarItemDesktop({ + className, + isDropdownItem = false, + ...props +}) { + const element = ( + + ); + + if (isDropdownItem) { + return
  • {element}
  • ; + } + + return element; +} + +function DefaultNavbarItemMobile({className, isDropdownItem, ...props}) { + return ( +
  • + +
  • + ); +} + +export default function DefaultNavbarItem({ + mobile = false, + position, + // Need to destructure position from props so that it doesn't get passed on. + ...props +}) { + const Comp = mobile ? DefaultNavbarItemMobile : DefaultNavbarItemDesktop; + return ( + + ); +} diff --git a/docs/src/theme/NavbarItem/DocNavbarItem.js b/docs/src/theme/NavbarItem/DocNavbarItem.js new file mode 100644 index 00000000..b91d8e90 --- /dev/null +++ b/docs/src/theme/NavbarItem/DocNavbarItem.js @@ -0,0 +1,37 @@ +import React from 'react'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import {useActiveDocContext} from '@docusaurus/plugin-content-docs/client'; +import clsx from 'clsx'; +import {getInfimaActiveClassName} from '@theme/NavbarItem/utils'; +import {useLayoutDoc} from '@docusaurus/theme-common'; +export default function DocNavbarItem({ + docId, + label: staticLabel, + docsPluginId, + ...props +}) { + const {activeDoc} = useActiveDocContext(docsPluginId); + const doc = useLayoutDoc(docId, docsPluginId); // Draft items are not displayed in the navbar. + + if (doc === null) { + return null; + } + + const activeDocInfimaClassName = getInfimaActiveClassName(props.mobile); + return ( + + ); +} diff --git a/docs/src/theme/NavbarItem/DocSidebarNavbarItem.js b/docs/src/theme/NavbarItem/DocSidebarNavbarItem.js new file mode 100644 index 00000000..5b95cb82 --- /dev/null +++ b/docs/src/theme/NavbarItem/DocSidebarNavbarItem.js @@ -0,0 +1,35 @@ +import React from 'react'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import {useActiveDocContext} from '@docusaurus/plugin-content-docs/client'; +import clsx from 'clsx'; +import {getInfimaActiveClassName} from '@theme/NavbarItem/utils'; +import {useLayoutDocsSidebar} from '@docusaurus/theme-common'; +export default function DocSidebarNavbarItem({ + sidebarId, + label, + docsPluginId, + ...props +}) { + const {activeDoc} = useActiveDocContext(docsPluginId); + const sidebarLink = useLayoutDocsSidebar(sidebarId, docsPluginId).link; + + if (!sidebarLink) { + throw new Error( + `DocSidebarNavbarItem: Sidebar with ID "${sidebarId}" doesn't have anything to be linked to.`, + ); + } + + const activeDocInfimaClassName = getInfimaActiveClassName(props.mobile); + return ( + + ); +} diff --git a/docs/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js b/docs/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js new file mode 100644 index 00000000..4ad52c5f --- /dev/null +++ b/docs/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js @@ -0,0 +1,87 @@ +import React from 'react'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; +import { + useVersions, + useActiveDocContext, +} from '@docusaurus/plugin-content-docs/client'; +import { + useDocsPreferredVersion, + useDocsVersionCandidates, +} from '@docusaurus/theme-common'; +import {translate} from '@docusaurus/Translate'; + +const getVersionMainDoc = (version) => + version.docs.find((doc) => doc.id === version.mainDocId); + +export default function DocsVersionDropdownNavbarItem({ + mobile, + docsPluginId, + dropdownActiveClassDisabled, + dropdownItemsBefore, + dropdownItemsAfter, + ...props +}) { + const activeDocContext = useActiveDocContext(docsPluginId); + const versions = useVersions(docsPluginId); + const {savePreferredVersionName} = useDocsPreferredVersion(docsPluginId); + const versionLinks = versions.map((version) => { + // We try to link to the same doc, in another version + // When not possible, fallback to the "main doc" of the version + const versionDoc = + activeDocContext?.alternateDocVersions[version.name] ?? + getVersionMainDoc(version); + return { + isNavLink: true, + label: version.label, + to: versionDoc.path, + isActive: () => version === activeDocContext?.activeVersion, + onClick: () => savePreferredVersionName(version.name), + }; + }); + const items = [ + ...dropdownItemsBefore, + ...versionLinks, + ...dropdownItemsAfter, + ]; + const dropdownVersion = useDocsVersionCandidates(docsPluginId)[0]; // Mobile dropdown is handled a bit differently + + const dropdownLabel = + mobile && items.length > 1 + ? translate({ + id: 'theme.navbar.mobileVersionsDropdown.label', + message: 'Versions', + description: + 'The label for the navbar versions dropdown on mobile view', + }) + : dropdownVersion.label; + const dropdownTo = + mobile && items.length > 1 + ? undefined + : getVersionMainDoc(dropdownVersion).path; // We don't want to render a version dropdown with 0 or 1 item. If we build + // the site with a single docs version (onlyIncludeVersions: ['1.0.0']), + // We'd rather render a button instead of a dropdown + + if (items.length <= 1) { + return ( + false : undefined} + /> + ); + } + + return ( + false : undefined} + /> + ); +} diff --git a/docs/src/theme/NavbarItem/DocsVersionNavbarItem.js b/docs/src/theme/NavbarItem/DocsVersionNavbarItem.js new file mode 100644 index 00000000..d7172dbc --- /dev/null +++ b/docs/src/theme/NavbarItem/DocsVersionNavbarItem.js @@ -0,0 +1,18 @@ +import React from 'react'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import {useDocsVersionCandidates} from '@docusaurus/theme-common'; + +const getVersionMainDoc = (version) => + version.docs.find((doc) => doc.id === version.mainDocId); + +export default function DocsVersionNavbarItem({ + label: staticLabel, + to: staticTo, + docsPluginId, + ...props +}) { + const version = useDocsVersionCandidates(docsPluginId)[0]; + const label = staticLabel ?? version.label; + const path = staticTo ?? getVersionMainDoc(version).path; + return ; +} diff --git a/docs/src/theme/NavbarItem/DropdownNavbarItem.js b/docs/src/theme/NavbarItem/DropdownNavbarItem.js new file mode 100644 index 00000000..eddae31d --- /dev/null +++ b/docs/src/theme/NavbarItem/DropdownNavbarItem.js @@ -0,0 +1,161 @@ +import React, {useState, useRef, useEffect} from 'react'; +import clsx from 'clsx'; +import { + isSamePath, + useCollapsible, + Collapsible, + isRegexpStringMatch, + useLocalPathname, +} from '@docusaurus/theme-common'; +import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink'; +import NavbarItem from '@theme/NavbarItem'; +const dropdownLinkActiveClass = 'dropdown__link--active'; + +function isItemActive(item, localPathname) { + if (isSamePath(item.to, localPathname)) { + return true; + } + + if (isRegexpStringMatch(item.activeBaseRegex, localPathname)) { + return true; + } + + if (item.activeBasePath && localPathname.startsWith(item.activeBasePath)) { + return true; + } + + return false; +} + +function containsActiveItems(items, localPathname) { + return items.some((item) => isItemActive(item, localPathname)); +} + +function DropdownNavbarItemDesktop({items, position, className, ...props}) { + const dropdownRef = useRef(null); + const [showDropdown, setShowDropdown] = useState(false); + useEffect(() => { + const handleClickOutside = (event) => { + if (!dropdownRef.current || dropdownRef.current.contains(event.target)) { + return; + } + + setShowDropdown(false); + }; + + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('touchstart', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('touchstart', handleClickOutside); + }; + }, [dropdownRef]); + return ( +
    + e.preventDefault()} + onKeyDown={(e) => { + if (e.key === 'Enter') { + e.preventDefault(); + setShowDropdown(!showDropdown); + } + }}> + {props.children ?? props.label} + +
      + {items.map((childItemProps, i) => ( + { + if (i === items.length - 1 && e.key === 'Tab') { + e.preventDefault(); + setShowDropdown(false); + const nextNavbarItem = dropdownRef.current.nextElementSibling; + + if (nextNavbarItem) { + const targetItem = + nextNavbarItem instanceof HTMLAnchorElement + ? nextNavbarItem // Next item is another dropdown; focus on the inner + : // anchor element instead so there's outline + nextNavbarItem.querySelector('a'); + targetItem.focus(); + } + } + }} + activeClassName={dropdownLinkActiveClass} + {...childItemProps} + key={i} + /> + ))} +
    +
    + ); +} + +function DropdownNavbarItemMobile({ + items, + className, + position, + // Need to destructure position from props so that it doesn't get passed on. + ...props +}) { + const localPathname = useLocalPathname(); + const containsActive = containsActiveItems(items, localPathname); + const {collapsed, toggleCollapsed, setCollapsed} = useCollapsible({ + initialState: () => !containsActive, + }); // Expand/collapse if any item active after a navigation + + useEffect(() => { + if (containsActive) { + setCollapsed(!containsActive); + } + }, [localPathname, containsActive, setCollapsed]); + return ( +
  • + { + e.preventDefault(); + toggleCollapsed(); + }}> + {props.children ?? props.label} + + + {items.map((childItemProps, i) => ( + + ))} + +
  • + ); +} + +export default function DropdownNavbarItem({mobile = false, ...props}) { + const Comp = mobile ? DropdownNavbarItemMobile : DropdownNavbarItemDesktop; + return ; +} diff --git a/docs/src/theme/NavbarItem/HtmlNavbarItem.js b/docs/src/theme/NavbarItem/HtmlNavbarItem.js new file mode 100644 index 00000000..0bc21714 --- /dev/null +++ b/docs/src/theme/NavbarItem/HtmlNavbarItem.js @@ -0,0 +1,24 @@ +import React from 'react'; +import clsx from 'clsx'; +export default function HtmlNavbarItem({ + value, + className, + mobile = false, + isDropdownItem = false, +}) { + const Comp = isDropdownItem ? 'li' : 'div'; + return ( + + ); +} diff --git a/docs/src/theme/NavbarItem/NavbarNavLink.js b/docs/src/theme/NavbarItem/NavbarNavLink.js new file mode 100644 index 00000000..dbaefa73 --- /dev/null +++ b/docs/src/theme/NavbarItem/NavbarNavLink.js @@ -0,0 +1,69 @@ +import React from 'react'; +import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import isInternalUrl from '@docusaurus/isInternalUrl'; +import {isRegexpStringMatch} from '@docusaurus/theme-common'; +const dropdownLinkActiveClass = 'dropdown__link--active'; +export default function NavbarNavLink({ + activeBasePath, + activeBaseRegex, + to, + href, + label, + html, + activeClassName = '', + prependBaseUrlToHref, + ...props +}) { + // TODO all this seems hacky + // {to: 'version'} should probably be forbidden, in favor of {to: '/version'} + const toUrl = useBaseUrl(to); + const activeBaseUrl = useBaseUrl(activeBasePath); + const normalizedHref = useBaseUrl(href, { + forcePrependBaseUrl: true, + }); + const isExternalLink = label && href && !isInternalUrl(href); + const isDropdownLink = activeClassName === dropdownLinkActiveClass; // Link content is set through html XOR label + + const linkContentProps = html + ? { + dangerouslySetInnerHTML: { + __html: html, + }, + } + : { + children: ( + <> + {label} + + ), + }; + + if (href) { + return ( + + ); + } + + return ( + + activeBaseRegex + ? isRegexpStringMatch(activeBaseRegex, location.pathname) + : location.pathname.startsWith(activeBaseUrl), + })} + {...props} + {...linkContentProps} + /> + ); +} diff --git a/docs/src/theme/NavbarItem/SearchNavbarItem.js b/docs/src/theme/NavbarItem/SearchNavbarItem.js new file mode 100644 index 00000000..4a2f90c8 --- /dev/null +++ b/docs/src/theme/NavbarItem/SearchNavbarItem.js @@ -0,0 +1,14 @@ +import React from 'react'; +import SearchBar from '@theme/SearchBar'; +import NavbarSearch from '@theme/Navbar/Search'; +export default function SearchNavbarItem({mobile}) { + if (mobile) { + return null; + } + + return ( + + + + ); +} diff --git a/docs/src/theme/NavbarItem/index.js b/docs/src/theme/NavbarItem/index.js new file mode 100644 index 00000000..50356312 --- /dev/null +++ b/docs/src/theme/NavbarItem/index.js @@ -0,0 +1,28 @@ +import React from 'react'; +import ComponentTypes from '@theme/NavbarItem/ComponentTypes'; + +const getNavbarItemComponent = (type) => { + const component = ComponentTypes[type]; + + if (!component) { + throw new Error(`No NavbarItem component found for type "${type}".`); + } + + return component; +}; + +function getComponentType(type, isDropdown) { + // Backward compatibility: navbar item with no type set + // but containing dropdown items should use the type "dropdown" + if (!type || type === 'default') { + return isDropdown ? 'dropdown' : 'default'; + } + + return type; +} + +export default function NavbarItem({type, ...props}) { + const componentType = getComponentType(type, props.items !== undefined); + const NavbarItemComponent = getNavbarItemComponent(componentType); + return ; +} diff --git a/docs/src/theme/NavbarItem/utils.js b/docs/src/theme/NavbarItem/utils.js new file mode 100644 index 00000000..f3a5d029 --- /dev/null +++ b/docs/src/theme/NavbarItem/utils.js @@ -0,0 +1,3 @@ +/* eslint-disable import/no-named-export */ +export const getInfimaActiveClassName = (mobile) => + mobile ? 'menu__link--active' : 'navbar__link--active'; diff --git a/docs/static/img/logo2.png b/docs/static/img/logo2.png new file mode 100644 index 00000000..6f9edc24 Binary files /dev/null and b/docs/static/img/logo2.png differ diff --git a/docs/static/img/rocket.svg b/docs/static/img/rocket.svg new file mode 100644 index 00000000..8d17b588 --- /dev/null +++ b/docs/static/img/rocket.svg @@ -0,0 +1 @@ + \ No newline at end of file