Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 13x 5x 5x 13x 13x 13x 13x 8x 5x 2x 3x 4x 4x 8x 4x 6x 1x 2x 5x 5x 2x 5x 4x 3x 2x 3x | /**
* @fds-uif/core - CSS Metadata Query Utilities (Browser-safe)
*
* Query and naming utilities for working with CssMetadata.
* These functions do NOT use PostCSS and are fully browser-compatible.
*
* @see RFC: uif-styling-layer.md
*/
import type { CssMetadata, CssRule, ComponentHook } from './types.js';
// ============================================================================
// Constants
// ============================================================================
const DEFAULT_SYSTEM = 'slds';
// ============================================================================
// Naming Utilities
// ============================================================================
/**
* Generate the output filename for CSS metadata.
*
* Format: `{component}.css.{system}.uif.json`
*/
export function getCssMetadataFilename(
componentName: string,
system: string = DEFAULT_SYSTEM,
): string {
const normalizedName = componentName.toLowerCase();
return `${normalizedName}.css.${system}.uif.json`;
}
/**
* Get the basename of a path (browser-safe implementation).
*/
function getBasename(filepath: string): string {
const lastSlash = Math.max(filepath.lastIndexOf('/'), filepath.lastIndexOf('\\'));
return lastSlash >= 0 ? filepath.slice(lastSlash + 1) : filepath;
}
/**
* Infer the design system from a UIF filename.
*/
export function inferSystemFromFilename(filename: string): string {
const base = getBasename(filename);
const match = base.match(/\.system\.([^.]+)\.uif\.json$/);
if (match) {
return match[1];
}
const legacyMatch = base.match(/\.([^.]+)\.uif\.json$/);
if (legacyMatch && legacyMatch[1] !== 'system' && legacyMatch[1] !== 'foundation') {
return legacyMatch[1];
}
return DEFAULT_SYSTEM;
}
// ============================================================================
// Query Utilities
// ============================================================================
/** Get all unique hook names. */
export function getAllHookNames(metadata: CssMetadata): string[] {
return metadata.hooks.map(hook => hook.name);
}
/** Get hooks by category. */
export function getHooksByCategory(metadata: CssMetadata, category: string): ComponentHook[] {
return metadata.hooks.filter(hook => hook.category === category);
}
/** Get hooks by element. */
export function getHooksByElement(metadata: CssMetadata, element: string): ComponentHook[] {
return metadata.hooks.filter(hook => hook.element === element);
}
/** Get hooks with global token references. */
export function getHooksWithGlobalValues(metadata: CssMetadata): ComponentHook[] {
return metadata.hooks.filter(hook => hook.globalValue);
}
/** Get hooks with shared hook references. */
export function getHooksWithSharedValues(metadata: CssMetadata): ComponentHook[] {
return metadata.hooks.filter(hook => hook.sharedValue);
}
/** Check if metadata has deprecated hooks. */
export function hasDeprecatedHooks(metadata: CssMetadata): boolean {
return metadata.deprecated.length > 0;
}
/** Get summary of hooks by category. */
export function getHookCategorySummary(metadata: CssMetadata): Record<string, number> {
const summary: Record<string, number> = {};
for (const hook of metadata.hooks) {
const category = hook.category || 'uncategorized';
summary[category] = (summary[category] || 0) + 1;
}
return summary;
}
/** Get rules from a specific layer. */
export function getRulesFromLayer(
metadata: CssMetadata,
layerType: 'theme' | 'defaults' | 'unlayered' | string,
): CssRule[] {
if (layerType === 'theme') return metadata.themeLayer?.rules || [];
if (layerType === 'defaults') return metadata.defaultsLayer?.rules || [];
if (layerType === 'unlayered') return metadata.unlayered.rules;
return metadata.themeOverrides[layerType]?.rules || [];
}
/** Get all theme override names. */
export function getThemeOverrideNames(metadata: CssMetadata): string[] {
return Object.keys(metadata.themeOverrides);
}
|