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 se pueden crear temas a nivel de componentes, tomemos unos momentos para hablar sobre cómo Ignite UI for Angular aborda la temática de componentes. Debido a que queremos ser compatibles con navegadores más antiguos, como IE11, tenemos dos enfoques completamente diferentes para los componentes temáticos.

    • 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);
    

    El código anterior produce variables CSS para el componente igx-avatar. Estas nuevas variables CSS sobrescriben las reglas de avatar predeterminadas. De manera similar, si incluyera el mixin css-vars más adelante en el archivo scss global, el mixin nuevamente sobrescribirá cualquier tema definido previamente.

    Por ejemplo:

    // ...
    @include css-vars($avatar-purple-theme);
    
    // Later
    $avatar-royalblue-theme: avatar-theme(
      $background: royalblue,
    );
    
    @include css-vars($avatar-royalblue-theme);
    

    En el código anterior, el tema global de facto es ahora $avatar-royalblue-theme, ya que sobrescribe cualquier mixin css-vars incluido previamente.

    Esto nos lleva al siguiente punto.

    Scoping Themes

    Como vimos en el ejemplo anterior, al agregar varios temas dirigidos al mismo componente en el mismo nivel, la última combinación de temas tiene prioridad. Esto se debe a la forma en que funciona la cascada CSS. Si desea tener dos o más temas dirigidos al mismo tipo de componente, deberá limitarlos a un selector. Por ejemplo, podemos crear múltiples temas igx-avatar y aplicarlos a selectores de CSS específicos que luego podremos usar en el marcado de nuestro componente.

    // ...
    // 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 de 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 View Encapsulation, y específicamente cómo se emula en Angular.

    El equipo Angular ha adoptado 3 estrategias para la encapsulación de vistas: emulada (predeterminada), ShadowDom y ninguna. Para obtener más información sobre cada una de estas estrategias, consulte la documentación Angular. Analizaremos más de cerca cómo manejar la temática de Ignite UI for Angular que forman parte de los componentes principales View Encapsulated.

    De todos modos, ¿qué significa exactamente encapsulación de vista Emulated? Este tipo de encapsulación de vista no aprovecha la especificación Shadow DOM, sino que emplea una forma de vincular estilos para un componente y sus hijos mediante el uso de un identificador de atributo único aplicado en el elemento host. Cualquier regla de estilo que agregue a una hoja de estilo de un componente Ver encapsulado que tenga como objetivo algún selector interno no se aplicará porque no hace referencia al atributo único del elemento anfitrión. Para poder 'penetrar' esta encapsulación, tenemos que utilizar alguna estrategia de penetración de View Encapsulation. En este momento, en Angular esta estrategia es::ng-deep; le permite apuntar a cualquier selector interno, que esté encapsulado por su elemento anfitrión. Es una buena práctica utilizar::ng-deep si trabaja con reglas CSS, en lugar de variables CSS y desea personalizar una única instancia de un componente. Proporcionaremos un ejemplo de esto en la siguiente sección.

    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);
    }
    

    Cuando usamos variables CSS, no tenemos que usar el pseudoselector::ng-deep. Con el código anterior hemos creado variables CSS para igx-avatar, que siempre tendrán royalblue como color de fondo. El tema de nuestro avatar personalizado no se "filtrará" a otras instancias del componente igx-avatar, por lo que permanecerá encapsulado dentro de nuestro componente personalizado app-avatar.

    Cualquier tema Ignite UI for Angular creado con $igx-legacy-support configurado en false permitirá diseñar componentes sin la necesidad de Sass en su proyecto. Por ejemplo, lo anterior podría lograrse estableciendo el valor de la variable CSS--igx-avatar-background en el color deseado:

    /* app-avatar.component.css */
    :host {
      --igx-avatar-background: royalblue;
    }
    

    Targeting Older Browsers

    En la sección de descripción general mencioné que podía usar valores codificados para diseñar sus componentes configurando la variable global $igx-legacy-support en true. Si usa el mixin theme y le pasa $legacy-support con el valor true, también establecerá $igx-legacy-support en true.

    Usage in global themes

    El siguiente ejemplo muestra cómo puede diseñar componentes utilizando valores codificados.

    // 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';
    
    @include core();
    @include theme($palette: $default-palette, $legacy-support: true);
    
    // Overwrite the default themes for igx-avatar using hard-coded values:
    $avatar-royalblue-theme: avatar-theme(
      $background: royalblue,
    );
    
    @include avatar($avatar-royalblue-theme);
    

    Usage in encapsulated views

    El siguiente ejemplo utiliza el ejemplo de la sección Ver encapsulación como punto de partida:

    // 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';
    
    // Enable legacy support first.
    // !IMPORTANT: Only applicable for versions older than Ignite UI for Angular 13.
    $igx-legacy-support: true;
    $avatar-royalblue-theme: avatar-theme(
      $initials-background: royalblue,
    );
    
    :host ::ng-deep {
      @include avatar($avatar-royalblue-theme);
    }
    

    API Overview

    Additional Resources

    Aprenda a configurar un tema global:

    Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.