Skip to content
This repository has been archived by the owner on Jan 6, 2025. It is now read-only.

Style Builders

CaerusKaru edited this page Nov 30, 2018 · 28 revisions

In its most simplistic form, the Angular Layout library is composed of two things: a series of responsive directives and the logic to generate styles for those directives. For a long time, these elements have been very tightly coupled together, with some configuration options sitting on the main module. However, with the release of v7.0.0-beta.20, we're decoupling this part of the library to allow for greater degrees of freedom for our users.

NOTE: This feature is best suited for advanced users; that is, those who want to dig deeper into the library. Understanding style builders is not a requirement for using the library

The API

Style generation was previously a one-and-done, trigger-then-generate algorithm. A directive would get an event, and then compile styles based on an input on-the-fly, every time. This is not only very inefficient, it presents a problem if one user disagrees with the style generation algorithm, and changing the algorithm would then affect all users.

To avoid this, we constructed an API that we believe provides the greatest flexibility and performance to our users without compromising the existing usability of the library.

export abstract class StyleBuilder {
  shouldCache = true;

  abstract buildStyles(input: string, parent?: Object): StyleDefinition;

  sideEffect(_input: string, _styles: StyleDefinition, _parent?: Object) {
    // This should be a no-op unless an algorithm is provided in a subclass
  }
}
  • buildStyles: this is the main event. All style computation that is destined for the host directive happens here, and is returned in the output. Not only that, but the output from this computation is cached, so if there is no need to regenerate styles for the same input, you don't have to!
  • shouldCache: a flag that tells the base directive whether or not to store the computed value from buildStyles in the cache (and also whether to retrieve it from the cache before generation)
  • sideEffect: this is meant as a salve in the event that extra computation is needed that doesn't occur on the main directive, and happens regardless of the caching mechanism. This fires each and every time an input event reaches the StyleBuilder

Finally, a note on the parent parameter. Each directive as it is built currently requires certain information from its parent that can't be retrieved from dependency injection alone. To resolve this, we pass in a parent object for certain directives that contain vital information. You might find it useful/necessary as well. Please take care in extending the StyleBuilders correctly to ensure the same functionality.

Benefits

  1. Full control over the style generation process on an ad-hoc basis, i.e. you don't need to override all directives if you don't want to, you can just override one or two
  2. The ability to handle custom inputs on an organizational/localization level, i.e. different languages for directions in fxLayoutAlign, or different keywords, i.e. cc === center center in fxLayoutAlign
  3. Better performance thanks to the new caching mechanism

Usage

To use the new StyleBuilder API, for instance to override fxFlexAlign, you would do the following:

import {Injectable, NgModule} from '@angular/core';
import {FlexAlignStyleBuilder, StyleBuilder, StyleDefinition} from '@angular/flex-layout';

@Injectable()
export class CustomAlignStyleBuilder extends StyleBuilder {
	buildStyles(input: string): StyleDefinition {
		return {CUSTOM_CSS};
	}
}

@NgModule({
	...,
	providers: [
		provide: FlexAlignStyleBuilder,
		useClass: CustomAlignStyleBuilder
	]
})
export class MyAppModule {}

Questions/Improvements

Please file an issue or feel free to open a PR. We're very excited about the potential for this API, and we hope you are too 😄

Clone this wiki locally