Type safe CSS-in-JS API heavily inspired by react-jss
—
The TSS (Type-Safe Styles) API is the foundation of tss-react, providing a fluent interface for creating type-safe, dynamic styles with context support and plugin extensibility.
Creates a TSS instance with custom context and optional plugin support.
/**
* Creates a TSS instance with context support
* @param params - Configuration object with context provider and optional plugin
* @returns Object containing the configured TSS instance
*/
function createTss<Context extends Record<string, unknown>>(params: {
useContext: () => Context;
usePlugin?: UsePlugin<Context, any>;
}): { tss: Tss<Context, {}, never, {}, never> };
type UsePlugin<Context, PluginParams> = (params: {
classes: Record<string, string>;
cx: Cx;
css: Css;
name: string | undefined;
idOfUseStyles: string;
} & Context & PluginParams) => {
classes?: Record<string, string>;
cx?: Cx;
css?: Css;
};Usage Examples:
import { createTss } from "tss-react";
// Basic TSS with empty context
const { tss } = createTss({
useContext: () => ({})
});
// TSS with theme context
const { tss } = createTss({
useContext: () => {
const theme = useMyTheme();
return { theme };
}
});
// TSS with plugin
const { tss } = createTss({
useContext: () => ({ theme: useTheme() }),
usePlugin: myCustomPlugin
});The main TSS interface providing chainable methods for configuration and style creation.
interface Tss<
Context extends Record<string, unknown>,
Params extends Record<string, unknown>,
RuleNameSubsetReferencableInNestedSelectors extends string,
PluginParams extends Record<string, unknown>,
ExcludedMethod extends "withParams" | "withName" | "withNestedSelectors" = never
> {
/**
* Creates a useStyles hook from CSS object or function
* @param cssObjectByRuleNameOrGetCssObjectByRuleName - CSS rules definition
* @returns React hook for generating styles
*/
create<RuleName extends string>(
cssObjectByRuleNameOrGetCssObjectByRuleName: CssObjectByRuleNameOrGetCssObjectByRuleName<
Context,
Params,
RuleNameSubsetReferencableInNestedSelectors,
RuleName
>
): UseStyles<Context, Params, RuleName, PluginParams>;
/**
* Adds parameter typing to TSS instance
* @returns New TSS instance with parameter support
*/
withParams<NewParams extends Record<string, unknown>>(): Tss<
Context,
NewParams,
RuleNameSubsetReferencableInNestedSelectors,
PluginParams,
ExcludedMethod | "withParams"
>;
/**
* Adds component name for debugging and theme overrides
* @param name - Component name or wrapped name object
* @returns New TSS instance with name
*/
withName(
name: string | Record<string, unknown>
): Tss<
Context,
Params,
RuleNameSubsetReferencableInNestedSelectors,
PluginParams,
ExcludedMethod | "withName"
>;
/**
* Enables type-safe nested selectors
* @returns New TSS instance with nested selector support
*/
withNestedSelectors<NewRuleNameSubset extends string>(): Tss<
Context,
Params,
NewRuleNameSubset,
PluginParams,
ExcludedMethod | "withNestedSelectors"
>;
}Types for defining CSS rules with functions and static objects.
type CssObjectByRuleNameOrGetCssObjectByRuleName<
Context,
Params,
RuleNameSubsetReferencableInNestedSelectors,
RuleName extends string
> =
| Record<RuleName, CSSObject>
| ((context: Context, params: Params, classes: Record<RuleNameSubsetReferencableInNestedSelectors, string>) => Record<RuleName, CSSObject>);
interface CSSObject {
[property: string]: any;
label?: string;
}The return type of tss.create() providing the styles hook interface.
type UseStyles<Context, Params, RuleName extends string, PluginParams> =
Params extends Record<string, never>
? () => {
classes: Record<RuleName, string>;
cx: Cx;
css: Css;
theme: Context extends { theme: infer Theme } ? Theme : never;
}
: (params: Params) => {
classes: Record<RuleName, string>;
cx: Cx;
css: Css;
theme: Context extends { theme: infer Theme } ? Theme : never;
};Usage Examples:
import { createTss } from "tss-react";
const { tss } = createTss({
useContext: () => ({ theme: { primaryColor: "blue" } })
});
// Static styles
const useStyles = tss.create({
root: {
backgroundColor: "white",
padding: 16
},
button: {
color: "blue",
"&:hover": {
color: "darkblue"
}
}
});
// Dynamic styles with parameters
const useStylesWithParams = tss
.withParams<{ isActive: boolean; size: "small" | "large" }>()
.create(({ theme }, { isActive, size }) => ({
root: {
backgroundColor: isActive ? theme.primaryColor : "gray",
padding: size === "small" ? 8 : 16
}
}));
// With component name for debugging
const useNamedStyles = tss
.withName("MyComponent")
.create({
root: { color: "red" }
});
// With nested selectors
const useNestedStyles = tss
.withNestedSelectors<"root" | "button">()
.create(({}, {}, classes) => ({
root: {
padding: 16,
[`& .${classes.button}`]: {
marginTop: 8
}
},
button: {
backgroundColor: "blue"
}
}));
// Usage in components
function MyComponent({ isActive }: { isActive: boolean }) {
const { classes, cx, css, theme } = useStylesWithParams({
isActive,
size: "large"
});
return (
<div className={classes.root}>
<button className={cx(classes.button, css({ border: "1px solid red" }))}>
Click me
</button>
</div>
);
}TSS-React provides a default TSS instance for immediate use without setup.
const tss: Tss<{}, {}, never, {}, never>;
const useStyles: UseStyles<{}, {}, string, {}>;Usage Examples:
import { tss, useStyles } from "tss-react";
// Using the default instance
const useButtonStyles = tss.create({
root: {
backgroundColor: "blue",
color: "white",
padding: "8px 16px",
border: "none",
borderRadius: 4,
cursor: "pointer"
}
});
// Using the default hook (equivalent to tss.create({}))
const useEmptyStyles = useStyles;TSS methods can be chained in any order to build up the desired configuration:
const useAdvancedStyles = tss
.withName("AdvancedComponent")
.withParams<{ variant: "primary" | "secondary" }>()
.withNestedSelectors<"root" | "icon">()
.create(({ theme }, { variant }, classes) => ({
root: {
backgroundColor: variant === "primary" ? theme.primaryColor : theme.secondaryColor,
[`& .${classes.icon}`]: {
marginRight: 8
}
},
icon: {
fontSize: 16
}
}));TSS instances automatically provide context values to style functions:
const { tss } = createTss({
useContext: () => {
const theme = useTheme();
const userPreferences = useUserPreferences();
return { theme, userPreferences };
}
});
const useContextStyles = tss.create(({ theme, userPreferences }) => ({
root: {
backgroundColor: theme.colors.background,
fontSize: userPreferences.fontSize,
fontFamily: userPreferences.fontFamily
}
}));Install with Tessl CLI
npx tessl i tessl/npm-tss-react