Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions apps/frontend/src/pages/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ export function HomeScreen({ stage, setStage }: HomeScreenProps): JSX.Element {
<ThemeStage
card={cardBuilder}
theme={theme}
isRepoCard={isRepoCard}
onThemeChange={(theme) => {
setTheme(theme);
setStage(4);
Expand Down
33 changes: 27 additions & 6 deletions apps/frontend/src/pages/Home/stages/Theme.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ThemeName } from "@stats-organization/github-readme-stats-core";
import { themes } from "@stats-organization/github-readme-stats-core";
import type { JSX } from "react";

Expand All @@ -10,8 +11,6 @@ import type { CardUrlBuilder } from "../../../models/CardUrl";
import { useTheme } from "../../../redux/selectors/themeSelectors";

const excludedThemes = [
"default",
"default_repocard",
"github_dark",
"merko",
"blue-green",
Expand All @@ -21,29 +20,51 @@ const excludedThemes = [
"holi",
];

const allThemeNames = Object.keys(themes) as Array<ThemeName>;

// Light themes first, adaptive themes in the middle, dark themes last.
const themeList = Object.keys(themes)
.filter((myTheme) => !excludedThemes.includes(myTheme))
.sort((a, b) => getThemeSortRank(a) - getThemeSortRank(b));
const forPicker = (names: ReadonlyArray<ThemeName>) =>
names
.filter((name) => !excludedThemes.includes(name))
.sort((a, b) => getThemeSortRank(a) - getThemeSortRank(b));

// Some themes come in pairs: `X_repocard` for the repo and gist cards, `X` for
// the stats, top languages and WakaTime cards. Each side offers only its own
// variant, so the theme Home.tsx starts on is always one of the entries here.
//
// Keep in sync with `generateTable` in `packages/core/scripts/generate-theme-readme.js`,
// which splits the theme README tables by the same rule.
const repoCardThemes = forPicker(
allThemeNames.filter(
(name) => !allThemeNames.includes(`${name}_repocard` as ThemeName),
),
);

const nonRepoCardThemes = forPicker(
allThemeNames.filter((name) => !name.endsWith("_repocard")),
);

interface ThemeStageProps {
card: CardUrlBuilder;
theme: string;
isRepoCard: boolean;
onThemeChange: (theme: string) => void;
}

export function ThemeStage({
theme,
card,
isRepoCard,
onThemeChange,
}: ThemeStageProps): JSX.Element {
const { isDark } = useTheme();
const themeList = isRepoCard ? repoCardThemes : nonRepoCardThemes;

return (
<>
<div className="flex flex-wrap">
{themeList.map((myTheme) => {
const themeColors = themes[myTheme as keyof typeof themes];
const themeColors = themes[myTheme];
return (
<button
className="p-2 lg:p-4"
Expand Down
4 changes: 2 additions & 2 deletions docs/advanced_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ You can look at a preview for [all available themes](../packages/core/src/themes

#### Light and Dark Mode

[![Anurag's GitHub stats-Dark](https://github-stats-extended.vercel.app/api?username=anuraghazra&show_icons=true&theme=dark_github#gh-dark-mode-only)](https://github.com/stats-organization/github-stats-extended#responsive-card-theme#gh-dark-mode-only)
[![Anurag's GitHub stats-Light](https://github-stats-extended.vercel.app/api?username=anuraghazra&show_icons=true&theme=light_github#gh-light-mode-only)](https://github.com/stats-organization/github-stats-extended#responsive-card-theme#gh-light-mode-only)
[![Anurag's GitHub stats-Dark](https://github-stats-extended.vercel.app/api?username=anuraghazra&show_icons=true&theme=dark_github#gh-dark-mode-only)](#light-and-dark-mode)
[![Anurag's GitHub stats-Light](https://github-stats-extended.vercel.app/api?username=anuraghazra&show_icons=true&theme=light_github#gh-light-mode-only)](#light-and-dark-mode)

There are several methods you can use to create dynamic themes on the client side.

Expand Down
20 changes: 17 additions & 3 deletions packages/core/scripts/generate-theme-readme.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,25 @@ const createTableItem = ({ link, label, isRepoCard }) => {
return `\`${label}\` ![${link}][${link}${isRepoCard ? "_repo" : ""}]`;
};

const allThemeNames = Object.keys(themes);

// Some themes come in pairs: `X_repocard` for the repo and gist cards, `X` for
// the stats, top languages and WakaTime cards. Each table lists only its own
// variant.
//
// Keep in sync with the theme lists in `apps/frontend/src/pages/Home/stages/Theme.tsx`,
// which splits the picker by the same rule.
const repoCardThemes = allThemeNames.filter(
(name) => !allThemeNames.includes(`${name}_repocard`),
);

const nonRepoCardThemes = allThemeNames.filter(
(name) => !name.endsWith("_repocard"),
);

const generateTable = ({ isRepoCard }) => {
const rows = [];
const themesFiltered = Object.keys(themes).filter(
(name) => name !== (isRepoCard ? "default" : "default_repocard"),
);
const themesFiltered = isRepoCard ? repoCardThemes : nonRepoCardThemes;

for (let i = 0; i < themesFiltered.length; i += 3) {
const one = themesFiltered[i];
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/cards/types.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type { themes } from "../themes/index.js";
import type { ThemeName } from "../themes/index.js";

type ThemeNames = keyof typeof themes;
type RankIcon = "default" | "github" | "percentile";

interface CommonOptions {
title_color: string;
icon_color: string;
text_color: string;
bg_color: string;
theme: ThemeNames;
theme: ThemeName;
border_radius: number;
border_color: string;
locale: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/common/color.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { themes } from "../themes/index.js";
import type { ThemeName } from "../themes/index.js";

/** Matches a 3-, 4-, 6-, or 8-digit hex color with no leading `#`. */
const HEX_COLOR =
Expand Down Expand Up @@ -174,7 +175,7 @@ const getCardColors = ({
const isThemeProvided = theme !== undefined && theme in themes;

const selectedTheme = isThemeProvided
? themes[theme as keyof typeof themes]
? themes[theme as ThemeName]
: defaultTheme;

const defaultBorderColor =
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ export { default as wakatime } from "./api/wakatime.js";
export { getConfig, loadConfigFromEnv } from "./common/config.js";

export { themes } from "./themes/index.js";
export type { ThemeName } from "./themes/index.js";
Loading