TSone

Style Management

TSone provides a built-in style management system that uses StyleManager to manage component styles.

Core Concepts

StyleManager

Every component instance has a styleManager for adding, changing, and removing styles.

Site builds and dev automatically emit static CSS for document.styles and fixed initStyles / fresh StyleManager initialization. Existing literals, local/module forEach arrays and supported pure theme expressions need no changes; props/state, unknown calls or visible mutations remain dynamic. Synchronous inline CSS stays until matching external CSS loads. Edits restore its position and unmount cleans up only that instance. styleElement is null during external activation, rules remain in the bundle and first initialization still serializes CSS. Relative/fragment URLs, @import, ambiguous URLs and base elements fall back. Dev serves CSS under its exact generation URL. Watch replaces scripts and CSS together on success and retains previous artifacts on failure. Non-watch dev retains generations; library builds keep their existing path. Discovery adds a build pass.

Style Objects

  • selector: CSS selector
  • properties: mapping of CSS properties to values

Basic Usage

Use in a Component

import { Component, VNode } from '@geektech/tsone';

class ButtonComponent extends Component<object, object> {
  protected initState() {
    return {};
  }

  protected initStyles() {
    this.styleManager.addStyle('.button', {
      selector: '.button',
      properties: {
        padding: '8px 16px',
        backgroundColor: '#007bff',
        color: '#fff',
        borderRadius: '4px',
      },
    });

    this.styleManager.addStyle('.button:hover', {
      selector: '.button:hover',
      properties: { backgroundColor: '#0069d9' },
    });
  }

  protected render(): VNode {
    return {
      tag: 'button',
      props: { className: 'button' },
      children: ['Click Me'],
    };
  }
}

Style Management API

Add Styles

this.styleManager.addStyle('.container', {
  selector: '.container',
  properties: {
    width: '100%',
    maxWidth: '1200px',
    margin: '0 auto',
    padding: '0 15px',
  },
});

Remove Styles

this.styleManager.removeStyle('.container');

Clear All Styles

this.styleManager.clearStyles();

Get Styles

const buttonStyle = this.styleManager.getStyle('.button');
console.log(buttonStyle);

Advanced Usage

Style Priority

  • More specific selectors have higher priority
  • With equal specificity, rules added later override earlier rules

Responsive Styles

this.styleManager.addStyle('@media (max-width: 768px)', {
  selector: '@media (max-width: 768px)',
  properties: {
    '.container': { padding: '10px' },
  },
});

Dynamic Styles

class DynamicStyleComponent extends Component<object, { isActive: boolean }> {
  protected initState() {
    return { isActive: false };
  }

  protected initStyles() {
    this.styleManager.addStyle('.box.active', {
      selector: '.box.active',
      properties: { backgroundColor: '#007bff' },
    });
  }

  protected render(): VNode {
    return {
      tag: 'div',
      props: {
        className: `box ${this.state.isActive ? 'active' : ''}`,
      },
      listeners: {
        click: () => {
          this.state.isActive = !this.state.isActive;
        },
      },
      children: ['Click to toggle'],
    };
  }
}

Global Styles

import { createApp } from '@geektech/tsone';

const app = createApp();

app.styleManager.addStyle('body', {
  selector: 'body',
  properties: {
    fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
    fontSize: '16px',
    lineHeight: '1.5',
  },
});

How Style Management Works

Style Injection

  • Create a style element
  • Convert style rules to a CSS string
  • Write CSS into the style element
  • Inject the style element into the document head

Style Updates

  • Update internal style storage
  • Regenerate the CSS string
  • Refresh the style element content

Best Practices

Style Organization

  • Each component should primarily manage its own styles
  • Use semantic class names
  • Keep related rules together

Performance Optimization

  • Add styles together in initStyles() whenever possible
  • Reduce frequent runtime style additions and removals
  • Avoid overly complex selectors

Common Issues

  • Styles do not apply: check selectors and overrides
  • Style conflicts: increase selector specificity or add a namespace
  • Dynamic style performance: consider CSS variables for high-frequency changes

Summary

StyleManager provides lightweight, composable component style management for both local styles and application-wide global styles.