Angular theme provider
(Source/Credits: https://dev.to/aziziyazit/angular-theme-provider-59pe)
Providing theme provider is a MUST in component library. All the components should be able to gain ac...
title: Angular theme provider published: true description: tags: angular, themeprovider
Providing theme provider is a MUST in component library. All the components should be able to gain access to the Theme Object. This includes palettes, spacings, sizings and many more.
In Angular, providing the theme provider is easy to be accomplished as the Angular have this ability out-of-the-box.
In this post we are using forwardRef and ngTemplate
forwardRef
Basically forwardRef is just a function that captures a class reference into closure. By using forwardRef we be able to get access to the component reference and use it in others components.
~~~javascript constructor( @Inject(forwardRef(() => YourComponentName)) private yourComponentName: YourComponentName ) {} ~~~
ng-template
ngTemplate can use properties of its parent context and can have its own private context.
~~~html
In above example, the data2 and data2 is the data's from Parent Component
ThemeProviderComponent
ThemeProviderComponent is the root component or the parent component for the other components. All the components must be wrapped in this provider component in order to gain access to the theme object. It's highly recommended to wrap your entire app at the highest level (see below)
~~~html
ThemeProviderComponent snippet code
~~~javascript
@Component({
selector: "theme-provider",
template: <ng-container *ngIf="childAsTemplate">
<ng-container *ngTemplateOutlet="template; context: theme"></ng-container>
</ng-container>
<ng-content *ngIf="!childAsTemplate"></ng-content>
})
export class ThemeProviderComponent implements AfterContentInit {
@ContentChild(TemplateRef, { static: false }) template!: TemplateRef
constructor() {}
ngAfterContentInit() { this.childAsTemplate = this.template && true; } } ~~~
palette snippet code
~~~javascript const palette = { uiBlueDarker: "#071d40", uiBlueDark: "#0d3880", uiBlue: "#184da8", uiBlueLight: "#2765cf", uiBlueLighter: "#e60278" ... }; ~~~
scales snippet code
~~~javascript const scales = { "spacing-01": "0.125rem", "spacing-02": "0.25rem", "spacing-03": "0.5rem", "spacing-04": "0.75rem" ... }; ~~~
palette and scales is the theme items provided for child components usage
usages
used in Component
In this example, we created a button component that accept color and scale as an inputs and use the theme object provided by ThemeProviderComponent for palette and scales values.
~~~javascript
@Component({
selector: "my-button",
template: <button type="button" [style.color]="themeProvider?.theme?.palette[color]" [style.font-size]="themeProvider?.theme?.scales['spacing-0'+scale]">
<ng-content></ng-content>
</button>
})
export class MyButtonComponent {
@HostBinding("class") className;
@Input() color: string;
@Input() scale: number;
constructor( @Inject(forwardRef(() => ThemeProviderComponent)) private themeProvider: ThemeProviderComponent ) {}
} ~~~
we get the reference of ThemeProviderComponent by using forwardRef. In the template markup, we utilised the theme for palette and scale.
Below is code implementation for my-button component
~~~html
used in ngTemplate
In this example we customised my-button component and gain access the theme object thru ngTemplate
~~~html
Summary
The theme provider let us use the theme object like palette, spacing and sizing in scripting layer rather than stylesheet layer. For those who more comfortable in styling the component in JavaScript, this pattern can help to speed up styling works.
You can get all the codes used in this post here - https://stackblitz.com/edit/theme-provider
Comments section
ngnam
•May 1, 2024
like reactjs <3 thank bro