CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-styled-jsx

Full CSS support for JSX without compromises, providing scoped component-friendly CSS with server-side rendering support

Pending
Overview
Eval results
Files

style-registry.mddocs/

Style Registry

Server-side rendering and style management system for handling style injection, deduplication, and extraction in React applications.

Capabilities

StyleRegistry Component

Provider component that manages the style registry context for a React component tree.

/**
 * Provider component for style registry context
 * @param children - React children to provide registry context to
 * @param registry - Optional registry instance, creates new one if not provided
 */
function StyleRegistry({
  children,
  registry
}: {
  children: JSX.Element | import('react').ReactNode;
  registry?: StyledJsxStyleRegistry;
}): JSX.Element;

Usage Examples:

import React from 'react';
import { StyleRegistry } from 'styled-jsx';
import App from './App';

// Basic usage - automatic registry creation
function Root() {
  return (
    <StyleRegistry>
      <App />
    </StyleRegistry>
  );
}

// Custom registry instance
import { createStyleRegistry } from 'styled-jsx';

function ServerApp() {
  const registry = createStyleRegistry();
  
  return (
    <StyleRegistry registry={registry}>
      <App />
    </StyleRegistry>
  );
}

createStyleRegistry Function

Factory function that creates a new style registry instance for manual style management.

/**
 * Creates a new style registry instance
 * @returns New StyledJsxStyleRegistry instance
 */
function createStyleRegistry(): StyledJsxStyleRegistry;

Usage Examples:

import { createStyleRegistry } from 'styled-jsx';

// Server-side rendering setup
function renderApp() {
  const registry = createStyleRegistry();
  
  // Render app with registry
  const appHtml = ReactDOM.renderToString(
    <StyleRegistry registry={registry}>
      <App />
    </StyleRegistry>
  );
  
  // Extract styles for SSR
  const styles = registry.styles();
  
  return { appHtml, styles };
}

// Multiple registry instances for isolation
function createIsolatedApp() {
  const registry1 = createStyleRegistry();
  const registry2 = createStyleRegistry();
  
  return (
    <>
      <StyleRegistry registry={registry1}>
        <ComponentA />
      </StyleRegistry>
      <StyleRegistry registry={registry2}>
        <ComponentB />
      </StyleRegistry>
    </>
  );
}

useStyleRegistry Hook

React hook that provides access to the current style registry from context.

/**
 * Hook to access current style registry from context
 * @returns Current StyledJsxStyleRegistry instance or null if none provided
 */
function useStyleRegistry(): StyledJsxStyleRegistry;

Usage Examples:

import React from 'react';
import { useStyleRegistry } from 'styled-jsx';

// Custom component that needs direct registry access
function StyleDebugger() {
  const registry = useStyleRegistry();
  
  if (!registry) {
    return <div>No style registry available</div>;
  }
  
  return (
    <div>
      <h3>Current Styles:</h3>
      <div>{registry.styles()}</div>
      <button onClick={() => registry.flush()}>
        Clear All Styles
      </button>
    </div>
  );
}

// Component that manually manages styles
function ManualStyleComponent() {
  const registry = useStyleRegistry();
  
  React.useEffect(() => {
    if (registry) {
      // Add custom style programmatically
      registry.add({
        id: 'manual-style',
        children: '.manual { color: red; }'
      });
      
      return () => {
        // Clean up on unmount
        registry.remove({
          id: 'manual-style',
          children: '.manual { color: red; }'
        });
      };
    }
  }, [registry]);
  
  return <div className="manual">Manually styled content</div>;
}

StyledJsxStyleRegistry Interface

The registry interface that manages style lifecycle, injection, and extraction.

interface StyledJsxStyleRegistry {
  /**
   * Get array of style elements for rendering
   * @param options - Optional configuration for style rendering
   * @param options.nonce - CSP nonce for style tags
   * @returns Array of React style elements
   */
  styles(options?: { nonce?: string }): JSX.Element[];
  
  /**
   * Clear all styles from registry
   * Removes all tracked styles and resets internal state
   */
  flush(): void;
  
  /**
   * Add style to registry
   * @param props - Style properties including id and CSS content
   */
  add(props: any): void;
  
  /**
   * Remove style from registry
   * @param props - Style properties to identify style for removal
   */
  remove(props: any): void;
}

Usage Examples:

// Server-side rendering with styles extraction
import React from 'react';
import ReactDOM from 'react-dom/server';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';

function ServerRenderer({ App }) {
  const registry = createStyleRegistry();
  
  // Render app to string
  const appHtml = ReactDOM.renderToString(
    <StyleRegistry registry={registry}>
      <App />
    </StyleRegistry>
  );
  
  // Extract all styles
  const styles = registry.styles({ nonce: 'xyz123' });
  
  // Create full HTML document
  const document = ReactDOM.renderToStaticMarkup(
    <html>
      <head>
        <title>My App</title>
        {styles}
      </head>
      <body>
        <div id="root" dangerouslySetInnerHTML={{ __html: appHtml }} />
      </body>
    </html>
  );
  
  return '<!DOCTYPE html>' + document;
}

// Manual style management
function StyleManager() {
  const registry = createStyleRegistry();
  
  const addGlobalStyles = () => {
    registry.add({
      id: 'global-reset',
      children: `
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: Arial, sans-serif; }
      `
    });
  };
  
  const removeGlobalStyles = () => {
    registry.remove({
      id: 'global-reset',
      children: `
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: Arial, sans-serif; }
      `
    });
  };
  
  const clearAllStyles = () => {
    registry.flush();
  };
  
  return (
    <StyleRegistry registry={registry}>
      <div>
        <button onClick={addGlobalStyles}>Add Global Styles</button>
        <button onClick={removeGlobalStyles}>Remove Global Styles</button>
        <button onClick={clearAllStyles}>Clear All Styles</button>
        <div>Current styles: {registry.styles().length}</div>
      </div>
    </StyleRegistry>
  );
}

Server-Side Rendering Pattern

Complete SSR setup pattern for Next.js and custom React applications.

// Server-side rendering with style extraction
const registry = createStyleRegistry();
const appHtml = ReactDOM.renderToString(
  <StyleRegistry registry={registry}>
    <App />
  </StyleRegistry>
);
const styles = registry.styles();

Complete SSR Example:

// pages/_document.js (Next.js)
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const registry = createStyleRegistry();
    const originalRenderPage = ctx.renderPage;
    
    ctx.renderPage = () =>
      originalRenderPage({
        enhanceApp: (App) => (props) => (
          <StyleRegistry registry={registry}>
            <App {...props} />
          </StyleRegistry>
        ),
      });
    
    const initialProps = await Document.getInitialProps(ctx);
    const styles = registry.styles();
    
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          {styles}
        </>
      ),
    };
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

// Custom Express.js server
import express from 'express';
import React from 'react';
import ReactDOM from 'react-dom/server';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
import App from './App';

const server = express();

server.get('*', (req, res) => {
  const registry = createStyleRegistry();
  
  const appHtml = ReactDOM.renderToString(
    <StyleRegistry registry={registry}>
      <App url={req.url} />
    </StyleRegistry>
  );
  
  const styles = registry.styles();
  
  const html = `
    <!DOCTYPE html>
    <html>
      <head>
        <title>My App</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        ${ReactDOM.renderToStaticMarkup(<>{styles}</>)}
      </head>
      <body>
        <div id="root">${appHtml}</div>
        <script src="/bundle.js"></script>
      </body>
    </html>
  `;
  
  res.send(html);
});

server.listen(3000);

JSXStyle Component

Internal style component used by the Babel plugin to inject styles. Also provides utilities for dynamic style handling.

/**
 * Internal JSX style component (auto-imported by Babel plugin)
 * @param props - Style properties including id, dynamic values, and CSS content
 * @returns null (styles are injected into DOM)
 */
function JSXStyle(props: any): null;

namespace JSXStyle {
  /**
   * Static method for computing dynamic style class names
   * @param info - Array of tuples containing base IDs and dynamic properties
   * @returns Space-separated string of computed style IDs
   */
  function dynamic(info: Array<[string, any]>): string;
}

Usage Examples:

import JSXStyle from 'styled-jsx/style';

// Manual usage (typically not needed - Babel handles this)
function ManualStyledComponent() {
  return (
    <div className="jsx-123">
      <JSXStyle 
        id="123"
        children={`
          .jsx-123 {
            color: red;
            font-size: 16px;
          }
        `}
      />
      Content
    </div>
  );
}

// Dynamic style ID computation
function DynamicStyleExample() {
  const dynamicInfo = [
    ['base-id-1', { color: 'red', size: 'large' }],
    ['base-id-2', { theme: 'dark' }]
  ];
  
  const computedClasses = JSXStyle.dynamic(dynamicInfo);
  // Returns: "jsx-computed-id-1 jsx-computed-id-2"
  
  return (
    <div className={computedClasses}>
      Dynamically styled content
    </div>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-styled-jsx

docs

babel-macro.md

build-integration.md

component-styling.md

external-css.md

index.md

style-registry.md

tile.json