ignite icon indicating copy to clipboard operation
ignite copied to clipboard

feat(Theming): Adds theming support with documentation.

Open markrickert opened this issue 1 year ago • 4 comments

Please verify the following:

  • [x] yarn test jest tests pass with new tests, if relevant
  • [x] yarn lint eslint checks pass with new code, if relevant
  • [x] yarn format:check prettier checks pass with new code, if relevant
  • [x] README.md (or relevant documentation) has been updated with your changes

Describe your PR

This PR adds theming support to the ignite boilerplate as well as relevant documentation on how to use the theming system.

Note that this PR is onto the v10 branch and not main.

markrickert avatar Feb 13 '24 22:02 markrickert

Before we merge this, I want to make sure we get some real-world experience. @markrickert you're starting a new project soon, so this will be a good opportunity for that.

jamonholmgren avatar Feb 13 '24 22:02 jamonholmgren

@jamonholmgren Absolutely. I'll keep this branch up to date with main and use this as the starting point for my next project.

markrickert avatar Feb 14 '24 00:02 markrickert

Rebased on the v10 branch and fixed a few issues caused by the Switch/Toggle rewrite

markrickert avatar May 13 '24 18:05 markrickert

TODO: need to check over the showroom issue: https://infiniteredcommunity.slack.com/archives/C41PK1LAY/p1716828905367989?thread_ts=1716662953.807429&cid=C41PK1LAY

frankcalise avatar May 29 '24 14:05 frankcalise

This is ready for another review.

markrickert avatar Jul 31 '24 01:07 markrickert

Looking into root cause of the screen jumping in this video (running on Android device), as I don't think it's themeing, but it does point out to me that I think we should be setting the actual app background as a dark background color so we don't get any white strips accidentally. Since we have expo-system-ui, I think https://docs.expo.dev/versions/latest/sdk/system-ui/#systemuisetbackgroundcolorasynccolor should do it?

https://github.com/user-attachments/assets/f463b03b-aaa4-421b-9083-bf91d132666c

lindboe avatar Aug 01 '24 04:08 lindboe

@markrickert I do think we should address https://github.com/infinitered/ignite/pull/2636#issuecomment-2261960598. It not only makes the demo look better, but there are likely to be other use cases where somebody needs to set a theme on non-React components (i.e., imperatively on a native component).

I took a stab at it:

https://github.com/user-attachments/assets/35e79a49-9813-41df-861f-ad9876ea19c7

Here's my diff:

diff --git a/app/utils/useAppTheme.ts b/app/utils/useAppTheme.ts
index 8d03a0c..712bf81 100644
--- a/app/utils/useAppTheme.ts
+++ b/app/utils/useAppTheme.ts
@@ -1,4 +1,4 @@
-import { createContext, useCallback, useContext, useMemo, useState } from "react"
+import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"
 import { StyleProp, useColorScheme } from "react-native"
 import { DarkTheme, DefaultTheme, useTheme as useNavTheme } from "@react-navigation/native"
 import {
@@ -9,6 +9,7 @@ import {
   lightTheme,
   darkTheme,
 } from "app/theme"
+import * as SystemUI from 'expo-system-ui';

 type ThemeContextType = {
   themeScheme: ThemeContexts
@@ -23,6 +24,13 @@ export const ThemeContext = createContext<ThemeContextType>({
   },
 })

+const themeContextToTheme = (themeContext: ThemeContexts): Theme => (
+    themeContext === "dark" ? darkTheme : lightTheme)
+
+const setImperativeThemeing = (theme: Theme) => {
+  SystemUI.setBackgroundColorAsync(theme.colors.background)
+}
+
 export const useThemeProvider = (initialTheme: ThemeContexts = undefined) => {
   const colorScheme = useColorScheme()
   const [overrideTheme, setTheme] = useState<ThemeContexts>(initialTheme)
@@ -34,6 +42,10 @@ export const useThemeProvider = (initialTheme: ThemeContexts = undefined) => {
   const themeScheme = overrideTheme || colorScheme || "light"
   const navigationTheme = themeScheme === "dark" ? DarkTheme : DefaultTheme

+  useEffect(() => {
+    setImperativeThemeing(themeContextToTheme(themeScheme))
+  }, [overrideTheme])
+
   return {
     themeScheme,
     navigationTheme,
@@ -78,7 +90,7 @@ export const useAppTheme = (): UseAppThemeValue => {
   )

   const themeVariant: Theme = useMemo(
-    () => (themeContext === "dark" ? darkTheme : lightTheme),
+    () => themeContextToTheme(themeContext),
     [themeContext],
   )

~My only concern here is that we haven't documented using useThemeProvider, which is what would run this. Is that meant to be a required part of the theming system?~

Edit: never mind on that framing, I was searching the wrong project.

Instead, do you think this is a good approach to this problem?

lindboe avatar Aug 09 '24 00:08 lindboe

Pushed commit with changes to set native background color after discussion with @markrickert https://github.com/infinitered/ignite/pull/2636/commits/4fb4d6127d63aba9790fa396fbc3011a38898dfe

lindboe avatar Aug 12 '24 19:08 lindboe