├── .editorconfig ├── .eslintrc.json ├── .github ├── dependabot.yml └── workflows │ └── ci-cd.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .storybook ├── main.js └── tsconfig.json ├── .vscode └── extensions.json ├── README.md ├── TODO.md ├── __tests__ └── fileMock.js ├── apps ├── .gitkeep ├── nextjs-app-e2e │ ├── .eslintrc.json │ ├── cypress.json │ ├── project.json │ ├── src │ │ ├── fixtures │ │ │ └── example.json │ │ ├── integration │ │ │ └── app.spec.ts │ │ └── support │ │ │ ├── app.po.ts │ │ │ ├── commands.ts │ │ │ └── index.ts │ └── tsconfig.json ├── nextjs-app │ ├── .analyze.env │ ├── .auto-changelog │ ├── .babelrc │ ├── .env │ ├── .eslintrc.json │ ├── .qa.env │ ├── .release-it.json │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── components │ │ ├── layout.tsx │ │ └── seo.tsx │ ├── index.d.ts │ ├── jest.config.ts │ ├── libs │ │ └── env.ts │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.tsx │ │ ├── _document.tsx │ │ ├── api │ │ │ └── healthz.tsx │ │ ├── index.tsx │ │ └── styles.css │ ├── project.json │ ├── public │ │ ├── .gitkeep │ │ ├── assets │ │ │ └── storybook.png │ │ ├── favicons │ │ │ ├── android-icon-144x144.png │ │ │ ├── android-icon-192x192.png │ │ │ ├── android-icon-36x36.png │ │ │ ├── android-icon-48x48.png │ │ │ ├── android-icon-72x72.png │ │ │ ├── android-icon-96x96.png │ │ │ ├── apple-icon-114x114.png │ │ │ ├── apple-icon-120x120.png │ │ │ ├── apple-icon-144x144.png │ │ │ ├── apple-icon-152x152.png │ │ │ ├── apple-icon-180x180.png │ │ │ ├── apple-icon-57x57.png │ │ │ ├── apple-icon-60x60.png │ │ │ ├── apple-icon-72x72.png │ │ │ ├── apple-icon-76x76.png │ │ │ ├── apple-icon-precomposed.png │ │ │ ├── apple-icon.png │ │ │ ├── browserconfig.xml │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.png │ │ │ ├── favicon.ico │ │ │ ├── favicon.svg │ │ │ ├── manifest.json │ │ │ ├── ms-icon-144x144.png │ │ │ ├── ms-icon-150x150.png │ │ │ ├── ms-icon-310x310.png │ │ │ └── ms-icon-70x70.png │ │ └── images │ │ │ └── large-og.png │ ├── specs │ │ └── index.spec.tsx │ ├── tsconfig.json │ └── tsconfig.spec.json ├── rn-app-e2e │ ├── .babelrc │ ├── .detoxrc.json │ ├── .eslintrc.json │ ├── environment.js │ ├── jest.config.json │ ├── project.json │ ├── src │ │ └── app.spec.ts │ ├── test-setup.ts │ ├── tsconfig.e2e.json │ └── tsconfig.json ├── rn-app │ ├── .dev.env │ ├── .env │ ├── .eslintrc.json │ ├── android │ │ ├── app │ │ │ ├── _BUCK │ │ │ ├── build.gradle │ │ │ ├── build_defs.bzl │ │ │ ├── debug.keystore │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidTest │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── rnapp │ │ │ │ │ └── DetoxTest.java │ │ │ │ ├── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── rnapp │ │ │ │ │ └── ReactNativeFlipper.java │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── rnapp │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── MainApplication.java │ │ │ │ │ └── newarchitecture │ │ │ │ │ ├── MainApplicationReactNativeHost.java │ │ │ │ │ ├── components │ │ │ │ │ └── MainComponentsRegistry.java │ │ │ │ │ └── modules │ │ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java │ │ │ │ ├── jni │ │ │ │ ├── Android.mk │ │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ │ ├── MainApplicationModuleProvider.h │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ │ ├── MainComponentsRegistry.cpp │ │ │ │ ├── MainComponentsRegistry.h │ │ │ │ └── OnLoad.cpp │ │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ │ └── xml │ │ │ │ └── network_security_config.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── app.json │ ├── assets │ │ └── storybook.png │ ├── babel.config.json │ ├── ios │ │ ├── Podfile │ │ ├── Podfile.lock │ │ ├── RnApp.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── RnApp.xcscheme │ │ ├── RnApp.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── RnApp │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.mm │ │ │ ├── Images.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Info.plist │ │ │ ├── LaunchScreen.storyboard │ │ │ └── main.m │ │ └── RnAppTests │ │ │ ├── Info.plist │ │ │ └── RnAppTests.m │ ├── jest.config.ts │ ├── metro.config.js │ ├── package.json │ ├── project.json │ ├── src │ │ ├── app │ │ │ ├── App.tsx │ │ │ └── icons │ │ │ │ ├── blog.svg │ │ │ │ ├── book.svg │ │ │ │ ├── checkmark.svg │ │ │ │ ├── chevron-right.svg │ │ │ │ ├── courses.svg │ │ │ │ ├── github.svg │ │ │ │ ├── heart.svg │ │ │ │ ├── logo.png │ │ │ │ ├── nx-cloud.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── terminal.svg │ │ │ │ ├── vscode.svg │ │ │ │ └── youtube.svg │ │ ├── libs │ │ │ └── env.ts │ │ └── main.tsx │ ├── test-setup.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── standalone-nextjs-app-e2e │ ├── .eslintrc.json │ ├── cypress.json │ ├── project.json │ ├── src │ │ ├── fixtures │ │ │ └── example.json │ │ ├── integration │ │ │ └── app.spec.ts │ │ └── support │ │ │ ├── app.po.ts │ │ │ ├── commands.ts │ │ │ └── index.ts │ └── tsconfig.json └── standalone-nextjs-app │ ├── .babelrc │ ├── .env │ ├── .eslintrc.json │ ├── .qa.env │ ├── Dockerfile │ ├── components │ ├── layout.tsx │ └── seo.tsx │ ├── generated │ ├── .gitkeep │ └── data.ts │ ├── index.d.ts │ ├── jest.config.ts │ ├── libs │ └── env.ts │ ├── main.ts │ ├── next-env.d.ts │ ├── next.config.js │ ├── pages │ ├── _app.tsx │ ├── _document.tsx │ ├── api │ │ └── healthz.tsx │ ├── index.tsx │ └── styles.css │ ├── project.json │ ├── public │ ├── .gitkeep │ ├── favicons │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-icon-114x114.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-144x144.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-180x180.png │ │ ├── apple-icon-57x57.png │ │ ├── apple-icon-60x60.png │ │ ├── apple-icon-72x72.png │ │ ├── apple-icon-76x76.png │ │ ├── apple-icon-precomposed.png │ │ ├── apple-icon.png │ │ ├── browserconfig.xml │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── favicon.svg │ │ ├── manifest.json │ │ ├── ms-icon-144x144.png │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ └── ms-icon-70x70.png │ └── images │ │ └── large-og.png │ ├── server.ts │ ├── specs │ └── index.spec.tsx │ ├── tsconfig.json │ ├── tsconfig.server.json │ └── tsconfig.spec.json ├── babel.config.json ├── jest.config.base.js ├── jest.config.ts ├── jest.preset.js ├── libs ├── .gitkeep ├── features │ ├── .gitkeep │ └── todo │ │ ├── .babelrc │ │ ├── .eslintrc.json │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── components │ │ │ ├── index.tsx │ │ │ └── todo-item │ │ │ │ ├── todo-item.spec.tsx │ │ │ │ ├── todo-item.stories.tsx │ │ │ │ └── todo-item.tsx │ │ │ ├── index.tsx │ │ │ ├── interfaces │ │ │ ├── index.ts │ │ │ └── todo.ts │ │ │ └── stores │ │ │ ├── index.tsx │ │ │ └── use-todo-store.tsx │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json ├── images │ ├── .babelrc │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── images.spec.tsx │ │ │ ├── images.tsx │ │ │ └── public │ │ │ └── assets │ │ │ └── storybook.png │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json ├── sdk │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── sdk.spec.ts │ │ │ └── sdk.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json └── shared │ ├── apis │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── custom-api.ts │ │ │ ├── healthz.ts │ │ │ └── request-api.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json │ ├── hooks │ ├── .babelrc │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── use-debounced-callback │ │ │ ├── use-debounced-callback.spec.ts │ │ │ └── use-debounced-callback.ts │ │ │ └── use-timer │ │ │ ├── use-timer.spec.ts │ │ │ └── use-timer.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json │ ├── libs │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── analytics.ts │ │ │ ├── error.ts │ │ │ ├── remote-config.ts │ │ │ └── storage.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json │ ├── stores │ ├── .babelrc │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ └── use-toast-store.tsx │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json │ ├── ui-components │ ├── .babelrc │ ├── .eslintrc.json │ ├── .storybook │ │ ├── main.js │ │ ├── preview.js │ │ └── tsconfig.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.tsx │ │ └── lib │ │ │ ├── image │ │ │ ├── image.spec.tsx │ │ │ ├── image.stories.tsx │ │ │ └── image.tsx │ │ │ ├── others │ │ │ ├── index.tsx │ │ │ └── seo │ │ │ │ ├── seo.spec.tsx │ │ │ │ └── seo.tsx │ │ │ ├── styles │ │ │ ├── colors.ts │ │ │ └── z-index.ts │ │ │ ├── text │ │ │ ├── text.spec.tsx │ │ │ ├── text.stories.tsx │ │ │ └── text.tsx │ │ │ ├── typography │ │ │ ├── typography.spec.tsx │ │ │ ├── typography.stories.tsx │ │ │ └── typography.tsx │ │ │ └── xeicon │ │ │ ├── xeicon.spec.tsx │ │ │ ├── xeicon.stories.tsx │ │ │ └── xeicon.tsx │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json │ └── utils │ ├── .babelrc │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ ├── index.ts │ └── lib │ │ ├── __tests__ │ │ ├── common.test.ts │ │ ├── string.test.ts │ │ └── uri.test.ts │ │ ├── common.ts │ │ ├── json.ts │ │ ├── object.ts │ │ ├── string.ts │ │ └── uri.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json ├── migrations.json ├── nx.json ├── package-lock.json ├── package.json ├── plopfile.mjs ├── tools ├── generators │ ├── .gitkeep │ ├── plop-templates │ │ └── ui-components │ │ │ ├── component.spec.txt │ │ │ ├── component.stories.txt │ │ │ ├── component.txt │ │ │ └── plopfile.mjs │ └── utils │ │ └── index.mjs └── tsconfig.tools.json ├── tsconfig.base.json ├── types └── global.d.ts ├── workspace.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "ignorePatterns": ["**/*"], 4 | "plugins": ["@nrwl/nx", "unused-imports"], 5 | "overrides": [ 6 | { 7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 8 | "rules": { 9 | "no-unused-vars": "off", 10 | "@typescript-eslint/no-unused-vars": "off", 11 | "unused-imports/no-unused-imports": "error", 12 | "unused-imports/no-unused-vars": [ 13 | "warn", 14 | { 15 | "vars": "all", 16 | "varsIgnorePattern": "^_", 17 | "args": "after-used", 18 | "argsIgnorePattern": "^_" 19 | } 20 | ], 21 | "@nrwl/nx/enforce-module-boundaries": [ 22 | "error", 23 | { 24 | "enforceBuildableLibDependency": true, 25 | "allow": [], 26 | "depConstraints": [ 27 | { 28 | "sourceTag": "*", 29 | "onlyDependOnLibsWithTags": ["*"] 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | }, 36 | { 37 | "files": ["*.ts", "*.tsx"], 38 | "extends": ["plugin:@nrwl/nx/typescript"], 39 | "rules": {} 40 | }, 41 | { 42 | "files": ["*.js", "*.jsx"], 43 | "extends": ["plugin:@nrwl/nx/javascript"], 44 | "rules": {} 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | 36 | # System Files 37 | .DS_Store 38 | Thumbs.db 39 | 40 | # React Native 41 | 42 | ## Xcode 43 | 44 | **/ios/**/build/ 45 | **/ios/**/*.pbxuser 46 | ios/.xcode.env.local 47 | !default.pbxuser 48 | *.mode1v3 49 | !default.mode1v3 50 | *.mode2v3 51 | !default.mode2v3 52 | *.perspectivev3 53 | !default.perspectivev3 54 | xcuserdata 55 | *.xccheckout 56 | *.moved-aside 57 | DerivedData 58 | *.hmap 59 | *.ipa 60 | *.xcuserstate 61 | 62 | ## Android 63 | 64 | **/android/**/build/ 65 | **/android/**/.gradle 66 | **/android/**/local.properties 67 | **/android/**/*.iml 68 | 69 | ## BUCK 70 | 71 | buck-out/ 72 | \.buckd/ 73 | *.keystore 74 | !debug.keystore 75 | 76 | ## fastlane 77 | # 78 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 79 | # screenshots whenever they are needed. 80 | # For more information about the recommended setup visit: 81 | # https://docs.fastlane.tools/best-practices/source-control/ 82 | # 83 | */fastlane/report.xml 84 | */fastlane/Preview.html 85 | */fastlane/screenshots 86 | **/fastlane/test_output 87 | 88 | ## Bundle artifact 89 | *.jsbundle 90 | 91 | ## CocoaPods 92 | **/ios/Pods/ 93 | / 94 | 95 | apps/rn-app-e2e/artifacts 96 | apps/rn-app-2-e2e/artifacts 97 | apps/rn-app-e2e/artifacts 98 | 99 | # Next.js 100 | .next 101 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.15.1 -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: [], 3 | addons: ['@storybook/addon-essentials'], 4 | typescript: { reactDocgen: false }, 5 | // uncomment the property below if you want to apply some webpack config globally 6 | // webpackFinal: async (config, { configType }) => { 7 | // // Make whatever fine-grained changes you need that should apply to all storybook configs 8 | 9 | // // Return the altered config 10 | // return config; 11 | // }, 12 | }; 13 | -------------------------------------------------------------------------------- /.storybook/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "exclude": [ 4 | "../**/*.spec.js", 5 | "../**/*.test.js", 6 | "../**/*.spec.ts", 7 | "../**/*.test.ts", 8 | "../**/*.spec.tsx", 9 | "../**/*.test.tsx", 10 | "../**/*.spec.jsx", 11 | "../**/*.test.jsx" 12 | ], 13 | "include": ["../**/*"] 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "nrwl.angular-console", 4 | "esbenp.prettier-vscode", 5 | "firsttris.vscode-jest-runner", 6 | "dbaeumer.vscode-eslint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # Todo 2 | 3 | - 🐶 Husky & Lint Staged — Run scripts on your staged files before they are committed 4 | - 🤖 Conventional Commit Lint — Make sure you & your teammates follow conventional commit 5 | - ⏰ Standard Version Changelog — Generate your changelog using npm run release 6 | - Refactoring Components 7 | - Default Components 8 | - Button, Header, Image ... 9 | - setup font-family 10 | - React Native Jest 설정 11 | 12 | ### Examine 13 | 14 | - 💎 Pre-built Components — Components that will **automatically adapt** with your brand color, [check here for the demo](https://tsnext-tw.thcl.dev/components) 15 | - 🚘 Automatic Branch and Issue Autolink — Branch will be automatically created on issue **assign**, and auto linked on PR 16 | - 👀 Default Open Graph — Awesome open graph generated using [og](https://github.com/theodorusclarence/og), fork it and deploy! 17 | - 🗺 Site Map — Automatically generate sitemap.xml 18 | -------------------------------------------------------------------------------- /__tests__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = ''; 2 | -------------------------------------------------------------------------------- /apps/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/.gitkeep -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["src/plugins/index.js"], 11 | "rules": { 12 | "@typescript-eslint/no-var-requires": "off", 13 | "no-undef": "off" 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileServerFolder": ".", 3 | "fixturesFolder": "./src/fixtures", 4 | "integrationFolder": "./src/integration", 5 | "modifyObstructiveCode": false, 6 | "supportFile": "./src/support/index.ts", 7 | "pluginsFile": false, 8 | "video": true, 9 | "videosFolder": "../../dist/cypress/apps/nextjs-app-e2e/videos", 10 | "screenshotsFolder": "../../dist/cypress/apps/nextjs-app-e2e/screenshots", 11 | "chromeWebSecurity": false 12 | } 13 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-app-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "apps/nextjs-app-e2e/src", 5 | "projectType": "application", 6 | "targets": { 7 | "e2e": { 8 | "executor": "@nrwl/cypress:cypress", 9 | "options": { 10 | "cypressConfig": "apps/nextjs-app-e2e/cypress.json", 11 | "devServerTarget": "nextjs-app:serve" 12 | }, 13 | "configurations": { 14 | "production": { 15 | "devServerTarget": "nextjs-app:serve:production" 16 | } 17 | } 18 | }, 19 | "lint": { 20 | "executor": "@nrwl/linter:eslint", 21 | "outputs": ["{options.outputFile}"], 22 | "options": { 23 | "lintFilePatterns": ["apps/nextjs-app-e2e/**/*.{js,ts}"] 24 | }, 25 | "configurations": { 26 | "fix": { 27 | "fix": true 28 | } 29 | } 30 | } 31 | }, 32 | "tags": [], 33 | "implicitDependencies": ["nextjs-app"] 34 | } 35 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/src/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io" 4 | } 5 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/src/integration/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { getGreeting } from '../support/app.po'; 2 | 3 | describe('nx-react-code-sharing', () => { 4 | beforeEach(() => cy.visit('/')); 5 | 6 | it('should display welcome message', () => { 7 | // Custom command example, see `../support/commands.ts` file 8 | cy.login('my-email@something.com', 'myPassword'); 9 | 10 | // Function helper example, see `../support/app.po.ts` file 11 | getGreeting().contains('Welcome nx-react-code-sharing'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/src/support/app.po.ts: -------------------------------------------------------------------------------- 1 | export const getGreeting = () => cy.get('h1'); 2 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/src/support/commands.ts: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-namespace 12 | declare namespace Cypress { 13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 14 | interface Chainable { 15 | login(email: string, password: string): void; 16 | } 17 | } 18 | // 19 | // -- This is a parent command -- 20 | Cypress.Commands.add('login', (email, password) => { 21 | console.log('Custom command example: Login', email, password); 22 | }); 23 | // 24 | // -- This is a child command -- 25 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 26 | // 27 | // 28 | // -- This is a dual command -- 29 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 30 | // 31 | // 32 | // -- This will overwrite an existing command -- 33 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 34 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/src/support/index.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands'; 18 | -------------------------------------------------------------------------------- /apps/nextjs-app-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "outDir": "../../dist/out-tsc", 6 | "allowJs": true, 7 | "types": ["cypress", "node"] 8 | }, 9 | "include": ["src/**/*.ts", "src/**/*.js"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/nextjs-app/.analyze.env: -------------------------------------------------------------------------------- 1 | API_URL=https://example.com/ 2 | ANALYZE=true -------------------------------------------------------------------------------- /apps/nextjs-app/.auto-changelog: -------------------------------------------------------------------------------- 1 | { 2 | "output": "CHANGELOG.md", 3 | "template": "keepachangelog", 4 | "unreleased": true, 5 | "commitLimit": false, 6 | "ignoreCommitPattern": "^\\[app\\][\\s\\S]*" 7 | } 8 | -------------------------------------------------------------------------------- /apps/nextjs-app/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": [ 4 | ["react-native-web", { "commonjs": true }], 5 | [ 6 | "module-resolver", 7 | { 8 | "alias": { 9 | "^react-native$": "react-native-web" 10 | } 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /apps/nextjs-app/.env: -------------------------------------------------------------------------------- 1 | API_URL=https://example.com/ -------------------------------------------------------------------------------- /apps/nextjs-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:@nrwl/nx/react-typescript", 4 | "../../.eslintrc.json", 5 | "next", 6 | "next/core-web-vitals" 7 | ], 8 | "ignorePatterns": ["!**/*"], 9 | "overrides": [ 10 | { 11 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 12 | "rules": { 13 | "@next/next/no-html-link-for-pages": [ 14 | "error", 15 | "apps/nx-react-code-sharing/pages" 16 | ] 17 | } 18 | }, 19 | { 20 | "files": ["*.ts", "*.tsx"], 21 | "rules": {} 22 | }, 23 | { 24 | "files": ["*.js", "*.jsx"], 25 | "rules": {} 26 | } 27 | ], 28 | "env": { 29 | "jest": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /apps/nextjs-app/.qa.env: -------------------------------------------------------------------------------- 1 | API_URL=https://example.com/qa -------------------------------------------------------------------------------- /apps/nextjs-app/.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "commit": true, 4 | "commitMessage": "chore(Release): v${version}", 5 | "requireUpstream": false, 6 | "requireCleanWorkingDir": true, 7 | "tag": true, 8 | "tagName": "v%s-nextjs-app", 9 | "push": false 10 | }, 11 | "npm": { 12 | "publish": false 13 | }, 14 | "github": { 15 | "release": false, 16 | "releaseName": "nextjs-app %s Released!", 17 | "draft": true 18 | }, 19 | "hooks": { 20 | "after:release": "echo Successfully released ${name} v${version} to ${repo.repository}.\n" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /apps/nextjs-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14.17.1-alpine3.11 2 | 3 | WORKDIR /app 4 | COPY ./dist/apps/nextjs-app . 5 | 6 | ENV PORT 3000 7 | 8 | RUN npm install --production 9 | 10 | EXPOSE 3000 11 | 12 | CMD ["node_modules/.bin/next", "start"] 13 | -------------------------------------------------------------------------------- /apps/nextjs-app/components/layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SEO, { SEOProps } from './seo'; 3 | 4 | interface LayoutProps { 5 | seoProps?: SEOProps; 6 | children: React.ReactNode; 7 | } 8 | 9 | export default function Layout(props: LayoutProps) { 10 | const { seoProps, children } = props; 11 | return ( 12 | <> 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/nextjs-app/components/seo.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | import { useRouter } from 'next/router'; 3 | import { 4 | SEO as SharedSEO, 5 | SEOProps as SharedSEOProps, 6 | } from '@nx-react-code-sharing/shared-ui-components'; 7 | 8 | // eslint-disable-next-line @typescript-eslint/no-empty-interface 9 | export interface SEOProps extends SharedSEOProps {} 10 | 11 | export default function SEO(props: SEOProps) { 12 | const router = useRouter(); 13 | 14 | return ( 15 | 16 | 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /apps/nextjs-app/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | declare module '*.svg' { 3 | const content: any; 4 | export const ReactComponent: any; 5 | export default content; 6 | } 7 | -------------------------------------------------------------------------------- /apps/nextjs-app/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'nextjs-app', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest', 7 | '^.+\\.[tj]sx?$': [ 8 | 'babel-jest', 9 | { presets: ['@nrwl/next/babel'], babelrc: false }, 10 | ], 11 | }, 12 | moduleNameMapper: { 13 | '^react-native$': 'react-native-web', 14 | }, 15 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 16 | coverageDirectory: '../../coverage/apps/nextjs-app', 17 | }; 18 | -------------------------------------------------------------------------------- /apps/nextjs-app/libs/env.ts: -------------------------------------------------------------------------------- 1 | import getConfig from 'next/config'; 2 | 3 | const { publicRuntimeConfig } = getConfig() ?? { 4 | serverRuntimeConfig: {}, 5 | publicRuntimeConfig: {}, 6 | }; 7 | const { 8 | API_URL, 9 | }: { 10 | API_URL: string; 11 | } = publicRuntimeConfig; 12 | 13 | export const env = { 14 | API_URL, 15 | }; 16 | -------------------------------------------------------------------------------- /apps/nextjs-app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /apps/nextjs-app/next.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const withNx = require('@nrwl/next/plugins/with-nx'); 3 | 4 | const { API_URL, ANALYZE } = process.env; 5 | const withBundleAnalyzer = require('@next/bundle-analyzer')({ 6 | enabled: ANALYZE === 'true', 7 | }); 8 | 9 | /** 10 | * @type {import('@nrwl/next/plugins/with-nx').WithNxOptions} 11 | **/ 12 | const nextConfig = { 13 | swcMinify: false, 14 | nx: { 15 | // Set this to true if you would like to to use SVGR 16 | // See: https://github.com/gregberge/svgr 17 | svgr: false, 18 | }, 19 | publicRuntimeConfig: { 20 | API_URL, 21 | }, 22 | webpack(config) { 23 | return { 24 | ...config, 25 | optimization: { 26 | ...config.optimization, 27 | providedExports: true, 28 | sideEffects: 'flag', 29 | }, 30 | }; 31 | }, 32 | }; 33 | 34 | module.exports = withBundleAnalyzer(withNx(nextConfig)); 35 | -------------------------------------------------------------------------------- /apps/nextjs-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-app", 3 | "version": "0.0.2", 4 | "type": "commonjs" 5 | } 6 | -------------------------------------------------------------------------------- /apps/nextjs-app/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { AppProps } from 'next/app'; 2 | import Head from 'next/head'; 3 | import './styles.css'; 4 | 5 | function CustomApp({ Component, pageProps }: AppProps) { 6 | return ( 7 | <> 8 | 9 | Welcome to nx-react-code-sharing! 10 | 11 |
12 | 13 |
14 | 15 | ); 16 | } 17 | 18 | export default CustomApp; 19 | -------------------------------------------------------------------------------- /apps/nextjs-app/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Document, { Html, Head, Main, NextScript } from 'next/document'; 3 | 4 | class MyDocument extends Document { 5 | public render() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | ); 22 | } 23 | } 24 | 25 | export default MyDocument; 26 | -------------------------------------------------------------------------------- /apps/nextjs-app/pages/api/healthz.tsx: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from 'next'; 2 | 3 | export const handler = async (req: NextApiRequest, res: NextApiResponse) => { 4 | res.statusCode = 200; 5 | res.setHeader('Content-Type', 'application/json'); 6 | res.end(JSON.stringify({ status: 'ok' })); 7 | }; 8 | 9 | export default handler; -------------------------------------------------------------------------------- /apps/nextjs-app/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { customAPI } from '@nx-react-code-sharing/shared-apis'; 2 | import { Bold, Image } from '@nx-react-code-sharing/shared-ui-components'; 3 | import { 4 | todosByOrderDESCSelector, 5 | useTodoStore, 6 | } from '@nx-react-code-sharing/features-todo'; 7 | import { useEffect } from 'react'; 8 | import { env } from '../libs/env'; 9 | import Layout from '../components/layout'; 10 | import { getImages } from '@nx-react-code-sharing/images'; 11 | 12 | export function Index() { 13 | const todos = useTodoStore(todosByOrderDESCSelector); 14 | 15 | useEffect(() => { 16 | const fetchTest = async () => { 17 | const testData = await customAPI<{ 18 | status: string; 19 | }>({ 20 | url: '/api/healthz', 21 | }); 22 | console.log(testData); 23 | }; 24 | fetchTest(); 25 | }, []); 26 | 27 | return ( 28 | 29 |
30 |
31 |
32 | 33 | Hello there, 34 | Welcome nx-react-code-sharing 👋 Todo List (API_URL={env.API_URL}) 35 | 36 | storybook 44 |
    45 | {todos.map((todo) => ( 46 |
  • {todo.name}
  • 47 | ))} 48 |
49 |
50 |
51 |
52 |
53 | ); 54 | } 55 | 56 | export default Index; 57 | -------------------------------------------------------------------------------- /apps/nextjs-app/pages/styles.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-text-size-adjust: 100%; 3 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 4 | Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, 5 | Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; 6 | line-height: 1.5; 7 | tab-size: 4; 8 | scroll-behavior: smooth; 9 | } 10 | body { 11 | font-family: inherit; 12 | line-height: inherit; 13 | margin: 0; 14 | } 15 | -------------------------------------------------------------------------------- /apps/nextjs-app/public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/.gitkeep -------------------------------------------------------------------------------- /apps/nextjs-app/public/assets/storybook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/assets/storybook.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/android-icon-144x144.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/android-icon-192x192.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/android-icon-36x36.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/android-icon-48x48.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/android-icon-72x72.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/android-icon-96x96.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-114x114.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-120x120.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-144x144.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-152x152.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-180x180.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-57x57.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-60x60.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-72x72.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-76x76.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon-precomposed.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/apple-icon.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/favicon.ico -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/ms-icon-144x144.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/ms-icon-150x150.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/ms-icon-310x310.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/favicons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/favicons/ms-icon-70x70.png -------------------------------------------------------------------------------- /apps/nextjs-app/public/images/large-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/nextjs-app/public/images/large-og.png -------------------------------------------------------------------------------- /apps/nextjs-app/specs/index.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | 4 | describe('Index', () => { 5 | it('should render successfully', () => { 6 | const { baseElement } = render(
); 7 | expect(baseElement).toBeTruthy(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /apps/nextjs-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "types": ["node", "jest"], 9 | "strict": false, 10 | "forceConsistentCasingInFileNames": true, 11 | "noEmit": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "incremental": true 15 | }, 16 | "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts"], 17 | "exclude": [ 18 | "**/*.spec.ts", 19 | "**/*.test.ts", 20 | "**/*.spec.tsx", 21 | "**/*.test.tsx", 22 | "**/*.spec.js", 23 | "**/*.test.js", 24 | "**/*.spec.jsx", 25 | "**/*.test.jsx", 26 | "**/*.stories.ts", 27 | "**/*.stories.js", 28 | "**/*.stories.jsx", 29 | "**/*.stories.tsx", 30 | "node_modules", 31 | "jest.config.ts" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /apps/nextjs-app/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "jsx": "react" 8 | }, 9 | "include": [ 10 | "**/*.test.ts", 11 | "**/*.spec.ts", 12 | "**/*.test.tsx", 13 | "**/*.spec.tsx", 14 | "**/*.test.js", 15 | "**/*.spec.js", 16 | "**/*.test.jsx", 17 | "**/*.spec.jsx", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@nrwl/react/babel", 5 | { 6 | "runtime": "automatic" 7 | } 8 | ] 9 | ], 10 | "plugins": [] 11 | } 12 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/environment.js: -------------------------------------------------------------------------------- 1 | const { 2 | DetoxCircusEnvironment, 3 | SpecReporter, 4 | WorkerAssignReporter, 5 | } = require('detox/runners/jest-circus'); 6 | 7 | class CustomDetoxEnvironment extends DetoxCircusEnvironment { 8 | constructor(config, context) { 9 | super(config, context); 10 | 11 | // Can be safely removed, if you are content with the default value (=300000ms) 12 | this.initTimeout = 300000; 13 | 14 | // This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level. 15 | // This is strictly optional. 16 | this.registerListeners({ 17 | SpecReporter, 18 | WorkerAssignReporter, 19 | }); 20 | } 21 | } 22 | 23 | module.exports = CustomDetoxEnvironment; 24 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "../../jest.preset", 3 | "testEnvironment": "./environment", 4 | "testRunner": "jest-circus/runner", 5 | "testTimeout": 120000, 6 | "reporters": ["detox/runners/jest/streamlineReporter"], 7 | "setupFilesAfterEnv": ["/test-setup.ts"], 8 | "transform": { 9 | "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nrwl/react/plugins/jest", 10 | "^.+\\.[tj]sx?$": "babel-jest" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/src/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { device, element, by, expect } from 'detox'; 2 | 3 | describe('RnApp', () => { 4 | beforeEach(async () => { 5 | await device.reloadReactNative(); 6 | }); 7 | 8 | it('should display welcome message', async () => { 9 | await expect(element(by.id('heading'))).toHaveText('Welcome RnApp 👋'); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/test-setup.ts: -------------------------------------------------------------------------------- 1 | import { device } from 'detox'; 2 | 3 | beforeAll(async () => { 4 | await device.launchApp(); 5 | }); 6 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "outDir": "../../dist/out-tsc", 6 | "allowJs": true, 7 | "types": ["node", "jest", "detox"] 8 | }, 9 | "include": ["src/**/*.ts", "src/**/*.js"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/rn-app-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.e2e.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /apps/rn-app/.dev.env: -------------------------------------------------------------------------------- 1 | API_URL=http://example.com -------------------------------------------------------------------------------- /apps/rn-app/.env: -------------------------------------------------------------------------------- 1 | API_URL=http://example.com -------------------------------------------------------------------------------- /apps/rn-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*", "public", ".cache", "node_modules"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": { 8 | "@typescript-eslint/ban-ts-comment": "off" 9 | } 10 | }, 11 | { 12 | "files": ["*.ts", "*.tsx"], 13 | "rules": {} 14 | }, 15 | { 16 | "files": ["*.js", "*.jsx"], 17 | "rules": {} 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/_BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.rnapp", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.rnapp", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/debug.keystore -------------------------------------------------------------------------------- /apps/rn-app/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/androidTest/java/com/rnapp/DetoxTest.java: -------------------------------------------------------------------------------- 1 | // Replace "com.rnapp" here and below with your app's package name from the top of MainActivity.java 2 | package com.rnapp; 3 | 4 | import com.wix.detox.Detox; 5 | import com.wix.detox.config.DetoxConfig; 6 | 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import androidx.test.ext.junit.runners.AndroidJUnit4; 12 | import androidx.test.filters.LargeTest; 13 | import androidx.test.rule.ActivityTestRule; 14 | 15 | @RunWith(AndroidJUnit4.class) 16 | @LargeTest 17 | public class DetoxTest { 18 | // Replace 'MainActivity' with the value of android:name entry in 19 | // in AndroidManifest.xml 20 | @Rule 21 | public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); 22 | 23 | @Test 24 | public void runDetoxTests() { 25 | // This is optional - in case you've decided to integrate TestButler 26 | // See https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#8-test-butler-support-optional 27 | // TestButlerProbe.assertReadyIfInstalled(); 28 | 29 | DetoxConfig detoxConfig = new DetoxConfig(); 30 | detoxConfig.idlePolicyConfig.masterTimeoutSec = 90; 31 | detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60; 32 | detoxConfig.rnContextLoadTimeoutSec = (com.rnapp.BuildConfig.DEBUG ? 180 : 60); 33 | 34 | Detox.runTests(mActivityRule, detoxConfig); 35 | } 36 | } -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 14 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/java/com/rnapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.rnapp; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.ReactRootView; 6 | 7 | public class MainActivity extends ReactActivity { 8 | 9 | /** 10 | * Returns the name of the main component registered from JavaScript. This is used to schedule 11 | * rendering of the component. 12 | */ 13 | @Override 14 | protected String getMainComponentName() { 15 | return "RnApp"; 16 | } 17 | 18 | /** 19 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and 20 | * you can specify the rendered you wish to use (Fabric or the older renderer). 21 | */ 22 | @Override 23 | protected ReactActivityDelegate createReactActivityDelegate() { 24 | return new MainActivityDelegate(this, getMainComponentName()); 25 | } 26 | 27 | public static class MainActivityDelegate extends ReactActivityDelegate { 28 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) { 29 | super(activity, mainComponentName); 30 | } 31 | 32 | @Override 33 | protected ReactRootView createRootView() { 34 | ReactRootView reactRootView = new ReactRootView(getContext()); 35 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 36 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); 37 | return reactRootView; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/java/com/rnapp/newarchitecture/components/MainComponentsRegistry.java: -------------------------------------------------------------------------------- 1 | package com.rnapp.newarchitecture.components; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.proguard.annotations.DoNotStrip; 5 | import com.facebook.react.fabric.ComponentFactory; 6 | import com.facebook.soloader.SoLoader; 7 | 8 | /** 9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a 10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 11 | * folder for you). 12 | * 13 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 14 | * `newArchEnabled` property). Is ignored otherwise. 15 | */ 16 | @DoNotStrip 17 | public class MainComponentsRegistry { 18 | static { 19 | SoLoader.loadLibrary("fabricjni"); 20 | } 21 | 22 | @DoNotStrip private final HybridData mHybridData; 23 | 24 | @DoNotStrip 25 | private native HybridData initHybrid(ComponentFactory componentFactory); 26 | 27 | @DoNotStrip 28 | private MainComponentsRegistry(ComponentFactory componentFactory) { 29 | mHybridData = initHybrid(componentFactory); 30 | } 31 | 32 | @DoNotStrip 33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) { 34 | return new MainComponentsRegistry(componentFactory); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/java/com/rnapp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java: -------------------------------------------------------------------------------- 1 | package com.rnapp.newarchitecture.modules; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.react.ReactPackage; 5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.soloader.SoLoader; 8 | import java.util.List; 9 | 10 | /** 11 | * Class responsible to load the TurboModules. This class has native methods and needs a 12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 13 | * folder for you). 14 | * 15 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 16 | * `newArchEnabled` property). Is ignored otherwise. 17 | */ 18 | public class MainApplicationTurboModuleManagerDelegate 19 | extends ReactPackageTurboModuleManagerDelegate { 20 | 21 | private static volatile boolean sIsSoLibraryLoaded; 22 | 23 | protected MainApplicationTurboModuleManagerDelegate( 24 | ReactApplicationContext reactApplicationContext, List packages) { 25 | super(reactApplicationContext, packages); 26 | } 27 | 28 | protected native HybridData initHybrid(); 29 | 30 | native boolean canCreateTurboModule(String moduleName); 31 | 32 | public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { 33 | protected MainApplicationTurboModuleManagerDelegate build( 34 | ReactApplicationContext context, List packages) { 35 | return new MainApplicationTurboModuleManagerDelegate(context, packages); 36 | } 37 | } 38 | 39 | @Override 40 | protected synchronized void maybeLoadOtherSoLibraries() { 41 | if (!sIsSoLibraryLoaded) { 42 | // If you change the name of your application .so file in the Android.mk file, 43 | // make sure you update the name here as well. 44 | SoLoader.loadLibrary("rnapp_appmodules"); 45 | sIsSoLibraryLoaded = true; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | THIS_DIR := $(call my-dir) 2 | 3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk 4 | 5 | # If you wish to add a custom TurboModule or Fabric component in your app you 6 | # will have to include the following autogenerated makefile. 7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk 8 | include $(CLEAR_VARS) 9 | 10 | LOCAL_PATH := $(THIS_DIR) 11 | 12 | # You can customize the name of your application .so file here. 13 | LOCAL_MODULE := rnapp_appmodules 14 | 15 | LOCAL_C_INCLUDES := $(LOCAL_PATH) 16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) 17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) 18 | 19 | # If you wish to add a custom TurboModule or Fabric component in your app you 20 | # will have to uncomment those lines to include the generated source 21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) 22 | # 23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) 25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 26 | 27 | # Here you should add any native library you wish to depend on. 28 | LOCAL_SHARED_LIBRARIES := \ 29 | libfabricjni \ 30 | libfbjni \ 31 | libfolly_futures \ 32 | libfolly_json \ 33 | libglog \ 34 | libjsi \ 35 | libreact_codegen_rncore \ 36 | libreact_debug \ 37 | libreact_nativemodule_core \ 38 | libreact_render_componentregistry \ 39 | libreact_render_core \ 40 | libreact_render_debug \ 41 | libreact_render_graphics \ 42 | librrc_view \ 43 | libruntimeexecutor \ 44 | libturbomodulejsijni \ 45 | libyoga 46 | 47 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall 48 | 49 | include $(BUILD_SHARED_LIBRARY) 50 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/MainApplicationModuleProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationModuleProvider.h" 2 | 3 | #include 4 | 5 | namespace facebook { 6 | namespace react { 7 | 8 | std::shared_ptr MainApplicationModuleProvider( 9 | const std::string moduleName, 10 | const JavaTurboModule::InitParams ¶ms) { 11 | // Here you can provide your own module provider for TurboModules coming from 12 | // either your application or from external libraries. The approach to follow 13 | // is similar to the following (for a library called `samplelibrary`: 14 | // 15 | // auto module = samplelibrary_ModuleProvider(moduleName, params); 16 | // if (module != nullptr) { 17 | // return module; 18 | // } 19 | // return rncore_ModuleProvider(moduleName, params); 20 | return rncore_ModuleProvider(moduleName, params); 21 | } 22 | 23 | } // namespace react 24 | } // namespace facebook 25 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/MainApplicationModuleProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | std::shared_ptr MainApplicationModuleProvider( 12 | const std::string moduleName, 13 | const JavaTurboModule::InitParams ¶ms); 14 | 15 | } // namespace react 16 | } // namespace facebook 17 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationTurboModuleManagerDelegate.h" 2 | #include "MainApplicationModuleProvider.h" 3 | 4 | namespace facebook { 5 | namespace react { 6 | 7 | jni::local_ref 8 | MainApplicationTurboModuleManagerDelegate::initHybrid( 9 | jni::alias_ref) { 10 | return makeCxxInstance(); 11 | } 12 | 13 | void MainApplicationTurboModuleManagerDelegate::registerNatives() { 14 | registerHybrid({ 15 | makeNativeMethod( 16 | "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), 17 | makeNativeMethod( 18 | "canCreateTurboModule", 19 | MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), 20 | }); 21 | } 22 | 23 | std::shared_ptr 24 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 25 | const std::string name, 26 | const std::shared_ptr jsInvoker) { 27 | // Not implemented yet: provide pure-C++ NativeModules here. 28 | return nullptr; 29 | } 30 | 31 | std::shared_ptr 32 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 33 | const std::string name, 34 | const JavaTurboModule::InitParams ¶ms) { 35 | return MainApplicationModuleProvider(name, params); 36 | } 37 | 38 | bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( 39 | std::string name) { 40 | return getTurboModule(name, nullptr) != nullptr || 41 | getTurboModule(name, {.moduleName = name}) != nullptr; 42 | } 43 | 44 | } // namespace react 45 | } // namespace facebook 46 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | namespace facebook { 8 | namespace react { 9 | 10 | class MainApplicationTurboModuleManagerDelegate 11 | : public jni::HybridClass< 12 | MainApplicationTurboModuleManagerDelegate, 13 | TurboModuleManagerDelegate> { 14 | public: 15 | // Adapt it to the package you used for your Java class. 16 | static constexpr auto kJavaDescriptor = 17 | "Lcom/rnapp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; 18 | 19 | static jni::local_ref initHybrid(jni::alias_ref); 20 | 21 | static void registerNatives(); 22 | 23 | std::shared_ptr getTurboModule( 24 | const std::string name, 25 | const std::shared_ptr jsInvoker) override; 26 | std::shared_ptr getTurboModule( 27 | const std::string name, 28 | const JavaTurboModule::InitParams ¶ms) override; 29 | 30 | /** 31 | * Test-only method. Allows user to verify whether a TurboModule can be 32 | * created by instances of this class. 33 | */ 34 | bool canCreateTurboModule(std::string name); 35 | }; 36 | 37 | } // namespace react 38 | } // namespace facebook 39 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/MainComponentsRegistry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | class MainComponentsRegistry 12 | : public facebook::jni::HybridClass { 13 | public: 14 | // Adapt it to the package you used for your Java class. 15 | constexpr static auto kJavaDescriptor = 16 | "Lcom/rnapp/newarchitecture/components/MainComponentsRegistry;"; 17 | 18 | static void registerNatives(); 19 | 20 | MainComponentsRegistry(ComponentFactory *delegate); 21 | 22 | private: 23 | static std::shared_ptr 24 | sharedProviderRegistry(); 25 | 26 | static jni::local_ref initHybrid( 27 | jni::alias_ref, 28 | ComponentFactory *delegate); 29 | }; 30 | 31 | } // namespace react 32 | } // namespace facebook 33 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/jni/OnLoad.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "MainApplicationTurboModuleManagerDelegate.h" 3 | #include "MainComponentsRegistry.h" 4 | 5 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { 6 | return facebook::jni::initialize(vm, [] { 7 | facebook::react::MainApplicationTurboModuleManagerDelegate:: 8 | registerNatives(); 9 | facebook::react::MainComponentsRegistry::registerNatives(); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RnApp 3 | 4 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /apps/rn-app/android/app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10.0.2.2 5 | localhost 6 | 7 | -------------------------------------------------------------------------------- /apps/rn-app/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.125.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=false 41 | -------------------------------------------------------------------------------- /apps/rn-app/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /apps/rn-app/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /apps/rn-app/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'RnApp' 2 | 3 | include ':react-native-config' 4 | project(':react-native-config').projectDir = new File(rootProject.projectDir, '../../../node_modules/react-native-config/android') 5 | 6 | 7 | include ':detox' 8 | project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox') 9 | 10 | 11 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); 12 | applyNativeModulesSettingsGradle(settings) 13 | 14 | include ':app' 15 | includeBuild('../node_modules/react-native-gradle-plugin') 16 | 17 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { 18 | include(":ReactAndroid") 19 | project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') 20 | } 21 | -------------------------------------------------------------------------------- /apps/rn-app/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RnApp", 3 | "displayName": "RnApp" 4 | } 5 | -------------------------------------------------------------------------------- /apps/rn-app/assets/storybook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/assets/storybook.png -------------------------------------------------------------------------------- /apps/rn-app/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["module:metro-react-native-babel-preset"] 3 | } 4 | -------------------------------------------------------------------------------- /apps/rn-app/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | require_relative '../node_modules/@nrwl/react-native/nx_post_install' 4 | 5 | platform :ios, '13.0' 6 | install! 'cocoapods', :deterministic_uuids => false 7 | 8 | target 'RnApp' do 9 | config = use_native_modules! 10 | 11 | # Flags change depending on the env values. 12 | flags = get_default_flags() 13 | 14 | use_react_native!( 15 | :path => config[:reactNativePath], 16 | # to enable hermes on iOS, change `false` to `true` and then install pods 17 | :hermes_enabled => flags[:hermes_enabled], 18 | :fabric_enabled => flags[:fabric_enabled], 19 | # An absolute path to your application root. 20 | :app_path => "#{Pod::Config.instance.installation_root}/.." 21 | ) 22 | 23 | target 'RnAppTests' do 24 | inherit! :complete 25 | # Pods for testing 26 | end 27 | 28 | # Enables Flipper. 29 | # 30 | # Note that if you have use_frameworks! enabled, Flipper will not work and 31 | # you should disable the next line. 32 | use_flipper!() 33 | 34 | post_install do |installer| 35 | react_native_post_install(installer) 36 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 37 | nx_post_install(installer) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "iphone", 5 | "scale": "2x", 6 | "size": "20x20" 7 | }, 8 | { 9 | "idiom": "iphone", 10 | "scale": "3x", 11 | "size": "20x20" 12 | }, 13 | { 14 | "idiom": "iphone", 15 | "scale": "2x", 16 | "size": "29x29" 17 | }, 18 | { 19 | "idiom": "iphone", 20 | "scale": "3x", 21 | "size": "29x29" 22 | }, 23 | { 24 | "idiom": "iphone", 25 | "scale": "2x", 26 | "size": "40x40" 27 | }, 28 | { 29 | "idiom": "iphone", 30 | "scale": "3x", 31 | "size": "40x40" 32 | }, 33 | { 34 | "idiom": "iphone", 35 | "scale": "2x", 36 | "size": "60x60" 37 | }, 38 | { 39 | "idiom": "iphone", 40 | "scale": "3x", 41 | "size": "60x60" 42 | }, 43 | { 44 | "idiom": "ios-marketing", 45 | "scale": "1x", 46 | "size": "1024x1024" 47 | } 48 | ], 49 | "info": { 50 | "author": "xcode", 51 | "version": 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RnApp 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnApp/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/rn-app/ios/RnAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /apps/rn-app/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | displayName: 'rn-app', 4 | preset: 'react-native', 5 | 6 | resolver: '@nrwl/jest/plugins/resolver', 7 | moduleFileExtensions: ['ts', 'js', 'html', 'tsx', 'jsx'], 8 | setupFilesAfterEnv: ['/test-setup.ts'], 9 | moduleNameMapper: { 10 | '.svg': '@nrwl/react-native/plugins/jest/svg-mock', 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /apps/rn-app/metro.config.js: -------------------------------------------------------------------------------- 1 | const { withNxMetro } = require('@nrwl/react-native'); 2 | const { getDefaultConfig } = require('metro-config'); 3 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 4 | 5 | module.exports = (async () => { 6 | const { 7 | resolver: { sourceExts, assetExts }, 8 | } = await getDefaultConfig(); 9 | return withNxMetro( 10 | { 11 | transformer: { 12 | getTransformOptions: async () => ({ 13 | transform: { 14 | experimentalImportSupport: false, 15 | inlineRequires: true, 16 | }, 17 | }), 18 | babelTransformerPath: require.resolve('react-native-svg-transformer'), 19 | }, 20 | resolver: { 21 | assetExts: assetExts.filter((ext) => ext !== 'svg'), 22 | sourceExts: [...sourceExts, 'svg'], 23 | resolverMainFields: ['sbmodern', 'browser', 'main'], 24 | blacklistRE: exclusionList([ 25 | /\.\/dist\/.*/, 26 | /libs\/.*package.json/, 27 | /apps\/nextjs-app\/.*package.json/, 28 | ]), 29 | }, 30 | }, 31 | { 32 | // Change this to true to see debugging info. 33 | // Useful if you have issues resolving modules 34 | debug: false, 35 | // all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json' 36 | extensions: [], 37 | // the project root to start the metro server 38 | projectRoot: __dirname, 39 | // Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules) 40 | watchFolders: [], 41 | } 42 | ); 43 | })(); 44 | -------------------------------------------------------------------------------- /apps/rn-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rn-app", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-native": "*", 7 | "@testing-library/react-native": "*", 8 | "react": "*", 9 | "react-native": "*", 10 | "react-native-config": "*", 11 | "react-native-svg": "*", 12 | "@react-native-async-storage/async-storage": "*", 13 | "@testing-library/react": "*", 14 | "@storybook/react": "*", 15 | "qs": "*", 16 | "immer": "*", 17 | "zustand": "*", 18 | "@storybook/addon-viewport": "*", 19 | "metro-config": "*" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/blog.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/book.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/checkmark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/chevron-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/courses.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/heart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/rn-app/src/app/icons/logo.png -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/nx-cloud.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/pointer.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/terminal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/vscode.svg: -------------------------------------------------------------------------------- 1 | Visual Studio Code -------------------------------------------------------------------------------- /apps/rn-app/src/app/icons/youtube.svg: -------------------------------------------------------------------------------- 1 | YouTube -------------------------------------------------------------------------------- /apps/rn-app/src/libs/env.ts: -------------------------------------------------------------------------------- 1 | import Config from 'react-native-config'; 2 | 3 | export const env = { 4 | API_URL: Config.API_URL, 5 | }; -------------------------------------------------------------------------------- /apps/rn-app/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './app/App'; 3 | 4 | AppRegistry.registerComponent('RnApp', () => App); 5 | -------------------------------------------------------------------------------- /apps/rn-app/test-setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-native/extend-expect'; 2 | -------------------------------------------------------------------------------- /apps/rn-app/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "exclude": [ 8 | "jest.config.ts", 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "test-setup.ts" 12 | ], 13 | "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"] 14 | } 15 | -------------------------------------------------------------------------------- /apps/rn-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "jsx": "react-native", 6 | "lib": ["dom", "esnext"], 7 | "moduleResolution": "node", 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "resolveJsonModule": true 11 | }, 12 | "files": ["../../node_modules/@nrwl/react-native/typings/svg.d.ts"], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.app.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /apps/rn-app/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "**/*.test.ts", 11 | "**/*.spec.ts", 12 | "**/*.test.tsx", 13 | "**/*.spec.tsx", 14 | "**/*.test.js", 15 | "**/*.spec.js", 16 | "**/*.test.jsx", 17 | "**/*.spec.jsx", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileServerFolder": ".", 3 | "fixturesFolder": "./src/fixtures", 4 | "integrationFolder": "./src/integration", 5 | "modifyObstructiveCode": false, 6 | "supportFile": "./src/support/index.ts", 7 | "pluginsFile": false, 8 | "video": true, 9 | "videosFolder": "../../dist/cypress/apps/standalone-nextjs-app-e2e/videos", 10 | "screenshotsFolder": "../../dist/cypress/apps/standalone-nextjs-app-e2e/screenshots", 11 | "chromeWebSecurity": false 12 | } 13 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "standalone-nextjs-app-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "apps/standalone-nextjs-app-e2e/src", 5 | "projectType": "application", 6 | "targets": { 7 | "e2e": { 8 | "executor": "@nrwl/cypress:cypress", 9 | "options": { 10 | "cypressConfig": "apps/standalone-nextjs-app-e2e/cypress.json", 11 | "devServerTarget": "standalone-nextjs-app:serve" 12 | }, 13 | "configurations": { 14 | "production": { 15 | "devServerTarget": "standalone-nextjs-app:serve:production" 16 | } 17 | } 18 | }, 19 | "lint": { 20 | "executor": "@nrwl/linter:eslint", 21 | "outputs": ["{options.outputFile}"], 22 | "options": { 23 | "lintFilePatterns": ["apps/standalone-nextjs-app-e2e/**/*.{js,ts}"] 24 | }, 25 | "configurations": { 26 | "fix": { 27 | "fix": true 28 | } 29 | } 30 | } 31 | }, 32 | "tags": [], 33 | "implicitDependencies": ["standalone-nextjs-app"] 34 | } 35 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/src/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io" 4 | } 5 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/src/integration/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { getGreeting } from '../support/app.po'; 2 | 3 | describe('standalone-nextjs-app', () => { 4 | beforeEach(() => cy.visit('/')); 5 | 6 | it('should display welcome message', () => { 7 | // Custom command example, see `../support/commands.ts` file 8 | cy.login('my-email@something.com', 'myPassword'); 9 | 10 | // Function helper example, see `../support/app.po.ts` file 11 | getGreeting().contains('Welcome standalone-nextjs-app'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/src/support/app.po.ts: -------------------------------------------------------------------------------- 1 | export const getGreeting = () => cy.get('h1'); 2 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/src/support/commands.ts: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-namespace 12 | declare namespace Cypress { 13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 14 | interface Chainable { 15 | login(email: string, password: string): void; 16 | } 17 | } 18 | // 19 | // -- This is a parent command -- 20 | Cypress.Commands.add('login', (email, password) => { 21 | console.log('Custom command example: Login', email, password); 22 | }); 23 | // 24 | // -- This is a child command -- 25 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 26 | // 27 | // 28 | // -- This is a dual command -- 29 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 30 | // 31 | // 32 | // -- This will overwrite an existing command -- 33 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 34 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/src/support/index.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands'; 18 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "outDir": "../../dist/out-tsc", 6 | "allowJs": true, 7 | "types": ["cypress", "node"] 8 | }, 9 | "include": ["src/**/*.ts", "src/**/*.js"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": [ 4 | ["react-native-web", { "commonjs": true }], 5 | [ 6 | "module-resolver", 7 | { 8 | "alias": { 9 | "^react-native$": "react-native-web" 10 | } 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/.env: -------------------------------------------------------------------------------- 1 | API_URL=https://example.com/ -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:@nrwl/nx/react-typescript", 4 | "../../.eslintrc.json", 5 | "next", 6 | "next/core-web-vitals" 7 | ], 8 | "ignorePatterns": ["!**/*"], 9 | "overrides": [ 10 | { 11 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 12 | "rules": { 13 | "@next/next/no-html-link-for-pages": [ 14 | "error", 15 | "apps/standalone-nextjs-app/pages" 16 | ] 17 | } 18 | }, 19 | { 20 | "files": ["*.ts", "*.tsx"], 21 | "rules": {} 22 | }, 23 | { 24 | "files": ["*.js", "*.jsx"], 25 | "rules": {} 26 | } 27 | ], 28 | "env": { 29 | "jest": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/.qa.env: -------------------------------------------------------------------------------- 1 | API_URL=https://example.com/qa -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14.17.1-alpine3.11 2 | 3 | WORKDIR /app 4 | COPY ./dist/apps/standalone-nextjs-app . 5 | 6 | ENV PORT 3000 7 | ENV NEXT_DIR . 8 | ENV NODE_ENV production 9 | 10 | RUN npm install --production 11 | 12 | EXPOSE 3000 13 | 14 | CMD ["node", "main.js"] 15 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/components/layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SEO, { SEOProps } from './seo'; 3 | 4 | interface LayoutProps { 5 | seoProps?: SEOProps; 6 | children: React.ReactNode; 7 | } 8 | 9 | export default function Layout(props: LayoutProps) { 10 | const { seoProps, children } = props; 11 | return ( 12 | <> 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/components/seo.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | import { useRouter } from 'next/router'; 3 | import { 4 | SEO as SharedSEO, 5 | SEOProps as SharedSEOProps, 6 | } from '@nx-react-code-sharing/shared-ui-components'; 7 | 8 | // eslint-disable-next-line @typescript-eslint/no-empty-interface 9 | export interface SEOProps extends SharedSEOProps {} 10 | 11 | export default function SEO(props: SEOProps) { 12 | const router = useRouter(); 13 | 14 | return ( 15 | 16 | 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/generated/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/generated/.gitkeep -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/generated/data.ts: -------------------------------------------------------------------------------- 1 | export const dummyData = { a: 1 }; 2 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | declare module '*.svg' { 3 | const content: any; 4 | export const ReactComponent: any; 5 | export default content; 6 | } 7 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'standalone-nextjs-app', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest', 7 | '^.+\\.[tj]sx?$': [ 8 | 'babel-jest', 9 | { presets: ['@nrwl/next/babel'], babelrc: false }, 10 | ], 11 | }, 12 | moduleNameMapper: { 13 | '^react-native$': 'react-native-web', 14 | }, 15 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 16 | coverageDirectory: '../../coverage/apps/standalone-nextjs-app', 17 | }; 18 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/libs/env.ts: -------------------------------------------------------------------------------- 1 | import getConfig from 'next/config'; 2 | 3 | const { publicRuntimeConfig } = getConfig() ?? { 4 | serverRuntimeConfig: {}, 5 | publicRuntimeConfig: {}, 6 | }; 7 | const { 8 | API_URL, 9 | }: { 10 | API_URL: string; 11 | } = publicRuntimeConfig; 12 | 13 | export const env = { 14 | API_URL, 15 | }; 16 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/main.ts: -------------------------------------------------------------------------------- 1 | import next from 'next'; 2 | import customServer from './server'; 3 | 4 | const port = parseInt(process.env.PORT || '3000', 10); 5 | const dev = process.env.NODE_ENV !== 'production'; 6 | const app = next({ 7 | dev, 8 | ...(process.env.NEXT_DIR 9 | ? { dir: process.env.NEXT_DIR } 10 | : { 11 | dir: 'dist/apps/standalone-nextjs-app', 12 | }), 13 | }); 14 | 15 | customServer(app, { port }, {}); 16 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/next.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const withNx = require('@nrwl/next/plugins/with-nx'); 3 | 4 | const { API_URL } = process.env; 5 | 6 | /** 7 | * @type {import('@nrwl/next/plugins/with-nx').WithNxOptions} 8 | **/ 9 | const nextConfig = { 10 | swcMinify: false, 11 | nx: { 12 | // Set this to true if you would like to to use SVGR 13 | // See: https://github.com/gregberge/svgr 14 | svgr: false, 15 | }, 16 | publicRuntimeConfig: { 17 | API_URL, 18 | }, 19 | webpack(config) { 20 | return { 21 | ...config, 22 | optimization: { 23 | ...config.optimization, 24 | providedExports: true, 25 | sideEffects: 'flag', 26 | }, 27 | }; 28 | }, 29 | }; 30 | 31 | module.exports = withNx(nextConfig); 32 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { AppProps } from 'next/app'; 2 | import Head from 'next/head'; 3 | import './styles.css'; 4 | 5 | function CustomApp({ Component, pageProps }: AppProps) { 6 | return ( 7 | <> 8 | 9 | Welcome to standalone-nextjs-app! 10 | 11 |

12 | 13 |
14 | 15 | ); 16 | } 17 | 18 | export default CustomApp; 19 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Document, { Html, Head, Main, NextScript } from 'next/document'; 3 | 4 | class MyDocument extends Document { 5 | public render() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | ); 22 | } 23 | } 24 | 25 | export default MyDocument; 26 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/pages/api/healthz.tsx: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from 'next'; 2 | 3 | export const handler = async (req: NextApiRequest, res: NextApiResponse) => { 4 | res.statusCode = 200; 5 | res.setHeader('Content-Type', 'application/json'); 6 | res.end(JSON.stringify({ status: 'ok' })); 7 | }; 8 | 9 | export default handler; -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { customAPI } from '@nx-react-code-sharing/shared-apis'; 2 | import { Bold } from '@nx-react-code-sharing/shared-ui-components'; 3 | import { 4 | todosByOrderDESCSelector, 5 | useTodoStore, 6 | } from '@nx-react-code-sharing/features-todo'; 7 | import { useEffect } from 'react'; 8 | import { env } from '../libs/env'; 9 | import Layout from '../components/layout'; 10 | 11 | export function Index() { 12 | const todos = useTodoStore(todosByOrderDESCSelector); 13 | 14 | useEffect(() => { 15 | const fetchTest = async () => { 16 | const testData = await customAPI<{ 17 | status: string; 18 | }>({ 19 | url: '/api/healthz', 20 | }); 21 | console.log(testData); 22 | }; 23 | fetchTest(); 24 | }, []); 25 | 26 | return ( 27 | 28 |
29 |
30 |
31 | 32 | Hello there, 33 | Welcome nx-react-code-sharing 👋 Todo List (API_URL={env.API_URL}) 34 | 35 |
    36 | {todos.map((todo) => ( 37 |
  • {todo.name}
  • 38 | ))} 39 |
40 |
41 |
42 |
43 |
44 | ); 45 | } 46 | 47 | export default Index; 48 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/pages/styles.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-text-size-adjust: 100%; 3 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 4 | Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, 5 | Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; 6 | line-height: 1.5; 7 | tab-size: 4; 8 | scroll-behavior: smooth; 9 | } 10 | body { 11 | font-family: inherit; 12 | line-height: inherit; 13 | margin: 0; 14 | } 15 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/.gitkeep -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/android-icon-144x144.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/android-icon-192x192.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/android-icon-36x36.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/android-icon-48x48.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/android-icon-72x72.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/android-icon-96x96.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-114x114.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-120x120.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-144x144.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-152x152.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-180x180.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-57x57.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-60x60.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-72x72.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-76x76.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon-precomposed.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/apple-icon.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/favicon.ico -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/ms-icon-144x144.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/ms-icon-150x150.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/ms-icon-310x310.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/favicons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/favicons/ms-icon-70x70.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/public/images/large-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/apps/standalone-nextjs-app/public/images/large-og.png -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/server.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | 3 | export default async function customServer(app, settings, proxyConfig) { 4 | const handle = app.getRequestHandler(); 5 | 6 | app.prepare().then(() => { 7 | const server = express(); 8 | 9 | server.all('*', (req, res) => { 10 | return handle(req, res); 11 | }); 12 | server.listen(settings.port, () => { 13 | console.log(`> Ready on http://localhost:${settings.port}`); 14 | }); 15 | server.on('error', console.error); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/specs/index.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | 4 | describe('Index', () => { 5 | it('should render successfully', () => { 6 | const { baseElement } = render(
); 7 | expect(baseElement).toBeTruthy(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "types": ["node", "jest"], 9 | "strict": false, 10 | "forceConsistentCasingInFileNames": true, 11 | "noEmit": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "incremental": true 15 | }, 16 | "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts"], 17 | "exclude": ["node_modules", "jest.config.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/tsconfig.server.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../dist/", 6 | "target": "es2017", 7 | "isolatedModules": false, 8 | "noEmit": false 9 | }, 10 | "include": ["server.ts", "main.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /apps/standalone-nextjs-app/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "jsx": "react" 8 | }, 9 | "include": [ 10 | "**/*.test.ts", 11 | "**/*.spec.ts", 12 | "**/*.test.tsx", 13 | "**/*.spec.tsx", 14 | "**/*.test.js", 15 | "**/*.spec.js", 16 | "**/*.test.jsx", 17 | "**/*.spec.jsx", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "babelrcRoots": ["*"] 3 | } 4 | -------------------------------------------------------------------------------- /jest.config.base.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleNameMapper: { 3 | '\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 4 | '/../../__tests__/fileMock.js', 5 | '\\.(css|less)$': '/../../__tests__/fileMock.js', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjects } from '@nrwl/jest'; 2 | 3 | export default { 4 | projects: getJestProjects(), 5 | }; 6 | -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nrwl/jest/preset').default; 2 | 3 | module.exports = { ...nxPreset }; 4 | -------------------------------------------------------------------------------- /libs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/libs/.gitkeep -------------------------------------------------------------------------------- /libs/features/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/libs/features/.gitkeep -------------------------------------------------------------------------------- /libs/features/todo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@nrwl/react/babel", 5 | { 6 | "runtime": "automatic", 7 | "useBuiltIns": "usage" 8 | } 9 | ] 10 | ], 11 | "plugins": [["react-native-web", { "commonjs": true }]] 12 | } 13 | -------------------------------------------------------------------------------- /libs/features/todo/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/features/todo/README.md: -------------------------------------------------------------------------------- 1 | # features-todo 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test features-todo` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/features/todo/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'features-todo', 4 | preset: '../../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }], 7 | }, 8 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 9 | coverageDirectory: '../../../coverage/libs/features/todo', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/features/todo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/features-todo", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/features/todo/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "features-todo", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/features/todo/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "targets": { 8 | "lint": { 9 | "executor": "@nrwl/linter:eslint", 10 | "outputs": ["{options.outputFile}"], 11 | "options": { 12 | "lintFilePatterns": ["libs/features/todo/**/*.{ts,tsx,js,jsx}"] 13 | }, 14 | "configurations": { 15 | "fix": { 16 | "fix": true 17 | } 18 | } 19 | }, 20 | "test": { 21 | "executor": "@nrwl/jest:jest", 22 | "outputs": ["{workspaceRoot}/coverage/libs/features/todo"], 23 | "options": { 24 | "jestConfig": "libs/features/todo/jest.config.ts", 25 | "passWithNoTests": true 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libs/features/todo/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/components'; 2 | export * from './lib/interfaces'; 3 | export * from './lib/stores'; 4 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/components/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './todo-item/todo-item'; 2 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/components/todo-item/todo-item.spec.tsx: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | 3 | import TodoItem from './todo-item'; 4 | 5 | describe('TodoItem', () => { 6 | it('should render successfully', () => { 7 | const { baseElement } = render(Helloworld); 8 | expect(baseElement).toBeTruthy(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/components/todo-item/todo-item.stories.tsx: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react'; 2 | import { TodoItem, TodoItemProps } from './todo-item'; 3 | 4 | export default { 5 | component: TodoItem, 6 | title: 'TodoItem', 7 | argTypes: {}, 8 | } as Meta; 9 | 10 | const Template: Story = (args) => ; 11 | 12 | export const Primary = Template.bind({}); 13 | Primary.args = {}; 14 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/components/todo-item/todo-item.tsx: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Text } from 'react-native'; 2 | 3 | const styles = StyleSheet.create({ 4 | TodoItem: { 5 | color: 'pink', 6 | }, 7 | }); 8 | 9 | export interface TodoItemProps { 10 | children: React.ReactNode; 11 | } 12 | 13 | export function TodoItem(props: TodoItemProps) { 14 | const { children } = props; 15 | return {children}; 16 | } 17 | 18 | export default TodoItem; 19 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './stores/use-todo-store'; 2 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './todo'; 2 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/interfaces/todo.ts: -------------------------------------------------------------------------------- 1 | export interface Todo { 2 | id: string; 3 | name: string; 4 | order: number; 5 | } 6 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/stores/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './use-todo-store'; 2 | -------------------------------------------------------------------------------- /libs/features/todo/src/lib/stores/use-todo-store.tsx: -------------------------------------------------------------------------------- 1 | import { uniqueId } from '@nx-react-code-sharing/shared-utils'; 2 | import produce from 'immer'; 3 | import create from 'zustand'; 4 | import { Todo } from '../interfaces/todo'; 5 | 6 | interface TodoStoreProps { 7 | todos: Todo[]; 8 | initialize: () => void; 9 | reset: () => void; 10 | addTodo: (name: string) => void; 11 | } 12 | 13 | const PREFIX_TODO_ID = 'todo'; 14 | 15 | export const useTodoStore = create((set, get) => ({ 16 | todos: [ 17 | { 18 | id: uniqueId('todo'), 19 | name: 'test', 20 | order: 1, 21 | }, 22 | ], 23 | // eslint-disable-next-line @typescript-eslint/no-empty-function 24 | initialize: () => {}, 25 | // eslint-disable-next-line @typescript-eslint/no-empty-function 26 | reset: () => {}, 27 | addTodo: (name: string) => { 28 | const id = uniqueId('todo'); 29 | set( 30 | produce((state) => { 31 | state.todos.push({ 32 | name, 33 | id: uniqueId(PREFIX_TODO_ID), 34 | order: state.todos.length + 1, 35 | }); 36 | }) 37 | ); 38 | }, 39 | })); 40 | 41 | export const todosByOrderDESCSelector = (state: TodoStoreProps) => 42 | state.todos.reverse(); 43 | export const todoTestSelector = (state: TodoStoreProps) => 'todoTest123'; 44 | -------------------------------------------------------------------------------- /libs/features/todo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitOverride": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true 14 | }, 15 | "files": [], 16 | "include": [], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.lib.json" 20 | }, 21 | { 22 | "path": "./tsconfig.spec.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/features/todo/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": [ 8 | "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", 9 | "../../../node_modules/@nrwl/react/typings/image.d.ts" 10 | ], 11 | "exclude": [ 12 | "jest.config.ts", 13 | "**/*.spec.ts", 14 | "**/*.test.ts", 15 | "**/*.spec.tsx", 16 | "**/*.test.tsx", 17 | "**/*.spec.js", 18 | "**/*.test.js", 19 | "**/*.spec.jsx", 20 | "**/*.test.jsx" 21 | ], 22 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] 23 | } 24 | -------------------------------------------------------------------------------- /libs/features/todo/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "**/*.test.ts", 11 | "**/*.spec.ts", 12 | "**/*.test.tsx", 13 | "**/*.spec.tsx", 14 | "**/*.test.js", 15 | "**/*.spec.js", 16 | "**/*.test.jsx", 17 | "**/*.spec.jsx", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /libs/images/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@nrwl/react/babel", 5 | { 6 | "runtime": "automatic", 7 | "useBuiltIns": "usage" 8 | } 9 | ] 10 | ], 11 | "plugins": [] 12 | } 13 | -------------------------------------------------------------------------------- /libs/images/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/images/README.md: -------------------------------------------------------------------------------- 1 | # images 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test images` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/images/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'images', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }], 7 | }, 8 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 9 | coverageDirectory: '../../coverage/libs/images', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/images/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "images", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/images/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "targets": { 8 | "lint": { 9 | "executor": "@nrwl/linter:eslint", 10 | "outputs": ["{options.outputFile}"], 11 | "options": { 12 | "lintFilePatterns": ["libs/images/**/*.{ts,tsx,js,jsx}"] 13 | } 14 | }, 15 | "test": { 16 | "executor": "@nrwl/jest:jest", 17 | "outputs": ["{workspaceRoot}/coverage/libs/images"], 18 | "options": { 19 | "jestConfig": "libs/images/jest.config.ts", 20 | "passWithNoTests": true 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libs/images/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/images'; 2 | -------------------------------------------------------------------------------- /libs/images/src/lib/images.spec.tsx: -------------------------------------------------------------------------------- 1 | import { setImagePrefixPath, getImages } from './images'; 2 | 3 | describe('Images', () => { 4 | it('prefix 이미지 설정', () => { 5 | setImagePrefixPath('/test'); 6 | expect(getImages().iconImages.storybook).toBe('/test/assets/storybook.png'); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /libs/images/src/lib/images.tsx: -------------------------------------------------------------------------------- 1 | import { getKeys } from '@nx-react-code-sharing/shared-utils'; 2 | 3 | let prefix = ''; 4 | 5 | export const setImagePrefixPath = (newPrefix: string) => { 6 | prefix = newPrefix; 7 | }; 8 | 9 | const withPrefixPath = ( 10 | imageKeys: T[], 11 | images: U 12 | ): U => { 13 | return imageKeys.reduce((res, curr) => { 14 | return { 15 | ...res, 16 | [curr]: `${prefix}${images[curr]}`, 17 | }; 18 | }, images); 19 | }; 20 | 21 | export const getImages = () => { 22 | const iconImages = { 23 | storybook: '/assets/storybook.png', 24 | }; 25 | const iconImageKeys = getKeys(iconImages); 26 | 27 | return { 28 | iconImages: withPrefixPath(iconImageKeys, iconImages), 29 | }; 30 | }; 31 | -------------------------------------------------------------------------------- /libs/images/src/lib/public/assets/storybook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/libs/images/src/lib/public/assets/storybook.png -------------------------------------------------------------------------------- /libs/images/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitOverride": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true 14 | }, 15 | "files": [], 16 | "include": [], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.lib.json" 20 | }, 21 | { 22 | "path": "./tsconfig.spec.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/images/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": [ 8 | "../../node_modules/@nrwl/react/typings/cssmodule.d.ts", 9 | "../../node_modules/@nrwl/react/typings/image.d.ts" 10 | ], 11 | "exclude": [ 12 | "jest.config.ts", 13 | "**/*.spec.ts", 14 | "**/*.test.ts", 15 | "**/*.spec.tsx", 16 | "**/*.test.tsx", 17 | "**/*.spec.js", 18 | "**/*.test.js", 19 | "**/*.spec.jsx", 20 | "**/*.test.jsx" 21 | ], 22 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] 23 | } 24 | -------------------------------------------------------------------------------- /libs/images/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "**/*.test.ts", 11 | "**/*.spec.ts", 12 | "**/*.test.tsx", 13 | "**/*.spec.tsx", 14 | "**/*.test.js", 15 | "**/*.spec.js", 16 | "**/*.test.jsx", 17 | "**/*.spec.jsx", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /libs/sdk/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/sdk/README.md: -------------------------------------------------------------------------------- 1 | # sdk 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build sdk` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test sdk` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /libs/sdk/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | displayName: 'sdk', 4 | preset: '../../jest.preset.js', 5 | globals: { 6 | 'ts-jest': { 7 | tsconfig: '/tsconfig.spec.json', 8 | }, 9 | }, 10 | transform: { 11 | '^.+\\.[tj]s$': 'ts-jest', 12 | }, 13 | moduleFileExtensions: ['ts', 'js', 'html'], 14 | coverageDirectory: '../../coverage/libs/sdk', 15 | }; 16 | -------------------------------------------------------------------------------- /libs/sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/sdk", 3 | "version": "0.0.1", 4 | "type": "commonjs" 5 | } 6 | -------------------------------------------------------------------------------- /libs/sdk/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sdk", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/sdk/src", 5 | "targets": { 6 | "build": { 7 | "executor": "@nrwl/js:tsc", 8 | "outputs": ["{options.outputPath}"], 9 | "options": { 10 | "outputPath": "dist/libs/sdk", 11 | "main": "libs/sdk/src/index.ts", 12 | "tsConfig": "libs/sdk/tsconfig.lib.json", 13 | "assets": ["libs/sdk/*.md"] 14 | } 15 | }, 16 | "publish": { 17 | "executor": "nx:run-commands", 18 | "outputs": [], 19 | "options": { 20 | "command": "npm publish --tag=latest --access public", 21 | "cwd": "dist/libs/sdk" 22 | } 23 | }, 24 | "lint": { 25 | "executor": "@nrwl/linter:eslint", 26 | "outputs": ["{options.outputFile}"], 27 | "options": { 28 | "lintFilePatterns": ["libs/sdk/**/*.ts"] 29 | }, 30 | "configurations": { 31 | "fix": { 32 | "fix": true 33 | } 34 | } 35 | }, 36 | "test": { 37 | "executor": "@nrwl/jest:jest", 38 | "outputs": ["{workspaceRoot}/coverage/libs/sdk"], 39 | "options": { 40 | "jestConfig": "libs/sdk/jest.config.ts", 41 | "passWithNoTests": true 42 | } 43 | } 44 | }, 45 | "tags": [] 46 | } 47 | -------------------------------------------------------------------------------- /libs/sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/sdk'; 2 | -------------------------------------------------------------------------------- /libs/sdk/src/lib/sdk.spec.ts: -------------------------------------------------------------------------------- 1 | import { SDK } from './sdk'; 2 | 3 | describe('sdk', () => { 4 | it('should work', () => { 5 | const sdk = new SDK(); 6 | expect(sdk.loggedInUserId).toEqual(undefined); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /libs/sdk/src/lib/sdk.ts: -------------------------------------------------------------------------------- 1 | export class SDK { 2 | constructor(public loggedInUserId?: string) {} 3 | 4 | createTodo() { 5 | this.asswertUserIsLoggedIn(); 6 | console.log('loggedInUserId is string', this.loggedInUserId); 7 | } 8 | 9 | asswertUserIsLoggedIn(): asserts this is this & { 10 | loggedInUserId: string; 11 | } { 12 | if (!this.loggedInUserId) { 13 | throw new Error('User is not logged in'); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libs/sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/sdk/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": [] 7 | }, 8 | "include": ["**/*.ts"], 9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/sdk/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /libs/shared/apis/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/shared/apis/README.md: -------------------------------------------------------------------------------- 1 | # shared-apis 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build shared-apis` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test shared-apis` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /libs/shared/apis/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'shared-apis', 4 | preset: '../../../jest.preset.js', 5 | globals: { 6 | 'ts-jest': { 7 | tsconfig: '/tsconfig.spec.json', 8 | }, 9 | }, 10 | transform: { 11 | '^.+\\.[tj]s$': 'ts-jest', 12 | }, 13 | moduleFileExtensions: ['ts', 'js', 'html'], 14 | coverageDirectory: '../../../coverage/libs/shared/apis', 15 | }; 16 | -------------------------------------------------------------------------------- /libs/shared/apis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/shared-apis", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/apis/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared-apis", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/shared/apis/src", 5 | "targets": { 6 | "build": { 7 | "executor": "@nrwl/js:tsc", 8 | "outputs": ["{options.outputPath}"], 9 | "options": { 10 | "outputPath": "dist/libs/shared/apis", 11 | "main": "libs/shared/apis/src/index.ts", 12 | "tsConfig": "libs/shared/apis/tsconfig.lib.json", 13 | "assets": ["libs/shared/apis/*.md"] 14 | } 15 | }, 16 | "lint": { 17 | "executor": "@nrwl/linter:eslint", 18 | "outputs": ["{options.outputFile}"], 19 | "options": { 20 | "lintFilePatterns": ["libs/shared/apis/**/*.ts"] 21 | }, 22 | "configurations": { 23 | "fix": { 24 | "fix": true 25 | } 26 | } 27 | }, 28 | "test": { 29 | "executor": "@nrwl/jest:jest", 30 | "outputs": ["{workspaceRoot}/coverage/libs/shared/apis"], 31 | "options": { 32 | "jestConfig": "libs/shared/apis/jest.config.ts", 33 | "passWithNoTests": true 34 | } 35 | } 36 | }, 37 | "tags": [] 38 | } 39 | -------------------------------------------------------------------------------- /libs/shared/apis/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/request-api'; 2 | export * from './lib/custom-api'; 3 | export * from './lib/healthz'; 4 | -------------------------------------------------------------------------------- /libs/shared/apis/src/lib/custom-api.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export const customAPI = async (params: { url: string }) => { 4 | const { url } = params; 5 | const response = await axios.get(url); 6 | return response.data; 7 | }; 8 | -------------------------------------------------------------------------------- /libs/shared/apis/src/lib/healthz.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export const healthz = async () => { 4 | const response = await axios.get(`/api/healthz`); 5 | return response.data; 6 | }; 7 | -------------------------------------------------------------------------------- /libs/shared/apis/src/lib/request-api.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export const initialize = (baseURL: string) => { 4 | axios.defaults.baseURL = baseURL; 5 | }; 6 | -------------------------------------------------------------------------------- /libs/shared/apis/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/shared/apis/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": [] 7 | }, 8 | "include": ["**/*.ts"], 9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/shared/apis/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /libs/shared/hooks/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@nrwl/react/babel"], 3 | "plugins": [] 4 | } 5 | -------------------------------------------------------------------------------- /libs/shared/hooks/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/shared/hooks/README.md: -------------------------------------------------------------------------------- 1 | # shared-hooks 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test shared-hooks` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/shared/hooks/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'shared-hooks', 4 | preset: '../../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }], 7 | }, 8 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 9 | coverageDirectory: '../../../coverage/libs/shared/hooks', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/shared/hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/shared-hooks", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/hooks/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared-hooks", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/shared/hooks/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "targets": { 8 | "lint": { 9 | "executor": "@nrwl/linter:eslint", 10 | "outputs": ["{options.outputFile}"], 11 | "options": { 12 | "lintFilePatterns": ["libs/shared/hooks/**/*.{ts,tsx,js,jsx}"] 13 | }, 14 | "configurations": { 15 | "fix": { 16 | "fix": true 17 | } 18 | } 19 | }, 20 | "test": { 21 | "executor": "@nrwl/jest:jest", 22 | "outputs": ["{workspaceRoot}/coverage/libs/shared/hooks"], 23 | "options": { 24 | "jestConfig": "libs/shared/hooks/jest.config.ts", 25 | "passWithNoTests": true 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libs/shared/hooks/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/use-timer/use-timer'; 2 | export * from './lib/use-debounced-callback/use-debounced-callback'; 3 | -------------------------------------------------------------------------------- /libs/shared/hooks/src/lib/use-debounced-callback/use-debounced-callback.spec.ts: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react'; 2 | import useDebouncedCallback from './use-debounced-callback'; 3 | 4 | describe('useDebouncedCallback', () => { 5 | it('should render successfully', () => { 6 | // eslint-disable-next-line @typescript-eslint/no-empty-function 7 | const { result } = renderHook(() => useDebouncedCallback(() => {}, 0)); 8 | 9 | expect(result.current()).toBe(undefined); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /libs/shared/hooks/src/lib/use-debounced-callback/use-debounced-callback.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | export function useDebouncedCallback( 4 | callback: (...args: A) => void, 5 | wait: number 6 | ): (...args: A) => void { 7 | // track args & timeout handle between calls 8 | const argsRef = useRef(); 9 | const timeout = useRef>(); 10 | 11 | function cleanup() { 12 | if (timeout.current) { 13 | clearTimeout(timeout.current); 14 | } 15 | } 16 | 17 | // make sure our timeout gets cleared if 18 | // our consuming component gets unmounted 19 | useEffect(() => cleanup, []); 20 | 21 | return function debouncedCallback(...args: A) { 22 | // capture latest args 23 | argsRef.current = args; 24 | 25 | // clear debounce timer 26 | cleanup(); 27 | 28 | // start waiting again 29 | timeout.current = setTimeout(() => { 30 | if (argsRef.current) { 31 | callback(...argsRef.current); 32 | } 33 | }, wait); 34 | }; 35 | } 36 | 37 | export default useDebouncedCallback; 38 | -------------------------------------------------------------------------------- /libs/shared/hooks/src/lib/use-timer/use-timer.spec.ts: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react'; 2 | import useTimer from './use-timer'; 3 | 4 | describe('useTimer', () => { 5 | it('should render successfully', () => { 6 | const { result } = renderHook(() => 7 | useTimer({ 8 | seconds: 1, 9 | // eslint-disable-next-line @typescript-eslint/no-empty-function 10 | onTimeEnd: () => {}, 11 | }) 12 | ); 13 | 14 | expect(result.current.timeLeft).toBe(1); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /libs/shared/hooks/src/lib/use-timer/use-timer.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-empty-interface 4 | export interface UseTimer { 5 | timeLeft: number; 6 | } 7 | 8 | export function useTimer({ 9 | seconds, 10 | onTimeEnd, 11 | }: { 12 | seconds: number; 13 | onTimeEnd?: () => void; 14 | }): UseTimer { 15 | const [timeLeft, setTimeLeft] = useState(seconds); 16 | 17 | useEffect(() => { 18 | if (!timeLeft) { 19 | onTimeEnd && onTimeEnd(); 20 | return; 21 | } 22 | const timeoutId = setTimeout(() => { 23 | setTimeLeft(timeLeft - 1); 24 | }, 1000); 25 | return () => clearTimeout(timeoutId); 26 | }, [onTimeEnd, timeLeft]); 27 | 28 | return { timeLeft }; 29 | } 30 | 31 | export default useTimer; 32 | -------------------------------------------------------------------------------- /libs/shared/hooks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitOverride": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true 14 | }, 15 | "files": [], 16 | "include": [], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.lib.json" 20 | }, 21 | { 22 | "path": "./tsconfig.spec.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/shared/hooks/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": [ 8 | "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", 9 | "../../../node_modules/@nrwl/react/typings/image.d.ts" 10 | ], 11 | "exclude": [ 12 | "**/*.spec.ts", 13 | "**/*.test.ts", 14 | "**/*.spec.tsx", 15 | "**/*.test.tsx", 16 | "**/*.spec.js", 17 | "**/*.test.js", 18 | "**/*.spec.jsx", 19 | "**/*.test.jsx", 20 | "jest.config.ts" 21 | ], 22 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] 23 | } 24 | -------------------------------------------------------------------------------- /libs/shared/hooks/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.test.ts", 10 | "**/*.spec.ts", 11 | "**/*.test.tsx", 12 | "**/*.spec.tsx", 13 | "**/*.test.js", 14 | "**/*.spec.js", 15 | "**/*.test.jsx", 16 | "**/*.spec.jsx", 17 | "**/*.d.ts", 18 | "jest.config.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /libs/shared/libs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/shared/libs/README.md: -------------------------------------------------------------------------------- 1 | # shared-libs 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build shared-libs` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test shared-libs` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /libs/shared/libs/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'shared-libs', 4 | preset: '../../../jest.preset.js', 5 | globals: { 6 | 'ts-jest': { 7 | tsconfig: '/tsconfig.spec.json', 8 | }, 9 | }, 10 | transform: { 11 | '^.+\\.[tj]s$': 'ts-jest', 12 | }, 13 | moduleFileExtensions: ['ts', 'js', 'html'], 14 | coverageDirectory: '../../../coverage/libs/shared/libs', 15 | }; 16 | -------------------------------------------------------------------------------- /libs/shared/libs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/shared-libs", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/libs/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared-libs", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/shared/libs/src", 5 | "targets": { 6 | "build": { 7 | "executor": "@nrwl/js:tsc", 8 | "outputs": ["{options.outputPath}"], 9 | "options": { 10 | "outputPath": "dist/libs/shared/libs", 11 | "main": "libs/shared/libs/src/index.ts", 12 | "tsConfig": "libs/shared/libs/tsconfig.lib.json", 13 | "assets": ["libs/shared/libs/*.md"] 14 | } 15 | }, 16 | "lint": { 17 | "executor": "@nrwl/linter:eslint", 18 | "outputs": ["{options.outputFile}"], 19 | "options": { 20 | "lintFilePatterns": ["libs/shared/libs/**/*.ts"] 21 | }, 22 | "configurations": { 23 | "fix": { 24 | "fix": true 25 | } 26 | } 27 | }, 28 | "test": { 29 | "executor": "@nrwl/jest:jest", 30 | "outputs": ["{workspaceRoot}/coverage/libs/shared/libs"], 31 | "options": { 32 | "jestConfig": "libs/shared/libs/jest.config.ts", 33 | "passWithNoTests": true 34 | } 35 | } 36 | }, 37 | "tags": [] 38 | } 39 | -------------------------------------------------------------------------------- /libs/shared/libs/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/analytics'; 2 | export * from './lib/error'; 3 | export * from './lib/remote-config'; 4 | export * from './lib/storage'; 5 | -------------------------------------------------------------------------------- /libs/shared/libs/src/lib/analytics.ts: -------------------------------------------------------------------------------- 1 | import { 2 | traverseObjectKeys, 3 | traverseObjectSliceStr, 4 | omit, 5 | } from '@nx-react-code-sharing/shared-utils'; 6 | 7 | const EVENT_TYPE_MAX_LENGTH = 40; 8 | 9 | export type EventType = 'test'; 10 | 11 | export interface IEventResult { 12 | eventType: EventType; 13 | [key: string]: any; 14 | } 15 | 16 | export function firebaseAnalyticsFactory( 17 | funcAnalytics: (eventName: string, params: object) => void, 18 | setUserId: (userId: string) => void, 19 | setCurrentScreen: (screenName: string) => void 20 | ) { 21 | function firebaseLogEvent(eventData: IEventResult) { 22 | const { eventType } = eventData; 23 | 24 | if (!eventType) { 25 | throw new Error('eventType is not provided!'); 26 | } 27 | 28 | if (eventType.length > EVENT_TYPE_MAX_LENGTH) { 29 | throw new Error( 30 | `${eventType} has over ${EVENT_TYPE_MAX_LENGTH} characters!` 31 | ); 32 | } 33 | 34 | const isAllKeysUnderLength40 = traverseObjectKeys( 35 | omit(eventData, 'eventType'), 36 | (key: string) => key.length <= EVENT_TYPE_MAX_LENGTH 37 | ); 38 | 39 | if (!isAllKeysUnderLength40) { 40 | return; 41 | } 42 | 43 | const parameters = traverseObjectSliceStr( 44 | omit(eventData, 'eventType'), 45 | 100 46 | ); 47 | funcAnalytics(eventData.eventType, parameters); 48 | } 49 | return { 50 | setUserId: (userId: string) => { 51 | setUserId(userId); 52 | }, 53 | setCurrentScreen: (screenName: string) => { 54 | setCurrentScreen(screenName); 55 | }, 56 | test: () => { 57 | firebaseLogEvent({ 58 | eventType: 'test', 59 | }); 60 | }, 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /libs/shared/libs/src/lib/error.ts: -------------------------------------------------------------------------------- 1 | export enum ErrorCode { 2 | UNKOWN_ERROR = 0, 3 | FORBIDDEN_ERROR = 4001, 4 | NOT_FOUND = 4004, 5 | } 6 | 7 | interface IProps { 8 | status: number; 9 | body: string; 10 | } 11 | 12 | export class RNError extends Error { 13 | public status: number; 14 | 15 | constructor(props: IProps) { 16 | super(props.body); 17 | this.status = props.status; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/shared/libs/src/lib/remote-config.ts: -------------------------------------------------------------------------------- 1 | import { isJSON, isEmpty } from '@nx-react-code-sharing/shared-utils'; 2 | 3 | type RemoteConfigType = 'test'; 4 | 5 | export function remoteConfigFactory( 6 | getStringValue: (key: string) => Promise, 7 | getBooleanValue: (key: string) => Promise 8 | ) { 9 | const getStringWithDefault = async ( 10 | key: RemoteConfigType, 11 | defaultValue: string 12 | ) => { 13 | try { 14 | const value = await getStringValue(key); 15 | return !isEmpty(value) ? value : defaultValue; 16 | } catch (error) { 17 | return defaultValue; 18 | } 19 | }; 20 | 21 | const getBooleanWithDefault = async ( 22 | key: RemoteConfigType, 23 | defaultValue: boolean 24 | ) => { 25 | try { 26 | return await getBooleanValue(key); 27 | } catch (error) { 28 | return defaultValue; 29 | } 30 | }; 31 | 32 | const getJSONWithDefault = async ( 33 | key: RemoteConfigType, 34 | defaultValue: T 35 | ) => { 36 | const val = await getStringValue(key); 37 | if (!isJSON(val)) { 38 | return defaultValue; 39 | } 40 | try { 41 | return JSON.parse(val) as T; 42 | } catch (error) { 43 | // NOTHING 44 | } 45 | return defaultValue; 46 | }; 47 | 48 | const getRemoteConfigs = { 49 | test: () => { 50 | return getStringWithDefault('test', ''); 51 | }, 52 | }; 53 | 54 | return { 55 | ...getRemoteConfigs, 56 | getStringWithDefault, 57 | getBooleanWithDefault, 58 | getJSONWithDefault, 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /libs/shared/libs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/shared/libs/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": [] 7 | }, 8 | "include": ["**/*.ts"], 9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/shared/libs/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /libs/shared/stores/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@nrwl/react/babel"], 3 | "plugins": [] 4 | } 5 | -------------------------------------------------------------------------------- /libs/shared/stores/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/shared/stores/README.md: -------------------------------------------------------------------------------- 1 | # shared-stores 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test shared-stores` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/shared/stores/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'shared-stores', 4 | preset: '../../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }], 7 | }, 8 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 9 | coverageDirectory: '../../../coverage/libs/shared/stores', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/shared/stores/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/shared-stores", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/stores/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared-stores", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/shared/stores/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "targets": { 8 | "lint": { 9 | "executor": "@nrwl/linter:eslint", 10 | "outputs": ["{options.outputFile}"], 11 | "options": { 12 | "lintFilePatterns": ["libs/shared/stores/**/*.{ts,tsx,js,jsx}"] 13 | }, 14 | "configurations": { 15 | "fix": { 16 | "fix": true 17 | } 18 | } 19 | }, 20 | "test": { 21 | "executor": "@nrwl/jest:jest", 22 | "outputs": ["{workspaceRoot}/coverage/libs/shared/stores"], 23 | "options": { 24 | "jestConfig": "libs/shared/stores/jest.config.ts", 25 | "passWithNoTests": true 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libs/shared/stores/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/use-toast-store'; 2 | export * from './lib/use-todo-store'; 3 | -------------------------------------------------------------------------------- /libs/shared/stores/src/lib/use-toast-store.tsx: -------------------------------------------------------------------------------- 1 | import { uniqueId } from '@nx-react-code-sharing/shared-utils'; 2 | import produce from 'immer'; 3 | import create from 'zustand'; 4 | 5 | interface ToastProps { 6 | id: string; 7 | message: string; 8 | delay: number; 9 | } 10 | 11 | interface ToastStoreProps { 12 | data: Record; 13 | showToastWithDelay: (message: string, delaySeconds: number | null) => void; 14 | showToast: (message: string) => void; 15 | dismissToast: (id: string) => void; 16 | } 17 | 18 | const DEFAULT_DELAY_SECONDS = 1500; 19 | 20 | export const useToastStore = create((set, get) => ({ 21 | data: {}, 22 | showToastWithDelay: (message: string, delaySeconds: number | null) => { 23 | const id = uniqueId('toast'); 24 | set( 25 | produce((state) => { 26 | state.data[id] = { 27 | delay: delaySeconds || DEFAULT_DELAY_SECONDS, 28 | id, 29 | message, 30 | }; 31 | }) 32 | ); 33 | }, 34 | showToast: (message: string) => { 35 | get().showToastWithDelay(message, DEFAULT_DELAY_SECONDS); 36 | }, 37 | dismissToast: (id: string) => { 38 | set( 39 | produce((state) => { 40 | if (state.data[id]) { 41 | delete state.data[id]; 42 | } 43 | }) 44 | ); 45 | }, 46 | })); 47 | -------------------------------------------------------------------------------- /libs/shared/stores/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitOverride": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true 14 | }, 15 | "files": [], 16 | "include": [], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.lib.json" 20 | }, 21 | { 22 | "path": "./tsconfig.spec.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/shared/stores/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": [ 8 | "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", 9 | "../../../node_modules/@nrwl/react/typings/image.d.ts" 10 | ], 11 | "exclude": [ 12 | "**/*.spec.ts", 13 | "**/*.test.ts", 14 | "**/*.spec.tsx", 15 | "**/*.test.tsx", 16 | "**/*.spec.js", 17 | "**/*.test.js", 18 | "**/*.spec.jsx", 19 | "**/*.test.jsx", 20 | "jest.config.ts" 21 | ], 22 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] 23 | } 24 | -------------------------------------------------------------------------------- /libs/shared/stores/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.test.ts", 10 | "**/*.spec.ts", 11 | "**/*.test.tsx", 12 | "**/*.spec.tsx", 13 | "**/*.test.js", 14 | "**/*.spec.js", 15 | "**/*.test.jsx", 16 | "**/*.spec.jsx", 17 | "**/*.d.ts", 18 | "jest.config.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /libs/shared/ui-components/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@nrwl/next/babel"], 3 | "plugins": [["react-native-web", { "commonjs": true }]] 4 | } 5 | -------------------------------------------------------------------------------- /libs/shared/ui-components/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/shared/ui-components/.storybook/main.js: -------------------------------------------------------------------------------- 1 | const rootMain = require('../../../../.storybook/main'); 2 | 3 | module.exports = { 4 | ...rootMain, 5 | 6 | core: { ...rootMain.core, builder: 'webpack5' }, 7 | 8 | stories: [ 9 | ...rootMain.stories, 10 | '../../../features/**/*.stories.mdx', 11 | '../../../features/**/*.stories.@(js|jsx|ts|tsx)', 12 | '../src/lib/**/*.stories.mdx', 13 | '../src/lib/**/*.stories.@(js|jsx|ts|tsx)', 14 | ], 15 | addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'], 16 | staticDirs: ['../../../images/src/lib/public'], 17 | webpackFinal: async (config, { configType }) => { 18 | // apply any global webpack configs that might have been specified in .storybook/main.js 19 | if (rootMain.webpackFinal) { 20 | config = await rootMain.webpackFinal(config, { configType }); 21 | } 22 | 23 | // add your own webpack tweaks if needed 24 | 25 | return config; 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /libs/shared/ui-components/.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; 2 | 3 | export const parameters = { 4 | layout: 'fullscreen', 5 | options: { 6 | storySort: { 7 | method: 'alphabetical', 8 | order: [], 9 | locales: '', 10 | }, 11 | }, 12 | viewport: { 13 | viewports: { 14 | ...INITIAL_VIEWPORTS, 15 | }, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /libs/shared/ui-components/.storybook/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "emitDecoratorMetadata": true, 5 | "outDir": "" 6 | }, 7 | "files": [ 8 | "../../../../types/global.d.ts", 9 | "../../../../node_modules/@nrwl/react/typings/styled-jsx.d.ts", 10 | "../../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", 11 | "../../../../node_modules/@nrwl/react/typings/image.d.ts" 12 | ], 13 | "exclude": [ 14 | "../**/*.spec.ts", 15 | "../**/*.spec.js", 16 | "../**/*.spec.tsx", 17 | "../**/*.spec.jsx", 18 | "jest.config.ts" 19 | ], 20 | "include": ["../src/**/*", "*.js"] 21 | } 22 | -------------------------------------------------------------------------------- /libs/shared/ui-components/README.md: -------------------------------------------------------------------------------- 1 | # shared-ui-components 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test shared-ui-components` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/shared/ui-components/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'shared-ui-components', 4 | preset: '../../../jest.preset.js', 5 | transform: { 6 | '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest', 7 | '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/next/babel'] }], 8 | }, 9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 10 | coverageDirectory: '../../../coverage/libs/shared/ui-components', 11 | }; 12 | -------------------------------------------------------------------------------- /libs/shared/ui-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/shared-ui-components", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/ui-components/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared-ui-components", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/shared/ui-components/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "targets": { 8 | "lint": { 9 | "executor": "@nrwl/linter:eslint", 10 | "outputs": ["{options.outputFile}"], 11 | "options": { 12 | "lintFilePatterns": ["libs/shared/ui-components/**/*.{ts,tsx,js,jsx}"] 13 | }, 14 | "configurations": { 15 | "fix": { 16 | "fix": true 17 | } 18 | } 19 | }, 20 | "test": { 21 | "executor": "@nrwl/jest:jest", 22 | "outputs": ["{workspaceRoot}/coverage/libs/shared/ui-components"], 23 | "options": { 24 | "jestConfig": "libs/shared/ui-components/jest.config.ts", 25 | "passWithNoTests": true 26 | } 27 | }, 28 | "storybook": { 29 | "executor": "@nrwl/storybook:storybook", 30 | "options": { 31 | "uiFramework": "@storybook/react", 32 | "port": 4400, 33 | "config": { 34 | "configFolder": "libs/shared/ui-components/.storybook" 35 | } 36 | }, 37 | "configurations": { 38 | "ci": { 39 | "quiet": true 40 | } 41 | } 42 | }, 43 | "build-storybook": { 44 | "executor": "@nrwl/storybook:build", 45 | "outputs": ["{options.outputPath}"], 46 | "options": { 47 | "uiFramework": "@storybook/react", 48 | "outputPath": "dist/storybook/components", 49 | "config": { 50 | "configFolder": "libs/shared/ui-components/.storybook" 51 | } 52 | }, 53 | "configurations": { 54 | "ci": { 55 | "quiet": true 56 | } 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './lib/text/text'; 2 | export * from './lib/image/image'; 3 | export * from './lib/typography/typography'; 4 | export * from './lib/xeicon/xeicon'; 5 | export * from './lib/others'; 6 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/image/image.spec.tsx: -------------------------------------------------------------------------------- 1 | import { getImages } from "@nx-react-code-sharing/images"; 2 | import { render } from '@testing-library/react'; 3 | 4 | import Image from './image'; 5 | 6 | describe('Image', () => { 7 | it('should render successfully', () => { 8 | const { baseElement } = render( 9 | 10 | ); 11 | expect(baseElement).toBeTruthy(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/image/image.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getImages } from '@nx-react-code-sharing/images'; 2 | import { Story, Meta } from '@storybook/react'; 3 | import { Image, ImageProps } from './image'; 4 | 5 | export default { 6 | component: Image, 7 | title: 'Image', 8 | } as Meta; 9 | 10 | const Template: Story = (args) => ; 11 | 12 | export const Primary = Template.bind({}); 13 | Primary.args = { 14 | style: { 15 | width: 100, 16 | height: 100, 17 | }, 18 | source: { 19 | uri: getImages().iconImages.storybook, 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/image/image.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Image as RNImage, ImageProps as RNImageProps } from 'react-native'; 3 | 4 | /* eslint-disable-next-line */ 5 | export interface ImageProps extends RNImageProps { 6 | alt: string; 7 | } 8 | 9 | export function Image(props: ImageProps) { 10 | return ; 11 | } 12 | 13 | export default Image; 14 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/others/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './seo/seo'; 2 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/others/seo/seo.spec.tsx: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | 3 | import SEO from './seo'; 4 | 5 | describe('SEO', () => { 6 | it('should render successfully', () => { 7 | const { baseElement } = render( 8 | 9 | ); 10 | expect(baseElement).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/styles/colors.ts: -------------------------------------------------------------------------------- 1 | export const colors = { 2 | black50: '#80000000', 3 | black70: 'rgba(33,33,33,.7)', 4 | white: '#ffffff', 5 | gray20: '#fafafa', 6 | gray50: '#f5f5f5', 7 | gray100: '#f0f0f0', 8 | gray200: '#eaeaea', 9 | gray300: '#e2e2e2', 10 | gray400: '#d5d5d5', 11 | gray450: '#aaaaaa', 12 | gray500: '#909090', 13 | gray700: '#555555', 14 | gray900: '#212121', 15 | green20: '#ecf8f4', 16 | green50: '#daf1e9', 17 | green200: '#c7ebdf', 18 | green300: '#8ed7bf', 19 | green400: '#69c9a9', 20 | green500: '#43bc94', 21 | green550: '#369676', 22 | green600: '#287159', 23 | green700: '#1b4b3b', 24 | red20: '#fee7e7', 25 | red50: '#fdcecf', 26 | red200: '#fcb6b8', 27 | red300: '#fb9396', 28 | red400: '#f96c70', 29 | red500: '#e9494e', 30 | red550: '#cc3337', 31 | red600: '#a3292c', 32 | red700: '#661a1b', 33 | purple20: '#ece5fa', 34 | purple50: '#dfd4f7', 35 | purple200: '#d0bff3', 36 | purple300: '#b398eb', 37 | purple400: '#a07fe6', 38 | purple500: '#9069e2', 39 | purple550: '#7747db', 40 | purple600: '#6433cc', 41 | purple700: '#46248f', 42 | sunflower: '#ffc310', 43 | }; 44 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/styles/z-index.ts: -------------------------------------------------------------------------------- 1 | export const zIndex = Object.freeze({ 2 | lowest: 0, 3 | veryLow: 1, 4 | low: 3, 5 | middle: 5, 6 | high: 7, 7 | veryHigh: 9, 8 | highest: 100, 9 | }); 10 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/text/text.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | 4 | import Text from './text'; 5 | 6 | describe('Text', () => { 7 | it('should render successfully', () => { 8 | const { baseElement } = render(test); 9 | expect(baseElement).toBeTruthy(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/text/text.stories.tsx: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react'; 2 | import { RNText, TextProps } from './text'; 3 | 4 | export default { 5 | component: RNText, 6 | title: 'Text', 7 | } as Meta; 8 | 9 | const Template: Story = (args) => ( 10 | Hello World 11 | ); 12 | 13 | export const Primary = Template.bind({}); 14 | Primary.args = {}; 15 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/text/text.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, TextProps as RNTextProps } from 'react-native'; 3 | import { colors } from "../styles/colors"; 4 | 5 | type FontWeight = 'BOLD' | 'MEDIUM' | 'REGULAR'; 6 | 7 | /* eslint-disable-next-line */ 8 | export interface TextProps extends RNTextProps { 9 | style?: RNTextProps['style']; 10 | sizeStyle?: RNTextProps['style']; 11 | fontWeight?: FontWeight; 12 | children: React.ReactNode; 13 | } 14 | 15 | const fontWeightBy: { [key in FontWeight]: string } = { 16 | BOLD: 'NotoSansKR-Bold', 17 | MEDIUM: 'NotoSansKR-Medium', 18 | REGULAR: 'NotoSansKR-Regular', 19 | }; 20 | 21 | const styles = StyleSheet.create({ 22 | text: { 23 | letterSpacing: -0.5, 24 | color: colors.gray900, 25 | }, 26 | }); 27 | 28 | export function RNText({ 29 | style, 30 | sizeStyle, 31 | fontWeight = 'REGULAR', 32 | ...props 33 | }: TextProps) { 34 | return ; 35 | } 36 | 37 | export default RNText; 38 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/typography/typography.spec.tsx: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | 3 | import { Bold } from './typography'; 4 | 5 | describe('Typography', () => { 6 | it('should render successfully Bold10', () => { 7 | const { baseElement } = render(test); 8 | expect(baseElement).toBeTruthy(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/typography/typography.stories.tsx: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react'; 2 | import { StyleSheet } from 'react-native'; 3 | import { Bold } from './typography'; 4 | 5 | export default { 6 | title: 'Typography', 7 | } as Meta; 8 | 9 | const styles = StyleSheet.create({ 10 | container: { 11 | display: 'flex', 12 | flex: 1, 13 | flexDirection: 'column', 14 | }, 15 | }); 16 | 17 | const Template: Story = () => { 18 | return ( 19 |
20 | Bold.Bold8 21 | Bold.Bold10 22 | Bold.Bold12 23 | Bold.Bold13 24 | Bold.Bold14 25 |
26 | ); 27 | }; 28 | 29 | export const Primary = Template.bind({}); 30 | Primary.args = {}; 31 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/xeicon/xeicon.spec.tsx: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | 3 | import XEIcon from './xeicon'; 4 | 5 | describe('XEIcon', () => { 6 | it('should render successfully', () => { 7 | const { baseElement } = render(); 8 | expect(baseElement).toBeTruthy(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/xeicon/xeicon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react'; 2 | import { XEIcon, XEIconProps } from './xeicon'; 3 | 4 | export default { 5 | component: XEIcon, 6 | title: 'XEIcon', 7 | } as Meta; 8 | 9 | const Template: Story = (args) => ; 10 | 11 | export const Primary = Template.bind({}); 12 | Primary.args = {}; 13 | -------------------------------------------------------------------------------- /libs/shared/ui-components/src/lib/xeicon/xeicon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text } from 'react-native'; 3 | 4 | /* eslint-disable-next-line */ 5 | export interface XEIconProps {} 6 | 7 | const styles = StyleSheet.create({ 8 | xeicon: { 9 | color: 'pink', 10 | }, 11 | }); 12 | 13 | export function XEIcon(props: XEIconProps) { 14 | return XEIcon; 15 | } 16 | 17 | export default XEIcon; 18 | -------------------------------------------------------------------------------- /libs/shared/ui-components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "allowJs": true, 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitOverride": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true 14 | }, 15 | "files": [], 16 | "include": [], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.lib.json" 20 | }, 21 | { 22 | "path": "./tsconfig.spec.json" 23 | }, 24 | { 25 | "path": "./.storybook/tsconfig.json" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /libs/shared/ui-components/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": [ 8 | "../../../types/global.d.ts", 9 | "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", 10 | "../../../node_modules/@nrwl/react/typings/image.d.ts" 11 | ], 12 | "exclude": [ 13 | "**/*.spec.ts", 14 | "**/*.test.ts", 15 | "**/*.spec.tsx", 16 | "**/*.test.tsx", 17 | "**/*.spec.js", 18 | "**/*.test.js", 19 | "**/*.spec.jsx", 20 | "**/*.test.jsx", 21 | "**/*.stories.ts", 22 | "**/*.stories.js", 23 | "**/*.stories.jsx", 24 | "**/*.stories.tsx", 25 | "jest.config.ts" 26 | ], 27 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] 28 | } 29 | -------------------------------------------------------------------------------- /libs/shared/ui-components/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["../../../types/global.d.ts"], 9 | "include": [ 10 | "**/*.test.ts", 11 | "**/*.spec.ts", 12 | "**/*.test.tsx", 13 | "**/*.spec.tsx", 14 | "**/*.test.js", 15 | "**/*.spec.js", 16 | "**/*.test.jsx", 17 | "**/*.spec.jsx", 18 | "**/*.d.ts", 19 | "jest.config.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/shared/utils/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]] 3 | } 4 | -------------------------------------------------------------------------------- /libs/shared/utils/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/shared/utils/README.md: -------------------------------------------------------------------------------- 1 | # shared-utils 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build shared-utils` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test shared-utils` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /libs/shared/utils/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'shared-utils', 4 | preset: '../../../jest.preset.js', 5 | globals: { 6 | 'ts-jest': { 7 | tsconfig: '/tsconfig.spec.json', 8 | }, 9 | }, 10 | transform: { 11 | '^.+\\.[tj]s$': 'ts-jest', 12 | }, 13 | moduleFileExtensions: ['ts', 'js', 'html'], 14 | coverageDirectory: '../../../coverage/libs/shared/utils', 15 | }; 16 | -------------------------------------------------------------------------------- /libs/shared/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-react-code-sharing/shared-utils", 3 | "version": "0.0.1", 4 | "sideEffects": false 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/utils/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared-utils", 3 | "$schema": "../../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/shared/utils/src", 5 | "targets": { 6 | "build": { 7 | "executor": "@nrwl/js:tsc", 8 | "outputs": ["{options.outputPath}"], 9 | "options": { 10 | "outputPath": "dist/libs/shared/utils", 11 | "main": "libs/shared/utils/src/index.ts", 12 | "tsConfig": "libs/shared/utils/tsconfig.lib.json", 13 | "assets": ["libs/shared/utils/*.md"] 14 | } 15 | }, 16 | "lint": { 17 | "executor": "@nrwl/linter:eslint", 18 | "outputs": ["{options.outputFile}"], 19 | "options": { 20 | "lintFilePatterns": ["libs/shared/utils/**/*.ts"] 21 | }, 22 | "configurations": { 23 | "fix": { 24 | "fix": true 25 | } 26 | } 27 | }, 28 | "test": { 29 | "executor": "@nrwl/jest:jest", 30 | "outputs": ["{workspaceRoot}/coverage/libs/shared/utils"], 31 | "options": { 32 | "jestConfig": "libs/shared/utils/jest.config.ts", 33 | "passWithNoTests": true 34 | } 35 | } 36 | }, 37 | "tags": [] 38 | } 39 | -------------------------------------------------------------------------------- /libs/shared/utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/common'; 2 | export * from './lib/json'; 3 | export * from './lib/object'; 4 | export * from './lib/string'; 5 | export * from './lib/uri'; 6 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/__tests__/common.test.ts: -------------------------------------------------------------------------------- 1 | import { cond, uniqueId, omit, once, sortedObject } from '../common'; 2 | 3 | describe('common test', () => { 4 | test('cond test', () => { 5 | const siteMetadataMap = cond([ 6 | { 7 | key: { isProduction: false }, 8 | value: { 9 | description: 'development', 10 | }, 11 | }, 12 | { 13 | key: { isProduction: true }, 14 | value: { 15 | description: 'production', 16 | }, 17 | }, 18 | ]); 19 | expect(siteMetadataMap({ isProduction: false })).toEqual({ 20 | description: 'development', 21 | }); 22 | expect(siteMetadataMap({ isProduction: true })).toEqual({ 23 | description: 'production', 24 | }); 25 | }); 26 | 27 | test('sortedObject test', () => { 28 | expect(JSON.stringify(sortedObject({ a: 1, b: 2 }))).toEqual( 29 | JSON.stringify(sortedObject({ b: 2, a: 1 })) 30 | ); 31 | }); 32 | test('sorting test', () => { 33 | const arr = ['4', '1', '2', '3']; 34 | expect( 35 | arr.sort((a: string, b: string) => { 36 | return a > b ? 1 : -1; 37 | }) 38 | ).toEqual(['1', '2', '3', '4']); 39 | }); 40 | 41 | test('uniqueId test', () => { 42 | const test0 = uniqueId('test'); 43 | const test1 = uniqueId('test'); 44 | const test20 = uniqueId('test2'); 45 | 46 | expect(test0).toEqual('test0'); 47 | expect(test1).toEqual('test1'); 48 | expect(test20).toEqual('test20'); 49 | }); 50 | 51 | test('omit test', () => { 52 | const data = { a: 1, b: 2, c: 3 }; 53 | const res = omit(data, 'a', 'b'); 54 | expect(res.c).toEqual(3); 55 | }); 56 | 57 | test('once test', () => { 58 | const add = (a: number, b: number) => { 59 | return a + b; 60 | }; 61 | const res = once(add); 62 | expect(res(1, 2)).toEqual(3); 63 | expect(res(1, 2)).toEqual(3); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/__tests__/string.test.ts: -------------------------------------------------------------------------------- 1 | import { traverseObjectKeys, traverseObjectSliceStr } from '../string'; 2 | 3 | describe('string', () => { 4 | it('traverseObjectKeys', () => { 5 | traverseObjectKeys( 6 | { 7 | a: 1, 8 | b: '1', 9 | c: null, 10 | d: undefined, 11 | }, 12 | (key) => key.length <= 40 13 | ); 14 | 15 | traverseObjectKeys( 16 | { 17 | a: [ 18 | 'test', 19 | 'test1', 20 | 'sdkfndsajk;fsanfkasndfk;adfadskfd;sdnfksdfa;lsfndkfnds;kldalfndas;klfadsfndslf;kadsnfl;adsknkldfnaskfnasd;', 21 | ], 22 | }, 23 | (key) => key.length <= 40 24 | ); 25 | }); 26 | 27 | it('traverseObjectSliceStr', () => { 28 | expect( 29 | traverseObjectSliceStr( 30 | { 31 | a: 1, 32 | b: 'test', 33 | c: '12345623948290432432084092348903423', 34 | d: ['dsa;lfsalnsd', 'kadsf;alsdnfasf;asnkf;'], 35 | e: null, 36 | f: undefined, 37 | h: { 38 | a: 1, 39 | b: 'test', 40 | c: '12345623948290432432084092348903423', 41 | d: ['dsa;lfsalnsd', 'kadsf;alsdnfasf;asnkf;'], 42 | e: null, 43 | f: undefined, 44 | }, 45 | }, 46 | 10 47 | ) 48 | ).toEqual({ 49 | a: 1, 50 | b: 'test', 51 | c: '1234562394', 52 | d: ['dsa;lfsaln', 'kadsf;alsd'], 53 | e: null, 54 | f: undefined, 55 | h: { 56 | a: 1, 57 | b: 'test', 58 | c: '1234562394', 59 | d: ['dsa;lfsaln', 'kadsf;alsd'], 60 | e: null, 61 | f: undefined, 62 | }, 63 | }); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/__tests__/uri.test.ts: -------------------------------------------------------------------------------- 1 | import { makeQueryParams } from '../uri'; 2 | 3 | describe('uri test', () => { 4 | test('uri normal test', () => { 5 | const search = '?width=50&height=50'; 6 | expect(makeQueryParams(search)).toEqual({ width: '50', height: '50' }); 7 | }); 8 | test('uri empty test', () => { 9 | const search = ''; 10 | expect(makeQueryParams(search, { width: 50, height: 50 })).toEqual({ 11 | width: 50, 12 | height: 50, 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/json.ts: -------------------------------------------------------------------------------- 1 | export function isJSON(str: string) { 2 | try { 3 | const obj = JSON.parse(str); 4 | if (obj && typeof obj === 'object' && obj !== null) { 5 | return true; 6 | } 7 | } catch (err) { 8 | // NOTHING 9 | } 10 | return false; 11 | } 12 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/object.ts: -------------------------------------------------------------------------------- 1 | export function callValue(supplier: () => T, defaultValue: T) { 2 | try { 3 | const value = supplier(); 4 | return value || defaultValue; 5 | } catch (err) { 6 | // console.error(supplier); 7 | return defaultValue; 8 | } 9 | } 10 | 11 | export function getKeys(obj: T): (keyof T)[] { 12 | return Object.keys(obj) as (keyof T)[]; 13 | } 14 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/string.ts: -------------------------------------------------------------------------------- 1 | export const toInteger = (value: string | null) => { 2 | if (!value) { 3 | return 0; 4 | } 5 | const floatValue = parseFloat(value); 6 | 7 | if (!floatValue) { 8 | return 0; 9 | } 10 | 11 | return Math.round(floatValue); 12 | }; 13 | 14 | export const noInfoIfZero = (price: string | null) => { 15 | const zeroPrices = ['0', '0원', 0]; 16 | if (zeroPrices.some((zeroPrice) => zeroPrice === price)) { 17 | return '가격 정보 없음'; 18 | } 19 | return price; 20 | }; 21 | 22 | export const traverseObjectKeys = ( 23 | o: { [key: string]: any }, 24 | predicate: (key: string) => boolean 25 | ) => { 26 | const keys = Object.keys(o); 27 | for (const key of keys) { 28 | let keyPredicateResult; 29 | if (typeof o[key] === 'object' && o[key] !== null) { 30 | keyPredicateResult = traverseObjectKeys(o[key], predicate); 31 | } else { 32 | keyPredicateResult = predicate(key); 33 | } 34 | 35 | if (keyPredicateResult === false) { 36 | return false; 37 | } 38 | } 39 | 40 | return true; 41 | }; 42 | 43 | export const traverseObjectSliceStr = ( 44 | o: { [key: string]: any }, 45 | maxLength: number 46 | ) => { 47 | const keys = Object.keys(o); 48 | for (const key of keys) { 49 | if (typeof o[key] === 'object' && o[key] !== null) { 50 | o[key] = traverseObjectSliceStr(o[key], maxLength); 51 | } else if (typeof o[key] === 'string') { 52 | o[key] = o[key].substr(0, maxLength); 53 | } 54 | } 55 | return o; 56 | }; 57 | -------------------------------------------------------------------------------- /libs/shared/utils/src/lib/uri.ts: -------------------------------------------------------------------------------- 1 | import * as qs from 'qs'; 2 | 3 | import { isEmpty } from './common'; 4 | 5 | export const makeQueryParams = (search: string, defaultValue?: T) => { 6 | const response: T = qs.parse(search.substring(1)) as any; 7 | if (isEmpty(response)) { 8 | return defaultValue; 9 | } 10 | return response; 11 | }; 12 | -------------------------------------------------------------------------------- /libs/shared/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ], 13 | "compilerOptions": { 14 | "forceConsistentCasingInFileNames": true, 15 | "strict": true, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": true, 18 | "allowSyntheticDefaultImports": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libs/shared/utils/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": [] 7 | }, 8 | "files": ["../../../types/global.d.ts"], 9 | "include": ["**/*.ts"], 10 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /libs/shared/utils/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["../../../types/global.d.ts"], 9 | "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 3 | "npmScope": "nx-react-code-sharing", 4 | "affected": { 5 | "defaultBase": "master" 6 | }, 7 | "tasksRunnerOptions": { 8 | "default": { 9 | "runner": "@nrwl/nx-cloud", 10 | "options": { 11 | "cacheableOperations": ["build", "lint", "test", "e2e"], 12 | "accessToken": "OTMzNGZiYjktOGY2OS00MDBjLWJmOTItNTI5N2RmMGY5YzIwfHJlYWQtd3JpdGU=" 13 | } 14 | } 15 | }, 16 | "generators": { 17 | "@nrwl/react": { 18 | "application": { 19 | "babel": true 20 | } 21 | }, 22 | "@nrwl/next": { 23 | "application": { 24 | "linter": "eslint" 25 | } 26 | } 27 | }, 28 | "defaultProject": "nextjs-app", 29 | "targetDefaults": { 30 | "build": { 31 | "dependsOn": ["^build"], 32 | "inputs": ["production", "^production"] 33 | }, 34 | "e2e": { 35 | "inputs": ["default", "^production"] 36 | }, 37 | "test": { 38 | "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"] 39 | }, 40 | "lint": { 41 | "inputs": ["default", "{workspaceRoot}/.eslintrc.json"] 42 | }, 43 | "build-storybook": { 44 | "inputs": ["default", "^production", "{workspaceRoot}/.storybook/**/*"] 45 | } 46 | }, 47 | "namedInputs": { 48 | "default": ["{projectRoot}/**/*", "sharedGlobals"], 49 | "sharedGlobals": ["{workspaceRoot}/babel.config.json"], 50 | "production": [ 51 | "default", 52 | "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", 53 | "!{projectRoot}/tsconfig.spec.json", 54 | "!{projectRoot}/jest.config.[jt]s", 55 | "!{projectRoot}/.eslintrc.json", 56 | "!{projectRoot}/.storybook/**/*", 57 | "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)" 58 | ] 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /plopfile.mjs: -------------------------------------------------------------------------------- 1 | import { uiComponentsPlop } from './tools/generators/plop-templates/ui-components/plopfile.mjs'; 2 | 3 | export default function (plop) { 4 | uiComponentsPlop(plop); 5 | } 6 | -------------------------------------------------------------------------------- /tools/generators/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoBeenLee/nx-react-code-sharing-starter/c0f1779487a03da5248130a247f38889dc850acd/tools/generators/.gitkeep -------------------------------------------------------------------------------- /tools/generators/plop-templates/ui-components/component.spec.txt: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | 3 | import -- PLOP COMPONENT NAME HERE -- from './-- PLOP COMPONENT FOLDER NAME HERE --'; 4 | 5 | describe('-- PLOP COMPONENT NAME HERE --', () => { 6 | it('should render successfully', () => { 7 | const { baseElement } = render( 8 | <-- PLOP COMPONENT NAME HERE -- /> 9 | ); 10 | expect(baseElement).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /tools/generators/plop-templates/ui-components/component.stories.txt: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react'; 2 | import { -- PLOP COMPONENT NAME HERE --, -- PLOP COMPONENT NAME HERE --Props } from './-- PLOP COMPONENT FOLDER NAME HERE --'; 3 | 4 | export default { 5 | component: -- PLOP COMPONENT NAME HERE --, 6 | title: '-- PLOP COMPONENT NAME HERE --', 7 | argTypes: {}, 8 | } as Meta; 9 | 10 | const Template: Story<-- PLOP COMPONENT NAME HERE --Props> = (args) => <-- PLOP COMPONENT NAME HERE -- {...args} />; 11 | 12 | export const Primary = Template.bind({}); 13 | Primary.args = {}; 14 | -------------------------------------------------------------------------------- /tools/generators/plop-templates/ui-components/component.txt: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Text } from 'react-native'; 2 | 3 | const styles = StyleSheet.create({ 4 | -- PLOP COMPONENT NAME HERE --: { 5 | color: 'pink', 6 | }, 7 | }); 8 | 9 | export interface -- PLOP COMPONENT NAME HERE --Props {} 10 | 11 | export function -- PLOP COMPONENT NAME HERE --(props: -- PLOP COMPONENT NAME HERE --Props) { 12 | return hello world; 13 | } 14 | 15 | export default -- PLOP COMPONENT NAME HERE --; 16 | -------------------------------------------------------------------------------- /tools/generators/utils/index.mjs: -------------------------------------------------------------------------------- 1 | export const camelize = (str) => { 2 | return str 3 | .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { 4 | return index === 0 ? word.toLowerCase() : word.toUpperCase(); 5 | }) 6 | .replace(/\s+/g, ''); 7 | }; 8 | 9 | export const toUppercaseFirstLetter = (str) => { 10 | return str.charAt(0).toUpperCase() + str.slice(1); 11 | }; 12 | 13 | export const toKebabCase = (str) => { 14 | return str.toLowerCase().replace(/ /g, '-'); 15 | }; 16 | 17 | export const toPascalCase = (str) => { 18 | return toUppercaseFirstLetter(camelize(str)); 19 | }; 20 | 21 | export const toExtensionTxtToTsx = (str) => { 22 | return str.toLowerCase().replace(/txt/g, 'tsx'); 23 | }; 24 | 25 | export const toFileNameWithExtensionTsx = ( 26 | componentFileName, 27 | componentName 28 | ) => { 29 | return toExtensionTxtToTsx(componentFileName).replace( 30 | `component`, 31 | componentName 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /tools/tsconfig.tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../dist/out-tsc/tools", 5 | "rootDir": ".", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": ["node"], 9 | "importHelpers": false 10 | }, 11 | "include": ["**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "importHelpers": true, 11 | "target": "es2015", 12 | "module": "esnext", 13 | "lib": ["es2017", "dom"], 14 | "skipLibCheck": true, 15 | "skipDefaultLibCheck": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@nx-react-code-sharing/features-todo": [ 19 | "libs/features/todo/src/index.ts" 20 | ], 21 | "@nx-react-code-sharing/images": ["libs/images/src/index.ts"], 22 | "@nx-react-code-sharing/sdk": ["libs/sdk/src/index.ts"], 23 | "@nx-react-code-sharing/shared-apis": ["libs/shared/apis/src/index.ts"], 24 | "@nx-react-code-sharing/shared-hooks": ["libs/shared/hooks/src/index.ts"], 25 | "@nx-react-code-sharing/shared-libs": ["libs/shared/libs/src/index.ts"], 26 | "@nx-react-code-sharing/shared-stores": [ 27 | "libs/shared/stores/src/index.ts" 28 | ], 29 | "@nx-react-code-sharing/shared-ui-components": [ 30 | "libs/shared/ui-components/src/index.tsx" 31 | ], 32 | "@nx-react-code-sharing/shared-utils": ["libs/shared/utils/src/index.ts"] 33 | } 34 | }, 35 | "files": ["./types/global.d.ts"], 36 | "exclude": ["node_modules", "tmp"] 37 | } 38 | -------------------------------------------------------------------------------- /types/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.json'; 2 | declare module 'moment/min/moment-with-locales'; 3 | 4 | type Subtract = Pick>; 5 | type RetrieveAsyncFunc any> = 6 | ReturnType extends Promise ? U : never; 7 | type RemoveKeys> = Pick< 8 | T, 9 | Exclude 10 | >; 11 | type RequireProperty = T & { [K in P]-?: T[P] }; 12 | type NoUndefinedField = { 13 | [P in keyof T]-?: NoUndefinedField>; 14 | }; 15 | -------------------------------------------------------------------------------- /workspace.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/nx/schemas/workspace-schema.json", 3 | "version": 2, 4 | "projects": { 5 | "features-todo": "libs/features/todo", 6 | "images": "libs/images", 7 | "nextjs-app": "apps/nextjs-app", 8 | "nextjs-app-e2e": "apps/nextjs-app-e2e", 9 | "rn-app": "apps/rn-app", 10 | "rn-app-e2e": "apps/rn-app-e2e", 11 | "sdk": "libs/sdk", 12 | "shared-apis": "libs/shared/apis", 13 | "shared-hooks": "libs/shared/hooks", 14 | "shared-libs": "libs/shared/libs", 15 | "shared-stores": "libs/shared/stores", 16 | "shared-ui-components": "libs/shared/ui-components", 17 | "shared-utils": "libs/shared/utils", 18 | "standalone-nextjs-app": "apps/standalone-nextjs-app", 19 | "standalone-nextjs-app-e2e": "apps/standalone-nextjs-app-e2e" 20 | } 21 | } 22 | --------------------------------------------------------------------------------