Initial commit: Clean DSS implementation

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
This commit is contained in:
Digital Production Factory
2025-12-09 18:45:48 -03:00
commit 276ed71f31
884 changed files with 373737 additions and 0 deletions

View File

@@ -0,0 +1,472 @@
/**
* Component Definitions - Metadata for all design system components
*
* This file defines the complete metadata for each component including:
* - State combinations and variants
* - Token dependencies
* - Accessibility requirements
* - Test case counts
*
* Used by VariantGenerator to auto-generate CSS and validate 123 component states
*/
export const componentDefinitions = {
components: {
'ds-button': {
name: 'Button',
group: 'interactive',
cssClass: '.ds-btn',
description: 'Primary interactive button component',
states: ['default', 'hover', 'active', 'disabled', 'loading', 'focus'],
variants: {
variant: ['primary', 'secondary', 'outline', 'ghost', 'destructive', 'success', 'link'],
size: ['sm', 'default', 'lg', 'icon', 'icon-sm', 'icon-lg']
},
variantCombinations: 42, // 7 variants × 6 sizes
stateCount: 6,
totalStates: 252, // 42 × 6
tokens: {
color: ['--primary', '--secondary', '--destructive', '--success', '--foreground'],
spacing: ['--space-3', '--space-4', '--space-6'],
typography: ['--text-xs', '--text-sm', '--text-base'],
radius: ['--radius'],
transitions: ['--duration-fast', '--ease-default'],
shadow: ['--shadow-sm']
},
a11y: {
ariaAttributes: ['aria-label', 'aria-disabled', 'aria-pressed'],
focusManagement: true,
contrastRatio: 'WCAG AA (4.5:1)',
keyboardInteraction: 'Enter, Space',
semantics: '<button> element'
},
darkMode: {
support: true,
colorOverrides: ['--primary', '--secondary', '--destructive', '--success']
},
testCases: 45 // unit tests
},
'ds-input': {
name: 'Input',
group: 'form',
cssClass: '.ds-input',
description: 'Text input with label, icon, and error states',
states: ['default', 'focus', 'hover', 'disabled', 'error', 'disabled-error'],
variants: {
type: ['text', 'password', 'email', 'number', 'search', 'tel', 'url'],
size: ['default']
},
variantCombinations: 7,
stateCount: 6,
totalStates: 42,
tokens: {
color: ['--foreground', '--muted-foreground', '--border', '--destructive'],
spacing: ['--space-3', '--space-4'],
typography: ['--text-sm', '--text-base'],
radius: ['--radius-md'],
transitions: ['--duration-normal'],
shadow: ['--shadow-sm']
},
a11y: {
ariaAttributes: ['aria-label', 'aria-invalid', 'aria-describedby'],
focusManagement: true,
contrastRatio: 'WCAG AA (4.5:1)',
keyboardInteraction: 'Tab, Arrow keys',
semantics: '<input> with associated <label>'
},
darkMode: {
support: true,
colorOverrides: ['--input', '--border', '--muted-foreground']
},
testCases: 38
},
'ds-card': {
name: 'Card',
group: 'container',
cssClass: '.ds-card',
description: 'Container with header, content, footer sections',
states: ['default', 'hover', 'interactive'],
variants: {
style: ['default', 'interactive']
},
variantCombinations: 2,
stateCount: 3,
totalStates: 6,
tokens: {
color: ['--card', '--card-foreground', '--border'],
spacing: ['--space-4', '--space-6'],
radius: ['--radius-lg'],
shadow: ['--shadow-md']
},
a11y: {
ariaAttributes: [],
focusManagement: false,
contrastRatio: 'WCAG AA (4.5:1)',
semantics: 'Article or Section'
},
darkMode: {
support: true,
colorOverrides: ['--card', '--card-foreground']
},
testCases: 28
},
'ds-badge': {
name: 'Badge',
group: 'indicator',
cssClass: '.ds-badge',
description: 'Status indicator badge',
states: ['default', 'hover'],
variants: {
variant: ['default', 'secondary', 'outline', 'destructive', 'success', 'warning'],
size: ['default']
},
variantCombinations: 6,
stateCount: 2,
totalStates: 12,
tokens: {
color: ['--primary', '--secondary', '--destructive', '--success', '--warning'],
spacing: ['--space-1', '--space-3'],
typography: ['--text-xs'],
radius: ['--radius-full']
},
a11y: {
ariaAttributes: ['aria-label'],
focusManagement: false,
semantics: 'span with role'
},
darkMode: {
support: true,
colorOverrides: ['--primary', '--secondary', '--destructive', '--success']
},
testCases: 22
},
'ds-toast': {
name: 'Toast',
group: 'notification',
cssClass: '.ds-toast',
description: 'Auto-dismiss notification toast',
states: ['entering', 'visible', 'exiting', 'swiped'],
variants: {
type: ['default', 'success', 'warning', 'error', 'info'],
duration: ['auto', 'manual']
},
variantCombinations: 10,
stateCount: 4,
totalStates: 40,
tokens: {
color: ['--success', '--warning', '--destructive', '--info', '--foreground'],
spacing: ['--space-4'],
shadow: ['--shadow-lg'],
transitions: ['--duration-slow'],
zIndex: ['--z-toast']
},
a11y: {
ariaAttributes: ['role="alert"', 'aria-live="polite"'],
focusManagement: false,
semantics: 'div with alert role'
},
darkMode: {
support: true,
colorOverrides: ['--success', '--warning', '--destructive']
},
testCases: 35
},
'ds-workflow': {
name: 'Workflow',
group: 'stepper',
cssClass: '.ds-workflow',
description: 'Multi-step workflow indicator',
states: ['pending', 'active', 'completed', 'error', 'skipped'],
variants: {
direction: ['vertical', 'horizontal']
},
variantCombinations: 2,
stateCount: 5,
totalStates: 10, // per step; multiply by step count
stepsPerWorkflow: 4,
tokens: {
color: ['--primary', '--success', '--destructive', '--muted'],
spacing: ['--space-4', '--space-6'],
transitions: ['--duration-normal']
},
a11y: {
ariaAttributes: ['aria-current="step"'],
focusManagement: true,
semantics: 'ol with li steps'
},
darkMode: {
support: true,
colorOverrides: ['--primary', '--success', '--destructive']
},
testCases: 37
},
'ds-notification-center': {
name: 'NotificationCenter',
group: 'notification',
cssClass: '.ds-notification-center',
description: 'Notification list with grouping and filtering',
states: ['empty', 'loading', 'open', 'closed', 'scrolling'],
variants: {
layout: ['compact', 'expanded'],
groupBy: ['type', 'date', 'none']
},
variantCombinations: 6,
stateCount: 5,
totalStates: 30,
tokens: {
color: ['--card', '--card-foreground', '--border', '--primary'],
spacing: ['--space-3', '--space-4'],
shadow: ['--shadow-md'],
zIndex: ['--z-popover']
},
a11y: {
ariaAttributes: ['role="region"', 'aria-label="Notifications"'],
focusManagement: true,
semantics: 'ul with li items'
},
darkMode: {
support: true,
colorOverrides: ['--card', '--card-foreground', '--border']
},
testCases: 40
},
'ds-action-bar': {
name: 'ActionBar',
group: 'layout',
cssClass: '.ds-action-bar',
description: 'Fixed or sticky action button bar',
states: ['default', 'expanded', 'collapsed', 'dismissing'],
variants: {
position: ['fixed', 'relative', 'sticky'],
alignment: ['left', 'center', 'right']
},
variantCombinations: 9,
stateCount: 4,
totalStates: 36,
tokens: {
color: ['--card', '--card-foreground', '--border'],
spacing: ['--space-4'],
shadow: ['--shadow-lg'],
transitions: ['--duration-normal']
},
a11y: {
ariaAttributes: ['role="toolbar"'],
focusManagement: true,
semantics: 'nav with button children'
},
darkMode: {
support: true,
colorOverrides: ['--card', '--card-foreground']
},
testCases: 31
},
'ds-toast-provider': {
name: 'ToastProvider',
group: 'provider',
cssClass: '.ds-toast-provider',
description: 'Global toast notification container and manager',
states: ['empty', 'toasts-visible', 'dismissing-all'],
variants: {
position: ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right']
},
variantCombinations: 6,
stateCount: 3,
totalStates: 18,
tokens: {
spacing: ['--space-4'],
zIndex: ['--z-toast']
},
a11y: {
ariaAttributes: ['aria-live="polite"'],
focusManagement: false,
semantics: 'div container'
},
darkMode: {
support: true,
colorOverrides: []
},
testCases: 23
}
},
/**
* Summary statistics
*/
summary: {
totalComponents: 9,
totalVariants: 123,
totalTestCases: 315,
averageTestsPerComponent: 35,
a11yComponentsSupported: 9,
darkModeComponentsSupported: 9,
totalTokensUsed: 42,
colorTokens: 20,
spacingTokens: 8,
typographyTokens: 6,
radiusTokens: 4,
transitionTokens: 2,
shadowTokens: 2
},
/**
* Token dependency map - which tokens are used where
*/
tokenDependencies: {
'--primary': ['ds-button', 'ds-input', 'ds-badge', 'ds-workflow', 'ds-notification-center', 'ds-action-bar'],
'--secondary': ['ds-button', 'ds-badge'],
'--destructive': ['ds-button', 'ds-badge', 'ds-input', 'ds-toast', 'ds-workflow'],
'--success': ['ds-button', 'ds-badge', 'ds-toast', 'ds-workflow'],
'--warning': ['ds-badge', 'ds-toast'],
'--foreground': ['ds-button', 'ds-input', 'ds-card', 'ds-badge', 'ds-toast', 'ds-notification-center', 'ds-action-bar'],
'--card': ['ds-card', 'ds-notification-center', 'ds-action-bar'],
'--border': ['ds-input', 'ds-card', 'ds-notification-center', 'ds-action-bar'],
'--space-1': ['ds-badge'],
'--space-2': ['ds-input'],
'--space-3': ['ds-button', 'ds-input', 'ds-notification-center', 'ds-action-bar'],
'--space-4': ['ds-button', 'ds-input', 'ds-card', 'ds-toast', 'ds-workflow', 'ds-action-bar', 'ds-toast-provider'],
'--space-6': ['ds-button', 'ds-card', 'ds-workflow'],
'--text-xs': ['ds-badge', 'ds-button'],
'--text-sm': ['ds-button', 'ds-input'],
'--text-base': ['ds-input'],
'--radius': ['ds-button'],
'--radius-md': ['ds-input', 'ds-action-bar'],
'--radius-lg': ['ds-card'],
'--radius-full': ['ds-badge'],
'--duration-fast': ['ds-button'],
'--duration-normal': ['ds-input', 'ds-workflow', 'ds-action-bar'],
'--duration-slow': ['ds-toast'],
'--shadow-sm': ['ds-button', 'ds-input'],
'--shadow-md': ['ds-card', 'ds-notification-center'],
'--shadow-lg': ['ds-toast', 'ds-action-bar'],
'--z-popover': ['ds-notification-center'],
'--z-toast': ['ds-toast', 'ds-toast-provider'],
'--ease-default': ['ds-button', 'ds-workflow'],
'--muted-foreground': ['ds-input', 'ds-workflow'],
'--input': ['ds-input']
},
/**
* Accessibility requirements matrix
*/
a11yRequirements: {
'ds-button': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: ['Enter', 'Space'],
ariaRoles: ['button (implicit)'],
screenReaderSupport: true
},
'ds-input': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: ['Tab', 'Arrow keys'],
ariaRoles: ['textbox (implicit)'],
screenReaderSupport: true
},
'ds-card': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: [],
ariaRoles: ['article', 'section'],
screenReaderSupport: true
},
'ds-badge': {
wcagLevel: 'AA',
contrastRatio: 3,
keyboardSupport: [],
ariaRoles: ['status (implicit)'],
screenReaderSupport: true
},
'ds-toast': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: ['Escape'],
ariaRoles: ['alert'],
screenReaderSupport: true
},
'ds-workflow': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: ['Tab', 'Arrow keys'],
ariaRoles: [],
screenReaderSupport: true
},
'ds-notification-center': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: ['Tab', 'Arrow keys', 'Enter'],
ariaRoles: ['region'],
screenReaderSupport: true
},
'ds-action-bar': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: ['Tab', 'Space/Enter'],
ariaRoles: ['toolbar'],
screenReaderSupport: true
},
'ds-toast-provider': {
wcagLevel: 'AA',
contrastRatio: 4.5,
keyboardSupport: [],
ariaRoles: [],
screenReaderSupport: true
}
}
};
/**
* Export utility functions for working with definitions
*/
export function getComponentDefinition(componentName) {
return componentDefinitions.components[componentName];
}
export function getComponentVariantCount(componentName) {
const def = getComponentDefinition(componentName);
return def ? def.variantCombinations : 0;
}
export function getTotalVariants() {
return componentDefinitions.summary.totalVariants;
}
export function getTokensForComponent(componentName) {
const def = getComponentDefinition(componentName);
return def ? def.tokens : {};
}
export function getComponentsUsingToken(tokenName) {
return componentDefinitions.tokenDependencies[tokenName] || [];
}
export function validateComponentDefinition(componentName) {
const def = getComponentDefinition(componentName);
if (!def) return { valid: false, errors: ['Component not found'] };
const errors = [];
if (!def.name) errors.push('Missing name');
if (!def.variants) errors.push('Missing variants');
if (!def.tokens) errors.push('Missing tokens');
if (!def.a11y) errors.push('Missing a11y info');
if (def.darkMode && !Array.isArray(def.darkMode.colorOverrides)) {
errors.push('Invalid darkMode.colorOverrides');
}
return {
valid: errors.length === 0,
errors
};
}
export default componentDefinitions;