@rific/auto-paper 0.9.5 → 0.10.1
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 +10 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +7 -2
- package/dist/index.mjs +9 -4
- package/package.json +10 -12
- package/src/ThemeProvider.tsx +20 -4
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ Adaptive theming for [`react-native-paper`](https://callstack.github.io/react-na
|
|
|
10
10
|
- System/light/dark appearance with live updates via `Appearance` API
|
|
11
11
|
- Tinted surface, surfaceVariant, outline, and elevation levels derived from the seed
|
|
12
12
|
- Fixed `success`/`warning`/`danger` semantic color roles (each with `on*`/`*Container` variants) alongside MD3's built-in `error`
|
|
13
|
+
- App-wide `fontFamily` override, applied across every Paper typography variant in one prop
|
|
13
14
|
- Optional Redux slice for wiring appearance and color into your store
|
|
14
15
|
- Wrapper components (`Appbar`, `AppearancePicker`, `AutoAppearancePicker`, `AutoPalettePicker`, `BlurView`, `BottomNavigation`, `Button`, `Chip`, `ColorPicker`, `Dialog`, `FAB`, `HarmonyPicker`, `IconButton`, `Menu`, `PalettePicker`, `TextInput`) with prop defaults via context
|
|
15
16
|
- All color utilities exported for standalone use
|
|
@@ -61,6 +62,14 @@ export default function App() {
|
|
|
61
62
|
</AutoPaperProvider>
|
|
62
63
|
```
|
|
63
64
|
|
|
65
|
+
Pass `fontFamily` to reskin every Paper component's text to a custom typeface app-wide, instead of passing `fontFamily` to each individual `Text`/`TextInput`/`Button` yourself:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
<AutoPaperProvider initialValue={{ appearance: 'system', color: '#6750a4' }} fontFamily='Menlo'>
|
|
69
|
+
{/* your app */}
|
|
70
|
+
</AutoPaperProvider>
|
|
71
|
+
```
|
|
72
|
+
|
|
64
73
|
Update theme settings from anywhere inside the tree using `useThemeSettings`:
|
|
65
74
|
|
|
66
75
|
```tsx
|
|
@@ -235,6 +244,7 @@ export default function App() {
|
|
|
235
244
|
| `children` | `ReactNode` | |
|
|
236
245
|
| `defaults` | `PaperDefaults` | Prop defaults for wrapper components (see below) |
|
|
237
246
|
| `expoBlur` | `ExpoBlurModule` | Injects `expo-blur` (`import * as ExpoBlur from 'expo-blur'`) so `<BlurView>` renders the real frosted-glass effect. Omit to always render its solid fallback. |
|
|
247
|
+
| `fontFamily` | `string` | Applied to every Paper typography variant (`bodyLarge`, `headlineMedium`, `labelSmall`, ...) via `configureFonts`'s flat-config mode — each variant keeps its own MD3 fontSize/lineHeight/weight, only fontFamily changes. Omit to keep each platform's system font. |
|
|
238
248
|
| `navigationBar` | `ExpoNavigationBarModule` | Injects `expo-navigation-bar` (`import * as ExpoNavigationBar from 'expo-navigation-bar'`) so the Android nav bar icon style auto-syncs with the theme while a `BottomNavigation` is mounted. Omit (and don't pass `onNavBarChange`) to skip nav bar syncing entirely. |
|
|
239
249
|
| `onNavBarChange` | `(color: string, dark: boolean) => void` | Overrides the built-in nav bar sync: called on Android when the theme changes while a `BottomNavigation` is mounted, instead of the automatic `navigationBar`-driven icon-style sync |
|
|
240
250
|
| `onReady` | `() => void` | Called once when the theme first resolves |
|
package/dist/index.d.mts
CHANGED
|
@@ -305,6 +305,12 @@ type ProviderProps = {
|
|
|
305
305
|
defaults?: PaperDefaults;
|
|
306
306
|
/** Injects expo-blur for `<BlurView>`. Pass `import * as ExpoBlur from 'expo-blur'`; omit to always render BlurView's solid fallback. */
|
|
307
307
|
expoBlur?: ExpoBlurModule;
|
|
308
|
+
/** Applied to every Paper typography variant (bodyLarge, headlineMedium, labelSmall, ...) via
|
|
309
|
+
* `configureFonts`'s flat-config mode — each variant keeps its own MD3 fontSize/lineHeight/weight,
|
|
310
|
+
* only fontFamily changes. The one-line way to reskin an app's whole text to a custom typeface,
|
|
311
|
+
* instead of passing `fontFamily` to every individual Text/TextInput/Button across the app. Omit
|
|
312
|
+
* to keep each platform's system font (MD3's own default). */
|
|
313
|
+
fontFamily?: string;
|
|
308
314
|
initialValue?: Partial<ThemeSettings>;
|
|
309
315
|
/** Injects expo-navigation-bar so the Android nav bar icon style auto-syncs with the theme. Pass `import * as ExpoNavigationBar from 'expo-navigation-bar'`; omit (and don't pass onNavBarChange) to skip nav bar syncing entirely. */
|
|
310
316
|
navigationBar?: ExpoNavigationBarModule;
|
|
@@ -316,7 +322,7 @@ type ProviderProps = {
|
|
|
316
322
|
statusBarProps?: StatusBarProps;
|
|
317
323
|
style?: StyleProp<ViewStyle>;
|
|
318
324
|
};
|
|
319
|
-
declare function Provider({ children, defaults, expoBlur, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }: ProviderProps): react.JSX.Element | null;
|
|
325
|
+
declare function Provider({ children, defaults, expoBlur, fontFamily, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }: ProviderProps): react.JSX.Element | null;
|
|
320
326
|
|
|
321
327
|
declare const useAutoPaperTheme: () => AutoPaperTheme;
|
|
322
328
|
|
package/dist/index.d.ts
CHANGED
|
@@ -305,6 +305,12 @@ type ProviderProps = {
|
|
|
305
305
|
defaults?: PaperDefaults;
|
|
306
306
|
/** Injects expo-blur for `<BlurView>`. Pass `import * as ExpoBlur from 'expo-blur'`; omit to always render BlurView's solid fallback. */
|
|
307
307
|
expoBlur?: ExpoBlurModule;
|
|
308
|
+
/** Applied to every Paper typography variant (bodyLarge, headlineMedium, labelSmall, ...) via
|
|
309
|
+
* `configureFonts`'s flat-config mode — each variant keeps its own MD3 fontSize/lineHeight/weight,
|
|
310
|
+
* only fontFamily changes. The one-line way to reskin an app's whole text to a custom typeface,
|
|
311
|
+
* instead of passing `fontFamily` to every individual Text/TextInput/Button across the app. Omit
|
|
312
|
+
* to keep each platform's system font (MD3's own default). */
|
|
313
|
+
fontFamily?: string;
|
|
308
314
|
initialValue?: Partial<ThemeSettings>;
|
|
309
315
|
/** Injects expo-navigation-bar so the Android nav bar icon style auto-syncs with the theme. Pass `import * as ExpoNavigationBar from 'expo-navigation-bar'`; omit (and don't pass onNavBarChange) to skip nav bar syncing entirely. */
|
|
310
316
|
navigationBar?: ExpoNavigationBarModule;
|
|
@@ -316,7 +322,7 @@ type ProviderProps = {
|
|
|
316
322
|
statusBarProps?: StatusBarProps;
|
|
317
323
|
style?: StyleProp<ViewStyle>;
|
|
318
324
|
};
|
|
319
|
-
declare function Provider({ children, defaults, expoBlur, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }: ProviderProps): react.JSX.Element | null;
|
|
325
|
+
declare function Provider({ children, defaults, expoBlur, fontFamily, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }: ProviderProps): react.JSX.Element | null;
|
|
320
326
|
|
|
321
327
|
declare const useAutoPaperTheme: () => AutoPaperTheme;
|
|
322
328
|
|
package/dist/index.js
CHANGED
|
@@ -685,7 +685,7 @@ var BlurModuleContext = (0, import_react7.createContext)(void 0);
|
|
|
685
685
|
var useBlurModule = () => (0, import_react7.useContext)(BlurModuleContext);
|
|
686
686
|
var ReanimatedModuleContext = (0, import_react7.createContext)(void 0);
|
|
687
687
|
var useReanimatedModule = () => (0, import_react7.useContext)(ReanimatedModuleContext);
|
|
688
|
-
function Provider({ children, defaults, expoBlur, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }) {
|
|
688
|
+
function Provider({ children, defaults, expoBlur, fontFamily, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }) {
|
|
689
689
|
const [settings, setSettings] = (0, import_react7.useState)(() => ({ ...defaultThemeSettings, ...initialValue }));
|
|
690
690
|
const set = (0, import_react7.useCallback)((patch) => {
|
|
691
691
|
setSettings((prev) => ({ ...prev, ...patch }));
|
|
@@ -701,7 +701,12 @@ function Provider({ children, defaults, expoBlur, initialValue, navigationBar, o
|
|
|
701
701
|
onChangeRef.current?.(settings);
|
|
702
702
|
}
|
|
703
703
|
}, [settings]);
|
|
704
|
-
const
|
|
704
|
+
const computedTheme = useComputedTheme(settings.appearance, settings.color, settings.harmony);
|
|
705
|
+
const theme = (0, import_react7.useMemo)(() => {
|
|
706
|
+
if (!computedTheme) return null;
|
|
707
|
+
if (!fontFamily) return computedTheme;
|
|
708
|
+
return { ...computedTheme, fonts: (0, import_react_native_paper4.configureFonts)({ config: { fontFamily } }) };
|
|
709
|
+
}, [computedTheme, fontFamily]);
|
|
705
710
|
const called = (0, import_react7.useRef)(false);
|
|
706
711
|
(0, import_react7.useEffect)(() => {
|
|
707
712
|
if (theme && !called.current) {
|
package/dist/index.mjs
CHANGED
|
@@ -423,9 +423,9 @@ import { Dialog as PaperDialog, Portal, useTheme as useTheme3 } from "react-nati
|
|
|
423
423
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
424
424
|
|
|
425
425
|
// src/ThemeProvider.tsx
|
|
426
|
-
import { createContext as createContext3, useCallback as useCallback2, useContext as useContext4, useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
426
|
+
import { createContext as createContext3, useCallback as useCallback2, useContext as useContext4, useEffect as useEffect2, useMemo, useRef, useState as useState3 } from "react";
|
|
427
427
|
import { StatusBar as StatusBar2, StyleSheet, View } from "react-native";
|
|
428
|
-
import { Provider as PaperProvider } from "react-native-paper";
|
|
428
|
+
import { configureFonts, Provider as PaperProvider } from "react-native-paper";
|
|
429
429
|
|
|
430
430
|
// src/useComputedTheme.ts
|
|
431
431
|
import { useCallback, useEffect, useState as useState2 } from "react";
|
|
@@ -603,7 +603,7 @@ var BlurModuleContext = createContext3(void 0);
|
|
|
603
603
|
var useBlurModule = () => useContext4(BlurModuleContext);
|
|
604
604
|
var ReanimatedModuleContext = createContext3(void 0);
|
|
605
605
|
var useReanimatedModule = () => useContext4(ReanimatedModuleContext);
|
|
606
|
-
function Provider({ children, defaults, expoBlur, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }) {
|
|
606
|
+
function Provider({ children, defaults, expoBlur, fontFamily, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }) {
|
|
607
607
|
const [settings, setSettings] = useState3(() => ({ ...defaultThemeSettings, ...initialValue }));
|
|
608
608
|
const set = useCallback2((patch) => {
|
|
609
609
|
setSettings((prev) => ({ ...prev, ...patch }));
|
|
@@ -619,7 +619,12 @@ function Provider({ children, defaults, expoBlur, initialValue, navigationBar, o
|
|
|
619
619
|
onChangeRef.current?.(settings);
|
|
620
620
|
}
|
|
621
621
|
}, [settings]);
|
|
622
|
-
const
|
|
622
|
+
const computedTheme = useComputedTheme(settings.appearance, settings.color, settings.harmony);
|
|
623
|
+
const theme = useMemo(() => {
|
|
624
|
+
if (!computedTheme) return null;
|
|
625
|
+
if (!fontFamily) return computedTheme;
|
|
626
|
+
return { ...computedTheme, fonts: configureFonts({ config: { fontFamily } }) };
|
|
627
|
+
}, [computedTheme, fontFamily]);
|
|
623
628
|
const called = useRef(false);
|
|
624
629
|
useEffect2(() => {
|
|
625
630
|
if (theme && !called.current) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rific/auto-paper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Adaptive react-native-paper theming: triadic palette from a seed color + system/light/dark appearance",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -50,35 +50,34 @@
|
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
52
52
|
"build:watch": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
53
|
+
"ci": "npm run lint && npm test && npm run typecheck && npm run build",
|
|
53
54
|
"fix": "eslint --fix",
|
|
54
55
|
"lint": "eslint",
|
|
55
56
|
"prepublishOnly": "npm run build",
|
|
56
57
|
"release": "git push --follow-tags",
|
|
57
|
-
"release:major": "npm version major &&
|
|
58
|
-
"release:minor": "npm version minor &&
|
|
59
|
-
"release:patch": "npm version patch &&
|
|
58
|
+
"release:major": "npm version major && npm run release",
|
|
59
|
+
"release:minor": "npm version minor && npm run release",
|
|
60
|
+
"release:patch": "npm version patch && npm run release",
|
|
60
61
|
"test": "jest",
|
|
61
62
|
"test:watch": "jest --watchAll",
|
|
62
63
|
"typecheck": "tsc --noEmit",
|
|
63
|
-
"preversion": "npm run
|
|
64
|
+
"preversion": "npm run ci"
|
|
64
65
|
},
|
|
66
|
+
"prettier": "@infinitetoken/eslint-config/prettier",
|
|
65
67
|
"overrides": {
|
|
66
68
|
"esbuild": "0.28.1"
|
|
67
69
|
},
|
|
68
70
|
"devDependencies": {
|
|
71
|
+
"@infinitetoken/eslint-config": "^0.1.4",
|
|
72
|
+
"@infinitetoken/tsconfig": "^0.1.1",
|
|
69
73
|
"@reduxjs/toolkit": "^2.0.0",
|
|
70
74
|
"@testing-library/dom": "^10.4.1",
|
|
71
75
|
"@testing-library/react": "^16.0.0",
|
|
72
76
|
"@types/jest": "^30.0.0",
|
|
73
77
|
"@types/react": "^19.0.0",
|
|
74
|
-
"@typescript-eslint/parser": "^8.59.3",
|
|
75
78
|
"eslint": "^9.39.4",
|
|
76
|
-
"eslint-config-prettier": "^10.1.8",
|
|
77
|
-
"eslint-plugin-package-json": "^1.0.0",
|
|
78
|
-
"eslint-plugin-prettier": "^5.5.5",
|
|
79
79
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
80
80
|
"eslint-plugin-react-native": "^5.0.0",
|
|
81
|
-
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
82
81
|
"expo-blur": "^56.0.3",
|
|
83
82
|
"expo-navigation-bar": "^56.0.3",
|
|
84
83
|
"jest": "^30.0.0",
|
|
@@ -92,8 +91,7 @@
|
|
|
92
91
|
"ts-jest": "^29.4.9",
|
|
93
92
|
"ts-node": "^10.9.2",
|
|
94
93
|
"tsup": "^8.0.0",
|
|
95
|
-
"typescript": "^6.0.3"
|
|
96
|
-
"typescript-eslint": "^8.59.3"
|
|
94
|
+
"typescript": "^6.0.3"
|
|
97
95
|
},
|
|
98
96
|
"peerDependencies": {
|
|
99
97
|
"expo-blur": ">=56.0.0",
|
package/src/ThemeProvider.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createContext, type ReactNode, useCallback, useContext, useEffect, useRef, useState } from 'react'
|
|
1
|
+
import { createContext, type ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'
|
|
2
2
|
import { StatusBar, type StatusBarProps, type StyleProp, StyleSheet, View, type ViewStyle } from 'react-native'
|
|
3
|
-
import { Provider as PaperProvider } from 'react-native-paper'
|
|
3
|
+
import { configureFonts, Provider as PaperProvider } from 'react-native-paper'
|
|
4
4
|
|
|
5
5
|
import type { ExpoBlurModule } from './components/BlurView'
|
|
6
6
|
import type { ReanimatedModule } from './components/Dialog'
|
|
@@ -29,6 +29,12 @@ export type ProviderProps = {
|
|
|
29
29
|
defaults?: PaperDefaults
|
|
30
30
|
/** Injects expo-blur for `<BlurView>`. Pass `import * as ExpoBlur from 'expo-blur'`; omit to always render BlurView's solid fallback. */
|
|
31
31
|
expoBlur?: ExpoBlurModule
|
|
32
|
+
/** Applied to every Paper typography variant (bodyLarge, headlineMedium, labelSmall, ...) via
|
|
33
|
+
* `configureFonts`'s flat-config mode — each variant keeps its own MD3 fontSize/lineHeight/weight,
|
|
34
|
+
* only fontFamily changes. The one-line way to reskin an app's whole text to a custom typeface,
|
|
35
|
+
* instead of passing `fontFamily` to every individual Text/TextInput/Button across the app. Omit
|
|
36
|
+
* to keep each platform's system font (MD3's own default). */
|
|
37
|
+
fontFamily?: string
|
|
32
38
|
initialValue?: Partial<ThemeSettings>
|
|
33
39
|
/** Injects expo-navigation-bar so the Android nav bar icon style auto-syncs with the theme. Pass `import * as ExpoNavigationBar from 'expo-navigation-bar'`; omit (and don't pass onNavBarChange) to skip nav bar syncing entirely. */
|
|
34
40
|
navigationBar?: ExpoNavigationBarModule
|
|
@@ -41,7 +47,7 @@ export type ProviderProps = {
|
|
|
41
47
|
style?: StyleProp<ViewStyle>
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
export function Provider({ children, defaults, expoBlur, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }: ProviderProps) {
|
|
50
|
+
export function Provider({ children, defaults, expoBlur, fontFamily, initialValue, navigationBar, onChange, onNavBarChange, onReady, reanimated, statusBarProps, style }: ProviderProps) {
|
|
45
51
|
const [settings, setSettings] = useState<ThemeSettings>(() => ({ ...defaultThemeSettings, ...initialValue }))
|
|
46
52
|
|
|
47
53
|
const set = useCallback((patch: Partial<ThemeSettings>) => {
|
|
@@ -60,7 +66,17 @@ export function Provider({ children, defaults, expoBlur, initialValue, navigatio
|
|
|
60
66
|
}
|
|
61
67
|
}, [settings])
|
|
62
68
|
|
|
63
|
-
const
|
|
69
|
+
const computedTheme = useComputedTheme(settings.appearance, settings.color, settings.harmony)
|
|
70
|
+
// Layered on top of useComputedTheme's own output rather than folded into it — that hook only
|
|
71
|
+
// ever recomputes for a color/appearance/harmony change, and fontFamily is a completely
|
|
72
|
+
// independent axis; merging it there would mean either re-running the whole color computation on
|
|
73
|
+
// every fontFamily change (wasteful) or threading fontFamily through as a fourth computeTheme
|
|
74
|
+
// dependency for a value it never actually uses.
|
|
75
|
+
const theme = useMemo(() => {
|
|
76
|
+
if (!computedTheme) return null
|
|
77
|
+
if (!fontFamily) return computedTheme
|
|
78
|
+
return { ...computedTheme, fonts: configureFonts({ config: { fontFamily } }) }
|
|
79
|
+
}, [computedTheme, fontFamily])
|
|
64
80
|
const called = useRef(false)
|
|
65
81
|
|
|
66
82
|
useEffect(() => {
|