Skip to content

Style System Architecture in Cavai Platform

This document explains the style system architecture used across the Cavai platform components, particularly in the Creative-Engine project.

Style System as "Lego Blocks"

The style system in the Cavai platform functions like modular "lego blocks" that can be combined to create complex visual components. Each style aspect (borders, shadows, background, positioning, etc.) is encapsulated into its own config object and combined through mixins.

Key Components of the Style System

1. Style Config Objects

Style configurations are defined as TypeScript interfaces that represent different aspects of visual styling:

  • BoxShadowConfig: Controls box shadow properties

    • Required properties: boxShadow, boxShadowSettings
  • BorderConfig: Controls border styles

    • Required properties: border, borderStyle
  • BackgroundConfig: Controls background properties

    • Required properties: background, backgroundSettings
  • SizeConfig: Controls dimension properties

    • There are two variants:
      • MandatorySizeConfig: Required properties: size: boolean, sizeStyle: MandatorySizeStyle
      • OptionalSizeConfig: For components where size is optional

2. Style Mixins

The style system is implemented through Vue mixins that apply these style configurations:

  • StyleAndClassNameGenerationMixin: Core mixin for generating style objects and class names
  • BlockMixin: Applies block-specific styling to components that have a block structure
  • VisualElementMixin: Specifically for visual elements with a position in the creative

Specialized Blocks vs Visual Elements

Visual Elements (Simple Blocks)

  • Use both BlockMixin and VisualElementMixin
  • Require a block prop that contains all styling properties
  • Examples: Text, Button, HTML, Graphic

Specialized Blocks (Complex Blocks)

  • Generally do not use BlockMixin or VisualElementMixin directly
  • Access their properties directly from the DataStore
  • Handle their own styling through computed properties
  • Examples: Form, Slider, Video, Conversation

Implementation Pattern for Specialized Blocks

For specialized blocks like FormBlock and SliderBlock:

  1. Create a computed property that accesses the block properties directly from DataStore:
javascript
typedBlock(): any {
  return DataStore.creativeSettings.creativeBlocks.formProperties
}
  1. Create a styles computed property that processes these properties:
javascript
styles() {
  const formProps = this.typedBlock || {}
  
  const styles = {
    wrap: {
      // Style properties
    },
    // Other style objects
  }
  
  return styles
}
  1. Apply these styles directly in the template:
html
<div :style="styles.wrap">
  <!-- Component content -->
</div>

Style System Best Practices

  1. Type Safety: Always ensure style objects match their expected TypeScript interfaces
  2. Defaults: Provide sensible defaults for all style properties to prevent rendering issues
  3. Specialized Block Pattern: For specialized blocks, follow the pattern of directly accessing DataStore properties rather than using the general mixins
  4. Consistent Naming: Use consistent naming conventions for style objects (wrap, container, etc.)
  5. Error Handling: Include null checks and fallbacks for style properties that might be missing

Common Issues and Solutions

  1. Missing Properties:

    • Problem: Errors like "Property 'boxShadow' is missing in type..."
    • Solution: Ensure all required properties (boxShadow, border, background, etc.) are defined in your style objects
  2. Type Mismatches:

    • Problem: "Type 'Record<string, any>' is not assignable to parameter..."
    • Solution: Define explicit types for your style objects that match the expected interfaces
  3. Missing Position:

    • Problem: Visual elements require position properties
    • Solution: For specialized blocks, don't use VisualElementMixin if position tracking is handled differently

Internal documentation