{"version":3,"file":"skeleton-factory.mjs","sources":["../../../src/lib/ux/skeleton-factory.ts"],"sourcesContent":["/**\n * @file Skeleton Factory\n * @description Dynamic skeleton generation with configurable patterns,\n * responsive layouts, and animation options.\n *\n * Features:\n * - Configurable skeleton patterns\n * - Responsive skeleton layouts\n * - Animation variants\n * - Auto-sizing from content\n * - Component-based skeletons\n * - Factory pattern for reusability\n * - Returns React elements (not HTML strings)\n */\n\nimport React, { type CSSProperties, type ReactElement } from 'react';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Skeleton element type\n */\nexport type SkeletonElementType =\n  | 'text'\n  | 'heading'\n  | 'paragraph'\n  | 'avatar'\n  | 'thumbnail'\n  | 'image'\n  | 'button'\n  | 'input'\n  | 'card'\n  | 'list'\n  | 'table'\n  | 'custom';\n\n/**\n * Skeleton animation type\n */\nexport type SkeletonAnimation = 'pulse' | 'wave' | 'shimmer' | 'none';\n\n/**\n * Skeleton element definition\n */\nexport interface SkeletonElement {\n  type: SkeletonElementType;\n  width?: string | number;\n  height?: string | number;\n  borderRadius?: string | number;\n  count?: number;\n  gap?: string | number;\n  className?: string;\n  children?: SkeletonElement[];\n}\n\n/**\n * Skeleton pattern definition\n */\nexport interface SkeletonPattern {\n  name: string;\n  elements: SkeletonElement[];\n  animation?: SkeletonAnimation;\n  baseColor?: string;\n  highlightColor?: string;\n  speed?: number;\n  direction?: 'ltr' | 'rtl';\n}\n\n/**\n * Skeleton factory configuration\n */\nexport interface SkeletonFactoryConfig {\n  /** Default animation */\n  defaultAnimation: SkeletonAnimation;\n  /** Base color */\n  baseColor: string;\n  /** Highlight color */\n  highlightColor: string;\n  /** Animation speed in ms */\n  speed: number;\n  /** Border radius */\n  borderRadius: string;\n  /** Default text height */\n  textHeight: string;\n  /** Default heading height */\n  headingHeight: string;\n  /** Default avatar size */\n  avatarSize: string;\n  /** Default thumbnail size */\n  thumbnailSize: string;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_CONFIG: SkeletonFactoryConfig = {\n  defaultAnimation: 'pulse',\n  baseColor: '#e5e7eb',\n  highlightColor: '#f3f4f6',\n  speed: 1500,\n  borderRadius: '4px',\n  textHeight: '1rem',\n  headingHeight: '1.5rem',\n  avatarSize: '40px',\n  thumbnailSize: '80px',\n};\n\n// Static base styles\nconst skeletonBaseStyle: CSSProperties = {\n  position: 'relative',\n  overflow: 'hidden',\n};\n\nconst containerStyle: CSSProperties = {\n  display: 'flex',\n  flexDirection: 'column',\n  gap: '0.75rem',\n};\n\nconst rowStyle: CSSProperties = {\n  display: 'flex',\n  gap: '0.75rem',\n  alignItems: 'center',\n};\n\n// ============================================================================\n// Skeleton Factory\n// ============================================================================\n\n/**\n * Factory for creating skeleton patterns - returns React elements\n */\nexport class SkeletonFactory {\n  private config: SkeletonFactoryConfig;\n  private patterns: Map<string, SkeletonPattern> = new Map();\n  private keyCounter = 0;\n\n  constructor(config: Partial<SkeletonFactoryConfig> = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n    this.registerBuiltInPatterns();\n  }\n\n  /**\n   * Register a skeleton pattern\n   */\n  registerPattern(pattern: SkeletonPattern): void {\n    this.patterns.set(pattern.name, pattern);\n  }\n\n  /**\n   * Get a registered pattern\n   */\n  getPattern(name: string): SkeletonPattern | undefined {\n    return this.patterns.get(name);\n  }\n\n  /**\n   * Create skeleton React element from a pattern\n   */\n  createFromPattern(patternName: string): ReactElement | null {\n    const pattern = this.patterns.get(patternName);\n    if (!pattern) {\n      console.warn(`Skeleton pattern \"${patternName}\" not found`);\n      return null;\n    }\n\n    return this.createSkeletonElement(pattern);\n  }\n\n  /**\n   * Create skeleton React element from elements\n   */\n  createFromElements(\n    elements: SkeletonElement[],\n    options: Partial<SkeletonPattern> = {}\n  ): ReactElement {\n    const pattern: SkeletonPattern = {\n      name: 'custom',\n      elements,\n      animation: options.animation ?? this.config.defaultAnimation,\n      baseColor: options.baseColor ?? this.config.baseColor,\n      highlightColor: options.highlightColor ?? this.config.highlightColor,\n      speed: options.speed ?? this.config.speed,\n      direction: options.direction ?? 'ltr',\n    };\n\n    return this.createSkeletonElement(pattern);\n  }\n\n  /**\n   * Create a text skeleton\n   */\n  createText(\n    options: {\n      lines?: number;\n      width?: string | number;\n      gap?: string | number;\n      lastLineWidth?: string;\n    } = {}\n  ): ReactElement {\n    const lines = options.lines ?? 1;\n    const elements: SkeletonElement[] = [];\n\n    for (let i = 0; i < lines; i++) {\n      const isLast = i === lines - 1;\n      const hasLastLineWidth =\n        options.lastLineWidth !== null &&\n        options.lastLineWidth !== undefined &&\n        options.lastLineWidth !== '';\n      elements.push({\n        type: 'text',\n        width: isLast && hasLastLineWidth ? options.lastLineWidth : (options.width ?? '100%'),\n        height: this.config.textHeight,\n      });\n    }\n\n    return this.createFromElements(elements, {\n      animation: this.config.defaultAnimation,\n    });\n  }\n\n  /**\n   * Create a paragraph skeleton\n   */\n  createParagraph(\n    options: {\n      lines?: number;\n      lineVariation?: boolean;\n    } = {}\n  ): ReactElement {\n    const lines = options.lines ?? 4;\n    const widths =\n      options.lineVariation === true ? this.generateLineWidths(lines) : Array(lines).fill('100%');\n\n    const elements: SkeletonElement[] = widths.map((width: string | number) => ({\n      type: 'text',\n      width,\n      height: this.config.textHeight,\n    }));\n\n    return this.createFromElements(elements);\n  }\n\n  /**\n   * Create an avatar skeleton\n   */\n  createAvatar(\n    options: {\n      size?: string | number;\n      shape?: 'circle' | 'square' | 'rounded';\n    } = {}\n  ): ReactElement {\n    const size = options.size ?? this.config.avatarSize;\n    let borderRadius: string;\n    if (options.shape === 'circle') {\n      borderRadius = '50%';\n    } else if (options.shape === 'rounded') {\n      borderRadius = '8px';\n    } else {\n      borderRadius = '0';\n    }\n\n    return this.createFromElements([\n      {\n        type: 'avatar',\n        width: size,\n        height: size,\n        borderRadius,\n      },\n    ]);\n  }\n\n  /**\n   * Create a card skeleton\n   */\n  createCard(\n    options: {\n      hasImage?: boolean;\n      imageHeight?: string;\n      hasTitle?: boolean;\n      hasSubtitle?: boolean;\n      textLines?: number;\n      hasButton?: boolean;\n    } = {}\n  ): ReactElement {\n    const elements: SkeletonElement[] = [];\n\n    if (options.hasImage === undefined || options.hasImage) {\n      elements.push({\n        type: 'image',\n        width: '100%',\n        height: options.imageHeight ?? '200px',\n        borderRadius: '0',\n      });\n    }\n\n    if (options.hasTitle === undefined || options.hasTitle) {\n      elements.push({\n        type: 'heading',\n        width: '70%',\n        height: this.config.headingHeight,\n      });\n    }\n\n    if (options.hasSubtitle === true) {\n      elements.push({\n        type: 'text',\n        width: '50%',\n        height: this.config.textHeight,\n      });\n    }\n\n    const textLines = options.textLines ?? 3;\n    for (let i = 0; i < textLines; i++) {\n      elements.push({\n        type: 'text',\n        width: i === textLines - 1 ? '80%' : '100%',\n        height: this.config.textHeight,\n      });\n    }\n\n    if (options.hasButton === true) {\n      elements.push({\n        type: 'button',\n        width: '120px',\n        height: '36px',\n      });\n    }\n\n    return this.createFromElements(elements);\n  }\n\n  /**\n   * Create a list skeleton\n   */\n  createList(\n    options: {\n      items?: number;\n      hasAvatar?: boolean;\n      hasSecondaryText?: boolean;\n    } = {}\n  ): ReactElement {\n    const items = options.items ?? 5;\n    const elements: SkeletonElement[] = [];\n\n    for (let i = 0; i < items; i++) {\n      const children: SkeletonElement[] = [];\n\n      if (options.hasAvatar === true) {\n        children.push({\n          type: 'avatar',\n          width: '40px',\n          height: '40px',\n          borderRadius: '50%',\n        });\n      }\n\n      children.push({\n        type: 'text',\n        width: '60%',\n        height: this.config.textHeight,\n      });\n\n      if (options.hasSecondaryText === true) {\n        children.push({\n          type: 'text',\n          width: '40%',\n          height: '0.875rem',\n        });\n      }\n\n      elements.push({\n        type: 'list',\n        children,\n        gap: '12px',\n      });\n    }\n\n    return this.createFromElements(elements);\n  }\n\n  /**\n   * Create a table skeleton\n   */\n  createTable(\n    options: {\n      rows?: number;\n      columns?: number;\n      hasHeader?: boolean;\n    } = {}\n  ): ReactElement {\n    const rows = options.rows ?? 5;\n    const columns = options.columns ?? 4;\n    const elements: SkeletonElement[] = [];\n\n    // Header\n    if (options.hasHeader === undefined || options.hasHeader) {\n      const headerChildren: SkeletonElement[] = [];\n      for (let col = 0; col < columns; col++) {\n        headerChildren.push({\n          type: 'text',\n          width: '80%',\n          height: '1rem',\n        });\n      }\n      elements.push({\n        type: 'table',\n        className: 'skeleton-table-header',\n        children: headerChildren,\n      });\n    }\n\n    // Rows\n    for (let row = 0; row < rows; row++) {\n      const rowChildren: SkeletonElement[] = [];\n      for (let col = 0; col < columns; col++) {\n        rowChildren.push({\n          type: 'text',\n          width: `${60 + Math.random() * 30}%`,\n          height: this.config.textHeight,\n        });\n      }\n      elements.push({\n        type: 'table',\n        className: 'skeleton-table-row',\n        children: rowChildren,\n      });\n    }\n\n    return this.createFromElements(elements);\n  }\n\n  /**\n   * Generate CSS for skeletons (for global stylesheet injection)\n   */\n  generateCSS(): string {\n    return `\n      .skeleton {\n        background: ${this.config.baseColor};\n        position: relative;\n        overflow: hidden;\n      }\n\n      .skeleton-container {\n        display: flex;\n        flex-direction: column;\n        gap: 0.75rem;\n      }\n\n      .skeleton-row {\n        display: flex;\n        gap: 0.75rem;\n        align-items: center;\n      }\n\n      .skeleton-text {\n        height: ${this.config.textHeight};\n        border-radius: ${this.config.borderRadius};\n      }\n\n      .skeleton-heading {\n        height: ${this.config.headingHeight};\n        border-radius: ${this.config.borderRadius};\n      }\n\n      .skeleton-avatar {\n        width: ${this.config.avatarSize};\n        height: ${this.config.avatarSize};\n        border-radius: 50%;\n        flex-shrink: 0;\n      }\n\n      .skeleton-thumbnail {\n        width: ${this.config.thumbnailSize};\n        height: ${this.config.thumbnailSize};\n        border-radius: ${this.config.borderRadius};\n        flex-shrink: 0;\n      }\n\n      .skeleton-image {\n        border-radius: ${this.config.borderRadius};\n      }\n\n      .skeleton-button {\n        border-radius: ${this.config.borderRadius};\n      }\n\n      .skeleton-input {\n        height: 40px;\n        border-radius: ${this.config.borderRadius};\n      }\n\n      .skeleton-table-header {\n        display: grid;\n        gap: 1rem;\n        padding: 0.75rem 0;\n        border-bottom: 1px solid ${this.config.baseColor};\n      }\n\n      .skeleton-table-row {\n        display: grid;\n        gap: 1rem;\n        padding: 0.75rem 0;\n      }\n\n      /* Pulse animation */\n      .skeleton-pulse {\n        animation: skeleton-pulse ${this.config.speed}ms ease-in-out infinite;\n      }\n\n      @keyframes skeleton-pulse {\n        0%, 100% { opacity: 1; }\n        50% { opacity: 0.5; }\n      }\n\n      /* Wave animation */\n      .skeleton-wave::after {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n        background: linear-gradient(\n          90deg,\n          transparent,\n          ${this.config.highlightColor},\n          transparent\n        );\n        animation: skeleton-wave ${this.config.speed}ms linear infinite;\n      }\n\n      @keyframes skeleton-wave {\n        0% { transform: translateX(-100%); }\n        100% { transform: translateX(100%); }\n      }\n\n      /* Shimmer animation */\n      .skeleton-shimmer {\n        background: linear-gradient(\n          90deg,\n          ${this.config.baseColor} 0%,\n          ${this.config.highlightColor} 50%,\n          ${this.config.baseColor} 100%\n        );\n        background-size: 200% 100%;\n        animation: skeleton-shimmer ${this.config.speed}ms linear infinite;\n      }\n\n      @keyframes skeleton-shimmer {\n        0% { background-position: 200% 0; }\n        100% { background-position: -200% 0; }\n      }\n    `;\n  }\n\n  // ============================================================================\n  // Private Methods\n  // ============================================================================\n\n  private registerBuiltInPatterns(): void {\n    // Article pattern\n    this.registerPattern({\n      name: 'article',\n      elements: [\n        { type: 'heading', width: '80%' },\n        { type: 'text', width: '40%' },\n        { type: 'image', width: '100%', height: '300px' },\n        { type: 'paragraph', count: 3 },\n      ],\n    });\n\n    // Profile pattern\n    this.registerPattern({\n      name: 'profile',\n      elements: [\n        {\n          type: 'custom',\n          className: 'skeleton-row',\n          children: [\n            { type: 'avatar', borderRadius: '50%' },\n            {\n              type: 'custom',\n              children: [\n                { type: 'heading', width: '200px' },\n                { type: 'text', width: '150px' },\n              ],\n            },\n          ],\n        },\n      ],\n    });\n\n    // Comment pattern\n    this.registerPattern({\n      name: 'comment',\n      elements: [\n        {\n          type: 'custom',\n          className: 'skeleton-row',\n          children: [\n            { type: 'avatar', width: '32px', height: '32px', borderRadius: '50%' },\n            {\n              type: 'custom',\n              children: [\n                { type: 'text', width: '120px' },\n                { type: 'text', width: '200px' },\n              ],\n            },\n          ],\n        },\n      ],\n    });\n\n    // Form pattern\n    this.registerPattern({\n      name: 'form',\n      elements: [\n        { type: 'text', width: '100px', height: '0.875rem' },\n        { type: 'input' },\n        { type: 'text', width: '100px', height: '0.875rem' },\n        { type: 'input' },\n        { type: 'text', width: '100px', height: '0.875rem' },\n        { type: 'input', height: '100px' },\n        { type: 'button', width: '100px' },\n      ],\n    });\n\n    // Dashboard widget pattern\n    this.registerPattern({\n      name: 'dashboard-widget',\n      elements: [\n        { type: 'heading', width: '50%' },\n        { type: 'text', width: '30%' },\n        { type: 'image', width: '100%', height: '150px' },\n      ],\n    });\n  }\n\n  private generateKey(): string {\n    return `skeleton-${++this.keyCounter}`;\n  }\n\n  private createSkeletonElement(pattern: SkeletonPattern): ReactElement {\n    const animationClass = this.getAnimationClass(pattern.animation);\n\n    const children = pattern.elements.map((el) =>\n      this.createElementComponent(el, animationClass, pattern)\n    );\n\n    return React.createElement(\n      'div',\n      {\n        key: this.generateKey(),\n        style: containerStyle,\n        className: 'skeleton-container',\n        'aria-hidden': true,\n        'aria-label': 'Loading content',\n      },\n      ...children\n    );\n  }\n\n  private createElementComponent(\n    element: SkeletonElement,\n    animationClass: string,\n    pattern: SkeletonPattern\n  ): ReactElement {\n    const style = this.createElementStyle(element, pattern);\n    const className = this.getElementClassName(element.type, animationClass, element.className);\n\n    // Handle children\n    if (element.children && element.children.length > 0) {\n      const childElements = element.children.map((child) =>\n        this.createElementComponent(child, animationClass, pattern)\n      );\n\n      const childContainerStyle: CSSProperties = {\n        ...style,\n        ...(element.type === 'list' || (element.className?.includes('row') ?? false)\n          ? rowStyle\n          : containerStyle),\n      };\n\n      return React.createElement(\n        'div',\n        {\n          key: this.generateKey(),\n          className,\n          style: childContainerStyle,\n        },\n        ...childElements\n      );\n    }\n\n    // Handle count (multiple of same element)\n    if (element.count !== null && element.count !== undefined && element.count > 1) {\n      const repeatedElements = Array(element.count)\n        .fill(null)\n        .map(() =>\n          React.createElement('div', {\n            key: this.generateKey(),\n            className,\n            style,\n          })\n        );\n\n      return React.createElement(React.Fragment, { key: this.generateKey() }, ...repeatedElements);\n    }\n\n    // Single element\n    return React.createElement('div', {\n      key: this.generateKey(),\n      className,\n      style,\n    });\n  }\n\n  private createElementStyle(element: SkeletonElement, pattern: SkeletonPattern): CSSProperties {\n    const style: CSSProperties = {\n      ...skeletonBaseStyle,\n      backgroundColor: pattern.baseColor ?? this.config.baseColor,\n    };\n\n    if (element.width !== null && element.width !== undefined) {\n      style.width = typeof element.width === 'number' ? `${element.width}px` : element.width;\n    }\n\n    if (element.height !== null && element.height !== undefined) {\n      style.height = typeof element.height === 'number' ? `${element.height}px` : element.height;\n    } else {\n      // Apply default heights based on type\n      switch (element.type) {\n        case 'text':\n          style.height = this.config.textHeight;\n          break;\n        case 'heading':\n          style.height = this.config.headingHeight;\n          break;\n        case 'avatar':\n          style.height = this.config.avatarSize;\n          style.width = style.width ?? this.config.avatarSize;\n          break;\n        case 'thumbnail':\n          style.height = this.config.thumbnailSize;\n          style.width = style.width ?? this.config.thumbnailSize;\n          break;\n        case 'input':\n          style.height = '40px';\n          break;\n        case 'button':\n          style.height = '36px';\n          break;\n      }\n    }\n\n    if (element.borderRadius !== null && element.borderRadius !== undefined) {\n      style.borderRadius =\n        typeof element.borderRadius === 'number'\n          ? `${element.borderRadius}px`\n          : element.borderRadius;\n    } else {\n      // Apply default border radius based on type\n      switch (element.type) {\n        case 'avatar':\n          style.borderRadius = '50%';\n          break;\n        case 'text':\n        case 'heading':\n        case 'button':\n        case 'input':\n        case 'thumbnail':\n        case 'image':\n          style.borderRadius = this.config.borderRadius;\n          break;\n      }\n    }\n\n    if (element.gap !== null && element.gap !== undefined) {\n      style.gap = typeof element.gap === 'number' ? `${element.gap}px` : element.gap;\n    }\n\n    // Apply flex-shrink for avatar and thumbnail\n    if (element.type === 'avatar' || element.type === 'thumbnail') {\n      style.flexShrink = 0;\n    }\n\n    return style;\n  }\n\n  private getElementClassName(\n    type: SkeletonElementType,\n    animationClass: string,\n    customClass?: string\n  ): string {\n    const classes = ['skeleton', `skeleton-${type}`, animationClass];\n    if (customClass !== null && customClass !== undefined && customClass !== '') {\n      classes.push(customClass);\n    }\n    return classes.filter(Boolean).join(' ');\n  }\n\n  private getAnimationClass(animation?: SkeletonAnimation): string {\n    switch (animation ?? this.config.defaultAnimation) {\n      case 'pulse':\n        return 'skeleton-pulse';\n      case 'wave':\n        return 'skeleton-wave';\n      case 'shimmer':\n        return 'skeleton-shimmer';\n      case 'none':\n      default:\n        return '';\n    }\n  }\n\n  private generateLineWidths(count: number): string[] {\n    const widths: string[] = [];\n    for (let i = 0; i < count; i++) {\n      if (i === count - 1) {\n        // Last line is shorter\n        widths.push(`${50 + Math.random() * 30}%`);\n      } else {\n        widths.push(`${85 + Math.random() * 15}%`);\n      }\n    }\n    return widths;\n  }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet factoryInstance: SkeletonFactory | null = null;\n\n/**\n * Get or create the global skeleton factory\n */\nexport function getSkeletonFactory(config?: Partial<SkeletonFactoryConfig>): SkeletonFactory {\n  factoryInstance ??= new SkeletonFactory(config);\n  return factoryInstance;\n}\n\n/**\n * Reset the factory instance\n */\nexport function resetSkeletonFactory(): void {\n  factoryInstance = null;\n}\n\n// ============================================================================\n// Convenience Functions - Return React Elements\n// ============================================================================\n\n/**\n * Create a text skeleton\n */\nexport function createTextSkeleton(\n  options?: Parameters<SkeletonFactory['createText']>[0]\n): ReactElement {\n  return getSkeletonFactory().createText(options);\n}\n\n/**\n * Create a paragraph skeleton\n */\nexport function createParagraphSkeleton(\n  options?: Parameters<SkeletonFactory['createParagraph']>[0]\n): ReactElement {\n  return getSkeletonFactory().createParagraph(options);\n}\n\n/**\n * Create a card skeleton\n */\nexport function createCardSkeleton(\n  options?: Parameters<SkeletonFactory['createCard']>[0]\n): ReactElement {\n  return getSkeletonFactory().createCard(options);\n}\n\n/**\n * Create a list skeleton\n */\nexport function createListSkeleton(\n  options?: Parameters<SkeletonFactory['createList']>[0]\n): ReactElement {\n  return getSkeletonFactory().createList(options);\n}\n\n/**\n * Create a table skeleton\n */\nexport function createTableSkeleton(\n  options?: Parameters<SkeletonFactory['createTable']>[0]\n): ReactElement {\n  return getSkeletonFactory().createTable(options);\n}\n\n// ============================================================================\n// React Hook for Skeleton Factory\n// ============================================================================\n\n/**\n * Hook to use skeleton factory within React components\n */\nexport function useSkeletonFactory(config?: Partial<SkeletonFactoryConfig>): SkeletonFactory {\n  return React.useMemo(() => {\n    if (config) {\n      return new SkeletonFactory(config);\n    }\n    return getSkeletonFactory();\n  }, [config]);\n}\n"],"names":["DEFAULT_CONFIG","skeletonBaseStyle","containerStyle","rowStyle","SkeletonFactory","config","pattern","name","patternName","elements","options","lines","i","isLast","hasLastLineWidth","width","size","borderRadius","textLines","items","children","rows","columns","headerChildren","col","row","rowChildren","animationClass","el","React","element","style","className","childElements","child","childContainerStyle","repeatedElements","type","customClass","classes","animation","count","widths","factoryInstance","getSkeletonFactory","resetSkeletonFactory","createTextSkeleton","createParagraphSkeleton","createCardSkeleton","createListSkeleton","createTableSkeleton"],"mappings":"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"}