@rific/auto-paper 0.8.0 → 0.9.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/dist/index.js CHANGED
@@ -55,6 +55,7 @@ __export(index_exports, {
55
55
  getContrastColor: () => getContrastColor,
56
56
  getHex: () => getHex,
57
57
  getRgb: () => getRgb,
58
+ getThirdColor: () => getThirdColor,
58
59
  getTintTextColor: () => getTintTextColor,
59
60
  getTonalColor: () => getTonalColor,
60
61
  getTriadicPalette: () => getTriadicPalette,
@@ -67,7 +68,9 @@ __export(index_exports, {
67
68
  themeReducer: () => themeReducer,
68
69
  useAutoPaperTheme: () => useAutoPaperTheme,
69
70
  useBlur: () => useBlur,
71
+ useBlurModule: () => useBlurModule,
70
72
  useComputedTheme: () => useComputedTheme,
73
+ useNavBarContext: () => useNavBarContext,
71
74
  usePaperDefaults: () => usePaperDefaults,
72
75
  useThemeSettings: () => useThemeSettings
73
76
  });
@@ -144,67 +147,20 @@ var AppearancePicker = ({ value, onChange, showLabels = true, icons }) => {
144
147
  };
145
148
 
146
149
  // src/components/BlurView.tsx
147
- var import_react4 = require("react");
148
- var import_react_native2 = require("react-native");
149
- var import_react_native_paper3 = require("react-native-paper");
150
- var import_jsx_runtime3 = require("react/jsx-runtime");
151
- var ExpoBlurView = (() => {
152
- try {
153
- return require("expo-blur").BlurView;
154
- } catch {
155
- return null;
156
- }
157
- })();
158
- var ELEVATION_OPACITY = { 0: 0, 1: 0.05, 2: 0.08, 3: 0.11, 4: 0.12, 5: 0.14 };
159
- var VARIANT_TINT_OPACITY = { light: 0.12, dark: 0.18 };
160
- var BlurView = ({ blur = true, children, elevation, style, tintColor, tintOpacity, variant = "surface", ...props }) => {
161
- const { dark, colors } = (0, import_react_native_paper3.useTheme)();
162
- const { settings } = (0, import_react4.useContext)(ThemeSettingsContext);
163
- const surfaceColor = variant === "surfaceVariant" ? colors.surfaceVariant : colors.surface;
164
- const variantColor = variant === "primary" ? colors.primary : variant === "secondary" ? colors.secondary : variant === "tertiary" ? colors.tertiary : variant === "error" ? colors.error : void 0;
165
- const resolvedTintColor = tintColor ?? variantColor ?? (elevation !== void 0 ? colors.primary : void 0);
166
- const resolvedTintOpacity = tintOpacity ?? (tintColor ? dark ? 0.24 : 0.16 : variantColor ? dark ? VARIANT_TINT_OPACITY.dark : VARIANT_TINT_OPACITY.light : elevation !== void 0 ? ELEVATION_OPACITY[elevation] : 0);
167
- const tint = resolvedTintColor && resolvedTintOpacity > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native2.View, { style: [import_react_native2.StyleSheet.absoluteFill, { backgroundColor: resolvedTintColor, opacity: resolvedTintOpacity }] }) : null;
168
- if (blur && ExpoBlurView)
169
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ExpoBlurView, { ...props, tint: dark ? "dark" : "light", style, children: [
170
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native2.View, { style: [import_react_native2.StyleSheet.absoluteFill, { backgroundColor: surfaceColor, opacity: settings.blurTint }] }),
171
- tint,
172
- children
173
- ] });
174
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native2.View, { ...props, style: [{ backgroundColor: surfaceColor }, style], children: [
175
- tint,
176
- children
177
- ] });
178
- };
179
-
180
- // src/components/BottomNavigation.tsx
181
- var import_react7 = require("react");
182
- var import_react_native5 = require("react-native");
183
- var import_react_native_paper6 = require("react-native-paper");
184
-
185
- // src/navigation-bar.ts
186
- var navigationBar = (() => {
187
- try {
188
- return require("expo-navigation-bar");
189
- } catch {
190
- return null;
191
- }
192
- })();
193
- var setNavigationBarStyle = (dark) => {
194
- if (!navigationBar) return;
195
- navigationBar.NavigationBar.setStyle(dark ? "light" : "dark");
196
- };
197
-
198
- // src/ThemeProvider.tsx
199
150
  var import_react6 = require("react");
200
151
  var import_react_native4 = require("react-native");
201
152
  var import_react_native_paper5 = require("react-native-paper");
202
153
 
203
- // src/useComputedTheme.ts
154
+ // src/ThemeProvider.tsx
204
155
  var import_react5 = require("react");
205
156
  var import_react_native3 = require("react-native");
206
157
  var import_react_native_paper4 = require("react-native-paper");
207
158
 
159
+ // src/useComputedTheme.ts
160
+ var import_react4 = require("react");
161
+ var import_react_native2 = require("react-native");
162
+ var import_react_native_paper3 = require("react-native-paper");
163
+
208
164
  // src/utils/colorNames.ts
209
165
  var colorNames = {
210
166
  aliceblue: "#f0f8ff",
@@ -586,18 +542,25 @@ function hslToHex(h, s, l) {
586
542
  }
587
543
 
588
544
  // src/useComputedTheme.ts
545
+ function normalizeExplicitColor(value) {
546
+ if (!getRgb(value)) throw new Error(`Invalid color format: ${value}`);
547
+ return getHex(value) ?? value;
548
+ }
589
549
  var SEMANTIC_BASE_COLORS = {
590
550
  success: "#2E7D32",
591
551
  warning: "#A15C00",
592
552
  danger: "#B00020"
593
553
  };
594
554
  function useComputedTheme(appearance, color, harmony = "split-complementary") {
595
- const [theme, setTheme] = (0, import_react5.useState)(null);
596
- const computeTheme = (0, import_react5.useCallback)(() => {
555
+ const [theme, setTheme] = (0, import_react4.useState)(null);
556
+ const primaryInput = typeof color === "string" ? color : color.primary;
557
+ const secondaryInput = typeof color === "string" ? null : color.secondary;
558
+ const tertiaryInput = typeof color === "string" ? null : color.tertiary;
559
+ const computeTheme = (0, import_react4.useCallback)(() => {
597
560
  let resolved = appearance;
598
- if (resolved === "system") resolved = import_react_native3.Appearance.getColorScheme();
561
+ if (resolved === "system") resolved = import_react_native2.Appearance.getColorScheme();
599
562
  if (resolved === "no-preference" || !resolved) resolved = "light";
600
- const base = resolved === "dark" ? import_react_native_paper4.MD3DarkTheme : import_react_native_paper4.MD3LightTheme;
563
+ const base = resolved === "dark" ? import_react_native_paper3.MD3DarkTheme : import_react_native_paper3.MD3LightTheme;
601
564
  const surface = base.colors.surface;
602
565
  const successRoles = getColorRoles(SEMANTIC_BASE_COLORS.success, surface);
603
566
  const warningRoles = getColorRoles(SEMANTIC_BASE_COLORS.warning, surface);
@@ -621,7 +584,7 @@ function useComputedTheme(appearance, color, harmony = "split-complementary") {
621
584
  onDangerContainer: dangerRoles.onContainer
622
585
  }
623
586
  };
624
- const palette = getTriadicPalette(color, harmony);
587
+ const palette = secondaryInput !== null && tertiaryInput !== null ? { primary: normalizeExplicitColor(primaryInput), secondary: normalizeExplicitColor(secondaryInput), tertiary: normalizeExplicitColor(tertiaryInput) } : getTriadicPalette(primaryInput, harmony);
625
588
  const primaryRoles = getColorRoles(palette.primary, surface);
626
589
  _theme.colors.primary = primaryRoles.color;
627
590
  _theme.colors.onPrimary = primaryRoles.onColor;
@@ -637,12 +600,12 @@ function useComputedTheme(appearance, color, harmony = "split-complementary") {
637
600
  _theme.colors.onTertiary = tertiaryRoles.onColor;
638
601
  _theme.colors.tertiaryContainer = tertiaryRoles.container;
639
602
  _theme.colors.onTertiaryContainer = tertiaryRoles.onContainer;
640
- const blended = getBlendedColor(color, palette.secondary, 0.5);
603
+ const blended = getBlendedColor(palette.primary, palette.secondary, 0.5);
641
604
  const tintSurface = (alpha) => getBlendedColor(blended, surface, alpha);
642
605
  _theme.colors.background = base.dark ? "#0F0F0F" : "#F0F0F0";
643
606
  _theme.colors.surface = surface;
644
607
  _theme.colors.surfaceVariant = tintSurface(0.2);
645
- _theme.colors.outline = getBlendedColor(color, base.colors.outline, 0.45);
608
+ _theme.colors.outline = getBlendedColor(palette.primary, base.colors.outline, 0.45);
646
609
  const grey = base.dark ? "#424242" : "#c2c2c2";
647
610
  const blendedGrey = getBlendedColor(blended, grey, 0.05);
648
611
  _theme.colors.elevation = {
@@ -654,63 +617,101 @@ function useComputedTheme(appearance, color, harmony = "split-complementary") {
654
617
  level5: getBlendedColor(blendedGrey, _theme.colors.surface, 0.7)
655
618
  };
656
619
  setTheme(_theme);
657
- }, [appearance, color, harmony]);
658
- (0, import_react5.useEffect)(() => {
620
+ }, [appearance, primaryInput, secondaryInput, tertiaryInput, harmony]);
621
+ (0, import_react4.useEffect)(() => {
659
622
  computeTheme();
660
623
  }, [computeTheme]);
661
- (0, import_react5.useEffect)(() => {
662
- const subscription = import_react_native3.Appearance.addChangeListener(computeTheme);
624
+ (0, import_react4.useEffect)(() => {
625
+ const subscription = import_react_native2.Appearance.addChangeListener(computeTheme);
663
626
  return subscription.remove;
664
627
  }, [computeTheme]);
665
628
  return theme;
666
629
  }
667
630
 
668
631
  // src/ThemeProvider.tsx
669
- var import_jsx_runtime4 = require("react/jsx-runtime");
670
- var NavBarContext = (0, import_react6.createContext)({});
671
- var useNavBarContext = () => (0, import_react6.useContext)(NavBarContext);
672
- function Provider({ initialValue, onChange, children, defaults, onNavBarChange, onReady, statusBarProps, style }) {
673
- const [settings, setSettings] = (0, import_react6.useState)(() => ({ ...defaultThemeSettings, ...initialValue }));
674
- const set = (0, import_react6.useCallback)((patch) => {
632
+ var import_jsx_runtime3 = require("react/jsx-runtime");
633
+ var NavBarContext = (0, import_react5.createContext)({});
634
+ var useNavBarContext = () => (0, import_react5.useContext)(NavBarContext);
635
+ var BlurModuleContext = (0, import_react5.createContext)(void 0);
636
+ var useBlurModule = () => (0, import_react5.useContext)(BlurModuleContext);
637
+ function Provider({ children, defaults, expoBlur, initialValue, navigationBar, onChange, onNavBarChange, onReady, statusBarProps, style }) {
638
+ const [settings, setSettings] = (0, import_react5.useState)(() => ({ ...defaultThemeSettings, ...initialValue }));
639
+ const set = (0, import_react5.useCallback)((patch) => {
675
640
  setSettings((prev) => ({ ...prev, ...patch }));
676
641
  }, []);
677
- const onChangeRef = (0, import_react6.useRef)(onChange);
642
+ const onChangeRef = (0, import_react5.useRef)(onChange);
678
643
  onChangeRef.current = onChange;
679
- const prevSettings = (0, import_react6.useRef)(settings);
680
- (0, import_react6.useEffect)(() => {
644
+ const prevSettings = (0, import_react5.useRef)(settings);
645
+ (0, import_react5.useEffect)(() => {
681
646
  if (prevSettings.current !== settings) {
682
647
  prevSettings.current = settings;
683
648
  onChangeRef.current?.(settings);
684
649
  }
685
650
  }, [settings]);
686
651
  const theme = useComputedTheme(settings.appearance, settings.color, settings.harmony);
687
- const called = (0, import_react6.useRef)(false);
688
- (0, import_react6.useEffect)(() => {
652
+ const called = (0, import_react5.useRef)(false);
653
+ (0, import_react5.useEffect)(() => {
689
654
  if (theme && !called.current) {
690
655
  called.current = true;
691
656
  onReady?.();
692
657
  }
693
658
  }, [theme, onReady]);
694
659
  if (!theme) return null;
695
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ThemeSettingsContext.Provider, { value: { settings, set }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native_paper5.Provider, { theme, children: [
696
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.StatusBar, { backgroundColor: theme.colors.background, barStyle: theme.dark ? "light-content" : "dark-content", ...statusBarProps }),
697
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PaperDefaultsContext.Provider, { value: defaults ?? {}, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NavBarContext.Provider, { value: { onNavBarChange }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [styles.flex, { backgroundColor: theme.colors.background }, style], children }) }) })
660
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ThemeSettingsContext.Provider, { value: { settings, set }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native_paper4.Provider, { theme, children: [
661
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.StatusBar, { backgroundColor: theme.colors.background, barStyle: theme.dark ? "light-content" : "dark-content", ...statusBarProps }),
662
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaperDefaultsContext.Provider, { value: defaults ?? {}, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NavBarContext.Provider, { value: { navigationBar, onNavBarChange }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BlurModuleContext.Provider, { value: expoBlur, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles.flex, { backgroundColor: theme.colors.background }, style], children }) }) }) })
698
663
  ] }) });
699
664
  }
700
- var styles = import_react_native4.StyleSheet.create({
665
+ var styles = import_react_native3.StyleSheet.create({
701
666
  flex: { flex: 1 }
702
667
  });
703
668
 
669
+ // src/components/BlurView.tsx
670
+ var import_jsx_runtime4 = require("react/jsx-runtime");
671
+ var ELEVATION_OPACITY = { 0: 0, 1: 0.05, 2: 0.08, 3: 0.11, 4: 0.12, 5: 0.14 };
672
+ var VARIANT_TINT_OPACITY = { light: 0.12, dark: 0.18 };
673
+ var BlurView = ({ blur = true, children, elevation, style, tintColor, tintOpacity, variant = "surface", ...props }) => {
674
+ const { dark, colors } = (0, import_react_native_paper5.useTheme)();
675
+ const { settings } = (0, import_react6.useContext)(ThemeSettingsContext);
676
+ const expoBlur = useBlurModule();
677
+ const surfaceColor = variant === "surfaceVariant" ? colors.surfaceVariant : colors.surface;
678
+ const variantColor = variant === "primary" ? colors.primary : variant === "secondary" ? colors.secondary : variant === "tertiary" ? colors.tertiary : variant === "error" ? colors.error : void 0;
679
+ const resolvedTintColor = tintColor ?? variantColor ?? (elevation !== void 0 ? colors.primary : void 0);
680
+ const resolvedTintOpacity = tintOpacity ?? (tintColor ? dark ? 0.24 : 0.16 : variantColor ? dark ? VARIANT_TINT_OPACITY.dark : VARIANT_TINT_OPACITY.light : elevation !== void 0 ? ELEVATION_OPACITY[elevation] : 0);
681
+ const tint = resolvedTintColor && resolvedTintOpacity > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [import_react_native4.StyleSheet.absoluteFill, { backgroundColor: resolvedTintColor, opacity: resolvedTintOpacity }] }) : null;
682
+ if (blur && expoBlur)
683
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(expoBlur.BlurView, { ...props, tint: dark ? "dark" : "light", style, children: [
684
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [import_react_native4.StyleSheet.absoluteFill, { backgroundColor: surfaceColor, opacity: settings.blurTint }] }),
685
+ tint,
686
+ children
687
+ ] });
688
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { ...props, style: [{ backgroundColor: surfaceColor }, style], children: [
689
+ tint,
690
+ children
691
+ ] });
692
+ };
693
+
694
+ // src/components/BottomNavigation.tsx
695
+ var import_react7 = require("react");
696
+ var import_react_native5 = require("react-native");
697
+ var import_react_native_paper6 = require("react-native-paper");
698
+
699
+ // src/navigation-bar.ts
700
+ var setNavigationBarStyle = (navigationBar, dark) => {
701
+ if (!navigationBar) return;
702
+ navigationBar.NavigationBar.setStyle(dark ? "light" : "dark");
703
+ };
704
+
704
705
  // src/components/BottomNavigation.tsx
705
706
  var import_jsx_runtime5 = require("react/jsx-runtime");
706
707
  function useNavigationBarSync() {
707
708
  const theme = (0, import_react_native_paper6.useTheme)();
708
- const { onNavBarChange } = useNavBarContext();
709
+ const { navigationBar, onNavBarChange } = useNavBarContext();
709
710
  (0, import_react7.useEffect)(() => {
710
711
  if (import_react_native5.Platform.OS !== "android") return;
711
712
  if (onNavBarChange) onNavBarChange(theme.colors.surface, theme.dark);
712
- else if (navigationBar) setNavigationBarStyle(theme.dark);
713
- }, [theme, onNavBarChange]);
713
+ else if (navigationBar) setNavigationBarStyle(navigationBar, theme.dark);
714
+ }, [theme, onNavBarChange, navigationBar]);
714
715
  }
715
716
  function BottomNavigationComponent(props) {
716
717
  const defaults = usePaperDefaults();
@@ -1074,6 +1075,82 @@ var useAutoPaperTheme = () => (0, import_react_native_paper17.useTheme)();
1074
1075
  var import_react14 = require("react");
1075
1076
  var useThemeSettings = () => (0, import_react14.useContext)(ThemeSettingsContext);
1076
1077
 
1078
+ // src/utils/getThirdColor.ts
1079
+ function rgbToHsl(r, g, b) {
1080
+ r /= 255;
1081
+ g /= 255;
1082
+ b /= 255;
1083
+ const max = Math.max(r, g, b);
1084
+ const min = Math.min(r, g, b);
1085
+ const delta = max - min;
1086
+ let h = 0;
1087
+ if (delta !== 0) {
1088
+ if (max === r) h = (g - b) / delta % 6;
1089
+ else if (max === g) h = (b - r) / delta + 2;
1090
+ else h = (r - g) / delta + 4;
1091
+ h = (h * 60 + 360) % 360;
1092
+ }
1093
+ const l = (max + min) / 2;
1094
+ const s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
1095
+ return { h, s, l };
1096
+ }
1097
+ function hslToHex2(h, s, l) {
1098
+ const c = (1 - Math.abs(2 * l - 1)) * s;
1099
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
1100
+ const m = l - c / 2;
1101
+ let r = 0;
1102
+ let g = 0;
1103
+ let b = 0;
1104
+ if (h < 60) {
1105
+ r = c;
1106
+ g = x;
1107
+ b = 0;
1108
+ } else if (h < 120) {
1109
+ r = x;
1110
+ g = c;
1111
+ b = 0;
1112
+ } else if (h < 180) {
1113
+ r = 0;
1114
+ g = c;
1115
+ b = x;
1116
+ } else if (h < 240) {
1117
+ r = 0;
1118
+ g = x;
1119
+ b = c;
1120
+ } else if (h < 300) {
1121
+ r = x;
1122
+ g = 0;
1123
+ b = c;
1124
+ } else {
1125
+ r = c;
1126
+ g = 0;
1127
+ b = x;
1128
+ }
1129
+ const toInt = (value) => Math.round((value + m) * 255);
1130
+ return getHex(`rgb(${toInt(r)}, ${toInt(g)}, ${toInt(b)})`) ?? "#000000";
1131
+ }
1132
+ var toRad = (deg) => deg * Math.PI / 180;
1133
+ var toDeg = (rad) => rad * 180 / Math.PI;
1134
+ function thirdHue(hA, hB) {
1135
+ const x = Math.cos(toRad(hA)) + Math.cos(toRad(hB));
1136
+ const y = Math.sin(toRad(hA)) + Math.sin(toRad(hB));
1137
+ if (Math.abs(x) < 1e-9 && Math.abs(y) < 1e-9) return (hA + 90) % 360;
1138
+ const meanHue = (toDeg(Math.atan2(y, x)) + 360) % 360;
1139
+ return (meanHue + 180) % 360;
1140
+ }
1141
+ function getThirdColor(colorA, colorB) {
1142
+ const rgbA = getRgb(colorA);
1143
+ const rgbB = getRgb(colorB);
1144
+ if (!rgbA) throw new Error(`Invalid color format: ${colorA}`);
1145
+ if (!rgbB) throw new Error(`Invalid color format: ${colorB}`);
1146
+ const hslA = rgbToHsl(rgbA.r, rgbA.g, rgbA.b);
1147
+ const hslB = rgbToHsl(rgbB.r, rgbB.g, rgbB.b);
1148
+ const h = thirdHue(hslA.h, hslB.h);
1149
+ const s = (hslA.s + hslB.s) / 2;
1150
+ const l = (hslA.l + hslB.l) / 2;
1151
+ return hslToHex2(h, s, l);
1152
+ }
1153
+
1077
1154
  // src/utils/getTintTextColor.ts
1078
1155
  var getTintTextColor = (tintColor, backdropColor, tintOpacity) => {
1079
1156
  const blended = getBlendedColor(tintColor, backdropColor, tintOpacity);
@@ -1106,6 +1183,7 @@ var getTintTextColor = (tintColor, backdropColor, tintOpacity) => {
1106
1183
  getContrastColor,
1107
1184
  getHex,
1108
1185
  getRgb,
1186
+ getThirdColor,
1109
1187
  getTintTextColor,
1110
1188
  getTonalColor,
1111
1189
  getTriadicPalette,
@@ -1118,7 +1196,9 @@ var getTintTextColor = (tintColor, backdropColor, tintOpacity) => {
1118
1196
  themeReducer,
1119
1197
  useAutoPaperTheme,
1120
1198
  useBlur,
1199
+ useBlurModule,
1121
1200
  useComputedTheme,
1201
+ useNavBarContext,
1122
1202
  usePaperDefaults,
1123
1203
  useThemeSettings
1124
1204
  });