Customizing Ignite UI for Angular Theming
Este artigo orientará você pelos detalhes da personalização do tema do aplicativo Ignite UI for Angular e da otimização do tamanho da folha de estilo produzida. O artigo mostra detalhes de como o mecanismo de temas Ignite UI for Angular funciona e apresenta o uso avançado dele. O artigo é muito útil para fazer a personalização completa dos estilos de componente, de modo que seu aplicativo Angular seja adaptado para corresponder à aparência desejada, e para tornar seu aplicativo ideal para implantação, reduzindo os tamanhos de estilo apenas para o que é usado pelo aplicativo.
Note
Este documento descreve o sistema de temas em Ignite UI for Angular a partir da versão 15. Os exemplos incluem o uso das APIs Sass fornecidas pelo mecanismo de temas e variáveis CSS expostas.
Getting Started
Usaremos o App Builder para produzir um aplicativo Angular e, em seguida, modificaremos o estilo dele no repositório gerado. Começamos criando um novo aplicativo a partir do modelo "Cabeçalho + mini navegação + conteúdo + painel lateral" no App Builder e adicionamos alguns componentes à superfície de design.

Em seguida, geramos nosso aplicativo, usando Angular como destino, para um repositório GitHub, sobre o qual trabalharemos tanto a partir do App Builder quanto modificando o próprio código gerado. Depois de clonar o repositório e construir o projeto, obtemos o aplicativo Angular em execução em seu estado inicial.

Como você pode ver, o aplicativo aplicou temas padrão, que é uma variante de luz material. O arquivo gerado styles.scss
tem esta aparência:
/* You can add global styles to this file, and also import other style files */
// Standard CSS normalize, comment out if not required or using a different module
@use "minireset.css/minireset";
@use "@infragistics/igniteui-angular/theming" as *;
@include core();
@include typography();
@include light-theme($light-material-palette);
body {
background: hsla(var(--ig-surface-500));
color: var(--ig-surface-500-contrast);
}
html, body {
height: 100%;
}
.ig-typography {
h1, h2, h3, h4, h5, h6, p, .ig-typography__body-1 {
margin: 0;
}
}
.outer-wrapper > *:not(router-outlet) {
width: 100%;
}
Theme Customization
Queremos uma variante escura do mesmo tema, adicionamos nossa própria paleta de cores para combinar com nossa marca e alteramos a fonte para Poppins
em vez do padrão Titillium Web
, tudo o que podemos alterar diretamente através do App Builder e podemos enviar a alteração como uma solicitação de pull do App Builder para o repositório.

A atualização styles.scss
fica assim:
@include core();
@include typography($font-family: "Poppins");
$custom-palette: palette(
$primary: #1028c7,
$secondary: #e0d94c,
$surface: #000,
$gray: #fff
);
@include theme(
$palette: $custom-palette,
$schema: $dark-material-schema
);
Como você pode ver, a geração de código mudou do específico @include light-theme($light-material-palette);
, que é o tema e a paleta de cores padrão, para um include genérico theme()
, que fornece como parâmetros nossa paleta de cores personalizada e um esquema de material escuro para a estrutura de temas. O resultado do aplicativo Angular em execução é semelhante a este agora:

Queremos nos aprofundar e personalizar um tema de componente específico em nosso aplicativo e faremos isso trazendo as variáveis CSS para um tema de componente individual, neste caso, o tema da barra de ferramentas da grade.
@include core();
@include typography($font-family: "Poppins");
$primary: #1028c7;
/* All of the components will use this custom color palette */
$custom-palette: palette(
$primary: $primary,
$secondary: #e0d94c,
$surface: #000,
$gray: #fff
);
@include theme(
$palette: $custom-palette,
$schema: $dark-material-schema
);
/* Grid Toolbar */
/* All grid toolbars will have custom background and elevations */
$toolbar-theme: grid-toolbar-theme(
$background-color: $primary
);
@include css-vars($toolbar-theme);
/* END Grid Toolbar */
E o resultado em nosso aplicativo agora é assim:

O mesmo processo pode ser aplicado para substituir e personalizar qualquer um dos temas componentes individualmente.
Switching custom themes at runtime
Agora vamos nos aprofundar ainda mais e criar duas versões personalizadas do tema, que podem ser alternadas em tempo de execução. Podemos fazer isso com controle/preferência do usuário e deixá-los trocá-lo a qualquer momento. Para o exemplo, no entanto, usaremos a preferência do usuário definida pelo sistema operacional (claro ou escuro) para aplicar um tema que corresponda à configuração atual do sistema operacional. Para fazer isso, precisaremos de duas paletas de cores:
@use "minireset.css/minireset";
@use "@infragistics/igniteui-angular/theming" as *;
@include core();
@include typography($font-family: "Poppins");
$primary-dark: #1028c7;
$primary-light: #3c55f1;
$secondary-dark: #e0d94c;
$secondary-light: #b4a904;
$custom-palette-dark: palette(
$primary: $primary-dark,
$secondary: $secondary-dark,
$surface: #000,
$gray: #ccc
);
$custom-palette-light: palette(
$primary: $primary-light,
$secondary: $secondary-light,
$surface: #fff,
$gray: #222
);
Em seguida, nossa definição de tema irá para o escopo geral, que usaremos para a variação de luz e criaremos uma substituição de paleta em uma @media
consulta quando a preferência do sistema operacional do esquema de cores escuras for detectada:
@include theme(
$palette: $custom-palette-light,
$schema: $light-material-schema
);
@media (prefers-color-scheme: light) {
/* Grid Toolbar override for light color scheme */
igx-grid-toolbar {
--background-color: #{$primary-light};
--title-text-color: #{text-contrast($primary-light)};
}
/* END Grid Toolbar */
}
@media (prefers-color-scheme: dark) {
// changes native element schema (scrollbars, select, etc.)
:root {
color-scheme: dark;
}
@include palette($custom-palette-dark);
/* Grid Toolbar override for dark color scheme */
igx-grid-toolbar {
--background-color: #{$primary-dark};
--title-text-color: #{text-contrast($primary-dark)};
}
/* END Grid Toolbar */
}
Note
Mudei a substituição do igx-grid-toolbar
tema para substituir apenas duas de suas variáveis, em vez de reincluir todas as variáveis do tema usando css-vars()
. Todas as variáveis de tema podem ser encontradas no documento da api sass correspondente e são equivalentes às variáveis sass, mas prefixadas com--
instead of $
.
E o resultado agora fica assim com o tema light OS:

E é assim que fica com o tema escuro do sistema operacional:

Note
A opção de tempo de execução completa, incluindo Ignite UI opção predefinida de esquema de tema, é possível somente se dois temas completos forem criados. No exemplo acima, estamos alternando as paletas de cores, mas o esquema do tema permanece $light-material-schema, portanto, nem todos os tons corretos da paleta de cores são usados quando mudamos para a paleta de cores escuras.
What can be customized
Ignite UI temas abstrai várias dimensões do tema e fornece recursos de retematização muito robustos. Desenvolvedores e designers podem aproveitar as APIs do mecanismo de temas para criar um design visual personalizado para seus aplicativos, o que lhes dá uma aparência única ao usar Ignite UI for Angular. O mecanismo de temas também expõe variáveis de cada uma das dimensões, que podem ser usadas para aplicar temas ao restante da estrutura do aplicativo, que não é criada diretamente com Ignite UI for Angular componentes como interface do usuário. As dimensões expostas para modificações são:
- Colors (color palette)
- Shape (borders and radiuses)
- Elevations (shadows)
- Tipografia (fontes e tamanhos de fonte)
- Tamanho (o tamanho da informação que é ajustada na tela)
Note
Se você realmente deseja um design visual totalmente personalizado, precisará modificar todas as dimensões de temas com suporte e aproveitará ao máximo as APIs do Sass. Se você só precisa alterar coisas como as fontes e algumas cores, basta dar uma olhada na seção de paletas e tipografia. Na maioria dos casos, tudo o que você precisa é alterar algumas variáveis CSS e não precisará das APIs Sass completas. Tornamos isso o mais granular possível, para que as modificações possam ser aplicadas sem resultados colaterais inesperados no design visual de seus aplicativos.
Theme Optimization
Depois de fazer algumas personalizações, vamos criar o aplicativo que geramos e modificamos para ver como é o tema do nosso aplicativo em termos de tamanho.

Como você pode ver, o tema do aplicativo é um pouco mais de 400kb, que se resume a ~ 40kb quando compactado e transferido. Isso não é grande, mas pode ser mais ideal? A resposta é sim, a menos que todos os componentes do pacote Ignite UI for Angular sejam usados. A chamada @include theme()
traz todos os temas componentes, mas temos um mecanismo para dizer à função o que excluir. Há um $exclude
parâmetro para o mixin de temas, que usa nomes de componentes como uma matriz e os exclui do tema no momento da compilação. Como não é tão fácil encontrar e listar todos os componentes disponíveis no pacote, é preferível que você possa listar todos os componentes que usa. Expomos a lista completa de componentes como uma variável, à qual você tem acesso assim que
@use "@infragistics/igniteui-angular/theming" as *;
A matriz de componentes é encontrada em $components
e você pode reduzir essa lista com os componentes que você usa e excluir todo o resto, como neste exemplo:
$include: (
igx-navbar,
igx-ripple,
igx-icon,
igx-button,
igx-input-group,
igx-combo,
igx-nav-drawer,
igx-grid,
igx-grid-toolbar
);
@include theme(
$palette: $custom-palette,
$schema: $dark-material-schema,
/* Removing all included components from the full list and excluding the rest */
$exclude: map.keys(map.remove($components, $include...))
);
Note
Alguns temas de componentes dependem de outros temas de componentes.
Mesmo se você excluir determinados temas, eles serão retidos pela compilação se você usar um tema de componente, que depende de um tema excluído.
Como fica nossa compilação depois de excluirmos certos temas?

Como você pode ver, o tamanho do nosso estilo é reduzido para quase metade do tamanho original. Isso parece muito bom no momento, mas podemos reduzir isso ainda mais? Na verdade, nós podemos. A maior parte do tamanho dos estilos é tomada pelos maiores componentes da suíte, neste caso o IgxTreeGridComponent
que temos em uma de nossas visualizações. No entanto, não usamos esse componente em nenhuma outra visualização. Podemos fazer a visualização com uma igx-tree-grid
rota carregada lentamente e podemos incluir o tema para as grades apenas para essa rota, tornando nosso css de nível superior ainda menor. Como isso é feito?
Começaremos criando um novo módulo e um novo módulo de roteamento na pasta com o componente employees em nosso aplicativo.
// employees.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { EmployeesRoutingModule } from './employees-routing.module';
import { EmployeesComponent } from './employees.component';
import { IgxButtonModule, IgxComboModule, IgxTreeGridModule } from '@infragistics/igniteui-angular';
@NgModule({
declarations: [
EmployeesComponent
],
imports: [
CommonModule,
EmployeesRoutingModule,
IgxComboModule,
IgxTreeGridModule,
IgxButtonModule
]
})
export class EmployeesModule { }
// employees-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { EmployeesComponent } from './employees.component';
const routes: Routes = [{ path: '', component: EmployeesComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class EmployeesRoutingModule { }
// Updated top-level app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PageNotFoundComponent } from './error-routing/not-found/not-found.component';
import { UncaughtErrorComponent } from './error-routing/error/uncaught-error.component';
import { ErrorRoutingModule } from './error-routing/error-routing.module';
import { StatisticsComponent } from './statistics/statistics.component';
export const routes: Routes = [
{ path: '', redirectTo: 'statistics', pathMatch: 'full' },
{ path: 'error', component: UncaughtErrorComponent },
// { path: 'employees', component: EmployeesComponent, data: { text: 'Employees' } },
// lazy-loading the employees route
{ path: 'employees', loadChildren: () => import('./employees/employees.module').then(m => m.EmployeesModule) },
{ path: 'statistics', component: StatisticsComponent, data: { text: 'Statistics' } },
{ path: '**', component: PageNotFoundComponent } // must always be last
];
@NgModule({
imports: [RouterModule.forRoot(routes), ErrorRoutingModule],
exports: [RouterModule, ErrorRoutingModule]
})
export class AppRoutingModule {
}
Agora removemos as IgxTreeGridModule
importações e IgxComboModule
, bem como as EmployeesComponent
de nossas app.module.ts
porque não usamos as importações em nenhuma outra visualização e podemos ter apenas uma declaração de componente em todos os módulos.
Em seguida, continuaremos removendo o,e igx-grid
igx-grid-toolbar
igx-combo
do nosso tema inclui, e vamos incluí-los no employees.component.scss
nível.
/* employees.component.scss */
@use "@infragistics/igniteui-angular/theming" as *;
:host ::ng-deep {
height: 100%;
display: flex;
justify-content: flex-start;
align-items: stretch;
align-content: flex-start;
$primary: #1028c7;
@include core();
@include grid(grid-theme());
@include combo(combo-theme());
@include grid-toolbar(
grid-toolbar-theme(
$background-color: $primary,
);
}
/* Updated styles.scss */
@use "sass:map";
@use "minireset.css/minireset";
@use "@infragistics/igniteui-angular/theming" as *;
@include core();
@include typography($font-family: "Poppins");
$primary: #1028c7;
$custom-palette: palette(
$primary: $primary,
$secondary: #e0d94c,
$surface: #000,
$gray: #fff
);
$include: (
igx-navbar,
igx-ripple,
igx-icon,
igx-button,
igx-nav-drawer
);
@include theme(
$palette: $custom-palette,
$schema: $dark-material-schema,
$exclude: map.keys(map.remove($components, $include...),)
);
Note
Você provavelmente deseja colocar todas as suas variáveis, como valores de paleta de cores, em um arquivo separado_variables.scss
, que pode ser incluído de vários componentes para reutilizar as variáveis.
O resultado em termos de compilação é o seguinte:

Como você pode ver, nosso nível styles.css
superior caiu para um pouco mais de 70kb, o que é um pouco menos de 6kb quando compactado. Começamos com ~ 428kb, ~ 40kb compactados e conseguimos reduzir isso cerca de 7 vezes em termos de tamanho compactado. O restante está sendo entregue somente quando a exibição que contém os igx-tree-grid
componentes e igx-combo
está sendo carregada.
Additional Resources
Tópicos relacionados:
Nossa comunidade é ativa e sempre acolhedora para novas ideias.