Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
85 lines
2.3 KiB
JavaScript
85 lines
2.3 KiB
JavaScript
/**
|
|
* ds-metric-card.js
|
|
* Reusable web component for displaying dashboard metrics
|
|
* Encapsulates styling and layout for consistency across dashboards
|
|
*/
|
|
|
|
export default class MetricCard extends HTMLElement {
|
|
static get observedAttributes() {
|
|
return ['title', 'value', 'subtitle', 'color', 'trend'];
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
this.attachShadow({ mode: 'open' });
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.render();
|
|
}
|
|
|
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
if (oldValue !== newValue) {
|
|
this.render();
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const title = this.getAttribute('title') || '';
|
|
const value = this.getAttribute('value') || '0';
|
|
const subtitle = this.getAttribute('subtitle') || '';
|
|
const color = this.getAttribute('color') || 'var(--vscode-textLink-foreground)';
|
|
|
|
// Trend implementation (optional enhancement)
|
|
const trend = this.getAttribute('trend'); // e.g., "up", "down"
|
|
|
|
this.shadowRoot.innerHTML = `
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
height: 100%;
|
|
}
|
|
.card {
|
|
background: var(--vscode-sidebar-background);
|
|
border: 1px solid var(--vscode-widget-border);
|
|
border-radius: 4px;
|
|
padding: 16px;
|
|
height: 100%;
|
|
box-sizing: border-box;
|
|
border-top: 3px solid var(--card-color, ${color});
|
|
transition: transform 0.1s ease-in-out;
|
|
}
|
|
.card:hover {
|
|
background: var(--vscode-list-hoverBackground);
|
|
}
|
|
.header {
|
|
color: var(--vscode-descriptionForeground);
|
|
font-size: 11px;
|
|
margin-bottom: 8px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
font-weight: 600;
|
|
}
|
|
.value {
|
|
font-size: 28px;
|
|
font-weight: 600;
|
|
margin-bottom: 4px;
|
|
color: var(--card-color, ${color});
|
|
}
|
|
.subtitle {
|
|
color: var(--vscode-descriptionForeground);
|
|
font-size: 11px;
|
|
line-height: 1.4;
|
|
}
|
|
</style>
|
|
<div class="card" style="--card-color: ${color}">
|
|
<div class="header">${title}</div>
|
|
<div class="value">${value}</div>
|
|
<div class="subtitle">${subtitle}</div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
customElements.define('ds-metric-card', MetricCard);
|