mirror of
https://github.com/Aviortheking/codestats-readme.git
synced 2025-06-07 16:29:57 +00:00
feat: added inbuilt themes (#105)
* feat: added inbuilt themes * docs: added theming docs * docs: update docs
This commit is contained in:
parent
b4a9bd4468
commit
2c26329e13
@ -16,6 +16,7 @@ module.exports = async (req, res) => {
|
|||||||
icon_color,
|
icon_color,
|
||||||
text_color,
|
text_color,
|
||||||
bg_color,
|
bg_color,
|
||||||
|
theme,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
let stats;
|
let stats;
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ module.exports = async (req, res) => {
|
|||||||
icon_color,
|
icon_color,
|
||||||
text_color,
|
text_color,
|
||||||
bg_color,
|
bg_color,
|
||||||
|
theme,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,7 @@ module.exports = async (req, res) => {
|
|||||||
icon_color,
|
icon_color,
|
||||||
text_color,
|
text_color,
|
||||||
bg_color,
|
bg_color,
|
||||||
|
theme,
|
||||||
show_owner,
|
show_owner,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ module.exports = async (req, res) => {
|
|||||||
icon_color,
|
icon_color,
|
||||||
text_color,
|
text_color,
|
||||||
bg_color,
|
bg_color,
|
||||||
|
theme,
|
||||||
show_owner: parseBoolean(show_owner),
|
show_owner: parseBoolean(show_owner),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
32
readme.md
32
readme.md
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
- [GitHub Stats Card](#github-stats-card)
|
- [GitHub Stats Card](#github-stats-card)
|
||||||
- [GitHub Extra Pins](#github-extra-pins)
|
- [GitHub Extra Pins](#github-extra-pins)
|
||||||
|
- [Themes](#themes)
|
||||||
- [Customization](#customization)
|
- [Customization](#customization)
|
||||||
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
|
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
|
||||||
|
|
||||||
@ -66,6 +67,22 @@ To enable icons, you can pass `show_icons=true` in the query param, like so:
|
|||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Themes
|
||||||
|
|
||||||
|
With inbuilt themes you can customize the look of the card without doing any [manual customization](#customization).
|
||||||
|
|
||||||
|
Use `?theme=THEME_NAME` parameter like so :-
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
#### All inbuilt themes :-
|
||||||
|
|
||||||
|
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||||
|
|
||||||
|
Check out more themes at [theme config file](./themes/index.js) & **you can also contribute new themes** if you like :D
|
||||||
|
|
||||||
### Customization
|
### Customization
|
||||||
|
|
||||||
You can customize the appearance of your `Stats Card` or `Repo Card` however you want with URL params.
|
You can customize the appearance of your `Stats Card` or `Repo Card` however you want with URL params.
|
||||||
@ -84,12 +101,9 @@ Customization Options:
|
|||||||
| hide_border | boolean | hides the stats card border | false | N/A |
|
| hide_border | boolean | hides the stats card border | false | N/A |
|
||||||
| show_owner | boolean | shows owner name in repo card | N/A | false |
|
| show_owner | boolean | shows owner name in repo card | N/A | false |
|
||||||
| show_icons | boolean | shows icons | false | N/A |
|
| show_icons | boolean | shows icons | false | N/A |
|
||||||
|
| theme | string | sets inbuilt theme | 'default' | 'default_repocard' |
|
||||||
|
|
||||||
- You can also customize the cards to be compatible with dark mode
|
---
|
||||||
|
|
||||||
```md
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||
### Demo
|
### Demo
|
||||||
|
|
||||||
@ -105,6 +119,12 @@ Customization Options:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
- Themes
|
||||||
|
|
||||||
|
Choose from any of the [default themes](#themes)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
- Customizing stats card
|
- Customizing stats card
|
||||||
|
|
||||||

|

|
||||||
@ -113,6 +133,8 @@ Customization Options:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# GitHub Extra Pins
|
# GitHub Extra Pins
|
||||||
|
|
||||||
GitHub extra pins allow you to pin more than 6 repositories in your profile using a GitHub readme profile.
|
GitHub extra pins allow you to pin more than 6 repositories in your profile using a GitHub readme profile.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const {
|
const {
|
||||||
kFormatter,
|
kFormatter,
|
||||||
encodeHTML,
|
encodeHTML,
|
||||||
fallbackColor,
|
getCardColors,
|
||||||
FlexLayout,
|
FlexLayout,
|
||||||
} = require("../src/utils");
|
} = require("../src/utils");
|
||||||
const icons = require("./icons");
|
const icons = require("./icons");
|
||||||
@ -16,7 +16,14 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
isArchived,
|
isArchived,
|
||||||
forkCount,
|
forkCount,
|
||||||
} = repo;
|
} = repo;
|
||||||
const { title_color, icon_color, text_color, bg_color, show_owner } = options;
|
const {
|
||||||
|
title_color,
|
||||||
|
icon_color,
|
||||||
|
text_color,
|
||||||
|
bg_color,
|
||||||
|
show_owner,
|
||||||
|
theme = "default_repocard",
|
||||||
|
} = options;
|
||||||
|
|
||||||
const header = show_owner ? nameWithOwner : name;
|
const header = show_owner ? nameWithOwner : name;
|
||||||
const langName = primaryLanguage ? primaryLanguage.name : "Unspecified";
|
const langName = primaryLanguage ? primaryLanguage.name : "Unspecified";
|
||||||
@ -30,10 +37,14 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
desc = `${description.slice(0, 55)}..`;
|
desc = `${description.slice(0, 55)}..`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const titleColor = fallbackColor(title_color, "#2f80ed");
|
// returns theme based colors with proper overrides and defaults
|
||||||
const iconColor = fallbackColor(icon_color, "#586069");
|
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||||
const textColor = fallbackColor(text_color, "#333");
|
title_color,
|
||||||
const bgColor = fallbackColor(bg_color, "#FFFEFE");
|
icon_color,
|
||||||
|
text_color,
|
||||||
|
bg_color,
|
||||||
|
theme,
|
||||||
|
});
|
||||||
|
|
||||||
const totalStars = kFormatter(stargazers.totalCount);
|
const totalStars = kFormatter(stargazers.totalCount);
|
||||||
const totalForks = kFormatter(forkCount);
|
const totalForks = kFormatter(forkCount);
|
||||||
@ -82,7 +93,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
.archive-badge { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; }
|
.archive-badge { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; }
|
||||||
.archive-badge rect { opacity: 0.2 }
|
.archive-badge rect { opacity: 0.2 }
|
||||||
</style>
|
</style>
|
||||||
<rect data-testid="card-border" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
|
<rect data-testid="card-bg" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
|
||||||
<svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
<svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
||||||
${icons.contribs}
|
${icons.contribs}
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { kFormatter, fallbackColor, FlexLayout } = require("../src/utils");
|
const { kFormatter, getCardColors, FlexLayout } = require("../src/utils");
|
||||||
const getStyles = require("./getStyles");
|
const getStyles = require("./getStyles");
|
||||||
const icons = require("./icons");
|
const icons = require("./icons");
|
||||||
|
|
||||||
@ -44,14 +44,19 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
|||||||
icon_color,
|
icon_color,
|
||||||
text_color,
|
text_color,
|
||||||
bg_color,
|
bg_color,
|
||||||
|
theme = "default",
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const lheight = parseInt(line_height);
|
const lheight = parseInt(line_height);
|
||||||
|
|
||||||
const titleColor = fallbackColor(title_color, "#2f80ed");
|
// returns theme based colors with proper overrides and defaults
|
||||||
const iconColor = fallbackColor(icon_color, "#4c71f2");
|
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||||
const textColor = fallbackColor(text_color, "#333");
|
title_color,
|
||||||
const bgColor = fallbackColor(bg_color, "#FFFEFE");
|
icon_color,
|
||||||
|
text_color,
|
||||||
|
bg_color,
|
||||||
|
theme,
|
||||||
|
});
|
||||||
|
|
||||||
// Meta data for creating text nodes with createTextNode function
|
// Meta data for creating text nodes with createTextNode function
|
||||||
const STATS = {
|
const STATS = {
|
||||||
@ -127,7 +132,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
|||||||
? ""
|
? ""
|
||||||
: `
|
: `
|
||||||
<rect
|
<rect
|
||||||
data-testid="card-border"
|
data-testid="card-bg"
|
||||||
x="0.5"
|
x="0.5"
|
||||||
y="0.5"
|
y="0.5"
|
||||||
width="494"
|
width="494"
|
||||||
|
36
src/utils.js
36
src/utils.js
@ -1,4 +1,5 @@
|
|||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
const themes = require("../themes");
|
||||||
|
|
||||||
const renderError = (message) => {
|
const renderError = (message) => {
|
||||||
return `
|
return `
|
||||||
@ -77,6 +78,40 @@ function FlexLayout({ items, gap, direction }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns theme based colors with proper overrides and defaults
|
||||||
|
function getCardColors({
|
||||||
|
title_color,
|
||||||
|
text_color,
|
||||||
|
icon_color,
|
||||||
|
bg_color,
|
||||||
|
theme,
|
||||||
|
fallbackTheme = "default",
|
||||||
|
}) {
|
||||||
|
const defaultTheme = themes[fallbackTheme];
|
||||||
|
const selectedTheme = themes[theme] || defaultTheme;
|
||||||
|
|
||||||
|
// get the color provided by the user else the theme color
|
||||||
|
// finally if both colors are invalid fallback to default theme
|
||||||
|
const titleColor = fallbackColor(
|
||||||
|
title_color || selectedTheme.title_color,
|
||||||
|
"#" + defaultTheme.title_color
|
||||||
|
);
|
||||||
|
const iconColor = fallbackColor(
|
||||||
|
icon_color || selectedTheme.icon_color,
|
||||||
|
"#" + defaultTheme.icon_color
|
||||||
|
);
|
||||||
|
const textColor = fallbackColor(
|
||||||
|
text_color || selectedTheme.text_color,
|
||||||
|
"#" + defaultTheme.text_color
|
||||||
|
);
|
||||||
|
const bgColor = fallbackColor(
|
||||||
|
bg_color || selectedTheme.bg_color,
|
||||||
|
"#" + defaultTheme.bg_color
|
||||||
|
);
|
||||||
|
|
||||||
|
return { titleColor, iconColor, textColor, bgColor };
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
renderError,
|
renderError,
|
||||||
kFormatter,
|
kFormatter,
|
||||||
@ -86,4 +121,5 @@ module.exports = {
|
|||||||
parseBoolean,
|
parseBoolean,
|
||||||
fallbackColor,
|
fallbackColor,
|
||||||
FlexLayout,
|
FlexLayout,
|
||||||
|
getCardColors,
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ const cssToObject = require("css-to-object");
|
|||||||
const renderRepoCard = require("../src/renderRepoCard");
|
const renderRepoCard = require("../src/renderRepoCard");
|
||||||
|
|
||||||
const { queryByTestId } = require("@testing-library/dom");
|
const { queryByTestId } = require("@testing-library/dom");
|
||||||
|
const themes = require("../themes");
|
||||||
|
|
||||||
const data_repo = {
|
const data_repo = {
|
||||||
repository: {
|
repository: {
|
||||||
@ -108,13 +109,13 @@ describe("Test renderRepoCard", () => {
|
|||||||
const stylesObject = cssToObject(styleTag.innerHTML);
|
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||||
|
|
||||||
const headerClassStyles = stylesObject[".header"];
|
const headerClassStyles = stylesObject[".header"];
|
||||||
const statClassStyles = stylesObject[".description"];
|
const descClassStyles = stylesObject[".description"];
|
||||||
const iconClassStyles = stylesObject[".icon"];
|
const iconClassStyles = stylesObject[".icon"];
|
||||||
|
|
||||||
expect(headerClassStyles.fill).toBe("#2f80ed");
|
expect(headerClassStyles.fill).toBe("#2f80ed");
|
||||||
expect(statClassStyles.fill).toBe("#333");
|
expect(descClassStyles.fill).toBe("#333");
|
||||||
expect(iconClassStyles.fill).toBe("#586069");
|
expect(iconClassStyles.fill).toBe("#586069");
|
||||||
expect(queryByTestId(document.body, "card-border")).toHaveAttribute(
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
"fill",
|
"fill",
|
||||||
"#FFFEFE"
|
"#FFFEFE"
|
||||||
);
|
);
|
||||||
@ -136,18 +137,63 @@ describe("Test renderRepoCard", () => {
|
|||||||
const stylesObject = cssToObject(styleTag.innerHTML);
|
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||||
|
|
||||||
const headerClassStyles = stylesObject[".header"];
|
const headerClassStyles = stylesObject[".header"];
|
||||||
const statClassStyles = stylesObject[".description"];
|
const descClassStyles = stylesObject[".description"];
|
||||||
const iconClassStyles = stylesObject[".icon"];
|
const iconClassStyles = stylesObject[".icon"];
|
||||||
|
|
||||||
expect(headerClassStyles.fill).toBe(`#${customColors.title_color}`);
|
expect(headerClassStyles.fill).toBe(`#${customColors.title_color}`);
|
||||||
expect(statClassStyles.fill).toBe(`#${customColors.text_color}`);
|
expect(descClassStyles.fill).toBe(`#${customColors.text_color}`);
|
||||||
expect(iconClassStyles.fill).toBe(`#${customColors.icon_color}`);
|
expect(iconClassStyles.fill).toBe(`#${customColors.icon_color}`);
|
||||||
expect(queryByTestId(document.body, "card-border")).toHaveAttribute(
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
"fill",
|
"fill",
|
||||||
"#252525"
|
"#252525"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should render custom colors with themes", () => {
|
||||||
|
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
||||||
|
title_color: "5a0",
|
||||||
|
theme: "radical",
|
||||||
|
});
|
||||||
|
|
||||||
|
const styleTag = document.querySelector("style");
|
||||||
|
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||||
|
|
||||||
|
const headerClassStyles = stylesObject[".header"];
|
||||||
|
const descClassStyles = stylesObject[".description"];
|
||||||
|
const iconClassStyles = stylesObject[".icon"];
|
||||||
|
|
||||||
|
expect(headerClassStyles.fill).toBe("#5a0");
|
||||||
|
expect(descClassStyles.fill).toBe(`#${themes.radical.text_color}`);
|
||||||
|
expect(iconClassStyles.fill).toBe(`#${themes.radical.icon_color}`);
|
||||||
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
|
"fill",
|
||||||
|
`#${themes.radical.bg_color}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render custom colors with themes and fallback to default colors if invalid", () => {
|
||||||
|
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
||||||
|
title_color: "invalid color",
|
||||||
|
text_color: "invalid color",
|
||||||
|
theme: "radical",
|
||||||
|
});
|
||||||
|
|
||||||
|
const styleTag = document.querySelector("style");
|
||||||
|
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||||
|
|
||||||
|
const headerClassStyles = stylesObject[".header"];
|
||||||
|
const descClassStyles = stylesObject[".description"];
|
||||||
|
const iconClassStyles = stylesObject[".icon"];
|
||||||
|
|
||||||
|
expect(headerClassStyles.fill).toBe(`#${themes.default.title_color}`);
|
||||||
|
expect(descClassStyles.fill).toBe(`#${themes.default.text_color}`);
|
||||||
|
expect(iconClassStyles.fill).toBe(`#${themes.radical.icon_color}`);
|
||||||
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
|
"fill",
|
||||||
|
`#${themes.radical.bg_color}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should render archive badge if repo is archived", () => {
|
it("should render archive badge if repo is archived", () => {
|
||||||
document.body.innerHTML = renderRepoCard({
|
document.body.innerHTML = renderRepoCard({
|
||||||
...data_repo.repository,
|
...data_repo.repository,
|
||||||
@ -176,7 +222,7 @@ describe("Test renderRepoCard", () => {
|
|||||||
|
|
||||||
expect(queryByTestId(document.body, "stargazers")).toBeDefined();
|
expect(queryByTestId(document.body, "stargazers")).toBeDefined();
|
||||||
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
||||||
|
|
||||||
document.body.innerHTML = renderRepoCard({
|
document.body.innerHTML = renderRepoCard({
|
||||||
...data_repo.repository,
|
...data_repo.repository,
|
||||||
stargazers: { totalCount: 0 },
|
stargazers: { totalCount: 0 },
|
||||||
|
@ -7,6 +7,7 @@ const {
|
|||||||
queryByTestId,
|
queryByTestId,
|
||||||
queryAllByTestId,
|
queryAllByTestId,
|
||||||
} = require("@testing-library/dom");
|
} = require("@testing-library/dom");
|
||||||
|
const themes = require("../themes");
|
||||||
|
|
||||||
describe("Test renderStatsCard", () => {
|
describe("Test renderStatsCard", () => {
|
||||||
const stats = {
|
const stats = {
|
||||||
@ -34,7 +35,7 @@ describe("Test renderStatsCard", () => {
|
|||||||
expect(getByTestId(document.body, "issues").textContent).toBe("300");
|
expect(getByTestId(document.body, "issues").textContent).toBe("300");
|
||||||
expect(getByTestId(document.body, "prs").textContent).toBe("400");
|
expect(getByTestId(document.body, "prs").textContent).toBe("400");
|
||||||
expect(getByTestId(document.body, "contribs").textContent).toBe("500");
|
expect(getByTestId(document.body, "contribs").textContent).toBe("500");
|
||||||
expect(queryByTestId(document.body, "card-border")).toBeInTheDocument();
|
expect(queryByTestId(document.body, "card-bg")).toBeInTheDocument();
|
||||||
expect(queryByTestId(document.body, "rank-circle")).toBeInTheDocument();
|
expect(queryByTestId(document.body, "rank-circle")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ describe("Test renderStatsCard", () => {
|
|||||||
it("should hide_border", () => {
|
it("should hide_border", () => {
|
||||||
document.body.innerHTML = renderStatsCard(stats, { hide_border: true });
|
document.body.innerHTML = renderStatsCard(stats, { hide_border: true });
|
||||||
|
|
||||||
expect(queryByTestId(document.body, "card-border")).not.toBeInTheDocument();
|
expect(queryByTestId(document.body, "card-bg")).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should hide_rank", () => {
|
it("should hide_rank", () => {
|
||||||
@ -79,7 +80,7 @@ describe("Test renderStatsCard", () => {
|
|||||||
expect(headerClassStyles.fill).toBe("#2f80ed");
|
expect(headerClassStyles.fill).toBe("#2f80ed");
|
||||||
expect(statClassStyles.fill).toBe("#333");
|
expect(statClassStyles.fill).toBe("#333");
|
||||||
expect(iconClassStyles.fill).toBe("#4c71f2");
|
expect(iconClassStyles.fill).toBe("#4c71f2");
|
||||||
expect(queryByTestId(document.body, "card-border")).toHaveAttribute(
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
"fill",
|
"fill",
|
||||||
"#FFFEFE"
|
"#FFFEFE"
|
||||||
);
|
);
|
||||||
@ -105,12 +106,57 @@ describe("Test renderStatsCard", () => {
|
|||||||
expect(headerClassStyles.fill).toBe(`#${customColors.title_color}`);
|
expect(headerClassStyles.fill).toBe(`#${customColors.title_color}`);
|
||||||
expect(statClassStyles.fill).toBe(`#${customColors.text_color}`);
|
expect(statClassStyles.fill).toBe(`#${customColors.text_color}`);
|
||||||
expect(iconClassStyles.fill).toBe(`#${customColors.icon_color}`);
|
expect(iconClassStyles.fill).toBe(`#${customColors.icon_color}`);
|
||||||
expect(queryByTestId(document.body, "card-border")).toHaveAttribute(
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
"fill",
|
"fill",
|
||||||
"#252525"
|
"#252525"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should render custom colors with themes", () => {
|
||||||
|
document.body.innerHTML = renderStatsCard(stats, {
|
||||||
|
title_color: "5a0",
|
||||||
|
theme: "radical",
|
||||||
|
});
|
||||||
|
|
||||||
|
const styleTag = document.querySelector("style");
|
||||||
|
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||||
|
|
||||||
|
const headerClassStyles = stylesObject[".header"];
|
||||||
|
const statClassStyles = stylesObject[".stat"];
|
||||||
|
const iconClassStyles = stylesObject[".icon"];
|
||||||
|
|
||||||
|
expect(headerClassStyles.fill).toBe("#5a0");
|
||||||
|
expect(statClassStyles.fill).toBe(`#${themes.radical.text_color}`);
|
||||||
|
expect(iconClassStyles.fill).toBe(`#${themes.radical.icon_color}`);
|
||||||
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
|
"fill",
|
||||||
|
`#${themes.radical.bg_color}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render custom colors with themes and fallback to default colors if invalid", () => {
|
||||||
|
document.body.innerHTML = renderStatsCard(stats, {
|
||||||
|
title_color: "invalid color",
|
||||||
|
text_color: "invalid color",
|
||||||
|
theme: "radical",
|
||||||
|
});
|
||||||
|
|
||||||
|
const styleTag = document.querySelector("style");
|
||||||
|
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||||
|
|
||||||
|
const headerClassStyles = stylesObject[".header"];
|
||||||
|
const statClassStyles = stylesObject[".stat"];
|
||||||
|
const iconClassStyles = stylesObject[".icon"];
|
||||||
|
|
||||||
|
expect(headerClassStyles.fill).toBe(`#${themes.default.title_color}`);
|
||||||
|
expect(statClassStyles.fill).toBe(`#${themes.default.text_color}`);
|
||||||
|
expect(iconClassStyles.fill).toBe(`#${themes.radical.icon_color}`);
|
||||||
|
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||||
|
"fill",
|
||||||
|
`#${themes.radical.bg_color}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should hide the title", () => {
|
it("should hide the title", () => {
|
||||||
document.body.innerHTML = renderStatsCard(stats, {
|
document.body.innerHTML = renderStatsCard(stats, {
|
||||||
hide_title: true,
|
hide_title: true,
|
||||||
|
@ -3,6 +3,7 @@ const {
|
|||||||
encodeHTML,
|
encodeHTML,
|
||||||
renderError,
|
renderError,
|
||||||
FlexLayout,
|
FlexLayout,
|
||||||
|
getCardColors,
|
||||||
} = require("../src/utils");
|
} = require("../src/utils");
|
||||||
|
|
||||||
describe("Test utils.js", () => {
|
describe("Test utils.js", () => {
|
||||||
@ -49,4 +50,48 @@ describe("Test utils.js", () => {
|
|||||||
`<g transform=\"translate(0, 0)\"><text>1</text></g><g transform=\"translate(0, 60)\"><text>2</text></g>`
|
`<g transform=\"translate(0, 0)\"><text>1</text></g><g transform=\"translate(0, 60)\"><text>2</text></g>`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("getCardColors: should return expected values", () => {
|
||||||
|
let colors = getCardColors({
|
||||||
|
title_color: "f00",
|
||||||
|
text_color: "0f0",
|
||||||
|
icon_color: "00f",
|
||||||
|
bg_color: "fff",
|
||||||
|
theme: "dark",
|
||||||
|
});
|
||||||
|
expect(colors).toStrictEqual({
|
||||||
|
titleColor: "#f00",
|
||||||
|
textColor: "#0f0",
|
||||||
|
iconColor: "#00f",
|
||||||
|
bgColor: "#fff",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("getCardColors: should fallback to default colors if color is invalid", () => {
|
||||||
|
let colors = getCardColors({
|
||||||
|
title_color: "invalidcolor",
|
||||||
|
text_color: "0f0",
|
||||||
|
icon_color: "00f",
|
||||||
|
bg_color: "fff",
|
||||||
|
theme: "dark",
|
||||||
|
});
|
||||||
|
expect(colors).toStrictEqual({
|
||||||
|
titleColor: "#2f80ed",
|
||||||
|
textColor: "#0f0",
|
||||||
|
iconColor: "#00f",
|
||||||
|
bgColor: "#fff",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("getCardColors: should fallback to specified theme colors if is not defined", () => {
|
||||||
|
let colors = getCardColors({
|
||||||
|
theme: "dark",
|
||||||
|
});
|
||||||
|
expect(colors).toStrictEqual({
|
||||||
|
titleColor: "#fff",
|
||||||
|
textColor: "#9f9f9f",
|
||||||
|
iconColor: "#79ff97",
|
||||||
|
bgColor: "#151515",
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
76
themes/index.js
Normal file
76
themes/index.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
const themes = {
|
||||||
|
default: {
|
||||||
|
title_color: "2f80ed",
|
||||||
|
icon_color: "4c71f2",
|
||||||
|
text_color: "333",
|
||||||
|
bg_color: "FFFEFE",
|
||||||
|
},
|
||||||
|
default_repocard: {
|
||||||
|
title_color: "2f80ed",
|
||||||
|
icon_color: "586069", // icon color is different
|
||||||
|
text_color: "333",
|
||||||
|
bg_color: "FFFEFE",
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
title_color: "fff",
|
||||||
|
icon_color: "79ff97",
|
||||||
|
text_color: "9f9f9f",
|
||||||
|
bg_color: "151515",
|
||||||
|
},
|
||||||
|
radical: {
|
||||||
|
title_color: "fe428e",
|
||||||
|
icon_color: "f8d847",
|
||||||
|
text_color: "a9fef7",
|
||||||
|
bg_color: "141321",
|
||||||
|
},
|
||||||
|
merko: {
|
||||||
|
title_color: "abd200",
|
||||||
|
icon_color: "b7d364",
|
||||||
|
text_color: "68b587",
|
||||||
|
bg_color: "0a0f0b",
|
||||||
|
},
|
||||||
|
gruvbox: {
|
||||||
|
title_color: "fabd2f",
|
||||||
|
icon_color: "fe8019",
|
||||||
|
text_color: "8ec07c",
|
||||||
|
bg_color: "282828",
|
||||||
|
},
|
||||||
|
tokyonight: {
|
||||||
|
title_color: "70a5fd",
|
||||||
|
icon_color: "bf91f3",
|
||||||
|
text_color: "38bdae",
|
||||||
|
bg_color: "1a1b27",
|
||||||
|
},
|
||||||
|
onedark: {
|
||||||
|
title_color: "e4bf7a",
|
||||||
|
icon_color: "8eb573",
|
||||||
|
text_color: "df6d74",
|
||||||
|
bg_color: "282c34",
|
||||||
|
},
|
||||||
|
cobalt: {
|
||||||
|
title_color: "e683d9",
|
||||||
|
icon_color: "0480ef",
|
||||||
|
text_color: "75eeb2",
|
||||||
|
bg_color: "193549",
|
||||||
|
},
|
||||||
|
synthwave: {
|
||||||
|
title_color: "e2e9ec",
|
||||||
|
icon_color: "ef8539",
|
||||||
|
text_color: "e5289e",
|
||||||
|
bg_color: "2b213a",
|
||||||
|
},
|
||||||
|
highcontrast: {
|
||||||
|
title_color: "e7f216",
|
||||||
|
icon_color: "00ffff",
|
||||||
|
text_color: "fff",
|
||||||
|
bg_color: "000",
|
||||||
|
},
|
||||||
|
dracula: {
|
||||||
|
title_color: "ff6e96",
|
||||||
|
icon_color: "79dafa",
|
||||||
|
text_color: "f8f8f2",
|
||||||
|
bg_color: "282a36",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = themes;
|
Loading…
x
Reference in New Issue
Block a user