/** * ds-token-list.js * List view of all design tokens in the project * UX Team Tool #2 */ import { createListView, setupListHandlers } from '../../utils/tool-templates.js'; import { ComponentHelpers } from '../../utils/component-helpers.js'; import contextStore from '../../stores/context-store.js'; import toolBridge from '../../services/tool-bridge.js'; class DSTokenList extends HTMLElement { constructor() { super(); this.tokens = []; this.filteredTokens = []; this.isLoading = false; } async connectedCallback() { this.render(); await this.loadTokens(); } async loadTokens() { this.isLoading = true; const container = this.querySelector('#token-list-container'); if (container) { container.innerHTML = ComponentHelpers.renderLoading('Loading design tokens...'); } try { const context = contextStore.getMCPContext(); if (!context.project_id) { throw new Error('No project selected'); } // Try to get resolved context which includes all tokens const result = await toolBridge.executeTool('dss_get_resolved_context', { manifest_path: `/projects/${context.project_id}/ds.config.json` }); // Extract tokens from result this.tokens = this.extractTokensFromContext(result); this.filteredTokens = [...this.tokens]; this.renderTokenList(); } catch (error) { console.error('[DSTokenList] Failed to load tokens:', error); if (container) { container.innerHTML = ComponentHelpers.renderError('Failed to load tokens', error); } } finally { this.isLoading = false; } } extractTokensFromContext(context) { const tokens = []; // Extract from colors, typography, spacing, etc. const categories = ['colors', 'typography', 'spacing', 'shadows', 'borders', 'radii']; for (const category of categories) { if (context[category]) { for (const [key, value] of Object.entries(context[category])) { tokens.push({ category, name: key, value: typeof value === 'object' ? JSON.stringify(value) : String(value), type: this.inferTokenType(category, key, value) }); } } } return tokens; } inferTokenType(category, key, value) { if (category === 'colors') return 'color'; if (category === 'typography') return 'font'; if (category === 'spacing') return 'size'; if (category === 'shadows') return 'shadow'; if (category === 'borders') return 'border'; if (category === 'radii') return 'radius'; return 'other'; } renderTokenList() { const container = this.querySelector('#token-list-container'); if (!container) return; const config = { title: 'Design Tokens', items: this.filteredTokens, columns: [ { key: 'name', label: 'Token Name', render: (token) => `${ComponentHelpers.escapeHtml(token.name)}` }, { key: 'category', label: 'Category', render: (token) => ComponentHelpers.createBadge(token.category, 'info') }, { key: 'value', label: 'Value', render: (token) => { if (token.type === 'color') { return `