update
This commit is contained in:
187
ts_web/elements/sz-stat-card.ts
Normal file
187
ts_web/elements/sz-stat-card.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import {
|
||||
DeesElement,
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
cssManager,
|
||||
property,
|
||||
type TemplateResult,
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'sz-stat-card': SzStatCard;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('sz-stat-card')
|
||||
export class SzStatCard extends DeesElement {
|
||||
public static demo = () => html`
|
||||
<style>
|
||||
.demo-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
padding: 24px;
|
||||
max-width: 800px;
|
||||
}
|
||||
</style>
|
||||
<div class="demo-grid">
|
||||
<sz-stat-card
|
||||
label="Total Services"
|
||||
value="7"
|
||||
icon="server"
|
||||
></sz-stat-card>
|
||||
<sz-stat-card
|
||||
label="Running"
|
||||
value="7"
|
||||
icon="check"
|
||||
variant="success"
|
||||
></sz-stat-card>
|
||||
<sz-stat-card
|
||||
label="Stopped"
|
||||
value="0"
|
||||
icon="stop"
|
||||
></sz-stat-card>
|
||||
<sz-stat-card
|
||||
label="Docker"
|
||||
value="Running"
|
||||
icon="container"
|
||||
variant="success"
|
||||
valueBadge
|
||||
></sz-stat-card>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@property({ type: String })
|
||||
public accessor label: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor value: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor icon: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor variant: 'default' | 'success' | 'warning' | 'error' = 'default';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public accessor valueBadge: boolean = false;
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
transition: all 200ms ease;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: ${cssManager.bdTheme('#d4d4d8', '#3f3f46')};
|
||||
box-shadow: 0 4px 12px ${cssManager.bdTheme('rgba(0,0,0,0.05)', 'rgba(0,0,0,0.2)')};
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.value.success {
|
||||
color: ${cssManager.bdTheme('#16a34a', '#22c55e')};
|
||||
}
|
||||
|
||||
.value.warning {
|
||||
color: ${cssManager.bdTheme('#ca8a04', '#facc15')};
|
||||
}
|
||||
|
||||
.value.error {
|
||||
color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 12px;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.badge.success {
|
||||
background: ${cssManager.bdTheme('#dcfce7', 'rgba(34, 197, 94, 0.2)')};
|
||||
color: ${cssManager.bdTheme('#16a34a', '#22c55e')};
|
||||
}
|
||||
|
||||
.badge.warning {
|
||||
background: ${cssManager.bdTheme('#fef9c3', 'rgba(250, 204, 21, 0.2)')};
|
||||
color: ${cssManager.bdTheme('#ca8a04', '#facc15')};
|
||||
}
|
||||
|
||||
.badge.error {
|
||||
background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')};
|
||||
color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
|
||||
}
|
||||
|
||||
.badge.default {
|
||||
background: ${cssManager.bdTheme('#f4f4f5', '#27272a')};
|
||||
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
const valueClass = this.valueBadge ? `badge ${this.variant}` : `value ${this.variant}`;
|
||||
|
||||
return html`
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<span class="label">${this.label}</span>
|
||||
${this.renderIcon()}
|
||||
</div>
|
||||
<div class="${valueClass}">${this.value}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderIcon(): TemplateResult {
|
||||
const icons: Record<string, TemplateResult> = {
|
||||
server: html`<svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>`,
|
||||
check: html`<svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>`,
|
||||
stop: html`<svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="10" y1="15" x2="10" y2="9"></line><line x1="14" y1="15" x2="14" y2="9"></line></svg>`,
|
||||
container: html`<svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path></svg>`,
|
||||
};
|
||||
|
||||
return icons[this.icon] || html``;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user