-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1ae2a58
commit 2ad2177
Showing
9 changed files
with
886 additions
and
187 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,270 @@ | ||
import { encodeHTML, flexLayout } from "./utils.js"; | ||
|
||
class Card { | ||
/** | ||
* Creates a new card instance. | ||
* | ||
* @param {object} args Card arguments. | ||
* @param {number?=} args.width Card width. | ||
* @param {number?=} args.height Card height. | ||
* @param {number?=} args.border_radius Card border radius. | ||
* @param {string?=} args.customTitle Card custom title. | ||
* @param {string?=} args.defaultTitle Card default title. | ||
* @param {string?=} args.titlePrefixIcon Card title prefix icon. | ||
* @param {object?=} args.colors Card colors arguments. | ||
* @param {string} args.colors.titleColor Card title color. | ||
* @param {string} args.colors.textColor Card text color. | ||
* @param {string} args.colors.iconColor Card icon color. | ||
* @param {string|Array} args.colors.bgColor Card background color. | ||
* @param {string} args.colors.borderColor Card border color. | ||
* @returns {Card} Card instance. | ||
*/ | ||
constructor({ | ||
width = 100, | ||
height = 100, | ||
border_radius = 4.5, | ||
colors = {}, | ||
customTitle, | ||
defaultTitle = "", | ||
titlePrefixIcon, | ||
}) { | ||
this.width = width; | ||
this.height = height; | ||
|
||
this.hideBorder = false; | ||
this.hideTitle = false; | ||
|
||
this.border_radius = border_radius; | ||
|
||
// returns theme based colors with proper overrides and defaults | ||
this.colors = colors; | ||
this.title = | ||
customTitle === undefined | ||
? encodeHTML(defaultTitle) | ||
: encodeHTML(customTitle); | ||
|
||
this.css = ""; | ||
|
||
this.paddingX = 25; | ||
this.paddingY = 35; | ||
this.titlePrefixIcon = titlePrefixIcon; | ||
this.animations = true; | ||
this.a11yTitle = ""; | ||
this.a11yDesc = ""; | ||
} | ||
|
||
/** | ||
* @returns {void} | ||
*/ | ||
disableAnimations() { | ||
this.animations = false; | ||
} | ||
|
||
/** | ||
* @param {Object} props The props object. | ||
* @param {string} props.title Accessibility title. | ||
* @param {string} props.desc Accessibility description. | ||
* @returns {void} | ||
*/ | ||
setAccessibilityLabel({ title, desc }) { | ||
this.a11yTitle = title; | ||
this.a11yDesc = desc; | ||
} | ||
|
||
/** | ||
* @param {string} value The CSS to add to the card. | ||
* @returns {void} | ||
*/ | ||
setCSS(value) { | ||
this.css = value; | ||
} | ||
|
||
/** | ||
* @param {boolean} value Whether to hide the border or not. | ||
* @returns {void} | ||
*/ | ||
setHideBorder(value) { | ||
this.hideBorder = value; | ||
} | ||
|
||
/** | ||
* @param {boolean} value Whether to hide the title or not. | ||
* @returns {void} | ||
*/ | ||
setHideTitle(value) { | ||
this.hideTitle = value; | ||
if (value) { | ||
this.height -= 30; | ||
} | ||
} | ||
|
||
/** | ||
* @param {string} text The title to set. | ||
* @returns {void} | ||
*/ | ||
setTitle(text) { | ||
this.title = text; | ||
} | ||
|
||
/** | ||
* @returns {string} The rendered card title. | ||
*/ | ||
renderTitle() { | ||
const titleText = ` | ||
<text | ||
x="0" | ||
y="0" | ||
class="header" | ||
data-testid="header" | ||
>${this.title}</text> | ||
`; | ||
|
||
const prefixIcon = ` | ||
<svg | ||
class="icon" | ||
x="0" | ||
y="-13" | ||
viewBox="0 0 16 16" | ||
version="1.1" | ||
width="16" | ||
height="16" | ||
> | ||
${this.titlePrefixIcon} | ||
</svg> | ||
`; | ||
return ` | ||
<g | ||
data-testid="card-title" | ||
transform="translate(${this.paddingX}, ${this.paddingY})" | ||
> | ||
${flexLayout({ | ||
items: [this.titlePrefixIcon && prefixIcon, titleText], | ||
gap: 25, | ||
}).join("")} | ||
</g> | ||
`; | ||
} | ||
|
||
/** | ||
* @returns {string} The rendered card gradient. | ||
*/ | ||
renderGradient() { | ||
if (typeof this.colors.bgColor !== "object") { | ||
return ""; | ||
} | ||
|
||
const gradients = this.colors.bgColor.slice(1); | ||
return typeof this.colors.bgColor === "object" | ||
? ` | ||
<defs> | ||
<linearGradient | ||
id="gradient" | ||
gradientTransform="rotate(${this.colors.bgColor[0]})" | ||
gradientUnits="userSpaceOnUse" | ||
> | ||
${gradients.map((grad, index) => { | ||
let offset = (index * 100) / (gradients.length - 1); | ||
return `<stop offset="${offset}%" stop-color="#${grad}" />`; | ||
})} | ||
</linearGradient> | ||
</defs> | ||
` | ||
: ""; | ||
} | ||
|
||
/** | ||
* Retrieves css animations for a card. | ||
* | ||
* @returns {string} Animation css. | ||
*/ | ||
getAnimations = () => { | ||
return ` | ||
/* Animations */ | ||
@keyframes scaleInAnimation { | ||
from { | ||
transform: translate(-5px, 5px) scale(0); | ||
} | ||
to { | ||
transform: translate(-5px, 5px) scale(1); | ||
} | ||
} | ||
@keyframes fadeInAnimation { | ||
from { | ||
opacity: 0; | ||
} | ||
to { | ||
opacity: 1; | ||
} | ||
} | ||
`; | ||
}; | ||
|
||
/** | ||
* @param {string} body The inner body of the card. | ||
* @returns {string} The rendered card. | ||
*/ | ||
render(body) { | ||
return ` | ||
<svg | ||
width="${this.width}" | ||
height="${this.height}" | ||
viewBox="0 0 ${this.width} ${this.height}" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
role="img" | ||
aria-labelledby="descId" | ||
> | ||
<title id="titleId">${this.a11yTitle}</title> | ||
<desc id="descId">${this.a11yDesc}</desc> | ||
<style> | ||
.header { | ||
font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; | ||
fill: ${this.colors.titleColor}; | ||
animation: fadeInAnimation 0.8s ease-in-out forwards; | ||
} | ||
@supports(-moz-appearance: auto) { | ||
/* Selector detects Firefox */ | ||
.header { font-size: 15.5px; } | ||
} | ||
${this.css} | ||
${process.env.NODE_ENV === "test" ? "" : this.getAnimations()} | ||
${this.animations === false | ||
? `* { animation-duration: 0s !important; animation-delay: 0s !important; }` | ||
: "" | ||
} | ||
</style> | ||
${this.renderGradient()} | ||
<rect | ||
data-testid="card-bg" | ||
x="0.5" | ||
y="0.5" | ||
rx="${this.border_radius}" | ||
height="99%" | ||
stroke="${this.colors.borderColor}" | ||
width="${this.width - 1}" | ||
fill="${typeof this.colors.bgColor === "object" | ||
? "url(#gradient)" | ||
: this.colors.bgColor | ||
}" | ||
stroke-opacity="${this.hideBorder ? 0 : 1}" | ||
/> | ||
${this.hideTitle ? "" : this.renderTitle()} | ||
<g | ||
data-testid="main-card-body" | ||
transform="translate(0, ${this.hideTitle ? this.paddingX : this.paddingY + 20 | ||
})" | ||
> | ||
${body} | ||
</g> | ||
</svg> | ||
`; | ||
} | ||
} | ||
|
||
export { Card }; | ||
export default Card; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import fetch from "node-fetch" | ||
|
||
const fetchRepo = async (username, reponame) => { | ||
let res = await fetch(`https://api.github.com/repos/${username}/${reponame}`); | ||
let data = await res.json() | ||
|
||
if (!data) { | ||
throw new Error("Not found"); | ||
} | ||
|
||
if (!data.html_url || data.private) { | ||
throw new Error("User Repository Not found"); | ||
} | ||
|
||
return { | ||
name: data.name, | ||
nameWithOwner: data.full_name, | ||
description: data.description, | ||
primaryLanguage: data.language, | ||
isArchived: data.archived, | ||
isTemplate: data.is_template, | ||
starCount: data.stargazers_count, | ||
forkCount: data.forks, | ||
} | ||
}; | ||
|
||
export default fetchRepo; |
Oops, something went wrong.