Skip to content

Commit 9aa39df

Browse files
feat: allow users to pass ring_color param (#2075)
* fix: prevent crash if undefined color is passed to func fallbackColor * feat: allow users to pass ring_color param Before this commit, the ring color was always equal to the title color. This commit allows the user to pass a ring_color property to allow him to style the ring color the way he pleases to. If no ring_color is passed we default to the title color. * docs: improves ring color documentation * fix: improve code style Co-authored-by: rickstaa <[email protected]>
1 parent 0c829e9 commit 9aa39df

File tree

9 files changed

+114
-8
lines changed

9 files changed

+114
-8
lines changed

api/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default async (req, res) => {
2626
include_all_commits,
2727
line_height,
2828
title_color,
29+
ring_color,
2930
icon_color,
3031
text_color,
3132
text_bold,
@@ -76,6 +77,7 @@ export default async (req, res) => {
7677
include_all_commits: parseBoolean(include_all_commits),
7778
line_height,
7879
title_color,
80+
ring_color,
7981
icon_color,
8082
text_color,
8183
text_bold: parseBoolean(text_bold),

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ You can provide multiple comma-separated values in the bg_color option to render
286286
- `custom_title` - Sets a custom title for the card. Default: `<username> GitHub Stats`.
287287
- `text_bold` - Use bold text _(boolean)_. Default: `true`.
288288
- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`.
289+
- `ring_color` - Color of the rank circle _(hex color)_. Defaults to the theme ring color if it exists and otherwise the title color.
289290

290291
> **Note**
291292
> When hide_rank=`true`, the minimum card width is 270 px + the title length and padding.

src/cards/stats-card.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
8989
include_all_commits = false,
9090
line_height = 25,
9191
title_color,
92+
ring_color,
9293
icon_color,
9394
text_color,
9495
text_bold = true,
@@ -104,13 +105,14 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
104105
const lheight = parseInt(String(line_height), 10);
105106

106107
// returns theme based colors with proper overrides and defaults
107-
const { titleColor, textColor, iconColor, bgColor, borderColor } =
108+
const { titleColor, iconColor, textColor, bgColor, borderColor, ringColor } =
108109
getCardColors({
109110
title_color,
110-
icon_color,
111111
text_color,
112+
icon_color,
112113
bg_color,
113114
border_color,
115+
ring_color,
114116
theme,
115117
});
116118

@@ -201,6 +203,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
201203
const progress = 100 - rank.score;
202204
const cssStyles = getStyles({
203205
titleColor,
206+
ringColor,
204207
textColor,
205208
iconColor,
206209
show_icons,

src/common/utils.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ function isValidGradient(colors) {
133133
* @returns {string | string[]} The gradient or color.
134134
*/
135135
function fallbackColor(color, fallbackColor) {
136-
let colors = color.split(",");
137136
let gradient = null;
138137

138+
let colors = color ? color.split(",") : [];
139139
if (colors.length > 1 && isValidGradient(colors)) {
140140
gradient = colors;
141141
}
@@ -207,6 +207,7 @@ function getCardColors({
207207
icon_color,
208208
bg_color,
209209
border_color,
210+
ring_color,
210211
theme,
211212
fallbackTheme = "default",
212213
}) {
@@ -221,6 +222,13 @@ function getCardColors({
221222
title_color || selectedTheme.title_color,
222223
"#" + defaultTheme.title_color,
223224
);
225+
226+
// get the color provided by the user else the theme color
227+
// finally if both colors are invalid we use the titleColor
228+
const ringColor = fallbackColor(
229+
ring_color || selectedTheme.ring_color,
230+
titleColor,
231+
);
224232
const iconColor = fallbackColor(
225233
icon_color || selectedTheme.icon_color,
226234
"#" + defaultTheme.icon_color,
@@ -239,7 +247,7 @@ function getCardColors({
239247
"#" + defaultBorderColor,
240248
);
241249

242-
return { titleColor, iconColor, textColor, bgColor, borderColor };
250+
return { titleColor, iconColor, textColor, bgColor, borderColor, ringColor };
243251
}
244252

245253
/**

src/getStyles.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const getStyles = ({
7777
titleColor,
7878
textColor,
7979
iconColor,
80+
ringColor,
8081
show_icons,
8182
progress,
8283
}) => {
@@ -105,13 +106,13 @@ const getStyles = ({
105106
}
106107
107108
.rank-circle-rim {
108-
stroke: ${titleColor};
109+
stroke: ${ringColor};
109110
fill: none;
110111
stroke-width: 6;
111112
opacity: 0.2;
112113
}
113114
.rank-circle {
114-
stroke: ${titleColor};
115+
stroke: ${ringColor};
115116
stroke-dasharray: 250;
116117
fill: none;
117118
stroke-width: 6;

tests/__snapshots__/renderWakatimeCard.test.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ exports[`Test Render Wakatime Card should render correctly with compact layout 1
5151
}
5252
5353
.rank-circle-rim {
54-
stroke: #2f80ed;
54+
stroke: undefined;
5555
fill: none;
5656
stroke-width: 6;
5757
opacity: 0.2;
5858
}
5959
.rank-circle {
60-
stroke: #2f80ed;
60+
stroke: undefined;
6161
stroke-dasharray: 250;
6262
fill: none;
6363
stroke-width: 6;

tests/api.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,39 @@ describe("Test /api/", () => {
248248
),
249249
);
250250
});
251+
252+
it("should allow changing ring_color", async () => {
253+
const { req, res } = faker(
254+
{
255+
username: "anuraghazra",
256+
hide: "issues,prs,contribs",
257+
show_icons: true,
258+
hide_border: true,
259+
line_height: 100,
260+
title_color: "fff",
261+
ring_color: "0000ff",
262+
icon_color: "fff",
263+
text_color: "fff",
264+
bg_color: "fff",
265+
},
266+
data,
267+
);
268+
269+
await api(req, res);
270+
271+
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
272+
expect(res.send).toBeCalledWith(
273+
renderStatsCard(stats, {
274+
hide: ["issues", "prs", "contribs"],
275+
show_icons: true,
276+
hide_border: true,
277+
line_height: 100,
278+
title_color: "fff",
279+
ring_color: "0000ff",
280+
icon_color: "fff",
281+
text_color: "fff",
282+
bg_color: "fff",
283+
}),
284+
);
285+
});
251286
});

tests/renderStatsCard.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,39 @@ describe("Test renderStatsCard", () => {
239239
);
240240
});
241241

242+
it("should render custom ring_color properly", () => {
243+
const customColors = {
244+
title_color: "5a0",
245+
ring_color: "0000ff",
246+
icon_color: "1b998b",
247+
text_color: "9991",
248+
bg_color: "252525",
249+
};
250+
251+
document.body.innerHTML = renderStatsCard(stats, { ...customColors });
252+
253+
const styleTag = document.querySelector("style");
254+
const stylesObject = cssToObject(styleTag.innerHTML);
255+
256+
const headerClassStyles = stylesObject[":host"][".header "];
257+
const statClassStyles = stylesObject[":host"][".stat "];
258+
const iconClassStyles = stylesObject[":host"][".icon "];
259+
const rankCircleStyles = stylesObject[":host"][".rank-circle "];
260+
const rankCircleRimStyles = stylesObject[":host"][".rank-circle-rim "];
261+
262+
expect(headerClassStyles.fill.trim()).toBe(`#${customColors.title_color}`);
263+
expect(statClassStyles.fill.trim()).toBe(`#${customColors.text_color}`);
264+
expect(iconClassStyles.fill.trim()).toBe(`#${customColors.icon_color}`);
265+
expect(rankCircleStyles.stroke.trim()).toBe(`#${customColors.ring_color}`);
266+
expect(rankCircleRimStyles.stroke.trim()).toBe(
267+
`#${customColors.ring_color}`,
268+
);
269+
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
270+
"fill",
271+
"#252525",
272+
);
273+
});
274+
242275
it("should render icons correctly", () => {
243276
document.body.innerHTML = renderStatsCard(stats, {
244277
show_icons: true,

tests/utils.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describe("Test utils.js", () => {
4848
let colors = getCardColors({
4949
title_color: "f00",
5050
text_color: "0f0",
51+
ring_color: "0000ff",
5152
icon_color: "00f",
5253
bg_color: "fff",
5354
border_color: "fff",
@@ -57,6 +58,7 @@ describe("Test utils.js", () => {
5758
titleColor: "#f00",
5859
textColor: "#0f0",
5960
iconColor: "#00f",
61+
ringColor: "#0000ff",
6062
bgColor: "#fff",
6163
borderColor: "#fff",
6264
});
@@ -75,6 +77,7 @@ describe("Test utils.js", () => {
7577
titleColor: "#2f80ed",
7678
textColor: "#0f0",
7779
iconColor: "#00f",
80+
ringColor: "#2f80ed",
7881
bgColor: "#fff",
7982
borderColor: "#e4e2e2",
8083
});
@@ -87,11 +90,31 @@ describe("Test utils.js", () => {
8790
expect(colors).toStrictEqual({
8891
titleColor: "#fff",
8992
textColor: "#9f9f9f",
93+
ringColor: "#fff",
9094
iconColor: "#79ff97",
9195
bgColor: "#151515",
9296
borderColor: "#e4e2e2",
9397
});
9498
});
99+
100+
it("getCardColors: should return ring color equal to title color if not ring color is defined", () => {
101+
let colors = getCardColors({
102+
title_color: "f00",
103+
text_color: "0f0",
104+
icon_color: "00f",
105+
bg_color: "fff",
106+
border_color: "fff",
107+
theme: "dark",
108+
});
109+
expect(colors).toStrictEqual({
110+
titleColor: "#f00",
111+
textColor: "#0f0",
112+
iconColor: "#00f",
113+
ringColor: "#f00",
114+
bgColor: "#fff",
115+
borderColor: "#fff",
116+
});
117+
});
95118
});
96119

97120
describe("wrapTextMultiline", () => {

0 commit comments

Comments
 (0)