Runtime CSS-in-JavaScript utilities for dynamic styling with high performance, RTL support, and TypeScript integration.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Advanced functionality for handling collections of related styles with automatic class name generation, type preservation, and support for functional styles.
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 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>>;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>>;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
);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 : {};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