Skip to content

Commit dd3e6c7

Browse files
committed
Transition to using theme context for colors
1 parent ea26346 commit dd3e6c7

File tree

9 files changed

+118
-16
lines changed

9 files changed

+118
-16
lines changed

components/button.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
1+
import { useTheme } from '../hooks/theme/index';
2+
13
export default function Button({ children, onClick = () => {} , attrs = {}, size = "large" }) {
4+
const [ theme ] = useTheme();
5+
const { buttonTextColor, buttonBgColor } = theme;
6+
27
const {
38
className = '',
49
type: buttonType,
510
...buttonAttrs
611
} = attrs;
712

813
const largeButtonClassNames = [
9-
"bg-transparent",
14+
buttonTextColor,
15+
buttonBgColor,
1016
"inline-block",
11-
"text-red-600",
1217
"font-medium",
1318
"py-1.5",
1419
"text-xl",
1520
];
1621

1722
const smallButtonClassNames = [
18-
"bg-transparent",
23+
buttonTextColor,
24+
buttonBgColor,
1925
"inline-block",
2026
"text-red-600",
2127
"font-medium",
22-
"py-1.5"
28+
"py-1.5",
2329
];
2430

2531
const sizeClassName =

components/rhythm/occurrence.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1+
import { useTheme } from '../../hooks/theme/index';
12
import { format } from 'date-fns';
23

34
export default function Occurrence({ hit, onClick, open, date }) {
5+
const [theme] = useTheme();
6+
const {
7+
occurrenceOpenBgColor,
8+
occurrenceClosedHitBgColor,
9+
occurrenceClosedMissBgColor,
10+
} = theme;
11+
412
const classNames = ["w-6", "h-6", "rounded-full", "inline-block"];
513
const formattedDate = format(date, "MMMM do, yyyy");
614

715
if (open) {
816
const ariaLabel = hit ? `Mark as missed on ${formattedDate}` : `Mark as hit on ${formattedDate}`;
9-
classNames.push("bg-white");
17+
classNames.push(occurrenceOpenBgColor);
1018

1119
if (!hit) {
1220
classNames.push("filter-blur-occurrence-miss");
@@ -21,7 +29,7 @@ export default function Occurrence({ hit, onClick, open, date }) {
2129
></button>
2230
);
2331
} else {
24-
classNames.push(hit ? "bg-red-600" : "bg-gray-100");
32+
classNames.push(hit ? occurrenceClosedHitBgColor : occurrenceClosedMissBgColor);
2533

2634
const ariaLabel = hit
2735
? `Hit target on ${formattedDate}`

components/stripe.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import { useTheme } from '../hooks/theme/index';
2+
13
export default function Stripe() {
4+
const [theme] = useTheme();
5+
const { stripeBgClass } = theme;
6+
27
return (
3-
<div className="absolute top-0 -right-12 bg-red-600 w-12 h-full"></div>
8+
<div
9+
className={`absolute top-0 -right-12 ${stripeBgClass} w-12 h-full`}
10+
></div>
411
);
512
}

hooks/theme/index.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React, { createContext, useState, useContext } from "react";
2+
import { getLocalStorageTheme, setLocalStorageTheme } from './local-storage';
3+
4+
const themeDefinitions = {
5+
swiss: {
6+
stripeBgClass: "bg-red-600",
7+
occurrenceClosedHitBgColor: "bg-red-600",
8+
occurrenceClosedMissBgColor: "bg-gray-100",
9+
occurrenceOpenBgColor: "bg-white",
10+
buttonTextColor: "text-red-600",
11+
buttonBgColor: "bg-transparent",
12+
},
13+
};
14+
15+
const DEFAULT_THEME = 'swiss';
16+
export const themeOptions = Object.keys(themeDefinitions);
17+
18+
const ThemeContext = createContext();
19+
20+
export const ThemeProvider = ({ children }) => {
21+
debugger;
22+
const { theme: localStorageTheme } = getLocalStorageTheme() ?? {};
23+
const initialThemeName = localStorageTheme ?? DEFAULT_THEME;
24+
const [themeName, setThemeName] = useState(initialThemeName);
25+
26+
const saveTheme = (theme) => {
27+
if (themeOptions.includes(theme)) {
28+
setLocalStorageTheme({ theme });
29+
setThemeName(theme);
30+
}
31+
};
32+
33+
return (
34+
<ThemeContext.Provider value={[themeDefinitions[themeName], saveTheme]}>
35+
{children}
36+
</ThemeContext.Provider>
37+
);
38+
};
39+
40+
export const useTheme = () => useContext(ThemeContext);

hooks/theme/local-storage.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const THEME_LOCAL_STORAGE_KEY = "app.theme";
2+
3+
export function getLocalStorageTheme() {
4+
try {
5+
const jsonData = window.localStorage.getItem(THEME_LOCAL_STORAGE_KEY);
6+
const themeData = JSON.parse(jsonData);
7+
return themeData;
8+
} catch {
9+
return;
10+
}
11+
}
12+
13+
export function setLocalStorageTheme(themeData) {
14+
window.localStorage.setItem(THEME_LOCAL_STORAGE_KEY, JSON.stringify(themeData));
15+
}

pages/_app.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import '../styles/globals.css'
1+
import dynamic from "next/dynamic";
2+
import "../styles/globals.css";
23
import { RhythmsProvider } from "../hooks/rhythms/index";
4+
import { ThemeProvider } from "../hooks/theme/index";
35

46
function MyApp({ Component, pageProps }) {
57
return (
6-
<RhythmsProvider>
7-
<Component {...pageProps} />
8-
</RhythmsProvider>
8+
<ThemeProvider>
9+
<RhythmsProvider>
10+
<Component {...pageProps} />
11+
</RhythmsProvider>
12+
</ThemeProvider>
913
);
1014
}
1115

12-
export default MyApp
16+
export default MyApp;

pages/index.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import dynamic from 'next/dynamic'
12
import Head from "next/head";
23
import { useState } from "react";
3-
import { useRhythms, RhythmsProvider } from "../hooks/rhythms/index";
4+
import { useRhythms } from "../hooks/rhythms/index";
45
import RhythmEdit from "../components/rhythm-edit/rhythm-edit";
56
import Stripe from "../components/stripe";
67
import Modal from "../components/modal";
@@ -16,7 +17,7 @@ function emptyRhythm() {
1617
};
1718
}
1819

19-
export default function Home() {
20+
function RhythmischApp() {
2021
const [modalIsOpen, setModal] = useState(false);
2122
const [rhythmToEdit, setRhythmToEdit] = useState();
2223
const [, rhythmsDispatch] = useRhythms();
@@ -81,3 +82,5 @@ export default function Home() {
8182
</>
8283
);
8384
}
85+
86+
export default dynamic(() => Promise.resolve(RhythmischApp), { ssr: false });

styles/globals.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
.bg-filter-blur-modal {
1111
backdrop-filter: blur(5px);
1212
}
13-
}
13+
}

tailwind.config.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,26 @@ function customContainer({ addComponents, theme }) {
1515
});
1616
}
1717

18+
function addColorCssProperties({ addComponents, config }) {
19+
const colors = config(`theme.colors`, []);
20+
const cssProperties = {};
1821

22+
for (const color in colors) {
23+
const colorObj = colors[color];
24+
25+
for (colorKey in colorObj) {
26+
const hexValue = colorObj[colorKey].toString();
27+
const cssPropertyName = `--color-${color}-${colorKey}`.replace(
28+
/-default$/,
29+
""
30+
);
31+
32+
cssProperties[cssPropertyName] = hexValue;
33+
}
34+
}
35+
36+
addComponents({ ':root': cssProperties });
37+
}
1938

2039
module.exports = {
2140
purge: ["./pages/**/*.js", "./components/**/*.js"],
@@ -29,5 +48,5 @@ module.exports = {
2948
variants: {
3049
extend: {},
3150
},
32-
plugins: [customContainer],
51+
plugins: [customContainer, addColorCssProperties],
3352
};

0 commit comments

Comments
 (0)