main 983cd67b0c55 cached
452 files
1.1 MB
324.8k tokens
472 symbols
1 requests
Download .txt
Showing preview only (1,289K chars total). Download the full file or copy to clipboard to get everything.
Repository: founded-labs/react-native-reusables
Branch: main
Commit: 983cd67b0c55
Files: 452
Total size: 1.1 MB

Directory structure:
gitextract___gsboks/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   └── pull_request_template.md
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── COMMUNITY_RESOURCES.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── apps/
│   ├── cli/
│   │   ├── .changeset/
│   │   │   └── config.json
│   │   ├── .github/
│   │   │   ├── actions/
│   │   │   │   └── setup/
│   │   │   │       └── action.yml
│   │   │   └── workflows/
│   │   │       ├── check.yml
│   │   │       ├── release.yml
│   │   │       └── snapshot.yml
│   │   ├── .gitignore
│   │   ├── .prettierrc
│   │   ├── .vscode/
│   │   │   ├── extensions.json
│   │   │   └── settings.json
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── eslint.config.mjs
│   │   ├── package.json
│   │   ├── patches/
│   │   │   └── @changesets__get-github-info@0.6.0.patch
│   │   ├── scripts/
│   │   │   └── copy-package-json.ts
│   │   ├── src/
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   ├── contexts/
│   │   │   │   └── cli-options.ts
│   │   │   ├── project-manifest.ts
│   │   │   ├── services/
│   │   │   │   ├── commands/
│   │   │   │   │   ├── add.ts
│   │   │   │   │   ├── doctor.ts
│   │   │   │   │   └── init.ts
│   │   │   │   ├── git.ts
│   │   │   │   ├── package-manager.ts
│   │   │   │   ├── project-config.ts
│   │   │   │   ├── required-files-checker.ts
│   │   │   │   ├── spinner.ts
│   │   │   │   └── template.ts
│   │   │   └── utils/
│   │   │       ├── retry-with.ts
│   │   │       └── run-command.ts
│   │   ├── test/
│   │   │   └── Dummy.test.ts
│   │   ├── tsconfig.base.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.scripts.json
│   │   ├── tsconfig.src.json
│   │   ├── tsconfig.test.json
│   │   ├── tsup.config.ts
│   │   └── vitest.config.ts
│   ├── docs/
│   │   ├── .eslintrc.json
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── app/
│   │   │   ├── (home)/
│   │   │   │   ├── BlockSection.tsx
│   │   │   │   ├── ComponentsGrid.tsx
│   │   │   │   ├── TemplatesSection.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── api/
│   │   │   │   └── search/
│   │   │   │       └── route.ts
│   │   │   ├── docs/
│   │   │   │   ├── [[...slug]]/
│   │   │   │   │   └── page.tsx
│   │   │   │   └── layout.tsx
│   │   │   ├── global.css
│   │   │   ├── layout.tsx
│   │   │   ├── og/
│   │   │   │   └── route.tsx
│   │   │   └── showcase/
│   │   │       ├── links/
│   │   │       │   └── [[...slug]]/
│   │   │       │       └── page.tsx
│   │   │       ├── privacy-policy/
│   │   │       │   └── page.tsx
│   │   │       └── support/
│   │   │           └── page.tsx
│   │   ├── components/
│   │   │   ├── app-store-button.tsx
│   │   │   ├── auth-block-tabs.tsx
│   │   │   ├── auth-integration-select.tsx
│   │   │   ├── blocks-grid.tsx
│   │   │   ├── blocks.tsx
│   │   │   ├── callout.tsx
│   │   │   ├── clerk-logo.tsx
│   │   │   ├── command-tabs.tsx
│   │   │   ├── cookies-provider.tsx
│   │   │   ├── copy-button.tsx
│   │   │   ├── download-app-banner.tsx
│   │   │   ├── examples.tsx
│   │   │   ├── external-links.tsx
│   │   │   ├── icons/
│   │   │   │   └── rnr-icon.tsx
│   │   │   ├── installation-tabs.tsx
│   │   │   ├── link-tabs.tsx
│   │   │   ├── platform-select.tsx
│   │   │   ├── play-store-button.tsx
│   │   │   ├── portal-info-alert.tsx
│   │   │   ├── preview-card.tsx
│   │   │   ├── safe-area-provider.tsx
│   │   │   ├── skip-navigation-button.tsx
│   │   │   ├── styling-library-tabs.tsx
│   │   │   ├── ui/
│   │   │   │   ├── alert.tsx
│   │   │   │   ├── badge.tsx
│   │   │   │   ├── button.tsx
│   │   │   │   ├── select.tsx
│   │   │   │   └── tabs.tsx
│   │   │   ├── use-styling-library.ts
│   │   │   └── vercel-oss-badge.tsx
│   │   ├── components.json
│   │   ├── content/
│   │   │   └── docs/
│   │   │       ├── blocks/
│   │   │       │   └── authentication/
│   │   │       │       ├── forgot-password-form.mdx
│   │   │       │       ├── index.mdx
│   │   │       │       ├── meta.json
│   │   │       │       ├── reset-password-form.mdx
│   │   │       │       ├── sign-in-form.mdx
│   │   │       │       ├── sign-up-form.mdx
│   │   │       │       ├── social-connections.mdx
│   │   │       │       ├── user-menu.mdx
│   │   │       │       └── verify-email-form.mdx
│   │   │       ├── changelog.mdx
│   │   │       ├── cli.mdx
│   │   │       ├── components/
│   │   │       │   ├── accordion.mdx
│   │   │       │   ├── alert-dialog.mdx
│   │   │       │   ├── alert.mdx
│   │   │       │   ├── aspect-ratio.mdx
│   │   │       │   ├── avatar.mdx
│   │   │       │   ├── badge.mdx
│   │   │       │   ├── button.mdx
│   │   │       │   ├── card.mdx
│   │   │       │   ├── checkbox.mdx
│   │   │       │   ├── collapsible.mdx
│   │   │       │   ├── context-menu.mdx
│   │   │       │   ├── dialog.mdx
│   │   │       │   ├── dropdown-menu.mdx
│   │   │       │   ├── hover-card.mdx
│   │   │       │   ├── input.mdx
│   │   │       │   ├── label.mdx
│   │   │       │   ├── menubar.mdx
│   │   │       │   ├── popover.mdx
│   │   │       │   ├── progress.mdx
│   │   │       │   ├── radio-group.mdx
│   │   │       │   ├── select.mdx
│   │   │       │   ├── separator.mdx
│   │   │       │   ├── skeleton.mdx
│   │   │       │   ├── switch.mdx
│   │   │       │   ├── tabs.mdx
│   │   │       │   ├── text.mdx
│   │   │       │   ├── textarea.mdx
│   │   │       │   ├── toggle-group.mdx
│   │   │       │   ├── toggle.mdx
│   │   │       │   └── tooltip.mdx
│   │   │       ├── create-your-own-registry.mdx
│   │   │       ├── customization.mdx
│   │   │       ├── index.mdx
│   │   │       ├── installation/
│   │   │       │   ├── index.mdx
│   │   │       │   └── manual.mdx
│   │   │       └── meta.json
│   │   ├── global.d.ts
│   │   ├── lib/
│   │   │   ├── FoundedLabsIcon.tsx
│   │   │   ├── file-generator.ts
│   │   │   ├── source.ts
│   │   │   └── utils.ts
│   │   ├── nativewind-env.d.ts
│   │   ├── next.config.mjs
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── public/
│   │   │   ├── .well-known/
│   │   │   │   ├── apple-app-site-association
│   │   │   │   └── assetlinks.json
│   │   │   └── r/
│   │   │       ├── nativewind/
│   │   │       │   ├── accordion.json
│   │   │       │   ├── alert-dialog.json
│   │   │       │   ├── alert.json
│   │   │       │   ├── aspect-ratio.json
│   │   │       │   ├── avatar.json
│   │   │       │   ├── badge.json
│   │   │       │   ├── button.json
│   │   │       │   ├── card.json
│   │   │       │   ├── checkbox.json
│   │   │       │   ├── collapsible.json
│   │   │       │   ├── context-menu.json
│   │   │       │   ├── dialog.json
│   │   │       │   ├── dropdown-menu.json
│   │   │       │   ├── forgot-password-form-clerk.json
│   │   │       │   ├── forgot-password-form.json
│   │   │       │   ├── hover-card.json
│   │   │       │   ├── icon.json
│   │   │       │   ├── input.json
│   │   │       │   ├── label.json
│   │   │       │   ├── menubar.json
│   │   │       │   ├── native-only-animated-view.json
│   │   │       │   ├── popover.json
│   │   │       │   ├── progress.json
│   │   │       │   ├── radio-group.json
│   │   │       │   ├── reset-password-form-clerk.json
│   │   │       │   ├── reset-password-form.json
│   │   │       │   ├── select.json
│   │   │       │   ├── separator.json
│   │   │       │   ├── sign-in-form-clerk.json
│   │   │       │   ├── sign-in-form.json
│   │   │       │   ├── sign-up-form-clerk.json
│   │   │       │   ├── sign-up-form.json
│   │   │       │   ├── skeleton.json
│   │   │       │   ├── social-connections-clerk.json
│   │   │       │   ├── social-connections.json
│   │   │       │   ├── switch.json
│   │   │       │   ├── tabs.json
│   │   │       │   ├── text.json
│   │   │       │   ├── textarea.json
│   │   │       │   ├── toggle-group.json
│   │   │       │   ├── toggle.json
│   │   │       │   ├── tooltip.json
│   │   │       │   ├── user-menu-clerk.json
│   │   │       │   ├── user-menu.json
│   │   │       │   ├── verify-email-form-clerk.json
│   │   │       │   └── verify-email-form.json
│   │   │       └── uniwind/
│   │   │           ├── accordion.json
│   │   │           ├── alert-dialog.json
│   │   │           ├── alert.json
│   │   │           ├── aspect-ratio.json
│   │   │           ├── avatar.json
│   │   │           ├── badge.json
│   │   │           ├── button.json
│   │   │           ├── card.json
│   │   │           ├── checkbox.json
│   │   │           ├── collapsible.json
│   │   │           ├── context-menu.json
│   │   │           ├── dialog.json
│   │   │           ├── dropdown-menu.json
│   │   │           ├── forgot-password-form-clerk.json
│   │   │           ├── forgot-password-form.json
│   │   │           ├── hover-card.json
│   │   │           ├── icon.json
│   │   │           ├── input.json
│   │   │           ├── label.json
│   │   │           ├── menubar.json
│   │   │           ├── native-only-animated-view.json
│   │   │           ├── popover.json
│   │   │           ├── progress.json
│   │   │           ├── radio-group.json
│   │   │           ├── reset-password-form-clerk.json
│   │   │           ├── reset-password-form.json
│   │   │           ├── select.json
│   │   │           ├── separator.json
│   │   │           ├── sign-in-form-clerk.json
│   │   │           ├── sign-in-form.json
│   │   │           ├── sign-up-form-clerk.json
│   │   │           ├── sign-up-form.json
│   │   │           ├── skeleton.json
│   │   │           ├── social-connections-clerk.json
│   │   │           ├── social-connections.json
│   │   │           ├── switch.json
│   │   │           ├── tabs.json
│   │   │           ├── text.json
│   │   │           ├── textarea.json
│   │   │           ├── toggle-group.json
│   │   │           ├── toggle.json
│   │   │           ├── tooltip.json
│   │   │           ├── user-menu-clerk.json
│   │   │           ├── user-menu.json
│   │   │           ├── verify-email-form-clerk.json
│   │   │           └── verify-email-form.json
│   │   ├── registry/
│   │   │   ├── nativewind.json
│   │   │   └── uniwind.json
│   │   ├── scripts/
│   │   │   └── generate-local-registry.js
│   │   ├── source.config.ts
│   │   ├── src/
│   │   │   └── content/
│   │   │       └── docs/
│   │   │           └── showcase/
│   │   │               ├── links/
│   │   │               │   ├── button.mdx
│   │   │               │   ├── input.mdx
│   │   │               │   └── wrong.mdx
│   │   │               ├── privacy-policy.mdx
│   │   │               └── support.mdx
│   │   ├── tailwind.config.js
│   │   ├── tsconfig.json
│   │   └── vercel.json
│   └── showcase/
│       ├── .gitignore
│       ├── app/
│       │   ├── +html.tsx
│       │   ├── +not-found.tsx
│       │   ├── _layout.tsx
│       │   ├── components/
│       │   │   ├── accordion.tsx
│       │   │   ├── alert-dialog.tsx
│       │   │   ├── alert.tsx
│       │   │   ├── aspect-ratio.tsx
│       │   │   ├── avatar.tsx
│       │   │   ├── badge.tsx
│       │   │   ├── button.tsx
│       │   │   ├── card.tsx
│       │   │   ├── checkbox.tsx
│       │   │   ├── collapsible.tsx
│       │   │   ├── context-menu.tsx
│       │   │   ├── dialog.tsx
│       │   │   ├── dropdown-menu.tsx
│       │   │   ├── hover-card.tsx
│       │   │   ├── input.tsx
│       │   │   ├── label.tsx
│       │   │   ├── menubar.tsx
│       │   │   ├── popover.tsx
│       │   │   ├── progress.tsx
│       │   │   ├── radio-group.tsx
│       │   │   ├── select.tsx
│       │   │   ├── separator.tsx
│       │   │   ├── skeleton.tsx
│       │   │   ├── switch.tsx
│       │   │   ├── tabs.tsx
│       │   │   ├── text.tsx
│       │   │   ├── textarea.tsx
│       │   │   ├── toggle-group.tsx
│       │   │   ├── toggle.tsx
│       │   │   └── tooltip.tsx
│       │   ├── index.tsx
│       │   └── showcase/
│       │       └── links/
│       │           └── [slug].tsx
│       ├── app.config.ts
│       ├── babel.config.js
│       ├── components/
│       │   ├── header-right-view.tsx
│       │   ├── preview-carousel.tsx
│       │   └── theme-toggle.tsx
│       ├── components.json
│       ├── eas.json
│       ├── global.css
│       ├── hooks/
│       │   └── use-geist-font.tsx
│       ├── index.js
│       ├── lib/
│       │   ├── constants.ts
│       │   ├── theme.ts
│       │   └── utils.ts
│       ├── metro.config.js
│       ├── nativewind-env.d.ts
│       ├── package.json
│       ├── plugins/
│       │   └── geistFontPlugin.js
│       ├── tailwind.config.js
│       ├── tsconfig.json
│       └── vercel.json
├── package.json
├── packages/
│   └── registry/
│       ├── nativewind-env.d.ts
│       ├── package.json
│       ├── src/
│       │   ├── blocks/
│       │   │   ├── clerk/
│       │   │   │   ├── forgot-password-form.tsx
│       │   │   │   ├── reset-password-form.tsx
│       │   │   │   ├── sign-in-form.tsx
│       │   │   │   ├── sign-up-form.tsx
│       │   │   │   ├── social-connections.tsx
│       │   │   │   ├── user-menu.tsx
│       │   │   │   └── verify-email-form.tsx
│       │   │   ├── forgot-password-form.tsx
│       │   │   ├── index.ts
│       │   │   ├── reset-password-form.tsx
│       │   │   ├── sign-in-form.tsx
│       │   │   ├── sign-up-form.tsx
│       │   │   ├── social-connections.tsx
│       │   │   ├── user-menu.tsx
│       │   │   └── verify-email-form.tsx
│       │   ├── examples/
│       │   │   ├── accordion.tsx
│       │   │   ├── alert-dialog.tsx
│       │   │   ├── alert.tsx
│       │   │   ├── aspect-ratio.tsx
│       │   │   ├── avatar.tsx
│       │   │   ├── badge.tsx
│       │   │   ├── button/
│       │   │   │   ├── button-destructive.tsx
│       │   │   │   ├── button-ghost.tsx
│       │   │   │   ├── button-icon.tsx
│       │   │   │   ├── button-link.tsx
│       │   │   │   ├── button-loading.tsx
│       │   │   │   ├── button-outline.tsx
│       │   │   │   ├── button-primary.tsx
│       │   │   │   ├── button-secondary.tsx
│       │   │   │   ├── button-with-icon.tsx
│       │   │   │   └── index.ts
│       │   │   ├── card.tsx
│       │   │   ├── checkbox.tsx
│       │   │   ├── collapsible.tsx
│       │   │   ├── context-menu.tsx
│       │   │   ├── dialog.tsx
│       │   │   ├── dropdown-menu.tsx
│       │   │   ├── hover-card.tsx
│       │   │   ├── index.ts
│       │   │   ├── input.tsx
│       │   │   ├── label.tsx
│       │   │   ├── menubar.tsx
│       │   │   ├── popover.tsx
│       │   │   ├── progress.tsx
│       │   │   ├── radio-group.tsx
│       │   │   ├── select/
│       │   │   │   ├── index.ts
│       │   │   │   ├── scrollable-select.tsx
│       │   │   │   └── select.tsx
│       │   │   ├── separator.tsx
│       │   │   ├── skeleton.tsx
│       │   │   ├── switch.tsx
│       │   │   ├── tabs.tsx
│       │   │   ├── text/
│       │   │   │   ├── index.ts
│       │   │   │   ├── text-cascade.tsx
│       │   │   │   ├── text-typorgaphy.tsx
│       │   │   │   └── text.tsx
│       │   │   ├── textarea.tsx
│       │   │   ├── toggle-group.tsx
│       │   │   ├── toggle.tsx
│       │   │   └── tooltip.tsx
│       │   ├── nativewind/
│       │   │   ├── components/
│       │   │   │   └── ui/
│       │   │   │       ├── accordion.tsx
│       │   │   │       ├── alert-dialog.tsx
│       │   │   │       ├── alert.tsx
│       │   │   │       ├── aspect-ratio.tsx
│       │   │   │       ├── avatar.tsx
│       │   │   │       ├── badge.tsx
│       │   │   │       ├── button.tsx
│       │   │   │       ├── card.tsx
│       │   │   │       ├── checkbox.tsx
│       │   │   │       ├── collapsible.tsx
│       │   │   │       ├── context-menu.tsx
│       │   │   │       ├── dialog.tsx
│       │   │   │       ├── dropdown-menu.tsx
│       │   │   │       ├── hover-card.tsx
│       │   │   │       ├── icon.tsx
│       │   │   │       ├── input.tsx
│       │   │   │       ├── label.tsx
│       │   │   │       ├── menubar.tsx
│       │   │   │       ├── native-only-animated-view.tsx
│       │   │   │       ├── popover.tsx
│       │   │   │       ├── progress.tsx
│       │   │   │       ├── radio-group.tsx
│       │   │   │       ├── select.tsx
│       │   │   │       ├── separator.tsx
│       │   │   │       ├── skeleton.tsx
│       │   │   │       ├── switch.tsx
│       │   │   │       ├── tabs.tsx
│       │   │   │       ├── text.tsx
│       │   │   │       ├── textarea.tsx
│       │   │   │       ├── toggle-group.tsx
│       │   │   │       ├── toggle.tsx
│       │   │   │       └── tooltip.tsx
│       │   │   └── lib/
│       │   │       ├── index.ts
│       │   │       └── utils.ts
│       │   └── uniwind/
│       │       ├── components/
│       │       │   └── ui/
│       │       │       ├── accordion.tsx
│       │       │       ├── alert-dialog.tsx
│       │       │       ├── alert.tsx
│       │       │       ├── aspect-ratio.tsx
│       │       │       ├── avatar.tsx
│       │       │       ├── badge.tsx
│       │       │       ├── button.tsx
│       │       │       ├── card.tsx
│       │       │       ├── checkbox.tsx
│       │       │       ├── collapsible.tsx
│       │       │       ├── context-menu.tsx
│       │       │       ├── dialog.tsx
│       │       │       ├── dropdown-menu.tsx
│       │       │       ├── hover-card.tsx
│       │       │       ├── icon.tsx
│       │       │       ├── input.tsx
│       │       │       ├── label.tsx
│       │       │       ├── menubar.tsx
│       │       │       ├── native-only-animated-view.tsx
│       │       │       ├── popover.tsx
│       │       │       ├── progress.tsx
│       │       │       ├── radio-group.tsx
│       │       │       ├── select.tsx
│       │       │       ├── separator.tsx
│       │       │       ├── skeleton.tsx
│       │       │       ├── switch.tsx
│       │       │       ├── tabs.tsx
│       │       │       ├── text.tsx
│       │       │       ├── textarea.tsx
│       │       │       ├── toggle-group.tsx
│       │       │       ├── toggle.tsx
│       │       │       └── tooltip.tsx
│       │       └── lib/
│       │           ├── index.ts
│       │           └── utils.ts
│       ├── tsconfig.json
│       └── uniwind-types.d.ts
├── pnpm-workspace.yaml
└── turbo.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: mrzachnugent


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: '[ BUG ]'
labels: bug
assignees: ''
---

<!--

⚠️ **Important**: Issues must include a valid reproduction link. Reports without one will be automatically closed.

You can quickly create a minimal reproduction using:

```bash
npx @react-native-reusables/cli@latest init -t minimal
```

-->

**Reproduction link**: `<link>`

**Describe the bug**
A clear and concise description of what the bug is.

**Steps to reproduce the behavior:**

1. Start the '...' app with '...'
2. Go to '...'
3. Click on '....'
4. Scroll down to '....'
5. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Platform (please complete the following information):**

- Type: [eg: Browser, Simulator, Emulator, Device]
- OS: [e.g. iOS]
- Browser (if applies) [e.g. chrome, safari]

**CLI output (paste the full command output)**

If applicable, paste the full command output by running it with the `--log-level all` flag.

```bash
npx @react-native-reusables/cli@latest --log-level all [command] [args] [options]

// example:
// npx @react-native-reusables/cli@latest --log-level all init -t minimal
```

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/pull_request_template.md
================================================
# Pull Request Template

<!--

⚠️ **Important**

**If you want to propose a new feature:**

1.  Make sure to read the [project scope](https://github.com/founded-labs/react-native-reusables/discussions/229) to confirm your proposal fits within the vision and purpose of `react-native-reusables`.
2. Before taking any action, please open a [new discussion](https://github.com/founded-labs/react-native-reusables/discussions). This allows us to collaborate, gather feedback, and ensure alignment with the project's goals.

-->

## Description:

<!-- Provide a brief description of the changes introduced by this pull request. -->

Fixes issue #<!-- Add the issue number that this PR fixes, if applicable. -->

## Tested Platforms:

<!-- Check the platforms that you have tested this PR on. -->

- [ ] Web
- [ ] iOS
- [ ] Android

## Affected Apps/Packages:

<!-- Specify which apps or packages are affected by this pull request. -->

- [ ] apps/docs
- [ ] apps/showcase
- [ ] apps/cli
- [ ] packages/registry

### Screenshots:

<!-- If applicable, add screenshots to showcase the changes visually. -->

#### Notes:

<!-- Add any additional notes or context that reviewers should be aware of. -->


================================================
FILE: .gitignore
================================================
# Monorepo
apps/*/credentials.json
apps/*/build
packages/*/build

# Turborepo
.turbo

# Expo
.expo
__generated__
web-build
expo-env.d.ts

packages/experimental

# macOS
.DS_Store

# Node
node_modules
npm-debug.log
yarn-error.log
package-lock.json

# Ruby
.direnv

# Emacs
*~

# Vim
.*.swp
.*.swo
.*.swn
.*.swm

# Sublime Text
*.sublime-project
*.sublime-workspace

# Xcode
*.pbxuser
!default.pbxuser
*.xccheckout
*.xcscmblueprint
xcuserdata

# Android Studio
*.iml
.gradle
.idea/libraries
.idea/workspace.xml
.idea/gradle.xml
.idea/misc.xml
.idea/modules.xml
.idea/vcs.xml

# Eclipse
.project
.settings

# VSCode
.history/


================================================
FILE: .npmrc
================================================
node-linker=hoisted

================================================
FILE: .nvmrc
================================================
20.11

================================================
FILE: .prettierrc
================================================
{
  "printWidth": 100,
  "tabWidth": 2,
  "singleQuote": true,
  "bracketSameLine": true,
  "trailingComma": "es5",
  "plugins": ["prettier-plugin-tailwindcss"],
  "tailwindFunctions": ["cva"]
}


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

- The use of sexualized language or imagery, and sexual attention or
  advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
  address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
hello@foundedlabs.com.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: COMMUNITY_RESOURCES.md
================================================
# Community Resources

Community-created components, libraries, and templates that extend React Native Reusables and fill in missing shadcn/ui elements.

_Contributions are welcome! Submit a PR to add your resource._

## Components & Libraries

### Calendar

- [React Native Flash Calendar](https://github.com/MarceloPrado/flash-calendar)  
  Incredibly fast and flexible library to build calendars in React Native.

### Carousel

- [Animated.ScrollView](https://medium.com/timeless/building-a-gallery-carousel-in-react-native-using-reanimated-i-19b19e6b6b10)  
  Article explaining how to create a carousel using the ScrollView component.

### Chart

- [Victory Native](https://github.com/FormidableLabs/victory-native-xl)  
  Charting library for React Native with a focus on performance and customization.

### Combobox

_TBD_

### Command

_TBD_

### Data Table

- [Tanstack Table](https://tanstack.com/table/latest)  
  Headless UI for building powerful tables and datagrids.

### Date Picker

- [React Native DateTimePicker](https://github.com/react-native-datetimepicker/datetimepicker)  
  Date and time picker component for iOS, Android, and Windows.

### Drawer

- [Universal Bottom Sheet](https://github.com/adebayoileri/universal-bottom-sheet) by [adebayoileri](https://github.com/adebayoileri)  
  Bottom sheet component that combines Gorhom Bottom Sheet and Vaul for a seamless, responsive experience across mobile and web.

### Form

- [React Hook Form](https://react-hook-form.com/get-started#ReactNative)  
  Performant, flexible, and extensible forms with easy-to-use validation.

### Input OTP

- [input-otp-native](https://github.com/yjose/input-otp-native)  
  🔐 OTP input for React Native/Expo apps: unstyled, copy-paste examples that are fully tested and compatible with Nativewind.

### Resizable

_TBD_

### Scroll Area

- [React Native ScrollView](https://reactnative.dev/docs/scrollview)  
  Generic scrolling container that can host multiple components and views.

### Sheet (Drawer Navigation)

- [Drawer Navigation](https://reactnavigation.org/docs/drawer-based-navigation/)  
  Drawer navigation component that slides in from the side.

### Sonner

- [Sonner Native](https://github.com/gunnartorfis/sonner-native) by [gunnartorfis](https://github.com/gunnartorfis)  
  Opinionated toast component for React Native. Port of @emilkowalski's sonner.

- [Burnt](https://www.npmjs.com/package/burnt)  
  Cross-platform toasts for React Native, powered by native elements. Uses [Sonner](https://github.com/emilkowalski/sonner) on Web.

---

## Templates

- [RNR Base Bare](https://github.com/a0m0rajab/rnr-base-bare) by [a0m0rajab](https://github.com/a0m0rajab)  
  Supabase-powered starter app with sign-in, sign-up, and profile functionality.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to React Native Reusables

Thank you for your interest in contributing to `react-native-reusables`! We welcome contributions from the community to improve and enhance this project. Before getting started, please take a moment to review the following guidelines.

## How to Contribute

> ⚠️ **Important**
>
> If you want to propose a new feature:
>
> 1.  Make sure to read the [project scope](https://github.com/founded-labs/react-native-reusables/discussions/229) to confirm your proposal fits within the vision and purpose of `react-native-reusables`.
> 2.  Before taking any action, please open a [new discussion](https://github.com/founded-labs/react-native-reusables/discussions). This allows us to collaborate, gather feedback, and ensure alignment with the project's goals.

<br />

1. Fork the repository to your GitHub account.
2. Clone the forked repository to your local machine:
   ```bash
   git clone https://github.com/your-username/react-native-reusables.git
   cd react-native-reusables
   ```
3. Create a new branch:

   ```bash
   git checkout -b your-username/your-feature-name
   ```

4. Make your changes and ensure that your code adheres to the existing coding standards.
5. Commit your changes with clear and concise commit messages:

```bash
git commit -m "Add your commit message here"
```

6. Push your changes to your forked repository:

   ```bash
   git push origin your-username/your-feature-name
   ```

7. Open a pull request (PR) against the main branch of the original repository.

## Code Style Guidelines

Please follow the coding style and guidelines used in the project. If there are specific coding conventions, linting rules, or documentation standards, make sure your contributions adhere to them.

> _If they are not clear, please create an issue and we will create a CODING_STYLE_GUIDELINE.md_

## Issue Tracker

Check the [issue tracker](https://github.com/founded-labs/react-native-reusables/issues) for existing issues or open a new issue to discuss and coordinate your contribution with the maintainers.

## Code of Conduct

Please review and adhere to our [Code of Conduct](https://github.com/founded-labs/react-native-reusables/blob/main/CODE_OF_CONDUCT.md). Be respectful and considerate towards others.

## License

By contributing to this project, you agree that your contributions will be licensed under the [LICENSE](https://github.com/founded-labs/react-native-reusables/blob/main/LICENSE) file of this repository.

## Contact

If you have any questions or need further assistance, feel free to contact us at hello@foundedlabs.com.

**We appreciate your contributions and look forward to working with you!**


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Founded Labs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# React Native Reusables

Bringing [shadcn/ui](https://ui.shadcn.com) to React Native. Beautifully crafted components with [Nativewind](https://www.nativewind.dev/), open source, and almost as easy to use.</i>

![hero](apps/docs/public/og.png)

## Documentation

Visit https://reactnativereusables.com/docs to view the documentation.

## Community Resources

See the [community resources](./COMMUNITY_RESOURCES.md) for community-maintained components, libraries, and templates.

## Contributing

Please read the [contributing guide](/CONTRIBUTING.md).

## License

Licensed under the [MIT license](/LICENSE).

<br />
<br />
<a href="https://vercel.com/oss">
  <img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" />
</a>


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Reporting a Security Issue

If you discover a security issue in this repository, please help us by responsibly disclosing it to us. We appreciate your efforts and will work with you to address and resolve the problem.

Please follow these guidelines when reporting security issues:

### Responsible Disclosure

1. **Do not create public issues for security-related concerns.**
2. Email us at [hello@foundedlabs.com](mailto:hello@foundedlabs.com) with details about the issue.
3. Allow us a reasonable amount of time to address the issue before disclosing it publicly.

### Information to Include

When reporting a security issue, please provide the following information:

- Description of the issue, including steps to reproduce.
- Any specific details or context that can help us understand and address the problem.
- Your contact information for further communication.

## Code Copy-Pasting Disclaimer

This repository allows users to copy and paste code snippets. While we aim to ensure the security of the code, users are responsible for reviewing and using the code responsibly in their own projects. The repository maintainers are not liable for any security vulnerabilities or issues that may arise from code usage.

## Updates and Security Notices

Security updates and notices related to this repository will be communicated through the repository's README or other appropriate channels. Users are encouraged to stay informed about security-related announcements.

## Support

If you have any questions or need further assistance, you can reach out to us at [hello@foundedlabs.com](mailto:hello@foundedlabs.com).

Thank you for helping us keep this repository secure!


================================================
FILE: apps/cli/.changeset/config.json
================================================
{
  "$schema": "https://unpkg.com/@changesets/config@3.0.2/schema.json",
  "changelog": [
    "@changesets/changelog-github",
    {
      "repo": "founded-labs/react-native-reusables"
    }
  ],
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "restricted",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}


================================================
FILE: apps/cli/.github/actions/setup/action.yml
================================================
name: Setup
description: Perform standard setup and install dependencies using pnpm.
inputs:
  node-version:
    description: The version of Node.js to install
    required: true
    default: 20.16.0

runs:
  using: composite
  steps:
    - name: Install pnpm
      uses: pnpm/action-setup@v3
    - name: Install node
      uses: actions/setup-node@v4
      with:
        cache: pnpm
        node-version: ${{ inputs.node-version }}
    - name: Install dependencies
      shell: bash
      run: pnpm install


================================================
FILE: apps/cli/.github/workflows/check.yml
================================================
name: Check

on:
  workflow_dispatch:
  pull_request:
    branches: [main]
  push:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions: {}

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        uses: ./.github/actions/setup

  types:
    name: Types
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        uses: ./.github/actions/setup
      - run: pnpm check

  lint:
    name: Lint
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        uses: ./.github/actions/setup
      - run: pnpm lint

  test:
    name: Test
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        uses: ./.github/actions/setup
      - run: pnpm test


================================================
FILE: apps/cli/.github/workflows/release.yml
================================================


================================================
FILE: apps/cli/.github/workflows/snapshot.yml
================================================
name: Snapshot

on:
  pull_request:
    branches: [main, next-minor, next-major]
  workflow_dispatch:

permissions: {}

jobs:
  snapshot:
    name: Snapshot
    if: github.repository_owner == 'Effect-Ts'
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        uses: ./.github/actions/setup
      - name: Build package
        run: pnpm build
      - name: Create snapshot
        id: snapshot
        run: pnpx pkg-pr-new@0.0.24 publish --pnpm --comment=off


================================================
FILE: apps/cli/.gitignore
================================================
coverage/
*.tsbuildinfo
node_modules/
yarn-error.log
.ultra.cache.json
.DS_Store
tmp/
build/
dist/
.direnv/
.env
.env.local
.env.development.local
.env.test.local
.env.production.local


================================================
FILE: apps/cli/.prettierrc
================================================
{
  "tabWidth": 2,
  "printWidth": 120,
  "semi": false,
  "singleQuote": false,
  "trailingComma": "none",
  "arrowParens": "always"
}


================================================
FILE: apps/cli/.vscode/extensions.json
================================================
{
  "recommendations": [
    "effectful-tech.effect-vscode",
    "dbaeumer.vscode-eslint"
  ]
}

================================================
FILE: apps/cli/.vscode/settings.json
================================================
{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.preferences.importModuleSpecifier": "relative",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "editor.formatOnSave": true,
  "eslint.format.enable": true,
  "[json]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "prettier.semi": false,
    "prettier.trailingComma": "none"
  },
  "[javascript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[typescript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "eslint.validate": ["markdown", "javascript", "typescript"],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "editor.quickSuggestions": {
    "other": true,
    "comments": false,
    "strings": false
  },
  "editor.acceptSuggestionOnCommitCharacter": true,
  "editor.acceptSuggestionOnEnter": "on",
  "editor.quickSuggestionsDelay": 10,
  "editor.suggestOnTriggerCharacters": true,
  "editor.tabCompletion": "off",
  "editor.suggest.localityBonus": true,
  "editor.suggestSelection": "recentlyUsed",
  "editor.wordBasedSuggestions": "matchingDocuments",
  "editor.parameterHints.enabled": true,
  "files.insertFinalNewline": true
}


================================================
FILE: apps/cli/LICENSE
================================================
MIT License

Copyright (c) 2024-present Founded Labs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: apps/cli/README.md
================================================
# React Native Reusables CLI

A command-line toolkit to streamline the integration, setup, and maintenance of reusable React Native components in your projects.

## Features

- **Add**: Quickly add reusable React Native components to your project, with style and path options.
- **Doctor**: Diagnose your project for missing files, misconfigurations, and required dependencies. Optionally auto-install missing dependencies.
- **Init**: Bootstrap a new React Native project pre-configured for reusables, or inspect/repair an existing setup.

## Getting Started

### Installation

You can run the CLI directly with your favorite package manager:

```sh
npx @react-native-reusables/cli@latest <command>
pnpm dlx @react-native-reusables/cli@latest <command>
yarn dlx @react-native-reusables/cli@latest <command>
bunx --bun @react-native-reusables/cli@latest <command>
```

## Commands

---

### `@react-native-reusables/cli@latest add [options] [components...]`

Add one or more React Native components to your project.

| Argument   | Description                                                                   |
| ---------- | ----------------------------------------------------------------------------- |
| components | Name of component(s) to add. (e.g. `button`, `input`, `card`, `avatar`, etc.) |

| Option              | Description                          | Default         |
| ------------------- | ------------------------------------ | --------------- |
| `-y, --yes`         | Skip confirmation prompts.           | false           |
| `-o, --overwrite`   | Overwrite existing files.            | false           |
| `-c, --cwd <cwd>`   | The working directory.               | . (current dir) |
| `-a, --all`         | Add all available components.        | false           |
| `-p, --path <path>` | The path to add the component(s) to. |                 |
| `--styling-library <styling-library>` | Override detected styling library (`nativewind` or `uniwind`). | auto-detect |
| `-h, --help`        | Display help for command.            |                 |

---

### `rnr doctor [options]`

Check your project setup and diagnose issues.

| Option            | Description                                            | Default         |
| ----------------- | ------------------------------------------------------ | --------------- |
| `-y, --yes`       | Skip confirmation prompts for installing dependencies. | false           |
| `-c, --cwd <cwd>` | The working directory.                                 | . (current dir) |
| `--summary`       | Output a summary only.                                 | false           |
| `-h, --help`      | Display help for command.                              |                 |

---

### `rnr init [options]`

Initialize a new React Native project with reusables.

| Option            | Description               | Default         |
| ----------------- | ------------------------- | --------------- |
| `-c, --cwd <cwd>` | The working directory.    | . (current dir) |
| `-h, --help`      | Display help for command. |                 |

---

## Development

### Scripts

- `pnpm build` – Build the CLI for production.
- `pnpm dev` – Run the CLI in development mode.

> **Note:** If you are developing locally and want to use the `add` command in development mode, you must have the `apps/docs` app running. Start it from the root with:
>
> ```sh
> pnpm dev:docs
> ```
>
> This serves the component registry required for local development.

### Structure

- `src/cli.ts` – Main CLI entrypoint and command definitions.
- `src/bin.ts` – Node boot-strapper.
- `src/services/commands/` – Command implementations (`add`, `doctor`, `init`).
- `src/contexts/` – CLI option/context definitions.
- `src/utils/` – Utility functions.

## Contributing

See the [main repo README](../../README.md) for guidelines.


================================================
FILE: apps/cli/eslint.config.mjs
================================================
import { fixupPluginRules } from "@eslint/compat"
import { FlatCompat } from "@eslint/eslintrc"
import js from "@eslint/js"
import tsParser from "@typescript-eslint/parser"
import codegen from "eslint-plugin-codegen"
import _import from "eslint-plugin-import"
import simpleImportSort from "eslint-plugin-simple-import-sort"
import sortDestructureKeys from "eslint-plugin-sort-destructure-keys"
import path from "node:path"
import { fileURLToPath } from "node:url"

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all
})

export default [
  {
    ignores: ["**/dist", "**/build", "**/docs", "**/*.md"]
  },
  ...compat.extends(
    "eslint:recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@effect/recommended"
  ),
  {
    plugins: {
      import: fixupPluginRules(_import),
      "sort-destructure-keys": sortDestructureKeys,
      "simple-import-sort": simpleImportSort,
      codegen
    },

    languageOptions: {
      parser: tsParser,
      ecmaVersion: 2018,
      sourceType: "module"
    },

    settings: {
      "import/parsers": {
        "@typescript-eslint/parser": [".ts", ".tsx"]
      },

      "import/resolver": {
        typescript: {
          alwaysTryTypes: true
        }
      }
    },

    rules: {
      "codegen/codegen": "error",
      "no-fallthrough": "off",
      "no-irregular-whitespace": "off",
      "object-shorthand": "error",
      "prefer-destructuring": "off",
      "sort-imports": "off",

      "no-restricted-syntax": [
        "error",
        {
          selector: "CallExpression[callee.property.name='push'] > SpreadElement.arguments",
          message: "Do not use spread arguments in Array.push"
        }
      ],

      "no-unused-vars": "off",
      "prefer-rest-params": "off",
      "prefer-spread": "off",
      "import/first": "error",
      "import/newline-after-import": "error",
      "import/no-duplicates": "error",
      "import/no-unresolved": "off",
      "import/order": "off",
      "simple-import-sort/imports": "off",
      "sort-destructure-keys/sort-destructure-keys": "error",
      "deprecation/deprecation": "off",

      "@typescript-eslint/array-type": [
        "warn",
        {
          default: "generic",
          readonly: "generic"
        }
      ],

      "@typescript-eslint/member-delimiter-style": 0,
      "@typescript-eslint/no-non-null-assertion": "off",
      "@typescript-eslint/ban-types": "off",
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-empty-interface": "off",
      "@typescript-eslint/consistent-type-imports": "warn",

      "@typescript-eslint/no-unused-vars": [
        "error",
        {
          argsIgnorePattern: "^_",
          varsIgnorePattern: "^_"
        }
      ],

      "@typescript-eslint/ban-ts-comment": "off",
      "@typescript-eslint/camelcase": "off",
      "@typescript-eslint/explicit-function-return-type": "off",
      "@typescript-eslint/explicit-module-boundary-types": "off",
      "@typescript-eslint/interface-name-prefix": "off",
      "@typescript-eslint/no-array-constructor": "off",
      "@typescript-eslint/no-use-before-define": "off",
      "@typescript-eslint/no-namespace": "off",
      "@effect/dprint": "off"
    }
  }
]


================================================
FILE: apps/cli/package.json
================================================
{
  "name": "@react-native-reusables/cli",
  "version": "0.7.1",
  "type": "module",
  "license": "MIT",
  "description": "A CLI for React Native Reusables",
  "repository": {
    "type": "git",
    "url": "https://github.com/founded-labs/react-native-reusables.git",
    "directory": "apps/cli"
  },
  "publishConfig": {
    "access": "public",
    "directory": "dist"
  },
  "scripts": {
    "build": "tsup && pnpm copy-package-json",
    "build:ts": "tsup",
    "clean": "rimraf dist/*",
    "check": "tsc -b tsconfig.json",
    "dev": "INTERNAL_ENV=development tsx src/bin.ts",
    "lint": "eslint \"**/{src,test,examples,scripts,dtslint}/**/*.{ts,mjs}\"",
    "lint-fix": "pnpm lint --fix",
    "test": "vitest run",
    "coverage": "vitest run --coverage",
    "copy-package-json": "tsx scripts/copy-package-json.ts",
    "changeset-version": "changeset version && node scripts/version.mjs",
    "changeset-publish": "pnpm build && TEST_DIST= pnpm vitest && changeset publish",
    "pub:beta": "pnpm publish --no-git-checks --access public --tag beta",
    "pub:next": "pnpm publish --no-git-checks --access public --tag next",
    "pub:release": "pnpm publish --access public"
  },
  "dependencies": {
    "tsconfig-paths": "^4.2.0"
  },
  "devDependencies": {
    "@changesets/changelog-github": "^0.5.0",
    "@changesets/cli": "^2.27.8",
    "@effect/cli": "latest",
    "@effect/eslint-plugin": "^0.2.0",
    "@effect/language-service": "^0.1.0",
    "@effect/platform": "latest",
    "@effect/platform-node": "latest",
    "@effect/vitest": "latest",
    "@eslint/compat": "1.1.1",
    "@eslint/eslintrc": "3.1.0",
    "@eslint/js": "9.10.0",
    "@types/node": "22.10.5",
    "@typescript-eslint/eslint-plugin": "^8.4.0",
    "@typescript-eslint/parser": "^8.4.0",
    "effect": "latest",
    "eslint": "^9.10.0",
    "eslint-import-resolver-typescript": "^3.6.3",
    "eslint-plugin-codegen": "0.28.0",
    "eslint-plugin-deprecation": "^3.0.0",
    "eslint-plugin-import": "^2.30.0",
    "eslint-plugin-simple-import-sort": "^12.1.1",
    "eslint-plugin-sort-destructure-keys": "^2.0.0",
    "execa": "^7.2.0",
    "log-symbols": "^7.0.1",
    "ora": "^6.1.2",
    "package-manager-detector": "^1.3.0",
    "tsup": "^8.2.4",
    "tsx": "^4.19.1",
    "typescript": "^5.9.3",
    "vitest": "^2.0.5"
  },
  "pnpm": {
    "patchedDependencies": {
      "@changesets/get-github-info@0.6.0": "patches/@changesets__get-github-info@0.6.0.patch"
    }
  }
}


================================================
FILE: apps/cli/patches/@changesets__get-github-info@0.6.0.patch
================================================
diff --git a/dist/changesets-get-github-info.cjs.js b/dist/changesets-get-github-info.cjs.js
index a74df59f8a5988f458a3476087399f5e6dfe4818..ce5e60ef9916eb0cb76ab1e9dd422abcad752bf6 100644
--- a/dist/changesets-get-github-info.cjs.js
+++ b/dist/changesets-get-github-info.cjs.js
@@ -251,18 +251,13 @@ async function getInfo(request) {
     b = new Date(b.mergedAt);
     return a > b ? 1 : a < b ? -1 : 0;
   })[0] : null;
-
-  if (associatedPullRequest) {
-    user = associatedPullRequest.author;
-  }
-
   return {
     user: user ? user.login : null,
     pull: associatedPullRequest ? associatedPullRequest.number : null,
     links: {
       commit: `[\`${request.commit.slice(0, 7)}\`](${data.commitUrl})`,
       pull: associatedPullRequest ? `[#${associatedPullRequest.number}](${associatedPullRequest.url})` : null,
-      user: user ? `[@${user.login}](${user.url})` : null
+      user: user ? `@${user.login}` : null
     }
   };
 }
diff --git a/dist/changesets-get-github-info.esm.js b/dist/changesets-get-github-info.esm.js
index 27e5c972ab1202ff16f5124b471f4bbcc46be2b5..3940a8fe86e10cb46d8ff6436dea1103b1839927 100644
--- a/dist/changesets-get-github-info.esm.js
+++ b/dist/changesets-get-github-info.esm.js
@@ -242,18 +242,13 @@ async function getInfo(request) {
     b = new Date(b.mergedAt);
     return a > b ? 1 : a < b ? -1 : 0;
   })[0] : null;
-
-  if (associatedPullRequest) {
-    user = associatedPullRequest.author;
-  }
-
   return {
     user: user ? user.login : null,
     pull: associatedPullRequest ? associatedPullRequest.number : null,
     links: {
       commit: `[\`${request.commit.slice(0, 7)}\`](${data.commitUrl})`,
       pull: associatedPullRequest ? `[#${associatedPullRequest.number}](${associatedPullRequest.url})` : null,
-      user: user ? `[@${user.login}](${user.url})` : null
+      user: user ? `@${user.login}` : null
     }
   };
 }


================================================
FILE: apps/cli/scripts/copy-package-json.ts
================================================
import { FileSystem, Path } from "@effect/platform"
import { NodeContext } from "@effect/platform-node"
import { Effect } from "effect"

const program = Effect.gen(function* () {
  const fs = yield* FileSystem.FileSystem
  const path = yield* Path.Path
  yield* Effect.log("[Build] Copying package.json ...")
  const json: any = yield* fs.readFileString("package.json").pipe(Effect.map(JSON.parse))
  const pkg = {
    name: json.name,
    version: json.version,
    type: json.type,
    description: json.description,
    main: "bin.cjs",
    bin: "bin.cjs",
    engines: json.engines,
    dependencies: json.dependencies,
    peerDependencies: json.peerDependencies,
    repository: json.repository,
    author: json.author,
    license: json.license,
    bugs: json.bugs,
    homepage: json.homepage,
    tags: json.tags,
    keywords: json.keywords
  }
  yield* fs.writeFileString(path.join("dist", "package.json"), JSON.stringify(pkg, null, 2))
  yield* Effect.log("[Build] Build completed.")
}).pipe(Effect.provide(NodeContext.layer))

Effect.runPromise(program).catch(console.error)


================================================
FILE: apps/cli/src/bin.ts
================================================
#!/usr/bin/env node

import * as NodeContext from "@effect/platform-node/NodeContext"
import * as NodeRuntime from "@effect/platform-node/NodeRuntime"
import * as Effect from "effect/Effect"
import * as Cli from "./cli.js"

Effect.suspend(Cli.run).pipe(
  Effect.provide(NodeContext.layer),
  Effect.catchAll((error) => {
    if (error instanceof Error) {
      Effect.logDebug(error)
      return Effect.logError(error.message)
    }
    return Effect.logError(error)
  }),
  NodeRuntime.runMain({ disableErrorReporting: true })
)


================================================
FILE: apps/cli/src/cli.ts
================================================
import { all, cwd, overwrite, path, stylingLibrary, summary, template, yes } from "@cli/contexts/cli-options.js"
import * as Add from "@cli/services/commands/add.js"
import * as Doctor from "@cli/services/commands/doctor.js"
import * as Init from "@cli/services/commands/init.js"
import { Args, Command, Prompt } from "@effect/cli"
import { Effect, pipe } from "effect"

const addArgs = Args.all({
  components: Args.text({ name: "components" }).pipe(Args.repeated)
})

const AddCommand = Command.make("add", { args: addArgs, cwd, yes, overwrite, all, path, stylingLibrary })
  .pipe(Command.withDescription("Add React Native components to your project"))
  .pipe(Command.withHandler(Add.make))

const DoctorCommand = Command.make("doctor", { cwd, summary, yes })
  .pipe(Command.withDescription("Check your project setup and diagnose issues"))
  .pipe(Command.withHandler(Doctor.make))

const InitCommand = Command.make("init", { cwd, template })
  .pipe(Command.withDescription("Initialize a new React Native project with reusables"))
  .pipe(Command.withHandler(Init.make))

const Cli = Command.make("react-native-reusables/cli", { cwd })
  .pipe(Command.withDescription("React Native Reusables CLI - A powerful toolkit for React Native development"))
  .pipe(
    Command.withHandler((options) =>
      Effect.gen(function* () {
        yield* Effect.log("React Native Reusables CLI - A powerful toolkit for React Native development")
        const choice = yield* Prompt.select({
          message: "What would you like to do?",
          choices: [
            { title: "Add a component", value: "add" },
            { title: "Inspect project configuration", value: "doctor" },
            { title: "Initialize a new project", value: "init" }
          ]
        })

        if (choice === "add") {
          yield* Add.make({
            cwd: options.cwd,
            yes: true,
            overwrite: false,
            all: false,
            path: "",
            stylingLibrary: undefined,
            args: { components: [] }
          })
        } else if (choice === "doctor") {
          yield* Doctor.make({ cwd: options.cwd, summary: false, yes: false })
        } else if (choice === "init") {
          yield* Init.make({ cwd: options.cwd, template: "" })
        }
      })
    )
  )
  .pipe(Command.withSubcommands([AddCommand, DoctorCommand, InitCommand]))

export const run = () =>
  pipe(
    process.argv,
    Command.run(Cli, {
      name: "@react-native-reusables/cli",
      version: "1.0.0"
    })
  )


================================================
FILE: apps/cli/src/contexts/cli-options.ts
================================================
import { Options } from "@effect/cli"
import { Context, Option } from "effect"

type StylingLibrary = "nativewind" | "uniwind"

class CliOptions extends Context.Tag("CommandOptions")<
  CliOptions,
  Readonly<{
    cwd: string
    yes: boolean
    stylingLibrary: StylingLibrary | undefined
  }>
>() { }

const cwd = Options.directory("cwd", { exists: "yes" }).pipe(Options.withDefault("."), Options.withAlias("c"))
const yes = Options.boolean("yes", { aliases: ["y"] })
const summary = Options.boolean("summary").pipe(Options.withAlias("s"))
const overwrite = Options.boolean("overwrite", { aliases: ["o"] })
const all = Options.boolean("all", { aliases: ["a"] })
const path = Options.text("path").pipe(Options.withDefault(""), Options.withAlias("p"))
const stylingLibrary = Options.choice("styling-library", ["nativewind", "uniwind"] as const).pipe(
  Options.optional,
  Options.map(Option.getOrUndefined),
  Options.withDescription("Override the detected styling library for this command"),
)
const template = Options.text("template").pipe(Options.withAlias("t"), Options.withDefault(""))

export { CliOptions, cwd, summary, yes, overwrite, all, path, stylingLibrary, template }
export type { StylingLibrary }


================================================
FILE: apps/cli/src/project-manifest.ts
================================================
interface FileCheck {
  name: string
  fileNames: Array<string>
  docs: string
  includes: Array<{
    content: Array<string>
    message: string
    docs: string
  }>
  stylingLibraries: Array<"nativewind" | "uniwind">
}

type CustomFileCheck = Omit<FileCheck, "fileNames"> & { defaultFileNames?: ReadonlyArray<string> }

interface FileWithContent extends FileCheck {
  content: string
}

interface MissingInclude {
  fileName: string
  content: ReadonlyArray<string>
  message: string
  docs: string
}

const CORE_DEPENDENCIES = [
  "expo",
  "react-native-reanimated",
  "react-native-safe-area-context",
  "tailwindcss-animate",
  "class-variance-authority",
  "clsx",
  "tailwind-merge"
]

const DEPENDENCIES = {
  nativewind: [...CORE_DEPENDENCIES, "nativewind"],
  uniwind: [...CORE_DEPENDENCIES, "uniwind"]
}

const DEV_DEPENDENCIES = ["tailwindcss@^3.4.14"]

const FILE_CHECKS: Array<FileCheck> = [
  {
    name: "Babel Config",
    fileNames: ["babel.config.js", "babel.config.ts"],
    docs: "https://www.nativewind.dev/docs/getting-started/installation#3-add-the-babel-preset",
    includes: [
      {
        content: ["nativewind/babel", "jsxImportSource"],
        message: "jsxImportSource or nativewind/babel is missing",
        docs: "https://www.nativewind.dev/docs/getting-started/installation#3-add-the-babel-preset"
      }
    ],
    stylingLibraries: ["nativewind"] as const
  },
  {
    name: "Metro Config",
    fileNames: ["metro.config.js", "metro.config.ts"],
    docs: "https://www.nativewind.dev/docs/getting-started/installation#4-create-or-modify-your-metroconfigjs",
    includes: [
      {
        content: ["withNativeWind("],
        message: "The withNativeWind function is missing",
        docs: "https://www.nativewind.dev/docs/getting-started/installation#4-create-or-modify-your-metroconfigjs"
      },
      {
        content: ["inlineRem", "16"],
        message: "The 'inlineRem: 16' is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#update-the-default-inlined-rem-value"
      }
    ],
    stylingLibraries: ["nativewind"] as const
  },
  {
    name: "Metro Config",
    fileNames: ["metro.config.js", "metro.config.ts"],
    docs: "https://www.nativewind.dev/docs/getting-started/installation#4-create-or-modify-your-metroconfigjs",
    includes: [
      {
        content: ["withUniwindConfig("],
        message: "The withUniwindConfig function is missing",
        docs: "https://docs.uniwind.dev/api/metro-config#metro-config-js"
      }
    ],
    stylingLibraries: ["uniwind"] as const
  },
  {
    name: "Root Layout",
    fileNames: ["app/_layout.tsx", "src/app/_layout.tsx"],
    docs: "https://reactnativereusables.com/docs/installation/manual#add-the-portal-host-to-your-root-layout", //
    includes: [
      {
        content: [".css"],
        message: "The css file import is missing",
        docs: "https://www.nativewind.dev/docs/getting-started/installation#5-import-your-css-file"
      },
      {
        content: ["<PortalHost"],
        message: "The PortalHost component is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#add-the-portal-host-to-your-root-layout"
      }
    ],
    stylingLibraries: ["nativewind", "uniwind"] as const
  }
]

const DEPRECATED_FROM_LIB: Array<Omit<FileCheck, "docs" | "stylingLibraries">> = [
  {
    name: "Icons",
    fileNames: ["icons/iconWithClassName.ts"],
    includes: [
      {
        content: ["iconWithClassName"],
        message: "lib/icons and its contents are deprecated. Use the new icon wrapper from components/ui/icon.",
        docs: "https://reactnativereusables.com/docs/changelog#august-2025-deprecated"
      }
    ]
  },
  {
    name: "Constants",
    fileNames: ["constants.ts"],
    includes: [
      {
        content: ["NAV_THEME"],
        message: "Usage of lib/constants for NAV_THEME is deprecated. Use lib/theme instead.",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      }
    ]
  },
  {
    name: "useColorScheme",
    fileNames: ["useColorScheme.tsx"],
    includes: [
      {
        content: ["useColorScheme"],
        message: "lib/useColorScheme is deprecated. Use Nativewind's color scheme hook instead.",
        docs: "https://www.nativewind.dev/docs/api/use-color-scheme"
      }
    ]
  }
]

const DEPRECATED_FROM_UI: Array<Omit<FileCheck, "docs" | "stylingLibraries">> = [
  {
    name: "Typography",
    fileNames: ["typography.tsx"],
    includes: [
      {
        content: [
          "function H1({",
          "function H2({",
          "function H3({",
          "function H4({",
          "function P({",
          "function BlockQuote({",
          "function Code({",
          "function Lead({",
          "function Large({",
          "function Small({",
          "function Muted({"
        ],
        message:
          "Typography is deprecated. Instead, use the Text component with its variant prop (e.g. <Text variant='h1'>Title</Text>)",
        docs: "https://reactnativereusables.com/docs/components/text#typography"
      }
    ]
  }
]

// Excludes foreground colors since it is formatted differently in all 3 styling files (tailwind config, global.css, theme.ts)
const CSS_VARIABLE_NAMES = [
  "background",
  "foreground",
  "card",
  "popover",
  "primary",
  "secondary",
  "muted",
  "accent",
  "destructive",
  "border",
  "input",
  "ring",
  "radius"
]

const CUSTOM_FILE_CHECKS: Record<string, CustomFileCheck> = {
  tailwindConfig: {
    name: "Tailwind Config",
    defaultFileNames: ["tailwind.config.js", "tailwind.config.ts"],
    docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles",
    includes: [
      {
        content: ["nativewind/preset"],
        message: "The nativewind preset is missing",
        docs: "https://www.nativewind.dev/docs/getting-started/installation#2-setup-tailwind-css"
      },
      {
        content: CSS_VARIABLE_NAMES,
        message: "At least one of the color css variables is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      }
    ],
    stylingLibraries: ["nativewind"] as const
  },
  theme: {
    name: "Theme",
    defaultFileNames: ["lib/theme.ts"],
    docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles",
    includes: [
      {
        content: CSS_VARIABLE_NAMES,
        message: "At least one of the color variables is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      },
      {
        content: ["NAV_THEME"],
        message: "The NAV_THEME is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      }
    ],
    stylingLibraries: ["nativewind", "uniwind"] as const
  },
  nativewindEnv: {
    name: "Nativewind Env",
    docs: "https://www.nativewind.dev/docs/getting-started/installation#7-typescript-setup-optional",
    includes: [
      {
        content: ["nativewind/types"],
        message: "The nativewind types are missing",
        docs: "https://www.nativewind.dev/docs/getting-started/installation#7-typescript-setup-optional"
      }
    ],
    stylingLibraries: ["nativewind"] as const
  },
  uniwindTypes: {
    name: "Uniwind Types",
    defaultFileNames: ["uniwind-types.d.ts"],
    docs: "https://docs.uniwind.dev/api/metro-config#dtsfile",
    includes: [
      {
        content: ["uniwind/types"],
        message: "The uniwind types are missing",
        docs: "https://docs.uniwind.dev/api/metro-config#dtsfile"
      }
    ],
    stylingLibraries: ["uniwind"] as const
  },
  utils: {
    name: "Utils",
    defaultFileNames: ["lib/utils.ts"],
    docs: "https://reactnativereusables.com/docs/installation/manual#add-a-cn-helper",
    includes: [
      {
        content: ["function cn("],
        message: "The cn function is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#add-a-cn-helper"
      }
    ],
    stylingLibraries: ["nativewind", "uniwind"] as const
  },
  css: {
    name: "CSS",
    defaultFileNames: ["globals.css", "src/global.css"],
    docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles",
    includes: [
      {
        content: ["@tailwind base", "@tailwind components", "@tailwind utilities"],
        message: "The tailwind layer directives are missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      },
      {
        content: CSS_VARIABLE_NAMES,
        message: "At least one of the color css variables is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      }
    ],
    stylingLibraries: ["nativewind"] as const
  },
  uniwindCss: {
    name: "CSS",
    defaultFileNames: ["globals.css", "src/global.css"],
    docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles",
    includes: [
      {
        content: ["tailwindcss", "uniwind"],
        message: "The tailwind layer directives are missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      },
      {
        content: CSS_VARIABLE_NAMES,
        message: "At least one of the color css variables is missing",
        docs: "https://reactnativereusables.com/docs/installation/manual#configure-your-styles"
      }
    ],
    stylingLibraries: ["uniwind"] as const
  }
}

const NATIVEWIND_ENV_FILE = "nativewind-env.d.ts"
const UNIWIND_TYPES_FILE = "uniwind-types.d.ts"

const COMPONENTS = [
  "accordion",
  "alert-dialog",
  "alert",
  "aspect-ratio",
  "avatar",
  "badge",
  "button",
  "card",
  "checkbox",
  "collapsible",
  "context-menu",
  "dialog",
  "dropdown-menu",
  "hover-card",
  "input",
  "label",
  "menubar",
  "popover",
  "progress",
  "radio-group",
  "select",
  "separator",
  "skeleton",
  "switch",
  "tabs",
  "text",
  "textarea",
  "toggle-group",
  "toggle",
  "tooltip"
]

const TEMPLATES = [
  {
    name: "Minimal (Nativewind)",
    url: "https://github.com/founded-labs/react-native-reusables-templates.git",
    subPath: "minimal"
  },
  {
    name: "Minimal (Uniwind)",
    url: "https://github.com/founded-labs/react-native-reusables-templates.git",
    subPath: "minimal-uniwind"
  },
  {
    name: "Clerk auth (Nativewind)",
    url: "https://github.com/founded-labs/react-native-reusables-templates.git",
    subPath: "clerk-auth"
  }
]

const PROJECT_MANIFEST = {
  dependencies: DEPENDENCIES,
  devDependencies: DEV_DEPENDENCIES,
  fileChecks: FILE_CHECKS,
  deprecatedFromLib: DEPRECATED_FROM_LIB,
  deprecatedFromUi: DEPRECATED_FROM_UI,
  customFileChecks: CUSTOM_FILE_CHECKS,
  nativewindEnvFile: NATIVEWIND_ENV_FILE,
  uniwindTypesFile: UNIWIND_TYPES_FILE,
  components: COMPONENTS,
  templates: TEMPLATES
}

export { PROJECT_MANIFEST }
export type { FileCheck, CustomFileCheck, FileWithContent, MissingInclude }


================================================
FILE: apps/cli/src/services/commands/add.ts
================================================
import { CliOptions, type StylingLibrary } from "@cli/contexts/cli-options.js"
import { PROJECT_MANIFEST } from "@cli/project-manifest.js"
import { Doctor } from "@cli/services/commands/doctor.js"
import { runCommand } from "@cli/utils/run-command.js"
import { Prompt } from "@effect/cli"
import { Effect, Layer } from "effect"
import { PackageManager } from "../package-manager.js"
import { ProjectConfig } from "../project-config.js"

type AddOptions = {
  cwd: string
  args: { components: Array<string> }
  yes: boolean
  overwrite: boolean
  all: boolean
  path: string
  stylingLibrary: StylingLibrary | undefined
}

class Add extends Effect.Service<Add>()("Add", {
  dependencies: [PackageManager.Default],
  effect: Effect.gen(function* () {
    const doctor = yield* Doctor
    const projectConfig = yield* ProjectConfig
    const packageManager = yield* PackageManager

    return {
      run: (options: AddOptions) =>
        Effect.gen(function* () {
          yield* Effect.logDebug(`Add options: ${JSON.stringify(options, null, 2)}`)

          yield* projectConfig.getComponentJson() // ensure components.json config is valid and prompt if not

          const components = options.all ? PROJECT_MANIFEST.components : (options.args?.components ?? [])

          if (components.length === 0) {
            const selectedComponents = yield* Prompt.multiSelect({
              message: "Select components to add",
              choices: PROJECT_MANIFEST.components.map((component) => ({
                title: component,
                value: component
              }))
            })
            for (const component of selectedComponents) {
              components.push(component)
            }
          }

          if (components.length === 0) {
            yield* Effect.fail(new Error("No components selected."))
          }

          yield* Effect.logDebug(`Selected components: ${components.join(", ")}`)

          const stylingLibrary = yield* projectConfig.getStylingLibrary()

          const registry = stylingLibrary === "uniwind" ? "uniwind" : "nativewind"

          const baseUrl =
            process.env.INTERNAL_ENV === "development"
              ? `http://localhost:3000/local/r/${registry}`
              : `https://reactnativereusables.com/r/${registry}`

          const componentUrls = components.map((component) => {
            const lowerCaseComponent = component.toLocaleLowerCase()
            return lowerCaseComponent.startsWith("http") ? lowerCaseComponent : `${baseUrl}/${lowerCaseComponent}.json`
          })

          const shadcnOptions = toShadcnOptions(options)

          const binaryRunner = yield* packageManager.getBinaryRunner(options.cwd)

          const commandArgs = [
            ...binaryRunner.slice(1),
            "shadcn@latest",
            "add",
            ...shadcnOptions,
            ...componentUrls
          ].filter((option) => option !== undefined)

          yield* Effect.logDebug(`Running command: ${binaryRunner[0]} ${commandArgs.join(" ")}`)

          yield* runCommand(binaryRunner[0], commandArgs, {
            cwd: options.cwd,
            stdio: "inherit"
          })

          yield* doctor.run({ ...options, summary: true })
        })
    }
  })
}) {}

function make(options: AddOptions) {
  const optionsLayer = Layer.succeed(CliOptions, { ...options, yes: true }) // For the project config
  return Effect.gen(function* () {
    const add = yield* Add

    return yield* add.run(options)
  }).pipe(
    Effect.provide(Add.Default),
    Effect.provide(Doctor.Default),
    Effect.provide(ProjectConfig.Default),
    Effect.provide(optionsLayer)
  )
}

export { make }

function toShadcnOptions(options: AddOptions) {
  const shadcnOptions = []

  if (options.overwrite) {
    shadcnOptions.push("--overwrite")
  }

  if (options.yes) {
    shadcnOptions.push("--yes")
  }

  if (options.path) {
    shadcnOptions.push("--path")
    shadcnOptions.push(options.path)
  }

  return shadcnOptions
}


================================================
FILE: apps/cli/src/services/commands/doctor.ts
================================================
import { CliOptions } from "@cli/contexts/cli-options.js"
import { type CustomFileCheck, type FileCheck, type MissingInclude, PROJECT_MANIFEST } from "@cli/project-manifest.js"
import { ProjectConfig } from "@cli/services/project-config.js"
import { RequiredFilesChecker } from "@cli/services/required-files-checker.js"
import { Spinner } from "@cli/services/spinner.js"
import { runCommand } from "@cli/utils/run-command.js"
import { Prompt } from "@effect/cli"
import { FileSystem, Path } from "@effect/platform"
import { Data, Effect, Layer, Schema } from "effect"
import logSymbols from "log-symbols"

const packageJsonSchema = Schema.Struct({
  dependencies: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.String })),
  devDependencies: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.String }))
})

class PackageJsonError extends Data.TaggedError("PackageJsonError")<{
  cause?: unknown
  message?: string
}> {}

type DoctorOptions = {
  cwd: string
  summary: boolean
  yes: boolean
}

class Doctor extends Effect.Service<Doctor>()("Doctor", {
  dependencies: [RequiredFilesChecker.Default, Spinner.Default],
  effect: Effect.gen(function* () {
    const options = yield* CliOptions
    const fs = yield* FileSystem.FileSystem
    const path = yield* Path.Path
    const requiredFileChecker = yield* RequiredFilesChecker
    const spinner = yield* Spinner
    const projectConfig = yield* ProjectConfig

    const stylingLibrary = yield* projectConfig.getStylingLibrary()

    if (stylingLibrary !== "unknown"){
      console.log(
        `\x1b[2m${logSymbols.info} Styling Library: ${stylingLibrary === "uniwind" ? "Uniwind" : "Nativewind"}\x1b[0m`
      )
    } 


    const checkRequiredDependencies = ({
      dependencies,
      devDependencies
    }: {
      dependencies: Array<string>
      devDependencies: Array<string>
    }) =>
      Effect.gen(function* () {
        const packageJsonExists = yield* fs.exists(path.join(options.cwd, "package.json"))
        if (!packageJsonExists) {
          return yield* Effect.fail(new PackageJsonError({ message: "A package.json was not found and is required." }))
        }

        const packageJson = yield* fs.readFileString(path.join(options.cwd, "package.json")).pipe(
          Effect.flatMap(Schema.decodeUnknown(Schema.parseJson())),
          Effect.flatMap(Schema.decodeUnknown(packageJsonSchema)),
          Effect.catchTags({
            ParseError: () => Effect.fail(new PackageJsonError({ message: "Failed to parse package.json" }))
          })
        )

        const uninstalledDependencies: Array<string> = []
        const uninstalledDevDependencies: Array<string> = []

        for (const dependency of dependencies) {
          if (
            !packageJson.dependencies?.[dependency.split("@")[0]] &&
            !packageJson.devDependencies?.[dependency.split("@")[0]]
          ) {
            uninstalledDependencies.push(dependency)
            continue
          }
          yield* Effect.logDebug(
            `${logSymbols.success} ${dependency}@${packageJson.dependencies?.[dependency.split("@")[0]]} is installed`
          )
        }

        for (const devDependency of devDependencies) {
          if (
            !packageJson.devDependencies?.[devDependency.split("@")[0]] &&
            !packageJson.dependencies?.[devDependency.split("@")[0]]
          ) {
            uninstalledDevDependencies.push(devDependency)
            continue
          }
          yield* Effect.logDebug(
            `${logSymbols.success} ${devDependency}@${packageJson.devDependencies?.[devDependency]} is installed`
          )
        }

        return { uninstalledDependencies, uninstalledDevDependencies }
      })

    const registry = stylingLibrary === "uniwind" ? "uniwind" : "nativewind"

    return {
      run: (options: DoctorOptions) =>
        Effect.gen(function* () {
          yield* Effect.logDebug(`Doctor options: ${JSON.stringify(options, null, 2)}`)
          const { uninstalledDependencies, uninstalledDevDependencies } = yield* checkRequiredDependencies({
            dependencies: PROJECT_MANIFEST.dependencies[registry],
            devDependencies: PROJECT_MANIFEST.devDependencies
          })

          const { customFileResults, deprecatedFileResults, fileResults } = yield* requiredFileChecker.run({
            customFileChecks: PROJECT_MANIFEST.customFileChecks,
            deprecatedFromLib: PROJECT_MANIFEST.deprecatedFromLib,
            deprecatedFromUi: PROJECT_MANIFEST.deprecatedFromUi,
            fileChecks: PROJECT_MANIFEST.fileChecks,
            stylingLibrary: registry 
          })

          const result = {
            missingFiles: [...fileResults.missingFiles, ...customFileResults.missingFiles],
            uninstalledDependencies,
            uninstalledDevDependencies,
            missingIncludes: [...fileResults.missingIncludes, ...customFileResults.missingIncludes],
            deprecatedFileResults
          }

          let total = Object.values(result).reduce((sum, cat) => sum + cat.length, 0)
          if (!options.summary) {
            const dependenciesToInstall: Array<string> = []
            for (const dep of result.uninstalledDependencies) {
              const confirmsInstall = options.yes
                ? true
                : yield* Prompt.confirm({
                    message: `The ${dep} dependency is missing. Do you want to install it?`,
                    initial: true
                  })
              if (confirmsInstall) {
                if (uninstalledDependencies.includes("expo")) {
                  continue
                }
                total--
                yield* Effect.logDebug(`Adding ${dep} to dependencies to install`)
                dependenciesToInstall.push(dep)
                result.uninstalledDependencies = result.uninstalledDependencies.filter((d) => d !== dep)
              }
            }

            if (dependenciesToInstall.length > 0) {
              yield* Effect.logDebug(`Installing ${dependenciesToInstall.join(", ")}`)
              if (process.env.INTERNAL_ENV !== "development") {
                spinner.start("Installing dependencies")
                yield* runCommand("npx", ["expo", "install", ...dependenciesToInstall], {
                  cwd: options.cwd
                })
                spinner.stop()
              }
            }

            const devDependenciesToInstall: Array<string> = []
            for (const dep of result.uninstalledDevDependencies) {
              const confirmsInstall = options.yes
                ? true
                : yield* Prompt.confirm({
                    message: `The ${dep} dependency is missing. Do you want to install it?`,
                    initial: true
                  })
              if (confirmsInstall) {
                if (uninstalledDependencies.includes("expo")) {
                  continue
                }
                total--
                yield* Effect.logDebug(`Adding ${dep} to devDependencies to install`)
                devDependenciesToInstall.push(dep)
                result.uninstalledDevDependencies = result.uninstalledDevDependencies.filter((d) => d !== dep)
              }
            }

            if (devDependenciesToInstall.length > 0) {
              yield* Effect.logDebug(`Installing ${devDependenciesToInstall.join(", ")}`)
              if (process.env.INTERNAL_ENV !== "development") {
                spinner.start("Installing dev dependencies")
                yield* runCommand("npx", ["expo", "install", ...devDependenciesToInstall], {
                  cwd: options.cwd
                })
                spinner.stop()
              }
            }
          }

          if (total === 0) {
            console.log(`\x1b[2m${logSymbols.success} All checks passed.\x1b[0m\n`)
            return yield* Effect.succeed(true)
          }

          const analysis = analyzeResult(result)
          if (options.summary) {
            console.log(
              `\x1b[2m${logSymbols.warning} ${total} Potential issue${
                total > 1 ? "s" : ""
              } found. For more info, run: 'npx @react-native-reusables/cli doctor${
                options.cwd !== "." ? ` -c ${options.cwd}` : ""
              }'\x1b[0m\n`
            )
          } else {
            yield* Effect.log("\n\n🩺 Diagnosis")
            for (const item of analysis) {
              console.group(`\n${item.title}`)
              item.logs.forEach((line) => console.log(line))
              console.groupEnd()
            }
            console.log(`\n`)
          }
        })
    }
  })
}) {}

function make(options: DoctorOptions) {
  const optionsLayer = Layer.succeed(CliOptions, { ...options, stylingLibrary: undefined })
  return Effect.gen(function* () {
    const doctor = yield* Doctor
    return yield* doctor.run(options)
  }).pipe(Effect.provide(Doctor.Default), Effect.provide(ProjectConfig.Default), Effect.provide(optionsLayer))
}

export { Doctor, make }

interface Result {
  missingFiles: Array<FileCheck | CustomFileCheck>
  missingIncludes: Array<MissingInclude>
  uninstalledDependencies: Array<string>
  uninstalledDevDependencies: Array<string>
  deprecatedFileResults: Array<Omit<FileCheck, "docs" | "stylingLibraries">>
}

function analyzeResult(result: Result) {
  const categories: Array<{ title: string; logs: Array<string>; count: number }> = []

  if (result.missingFiles.length > 0) {
    categories.push({
      title: `${logSymbols.error} Missing Files (${result.missingFiles.length})`,
      count: result.missingFiles.length,
      logs: result.missingFiles.flatMap((f) => [`• ${f.name}`, `  📘 Docs: ${f.docs}`])
    })
  }

  if (result.missingIncludes.length > 0) {
    categories.push({
      title: `${logSymbols.error} Potentially Misconfigured Files (${result.missingIncludes.length})`,
      count: result.missingIncludes.length,
      logs: result.missingIncludes.flatMap((inc) => [
        `• ${inc.fileName}`,
        `  ↪ ${inc.message}`,
        `  📘 Docs: ${inc.docs}`
      ])
    })
  }

  if (result.uninstalledDependencies.length > 0) {
    categories.push({
      title: `${logSymbols.error} Missing Dependencies (${result.uninstalledDependencies.length})`,
      count: result.uninstalledDependencies.length,
      logs: ["• Install with:", `  ↪ npx expo install ${result.uninstalledDependencies.join(" ")}`]
    })
  }

  if (result.uninstalledDevDependencies.length > 0) {
    categories.push({
      title: `${logSymbols.error} Missing Dev Dependencies (${result.uninstalledDevDependencies.length})`,
      count: result.uninstalledDevDependencies.length,
      logs: ["• Install with:", `  ↪ npx expo install -- -D ${result.uninstalledDevDependencies.join(" ")}`]
    })
  }

  if (result.deprecatedFileResults.length > 0) {
    categories.push({
      title: `${logSymbols.warning} Deprecated (${result.deprecatedFileResults.length})`,
      count: result.deprecatedFileResults.length,
      logs: result.deprecatedFileResults.flatMap((deprecatedFile) => [
        `• ${deprecatedFile.name}`,
        ...deprecatedFile.includes.map((item) => `  ↪ ${item.message}\n  📘 Docs: ${item.docs}`)
      ])
    })
  }

  return categories
}


================================================
FILE: apps/cli/src/services/commands/init.ts
================================================
import { CliOptions } from "@cli/contexts/cli-options.js"
import { PROJECT_MANIFEST } from "@cli/project-manifest.js"
import { Doctor } from "@cli/services/commands/doctor.js"
import { ProjectConfig } from "@cli/services/project-config.js"
import { Template } from "@cli/services/template.js"
import { Prompt } from "@effect/cli"
import { FileSystem, Path } from "@effect/platform"
import { Effect, Layer } from "effect"
import logSymbols from "log-symbols"

type InitOptions = {
  cwd: string
  template: string
}

class Init extends Effect.Service<Init>()("Init", {
  dependencies: [Template.Default],
  effect: Effect.gen(function* () {
    const fs = yield* FileSystem.FileSystem
    const path = yield* Path.Path
    const doctor = yield* Doctor
    const template = yield* Template

    return {
      run: (options: InitOptions) =>
        Effect.gen(function* () {
          yield* Effect.logDebug(`Init options: ${JSON.stringify(options, null, 2)}`)

          const packageJsonExists = yield* fs.exists(path.join(options.cwd, "package.json"))

          yield* Effect.logDebug(`Does package.json exist: ${packageJsonExists ? "yes" : "no"}`)

          if (packageJsonExists) {
            yield* Effect.logWarning(`${logSymbols.warning} A project already exists in this directory.`)
            const choice = yield* Prompt.select({
              message: "How would you like to proceed?",
              choices: [
                { title: "Initialize a new project here anyway", value: "init-new" },
                { title: "Inspect project configuration", value: "doctor" },
                { title: "Cancel and exit", value: "cancel" }
              ]
            })
            yield* Effect.logDebug(`Init choice: ${choice}`)
            if (choice === "cancel") {
              return yield* Effect.succeed(true)
            }
            if (choice === "doctor") {
              console.log("")
              return yield* doctor.run({ ...options, summary: false, yes: false })
            }
          }

          const projectName = yield* Prompt.text({
            message: "What is the name of your project? (e.g. my-app)",
            default: "my-app"
          })

          const templateFromFlag = PROJECT_MANIFEST.templates.find((t) => t.subPath === options.template)

          const selectedTemplate = templateFromFlag
            ? templateFromFlag
            : yield* Prompt.select({
                message: "Select a template",
                choices: PROJECT_MANIFEST.templates.map((template) => ({
                  title: template.name,
                  value: template
                }))
              })

          yield* template.clone({
            cwd: options.cwd,
            name: projectName,
            repo: selectedTemplate
          })
        })
    }
  })
}) {}

function make(options: InitOptions) {
  const optionsLayer = Layer.succeed(CliOptions, { ...options, yes: true, stylingLibrary: undefined })
  return Effect.gen(function* () {
    const init = yield* Init

    return yield* init.run(options)
  }).pipe(
    Effect.provide(Init.Default),
    Effect.provide(Doctor.Default),
    Effect.provide(ProjectConfig.Default),
    Effect.provide(optionsLayer)
  )
}

export { make }


================================================
FILE: apps/cli/src/services/git.ts
================================================
import { Data, Effect } from "effect"
import { Command } from "@effect/platform"
import { Prompt } from "@effect/cli"
import logSymbols from "log-symbols"

export class GitError extends Data.TaggedError("GitError")<{
  cause?: unknown
  message?: string
}> {}

const COMMANDS = {
  status: Command.make("git", "status", "--porcelain")
} as const

export class Git extends Effect.Service<Git>()("Git", {
  succeed: {
    promptIfDirty: () =>
      Effect.gen(function* () {
        const gitStatus = yield* COMMANDS.status.pipe(
          Command.string,
          Effect.catchAll(() => Effect.succeed("")) // Not a git repository
        )
        const isDirty = gitStatus.trim().length > 0
        if (!isDirty) {
          return false
        }
        const result = yield* Prompt.confirm({
          message: `${logSymbols.warning} The Git repository is dirty (uncommitted changes). Continue anyway?`,
          initial: true
        })

        if (!result) {
          return yield* Effect.fail(new GitError({ message: "Aborted due to uncommitted changes." }))
        }

        return result
      })
  }
}) {}


================================================
FILE: apps/cli/src/services/package-manager.ts
================================================
import { Effect } from "effect"
import { detect } from "package-manager-detector"

const PACKAGE_MANAGERS = ["npm", "bun", "pnpm", "yarn@berry", "yarn"] as const

const BINARY_RUNNERS = {
  npm: ["npx"],
  bun: ["bunx", "--bun"],
  pnpm: ["pnpm", "dlx"],
  yarn: ["npx"],
  "yarn@berry": ["npx"]
} as const

const detectPackageManager = (cwd: string) =>
  Effect.tryPromise({
    try: () => {
      return detect({
        cwd,
        strategies: ["install-metadata", "lockfile", "packageManager-field", "devEngines-field"]
      })
    },
    catch: () => new Error("Failed to get package manager")
  })

const getPackageManager = (cwd: string) =>
  Effect.gen(function* () {
    const pm = yield* detectPackageManager(cwd)
    if (!pm) {
      return "npm"
    }
    const name = PACKAGE_MANAGERS.find((name) => pm.agent.startsWith(name) || pm.name.startsWith(name)) ?? "npm"
    return name
  })
const getBinaryRunner = (cwd: string) =>
  Effect.gen(function* () {
    const pm = yield* getPackageManager(cwd)
    return BINARY_RUNNERS[pm]
  })

class PackageManager extends Effect.Service<PackageManager>()("PackageManager", {
  succeed: {
    detectPackageManager,
    getPackageManager,
    getBinaryRunner
  }
}) {}

export { PackageManager }


================================================
FILE: apps/cli/src/services/project-config.ts
================================================
import { CliOptions } from "@cli/contexts/cli-options.js"
import { retryWith } from "@cli/utils/retry-with.js"
import { Prompt } from "@effect/cli"
import { FileSystem, Path } from "@effect/platform"
import { Effect, Schema } from "effect"
import { Git } from "./git.js"
import { type ConfigLoaderSuccessResult, createMatchPath, loadConfig as loadTypescriptConfig } from "tsconfig-paths"
import { PROJECT_MANIFEST } from "@cli/project-manifest.js"

const componentJsonSchema = Schema.Struct({
  $schema: Schema.optional(Schema.String),
  style: Schema.String,
  rsc: Schema.Boolean,
  tsx: Schema.Boolean,
  tailwind: Schema.Struct({
    config: Schema.optional(Schema.String),
    css: Schema.String,
    baseColor: Schema.String,
    cssVariables: Schema.Boolean,
    prefix: Schema.optional(Schema.String)
  }),
  aliases: Schema.Struct({
    components: Schema.String,
    utils: Schema.String,
    ui: Schema.optional(Schema.String),
    lib: Schema.optional(Schema.String),
    hooks: Schema.optional(Schema.String)
  }),
  iconLibrary: Schema.optional(Schema.String)
})

const supportedExtensions = [".ts", ".tsx", ".jsx", ".js", ".css"]

class ProjectConfig extends Effect.Service<ProjectConfig>()("ProjectConfig", {
  dependencies: [Git.Default],
  effect: Effect.gen(function* () {
    const fs = yield* FileSystem.FileSystem
    const path = yield* Path.Path
    const options = yield* CliOptions
    const git = yield* Git

    let componentJsonConfig: typeof componentJsonSchema.Type | null = null
    let tsConfig: ConfigLoaderSuccessResult | null = null

    const getComponentJson = () =>
      Effect.gen(function* () {
        if (componentJsonConfig) {
          return componentJsonConfig
        }

        const componentJsonExists = yield* fs.exists(path.join(options.cwd, "components.json"))
        if (!componentJsonExists) {
          return yield* handleInvalidComponentJson(false)
        }
        const config = yield* fs.readFileString(path.join(options.cwd, "components.json")).pipe(
          Effect.flatMap(Schema.decodeUnknown(Schema.parseJson())),
          Effect.flatMap(Schema.decodeUnknown(componentJsonSchema)),
          Effect.catchTags({
            ParseError: () => handleInvalidComponentJson(true)
          })
        )

        componentJsonConfig = config

        yield* Effect.logDebug(`componentJsonConfig: ${JSON.stringify(componentJsonConfig, null, 2)}`)
        return config
      })

    const getUniwindDtsPath = () =>
      Effect.gen(function* () {
        const metroConfigPaths = ["metro.config.js", "metro.config.ts"].map((p) => path.join(options.cwd, p)) as [
          string,
          ...Array<string>
        ]

        const metroContent = yield* retryWith((filePath: string) => fs.readFileString(filePath), metroConfigPaths).pipe(
          Effect.catchAll(() => Effect.succeed(null))
        )

        if (!metroContent?.includes("withUniwindConfig")) {
          return null
        }

        const dtsFileMatch = metroContent.match(/dtsFile\s*:\s*["']([^"']+)["']/)
        if (dtsFileMatch?.[1]) {
          const dtsPath = dtsFileMatch[1].replace(/^\.\//, "")
          return path.join(options.cwd, dtsPath)
        }

        return path.join(options.cwd, PROJECT_MANIFEST.uniwindTypesFile)
      })

    const getStylingLibrary = () =>
      Effect.gen(function* () {
        if (options.stylingLibrary) {
          return options.stylingLibrary
        }

        const metroConfigPaths = ["metro.config.js", "metro.config.ts"].map((p) => path.join(options.cwd, p)) as [
          string,
          ...Array<string>
        ]

        const metroContent = yield* retryWith((filePath: string) => fs.readFileString(filePath), metroConfigPaths).pipe(
          Effect.catchAll(() => Effect.succeed(null))
        )

        if (metroContent?.includes("withUniwindConfig")) {
          return "uniwind" as const
        }

        // v4 uses withNativeWind
        // v5 uses withNativewind
        if (metroContent?.toLowerCase().includes("withnativewind")) {
          return "nativewind" as const
        }

        return "unknown" as const 
      })

    const handleInvalidComponentJson = (exists: boolean) =>
      Effect.gen(function* () {
        yield* Effect.logWarning(
          `${exists ? "Invalid components.json" : "Missing components.json"}${" (required to continue)"}`
        )
        const agreeToWrite =  yield* Prompt.confirm({
              message: `Would you like to ${exists ? "update the" : "write a"} components.json file?`,
              label: { confirm: "y", deny: "n" },
              initial: true,
              placeholder: { defaultConfirm: "y/n" }
            })
        if (!agreeToWrite) {
          return yield* Effect.fail(new Error("Unable to continue without a valid components.json file."))
        }

        const baseColor = options.yes
          ? "neutral"
          : yield* Prompt.select({
              message: "Which color would you like to use as the base color?",
              choices: [
                { title: "neutral", value: "neutral" },
                { title: "stone", value: "stone" },
                { title: "zinc", value: "zinc" },
                { title: "gray", value: "gray" },
                { title: "slate", value: "slate" }
              ] as const
            })

        const hasRootGlobalCss = yield* fs.exists(path.join(options.cwd, "global.css"))

        const hasSrcGlobalCss = hasRootGlobalCss ? false : yield* fs.exists(path.join(options.cwd, "src/global.css"))

        const detectedCss = hasRootGlobalCss ? "global.css" : hasSrcGlobalCss ? "src/global.css" : ""

        const css =
          options.yes && detectedCss
            ? detectedCss
            : yield* Prompt.text({
                message: "What is the name of the CSS file and path to it? (e.g. global.css or src/global.css)",
                default: detectedCss
              })
        
        const stylingLibrary = yield* getStylingLibrary()

        const hasTailwindConfig = yield* fs.exists(path.join(options.cwd, "tailwind.config.js"))
        const tailwindConfig = stylingLibrary === "uniwind" ? "" :
          options.yes && hasTailwindConfig
            ? "tailwind.config.js"
            : yield* Prompt.text({
                message:
                  "What is the name of the Tailwind config file and path to it? (e.g. tailwind.config.js or src/tailwind.config.js)",
                default: "tailwind.config.js"
              })

        const tsConfig = yield* getTsConfig()

        const aliasSymbol = `${(Object.keys(tsConfig.paths ?? {})[0] ?? "@/*").split("/*")[0]}`

        const detectedAliases = {
          components: `${aliasSymbol}/components`,
          utils: `${aliasSymbol}/lib/utils`,
          ui: `${aliasSymbol}/components/ui`,
          lib: `${aliasSymbol}/lib`,
          hooks: `${aliasSymbol}/hooks`
        }

        let aliases = detectedAliases

        if (!options.yes) {
          const useDetectedAliases = yield* Prompt.confirm({
            message: `Use detected alias (${aliasSymbol}/*) in your setup?`,
            initial: true
          })

          if (!useDetectedAliases) {
            const [componentsAlias, utilsAlias, uiAlias, libAlias, hooksAlias] = yield* Prompt.all([
              Prompt.text({
                message: "What is the name of the components alias?",
                default: detectedAliases.components
              }),
              Prompt.text({
                message: "What is the name of the utils alias?",
                default: detectedAliases.utils
              }),
              Prompt.text({
                message: "What is the name of the ui alias?",
                default: detectedAliases.ui
              }),
              Prompt.text({
                message: "What is the name of the lib alias?",
                default: detectedAliases.lib
              }),
              Prompt.text({
                message: "What is the name of the hooks alias?",
                default: detectedAliases.hooks
              })
            ])

            aliases = {
              components: componentsAlias,
              utils: utilsAlias,
              ui: uiAlias,
              lib: libAlias,
              hooks: hooksAlias
            }
          }
        }

        const newComponentJson = yield* Schema.encode(componentJsonSchema)({
          $schema: "https://ui.shadcn.com/schema.json",
          style: "new-york",
          aliases,
          rsc: false,
          tsx: true,
          tailwind: {
            css,
            baseColor,
            cssVariables: true,
            config: tailwindConfig
          }
        })

        yield* git.promptIfDirty()
        yield* fs.writeFileString(path.join(options.cwd, "components.json"), JSON.stringify(newComponentJson, null, 2))
        yield* Effect.logDebug(`newComponentJson: ${JSON.stringify(newComponentJson, null, 2)}`)
        return newComponentJson
      })

    const getTsConfig = () =>
      Effect.try({
        try: () => {
          if (tsConfig) {
            return tsConfig
          }
          const configResult = loadTypescriptConfig(options.cwd)
          if (configResult.resultType === "failed") {
            throw new Error("Error loading tsconfig.json", { cause: configResult.message })
          }
          tsConfig = configResult
          return configResult
        },
        catch: (error) => new Error("Error loading {ts,js}config.json", { cause: String(error) })
      })

    const resolvePathFromAlias = (aliasPath: string) =>
      Effect.gen(function* () {
        const config = yield* getTsConfig()
        return yield* Effect.try({
          try: () => {
            const matchPath = createMatchPath(config.absoluteBaseUrl, config.paths)(
              aliasPath,
              undefined,
              () => true,
              supportedExtensions
            )
            if (!matchPath) {
              throw new Error("Path not found", { cause: aliasPath })
            }
            return matchPath
          },
          catch: (error) => new Error("Path not found", { cause: String(error) })
        })
      })

    return {
      getComponentJson,
      getTsConfig,
      resolvePathFromAlias,
      getStylingLibrary,
      getUniwindDtsPath
    }
  })
}) {}

export { ProjectConfig }


================================================
FILE: apps/cli/src/services/required-files-checker.ts
================================================
import { CliOptions } from "@cli/contexts/cli-options.js"
import type { CustomFileCheck, FileCheck, FileWithContent, MissingInclude } from "@cli/project-manifest.js"
import { PROJECT_MANIFEST } from "@cli/project-manifest.js"
import { ProjectConfig } from "@cli/services/project-config.js"
import { retryWith } from "@cli/utils/retry-with.js"
import { FileSystem, Path } from "@effect/platform"
import { Data, Effect } from "effect"
import logSymbols from "log-symbols"

class RequiredFileError extends Data.TaggedError("RequiredFileError")<{
  file: string
  message?: string
}> { }

class RequiredFilesChecker extends Effect.Service<RequiredFilesChecker>()("RequiredFilesChecker", {
  effect: Effect.gen(function* () {
    const fs = yield* FileSystem.FileSystem
    const path = yield* Path.Path
    const options = yield* CliOptions
    const projectConfig = yield* ProjectConfig

    const checkFiles = (fileChecks: Array<FileCheck>, stylingLibrary: "nativewind" | "uniwind") =>
      Effect.gen(function* () {
        const missingFiles: Array<FileCheck> = []
        const missingIncludes: Array<MissingInclude> = []

        const filesWithContent = yield* Effect.forEach(
          fileChecks.filter((file) => file.stylingLibraries.includes(stylingLibrary)),
          (file) =>
            retryWith(
              (filePath: string) =>
                Effect.gen(function* () {
                  const fileContents = yield* fs.readFileString(filePath)
                  yield* Effect.logDebug(`${logSymbols.success} ${file.name} found`)
                  return { ...file, content: fileContents } as FileWithContent
                }),
              file.fileNames.map((p) => path.join(options.cwd, p)) as [string, ...Array<string>]
            ).pipe(
              Effect.catchAll(() => {
                missingFiles.push(file)
                return Effect.logDebug(`${logSymbols.error} ${file.name} not found`).pipe(() => Effect.succeed(null))
              })
            ),
          { concurrency: "unbounded" }
        ).pipe(Effect.map((files) => files.filter((file): file is FileWithContent => file !== null)))

        yield* Effect.forEach(filesWithContent, (file) =>
          Effect.gen(function* () {
            const { content, includes, name } = file
            for (const include of includes) {
              if (include.content.every((str) => content.includes(str))) {
                yield* Effect.logDebug(`${logSymbols.success} ${name} has ${include.content.join(", ")}`)
                continue
              }
              yield* Effect.logDebug(`${logSymbols.error} ${name} missing ${include.content.join(", ")}`)
              missingIncludes.push({ ...include, fileName: name })
            }
          })
        )

        return { missingFiles, missingIncludes }
      })

    const checkDeprecatedFiles = (
      deprecatedFromLib: Array<Omit<FileCheck, "docs" | "stylingLibraries">>,
      deprecatedFromUi: Array<Omit<FileCheck, "docs" | "stylingLibraries">>
    ) =>
      Effect.gen(function* () {
        const componentJson = yield* projectConfig.getComponentJson()
        const aliasForLib = componentJson.aliases.lib ?? `${componentJson.aliases.utils}/lib`

        const existingDeprecatedFromLibs = yield* Effect.forEach(
          deprecatedFromLib,
          (file) =>
            projectConfig.resolvePathFromAlias(`${aliasForLib}/${file.fileNames[0]}`).pipe(
              Effect.flatMap((fullPath) =>
                Effect.gen(function* () {
                  const exists = yield* fs.exists(fullPath)
                  if (!exists) {
                    yield* Effect.logDebug(
                      `${logSymbols.success} Deprecated ${aliasForLib}/${file.fileNames[0]} not found`
                    )
                    return { ...file, hasIncludes: false }
                  }

                  yield* Effect.logDebug(`${logSymbols.error} Deprecated ${aliasForLib}/${file.fileNames[0]} found`)

                  const fileContent = yield* fs.readFileString(fullPath)

                  return {
                    ...file,
                    hasIncludes: file.includes.some((include) =>
                      include.content.some((content) => fileContent.includes(content))
                    )
                  }
                })
              )
            ),
          { concurrency: "unbounded" }
        ).pipe(
          Effect.map((results) =>
            results.filter((result) => result.hasIncludes).map(({ hasIncludes: _hasIncludes, ...result }) => result)
          )
        )

        const aliasForUi = componentJson.aliases.ui ?? `${componentJson.aliases.components}/ui`

        const existingDeprecatedFromUi = yield* Effect.forEach(
          deprecatedFromUi,
          (file) =>
            projectConfig.resolvePathFromAlias(`${aliasForUi}/${file.fileNames[0]}`).pipe(
              Effect.flatMap((fullPath) =>
                Effect.gen(function* () {
                  const exists = yield* fs.exists(fullPath)
                  if (!exists) {
                    yield* Effect.logDebug(
                      `${logSymbols.success} Deprecated ${aliasForUi}/${file.fileNames[0]} not found`
                    )
                    return { ...file, hasIncludes: false }
                  }

                  yield* Effect.logDebug(`${logSymbols.error} Deprecated ${aliasForUi}/${file.fileNames[0]} found`)

                  const fileContent = yield* fs.readFileString(fullPath)

                  return {
                    ...file,
                    hasIncludes: file.includes.some((include) =>
                      include.content.some((content) => fileContent.includes(content))
                    )
                  }
                })
              )
            ),
          { concurrency: "unbounded" }
        ).pipe(
          Effect.map((results) =>
            results.filter((result) => result.hasIncludes).map(({ hasIncludes: _hasIncludes, ...result }) => result)
          )
        )

        return [...existingDeprecatedFromLibs, ...existingDeprecatedFromUi]
      })

    const checkCustomFiles = (
      customFileChecks: Record<string, CustomFileCheck>,
      stylingLibrary: "nativewind" | "uniwind"
    ) =>
      Effect.gen(function* () {
        const componentJson = yield* projectConfig.getComponentJson()
        const aliasForLib = componentJson.aliases.lib ?? `${componentJson.aliases.utils}/lib`
        const missingFiles: Array<CustomFileCheck> = []
        const missingIncludes: Array<MissingInclude> = []

        // Check CSS files
        const cssPaths = [componentJson.tailwind.css, "global.css", "src/global.css"].filter((p) => p != null)
        const cssContent = yield* retryWith(
          (filePath: string) =>
            Effect.gen(function* () {
              const content = yield* fs.readFileString(filePath)
              yield* Effect.logDebug(`${logSymbols.success} ${customFileChecks.css.name} found`)
              return content
            }),
          cssPaths.map((p) => path.join(options.cwd, p)) as [string, ...Array<string>]
        ).pipe(
          Effect.catchAll(() =>
            Effect.fail(
              new RequiredFileError({
                file: "CSS",
                message:
                  "CSS file not found. Please follow the instructions at https://www.nativewind.dev/docs/getting-started/installation#installation-with-expo"
              })
            )
          )
        )

        const cssShouldInclude =
          stylingLibrary === "uniwind" ? customFileChecks.uniwindCss.includes : customFileChecks.css.includes

        for (const include of cssShouldInclude) {
          if (include.content.every((str) => cssContent.includes(str))) {
            yield* Effect.logDebug(
              `${logSymbols.success} ${customFileChecks.css.name} has ${include.content.join(", ")}`
            )
            continue
          }
          yield* Effect.logDebug(
            `${logSymbols.error} ${customFileChecks.css.name} missing ${include.content.join(", ")}`
          )
          missingIncludes.push({ ...include, fileName: customFileChecks.css.name })
        }

        // Check Nativewind env or Uniwind types file
        if (componentJson.tsx !== false) {
          const missingTypeFiles: Array<CustomFileCheck> = []

          if (stylingLibrary === "nativewind") {
            const nativewindEnvContent = yield* fs
              .readFileString(path.join(options.cwd, PROJECT_MANIFEST.nativewindEnvFile))
              .pipe(
                Effect.catchAll(() => {
                  missingTypeFiles.push(customFileChecks.nativewindEnv)
                  return Effect.succeed(null)
                })
              )

            if (nativewindEnvContent) {
              for (const include of customFileChecks.nativewindEnv.includes) {
                if (include.content.every((str) => nativewindEnvContent.includes(str))) {
                  yield* Effect.logDebug(
                    `${logSymbols.success} ${customFileChecks.nativewindEnv.name} has ${include.content.join(", ")}`
                  )
                  continue
                }
                yield* Effect.logDebug(
                  `${logSymbols.error} ${customFileChecks.nativewindEnv.name} missing ${include.content.join(", ")}`
                )
                missingIncludes.push({ ...include, fileName: customFileChecks.nativewindEnv.name })
              }
            }
          }

          if (stylingLibrary === "uniwind") {
            // Get uniwind dts path from metro config (supports custom dtsFile)
            const uniwindDtsPath = yield* projectConfig.getUniwindDtsPath()
            const uniwindTypesContent: string | null = uniwindDtsPath
              ? yield* fs.readFileString(uniwindDtsPath).pipe(
                Effect.catchAll(() => {
                  missingTypeFiles.push(customFileChecks.uniwindTypes)
                  return Effect.succeed(null)
                })
              )
              : null

            if (uniwindTypesContent) {
              for (const include of customFileChecks.uniwindTypes.includes) {
                if (include.content.every((str) => uniwindTypesContent.includes(str))) {
                  yield* Effect.logDebug(
                    `${logSymbols.success} ${customFileChecks.uniwindTypes.name} has ${include.content.join(", ")}`
                  )
                  continue
                }
                yield* Effect.logDebug(
                  `${logSymbols.error} ${customFileChecks.uniwindTypes.name} missing ${include.content.join(", ")}`
                )
                missingIncludes.push({ ...include, fileName: customFileChecks.uniwindTypes.name })
              }
            }
          }

          if (missingTypeFiles.length === 2) {
            missingFiles.push(missingTypeFiles[0], missingTypeFiles[1])
          }
        }

        if (stylingLibrary === "nativewind") {
          // Check Tailwind config
          const tailwindConfigPaths = [
            componentJson.tailwind.config,
            "tailwind.config.js",
            "tailwind.config.ts"
          ].filter((p) => p != null)
          const tailwindConfigContent = yield* retryWith(
            (filePath: string) =>
              Effect.gen(function* () {
                const content = yield* fs.readFileString(filePath)
                yield* Effect.logDebug(`${logSymbols.success} ${customFileChecks.tailwindConfig.name} found`)
                return content
              }),
            tailwindConfigPaths.map((p) => path.join(options.cwd, p)) as [string, ...Array<string>]
          ).pipe(
            Effect.catchAll(() => {
              console.warn(
                `${logSymbols.warning} Tailwind config not found, Please follow the instructions at https://www.nativewind.dev/docs/getting-started/installation#installation-with-expo`);
              return Effect.succeed("")
            })
          )

          for (const include of customFileChecks.tailwindConfig.includes) {
            if (include.content.every((str) => tailwindConfigContent.includes(str))) {
              yield* Effect.logDebug(
                `${logSymbols.success} ${customFileChecks.tailwindConfig.name} has ${include.content.join(", ")}`
              )
              continue
            }
            yield* Effect.logDebug(
              `${logSymbols.error} ${customFileChecks.tailwindConfig.name} missing ${include.content.join(", ")}`
            )
            missingIncludes.push({ ...include, fileName: customFileChecks.tailwindConfig.name })
          }
        }

        // Check theme file
        const themeAliasPath = yield* projectConfig.resolvePathFromAlias(`${aliasForLib}/theme.ts`)
        const themeContent = yield* fs.readFileString(themeAliasPath).pipe(
          Effect.catchAll(() => {
            missingFiles.push(customFileChecks.theme)
            return Effect.succeed(null)
          })
        )

        if (themeContent) {
          for (const include of customFileChecks.theme.includes) {
            if (include.content.every((str) => themeContent.includes(str))) {
              yield* Effect.logDebug(
                `${logSymbols.success} ${customFileChecks.theme.name} has ${include.content.join(", ")}`
              )
              continue
            }
            yield* Effect.logDebug(
              `${logSymbols.error} ${customFileChecks.theme.name} missing ${include.content.join(", ")}`
            )
            missingIncludes.push({ ...include, fileName: customFileChecks.theme.name })
          }
        } else {
          yield* Effect.logDebug(`${logSymbols.error} ${customFileChecks.theme.name} not found`)
        }

        // Check utils file
        const utilsPath = yield* projectConfig.resolvePathFromAlias(`${aliasForLib}/utils.ts`)
        const utilsContent = yield* fs.readFileString(utilsPath).pipe(
          Effect.catchAll(() => {
            missingFiles.push(customFileChecks.utils)
            return Effect.succeed(null)
          })
        )

        if (utilsContent) {
          for (const include of customFileChecks.utils.includes) {
            if (include.content.every((str) => utilsContent.includes(str))) {
              yield* Effect.logDebug(
                `${logSymbols.success} ${customFileChecks.utils.name} has ${include.content.join(", ")}`
              )
              continue
            }
            yield* Effect.logDebug(
              `${logSymbols.error} ${customFileChecks.utils.name} missing ${include.content.join(", ")}`
            )
            missingIncludes.push({ ...include, fileName: customFileChecks.utils.name })
          }
        } else {
          yield* Effect.logDebug(`${logSymbols.error} ${customFileChecks.utils.name} not found`)
        }

        return { missingFiles, missingIncludes }
      })

    return {
      run: ({
        customFileChecks,
        deprecatedFromLib,
        deprecatedFromUi,
        fileChecks,
        stylingLibrary
      }: {
        fileChecks: Array<FileCheck>
        customFileChecks: Record<string, CustomFileCheck>
        deprecatedFromLib: Array<Omit<FileCheck, "docs" | "stylingLibraries">>
        deprecatedFromUi: Array<Omit<FileCheck, "docs" | "stylingLibraries">>
        stylingLibrary: "nativewind" | "uniwind"
      }) =>
        Effect.gen(function* () {
          const [fileResults, customFileResults, deprecatedFileResults] = yield* Effect.all([
            checkFiles(fileChecks, stylingLibrary),
            checkCustomFiles(customFileChecks, stylingLibrary),
            checkDeprecatedFiles(deprecatedFromLib, deprecatedFromUi)
          ])

          return { fileResults, customFileResults, deprecatedFileResults }
        })
    }
  })
}) { }

export { RequiredFilesChecker }


================================================
FILE: apps/cli/src/services/spinner.ts
================================================
import { Effect } from "effect"
import ora from "ora"

class Spinner extends Effect.Service<Spinner>()("Spinner", {
  effect: Effect.gen(function* () {
    const spinner = yield* Effect.try({
      try: () => ora(),
      catch: () => new Error("Failed to create spinner")
    })

    return spinner
  })
}) {}

export { Spinner }


================================================
FILE: apps/cli/src/services/template.ts
================================================
import { runCommand } from "@cli/utils/run-command.js"
import { Prompt } from "@effect/cli"
import { FileSystem, Path } from "@effect/platform"
import { Effect } from "effect"
import { Spinner } from "@cli/services/spinner.js"
import logSymbols from "log-symbols"

class Template extends Effect.Service<Template>()("src/services/template", {
  dependencies: [Spinner.Default],
  effect: Effect.gen(function* () {
    const fs = yield* FileSystem.FileSystem
    const path = yield* Path.Path
    const spinner = yield* Spinner

    return {
      clone: ({ cwd, name, repo }: { cwd: string; name: string; repo: { subPath?: string; url: string } }) =>
        Effect.acquireUseRelease(
          fs.makeTempDirectory(),
          (tempDirPath) =>
            Effect.gen(function* () {
              yield* Effect.logDebug(`Template.clone args: ${JSON.stringify({ cwd, name, repo }, null, 2)}`)

              const newRepoPath = path.join(cwd, name)

              const newRepoPathExists = yield* fs.exists(newRepoPath)

              yield* Effect.logDebug(`Does ${newRepoPath} exist? ${newRepoPathExists ? "yes" : "no"}`)

              if (newRepoPathExists) {
                yield* Effect.logWarning(`${logSymbols.warning} A project already exists in this directory.`)
                const choice = yield* Prompt.select({
                  message: "How would you like to proceed?",
                  choices: [
                    { title: "Cancel and exit", value: "cancel" },
                    { title: "Overwrite the existing project", value: "overwrite" }
                  ]
                })

                if (choice === "cancel") {
                  yield* Effect.logDebug(`User chose to cancel`)
                  return yield* Effect.succeed(true)
                }

                const confirmOverwrite = yield* Prompt.confirm({
                  message: "Are you sure you want to overwrite the existing project?",
                  initial: true
                })

                if (!confirmOverwrite) {
                  yield* Effect.logDebug(`User chose to not overwrite the existing project`)
                  return yield* Effect.succeed(true)
                }
              }

              yield* Effect.logDebug(`Created temp directory: ${tempDirPath}`)

              const templateName = repo.subPath
                ? path.basename(repo.subPath)
                : path.basename(repo.url).replace(".git", "")

              spinner.start(`Initializing the ${templateName} template...`)
              yield* runCommand("git", ["clone", "--depth=1", "--branch", "main", repo.url, name], {
                cwd: tempDirPath
              })

              const cloneToTempPath = path.join(tempDirPath, name)

              yield* Effect.logDebug(`Cloned temp template to ${cloneToTempPath}`)

              yield* fs.copy(repo.subPath ? path.join(cloneToTempPath, repo.subPath) : cloneToTempPath, newRepoPath, {
                overwrite: true
              })

              yield* Effect.logDebug(`Copied template to ${newRepoPath}`)

              const allPaths = yield* fs.readDirectory(newRepoPath, { recursive: true })

              yield* Effect.logDebug(`Replacing template name ${templateName} with ${name} in ${allPaths.length} files`)
              yield* Effect.logDebug(`All paths: ${allPaths.join("\n")}`)

              yield* Effect.forEach(allPaths, (file) =>
                Effect.gen(function* () {
                  const content = yield* fs
                    .readFileString(path.join(newRepoPath, file))
                    .pipe(Effect.catchAll(() => Effect.succeed("")))

                  if (!content.includes(templateName)) {
                    return
                  }

                  yield* Effect.logDebug(`Replacing template name "${templateName}" with "${name}" in ${file}`)

                  const replaced = content.replaceAll(templateName, name)
                  yield* fs.writeFileString(path.join(newRepoPath, file), replaced)
                })
              )

              spinner.stop()

              const installDependencies = yield* Prompt.confirm({
                message: "Would you like to install dependencies?",
                initial: true
              })
              let packageManager = "none"
              if (installDependencies) {
                packageManager = yield* Prompt.select({
                  message: "Which package manager would you like to use?",
                  choices: [
                    { title: "bun", value: "bun" },
                    { title: "pnpm", value: "pnpm" },
                    { title: "npm", value: "npm" },
                    { title: "yarn", value: "yarn" }
                  ]
                })

                const npmrcPath = path.join(newRepoPath, ".npmrc")
                const hasNpmrc = yield* fs.exists(npmrcPath)

                if (packageManager === "pnpm" && !hasNpmrc) {
                  yield* Effect.logDebug(`Writing .npmrc file...`)
                  yield* fs.writeFileString(npmrcPath, "node-linker=hoisted\nenable-pre-post-scripts=true")
                }

                if (packageManager !== "pnpm" && packageManager !== "none" && hasNpmrc) {
                  yield* Effect.logDebug(`Removing .npmrc file...`)
                  yield* fs.remove(npmrcPath)
                }

                yield* runCommand(packageManager, ["install"], {
                  cwd: newRepoPath,
                  stdio: "inherit"
                })

                yield* runCommand("npx", ["expo", "install", "--fix"], {
                  cwd: newRepoPath,
                  stdio: "inherit"
                })
              }

              const gitInit = yield* Prompt.confirm({
                message: "Would you like to initialize a Git repository?",
                initial: true
              })

              if (gitInit) {
                spinner.start(`Initializing Git repository...`)

                let hasGitError = false
                yield* runCommand("git", ["init"], {
                  cwd: newRepoPath,
                  stdio: "inherit"
                }).pipe(
                  Effect.catchAll(() => {
                    hasGitError = true
                    return Effect.succeed(true)
                  })
                )

                if (!hasGitError) {
                  yield* runCommand("git", ["add", "-A"], {
                    cwd: newRepoPath,
                    stdio: "inherit"
                  }).pipe(
                    Effect.catchAll(() => {
                      hasGitError = true
                      return Effect.succeed(true)
                    })
                  )
                }

                if (!hasGitError) {
                  yield* runCommand("git", ["commit", "-m", "initialize project with @react-native-reusables/cli"], {
                    cwd: newRepoPath,
                    stdio: "inherit"
                  }).pipe(Effect.catchAll(() => Effect.succeed(true)))
                }
                spinner.stop()
              }

              console.log("\n")
              yield* Effect.log(`\x1b[37m${logSymbols.success} New project initialized successfully!\x1b[0m`)
              if (packageManager !== "none") {
                yield* Effect.log(
                  `\x1b[22m\x1b[38;5;250m${logSymbols.info} To get started, run: \x1b[37m\`cd ${path.join(
                    cwd,
                    name
                  )} && ${packageManager} ${
                    packageManager === "npm" || packageManager === "bun" ? "run" : ""
                  } dev\`\x1b[0m`
                )
              }

              if (packageManager === "none") {
                yield* Effect.log(`\x1b[22m\x1b[38;5;250m${logSymbols.info} To get started:\x1b[0m`)
                yield* Effect.log(
                  "\x1b[22m\x1b[38;5;250m↪ Install the dependencies manually using your package manager of choice.\x1b[0m"
                )
                yield* Effect.log("\x1b[22m\x1b[38;5;250m↪ Run the dev script.\x1b[0m")
              }
              console.log("\n")
              yield* Effect.log(`\x1b[37m${logSymbols.info} Additional resources\x1b[0m`)
              yield* Effect.log(
                `\x1b[22m\x1b[38;5;250m↪ Documentation: \x1b[37mhttps://reactnativereusables.com\x1b[0m`
              )
              yield* Effect.log(
                `\x1b[22m\x1b[38;5;250m↪ Report issues: \x1b[37mhttps://github.com/founded-labs/react-native-reusables/issues\x1b[0m`
              )

              return newRepoPath
            }),
          (tempDirPath) => {
            spinner.stop()
            return fs
              .remove(tempDirPath, { recursive: true })
              .pipe(Effect.catchAll(() => Effect.logError(`Failed to remove temp directory at ${tempDirPath}`)))
          }
        )
    }
  })
}) {}

export { Template }


================================================
FILE: apps/cli/src/utils/retry-with.ts
================================================
import { Effect } from "effect"

const retryWith = <A, R, E, B>(
  fn: (input: A) => Effect.Effect<R, E, B>,
  inputs: readonly [A, ...Array<A>]
): Effect.Effect<R, E, B> =>
  inputs.slice(1).reduce((acc, input) => acc.pipe(Effect.orElse(() => fn(input))), fn(inputs[0]))

export { retryWith }


================================================
FILE: apps/cli/src/utils/run-command.ts
================================================
import { Effect } from "effect"
import { execa } from "execa"

const runCommand = (file: string, args: Array<string>, options: Parameters<typeof execa>[1]) =>
  Effect.tryPromise({
    try: () => execa(file, args, options),
    catch: (error) => new Error(`Failed to run command: ${file} ${args.join(" ")}`, { cause: String(error) })
  })

export { runCommand }


================================================
FILE: apps/cli/test/Dummy.test.ts
================================================
import { describe, expect, it } from "@effect/vitest"

describe("Dummy", () => {
  it("should pass", () => {
    expect(true).toBe(true)
  })
})


================================================
FILE: apps/cli/tsconfig.base.json
================================================
{
  "include": [],
  "compilerOptions": {
    "strict": true,
    "moduleDetection": "force",
    "composite": true,
    "downlevelIteration": true,
    "resolveJsonModule": true,
    "esModuleInterop": false,
    "declaration": true,
    "skipLibCheck": true,
    "exactOptionalPropertyTypes": true,
    "emitDecoratorMetadata": false,
    "experimentalDecorators": true,
    "moduleResolution": "NodeNext",
    "lib": [
      "ES2022",
      "DOM"
    ],
    "isolatedModules": true,
    "sourceMap": true,
    "declarationMap": true,
    "noImplicitReturns": false,
    "noUnusedLocals": true,
    "noUnusedParameters": false,
    "noFallthroughCasesInSwitch": true,
    "noEmitOnError": false,
    "noErrorTruncation": false,
    "allowJs": false,
    "checkJs": false,
    "forceConsistentCasingInFileNames": true,
    "stripInternal": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "noUncheckedIndexedAccess": false,
    "strictNullChecks": true,
    "baseUrl": ".",
    "target": "ES2022",
    "module": "NodeNext",
    "incremental": true,
    "removeComments": false,
    "plugins": [
      {
        "name": "@effect/language-service"
      }
    ],
    "paths": {
      "@cli/*": [
        "./src/*"
      ]
    }
  }
}

================================================
FILE: apps/cli/tsconfig.json
================================================
{
  "extends": "./tsconfig.base.json",
  "references": [
    {
      "path": "tsconfig.src.json"
    },
    {
      "path": "tsconfig.test.json"
    },
    {
      "path": "tsconfig.scripts.json"
    }
  ]
}

================================================
FILE: apps/cli/tsconfig.scripts.json
================================================
{
  "extends": "./tsconfig.base.json",
  "include": [
    "scripts",
    "eslint.config.mjs",
    "tsup.config.ts",
    "vitest.config.ts"
  ],
  "compilerOptions": {
    "types": [
      "node"
    ],
    "tsBuildInfoFile": ".tsbuildinfo/scripts.tsbuildinfo",
    "rootDir": ".",
    "noEmit": true
  }
}

================================================
FILE: apps/cli/tsconfig.src.json
================================================
{
  "extends": "./tsconfig.base.json",
  "include": ["src"],
  "compilerOptions": {
    "types": ["node"],
    "tsBuildInfoFile": ".tsbuildinfo/src.tsbuildinfo",
    "rootDir": "src",
    "noEmit": true
  }
}


================================================
FILE: apps/cli/tsconfig.test.json
================================================
{
  "extends": "./tsconfig.base.json",
  "include": ["test"],
  "compilerOptions": {
    "types": ["node"],
    "tsBuildInfoFile": ".tsbuildinfo/test.tsbuildinfo",
    "rootDir": "test",
    "noEmit": true
  }
}


================================================
FILE: apps/cli/tsup.config.ts
================================================
import { defineConfig } from "tsup"

export default defineConfig({
  entry: ["src/bin.ts"],
  clean: true,
  publicDir: true,
  treeshake: "smallest",
  external: ["@parcel/watcher"]
})


================================================
FILE: apps/cli/vitest.config.ts
================================================
import { defineConfig } from "vitest/config"

export default defineConfig({
  test: {
    include: ["./test/**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
    exclude: [],
    globals: true,
    coverage: {
      provider: "v8"
    }
  }
})


================================================
FILE: apps/docs/.eslintrc.json
================================================
{
  "extends": ["next/core-web-vitals", "next/typescript"]
}


================================================
FILE: apps/docs/.gitignore
================================================
# deps
/node_modules

# generated content
.contentlayer
.content-collections
.source

# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo
/dist

# misc
.DS_Store
*.pem
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts

# local registry
public/local
registry/nativewind.local.json
registry/uniwind.local.json

================================================
FILE: apps/docs/README.md
================================================
# docs

This is a Next.js application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).

Run development server:

```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```

Open http://localhost:3000 with your browser to see the result.

## Learn More

To learn more about Next.js and Fumadocs, take a look at the following
resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
  features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs


================================================
FILE: apps/docs/app/(home)/BlockSection.tsx
================================================
import { Badge } from '@docs/components/ui/badge';
import { Button } from '@docs/components/ui/button';
import { Heart } from 'lucide-react';
import Link from 'next/link';

export default function BlocksSection() {
  return (
    <div className="flex w-full">
      <div className="flex w-1/3 flex-1 flex-col items-start gap-2 py-64">
        <Badge
          variant="outline"
          className="bg-card dark:bg-secondary border-border/70 gap-1 pr-2 font-normal shadow-sm">
          <Heart className="size-3" />
          Sponsored by Clerk
        </Badge>
        <h1 className="text-foreground/90 w-full text-2xl font-semibold">Authentication Blocks</h1>
        <Button asChild size="sm">
          <Link href="/docs">Explore all Blocks</Link>
        </Button>
      </div>
      <div className="relative w-2/3 overflow-hidden bg-red-500 [mask-image:radial-gradient(circle_at_center,red,#0000)]">
        <div className="absolute left-1/2 top-1/2 flex w-[90rem] -translate-x-1/2 -translate-y-1/2 flex-wrap justify-center gap-4">
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
          <div className="h-96 w-96 rounded-2xl bg-neutral-900" />
        </div>
      </div>
    </div>
  );
}


================================================
FILE: apps/docs/app/(home)/ComponentsGrid.tsx
================================================
'use client';
import {
  AccordionPreview,
  AlertDialogPreview,
  AlertPreview,
  AspectRatioPreview,
  AvatarPreview,
  BadgePreview,
  ButtonPreview,
  // CardPreview,
  CheckboxPreview,
  CollapsiblePreview,
  DialogPreview,
  DropdownMenuPreview,
  HoverCardPreview,
  InputPreview,
  LabelPreview,
  MenubarPreview,
  PopoverPreview,
  ProgressPreview,
  RadioGroupPreview,
  SelectPreview,
  // SeparatorPreview,
  // SkeletonPreview,
  SwitchPreview,
  TabsPreview,
  // TextPreview,
  TextareaPreview,
  // TogglePreview,
  ToggleGroupPreview,
  TooltipPreview,
} from '@docs/components/examples';
import { useIsDarkMode } from '@docs/components/preview-card';
import Image from 'next/image';
import { QRCodeSVG } from 'qrcode.react';
import * as React from 'react';

export default function ComponentsGrid() {
  const isDark = useIsDarkMode();
  const [nativePreview, setNativePreview] = React.useState(false);

  return (
    <div className="flex flex-col gap-4 max-2xl:px-4">
      <div className="hidden w-fit sm:block">
        <div className="bg-fd-background relative flex items-center gap-1 rounded-md border py-0.5 pl-2.5 pr-0.5 text-xs">
          <span className="text-muted-foreground">Platform:</span>{' '}
          <button
            className={`cursor-pointer rounded-sm border px-1.5 py-1 duration-150 ${!nativePreview ? 'bg-white shadow dark:bg-neutral-800' : 'hover:bg-fd-accent/70 border-transparent'}`}
            onClick={() => setNativePreview(false)}>
            Web
          </button>
          <button
            className={`cursor-pointer rounded-sm border px-1.5 py-1 duration-150 ${nativePreview ? 'bg-white shadow dark:bg-neutral-800' : 'hover:bg-fd-accent/70 border-transparent'}`}
            onClick={() => setNativePreview(true)}>
            Native
          </button>
          <div
            className={`absolute left-0 top-10 z-20 flex max-w-sm flex-col items-center gap-6 rounded-lg border border-dashed bg-white p-4 shadow-xl duration-100 dark:bg-black ${nativePreview ? 'translate-y-0 opacity-100 blur-0' : 'pointer-events-none -translate-y-2 opacity-0 blur-md'}`}>
            <QRCodeSVG
              value="https://reactnativereusables.com/showcase/links/home-screen"
              bgColor={isDark ? 'black' : 'white'}
              fgColor={isDark ? 'white' : 'black'}
              size={230}
              level="H"
            />
            <p className="text-center font-mono text-sm">Scan to preview.</p>
          </div>
        </div>
      </div>
      <div className="sm:hidden" />

      <Image
        src="/mobile-component-previews/default_dark.png"
        alt="Components Grid"
        width={2520}
        height={1704}
        className="hidden rounded-lg md:hidden max-md:dark:block"
      />
      <Image
        src="/mobile-component-previews/default_light.png"
        alt="Components Grid"
        width={2520}
        height={1704}
        className="rounded-lg md:hidden dark:hidden"
      />

      <div className="dark:from-fd-background dark:to-fd-accent/70 to-fd-accent relative flex w-full flex-wrap overflow-clip rounded-lg border border-dashed bg-gradient-to-bl from-white max-md:hidden">
        <div className="flex w-full flex-wrap items-center border-b">
          <div className="border-r p-4">
            <HoverCardPreview />
          </div>
          <div className="flex justify-end border-r p-4">
            <SelectPreview />
          </div>
          <div className="flex justify-center border-r p-4">
            <MenubarPreview />
          </div>
          <div className="flex w-full flex-1 items-center justify-center border-r p-4 max-xl:hidden">
            <ProgressPreview />
          </div>
          <div className="border-r p-4">
            <ToggleGroupPreview />
          </div>
          <div className="ml-auto flex justify-center p-4 max-[857px]:hidden xl:border-r">
            <ButtonPreview />
          </div>
          <div className="p-4 max-xl:hidden">
            <AvatarPreview />
          </div>
        </div>
        <div className="flex max-xl:flex-col max-lg:flex-1">
          <div className="border-r lg:w-[572.5px] xl:flex-1">
            <div className="relative p-4">
              <CheckboxPreview />
            </div>
            <div className="relative border-t px-6">
              <AccordionPreview />
            </div>
            <div className="relative border-t p-4">
              <AlertPreview />
            </div>
          </div>
          <div className="w-full border-r xl:w-[400px]">
            {/* <div className="flex w-full justify-center p-4 py-10">
              <ContextMenuPreview /> 
            </div> */}
            <div className="p-5 max-lg:hidden">
              <BadgePreview />
            </div>
            <div className="border-t p-4 max-xl:hidden">
              <CollapsiblePreview />
            </div>
            <div className="border-t p-4">
              <TabsPreview />
            </div>
            <div className="border-t p-5 max-xl:hidden">
              <SwitchPreview />
            </div>
            <div className="border-t p-5 max-xl:hidden">
              <RadioGroupPreview />
            </div>
          </div>
        </div>
        <div className="w-full flex-1">
          <div className="flex w-full justify-end border-b p-4 xl:hidden">
            <AvatarPreview />
          </div>
          <div className="p-4">
            <AspectRatioPreview />
          </div>
          <div className="border-t p-4 xl:hidden">
            <ProgressPreview />
          </div>
          <div className="border-t p-4">
            <InputPreview />
          </div>
          <div className="border-t p-4">
            <TextareaPreview />
          </div>
          <div className="border-t p-4">
            <LabelPreview />
          </div>

          <div className="border-t p-4">
            <AlertDialogPreview />
          </div>
          <div className="border-t p-4">
            <DialogPreview />
          </div>
          <div className="border-t p-4">
            <PopoverPreview />
          </div>
          <div className="border-t p-4">
            <TooltipPreview />
          </div>
          <div className="border-t p-4">
            <DropdownMenuPreview />
          </div>

          <div className="hidden border-t p-5 max-xl:block">
            <SwitchPreview />
          </div>
          <div className="hidden border-t p-5 max-xl:block">
            <RadioGroupPreview />
          </div>
          <div className="hidden border-t p-4 max-xl:block">
            <CollapsiblePreview />
          </div>
          <div className="hidden p-5 max-lg:block">
            <BadgePreview />
          </div>
          <div className="ml-auto hidden justify-center border-t p-4 max-[857px]:flex">
            <ButtonPreview />
          </div>
        </div>
      </div>
    </div>
  );
}


================================================
FILE: apps/docs/app/(home)/TemplatesSection.tsx
================================================
import { Badge } from '@docs/components/ui/badge';
import { Button } from '@docs/components/ui/button';
import { BatteryCharging } from 'lucide-react';
import Link from 'next/link';

export default function TemplatesSection() {
  return (
    <div className="flex w-full">
      <div className="flex w-1/3 flex-1 flex-col items-start gap-2 py-64">
        <Badge
          variant="outline"
          className="bg-card dark:bg-secondary border-border/70 gap-1 pr-2 font-normal shadow-sm">
          <BatteryCharging className="size-3" />
          Batteries Included!
        </Badge>
        <h1 className="text-foreground/90 w-full text-2xl font-semibold">
          Authentication Template
        </h1>
        <p className="text-foreground/80 max-w-3xl text-balance text-base sm:text-lg">
          A complete authentication solution for your app, including sign-up, sign-in, and user
          management. Powered by Clerk, this template provides a seamless user experience with
          pre-built components and flows.
        </p>
        <Button asChild size="sm">
          <Link href="/docs">Add it to your app</Link>
        </Button>
      </div>
      <div className="relative w-2/3 overflow-hidden bg-red-500"></div>
    </div>
  );
}


================================================
FILE: apps/docs/app/(home)/layout.tsx
================================================
import { RnrIcon } from '@docs/components/icons/rnr-icon';
import { SkipNavigationButton } from '@docs/components/skip-navigation-button';
import { Button } from '@docs/components/ui/button';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import type { Metadata } from 'next';
import Link from 'next/link';
import type { ReactNode } from 'react';

export const metadata: Metadata = {
  title: 'React Native Reusables',
  description:
    'Bringing shadcn/ui to React Native. Beautifully crafted components with Nativewind or Uniwind, open source, and almost as easy to use.',
};

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <>
      <SkipNavigationButton />
      <HomeLayout
        githubUrl="https://github.com/founded-labs/react-native-reusables"
        className="dark:from-fd-background dark:to-fd-background from-fd-accent bg-gradient-to-b to-white"
        nav={{
          title: (
            <div className="hover:bg-fd-accent -ml-0.5 flex size-8 items-center justify-center rounded-md transition-colors duration-200">
              <RnrIcon className="w-6" pathClassName="stroke-[1px]" />
            </div>
          ),
        }}
        links={[
          {
            type: 'custom',
            children: (
              <Button
                variant="ghost"
                size="sm"
                asChild
                className="hover:bg-fd-accent dark:hover:bg-fd-accent -ml-1.5 justify-start sm:ml-0 sm:justify-center">
                <Link href="/docs">Docs</Link>
              </Button>
            ),
          },
          {
            type: 'custom',
            children: (
              <Button
                variant="ghost"
                size="sm"
                asChild
                className="hover:bg-fd-accent dark:hover:bg-fd-accent -ml-1.5 justify-start sm:ml-0 sm:justify-center">
                <Link href="/docs/blocks/authentication">Blocks</Link>
              </Button>
            ),
          },
          {
            type: 'custom',
            children: (
              <Button
                variant="ghost"
                size="sm"
                asChild
                className="hover:bg-fd-accent dark:hover:bg-fd-accent -ml-1.5 justify-start sm:ml-0 sm:justify-center">
                <Link href="/docs/components/accordion">Components</Link>
              </Button>
            ),
          },
        ]}>
        {children}
      </HomeLayout>
    </>
  );
}


================================================
FILE: apps/docs/app/(home)/page.tsx
================================================
import { Badge } from '@docs/components/ui/badge';
import { Button } from '@docs/components/ui/button';
import { ArrowRightIcon } from 'lucide-react';
import Link from 'next/link';
import { Footer } from '../docs/[[...slug]]/page';
import ComponentsGrid from './ComponentsGrid';

export default function HomePage() {
  return (
    <div className="flex flex-1 flex-col">
      <main
        id="nd-page"
        className="max-w-fd-container mx-auto flex w-full flex-1 flex-col items-center gap-4 pt-4 md:pt-0">
        <div className="container relative z-0 flex flex-col items-center gap-2 py-8 text-center md:pt-16 lg:pt-20 xl:gap-4">
          <div className="bg-grid-print pointer-events-none absolute inset-0 -bottom-16 z-[-1] bg-white opacity-60 [mask-image:radial-gradient(ellipse_50%_100%_at_50%_100%,red,#0000)] dark:bg-neutral-800" />
          <div className="h-6">
            <Badge
              variant="outline"
              asChild
              className="bg-card dark:bg-secondary border-border/75 gap-1 rounded-full pr-2 font-normal">
              <Link href="/docs/blocks/authentication">
                New Authentication Blocks <ArrowRightIcon className="size-3" />
              </Link>
            </Badge>
          </div>
          <h1 className="text-primary/90 leading-tighter max-w-3xl text-balance text-4xl font-semibold tracking-tight lg:leading-[1.1] xl:max-w-7xl xl:text-5xl xl:font-medium xl:tracking-tighter">
            Build your Universal Component Library
          </h1>
          <p className="text-foreground/80 max-w-3xl text-balance text-base sm:text-lg">
            Bringing{' '}
            <a
              href="https://ui.shadcn.com"
              target="_blank"
              className="decoration-fd-muted-foreground/0 hover:decoration-fd-muted-foreground underline underline-offset-4">
              shadcn/ui
            </a>{' '}
            to React Native. Beautifully crafted components with Nativewind or Uniwind, open source,
            and <i>almost as easy to use.</i>
          </p>
          <div className="**:data-[slot=button]:shadow-none flex w-full items-center justify-center gap-2 pt-2">
            <Button asChild size="sm">
              <Link href="/docs">Get Started</Link>
            </Button>
          </div>
        </div>
        <ComponentsGrid />
      </main>
      <Footer url="/" />
    </div>
  );
}


================================================
FILE: apps/docs/app/api/search/route.ts
================================================
import { source } from '@docs/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

export const { GET } = createFromSource(source);


================================================
FILE: apps/docs/app/docs/[[...slug]]/page.tsx
================================================
import { Button } from '@docs/components/ui/button';
import { source } from '@docs/lib/source';
import { cn } from '@docs/lib/utils';
import { findNeighbour } from 'fumadocs-core/server';
import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';
import { ArrowLeftIcon, ArrowRightIcon, ExternalLinkIcon } from 'lucide-react';
import Link from 'next/link';
import { notFound } from 'next/navigation';

export default async function Page(props: { params: Promise<{ slug?: string[] }> }) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  const MDX = page.data.body;

  return (
    <DocsPage
      toc={page.data.toc}
      full={page.data.full}
      breadcrumb={{ enabled: false }}
      tableOfContent={{
        footer: <TableOfContentFooter />,
      }}
      footer={{
        component: <Footer url={page.url} />,
      }}>
      <DocsBody>
        <div className="flex items-center justify-between gap-2">
          <DocsTitle className="mb-0 font-semibold">{page.data.title}</DocsTitle>
          <NeighbourButtons url={page.url} />
        </div>
        <DocsDescription className="mb-4 mt-2.5 text-base">{page.data.description}</DocsDescription>
        <MDX
          components={{
            ...defaultMdxComponents,
            h2: ({ className, ...props }) => (
              <defaultMdxComponents.h2 className={cn(className, 'font-medium')} {...props} />
            ),
            //  HTML `ref` attribute conflicts with `forwardRef`
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            pre: ({ ref: _ref, className, ...props }) => (
              <CodeBlock
                {...props}
                className={cn(
                  className,
                  'bg-fd-foreground/95 dark:bg-fd-secondary/50 text-background dark:text-foreground *:dark relative'
                )}>
                <Pre>{props.children}</Pre>
              </CodeBlock>
            ),
            h3: ({ className, ...props }) => (
              <h3 className={cn(className, 'mb-6 mt-10 scroll-mt-20 font-medium')} {...props} />
            ),
          }}
        />
      </DocsBody>
    </DocsPage>
  );
}

function NeighbourButtons({ url }: { url: string }) {
  const neighbours = findNeighbour(source.pageTree, url);

  const isManualInstallation = url === '/docs/installation/manual';

  return (
    <div className="flex items-center gap-2">
      {neighbours.previous || isManualInstallation ? (
        <Button variant="outline" size="icon" className="border-border/70 size-8" asChild>
          <Link href={neighbours.previous?.url || '/docs'}>
            <ArrowLeftIcon />
          </Link>
        </Button>
      ) : null}
      {neighbours.next || isManualInstallation ? (
        <Button variant="outline" size="icon" className="border-border/70 size-8" asChild>
          <Link
            href={neighbours.next?.url || '/docs/customization'}
            target={
              neighbours.next?.url.startsWith('https://foundedlabs.com') ? '_blank' : undefined
            }>
            <ArrowRightIcon />
          </Link>
        </Button>
      ) : null}
    </div>
  );
}

export function Footer({ url }: { url: string }) {
  const neighbours = findNeighbour(source.pageTree, url);

  const isManualInstallation = url === '/docs/installation/manual';

  return (
    <footer>
      <div className="flex h-16 w-full items-center justify-between gap-2">
        {neighbours.previous || isManualInstallation ? (
          <Button
            variant="ghost"
            size="sm"
            asChild
            className="bg-fd-accent hover:bg-fd-accent/80 dark:hover:bg-fd-accent/80">
            <Link href={neighbours.previous?.url || '/docs'}>
              <ArrowLeftIcon />
              {neighbours.previous?.name || 'Introduction'}
            </Link>
          </Button>
        ) : (
          <div />
        )}
        {neighbours.next || isManualInstallation ? (
          <Button
            variant="ghost"
            size="sm"
            asChild
            className="bg-fd-accent hover:bg-fd-accent/80 dark:hover:bg-fd-accent/80">
            <Link href={neighbours.next?.url || '/docs/customization'}>
              {neighbours.next?.name || 'Customization'}
              <ArrowRightIcon />
            </Link>
          </Button>
        ) : null}
      </div>
      <div className="flex h-20 items-center justify-between">
        <div className="text-fd-muted-foreground w-full text-balance px-4 text-center text-xs leading-loose lg:text-sm">
          Built by{' '}
          <a
            href="https://x.com/mrzachnugent"
            target="_blank"
            rel="noreferrer"
            className="underline underline-offset-4">
            mrzachnugent
          </a>{' '}
          at{' '}
          <a
            href="https://foundedlabs.com"
            target="_blank"
            rel="noreferrer"
            className="decoration-fd-muted-foreground/0 hover:decoration-fd-muted-foreground underline underline-offset-4">
            Founded Labs
          </a>
          , bringing{' '}
          <a
            href="https://ui.shadcn.com"
            target="_blank"
            rel="noreferrer"
            className="underline underline-offset-4">
            shadcn/ui
          </a>{' '}
          to React Native. Source on{' '}
          <a
            href="https://github.com/founded-labs/react-native-reusables"
            target="_blank"
            rel="noreferrer"
            className="underline underline-offset-4">
            GitHub
          </a>
          .
        </div>
      </div>
    </footer>
  );
}

function TableOfContentFooter() {
  return (
    <div className="bg-card dark:bg-fd-muted border-border/50 text-fd-foreground/80 group relative mt-12 flex flex-col gap-2 overflow-clip rounded-lg border p-6 text-sm">
      <div className="text-balance text-base font-semibold leading-tight group-hover:underline">
        Want to work with us?
      </div>
      <div className="">Mention us to your team.</div>
      <div className="text-muted-foreground pb-2">We help companies ship world-class UI/UX.</div>
      <Button
        size="sm"
        className="from-primary to-primary/75 group-hover:to-primary/80 relative w-fit bg-transparent bg-gradient-to-br duration-150 group-hover:pr-8">
        Learn more
        <ExternalLinkIcon className="absolute right-2 top-1/2 size-3.5 -translate-x-1 -translate-y-1/2 scale-y-0 opacity-0 duration-100 group-hover:translate-x-0 group-hover:scale-y-100 group-hover:opacity-100" />
      </Button>
      <Link href="https://foundedlabs.com" target="_blank" className="absolute inset-0">
        <span className="sr-only">Learn more about Founded Labs</span>
      </Link>
    </div>
  );
}

export async function generateStaticParams() {
  return source.generateParams();
}

export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  return {
    title: page.data.title,
    description: page.data.description,
  };
}


================================================
FILE: apps/docs/app/docs/layout.tsx
================================================
import { RnrIcon } from '@docs/components/icons/rnr-icon';
import { SkipNavigationButton } from '@docs/components/skip-navigation-button';
import { source } from '@docs/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/notebook';
import type { ReactNode } from 'react';

const SIDEBAR_PROPS = { className: '[&>div]:pt-3' };

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <>
      <SkipNavigationButton />
      <DocsLayout
        tree={source.pageTree}
        nav={{
          title: (
            <div className="text-foreground/80 -ml-px flex items-center gap-1.5 opacity-90 transition-opacity duration-200 hover:opacity-100">
              <div className="flex items-center justify-center">
                <RnrIcon />
              </div>
              <p className="text-base">Reusables</p>
            </div>
          ),
        }}
        sidebar={SIDEBAR_PROPS}
        githubUrl="https://github.com/founded-labs/react-native-reusables">
        {children}
      </DocsLayout>
    </>
  );
}


================================================
FILE: apps/docs/app/global.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 0 0% 3.9%;
    --card: 0 0% 100%;
    --card-foreground: 0 0% 3.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 0 0% 3.9%;
    --primary: 0 0% 9%;
    --primary-foreground: 0 0% 98%;
    --secondary: 0 0% 96.1%;
    --secondary-foreground: 0 0% 9%;
    --muted: 0 0% 96.1%;
    --muted-foreground: 0 0% 45.1%;
    --accent: 0 0% 96.1%;
    --accent-foreground: 0 0% 9%;
    --destructive: 0 84.2% 60.2%;
    --border: 0 0% 89.8%;
    --input: 0 0% 89.8%;
    --ring: 0 0% 63%;
    --radius: 0.625rem;
    --chart-1: 12 76% 61%;
    --chart-2: 173 58% 39%;
    --chart-3: 197 37% 24%;
    --chart-4: 43 74% 66%;
    --chart-5: 27 87% 67%;
  }

  .dark {
    --background: 0 0% 3.9%;
    --foreground: 0 0% 98%;
    --card: 0 0% 3.9%;
    --card-foreground: 0 0% 98%;
    --popover: 0 0% 3.9%;
    --popover-foreground: 0 0% 98%;
    --primary: 0 0% 98%;
    --primary-foreground: 0 0% 9%;
    --secondary: 0 0% 14.9%;
    --secondary-foreground: 0 0% 98%;
    --muted: 0 0% 14.9%;
    --muted-foreground: 0 0% 63.9%;
    --accent: 0 0% 14.9%;
    --accent-foreground: 0 0% 98%;
    --destructive: 0 70.9% 59.4%;
    --border: 0 0% 14.9%;
    --input: 0 0% 14.9%;
    --ring: 300 0% 45%;
    --chart-1: 220 70% 50%;
    --chart-2: 160 60% 45%;
    --chart-3: 30 80% 55%;
    --chart-4: 280 65% 60%;
    --chart-5: 340 75% 55%;
  }
}

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  ::selection {
    @apply bg-primary text-primary-foreground;
  }
  html {
    @apply scroll-smooth;
  }
  body {
    font-synthesis-weight: none;
    text-rendering: optimizeLegibility;
  }
  #nd-page {
    @apply scroll-mt-20;
  }
}

.bg-grid-print {
  background-image:
    radial-gradient(circle at 0px 0px, rgb(119, 119, 119) 1.5px, rgba(0, 0, 0, 0) 0px),
    radial-gradient(circle at 100% 100%, rgb(119, 119, 119) 1.5px, rgba(0, 0, 0, 0) 0px);
  background-size: 20px 20px;
  background-position:
    0px 0px,
    10px 10px;
}

.bg-grid-dots {
  background-image: radial-gradient(
    circle at 0px 0px,
    rgb(119, 119, 119) 1.5px,
    rgba(0, 0, 0, 0) 0px
  );
  background-size: 20px 20px;
}

.bg-grid-lines {
  background-image:
    linear-gradient(90deg, rgba(119, 119, 119, 0.5) 1px, transparent 1px),
    linear-gradient(0deg, rgba(119, 119, 119, 0.5) 1px, transparent 1px);
  background-size: 20px 20px;
}


================================================
FILE: apps/docs/app/layout.tsx
================================================
import './global.css';

import { CookiesProvider } from '@docs/components/cookies-provider';
import { SafeAreaProvider } from '@docs/components/safe-area-provider';
import { cn } from '@docs/lib/utils';
import { Analytics } from '@vercel/analytics/next';
import type { SearchLink } from 'fumadocs-ui/components/dialog/search';
import { RootProvider } from 'fumadocs-ui/provider';
import { Geist, Geist_Mono } from 'next/font/google';

const fontSans = Geist({
  subsets: ['latin'],
  variable: '--font-sans',
});

const fontMono = Geist_Mono({
  subsets: ['latin'],
  variable: '--font-mono',
  weight: ['400'],
});

const SEARCH_OPTIONS = {
  links: [
    ['Docs', '/docs/installation'],
    ['Blocks', '/docs/blocks/authentication'],
    ['Components', '/docs/components/accordion'],
    ['Changelog', '/docs/changelog'],
  ] satisfies SearchLink[],
};

export default function Layout({ children }: React.PropsWithChildren) {
  return (
    <html lang="en" className={cn(fontSans.variable, fontMono.variable)} suppressHydrationWarning>
      <head>
        <link rel="icon" href="/favicon.svg" />
      </head>
      <body className="flex min-h-svh flex-col">
        <CookiesProvider>
          <SafeAreaProvider>
            <RootProvider search={SEARCH_OPTIONS}>
              {children}
              <Analytics />
            </RootProvider>
          </SafeAreaProvider>
        </CookiesProvider>
      </body>
    </html>
  );
}


================================================
FILE: apps/docs/app/og/route.tsx
================================================
import { ImageResponse } from 'next/og';

async function loadGoogleFont(weight: string, text: string) {
  const url = `https://fonts.googleapis.com/css2?family=Geist:wght@${weight}&display=swap&text=${encodeURIComponent(
    text
  )}`;
  const css = await (await fetch(url)).text();
  const resource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);

  if (resource) {
    const response = await fetch(resource[1]);
    if (response.status == 200) {
      return await response.arrayBuffer();
    }
  }

  throw new Error('failed to load font data');
}

export async function GET(request: Request) {
  const url = new URL(request.url);
  const title = url.searchParams.get('title') ?? 'React Native Reusables';
  const description = url.searchParams.get('description') ?? 'Bringing shadcn/ui to React Native';

  return new ImageResponse(
    (
      <div tw="w-full h-full bg-white flex flex-col">
        <div tw="flex flex-col w-full h-full items-center justify-center bg-white ">
          {/*  */}
          <div tw="absolute left-20 h-full w-px bg-[#E4E4E7]" />
          <div tw="absolute right-20 h-full w-px bg-[#E4E4E7]" />
          <div tw="absolute top-[61px] h-px w-full bg-[#E4E4E7]" />
          <div tw="absolute bottom-[61px] h-px w-full bg-[#E4E4E7]" />
          {/*  */}
          <div tw="absolute left-[79px] top-[38px] h-12 w-[3px] bg-[#B7B7C4]"></div>
          <div tw="absolute top-[60px] left-14 h-[3px] w-12 bg-[#B7B7C4]"></div>
          <div tw="absolute right-[79px] bottom-[38px] h-12 w-[3px] bg-[#B7B7C4]"></div>
          <div tw="absolute bottom-[60px] right-14 h-[3px] w-12 bg-[#B7B7C4]"></div>

          <div tw="flex-1 flex items-center justify-center p-12 overflow-hidden">
            <img
              src="https://exqr2q84pq.ufs.sh/f/r8NDF0EyEd5ox95GIV1BVwTqQuzWyE0Sj7IHZOJ9vs6tkc1G"
              height={504}
              width={1040}
              style={{
                opacity: 0.5,
                filter: 'contrast(10%)',
                objectFit: 'cover',
              }}
            />
            <span tw="absolute bottom-24 left-0 right-0 flex items-center justify-center">
              <svg
                width="44"
                height="39"
                viewBox="0 0 100 89"
                fill="none"
                xmlns="http://www.w3.org/2000/svg">
                <path
                  d="M61.3902 44.3533L50.0005 55.6349M59.1123 31.9434L37.4717 53.3786M50.0005 65.869C76.5099 65.869 98 56.302 98 44.5002C98 32.6983 76.5099 23.1313 50.0005 23.1313C23.491 23.1313 2 32.6983 2 44.5002C2 56.302 23.491 65.869 50.0005 65.869ZM31.294 55.1846C44.5492 77.897 63.6687 91.525 73.9998 85.6245C84.3317 79.7231 81.9612 56.5273 68.706 33.8158C55.4517 11.1025 36.3313 -2.52551 26.0011 3.37585C15.6692 9.27632 18.0398 32.4722 31.294 55.1846ZM31.294 33.8158C18.0398 56.5282 15.6701 79.7231 26.0002 85.6245C36.3322 91.525 55.4517 77.8961 68.706 55.1846C81.9611 32.4713 84.3317 9.27721 74.0007 3.37585C63.6687 -2.52551 44.5492 11.1034 31.294 33.8158Z"
                  stroke="#0A0A0A"
                  strokeWidth="4"
                  strokeLinecap="round"
                />
              </svg>
            </span>
            <span tw="absolute block top-12 right-12 left-12 bottom-12 flex flex-col items-center justify-center">
              <h1
                tw="text-7xl tracking-tight text-center mt-5 mb-0.5"
                style={{
                  textWrap: title?.split(' ').length > 1 ? 'balance' : 'initial',
                }}>
                {title}
              </h1>
              <p tw="text-2xl text-center max-w-[800px] text-neutral-600 pb-2">{description}</p>
            </span>
          </div>
        </div>
      </div>
    ),
    {
      width: 1200,
      height: 628,
      fonts: [
        {
          name: 'Geist',
          data: await loadGoogleFont('700', title ?? ''),
          style: 'normal',
          weight: 700,
        },
        {
          name: 'Geist',
          data: await loadGoogleFont('500', description ?? ''),
          style: 'normal',
          weight: 500,
        },
      ],
    }
  );
}


================================================
FILE: apps/docs/app/showcase/links/[[...slug]]/page.tsx
================================================
import { DownloadAppBanner } from '@docs/components/download-app-banner';

export default async function Page() {
  return (
    <main className="flex min-h-svh items-center justify-center p-2">
      <DownloadAppBanner
        size="sm"
        title="Download the App"
        description="This content is available only through the React Native Reusables app."
      />
    </main>
  );
}


================================================
FILE: apps/docs/app/showcase/privacy-policy/page.tsx
================================================
export default function Page() {
  return (
    <div className="prose mx-auto max-w-3xl px-4 py-24">
      <h1>Privacy Policy</h1>
      <p>Effective Date: July 19, 2025</p>

      <p>
        The React Native Reusables App (“the App”) is an interactive developer tool that allows
        users to explore, preview, and interact with a wide range of UI components and blocks
        provided by the React Native Reusables project. It is designed for developers and designers
        who want to evaluate, learn from, and integrate these components into their own
        applications.
      </p>

      <h2>1. Information We Collect</h2>
      <p>
        We do not collect, store, or share any personal data. At this time, the App does not require
        authentication and does not track user behavior, usage statistics, or analytics data.
      </p>

      <h2>2. Authentication</h2>
      <p>
        No authentication mechanisms are currently implemented. If authentication is added in the
        future, this Privacy Policy will be updated to reflect that change.
      </p>

      <h2>3. Data Usage and Sharing</h2>
      <p>Since we do not collect any data, we do not share any data with third parties.</p>

      <h2>4. Changes to This Policy</h2>
      <p>
        We may update this Privacy Policy if features change. If we do, we will revise the
        “Effective Date” at the top of this page. For any significant changes, we may provide
        additional notice within the app.
      </p>

      <h2>5. Contact</h2>
      <p>
        If you have any questions about this Privacy Policy or the App, please contact us at:
        hello@foundedlabs.com
      </p>
    </div>
  );
}


================================================
FILE: apps/docs/app/showcase/support/page.tsx
================================================
export default function Page() {
  return (
    <div className="prose mx-auto max-w-3xl px-4 py-24">
      <h1>Support</h1>
      <p>Effective Date: July 26, 2025</p>
      <p>
        The React Native Reusables App (“the App”) is an interactive developer tool that enables
        users to explore and implement UI components and blocks provided by the React Native
        Reusables project.
      </p>
      <h2>1. How to Get Support</h2>
      <p>If you need help with the App or React Native Reusables, you can:</p>
      <ul>
        <li>
          Browse the documentation available on this{' '}
          <a href="https://reactnativereusables.com/docs">website</a>.
        </li>
        <li>
          Open a discussion or report an issue on the{' '}
          <a href="https://github.com/founded-labs/react-native-reusables" target="_blank">
            GitHub repository
          </a>
          .
        </li>
        <li>Reach out directly by email at: hello@foundedlabs.com</li>
      </ul>
      <h2>2. Response Time</h2>
      <p>
        Support inquiries will be reviewed as time permits. While there is no guaranteed response
        time, every effort will be made to address questions and issues promptly.
      </p>
      <h2>3. Updates to Support Information</h2>
      <p>
        Support details may be updated in the future. When changes occur, they will be reflected on
        this page.
      </p>
      <h2>4. Contact</h2>
      <p>
        For any additional assistance, contact: <br />
        hello@foundedlabs.com
      </p>
    </div>
  );
}


================================================
FILE: apps/docs/components/app-store-button.tsx
================================================
export function AppStoreButton() {
  return (
    <a
      target="_blank"
      href="https://apps.apple.com/ca/app/react-native-reusables/id6748838250"
      className="rounded-md">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        id="livetype"
        viewBox="0 0 119.66407 40"
        className="h-10 sm:h-12">
        <title>Download_on_the_App_Store_Badge_US-UK_RGB_wht_092917</title>
        <g>
          <g>
            <g>
              <path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z" />
              <path
                d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z"
                className="fill-black dark:fill-white"
              />
            </g>
            <g id="_Group_" data-name="&lt;Group&gt;" className="fill-white dark:fill-black">
              <g id="_Group_2" data-name="&lt;Group&gt;">
                <g id="_Group_3" data-name="&lt;Group&gt;">
                  <path
                    id="_Path_"
                    data-name="&lt;Path&gt;"
                    d="M24.99671,19.88935a5.14625,5.14625,0,0,1,2.45058-4.31771,5.26776,5.26776,0,0,0-4.15039-2.24376c-1.74624-.1833-3.43913,1.04492-4.329,1.04492-.90707,0-2.27713-1.02672-3.75247-.99637a5.52735,5.52735,0,0,0-4.65137,2.8367c-2.01111,3.482-.511,8.59939,1.41551,11.414.96388,1.37823,2.09037,2.91774,3.56438,2.86315,1.4424-.05983,1.98111-.91977,3.7222-.91977,1.72494,0,2.23035.91977,3.73427.88506,1.54777-.02512,2.52292-1.38435,3.453-2.77563a11.39931,11.39931,0,0,0,1.579-3.21589A4.97284,4.97284,0,0,1,24.99671,19.88935Z"
                  />
                  <path
                    id="_Path_2"
                    data-name="&lt;Path&gt;"
                    d="M22.15611,11.47681a5.06687,5.06687,0,0,0,1.159-3.62989,5.15524,5.15524,0,0,0-3.33555,1.72582,4.82131,4.82131,0,0,0-1.18934,3.4955A4.26259,4.26259,0,0,0,22.15611,11.47681Z"
                  />
                </g>
              </g>
              <g>
                <path d="M42.30178,27.13965h-4.7334l-1.13672,3.35645H34.42678l4.4834-12.418h2.083l4.4834,12.418H43.43752Zm-4.24316-1.54883h3.752L39.961,20.14355H39.9092Z" />
                <path d="M55.1592,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238h1.79883v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.64455,21.34766,55.1592,23.16406,55.1592,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30178,29.01563,53.249,27.81934,53.249,25.96973Z" />
                <path d="M65.12453,25.96973c0,2.81348-1.50635,4.62109-3.77881,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238h1.79883v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C63.6094,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91064,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26662,29.01563,63.21389,27.81934,63.21389,25.96973Z" />
                <path d="M71.70949,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51758-3.61426,2.625,0,4.42383,1.47168,4.48438,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60547,1.626,3.60547,3.44238,0,2.32324-1.84961,3.77832-4.793,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z" />
                <path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z" />
                <path d="M86.064,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72512,30.6084,86.064,28.82617,86.064,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40137,1.16211-2.40137,3.10742c0,1.96191.89551,3.10645,2.40137,3.10645S92.7593,27.93164,92.7593,25.96973Z" />
                <path d="M96.18508,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z" />
                <path d="M109.38332,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10109,25.13477Z" />
              </g>
            </g>
          </g>
          <g id="_Group_4" data-name="&lt;Group&gt;" className="fill-white dark:fill-black">
            <g>
              <path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z" />
              <path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z" />
              <path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z" />
              <path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" />
              <path d="M59.09377,8.437h.88867v6.26074h-.88867Z" />
              <path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z" />
              <path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z" />
              <path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z" />
              <path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z" />
              <path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" />
              <path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z" />
              <path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z" />
              <path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z" />
            </g>
          </g>
        </g>
      </svg>
    </a>
  );
}


================================================
FILE: apps/docs/components/auth-block-tabs.tsx
================================================
'use client';

import {
  AuthIntegrationSelect,
  useAuthIntegration,
} from '@docs/components/auth-integration-select';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@docs/components/ui/tabs';
import * as React from 'react';

export function AuthBlockTabs({ children }: React.PropsWithChildren) {
  return (
    <Tabs defaultValue="cli">
      <div className="flex items-center justify-between">
        <TabsList>
          <TabsTrigger id="cli" value="cli">
            CLI
          </TabsTrigger>
          <TabsTrigger id="manual" value="manual">
            Manual
          </TabsTrigger>
        </TabsList>
        <AuthIntegrationSelect className="mt-px" />
      </div>
      {children}
    </Tabs>
  );
}
type AuthIntegration = 'none' | 'clerk';

type ContentProps = {
  integration: AuthIntegration;
  children: React.ReactNode;
};

export function AuthBlockTabsCliContent({ children, integration: integrationProp }: ContentProps) {
  const [integration] = useAuthIntegration();

  if (integration !== integrationProp) {
    return null;
  }
  return <TabsContent value="cli">{children}</TabsContent>;
}

export function AuthBlockTabsManualContent({
  children,
  integration: integrationProp,
}: ContentProps) {
  const [integration] = useAuthIntegration();

  if (integration !== integrationProp) {
    return null;
  }

  return <TabsContent value="manual">{children}</TabsContent>;
}


================================================
FILE: apps/docs/components/auth-integration-select.tsx
================================================
'use client';

import type { SelectProps } from '@radix-ui/react-select';
import * as React from 'react';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@docs/components/ui/select';
import { useReactiveGetCookie, useReactiveSetCookie } from 'cookies-next/client';
import { Button } from '@docs/components/ui/button';

const INTEGRATIONS = [
  { name: 'none', label: 'None' },
  { name: 'clerk', label: 'Clerk' },
] as const;

type Integration = (typeof INTEGRATIONS)[number]['name'];

export function AuthIntegrationSelect({
  className,
  ...props
}: SelectProps & { className?: string }) {
  const [isClient, setIsClient] = React.useState(false);
  const [integration, onIntegrationChange] = useAuthIntegration();

  React.useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <Select {...props} defaultValue="none" value={integration} onValueChange={onIntegrationChange}>
      <Button asChild variant="outline" size="sm" className={className}>
        <SelectTrigger className="dark:bg-muted dark:hover:bg-muted/80 dark:border-muted-foreground/15 w-fit">
          <span className="text-muted-foreground flex-1 pr-1">Integration:</span>
          {!isClient ? (
            <span className="opacity-50">
              {
                INTEGRATIONS.find((integration) =>
                  integration.name === props.value ? props.value : props.defaultValue
                )?.label
              }
            </span>
          ) : (
            <SelectValue placeholder="Select integration" />
          )}
        </SelectTrigger>
      </Button>
      <SelectContent onCloseAutoFocus={preventDefault} className="dark:bg-neutral-900">
        {INTEGRATIONS.map((integration) => (
          <SelectItem key={integration.name} value={integration.name} className="text-xs">
            {integration.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

export function useAuthIntegration() {
  const getCookie = useReactiveGetCookie();
  const setCookie = useReactiveSetCookie();
  const integration = getCookie('user.auth-integration') ?? 'none';
  function onIntegrationChange(value: Integration) {
    setCookie('user.auth-integration', value);
  }

  return [integration, onIntegrationChange] as const;
}

function preventDefault(e: Event) {
  e.preventDefault();
}


================================================
FILE: apps/docs/components/blocks-grid.tsx
================================================
import { Button } from '@docs/components/ui/button';
import Link from 'next/link';

const BLOCKS = [
  { title: 'Sign in form', href: '/docs/blocks/authentication/sign-in-form' },
  { title: 'Sign up form', href: '/docs/blocks/authentication/sign-up-form' },
  { title: 'Verify email form', href: '/docs/blocks/authentication/verify-email-form' },
  { title: 'Reset password form', href: '/docs/blocks/authentication/reset-password-form' },
  { title: 'Forgot password form', href: '/docs/blocks/authentication/forgot-password-form' },
  { title: 'Social connections', href: '/docs/blocks/authentication/social-connections' },
  { title: 'User menu', href: '/docs/blocks/authentication/user-menu' },
];

export function BlocksGrid() {
  return (
    <div className="not-prose sm:gird-cols-3 grid grid-cols-2 gap-4 xl:grid-cols-4">
      {BLOCKS.map((block) => (
        <Button
          asChild
          size="lg"
          variant="link"
          key={block.href}
          className="justify-start px-0 text-base font-normal">
          <Link href={block.href}>{block.title}</Link>
        </Button>
      ))}
    </div>
  );
}


================================================
FILE: apps/docs/components/blocks.tsx
================================================
'use client';

export * from '@/registry/blocks';


================================================
FILE: apps/docs/components/callout.tsx
================================================
import { CircleCheckIcon, CircleXIcon, InfoIcon, TriangleAlertIcon } from 'lucide-react';
import { cn } from '@docs/lib/utils';

const ICONS = {
  info: InfoIcon,
  warning: TriangleAlertIcon,
  error: CircleXIcon,
  success: CircleCheckIcon,
};

type CalloutProps = Omit<React.ComponentProps<'div'>, 'title' | 'type' | 'icon'> & {
  title?: React.ReactNode;
  /**
   * @defaultValue info
   */
  type?: 'info' | 'warn' | 'error' | 'success' | 'warning';
};

export function Callout({ className, children, title, type, ...props }: CalloutProps) {
  if (type === 'warn') {
    type = 'warning';
  }

  const Icon = type ? ICONS[type] : null;

  return (
    <div
      className={cn(
        'bg-fd-card text-fd-card-foreground my-4 flex gap-2 rounded-xl border p-3 ps-1 text-sm shadow-sm',
        className
      )}
      {...props}>
      <div role="none" className={!type ? 'w-1' : 'w-0.5'} />
      {Icon && <Icon className="mt-0.5 size-4" />}
      <div className="flex min-w-0 flex-1 flex-col gap-2">
        {title && <p className="!my-0 font-medium">{title}</p>}
        <div className="text-fd-muted-foreground prose-no-margin empty:hidden">{children}</div>
      </div>
    </div>
  );
}


================================================
FILE: apps/docs/components/clerk-logo.tsx
================================================
import { cn } from '@docs/lib/utils';

export function ClerkLogo({ className, ...props }: React.SVGProps<SVGSVGElement>) {
  return (
    <svg
      viewBox="0 0 441 128"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      className={cn('fill-fd-foreground h-6', className)}
      {...props}>
      <path d="M166.971 40.9172C178.576 40.9172 190.795 45.5232 198.363 54.4358C198.413 54.4943 198.406 54.5818 198.348 54.6321L186.955 64.4905C186.897 64.5411 186.808 64.5348 186.757 64.4768C184.442 61.8452 181.568 59.7383 178.335 58.303C175.059 56.8492 171.495 56.1207 167.898 56.1702C154.488 56.1702 145.548 65.3619 145.548 78.8C145.548 85.5131 147.771 91.145 151.635 95.0891C153.762 97.1729 156.302 98.8083 159.099 99.8948C161.896 100.981 164.891 101.496 167.898 101.406C171.46 101.438 174.992 100.759 178.276 99.4104C181.52 98.0791 184.457 96.1229 186.911 93.6584C186.963 93.6061 187.047 93.6025 187.103 93.6506L198.748 103.698C198.808 103.749 198.814 103.839 198.761 103.898C192.264 111.073 180.762 116.764 166.364 116.764C155.225 116.764 145.571 112.854 138.795 106.199C132.019 99.5445 128 90.1203 128 78.928C128 56.2988 144.169 40.9174 166.971 40.9172ZM272.297 40.9241C294.364 40.9243 308.634 56.4443 308.634 77.8733C308.603 80.0994 308.45 82.3226 308.177 84.5325C308.168 84.6028 308.108 84.6555 308.037 84.6555H253.776C253.687 84.6555 253.62 84.7398 253.64 84.8274C255.961 95.114 263.91 101.384 274.9 101.384C278.479 101.459 282.026 100.724 285.269 99.2327C288.467 97.7617 291.284 95.5949 293.505 92.8977C293.555 92.8373 293.644 92.829 293.704 92.8792L294.151 93.2522L305.314 102.971C305.371 103.02 305.379 103.107 305.332 103.165C299.016 110.999 288.524 116.764 273.977 116.764C252.205 116.764 235.781 101.687 235.781 78.7805C235.781 67.5426 239.651 58.1184 246.1 51.4641C249.503 48.0425 253.584 45.3422 258.089 43.5295C262.594 41.7168 267.43 40.83 272.297 40.9241ZM225.661 11.9758C225.739 11.9758 225.802 12.0388 225.802 12.1165V115.625C225.802 115.703 225.739 115.766 225.661 115.766H208.977C208.899 115.766 208.836 115.703 208.836 115.625V12.1165C208.836 12.0389 208.899 11.976 208.977 11.9758H225.661ZM361.385 40.9192C361.463 40.9183 361.527 40.9816 361.527 41.0598V59.6116C361.527 59.6933 361.457 59.7582 361.376 59.7522C359.432 59.6052 357.496 59.4612 356.304 59.4612C343.246 59.4613 335.579 68.6515 335.579 80.7151V115.625C335.579 115.703 335.516 115.766 335.438 115.766H318.755C318.677 115.766 318.614 115.703 318.614 115.625V42.1047C318.614 42.0272 318.677 41.9641 318.755 41.9641H335.438C335.516 41.9641 335.579 42.0272 335.579 42.1047V53.0413C335.579 53.098 335.626 53.1438 335.683 53.1438C335.715 53.1438 335.746 53.1287 335.766 53.1028C341.617 45.2882 350.254 40.9407 359.379 40.9407L361.385 40.9192ZM388.332 11.9758C388.41 11.9759 388.473 12.0388 388.473 12.1165V75.2815C388.473 75.4096 388.63 75.4707 388.717 75.3762L419.408 41.9211C419.435 41.8922 419.472 41.8752 419.512 41.8752H439.575C439.697 41.8752 439.762 42.0202 439.68 42.1106L412.928 71.6262C412.886 71.6727 412.879 71.7419 412.912 71.7952L440.031 115.551C440.089 115.645 440.022 115.766 439.912 115.766H420.879C420.83 115.766 420.784 115.741 420.759 115.699L401.525 84.7874C401.5 84.7463 401.455 84.7209 401.406 84.7209H401.226C401.187 84.7209 401.149 84.7373 401.122 84.7659L388.51 98.3167C388.486 98.3426 388.473 98.3769 388.473 98.4124V115.625C388.473 115.703 388.41 115.766 388.332 115.766H371.647C371.57 115.766 371.507 115.703 371.507 115.625V12.1165C371.507 12.0388 371.57 11.9759 371.647 11.9758H388.332ZM273.184 56.1526C270.429 56.0653 267.689 56.5639 265.148 57.6135C262.608 58.6639 260.328 60.2418 258.465 62.2375C256.265 64.7317 254.709 67.7085 253.927 70.9172C253.905 71.0052 253.972 71.09 254.062 71.0901H291.098C291.188 71.0901 291.255 71.0045 291.233 70.9163C289.077 62.1122 282.94 56.1526 273.184 56.1526Z" />
      <circle cx="64" cy="64" r="20" />
      <path
        d="M99.5716 10.788C101.571 12.1272 101.742 14.9444 100.04 16.646L85.4244 31.2618C84.1035 32.5828 82.0542 32.7914 80.3915 31.9397C75.4752 29.421 69.9035 28 64 28C44.1177 28 28 44.1177 28 64C28 69.9035 29.421 75.4752 31.9397 80.3915C32.7914 82.0542 32.5828 84.1035 31.2618 85.4244L16.646 100.04C14.9444 101.742 12.1272 101.571 10.788 99.5716C3.97411 89.3989 0 77.1635 0 64C0 28.6538 28.6538 0 64 0C77.1635 0 89.3989 3.97411 99.5716 10.788Z"
        fillOpacity="0.4"
      />
      <path d="M100.04 111.354C101.742 113.056 101.571 115.873 99.5717 117.212C89.3989 124.026 77.1636 128 64 128C50.8364 128 38.6011 124.026 28.4283 117.212C26.4289 115.873 26.2581 113.056 27.9597 111.354L42.5755 96.7382C43.8964 95.4172 45.9457 95.2085 47.6084 96.0603C52.5247 98.579 58.0964 100 64 100C69.9036 100 75.4753 98.579 80.3916 96.0603C82.0543 95.2085 84.1035 95.4172 85.4245 96.7382L100.04 111.354Z" />
    </svg>
  );
}


================================================
FILE: apps/docs/components/command-tabs.tsx
================================================
import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';

const MANAGERS = ['npm', 'bun', 'pnpm', 'yarn', 'yarn@berry'] as const;

const COMMAND: Record<(typeof MANAGERS)[number], string[]> = {
  npm: ['npx'],
  bun: ['bunx', '--bun'],
  pnpm: ['pnpm', 'dlx'],
  yarn: ['npx'],
  'yarn@berry': ['yarn', 'dlx'],
};

export function CommandTabs({ args }: { args: string[] }) {
  return (
    <div className="dark">
      <Tabs items={MANAGERS as unknown as string[]} groupId="manager" persist>
        {MANAGERS.map((manager) => (
          <Tab key={manager} value={manager} className="dark:text-foreground *:dark">
            <CodeBlock>
              <Pre>
                <code>
                  {[...COMMAND[manager], '@react-native-reusables/cli@latest', ...args].join(' ')}
                </code>
              </Pre>
            </CodeBlock>
          </Tab>
        ))}
      </Tabs>
    </div>
  );
}


================================================
FILE: apps/docs/components/cookies-provider.tsx
================================================
'use client';

import { CookiesNextProvider } from 'cookies-next';

export function CookiesProvider({ children }: { children: React.ReactNode }) {
  return <CookiesNextProvider>{children}</CookiesNextProvider>;
}


================================================
FILE: apps/docs/components/copy-button.tsx
================================================
'use client';

// This project uses code from fumadocs.
// The code is licensed under the MIT License.
// https://github.com/fuma-nama/fumadocs

import { cn } from '@docs/lib/utils';
import { CheckIcon, CopyIcon } from 'lucide-react';
import * as React from 'react';
import { buttonVariants } from './ui/button';

export function CopyButton({
  className,
  content,
  ...props
}: React.ButtonHTMLAttributes<HTMLButtonElement> & {
  content: string;
}): React.ReactElement {
  const onCopy = React.useCallback(() => {
    void navigator.clipboard.writeText(content ?? '');
  }, [content]);
  const [checked, onClick] = useCopyButton(onCopy);

  return (
    <button
      type="button"
      className={cn(
        buttonVariants({
          variant: 'ghost',
          size: 'icon',
        }),
        'size-7 transition-opacity group-hover:opacity-100',
        !checked && 'opacity-0',
        className
      )}
      aria-label="Copy Text"
      onClick={onClick}
      {...props}>
      <CheckIcon className={cn('!size-3.5 transition-transform', !checked && 'scale-0')} />
      <CopyIcon className={cn('absolute !size-3.5 transition-transform', checked && 'scale-0')} />
    </button>
  );
}

function useCopyButton(onCopy: () => void): [checked: boolean, onClick: React.MouseEventHandler] {
  const [checked, setChecked] = React.useState(false);
  const timeoutRef = React.useRef<number | null>(null);
  const callbackRef = React.useRef(onCopy);
  callbackRef.current = onCopy;

  const onClick: React.MouseEventHandler = React.useCallback(() => {
    if (timeoutRef.current) window.clearTimeout(timeoutRef.current);
    timeoutRef.current = window.setTimeout(() => {
      setChecked(false);
    }, 1500);
    callbackRef.current();
    setChecked(true);
  }, []);

  // Avoid updates after being unmounted
  React.useEffect(() => {
    return () => {
      if (timeoutRef.current) window.clearTimeout(timeoutRef.current);
    };
  }, []);

  return [checked, onClick];
}


================================================
FILE: apps/docs/components/download-app-banner.tsx
================================================
import { AppStoreButton } from './app-store-button';
import { PlayStoreButton } from './play-store-button';
import { RnrIcon } from './icons/rnr-icon';
import { cn } from '@docs/lib/utils';

export function DownloadAppBanner({
  title = 'React Native Reusables',
  description = 'Preview components on your phone by scanning QR codes from the docs.',
  size = 'default',
}: {
  title?: string;
  description?: string;
  size?: 'default' | 'sm';
}) {
  return (
    <div className="bg-card not-prose flex flex-col-reverse items-center justify-between gap-6 rounded-xl border p-12 shadow-sm sm:gap-8 lg:flex-row lg:p-14">
      <div
        className={cn(
          'flex max-w-[25.5rem] flex-col items-center justify-center gap-8 lg:items-start',
          size === 'sm' && 'max-w-xs'
        )}>
        <div>
          <h1 className="pb-1 text-center text-3xl font-medium lg:text-left lg:text-4xl">
            {title}
          </h1>
          <p className="text-muted-foreground text-center text-base lg:text-left">{description}</p>
        </div>
        <div className="flex gap-2 lg:gap-3">
          <AppStoreButton />
          <PlayStoreButton />
        </div>
      </div>
      <div className="flex items-center justify-center">
        <div className="border-border/0 dark:border-border flex items-center justify-center rounded-3xl border bg-black p-4 shadow-md md:rounded-[2.5rem] md:p-6">
          <RnrIcon className="size-16 text-white md:size-32" pathClassName="stroke-1" />
        </div>
      </div>
    </div>
  );
}


================================================
FILE: apps/docs/components/examples.tsx
================================================
'use client';

export * from '@/registry/examples';


================================================
FILE: apps/docs/components/external-links.tsx
================================================
import { ExternalLinkIcon } from 'lucide-react';

type ExternalLinksProps = {
  links: {
    title: string;
    url: string;
  }[];
};

export function ExternalLinks(props: ExternalLinksProps) {
  return (
    <div className="flex flex-wrap gap-2 pb-5">
      {props.links.map((link) => (
        <a
          key={link.title}
          href={link.url}
          target="_blank"
          className="bg-muted hover:bg-muted/50 inline-flex rounded-md border px-2 py-0.5 no-underline">
          <div className="text-foreground/80 flex items-center gap-1 text-xs font-medium">
            {link.title} <ExternalLinkIcon strokeWidth={2.5} className="h-3 w-3" />
          </div>
        </a>
      ))}
    </div>
  );
}


================================================
FILE: apps/docs/components/icons/rnr-icon.tsx
================================================
import { cn } from '@docs/lib/utils';

export function RnrIcon({
  className,
  pathClassName,
  ...props
}: {
  className?: string;
  pathClassName?: string;
}) {
  return (
    <svg
      viewBox="0 0 26 23"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      className={cn('w-5', className)}
      shapeRendering="geometricPrecision"
      {...props}>
      <path
        d="M15.2858 11.4777L13.0001 13.7131M14.8287 9.01884L10.4858 13.266M13.0001 16.7794C19.6275 16.7794 25 14.4158 25 11.5C25 8.5843 19.6275 6.22068 13.0001 6.22068C6.37276 6.22068 1 8.5843 1 11.5C1 14.4158 6.37276 16.7794 13.0001 16.7794ZM8.3235 14.1397C11.6373 19.751 16.4172 23.1179 18.9999 21.6602C21.5829 20.2022 20.9903 14.4714 17.6765 8.86036C14.3629 3.24884 9.58282 -0.118067 7.00028 1.33992C4.41729 2.79768 5.00994 8.52842 8.3235 14.1397ZM8.3235 8.86036C5.00994 14.4717 4.41751 20.2022 7.00006 21.6602C9.58305 23.1179 14.3629 19.7508 17.6765 14.1397C20.9903 8.52821 21.5829 2.7979 19.0002 1.33992C16.4172 -0.118067 11.6373 3.24907 8.3235 8.86036Z"
        stroke="currentColor"
        strokeLinecap="round"
        className={cn('stroke-[1.2px]', pathClassName)}
      />
    </svg>
  );
}


================================================
FILE: apps/docs/components/installation-tabs.tsx
================================================
'use client';

import {
  LinkTabs,
  LinkTabsList,
  LinkTabsTrigger,
  LinkTabsContent,
} from '@docs/components/link-tabs';
import * as React from 'react';

function InstallationTabs({
  value,
  children,
}: {
  value: 'cli' | 'manual';
  children: React.ReactNode;
}) {
  return (
    <LinkTabs
      ref={onRef(value)}
      value={value === 'cli' ? '/docs/installation' : '/docs/installation/manual'}>
      <LinkTabsList>
        <LinkTabsTrigger href="/docs/installation">CLI</LinkTabsTrigger>
        <LinkTabsTrigger href="/docs/installation/manual">Manual</LinkTabsTrigger>
      </LinkTabsList>
      <LinkTabsContent value={value === 'cli' ? '/docs/installation' : '/docs/installation/manual'}>
        {children}
      </LinkTabsContent>
    </LinkTabs>
  );
}

function onRef(value: 'cli' | 'manual') {
  return () => {
    if (value === 'cli') {
      return;
    }
    const link = document.querySelector(
      'a[data-active="false"][href="/docs/installation"]'
    ) as HTMLAnchorElement | null;
    if (!link) {
      return;
    }
    link.classList.add('!bg-primary/10');
    link.classList.add('!text-primary');
    link.classList.add('!font-medium');
    return () => {
      link.classList.remove('!bg-primary/10');
      link.classList.remove('!text-primary');
      link.classList.remove('!font-medium');
    };
  };
}

export { InstallationTabs };


================================================
FILE: apps/docs/components/link-tabs.tsx
================================================
'use client';

import * as React from 'react';
import * as TabsPrimitive from '@radix-ui/react-tabs';

import { cn } from '@docs/lib/utils';
import Link from 'next/link';

function LinkTabs({
  className,
  ...props
}: Omit<
  React.ComponentProps<typeof TabsPrimitive.Root>,
  'value' | 'defaultValue' | 'onValueChange' | 'activationMode'
> & {
  value: `/${string}`;
}) {
  return (
    <TabsPrimitive.Root
      className={cn('relative w-full', className)}
      {...props}
      activationMode="manual"
    />
  );
}

function LinkTabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>) {
  return (
    <TabsPrimitive.List
      className={cn(
        'text-muted-foreground inline-flex h-9 w-full items-center justify-start rounded-none border-b p-0',
        className
      )}
      {...props}
    />
  );
}

function LinkTabsTrigger({ className, ...props }: React.ComponentProps<typeof Link>) {
  return (
    <TabsPrimitive.Trigger value={props.href.toString()} asChild>
      <Link
        className={cn(
          'ring-offset-background focus-visible:ring-ring text-muted-foreground data-[state=active]:border-b-primary data-[state=active]:text-foreground relative inline-flex h-9 items-center justify-center whitespace-nowrap rounded-none border-b-2 border-b-transparent px-4 py-1 pb-3 pt-2 text-sm font-semibold no-underline shadow-none transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-none',
          className
        )}
        {...props}
      />
    </TabsPrimitive.Trigger>
  );
}

function LinkTabsContent({
  className,
  ...props
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
  return (
    <TabsPrimitive.Content
      className={cn(
        'ring-offset-background focus-visible:ring-ring relative mt-5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 [&_h3.font-heading]:text-base [&_h3.font-heading]:font-semibold',
        className
      )}
      {...props}
    />
  );
}

export { LinkTabs, LinkTabsList, LinkTabsTrigger, LinkTabsContent };


================================================
FILE: apps/docs/components/platform-select.tsx
================================================
'use client';

import { Button } from '@docs/components/ui/button';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@docs/components/ui/select';
import { type SelectProps } from '@radix-ui/react-select';
import { useReactiveGetCookie, useReactiveSetCookie } from 'cookies-next/client';
import * as React from 'react';

const PLATFORMS = [
  { name: 'web', label: 'Web' },
  { name: 'native', label: 'Native' },
] as const;

type Platform = (typeof PLATFORMS)[number]['name'];

export function PlatformSelect(props: SelectProps) {
  const [isClient, setIsClient] = React.useState(false);
  const [platform, onPlatformChange] = usePlatform();

  React.useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <Select {...props} defaultValue="web" value={platform} onValueChange={onPlatformChange}>
      <Button asChild variant="outline" size="sm">
        <SelectTrigger className="dark:bg-muted dark:hover:bg-muted/80 dark:border-muted-foreground/15 w-fit">
          <span className="text-muted-foreground flex-1 pr-1">Platform:</span>
          {!isClient ? (
            <span className="opacity-50">
              {
                PLATFORMS.find((platform) =>
                  platform.name === props.value ? props.value : props.defaultValue
                )?.label
              }
            </span>
          ) : (
            <SelectValue placeholder="Select platform" />
          )}
        </SelectTrigger>
      </Button>
      <SelectContent onCloseAutoFocus={preventDefault} className="dark:bg-neutral-900">
        {PLATFORMS.map((platform) => (
          <SelectItem key={platform.name} value={platform.name} className="text-xs">
            {platform.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

export function usePlatform() {
  const getCookie = useReactiveGetCookie();
  const setCookie = useReactiveSetCookie();
  const platform = getCookie('user.platform') ?? 'web';
  function onPlatformChange(value: Platform) {
    setCookie('user.platform', value);
  }
  return [platform, onPlatformChange] as const;
}

function preventDefault(e: Event) {
  e.preventDefault();
}


================================================
FILE: apps/docs/components/play-store-button.tsx
================================================
import Image from 'next/image';

export function PlayStoreButton() {
  return (
    <a
      href="https://play.google.com/store/apps/details?id=com.reactnativereusables.android"
      target="_blank"
      className="relative aspect-[16/5] h-10 rounded-sm sm:h-12">
      <Image alt="Get it on Google Play" src={'/google-play-badge.png'} fill />
    </a>
  );
}


================================================
FILE: apps/docs/components/portal-info-alert.tsx
================================================
import { Callout } from '@docs/components/callout';
import Link from 'next/link';

export function PortalInfoAlert() {
  return (
    <Callout type="warn" title="Portal Setup Required">
      A{' '}
      <Link
        href="/docs/installation/manual#add-the-portal-host-to-your-root-layout"
        className="hover:underline">
        <code className="bg-muted rounded-sm px-1 py-0.5 text-[0.813rem]">PortalHost</code>
      </Link>{' '}
      must be added at the root of your app to support portal rendering on native platforms. Without
      it, components that rely on portals, like this one, will not render correctly.
    </Callout>
  );
}


================================================
FILE: apps/docs/components/preview-card.tsx
================================================
'use client';

import { RnrIcon } from '@docs/components/icons/rnr-icon';
import { PlatformSelect, usePlatform } from '@docs/components/platform-select';
import { useParams } from 'next/navigation';
import { QRCodeSVG } from 'qrcode.react';
import * as React from 'react';

type PreviewCardProps = {
  preview: React.ReactNode;
};

export function PreviewCard({ preview }: PreviewCardProps) {
  const { width } = useWindowSize();
  const isDark = useIsDarkMode();
  const params = useParams<{ slug: string[] }>();
  const [platform] = usePlatform();

  const component = params.slug.at(-1);

  return (
    <>
      <div className="group/copy bg-card not-prose relative flex min-h-[450px] flex-col rounded-md border p-4">
        <div className="absolute -top-11 right-0 mt-px hidden items-center justify-end sm:flex">
          <PlatformSelect />
        </div>
        <div className="flex flex-1 flex-col items-center justify-center">
          {platform === 'native' && width >= 640 ? (
            <div className="flex max-w-sm flex-col items-center gap-6 p-4">
              <QRCodeSVG
                value={`https://reactnativereusables.com/showcase/links/${component}`}
                bgColor={isDark ? 'black' : 'white'}
                fgColor={isDark ? 'white' : 'black'}
                size={230}
                level="H"
              />
              <p className="text-center font-mono text-sm">Scan to preview.</p>
            </div>
          ) : (
            preview
          )}
        </div>
      </div>
      <a
        href={`https://reactnativereusables.com/showcase/links/${component}`}
        target="_blank"
        className="not-prose bg-primary text-primary-foreground focus-visible:border-ring focus-visible:ring-ring/50 mt-4 inline-flex w-full shrink-0 items-center gap-2.5 rounded-lg p-2.5 text-sm font-medium shadow-sm outline-none transition-all focus-visible:ring-[3px] sm:hidden dark:p-2 [&_svg]:shrink-0">
        <div className="bg-primary flex items-center justify-center rounded-lg p-1 shadow-md dark:bg-black dark:p-2">
          <RnrIcon className="size-11 text-white dark:size-10" pathClassName="stroke-1" />
        </div>
        <div className="flex flex-col gap-1">
          <p className="leading-none">Tap to preview in the app</p>
          <p className="text-[1.3rem] font-semibold leading-none">React Native Reusables</p>
        </div>
      </a>
    </>
  );
}

export function BlockPreviewCard({ preview }: PreviewCardProps) {
  return (
    <div className="group/copy bg-card not-prose relative flex min-h-[450px] flex-col rounded-md border">
      <div className="flex flex-1 flex-col items-center justify-center py-6 sm:px-4 sm:py-8">
        {preview}
      </div>
    </div>
  );
}

type WindowSize = {
  width: number;
  height: number;
};

function useWindowSize(): WindowSize {
  const [size, setSize] = React.useState<WindowSize>({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  React.useEffect(() => {
    function handleResize() {
      setSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }

    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return size;
}

export function useIsDarkMode(): boolean {
  const [isDark, setIsDark] = React.useState(() =>
    document.documentElement.classList.contains('dark')
  );

  React.useEffect(() => {
    const htmlEl = document.documentElement;

    const updateDarkMode = () => {
      setIsDark(htmlEl.classList.contains('dark'));
    };

    updateDarkMode();

    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
          updateDarkMode();
        }
      }
    });

    observer.observe(htmlEl, { attributes: true, attributeFilter: ['class'] });

    return () => {
      observer.disconnect();
    };
  }, []);

  return isDark;
}


================================================
FILE: apps/docs/components/safe-area-provider.tsx
================================================
'use client';

export { SafeAreaProvider } from 'react-native-safe-area-context';


================================================
FILE: apps/docs/components/skip-navigation-button.tsx
================================================
import { Button } from './ui/button';

export function SkipNavigationButton() {
  return (
    <Button
      asChild
      variant="secondary"
      className="absolute -left-60 top-3.5 z-50 mt-px px-4 py-2 transition-none focus:left-4 focus:outline-none"
      aria-label="Skip navigation">
      <a href="#nd-page">Skip navigation</a>
    </Button>
  );
}


================================================
FILE: apps/docs/components/styling-library-tabs.tsx
================================================
'use client';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@docs/components/ui/tabs';
import * as React from 'react';
import { useStylingLibrary } from './use-styling-library';

export function StylingLibraryTabs({ children }: React.PropsWithChildren) {
  const [stylingLibrary, onStylingLibraryChange] = useStylingLibrary();
  return (
    <Tabs value={stylingLibrary} onValueChange={onStylingLibraryChange}>
      <div className="flex items-center justify-between">
        <TabsList>
          <TabsTrigger id="nativewind" value="nativewind">
            Nativewind
          </TabsTrigger>
          <TabsTrigger id="uniwind" value="uniwind">
            Uniwi
Download .txt
gitextract___gsboks/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   └── pull_request_template.md
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── COMMUNITY_RESOURCES.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── apps/
│   ├── cli/
│   │   ├── .changeset/
│   │   │   └── config.json
│   │   ├── .github/
│   │   │   ├── actions/
│   │   │   │   └── setup/
│   │   │   │       └── action.yml
│   │   │   └── workflows/
│   │   │       ├── check.yml
│   │   │       ├── release.yml
│   │   │       └── snapshot.yml
│   │   ├── .gitignore
│   │   ├── .prettierrc
│   │   ├── .vscode/
│   │   │   ├── extensions.json
│   │   │   └── settings.json
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── eslint.config.mjs
│   │   ├── package.json
│   │   ├── patches/
│   │   │   └── @changesets__get-github-info@0.6.0.patch
│   │   ├── scripts/
│   │   │   └── copy-package-json.ts
│   │   ├── src/
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   ├── contexts/
│   │   │   │   └── cli-options.ts
│   │   │   ├── project-manifest.ts
│   │   │   ├── services/
│   │   │   │   ├── commands/
│   │   │   │   │   ├── add.ts
│   │   │   │   │   ├── doctor.ts
│   │   │   │   │   └── init.ts
│   │   │   │   ├── git.ts
│   │   │   │   ├── package-manager.ts
│   │   │   │   ├── project-config.ts
│   │   │   │   ├── required-files-checker.ts
│   │   │   │   ├── spinner.ts
│   │   │   │   └── template.ts
│   │   │   └── utils/
│   │   │       ├── retry-with.ts
│   │   │       └── run-command.ts
│   │   ├── test/
│   │   │   └── Dummy.test.ts
│   │   ├── tsconfig.base.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.scripts.json
│   │   ├── tsconfig.src.json
│   │   ├── tsconfig.test.json
│   │   ├── tsup.config.ts
│   │   └── vitest.config.ts
│   ├── docs/
│   │   ├── .eslintrc.json
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── app/
│   │   │   ├── (home)/
│   │   │   │   ├── BlockSection.tsx
│   │   │   │   ├── ComponentsGrid.tsx
│   │   │   │   ├── TemplatesSection.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   └── page.tsx
│   │   │   ├── api/
│   │   │   │   └── search/
│   │   │   │       └── route.ts
│   │   │   ├── docs/
│   │   │   │   ├── [[...slug]]/
│   │   │   │   │   └── page.tsx
│   │   │   │   └── layout.tsx
│   │   │   ├── global.css
│   │   │   ├── layout.tsx
│   │   │   ├── og/
│   │   │   │   └── route.tsx
│   │   │   └── showcase/
│   │   │       ├── links/
│   │   │       │   └── [[...slug]]/
│   │   │       │       └── page.tsx
│   │   │       ├── privacy-policy/
│   │   │       │   └── page.tsx
│   │   │       └── support/
│   │   │           └── page.tsx
│   │   ├── components/
│   │   │   ├── app-store-button.tsx
│   │   │   ├── auth-block-tabs.tsx
│   │   │   ├── auth-integration-select.tsx
│   │   │   ├── blocks-grid.tsx
│   │   │   ├── blocks.tsx
│   │   │   ├── callout.tsx
│   │   │   ├── clerk-logo.tsx
│   │   │   ├── command-tabs.tsx
│   │   │   ├── cookies-provider.tsx
│   │   │   ├── copy-button.tsx
│   │   │   ├── download-app-banner.tsx
│   │   │   ├── examples.tsx
│   │   │   ├── external-links.tsx
│   │   │   ├── icons/
│   │   │   │   └── rnr-icon.tsx
│   │   │   ├── installation-tabs.tsx
│   │   │   ├── link-tabs.tsx
│   │   │   ├── platform-select.tsx
│   │   │   ├── play-store-button.tsx
│   │   │   ├── portal-info-alert.tsx
│   │   │   ├── preview-card.tsx
│   │   │   ├── safe-area-provider.tsx
│   │   │   ├── skip-navigation-button.tsx
│   │   │   ├── styling-library-tabs.tsx
│   │   │   ├── ui/
│   │   │   │   ├── alert.tsx
│   │   │   │   ├── badge.tsx
│   │   │   │   ├── button.tsx
│   │   │   │   ├── select.tsx
│   │   │   │   └── tabs.tsx
│   │   │   ├── use-styling-library.ts
│   │   │   └── vercel-oss-badge.tsx
│   │   ├── components.json
│   │   ├── content/
│   │   │   └── docs/
│   │   │       ├── blocks/
│   │   │       │   └── authentication/
│   │   │       │       ├── forgot-password-form.mdx
│   │   │       │       ├── index.mdx
│   │   │       │       ├── meta.json
│   │   │       │       ├── reset-password-form.mdx
│   │   │       │       ├── sign-in-form.mdx
│   │   │       │       ├── sign-up-form.mdx
│   │   │       │       ├── social-connections.mdx
│   │   │       │       ├── user-menu.mdx
│   │   │       │       └── verify-email-form.mdx
│   │   │       ├── changelog.mdx
│   │   │       ├── cli.mdx
│   │   │       ├── components/
│   │   │       │   ├── accordion.mdx
│   │   │       │   ├── alert-dialog.mdx
│   │   │       │   ├── alert.mdx
│   │   │       │   ├── aspect-ratio.mdx
│   │   │       │   ├── avatar.mdx
│   │   │       │   ├── badge.mdx
│   │   │       │   ├── button.mdx
│   │   │       │   ├── card.mdx
│   │   │       │   ├── checkbox.mdx
│   │   │       │   ├── collapsible.mdx
│   │   │       │   ├── context-menu.mdx
│   │   │       │   ├── dialog.mdx
│   │   │       │   ├── dropdown-menu.mdx
│   │   │       │   ├── hover-card.mdx
│   │   │       │   ├── input.mdx
│   │   │       │   ├── label.mdx
│   │   │       │   ├── menubar.mdx
│   │   │       │   ├── popover.mdx
│   │   │       │   ├── progress.mdx
│   │   │       │   ├── radio-group.mdx
│   │   │       │   ├── select.mdx
│   │   │       │   ├── separator.mdx
│   │   │       │   ├── skeleton.mdx
│   │   │       │   ├── switch.mdx
│   │   │       │   ├── tabs.mdx
│   │   │       │   ├── text.mdx
│   │   │       │   ├── textarea.mdx
│   │   │       │   ├── toggle-group.mdx
│   │   │       │   ├── toggle.mdx
│   │   │       │   └── tooltip.mdx
│   │   │       ├── create-your-own-registry.mdx
│   │   │       ├── customization.mdx
│   │   │       ├── index.mdx
│   │   │       ├── installation/
│   │   │       │   ├── index.mdx
│   │   │       │   └── manual.mdx
│   │   │       └── meta.json
│   │   ├── global.d.ts
│   │   ├── lib/
│   │   │   ├── FoundedLabsIcon.tsx
│   │   │   ├── file-generator.ts
│   │   │   ├── source.ts
│   │   │   └── utils.ts
│   │   ├── nativewind-env.d.ts
│   │   ├── next.config.mjs
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── public/
│   │   │   ├── .well-known/
│   │   │   │   ├── apple-app-site-association
│   │   │   │   └── assetlinks.json
│   │   │   └── r/
│   │   │       ├── nativewind/
│   │   │       │   ├── accordion.json
│   │   │       │   ├── alert-dialog.json
│   │   │       │   ├── alert.json
│   │   │       │   ├── aspect-ratio.json
│   │   │       │   ├── avatar.json
│   │   │       │   ├── badge.json
│   │   │       │   ├── button.json
│   │   │       │   ├── card.json
│   │   │       │   ├── checkbox.json
│   │   │       │   ├── collapsible.json
│   │   │       │   ├── context-menu.json
│   │   │       │   ├── dialog.json
│   │   │       │   ├── dropdown-menu.json
│   │   │       │   ├── forgot-password-form-clerk.json
│   │   │       │   ├── forgot-password-form.json
│   │   │       │   ├── hover-card.json
│   │   │       │   ├── icon.json
│   │   │       │   ├── input.json
│   │   │       │   ├── label.json
│   │   │       │   ├── menubar.json
│   │   │       │   ├── native-only-animated-view.json
│   │   │       │   ├── popover.json
│   │   │       │   ├── progress.json
│   │   │       │   ├── radio-group.json
│   │   │       │   ├── reset-password-form-clerk.json
│   │   │       │   ├── reset-password-form.json
│   │   │       │   ├── select.json
│   │   │       │   ├── separator.json
│   │   │       │   ├── sign-in-form-clerk.json
│   │   │       │   ├── sign-in-form.json
│   │   │       │   ├── sign-up-form-clerk.json
│   │   │       │   ├── sign-up-form.json
│   │   │       │   ├── skeleton.json
│   │   │       │   ├── social-connections-clerk.json
│   │   │       │   ├── social-connections.json
│   │   │       │   ├── switch.json
│   │   │       │   ├── tabs.json
│   │   │       │   ├── text.json
│   │   │       │   ├── textarea.json
│   │   │       │   ├── toggle-group.json
│   │   │       │   ├── toggle.json
│   │   │       │   ├── tooltip.json
│   │   │       │   ├── user-menu-clerk.json
│   │   │       │   ├── user-menu.json
│   │   │       │   ├── verify-email-form-clerk.json
│   │   │       │   └── verify-email-form.json
│   │   │       └── uniwind/
│   │   │           ├── accordion.json
│   │   │           ├── alert-dialog.json
│   │   │           ├── alert.json
│   │   │           ├── aspect-ratio.json
│   │   │           ├── avatar.json
│   │   │           ├── badge.json
│   │   │           ├── button.json
│   │   │           ├── card.json
│   │   │           ├── checkbox.json
│   │   │           ├── collapsible.json
│   │   │           ├── context-menu.json
│   │   │           ├── dialog.json
│   │   │           ├── dropdown-menu.json
│   │   │           ├── forgot-password-form-clerk.json
│   │   │           ├── forgot-password-form.json
│   │   │           ├── hover-card.json
│   │   │           ├── icon.json
│   │   │           ├── input.json
│   │   │           ├── label.json
│   │   │           ├── menubar.json
│   │   │           ├── native-only-animated-view.json
│   │   │           ├── popover.json
│   │   │           ├── progress.json
│   │   │           ├── radio-group.json
│   │   │           ├── reset-password-form-clerk.json
│   │   │           ├── reset-password-form.json
│   │   │           ├── select.json
│   │   │           ├── separator.json
│   │   │           ├── sign-in-form-clerk.json
│   │   │           ├── sign-in-form.json
│   │   │           ├── sign-up-form-clerk.json
│   │   │           ├── sign-up-form.json
│   │   │           ├── skeleton.json
│   │   │           ├── social-connections-clerk.json
│   │   │           ├── social-connections.json
│   │   │           ├── switch.json
│   │   │           ├── tabs.json
│   │   │           ├── text.json
│   │   │           ├── textarea.json
│   │   │           ├── toggle-group.json
│   │   │           ├── toggle.json
│   │   │           ├── tooltip.json
│   │   │           ├── user-menu-clerk.json
│   │   │           ├── user-menu.json
│   │   │           ├── verify-email-form-clerk.json
│   │   │           └── verify-email-form.json
│   │   ├── registry/
│   │   │   ├── nativewind.json
│   │   │   └── uniwind.json
│   │   ├── scripts/
│   │   │   └── generate-local-registry.js
│   │   ├── source.config.ts
│   │   ├── src/
│   │   │   └── content/
│   │   │       └── docs/
│   │   │           └── showcase/
│   │   │               ├── links/
│   │   │               │   ├── button.mdx
│   │   │               │   ├── input.mdx
│   │   │               │   └── wrong.mdx
│   │   │               ├── privacy-policy.mdx
│   │   │               └── support.mdx
│   │   ├── tailwind.config.js
│   │   ├── tsconfig.json
│   │   └── vercel.json
│   └── showcase/
│       ├── .gitignore
│       ├── app/
│       │   ├── +html.tsx
│       │   ├── +not-found.tsx
│       │   ├── _layout.tsx
│       │   ├── components/
│       │   │   ├── accordion.tsx
│       │   │   ├── alert-dialog.tsx
│       │   │   ├── alert.tsx
│       │   │   ├── aspect-ratio.tsx
│       │   │   ├── avatar.tsx
│       │   │   ├── badge.tsx
│       │   │   ├── button.tsx
│       │   │   ├── card.tsx
│       │   │   ├── checkbox.tsx
│       │   │   ├── collapsible.tsx
│       │   │   ├── context-menu.tsx
│       │   │   ├── dialog.tsx
│       │   │   ├── dropdown-menu.tsx
│       │   │   ├── hover-card.tsx
│       │   │   ├── input.tsx
│       │   │   ├── label.tsx
│       │   │   ├── menubar.tsx
│       │   │   ├── popover.tsx
│       │   │   ├── progress.tsx
│       │   │   ├── radio-group.tsx
│       │   │   ├── select.tsx
│       │   │   ├── separator.tsx
│       │   │   ├── skeleton.tsx
│       │   │   ├── switch.tsx
│       │   │   ├── tabs.tsx
│       │   │   ├── text.tsx
│       │   │   ├── textarea.tsx
│       │   │   ├── toggle-group.tsx
│       │   │   ├── toggle.tsx
│       │   │   └── tooltip.tsx
│       │   ├── index.tsx
│       │   └── showcase/
│       │       └── links/
│       │           └── [slug].tsx
│       ├── app.config.ts
│       ├── babel.config.js
│       ├── components/
│       │   ├── header-right-view.tsx
│       │   ├── preview-carousel.tsx
│       │   └── theme-toggle.tsx
│       ├── components.json
│       ├── eas.json
│       ├── global.css
│       ├── hooks/
│       │   └── use-geist-font.tsx
│       ├── index.js
│       ├── lib/
│       │   ├── constants.ts
│       │   ├── theme.ts
│       │   └── utils.ts
│       ├── metro.config.js
│       ├── nativewind-env.d.ts
│       ├── package.json
│       ├── plugins/
│       │   └── geistFontPlugin.js
│       ├── tailwind.config.js
│       ├── tsconfig.json
│       └── vercel.json
├── package.json
├── packages/
│   └── registry/
│       ├── nativewind-env.d.ts
│       ├── package.json
│       ├── src/
│       │   ├── blocks/
│       │   │   ├── clerk/
│       │   │   │   ├── forgot-password-form.tsx
│       │   │   │   ├── reset-password-form.tsx
│       │   │   │   ├── sign-in-form.tsx
│       │   │   │   ├── sign-up-form.tsx
│       │   │   │   ├── social-connections.tsx
│       │   │   │   ├── user-menu.tsx
│       │   │   │   └── verify-email-form.tsx
│       │   │   ├── forgot-password-form.tsx
│       │   │   ├── index.ts
│       │   │   ├── reset-password-form.tsx
│       │   │   ├── sign-in-form.tsx
│       │   │   ├── sign-up-form.tsx
│       │   │   ├── social-connections.tsx
│       │   │   ├── user-menu.tsx
│       │   │   └── verify-email-form.tsx
│       │   ├── examples/
│       │   │   ├── accordion.tsx
│       │   │   ├── alert-dialog.tsx
│       │   │   ├── alert.tsx
│       │   │   ├── aspect-ratio.tsx
│       │   │   ├── avatar.tsx
│       │   │   ├── badge.tsx
│       │   │   ├── button/
│       │   │   │   ├── button-destructive.tsx
│       │   │   │   ├── button-ghost.tsx
│       │   │   │   ├── button-icon.tsx
│       │   │   │   ├── button-link.tsx
│       │   │   │   ├── button-loading.tsx
│       │   │   │   ├── button-outline.tsx
│       │   │   │   ├── button-primary.tsx
│       │   │   │   ├── button-secondary.tsx
│       │   │   │   ├── button-with-icon.tsx
│       │   │   │   └── index.ts
│       │   │   ├── card.tsx
│       │   │   ├── checkbox.tsx
│       │   │   ├── collapsible.tsx
│       │   │   ├── context-menu.tsx
│       │   │   ├── dialog.tsx
│       │   │   ├── dropdown-menu.tsx
│       │   │   ├── hover-card.tsx
│       │   │   ├── index.ts
│       │   │   ├── input.tsx
│       │   │   ├── label.tsx
│       │   │   ├── menubar.tsx
│       │   │   ├── popover.tsx
│       │   │   ├── progress.tsx
│       │   │   ├── radio-group.tsx
│       │   │   ├── select/
│       │   │   │   ├── index.ts
│       │   │   │   ├── scrollable-select.tsx
│       │   │   │   └── select.tsx
│       │   │   ├── separator.tsx
│       │   │   ├── skeleton.tsx
│       │   │   ├── switch.tsx
│       │   │   ├── tabs.tsx
│       │   │   ├── text/
│       │   │   │   ├── index.ts
│       │   │   │   ├── text-cascade.tsx
│       │   │   │   ├── text-typorgaphy.tsx
│       │   │   │   └── text.tsx
│       │   │   ├── textarea.tsx
│       │   │   ├── toggle-group.tsx
│       │   │   ├── toggle.tsx
│       │   │   └── tooltip.tsx
│       │   ├── nativewind/
│       │   │   ├── components/
│       │   │   │   └── ui/
│       │   │   │       ├── accordion.tsx
│       │   │   │       ├── alert-dialog.tsx
│       │   │   │       ├── alert.tsx
│       │   │   │       ├── aspect-ratio.tsx
│       │   │   │       ├── avatar.tsx
│       │   │   │       ├── badge.tsx
│       │   │   │       ├── button.tsx
│       │   │   │       ├── card.tsx
│       │   │   │       ├── checkbox.tsx
│       │   │   │       ├── collapsible.tsx
│       │   │   │       ├── context-menu.tsx
│       │   │   │       ├── dialog.tsx
│       │   │   │       ├── dropdown-menu.tsx
│       │   │   │       ├── hover-card.tsx
│       │   │   │       ├── icon.tsx
│       │   │   │       ├── input.tsx
│       │   │   │       ├── label.tsx
│       │   │   │       ├── menubar.tsx
│       │   │   │       ├── native-only-animated-view.tsx
│       │   │   │       ├── popover.tsx
│       │   │   │       ├── progress.tsx
│       │   │   │       ├── radio-group.tsx
│       │   │   │       ├── select.tsx
│       │   │   │       ├── separator.tsx
│       │   │   │       ├── skeleton.tsx
│       │   │   │       ├── switch.tsx
│       │   │   │       ├── tabs.tsx
│       │   │   │       ├── text.tsx
│       │   │   │       ├── textarea.tsx
│       │   │   │       ├── toggle-group.tsx
│       │   │   │       ├── toggle.tsx
│       │   │   │       └── tooltip.tsx
│       │   │   └── lib/
│       │   │       ├── index.ts
│       │   │       └── utils.ts
│       │   └── uniwind/
│       │       ├── components/
│       │       │   └── ui/
│       │       │       ├── accordion.tsx
│       │       │       ├── alert-dialog.tsx
│       │       │       ├── alert.tsx
│       │       │       ├── aspect-ratio.tsx
│       │       │       ├── avatar.tsx
│       │       │       ├── badge.tsx
│       │       │       ├── button.tsx
│       │       │       ├── card.tsx
│       │       │       ├── checkbox.tsx
│       │       │       ├── collapsible.tsx
│       │       │       ├── context-menu.tsx
│       │       │       ├── dialog.tsx
│       │       │       ├── dropdown-menu.tsx
│       │       │       ├── hover-card.tsx
│       │       │       ├── icon.tsx
│       │       │       ├── input.tsx
│       │       │       ├── label.tsx
│       │       │       ├── menubar.tsx
│       │       │       ├── native-only-animated-view.tsx
│       │       │       ├── popover.tsx
│       │       │       ├── progress.tsx
│       │       │       ├── radio-group.tsx
│       │       │       ├── select.tsx
│       │       │       ├── separator.tsx
│       │       │       ├── skeleton.tsx
│       │       │       ├── switch.tsx
│       │       │       ├── tabs.tsx
│       │       │       ├── text.tsx
│       │       │       ├── textarea.tsx
│       │       │       ├── toggle-group.tsx
│       │       │       ├── toggle.tsx
│       │       │       └── tooltip.tsx
│       │       └── lib/
│       │           ├── index.ts
│       │           └── utils.ts
│       ├── tsconfig.json
│       └── uniwind-types.d.ts
├── pnpm-workspace.yaml
└── turbo.json
Download .txt
SYMBOL INDEX (472 symbols across 215 files)

FILE: apps/cli/src/contexts/cli-options.ts
  type StylingLibrary (line 4) | type StylingLibrary = "nativewind" | "uniwind"
  class CliOptions (line 6) | class CliOptions extends Context.Tag("CommandOptions")<

FILE: apps/cli/src/project-manifest.ts
  type FileCheck (line 1) | interface FileCheck {
  type CustomFileCheck (line 13) | type CustomFileCheck = Omit<FileCheck, "fileNames"> & { defaultFileNames...
  type FileWithContent (line 15) | interface FileWithContent extends FileCheck {
  type MissingInclude (line 19) | interface MissingInclude {
  constant CORE_DEPENDENCIES (line 26) | const CORE_DEPENDENCIES = [
  constant DEPENDENCIES (line 36) | const DEPENDENCIES = {
  constant DEV_DEPENDENCIES (line 41) | const DEV_DEPENDENCIES = ["tailwindcss@^3.4.14"]
  constant FILE_CHECKS (line 43) | const FILE_CHECKS: Array<FileCheck> = [
  constant DEPRECATED_FROM_LIB (line 108) | const DEPRECATED_FROM_LIB: Array<Omit<FileCheck, "docs" | "stylingLibrar...
  constant DEPRECATED_FROM_UI (line 144) | const DEPRECATED_FROM_UI: Array<Omit<FileCheck, "docs" | "stylingLibrari...
  constant CSS_VARIABLE_NAMES (line 172) | const CSS_VARIABLE_NAMES = [
  constant CUSTOM_FILE_CHECKS (line 188) | const CUSTOM_FILE_CHECKS: Record<string, CustomFileCheck> = {
  constant NATIVEWIND_ENV_FILE (line 301) | const NATIVEWIND_ENV_FILE = "nativewind-env.d.ts"
  constant UNIWIND_TYPES_FILE (line 302) | const UNIWIND_TYPES_FILE = "uniwind-types.d.ts"
  constant COMPONENTS (line 304) | const COMPONENTS = [
  constant TEMPLATES (line 337) | const TEMPLATES = [
  constant PROJECT_MANIFEST (line 355) | const PROJECT_MANIFEST = {

FILE: apps/cli/src/services/commands/add.ts
  type AddOptions (line 10) | type AddOptions = {
  class Add (line 20) | class Add extends Effect.Service<Add>()("Add", {
  function make (line 94) | function make(options: AddOptions) {
  function toShadcnOptions (line 110) | function toShadcnOptions(options: AddOptions) {

FILE: apps/cli/src/services/commands/doctor.ts
  class PackageJsonError (line 17) | class PackageJsonError extends Data.TaggedError("PackageJsonError")<{
  type DoctorOptions (line 22) | type DoctorOptions = {
  class Doctor (line 28) | class Doctor extends Effect.Service<Doctor>()("Doctor", {
  function make (line 218) | function make(options: DoctorOptions) {
  type Result (line 228) | interface Result {
  function analyzeResult (line 236) | function analyzeResult(result: Result) {

FILE: apps/cli/src/services/commands/init.ts
  type InitOptions (line 11) | type InitOptions = {
  class Init (line 16) | class Init extends Effect.Service<Init>()("Init", {
  function make (line 80) | function make(options: InitOptions) {

FILE: apps/cli/src/services/git.ts
  class GitError (line 6) | class GitError extends Data.TaggedError("GitError")<{
  constant COMMANDS (line 11) | const COMMANDS = {
  class Git (line 15) | class Git extends Effect.Service<Git>()("Git", {

FILE: apps/cli/src/services/package-manager.ts
  constant PACKAGE_MANAGERS (line 4) | const PACKAGE_MANAGERS = ["npm", "bun", "pnpm", "yarn@berry", "yarn"] as...
  constant BINARY_RUNNERS (line 6) | const BINARY_RUNNERS = {
  class PackageManager (line 40) | class PackageManager extends Effect.Service<PackageManager>()("PackageMa...

FILE: apps/cli/src/services/project-config.ts
  class ProjectConfig (line 34) | class ProjectConfig extends Effect.Service<ProjectConfig>()("ProjectConf...

FILE: apps/cli/src/services/required-files-checker.ts
  class RequiredFileError (line 10) | class RequiredFileError extends Data.TaggedError("RequiredFileError")<{
  class RequiredFilesChecker (line 15) | class RequiredFilesChecker extends Effect.Service<RequiredFilesChecker>(...

FILE: apps/cli/src/services/spinner.ts
  class Spinner (line 4) | class Spinner extends Effect.Service<Spinner>()("Spinner", {

FILE: apps/cli/src/services/template.ts
  class Template (line 8) | class Template extends Effect.Service<Template>()("src/services/template...

FILE: apps/docs/app/(home)/BlockSection.tsx
  function BlocksSection (line 6) | function BlocksSection() {

FILE: apps/docs/app/(home)/ComponentsGrid.tsx
  function ComponentsGrid (line 38) | function ComponentsGrid() {

FILE: apps/docs/app/(home)/TemplatesSection.tsx
  function TemplatesSection (line 6) | function TemplatesSection() {

FILE: apps/docs/app/(home)/layout.tsx
  function Layout (line 15) | function Layout({ children }: { children: ReactNode }) {

FILE: apps/docs/app/(home)/page.tsx
  function HomePage (line 8) | function HomePage() {

FILE: apps/docs/app/docs/[[...slug]]/page.tsx
  function Page (line 12) | async function Page(props: { params: Promise<{ slug?: string[] }> }) {
  function NeighbourButtons (line 64) | function NeighbourButtons({ url }: { url: string }) {
  function Footer (line 93) | function Footer({ url }: { url: string }) {
  function TableOfContentFooter (line 169) | function TableOfContentFooter() {
  function generateStaticParams (line 190) | async function generateStaticParams() {
  function generateMetadata (line 194) | async function generateMetadata(props: { params: Promise<{ slug?: string...

FILE: apps/docs/app/docs/layout.tsx
  constant SIDEBAR_PROPS (line 7) | const SIDEBAR_PROPS = { className: '[&>div]:pt-3' };
  function Layout (line 9) | function Layout({ children }: { children: ReactNode }) {

FILE: apps/docs/app/layout.tsx
  constant SEARCH_OPTIONS (line 22) | const SEARCH_OPTIONS = {
  function Layout (line 31) | function Layout({ children }: React.PropsWithChildren) {

FILE: apps/docs/app/og/route.tsx
  function loadGoogleFont (line 3) | async function loadGoogleFont(weight: string, text: string) {
  function GET (line 20) | async function GET(request: Request) {

FILE: apps/docs/app/showcase/links/[[...slug]]/page.tsx
  function Page (line 3) | async function Page() {

FILE: apps/docs/app/showcase/privacy-policy/page.tsx
  function Page (line 1) | function Page() {

FILE: apps/docs/app/showcase/support/page.tsx
  function Page (line 1) | function Page() {

FILE: apps/docs/components/app-store-button.tsx
  function AppStoreButton (line 1) | function AppStoreButton() {

FILE: apps/docs/components/auth-block-tabs.tsx
  function AuthBlockTabs (line 10) | function AuthBlockTabs({ children }: React.PropsWithChildren) {
  type AuthIntegration (line 28) | type AuthIntegration = 'none' | 'clerk';
  type ContentProps (line 30) | type ContentProps = {
  function AuthBlockTabsCliContent (line 35) | function AuthBlockTabsCliContent({ children, integration: integrationPro...
  function AuthBlockTabsManualContent (line 44) | function AuthBlockTabsManualContent({

FILE: apps/docs/components/auth-integration-select.tsx
  constant INTEGRATIONS (line 15) | const INTEGRATIONS = [
  type Integration (line 20) | type Integration = (typeof INTEGRATIONS)[number]['name'];
  function AuthIntegrationSelect (line 22) | function AuthIntegrationSelect({
  function useAuthIntegration (line 62) | function useAuthIntegration() {
  function preventDefault (line 73) | function preventDefault(e: Event) {

FILE: apps/docs/components/blocks-grid.tsx
  constant BLOCKS (line 4) | const BLOCKS = [
  function BlocksGrid (line 14) | function BlocksGrid() {

FILE: apps/docs/components/callout.tsx
  constant ICONS (line 4) | const ICONS = {
  type CalloutProps (line 11) | type CalloutProps = Omit<React.ComponentProps<'div'>, 'title' | 'type' |...
  function Callout (line 19) | function Callout({ className, children, title, type, ...props }: Callout...

FILE: apps/docs/components/clerk-logo.tsx
  function ClerkLogo (line 3) | function ClerkLogo({ className, ...props }: React.SVGProps<SVGSVGElement...

FILE: apps/docs/components/command-tabs.tsx
  constant MANAGERS (line 4) | const MANAGERS = ['npm', 'bun', 'pnpm', 'yarn', 'yarn@berry'] as const;
  constant COMMAND (line 6) | const COMMAND: Record<(typeof MANAGERS)[number], string[]> = {
  function CommandTabs (line 14) | function CommandTabs({ args }: { args: string[] }) {

FILE: apps/docs/components/cookies-provider.tsx
  function CookiesProvider (line 5) | function CookiesProvider({ children }: { children: React.ReactNode }) {

FILE: apps/docs/components/copy-button.tsx
  function CopyButton (line 12) | function CopyButton({
  function useCopyButton (line 45) | function useCopyButton(onCopy: () => void): [checked: boolean, onClick: ...

FILE: apps/docs/components/download-app-banner.tsx
  function DownloadAppBanner (line 6) | function DownloadAppBanner({

FILE: apps/docs/components/external-links.tsx
  type ExternalLinksProps (line 3) | type ExternalLinksProps = {
  function ExternalLinks (line 10) | function ExternalLinks(props: ExternalLinksProps) {

FILE: apps/docs/components/icons/rnr-icon.tsx
  function RnrIcon (line 3) | function RnrIcon({

FILE: apps/docs/components/installation-tabs.tsx
  function InstallationTabs (line 11) | function InstallationTabs({
  function onRef (line 33) | function onRef(value: 'cli' | 'manual') {

FILE: apps/docs/components/link-tabs.tsx
  function LinkTabs (line 9) | function LinkTabs({
  function LinkTabsList (line 27) | function LinkTabsList({ className, ...props }: React.ComponentProps<type...
  function LinkTabsTrigger (line 39) | function LinkTabsTrigger({ className, ...props }: React.ComponentProps<t...
  function LinkTabsContent (line 53) | function LinkTabsContent({

FILE: apps/docs/components/platform-select.tsx
  constant PLATFORMS (line 15) | const PLATFORMS = [
  type Platform (line 20) | type Platform = (typeof PLATFORMS)[number]['name'];
  function PlatformSelect (line 22) | function PlatformSelect(props: SelectProps) {
  function usePlatform (line 59) | function usePlatform() {
  function preventDefault (line 69) | function preventDefault(e: Event) {

FILE: apps/docs/components/play-store-button.tsx
  function PlayStoreButton (line 3) | function PlayStoreButton() {

FILE: apps/docs/components/portal-info-alert.tsx
  function PortalInfoAlert (line 4) | function PortalInfoAlert() {

FILE: apps/docs/components/preview-card.tsx
  type PreviewCardProps (line 9) | type PreviewCardProps = {
  function PreviewCard (line 13) | function PreviewCard({ preview }: PreviewCardProps) {
  function BlockPreviewCard (line 60) | function BlockPreviewCard({ preview }: PreviewCardProps) {
  type WindowSize (line 70) | type WindowSize = {
  function useWindowSize (line 75) | function useWindowSize(): WindowSize {
  function useIsDarkMode (line 98) | function useIsDarkMode(): boolean {

FILE: apps/docs/components/skip-navigation-button.tsx
  function SkipNavigationButton (line 3) | function SkipNavigationButton() {

FILE: apps/docs/components/styling-library-tabs.tsx
  function StylingLibraryTabs (line 7) | function StylingLibraryTabs({ children }: React.PropsWithChildren) {
  function StylingLibraryTabsNativewindContent (line 26) | function StylingLibraryTabsNativewindContent({ children }: React.PropsWi...
  function StylingLibraryTabsUnwindContent (line 35) | function StylingLibraryTabsUnwindContent({ children }: React.PropsWithCh...

FILE: apps/docs/components/ui/badge.tsx
  type BadgeProps (line 25) | interface BadgeProps
  function Badge (line 29) | function Badge({

FILE: apps/docs/components/ui/button.tsx
  type ButtonProps (line 35) | interface ButtonProps

FILE: apps/docs/components/ui/tabs.tsx
  function Tabs (line 8) | function Tabs({ className, ...props }: React.ComponentProps<typeof TabsP...
  function TabsList (line 18) | function TabsList({ className, ...props }: React.ComponentProps<typeof T...
  function TabsTrigger (line 31) | function TabsTrigger({ className, ...props }: React.ComponentProps<typeo...
  function TabsContent (line 44) | function TabsContent({ className, ...props }: React.ComponentProps<typeo...

FILE: apps/docs/components/use-styling-library.ts
  function useStylingLibrary (line 3) | function useStylingLibrary() {

FILE: apps/docs/components/vercel-oss-badge.tsx
  function VercelOssBadge (line 3) | function VercelOssBadge() {

FILE: apps/docs/lib/FoundedLabsIcon.tsx
  function FoundedLabsIcon (line 1) | function FoundedLabsIcon() {

FILE: apps/docs/lib/file-generator.ts
  function fileGenerator (line 30) | function fileGenerator(): DocGenerator {
  function fixImports (line 58) | function fixImports(value: string) {

FILE: apps/docs/lib/source.ts
  method icon (line 11) | icon(icon) {

FILE: apps/docs/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: apps/docs/next.config.mjs
  method redirects (line 51) | async redirects() {
  function withExpo (line 75) | function withExpo(nextConfig) {

FILE: apps/showcase/app.config.ts
  function getConfig (line 95) | function getConfig() {

FILE: apps/showcase/app/+html.tsx
  function Root (line 8) | function Root({ children }: PropsWithChildren) {

FILE: apps/showcase/app/+not-found.tsx
  function NotFoundScreen (line 5) | function NotFoundScreen() {

FILE: apps/showcase/app/_layout.tsx
  function RootLayout (line 30) | function RootLayout() {
  function toOptions (line 81) | function toOptions(name: string) {

FILE: apps/showcase/app/components/accordion.tsx
  function AccordionScreen (line 4) | function AccordionScreen() {

FILE: apps/showcase/app/components/alert-dialog.tsx
  function AlertDialogScreen (line 4) | function AlertDialogScreen() {

FILE: apps/showcase/app/components/alert.tsx
  function AlertScreen (line 4) | function AlertScreen() {

FILE: apps/showcase/app/components/aspect-ratio.tsx
  function AspectRatioScreen (line 4) | function AspectRatioScreen() {

FILE: apps/showcase/app/components/avatar.tsx
  function AvatarScreen (line 4) | function AvatarScreen() {

FILE: apps/showcase/app/components/badge.tsx
  function BadgeScreen (line 4) | function BadgeScreen() {

FILE: apps/showcase/app/components/button.tsx
  function ButtonScreen (line 27) | function ButtonScreen() {

FILE: apps/showcase/app/components/card.tsx
  function CardScreen (line 4) | function CardScreen() {

FILE: apps/showcase/app/components/checkbox.tsx
  function CheckboxScreen (line 5) | function CheckboxScreen() {

FILE: apps/showcase/app/components/collapsible.tsx
  function CollapsibleScreen (line 5) | function CollapsibleScreen() {

FILE: apps/showcase/app/components/context-menu.tsx
  function ContextScreen (line 5) | function ContextScreen() {

FILE: apps/showcase/app/components/dialog.tsx
  function DialogScreen (line 4) | function DialogScreen() {

FILE: apps/showcase/app/components/dropdown-menu.tsx
  function DropdownMenuScreen (line 5) | function DropdownMenuScreen() {

FILE: apps/showcase/app/components/hover-card.tsx
  function HoverCardScreen (line 5) | function HoverCardScreen() {

FILE: apps/showcase/app/components/input.tsx
  function InputScreen (line 6) | function InputScreen() {

FILE: apps/showcase/app/components/label.tsx
  function LabelScreen (line 5) | function LabelScreen() {

FILE: apps/showcase/app/components/menubar.tsx
  function MenubarScreen (line 5) | function MenubarScreen() {

FILE: apps/showcase/app/components/popover.tsx
  function PopoverScreen (line 5) | function PopoverScreen() {

FILE: apps/showcase/app/components/progress.tsx
  function ProgressScreen (line 5) | function ProgressScreen() {

FILE: apps/showcase/app/components/radio-group.tsx
  function RadioGroupScreen (line 5) | function RadioGroupScreen() {

FILE: apps/showcase/app/components/select.tsx
  function SelectScreen (line 10) | function SelectScreen() {

FILE: apps/showcase/app/components/separator.tsx
  function SeparatorScreen (line 4) | function SeparatorScreen() {

FILE: apps/showcase/app/components/skeleton.tsx
  function SkeletonScreen (line 4) | function SkeletonScreen() {

FILE: apps/showcase/app/components/switch.tsx
  function SwitchScreen (line 5) | function SwitchScreen() {

FILE: apps/showcase/app/components/tabs.tsx
  function TabsScreen (line 4) | function TabsScreen() {

FILE: apps/showcase/app/components/text.tsx
  function TextScreen (line 10) | function TextScreen() {

FILE: apps/showcase/app/components/textarea.tsx
  function InputScreen (line 5) | function InputScreen() {

FILE: apps/showcase/app/components/toggle-group.tsx
  function ToggleGroupScreen (line 4) | function ToggleGroupScreen() {

FILE: apps/showcase/app/components/toggle.tsx
  function ToggleScreen (line 4) | function ToggleScreen() {

FILE: apps/showcase/app/components/tooltip.tsx
  function TooltipScreen (line 5) | function TooltipScreen() {

FILE: apps/showcase/app/index.tsx
  function ComponentsScreen (line 19) | function ComponentsScreen() {

FILE: apps/showcase/app/showcase/links/[slug].tsx
  function Screen (line 4) | function Screen() {
  function getIsComponent (line 26) | function getIsComponent(slug: string) {

FILE: apps/showcase/components/header-right-view.tsx
  function HeaderRightView (line 8) | function HeaderRightView() {

FILE: apps/showcase/components/preview-carousel.tsx
  type PreviewCarouselProps (line 18) | type PreviewCarouselProps = {
  function PreviewCarousel (line 23) | function PreviewCarousel({ previews, removeBottomSafeArea = false }: Pre...
  function renderItem (line 78) | function renderItem({
  function keyExtractor (line 89) | function keyExtractor(item: { name: string }) {

FILE: apps/showcase/components/theme-toggle.tsx
  constant THEME_TOGGLE_IMAGES (line 6) | const THEME_TOGGLE_IMAGES = {
  constant IMAGE_STYLE (line 11) | const IMAGE_STYLE: ImageStyle = {
  function ThemeToggle (line 16) | function ThemeToggle() {

FILE: apps/showcase/hooks/use-geist-font.tsx
  function useGeistFont (line 12) | function useGeistFont() {

FILE: apps/showcase/index.js
  function App (line 5) | function App() {

FILE: apps/showcase/lib/constants.ts
  constant COMPONENTS (line 1) | const COMPONENTS = [

FILE: apps/showcase/lib/theme.ts
  constant THEME (line 3) | const THEME = {
  constant NAV_THEME (line 58) | const NAV_THEME: Record<'light' | 'dark', Theme> = {

FILE: apps/showcase/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: packages/registry/src/blocks/clerk/forgot-password-form.tsx
  function ForgotPasswordForm (line 16) | function ForgotPasswordForm() {

FILE: packages/registry/src/blocks/clerk/reset-password-form.tsx
  function ResetPasswordForm (line 16) | function ResetPasswordForm() {

FILE: packages/registry/src/blocks/clerk/sign-in-form.tsx
  function SignInForm (line 18) | function SignInForm() {

FILE: packages/registry/src/blocks/clerk/sign-up-form.tsx
  function SignUpForm (line 18) | function SignUpForm() {

FILE: packages/registry/src/blocks/clerk/social-connections.tsx
  type SocialConnectionStrategy (line 12) | type SocialConnectionStrategy = Extract<
  constant SOCIAL_CONNECTION_STRATEGIES (line 17) | const SOCIAL_CONNECTION_STRATEGIES: {
  function SocialConnections (line 39) | function SocialConnections() {

FILE: packages/registry/src/blocks/clerk/user-menu.tsx
  function UserMenu (line 16) | function UserMenu() {
  function UserAvatar (line 84) | function UserAvatar(props: Omit<React.ComponentProps<typeof Avatar>, 'al...

FILE: packages/registry/src/blocks/clerk/verify-email-form.tsx
  constant RESEND_CODE_INTERVAL_SECONDS (line 16) | const RESEND_CODE_INTERVAL_SECONDS = 30;
  constant TABULAR_NUMBERS_STYLE (line 18) | const TABULAR_NUMBERS_STYLE: TextStyle = { fontVariant: ['tabular-nums'] };
  function VerifyEmailForm (line 20) | function VerifyEmailForm() {
  function useCountdown (line 129) | function useCountdown(seconds = 30) {

FILE: packages/registry/src/blocks/forgot-password-form.tsx
  function ForgotPasswordForm (line 14) | function ForgotPasswordForm() {

FILE: packages/registry/src/blocks/reset-password-form.tsx
  function ResetPasswordForm (line 15) | function ResetPasswordForm() {

FILE: packages/registry/src/blocks/sign-in-form.tsx
  function SignInForm (line 17) | function SignInForm() {

FILE: packages/registry/src/blocks/sign-up-form.tsx
  function SignUpForm (line 17) | function SignUpForm() {

FILE: packages/registry/src/blocks/social-connections.tsx
  constant SOCIAL_CONNECTION_STRATEGIES (line 6) | const SOCIAL_CONNECTION_STRATEGIES = [
  function SocialConnections (line 24) | function SocialConnections() {

FILE: packages/registry/src/blocks/user-menu.tsx
  constant USER (line 16) | const USER = {
  function UserMenu (line 23) | function UserMenu() {
  function UserAvatar (line 86) | function UserAvatar({ className, ...props }: Omit<React.ComponentProps<t...

FILE: packages/registry/src/blocks/verify-email-form.tsx
  constant RESEND_CODE_INTERVAL_SECONDS (line 15) | const RESEND_CODE_INTERVAL_SECONDS = 30;
  constant TABULAR_NUMBERS_STYLE (line 17) | const TABULAR_NUMBERS_STYLE: TextStyle = { fontVariant: ['tabular-nums'] };
  function VerifyEmailForm (line 19) | function VerifyEmailForm() {
  function useCountdown (line 86) | function useCountdown(seconds = 30) {

FILE: packages/registry/src/examples/accordion.tsx
  function AccordionPreview (line 9) | function AccordionPreview() {

FILE: packages/registry/src/examples/alert-dialog.tsx
  function AlertDialogPreview (line 15) | function AlertDialogPreview() {

FILE: packages/registry/src/examples/alert.tsx
  function AlertPreview (line 6) | function AlertPreview() {

FILE: packages/registry/src/examples/aspect-ratio.tsx
  function AspectRatioPreview (line 4) | function AspectRatioPreview() {

FILE: packages/registry/src/examples/avatar.tsx
  function AvatarPreview (line 5) | function AvatarPreview() {

FILE: packages/registry/src/examples/badge.tsx
  function BadgePreview (line 7) | function BadgePreview() {

FILE: packages/registry/src/examples/button/button-destructive.tsx
  function ButtonDestructivePreview (line 4) | function ButtonDestructivePreview() {

FILE: packages/registry/src/examples/button/button-ghost.tsx
  function ButtonGhostPreview (line 4) | function ButtonGhostPreview() {

FILE: packages/registry/src/examples/button/button-icon.tsx
  function ButtonIconPreview (line 5) | function ButtonIconPreview() {

FILE: packages/registry/src/examples/button/button-link.tsx
  function ButtonLinkPreview (line 4) | function ButtonLinkPreview() {

FILE: packages/registry/src/examples/button/button-loading.tsx
  function ButtonLoadingPreview (line 7) | function ButtonLoadingPreview() {

FILE: packages/registry/src/examples/button/button-outline.tsx
  function ButtonOutlinePreview (line 4) | function ButtonOutlinePreview() {

FILE: packages/registry/src/examples/button/button-primary.tsx
  function ButtonPreview (line 4) | function ButtonPreview() {

FILE: packages/registry/src/examples/button/button-secondary.tsx
  function ButtonSecondaryPreview (line 4) | function ButtonSecondaryPreview() {

FILE: packages/registry/src/examples/button/button-with-icon.tsx
  function ButtonWithIconPreview (line 6) | function ButtonWithIconPreview() {

FILE: packages/registry/src/examples/card.tsx
  function CardPreview (line 15) | function CardPreview() {

FILE: packages/registry/src/examples/checkbox.tsx
  function CheckboxPreview (line 9) | function CheckboxPreview() {

FILE: packages/registry/src/examples/collapsible.tsx
  function CollapsiblePreview (line 11) | function CollapsiblePreview() {

FILE: packages/registry/src/examples/context-menu.tsx
  function ContextMenuPreview (line 22) | function ContextMenuPreview() {

FILE: packages/registry/src/examples/dialog.tsx
  function DialogPreview (line 17) | function DialogPreview() {

FILE: packages/registry/src/examples/dropdown-menu.tsx
  function DropdownMenuPreview (line 18) | function DropdownMenuPreview() {

FILE: packages/registry/src/examples/hover-card.tsx
  function HoverCardPreview (line 12) | function HoverCardPreview() {

FILE: packages/registry/src/examples/input.tsx
  function InputPreview (line 3) | function InputPreview() {

FILE: packages/registry/src/examples/label.tsx
  function LabelPreview (line 7) | function LabelPreview() {

FILE: packages/registry/src/examples/menubar.tsx
  function MenubarPreview (line 21) | function MenubarPreview() {

FILE: packages/registry/src/examples/popover.tsx
  function PopoverPreview (line 12) | function PopoverPreview() {

FILE: packages/registry/src/examples/progress.tsx
  function ProgressPreview (line 4) | function ProgressPreview() {

FILE: packages/registry/src/examples/radio-group.tsx
  function RadioGroupPreview (line 7) | function RadioGroupPreview() {

FILE: packages/registry/src/examples/select/scrollable-select.tsx
  function ScrollableSelectPreview (line 38) | function ScrollableSelectPreview() {
  function NativeSelectScrollView (line 79) | function NativeSelectScrollView({ className, ...props }: React.Component...

FILE: packages/registry/src/examples/select/select.tsx
  function SelectPreview (line 23) | function SelectPreview() {

FILE: packages/registry/src/examples/separator.tsx
  function SeparatorPreview (line 5) | function SeparatorPreview() {

FILE: packages/registry/src/examples/skeleton.tsx
  function SkeletonPreview (line 4) | function SkeletonPreview() {

FILE: packages/registry/src/examples/switch.tsx
  function SwitchPreview (line 7) | function SwitchPreview() {

FILE: packages/registry/src/examples/tabs.tsx
  function TabsPreview (line 17) | function TabsPreview() {

FILE: packages/registry/src/examples/text/text-cascade.tsx
  function TextCascadePreview (line 4) | function TextCascadePreview() {
  function Parent (line 35) | function Parent({ children }: React.ComponentProps<typeof View>) {
  function NestedParent (line 44) | function NestedParent({ children }: React.ComponentProps<typeof View>) {

FILE: packages/registry/src/examples/text/text-typorgaphy.tsx
  function TextTypographyPreview (line 4) | function TextTypographyPreview() {

FILE: packages/registry/src/examples/text/text.tsx
  function TextPreview (line 3) | function TextPreview() {

FILE: packages/registry/src/examples/textarea.tsx
  function TextareaPreview (line 3) | function TextareaPreview() {

FILE: packages/registry/src/examples/toggle-group.tsx
  function ToggleGroupPreview (line 10) | function ToggleGroupPreview() {

FILE: packages/registry/src/examples/toggle.tsx
  function TogglePreview (line 6) | function TogglePreview() {

FILE: packages/registry/src/examples/tooltip.tsx
  function TooltipPreview (line 10) | function TooltipPreview() {

FILE: packages/registry/src/nativewind/components/ui/accordion.tsx
  function Accordion (line 16) | function Accordion({
  function AccordionItem (line 32) | function AccordionItem({
  function AccordionTrigger (line 59) | function AccordionTrigger({
  function AccordionContent (line 115) | function AccordionContent({

FILE: packages/registry/src/nativewind/components/ui/alert-dialog.tsx
  function AlertDialogOverlay (line 19) | function AlertDialogOverlay({
  function AlertDialogContent (line 48) | function AlertDialogContent({
  function AlertDialogHeader (line 74) | function AlertDialogHeader({ className, ...props }: ViewProps) {
  function AlertDialogFooter (line 82) | function AlertDialogFooter({ className, ...props }: ViewProps) {
  function AlertDialogTitle (line 91) | function AlertDialogTitle({
  function AlertDialogDescription (line 103) | function AlertDialogDescription({
  function AlertDialogAction (line 116) | function AlertDialogAction({
  function AlertDialogCancel (line 127) | function AlertDialogCancel({

FILE: packages/registry/src/nativewind/components/ui/alert.tsx
  function Alert (line 8) | function Alert({
  function AlertTitle (line 47) | function AlertTitle({
  function AlertDescription (line 59) | function AlertDescription({

FILE: packages/registry/src/nativewind/components/ui/avatar.tsx
  function Avatar (line 4) | function Avatar({
  function AvatarImage (line 16) | function AvatarImage({
  function AvatarFallback (line 23) | function AvatarFallback({

FILE: packages/registry/src/nativewind/components/ui/badge.tsx
  type BadgeProps (line 52) | type BadgeProps = ViewProps &
  function Badge (line 57) | function Badge({ className, variant, asChild, ...props }: BadgeProps) {

FILE: packages/registry/src/nativewind/components/ui/button.tsx
  type ButtonProps (line 91) | type ButtonProps = React.ComponentProps<typeof Pressable> &
  function Button (line 95) | function Button({ className, variant, size, ...props }: ButtonProps) {

FILE: packages/registry/src/nativewind/components/ui/card.tsx
  function Card (line 5) | function Card({ className, ...props }: ViewProps & React.RefAttributes<V...
  function CardHeader (line 19) | function CardHeader({ className, ...props }: ViewProps & React.RefAttrib...
  function CardTitle (line 23) | function CardTitle({
  function CardDescription (line 37) | function CardDescription({
  function CardContent (line 44) | function CardContent({ className, ...props }: ViewProps & React.RefAttri...
  function CardFooter (line 48) | function CardFooter({ className, ...props }: ViewProps & React.RefAttrib...

FILE: packages/registry/src/nativewind/components/ui/checkbox.tsx
  constant DEFAULT_HIT_SLOP (line 7) | const DEFAULT_HIT_SLOP = 24;
  function Checkbox (line 9) | function Checkbox({

FILE: packages/registry/src/nativewind/components/ui/context-menu.tsx
  function ContextMenuSubTrigger (line 26) | function ContextMenuSubTrigger({
  function ContextMenuSubContent (line 64) | function ContextMenuSubContent({
  function ContextMenuContent (line 86) | function ContextMenuContent({
  function ContextMenuItem (line 136) | function ContextMenuItem({
  function ContextMenuCheckboxItem (line 173) | function ContextMenuCheckboxItem({
  function ContextMenuRadioItem (line 210) | function ContextMenuRadioItem({
  function ContextMenuLabel (line 241) | function ContextMenuLabel({
  function ContextMenuSeparator (line 262) | function ContextMenuSeparator({
  function ContextMenuShortcut (line 274) | function ContextMenuShortcut({ className, ...props }: TextProps & React....

FILE: packages/registry/src/nativewind/components/ui/dialog.tsx
  function DialogOverlay (line 21) | function DialogOverlay({
  function DialogContent (line 50) | function DialogContent({
  function DialogHeader (line 92) | function DialogHeader({ className, ...props }: ViewProps) {
  function DialogFooter (line 98) | function DialogFooter({ className, ...props }: ViewProps) {
  function DialogTitle (line 107) | function DialogTitle({
  function DialogDescription (line 119) | function DialogDescription({

FILE: packages/registry/src/nativewind/components/ui/dropdown-menu.tsx
  function DropdownMenuSubTrigger (line 32) | function DropdownMenuSubTrigger({
  function DropdownMenuSubContent (line 70) | function DropdownMenuSubContent({
  function DropdownMenuContent (line 93) | function DropdownMenuContent({
  function DropdownMenuItem (line 143) | function DropdownMenuItem({
  function DropdownMenuCheckboxItem (line 180) | function DropdownMenuCheckboxItem({
  function DropdownMenuRadioItem (line 217) | function DropdownMenuRadioItem({
  function DropdownMenuLabel (line 248) | function DropdownMenuLabel({
  function DropdownMenuSeparator (line 269) | function DropdownMenuSeparator({
  function DropdownMenuShortcut (line 281) | function DropdownMenuShortcut({ className, ...props }: TextProps & React...

FILE: packages/registry/src/nativewind/components/ui/hover-card.tsx
  function HoverCardContent (line 16) | function HoverCardContent({

FILE: packages/registry/src/nativewind/components/ui/icon.tsx
  type IconProps (line 7) | type IconProps = LucideProps & {
  function IconImpl (line 11) | function IconImpl({ as: IconComponent, ...props }: IconProps) {
  function Icon (line 45) | function Icon({ as: IconComponent, className, size = 14, ...props }: Ico...

FILE: packages/registry/src/nativewind/components/ui/input.tsx
  function Input (line 4) | function Input({ className, ...props }: TextInputProps & React.RefAttrib...

FILE: packages/registry/src/nativewind/components/ui/label.tsx
  function Label (line 5) | function Label({

FILE: packages/registry/src/nativewind/components/ui/menubar.tsx
  function Menubar (line 34) | function Menubar({
  function MenubarTrigger (line 71) | function MenubarTrigger({
  function MenubarSubTrigger (line 99) | function MenubarSubTrigger({
  function MenubarSubContent (line 137) | function MenubarSubContent({
  function MenubarContent (line 157) | function MenubarContent({
  function MenubarItem (line 200) | function MenubarItem({
  function MenubarCheckboxItem (line 237) | function MenubarCheckboxItem({
  function MenubarRadioItem (line 274) | function MenubarRadioItem({
  function MenubarLabel (line 305) | function MenubarLabel({
  function MenubarSeparator (line 326) | function MenubarSeparator({
  function MenubarShortcut (line 335) | function MenubarShortcut({ className, ...props }: TextProps & React.RefA...

FILE: packages/registry/src/nativewind/components/ui/native-only-animated-view.tsx
  function NativeOnlyAnimatedView (line 13) | function NativeOnlyAnimatedView(

FILE: packages/registry/src/nativewind/components/ui/popover.tsx
  function PopoverContent (line 16) | function PopoverContent({

FILE: packages/registry/src/nativewind/components/ui/progress.tsx
  function Progress (line 12) | function Progress({
  type IndicatorProps (line 38) | type IndicatorProps = {
  function WebIndicator (line 43) | function WebIndicator({ value, className }: IndicatorProps) {
  function NativeIndicator (line 57) | function NativeIndicator({ value, className }: IndicatorProps) {
  function NullIndicator (line 80) | function NullIndicator(_props: IndicatorProps) {

FILE: packages/registry/src/nativewind/components/ui/radio-group.tsx
  function RadioGroup (line 5) | function RadioGroup({
  function RadioGroupItem (line 12) | function RadioGroupItem({

FILE: packages/registry/src/nativewind/components/ui/select.tsx
  type Option (line 12) | type Option = SelectPrimitive.Option;
  function SelectValue (line 18) | function SelectValue({
  function SelectTrigger (line 40) | function SelectTrigger({
  function SelectContent (line 72) | function SelectContent({
  function SelectLabel (line 135) | function SelectLabel({
  function SelectItem (line 147) | function SelectItem({
  function SelectSeparator (line 173) | function SelectSeparator({
  function SelectScrollUpButton (line 193) | function SelectScrollUpButton({
  function SelectScrollDownButton (line 213) | function SelectScrollDownButton({

FILE: packages/registry/src/nativewind/components/ui/separator.tsx
  function Separator (line 4) | function Separator({

FILE: packages/registry/src/nativewind/components/ui/skeleton.tsx
  function Skeleton (line 4) | function Skeleton({

FILE: packages/registry/src/nativewind/components/ui/switch.tsx
  function Switch (line 5) | function Switch({

FILE: packages/registry/src/nativewind/components/ui/tabs.tsx
  function Tabs (line 6) | function Tabs({
  function TabsList (line 13) | function TabsList({
  function TabsTrigger (line 29) | function TabsTrigger({
  function TabsContent (line 56) | function TabsContent({

FILE: packages/registry/src/nativewind/components/ui/text.tsx
  type TextVariantProps (line 45) | type TextVariantProps = VariantProps<typeof textVariants>;
  type TextVariant (line 47) | type TextVariant = NonNullable<TextVariantProps['variant']>;
  constant ROLE (line 49) | const ROLE: Partial<Record<TextVariant, Role>> = {
  constant ARIA_LEVEL (line 58) | const ARIA_LEVEL: Partial<Record<TextVariant, string>> = {
  function Text (line 67) | function Text({

FILE: packages/registry/src/nativewind/components/ui/textarea.tsx
  function Textarea (line 4) | function Textarea({

FILE: packages/registry/src/nativewind/components/ui/toggle-group.tsx
  function ToggleGroup (line 12) | function ToggleGroup({
  function useToggleGroupContext (line 37) | function useToggleGroupContext() {
  function ToggleGroupItem (line 47) | function ToggleGroupItem({
  function ToggleGroupIcon (line 97) | function ToggleGroupIcon({ className, ...props }: React.ComponentProps<t...

FILE: packages/registry/src/nativewind/components/ui/toggle.tsx
  function Toggle (line 40) | function Toggle({
  function ToggleIcon (line 70) | function ToggleIcon({ className, ...props }: React.ComponentProps<typeof...

FILE: packages/registry/src/nativewind/components/ui/tooltip.tsx
  function TooltipContent (line 16) | function TooltipContent({

FILE: packages/registry/src/nativewind/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: packages/registry/src/uniwind/components/ui/accordion.tsx
  function Accordion (line 16) | function Accordion({
  function AccordionItem (line 32) | function AccordionItem({
  function AccordionTrigger (line 59) | function AccordionTrigger({
  function AccordionContent (line 115) | function AccordionContent({

FILE: packages/registry/src/uniwind/components/ui/alert-dialog.tsx
  function AlertDialogOverlay (line 19) | function AlertDialogOverlay({
  function AlertDialogContent (line 48) | function AlertDialogContent({
  function AlertDialogHeader (line 74) | function AlertDialogHeader({ className, ...props }: ViewProps) {
  function AlertDialogFooter (line 82) | function AlertDialogFooter({ className, ...props }: ViewProps) {
  function AlertDialogTitle (line 91) | function AlertDialogTitle({
  function AlertDialogDescription (line 103) | function AlertDialogDescription({
  function AlertDialogAction (line 116) | function AlertDialogAction({
  function AlertDialogCancel (line 127) | function AlertDialogCancel({

FILE: packages/registry/src/uniwind/components/ui/alert.tsx
  function Alert (line 8) | function Alert({
  function AlertTitle (line 47) | function AlertTitle({
  function AlertDescription (line 59) | function AlertDescription({

FILE: packages/registry/src/uniwind/components/ui/avatar.tsx
  function Avatar (line 4) | function Avatar({
  function AvatarImage (line 16) | function AvatarImage({
  function AvatarFallback (line 23) | function AvatarFallback({

FILE: packages/registry/src/uniwind/components/ui/badge.tsx
  type BadgeProps (line 52) | type BadgeProps = ViewProps &
  function Badge (line 57) | function Badge({ className, variant, asChild, ...props }: BadgeProps) {

FILE: packages/registry/src/uniwind/components/ui/button.tsx
  type ButtonProps (line 93) | type ButtonProps = React.ComponentProps<typeof Pressable> &
  function Button (line 97) | function Button({ className, variant, size, ...props }: ButtonProps) {

FILE: packages/registry/src/uniwind/components/ui/card.tsx
  function Card (line 5) | function Card({ className, ...props }: ViewProps & React.RefAttributes<V...
  function CardHeader (line 19) | function CardHeader({ className, ...props }: ViewProps & React.RefAttrib...
  function CardTitle (line 23) | function CardTitle({
  function CardDescription (line 37) | function CardDescription({
  function CardContent (line 44) | function CardContent({ className, ...props }: ViewProps & React.RefAttri...
  function CardFooter (line 48) | function CardFooter({ className, ...props }: ViewProps & React.RefAttrib...

FILE: packages/registry/src/uniwind/components/ui/checkbox.tsx
  constant DEFAULT_HIT_SLOP (line 7) | const DEFAULT_HIT_SLOP = 24;
  function Checkbox (line 9) | function Checkbox({

FILE: packages/registry/src/uniwind/components/ui/context-menu.tsx
  function ContextMenuSubTrigger (line 26) | function ContextMenuSubTrigger({
  function ContextMenuSubContent (line 64) | function ContextMenuSubContent({
  function ContextMenuContent (line 86) | function ContextMenuContent({
  function ContextMenuItem (line 136) | function ContextMenuItem({
  function ContextMenuCheckboxItem (line 173) | function ContextMenuCheckboxItem({
  function ContextMenuRadioItem (line 210) | function ContextMenuRadioItem({
  function ContextMenuLabel (line 241) | function ContextMenuLabel({
  function ContextMenuSeparator (line 262) | function ContextMenuSeparator({
  function ContextMenuShortcut (line 274) | function ContextMenuShortcut({ className, ...props }: TextProps & React....

FILE: packages/registry/src/uniwind/components/ui/dialog.tsx
  function DialogOverlay (line 21) | function DialogOverlay({
  function DialogContent (line 50) | function DialogContent({
  function DialogHeader (line 92) | function DialogHeader({ className, ...props }: ViewProps) {
  function DialogFooter (line 98) | function DialogFooter({ className, ...props }: ViewProps) {
  function DialogTitle (line 107) | function DialogTitle({
  function DialogDescription (line 119) | function DialogDescription({

FILE: packages/registry/src/uniwind/components/ui/dropdown-menu.tsx
  function DropdownMenuSubTrigger (line 32) | function DropdownMenuSubTrigger({
  function DropdownMenuSubContent (line 70) | function DropdownMenuSubContent({
  function DropdownMenuContent (line 93) | function DropdownMenuContent({
  function DropdownMenuItem (line 143) | function DropdownMenuItem({
  function DropdownMenuCheckboxItem (line 180) | function DropdownMenuCheckboxItem({
  function DropdownMenuRadioItem (line 217) | function DropdownMenuRadioItem({
  function DropdownMenuLabel (line 248) | function DropdownMenuLabel({
  function DropdownMenuSeparator (line 269) | function DropdownMenuSeparator({
  function DropdownMenuShortcut (line 281) | function DropdownMenuShortcut({ className, ...props }: TextProps & React...

FILE: packages/registry/src/uniwind/components/ui/hover-card.tsx
  function HoverCardContent (line 16) | function HoverCardContent({

FILE: packages/registry/src/uniwind/components/ui/icon.tsx
  type IconProps (line 7) | type IconProps = LucideProps & {
  function IconImpl (line 11) | function IconImpl({ as: IconComponent, ...props }: IconProps) {
  function Icon (line 46) | function Icon({ as: IconComponent, className, ...props }: IconProps) {

FILE: packages/registry/src/uniwind/components/ui/input.tsx
  function Input (line 4) | function Input({

FILE: packages/registry/src/uniwind/components/ui/label.tsx
  function Label (line 5) | function Label({

FILE: packages/registry/src/uniwind/components/ui/menubar.tsx
  function Menubar (line 34) | function Menubar({
  function MenubarTrigger (line 71) | function MenubarTrigger({
  function MenubarSubTrigger (line 99) | function MenubarSubTrigger({
  function MenubarSubContent (line 137) | function MenubarSubContent({
  function MenubarContent (line 157) | function MenubarContent({
  function MenubarItem (line 204) | function MenubarItem({
  function MenubarCheckboxItem (line 241) | function MenubarCheckboxItem({
  function MenubarRadioItem (line 278) | function MenubarRadioItem({
  function MenubarLabel (line 309) | function MenubarLabel({
  function MenubarSeparator (line 330) | function MenubarSeparator({
  function MenubarShortcut (line 339) | function MenubarShortcut({ className, ...props }: TextProps & React.RefA...

FILE: packages/registry/src/uniwind/components/ui/native-only-animated-view.tsx
  function NativeOnlyAnimatedView (line 13) | function NativeOnlyAnimatedView(

FILE: packages/registry/src/uniwind/components/ui/popover.tsx
  function PopoverContent (line 16) | function PopoverContent({

FILE: packages/registry/src/uniwind/components/ui/progress.tsx
  function Progress (line 12) | function Progress({
  type IndicatorProps (line 38) | type IndicatorProps = {
  function WebIndicator (line 43) | function WebIndicator({ value, className }: IndicatorProps) {
  function NativeIndicator (line 57) | function NativeIndicator({ value, className }: IndicatorProps) {
  function NullIndicator (line 80) | function NullIndicator(_props: IndicatorProps) {

FILE: packages/registry/src/uniwind/components/ui/radio-group.tsx
  function RadioGroup (line 5) | function RadioGroup({
  function RadioGroupItem (line 12) | function RadioGroupItem({

FILE: packages/registry/src/uniwind/components/ui/select.tsx
  type Option (line 12) | type Option = SelectPrimitive.Option;
  function SelectValue (line 18) | function SelectValue({
  function SelectTrigger (line 40) | function SelectTrigger({
  function SelectContent (line 72) | function SelectContent({
  function SelectLabel (line 135) | function SelectLabel({
  function SelectItem (line 147) | function SelectItem({
  function SelectSeparator (line 172) | function SelectSeparator({
  function SelectScrollUpButton (line 192) | function SelectScrollUpButton({
  function SelectScrollDownButton (line 212) | function SelectScrollDownButton({

FILE: packages/registry/src/uniwind/components/ui/separator.tsx
  function Separator (line 4) | function Separator({

FILE: packages/registry/src/uniwind/components/ui/skeleton.tsx
  function Skeleton (line 13) | function Skeleton({

FILE: packages/registry/src/uniwind/components/ui/switch.tsx
  function Switch (line 5) | function Switch({

FILE: packages/registry/src/uniwind/components/ui/tabs.tsx
  function Tabs (line 6) | function Tabs({
  function TabsList (line 13) | function TabsList({
  function TabsTrigger (line 29) | function TabsTrigger({
  function TabsContent (line 56) | function TabsContent({

FILE: packages/registry/src/uniwind/components/ui/text.tsx
  type TextVariantProps (line 45) | type TextVariantProps = VariantProps<typeof textVariants>;
  type TextVariant (line 47) | type TextVariant = NonNullable<TextVariantProps['variant']>;
  constant ROLE (line 49) | const ROLE: Partial<Record<TextVariant, Role>> = {
  constant ARIA_LEVEL (line 58) | const ARIA_LEVEL: Partial<Record<TextVariant, string>> = {
  function Text (line 67) | function Text({

FILE: packages/registry/src/uniwind/components/ui/textarea.tsx
  function Textarea (line 4) | function Textarea({

FILE: packages/registry/src/uniwind/components/ui/toggle-group.tsx
  function ToggleGroup (line 12) | function ToggleGroup({
  function useToggleGroupContext (line 37) | function useToggleGroupContext() {
  function ToggleGroupItem (line 47) | function ToggleGroupItem({
  function ToggleGroupIcon (line 97) | function ToggleGroupIcon({ className, ...props }: React.ComponentProps<t...

FILE: packages/registry/src/uniwind/components/ui/toggle.tsx
  function Toggle (line 40) | function Toggle({
  function ToggleIcon (line 70) | function ToggleIcon({ className, ...props }: React.ComponentProps<typeof...

FILE: packages/registry/src/uniwind/components/ui/tooltip.tsx
  function TooltipContent (line 16) | function TooltipContent({

FILE: packages/registry/src/uniwind/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: packages/registry/uniwind-types.d.ts
  type UniwindConfig (line 5) | interface UniwindConfig {
Condensed preview — 452 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,293K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 21,
    "preview": "github: mrzachnugent\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1342,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: '[ BUG ]'\nlabels: bug\nassignees: ''\n---\n\n<!--\n\n⚠️ "
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 1193,
    "preview": "# Pull Request Template\n\n<!--\n\n⚠️ **Important**\n\n**If you want to propose a new feature:**\n\n1.  Make sure to read the [p"
  },
  {
    "path": ".gitignore",
    "chars": 623,
    "preview": "# Monorepo\napps/*/credentials.json\napps/*/build\npackages/*/build\n\n# Turborepo\n.turbo\n\n# Expo\n.expo\n__generated__\nweb-bui"
  },
  {
    "path": ".npmrc",
    "chars": 19,
    "preview": "node-linker=hoisted"
  },
  {
    "path": ".nvmrc",
    "chars": 5,
    "preview": "20.11"
  },
  {
    "path": ".prettierrc",
    "chars": 195,
    "preview": "{\n  \"printWidth\": 100,\n  \"tabWidth\": 2,\n  \"singleQuote\": true,\n  \"bracketSameLine\": true,\n  \"trailingComma\": \"es5\",\n  \"p"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5222,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "COMMUNITY_RESOURCES.md",
    "chars": 2770,
    "preview": "# Community Resources\n\nCommunity-created components, libraries, and templates that extend React Native Reusables and fil"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2678,
    "preview": "# Contributing to React Native Reusables\n\nThank you for your interest in contributing to `react-native-reusables`! We we"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2025 Founded Labs\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 745,
    "preview": "# React Native Reusables\n\nBringing [shadcn/ui](https://ui.shadcn.com) to React Native. Beautifully crafted components wi"
  },
  {
    "path": "SECURITY.md",
    "chars": 1700,
    "preview": "# Security Policy\n\n## Reporting a Security Issue\n\nIf you discover a security issue in this repository, please help us by"
  },
  {
    "path": "apps/cli/.changeset/config.json",
    "chars": 353,
    "preview": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@3.0.2/schema.json\",\n  \"changelog\": [\n    \"@changesets/changelog-git"
  },
  {
    "path": "apps/cli/.github/actions/setup/action.yml",
    "chars": 508,
    "preview": "name: Setup\ndescription: Perform standard setup and install dependencies using pnpm.\ninputs:\n  node-version:\n    descrip"
  },
  {
    "path": "apps/cli/.github/workflows/check.yml",
    "chars": 1064,
    "preview": "name: Check\n\non:\n  workflow_dispatch:\n  pull_request:\n    branches: [main]\n  push:\n    branches: [main]\n\nconcurrency:\n  "
  },
  {
    "path": "apps/cli/.github/workflows/release.yml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "apps/cli/.github/workflows/snapshot.yml",
    "chars": 541,
    "preview": "name: Snapshot\n\non:\n  pull_request:\n    branches: [main, next-minor, next-major]\n  workflow_dispatch:\n\npermissions: {}\n\n"
  },
  {
    "path": "apps/cli/.gitignore",
    "chars": 185,
    "preview": "coverage/\n*.tsbuildinfo\nnode_modules/\nyarn-error.log\n.ultra.cache.json\n.DS_Store\ntmp/\nbuild/\ndist/\n.direnv/\n.env\n.env.lo"
  },
  {
    "path": "apps/cli/.prettierrc",
    "chars": 136,
    "preview": "{\n  \"tabWidth\": 2,\n  \"printWidth\": 120,\n  \"semi\": false,\n  \"singleQuote\": false,\n  \"trailingComma\": \"none\",\n  \"arrowPare"
  },
  {
    "path": "apps/cli/.vscode/extensions.json",
    "chars": 95,
    "preview": "{\n  \"recommendations\": [\n    \"effectful-tech.effect-vscode\",\n    \"dbaeumer.vscode-eslint\"\n  ]\n}"
  },
  {
    "path": "apps/cli/.vscode/settings.json",
    "chars": 1456,
    "preview": "{\n  \"typescript.tsdk\": \"node_modules/typescript/lib\",\n  \"typescript.preferences.importModuleSpecifier\": \"relative\",\n  \"t"
  },
  {
    "path": "apps/cli/LICENSE",
    "chars": 1077,
    "preview": "MIT License\n\nCopyright (c) 2024-present Founded Labs\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "apps/cli/README.md",
    "chars": 3858,
    "preview": "# React Native Reusables CLI\n\nA command-line toolkit to streamline the integration, setup, and maintenance of reusable R"
  },
  {
    "path": "apps/cli/eslint.config.mjs",
    "chars": 3454,
    "preview": "import { fixupPluginRules } from \"@eslint/compat\"\nimport { FlatCompat } from \"@eslint/eslintrc\"\nimport js from \"@eslint/"
  },
  {
    "path": "apps/cli/package.json",
    "chars": 2465,
    "preview": "{\n  \"name\": \"@react-native-reusables/cli\",\n  \"version\": \"0.7.1\",\n  \"type\": \"module\",\n  \"license\": \"MIT\",\n  \"description\""
  },
  {
    "path": "apps/cli/patches/@changesets__get-github-info@0.6.0.patch",
    "chars": 1890,
    "preview": "diff --git a/dist/changesets-get-github-info.cjs.js b/dist/changesets-get-github-info.cjs.js\nindex a74df59f8a5988f458a34"
  },
  {
    "path": "apps/cli/scripts/copy-package-json.ts",
    "chars": 1090,
    "preview": "import { FileSystem, Path } from \"@effect/platform\"\nimport { NodeContext } from \"@effect/platform-node\"\nimport { Effect "
  },
  {
    "path": "apps/cli/src/bin.ts",
    "chars": 532,
    "preview": "#!/usr/bin/env node\n\nimport * as NodeContext from \"@effect/platform-node/NodeContext\"\nimport * as NodeRuntime from \"@eff"
  },
  {
    "path": "apps/cli/src/cli.ts",
    "chars": 2531,
    "preview": "import { all, cwd, overwrite, path, stylingLibrary, summary, template, yes } from \"@cli/contexts/cli-options.js\"\nimport "
  },
  {
    "path": "apps/cli/src/contexts/cli-options.ts",
    "chars": 1214,
    "preview": "import { Options } from \"@effect/cli\"\nimport { Context, Option } from \"effect\"\n\ntype StylingLibrary = \"nativewind\" | \"un"
  },
  {
    "path": "apps/cli/src/project-manifest.ts",
    "chars": 11061,
    "preview": "interface FileCheck {\n  name: string\n  fileNames: Array<string>\n  docs: string\n  includes: Array<{\n    content: Array<st"
  },
  {
    "path": "apps/cli/src/services/commands/add.ts",
    "chars": 3998,
    "preview": "import { CliOptions, type StylingLibrary } from \"@cli/contexts/cli-options.js\"\nimport { PROJECT_MANIFEST } from \"@cli/pr"
  },
  {
    "path": "apps/cli/src/services/commands/doctor.ts",
    "chars": 11251,
    "preview": "import { CliOptions } from \"@cli/contexts/cli-options.js\"\nimport { type CustomFileCheck, type FileCheck, type MissingInc"
  },
  {
    "path": "apps/cli/src/services/commands/init.ts",
    "chars": 3242,
    "preview": "import { CliOptions } from \"@cli/contexts/cli-options.js\"\nimport { PROJECT_MANIFEST } from \"@cli/project-manifest.js\"\nim"
  },
  {
    "path": "apps/cli/src/services/git.ts",
    "chars": 1121,
    "preview": "import { Data, Effect } from \"effect\"\nimport { Command } from \"@effect/platform\"\nimport { Prompt } from \"@effect/cli\"\nim"
  },
  {
    "path": "apps/cli/src/services/package-manager.ts",
    "chars": 1251,
    "preview": "import { Effect } from \"effect\"\nimport { detect } from \"package-manager-detector\"\n\nconst PACKAGE_MANAGERS = [\"npm\", \"bun"
  },
  {
    "path": "apps/cli/src/services/project-config.ts",
    "chars": 10359,
    "preview": "import { CliOptions } from \"@cli/contexts/cli-options.js\"\nimport { retryWith } from \"@cli/utils/retry-with.js\"\nimport { "
  },
  {
    "path": "apps/cli/src/services/required-files-checker.ts",
    "chars": 15839,
    "preview": "import { CliOptions } from \"@cli/contexts/cli-options.js\"\nimport type { CustomFileCheck, FileCheck, FileWithContent, Mis"
  },
  {
    "path": "apps/cli/src/services/spinner.ts",
    "chars": 331,
    "preview": "import { Effect } from \"effect\"\nimport ora from \"ora\"\n\nclass Spinner extends Effect.Service<Spinner>()(\"Spinner\", {\n  ef"
  },
  {
    "path": "apps/cli/src/services/template.ts",
    "chars": 8915,
    "preview": "import { runCommand } from \"@cli/utils/run-command.js\"\nimport { Prompt } from \"@effect/cli\"\nimport { FileSystem, Path } "
  },
  {
    "path": "apps/cli/src/utils/retry-with.ts",
    "chars": 294,
    "preview": "import { Effect } from \"effect\"\n\nconst retryWith = <A, R, E, B>(\n  fn: (input: A) => Effect.Effect<R, E, B>,\n  inputs: r"
  },
  {
    "path": "apps/cli/src/utils/run-command.ts",
    "chars": 362,
    "preview": "import { Effect } from \"effect\"\nimport { execa } from \"execa\"\n\nconst runCommand = (file: string, args: Array<string>, op"
  },
  {
    "path": "apps/cli/test/Dummy.test.ts",
    "chars": 145,
    "preview": "import { describe, expect, it } from \"@effect/vitest\"\n\ndescribe(\"Dummy\", () => {\n  it(\"should pass\", () => {\n    expect("
  },
  {
    "path": "apps/cli/tsconfig.base.json",
    "chars": 1248,
    "preview": "{\n  \"include\": [],\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"moduleDetection\": \"force\",\n    \"composite\": true,\n   "
  },
  {
    "path": "apps/cli/tsconfig.json",
    "chars": 207,
    "preview": "{\n  \"extends\": \"./tsconfig.base.json\",\n  \"references\": [\n    {\n      \"path\": \"tsconfig.src.json\"\n    },\n    {\n      \"pat"
  },
  {
    "path": "apps/cli/tsconfig.scripts.json",
    "chars": 305,
    "preview": "{\n  \"extends\": \"./tsconfig.base.json\",\n  \"include\": [\n    \"scripts\",\n    \"eslint.config.mjs\",\n    \"tsup.config.ts\",\n    "
  },
  {
    "path": "apps/cli/tsconfig.src.json",
    "chars": 209,
    "preview": "{\n  \"extends\": \"./tsconfig.base.json\",\n  \"include\": [\"src\"],\n  \"compilerOptions\": {\n    \"types\": [\"node\"],\n    \"tsBuildI"
  },
  {
    "path": "apps/cli/tsconfig.test.json",
    "chars": 212,
    "preview": "{\n  \"extends\": \"./tsconfig.base.json\",\n  \"include\": [\"test\"],\n  \"compilerOptions\": {\n    \"types\": [\"node\"],\n    \"tsBuild"
  },
  {
    "path": "apps/cli/tsup.config.ts",
    "chars": 186,
    "preview": "import { defineConfig } from \"tsup\"\n\nexport default defineConfig({\n  entry: [\"src/bin.ts\"],\n  clean: true,\n  publicDir: "
  },
  {
    "path": "apps/cli/vitest.config.ts",
    "chars": 239,
    "preview": "import { defineConfig } from \"vitest/config\"\n\nexport default defineConfig({\n  test: {\n    include: [\"./test/**/*.test.{j"
  },
  {
    "path": "apps/docs/.eslintrc.json",
    "chars": 61,
    "preview": "{\n  \"extends\": [\"next/core-web-vitals\", \"next/typescript\"]\n}\n"
  },
  {
    "path": "apps/docs/.gitignore",
    "chars": 370,
    "preview": "# deps\n/node_modules\n\n# generated content\n.contentlayer\n.content-collections\n.source\n\n# test & build\n/coverage\n/.next/\n/"
  },
  {
    "path": "apps/docs/README.md",
    "chars": 590,
    "preview": "# docs\n\nThis is a Next.js application generated with\n[Create Fumadocs](https://github.com/fuma-nama/fumadocs).\n\nRun deve"
  },
  {
    "path": "apps/docs/app/(home)/BlockSection.tsx",
    "chars": 1620,
    "preview": "import { Badge } from '@docs/components/ui/badge';\nimport { Button } from '@docs/components/ui/button';\nimport { Heart }"
  },
  {
    "path": "apps/docs/app/(home)/ComponentsGrid.tsx",
    "chars": 6914,
    "preview": "'use client';\nimport {\n  AccordionPreview,\n  AlertDialogPreview,\n  AlertPreview,\n  AspectRatioPreview,\n  AvatarPreview,\n"
  },
  {
    "path": "apps/docs/app/(home)/TemplatesSection.tsx",
    "chars": 1252,
    "preview": "import { Badge } from '@docs/components/ui/badge';\nimport { Button } from '@docs/components/ui/button';\nimport { Battery"
  },
  {
    "path": "apps/docs/app/(home)/layout.tsx",
    "chars": 2491,
    "preview": "import { RnrIcon } from '@docs/components/icons/rnr-icon';\nimport { SkipNavigationButton } from '@docs/components/skip-n"
  },
  {
    "path": "apps/docs/app/(home)/page.tsx",
    "chars": 2396,
    "preview": "import { Badge } from '@docs/components/ui/badge';\nimport { Button } from '@docs/components/ui/button';\nimport { ArrowRi"
  },
  {
    "path": "apps/docs/app/api/search/route.ts",
    "chars": 157,
    "preview": "import { source } from '@docs/lib/source';\nimport { createFromSource } from 'fumadocs-core/search/server';\n\nexport const"
  },
  {
    "path": "apps/docs/app/docs/[[...slug]]/page.tsx",
    "chars": 7330,
    "preview": "import { Button } from '@docs/components/ui/button';\nimport { source } from '@docs/lib/source';\nimport { cn } from '@doc"
  },
  {
    "path": "apps/docs/app/docs/layout.tsx",
    "chars": 1055,
    "preview": "import { RnrIcon } from '@docs/components/icons/rnr-icon';\nimport { SkipNavigationButton } from '@docs/components/skip-n"
  },
  {
    "path": "apps/docs/app/global.css",
    "chars": 2460,
    "preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --f"
  },
  {
    "path": "apps/docs/app/layout.tsx",
    "chars": 1439,
    "preview": "import './global.css';\n\nimport { CookiesProvider } from '@docs/components/cookies-provider';\nimport { SafeAreaProvider }"
  },
  {
    "path": "apps/docs/app/og/route.tsx",
    "chars": 4137,
    "preview": "import { ImageResponse } from 'next/og';\n\nasync function loadGoogleFont(weight: string, text: string) {\n  const url = `h"
  },
  {
    "path": "apps/docs/app/showcase/links/[[...slug]]/page.tsx",
    "chars": 392,
    "preview": "import { DownloadAppBanner } from '@docs/components/download-app-banner';\n\nexport default async function Page() {\n  retu"
  },
  {
    "path": "apps/docs/app/showcase/privacy-policy/page.tsx",
    "chars": 1697,
    "preview": "export default function Page() {\n  return (\n    <div className=\"prose mx-auto max-w-3xl px-4 py-24\">\n      <h1>Privacy P"
  },
  {
    "path": "apps/docs/app/showcase/support/page.tsx",
    "chars": 1578,
    "preview": "export default function Page() {\n  return (\n    <div className=\"prose mx-auto max-w-3xl px-4 py-24\">\n      <h1>Support</"
  },
  {
    "path": "apps/docs/components/app-store-button.tsx",
    "chars": 11180,
    "preview": "export function AppStoreButton() {\n  return (\n    <a\n      target=\"_blank\"\n      href=\"https://apps.apple.com/ca/app/rea"
  },
  {
    "path": "apps/docs/components/auth-block-tabs.tsx",
    "chars": 1415,
    "preview": "'use client';\n\nimport {\n  AuthIntegrationSelect,\n  useAuthIntegration,\n} from '@docs/components/auth-integration-select'"
  },
  {
    "path": "apps/docs/components/auth-integration-select.tsx",
    "chars": 2363,
    "preview": "'use client';\n\nimport type { SelectProps } from '@radix-ui/react-select';\nimport * as React from 'react';\nimport {\n  Sel"
  },
  {
    "path": "apps/docs/components/blocks-grid.tsx",
    "chars": 1133,
    "preview": "import { Button } from '@docs/components/ui/button';\nimport Link from 'next/link';\n\nconst BLOCKS = [\n  { title: 'Sign in"
  },
  {
    "path": "apps/docs/components/blocks.tsx",
    "chars": 50,
    "preview": "'use client';\n\nexport * from '@/registry/blocks';\n"
  },
  {
    "path": "apps/docs/components/callout.tsx",
    "chars": 1198,
    "preview": "import { CircleCheckIcon, CircleXIcon, InfoIcon, TriangleAlertIcon } from 'lucide-react';\nimport { cn } from '@docs/lib/"
  },
  {
    "path": "apps/docs/components/clerk-logo.tsx",
    "chars": 4786,
    "preview": "import { cn } from '@docs/lib/utils';\n\nexport function ClerkLogo({ className, ...props }: React.SVGProps<SVGSVGElement>)"
  },
  {
    "path": "apps/docs/components/command-tabs.tsx",
    "chars": 979,
    "preview": "import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';\nimport { Tab, Tabs } from 'fumadocs-ui/components/tab"
  },
  {
    "path": "apps/docs/components/cookies-provider.tsx",
    "chars": 213,
    "preview": "'use client';\n\nimport { CookiesNextProvider } from 'cookies-next';\n\nexport function CookiesProvider({ children }: { chil"
  },
  {
    "path": "apps/docs/components/copy-button.tsx",
    "chars": 1982,
    "preview": "'use client';\n\n// This project uses code from fumadocs.\n// The code is licensed under the MIT License.\n// https://github"
  },
  {
    "path": "apps/docs/components/download-app-banner.tsx",
    "chars": 1539,
    "preview": "import { AppStoreButton } from './app-store-button';\nimport { PlayStoreButton } from './play-store-button';\nimport { Rnr"
  },
  {
    "path": "apps/docs/components/examples.tsx",
    "chars": 52,
    "preview": "'use client';\n\nexport * from '@/registry/examples';\n"
  },
  {
    "path": "apps/docs/components/external-links.tsx",
    "chars": 717,
    "preview": "import { ExternalLinkIcon } from 'lucide-react';\n\ntype ExternalLinksProps = {\n  links: {\n    title: string;\n    url: str"
  },
  {
    "path": "apps/docs/components/icons/rnr-icon.tsx",
    "chars": 1183,
    "preview": "import { cn } from '@docs/lib/utils';\n\nexport function RnrIcon({\n  className,\n  pathClassName,\n  ...props\n}: {\n  classNa"
  },
  {
    "path": "apps/docs/components/installation-tabs.tsx",
    "chars": 1378,
    "preview": "'use client';\n\nimport {\n  LinkTabs,\n  LinkTabsList,\n  LinkTabsTrigger,\n  LinkTabsContent,\n} from '@docs/components/link-"
  },
  {
    "path": "apps/docs/components/link-tabs.tsx",
    "chars": 2157,
    "preview": "'use client';\n\nimport * as React from 'react';\nimport * as TabsPrimitive from '@radix-ui/react-tabs';\n\nimport { cn } fro"
  },
  {
    "path": "apps/docs/components/platform-select.tsx",
    "chars": 2188,
    "preview": "'use client';\n\nimport { Button } from '@docs/components/ui/button';\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  "
  },
  {
    "path": "apps/docs/components/play-store-button.tsx",
    "chars": 363,
    "preview": "import Image from 'next/image';\n\nexport function PlayStoreButton() {\n  return (\n    <a\n      href=\"https://play.google.c"
  },
  {
    "path": "apps/docs/components/portal-info-alert.tsx",
    "chars": 648,
    "preview": "import { Callout } from '@docs/components/callout';\nimport Link from 'next/link';\n\nexport function PortalInfoAlert() {\n "
  },
  {
    "path": "apps/docs/components/preview-card.tsx",
    "chars": 4050,
    "preview": "'use client';\n\nimport { RnrIcon } from '@docs/components/icons/rnr-icon';\nimport { PlatformSelect, usePlatform } from '@"
  },
  {
    "path": "apps/docs/components/safe-area-provider.tsx",
    "chars": 82,
    "preview": "'use client';\n\nexport { SafeAreaProvider } from 'react-native-safe-area-context';\n"
  },
  {
    "path": "apps/docs/components/skip-navigation-button.tsx",
    "chars": 358,
    "preview": "import { Button } from './ui/button';\n\nexport function SkipNavigationButton() {\n  return (\n    <Button\n      asChild\n   "
  },
  {
    "path": "apps/docs/components/styling-library-tabs.tsx",
    "chars": 1314,
    "preview": "'use client';\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@docs/components/ui/tabs';\nimport * as React fr"
  },
  {
    "path": "apps/docs/components/ui/alert.tsx",
    "chars": 1587,
    "preview": "import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '"
  },
  {
    "path": "apps/docs/components/ui/badge.tsx",
    "chars": 1716,
    "preview": "import { cn } from '@docs/lib/utils';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } fro"
  },
  {
    "path": "apps/docs/components/ui/button.tsx",
    "chars": 2257,
    "preview": "import * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'cla"
  },
  {
    "path": "apps/docs/components/ui/select.tsx",
    "chars": 5594,
    "preview": "'use client';\n\nimport * as React from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\nimport { Check"
  },
  {
    "path": "apps/docs/components/ui/tabs.tsx",
    "chars": 1994,
    "preview": "'use client';\n\nimport * as React from 'react';\nimport * as TabsPrimitive from '@radix-ui/react-tabs';\n\nimport { cn } fro"
  },
  {
    "path": "apps/docs/components/use-styling-library.ts",
    "chars": 477,
    "preview": "import { useReactiveGetCookie, useReactiveSetCookie } from 'cookies-next';\n\nexport function useStylingLibrary() {\n  cons"
  },
  {
    "path": "apps/docs/components/vercel-oss-badge.tsx",
    "chars": 14124,
    "preview": "// Needed to modify the fill. On some devices, the primary color did not fit with the selected theme\n\nexport function Ve"
  },
  {
    "path": "apps/docs/components.json",
    "chars": 463,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": true,\n  \"tsx\": true,\n  \"tailwind\": {\n"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/forgot-password-form.mdx",
    "chars": 5496,
    "preview": "---\ntitle: Forgot password form\ndescription: A form that sends a password reset OTP to the user's email address.\n---\n\nim"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/index.mdx",
    "chars": 1172,
    "preview": "---\ntitle: Authentication\ndescription: Copy and paste or add them with the CLI.\n---\n\nimport { Callout } from \"@docs/comp"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/meta.json",
    "chars": 183,
    "preview": "{\n  \"pages\": [\n    \"sign-in-form\",\n    \"sign-up-form\",\n    \"verify-email-form\",\n    \"reset-password-form\",\n    \"forgot-p"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/reset-password-form.mdx",
    "chars": 5463,
    "preview": "---\ntitle: Reset password form\ndescription: A form for resetting a password with an OTP sent via email.\n---\n\nimport { Bl"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/sign-in-form.mdx",
    "chars": 5659,
    "preview": "---\ntitle: Sign in form\ndescription: A form for signing in using email and password or social providers.\n---\n\nimport { B"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/sign-up-form.mdx",
    "chars": 5635,
    "preview": "---\ntitle: Sign up form\ndescription: A form for creating an account with email and password or social providers.\n---\n\nim"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/social-connections.mdx",
    "chars": 4927,
    "preview": "---\ntitle: Social connections\ndescription: A set of buttons for authenticating through social providers.\n---\n\nimport { B"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/user-menu.mdx",
    "chars": 4668,
    "preview": "---\ntitle: User menu\ndescription: A popover menu presenting options and actions for the current user.\n---\n\nimport { Bloc"
  },
  {
    "path": "apps/docs/content/docs/blocks/authentication/verify-email-form.mdx",
    "chars": 5434,
    "preview": "---\ntitle: Verify email form\ndescription: A form for verifying an email address with an OTP sent via email.\n---\n\nimport "
  },
  {
    "path": "apps/docs/content/docs/changelog.mdx",
    "chars": 6946,
    "preview": "---\ntitle: Changelog\ndescription: Latest updates and announcements.\n---\n\nimport { Callout } from '@docs/components/callo"
  },
  {
    "path": "apps/docs/content/docs/cli.mdx",
    "chars": 2730,
    "preview": "---\ntitle: CLI\ndescription: Use the CLI to add components and more\n---\n\nimport { Callout } from '@docs/components/callou"
  },
  {
    "path": "apps/docs/content/docs/components/accordion.mdx",
    "chars": 6579,
    "preview": "---\ntitle: Accordion\ndescription: A vertically stacked set of interactive headings that each reveal a section of content"
  },
  {
    "path": "apps/docs/content/docs/components/alert-dialog.mdx",
    "chars": 5970,
    "preview": "---\ntitle: Alert Dialog\ndescription: A modal dialog that interrupts the user with important content and expects a respon"
  },
  {
    "path": "apps/docs/content/docs/components/alert.mdx",
    "chars": 4034,
    "preview": "---\ntitle: Alert\ndescription: Displays a callout for user attention.\n---\n\nimport { CommandTabs } from \"@docs/components/"
  },
  {
    "path": "apps/docs/content/docs/components/aspect-ratio.mdx",
    "chars": 3168,
    "preview": "---\ntitle: Aspect Ratio\ndescription: Displays content within a desired ratio.\n---\n\nimport { CommandTabs } from \"@docs/co"
  },
  {
    "path": "apps/docs/content/docs/components/avatar.mdx",
    "chars": 3292,
    "preview": "---\ntitle: Avatar\ndescription: An image element with a fallback for representing the user.\n---\n\nimport { CommandTabs } f"
  },
  {
    "path": "apps/docs/content/docs/components/badge.mdx",
    "chars": 3858,
    "preview": "---\ntitle: Badge\ndescription: Displays a badge or a component that looks like a badge.\n---\n\nimport { CommandTabs } from "
  },
  {
    "path": "apps/docs/content/docs/components/button.mdx",
    "chars": 9086,
    "preview": "---\ntitle: Button\ndescription: Displays a button or a component that looks like a button.\n---\n\nimport { CommandTabs } fr"
  },
  {
    "path": "apps/docs/content/docs/components/card.mdx",
    "chars": 3656,
    "preview": "---\ntitle: Card\ndescription: Displays a card with header, content, and footer.\n---\n\nimport { CommandTabs } from \"@docs/c"
  },
  {
    "path": "apps/docs/content/docs/components/checkbox.mdx",
    "chars": 3670,
    "preview": "---\ntitle: Checkbox\ndescription: A control that allows the user to toggle between checked and not checked.\n---\n\nimport {"
  },
  {
    "path": "apps/docs/content/docs/components/collapsible.mdx",
    "chars": 3431,
    "preview": "---\ntitle: Collapsible\ndescription: A control that allows the user to toggle between checked and not checked.\n---\n\nimpor"
  },
  {
    "path": "apps/docs/content/docs/components/context-menu.mdx",
    "chars": 4965,
    "preview": "---\ntitle: Context Menu\ndescription: Displays a menu to the user — such as a set of actions or functions — triggered by "
  },
  {
    "path": "apps/docs/content/docs/components/dialog.mdx",
    "chars": 5163,
    "preview": "---\ntitle: Dialog\ndescription: A window overlaid on either the primary window or another dialog window, rendering the co"
  },
  {
    "path": "apps/docs/content/docs/components/dropdown-menu.mdx",
    "chars": 4992,
    "preview": "---\ntitle: Dropdown Menu\ndescription: Displays a menu to the user — such as a set of actions or functions — triggered by"
  },
  {
    "path": "apps/docs/content/docs/components/hover-card.mdx",
    "chars": 4053,
    "preview": "---\ntitle: Hover Card\ndescription: For sighted users to preview content available behind a link.\n---\n\nimport { CommandTa"
  },
  {
    "path": "apps/docs/content/docs/components/input.mdx",
    "chars": 2806,
    "preview": "---\ntitle: Input\ndescription: Displays a form input field or a component that looks like an input field.\n---\n\nimport { C"
  },
  {
    "path": "apps/docs/content/docs/components/label.mdx",
    "chars": 2914,
    "preview": "---\ntitle: Label\ndescription: Renders an accessible label associated with controls.\n---\n\nimport { CommandTabs } from \"@d"
  },
  {
    "path": "apps/docs/content/docs/components/menubar.mdx",
    "chars": 5058,
    "preview": "---\ntitle: Menubar\ndescription: A visually persistent menu common in desktop applications that provides quick access to "
  },
  {
    "path": "apps/docs/content/docs/components/popover.mdx",
    "chars": 3975,
    "preview": "---\ntitle: Popover\ndescription: Displays rich content in a portal, triggered by a button.\n---\n\nimport { CommandTabs } fr"
  },
  {
    "path": "apps/docs/content/docs/components/progress.mdx",
    "chars": 3203,
    "preview": "---\ntitle: Progress\ndescription: Displays an indicator showing the completion progress of a task, typically displayed as"
  },
  {
    "path": "apps/docs/content/docs/components/radio-group.mdx",
    "chars": 3771,
    "preview": "---\ntitle: Radio Group\ndescription: A set of checkable buttons—known as radio buttons—where no more than one of the butt"
  },
  {
    "path": "apps/docs/content/docs/components/select.mdx",
    "chars": 7164,
    "preview": "---\ntitle: Select\ndescription: Displays a list of options for the user to pick from—triggered by a button.\n---\n\nimport {"
  },
  {
    "path": "apps/docs/content/docs/components/separator.mdx",
    "chars": 3077,
    "preview": "---\ntitle: Separator\ndescription: Visually or semantically separates content.\n---\n\nimport { CommandTabs } from \"@docs/co"
  },
  {
    "path": "apps/docs/content/docs/components/skeleton.mdx",
    "chars": 2964,
    "preview": "---\ntitle: Skeleton\ndescription: Use to show a placeholder while content is loading.\n---\n\nimport { CommandTabs } from \"@"
  },
  {
    "path": "apps/docs/content/docs/components/switch.mdx",
    "chars": 3063,
    "preview": "---\ntitle: Switch\ndescription: A control that allows the user to toggle between checked and not checked.\n---\n\nimport { C"
  },
  {
    "path": "apps/docs/content/docs/components/tabs.mdx",
    "chars": 4132,
    "preview": "---\ntitle: Tabs\ndescription: A set of layered sections of content—known as tab panels—that are displayed one at a time.\n"
  },
  {
    "path": "apps/docs/content/docs/components/text.mdx",
    "chars": 4376,
    "preview": "---\ntitle: Text\ndescription: A component for displaying text.\n---\n\nimport { CommandTabs } from \"@docs/components/command"
  },
  {
    "path": "apps/docs/content/docs/components/textarea.mdx",
    "chars": 2794,
    "preview": "---\ntitle: Textarea\ndescription: Displays a form textarea or a component that looks like a textarea.\n---\n\nimport { Comma"
  },
  {
    "path": "apps/docs/content/docs/components/toggle-group.mdx",
    "chars": 5624,
    "preview": "---\ntitle: Toggle Group\ndescription: A set of two-state buttons that can be toggled on or off.\n---\n\nimport { CommandTabs"
  },
  {
    "path": "apps/docs/content/docs/components/toggle.mdx",
    "chars": 4321,
    "preview": "---\ntitle: Toggle\ndescription: A two-state button that can be either on or off.\n---\n\nimport { CommandTabs } from \"@docs/"
  },
  {
    "path": "apps/docs/content/docs/components/tooltip.mdx",
    "chars": 4033,
    "preview": "---\ntitle: Tooltip\ndescription: A popup that displays information related to an element when the element receives keyboa"
  },
  {
    "path": "apps/docs/content/docs/create-your-own-registry.mdx",
    "chars": 2180,
    "preview": "---\ntitle: Create Your Own Registry\ndescription: Host a registry and allow others to add your code to their projects.\n--"
  },
  {
    "path": "apps/docs/content/docs/customization.mdx",
    "chars": 2390,
    "preview": "---\ntitle: Customization\ndescription: How to customize your project\n---\n\nReact Native Reusables uses a theme system base"
  },
  {
    "path": "apps/docs/content/docs/index.mdx",
    "chars": 3447,
    "preview": "---\ntitle: Introduction\n---\n\nimport { DownloadAppBanner } from '@docs/components/download-app-banner';\n\n<blockquote cite"
  },
  {
    "path": "apps/docs/content/docs/installation/index.mdx",
    "chars": 1418,
    "preview": "---\ntitle: Installation\ndescription: Getting Started with React Native Reusables\n---\n\nimport { Button } from '@docs/comp"
  },
  {
    "path": "apps/docs/content/docs/installation/manual.mdx",
    "chars": 11606,
    "preview": "---\ntitle: Installation\ndescription: Getting Started with React Native Reusables\n---\n\nimport { Button } from '@docs/comp"
  },
  {
    "path": "apps/docs/content/docs/meta.json",
    "chars": 792,
    "preview": "{\n  \"title\": \"React Native Reusables\",\n  \"description\": \"\",\n  \"icon\": \"Building2\",\n  \"root\": true,\n  \"pages\": [\n    \"---"
  },
  {
    "path": "apps/docs/global.d.ts",
    "chars": 87,
    "preview": "declare module '!!raw-loader!*' {\n  const content: string;\n  export default content;\n}\n"
  },
  {
    "path": "apps/docs/lib/FoundedLabsIcon.tsx",
    "chars": 5963,
    "preview": "export default function FoundedLabsIcon() {\n  return (\n    <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" x"
  },
  {
    "path": "apps/docs/lib/file-generator.ts",
    "chars": 1572,
    "preview": "import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Code, Paragraph } from 'mdast';"
  },
  {
    "path": "apps/docs/lib/source.ts",
    "chars": 583,
    "preview": "import { docs, meta } from '@docs/.source';\nimport { loader } from 'fumadocs-core/source';\nimport { createMDXSource } fr"
  },
  {
    "path": "apps/docs/lib/utils.ts",
    "chars": 169,
    "preview": "import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: C"
  },
  {
    "path": "apps/docs/nativewind-env.d.ts",
    "chars": 43,
    "preview": "/// <reference types=\"nativewind/types\" />\n"
  },
  {
    "path": "apps/docs/next.config.mjs",
    "chars": 3180,
    "preview": "import { createMDX } from 'fumadocs-mdx/next';\n\nconst withMDX = createMDX({\n  extension: /\\.mdx?$/,\n});\n\n/** @type {impo"
  },
  {
    "path": "apps/docs/package.json",
    "chars": 2239,
    "preview": "{\n  \"name\": \"@rnr/docs\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"build\": \"next build\",\n    \"clean\":"
  },
  {
    "path": "apps/docs/postcss.config.js",
    "chars": 83,
    "preview": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n};\n"
  },
  {
    "path": "apps/docs/public/.well-known/apple-app-site-association",
    "chars": 203,
    "preview": "{\n    \"applinks\": {\n        \"details\": [\n            {\n                \"appID\" : \"HA68FZH26V.com.reactnativereusables.ap"
  },
  {
    "path": "apps/docs/public/.well-known/assetlinks.json",
    "chars": 801,
    "preview": "[\n  {\n    \"relation\": [\n      \"delegate_permission/common.handle_all_urls\",\n      \"delegate_permission/common.get_login_"
  },
  {
    "path": "apps/docs/public/r/nativewind/accordion.json",
    "chars": 5218,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"accordion\",\n  \"type\": \"registry:ui\",\n  \"tit"
  },
  {
    "path": "apps/docs/public/r/nativewind/alert-dialog.json",
    "chars": 5462,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"alert-dialog\",\n  \"type\": \"registry:ui\",\n  \""
  },
  {
    "path": "apps/docs/public/r/nativewind/alert.json",
    "chars": 2604,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"alert\",\n  \"type\": \"registry:ui\",\n  \"title\":"
  },
  {
    "path": "apps/docs/public/r/nativewind/aspect-ratio.json",
    "chars": 611,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"aspect-ratio\",\n  \"type\": \"registry:ui\",\n  \""
  },
  {
    "path": "apps/docs/public/r/nativewind/avatar.json",
    "chars": 1516,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"avatar\",\n  \"type\": \"registry:ui\",\n  \"title\""
  },
  {
    "path": "apps/docs/public/r/nativewind/badge.json",
    "chars": 2893,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"badge\",\n  \"type\": \"registry:ui\",\n  \"title\":"
  },
  {
    "path": "apps/docs/public/r/nativewind/button.json",
    "chars": 4438,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"button\",\n  \"type\": \"registry:ui\",\n  \"title\""
  },
  {
    "path": "apps/docs/public/r/nativewind/card.json",
    "chars": 2194,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"card\",\n  \"type\": \"registry:ui\",\n  \"title\": "
  },
  {
    "path": "apps/docs/public/r/nativewind/checkbox.json",
    "chars": 2331,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"checkbox\",\n  \"type\": \"registry:ui\",\n  \"titl"
  },
  {
    "path": "apps/docs/public/r/nativewind/collapsible.json",
    "chars": 799,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"collapsible\",\n  \"type\": \"registry:ui\",\n  \"t"
  },
  {
    "path": "apps/docs/public/r/nativewind/context-menu.json",
    "chars": 11159,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"context-menu\",\n  \"type\": \"registry:ui\",\n  \""
  },
  {
    "path": "apps/docs/public/r/nativewind/dialog.json",
    "chars": 5231,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"dialog\",\n  \"type\": \"registry:ui\",\n  \"title\""
  },
  {
    "path": "apps/docs/public/r/nativewind/dropdown-menu.json",
    "chars": 11287,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"dropdown-menu\",\n  \"type\": \"registry:ui\",\n  "
  },
  {
    "path": "apps/docs/public/r/nativewind/forgot-password-form-clerk.json",
    "chars": 3678,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"forgot-password-form-clerk\",\n  \"type\": \"reg"
  },
  {
    "path": "apps/docs/public/r/nativewind/forgot-password-form.json",
    "chars": 2584,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"forgot-password-form\",\n  \"type\": \"registry:"
  },
  {
    "path": "apps/docs/public/r/nativewind/hover-card.json",
    "chars": 2903,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"hover-card\",\n  \"type\": \"registry:ui\",\n  \"ti"
  },
  {
    "path": "apps/docs/public/r/nativewind/icon.json",
    "chars": 2151,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"icon\",\n  \"type\": \"registry:ui\",\n  \"title\": "
  },
  {
    "path": "apps/docs/public/r/nativewind/input.json",
    "chars": 1670,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"input\",\n  \"type\": \"registry:ui\",\n  \"title\":"
  },
  {
    "path": "apps/docs/public/r/nativewind/label.json",
    "chars": 1610,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"label\",\n  \"type\": \"registry:ui\",\n  \"title\":"
  },
  {
    "path": "apps/docs/public/r/nativewind/menubar.json",
    "chars": 12530,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"menubar\",\n  \"type\": \"registry:ui\",\n  \"title"
  },
  {
    "path": "apps/docs/public/r/nativewind/native-only-animated-view.json",
    "chars": 1269,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"native-only-animated-view\",\n  \"type\": \"regi"
  },
  {
    "path": "apps/docs/public/r/nativewind/popover.json",
    "chars": 2917,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"popover\",\n  \"type\": \"registry:ui\",\n  \"title"
  },
  {
    "path": "apps/docs/public/r/nativewind/progress.json",
    "chars": 2626,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"progress\",\n  \"type\": \"registry:ui\",\n  \"titl"
  },
  {
    "path": "apps/docs/public/r/nativewind/radio-group.json",
    "chars": 1834,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"radio-group\",\n  \"type\": \"registry:ui\",\n  \"t"
  },
  {
    "path": "apps/docs/public/r/nativewind/reset-password-form-clerk.json",
    "chars": 4871,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"reset-password-form-clerk\",\n  \"type\": \"regi"
  },
  {
    "path": "apps/docs/public/r/nativewind/reset-password-form.json",
    "chars": 3227,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"reset-password-form\",\n  \"type\": \"registry:c"
  },
  {
    "path": "apps/docs/public/r/nativewind/select.json",
    "chars": 8861,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"select\",\n  \"type\": \"registry:ui\",\n  \"title\""
  },
  {
    "path": "apps/docs/public/r/nativewind/separator.json",
    "chars": 1089,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"separator\",\n  \"type\": \"registry:ui\",\n  \"tit"
  },
  {
    "path": "apps/docs/public/r/nativewind/sign-in-form-clerk.json",
    "chars": 6491,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"sign-in-form-clerk\",\n  \"type\": \"registry:co"
  },
  {
    "path": "apps/docs/public/r/nativewind/sign-in-form.json",
    "chars": 4575,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"sign-in-form\",\n  \"type\": \"registry:componen"
  },
  {
    "path": "apps/docs/public/r/nativewind/sign-up-form-clerk.json",
    "chars": 5746,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"sign-up-form-clerk\",\n  \"type\": \"registry:co"
  },
  {
    "path": "apps/docs/public/r/nativewind/sign-up-form.json",
    "chars": 4181,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"sign-up-form\",\n  \"type\": \"registry:componen"
  },
  {
    "path": "apps/docs/public/r/nativewind/skeleton.json",
    "chars": 737,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"skeleton\",\n  \"type\": \"registry:ui\",\n  \"titl"
  },
  {
    "path": "apps/docs/public/r/nativewind/social-connections-clerk.json",
    "chars": 4590,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"social-connections-clerk\",\n  \"type\": \"regis"
  },
  {
    "path": "apps/docs/public/r/nativewind/social-connections.json",
    "chars": 2142,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"social-connections\",\n  \"type\": \"registry:co"
  },
  {
    "path": "apps/docs/public/r/nativewind/switch.json",
    "chars": 1757,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"switch\",\n  \"type\": \"registry:ui\",\n  \"title\""
  },
  {
    "path": "apps/docs/public/r/nativewind/tabs.json",
    "chars": 2972,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"tabs\",\n  \"type\": \"registry:ui\",\n  \"title\": "
  },
  {
    "path": "apps/docs/public/r/nativewind/text.json",
    "chars": 3101,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"text\",\n  \"type\": \"registry:ui\",\n  \"title\": "
  },
  {
    "path": "apps/docs/public/r/nativewind/textarea.json",
    "chars": 1780,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"textarea\",\n  \"type\": \"registry:ui\",\n  \"titl"
  },
  {
    "path": "apps/docs/public/r/nativewind/toggle-group.json",
    "chars": 4128,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"toggle-group\",\n  \"type\": \"registry:ui\",\n  \""
  },
  {
    "path": "apps/docs/public/r/nativewind/toggle.json",
    "chars": 3234,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"toggle\",\n  \"type\": \"registry:ui\",\n  \"title\""
  },
  {
    "path": "apps/docs/public/r/nativewind/tooltip.json",
    "chars": 3332,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"tooltip\",\n  \"type\": \"registry:ui\",\n  \"title"
  },
  {
    "path": "apps/docs/public/r/nativewind/user-menu-clerk.json",
    "chars": 4975,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"user-menu-clerk\",\n  \"type\": \"registry:compo"
  }
]

// ... and 252 more files (download for full content)

About this extraction

This page contains the full source code of the founded-labs/react-native-reusables GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 452 files (1.1 MB), approximately 324.8k tokens, and a symbol index with 472 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!