@rific/auto-paper 0.9.3 → 0.9.5
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 +29 -2
- package/dist/index.d.mts +49 -34
- package/dist/index.d.ts +49 -34
- package/dist/index.js +327 -298
- package/dist/index.mjs +299 -273
- package/package.json +2 -1
- package/src/ThemeProvider.tsx +3 -1
- package/src/components/AutoAppearancePicker.tsx +17 -0
- package/src/components/AutoPalettePicker.tsx +21 -0
- package/src/components/Dialog.tsx +7 -4
- package/src/index.ts +3 -0
- package/src/useComputedTheme.ts +1 -0
- package/src/utils/resolveSeedColor.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rific/auto-paper",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
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",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"eslint-config-prettier": "^10.1.8",
|
|
77
77
|
"eslint-plugin-package-json": "^1.0.0",
|
|
78
78
|
"eslint-plugin-prettier": "^5.5.5",
|
|
79
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
79
80
|
"eslint-plugin-react-native": "^5.0.0",
|
|
80
81
|
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
81
82
|
"expo-blur": "^56.0.3",
|
package/src/ThemeProvider.tsx
CHANGED
|
@@ -49,7 +49,9 @@ export function Provider({ children, defaults, expoBlur, initialValue, navigatio
|
|
|
49
49
|
}, [])
|
|
50
50
|
|
|
51
51
|
const onChangeRef = useRef(onChange)
|
|
52
|
-
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
onChangeRef.current = onChange
|
|
54
|
+
})
|
|
53
55
|
const prevSettings = useRef(settings)
|
|
54
56
|
useEffect(() => {
|
|
55
57
|
if (prevSettings.current !== settings) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useThemeSettings } from '../useThemeSettings'
|
|
2
|
+
import { type AppearanceIcons, AppearancePicker } from './AppearancePicker'
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
showLabels?: boolean
|
|
6
|
+
icons?: AppearanceIcons
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// AppearancePicker wired straight to the Provider's own ThemeSettings, for the common case where
|
|
10
|
+
// the appearance being edited IS the whole app's own theme. Takes neither `value` nor `onChange`
|
|
11
|
+
// — reads/writes useThemeSettings() itself, so there's nothing for a consumer to wire up. Reach
|
|
12
|
+
// for the plain AppearancePicker instead when it needs to be controlled by something other than
|
|
13
|
+
// the global theme (a local preview before committing, one-off UI unrelated to Provider).
|
|
14
|
+
export const AutoAppearancePicker = (props: Props) => {
|
|
15
|
+
const { settings, set } = useThemeSettings()
|
|
16
|
+
return <AppearancePicker {...props} value={settings.appearance} onChange={(appearance) => set({ appearance })} />
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useThemeSettings } from '../useThemeSettings'
|
|
2
|
+
import { resolveSeedColor } from '../utils/resolveSeedColor'
|
|
3
|
+
import type { SeedColor } from './ColorPicker'
|
|
4
|
+
import { PalettePicker, type PaletteWeights } from './PalettePicker'
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
weights?: PaletteWeights
|
|
8
|
+
colors?: SeedColor[]
|
|
9
|
+
blur?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// PalettePicker wired straight to the Provider's own ThemeSettings — both color AND harmony —
|
|
13
|
+
// for the common case where the palette being edited IS the whole app's own theme. Takes none of
|
|
14
|
+
// `value`/`onChange`/`harmony`/`onHarmonyChange` — reads/writes useThemeSettings() itself
|
|
15
|
+
// (resolveSeedColor narrows ThemeSettings.color's `string | TriadicPalette` down to the plain
|
|
16
|
+
// string PalettePicker's own `value` wants). Reach for the plain PalettePicker instead when it
|
|
17
|
+
// needs to be controlled by something other than the global theme.
|
|
18
|
+
export const AutoPalettePicker = (props: Props) => {
|
|
19
|
+
const { settings, set } = useThemeSettings()
|
|
20
|
+
return <PalettePicker {...props} value={resolveSeedColor(settings.color)} onChange={(color) => set({ color })} harmony={settings.harmony} onHarmonyChange={(harmony) => set({ harmony })} />
|
|
21
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { type ComponentType, type ReactNode, useEffect,
|
|
1
|
+
import React, { type ComponentType, type ReactNode, useEffect, useState } from 'react'
|
|
2
2
|
import { Animated, BackHandler, Easing, Pressable, type StyleProp, StyleSheet, View, type ViewStyle } from 'react-native'
|
|
3
3
|
import { Dialog as PaperDialog, type DialogActionsProps, type DialogContentProps, type DialogProps as PaperDialogProps, type DialogScrollAreaProps, type DialogTitleProps, Portal, useTheme } from 'react-native-paper'
|
|
4
4
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
@@ -46,19 +46,22 @@ function DialogComponent({ animatedStyle, blur: blurProp, dismissable = true, di
|
|
|
46
46
|
const { colors, isV3, roundness } = theme
|
|
47
47
|
const { scale } = theme.animation
|
|
48
48
|
const { bottom, left, right, top } = useSafeAreaInsets()
|
|
49
|
-
const opacity =
|
|
49
|
+
const [opacity] = useState(() => new Animated.Value(visible ? 1 : 0))
|
|
50
50
|
const [mounted, setMounted] = useState(visible)
|
|
51
51
|
|
|
52
|
+
if (visible && !mounted) {
|
|
53
|
+
setMounted(true)
|
|
54
|
+
}
|
|
55
|
+
|
|
52
56
|
useEffect(() => {
|
|
53
57
|
if (visible) {
|
|
54
|
-
setMounted(true)
|
|
55
58
|
Animated.timing(opacity, { duration: scale * ANIMATION_DURATION, easing: Easing.out(Easing.cubic), toValue: 1, useNativeDriver: true }).start()
|
|
56
59
|
} else {
|
|
57
60
|
Animated.timing(opacity, { duration: scale * ANIMATION_DURATION, easing: Easing.out(Easing.cubic), toValue: 0, useNativeDriver: true }).start(({ finished }) => {
|
|
58
61
|
if (finished) setMounted(false)
|
|
59
62
|
})
|
|
60
63
|
}
|
|
61
|
-
}, [visible])
|
|
64
|
+
}, [visible, opacity, scale])
|
|
62
65
|
|
|
63
66
|
useEffect(() => {
|
|
64
67
|
if (!visible) return undefined
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ export { useBlur } from './BlurContext'
|
|
|
2
2
|
export { Appbar } from './components/Appbar'
|
|
3
3
|
export type { AppearanceIcons } from './components/AppearancePicker'
|
|
4
4
|
export { AppearancePicker } from './components/AppearancePicker'
|
|
5
|
+
export { AutoAppearancePicker } from './components/AutoAppearancePicker'
|
|
6
|
+
export { AutoPalettePicker } from './components/AutoPalettePicker'
|
|
5
7
|
export type { BlurViewProps, ExpoBlurModule } from './components/BlurView'
|
|
6
8
|
export { BlurView } from './components/BlurView'
|
|
7
9
|
export { BottomNavigation } from './components/BottomNavigation'
|
|
@@ -47,6 +49,7 @@ export { getTonalColor } from './utils/getTonalColor'
|
|
|
47
49
|
export type { ColorHarmony, TriadicPalette } from './utils/getTriadicPalette'
|
|
48
50
|
export { getTriadicPalette } from './utils/getTriadicPalette'
|
|
49
51
|
export { isDarkColor } from './utils/isDarkColor'
|
|
52
|
+
export { resolveSeedColor } from './utils/resolveSeedColor'
|
|
50
53
|
export type { AppbarHeaderProps } from 'react-native-paper'
|
|
51
54
|
export type { BottomNavigationProps } from 'react-native-paper'
|
|
52
55
|
export type { BottomNavigationRoute } from 'react-native-paper'
|
package/src/useComputedTheme.ts
CHANGED
|
@@ -147,6 +147,7 @@ export function useComputedTheme(appearance: ThemeAppearance, color: string | Tr
|
|
|
147
147
|
}, [appearance, primaryInput, secondaryInput, tertiaryInput, harmony])
|
|
148
148
|
|
|
149
149
|
useEffect(() => {
|
|
150
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect -- intentional: first render must stay theme-less (README's onReady/splash-screen contract) and Appearance must not be read during render (SSR/hydration risk)
|
|
150
151
|
computeTheme()
|
|
151
152
|
}, [computeTheme])
|
|
152
153
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TriadicPalette } from './getTriadicPalette'
|
|
2
|
+
|
|
3
|
+
// ThemeSettings.color is `string | TriadicPalette` — a plain seed hex normally, or an explicit
|
|
4
|
+
// triad when a consumer bypassed harmony math entirely (see the README's own "Explicit triad"
|
|
5
|
+
// section). Anything that needs a single representative color from it — a picker's own `value`,
|
|
6
|
+
// a card's accent — narrows via this: `.primary` is that triad's own seed, so it's the
|
|
7
|
+
// representative color on the rare path where this branch is actually hit.
|
|
8
|
+
export const resolveSeedColor = (color: string | TriadicPalette): string => (typeof color === 'string' ? color : color.primary)
|