├── .editorconfig ├── .github └── workflows │ ├── deploy-blog.yml │ └── sync-app-repo.yml ├── .gitignore ├── .npmrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── assets ├── blog_blog.png ├── blog_dark.png ├── blog_demo.png ├── blog_light.png ├── blog_music.png ├── blog_search.png ├── blog_theme_dark.png ├── blog_theme_light.png └── repl.png ├── cli ├── configs ├── vscode-plugins.txt └── vscode-settings.json ├── eslint.config.js ├── package.json ├── packages ├── @rick-ui │ ├── .dumirc.ts │ ├── .fatherrc.ts │ ├── assets │ │ ├── images │ │ │ ├── bg1.jpg │ │ │ ├── bg2.jpg │ │ │ ├── bg3.jpg │ │ │ ├── bg4.jpg │ │ │ ├── cover1.jpg │ │ │ ├── cover2.jpg │ │ │ └── cover3.jpg │ │ └── index.ts │ ├── config │ │ ├── hotkey.ts │ │ └── theme.ts │ ├── docs │ │ └── controls │ │ │ └── index.tsx │ ├── package.json │ ├── public │ │ └── react.webp │ ├── src │ │ ├── Editor │ │ │ ├── common │ │ │ │ ├── config.ts │ │ │ │ └── setup.ts │ │ │ ├── components │ │ │ │ ├── DiffEditor.tsx │ │ │ │ ├── Editor.tsx │ │ │ │ └── Loading.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ ├── index.ts │ │ │ └── themes │ │ │ │ ├── Active4D.json │ │ │ │ ├── All Hallows Eve.json │ │ │ │ ├── Amy.json │ │ │ │ ├── Birds of Paradise.json │ │ │ │ ├── Blackboard.json │ │ │ │ ├── Brilliance Black.json │ │ │ │ ├── Brilliance Dull.json │ │ │ │ ├── Chrome DevTools.json │ │ │ │ ├── Clouds Midnight.json │ │ │ │ ├── Clouds.json │ │ │ │ ├── Cobalt.json │ │ │ │ ├── Cobalt2.json │ │ │ │ ├── Dawn.json │ │ │ │ ├── Dominion Day.json │ │ │ │ ├── Dracula.json │ │ │ │ ├── Dreamweaver.json │ │ │ │ ├── Eiffel.json │ │ │ │ ├── Espresso Libre.json │ │ │ │ ├── GitHub Dark.json │ │ │ │ ├── GitHub Light.json │ │ │ │ ├── GitHub.json │ │ │ │ ├── IDLE.json │ │ │ │ ├── Katzenmilch.json │ │ │ │ ├── Kuroir Theme.json │ │ │ │ ├── LAZY.json │ │ │ │ ├── MagicWB (Amiga).json │ │ │ │ ├── Merbivore Soft.json │ │ │ │ ├── Merbivore.json │ │ │ │ ├── Monokai Bright.json │ │ │ │ ├── Monokai.json │ │ │ │ ├── Night Owl.json │ │ │ │ ├── Nord.json │ │ │ │ ├── Oceanic Next.json │ │ │ │ ├── Pastels on Dark.json │ │ │ │ ├── Slush and Poppies.json │ │ │ │ ├── Solarized-dark.json │ │ │ │ ├── Solarized-light.json │ │ │ │ ├── SpaceCadet.json │ │ │ │ ├── Sunburst.json │ │ │ │ ├── Textmate (Mac Classic).json │ │ │ │ ├── Tomorrow-Night-Blue.json │ │ │ │ ├── Tomorrow-Night-Bright.json │ │ │ │ ├── Tomorrow-Night-Eighties.json │ │ │ │ ├── Tomorrow-Night.json │ │ │ │ ├── Tomorrow.json │ │ │ │ ├── Twilight.json │ │ │ │ ├── Upstream Sunburst.json │ │ │ │ ├── Vibrant Ink.json │ │ │ │ ├── Xcode_default.json │ │ │ │ ├── Zenburnesque.json │ │ │ │ ├── dark.ts │ │ │ │ ├── iPlastic.json │ │ │ │ ├── idleFingers.json │ │ │ │ ├── index.ts │ │ │ │ ├── krTheme.json │ │ │ │ ├── light.ts │ │ │ │ └── monoindustrial.json │ │ ├── Show │ │ │ ├── Show.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── Switch │ │ │ ├── Switch.tsx │ │ │ ├── index.tsx │ │ │ └── style │ │ │ │ └── index.ts │ │ ├── aurora │ │ │ ├── Aurora.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── code-input │ │ │ ├── CodeInput.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── file-icon │ │ │ ├── FileIcon.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── icon │ │ │ │ ├── babel.svg │ │ │ │ ├── browserList.svg │ │ │ │ ├── changelog.svg │ │ │ │ ├── css.svg │ │ │ │ ├── eslint.svg │ │ │ │ ├── file.svg │ │ │ │ ├── folder-close.svg │ │ │ │ ├── folder-components.svg │ │ │ │ ├── folder-open.svg │ │ │ │ ├── gulp.svg │ │ │ │ ├── html.svg │ │ │ │ ├── image.svg │ │ │ │ ├── javascript.svg │ │ │ │ ├── jest.svg │ │ │ │ ├── json.svg │ │ │ │ ├── less.svg │ │ │ │ ├── lightning.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── log.svg │ │ │ │ ├── markdown.svg │ │ │ │ ├── pdf.svg │ │ │ │ ├── postcss.svg │ │ │ │ ├── react.svg │ │ │ │ ├── react_ts.svg │ │ │ │ ├── readme.svg │ │ │ │ ├── sass.svg │ │ │ │ ├── stylus.svg │ │ │ │ ├── svg.svg │ │ │ │ ├── tailwindcss.svg │ │ │ │ ├── test-js.svg │ │ │ │ ├── test-ts.svg │ │ │ │ ├── typescript-def.svg │ │ │ │ ├── typescript.svg │ │ │ │ ├── video.svg │ │ │ │ ├── xml.svg │ │ │ │ ├── yarn.svg │ │ │ │ └── zip.svg │ │ │ ├── index.md │ │ │ ├── index.tsx │ │ │ └── utils │ │ │ │ ├── file-icon.tsx │ │ │ │ ├── file-language.ts │ │ │ │ └── file-type.ts │ │ ├── fuzzy-text │ │ │ ├── FuzzyText.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── grid-distortion │ │ │ ├── GridDistortion.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── grid-motion │ │ │ ├── GridMotion.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── index.ts │ │ ├── squares │ │ │ ├── Squares.tsx │ │ │ ├── demo │ │ │ │ └── basic.tsx │ │ │ ├── index.md │ │ │ └── index.tsx │ │ ├── tabs │ │ │ ├── Tabs.tsx │ │ │ └── index.tsx │ │ ├── theme-provider │ │ │ ├── Theme.tsx │ │ │ ├── ThemeProvider.tsx │ │ │ ├── hooks │ │ │ │ └── useTheme.ts │ │ │ ├── index.tsx │ │ │ └── style │ │ │ │ ├── antd.ts │ │ │ │ └── global.ts │ │ ├── theme-switch │ │ │ ├── ThemeSwitch.tsx │ │ │ ├── index.tsx │ │ │ └── style │ │ │ │ └── index.ts │ │ └── theme-wrapper │ │ │ ├── ThemeWrapper.tsx │ │ │ └── index.tsx │ ├── tailwind.css │ └── tsconfig.json └── @rick-utils │ ├── browser │ └── copyText.ts │ ├── common │ ├── eventEmitter.ts │ └── sleep.ts │ ├── console │ ├── Logger.ts │ └── signature.ts │ ├── editor │ └── formatCode.ts │ ├── files │ ├── parseDir.ts │ ├── parseFiles.ts │ ├── parseZip.ts │ ├── sortFiles.ts │ └── type.ts │ ├── index.ts │ ├── json │ ├── isObjectOrJsonString.ts │ ├── object.test.ts │ ├── prettyJsonString.ts │ └── safeJsonParse.ts │ ├── package.json │ ├── react │ └── memo.ts │ └── typescript │ ├── MakeKeysOptional.ts │ ├── MakeKeysRequired.ts │ └── RecordMapping.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── prettier.config.cjs ├── projects ├── @rick-awesome │ ├── .env │ ├── .eslintignore │ ├── README.md │ ├── TECH.md │ ├── index.html │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── icon-192.png │ │ ├── icon-512.png │ │ ├── icon-64.png │ │ └── icon.png │ ├── src │ │ ├── app │ │ │ ├── index.tsx │ │ │ └── repl │ │ │ │ └── index.tsx │ │ ├── assets │ │ │ ├── docs │ │ │ │ └── demo.docx │ │ │ ├── music │ │ │ │ ├── between-worlds.mp3 │ │ │ │ ├── index.ts │ │ │ │ ├── mystery-of-love.mp3 │ │ │ │ ├── 在雨中.mp3 │ │ │ │ ├── 没有理想的人不伤心.mp3 │ │ │ │ └── 爱在夏天-盛夏之约.mp3 │ │ │ ├── pdf │ │ │ │ └── http.pdf │ │ │ └── pic │ │ │ │ ├── bg.jpg │ │ │ │ ├── cover1.jpg │ │ │ │ ├── cover2.jpg │ │ │ │ ├── cover3.jpg │ │ │ │ └── index.ts │ │ ├── blog │ │ │ ├── components │ │ │ │ ├── article │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.ts │ │ │ │ ├── codepen │ │ │ │ │ └── index.tsx │ │ │ │ ├── codesandbox │ │ │ │ │ └── index.tsx │ │ │ │ └── sequence-chart │ │ │ │ │ └── index.tsx │ │ │ ├── content │ │ │ │ ├── README.mdx │ │ │ │ ├── angular │ │ │ │ │ ├── directive.md │ │ │ │ │ ├── html-in-service.md │ │ │ │ │ ├── http.md │ │ │ │ │ ├── module.md │ │ │ │ │ ├── monaco-editor.md │ │ │ │ │ ├── pipe.md │ │ │ │ │ ├── project.md │ │ │ │ │ ├── router.md │ │ │ │ │ ├── rxjs.md │ │ │ │ │ └── standalone.md │ │ │ │ ├── javascript │ │ │ │ │ ├── debounce-throttle.md │ │ │ │ │ ├── decorate.md │ │ │ │ │ ├── defineProperty-proxy.md │ │ │ │ │ ├── design-patterns-singleton.md │ │ │ │ │ ├── design-patterns-strategy.md │ │ │ │ │ ├── design-patterns-subscriber.md │ │ │ │ │ ├── file-upload.md │ │ │ │ │ ├── how-equality-operator-work.md │ │ │ │ │ ├── operator-chaining-nullish-coalescing-operator.md │ │ │ │ │ ├── prototype.md │ │ │ │ │ ├── pwa.md │ │ │ │ │ └── this.md │ │ │ │ ├── network │ │ │ │ │ └── http-referer.md │ │ │ │ ├── node │ │ │ │ │ └── express.md │ │ │ │ ├── others │ │ │ │ │ ├── cors.md │ │ │ │ │ ├── git-branch-manager.md │ │ │ │ │ ├── github-actions.md │ │ │ │ │ └── single-page-app-github-refresh-404.md │ │ │ │ ├── react │ │ │ │ │ ├── basic.mdx │ │ │ │ │ ├── cra-config.md │ │ │ │ │ ├── css.md │ │ │ │ │ ├── diy.md │ │ │ │ │ ├── hooks.md │ │ │ │ │ ├── jsx.mdx │ │ │ │ │ ├── lifecycle.md │ │ │ │ │ ├── mobx.md │ │ │ │ │ ├── props-state.md │ │ │ │ │ ├── react-library.md │ │ │ │ │ ├── redux-basic.mdx │ │ │ │ │ ├── redux-middleware.mdx │ │ │ │ │ ├── redux-toolkit.mdx │ │ │ │ │ ├── router.md │ │ │ │ │ └── ssr.md │ │ │ │ ├── sidebar.md │ │ │ │ └── typescript │ │ │ │ │ ├── advanced-type.md │ │ │ │ │ ├── data-types.md │ │ │ │ │ └── keywords.md │ │ │ ├── layout │ │ │ │ ├── content │ │ │ │ │ └── index.tsx │ │ │ │ ├── header │ │ │ │ │ └── index.tsx │ │ │ │ ├── homepage.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── sidebar │ │ │ │ │ └── index.tsx │ │ │ │ └── style.ts │ │ │ └── plugins │ │ │ │ └── inject-import.ts │ │ ├── components │ │ │ ├── background │ │ │ │ └── index.tsx │ │ │ ├── commands │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── error-page │ │ │ │ └── index.tsx │ │ │ ├── iframe │ │ │ │ └── index.tsx │ │ │ └── vue-component │ │ │ │ └── index.tsx │ │ ├── config │ │ │ ├── shortcut.ts │ │ │ └── web-vitals.ts │ │ ├── hooks │ │ │ └── useShortkey.ts │ │ ├── index.css │ │ ├── interface │ │ │ └── index.ts │ │ ├── main.tsx │ │ ├── modules │ │ │ ├── chart │ │ │ │ └── sequence │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── msc.ts │ │ │ ├── demo │ │ │ │ ├── climate │ │ │ │ │ ├── app.html │ │ │ │ │ └── index.tsx │ │ │ │ ├── keyborad │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.ts │ │ │ │ ├── lion │ │ │ │ │ ├── app.html │ │ │ │ │ └── index.tsx │ │ │ │ ├── navigation │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.ts │ │ │ │ ├── puppy │ │ │ │ │ ├── app.html │ │ │ │ │ └── index.tsx │ │ │ │ └── switch │ │ │ │ │ └── index.tsx │ │ │ ├── rick │ │ │ │ ├── blog │ │ │ │ │ └── index.tsx │ │ │ │ ├── memorial-day │ │ │ │ │ ├── flipdown.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.ts │ │ │ │ └── music │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── index.v2.vue │ │ │ └── settings │ │ │ │ ├── appearance │ │ │ │ └── index.tsx │ │ │ │ └── vscode-config │ │ │ │ └── index.tsx │ │ ├── resource.ts │ │ ├── roadmap │ │ │ ├── preview │ │ │ │ └── pdf │ │ │ │ │ └── index.tsx │ │ │ └── ticket │ │ │ │ └── index.tsx │ │ ├── router │ │ │ ├── blog.tsx │ │ │ ├── index.tsx │ │ │ ├── meta-data.tsx │ │ │ └── rick.tsx │ │ ├── store │ │ │ └── useModalOpenConfigModel.ts │ │ ├── theme │ │ │ ├── content-wrapper.tsx │ │ │ └── index.tsx │ │ ├── type.d.ts │ │ ├── utils │ │ │ └── index.tsx │ │ └── vite-env.d.ts │ └── vite.config.ts └── @rick-repl │ ├── .github │ └── workflows │ │ └── deploy.yml │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── icon-192.png │ ├── icon-512.png │ ├── icon-64.png │ └── icon.png │ ├── src │ ├── Repl.tsx │ ├── assets │ │ └── webp │ │ │ ├── github.webp │ │ │ ├── index.ts │ │ │ ├── js.webp │ │ │ ├── python.webp │ │ │ ├── react.webp │ │ │ ├── vscode.webp │ │ │ └── vue.webp │ ├── config │ │ └── const.ts │ ├── editor │ │ ├── core.tsx │ │ └── index.tsx │ ├── hooks │ │ ├── useInit.ts │ │ ├── useTabs.ts │ │ └── useTheme.ts │ ├── index.css │ ├── main.tsx │ ├── preview │ │ ├── iframe.html │ │ └── index.tsx │ ├── setup │ │ ├── JSON.tmLanguage.json │ │ ├── JavaScriptReact.tmLanguage.json │ │ ├── TypeScriptReact.tmLanguage.json │ │ ├── css.tmLanguage.json │ │ ├── default │ │ │ ├── app.tsx │ │ │ ├── const.tsx │ │ │ ├── main.tsx │ │ │ └── style.css │ │ ├── defaultTabs.ts │ │ ├── html.tmLanguage.json │ │ ├── index.ts │ │ ├── vs_dark_rick.json │ │ └── vs_light_rick.json │ ├── types │ │ └── index.tsx │ ├── vite-env.d.ts │ └── worker │ │ ├── compiler.worker.ts │ │ ├── formatter.worker.ts │ │ ├── linter.worker.ts │ │ └── tailwindcss.worker.ts │ └── vite.config.ts ├── scripts ├── export-vscode-configs.ts ├── polyfills.ts └── regenerate-dependencies.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── type.def.d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | 12 | [*.md] 13 | max_line_length = 0 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.github/workflows/deploy-blog.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Rick.Zhou's Blog 2 | 3 | on: 4 | - push 5 | 6 | jobs: 7 | Build: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | # https://github.com/actions/checkout 12 | - name: Checkout 🛎️ 13 | uses: actions/checkout@v3 14 | 15 | - name: Install pnpm 🧰 16 | uses: pnpm/action-setup@v4 17 | 18 | - name: Build 📦 19 | env: 20 | ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} 21 | EMAIL: 944268618@qq.com 22 | USERNAME: Rick.Zhou 23 | REPO: github.com/rick-chou/one-piece-react.git 24 | run: | 25 | 26 | echo node version 27 | node -v 28 | 29 | echo pnpm version 30 | pnpm -v 31 | 32 | pnpm install 33 | pnpm build:blog 34 | 35 | cd projects/@rick-awesome 36 | cd dist 37 | cp index.html 404.html 38 | 39 | # git init 40 | # git config --global user.email $EMAIL 41 | # git config --global user.name $USERNAME 42 | # git remote add origin https://$ACCESS_TOKEN@$REPO 43 | 44 | # git checkout -b gh-pages 45 | # git add . 46 | # git commit -m "🌈 @rickzhou/awesome" 47 | # git push -f --set-upstream origin gh-pages 48 | 49 | - name: Upload 📦 50 | # https://github.com/JamesIves/github-pages-deploy-action 51 | uses: JamesIves/github-pages-deploy-action@v4 52 | with: 53 | folder: projects/@rick-awesome/dist 54 | token: ${{ secrets.ACCESS_TOKEN }} 55 | 56 | Deploy: 57 | runs-on: ubuntu-latest 58 | needs: Build 59 | steps: 60 | - name: Deploy 🚀 61 | # https://github.com/peaceiris/actions-gh-pages 62 | uses: peaceiris/actions-gh-pages@v3 63 | with: 64 | personal_token: ${{ secrets.ACCESS_TOKEN }} 65 | publish_dir: . 66 | publish_branch: gh-pages 67 | keep_files: true 68 | full_commit_message: ${{ github.event.head_commit.message }} 69 | user_name: 'github-actions[bot]' 70 | user_email: 'github-actions[bot]@users.rick-chou.github.com' 71 | -------------------------------------------------------------------------------- /.github/workflows/sync-app-repo.yml: -------------------------------------------------------------------------------- 1 | name: SYNC APP REPO 2 | 3 | on: 4 | - push 5 | 6 | jobs: 7 | repl: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | # https://github.com/actions/checkout 12 | - name: Checkout 🛎️ 13 | uses: actions/checkout@v3 14 | 15 | - name: Install pnpm 🧰 16 | uses: pnpm/action-setup@v4 17 | 18 | - name: Push 📦 19 | env: 20 | EMAIL: 944268618@qq.com 21 | USERNAME: Rick.Zhou 22 | ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} 23 | REPO: github.com/rick-chou/repl.git 24 | run: | 25 | 26 | pnpm install 27 | pnpm build:repl 28 | 29 | cd projects/@rick-repl/dist 30 | cp index.html 404.html 31 | 32 | git init 33 | git config --global user.email $EMAIL 34 | git config --global user.name $USERNAME 35 | git remote add origin https://$ACCESS_TOKEN@$REPO 36 | 37 | git checkout -b gh-pages 38 | git add . 39 | git commit -m "🌈 @rickzhou/repl" 40 | git push -f --set-upstream origin gh-pages 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .idea 17 | .DS_Store 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | 24 | # PWA files 25 | dev-dist 26 | 27 | 28 | .dumi 29 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # registry=https://registry.npmjs.org/ 2 | registry=https://registry.npmmirror.com/ 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.organizeImports": "explicit", // Explicitly organize imports 4 | "source.fixAll": "explicit", // Explicitly fix all issues 5 | "source.fixAll.eslint": "explicit" // Explicitly fix ESLint issues 6 | }, 7 | "cSpell.words": ["mscgenjs", "rickzhou", "Zhou"] 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) rick zhou <944268618@qq.com> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

ONE PIECE REACT

2 | 3 |

4 | 5 |

6 | 7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 |

15 | 16 |
17 | 18 | ## 🌈 Time Machine 19 | 20 | ### 2021 21 | 22 | - [x] Graduation! 🥂 🧱 👷🏿‍♂️ 23 | - [x] Vue2 Developer 😀 24 | - [x] React Developer 😍 25 | 26 | ### 2022 27 | 28 | - [x] React Native Developer 😅 29 | 30 | ### 2023 31 | 32 | - [x] Angular2.0+ Developer 🤔 33 | - [x] React Developer 😅 34 | - [x] Learn Java 😎 35 | - [x] Get married 🥰 36 | 37 | ### 2024 38 | 39 | - [x] Our little one has arrived! 🍼🧑‍🍼👩‍🍼 40 | 41 | ![bg](https://cdn.jsdelivr.net/gh/rick-chou/rick-assets/jpg/43.jpg) 42 | 43 | ## 🌟 Blog 44 | 45 | > https://rick-chou.github.io/one-piece-react/ 46 | 47 | ![demo](assets/blog_demo.png) 48 | ![demo](assets/blog_theme_light.png) 49 | ![demo](assets/blog_theme_dark.png) 50 | ![demo](assets/blog_music.png) 51 | ![demo](assets/blog_search.png) 52 | ![demo](assets/blog_blog.png) 53 | ![demo](assets/blog_light.png) 54 | ![demo](assets/blog_dark.png) 55 | ![demo](assets/repl.png) 56 | -------------------------------------------------------------------------------- /assets/blog_blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_blog.png -------------------------------------------------------------------------------- /assets/blog_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_dark.png -------------------------------------------------------------------------------- /assets/blog_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_demo.png -------------------------------------------------------------------------------- /assets/blog_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_light.png -------------------------------------------------------------------------------- /assets/blog_music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_music.png -------------------------------------------------------------------------------- /assets/blog_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_search.png -------------------------------------------------------------------------------- /assets/blog_theme_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_theme_dark.png -------------------------------------------------------------------------------- /assets/blog_theme_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/blog_theme_light.png -------------------------------------------------------------------------------- /assets/repl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/assets/repl.png -------------------------------------------------------------------------------- /cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | ./node_modules/.bin/tsx $@ 6 | -------------------------------------------------------------------------------- /configs/vscode-plugins.txt: -------------------------------------------------------------------------------- 1 | alefragnani.bookmarks 2 | antfu.icons-carbon 3 | be5invis.vscode-custom-css 4 | bradlc.vscode-tailwindcss 5 | brandonkirbyson.vscode-animations 6 | christian-kohler.npm-intellisense 7 | christian-kohler.path-intellisense 8 | dbaeumer.vscode-eslint 9 | dsznajder.es7-react-js-snippets 10 | eamodio.gitlens 11 | editorconfig.editorconfig 12 | esbenp.prettier-vscode 13 | github.github-vscode-theme 14 | gruntfuggly.todo-tree 15 | kisstkondoros.vscode-gutter-preview 16 | naumovs.color-highlight 17 | pkief.material-icon-theme 18 | ritwickdey.liveserver 19 | streetsidesoftware.code-spell-checker 20 | teabyii.ayu 21 | vscode-icons-team.vscode-icons 22 | vue.volar 23 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import js from '@eslint/js'; 4 | import reactHooks from 'eslint-plugin-react-hooks'; 5 | import reactRefresh from 'eslint-plugin-react-refresh'; 6 | import globals from 'globals'; 7 | import tseslint from 'typescript-eslint'; 8 | 9 | export default tseslint.config( 10 | { ignores: ['dist'] }, 11 | { 12 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 13 | files: ['**/*.{ts,tsx}'], 14 | languageOptions: { 15 | ecmaVersion: 2020, 16 | globals: globals.browser, 17 | }, 18 | plugins: { 19 | 'react-hooks': reactHooks, 20 | 'react-refresh': reactRefresh, 21 | }, 22 | rules: { 23 | ...reactHooks.configs.recommended.rules, 24 | 'react-refresh/only-export-components': [ 25 | 'warn', 26 | { allowConstantExport: true }, 27 | ], 28 | '@typescript-eslint/no-explicit-any': 'off', 29 | '@typescript-eslint/consistent-type-imports': [ 30 | 'error', 31 | { 32 | fixStyle: 'inline-type-imports', 33 | }, 34 | ], 35 | }, 36 | }, 37 | ); 38 | -------------------------------------------------------------------------------- /packages/@rick-ui/.dumirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'dumi'; 2 | import { defineThemeConfig } from 'dumi-theme-antd/dist/defineThemeConfig'; 3 | import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin'; 4 | 5 | export default defineConfig({ 6 | outputPath: 'docs-dist', 7 | mfsu: true, 8 | themeConfig: defineThemeConfig({ 9 | name: '@rickzhou/react-ui', 10 | showLineNum: false, 11 | logo: '/react.webp', 12 | nav: [{ title: 'Components', link: '/components/aurora' }], 13 | footer: false, 14 | socialLinks: { 15 | github: 'https://github.com/rick-chou', 16 | }, 17 | title: '@rickzhou/react-ui', 18 | description: 'nothing changes if nothing changes', 19 | features: [], 20 | bannerConfig: { 21 | showBanner: true, 22 | bannerImgUrl: 23 | 'https://cdn.jsdelivr.net/gh/rick-chou/rick-assets/jpg/42.jpg', 24 | }, 25 | }), 26 | scripts: ['https://cdn.tailwindcss.com?plugins=typography'], 27 | 28 | chainWebpack(memo, args) { 29 | memo 30 | .plugin('monaco-editor') 31 | .use(MonacoWebpackPlugin, [ 32 | { 33 | features: [], 34 | languages: ['json', 'html', 'css', 'javascript', 'typescript'], 35 | customLanguages: [ 36 | { 37 | label: 'mysql', 38 | entry: 39 | 'monaco-sql-languages/esm/languages/mysql/mysql.contribution', 40 | worker: { 41 | id: '/esm/languages/mysql/', 42 | entry: 'monaco-sql-languages/esm/languages/mysql/mysql.worker', 43 | }, 44 | }, 45 | ], 46 | }, 47 | ]) 48 | .end(); 49 | // console.log('memo', memo); 50 | return memo; 51 | }, 52 | apiParser: {}, 53 | resolve: { 54 | entryFile: './src/index.ts', 55 | }, 56 | locales: [ 57 | { id: 'en-US', name: 'EN' }, 58 | { id: 'zh-CN', name: '中文' }, 59 | ], 60 | }); 61 | -------------------------------------------------------------------------------- /packages/@rick-ui/.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'father'; 2 | 3 | export default defineConfig({ 4 | // more father config: https://github.com/umijs/father/blob/master/docs/config.md 5 | esm: { output: 'dist' }, 6 | }); 7 | -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/bg1.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/bg2.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/bg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/bg3.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/bg4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/bg4.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/cover1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/cover1.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/cover2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/cover2.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/images/cover3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/assets/images/cover3.jpg -------------------------------------------------------------------------------- /packages/@rick-ui/assets/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Bg1 } from './images/bg1.jpg'; 2 | export { default as Bg2 } from './images/bg2.jpg'; 3 | export { default as Bg3 } from './images/bg3.jpg'; 4 | export { default as Bg4 } from './images/bg4.jpg'; 5 | export { default as Cover1 } from './images/cover1.jpg'; 6 | export { default as Cover2 } from './images/cover2.jpg'; 7 | export { default as Cover3 } from './images/cover3.jpg'; 8 | -------------------------------------------------------------------------------- /packages/@rick-ui/config/hotkey.ts: -------------------------------------------------------------------------------- 1 | export const Hotkey = { 2 | Shift: '⇧', 3 | Meta: '⌘', 4 | Ctrl: '⌃', 5 | Alt: '⌥', 6 | 7 | ArrowDown: 'ArrowDown', 8 | ArrowUp: 'ArrowUp', 9 | ArrowLeft: 'ArrowLeft', 10 | ArrowRight: 'ArrowRight', 11 | Enter: 'Enter', 12 | 13 | A: 'A', 14 | B: 'B', 15 | C: 'C', 16 | D: 'D', 17 | E: 'E', 18 | F: 'F', 19 | G: 'G', 20 | H: 'H', 21 | I: 'I', 22 | J: 'J', 23 | K: 'K', 24 | L: 'L', 25 | M: 'M', 26 | N: 'N', 27 | O: 'O', 28 | P: 'P', 29 | Q: 'Q', 30 | R: 'R', 31 | S: 'S', 32 | T: 'T', 33 | U: 'U', 34 | V: 'V', 35 | W: 'W', 36 | X: 'X', 37 | Y: 'Y', 38 | Z: 'Z', 39 | }; 40 | -------------------------------------------------------------------------------- /packages/@rick-ui/config/theme.ts: -------------------------------------------------------------------------------- 1 | import { type ThemeMode } from '@root/src/theme-provider/hooks/useTheme'; 2 | 3 | const fontFamily = 'Oswald'; 4 | const codeFontFamily = 'Fira Code'; 5 | const opacity = 90; 6 | 7 | export const successColor = '#28a745'; 8 | export const warningColor = '#ffc107'; 9 | export const errorColor = '#dc3545'; 10 | export const processingColor = '#007bff'; 11 | 12 | export const typography: Typography = { 13 | fontFamily, 14 | codeFontFamily, 15 | opacity, 16 | }; 17 | 18 | export type Typography = { 19 | fontFamily: string; 20 | codeFontFamily: string; 21 | opacity: number; 22 | }; 23 | 24 | export type ThemeConfig = { 25 | [key: string]: string; 26 | colorPrimaryBg: string; 27 | colorSecondaryBg: string; 28 | colorInverseBg: string; 29 | colorPrimaryBgHover: string; 30 | colorPrimaryText: string; 31 | colorActive: string; 32 | }; 33 | 34 | const light: ThemeConfig = { 35 | colorPrimaryBg: '#e0e5ec', 36 | colorSecondaryBg: '#fff', 37 | colorInverseBg: '#000', 38 | colorPrimaryBgHover: '#fafafa', 39 | colorPrimaryText: '#16171a', 40 | colorActive: '#bae0ff', 41 | }; 42 | 43 | const dark: ThemeConfig = { 44 | colorPrimaryBg: '#16171a', 45 | colorSecondaryBg: '#000', 46 | colorInverseBg: '#fff', 47 | colorPrimaryBgHover: '#303133', 48 | colorPrimaryText: '#c7c7c7', 49 | colorActive: '#bae0ff', 50 | }; 51 | 52 | export const themeConfig: Record = { 53 | light, 54 | dark, 55 | }; 56 | -------------------------------------------------------------------------------- /packages/@rick-ui/docs/controls/index.tsx: -------------------------------------------------------------------------------- 1 | // TODO 2 | 3 | const Controls = () => {}; 4 | 5 | export default Controls; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rickzhou/react-ui", 3 | "version": "1.0.0", 4 | "description": "React Library", 5 | "license": "MIT", 6 | "type": "module", 7 | "module": "src/index.ts", 8 | "types": "src/index.ts", 9 | "files": [ 10 | "src", 11 | "styles", 12 | "assets", 13 | "tailwind.css" 14 | ], 15 | "scripts": { 16 | "dev": "dumi dev" 17 | }, 18 | "dependencies": { 19 | "@monaco-editor/react": "^4.6.0", 20 | "dumi-theme-antd": "^0.4.4", 21 | "monaco-editor": "^0.31.0", 22 | "monaco-sql-languages": "^0.12.2", 23 | "ogl": "^1.0.11", 24 | "react-code-input": "^3.10.1", 25 | "three": "^0.175.0" 26 | }, 27 | "devDependencies": { 28 | "@types/react": "^18.0.0", 29 | "@types/react-dom": "^18.0.0", 30 | "@types/three": "^0.175.0", 31 | "dumi": "^2.4.17", 32 | "father": "^4.1.0", 33 | "monaco-editor-webpack-plugin": "^7.1.0" 34 | }, 35 | "peerDependencies": { 36 | "react": ">=16.9.0", 37 | "react-dom": ">=16.9.0" 38 | }, 39 | "authors": [ 40 | "rick zhou <944268618@qq.com>" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /packages/@rick-ui/public/react.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/packages/@rick-ui/public/react.webp -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/common/config.ts: -------------------------------------------------------------------------------- 1 | import { type editor } from 'monaco-editor'; 2 | 3 | export const EDITOR_OPTIONS: editor.IEditorOptions = { 4 | minimap: { 5 | enabled: false, 6 | }, 7 | renderFinalNewline: true, 8 | scrollbar: { 9 | vertical: 'auto', 10 | horizontal: 'auto', 11 | verticalSliderSize: 4, 12 | verticalScrollbarSize: 4, 13 | horizontalScrollbarSize: 4, 14 | horizontalSliderSize: 4, 15 | }, 16 | mouseWheelZoom: false, 17 | contextmenu: true, 18 | fontSize: 14, 19 | fontWeight: '500', 20 | scrollBeyondLastLine: true, 21 | smoothScrolling: true, 22 | cursorWidth: 0, 23 | renderValidationDecorations: 'off', 24 | colorDecorators: false, 25 | hideCursorInOverviewRuler: true, 26 | overviewRulerLanes: 0, 27 | overviewRulerBorder: false, 28 | automaticLayout: true, 29 | lineNumbers: 'on', 30 | fontFamily: 'Fira Code', 31 | cursorSmoothCaretAnimation: true, 32 | renderLineHighlight: 'none', 33 | cursorBlinking: 'smooth', 34 | cursorStyle: 'line', 35 | padding: { top: 8, bottom: 8 }, 36 | lineNumbersMinChars: 4, 37 | formatOnPaste: true, 38 | foldingImportsByDefault: true, 39 | foldingHighlight: true, 40 | folding: true, 41 | }; 42 | 43 | export const DIFF_EDITOR_OPTIONS: editor.IDiffEditorOptions = { 44 | ...EDITOR_OPTIONS, 45 | renderSideBySide: true, 46 | }; 47 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/common/setup.ts: -------------------------------------------------------------------------------- 1 | import { loader } from '@monaco-editor/react'; 2 | import { Logger } from '@rickzhou/react-utils'; 3 | import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; 4 | import { LanguageIdEnum, setupLanguageFeatures } from 'monaco-sql-languages'; 5 | 6 | loader.config({ monaco }); 7 | 8 | loader.init().then(monaco => { 9 | /** define theme */ 10 | Logger.success('MONACO EDITOR THEME INIT'); 11 | setupLanguageFeatures(LanguageIdEnum.MYSQL, { 12 | completionItems: { enable: true, triggerCharacters: [' ', '.'] }, 13 | }); 14 | Logger.success('MYSQL LANGUAGE SERVICE INIT'); 15 | // monaco.editor.defineTheme('dark', darkTheme); 16 | // monaco.editor.defineTheme('light', lightTheme); 17 | }); 18 | 19 | export { monaco }; 20 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/components/DiffEditor.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | DiffEditor as _DiffEditor, 3 | useMonaco, 4 | type DiffEditorProps as _DiffEditorProps, 5 | type Monaco, 6 | } from '@monaco-editor/react'; 7 | import { memoSVC } from '@rickzhou/react-utils'; 8 | import { type editor } from 'monaco-editor'; 9 | import { useEffect, useMemo, type FC } from 'react'; 10 | import { useTheme } from '../../theme-provider/hooks/useTheme'; 11 | import { DIFF_EDITOR_OPTIONS } from '../common/config'; 12 | import { Loading } from './Loading'; 13 | 14 | export type DiffEditorProps = Omit<_DiffEditorProps, 'theme'> & { 15 | readOnly?: boolean; 16 | language: string; 17 | }; 18 | 19 | const DiffEditor: FC = memoSVC( 20 | ({ readOnly = false, ...props }) => { 21 | const options = useMemo(() => { 22 | return { 23 | ...DIFF_EDITOR_OPTIONS, 24 | ...props?.options, 25 | readOnly, 26 | }; 27 | }, [props?.options, readOnly]); 28 | 29 | const monaco = useMonaco(); 30 | const { theme } = useTheme(); 31 | 32 | function handleEditorDidMount( 33 | editor: editor.IStandaloneDiffEditor, 34 | monaco: Monaco, 35 | ) { 36 | props?.onMount?.(editor, monaco); 37 | monaco.editor.setTheme(theme); 38 | } 39 | 40 | useEffect(() => { 41 | if (monaco) { 42 | monaco.editor.setTheme(theme); 43 | } 44 | }, [monaco, theme]); 45 | 46 | return ( 47 | <_DiffEditor 48 | loading={} 49 | {...props} 50 | options={options} 51 | onMount={handleEditorDidMount} 52 | /> 53 | ); 54 | }, 55 | ); 56 | 57 | export default DiffEditor; 58 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/components/Editor.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Editor as _Editor, 3 | type EditorProps as _EditorProps, 4 | type Monaco, 5 | useMonaco, 6 | } from '@monaco-editor/react'; 7 | import { memoSVC } from '@rickzhou/react-utils'; 8 | import { type editor } from 'monaco-editor'; 9 | import { type FC, useEffect, useMemo, useRef } from 'react'; 10 | import { useTheme } from '../../theme-provider/hooks/useTheme'; 11 | import { EDITOR_OPTIONS } from '../common/config'; 12 | import { Loading } from './Loading'; 13 | 14 | export type EditorProps = Omit<_EditorProps, 'theme'> & { 15 | readOnly?: boolean; 16 | language: string; 17 | }; 18 | 19 | const Editor: FC = memoSVC( 20 | ({ readOnly = false, language, ...props }) => { 21 | const monaco = useMonaco(); 22 | const { theme } = useTheme(); 23 | const editorRef = useRef(); 24 | 25 | function handleEditorDidMount( 26 | editor: editor.IStandaloneCodeEditor, 27 | monaco: Monaco, 28 | ) { 29 | editorRef.current = editor; 30 | props?.onMount?.(editor, monaco); 31 | monaco.editor.setTheme(theme); 32 | } 33 | 34 | useEffect(() => { 35 | if (monaco) { 36 | monaco.editor.setTheme(theme); 37 | } 38 | }, [monaco, theme]); 39 | 40 | const options = useMemo(() => { 41 | return { 42 | ...EDITOR_OPTIONS, 43 | ...props?.options, 44 | readOnly, 45 | }; 46 | }, [props?.options, readOnly]); 47 | 48 | return ( 49 | <_Editor 50 | loading={} 51 | {...props} 52 | language={language} 53 | options={options} 54 | onMount={handleEditorDidMount} 55 | /> 56 | ); 57 | }, 58 | ); 59 | 60 | export default Editor; 61 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/components/Loading.tsx: -------------------------------------------------------------------------------- 1 | import { Spin } from 'antd'; 2 | 3 | export const Loading = () => { 4 | return ; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/demo/basic.tsx: -------------------------------------------------------------------------------- 1 | import { Editor, Tabs } from '@rickzhou/react-ui'; 2 | 3 | const defaultValue = { 4 | sql: 'SELECT * FROM', 5 | typescript: 'console.log(1)', 6 | css: '.box { color: red;}', 7 | html: '
Editor
', 8 | json: '{"name": "rick.zhou"}', 9 | }; 10 | 11 | const App = () => { 12 | return ( 13 | 24 | ), 25 | }, 26 | { 27 | label: 'Typescript', 28 | key: 'Typescript', 29 | children: ( 30 | 35 | ), 36 | }, 37 | { 38 | label: 'Css', 39 | key: 'Css', 40 | children: ( 41 | 46 | ), 47 | }, 48 | { 49 | label: 'Html', 50 | key: 'Html', 51 | children: ( 52 | 57 | ), 58 | }, 59 | { 60 | label: 'Json', 61 | key: 'Json', 62 | children: ( 63 | 68 | ), 69 | }, 70 | ]} 71 | /> 72 | ); 73 | }; 74 | 75 | export default App; 76 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/index.md: -------------------------------------------------------------------------------- 1 | # Editor 2 | 3 | Basic 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/index.ts: -------------------------------------------------------------------------------- 1 | import './common/setup'; 2 | 3 | export { default as DiffEditor } from './components/DiffEditor'; 4 | export type { DiffEditorProps } from './components/DiffEditor'; 5 | 6 | export { default as Editor } from './components/Editor'; 7 | export type { EditorProps } from './components/Editor'; 8 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/themes/All Hallows Eve.json: -------------------------------------------------------------------------------- 1 | { 2 | "base": "vs-dark", 3 | "inherit": true, 4 | "rules": [ 5 | { 6 | "background": "000000", 7 | "token": "" 8 | }, 9 | { 10 | "foreground": "ffffff", 11 | "background": "434242", 12 | "token": "text" 13 | }, 14 | { 15 | "foreground": "ffffff", 16 | "background": "000000", 17 | "token": "source" 18 | }, 19 | { 20 | "foreground": "9933cc", 21 | "token": "comment" 22 | }, 23 | { 24 | "foreground": "3387cc", 25 | "token": "constant" 26 | }, 27 | { 28 | "foreground": "cc7833", 29 | "token": "keyword" 30 | }, 31 | { 32 | "foreground": "d0d0ff", 33 | "token": "meta.preprocessor.c" 34 | }, 35 | { 36 | "fontStyle": "italic", 37 | "token": "variable.parameter" 38 | }, 39 | { 40 | "foreground": "ffffff", 41 | "background": "9b9b9b", 42 | "token": "source comment.block" 43 | }, 44 | { 45 | "foreground": "66cc33", 46 | "token": "string" 47 | }, 48 | { 49 | "foreground": "aaaaaa", 50 | "token": "string constant.character.escape" 51 | }, 52 | { 53 | "foreground": "000000", 54 | "background": "cccc33", 55 | "token": "string.interpolated" 56 | }, 57 | { 58 | "foreground": "cccc33", 59 | "token": "string.regexp" 60 | }, 61 | { 62 | "foreground": "cccc33", 63 | "token": "string.literal" 64 | }, 65 | { 66 | "foreground": "555555", 67 | "token": "string.interpolated constant.character.escape" 68 | }, 69 | { 70 | "fontStyle": "underline", 71 | "token": "entity.name.type" 72 | }, 73 | { 74 | "fontStyle": "italic underline", 75 | "token": "entity.other.inherited-class" 76 | }, 77 | { 78 | "fontStyle": "underline", 79 | "token": "entity.name.tag" 80 | }, 81 | { 82 | "foreground": "c83730", 83 | "token": "support.function" 84 | } 85 | ], 86 | "colors": { 87 | "editor.foreground": "#FFFFFF", 88 | "editor.background": "#000000", 89 | "editor.selectionBackground": "#73597EE0", 90 | "editor.lineHighlightBackground": "#333300", 91 | "editorCursor.foreground": "#FFFFFF", 92 | "editorWhitespace.foreground": "#404040" 93 | } 94 | } -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/themes/IDLE.json: -------------------------------------------------------------------------------- 1 | { 2 | "base": "vs", 3 | "inherit": true, 4 | "rules": [ 5 | { 6 | "background": "FFFFFF", 7 | "token": "" 8 | }, 9 | { 10 | "foreground": "919191", 11 | "token": "comment" 12 | }, 13 | { 14 | "foreground": "00a33f", 15 | "token": "string" 16 | }, 17 | { 18 | "foreground": "a535ae", 19 | "token": "constant.language" 20 | }, 21 | { 22 | "foreground": "ff5600", 23 | "token": "keyword" 24 | }, 25 | { 26 | "foreground": "ff5600", 27 | "token": "storage" 28 | }, 29 | { 30 | "foreground": "21439c", 31 | "token": "entity.name.type" 32 | }, 33 | { 34 | "foreground": "21439c", 35 | "token": "entity.name.function" 36 | }, 37 | { 38 | "foreground": "a535ae", 39 | "token": "support.function" 40 | }, 41 | { 42 | "foreground": "a535ae", 43 | "token": "support.constant" 44 | }, 45 | { 46 | "foreground": "a535ae", 47 | "token": "support.type" 48 | }, 49 | { 50 | "foreground": "a535ae", 51 | "token": "support.class" 52 | }, 53 | { 54 | "foreground": "a535ae", 55 | "token": "support.variable" 56 | }, 57 | { 58 | "foreground": "ffffff", 59 | "background": "990000", 60 | "token": "invalid" 61 | }, 62 | { 63 | "foreground": "990000", 64 | "token": "constant.other.placeholder.py" 65 | } 66 | ], 67 | "colors": { 68 | "editor.foreground": "#000000", 69 | "editor.background": "#FFFFFF", 70 | "editor.selectionBackground": "#BAD6FD", 71 | "editor.lineHighlightBackground": "#00000012", 72 | "editorCursor.foreground": "#000000", 73 | "editorWhitespace.foreground": "#BFBFBF" 74 | } 75 | } -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/themes/Nord.json: -------------------------------------------------------------------------------- 1 | { 2 | "base": "vs-dark", 3 | "inherit": true, 4 | "rules": [ 5 | { 6 | "background": "2E3440", 7 | "token": "" 8 | }, 9 | { 10 | "foreground": "616e88", 11 | "token": "comment" 12 | }, 13 | { 14 | "foreground": "a3be8c", 15 | "token": "string" 16 | }, 17 | { 18 | "foreground": "b48ead", 19 | "token": "constant.numeric" 20 | }, 21 | { 22 | "foreground": "81a1c1", 23 | "token": "constant.language" 24 | }, 25 | { 26 | "foreground": "81a1c1", 27 | "token": "keyword" 28 | }, 29 | { 30 | "foreground": "81a1c1", 31 | "token": "storage" 32 | }, 33 | { 34 | "foreground": "81a1c1", 35 | "token": "storage.type" 36 | }, 37 | { 38 | "foreground": "8fbcbb", 39 | "token": "entity.name.class" 40 | }, 41 | { 42 | "foreground": "8fbcbb", 43 | "fontStyle": " bold", 44 | "token": "entity.other.inherited-class" 45 | }, 46 | { 47 | "foreground": "88c0d0", 48 | "token": "entity.name.function" 49 | }, 50 | { 51 | "foreground": "81a1c1", 52 | "token": "entity.name.tag" 53 | }, 54 | { 55 | "foreground": "8fbcbb", 56 | "token": "entity.other.attribute-name" 57 | }, 58 | { 59 | "foreground": "88c0d0", 60 | "token": "support.function" 61 | }, 62 | { 63 | "foreground": "f8f8f0", 64 | "background": "f92672", 65 | "token": "invalid" 66 | }, 67 | { 68 | "foreground": "f8f8f0", 69 | "background": "ae81ff", 70 | "token": "invalid.deprecated" 71 | }, 72 | { 73 | "foreground": "b48ead", 74 | "token": "constant.color.other.rgb-value" 75 | }, 76 | { 77 | "foreground": "ebcb8b", 78 | "token": "constant.character.escape" 79 | }, 80 | { 81 | "foreground": "8fbcbb", 82 | "token": "variable.other.constant" 83 | } 84 | ], 85 | "colors": { 86 | "editor.foreground": "#D8DEE9", 87 | "editor.background": "#2E3440", 88 | "editor.selectionBackground": "#434C5ECC", 89 | "editor.lineHighlightBackground": "#3B4252", 90 | "editorCursor.foreground": "#D8DEE9", 91 | "editorWhitespace.foreground": "#434C5ECC" 92 | } 93 | } -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/themes/Slush and Poppies.json: -------------------------------------------------------------------------------- 1 | { 2 | "base": "vs", 3 | "inherit": true, 4 | "rules": [ 5 | { 6 | "background": "F1F1F1", 7 | "token": "" 8 | }, 9 | { 10 | "foreground": "406040", 11 | "token": "comment" 12 | }, 13 | { 14 | "foreground": "c03030", 15 | "token": "string" 16 | }, 17 | { 18 | "foreground": "0080a0", 19 | "token": "constant.numeric" 20 | }, 21 | { 22 | "fontStyle": "underline", 23 | "token": "source.ocaml constant.numeric.floating-point" 24 | }, 25 | { 26 | "foreground": "800000", 27 | "token": "constant.character" 28 | }, 29 | { 30 | "foreground": "2060a0", 31 | "token": "keyword" 32 | }, 33 | { 34 | "foreground": "2060a0", 35 | "token": "keyword.operator" 36 | }, 37 | { 38 | "fontStyle": "underline", 39 | "token": "source.ocaml keyword.operator.symbol.prefix.floating-point" 40 | }, 41 | { 42 | "fontStyle": "underline", 43 | "token": "source.ocaml keyword.operator.symbol.infix.floating-point" 44 | }, 45 | { 46 | "foreground": "0080ff", 47 | "token": "entity.name.module" 48 | }, 49 | { 50 | "foreground": "0080ff", 51 | "token": "support.other.module" 52 | }, 53 | { 54 | "foreground": "a08000", 55 | "token": "storage.type" 56 | }, 57 | { 58 | "foreground": "008080", 59 | "token": "storage" 60 | }, 61 | { 62 | "foreground": "c08060", 63 | "token": "entity.name.class.variant" 64 | }, 65 | { 66 | "fontStyle": "bold", 67 | "token": "keyword.other.directive" 68 | }, 69 | { 70 | "foreground": "800000", 71 | "token": "entity.name.function" 72 | }, 73 | { 74 | "foreground": "800080", 75 | "token": "storage.type.user-defined" 76 | }, 77 | { 78 | "foreground": "8000c0", 79 | "token": "entity.name.type.class.type" 80 | } 81 | ], 82 | "colors": { 83 | "editor.foreground": "#000000", 84 | "editor.background": "#F1F1F1", 85 | "editor.selectionBackground": "#B0B0FF", 86 | "editor.lineHighlightBackground": "#00000026", 87 | "editorCursor.foreground": "#000000", 88 | "editorWhitespace.foreground": "#BFBFBF" 89 | } 90 | } -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/themes/SpaceCadet.json: -------------------------------------------------------------------------------- 1 | { 2 | "base": "vs-dark", 3 | "inherit": true, 4 | "rules": [ 5 | { 6 | "background": "0D0D0D", 7 | "token": "" 8 | }, 9 | { 10 | "foreground": "473c45", 11 | "token": "comment" 12 | }, 13 | { 14 | "foreground": "805978", 15 | "token": "string" 16 | }, 17 | { 18 | "foreground": "a8885a", 19 | "token": "constant" 20 | }, 21 | { 22 | "foreground": "596380", 23 | "token": "variable.parameter" 24 | }, 25 | { 26 | "foreground": "596380", 27 | "token": "variable.other" 28 | }, 29 | { 30 | "foreground": "728059", 31 | "token": "keyword - keyword.operator" 32 | }, 33 | { 34 | "foreground": "728059", 35 | "token": "keyword.operator.logical" 36 | }, 37 | { 38 | "foreground": "9ebf60", 39 | "token": "storage" 40 | }, 41 | { 42 | "foreground": "6078bf", 43 | "token": "entity" 44 | }, 45 | { 46 | "fontStyle": "italic", 47 | "token": "entity.other.inherited-class" 48 | }, 49 | { 50 | "foreground": "8a4b66", 51 | "token": "support" 52 | }, 53 | { 54 | "foreground": "893062", 55 | "token": "support.type.exception" 56 | }, 57 | { 58 | "background": "5f0047", 59 | "token": "invalid" 60 | }, 61 | { 62 | "background": "371d28", 63 | "token": "meta.function.section" 64 | } 65 | ], 66 | "colors": { 67 | "editor.foreground": "#DDE6CF", 68 | "editor.background": "#0D0D0D", 69 | "editor.selectionBackground": "#40002F", 70 | "editor.lineHighlightBackground": "#00000012", 71 | "editorCursor.foreground": "#7F005D", 72 | "editorWhitespace.foreground": "#BFBFBF" 73 | } 74 | } -------------------------------------------------------------------------------- /packages/@rick-ui/src/Editor/themes/Xcode_default.json: -------------------------------------------------------------------------------- 1 | { 2 | "base": "vs", 3 | "inherit": true, 4 | "rules": [ 5 | { 6 | "background": "FFFFFF", 7 | "token": "" 8 | }, 9 | { 10 | "foreground": "008e00", 11 | "token": "comment" 12 | }, 13 | { 14 | "foreground": "7d4726", 15 | "token": "meta.preprocessor" 16 | }, 17 | { 18 | "foreground": "7d4726", 19 | "token": "keyword.control.import" 20 | }, 21 | { 22 | "foreground": "df0002", 23 | "token": "string" 24 | }, 25 | { 26 | "foreground": "3a00dc", 27 | "token": "constant.numeric" 28 | }, 29 | { 30 | "foreground": "c800a4", 31 | "token": "constant.language" 32 | }, 33 | { 34 | "foreground": "275a5e", 35 | "token": "constant.character" 36 | }, 37 | { 38 | "foreground": "275a5e", 39 | "token": "constant.other" 40 | }, 41 | { 42 | "foreground": "c800a4", 43 | "token": "variable.language" 44 | }, 45 | { 46 | "foreground": "c800a4", 47 | "token": "variable.other" 48 | }, 49 | { 50 | "foreground": "c800a4", 51 | "token": "keyword" 52 | }, 53 | { 54 | "foreground": "c900a4", 55 | "token": "storage" 56 | }, 57 | { 58 | "foreground": "438288", 59 | "token": "entity.name.class" 60 | }, 61 | { 62 | "foreground": "790ead", 63 | "token": "entity.name.tag" 64 | }, 65 | { 66 | "foreground": "450084", 67 | "token": "entity.other.attribute-name" 68 | }, 69 | { 70 | "foreground": "450084", 71 | "token": "support.function" 72 | }, 73 | { 74 | "foreground": "450084", 75 | "token": "support.constant" 76 | }, 77 | { 78 | "foreground": "790ead", 79 | "token": "support.type" 80 | }, 81 | { 82 | "foreground": "790ead", 83 | "token": "support.class" 84 | }, 85 | { 86 | "foreground": "790ead", 87 | "token": "support.other.variable" 88 | } 89 | ], 90 | "colors": { 91 | "editor.foreground": "#000000", 92 | "editor.background": "#FFFFFF", 93 | "editor.selectionBackground": "#B5D5FF", 94 | "editor.lineHighlightBackground": "#00000012", 95 | "editorCursor.foreground": "#000000", 96 | "editorWhitespace.foreground": "#BFBFBF" 97 | } 98 | } -------------------------------------------------------------------------------- /packages/@rick-ui/src/Show/Show.tsx: -------------------------------------------------------------------------------- 1 | import { memoSVC } from '@rickzhou/react-utils'; 2 | import type { FC, ReactNode } from 'react'; 3 | 4 | type Children = (() => ReactNode) | ReactNode; 5 | 6 | export type ShowProps = { 7 | /** 8 | * @description condition 9 | */ 10 | when: boolean; 11 | /** 12 | * @description render when false 13 | */ 14 | fallback?: Children; 15 | /** 16 | * @description render when true 17 | */ 18 | children: Children; 19 | }; 20 | 21 | const render = (children?: Children) => { 22 | if (typeof children === 'function') { 23 | return children(); 24 | } 25 | 26 | return children; 27 | }; 28 | 29 | const Show: FC = memoSVC(({ when, fallback, children }) => { 30 | return <>{when ? render(children) : render(fallback)}; 31 | }); 32 | 33 | export default Show; 34 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Show/demo/basic.tsx: -------------------------------------------------------------------------------- 1 | import { Show } from '@rickzhou/react-ui'; 2 | import { Button, Space } from 'antd'; 3 | import { useState } from 'react'; 4 | 5 | const App = () => { 6 | const [condition, setCondition] = useState(false); 7 | return ( 8 | 9 | 12 | 13 | show 14 | 15 | 16 | ); 17 | }; 18 | 19 | export default App; 20 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Show/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | title: Show 4 | description: condition 5 | --- 6 | 7 | # Show 8 | 9 | Basic 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Show/index.tsx: -------------------------------------------------------------------------------- 1 | import Show from './Show'; 2 | 3 | export type { ShowProps } from './Show'; 4 | 5 | export default Show; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Switch/Switch.tsx: -------------------------------------------------------------------------------- 1 | import { CheckOutlined, CloseOutlined } from '@ant-design/icons'; 2 | import { memoSVC } from '@rickzhou/react-utils'; 3 | import { useState } from 'react'; 4 | import { themeSwitchStyle } from './style'; 5 | 6 | export type SwitchProps = { 7 | className?: string; 8 | disabled?: boolean; 9 | value?: boolean; 10 | onChange?: (value: boolean) => void; 11 | }; 12 | 13 | const Switch = memoSVC( 14 | ({ className = '', disabled, onChange, value }) => { 15 | const [check, setCheck] = useState(value ?? true); 16 | const iconStyles = { 17 | fontSize: '4vw', 18 | opacity: 0, 19 | }; 20 | 21 | return ( 22 |
23 |
24 | 47 |
48 |
49 | ); 50 | }, 51 | ); 52 | 53 | export default Switch; 54 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/Switch/index.tsx: -------------------------------------------------------------------------------- 1 | import Switch from './Switch'; 2 | 3 | export type { SwitchProps } from './Switch'; 4 | 5 | export default Switch; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/aurora/demo/basic.tsx: -------------------------------------------------------------------------------- 1 | import { Aurora } from '@rickzhou/react-ui'; 2 | 3 | const App = () => { 4 | return ; 5 | }; 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/aurora/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | title: Aurora 4 | --- 5 | 6 | # Aurora 7 | 8 | Basic 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/aurora/index.tsx: -------------------------------------------------------------------------------- 1 | import Aurora from './Aurora'; 2 | 3 | export type { AuroraProps } from './Aurora'; 4 | 5 | export default Aurora; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/code-input/CodeInput.tsx: -------------------------------------------------------------------------------- 1 | import { css } from '@emotion/react'; 2 | import { memoSVC } from '@rickzhou/react-utils'; 3 | import { type FC } from 'react'; 4 | import ReactCodeInput, { type ReactCodeInputProps } from 'react-code-input'; 5 | 6 | export type CodeInputProps = { 7 | /** 8 | * @description onComplete callback 9 | */ 10 | onComplete(values: string): void; 11 | /** 12 | * @description verification code length 13 | * @default 4 14 | */ 15 | length: ReactCodeInputProps['fields']; 16 | /** 17 | * @description key 18 | */ 19 | name: ReactCodeInputProps['name']; 20 | }; 21 | 22 | const CodeInput: FC = memoSVC( 23 | ({ onComplete, length, name }) => { 24 | return ( 25 | { 54 | if (values.length === length) { 55 | onComplete(values); 56 | } 57 | }} 58 | /> 59 | ); 60 | }, 61 | ); 62 | 63 | export default CodeInput; 64 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/code-input/demo/basic.tsx: -------------------------------------------------------------------------------- 1 | import { CodeInput } from '@rickzhou/react-ui'; 2 | 3 | const App = () => { 4 | return ( 5 | 6 | ); 7 | }; 8 | 9 | export default App; 10 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/code-input/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | title: CodeInput 4 | description: verification code input component 5 | --- 6 | 7 | # CodeInput 8 | 9 | Basic 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/code-input/index.tsx: -------------------------------------------------------------------------------- 1 | import CodeInput from './CodeInput'; 2 | 3 | export type { CodeInputProps } from './CodeInput'; 4 | 5 | export default CodeInput; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/file-icon/demo/basic.tsx: -------------------------------------------------------------------------------- 1 | import { FileIcon } from '@rickzhou/react-ui'; 2 | import { copyText } from '@rickzhou/react-utils'; 3 | import { Button, Space, Tooltip } from 'antd'; 4 | import { omit } from 'lodash-es'; 5 | 6 | const IconMap = omit(FileIcon, [ 7 | 'getFileIcon', 8 | 'getFileType', 9 | 'getFileLanguage', 10 | ]); 11 | 12 | const App = () => { 13 | return ( 14 | 15 | {Object.entries(IconMap).map(([IconKey, Icon]) => { 16 | return ( 17 | 18 | 41 | 42 | 43 | ); 44 | }); 45 | 46 | export default ThemeSwitch; 47 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/theme-switch/index.tsx: -------------------------------------------------------------------------------- 1 | import ThemeSwitch from './ThemeSwitch'; 2 | 3 | export type { ThemeSwitchProps } from './ThemeSwitch'; 4 | 5 | export default ThemeSwitch; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/theme-wrapper/ThemeWrapper.tsx: -------------------------------------------------------------------------------- 1 | import { type SerializedStyles } from '@emotion/react'; 2 | import { type PropsWithChildren } from 'react'; 3 | import { memoSVC } from '../../../@rick-utils'; 4 | import { useTheme } from '../theme-provider/hooks/useTheme'; 5 | 6 | export type ThemeWrapperProps = PropsWithChildren<{ style?: SerializedStyles }>; 7 | 8 | const ThemeWrapper = memoSVC(({ children, style }) => { 9 | const { theme } = useTheme(); 10 | return ( 11 |
12 | {children} 13 |
14 | ); 15 | }); 16 | 17 | export default ThemeWrapper; 18 | -------------------------------------------------------------------------------- /packages/@rick-ui/src/theme-wrapper/index.tsx: -------------------------------------------------------------------------------- 1 | import ThemeWrapper from './ThemeWrapper'; 2 | 3 | export type { ThemeWrapperProps } from './ThemeWrapper'; 4 | 5 | export default ThemeWrapper; 6 | -------------------------------------------------------------------------------- /packages/@rick-ui/tailwind.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss'; 2 | @source '../@rick-ui/src'; 3 | @plugin '@tailwindcss/typography'; 4 | 5 | @custom-variant dark (&:where(.dark, .dark *)); 6 | 7 | /* Typography plugin */ 8 | @utility prose { 9 | :not(pre) > code { 10 | &::before, 11 | &::after { 12 | display: none; 13 | } 14 | color: var(--color-slate-500); 15 | background-color: var(--color-stone-100); 16 | border-radius: 0.25rem; 17 | padding: 0.25rem; 18 | margin-left: 0.25rem; 19 | margin-right: 0.25rem; 20 | @apply no-scrollbar; 21 | } 22 | } 23 | 24 | @utility no-scrollbar { 25 | /* Hide scrollbar for Chrome, Safari and Opera */ 26 | &::-webkit-scrollbar { 27 | display: none; 28 | } 29 | 30 | /* Hide scrollbar for IE, Edge and Firefox */ 31 | -ms-overflow-style: none; /* IE and Edge */ 32 | scrollbar-width: none; /* Firefox */ 33 | } 34 | -------------------------------------------------------------------------------- /packages/@rick-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "declaration": true, 5 | "skipLibCheck": true, 6 | "esModuleInterop": true, 7 | "jsx": "react-jsx", 8 | "baseUrl": "./", 9 | "types": ["../../type.def.d.ts"], 10 | "jsxImportSource": "@emotion/react", 11 | "paths": { 12 | "@@/*": [".dumi/tmp/*"], 13 | "@root/*": ["./*"], 14 | "@rickzhou/react-ui": ["src"], 15 | "@rickzhou/react-ui/*": ["src/*", "*"] 16 | } 17 | }, 18 | "include": [".dumirc.ts", "src/**/*"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/@rick-utils/browser/copyText.ts: -------------------------------------------------------------------------------- 1 | import { message } from 'antd'; 2 | 3 | export const copyText = async (text: string, showSuccessMsg = true) => { 4 | try { 5 | await navigator.clipboard.writeText(text); 6 | } catch (error) { 7 | console.log('error', error); 8 | const input = document.createElement('input'); 9 | input.style.cssText += `; opacity: 0;`; 10 | document.body.appendChild(input); 11 | input.value = text; 12 | input.select(); 13 | document.execCommand('copy'); 14 | input.remove(); 15 | } 16 | 17 | if (showSuccessMsg) void message.success(`${text} Copied successful!`); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/@rick-utils/common/eventEmitter.ts: -------------------------------------------------------------------------------- 1 | import __EventEmitter__ from 'eventemitter3'; 2 | 3 | export const EventEmitter = new __EventEmitter__(); 4 | -------------------------------------------------------------------------------- /packages/@rick-utils/common/sleep.ts: -------------------------------------------------------------------------------- 1 | export const sleep = async (time: number) => { 2 | await new Promise(resolve => { 3 | setTimeout(() => { 4 | resolve('done'); 5 | }, time); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/@rick-utils/console/Logger.ts: -------------------------------------------------------------------------------- 1 | import { 2 | errorColor, 3 | processingColor, 4 | successColor, 5 | warningColor, 6 | } from '@rickzhou/react-ui'; 7 | 8 | const CONSOLE_STYLE = [ 9 | 'color: #FFF', 10 | 'font-size: 14px', 11 | 'padding: 6px', 12 | 'border-radius:4px', 13 | ]; 14 | 15 | export class Logger { 16 | static success(log: string) { 17 | console.log( 18 | `%c ✅ SUCCESS : ${log}`, 19 | [...CONSOLE_STYLE, `background: ${successColor}`].join(';'), 20 | ); 21 | } 22 | static warning(log: string) { 23 | console.log( 24 | `%c ⚠️ WARNING : ${log}`, 25 | [...CONSOLE_STYLE, `background: ${warningColor}`].join(';'), 26 | ); 27 | } 28 | static error(log: string) { 29 | console.log( 30 | `%c ❌ ERROR : ${log}`, 31 | [...CONSOLE_STYLE, `background: ${errorColor}`].join(';'), 32 | ); 33 | } 34 | static processing(log: string) { 35 | console.log( 36 | `%c ⏳ PROCESSING : ${log}`, 37 | [...CONSOLE_STYLE, `background: ${processingColor}`].join(';'), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/@rick-utils/console/signature.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import figlet from 'figlet'; 3 | 4 | type Params = { 5 | text: string; 6 | output?: boolean; 7 | }; 8 | 9 | export const signature = ({ text, output = true }: Params) => { 10 | return new Promise((resolve, reject) => { 11 | figlet.text( 12 | text, 13 | { 14 | font: 'Larry 3D', // Larry 3D | Larry 3D 2 15 | horizontalLayout: 'fitted', 16 | verticalLayout: 'default', 17 | width: 120, 18 | whitespaceBreak: true, 19 | }, 20 | (err: Error, data: string) => { 21 | if (err) { 22 | reject(err); 23 | } 24 | if (output) { 25 | console.log(chalk.blueBright(data)); 26 | } 27 | resolve(chalk.blueBright(data)); 28 | }, 29 | ); 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /packages/@rick-utils/editor/formatCode.ts: -------------------------------------------------------------------------------- 1 | import { type Options, type ParserOptions } from 'prettier'; 2 | import parseHtmlPlugin from 'prettier/parser-html'; 3 | import parseMdPlugin from 'prettier/parser-markdown'; 4 | import parserTypeScriptPlugin from 'prettier/parser-typescript'; 5 | import prettier from 'prettier/standalone'; 6 | 7 | const prettierConfig: Options = { 8 | tabWidth: 2, 9 | useTabs: false, 10 | singleQuote: true, 11 | semi: true, 12 | bracketSpacing: true, 13 | arrowParens: 'avoid', 14 | trailingComma: 'all', 15 | bracketSameLine: true, 16 | printWidth: 80, 17 | endOfLine: 'lf', 18 | }; 19 | 20 | /** 21 | * @since 1.0.0 22 | */ 23 | export const formatCode = ( 24 | content: string, 25 | parser: ParserOptions['parser'] = 'typescript', 26 | ) => { 27 | return prettier.format(content, { 28 | ...prettierConfig, 29 | parser, 30 | plugins: [parserTypeScriptPlugin, parseHtmlPlugin, parseMdPlugin], 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /packages/@rick-utils/files/parseDir.ts: -------------------------------------------------------------------------------- 1 | import { cloneDeep } from 'lodash-es'; 2 | import { sortFiles } from './sortFiles'; 3 | import { defaultFileTree, type FileObj } from './type'; 4 | 5 | /** 6 | * @description transform dirHandle to FileObj 7 | * @see FileSystemDirectoryHandle 8 | * @see FileObj 9 | */ 10 | export const parseDir = async (dirHandle: FileSystemDirectoryHandle): Promise => { 11 | const fileTree: FileObj['fileTree'] = cloneDeep(defaultFileTree); 12 | const fileSet: FileObj['fileSet'] = {}; 13 | 14 | const buildFileTree = async ( 15 | handle: FileSystemDirectoryHandle | FileSystemFileHandle, 16 | rootDirHandle: FileSystemDirectoryHandle, 17 | fileTree: FileObj['fileTree'], 18 | fileSet: FileObj['fileSet'], 19 | ) => { 20 | if (handle.name === '.DS_Store') return; 21 | const path = (await rootDirHandle.resolve(handle))!.join('/'); 22 | let currentDirectory = fileTree; 23 | const segments = path.split('/'); 24 | for (const segment of segments) { 25 | if (!segment) continue; 26 | let child = currentDirectory.children.find(c => c.title === segment); 27 | if (!child) { 28 | child = { 29 | key: path, 30 | dir: handle.kind === 'directory', 31 | title: segment, 32 | children: [], 33 | }; 34 | currentDirectory.children.push(child); 35 | } 36 | 37 | currentDirectory = child; 38 | } 39 | 40 | if (handle.kind === 'directory') { 41 | for await (const entry of handle.values()) { 42 | await buildFileTree(entry, rootDirHandle, fileTree, fileSet); 43 | } 44 | } 45 | 46 | if (handle.kind === 'file') { 47 | fileSet[currentDirectory.key] = await handle.getFile(); 48 | currentDirectory.dir = false; 49 | currentDirectory.isLeaf = true; 50 | } 51 | }; 52 | 53 | for await (const entry of dirHandle.values()) { 54 | await buildFileTree(entry, dirHandle, fileTree, fileSet); 55 | } 56 | 57 | return { fileTree: sortFiles(fileTree), fileSet }; 58 | }; 59 | -------------------------------------------------------------------------------- /packages/@rick-utils/files/parseFiles.ts: -------------------------------------------------------------------------------- 1 | import { cloneDeep } from 'lodash-es'; 2 | import { sortFiles } from './sortFiles'; 3 | import { defaultFileTree, type FileObj } from './type'; 4 | 5 | /** 6 | * @description transform files to FileObj 7 | * @see FileObj 8 | */ 9 | export const parseFiles = (files: File[]) => { 10 | const fileTree: FileObj['fileTree'] = cloneDeep(defaultFileTree); 11 | const fileSet: FileObj['fileSet'] = {}; 12 | 13 | files.forEach(file => { 14 | fileSet[file.name] = file; 15 | fileTree.children.push({ 16 | key: file.name, 17 | title: file.name, 18 | dir: false, 19 | children: [], 20 | isLeaf: true, 21 | }); 22 | }); 23 | 24 | return { fileTree: sortFiles(fileTree), fileSet }; 25 | }; 26 | -------------------------------------------------------------------------------- /packages/@rick-utils/files/parseZip.ts: -------------------------------------------------------------------------------- 1 | import zip from 'jszip'; 2 | import { cloneDeep } from 'lodash-es'; 3 | import { sortFiles } from './sortFiles'; 4 | import { defaultFileTree, type FileObj, type FilePath } from './type'; 5 | 6 | /** 7 | * @description transform zip file to FileObj 8 | * @see FileObj 9 | */ 10 | export const parseZip = async (file: File): Promise => { 11 | const zipData = await zip.loadAsync(file); 12 | const fileTree: FileObj['fileTree'] = cloneDeep(defaultFileTree); 13 | const fileSet: FileObj['fileSet'] = {}; 14 | 15 | const buildFileTree = async ( 16 | path: FilePath, 17 | file: zip.JSZipObject, 18 | fileTree: FileObj['fileTree'], 19 | fileSet: FileObj['fileSet'], 20 | ) => { 21 | let currentDirectory = fileTree; 22 | const segments = path.split('/'); 23 | for (const segment of segments) { 24 | if (!segment) continue; 25 | let child = currentDirectory.children.find(c => c.title === segment); 26 | if (!child) { 27 | child = { 28 | key: path, 29 | dir: file.dir, 30 | title: segment, 31 | children: [], 32 | }; 33 | currentDirectory.children.push(child); 34 | } 35 | 36 | currentDirectory = child; 37 | } 38 | 39 | if (!file.dir) { 40 | if (file.name.includes('.zip')) { 41 | const zipData = await zip.loadAsync(await file.async('blob')); 42 | zipData.forEach(async (_relativePath, _file) => { 43 | // remove macos extra file 44 | if (!_relativePath.includes('__MACOSX') && !_relativePath.includes('.DS_Store')) { 45 | await buildFileTree(`${file.name}/${_relativePath}`, _file, fileTree, fileSet); 46 | } 47 | }); 48 | } else { 49 | fileSet[currentDirectory.key] = new File([await file.async('arraybuffer')], currentDirectory.title); 50 | currentDirectory.dir = false; 51 | currentDirectory.isLeaf = true; 52 | } 53 | } 54 | }; 55 | 56 | await Promise.all( 57 | Object.entries(zipData.files).map(async ([relativePath, file]) => { 58 | if (!relativePath.startsWith('__MACOSX') && !relativePath.includes('.DS_Store')) { 59 | await buildFileTree(relativePath, file, fileTree, fileSet); 60 | } 61 | }), 62 | ); 63 | 64 | return { fileTree: sortFiles(fileTree), fileSet }; 65 | }; 66 | -------------------------------------------------------------------------------- /packages/@rick-utils/files/sortFiles.ts: -------------------------------------------------------------------------------- 1 | import { type FileTreeTypes } from './type'; 2 | 3 | const compareFileName = (a: FileTreeTypes, b: FileTreeTypes) => { 4 | if (a.dir === b.dir) { 5 | return a.title.localeCompare(b.title); 6 | } 7 | 8 | return a.dir ? -1 : 1; 9 | }; 10 | 11 | /** 12 | * @description sort files by filename 13 | * @see FileTreeTypes 14 | */ 15 | export const sortFiles = (fileTrees: FileTreeTypes) => { 16 | fileTrees.children.sort(compareFileName); 17 | fileTrees.children.forEach(child => { 18 | if (child.children) { 19 | sortFiles(child); 20 | } 21 | }); 22 | return fileTrees; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/@rick-utils/files/type.ts: -------------------------------------------------------------------------------- 1 | export type FilePath = string; 2 | export type FileName = string; 3 | 4 | export type FileObj = { 5 | fileTree: FileTreeTypes; 6 | fileSet: Record; 7 | }; 8 | 9 | export type FileTreeTypes = { 10 | key: FilePath; 11 | title: FileName; 12 | dir: boolean; 13 | isLeaf?: boolean; 14 | children: FileTreeTypes[]; 15 | }; 16 | 17 | export const defaultFileTree: FileTreeTypes = { 18 | key: '', 19 | title: '', 20 | dir: true, 21 | children: [], 22 | }; 23 | -------------------------------------------------------------------------------- /packages/@rick-utils/index.ts: -------------------------------------------------------------------------------- 1 | // React 2 | export { memoSVC } from './react/memo'; 3 | 4 | // Console 5 | export { Logger } from './console/Logger'; 6 | export { signature } from './console/signature'; 7 | 8 | // File 9 | export { parseDir } from './files/parseDir'; 10 | export { parseFiles } from './files/parseFiles'; 11 | export { parseZip } from './files/parseZip'; 12 | export { sortFiles } from './files/sortFiles'; 13 | 14 | // Editor 15 | export { formatCode } from './editor/formatCode'; 16 | 17 | // Json 18 | export { isObjectOrJsonString } from './json/isObjectOrJsonString'; 19 | export { prettyJsonString } from './json/prettyJsonString'; 20 | export { safeJsonParse } from './json/safeJsonParse'; 21 | 22 | // Typescript 23 | export type { MakeKeysOptional } from './typescript/MakeKeysOptional'; 24 | export type { MakeKeysRequired } from './typescript/MakeKeysRequired'; 25 | export type { RecordMapping } from './typescript/RecordMapping'; 26 | 27 | // Browser 28 | export { copyText } from './browser/copyText'; 29 | -------------------------------------------------------------------------------- /packages/@rick-utils/json/isObjectOrJsonString.ts: -------------------------------------------------------------------------------- 1 | import { isObject, isString } from 'lodash-es'; 2 | 3 | export function isObjectOrJsonString(value: any) { 4 | if (isObject(value)) { 5 | return true; 6 | } 7 | 8 | if (isString(value)) { 9 | try { 10 | return isObject(JSON.parse(value)); 11 | } catch (error) { 12 | console.error(error); 13 | return false; 14 | } 15 | } 16 | 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /packages/@rick-utils/json/object.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest'; 2 | import { isObjectOrJsonString } from './isObjectOrJsonString'; 3 | import { safeJsonParse } from './safeJsonParse'; 4 | 5 | test('safeJsonParse()', () => { 6 | const obj = { name: 'rick' }; 7 | expect(safeJsonParse(JSON.stringify(obj))).toEqual(obj); 8 | expect(safeJsonParse(undefined)).toEqual({}); 9 | expect(safeJsonParse(undefined, '')).toEqual(''); 10 | }); 11 | 12 | test('isObjectOrJsonString()', () => { 13 | expect(isObjectOrJsonString(1)).toBe(false); 14 | expect(isObjectOrJsonString('1')).toBe(false); 15 | expect(isObjectOrJsonString('{}')).toBe(true); 16 | expect(isObjectOrJsonString(false)).toBe(false); 17 | expect(isObjectOrJsonString(true)).toBe(false); 18 | expect(isObjectOrJsonString(JSON.stringify({ name: 'rick' }))).toBe(true); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/@rick-utils/json/prettyJsonString.ts: -------------------------------------------------------------------------------- 1 | import { safeJsonParse } from './safeJsonParse'; 2 | 3 | export function prettyJsonString(value: string | object) { 4 | return JSON.stringify(safeJsonParse(value), null, 2); 5 | } 6 | -------------------------------------------------------------------------------- /packages/@rick-utils/json/safeJsonParse.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from 'lodash-es'; 2 | 3 | export function safeJsonParse(value: any, defaultValue = {}) { 4 | if (isObject(value)) { 5 | return value; 6 | } 7 | try { 8 | return JSON.parse(value); 9 | } catch (error) { 10 | console.error(error); 11 | return defaultValue; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/@rick-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rickzhou/react-utils", 3 | "version": "1.0.0", 4 | "private": false, 5 | "description": "React Utils", 6 | "keywords": [ 7 | "React", 8 | "Utils" 9 | ], 10 | "homepage": "https://github.com/rick-chou/one-piece-react#readme", 11 | "author": "rick zhou <944268618@qq.com>", 12 | "contributors": [ 13 | "rick zhou <944268618@qq.com>" 14 | ], 15 | "type": "module", 16 | "main": "index.ts", 17 | "scripts": {}, 18 | "dependencies": { 19 | "eventemitter3": "^5.0.1", 20 | "jszip": "^3.10.1", 21 | "react-fast-compare": "^3.2.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/@rick-utils/react/memo.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ComponentType, 3 | FunctionComponent, 4 | MemoExoticComponent, 5 | NamedExoticComponent, 6 | } from 'react'; 7 | import { memo } from 'react'; 8 | import isEqual from 'react-fast-compare'; 9 | 10 | /** 11 | * @note "SVC" is short for "Shallow-Value-Compare" 12 | */ 13 | export function memoSVC

>( 14 | Component: FunctionComponent

, 15 | ): NamedExoticComponent

; 16 | export function memoSVC>( 17 | Component: T, 18 | ): MemoExoticComponent { 19 | return memo(Component, isEqual); 20 | } 21 | -------------------------------------------------------------------------------- /packages/@rick-utils/typescript/MakeKeysOptional.ts: -------------------------------------------------------------------------------- 1 | export type MakeKeysOptional = Partial> & 2 | Omit; 3 | -------------------------------------------------------------------------------- /packages/@rick-utils/typescript/MakeKeysRequired.ts: -------------------------------------------------------------------------------- 1 | export type MakeKeysRequired = Omit & { 2 | [P in K]-?: T[P]; 3 | }; 4 | -------------------------------------------------------------------------------- /packages/@rick-utils/typescript/RecordMapping.ts: -------------------------------------------------------------------------------- 1 | export type RecordMapping = { 2 | [K in keyof T]: T[K]; 3 | }; 4 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'projects/*' 4 | -------------------------------------------------------------------------------- /prettier.config.cjs: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @see https://prettier.io/docs/en/configuration.html 5 | * @type {import("prettier").Config} 6 | */ 7 | module.exports = { 8 | pluginSearchDirs: false, 9 | plugins: [ 10 | require.resolve('prettier-plugin-organize-imports'), 11 | require.resolve('prettier-plugin-packagejson'), 12 | require.resolve('prettier-plugin-tailwindcss'), 13 | ], 14 | tabWidth: 2, 15 | useTabs: false, 16 | singleQuote: true, 17 | semi: true, 18 | bracketSpacing: true, 19 | arrowParens: 'avoid', 20 | trailingComma: 'all', 21 | bracketSameLine: true, 22 | printWidth: 80, 23 | endOfLine: 'lf', 24 | overrides: [ 25 | { 26 | files: '*.md', 27 | options: { 28 | proseWrap: 'preserve', 29 | }, 30 | }, 31 | ], 32 | }; 33 | -------------------------------------------------------------------------------- /projects/@rick-awesome/.env: -------------------------------------------------------------------------------- 1 | RICK_AUTHOR=Rick.Zhou 2 | RICK_GITHUB=https://github.com/rick-chou 3 | RICK_JUEJIN=https://juejin.cn/user/1574156383563496 4 | RICK_ISSUE=https://github.com/rick-chou/one-piece-react/issues/new 5 | RICK_AVATAR=https://cdn.jsdelivr.net/gh/rick-chou/rick-assets/png/2.png 6 | 7 | # CONFIG 8 | RICK_REDUX_LOGGER=false 9 | -------------------------------------------------------------------------------- /projects/@rick-awesome/.eslintignore: -------------------------------------------------------------------------------- 1 | flipdown.ts 2 | style.ts 3 | -------------------------------------------------------------------------------- /projects/@rick-awesome/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/projects/@rick-awesome/README.md -------------------------------------------------------------------------------- /projects/@rick-awesome/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | %RICK_AUTHOR%'s Blog 🚀 18 | 19 | 20 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 |

33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /projects/@rick-awesome/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rickzhou/blog", 3 | "version": "3.0.0", 4 | "private": true, 5 | "description": "Rick.Zhou's Blog 🚀", 6 | "keywords": [ 7 | "RICK.ZHOU", 8 | "BLOG", 9 | "FE", 10 | "UI", 11 | "REACT", 12 | "VUE" 13 | ], 14 | "homepage": "https://github.com/rick-chou/react-awesome/", 15 | "author": "Rick.Zhou", 16 | "type": "module", 17 | "scripts": { 18 | "//": "小心使用 不确定大版本是否有breakchange", 19 | "build": "tsc && vite build", 20 | "dev": "vite", 21 | "preview": "tsc && vite build --mode=preview && vite preview --mode=preview", 22 | "update": "npx ncu \\!vue* -u" 23 | }, 24 | "dependencies": { 25 | "@emotion/react": "^11.11.1", 26 | "@mdx-js/react": "^2.3.0", 27 | "@mdx-js/rollup": "^2.3.0", 28 | "acorn": "^8.10.0", 29 | "chance": "^1.1.11", 30 | "mdx-mermaid": "^2.0.0", 31 | "mermaid": "^10.5.1", 32 | "mscgenjs": "^6.0.2", 33 | "react-pdf": "^9.2.1", 34 | "react-router-dom": "^6.17.0", 35 | "react-transition-group": "^4.4.5", 36 | "rehype-highlight": "^6.0.0", 37 | "rehype-mdx-code-props": "^1.0.0", 38 | "remark-frontmatter": "^3.0.0", 39 | "remark-gfm": "^3.0.1", 40 | "remark-mdx-frontmatter": "^3.0.0", 41 | "vue2": "npm:vue@^2.7.14", 42 | "vue3": "npm:vue@^3.3.4", 43 | "vueCompiler2": "npm:@vue/compiler-sfc@^2.7.14", 44 | "vueCompiler3": "npm:@vue/compiler-sfc@^3.3.4", 45 | "web-vitals": "^3.5.0" 46 | }, 47 | "devDependencies": { 48 | "@types/chance": "^1.1.5", 49 | "@types/dagre": "^0.7.51", 50 | "@types/react-transition-group": "^4.4.8", 51 | "@vitejs/plugin-vue": "^4.4.0", 52 | "@vitejs/plugin-vue2": "^2.2.0" 53 | }, 54 | "overrides": { 55 | "@vitejs/plugin-vue2": { 56 | "vue": "^3.3.4" 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /projects/@rick-awesome/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/projects/@rick-awesome/public/favicon.ico -------------------------------------------------------------------------------- /projects/@rick-awesome/public/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/projects/@rick-awesome/public/icon-192.png -------------------------------------------------------------------------------- /projects/@rick-awesome/public/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/projects/@rick-awesome/public/icon-512.png -------------------------------------------------------------------------------- /projects/@rick-awesome/public/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/projects/@rick-awesome/public/icon-64.png -------------------------------------------------------------------------------- /projects/@rick-awesome/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rick-chou/one-piece-react/1443e84616e926f49656946e0cd4090e29cd6f7c/projects/@rick-awesome/public/icon.png -------------------------------------------------------------------------------- /projects/@rick-awesome/src/app/index.tsx: -------------------------------------------------------------------------------- 1 | import Blog from '@rickzhou/awesome/blog/layout'; 2 | import CmdModal from '@rickzhou/awesome/components/commands'; 3 | import { ThemeProvider } from '@rickzhou/react-ui'; 4 | import { App as AppWrapper } from 'antd'; 5 | import { ScrollRestoration } from 'react-router-dom'; 6 | 7 | export const App = () => { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/app/repl/index.tsx: -------------------------------------------------------------------------------- 1 | const Repl = () => { 2 | return ( 3 |
4 | 12 | ); 13 | }; 14 | 15 | export default Codesandbox; 16 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/components/sequence-chart/index.tsx: -------------------------------------------------------------------------------- 1 | import { uniqueId } from 'lodash-es'; 2 | import { renderMsc } from 'mscgenjs'; 3 | import { useEffect, useRef } from 'react'; 4 | 5 | const SequenceChart: React.FC<{ 6 | msc: string; 7 | onClick: (key: string) => void; 8 | }> = ({ msc, onClick }) => { 9 | const id = useRef(uniqueId('msc_sequence_diagram_')); 10 | 11 | const bindEvents = (event: MouseEvent) => { 12 | event.preventDefault(); 13 | const path = event.composedPath(); 14 | for (const i in path) { 15 | const link = path[i] as HTMLElement; 16 | if ('getAttribute' in link && link.getAttribute('xlink:title')) { 17 | const key = link.getAttribute('xlink:title'); 18 | if (key) { 19 | onClick(key); 20 | } 21 | 22 | break; 23 | } 24 | } 25 | }; 26 | 27 | useEffect(() => { 28 | const elementId = id.current; 29 | 30 | if (msc) { 31 | document.getElementById(elementId)!.innerHTML = ''; 32 | renderMsc( 33 | msc, 34 | { 35 | additionalTemplate: 'fountainpen', 36 | mirrorEntitiesOnBottom: true, 37 | elementId, 38 | styleAdditions: 'backfround: red', 39 | }, 40 | handleRenderMscResult, 41 | ); 42 | } 43 | 44 | return () => { 45 | document 46 | .getElementById(elementId) 47 | ?.removeEventListener('click', bindEvents); 48 | }; 49 | }, [msc]); 50 | 51 | function handleRenderMscResult(pError: Error, pSuccess: string) { 52 | if (pError) { 53 | console.error(pError); 54 | return; 55 | } 56 | 57 | if (pSuccess) { 58 | document 59 | .getElementById(id.current) 60 | ?.addEventListener('click', bindEvents); 61 | return; 62 | } 63 | 64 | console.log('Wat! Error nor success?'); 65 | } 66 | 67 | return
; 68 | }; 69 | 70 | export default SequenceChart; 71 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/README.mdx: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | 3 |

ONE PIECE

4 | 5 |

6 | 11 | 12 | Abandon all the past and bonds, don't begrudge the tears shed for the dream 13 |
- Luffy. 14 |
15 |
16 |

17 | 18 |

19 | 20 | Blog 21 | 22 | 23 | 24 | JueJin 25 | 26 |

27 | 28 |

29 | 33 | 37 | 41 | 45 | 49 | 53 |

54 | 55 |
56 | 57 | ## 🌈 Time Machine 58 | 59 | ### 2021 60 | 61 | - [x] Graduation! 🥂 🧱 👷🏿‍♂️ 62 | - [x] Vue2 Developer 😀 63 | - [x] React Developer 😍 64 | 65 | ### 2022 66 | 67 | - [x] React Native Developer 😅 68 | 69 | ### 2023 70 | 71 | - [x] Angular2.0+ Developer 🤔 72 | - [x] React Developer 😅 73 | - [x] Learn Java 😎 74 | - [x] Get married 🥰 75 | 76 | ### 2024 77 | 78 | - [x] Our little one has arrived! 🍼🧑‍🍼👩‍🍼 79 | 80 | ![bg](https://cdn.jsdelivr.net/gh/rick-chou/rick-assets/jpg/43.jpg) 81 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/angular/directive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Angular Quick Start - Directive 3 | --- 4 | 5 | Directive 用来修饰 DOM 给它添加额外的行为 6 | 7 | > Angular 内置指令 https://angular.cn/guide/built-in-directives 8 | 9 | 例如 开发中常用的 `*ngFor` 就是一个指令 用来遍历渲染 DOM 元素 10 | 11 | 可以参考下面的 Link 我为这些指令都编写了用例 12 | 13 | > https://rick-chou.github.io/angular-tutorial/basic-syntax/directive 14 | 15 | 这里我主要介绍一下如何自定义一个自己的指令 16 | 17 | 举个例子 我们希望鼠标移入/移出的时候 DOM 背景色有切换 18 | 19 | ```html 20 | 21 |

Highlight me!

22 | 23 |

Highlight me!

24 | ``` 25 | 26 | 下面 我们来实现这个例子 27 | 28 | ```ts 29 | import { Directive, ElementRef, HostListener, Input } from '@angular/core'; 30 | 31 | // Directive装饰器 可以接收一个对象参数 但是现在我们还不需要 32 | @Directive() 33 | export class HighlightDirective { 34 | // 给这个指定定义一个 highlight 属性 35 | @Input() highlight = 'yellow'; 36 | 37 | // 这里的 el 就是被我们的指令直接修饰的那个dom 38 | constructor(private el: ElementRef) { 39 | // 你可以在这里直接操作 dom 40 | } 41 | 42 | // 给这个dom定义一个mouseenter的监听器 后面的名字可以自定定义 43 | @HostListener('mouseenter') 44 | onMouseEnter() { 45 | this.highlight(this.highlight); 46 | } 47 | 48 | // 添加鼠标移出的监听器 绑定对应的事件逻辑 49 | @HostListener('mouseleave') 50 | onMouseLeave() { 51 | this.highlight(''); 52 | } 53 | 54 | private highlight(color: string) { 55 | this.el.nativeElement.style.backgroundColor = color; 56 | } 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/angular/rxjs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Angular Quick Start - Rxjs 3 | --- 4 | 5 | 因为 Angular2.0 是构建在 Rxjs 之上的 6 | 7 | 所以在介绍 Angular 具体用法之前 很有必要先介绍一下 Rxjs 的简单使用 8 | 9 | 下面列出了一些你可以具体学习 Rxjs 的 Reference link 10 | 11 | > https://reactive.how/ 12 | 13 | > https://www.learnrxjs.io/ 14 | 15 | > https://rxjs.dev/ 16 | 17 | Rxjs 的官网介绍了很多概念 例如 18 | 19 | - Observable 20 | - Observer 21 | - Subscription 22 | - Operators 23 | - Subject 24 | - Schedulers 25 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/javascript/debounce-throttle.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript - debounce & throttle 3 | --- 4 | 5 | ## 函数防抖 6 | 7 | ```js 8 | /* 9 | 函数防抖:一个频繁触发的函数,在规定时间内,只让函数最后一次触发 例如: 10 | 11 | - 用户输入搜索框 避免每次敲击键盘都发送请求 12 | - 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求 13 | - 调整浏览器窗口大小时,resize 次数过于频繁 14 | 15 | 思路:关键在于清零 例如登录按钮点击一秒后发送登录请求 我们就可以创建一个定时器 每次用户点击的时候都清除这个定时器 让定时器重置 16 | 这样就保证了这一秒内不会因为用户都频繁点击而一直发送请求 代码如下 17 | */ 18 | 19 | /** 20 | * 防抖函数 21 | * @param fn 要执行的函数 22 | * @param delay 延迟的时间 23 | */ 24 | function debounce(fn, delay) { 25 | var timer = null; 26 | return function () { 27 | clearTimeout(timer); 28 | timer = setTimeout(() => { 29 | fn.call(this); 30 | }, delay); 31 | }; 32 | } 33 | ``` 34 | 35 | ## 函数节流 36 | 37 | ```js 38 | /* 39 | 函数节流:一个函数执行一次后,只有大于设定的执行周期才会执行第二次 40 | 适用场景:有一个频繁触发的函数,在规定时间内,只让函数触发一次 优化性能 例如 41 | 42 | - scroll时间 每隔1s重新计算位置 而不是一直计算 43 | - 浏览器播放时间 每隔1s重新计算一次播放进度 44 | 45 | 思路:需要两个时间 lastTime 和 nowTime 来计算时间差 由此来判断是否执行事件 46 | 先将lastTime初始化为0 然后获取系统时间 做差判断是否大于delay 如果大于则执行事件并将nowTime赋予lastTime 由此完成节流 47 | */ 48 | 49 | /** 50 | * 节流函数 51 | * @param fn 要执行的函数 52 | * @param delay 延迟的时间 53 | */ 54 | function throttle(fn, delay) { 55 | var lastTime = 0; 56 | return function () { 57 | var nowTime = Date.now(); 58 | if (nowTime - lastTime > delay) { 59 | fn.call(this); 60 | lastTime = nowTime; 61 | } 62 | }; 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/javascript/design-patterns-singleton.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript - design-patterns-singleton 3 | --- 4 | 5 | 单例模式的定义是: 保证一个类有且仅有一个实例,并提供一个访问它的全局访问点。 6 | 7 | 思路: 用闭包返回一个实例 对这个实例做条件判断 有就返回 没有就初始化 这样我们在每次 new 的时候就只能得到一个实例 8 | 9 | 例如 全局的蒙层 全局的变量都适合用单例模式来创建 因为我们谁也不希望存在两个蒙层 10 | 11 | ```js 12 | const Singleton = (function () { 13 | let instance = null; 14 | 15 | return function (name, age) { 16 | if (instance) { 17 | return instance; 18 | } 19 | 20 | this.name = name; 21 | this.age = age; 22 | 23 | return (instance = this); 24 | }; 25 | })(); 26 | 27 | // test 28 | const a = new Singleton('rick', 18); 29 | const b = new Singleton('rick', 18); 30 | 31 | console.log(a === b); // true 32 | console.log(a); // { name: 'rick', age: 18 } 33 | ``` 34 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/javascript/file-upload.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript - file upload 3 | --- 4 | 5 | ## TODO 6 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/javascript/how-equality-operator-work.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript - equality operator 3 | --- 4 | 5 | 首先,== 的定义是: 6 | 7 | 8 | 9 | GetValue 会获取一个子表达式的值(消除掉左值引用),在表达式 [] == ![] 中,[] 的结果就是一个空数组的引用,而 ![] 就有意思了,它会按照 11.4.9 和 9.2 节的要求得到 false。比较的行为在 11.9.3 节里,所以翻到 11.9.3: 10 | 11 | 12 | 13 | 在这段算法里,和 `[] == ![]`匹配的是条件 7,所以会递归地调用 `[] == ToNumber(false)` 进行比较。 14 | 15 | 在 9.3 节中定义了 ToNumber 原语,ToNumber(false) 等于 0,于是比较变为 `[] == 0`。 16 | 17 | 在此处因为 [] 是对象,比较过程走分支 9,依 `ToPrimitive([]) == 0` 比较。 18 | 19 | ToPrimitive 默认是调用 toString 方法的(依 8.2.8),于是 ToPrimitice([]) 等于空字符串。 20 | 21 | 结果,`[] == ![]` 的比较最后落到了 `''==false` 上, 22 | 23 | 按照 11.9.3 中的定义会依分支 5 比较 `ToNumber('')==0` ToNumber('') 依 9.3.1 等于 0,所以结果为 true。 24 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/javascript/prototype.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript - prototype 3 | --- 4 | 5 | 在 ES2019 中 对于 prototype 的定义为 6 | 7 | > 给其它对象提供共享属性的对象 8 | 9 | 看完后 突然想到了一句话 Vue 中一切组件继承自 Vue 的原型 10 | 11 | 这也解释了为什么在每个组件中都可以直接使用 Vue 的一些方法 因为这些方法被写在了 Vue 的原型上 12 | 13 | 原型对象被创建时,会自动生成一个 `constructor` 属性,指向创建它的构造函数 14 | 15 | 构造函数的`prototype`指向原型对象 16 | 17 | 实例对象的`__proto__`指向原型对象 18 | 19 | (注)如果在 MDN 上查阅`__proto__`这一属性 你可以看到 20 | 21 | > 已废弃 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。 22 | > 23 | > 警告: 通过现代浏览器的操作属性的便利性,可以改变一个对象的 \[\[Prototype\]\] 属性, 这种行为在每一个 JavaScript 引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.**proto** = ... 语句上, 它还会影响到所有继承来自该 \[\[Prototype\]\] 的对象,如果你关心性能,你就不应该在一个对象中修改它的 \[\[Prototype\]\]。相反, 创建一个新的且可以继承 \[\[Prototype\]\] 的对象,推荐使用 Object.create\(\)。 24 | > 25 | > 警告: 当 Object.prototype.**proto** 已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在 ECMAScript 2015 规范中被标准化为传统功能,以确保 Web 浏览器的兼容性。为了更好的支持,建议只使用 Object.getPrototypeOf\(\)。 26 | 27 | 官网说的很明白 如果还不理解 看完下面原型链的作用 你应该就明白了 28 | 29 | 这一部分 看着比较绕 但是理解后 对我们还是很有帮助的 比如原型链的作用 30 | 31 | **原型链的作用:** 原型链如此的重要的原因就在于它决定了 `JavaScript` 中继承的实现方式。 32 | 33 | 当我们访问一个属性时,查找机制如下: 34 | 35 | - 访问对象实例属性,有则返回,没有就通过 `__proto__` 去它的原型对象查找。 36 | - 原型对象上找到即返回,找不到,继续通过原型对象的 `__proto__` 查找。 37 | - 一层一层一直找到 `Object.prototype` ,如果找到目标属性即返回, 38 | 39 | 找不到就返回 `undefined`,不会再往下找,因为在往下找 `__proto__` 就是 `null` 了。 40 | 41 | 所以 如果我们用`Object.prototype`去操作了 Object 的原型对象 那么所有的对象都会受到影响 因为 Object 是对象的顶级父类 所有的对象都继承自它们的顶级父类 Object 42 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/network/http-referer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Network - http header referer 3 | --- 4 | 5 | ## 背景 6 | 7 | 前段日子 在自学做项目的时候发现 明明在项目中引用了线上存在的图片 但是在自己的项目中却怎么也显示出来 8 | 9 | 查阅资料后发现是这些第三方网站设置了**防盗链** 10 | 11 | ## 破解防盗链 12 | 13 | 先说说防盗链的原理,http 协议中,如果从一个网页跳到另一个网页,http 头字段里面会带个 Referer。 14 | 15 | 这里的 Referer 是由于历史原因导致了拼写错误 后来也就一直沿用。 16 | 17 | 图片服务器通过检测 Referer 是否来自规定域名,来进行防盗链。 18 | 19 | 如果盗用网站是 https 的 protocol,而图片链接是 http 的话, 20 | 21 | 则从 https 向 http 发起的请求会因为安全性的规定,而不带 referer,从而实现防盗链的绕过。 22 | 23 | 官方输出图片的时候,判断了来源(Referer),就是从哪个网站访问这个图片, 24 | 25 | 如果是你的网站去加载这个图片,那么 Referer 就是:你的网站地址; 26 | 27 | 你网站地址,肯定没在官方的白名单内,所以就看不到图片了。 28 | 29 | 因此,若不发送 Referer,也就是没有来源。那么官方那边,就认为是从浏览器直接访问的,所以就能加载正常的图片了。 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | 比如在掘金上 查看我的一篇文章中一张图片的 Request Headers 就可以看到 Referer 36 | 37 | referer 38 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/others/cors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CORS 3 | --- 4 | 5 | > https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS 6 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/others/git-branch-manager.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Git branch manager 3 | --- 4 | 5 | > http://matrixzk.github.io/blog/20141104/git-flow-model/ 6 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/others/github-actions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Github actions 3 | --- 4 | 5 | > https://docs.github.com/cn/actions/quickstart 6 | 7 | ```yml 8 | # 当前 workflow 的名称 9 | name: Frontend Weekly 10 | 11 | # 指定 workflow 触发的 event 12 | on: 13 | push: 14 | branches: 15 | - main 16 | 17 | # 一个 workflow 由一个或多个 job 组成 18 | jobs: 19 | # job id: 是 job 的唯一标识 20 | build_and_deploy: 21 | # 在 Github 中显示的 job 名称 22 | name: Build and Deploy 23 | # job 运行的环境配置 24 | runs-on: ubuntu-latest 25 | # 一个 job 由多个 step 组成 26 | steps: 27 | # 当前 step 的名字 28 | - name: Checkout 29 | # checkout action 主要用于向 github 仓库拉取源代码 30 | # https://github.com/actions/checkout 31 | uses: actions/checkout@v2 32 | with: 33 | ref: main 34 | - name: Cache 35 | # cache 在这里主要用于缓存 npm,提升构建速率 36 | # https://github.com/actions/cache 37 | uses: actions/cache@v2 38 | # npm 缓存的路径可查看 https://docs.npmjs.com/cli/cache#cache 39 | # 由于这里 runs-on 是 ubuntu-latest,因此配置 ~/.npm 40 | with: 41 | path: ~/.npm 42 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 43 | restore-keys: | 44 | ${{ runner.os }}-node- 45 | - name: Use Node.js 46 | # 配置 Node 执行环境(当前构建的服务器默认没有 Node 环境,可以通过 Action 安装 Node) 47 | # https://github.com/actions/setup-node 48 | uses: actions/setup-node@v1 49 | with: 50 | node-version: 14 51 | - name: Build 52 | # 安装 Node 之后就可以执行构建脚本 53 | run: | 54 | npm install yarn -g 55 | yarn 56 | yarn build 57 | - name: Deploy 58 | # 将构建产物 commit 到一个分支上,用于发布静态站点资源 59 | # https://github.com/peaceiris/actions-gh-pages 60 | uses: peaceiris/actions-gh-pages@v3 61 | with: 62 | # Github 会在 workflow 中自动生成 GIHUBT_TOKEN,用于认证 workflow 的运行 63 | github_token: ${{ secrets.GITHUB_TOKEN }} 64 | # 静态资源目录设置 65 | publish_dir: ./build 66 | # 默认发布到 gh-pages 分支上,可以指定特定的发布分支(不能选拉取代码的分支) 67 | publish_branch: gh-pages 68 | full_commit_message: ${{ github.event.head_commit.message }} 69 | ``` 70 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/others/single-page-app-github-refresh-404.md: -------------------------------------------------------------------------------- 1 | ## 背景 2 | 3 | 单页应用部署在 `Github Pages` 后 刷新 404 4 | 5 | ## 解决 6 | 7 | `Github Pages` 在找不到页面的情况下 会默认去加载 `404.html` 利用这个特性 8 | 9 | 我们可以拷贝一份打包后的 `index.html` 重命名成 `404.html` 即可 10 | 11 | 例如在 `build` 后执行命令 `cp dist/index.html dist/404.html` 12 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/react/mobx.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: React Quick Start - Mobx 3 | --- 4 | 5 | ## TODO 施工中 👷‍♀️ 6 | 7 | > EN https://mobx.js.org/README.html 8 | 9 | > CN https://www.mobxjs.com/ 10 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/react/redux-toolkit.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: React Quick Start - Redux Toolkit 3 | --- 4 | 5 | > EN https://redux-toolkit.js.org/ 6 | 7 | 8 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/content/react/ssr.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: React Quick Start - SSR 3 | --- 4 | 5 | ## TODO 施工中 👷‍♀️ 6 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/layout/content/index.tsx: -------------------------------------------------------------------------------- 1 | import { routes } from '@rickzhou/awesome/router'; 2 | import { useEffect, useRef } from 'react'; 3 | import { 4 | matchRoutes, 5 | useLocation, 6 | useNavigation, 7 | useOutlet, 8 | } from 'react-router-dom'; 9 | import { CSSTransition, SwitchTransition } from 'react-transition-group'; 10 | import { animationDelay, mainContainerStyle } from '../style'; 11 | 12 | const Content = () => { 13 | const location = useLocation(); 14 | const currentRoute = matchRoutes(routes, location)?.at(-1)?.route; 15 | const ref = useRef(null); 16 | const currentOutlet = useOutlet(currentRoute?.path); 17 | const navigation = useNavigation(); 18 | 19 | useEffect(() => { 20 | if (navigation.state === 'idle') { 21 | setTimeout(() => { 22 | ref.current?.scrollTo(0, 0); 23 | }, 300); 24 | } 25 | }, [navigation.state]); 26 | 27 | return ( 28 |
29 | 30 | 36 | {() =>
{currentOutlet}
} 37 |
38 |
39 |
40 | ); 41 | }; 42 | 43 | export default Content; 44 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/layout/header/index.tsx: -------------------------------------------------------------------------------- 1 | import { GithubOutlined } from '@ant-design/icons'; 2 | import { css } from '@emotion/react'; 3 | import { Hotkey } from '@rickzhou/awesome/config/shortcut'; 4 | import { 5 | OpenTypeConfig, 6 | useModalOpen, 7 | } from '@rickzhou/awesome/store/useModalOpenConfigModel'; 8 | import { ThemeSwitch } from '@rickzhou/react-ui'; 9 | import { Divider } from 'antd'; 10 | import { 11 | headerStyle, 12 | searchBarStyle, 13 | userImgStyle, 14 | userNameStyle, 15 | userStyle, 16 | } from '../style'; 17 | 18 | const Header = () => { 19 | const { onShow } = useModalOpen(OpenTypeConfig.CommandOpen); 20 | 21 | return ( 22 |
23 |
24 | 30 |
31 |
32 | 33 | 34 |
35 |
{import.meta.env.RICK_AUTHOR}
36 |
37 | 38 | 42 | 43 | window.open(import.meta.env.RICK_GITHUB)} 46 | /> 47 | 48 | 49 |
50 |
51 | ); 52 | }; 53 | 54 | export default Header; 55 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/layout/homepage.tsx: -------------------------------------------------------------------------------- 1 | import Article from '@rickzhou/awesome/blog/components/article'; 2 | import Blog from '@rickzhou/awesome/blog/content/README.mdx'; 3 | import README from '../../../README.md'; 4 | 5 | const Homepage = () => { 6 | return ( 7 |
8 | 9 | 10 |
11 | ); 12 | }; 13 | 14 | export default Homepage; 15 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/layout/index.tsx: -------------------------------------------------------------------------------- 1 | import { useShortKey } from '@rickzhou/awesome/hooks/useShortkey'; 2 | import { useLocation } from 'react-router-dom'; 3 | import Content from './content'; 4 | import Header from './header'; 5 | import Homepage from './homepage'; 6 | import Sidebar from './sidebar'; 7 | import { containerStyle } from './style'; 8 | 9 | const Blog = () => { 10 | const location = useLocation(); 11 | 12 | useShortKey(); 13 | 14 | const renderContent = () => { 15 | if (location.pathname === import.meta.env.BASE_URL) { 16 | return ( 17 |
18 | 19 |
20 | ); 21 | } 22 | 23 | return ; 24 | }; 25 | 26 | return ( 27 |
28 | 29 |
30 |
31 | {renderContent()} 32 |
33 |
34 | ); 35 | }; 36 | 37 | export default Blog; 38 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/layout/sidebar/index.tsx: -------------------------------------------------------------------------------- 1 | import { metaData } from '@rickzhou/awesome/router/meta-data'; 2 | import { genRandomSvg } from '@rickzhou/awesome/utils'; 3 | import { isEmpty, startCase, upperCase } from 'lodash-es'; 4 | import { memo } from 'react'; 5 | import { Link } from 'react-router-dom'; 6 | import { 7 | logoStyle, 8 | sideMenuStyle, 9 | sideTitleStyle, 10 | sideWrapperStyle, 11 | sidebarStyle, 12 | } from '../style'; 13 | 14 | const SideBar = () => { 15 | return ( 16 |
17 | 18 | @{import.meta.env.RICK_AUTHOR} 19 | 20 | {!isEmpty(metaData) && 21 | Object.entries(metaData) 22 | .reverse() 23 | .map(([key, value]) => { 24 | return ( 25 |
26 |
{upperCase(key)}
27 |
28 | {value.map(i => ( 29 | 30 |
33 | {startCase(i.name)} 34 | 35 | ))} 36 |
37 |
38 | ); 39 | })} 40 |
41 | ); 42 | }; 43 | 44 | export default memo(SideBar); 45 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/blog/plugins/inject-import.ts: -------------------------------------------------------------------------------- 1 | import * as acorn from 'acorn'; 2 | 3 | const impCodesanbox = 4 | "import Codesandbox from '@rickzhou/awesome/blog/components/codesandbox'"; 5 | 6 | const impCodepen = 7 | "import Codepen from '@rickzhou/awesome/blog/components/codepen'"; 8 | 9 | export default function retextSentenceSpacing() { 10 | return (tree: any, file: any) => { 11 | tree.children.unshift( 12 | { 13 | type: 'mdxjsEsm', 14 | value: impCodesanbox, 15 | data: { 16 | estree: acorn.parse(impCodesanbox, { 17 | ecmaVersion: 2020, 18 | sourceType: 'module', 19 | }), 20 | }, 21 | }, 22 | { 23 | type: 'mdxjsEsm', 24 | value: impCodepen, 25 | data: { 26 | estree: acorn.parse(impCodepen, { 27 | ecmaVersion: 2020, 28 | sourceType: 'module', 29 | }), 30 | }, 31 | }, 32 | ); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/components/background/index.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Background = styled.div` 4 | position: fixed; 5 | top: 0; 6 | left: 0; 7 | height: 100vh; 8 | width: 100vw; 9 | `; 10 | 11 | export default Background; 12 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/components/commands/style.ts: -------------------------------------------------------------------------------- 1 | import { css } from '@emotion/react'; 2 | import { type CommandItemTypes } from '.'; 3 | 4 | export const CommandModalContainer = css({ 5 | paddingTop: '1rem', 6 | paddingBottom: '0.5rem', 7 | }); 8 | 9 | export const CommandModalInputStyle = css({ 10 | backgroundColor: 'transparent', 11 | border: 'none', 12 | outline: 'none', 13 | color: '#e5e5e5', 14 | width: '100%', 15 | fontSize: '16px', 16 | lineHeight: 1, 17 | padding: '16px', 18 | marginLeft: '1rem', 19 | marginRight: '1rem', 20 | }); 21 | 22 | export const CommandModalInputDividerWrapperStyle = css({ 23 | paddingLeft: '16px', 24 | paddingRight: '16px', 25 | marginBottom: '4px', 26 | }); 27 | 28 | export const CommandModalInputDividerStyle = css({ 29 | backgroundcolor: '#e5e5e514', 30 | height: '1px', 31 | border: 'none', 32 | }); 33 | 34 | export const CommandItemTitleStyle = css({ 35 | color: 'rgb(128, 128, 128)', 36 | fontSize: '12px', 37 | fontWeight: 700, 38 | paddingTop: '8px', 39 | paddingBottom: '8px', 40 | userSelect: 'none', 41 | paddingLeft: '16px', 42 | marginLeft: '1rem', 43 | textTransform: 'uppercase', 44 | }); 45 | 46 | export const CommandListStyle = css({ 47 | height: '24rem', 48 | maxHeight: '24rem', 49 | overflowY: 'scroll', 50 | }); 51 | 52 | export const CommandItemStyle = (i?: CommandItemTypes) => { 53 | return css({ 54 | color: 'var(--color-primary-text)', 55 | fontSize: '13px', 56 | fontFamily: i?.type === 'font' ? i.title : 'inherit', 57 | height: '36px', 58 | paddingTop: '8px', 59 | paddingBottom: '8px', 60 | userSelect: 'none', 61 | paddingLeft: '24px', 62 | cursor: 'pointer', 63 | marginLeft: '1rem', 64 | marginRight: '1rem', 65 | textTransform: 'uppercase', 66 | '&.hover': { 67 | backgroundColor: 'var(--color-primary-bg-hover)', 68 | borderRadius: '4px', 69 | }, 70 | }); 71 | }; 72 | 73 | export const CommandHotkeyStyle = css({ 74 | borderRadius: '4px', 75 | padding: '4px', 76 | lineHeight: 1, 77 | margin: '0px', 78 | height: '20px', 79 | minWidth: '20px', 80 | display: 'flex', 81 | alignItems: 'center', 82 | justifyContent: 'center', 83 | textTransform: 'uppercase', 84 | backgroundColor: '#e5e5e51a', 85 | fontSize: '12px', 86 | color: '#e5e5e5', 87 | userSelect: 'none', 88 | }); 89 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/components/error-page/index.tsx: -------------------------------------------------------------------------------- 1 | import { Editor, FuzzyText } from '@rickzhou/react-ui'; 2 | import { Space } from 'antd'; 3 | import { useRouteError } from 'react-router-dom'; 4 | 5 | const ErrorPage = () => { 6 | const error = useRouteError() as Error; 7 | return ( 8 |
9 | 10 | 🤖 ERROR 11 | 12 | 13 |
14 | ); 15 | }; 16 | 17 | export default ErrorPage; 18 | -------------------------------------------------------------------------------- /projects/@rick-awesome/src/components/iframe/index.tsx: -------------------------------------------------------------------------------- 1 | import { ContentWrapper } from '@rickzhou/awesome/theme/content-wrapper'; 2 | import { type FC } from 'react'; 3 | 4 | type IframeProps = { 5 | path: string; 6 | }; 7 | 8 | const Iframe: FC = ({ path }) => { 9 | return ( 10 | 11 |
12 |