166 lines
3.5 KiB
JavaScript
166 lines
3.5 KiB
JavaScript
const { FlexLayout } = require("../common/utils");
|
|
const { getAnimations } = require("../getStyles");
|
|
|
|
class Card {
|
|
constructor({
|
|
width = 100,
|
|
height = 100,
|
|
colors = {},
|
|
title = "",
|
|
titlePrefixIcon,
|
|
}) {
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
this.hideBorder = false;
|
|
this.hideTitle = false;
|
|
|
|
// returns theme based colors with proper overrides and defaults
|
|
this.colors = colors;
|
|
this.title = title;
|
|
this.css = "";
|
|
|
|
this.paddingX = 25;
|
|
this.paddingY = 35;
|
|
this.titlePrefixIcon = titlePrefixIcon;
|
|
this.animations = true;
|
|
}
|
|
|
|
disableAnimations() {
|
|
this.animations = false;
|
|
}
|
|
|
|
setCSS(value) {
|
|
this.css = value;
|
|
}
|
|
|
|
setHideBorder(value) {
|
|
this.hideBorder = value;
|
|
}
|
|
|
|
setHideTitle(value) {
|
|
this.hideTitle = value;
|
|
if (value) {
|
|
this.height -= 30;
|
|
}
|
|
}
|
|
|
|
setTitle(text) {
|
|
this.title = text;
|
|
}
|
|
|
|
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>
|
|
`;
|
|
}
|
|
|
|
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]})"
|
|
>
|
|
${gradients.map((grad, index) => {
|
|
let offset = (index * 100) / (gradients.length - 1);
|
|
return `<stop offset="${offset}%" stop-color="#${grad}" />`;
|
|
})}
|
|
</linearGradient>
|
|
</defs>
|
|
`
|
|
: "";
|
|
}
|
|
|
|
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"
|
|
>
|
|
<style>
|
|
.header {
|
|
font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif;
|
|
fill: ${this.colors.titleColor};
|
|
animation: fadeInAnimation 0.8s ease-in-out forwards;
|
|
}
|
|
${this.css}
|
|
|
|
${
|
|
process.env.NODE_ENV === "test" || !this.animations
|
|
? ""
|
|
: getAnimations()
|
|
}
|
|
</style>
|
|
|
|
${this.renderGradient()}
|
|
|
|
<rect
|
|
data-testid="card-bg"
|
|
x="0.5"
|
|
y="0.5"
|
|
rx="4.5"
|
|
height="99%"
|
|
stroke="#E4E2E2"
|
|
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>
|
|
`;
|
|
}
|
|
}
|
|
|
|
module.exports = Card;
|