or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcss-features.mdindex.mdstyle-merging.mdstyle-sets.mdstylesheet-management.md
tile.json

style-sets.mddocs/

Style Set Processing

Advanced functionality for handling collections of related styles with automatic class name generation, type preservation, and support for functional styles.

Capabilities

Basic Style Set Merging

Processes multiple style sets into a single object with CSS class names.

/**
 * Merges style sets into processed style set with class names
 * @param styleSets - One or more style set objects
 * @returns Processed style set with class names for each area
 */
function mergeStyleSets<TStyleSet>(
  ...styleSets: Array<IStyleSet | Missing>
): IProcessedStyleSet<TStyleSet>;

function mergeStyleSets<TStyleSet1, TStyleSet2>(
  styleSet1: TStyleSet1 | Missing,
  styleSet2: TStyleSet2 | Missing
): IProcessedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2>>;

function mergeStyleSets<TStyleSet1, TStyleSet2, TStyleSet3>(
  styleSet1: TStyleSet1 | Missing,
  styleSet2: TStyleSet2 | Missing,
  styleSet3: TStyleSet3 | Missing
): IProcessedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2> & ObjectOnly<TStyleSet3>>;

function mergeStyleSets<TStyleSet1, TStyleSet2, TStyleSet3, TStyleSet4>(
  styleSet1: TStyleSet1 | Missing,
  styleSet2: TStyleSet2 | Missing,
  styleSet3: TStyleSet3 | Missing,
  styleSet4: TStyleSet4 | Missing
): IProcessedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2> & ObjectOnly<TStyleSet3> & ObjectOnly<TStyleSet4>>;

// Shadow DOM overloads
function mergeStyleSets<TStyleSet>(
  shadowConfig: ShadowConfig,
  ...styleSets: Array<IStyleSet | Missing>
): IProcessedStyleSet<TStyleSet>;

Usage Examples:

import { mergeStyleSets } from "@fluentui/merge-styles";

// Basic style set
const classNames = mergeStyleSets({
  container: {
    padding: "20px",
    backgroundColor: "white",
    border: "1px solid gray"
  },
  header: {
    fontSize: "24px",
    fontWeight: "bold",
    marginBottom: "10px"
  },
  content: {
    fontSize: "16px",
    lineHeight: "1.5"
  }
});

// Usage: classNames.container, classNames.header, classNames.content

// Merging multiple style sets
const baseStyles = {
  button: { padding: "8px 16px" },
  text: { fontSize: "14px" }
};

const themeStyles = {
  button: { backgroundColor: "blue", color: "white" },
  text: { color: "black" }
};

const mergedClassNames = mergeStyleSets(baseStyles, themeStyles);

// Shadow DOM usage
import { makeShadowConfig } from "@fluentui/merge-styles";

const shadowConfig = makeShadowConfig("my-component", true);
const shadowClassNames = mergeStyleSets(shadowConfig, {
  container: {
    backgroundColor: "blue",
    padding: "10px"
  }
});

Style Set Merging with Options

Style set processing with explicit configuration options.

/**
 * Merges style sets with explicit options
 * @param styleSets - Array of style sets to merge
 * @param options - Configuration options for style processing
 * @returns Processed style set with class names
 */
function mergeCssSets<TStyleSet>(
  styleSets: [TStyleSet | Missing],
  options?: IStyleOptions
): IProcessedStyleSet<ObjectOnly<TStyleSet>>;

function mergeCssSets<TStyleSet1, TStyleSet2>(
  styleSets: [TStyleSet1 | Missing, TStyleSet2 | Missing],
  options?: IStyleOptions
): IProcessedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2>>;

function mergeCssSets<TStyleSet1, TStyleSet2, TStyleSet3>(
  styleSets: [TStyleSet1 | Missing, TStyleSet2 | Missing, TStyleSet3 | Missing],
  options?: IStyleOptions
): IProcessedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2> & ObjectOnly<TStyleSet3>>;

function mergeCssSets<TStyleSet1, TStyleSet2, TStyleSet3, TStyleSet4>(
  styleSets: [TStyleSet1 | Missing, TStyleSet2 | Missing, TStyleSet3 | Missing, TStyleSet4 | Missing],
  options?: IStyleOptions
): IProcessedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2> & ObjectOnly<TStyleSet3> & ObjectOnly<TStyleSet4>>;

Style Set Concatenation

Combines style sets without CSS class generation for intermediate processing.

/**
 * Combines style sets without registering CSS classes
 * @param styleSets - One or more style sets to concatenate
 * @returns Concatenated style set with combined styles
 */
function concatStyleSets<TStyleSet>(
  ...styleSets: Array<TStyleSet | Missing>
): IConcatenatedStyleSet<ObjectOnly<TStyleSet>>;

function concatStyleSets<TStyleSet1, TStyleSet2>(
  styleSet1: TStyleSet1 | Missing,
  styleSet2: TStyleSet2 | Missing
): IConcatenatedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2>>;

function concatStyleSets<TStyleSet1, TStyleSet2, TStyleSet3>(
  styleSet1: TStyleSet1 | Missing,
  styleSet2: TStyleSet2 | Missing,
  styleSet3: TStyleSet3 | Missing
): IConcatenatedStyleSet<ObjectOnly<TStyleSet1> & ObjectOnly<TStyleSet2> & ObjectOnly<TStyleSet3>>;

// Shadow DOM overloads
function concatStyleSets<TStyleSet>(
  shadowConfig: ShadowConfig,
  ...styleSets: Array<TStyleSet | Missing>
): IConcatenatedStyleSet<ObjectOnly<TStyleSet>>;

Functional Style Sets with Props

Processes functional style sets that accept props for dynamic styling.

/**
 * Concatenates style sets resolving functional sets with props
 * @param styleProps - Props to pass to functional style sets
 * @param allStyles - Style sets which can be functions or objects
 * @returns Deep partial style set with resolved styles
 */
function concatStyleSetsWithProps<TStyleProps, TStyleSet extends IStyleSetBase>(
  styleProps: TStyleProps,
  ...allStyles: (IStyleFunctionOrObject<TStyleProps, TStyleSet> | undefined)[]
): DeepPartial<TStyleSet>;

Usage Examples:

import { concatStyleSetsWithProps } from "@fluentui/merge-styles";

interface ButtonProps {
  variant: "primary" | "secondary";
  size: "small" | "large";
  disabled?: boolean;
}

const buttonStyles = (props: ButtonProps) => ({
  root: {
    padding: props.size === "small" ? "4px 8px" : "8px 16px",
    backgroundColor: props.variant === "primary" ? "blue" : "gray",
    opacity: props.disabled ? 0.5 : 1,
    ":hover": props.disabled ? {} : {
      backgroundColor: props.variant === "primary" ? "darkblue" : "darkgray"
    }
  }
});

const staticStyles = {
  root: {
    border: "none",
    borderRadius: "4px",
    cursor: "pointer"
  }
};

// Resolve functional styles with props
const resolvedStyles = concatStyleSetsWithProps(
  { variant: "primary", size: "large", disabled: false },
  buttonStyles,
  staticStyles
);

Core Types

interface IStyleSetBase {
  [key: string]: any;
  subComponentStyles?: any;
}

interface IStyleSet<TStyleSet extends IStyleSetBase = { [key: string]: any }> {
  [P in keyof Omit<TStyleSet, 'subComponentStyles'>]: IStyle;
} & {
  subComponentStyles?: {
    [P in keyof TStyleSet['subComponentStyles']]: IStyleFunctionOrObject<any, any>;
  };
}

interface IConcatenatedStyleSet<TStyleSet extends IStyleSetBase> {
  [P in keyof Omit<TStyleSet, 'subComponentStyles'>]: IStyle;
} & {
  subComponentStyles?: {
    [P in keyof TStyleSet['subComponentStyles']]: IStyleFunction<any, any>;
  };
}

interface IProcessedStyleSet<TStyleSet extends IStyleSetBase> {
  [P in keyof Omit<TStyleSet, 'subComponentStyles'>]: string;
} & {
  subComponentStyles: {
    [P in keyof TStyleSet['subComponentStyles']]: Function;
  };
}

type IStyleFunction<TStylesProps, TStyleSet extends IStyleSetBase> = 
  (props: TStylesProps) => DeepPartial<TStyleSet>;

type IStyleFunctionOrObject<TStylesProps, TStyleSet extends IStyleSetBase> = 
  IStyleFunction<TStylesProps, TStyleSet> | DeepPartial<TStyleSet>;

type ObjectOnly<TArg> = TArg extends {} ? TArg : {};

Sub-Component Styles

Style sets support nested sub-component styles for complex component hierarchies:

interface ComponentStyleSet {
  root: IStyle;
  header: IStyle;
  content: IStyle;
  subComponentStyles?: {
    button: IStyleFunctionOrObject<ButtonProps, ButtonStyleSet>;
    icon: IStyleFunctionOrObject<IconProps, IconStyleSet>;
  };
}

const componentStyles: ComponentStyleSet = {
  root: { display: "flex", flexDirection: "column" },
  header: { padding: "10px", backgroundColor: "lightgray" },
  content: { flex: 1, padding: "20px" },
  subComponentStyles: {
    button: (props: ButtonProps) => ({
      root: {
        backgroundColor: props.primary ? "blue" : "gray"
      }
    }),
    icon: {
      root: { fontSize: "16px", color: "currentColor" }
    }
  }
};

const processedStyles = mergeStyleSets(componentStyles);
// processedStyles.subComponentStyles.button is now a function
// processedStyles.subComponentStyles.icon is now a function