create-react-native-library-template 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/AGENTS.md +36 -7
- package/template/README.md +14 -0
- package/template/bun.lock +316 -48
- package/template/gitignore +3 -0
- package/template/packages/ui/package.json +10 -6
- package/template/packages/ui/src/components/Button/button.tsx +59 -72
- package/template/packages/ui/src/uniwind-env.d.ts +1 -0
- package/template/storybook/native/.rnstorybook/preview.tsx +2 -2
- package/template/storybook/native/global.css +5 -0
- package/template/storybook/native/metro.config.js +14 -4
- package/template/storybook/native/package.json +3 -1
- package/template/storybook/native/uniwind-env.d.ts +3 -0
- package/template/storybook/web/.storybook/main.ts +16 -0
- package/template/storybook/web/.storybook/preview.tsx +1 -0
- package/template/storybook/web/.storybook/uniwind-env.d.ts +3 -0
- package/template/storybook/web/global.css +5 -0
- package/template/storybook/web/package.json +3 -0
- package/template/packages/ui/src/theme/tokens.ts +0 -40
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-react-native-library-template",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Scaffold a React Native UI library monorepo: Bun workspaces, Expo, Storybook (web + native), Vitest, Biome and Changesets",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/template/AGENTS.md
CHANGED
|
@@ -12,7 +12,9 @@ Tooling: **bun** (package manager + script runner), **biome** (lint + format), *
|
|
|
12
12
|
(strict, `verbatimModuleSyntax` — use `import type` for types), **vitest** (unit tests via
|
|
13
13
|
react-native-web in jsdom; story tests via `@storybook/addon-vitest` in Chromium),
|
|
14
14
|
**react-native-builder-bob** (library build), **changesets** (versioning/publishing),
|
|
15
|
-
**husky** (git hooks — a `pre-commit` hook runs lint, typecheck, and unit tests).
|
|
15
|
+
**husky** (git hooks — a `pre-commit` hook runs lint, typecheck, and unit tests). Components are
|
|
16
|
+
styled with **[Uniwind](https://uniwind.dev)** (Tailwind CSS 4 `className` for React Native) plus
|
|
17
|
+
**[cva](https://cva.style)** for variants — see [Styling](#styling-uniwind).
|
|
16
18
|
|
|
17
19
|
## Commands (run from the repo root)
|
|
18
20
|
|
|
@@ -41,17 +43,21 @@ implementation. For a component named `Foo`:
|
|
|
41
43
|
|
|
42
44
|
**No `index.ts`** — barrel files are forbidden everywhere in the library. Public entry
|
|
43
45
|
points are declared in the `exports` map of `packages/ui/package.json` (step 3), and
|
|
44
|
-
internal imports always target the concrete file (`../../
|
|
46
|
+
internal imports always target the concrete file (`../../components/Button/button`), never a folder.
|
|
45
47
|
2. **Write the component** (`foo.tsx`):
|
|
46
48
|
- Named function export (`export function Foo(...)`), never a default export.
|
|
47
49
|
- Export a `FooProps` interface with a JSDoc comment per prop; document defaults with `@default`.
|
|
48
50
|
- Only import from `react`, `react-native`, and internal modules. New runtime dependencies
|
|
49
51
|
need explicit approval — they become dependencies for every consumer of the library.
|
|
50
|
-
- Use only RN APIs that exist on react-native-web (`View`, `Text`, `Pressable`,
|
|
51
|
-
|
|
52
|
-
- Style with `
|
|
53
|
-
`
|
|
54
|
-
|
|
52
|
+
- Use only RN APIs that exist on react-native-web (`View`, `Text`, `Pressable`, ...),
|
|
53
|
+
otherwise unit tests and the web Storybook will break.
|
|
54
|
+
- Style with Tailwind `className` (resolved by [Uniwind](https://uniwind.dev)) — no
|
|
55
|
+
`StyleSheet.create`, no hard-coded colors or magic numbers. Compose variants with
|
|
56
|
+
[`class-variance-authority`](https://cva.style) (`cva`), following `Button` as the
|
|
57
|
+
reference. Keep class strings as static literals so Tailwind's scanner can see them.
|
|
58
|
+
`View`/`Text`/`Pressable` take `className`; `ActivityIndicator` takes `colorClassName`
|
|
59
|
+
(see the full prop list in `uniwind/types`). Still accept a `style` prop for escape-hatch
|
|
60
|
+
overrides.
|
|
55
61
|
- Accessibility is required: set `accessibilityRole`, `accessibilityState`, and accept an
|
|
56
62
|
`accessibilityLabel` prop. Also accept `style` (as `StyleProp<...>`) and `testID`.
|
|
57
63
|
3. **Export it from the library**: add a `./foo` subpath to the `exports` map in
|
|
@@ -84,6 +90,29 @@ implementation. For a component named `Foo`:
|
|
|
84
90
|
component (`patch` for fixes, `major` for breaking changes), write a one-line summary.
|
|
85
91
|
Commit the generated `.changeset/*.md` file with your change.
|
|
86
92
|
|
|
93
|
+
## Styling (Uniwind)
|
|
94
|
+
|
|
95
|
+
The library styles React Native components with Tailwind classes through
|
|
96
|
+
[Uniwind](https://uniwind.dev), the Tailwind provider for React Native. There is no runtime
|
|
97
|
+
provider to mount: Uniwind rewrites `react-native` imports to className-aware components in the
|
|
98
|
+
**bundler**, so components just import from `react-native` and set `className`. That rewrite is
|
|
99
|
+
configured once per app, and the three pieces below are already wired in this repo:
|
|
100
|
+
|
|
101
|
+
- **Native (Metro)** — `storybook/native/metro.config.js` wraps the config with
|
|
102
|
+
`withUniwindConfig(...)` from `uniwind/metro`, as the **outermost** wrapper. `cssEntryFile`
|
|
103
|
+
must be a plain relative string.
|
|
104
|
+
- **Web (Vite)** — `storybook/web/.storybook/main.ts` adds `@tailwindcss/vite` and
|
|
105
|
+
`uniwind({...})` from `uniwind/vite` in `viteFinal`.
|
|
106
|
+
- **CSS entry** — each Storybook has a `global.css` (`@import 'tailwindcss'; @import 'uniwind';`)
|
|
107
|
+
imported from its `preview`. Because components live in `packages/ui`, each `global.css` has an
|
|
108
|
+
`@source '../../packages/ui/src'` so Tailwind's scanner finds the class strings there.
|
|
109
|
+
|
|
110
|
+
`className` typechecks via a per-workspace `uniwind-env.d.ts` (`/// <reference types="uniwind/types" />`),
|
|
111
|
+
which augments `react-native` to add `className`/`colorClassName`. Uniwind's generated
|
|
112
|
+
`uniwind-types.d.ts` (theme-aware autocomplete) is gitignored. Unit tests need none of this:
|
|
113
|
+
they run in jsdom on react-native-web, which passes `className` through harmlessly, and they
|
|
114
|
+
assert behavior by role/name — never computed styles.
|
|
115
|
+
|
|
87
116
|
## Releasing
|
|
88
117
|
|
|
89
118
|
CI (`.github/workflows/ci.yml`) runs lint, typecheck, tests, build, and Storybook tests on
|
package/template/README.md
CHANGED
|
@@ -4,6 +4,7 @@ Template for building and publishing a React Native UI component library.
|
|
|
4
4
|
|
|
5
5
|
- **[Bun](https://bun.sh)** — package manager, script runner, workspaces
|
|
6
6
|
- **[TypeScript 6](https://www.typescriptlang.org)** — strict mode everywhere
|
|
7
|
+
- **[Uniwind](https://uniwind.dev)** — Tailwind CSS for React Native (`className` on RN components), with [`cva`](https://cva.style) for variants
|
|
7
8
|
- **[Biome](https://biomejs.dev)** — linting + formatting
|
|
8
9
|
- **[Vitest](https://vitest.dev)** — unit tests (react-native-web in jsdom)
|
|
9
10
|
- **[Storybook 10](https://storybook.js.org)** — web (react-native-web + Vite) **and** on-device (Expo) demos from the same stories
|
|
@@ -49,6 +50,19 @@ bun run build # library build → packages/ui/lib
|
|
|
49
50
|
See [AGENTS.md](./AGENTS.md) — it documents the full checklist (component, tests, stories,
|
|
50
51
|
exports, changeset). `packages/ui/src/components/Button` is the reference implementation.
|
|
51
52
|
|
|
53
|
+
## Styling
|
|
54
|
+
|
|
55
|
+
Components are styled with Tailwind classes via [Uniwind](https://uniwind.dev), which resolves
|
|
56
|
+
`className` on React Native components at bundle time (Metro for native, Vite for web) — there's
|
|
57
|
+
no runtime provider to mount. Variants are composed with [`cva`](https://cva.style); see
|
|
58
|
+
`packages/ui/src/components/Button/button.tsx`.
|
|
59
|
+
|
|
60
|
+
Each app has a `global.css` (`@import 'tailwindcss'; @import 'uniwind';`) that the bundler is
|
|
61
|
+
pointed at: `storybook/web` wires `@tailwindcss/vite` + `uniwind/vite` in `.storybook/main.ts`,
|
|
62
|
+
and `storybook/native` wraps its Metro config with `withUniwindConfig`. A consumer of the
|
|
63
|
+
published library does the same in their own app. Keep class strings as static literals so
|
|
64
|
+
Tailwind's scanner picks them up.
|
|
65
|
+
|
|
52
66
|
## Releasing
|
|
53
67
|
|
|
54
68
|
1. With every user-facing change, run `bun run changeset` and commit the generated file.
|