Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dark Mode issue#157 #246

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
- Dark Mode issue#157
- ThemeContext
Implemented ThemeContext to provide a light/dark theme.
- ThemeToggleButton
Added a toggle button to header
- _app
Refined the structure of Map to now utilize PrimerTheme and ThemeContext to utilize theme change easily.
- Header
Adding ThemeToggleButton to the header.
Fixing UI with flex and div
- Header.scss
Fixing UI with flex and justify content
- package.json
Added octicons to utilize theme icons
- global.scss
utilizing react-primer's built in theming to implement light/dark mode. The global css simply applied using the themeProvider's data-color-mode
- ColourStyles.tsx
Added in order to override the react-select components to override default styles and follow current theme.
- LanguageFilter & SDGFilter
Override default react-select style with newly implemented ColourStyles.
  • Loading branch information
DecodersLord committed Feb 11, 2025
commit d5086201dc2dc39b94d20f2a079035ffd6c20f2b
29 changes: 29 additions & 0 deletions components/ColorStyles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { StylesConfig } from "react-select";

export const ColorStyles: StylesConfig = {
control: (styles) => ({ ...styles, backgroundColor: "var(--brand-color-canvas-default)" }),
option: (styles, { isDisabled, isFocused, isSelected }) => {
return {
...styles,
backgroundColor: isDisabled
? undefined
: isSelected
? "var(--brand-color-text-subtle)"
: isFocused
? "var(--brand-color-focus)"
: "var(--brand-color-canvas-default)",
color: isDisabled ? "var(--brand-color-text-muted)" : "var(--brand-color-text-default)",
cursor: isDisabled ? "not-allowed" : "default",

":active": {
...styles[":active"],
backgroundColor: !isDisabled ? "var(--brand-color-focus)" : undefined
}
};
},
menu: (styles) => ({
...styles,
backgroundColor: "var(--brand-color-canvas-default)",
border: "1px solid var(--brand-color-border-default)"
})
};
11 changes: 8 additions & 3 deletions components/Header/Header.module.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

.siteHeader {
background: #26292E;
background: #26292e;

> div {
height: 72px;
@@ -13,7 +12,13 @@
margin: 0 auto;
}

@media(max-width: 800px) {
> div > div {
display: flex;
align-items: center;
grid-gap: 10px;
}

@media (max-width: 800px) {
.hideSm {
display: none;
}
30 changes: 17 additions & 13 deletions components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import styles from "./Header.module.scss";
import Link from 'next/link';
import Image from 'next/image';
import {Button} from '@primer/react-brand';
import Link from "next/link";
import Image from "next/image";
import { Button } from "@primer/react-brand";
import { ThemeToggleButton } from "./ThemeToggleButton";

export const Header = () => {
return (
<>
<header className={styles.siteHeader} data-color-mode="dark">
<header className={styles.siteHeader}>
<div>
<Link href="/" className={styles.homeLink}>
<Image
@@ -16,15 +17,18 @@ export const Header = () => {
alt="For Good First Issue logo"
/>
</Link>
<Button
variant="primary"
as="a"
href="https://github.com/rubyforgood/happycommits/issues/new?assignees=&labels=💪+New+Project&projects=&template=suggest_project.yml&title=%5BNew+Project%5D%3A+%3Ctitle%3E"
target="_blank"
rel="noopener noreferrer"
>
<span className={styles.btnText}>Recommend a project</span>
</Button>
<div>
<Button
variant="primary"
as="a"
href="https://github.com/rubyforgood/happycommits/issues/new?assignees=&labels=💪+New+Project&projects=&template=suggest_project.yml&title=%5BNew+Project%5D%3A+%3Ctitle%3E"
target="_blank"
rel="noopener noreferrer"
>
<span className={styles.btnText}>Recommend a project</span>
</Button>
<ThemeToggleButton />
</div>
</div>
</header>
</>
24 changes: 24 additions & 0 deletions components/Header/ThemeToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import { useTheme } from "../../context/ThemeContext";
import { SunIcon } from "@primer/octicons-react";
import { MoonIcon } from "@primer/octicons-react";

import { Button } from "@primer/react-brand";

export const ThemeToggleButton = () => {
const { colorMode, toggleColorMode } = useTheme();

return (
<>
<Button
variant="subtle"
size="medium"
onClick={toggleColorMode}
hasArrow={false}
colorMode={colorMode}
>
{colorMode === "light" ? <MoonIcon size={24} fill="#fff" /> : <SunIcon size={24} />}
</Button>
</>
);
};
14 changes: 12 additions & 2 deletions components/LanguageFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Select from "react-select";
import { ColorStyles } from "./ColorStyles";

type LanguageFilterProps = {
setSelectedLanguages: (languages: string[]) => void;
@@ -10,9 +11,18 @@ export const LanguageFilter = ({ setSelectedLanguages, languageOptions }: Langua
<>
<div>
<label className="label">Language</label>
<Select isMulti closeMenuOnSelect={false} className="" onChange={(selectedOptions) => setSelectedLanguages(selectedOptions.map((option) => option.value))} options={languageOptions} classNamePrefix="select" />
<Select
styles={ColorStyles}
isMulti
closeMenuOnSelect={false}
className=""
onChange={(selectedOptions) =>
setSelectedLanguages(selectedOptions.map((option) => option.value))
}
options={languageOptions}
classNamePrefix="select"
/>
</div>
</>

);
};
2 changes: 2 additions & 0 deletions components/SDGFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Select from "react-select";
import { ColorStyles } from "./ColorStyles";

type SDGFilterProps = {
setSelectedTopics: (topics: string[]) => void;
@@ -13,6 +14,7 @@ export const SDGFilter = ({ setSelectedTopics, topicOptions }: SDGFilterProps) =
<Select
isMulti
className=""
styles={ColorStyles}
options={topicOptions}
getOptionLabel={(option) => option.label}
getOptionValue={(option) => option.value ?? ""}
28 changes: 28 additions & 0 deletions context/ThemeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { createContext, useContext, useState } from "react";

interface ThemeContextType {
colorMode: "light" | "dark";
toggleColorMode: () => void;
}

const ThemeContext = createContext<ThemeContextType | undefined>(undefined);

export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [colorMode, setColorMode] = useState<"light" | "dark">("light");

const toggleColorMode = () => {
setColorMode((prevMode) => (prevMode === "light" ? "dark" : "light"));
};

return (
<ThemeContext.Provider value={{ colorMode, toggleColorMode }}>{children}</ThemeContext.Provider>
);
};

export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
};
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/react-fontawesome": "^0.2.1",
"@primer/octicons-react": "^19.15.0",
"@primer/react-brand": "^0.44.1",
"@types/node": "20.13.0",
"@types/react": "^18.2.0",
30 changes: 22 additions & 8 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import '@primer/react-brand/lib/css/main.css';
import '@primer/react-brand/fonts/fonts.css';
import "@primer/react-brand/lib/css/main.css";
import "@primer/react-brand/fonts/fonts.css";
import type { AppProps } from "next/app";
import Head from "next/head";
import { Layout } from "../components/Layout";
import { AppDataProvider } from "../context/AppDataContext";
import "../styles/globals.scss";
import {ThemeProvider} from '@primer/react-brand'
import { ThemeProvider as PrimerThemeProvider } from "@primer/react-brand";
import { ThemeProvider, useTheme } from "../context/ThemeContext";

// Fontawesome and TailwindCSS related settings
//config.autoAddCss = false;
function AppWithTheme({ Component, pageProps }: AppProps) {
const { colorMode } = useTheme();

// Entry point for the app
export default function App({ Component, pageProps }: AppProps) {
return (
<ThemeProvider>
<PrimerThemeProvider
colorMode={colorMode}
style={{ backgroundColor: "var(--brand-color-canvas-default)" }}
>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>
@@ -24,6 +26,18 @@ export default function App({ Component, pageProps }: AppProps) {
</Layout>
</main>
</AppDataProvider>
</PrimerThemeProvider>
);
}

// Fontawesome and TailwindCSS related settings
//config.autoAddCss = false;

// Entry point for the app
export default function App(props: AppProps) {
return (
<ThemeProvider>
<AppWithTheme {...props} />
</ThemeProvider>
);
}
Loading
Oops, something went wrong.