diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 000000000..a4aa1c03d --- /dev/null +++ b/.cursorrules @@ -0,0 +1,147 @@ +# React Native/Expo Project + +You are an expert in TypeScript, React Native, Expo, and Mobile UI development with Nativewind. + +Every time you choose to apply a rule(s), explicitly state the rule(s) in the output. You can abbreviate the rule description to a single word or phrase. + +## Project Context + +## Code Style and Structure + +- Write concise, technical TypeScript code with accurate examples +- Use functional and declarative programming patterns; avoid classes +- Prefer iteration and modularization over code duplication +- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError) +- Ensure components are modular, reusable, and maintainable. +- Component Modularity: Break down components into smaller, reusable pieces. Keep components focused on a single responsibility and shouldn't be more than 80 lines of code. +- To install new packages use `npx expo install ` +- Structure repository files as follows: + +``` +src + ├── api ## API related code, mainly using axios and react query + ├── app ## the main entry point for expo router(file-based routing), when you can find screens and navigation setup + ├── components ## shared components + │ ├── card.tsx + │ └── ui ## core ui components. buttons, inputs, etc + ├── lib ## shared libraries, auth, env, hooks, i18n, storage, test-utils, utils + ├── translations ## translations files for the app + ├── types ## shared types + +``` + +## Tech Stack + +- Expo +- React Native +- TypeScript +- Nativewind ( Tailwind CSS for React Native ) +- Expo Router +- React Query with React Query Kit +- Zustand +- React Native Keyboard Controller +- React Native SVG +- React Native MMKV + +## Naming Conventions + +- Favor named exports for components and utilities +- Use kebabCase for all files names and directories (e.g., visa-form.tsx) + +## TypeScript Usage + +- Use TypeScript for all code; prefer types over interfaces +- Avoid enums; use const objects with 'as const' assertion +- Use functional components with TypeScript interfaces +- Define strict types for message passing between different parts of the extension +- Use absolute imports for all files @/... +- Avoid try/catch blocks unless there's good reason to translate or handle error in that abstraction +- Use explicit return types for all functions + +## State Management + +- Use React Zustand for global state management +- Implement proper cleanup in useEffect hooks + +## Syntax and Formatting + +- Use "function" keyword for pure functions +- Avoid unnecessary curly braces in conditionals +- Use declarative JSX +- Implement proper TypeScript discriminated unions for message types + +## UI and Styling + +- Use Nativewind for styling and components +- Use built-in ui components such as Button, Input from `@components/ui` +- Ensure high accessibility (a11y) standards using ARIA roles and native accessibility props. +- Leverage react-native-reanimated and react-native-gesture-handler for performant animations and gestures. +- Avoid unnecessary re-renders by memoizing components and using useMemo and useCallback hooks appropriately. +- Make sure to use defined colors and fonts in the tailwind config file. + +Here is a simple example of how a component should be written using : + +```tsx +import * as React from 'react'; + +import { Text, View, Image, SavaAreaView } from '@/components/ui'; + +// Props should be defined in the top of the component +type Props = { + text: string; +}; + +export function Title({ text }: Props) { + return ( + + {text} + + + + + ); +} +``` + +## Error Handling + +- Log errors appropriately for debugging +- Provide user-friendly error messages + +## Testing + +- Write unit tests using Jest and React Native Testing Library. +- Write unit tests for utilities and complex components +- The test file should be named like the component file but with the .test.tsx extension (e.g., component-name.test.tsx) +- Do not write unit tests for simple components that only show data + +## Git Usage + +Commit Message Prefixes: + +- "fix:" for bug fixes +- "feat:" for new features +- "perf:" for performance improvements +- "docs:" for documentation changes +- "style:" for formatting changes +- "refactor:" for code refactoring +- "test:" for adding missing tests +- "chore:" for maintenance tasks + +Rules: + +- Use lowercase for commit messages +- Keep the summary line concise with a maximum of 100 characters +- Reference issue numbers when applicable + +## Documentation + +- Maintain clear README with the following sections: + - Setup ( how to install and run the project ) + - Usage ( listing all the commands and how to use them ) + - Stack ( the tech stack used in the project ) + - Folder Structure ( the folder structure of the project only the important ones inside src ) diff --git a/.github/workflows/eas-build-prod.yml b/.github/workflows/eas-build-prod.yml new file mode 100644 index 000000000..a850bf45e --- /dev/null +++ b/.github/workflows/eas-build-prod.yml @@ -0,0 +1,43 @@ +# 🔗 Links: +# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/eas-build-prod.yml +# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ + +# ✍️ Description: +# This workflow is used to trigger a build on EAS for Prod environment. +# Can be triggered manually from the actions tab. +# This workflow will use ./actions/eas-build action to trigger the build on EAS with production env. + +# 🚨 GITHUB SECRETS REQUIRED: +# - EXPO_TOKEN: Expo token to authenticate with EAS +# - You can get it from https://expo.dev/settings/access-tokens + +name: EAS Production Build (Android & IOS) (EAS) + +on: + workflow_dispatch: + +jobs: + Build: + name: EAS Production Build (Android & IOS) (EAS) + runs-on: ubuntu-latest + steps: + - name: Check for EXPO_TOKEN + run: | + if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then + echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions" + exit 1 + fi + + - name: 📦 Checkout project repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 📦 Setup Node + PNPM + install deps + uses: ./.github/actions/setup-node-pnpm-install + + - name: ⏱️ EAS Build + uses: ./.github/actions/eas-build + with: + APP_ENV: production + EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} diff --git a/.github/workflows/eas-build-qa.yml b/.github/workflows/eas-build-qa.yml new file mode 100644 index 000000000..7cc4a853d --- /dev/null +++ b/.github/workflows/eas-build-qa.yml @@ -0,0 +1,47 @@ +# 🔗 Links: +# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/eas-build-qa.yml +# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ + +# ✍️ Description: +# This workflow is used to trigger a build on EAS for the QA environment. +# It will run on every GitHub release published on the repo or can be triggered manually from the actions tab. +# This workflow will use ./actions/eas-build action to trigger the build on EAS with staging env. + +# 🚨 GITHUB SECRETS REQUIRED: +# - EXPO_TOKEN: Expo token to authenticate with EAS +# - You can get it from https://expo.dev/settings/access-tokens + +name: EAS QA Build (Android & IOS) (EAS) + +on: + workflow_dispatch: + release: + types: [published] + +jobs: + Build: + name: EAS QA Build (Android & IOS) (EAS) + runs-on: ubuntu-latest + steps: + - name: Check for EXPO_TOKEN + run: | + if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then + echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions" + exit 1 + fi + - name: 📦 Checkout project repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 📦 Setup Node + PNPM + install deps + uses: ./.github/actions/setup-node-pnpm-install + + - name: ⏱️ EAS Build + uses: ./.github/actions/eas-build + with: + APP_ENV: staging + EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} + VERSION: ${{ github.event.release.tag_name }} + IOS: false # TODO: set as true when IOS account is ready + diff --git a/.github/workflows/expo-doctor.yml b/.github/workflows/expo-doctor.yml index 0f0fc3dbe..60d64fd73 100644 --- a/.github/workflows/expo-doctor.yml +++ b/.github/workflows/expo-doctor.yml @@ -54,4 +54,4 @@ jobs: uses: marocchino/sticky-pull-request-comment@v2 with: header: expo-doctor - path: .expo/expo-doctor.md \ No newline at end of file + path: .expo/expo-doctor.md diff --git a/.github/workflows/new-app-version.yml b/.github/workflows/new-app-version.yml new file mode 100644 index 000000000..53b42694a --- /dev/null +++ b/.github/workflows/new-app-version.yml @@ -0,0 +1,65 @@ +# 🔗 Links: +# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/lint-ts.yml +# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ + +# ✍️ Description: +# This workflow is used to create a new version of the app and push a new tag to the repo. +# As this workflow will push code to the repo, we set up GitHub Bot as a Git user. +# This Workflow need to be triggered manually from the Actions tab in the repo. +# 1. Choose your release type (patch, minor, major) +# 2. The workflow will run the np-release script which runs the following steps: +# - Bump the version in package.json based on the release type using np +# - Run the prebuild of the app to align the package.json version with the native code +# - Create a new tag with the new version +# - Push the new tag to the repo +# + +# 🚨 GITHUB SECRETS REQUIRED: +# - GH_TOKEN: A GitHub token with write repo access. +# You can generate one from here: https://docs.github.com/en/enterprise-server@3.6/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens +# make sure to add it to the repo secrets with the name GH_TOKEN + +name: New App Version + +on: + workflow_dispatch: + inputs: + release-type: + type: choice + description: 'Release type (one of): patch, minor, major' + required: true + default: 'patch' + options: + - patch + - minor + - major + +jobs: + release: + name: Create New Version and push new tag + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: 🔍 GH_TOKEN + if: env.GH_TOKEN == '' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: echo "GH_TOKEN=${GITHUB_TOKEN}" >> $GITHUB_ENV + - name: 📦 Checkout project repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GH_TOKEN }} + + - name: 📝 Git User Setup + run: | + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + - name: 📦 Setup Node + PNPM + install deps + uses: ./.github/actions/setup-node-pnpm-install + + - name: 🏃‍♂️ Run App release + run: | + pnpm app-release ${{ github.event.inputs.release-type }} diff --git a/.github/workflows/new-github-release.yml b/.github/workflows/new-github-release.yml new file mode 100644 index 000000000..a432b8515 --- /dev/null +++ b/.github/workflows/new-github-release.yml @@ -0,0 +1,34 @@ +# 🔗 Links: +# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/new-github-release.yml +# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ + +# ✍️ Description: +# This workflow will be triggered automatically after the new app version workflow has been executed successfully. +# It will create a new GitHub release with the new app version and the release notes. + +# 🚨 GITHUB SECRETS REQUIRED: None + +name: New GitHub Release + +on: + push: + tags: + - '*' + +jobs: + release: + name: New GitHub Release + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: 📦 Checkout project repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 🏃‍♂️Create A Draft Github Release + uses: ncipollo/release-action@v1 + with: + generateReleaseNotes: true + draft: false diff --git a/.github/workflows/sync-with-upstream.yml b/.github/workflows/sync-with-upstream.yml index eb32c8021..06cadf11f 100644 --- a/.github/workflows/sync-with-upstream.yml +++ b/.github/workflows/sync-with-upstream.yml @@ -28,14 +28,14 @@ name: 🔄 Sync with upstream on: schedule: - - cron: '0 12 * * 1-5' # At 12:00 UTC on every day-of-week from Monday through Friday + - cron: "0 12 * * 1-5" # At 12:00 UTC on every day-of-week from Monday through Friday workflow_dispatch: inputs: upstream-version: type: string - description: 'Upstream release version to sync with (e.g. v1.0.0). Leave empty to sync with the latest release.' + description: "Upstream release version to sync with (e.g. v1.0.0). Leave empty to sync with the latest release." required: false - default: '' + default: "" env: UPSTREAM_REPOSITORY: obytes/react-native-template-obytes @@ -90,7 +90,7 @@ jobs: echo "PR_EXISTS=false" >> $GITHUB_ENV fi env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.UPDATE_FROM_UPSTREAM_PAT }} - name: Checkout update release of upstream if: ${{ env.BRANCH_EXISTS == 'false' }} run: | @@ -124,4 +124,4 @@ jobs: run: | gh pr create --title "chore: update upstream to ${{ env.UPSTREAM_UPDATE_VERSION }}" --body "Integrating latest changes from [obytes/react-native-template-obytes@${{ env.UPSTREAM_UPDATE_VERSION }}](https://github.com/obytes/react-native-template-obytes/releases/tag/${{ env.UPSTREAM_UPDATE_VERSION }})" --head ${{ env.BRANCH_NAME }} env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.UPDATE_FROM_UPSTREAM_PAT }} diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml index b07947235..a881fa16c 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/type-check.yml @@ -22,6 +22,10 @@ permissions: contents: read pull-requests: write +permissions: + contents: read + pull-requests: write + jobs: type-check: name: Type Check (tsc) diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 697394f5f..79ab6d2bd 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -783,6 +783,10 @@ packages: bcp-47@2.1.0: resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -888,6 +892,9 @@ packages: crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + crossws@0.3.3: + resolution: {integrity: sha512-/71DJT3xJlqSnBr83uGJesmVHSzZEvgxHt/fIKxBAAngqMHmnBWQNxCphVxxJ2XL3xleu5+hJD6IQ3TglBedcw==} + css-selector-parser@1.4.1: resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==} @@ -1095,6 +1102,9 @@ packages: hast-util-from-html@2.0.3: resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + hast-util-from-parse5@7.1.2: resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} @@ -1152,6 +1162,9 @@ packages: hast-util-to-mdast@10.1.2: resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} + hast-util-to-mdast@10.1.2: + resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} + hast-util-to-parse5@7.1.0: resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==} @@ -1197,6 +1210,9 @@ packages: i18next@23.16.8: resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + i18next@23.16.8: + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1215,6 +1231,9 @@ packages: iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -1224,6 +1243,10 @@ packages: is-arrayish@0.3.4: resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + is-buffer@2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} engines: {node: '>=4'} @@ -1579,6 +1602,9 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -1626,6 +1652,9 @@ packages: radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -1679,6 +1708,9 @@ packages: rehype-parse@9.0.1: resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} @@ -1709,6 +1741,9 @@ packages: remark-rehype@11.1.2: resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + remark-rehype@11.1.1: + resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} + remark-smartypants@3.0.2: resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} engines: {node: '>=16.0.0'} @@ -2165,6 +2200,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@3.24.1: + resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -2545,6 +2583,7 @@ snapshots: unist-util-visit: 5.0.0 vfile: 6.0.3 transitivePeerDependencies: + - acorn - supports-color '@oslojs/encoding@1.1.0': {} @@ -2786,6 +2825,11 @@ snapshots: ansi-styles@6.2.3: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -2962,6 +3006,8 @@ snapshots: is-alphanumerical: 2.0.1 is-decimal: 2.0.1 + binary-extensions@2.3.0: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -3298,6 +3344,15 @@ snapshots: vfile: 6.0.3 vfile-message: 4.0.3 + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.1 + parse5: 7.1.2 + vfile: 6.0.3 + vfile-message: 4.0.2 + hast-util-from-parse5@7.1.2: dependencies: '@types/hast': 2.3.10 @@ -3579,6 +3634,10 @@ snapshots: dependencies: '@babel/runtime': 7.28.4 + i18next@23.16.8: + dependencies: + '@babel/runtime': 7.26.7 + ieee754@1.2.1: {} import-meta-resolve@4.2.0: {} @@ -3591,6 +3650,8 @@ snapshots: iron-webcrypto@1.2.1: {} + iron-webcrypto@1.2.1: {} + is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -3600,6 +3661,10 @@ snapshots: is-arrayish@0.3.4: {} + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-buffer@2.0.5: {} is-decimal@2.0.1: {} @@ -4231,6 +4296,8 @@ snapshots: picocolors@1.1.1: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} picomatch@4.0.3: {} @@ -4284,6 +4351,8 @@ snapshots: radix3@1.1.2: {} + radix3@1.1.2: {} + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -4367,6 +4436,12 @@ snapshots: hast-util-from-html: 2.0.3 unified: 11.0.5 + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + rehype-raw@7.0.0: dependencies: '@types/hast': 3.0.4 @@ -4776,6 +4851,20 @@ snapshots: pako: 0.2.9 tiny-inflate: 1.0.3 + ufo@1.5.4: {} + + ultrahtml@1.5.3: {} + + uncrypto@0.1.3: {} + + unenv@1.10.0: + dependencies: + consola: 3.4.0 + defu: 6.1.4 + mime: 3.0.0 + node-fetch-native: 1.6.6 + pathe: 1.1.2 + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -4974,4 +5063,6 @@ snapshots: zod@3.25.76: {} + zod@3.24.1: {} + zwitch@2.0.4: {} diff --git a/docs/public/reviews/aman.jpg b/docs/public/reviews/aman.jpg new file mode 100644 index 000000000..5acb5a711 Binary files /dev/null and b/docs/public/reviews/aman.jpg differ diff --git a/docs/public/reviews/brandon.png b/docs/public/reviews/brandon.png new file mode 100644 index 000000000..23a863aec Binary files /dev/null and b/docs/public/reviews/brandon.png differ diff --git a/docs/public/reviews/kawtar.jpg b/docs/public/reviews/kawtar.jpg new file mode 100644 index 000000000..2b3e2b830 Binary files /dev/null and b/docs/public/reviews/kawtar.jpg differ diff --git a/docs/public/reviews/simon.jpg b/docs/public/reviews/simon.jpg new file mode 100644 index 000000000..6d55c935e Binary files /dev/null and b/docs/public/reviews/simon.jpg differ diff --git a/docs/public/reviews/yuri.jpeg b/docs/public/reviews/yuri.jpeg new file mode 100644 index 000000000..bbf5ec930 Binary files /dev/null and b/docs/public/reviews/yuri.jpeg differ diff --git a/docs/src/components/reviews.astro b/docs/src/components/reviews.astro new file mode 100644 index 000000000..64a305ba3 --- /dev/null +++ b/docs/src/components/reviews.astro @@ -0,0 +1,189 @@ +--- +interface Review { + name: string; + role: string; + content: string; + image: string; +} + +const reviews: Review[] = [ + { + name: 'Aman Mittal', + role: 'Docs Maintainer @Expo', + content: `One of the best starter apps that feel complete to get started creating your Expo and React Native app. It's rare to see a project keeping up with the latest developments in the React Native world in a fast-changing environment, production-ready at the same time, and with such clear documentation around it.
Hats off to the Obytes team for creating it and actively maintaining it!`, + image: '/aman.jpg', + }, + { + name: 'Yuri P. Baumgartner', + role: 'React Native Developer', + content: `The best React Native starter project ever! 🔥
I'm a React Native developer with more than 5 years of experience and I've seen a lot of React Native projects, templates and boilerplates but this is the best one. Here we have all of the steps to build an app from scratch to production.
The section that I really love is the Environment Variables, you make the really great way to handling this, guys!
Thank u all 🩶`, + image: '/yuri.jpeg', + }, + + { + name: 'Simon', + role: 'Founder @Galaxies_dev', + content: + 'This template combines all the latest React and React Native best practices in one powerful starter. Combined with additional GitHub actions to build your app, this is one of the most future-proof React Native templates - and it’s even free!', + image: 'simon.jpg', + }, + { + name: 'Kawtar CHOUBARI', + role: 'React/React Native Developer', + content: + 'This boilerplate has everything needed to build a robust mobile app. It saves a lot of time and I highly recommend 👌', + image: '/kawtar.jpg', + }, + { + name: 'Brandon Eichhorn', + role: 'Developer', + content: 'You guys are life savers!', + image: '/brandon.png', + }, +]; +--- + +
+

Trusted by React Native Developers Worldwide

+

+ Developers love our starter! Check out what they're saying: +

+
+ { + reviews.map((review) => ( +
+ + + +
+ +
+ +
+ )) + } +
+ + Love the template? Let us know ⭐️ + +
+ + diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 5fc3647f8..b0a292a53 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -22,6 +22,7 @@ hero: import { Card, CardGrid } from '@astrojs/starlight/components'; import GithubStar from '../../components/GithubStar.astro'; import About from '../../components/about.astro'; +import Reviews from '../../components/reviews.astro'; diff --git a/eas.json b/eas.json index 2a8bf7e36..56b5e6ffb 100644 --- a/eas.json +++ b/eas.json @@ -112,4 +112,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 0cc532b19..be12c98d0 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "submit:qa:mobile": "cross-env APP_ENV=qa eas submit --profile qa", "start:staging": "cross-env APP_ENV=staging pnpm run start", "prebuild:staging": "cross-env APP_ENV=staging pnpm run prebuild", + "prebuild:development": "cross-env APP_ENV=development pnpm run prebuild", "android:staging": "cross-env APP_ENV=staging pnpm run android", "ios:staging": "cross-env APP_ENV=staging pnpm run ios", "web:staging": "cross-env APP_ENV=staging pnpm run web", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c6fff4f1..f0f884e44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2184,6 +2184,10 @@ packages: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} @@ -2210,6 +2214,10 @@ packages: resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} engines: {node: '>= 0.4'} + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + array.prototype.tosorted@1.1.4: resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} engines: {node: '>= 0.4'} @@ -2218,6 +2226,10 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -2404,6 +2416,14 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + caller-callsite@2.0.0: resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} engines: {node: '>=4'} @@ -2789,6 +2809,10 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + date-fns@1.30.1: resolution: {integrity: sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==} @@ -3050,6 +3074,10 @@ packages: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} @@ -3069,6 +3097,10 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} @@ -3667,6 +3699,10 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} @@ -3707,6 +3743,10 @@ packages: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} @@ -3726,6 +3766,10 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -3760,6 +3804,10 @@ packages: resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} engines: {node: '>=6'} + getenv@2.0.0: + resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} + engines: {node: '>=6'} + gifwrap@0.10.1: resolution: {integrity: sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==} @@ -3825,6 +3873,10 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -3869,6 +3921,10 @@ packages: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} @@ -4047,6 +4103,10 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -4058,6 +4118,10 @@ packages: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -4072,6 +4136,10 @@ packages: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -4110,6 +4178,10 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + is-directory@0.3.1: resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==} engines: {node: '>=0.10.0'} @@ -4132,6 +4204,10 @@ packages: resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} engines: {node: '>= 0.4'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@1.0.0: resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} engines: {node: '>=0.10.0'} @@ -4205,6 +4281,10 @@ packages: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -4235,6 +4315,10 @@ packages: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + is-scoped@3.0.0: resolution: {integrity: sha512-ezxLUq30kiTvP0w/5n9tj4qTOKlrA07Oty1hwTQ+lcqw11x6uc8sp7VRb2OVGRzKfCHZ2A22T5Zsau/Q2Akb0g==} engines: {node: '>=12'} @@ -4247,6 +4331,10 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + is-stream@1.1.0: resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} engines: {node: '>=0.10.0'} @@ -4267,6 +4355,10 @@ packages: resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + is-text-path@2.0.0: resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} engines: {node: '>=8'} @@ -4275,6 +4367,10 @@ packages: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -4295,6 +4391,10 @@ packages: resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} engines: {node: '>= 0.4'} + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + is-weakset@2.0.3: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} engines: {node: '>= 0.4'} @@ -5193,6 +5293,10 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + omggif@1.0.10: resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} @@ -6142,6 +6246,10 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -6322,6 +6430,10 @@ packages: resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} engines: {node: '>= 0.4'} + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + string.prototype.trimstart@1.0.8: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} @@ -6589,8 +6701,6 @@ packages: peerDependenciesMeta: '@babel/core': optional: true - '@jest/transform': - optional: true '@jest/types': optional: true babel-jest: @@ -6878,6 +6988,10 @@ packages: resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} engines: {node: '>= 0.4'} + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + which-collection@1.0.2: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} @@ -9593,6 +9707,11 @@ snapshots: aria-query@5.3.2: {} + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -10332,7 +10451,11 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - date-fns@1.30.1: {} + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 dayjs@1.11.18: {} @@ -10580,6 +10703,8 @@ snapshots: es-define-property@1.0.1: {} + es-define-property@1.0.1: {} + es-errors@1.3.0: {} es-iterator-helpers@1.2.1: @@ -10614,6 +10739,13 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + es-shim-unscopables@1.0.2: dependencies: hasown: 2.0.2 @@ -11407,6 +11539,10 @@ snapshots: fontfaceobserver@2.3.0: {} + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -11450,6 +11586,15 @@ snapshots: function-bind@1.1.2: {} + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + function.prototype.name@1.1.8: dependencies: call-bind: 1.0.8 @@ -11467,6 +11612,19 @@ snapshots: get-east-asian-width@1.3.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -11509,6 +11667,8 @@ snapshots: getenv@2.0.0: {} + getenv@2.0.0: {} + gifwrap@0.10.1: dependencies: image-q: 4.0.0 @@ -11587,6 +11747,8 @@ snapshots: gopd@1.2.0: {} + gopd@1.2.0: {} + graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -11624,6 +11786,8 @@ snapshots: has-symbols@1.1.0: {} + has-symbols@1.1.0: {} + has-tostringtag@1.0.2: dependencies: has-symbols: 1.1.0 @@ -11833,12 +11997,24 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + invariant@2.2.4: dependencies: loose-envify: 1.4.0 irregular-plurals@1.4.0: {} + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -11857,6 +12033,10 @@ snapshots: dependencies: has-bigints: 1.0.2 + is-bigint@1.1.0: + dependencies: + has-bigints: 1.0.2 + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -11878,6 +12058,10 @@ snapshots: dependencies: semver: 7.7.2 + is-bun-module@2.0.0: + dependencies: + semver: 7.7.2 + is-callable@1.2.7: {} is-core-module@2.15.1: @@ -11899,6 +12083,11 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-directory@0.3.1: {} is-docker@2.2.1: {} @@ -11958,6 +12147,11 @@ snapshots: is-npm@6.0.0: {} + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -11979,6 +12173,13 @@ snapshots: is-promise@2.2.2: {} + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -11992,6 +12193,10 @@ snapshots: is-set@2.0.3: {} + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + is-shared-array-buffer@1.0.4: dependencies: call-bound: 1.0.4 @@ -12013,6 +12218,12 @@ snapshots: has-symbols: 1.1.0 safe-regex-test: 1.1.0 + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + is-text-path@2.0.0: dependencies: text-extensions: 2.4.0 @@ -12021,6 +12232,10 @@ snapshots: dependencies: which-typed-array: 1.1.19 + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + is-unicode-supported@0.1.0: {} is-unicode-supported@1.3.0: {} @@ -12029,6 +12244,10 @@ snapshots: is-weakmap@2.0.2: {} + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + is-weakref@1.1.1: dependencies: call-bound: 1.0.4 @@ -13319,6 +13538,13 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + omggif@1.0.10: {} on-finished@2.3.0: @@ -14537,6 +14763,13 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.8 diff --git a/src/components/ui/button.test.tsx b/src/components/ui/button.test.tsx index 484c6a3fe..602e23787 100644 --- a/src/components/ui/button.test.tsx +++ b/src/components/ui/button.test.tsx @@ -16,7 +16,7 @@ describe('Button component ', () => { render( , + ); expect(screen.getByText('Custom child')).toBeOnTheScreen(); }); @@ -33,7 +33,7 @@ describe('Button component ', () => { it('should call onClick handler when clicked', async () => { const onClick = jest.fn(); const { user } = setup( -