Themes #
Themes allow you to customize the look and feel of aFP Design System. They provide a centralized way to control colors, typography, spacing, and other design elements, enabling a consistent and flexible visual experience across your application.
Schemes #
Each theme provides two visual schemes: light and dark.
The scheme defines the overall brightness and color tone of the interface, allowing you to adapt your application to different environments or user preferences.
By default, the light scheme is applied automatically.
You can explicitly set the desired scheme using the data-scheme attribute on any container element (such as <html>, <body>, or even specific components).
Example usage on the <html> element:
<html data-scheme="dark">
You can also apply the scheme to individual elements to style them differently from the global setting:
<afp-button data-scheme="dark">Dark Button</afp-button>
<afp-button [data-scheme]="'dark'">Dark Button</afp-button>
<AfpButton data-scheme="dark">Dark Button</AfpButton>
<AfpButton :data-scheme="'dark'">Dark Button</AfpButton>
This flexibility allows you to mix light and dark appearances within the same page if needed.
CSS Parts #
The CSS shadow parts module defines the ::part() pseudo-element that can be set on a shadow host. Using this pseudo-element, you can enable shadow hosts to expose the selected element in the shadow tree to the outside page for styling purposes.
<style>
afp-button.custom-button::part(button) {
background-color: deeppink;
color: white;
}
</style>
<afp-button class="custom-button">Custom style</afp-button>
<style>
afp-button.custom-button::part(button) {
background-color: deeppink;
color: white;
}
</style>
<afp-button [class]="'custom-button'">Custom style</afp-button>
<style>
afp-button.custom-button::part(button) {
background-color: deeppink;
color: white;
}
</style>
<AfpButton class="custom-button">Custom style</AfpButton>
<style>
afp-button.custom-button::part(button) {
background-color: deeppink;
color: white;
}
</style>
<AfpButton :class="'custom-button'">Custom style</AfpButton>
CSS Attributes #
Components may expose (dynamic) attributes and properties that reflect their current state, such as disabled, loading, or icon.
These attributes can be combined with ::part() to apply styles conditionally from outside the component.
<style>
afp-button.custom-btn[icon]::part(button) {
color: var(--afp-color-red-500);
}
</style>
<div class="afp-stack">
<small>Style icon-only buttons:</small>
<div class="afp-cluster afp-gap-xs">
<afp-button class="custom-btn" appearance="filled">
<afp-icon name="balloon-heart-fill"></afp-icon>
</afp-button>
<afp-button class="custom-btn" appearance="filled">
This color isn’t red
</afp-button>
</div>
</div>
<style>
afp-button.custom-btn[icon]::part(button) {
color: var(--afp-color-red-500);
}
</style>
<div class="afp-stack">
<small>Style icon-only buttons:</small>
<div class="afp-cluster afp-gap-xs">
<afp-button [class]="'custom-btn'" [appearance]="'filled'">
<afp-icon [name]="'balloon-heart-fill'"></afp-icon>
</afp-button>
<afp-button [class]="'custom-btn'" [appearance]="'filled'">
This color isn’t red
</afp-button>
</div>
</div>
<style>
afp-button.custom-btn[icon]::part(button) {
color: var(--afp-color-red-500);
}
</style>
<div class="afp-stack">
<small>Style icon-only buttons:</small>
<div class="afp-cluster afp-gap-xs">
<AfpButton class="custom-btn" appearance="filled">
<AfpIcon name="balloon-heart-fill"></AfpIcon>
</AfpButton>
<AfpButton class="custom-btn" appearance="filled">
This color isn’t red
</AfpButton>
</div>
</div>
<style>
afp-button.custom-btn[icon]::part(button) {
color: var(--afp-color-red-500);
}
</style>
<div class="afp-stack">
<small>Style icon-only buttons:</small>
<div class="afp-cluster afp-gap-xs">
<AfpButton :class="'custom-btn'" :appearance="'filled'">
<AfpIcon :name="'balloon-heart-fill'"></AfpIcon>
</AfpButton>
<AfpButton :class="'custom-btn'" :appearance="'filled'">
This color isn’t red
</AfpButton>
</div>
</div>
Using attributes on the host together with CSS Parts provides a stable and state-aware styling API without relying on internal class names.