Files
dss/admin-ui/js/core/component-definitions.js
Digital Production Factory 276ed71f31 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
2025-12-09 18:45:48 -03:00

473 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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;