@tamilvananmurugan/xlibs
Version:
Comprehensive UI component library with Aceternity, MagicUI, and ShadCN components
248 lines (209 loc) • 7.13 kB
text/typescript
// YAML Parser for UI Specification Files
import * as yaml from 'js-yaml';
import { readFileSync } from 'fs';
import { ComponentMetadata } from './component-registry';
export interface UIComponentSpec {
type: string;
variant?: string;
props?: Record<string, any>;
content?: string;
components?: UIComponentSpec[];
elements?: UIComponentSpec[];
[key: string]: any;
}
export interface UIScreenSpec {
name: string;
title?: string;
description?: string;
workareas?: UIWorkareaSpec[];
sections?: UISectionSpec[];
components?: UIComponentSpec[];
elements?: UIComponentSpec[];
}
export interface UIWorkareaSpec {
name: string;
sections?: UISectionSpec[];
components?: UIComponentSpec[];
elements?: UIComponentSpec[];
}
export interface UISectionSpec {
name: string;
type?: string;
elements?: UIComponentSpec[];
components?: UIComponentSpec[];
}
export interface UIGlobalElementSpec {
name: string;
type: string;
components?: UIComponentSpec[];
elements?: UIComponentSpec[];
}
export interface UISpecification {
version: number;
type: string;
global_elements?: UIGlobalElementSpec[];
screens: UIScreenSpec[];
}
export class YAMLParser {
/**
* Parse a YAML file containing UI specifications
* @param filePath Path to the YAML file
* @returns Parsed UI specification
*/
static parseUISpec(filePath: string): UISpecification {
try {
const fileContent = readFileSync(filePath, 'utf8');
const parsed = yaml.load(fileContent) as UISpecification;
// Validate required fields
if (!parsed.version) {
throw new Error('Missing required field: version');
}
if (!parsed.type) {
throw new Error('Missing required field: type');
}
if (!parsed.screens) {
throw new Error('Missing required field: screens');
}
return parsed;
} catch (error) {
throw new Error(`Failed to parse YAML file ${filePath}: ${(error as Error).message}`);
}
}
/**
* Parse a YAML file containing layout specifications
* @param filePath Path to the YAML file
* @returns Parsed layout specification
*/
static parseLayoutSpec(filePath: string): any {
try {
const fileContent = readFileSync(filePath, 'utf8');
const parsed = yaml.load(fileContent);
return parsed;
} catch (error) {
throw new Error(`Failed to parse layout YAML file ${filePath}: ${(error as Error).message}`);
}
}
/**
* Extract all component specifications from a UI specification
* @param uiSpec Parsed UI specification
* @returns Array of component specifications with their variants and props
*/
static extractComponentSpecs(uiSpec: UISpecification): UIComponentSpec[] {
const components: UIComponentSpec[] = [];
// Extract from global elements
if (uiSpec.global_elements) {
for (const globalElement of uiSpec.global_elements) {
if (globalElement.components) {
components.push(...this.extractComponentsFromList(globalElement.components));
}
if (globalElement.elements) {
components.push(...this.extractComponentsFromList(globalElement.elements));
}
}
}
// Extract from screens
for (const screen of uiSpec.screens) {
components.push(...this.extractComponentsFromScreen(screen));
}
return components;
}
/**
* Extract components from a screen specification
* @param screen Screen specification
* @returns Array of component specifications
*/
private static extractComponentsFromScreen(screen: UIScreenSpec): UIComponentSpec[] {
const components: UIComponentSpec[] = [];
if (screen.components) {
components.push(...this.extractComponentsFromList(screen.components));
}
if (screen.elements) {
components.push(...this.extractComponentsFromList(screen.elements));
}
if (screen.sections) {
for (const section of screen.sections) {
components.push(...this.extractComponentsFromSection(section));
}
}
if (screen.workareas) {
for (const workarea of screen.workareas) {
if (workarea.components) {
components.push(...this.extractComponentsFromList(workarea.components));
}
if (workarea.elements) {
components.push(...this.extractComponentsFromList(workarea.elements));
}
if (workarea.sections) {
for (const section of workarea.sections) {
components.push(...this.extractComponentsFromSection(section));
}
}
}
}
return components;
}
/**
* Extract components from a section specification
* @param section Section specification
* @returns Array of component specifications
*/
private static extractComponentsFromSection(section: UISectionSpec): UIComponentSpec[] {
const components: UIComponentSpec[] = [];
if (section.components) {
components.push(...this.extractComponentsFromList(section.components));
}
if (section.elements) {
components.push(...this.extractComponentsFromList(section.elements));
}
return components;
}
/**
* Extract components from a list of component specifications
* @param componentList List of component specifications
* @returns Array of component specifications
*/
private static extractComponentsFromList(componentList: UIComponentSpec[]): UIComponentSpec[] {
const components: UIComponentSpec[] = [];
for (const component of componentList) {
components.push(component);
// Recursively extract nested components
if (component.components) {
components.push(...this.extractComponentsFromList(component.components));
}
if (component.elements) {
components.push(...this.extractComponentsFromList(component.elements));
}
}
return components;
}
/**
* Apply component variants and props to component metadata
* @param componentMetadata Base component metadata
* @returns Updated component metadata with variants and props applied
*/
static applyComponentSpec(
componentMetadata: ComponentMetadata
): ComponentMetadata {
// For now, we're just returning the base metadata
// In the future, we might want to enhance this to apply variants/props
// to the component configuration
return componentMetadata;
}
// Generate component code from UI specification
generateComponentCode(): string {
// Basic component generation logic
return `import React from 'react';
export const Component = (props) => {
return (
<div className="component">
Component
</div>
);
};
`;
}
}
// Utility functions for common parsing tasks
export const parseUISpec = (filePath: string) => YAMLParser.parseUISpec(filePath);
export const parseLayoutSpec = (filePath: string) => YAMLParser.parseLayoutSpec(filePath);
export const extractComponentSpecs = (uiSpec: UISpecification) => YAMLParser.extractComponentSpecs(uiSpec);