panelui-native 0.22.3 → 0.22.6
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/README.md +118 -24
- package/package.json +1 -1
- package/theme.css +22 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# PanelUI — React Native UI components for Expo, styled with Tailwind CSS
|
|
2
2
|
|
|
3
3
|
**PanelUI** (`panelui-native`) is an accessible, high-performance React Native component
|
|
4
|
-
library for Expo apps.
|
|
4
|
+
library for Expo apps. 53 typed components — buttons, bottom sheets, dialogs, selects,
|
|
5
5
|
toasts, forms — styled with Tailwind CSS v4 and animated on the UI thread with Reanimated.
|
|
6
6
|
Zero native code, so it runs in Expo Go.
|
|
7
7
|
|
|
@@ -24,15 +24,35 @@ Zero native code, so it runs in Expo Go.
|
|
|
24
24
|
state and labels.
|
|
25
25
|
- 📦 **TypeScript, tree-shakeable, zero native modules** — works in Expo Go, no prebuild needed.
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
Needs an Expo SDK 57+ app and Node 20+. No Xcode, no Android Studio, no `prebuild` — PanelUI has
|
|
30
|
+
no native modules, so it runs in Expo Go. No app yet? `npx create-expo-app@latest my-app`.
|
|
31
|
+
|
|
32
|
+
Five steps. The full walkthrough, with a fix for every error people hit, is at
|
|
33
|
+
**[panelui.dev/docs/installation](https://panelui.dev/docs/installation)**.
|
|
34
|
+
|
|
35
|
+
### 1. Install the packages
|
|
28
36
|
|
|
29
37
|
```sh
|
|
30
|
-
npx expo install panelui-native uniwind tailwindcss react-native-
|
|
38
|
+
npx expo install panelui-native uniwind tailwindcss @react-native-masked-view/masked-view expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-svg react-native-worklets
|
|
31
39
|
```
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
Install all of them, including the ones you think you don't need. Metro resolves every import in
|
|
42
|
+
the library when it builds your bundle, so leaving one out fails the **first** bundle with
|
|
43
|
+
`Unable to resolve module …` — for a component you may never use. `npx expo install` (rather than
|
|
44
|
+
`npm install`) picks the versions that match your SDK.
|
|
45
|
+
|
|
46
|
+
Optional, each behind a guarded import: `expo-haptics` (the `haptics` prop), `expo-blur` (blurred
|
|
47
|
+
overlay backdrops), `expo-clipboard` (`useCopyToClipboard`), `react-native-keyboard-controller`
|
|
48
|
+
(keyboard avoidance on Android), `expo-file-system` + `react-native-view-shot` (Signature export),
|
|
49
|
+
`@expo/ui` (native platform controls).
|
|
34
50
|
|
|
35
|
-
|
|
51
|
+
### 2. Add `metro.config.js`
|
|
52
|
+
|
|
53
|
+
**In the root of your project, next to `package.json`** — not in `app/`, not in `src/`. A Metro
|
|
54
|
+
config anywhere else is silently ignored and none of your classes will do anything. A fresh Expo
|
|
55
|
+
app has no such file; `npx expo customize metro.config.js` writes one.
|
|
36
56
|
|
|
37
57
|
```js
|
|
38
58
|
// metro.config.js
|
|
@@ -42,49 +62,104 @@ const { withUniwindConfig } = require('uniwind/metro');
|
|
|
42
62
|
const config = getDefaultConfig(__dirname);
|
|
43
63
|
|
|
44
64
|
module.exports = withUniwindConfig(config, {
|
|
45
|
-
cssEntryFile: './global.css',
|
|
65
|
+
cssEntryFile: './src/global.css',
|
|
46
66
|
dtsFile: './uniwind-types.d.ts',
|
|
47
|
-
// Only needed
|
|
67
|
+
// Only needed to switch to the Moon or Grass themes at runtime.
|
|
48
68
|
extraThemes: ['moon', 'moon-dark', 'grass', 'grass-dark'],
|
|
49
69
|
});
|
|
50
70
|
```
|
|
51
71
|
|
|
52
|
-
|
|
72
|
+
`cssEntryFile` and `dtsFile` are relative to this file. `./src/global.css` is where
|
|
73
|
+
`create-expo-app` puts the CSS — if yours is at the project root, change it to `'./global.css'`.
|
|
74
|
+
|
|
75
|
+
**Nothing validates that path.** Point it at a file that does not exist and Metro still bundles, the
|
|
76
|
+
app still launches, and not one class resolves — no `flex-1`, so views collapse and you get a blank
|
|
77
|
+
screen with `Uniwind - We couldn't find your variable --color-background`.
|
|
78
|
+
|
|
79
|
+
### 3. Add the imports to `global.css`
|
|
80
|
+
|
|
81
|
+
**Look for this file before you create one** — an app made by `create-expo-app` already has
|
|
82
|
+
`src/global.css`. Add these lines at the top of it and leave the rest below. A second CSS file at
|
|
83
|
+
the project root gives you two entries, only one of which is compiled, and nothing gets styled.
|
|
53
84
|
|
|
54
85
|
```css
|
|
86
|
+
/* src/global.css */
|
|
55
87
|
@import 'tailwindcss';
|
|
56
88
|
@import 'uniwind';
|
|
57
89
|
@import 'panelui-native/theme.css';
|
|
58
90
|
|
|
59
|
-
@source '
|
|
91
|
+
@source '../node_modules/panelui-native/src';
|
|
60
92
|
```
|
|
61
93
|
|
|
62
|
-
**
|
|
94
|
+
`@source` is relative to **the CSS file**, and has to land on `node_modules/panelui-native/src` —
|
|
95
|
+
hence the `../` above, from `src/`. From the project root it is `'./node_modules/…'`, from
|
|
96
|
+
`src/styles/` it is `'../../node_modules/…'`. Get it wrong and your own classes work while
|
|
97
|
+
PanelUI's components come out unstyled. Whichever file you used is what `cssEntryFile` must name.
|
|
98
|
+
|
|
99
|
+
### 4. Import the CSS and add the provider
|
|
100
|
+
|
|
101
|
+
At the top of your app's entry file. The default template uses Expo Router with routes under
|
|
102
|
+
`src/`, so there is usually no `App.tsx` — the entry is `src/app/_layout.tsx`, and it already
|
|
103
|
+
returns a navigation `ThemeProvider` to wrap rather than replace:
|
|
63
104
|
|
|
64
105
|
```tsx
|
|
65
|
-
//
|
|
66
|
-
import '
|
|
67
|
-
|
|
106
|
+
// src/app/_layout.tsx
|
|
107
|
+
import '../global.css';
|
|
108
|
+
|
|
109
|
+
import { DarkTheme, DefaultTheme, ThemeProvider } from 'expo-router';
|
|
110
|
+
import { useColorScheme } from 'react-native';
|
|
111
|
+
import { PanelUIProvider } from 'panelui-native';
|
|
112
|
+
|
|
113
|
+
import AppTabs from '@/components/app-tabs';
|
|
114
|
+
|
|
115
|
+
export default function RootLayout() {
|
|
116
|
+
const colorScheme = useColorScheme();
|
|
68
117
|
|
|
69
|
-
export default function App() {
|
|
70
118
|
return (
|
|
71
119
|
<PanelUIProvider>
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
<Card.Description>Deploy your new project in one click.</Card.Description>
|
|
76
|
-
</Card.Header>
|
|
77
|
-
<Card.Footer>
|
|
78
|
-
<Button>Deploy</Button>
|
|
79
|
-
</Card.Footer>
|
|
80
|
-
</Card>
|
|
120
|
+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
|
121
|
+
<AppTabs />
|
|
122
|
+
</ThemeProvider>
|
|
81
123
|
</PanelUIProvider>
|
|
82
124
|
);
|
|
83
125
|
}
|
|
84
126
|
```
|
|
85
127
|
|
|
128
|
+
That navigation theme paints over PanelUI's background once you switch themes — see
|
|
129
|
+
[Using Expo Router?](#using-expo-router-read-this) below for the version fed from live tokens.
|
|
130
|
+
|
|
86
131
|
`PanelUIProvider` sets up the gesture root, the themed page background, the portal host used by
|
|
87
|
-
overlays, and the toast viewport.
|
|
132
|
+
overlays, and the toast viewport. One at the root is enough — don't nest a second.
|
|
133
|
+
|
|
134
|
+
You do **not** need a `babel.config.js`; Expo's default preset already wires the worklets plugin
|
|
135
|
+
Reanimated needs.
|
|
136
|
+
|
|
137
|
+
### 5. Restart
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
npx expo start --clear
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Metro reads `metro.config.js`, `global.css` and `extraThemes` once, at startup. After changing any
|
|
144
|
+
of them, stop the dev server and start it again — `--clear` on a running one is not enough.
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
import { Button, Card } from 'panelui-native';
|
|
148
|
+
|
|
149
|
+
<Card>
|
|
150
|
+
<Card.Header>
|
|
151
|
+
<Card.Title>It works</Card.Title>
|
|
152
|
+
<Card.Description>PanelUI is installed and themed.</Card.Description>
|
|
153
|
+
</Card.Header>
|
|
154
|
+
<Card.Footer>
|
|
155
|
+
<Button>Deploy</Button>
|
|
156
|
+
</Card.Footer>
|
|
157
|
+
</Card>;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
A themed background, a card with a border and radius, and a button that dips when pressed means
|
|
161
|
+
you are done. Unstyled text on a white screen means the styles are not reaching the bundle — see
|
|
162
|
+
[Troubleshooting](https://panelui.dev/docs/installation#troubleshooting).
|
|
88
163
|
|
|
89
164
|
## Components
|
|
90
165
|
|
|
@@ -246,6 +321,25 @@ the named themes, which the OS `Appearance` API knows nothing about. For the sam
|
|
|
246
321
|
|
|
247
322
|
## FAQ
|
|
248
323
|
|
|
324
|
+
### The first bundle fails with `Unable to resolve module …`
|
|
325
|
+
|
|
326
|
+
A required package is missing. Run the [install command](#1-install-the-packages) again — all of
|
|
327
|
+
it, not just the package named in the error. Metro resolves every import in the library, so this
|
|
328
|
+
happens even for components you never use.
|
|
329
|
+
|
|
330
|
+
### `Cannot use @variant with unknown variant: moon` when building
|
|
331
|
+
|
|
332
|
+
Fixed in 0.22.5 — upgrade with `npx expo install panelui-native`. Before that release the Moon and
|
|
333
|
+
Grass token blocks leaned on variants that only existed in the artifact Uniwind generates from your
|
|
334
|
+
Metro config, so the dev server worked while `npx expo export` and EAS builds failed.
|
|
335
|
+
|
|
336
|
+
### None of my classes do anything
|
|
337
|
+
|
|
338
|
+
In order of likelihood: `metro.config.js` is not in the project root; it does not wrap the config
|
|
339
|
+
in `withUniwindConfig`; `cssEntryFile` does not point at your CSS file; `import './global.css'` is
|
|
340
|
+
missing from the entry file; or the dev server was running when you changed one of those. Full
|
|
341
|
+
list at [Troubleshooting](https://panelui.dev/docs/installation#troubleshooting).
|
|
342
|
+
|
|
249
343
|
### How is PanelUI different from NativeWind?
|
|
250
344
|
|
|
251
345
|
NativeWind is a styling engine; PanelUI is a component library. PanelUI is built on **Uniwind**,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "panelui-native",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.6",
|
|
4
4
|
"description": "High-performance React Native UI components for Expo. Semantic design tokens, powered by Uniwind (Tailwind v4) and Reanimated.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"module": "./lib/module/index.js",
|
package/theme.css
CHANGED
|
@@ -16,6 +16,28 @@
|
|
|
16
16
|
* @source './node_modules/panelui-native/src';
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
/*
|
|
20
|
+
* The named themes declare their own variants, so this file compiles on its
|
|
21
|
+
* own terms.
|
|
22
|
+
*
|
|
23
|
+
* `light` and `dark` exist wherever Uniwind does. The other four are extra
|
|
24
|
+
* themes, and their variants are otherwise only defined in the artifact
|
|
25
|
+
* Uniwind generates from the theme list in a project's Metro config — which
|
|
26
|
+
* that generation step has to compile *this file* to produce. A fresh install
|
|
27
|
+
* therefore had nothing defining `moon` at the moment it was first used: the
|
|
28
|
+
* dev server got away with it because it registers the themes in memory, while
|
|
29
|
+
* a production bundle failed with `Cannot use @variant with unknown variant`.
|
|
30
|
+
*
|
|
31
|
+
* Declared here, the cycle does not exist and neither does the difference
|
|
32
|
+
* between the two. Registering a theme in `extraThemes` is then only about
|
|
33
|
+
* being able to switch to it at runtime, which is what that option reads like
|
|
34
|
+
* it is for.
|
|
35
|
+
*/
|
|
36
|
+
@custom-variant moon (&:where(.moon, .moon *));
|
|
37
|
+
@custom-variant moon-dark (&:where(.moon-dark, .moon-dark *));
|
|
38
|
+
@custom-variant grass (&:where(.grass, .grass *));
|
|
39
|
+
@custom-variant grass-dark (&:where(.grass-dark, .grass-dark *));
|
|
40
|
+
|
|
19
41
|
@theme {
|
|
20
42
|
--color-background: unset;
|
|
21
43
|
--color-foreground: unset;
|