Angular Material - wyciągnięcie koloru z aktywnego theme

0

Witam.
Pracuje nad możliwością wyboru motywu w projekcie. Coś na wzór tego co jest na głównej stronie Angular Material https://material.angular.io/. Nie mówię tutaj o trybie ciemnym, mówię tutaj o kolorze primary, accent oraz warn. Z tego względu, że tworze własnych styl aplikacji, niektóre rzeczy jestem zmuszony obsłużyć ręcznie. Na przykład mat-stroked-button powinien mieć border w kolorze primary.

angular_theme.png

Korzystam również z FontAwesome, które mają ikony duo-tone, w których również można zmieniać kolory na jakie się chce. Teraz mam te kolory zrobione statycznie

    <i class="fad fa-file-alt"
    style="margin-right:10px;font-size: 20px;--fa-primary-opacity: 0.80;--fa-primary-opacity: 0.80;--fa-primary-color: #b56a3f; --fa-secondary-color: #c0805c;"></i>

W pliku themes.scss stworzę kilka predefiniowanych motywów, które będą miały swoje 3 podstawowe kolory i nie mam pojęcia jak uzyskać dostęp do kolorów wybranego motywu. Chciałbym mieć możliwość stworzenia serwisu, który by wybrany motyw aplikacji przechowywał jako BehaviorSubject<Theme>. Jest to w ogóle możliwe w Angular?

0

https://stackblitz.com/edit/angular-6nenxf
tam masz komponent.html w nim [attr.data-open]="menu" i jak podbindujesz sobie diva to w pliku scss mozesz zmieniac kolor czy cos i one ci sie dynamicznie przekazuja do widoku, chyba ze nie o to chodzi.

0

a jak teraz wybierasz theme? W pliku theme'a gdzie includujesz wszystkie style z materiala po prostu dodaj

@include app-theme($theme)

i stwórz mixin o tej nazwie i wewnątrz masz dostęp do wszystkich zmiennych. Teoretycznie powinieneś includować tak style do każdego komponentu tak jak to robi material, ale ja poszedłem na łatwiznę i przepisuję zmienne do cssowych w ten sposób:

$primary: map.get($theme, primary);

--primary-color: #{mat.get-color-from-palette($primary, default);

i wtedy masz prosty dostęp do kolorów z dowolnego miejsca

0

Na tę chwilę nie mam jeszcze nic. Chciałem wziąć rozwiązanie do dark mode z poprzedniego projektu ale okazuje się, że inaczej się teraz koduje theme od wersji 12. Tamten projekt był tworzony w wersji 11 albo nawet 10. Nigdzie nie jest opisane jak uzyskać wartość primary color z poziomu komponentu albo serwisu.

PRZYKŁAD

export class ThemeService {

    const subject = new BehaviorSubject<Theme>(undefined);
}

export class Theme {
   primary: string;
   accent: string;
   warn: string;
   background: string;
}

PO STRONIE KOMPONENTU

constructor(public themeService: ThemeService) {}

WIDOK - dostęp do themeService lub zmiennej, która będzie ten kolor przechowywać.

<button mat-stroked-button color="primary">
​<i class='fad fa-file-alt' ​style='--fa-primary-color: {{ themeService.primary }}; --fa-secondary-color: {{ themeService.accent }};'></i>
Primary
</button>    

Gdzie Angular ze swoimi komponentami sobie sam automatycznie poradzi, tak moje wodotryski muszę obsłużyć sam - kolor ikon, border-color przycisków i dojdzie do tego wiele więcej. Oczywiście tyczy się to też trybu ciemnego.

0

Udało się to ogarnąć nieco na około. Wrzucam tutaj rezultat dla potomnych ✌

ClientApp - Angular Theme Selector
Angular Theme Selector - Repository

2

no i chodziło mi o to żebyś właśnie przykładowo w klasie

.wiosna {
@include mat.all-component-themes($theme1);
}

dopisał to co wkleiłem (możesz to includować):

$primary: map.get($theme, primary);

--primary: #{mat.get-color-from-palette($primary, default);

a potem w komponentach mógłbyś używać:

<button mat-stroked-button color="primary">
​<i class='fad fa-file-alt' ​style='--fa-primary-color: var(--primary); --fa-secondary-color: var(--accent);'></i>
Primary
</button>

wciągnięcie zmiennej ze styli do zmiennej w js/ts nie wiem czy jest możliwe (poza oczywiście stworzeniem obiektu i odczytaniu jego koloru), ale jej zapewne tam nie potrzebujesz

0

Ok, teraz kumam. Jest to zdecydowanie lepsze rozwiązanie, ponieważ nie muszę do każdego komponentu wstrzykiwać ThemesService. Dodatkowo jeszcze tylko zaznaczę, że parę błędów miałeś w swoim wpisie. Na górze pliku themes.scss trzeba było zaimportować @use "sass:map"; a w linii

--primary: #{mat.get-color-from-palette($primary, default)};

brakowało } przed ;

1 użytkowników online, w tym zalogowanych: 0, gości: 1