@rific/auto-paper 0.1.2 → 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/README.md CHANGED
@@ -8,6 +8,7 @@ Adaptive theming for [`react-native-paper`](https://callstack.github.io/react-na
8
8
  - System/light/dark appearance with live updates via `Appearance` API
9
9
  - Tinted surface, surfaceVariant, outline, and elevation levels derived from the seed
10
10
  - Optional Redux slice for wiring appearance and color into your store
11
+ - Wrapper components (`Appbar`, `BottomNavigation`, `Button`, `Chip`, `FAB`, `IconButton`, `TextInput`) with prop defaults via context
11
12
  - All color utilities exported for standalone use
12
13
 
13
14
  ## Installation
@@ -22,6 +23,12 @@ Peer dependencies:
22
23
  npm install react-native react-native-paper
23
24
  ```
24
25
 
26
+ Optional — needed only if you use `BottomNavigation` on Android (syncs the system navigation bar color):
27
+
28
+ ```bash
29
+ npm install expo-navigation-bar
30
+ ```
31
+
25
32
  ## Usage
26
33
 
27
34
  ### Provider (simplest)
@@ -49,6 +56,31 @@ export default function App() {
49
56
  </AutoPaperProvider>
50
57
  ```
51
58
 
59
+ ### With component defaults
60
+
61
+ Pass a `defaults` object to `Provider` to set prop defaults for any of the included wrapper components. Each component merges defaults under its own props, so per-instance props always win:
62
+
63
+ ```tsx
64
+ import { Button, Chip, Provider as AutoPaperProvider } from '@rific/auto-paper'
65
+
66
+ <AutoPaperProvider
67
+ appearance={appearance}
68
+ color={color}
69
+ defaults={{
70
+ AppbarHeader: { elevated: true },
71
+ BottomNavigation: { labeled: false },
72
+ Button: { mode: 'contained' },
73
+ Chip: { compact: true },
74
+ }}
75
+ >
76
+ <Button>Save</Button> {/* mode="contained" from defaults */}
77
+ <Button mode="text">Cancel</Button> {/* overrides default */}
78
+ <Chip>Tag</Chip> {/* compact=true from defaults */}
79
+ </AutoPaperProvider>
80
+ ```
81
+
82
+ Available wrapper components: `Appbar`, `BottomNavigation`, `Button`, `Chip`, `FAB`, `IconButton`, `TextInput`. Each is a thin wrapper around the matching `react-native-paper` component and accepts the same props.
83
+
52
84
  ### With Redux
53
85
 
54
86
  The package exports an optional Redux slice. Use `createThemeReducer` to register it in your store with a custom initial color:
@@ -132,6 +164,7 @@ export default function App() {
132
164
  | `appearance` | `'system' \| 'light' \| 'dark'` | Appearance mode |
133
165
  | `color` | `string` | Seed color (hex, rgb, or CSS name) |
134
166
  | `children` | `ReactNode` | |
167
+ | `defaults` | `PaperDefaults` | Prop defaults for wrapper components (see below) |
135
168
  | `onReady` | `() => void` | Called once when the theme first resolves |
136
169
  | `statusBarProps` | `StatusBarProps` | Spread over the auto-derived `StatusBar` defaults |
137
170
  | `style` | `StyleProp<ViewStyle>` | Applied to the wrapper `View` |
@@ -144,6 +177,62 @@ Returns `MD3Theme | null`. `null` on the first render while the theme computes.
144
177
  const theme = useComputedTheme('system', '#6750a4')
145
178
  ```
146
179
 
180
+ ### `Appbar`
181
+
182
+ A thin wrapper around `react-native-paper`'s `Appbar` that automatically syncs `StatusBar` background color and bar style to the current theme surface color.
183
+
184
+ ```tsx
185
+ import { Appbar } from '@rific/auto-paper'
186
+
187
+ <Appbar.Header>
188
+ <Appbar.BackAction onPress={router.back} />
189
+ <Appbar.Content title="Settings" />
190
+ <Appbar.Action icon="magnify" onPress={onSearch} />
191
+ </Appbar.Header>
192
+ ```
193
+
194
+ `Appbar.Content`, `Appbar.Action`, and `Appbar.BackAction` are re-exported directly from `react-native-paper`. Only `Appbar.Header` is wrapped — it applies `AppbarHeader` defaults from context and renders the synced `StatusBar`.
195
+
196
+ ### `BottomNavigation`
197
+
198
+ A thin wrapper around `react-native-paper`'s `BottomNavigation` that automatically syncs the Android system navigation bar color and button style to the current theme surface color (requires `expo-navigation-bar`; silently no-ops when not installed).
199
+
200
+ ```tsx
201
+ import { BottomNavigation } from '@rific/auto-paper'
202
+
203
+ <BottomNavigation
204
+ navigationState={{ index, routes }}
205
+ onIndexChange={setIndex}
206
+ renderScene={BottomNavigation.SceneMap({ home: HomeScreen, settings: SettingsScreen })}
207
+ />
208
+ ```
209
+
210
+ `BottomNavigation.Bar` and `BottomNavigation.SceneMap` are also available and both sync the navigation bar.
211
+
212
+ ### `PaperDefaults` / `usePaperDefaults`
213
+
214
+ `PaperDefaults` is the type for the `defaults` prop on `Provider`:
215
+
216
+ ```ts
217
+ type PaperDefaults = {
218
+ AppbarHeader?: Partial<AppbarHeaderProps>
219
+ BottomNavigation?: Partial<BottomNavigationProps<BottomNavigationRoute>>
220
+ Button?: Partial<ButtonProps>
221
+ Chip?: Partial<ChipProps>
222
+ FAB?: Partial<FABProps>
223
+ IconButton?: Partial<IconButtonProps>
224
+ TextInput?: Partial<TextInputProps>
225
+ }
226
+ ```
227
+
228
+ Use `usePaperDefaults` if you need to read the defaults in a custom component:
229
+
230
+ ```ts
231
+ import { usePaperDefaults } from '@rific/auto-paper'
232
+
233
+ const defaults = usePaperDefaults()
234
+ ```
235
+
147
236
  ### `createThemeReducer(initialState?)`
148
237
 
149
238
  Returns a Redux reducer with an optional initial state override. Useful for setting a custom default color without dispatching an action at startup.
package/dist/index.d.mts CHANGED
@@ -1,10 +1,63 @@
1
+ import * as react_native_paper_lib_typescript_utils_forwardRef from 'react-native-paper/lib/typescript/utils/forwardRef';
2
+ import * as react_native from 'react-native';
3
+ import { TextInput as TextInput$1, StatusBarProps, StyleProp, ViewStyle } from 'react-native';
4
+ import * as react from 'react';
5
+ import react__default, { ReactNode } from 'react';
6
+ import * as react_native_paper from 'react-native-paper';
7
+ import { AppbarHeaderProps, BottomNavigationRoute, BottomNavigationProps, BottomNavigation as BottomNavigation$1, ButtonProps, ChipProps, FABProps, IconButtonProps, TextInputProps, MD3Theme } from 'react-native-paper';
8
+ export { AppbarHeaderProps, BottomNavigationProps, BottomNavigationRoute, ButtonProps, ChipProps, FABProps, IconButtonProps, TextInputProps } from 'react-native-paper';
9
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
10
  import * as _reduxjs_toolkit from '@reduxjs/toolkit';
2
11
  import { PayloadAction } from '@reduxjs/toolkit';
3
12
  import * as redux from 'redux';
4
- import { MD3Theme } from 'react-native-paper';
5
- import * as react from 'react';
6
- import { ReactNode } from 'react';
7
- import { StatusBarProps, StyleProp, ViewStyle } from 'react-native';
13
+
14
+ declare function Header({ style, ...props }: AppbarHeaderProps): react_jsx_runtime.JSX.Element;
15
+ declare const Appbar: {
16
+ Header: typeof Header;
17
+ Content: {
18
+ ({ color: titleColor, subtitle, subtitleStyle, onPress, disabled, style, titleRef, titleStyle, title, titleMaxFontSizeMultiplier, mode, theme: themeOverrides, testID, ...rest }: react_native_paper.Props): react.JSX.Element;
19
+ displayName: string;
20
+ };
21
+ Action: react_native_paper_lib_typescript_utils_forwardRef.ForwardRefComponent<react_native.View, react_native_paper.AppbarActionProps>;
22
+ BackAction: react_native_paper_lib_typescript_utils_forwardRef.ForwardRefComponent<react_native.View, react_native_paper.AppbarBackActionProps>;
23
+ };
24
+
25
+ declare function BottomNavigationComponent<Route extends BottomNavigationRoute>(props: BottomNavigationProps<Route>): react_jsx_runtime.JSX.Element;
26
+ declare namespace BottomNavigationComponent {
27
+ var Bar: (props: BarProps) => react_jsx_runtime.JSX.Element;
28
+ var SceneMap: <Route extends BottomNavigationRoute>(scenes: {
29
+ [key: string]: react__default.ComponentType<{
30
+ route: Route;
31
+ jumpTo: (key: string) => void;
32
+ }>;
33
+ }) => ({ route, jumpTo, }: {
34
+ route: Route;
35
+ jumpTo: (key: string) => void;
36
+ }) => react__default.JSX.Element;
37
+ }
38
+ type BarProps = react__default.ComponentProps<typeof BottomNavigation$1.Bar>;
39
+ declare const BottomNavigation: typeof BottomNavigationComponent;
40
+
41
+ declare function Button(props: ButtonProps): react_jsx_runtime.JSX.Element;
42
+
43
+ declare function Chip(props: ChipProps): react_jsx_runtime.JSX.Element;
44
+
45
+ declare function FAB(props: FABProps): react_jsx_runtime.JSX.Element;
46
+
47
+ declare function IconButton(props: IconButtonProps): react_jsx_runtime.JSX.Element;
48
+
49
+ declare const TextInput: react.ForwardRefExoticComponent<Omit<TextInputProps, "ref"> & react.RefAttributes<TextInput$1>>;
50
+
51
+ type PaperDefaults = {
52
+ AppbarHeader?: Partial<AppbarHeaderProps>;
53
+ BottomNavigation?: Partial<BottomNavigationProps<BottomNavigationRoute>>;
54
+ Button?: Partial<ButtonProps>;
55
+ Chip?: Partial<ChipProps>;
56
+ FAB?: Partial<FABProps>;
57
+ IconButton?: Partial<IconButtonProps>;
58
+ TextInput?: Partial<TextInputProps>;
59
+ };
60
+ declare function usePaperDefaults(): PaperDefaults;
8
61
 
9
62
  type ThemeAppearance = 'system' | 'light' | 'dark';
10
63
  declare function useComputedTheme(appearance: ThemeAppearance, color: string): MD3Theme | null;
@@ -39,11 +92,12 @@ type ProviderProps = {
39
92
  appearance: ThemeAppearance;
40
93
  color: string;
41
94
  children: ReactNode;
95
+ defaults?: PaperDefaults;
42
96
  onReady?: () => void;
43
97
  statusBarProps?: StatusBarProps;
44
98
  style?: StyleProp<ViewStyle>;
45
99
  };
46
- declare function Provider({ appearance, color, children, onReady, statusBarProps, style }: ProviderProps): react.JSX.Element | null;
100
+ declare function Provider({ appearance, color, children, defaults, onReady, statusBarProps, style }: ProviderProps): react_jsx_runtime.JSX.Element | null;
47
101
 
48
102
  declare const getBlendedColor: (foreground: string, background: string, alpha: number) => string;
49
103
 
@@ -66,4 +120,4 @@ declare function getTriadicPalette(primaryColor: string): TriadicPalette;
66
120
 
67
121
  declare const isDarkColor: (value: string) => boolean;
68
122
 
69
- export { Provider, type ProviderProps, type RGB, type ThemeAppearance, type ThemeState, type TriadicPalette, createThemeReducer, getBlendedColor, getHex, getRgb, getTriadicPalette, isDarkColor, selectThemeAppearance, selectThemeColor, themeActions, themeReducer, useComputedTheme };
123
+ export { Appbar, BottomNavigation, Button, Chip, FAB, IconButton, type PaperDefaults, Provider, type ProviderProps, type RGB, TextInput, type ThemeAppearance, type ThemeState, type TriadicPalette, createThemeReducer, getBlendedColor, getHex, getRgb, getTriadicPalette, isDarkColor, selectThemeAppearance, selectThemeColor, themeActions, themeReducer, useComputedTheme, usePaperDefaults };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,63 @@
1
+ import * as react_native_paper_lib_typescript_utils_forwardRef from 'react-native-paper/lib/typescript/utils/forwardRef';
2
+ import * as react_native from 'react-native';
3
+ import { TextInput as TextInput$1, StatusBarProps, StyleProp, ViewStyle } from 'react-native';
4
+ import * as react from 'react';
5
+ import react__default, { ReactNode } from 'react';
6
+ import * as react_native_paper from 'react-native-paper';
7
+ import { AppbarHeaderProps, BottomNavigationRoute, BottomNavigationProps, BottomNavigation as BottomNavigation$1, ButtonProps, ChipProps, FABProps, IconButtonProps, TextInputProps, MD3Theme } from 'react-native-paper';
8
+ export { AppbarHeaderProps, BottomNavigationProps, BottomNavigationRoute, ButtonProps, ChipProps, FABProps, IconButtonProps, TextInputProps } from 'react-native-paper';
9
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
10
  import * as _reduxjs_toolkit from '@reduxjs/toolkit';
2
11
  import { PayloadAction } from '@reduxjs/toolkit';
3
12
  import * as redux from 'redux';
4
- import { MD3Theme } from 'react-native-paper';
5
- import * as react from 'react';
6
- import { ReactNode } from 'react';
7
- import { StatusBarProps, StyleProp, ViewStyle } from 'react-native';
13
+
14
+ declare function Header({ style, ...props }: AppbarHeaderProps): react_jsx_runtime.JSX.Element;
15
+ declare const Appbar: {
16
+ Header: typeof Header;
17
+ Content: {
18
+ ({ color: titleColor, subtitle, subtitleStyle, onPress, disabled, style, titleRef, titleStyle, title, titleMaxFontSizeMultiplier, mode, theme: themeOverrides, testID, ...rest }: react_native_paper.Props): react.JSX.Element;
19
+ displayName: string;
20
+ };
21
+ Action: react_native_paper_lib_typescript_utils_forwardRef.ForwardRefComponent<react_native.View, react_native_paper.AppbarActionProps>;
22
+ BackAction: react_native_paper_lib_typescript_utils_forwardRef.ForwardRefComponent<react_native.View, react_native_paper.AppbarBackActionProps>;
23
+ };
24
+
25
+ declare function BottomNavigationComponent<Route extends BottomNavigationRoute>(props: BottomNavigationProps<Route>): react_jsx_runtime.JSX.Element;
26
+ declare namespace BottomNavigationComponent {
27
+ var Bar: (props: BarProps) => react_jsx_runtime.JSX.Element;
28
+ var SceneMap: <Route extends BottomNavigationRoute>(scenes: {
29
+ [key: string]: react__default.ComponentType<{
30
+ route: Route;
31
+ jumpTo: (key: string) => void;
32
+ }>;
33
+ }) => ({ route, jumpTo, }: {
34
+ route: Route;
35
+ jumpTo: (key: string) => void;
36
+ }) => react__default.JSX.Element;
37
+ }
38
+ type BarProps = react__default.ComponentProps<typeof BottomNavigation$1.Bar>;
39
+ declare const BottomNavigation: typeof BottomNavigationComponent;
40
+
41
+ declare function Button(props: ButtonProps): react_jsx_runtime.JSX.Element;
42
+
43
+ declare function Chip(props: ChipProps): react_jsx_runtime.JSX.Element;
44
+
45
+ declare function FAB(props: FABProps): react_jsx_runtime.JSX.Element;
46
+
47
+ declare function IconButton(props: IconButtonProps): react_jsx_runtime.JSX.Element;
48
+
49
+ declare const TextInput: react.ForwardRefExoticComponent<Omit<TextInputProps, "ref"> & react.RefAttributes<TextInput$1>>;
50
+
51
+ type PaperDefaults = {
52
+ AppbarHeader?: Partial<AppbarHeaderProps>;
53
+ BottomNavigation?: Partial<BottomNavigationProps<BottomNavigationRoute>>;
54
+ Button?: Partial<ButtonProps>;
55
+ Chip?: Partial<ChipProps>;
56
+ FAB?: Partial<FABProps>;
57
+ IconButton?: Partial<IconButtonProps>;
58
+ TextInput?: Partial<TextInputProps>;
59
+ };
60
+ declare function usePaperDefaults(): PaperDefaults;
8
61
 
9
62
  type ThemeAppearance = 'system' | 'light' | 'dark';
10
63
  declare function useComputedTheme(appearance: ThemeAppearance, color: string): MD3Theme | null;
@@ -39,11 +92,12 @@ type ProviderProps = {
39
92
  appearance: ThemeAppearance;
40
93
  color: string;
41
94
  children: ReactNode;
95
+ defaults?: PaperDefaults;
42
96
  onReady?: () => void;
43
97
  statusBarProps?: StatusBarProps;
44
98
  style?: StyleProp<ViewStyle>;
45
99
  };
46
- declare function Provider({ appearance, color, children, onReady, statusBarProps, style }: ProviderProps): react.JSX.Element | null;
100
+ declare function Provider({ appearance, color, children, defaults, onReady, statusBarProps, style }: ProviderProps): react_jsx_runtime.JSX.Element | null;
47
101
 
48
102
  declare const getBlendedColor: (foreground: string, background: string, alpha: number) => string;
49
103
 
@@ -66,4 +120,4 @@ declare function getTriadicPalette(primaryColor: string): TriadicPalette;
66
120
 
67
121
  declare const isDarkColor: (value: string) => boolean;
68
122
 
69
- export { Provider, type ProviderProps, type RGB, type ThemeAppearance, type ThemeState, type TriadicPalette, createThemeReducer, getBlendedColor, getHex, getRgb, getTriadicPalette, isDarkColor, selectThemeAppearance, selectThemeColor, themeActions, themeReducer, useComputedTheme };
123
+ export { Appbar, BottomNavigation, Button, Chip, FAB, IconButton, type PaperDefaults, Provider, type ProviderProps, type RGB, TextInput, type ThemeAppearance, type ThemeState, type TriadicPalette, createThemeReducer, getBlendedColor, getHex, getRgb, getTriadicPalette, isDarkColor, selectThemeAppearance, selectThemeColor, themeActions, themeReducer, useComputedTheme, usePaperDefaults };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
9
  var __export = (target, all) => {
@@ -16,13 +18,28 @@ var __copyProps = (to, from, except, desc) => {
16
18
  }
17
19
  return to;
18
20
  };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
19
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
30
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
31
 
22
32
  // src/index.ts
23
33
  var index_exports = {};
24
34
  __export(index_exports, {
35
+ Appbar: () => Appbar,
36
+ BottomNavigation: () => BottomNavigation,
37
+ Button: () => Button,
38
+ Chip: () => Chip,
39
+ FAB: () => FAB,
40
+ IconButton: () => IconButton,
25
41
  Provider: () => Provider,
42
+ TextInput: () => TextInput,
26
43
  createThemeReducer: () => createThemeReducer,
27
44
  getBlendedColor: () => getBlendedColor,
28
45
  getHex: () => getHex,
@@ -33,10 +50,109 @@ __export(index_exports, {
33
50
  selectThemeColor: () => selectThemeColor,
34
51
  themeActions: () => themeActions,
35
52
  themeReducer: () => themeReducer,
36
- useComputedTheme: () => useComputedTheme
53
+ useComputedTheme: () => useComputedTheme,
54
+ usePaperDefaults: () => usePaperDefaults
37
55
  });
38
56
  module.exports = __toCommonJS(index_exports);
39
57
 
58
+ // src/components/Appbar.tsx
59
+ var import_react_native = require("react-native");
60
+ var import_react_native_paper = require("react-native-paper");
61
+
62
+ // src/PaperDefaultsContext.tsx
63
+ var import_react = require("react");
64
+ var PaperDefaultsContext = (0, import_react.createContext)({});
65
+ function usePaperDefaults() {
66
+ return (0, import_react.useContext)(PaperDefaultsContext);
67
+ }
68
+
69
+ // src/components/Appbar.tsx
70
+ var import_jsx_runtime = require("react/jsx-runtime");
71
+ function Header({ style, ...props }) {
72
+ const defaults = usePaperDefaults();
73
+ const theme = (0, import_react_native_paper.useTheme)();
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.StatusBar, { backgroundColor: theme.colors.surface, barStyle: theme.dark ? "light-content" : "dark-content" }),
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Appbar.Header, { ...defaults.AppbarHeader, ...props, style })
77
+ ] });
78
+ }
79
+ var Appbar = {
80
+ Header,
81
+ Content: import_react_native_paper.Appbar.Content,
82
+ Action: import_react_native_paper.Appbar.Action,
83
+ BackAction: import_react_native_paper.Appbar.BackAction
84
+ };
85
+
86
+ // src/components/BottomNavigation.tsx
87
+ var import_react2 = require("react");
88
+ var import_react_native2 = require("react-native");
89
+ var import_react_native_paper2 = require("react-native-paper");
90
+ var import_jsx_runtime2 = require("react/jsx-runtime");
91
+ function useNavigationBarSync() {
92
+ const theme = (0, import_react_native_paper2.useTheme)();
93
+ (0, import_react2.useEffect)(() => {
94
+ if (import_react_native2.Platform.OS !== "android") return;
95
+ import("expo-navigation-bar").then(({ setBackgroundColorAsync, setButtonStyleAsync }) => {
96
+ setBackgroundColorAsync(theme.colors.surface);
97
+ setButtonStyleAsync(theme.dark ? "light" : "dark");
98
+ }).catch(() => {
99
+ });
100
+ }, [theme]);
101
+ }
102
+ function BottomNavigationComponent(props) {
103
+ const defaults = usePaperDefaults();
104
+ useNavigationBarSync();
105
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.BottomNavigation, { ...defaults.BottomNavigation, ...props });
106
+ }
107
+ function Bar(props) {
108
+ useNavigationBarSync();
109
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.BottomNavigation.Bar, { ...props });
110
+ }
111
+ BottomNavigationComponent.Bar = Bar;
112
+ BottomNavigationComponent.SceneMap = import_react_native_paper2.BottomNavigation.SceneMap;
113
+ var BottomNavigation = BottomNavigationComponent;
114
+
115
+ // src/components/Button.tsx
116
+ var import_react_native_paper3 = require("react-native-paper");
117
+ var import_jsx_runtime3 = require("react/jsx-runtime");
118
+ function Button(props) {
119
+ const defaults = usePaperDefaults();
120
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Button, { ...defaults.Button, ...props });
121
+ }
122
+
123
+ // src/components/Chip.tsx
124
+ var import_react_native_paper4 = require("react-native-paper");
125
+ var import_jsx_runtime4 = require("react/jsx-runtime");
126
+ function Chip(props) {
127
+ const defaults = usePaperDefaults();
128
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Chip, { ...defaults.Chip, ...props });
129
+ }
130
+
131
+ // src/components/FAB.tsx
132
+ var import_react_native_paper5 = require("react-native-paper");
133
+ var import_jsx_runtime5 = require("react/jsx-runtime");
134
+ function FAB(props) {
135
+ const defaults = usePaperDefaults();
136
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native_paper5.FAB, { ...defaults.FAB, ...props });
137
+ }
138
+
139
+ // src/components/IconButton.tsx
140
+ var import_react_native_paper6 = require("react-native-paper");
141
+ var import_jsx_runtime6 = require("react/jsx-runtime");
142
+ function IconButton(props) {
143
+ const defaults = usePaperDefaults();
144
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper6.IconButton, { ...defaults.IconButton, ...props });
145
+ }
146
+
147
+ // src/components/TextInput.tsx
148
+ var import_react3 = require("react");
149
+ var import_react_native_paper7 = require("react-native-paper");
150
+ var import_jsx_runtime7 = require("react/jsx-runtime");
151
+ var TextInput = (0, import_react3.forwardRef)(function TextInput2(props, ref) {
152
+ const defaults = usePaperDefaults();
153
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper7.TextInput, { ref, ...defaults.TextInput, ...props });
154
+ });
155
+
40
156
  // node_modules/redux/dist/redux.mjs
41
157
  var randomString = () => Math.random().toString(36).substring(7).split("").join(".");
42
158
  var ActionTypes = {
@@ -1603,14 +1719,14 @@ var selectThemeAppearance = (state) => state.appearance;
1603
1719
  var selectThemeColor = (state) => state.color;
1604
1720
 
1605
1721
  // src/ThemeProvider.tsx
1606
- var import_react2 = require("react");
1607
- var import_react_native2 = require("react-native");
1608
- var import_react_native_paper2 = require("react-native-paper");
1722
+ var import_react5 = require("react");
1723
+ var import_react_native4 = require("react-native");
1724
+ var import_react_native_paper9 = require("react-native-paper");
1609
1725
 
1610
1726
  // src/useComputedTheme.ts
1611
- var import_react = require("react");
1612
- var import_react_native = require("react-native");
1613
- var import_react_native_paper = require("react-native-paper");
1727
+ var import_react4 = require("react");
1728
+ var import_react_native3 = require("react-native");
1729
+ var import_react_native_paper8 = require("react-native-paper");
1614
1730
 
1615
1731
  // src/utils/colorNames.ts
1616
1732
  var colorNames = {
@@ -1921,12 +2037,12 @@ var isDarkColor = (value) => {
1921
2037
 
1922
2038
  // src/useComputedTheme.ts
1923
2039
  function useComputedTheme(appearance, color) {
1924
- const [theme, setTheme] = (0, import_react.useState)(null);
1925
- const computeTheme = (0, import_react.useCallback)(() => {
2040
+ const [theme, setTheme] = (0, import_react4.useState)(null);
2041
+ const computeTheme = (0, import_react4.useCallback)(() => {
1926
2042
  let resolved = appearance;
1927
- if (resolved === "system") resolved = import_react_native.Appearance.getColorScheme();
2043
+ if (resolved === "system") resolved = import_react_native3.Appearance.getColorScheme();
1928
2044
  if (resolved === "no-preference" || !resolved) resolved = "light";
1929
- const base = resolved === "dark" ? import_react_native_paper.MD3DarkTheme : import_react_native_paper.MD3LightTheme;
2045
+ const base = resolved === "dark" ? import_react_native_paper8.MD3DarkTheme : import_react_native_paper8.MD3LightTheme;
1930
2046
  const _theme = {
1931
2047
  ...base,
1932
2048
  colors: {
@@ -1965,35 +2081,46 @@ function useComputedTheme(appearance, color) {
1965
2081
  };
1966
2082
  setTheme(_theme);
1967
2083
  }, [appearance, color]);
1968
- (0, import_react.useEffect)(() => {
2084
+ (0, import_react4.useEffect)(() => {
1969
2085
  computeTheme();
1970
2086
  }, [computeTheme]);
1971
- (0, import_react.useEffect)(() => {
1972
- const subscription = import_react_native.Appearance.addChangeListener(computeTheme);
2087
+ (0, import_react4.useEffect)(() => {
2088
+ const subscription = import_react_native3.Appearance.addChangeListener(computeTheme);
1973
2089
  return subscription.remove;
1974
2090
  }, [computeTheme]);
1975
2091
  return theme;
1976
2092
  }
1977
2093
 
1978
2094
  // src/ThemeProvider.tsx
1979
- function Provider({ appearance, color, children, onReady, statusBarProps, style }) {
2095
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2096
+ function Provider({ appearance, color, children, defaults, onReady, statusBarProps, style }) {
1980
2097
  const theme = useComputedTheme(appearance, color);
1981
- const called = (0, import_react2.useRef)(false);
1982
- (0, import_react2.useEffect)(() => {
2098
+ const called = (0, import_react5.useRef)(false);
2099
+ (0, import_react5.useEffect)(() => {
1983
2100
  if (theme && !called.current) {
1984
2101
  called.current = true;
1985
2102
  onReady?.();
1986
2103
  }
1987
2104
  }, [theme, onReady]);
1988
2105
  if (!theme) return null;
1989
- return /* @__PURE__ */ React.createElement(import_react_native_paper2.Provider, { theme }, /* @__PURE__ */ React.createElement(import_react_native2.StatusBar, { backgroundColor: theme.colors.background, barStyle: theme.dark ? "light-content" : "dark-content", ...statusBarProps }), /* @__PURE__ */ React.createElement(import_react_native2.View, { style: [styles.flex, { backgroundColor: theme.colors.background }, style] }, children));
2106
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native_paper9.Provider, { theme, children: [
2107
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native4.StatusBar, { backgroundColor: theme.colors.background, barStyle: theme.dark ? "light-content" : "dark-content", ...statusBarProps }),
2108
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaperDefaultsContext.Provider, { value: defaults ?? {}, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native4.View, { style: [styles.flex, { backgroundColor: theme.colors.background }, style], children }) })
2109
+ ] });
1990
2110
  }
1991
- var styles = import_react_native2.StyleSheet.create({
2111
+ var styles = import_react_native4.StyleSheet.create({
1992
2112
  flex: { flex: 1 }
1993
2113
  });
1994
2114
  // Annotate the CommonJS export names for ESM import in node:
1995
2115
  0 && (module.exports = {
2116
+ Appbar,
2117
+ BottomNavigation,
2118
+ Button,
2119
+ Chip,
2120
+ FAB,
2121
+ IconButton,
1996
2122
  Provider,
2123
+ TextInput,
1997
2124
  createThemeReducer,
1998
2125
  getBlendedColor,
1999
2126
  getHex,
@@ -2004,5 +2131,6 @@ var styles = import_react_native2.StyleSheet.create({
2004
2131
  selectThemeColor,
2005
2132
  themeActions,
2006
2133
  themeReducer,
2007
- useComputedTheme
2134
+ useComputedTheme,
2135
+ usePaperDefaults
2008
2136
  });
package/dist/index.mjs CHANGED
@@ -2,6 +2,104 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
 
5
+ // src/components/Appbar.tsx
6
+ import { StatusBar } from "react-native";
7
+ import { Appbar as PaperAppbar, useTheme } from "react-native-paper";
8
+
9
+ // src/PaperDefaultsContext.tsx
10
+ import { createContext, useContext } from "react";
11
+ var PaperDefaultsContext = createContext({});
12
+ function usePaperDefaults() {
13
+ return useContext(PaperDefaultsContext);
14
+ }
15
+
16
+ // src/components/Appbar.tsx
17
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
18
+ function Header({ style, ...props }) {
19
+ const defaults = usePaperDefaults();
20
+ const theme = useTheme();
21
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
22
+ /* @__PURE__ */ jsx(StatusBar, { backgroundColor: theme.colors.surface, barStyle: theme.dark ? "light-content" : "dark-content" }),
23
+ /* @__PURE__ */ jsx(PaperAppbar.Header, { ...defaults.AppbarHeader, ...props, style })
24
+ ] });
25
+ }
26
+ var Appbar = {
27
+ Header,
28
+ Content: PaperAppbar.Content,
29
+ Action: PaperAppbar.Action,
30
+ BackAction: PaperAppbar.BackAction
31
+ };
32
+
33
+ // src/components/BottomNavigation.tsx
34
+ import { useEffect } from "react";
35
+ import { Platform } from "react-native";
36
+ import { BottomNavigation as PaperBottomNavigation, useTheme as useTheme2 } from "react-native-paper";
37
+ import { jsx as jsx2 } from "react/jsx-runtime";
38
+ function useNavigationBarSync() {
39
+ const theme = useTheme2();
40
+ useEffect(() => {
41
+ if (Platform.OS !== "android") return;
42
+ import("expo-navigation-bar").then(({ setBackgroundColorAsync, setButtonStyleAsync }) => {
43
+ setBackgroundColorAsync(theme.colors.surface);
44
+ setButtonStyleAsync(theme.dark ? "light" : "dark");
45
+ }).catch(() => {
46
+ });
47
+ }, [theme]);
48
+ }
49
+ function BottomNavigationComponent(props) {
50
+ const defaults = usePaperDefaults();
51
+ useNavigationBarSync();
52
+ return /* @__PURE__ */ jsx2(PaperBottomNavigation, { ...defaults.BottomNavigation, ...props });
53
+ }
54
+ function Bar(props) {
55
+ useNavigationBarSync();
56
+ return /* @__PURE__ */ jsx2(PaperBottomNavigation.Bar, { ...props });
57
+ }
58
+ BottomNavigationComponent.Bar = Bar;
59
+ BottomNavigationComponent.SceneMap = PaperBottomNavigation.SceneMap;
60
+ var BottomNavigation = BottomNavigationComponent;
61
+
62
+ // src/components/Button.tsx
63
+ import { Button as PaperButton } from "react-native-paper";
64
+ import { jsx as jsx3 } from "react/jsx-runtime";
65
+ function Button(props) {
66
+ const defaults = usePaperDefaults();
67
+ return /* @__PURE__ */ jsx3(PaperButton, { ...defaults.Button, ...props });
68
+ }
69
+
70
+ // src/components/Chip.tsx
71
+ import { Chip as PaperChip } from "react-native-paper";
72
+ import { jsx as jsx4 } from "react/jsx-runtime";
73
+ function Chip(props) {
74
+ const defaults = usePaperDefaults();
75
+ return /* @__PURE__ */ jsx4(PaperChip, { ...defaults.Chip, ...props });
76
+ }
77
+
78
+ // src/components/FAB.tsx
79
+ import { FAB as PaperFAB } from "react-native-paper";
80
+ import { jsx as jsx5 } from "react/jsx-runtime";
81
+ function FAB(props) {
82
+ const defaults = usePaperDefaults();
83
+ return /* @__PURE__ */ jsx5(PaperFAB, { ...defaults.FAB, ...props });
84
+ }
85
+
86
+ // src/components/IconButton.tsx
87
+ import { IconButton as PaperIconButton } from "react-native-paper";
88
+ import { jsx as jsx6 } from "react/jsx-runtime";
89
+ function IconButton(props) {
90
+ const defaults = usePaperDefaults();
91
+ return /* @__PURE__ */ jsx6(PaperIconButton, { ...defaults.IconButton, ...props });
92
+ }
93
+
94
+ // src/components/TextInput.tsx
95
+ import { forwardRef } from "react";
96
+ import { TextInput as PaperTextInput } from "react-native-paper";
97
+ import { jsx as jsx7 } from "react/jsx-runtime";
98
+ var TextInput = forwardRef(function TextInput2(props, ref) {
99
+ const defaults = usePaperDefaults();
100
+ return /* @__PURE__ */ jsx7(PaperTextInput, { ref, ...defaults.TextInput, ...props });
101
+ });
102
+
5
103
  // node_modules/redux/dist/redux.mjs
6
104
  var randomString = () => Math.random().toString(36).substring(7).split("").join(".");
7
105
  var ActionTypes = {
@@ -1568,12 +1666,12 @@ var selectThemeAppearance = (state) => state.appearance;
1568
1666
  var selectThemeColor = (state) => state.color;
1569
1667
 
1570
1668
  // src/ThemeProvider.tsx
1571
- import { useEffect as useEffect2, useRef } from "react";
1572
- import { StatusBar, StyleSheet, View } from "react-native";
1669
+ import { useEffect as useEffect3, useRef } from "react";
1670
+ import { StatusBar as StatusBar2, StyleSheet, View } from "react-native";
1573
1671
  import { Provider as PaperProvider } from "react-native-paper";
1574
1672
 
1575
1673
  // src/useComputedTheme.ts
1576
- import { useCallback, useEffect, useState } from "react";
1674
+ import { useCallback, useEffect as useEffect2, useState } from "react";
1577
1675
  import { Appearance } from "react-native";
1578
1676
  import { MD3DarkTheme, MD3LightTheme } from "react-native-paper";
1579
1677
 
@@ -1930,10 +2028,10 @@ function useComputedTheme(appearance, color) {
1930
2028
  };
1931
2029
  setTheme(_theme);
1932
2030
  }, [appearance, color]);
1933
- useEffect(() => {
2031
+ useEffect2(() => {
1934
2032
  computeTheme();
1935
2033
  }, [computeTheme]);
1936
- useEffect(() => {
2034
+ useEffect2(() => {
1937
2035
  const subscription = Appearance.addChangeListener(computeTheme);
1938
2036
  return subscription.remove;
1939
2037
  }, [computeTheme]);
@@ -1941,23 +2039,34 @@ function useComputedTheme(appearance, color) {
1941
2039
  }
1942
2040
 
1943
2041
  // src/ThemeProvider.tsx
1944
- function Provider({ appearance, color, children, onReady, statusBarProps, style }) {
2042
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
2043
+ function Provider({ appearance, color, children, defaults, onReady, statusBarProps, style }) {
1945
2044
  const theme = useComputedTheme(appearance, color);
1946
2045
  const called = useRef(false);
1947
- useEffect2(() => {
2046
+ useEffect3(() => {
1948
2047
  if (theme && !called.current) {
1949
2048
  called.current = true;
1950
2049
  onReady?.();
1951
2050
  }
1952
2051
  }, [theme, onReady]);
1953
2052
  if (!theme) return null;
1954
- return /* @__PURE__ */ React.createElement(PaperProvider, { theme }, /* @__PURE__ */ React.createElement(StatusBar, { backgroundColor: theme.colors.background, barStyle: theme.dark ? "light-content" : "dark-content", ...statusBarProps }), /* @__PURE__ */ React.createElement(View, { style: [styles.flex, { backgroundColor: theme.colors.background }, style] }, children));
2053
+ return /* @__PURE__ */ jsxs2(PaperProvider, { theme, children: [
2054
+ /* @__PURE__ */ jsx8(StatusBar2, { backgroundColor: theme.colors.background, barStyle: theme.dark ? "light-content" : "dark-content", ...statusBarProps }),
2055
+ /* @__PURE__ */ jsx8(PaperDefaultsContext.Provider, { value: defaults ?? {}, children: /* @__PURE__ */ jsx8(View, { style: [styles.flex, { backgroundColor: theme.colors.background }, style], children }) })
2056
+ ] });
1955
2057
  }
1956
2058
  var styles = StyleSheet.create({
1957
2059
  flex: { flex: 1 }
1958
2060
  });
1959
2061
  export {
2062
+ Appbar,
2063
+ BottomNavigation,
2064
+ Button,
2065
+ Chip,
2066
+ FAB,
2067
+ IconButton,
1960
2068
  Provider,
2069
+ TextInput,
1961
2070
  createThemeReducer,
1962
2071
  getBlendedColor,
1963
2072
  getHex,
@@ -1968,5 +2077,6 @@ export {
1968
2077
  selectThemeColor,
1969
2078
  themeActions,
1970
2079
  themeReducer,
1971
- useComputedTheme
2080
+ useComputedTheme,
2081
+ usePaperDefaults
1972
2082
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rific/auto-paper",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
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",
@@ -54,7 +54,7 @@
54
54
  "test": "jest",
55
55
  "test:watch": "jest --watchAll",
56
56
  "typecheck": "tsc --noEmit",
57
- "preversion": "npm run lint && npm test"
57
+ "preversion": "npm run lint && npm test && npm run build"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@reduxjs/toolkit": "^2.0.0",
@@ -70,6 +70,7 @@
70
70
  "eslint-plugin-prettier": "^5.5.5",
71
71
  "eslint-plugin-react-native": "^5.0.0",
72
72
  "eslint-plugin-simple-import-sort": "^13.0.0",
73
+ "expo-navigation-bar": "^56.0.3",
73
74
  "jest": "^30.0.0",
74
75
  "jest-environment-jsdom": "^30.0.0",
75
76
  "prettier": "^3.8.3",
@@ -84,10 +85,16 @@
84
85
  "typescript-eslint": "^8.59.3"
85
86
  },
86
87
  "peerDependencies": {
88
+ "expo-navigation-bar": ">=4.0.0",
87
89
  "react": ">=18.0.0",
88
90
  "react-native": ">=0.73.0",
89
91
  "react-native-paper": ">=5.0.0"
90
92
  },
93
+ "peerDependenciesMeta": {
94
+ "expo-navigation-bar": {
95
+ "optional": true
96
+ }
97
+ },
91
98
  "optionalDependencies": {
92
99
  "@reduxjs/toolkit": "^2.0.0"
93
100
  },