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

withstyles.mddocs/

Higher-Order Component API

The Higher-Order Component (HOC) API provides the classic React pattern for injecting styles into components as a classes prop. This approach is ideal for class components and when following traditional HOC patterns.

Capabilities

withStyles Function

Creates a higher-order component that injects styles as a classes prop into the wrapped component.

/**
 * Creates a higher-order component that injects styles as classes prop
 * @param styles - JSS styles object or function that returns styles
 * @param options - Configuration options for the HOC
 * @returns HOC function that wraps components with injected styles
 */
function withStyles<ClassNames extends string | number | symbol, Props, Theme>(
  styles: Styles<ClassNames, Props, Theme> | ((theme: Theme) => Styles<ClassNames, Props, undefined>),
  options?: WithStylesOptions
): <C>(component: C) => ComponentType<
  JSX.LibraryManagedAttributes<
    C,
    Omit<GetProps<C>, 'classes'> & {
      classes?: Partial<ClassesForStyles<typeof styles>>;
      innerRef?: RefObject<any> | ((instance: any) => void);
    }
  >
>;

interface WithStylesOptions extends BaseOptions {
  /** Whether to inject theme as a prop to the wrapped component */
  injectTheme?: boolean;
  /** Custom JSS instance to use for this component */
  jss?: Jss;
}

Usage Examples:

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

// Static styles
const styles = {
  button: {
    padding: '10px 20px',
    backgroundColor: '#007bff',
    color: 'white',
    border: 'none',
    borderRadius: '4px',
    cursor: 'pointer',
    '&:hover': {
      backgroundColor: '#0056b3'
    }
  }
};

// Class component usage
class MyButton extends React.Component {
  render() {
    const { classes, children, ...props } = this.props;
    return (
      <button className={classes.button} {...props}>
        {children}
      </button>
    );
  }
}

const StyledButton = withStyles(styles)(MyButton);

// Functional component usage
const MyFunctionalButton = ({ classes, children, ...props }) => (
  <button className={classes.button} {...props}>
    {children}
  </button>
);

const StyledFunctionalButton = withStyles(styles)(MyFunctionalButton);

Dynamic Styles with Theme

Using function-based styles that respond to theme and props:

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

const dynamicStyles = (theme) => ({
  container: {
    padding: '20px',
    backgroundColor: theme.backgroundColor,
    color: theme.textColor,
    borderRadius: theme.borderRadius
  },
  title: {
    fontSize: (props) => props.large ? '24px' : '18px',
    fontWeight: theme.fontWeight.bold,
    marginBottom: '16px'
  }
});

const MyComponent = ({ classes, title, children }) => (
  <div className={classes.container}>
    <h2 className={classes.title}>{title}</h2>
    {children}
  </div>
);

const StyledComponent = withStyles(dynamicStyles)(MyComponent);

// Usage with theme
const theme = {
  backgroundColor: '#f5f5f5',
  textColor: '#333',
  borderRadius: '8px',
  fontWeight: {
    bold: 600
  }
};

function App() {
  return (
    <ThemeProvider theme={theme}>
      <StyledComponent title="Hello" large>
        Content here
      </StyledComponent>
    </ThemeProvider>
  );
}

Theme Injection

Automatically inject theme as a prop to the wrapped component:

const styles = {
  card: {
    padding: '16px',
    borderRadius: '8px',
    boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
  }
};

const Card = ({ classes, theme, children }) => (
  <div 
    className={classes.card}
    style={{ backgroundColor: theme.cardBackground }}
  >
    {children}
  </div>
);

const StyledCard = withStyles(styles, { injectTheme: true })(Card);

Custom Classes Override

Components wrapped with withStyles accept a classes prop to override specific style classes:

const Button = withStyles({
  root: {
    padding: '10px',
    backgroundColor: 'blue'
  }
})(({ classes, children }) => (
  <button className={classes.root}>{children}</button>
));

// Override specific classes
<Button classes={{ root: 'my-custom-button-class' }}>
  Click me
</Button>

Inner Ref Access

Access the ref of the wrapped component using innerRef:

const Input = withStyles({
  input: {
    padding: '8px',
    border: '1px solid #ccc'
  }
})(React.forwardRef(({ classes, ...props }, ref) => (
  <input className={classes.input} ref={ref} {...props} />
)));

function App() {
  const inputRef = React.useRef();
  
  const focusInput = () => {
    inputRef.current?.focus();
  };

  return (
    <div>
      <Input innerRef={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

Types

interface WithStylesProps<S extends Styles<any, any, any> | ((theme: any) => Styles<any, any, undefined>)> {
  /** Generated CSS class names object */
  classes: ClassesForStyles<S>;
}

/** @deprecated Please use WithStylesProps instead */
type WithStyles<S extends Styles<any, any, any> | ((theme: any) => Styles<any, any, undefined>)> = WithStylesProps<S>;

type GetProps<C> = C extends ComponentType<infer P> ? P : never;

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