diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 319929c..cf3a028 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,9 +4,6 @@ on: push: branches: - release - pull_request: - branches: - - release jobs: release: diff --git a/README.md b/README.md index df81a4e..77c2127 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Bring material color utilities from the [`@material-foundation/material-color-utilities`](https://github.com/material-foundation/material-color-utilities), including the material color builder from an image, and the special [Android Dynamic Color](https://developer.android.com/develop/ui/views/theming/dynamic-colors). +![screenshot](https://github.com/RakaDoank/material-color-react-native/blob/main/docusaurus/static/img/screenshot.png?raw=true) + ## Motives Basically, this library is similar as other libraries you can found to build material color, as [The Science of Color & Design](https://m3.material.io/blog/science-of-color-design) has been done by a Google engineer including their [source code](https://github.com/material-foundation/material-color-utilities), but the inexistence of the utility for building material color from an image for React Native especially on Android, iOS (including macOS) is really the main motive why [`material-color-react-native`](https://github.com/RakaDoank/material-color-react-native) was created. diff --git a/docusaurus/docs/guides/THEMING_WITH_REACT_NATIVE_PAPER.mdx b/docusaurus/docs/guides/THEMING_WITH_REACT_NATIVE_PAPER.mdx index a6fa4e4..3df4bf5 100644 --- a/docusaurus/docs/guides/THEMING_WITH_REACT_NATIVE_PAPER.mdx +++ b/docusaurus/docs/guides/THEMING_WITH_REACT_NATIVE_PAPER.mdx @@ -8,6 +8,12 @@ slug: /theming-with-react-native-paper Bring your app components with [React Native Paper](https://reactnativepaper.com) and [Material Color React Native](/docs/introduction)! +![Screenshot](/img/screenshot.png) + +:::note +The image above is an actual example app of this project library. Check the example [source code at GitHub](https://github.com/RakaDoank/material-color-react-native). +::: + :::info This adapter is only providing an integration to Paper color v3. Simply, because Material Color React Native is not using Material Design 2 color system. ::: diff --git a/docusaurus/static/img/screenshot.png b/docusaurus/static/img/screenshot.png new file mode 100644 index 0000000..5a1f5bc Binary files /dev/null and b/docusaurus/static/img/screenshot.png differ diff --git a/example/src/screens/home/Page.tsx b/example/src/screens/home/Page.tsx index 96e868c..e3f28f4 100644 --- a/example/src/screens/home/Page.tsx +++ b/example/src/screens/home/Page.tsx @@ -1,212 +1,27 @@ import { - useContext, - useImperativeHandle, - useRef, - useState, -} from "react" - -import { - Appearance, - Platform, ScrollView, StyleSheet, - View, - useWindowDimensions, - type ScrollViewProps, } from "react-native" -import * as ExpoImagePicker from "expo-image-picker" - -import * as ExpoStatusBar from "expo-status-bar" - -import { - MaterialColor, -} from "material-color-react-native" - import { Appbar, + Avatar, Button, - Text, - useTheme, - type ButtonProps, + Chip, } from "react-native-paper" -import { - ThemeContext, -} from "@/contexts" +import ImageIcon from "../../../assets/icon.png" import { - GlobalStyleSheet, -} from "@/styles" + Actions, +} from "./_actions" import { - ModalInputColor, - type ModalInputColorProps, - type ModalInputColorRef, -} from "./_modal-input-color" - -import StaticImage1 from "./_nougat-wallpaper.png" -import StaticImage2 from "./_wallpaper.png" + Section, +} from "./_section" export function Page() { - const - buttonStaticImage1Ref = - useRef(null), - - buttonStaticImage2Ref = - useRef(null), - - buttonLocalImageRef = - useRef(null), - - buttonRemoteImageRef = - useRef(null), - - modalInputColorRef = - useRef(null), - - themeContext = - useContext(ThemeContext), - - windowDimensions = - useWindowDimensions(), - - getAndroidDynamicColor = - () => { - themeContext.setAndroidDynamicColor("dynamic") - ExpoStatusBar.setStatusBarStyle( - Appearance.getColorScheme() === "dark" ? "light" : "dark", - ) - }, - - getAndroidDynamicDarkColor = - () => { - themeContext.setAndroidDynamicColor("dark") - ExpoStatusBar.setStatusBarStyle("light") - }, - - getAndroidDynamicLightColor = - () => { - themeContext.setAndroidDynamicColor("light") - ExpoStatusBar.setStatusBarStyle("dark") - }, - - fromStaticImage = - ( - image: typeof StaticImage1, - buttonRef: ButtonLoadingImperativeRef | null, - ) => { - buttonRef?.setLoading(true) - - MaterialColor.fromSourceImage( - image, - - // material color options - undefined, - - // other options - { - // maxWidthOrHeight: 1920, - }, - ) - .then(res => { - if(res) { - themeContext.setSourceColor(res.sourceColor) - } - }) - .catch(() => { - // NOOP - }) - .finally(() => { - buttonRef?.setLoading(false) - }) - }, - - fromLocalImage = - async () => { - buttonLocalImageRef.current?.setLoading(true) - - try { - // You can use other photo/file picker module here - - const image = await ExpoImagePicker.launchImageLibraryAsync({ - mediaTypes: "images", - }) - const uri = image.assets?.[0]?.uri - - if(!uri) { - throw new Error() - } - - const materialColor = await MaterialColor.fromSourceImageUri( - uri, - - // material color options - undefined, - - // other options - { - // maxWidthOrHeight: 1920, - }, - ) - - if(!materialColor) { - throw new Error() - } - - themeContext.setSourceColor(materialColor.sourceColor) - } catch { - // NOOP - } finally { - buttonLocalImageRef.current?.setLoading(false) - } - }, - - fromRemoteImage = - async () => { - buttonRemoteImageRef.current?.setLoading(true) - - try { - const materialColor = await MaterialColor.fromSourceImageUri( - // Image thumbnail of a YouTube video - // See the video at https://www.youtube.com/watch?v=XGxIE1hr0w4 - "https://i3.ytimg.com/vi/XGxIE1hr0w4/maxresdefault.jpg", - - // material color options - undefined, - - // other options - { - // maxWidthOrHeight: 1920, - }, - ) - - if(!materialColor) { - throw new Error() - } - - themeContext.setSourceColor(materialColor.sourceColor) - } catch { - // NOOP - } finally { - buttonRemoteImageRef.current?.setLoading(false) - } - }, - - showModalInputColor = - () => { - modalInputColorRef.current?.present() - }, - - onSubmitModalInputColor: ModalInputColorProps["onSubmit"] = - hexColor => { - themeContext.setSourceColor(hexColor) - }, - - rowMode = - windowDimensions.width > 480 - return (<> - - - { Platform.OS === "android" && (<> - - - + + Simple + + + With Selected Overlay + + + Elevated + + + Compact Chip + + + Close Button + + + } + > + Avatar + + + } + > + Avatar (selected) + + + Icon (disabled) + + - - ) } +
- fromStaticImage(StaticImage1, buttonStaticImage1Ref.current) } - ref={ buttonStaticImage1Ref } + - Use Static Import Image 1 - - - fromStaticImage(StaticImage2, buttonStaticImage2Ref.current) } - ref={ buttonStaticImage2Ref } + Simple + + - Use Static Import Image 2 - - - + void } - ref={ buttonLocalImageRef } + elevated > - Use Local Image - - - + + Compact Chip + + + Close Button + + + } + > + Avatar + + + } + > + Avatar (selected) + + void } - ref={ buttonRemoteImageRef } + disabled + icon="alien" > - Use Remote Image - + Icon (disabled) + +
+
+ + + + + - +
- -
+
+ + + + + + +
+ - + ) } @@ -316,103 +252,10 @@ export function Page() { const styleSheet = StyleSheet.create({ - buttonsContainer: { - rowGap: 16, + scrollContentContainer: { + paddingBottom: 48, }, - colorSchemePrintView: { - padding: 16, - }, - colorSchemePrintViewMaxWidth: { - maxWidth: 360, - }, - colorSchemePrintViewMaxHeight: { - maxHeight: 240, - }, - colorSchemePrintViewContentContainer: { - width: "100%", - maxWidth: 380, + flex_row_reverse: { + flexDirection: "row-reverse", }, }) - -interface ColorSchemePrintViewProps extends ScrollViewProps { -} - -function ColorSchemePrintView({ - contentContainerStyle, - style, - ...props -}: ColorSchemePrintViewProps) { - - const - themeContext = - useContext(ThemeContext), - - theme = - useTheme() - - let nextText = "" - - nextText += "{" - nextText += `\n "": "${themeContext.usingAndroidDynamicColor ? "Android Dynamic Color" : themeContext.sourceColor}"` - Object.entries(themeContext.colorScheme).forEach(([key, val]) => { - nextText += `\n "${key}": "${val}",` - }) - nextText += "\n}" - - return ( - - - { nextText } - - - ) - -} - -interface ButtonLoadingImperativeProps extends Omit { - ref?: React.Ref, -} -interface ButtonLoadingImperativeRef { - setLoading: (value: boolean) => void, -} -function ButtonLoadingImperative({ - ref, - ...props -}: ButtonLoadingImperativeProps) { - - const - [loading, setLoading] = - useState(false) - - useImperativeHandle(ref, () => { - return { - setLoading, - } - }, []) - - return ( -