Registered variants for code components

When a Plasmic component’s root element is a default Plasmic element (such as a horizontal stack, page container, etc.), you can utilize interaction variants in the Plasmic studio. These variants are used to define the design of the component when a user interacts with it.

However, when the root element is a code component, you cannot use built-in interaction variants. In this case, you need to define variants in the code for your custom components. This feature is called registered variants.

Registered variants is a feature that allows you to change the appearance of your component based on its state. In order to register a variant, you need to define it in the code component’s meta, like this:

Copy
import React from 'react';
interface LoadingButtonProps extends React.PropsWithChildren {
className: string;
}
export function LoadingButton(props: LoadingButtonProps) {
const { children, className } = props;
return (
// Registered variants rely on className passed to the code component.
<button className={className}>{children}</button>
);
}
PLASMIC.registerComponent(LoadingButton, {
name: 'LoadingButton',
variants: {
// Registered variants
hovered: {
cssSelector: ':hover',
displayName: 'Hovered'
}
},
props: {
children: 'slot'
}
});

Each registered variant is defined as a key-value pair in the variants object. The key is the name of the variant, and the value is an object with the following properties:

  • cssSelector: The CSS selector that will be used to apply the variant. This can be any valid CSS selector, such as :hover, :first-child, :disabled, etc.
  • displayName: The name of the variant that will be displayed in the Plasmic studio.

Each registered variant is represented as a new artboard in the Plasmic studio, where you can design the appearance of the component when the variant is active. You can then switch between the different variants in the studio to see how the component will look in each state.

Registered variant artboard

You can change any elements nested inside the code component when the variant is active. Here is how your component tree might look:

Registered variant component tree

Non-style changes (for example, changing the loading state from within the component) are also possible, but the code component must be tweaked to utilize the special plasmicUpdateVariant function provided by Plasmic. Here is the updated example, which also includes a new variant for the loading state:

Copy
import React from 'react';
export const VARIANTS = {
hovered: {
cssSelector: ':hover',
displayName: 'Hovered'
},
loading: {
cssSelector: '[data-loading=true]',
displayName: 'Loading'
}
};
type VariantType = keyof typeof VARIANTS;
interface LoadingButtonProps extends React.PropsWithChildren {
className: string;
plasmicUpdateVariant?: (changes: Partial<Record<VariantType, boolean>>) => void;
}
export function LoadingButton(props: LoadingButtonProps) {
const { children, className, plasmicUpdateVariant } = props;
const [isLoading, setIsLoading] = React.useState(false);
React.useEffect(() => {
plasmicUpdateVariant?.({ loading: isLoading });
}, [isLoading]);
return (
<button className={className} data-loading={isLoading} onClick={() => setIsLoading(true)}>
{children}
</button>
);
}
PLASMIC.registerComponent(LoadingButton, {
name: 'LoadingButton',
variants: VARIANTS,
props: {
children: 'slot'
}
});
Was this page helpful?

Have feedback on this page? Let us know on our forum.