diff --git a/boilerplate/app/app.tsx b/boilerplate/app/app.tsx index 1df69d5a9..c28eaaa02 100644 --- a/boilerplate/app/app.tsx +++ b/boilerplate/app/app.tsx @@ -16,6 +16,7 @@ if (__DEV__) { // If you turn it off in metro.config.js, you'll have to manually import it. require("./devtools/ReactotronConfig.ts") } +import "./utils/gestureHandler" import "./i18n" import "./utils/ignoreWarnings" import { useFonts } from "expo-font" @@ -28,8 +29,6 @@ import { ErrorBoundary } from "./screens/ErrorScreen/ErrorBoundary" import * as storage from "./utils/storage" import { customFontsToLoad } from "./theme" import Config from "./config" -import { GestureHandlerRootView } from "react-native-gesture-handler" -import { ViewStyle } from "react-native" export const NAVIGATION_PERSISTENCE_KEY = "NAVIGATION_STATE" @@ -102,20 +101,14 @@ function App(props: AppProps) { return ( - - - + ) } export default App - -const $container: ViewStyle = { - flex: 1, -} diff --git a/boilerplate/app/components/Text.test.tsx b/boilerplate/app/components/Text.test.tsx new file mode 100644 index 000000000..7368b7b5f --- /dev/null +++ b/boilerplate/app/components/Text.test.tsx @@ -0,0 +1,16 @@ +import { render } from "@testing-library/react-native" +import React from "react" + +import { Text } from "./Text" + +/* This is an example component test using react-native-testing-library. For more + * information on how to write your own, see the documentation here: + * https://callstack.github.io/react-native-testing-library/ */ +const testText = "Test string" + +describe("Text", () => { + it("should render the component", () => { + const { getByText } = render() + expect(getByText(testText)).toBeDefined() + }) +}) diff --git a/boilerplate/app/utils/gestureHandler.native.ts b/boilerplate/app/utils/gestureHandler.native.ts new file mode 100644 index 000000000..b72fc9463 --- /dev/null +++ b/boilerplate/app/utils/gestureHandler.native.ts @@ -0,0 +1,3 @@ +// Only import react-native-gesture-handler on native platforms +// https://reactnavigation.org/docs/drawer-navigator/#installation +import "react-native-gesture-handler" diff --git a/boilerplate/app/utils/gestureHandler.ts b/boilerplate/app/utils/gestureHandler.ts new file mode 100644 index 000000000..172371fd0 --- /dev/null +++ b/boilerplate/app/utils/gestureHandler.ts @@ -0,0 +1,2 @@ +// Don't import react-native-gesture-handler on web +// https://reactnavigation.org/docs/drawer-navigator/#installation diff --git a/boilerplate/jest.config.js b/boilerplate/jest.config.js index 426d6adc4..8b5505b41 100644 --- a/boilerplate/jest.config.js +++ b/boilerplate/jest.config.js @@ -1,34 +1,5 @@ -const { defaults: tsjPreset } = require("ts-jest/presets") - -const thirdPartyIgnorePatterns = [ - "((jest-)?react-native|@react-native(-community)?)", - "expo(nent)?", - "@expo(nent)?/.*", - "@expo-google-fonts/.*", - "react-navigation", - "@react-navigation/.*", - "@unimodules/.*", - "unimodules", - "sentry-expo", - "native-base", - "react-native-svg", - "react-clone-referenced-element", - "react-native-code-push", -] - /** @type {import('@jest/types').Config.ProjectConfig} */ module.exports = { - ...tsjPreset, preset: "jest-expo", - transformIgnorePatterns: [ - `/node_modules/(?!${thirdPartyIgnorePatterns.join("|")})`, - "jest-runner", - ], - testPathIgnorePatterns: ["/node_modules/", "/.maestro/", "@react-native"], setupFiles: ["/test/setup.ts"], - transform:{ - '^.+\\.test.tsx?$': ['ts-jest', { - tsconfig: '/test/test-tsconfig.json' - }] - } } diff --git a/boilerplate/package.json b/boilerplate/package.json index f56cffcdd..abde53625 100644 --- a/boilerplate/package.json +++ b/boilerplate/package.json @@ -69,10 +69,10 @@ "@babel/plugin-transform-template-literals": "^7.0.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", + "@testing-library/react-native": "^12.5.2", "@types/i18n-js": "3.8.2", "@types/jest": "^29.2.1", "@types/react": "~18.2.14", - "@types/react-test-renderer": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", "babel-jest": "^29.2.1", @@ -90,7 +90,6 @@ "patch-package": "^8.0.0", "postinstall-prepare": "1.0.1", "prettier": "2.8.8", - "react-test-renderer": "18.2.0", "reactotron-core-client": "^2.8.13", "reactotron-mst": "^3.1.7", "reactotron-react-js": "^3.3.11", diff --git a/docs/boilerplate/app/components/AutoImage.md b/docs/boilerplate/app/components/AutoImage.md index b53d6aa55..00b7d4ad0 100644 --- a/docs/boilerplate/app/components/AutoImage.md +++ b/docs/boilerplate/app/components/AutoImage.md @@ -6,6 +6,8 @@ sidebar_position: 30 Ignite's `AutoImage` Component is an enhanced version of the built-in React Native [Image](https://reactnative.dev/docs/image) component. It automatically resizes the image view to fit a max width or height constraint +![autoimage-component](https://github.com/user-attachments/assets/8fba1f1d-81d2-4f0d-84bb-8286b048ff16) + ```tsx ``` @@ -38,6 +40,8 @@ The `preset` prop is used to set the preset container style of the card. This af The `verticalAlignment` prop is used to set the vertical alignment of the card's content. This affects the alignment of the heading, content, and footer. There are four preconfigured alignments: `top`, `center`, `space-between`, and `force-footer-bottom`. `force-footer-bottom` behaves like `top`, but will force the footer to the bottom of the card. +![card-component-02](https://github.com/user-attachments/assets/e5e9f331-6c4d-4ce3-833d-a00fdf7244f1) + ```tsx diff --git a/docs/boilerplate/app/components/Header.md b/docs/boilerplate/app/components/Header.md index 16faa2f65..d09c0cfc5 100644 --- a/docs/boilerplate/app/components/Header.md +++ b/docs/boilerplate/app/components/Header.md @@ -6,6 +6,8 @@ sidebar_position: 34 The `Header` component is a component that will appear at the top of your screen. It is used to hold navigation buttons and the screen title. +![header-component](https://github.com/user-attachments/assets/ab308ec1-21e8-41dc-a7f3-bbc6cac866e0) + ```tsx
Alert.alert("Hello")} /> ``` diff --git a/docs/boilerplate/app/components/ListItem.md b/docs/boilerplate/app/components/ListItem.md index be2c87a2f..d8505383b 100644 --- a/docs/boilerplate/app/components/ListItem.md +++ b/docs/boilerplate/app/components/ListItem.md @@ -6,6 +6,8 @@ sidebar_position: 36 The `ListItem` component is a component that is used to display a single item in a list. It provides a lot of flexibility in terms of what you can do with it. It can be used to display a simple piece text, or a complex component with multiple actionable and custom styled elements inside. +![listitem-component](https://github.com/user-attachments/assets/009aed59-5597-4d0b-b861-972608ddb8ea) + ```tsx ``` diff --git a/docs/boilerplate/app/components/Text.md b/docs/boilerplate/app/components/Text.md index 53ef2473e..cc69daa6a 100644 --- a/docs/boilerplate/app/components/Text.md +++ b/docs/boilerplate/app/components/Text.md @@ -8,6 +8,8 @@ Ignite's `Text` Component is an enhanced version of the built-in React Native [` By enhancing the Ignite Text component and using it across your app, you can make sure the right fonts, font weight, and other styles and behaviors are shared across your whole app. +![text-component](https://github.com/user-attachments/assets/61277e64-c530-4043-93fe-5da41c9e9351) + ## Props ### `text` diff --git a/docs/boilerplate/app/components/TextField.md b/docs/boilerplate/app/components/TextField.md index fc4df40ed..ad9ef2a13 100644 --- a/docs/boilerplate/app/components/TextField.md +++ b/docs/boilerplate/app/components/TextField.md @@ -8,6 +8,8 @@ Ignite's `TextField` Component is an enhanced version of the built-in React Nati With this component you will be able to standardise TextInput component across your app. +![textfield-component](https://github.com/user-attachments/assets/cfdc97dc-5692-4286-8682-9243ee0e7650) + ```tsx import { TextField } from '../components'; diff --git a/docs/boilerplate/app/components/Toggle.md b/docs/boilerplate/app/components/Toggle.md index 2b0ff12d6..f7e6212f2 100644 --- a/docs/boilerplate/app/components/Toggle.md +++ b/docs/boilerplate/app/components/Toggle.md @@ -6,6 +6,8 @@ sidebar_position: 41 This component is a flexible component that can be used to toggle a boolean value. It can be used to render a switch, checkbox, or radio button, and exposes style props for every element. +![toggle-component](https://github.com/user-attachments/assets/ffbbe61e-9aea-4895-ab19-d38f76b3e379) + ## Props ### `variant` diff --git a/package.json b/package.json index 521aca0ac..e932f09cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ignite-cli", - "version": "9.8.0", + "version": "9.8.1", "description": "Infinite Red's hottest boilerplate for React Native.", "bin": { "ignite": "bin/ignite", diff --git a/src/commands/new.ts b/src/commands/new.ts index 3278c000a..a54a4b896 100644 --- a/src/commands/new.ts +++ b/src/commands/new.ts @@ -30,7 +30,11 @@ import { expoGoCompatExpectedVersions, findAndUpdateDependencyVersions, } from "../tools/expoGoCompatibility" -import { demoDependenciesToRemove, findAndRemoveDemoDependencies } from "../tools/demo" +import { + demoDependenciesToRemove, + findAndRemoveDemoDependencies, + findDemoPatches, +} from "../tools/demo" // deprecated: 'prebuild'. in favor of 'cng' instead. type Workflow = "expo" | "cng" | "prebuild" | "manual" @@ -601,6 +605,9 @@ module.exports = { if (removeDemo) { log(`Removing demo dependencies... ${demoDependenciesToRemove.join(", ")}`) packageJsonRaw = findAndRemoveDemoDependencies(packageJsonRaw) + const patchesToRemove = findDemoPatches() + log(`Removing demo patches... ${patchesToRemove}`) + patchesToRemove.forEach((patch) => filesystem.remove(patch)) } // - Then write it back out. diff --git a/src/tools/demo.ts b/src/tools/demo.ts index 55d33ab4d..9484e75ef 100644 --- a/src/tools/demo.ts +++ b/src/tools/demo.ts @@ -215,6 +215,14 @@ export const demoDependenciesToRemove = [ "react-native-drawer-layout", ] +export function findDemoPatches(): string[] { + const globs = demoDependenciesToRemove.map((dep) => `${dep}*.patch`) + const filePaths = filesystem.cwd("./patches").find({ + matching: globs, + }) + return filePaths +} + // This function takes a package.json file as a string and removes the dependencies // specified in demoDependenciesToRemove and returns the updated package.json as a string. export function findAndRemoveDemoDependencies(packageJsonRaw: string): string { diff --git a/test/vanilla/ignite-new.test.ts b/test/vanilla/ignite-new.test.ts index 5bf227490..c060de7e4 100644 --- a/test/vanilla/ignite-new.test.ts +++ b/test/vanilla/ignite-new.test.ts @@ -334,6 +334,51 @@ describe("ignite new", () => { }) }) }) + + // Yarn (only testing what might be affected by a different package manager: dependency installation, running commands) + describe(`ignite new ${APP_NAME} --debug --packager=yarn --workflow=cng --yes`, () => { + let tempDir: string + let result: string + let appPath: string + beforeAll(async () => { + tempDir = tempy.directory({ prefix: "ignite-" }) + + result = await runIgnite(`new ${APP_NAME} --debug --packager=yarn --workflow=cng --yes`, { + pre: `cd ${tempDir}`, + post: `cd ${originalDir}`, + }) + + appPath = filesystem.path(tempDir, APP_NAME) + }) + + afterAll(() => { + // console.log(tempDir) // uncomment for debugging, then run `code ` to see the generated app + filesystem.remove(tempDir) // clean up our mess + }) + + it("should print success message", () => { + // at some point this should probably be a snapshot? + expect(result).toContain("Now get cooking! 🍽") + }) + + it("should be able to use `generate` command and have pass output pass yarn test, yarn lint, and yarn compile scripts", async () => { + // other common test operations + const runOpts = { + pre: `cd ${appPath}`, + post: `cd ${originalDir}`, + } + + // #region Assert package.json Scripts Can Be Run + // run the tests; if they fail, run will raise and this test will fail + await run(`yarn test`, runOpts) + await run(`yarn lint`, runOpts) + await run(`yarn compile`, runOpts) + expect(await run("git diff HEAD --no-ext-diff", runOpts)).toBe("") + }) + // #endregion + + // we're done! + }) }) async function checkForLeftoverHelloWorld(filePath: string) {