Temas de componentes
Los temas de componentes le permiten cambiar los estilos de instancias de componentes específicos anulando el tema definido globalmente.
Descripción general
Antes de profundizar en cómo puede crear temas a nivel de componente, dediquemos unos minutos a hablar sobre cómo Ignite UI for Angular aborda la creación de temas de componentes. Debido a que queremos poder admitir navegadores más antiguos, como IE11, tenemos dos enfoques completamente diferentes para la tematización de componentes.
- El primer enfoque consiste en diseñar instancias de componentes utilizando variables CSS. Al utilizar variables CSS, obtenemos la capacidad de crear temas de componentes sin replicar sus estilos una y otra vez. Además, este enfoque nos permite modificar el valor de las variables CSS en tiempo de ejecución.
- El segundo enfoque consiste en crear un nuevo conjunto de reglas CSS que sobrescriban cualquier regla CSS previamente declarada para un componente específico. Este enfoque es bastante sencillo y es la única forma en que podemos brindar compatibilidad con temas sensibles para navegadores más antiguos, aunque no es ideal ya que agrega muchas reglas CSS adicionales al tema CSS generado.
Veremos cómo funcionan estos enfoques en la práctica y cómo usar uno en lugar del otro al generar temas a nivel de componentes.
Creating Themes
Un tema componente consta de varias partes:
- La función del tema del componente: una función Sass que normaliza los argumentos pasados y produce un tema para ser consumido por un mixin de componentes.
- El mixin de variables CSS: un mixin de Sass que consume un tema de componente y produce variables CSS que se utilizan para diseñar un componente en particular.
- El mixin de componentes: un mixin de Sass que consume un tema de componente y produce reglas CSS que se utilizan para diseñar un componente en particular.
Supongamos que desea crear un nuevo tema de avatar global que tenga un color de fondo diferente al que configuramos en el tema predeterminado del avatar. Como se mencionó en la sección de descripción general, existen dos enfoques generales para crear un tema de componente. Hay incluso más formas de organizar y definir el alcance de los temas de sus componentes. La forma más sencilla de hacerlo es en el mismo archivo en el que definiste tu tema global.
Definiendo un tema de avatar:
// Some place after @include theme(...);
// Change the background of the avatar to purple.
$avatar-purple-theme: avatar-theme(
$background: purple,
);
// Pass the css-vars to the `css-vars` mixin
@include css-vars($avatar-purple-theme);
The above code produces CSS variables for the igx-avatar component. These new CSS variables overwrite the default avatar rules.
Similarly, if you were to include css-vars mixin later down in the global scss file, the mixin will again overwrite any previously defined themes.
Por ejemplo:
// ...
@include css-vars($avatar-purple-theme);
// Later
$avatar-royalblue-theme: avatar-theme(
$background: royalblue,
);
@include css-vars($avatar-royalblue-theme);
In the above code, the de facto global theme is now the $avatar-royalblue-theme as it overwrites any previously included css-vars mixins.
Esto nos lleva al siguiente punto.
Scoping Themes
As we saw in the previous example, when adding multiple themes targeting the same component at the same level, the last theme mixin takes precedence. This is due to the way the CSS cascade works. If you want to have two or more themes targeting the same type of component, you will have to scope them to a selector. For instance we can create multiple igx-avatar themes and scope them to specific CSS selectors we can later use in our component markup.
// ...
// CSS class selectors
.avatar-royalblue {
@include css-vars($avatar-royalblue-theme);
}
.avatar-purple {
@include css-vars($avatar-purple-theme);
}
En una plantilla de componente:
<div class="avatar-royalblue">
<igx-avatar initials="AZ"></igx-avatar>
</div>
<div class="avatar-purple">
<igx-avatar icon="home"></igx-avatar>
</div>
View Encapsulation
Hasta ahora hemos explorado formas de crear temas con alcance global y que se incluyen en un único archivo Sass. Sin embargo, esto no siempre es deseable y, en algunos casos, querrá que el archivo Sass esté vinculado a un componente específico. En esos casos, debemos tener en cuenta la encapsulación de vistas y, específicamente, cómo se emula en Angular.
El equipo de Angular ha adoptado 3 estrategias para la encapsulación de vistas: Emulado (predeterminado), ShadowDom y Ninguno. Para obtener más información sobre cada una de estas estrategias, eche un vistazo a la documentación Angular. Echaremos un vistazo más de cerca a cómo manejar la creación de temas de Ignite UI for Angular componentes que forman parte de los componentes primarios encapsulados de vista.
What exactly does Emulated View Encapsulation mean, anyway? This type of View Encapsulation does not take advantage of the Shadow DOM specification, instead it employs a way to bind styles for a component and its children by using a unique attribute identifier applied on the host element.
Echemos un vistazo a un ejemplo que utiliza variables CSS. Creemos un tema de avatar que esté vinculado a un componente principal específico.
Aquí está nuestro componente simple:
import { Component, Input } from "@angular/core";
@Component({
selector: "app-avatar",
styleUrls: ["./app-avatar.component.scss"],
template: `<igx-avatar [initials]="initials"></igx-avatar>`,
})
export class AvatarComponent extends Component {
@Input() public initials = "AZ";
}
Y así es como se ve nuestra hoja de estilo Sass:
// app-avatar.component.scss
// Import the theming module
@use "igniteui-angular/theming" as *;
// !IMPORTANT: Prior to Ignite UI for Angular version 13 use:
// @import '~igniteui-angular/lib/core/styles/themes/index';
$avatar-royalblue-theme: avatar-theme(
$background: royalblue,
);
:host {
@include css-vars($avatar-royalblue-theme);
}
When using CSS variables, we don't have to use the ::ng-deep pseudo-selector. With the code above we've created CSS variables for the igx-avatar, which will always have royalblue as its background color. The theme for our custom avatar will not 'leak' into other igx-avatar component instances, thus staying encapsulated within our custom app-avatar component.
The above instance could also be achieved without using any Sass. All we need to do is to set the value of --igx-avatar-background CSS variable to the desired color:
/* app-avatar.component.css */
:host {
--igx-avatar-background: royalblue;
}
API Overview
Additional Resources
Aprenda a configurar un tema global:
Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.