CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-jss

JSS integration with React providing CSS-in-JS styling solutions with theming support

Pending
Overview
Eval results
Files

styled.mddocs/

Styled Components API

The Styled Components API provides a styled-components-like interface for creating styled React components. This approach is ideal for component libraries and when you prefer component-based styling patterns.

Capabilities

styled Function

Creates styled components with CSS-in-JS capabilities, supporting both HTML tags and custom React components.

/**
 * Creates styled components similar to styled-components library
 * @param tagOrComponent - HTML tag name or React component to style
 * @param options - Configuration options for styled component creation
 * @returns Function that accepts style definitions and returns a styled component
 */
function styled(
  tagOrComponent: string | ComponentType<any>,
  options?: StyledOptions
): (...styles: Array<CSSObject | ((props: any) => CSSObject)>) => ComponentType<any>;

interface StyledOptions extends BaseOptions {
  /** Function to determine which props should be forwarded to the DOM */
  shouldForwardProp?: (prop: string) => boolean;
  /** Custom theming context */
  theming?: Theming<any>;
}

Usage Examples:

import React from 'react';
import { styled } from 'react-jss';

// Basic styled component
const StyledButton = styled('button')({
  padding: '10px 20px',
  backgroundColor: '#007bff',
  color: 'white',
  border: 'none',
  borderRadius: '4px',
  cursor: 'pointer',
  '&:hover': {
    backgroundColor: '#0056b3'
  }
});

function App() {
  return (
    <StyledButton onClick={() => alert('Clicked!')}>
      Click me
    </StyledButton>
  );
}

Dynamic Styling with Props

Create styled components that respond to props:

import React from 'react';
import { styled } from 'react-jss';

const StyledCard = styled('div')({
  padding: '16px',
  borderRadius: '8px',
  border: '1px solid #dee2e6',
  backgroundColor: (props) => {
    switch (props.variant) {
      case 'primary': return '#007bff';
      case 'success': return '#28a745';
      case 'warning': return '#ffc107';
      case 'danger': return '#dc3545';
      default: return '#f8f9fa';
    }
  },
  color: (props) => props.variant && props.variant !== 'warning' ? 'white' : '#333',
  width: (props) => props.fullWidth ? '100%' : 'auto',
  opacity: (props) => props.disabled ? 0.6 : 1,
  cursor: (props) => props.disabled ? 'not-allowed' : 'default'
});

const StyledTitle = styled('h2')({
  fontSize: (props) => props.size === 'large' ? '24px' : '18px',
  fontWeight: (props) => props.bold ? 'bold' : 'normal',
  marginBottom: '12px',
  textAlign: (props) => props.centered ? 'center' : 'left'
});

function Card({ variant, fullWidth, disabled, title, size, bold, centered, children, ...props }) {
  return (
    <StyledCard variant={variant} fullWidth={fullWidth} disabled={disabled} {...props}>
      <StyledTitle size={size} bold={bold} centered={centered}>
        {title}
      </StyledTitle>
      {children}
    </StyledCard>
  );
}

// Usage
<Card variant="primary" fullWidth title="My Card" size="large" bold centered>
  Card content here
</Card>

Multiple Style Objects

Combine multiple style objects for complex styling:

import React from 'react';
import { styled } from 'react-jss';

const baseButtonStyles = {
  padding: '10px 20px',
  border: 'none',
  borderRadius: '4px',
  cursor: 'pointer',
  fontSize: '16px',
  transition: 'all 0.3s ease'
};

const primaryButtonStyles = {
  backgroundColor: '#007bff',
  color: 'white',
  '&:hover': {
    backgroundColor: '#0056b3'
  }
};

const sizeStyles = (props) => ({
  padding: props.size === 'large' ? '12px 24px' : props.size === 'small' ? '6px 12px' : '10px 20px',
  fontSize: props.size === 'large' ? '18px' : props.size === 'small' ? '14px' : '16px'
});

const StyledButton = styled('button')(
  baseButtonStyles,
  primaryButtonStyles,
  sizeStyles
);

function Button({ size = 'medium', children, ...props }) {
  return (
    <StyledButton size={size} {...props}>
      {children}
    </StyledButton>
  );
}

Styling Custom Components

Style existing React components:

import React from 'react';
import { styled } from 'react-jss';

// Original component
const CustomInput = React.forwardRef(({ label, error, ...props }, ref) => (
  <div>
    {label && <label>{label}</label>}
    <input ref={ref} {...props} />
    {error && <span className="error">{error}</span>}
  </div>
));

// Styled version
const StyledInput = styled(CustomInput)({
  '& label': {
    display: 'block',
    marginBottom: '4px',
    fontWeight: 'bold',
    color: '#333'
  },
  '& input': {
    width: '100%',
    padding: '8px 12px',
    border: '1px solid #ccc',
    borderRadius: '4px',
    fontSize: '16px',
    '&:focus': {
      outline: 'none',
      borderColor: '#007bff',
      boxShadow: '0 0 0 2px rgba(0, 123, 255, 0.25)'
    }
  },
  '& .error': {
    display: 'block',
    marginTop: '4px',
    color: '#dc3545',
    fontSize: '14px'
  }
});

// Usage
<StyledInput 
  label="Email" 
  type="email" 
  placeholder="Enter your email"
  error="Please enter a valid email"
/>

Theme Integration

Use themed styled components:

import React from 'react';
import { styled, ThemeProvider } from 'react-jss';

const ThemedButton = styled('button')((props) => ({
  padding: props.theme.spacing.medium,
  backgroundColor: props.theme.colors.primary,
  color: props.theme.colors.white,
  border: 'none',
  borderRadius: props.theme.borderRadius,
  fontSize: props.theme.typography.button.fontSize,
  fontWeight: props.theme.typography.button.fontWeight,
  cursor: 'pointer',
  transition: 'all 0.3s ease',
  '&:hover': {
    backgroundColor: props.theme.colors.primaryDark
  },
  '&:disabled': {
    backgroundColor: props.theme.colors.disabled,
    cursor: 'not-allowed'
  }
}));

const theme = {
  colors: {
    primary: '#007bff',
    primaryDark: '#0056b3',
    white: '#ffffff',
    disabled: '#6c757d'
  },
  spacing: {
    small: '8px',
    medium: '16px',
    large: '24px'
  },
  borderRadius: '4px',
  typography: {
    button: {
      fontSize: '16px',
      fontWeight: 600
    }
  }
};

function App() {
  return (
    <ThemeProvider theme={theme}>
      <ThemedButton>Themed Button</ThemedButton>
    </ThemeProvider>
  );
}

Prop Forwarding Control

Control which props are forwarded to the DOM:

import React from 'react';
import { styled } from 'react-jss';

// Only forward standard HTML props, not custom styling props
const StyledDiv = styled('div', {
  shouldForwardProp: (prop) => !['variant', 'size', 'fullWidth'].includes(prop)
})({
  padding: '16px',
  backgroundColor: (props) => props.variant === 'dark' ? '#333' : '#f8f9fa',
  color: (props) => props.variant === 'dark' ? 'white' : '#333',
  width: (props) => props.fullWidth ? '100%' : 'auto',
  fontSize: (props) => props.size === 'large' ? '18px' : '16px'
});

// Usage - custom props won't appear in DOM
<StyledDiv variant="dark" size="large" fullWidth>
  This div gets styled but custom props aren't in the DOM
</StyledDiv>

Polymorphic Components

Create components that can render as different HTML elements:

import React from 'react';
import { styled } from 'react-jss';

const StyledBox = styled('div')({
  padding: '16px',
  backgroundColor: '#f8f9fa',
  borderRadius: '8px',
  border: '1px solid #dee2e6'
});

function Box({ as = 'div', children, ...props }) {
  return (
    <StyledBox as={as} {...props}>
      {children}
    </StyledBox>
  );
}

// Usage
<Box>Default div</Box>
<Box as="section">Rendered as section</Box>
<Box as="article">Rendered as article</Box>

Types

interface CSSObject {
  [key: string]: any;
}

interface BaseOptions<Theme = DefaultTheme> extends StyleSheetFactoryOptions {
  /** Index for controlling stylesheet insertion order */
  index?: number;
  /** Custom theming context */
  theming?: Theming<Theme>;
}

Install with Tessl CLI

npx tessl i tessl/npm-react-jss

docs

hooks.md

index.md

jsx.md

providers.md

styled.md

theming.md

withstyles.md

tile.json