Schemas are a simple, declarative way to list all properties a component theme uses.
Schemas are like recipes. They are simple Sass maps, similar to JSON that allow us to define all properties a theme might use. Those properties can be colors, elevation levels, roundness, etc. Anything a theme consumes can be described as a
schema, then passed to the global or component theme. A component schema can extend an existing component schema and override its properties.
Schemas should be used when you want to change the default theme properties of a component in a way that will not result in duplicating CSS style rules or CSS variables.
Let's take a look at the light Material Avatar schema:
$_light-avatar: extend( $_square-shape-avatar, ( background: ( color: ('gray', 400) ), color: ( color: ('gray', 800) ), ) );
As you can see from the example above, the component schema defines the properties the Avatar Theme consumes. It just prescribes the colors the avatar should use, without referencing a concrete color palette map.
Let's take the
background property for example. It tells the avatar theme what the default background should be.
background can be assigned any value, that is, a value that can be assigned to the CSS
background-color property. You can also assign a map to
background, like in the sample above. When you assign a map to the
background property, the map should contain functions as the key names (e.g.
color), and arguments for the functions as values for said keys. We do this to be able to resolve the values later on, when the avatar theme is being built. See, because we don't know the palette a user might pass to the avatar theme, we should be able to resolve it later on, only when the palette is known.
We can also add other functions and arguments to the
background map as key value pairs. For instance we may want to run the resolved result from
color: ('gray', 400) through the
to-opaque function we have, to resolve the HEX value for the
400 color variant of the
gray palette, which is usually represented in rgba.
Let's see how the schema will change when we make this addition:
$_light-avatar: ( icon-background: ( color: ('gray', 400), to-opaque: #fff ), ... );
The result of the
color function call will automatically be passed as the first argument to the
to-opaque function. Since
to-opaque accepts a second argument for the background color, we provide it as the value. If the function doesn't accept any additional arguments, you should assign an empty list
() as its value.
As you saw from the example above. Schemas are simple maps and as such can be extended by overriding some of their properties. You might want to extend the material avatar schema by only changing its
background property, without having to copy all other properties manually. This is easily done using the
extend function we provide.
$my-avatar-schema: extend($_light-avatar, ( background: limegreen ));
Now the value of
$my-avatar-schema will contain all properties of
$_light-avatar, but the value for
background will have be
We provide predefined light and dark schemas that we use in our theme presets:
- Light Schemas
- Dark Schemas
We use the light and dark schemas accordingly with the light and dark palettes to create the component themes. For example, using the
$light-material-schema along with the
$light-material-palette will help us create all of the light material component themes. And vice versa - using the
$dark-material-schema along with the
$dark-material-palette will give us the dark material component themes.
Until now we have shown what a component schema is and how you can create one, but we have not talked about how you can use schemas in your Sass project.
Individual component schemas are bundled up in a global schema map for all components we have. So the
$_light-avatar schema is part of the global
$light-material-schema maps component schemas to component names. The
$light-material-schema looks something like this:
$light-material-schema: ( igx-avatar: $_light-avatar, igx-badge: $_light-badge, ... );
We do this so we can pass the entire
$light-material-schema to the
theme mixin. So for instance if we wanted to modify the
$light-material-schema by replacing the default component schema the avatar component uses we might do:
$my-light-schema: extend($light-material-schema, ( igx-avatar: $my-avatar-schema ));
Now we can pass all that to the global theme mixin:
// styles.scss @include theme( $schema: $my-light-schema, $palette: $default-palette );
Avatars in your global theme will now have use limegreen color for their background.
Some component schemas, like the button schema, have property definitions for roundness. This means that you can change the default button roundness for all buttons.
Finally, let's see how individual component themes can use the schema we created above.
$my-avatar-theme: avatar-theme( $schema: $my-avatar-schema );
Although schemas require a deeper knowledge of our theming library compared to theme functions and mixins, they allow us to declare component themes without increasing the size of the produced CSS. Another benefit of using schemas is how reusable and extensible they are as they are simple Sass maps. You can mix and match component schemas to create global theme schemas.
We use schemas internally to create variations that result in different pre-bundled themes for Material, Bootstrap, Fluent, and Indigo.
Our community is active and always welcoming to new ideas.