Како направити прилагођену тему у кутном материјалу

Ангулар Материал је сјајна библиотека која примењује Материал Десигн за Ангулар 2+. Званични документ је довољан у погледу употребе компонената, док је мало чланака о томе како прилагодити саму тему, посебно боје које се користе у теми.

У овом посту бих желео да резимирам оно што сам научио ових месеци од прилагођавања тема Кутног материјала.

Имајте на уму да овај чланак НИЈЕ о АнгуларЈС материјалу, који се користи за АнгуларЈС 1.к.

Повезани постови

Неки уобичајени постови о прилагођавању тема су:

  • „Темирање апликације Ангулар Материал“, званични водич за прилагођене теме,
  • „Комплетни водич за теме угаоне грађе“ Томаса Трајана, који пружа мноштво недокументираних упутстава. Топло препоручено .

Нисам пронашао друге корисне постове и био бих захвалан ако би неко могао да пружи неке ресурсе у коментарима.

Како створити прилагођену тему

Стварање теме материјала изузетно је једноставно: требате одабрати само три боје - примарну , наглашену и упозоравајућу - а Угаони материјал ће све учинити за вас. Страница палете материјала објашњава како то јасно функционише, а тему можете да направите и визуелно помоћу Алата за боје.

Што се тиче кода, све што треба да урадите је да креирате следећу датотеку теме:

// [email protected] '[email protected]/material/theming';
$my-theme-primary: mat-palette($mat-green);$my-theme-accent : mat-palette($mat-amber);$my-theme-warn : mat-palette($mat-red);
$my-theme: mat-light-theme( $my-theme-primary, $my-theme-accent, $my-theme-warn);

Затим морате да примените ову тему у главној style.scssдатотеци:

@import "theme.scss";
@include mat-core();@include angular-material-theme($my-theme);

Како се користи прилагођена тема у компонентама

Након стварања сопствене теме, повећаће се захтеви попут овог:

Желим да направим оквир за текст. Боја текста, боја позадине и боја обруба треба да потичу из наше теме, а не строгим кодирањем.

Овај захтев је прилично чест - у сваком случају, могућност употребе у компонентама је управо разлог зашто желимо да креирамо прилагођену тему. Проблем је у томе како.

Комбиновани приступ

Први званични документ који сам поделио предложио је начин коришћења СЦСС-овог миксина. Ја то називам приступом „одоздо према горе“, који укључује следеће кораке:

  1. Свака компонента дефинише комбинацију тема и преузима боје из $themeпараметра.
  2. Глобал theme.scssдефинише прилагођену тему, а затим укључује све комбинације тема компонената и позива их са прилагођеном темом.

Поред theme.scssгоре поменуте дефиниције, свака компонента треба да креира датотеку теме попут ове:

// src/app/comp-a/[email protected] '[email protected]/material/theming';
@mixin comp-a-theme($theme) { // define mixin $primary: map-get($theme, primary); // retrieve color def button { // apply theme to component background-color: mat-color($primary); }}

И вероватно желите custom-theme.scssда увозите све теме на нивоу компоненте:

// src/app/[email protected] '[email protected]/material/theming';@import 'src/app/comp-a/comp-a.theme';@import 'src/app/comp-b/comp-b.theme';
@mixin custom-themes($theme) { @include comp-a-theme($theme); @include comp-b-theme($theme);}

Затим увезите горе наведено custom-theme.scssу theme.scss:

// [email protected] './custom-theme';@include custom-themes($my-theme);

Ова хијерархија функционише и вероватно је једини начин када треба да подржите више тема .

Међутим, већину времена подржавамо само једну тему, а коришћење микина може бити незгодно. Углавном постоје три недостатка код овог приступа:

  1. За сваку поједину референцу боје потребна је посебна .theme.scssдатотека.
  2. custom-theme.scssморају тачно знати које компоненте пружају прилагођене теме. Ово ствара непотребне зависности.
  3. Најважније је да датотеке са темама на нивоу компоненте нису обухваћене.

Прва и друга тачка прилично су објашњене. Дозволите ми да објасним мало о тачки 3. То укључује нека основна знања која се називају „Капсулација погледа“.

Angular uses a technique called “View Encapsulation” to keep component CSS local. In other words, rules defined for one component will stay in that component and will not affect other components.

In this way you can define CSS class name freely in your component without worrying about naming conflicts. However, view encapsulation is done only if the CSS is defined through @Component, i.e. @Component({ styleUrls: ['./comp-a.scss'] }).

As to our custom theme file comp-a.theme.scss, since it is imported directly by custom-theme.scss, its rules are not encapsulated so it will apply to all elements on the page. In the example above, I used the following code (which was WRONG!):

@mixin comp-a-theme($theme) { button { ... } // This will apply to ALL buttons!}

But this will apply the style to all the buttons instead of those buttons belonging to comp-a only. You have to do something like comp-a button in order to make this work correctly.

The direct approach

Therefore I propose a better approach. Instead of using a mixin, we let each component include the theme file and use the color definition directly.

In this approach, the component theme file will look like this:

// NOTE: just do this in your regular scss file.// No need to create separate theme file!// src/app/comp-a/[email protected] 'src/theme.scss';
$primary: map-get($my-theme, primary);button { background-color: mat-color($primary);}

And that’s all.

Let’s see how this works. First, theme related rules are put into the component SCSS file, so no extra component level theme file required. Second, the main theme.scss does not need to know component level themes (since it does not need to import them), so a simple theme definition is adequate. Third, the component SCSS file is used with @Component so it is encapsulated correctly, which means we can simply define rules for button.

Predefined Theme Keys

Probably you have noticed the next problem. What are the foreground, primary in above theme files ( map-get($my-theme, primary))? Are there any other keys I can use?

Па, ови „тастери“ се односе на различите боје дефинисане у теми. Међутим, нисам успео да пронађем ниједан документ који објашњава ове „кључеве“, па је једини начин на који сам то могао сазнати читати изворни код . (Иако се каже да су добри програмери треба читати код, који за читање код дефинитивно није добар знак за библиотеку.)

Отворите node_modules/@angular/material/_theming.scssи видећете дефиниције ових тастера. За будуће референце, желео бих да овде сумирам кључеве.

$theme |- primary |- accent |- warn |- foreground | |- base | |- divider | |- dividers | |- disabled | |- disabled-button | |- disabled-text | |- hint-text | |- secondary-text | |- icon | |- icons | |- text | |- slider-min | |- slider-off | `- slider-off-active |- background | |- status-bar | |- app-bar | |- background | |- hover | |- card | |- dialog | |- disabled-button | |- raised-button | |- focused-button | |- selected-button | |- selected-disabled-button | |- disabled-button-toggle | |- unselected-chip | `- disabled-list-option `- is-dark // bool, whether dark theme or not

На пример, ако желите да у својој компоненти прикажете онемогућени текст, можда ћете желети да користите следећи код:

$foreground: map-get($my-theme, foreground);.disabled-text { color: mat-color($foreground, disabled-text);}

У реду, ово су неке лекције које сам научио из борбе са Угаоним материјалом. Надам се да је овај пост користан ако се суочавате са сличним проблемима.