Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An Insight into Modern Design Systems with Angular

Markus Nissl
February 11, 2024

An Insight into Modern Design Systems with Angular

Markus Nissl

February 11, 2024
Tweet

More Decks by Markus Nissl

Other Decks in Programming

Transcript

  1. The green bars do not fit in our design philosophy.

    We have to change them to a different color. Motivation
  2. The green bars do not fit in our design philosophy.

    We have to change them to a different color. Motivation There are so many competitors, let’s make a second brand to gain market share
  3. The green bars do not fit in our design philosophy.

    We have to change them to a different color. Motivation There are so many competitors, let’s make a second brand to gain most users …
  4. 1. Designer changes files 2. Designer notifies developer 3. Go

    to design file 4. Check what changed 5. Copy changed values and update css files a. Ensure one does not make a copy & paste error b. Ensure one does not miss a value 6. Test application if values are applied correctly a. Peer review b. Different devices/browsers 7. Designers review application 8. Deploy app Motivation
  5. 1. Designer changes files 2. Designer notifies developer 3. Go

    to design file 4. Check what changed 5. Copy changed values and update css files a. Ensure one does not make a copy & paste error b. Ensure one does not miss a value 6. Test application if values are applied correctly a. Peer review b. Different devices/browsers 7. Designers review application 8. Deploy app What if we could entirely eliminate the need for developer involvement? Motivation
  6. @markusnissl @markus.nissl @nisslmarkus I’m Markus :) I am a consultant,

    trainer, scientific researcher, software architect, mental coach and entrepreneur. [email protected] www.markusnissl.com www.data-insights.ai www.push-based.io About Me
  7. Designer changes verifies Merge PR if review is ok On

    new tokens Trigger & commit css On change Upload new tokens to git On new CSS Deploy Storybook Overview
  8. Design Token “A (Design) Token is an information associated with

    a name” Information: • Value • Description • Type • Other Metadata
  9. Background Design Tools Translation Tools Documentation Tools Figma Photoshop Sketch

    Illustrator Gimp … Style Dictionary Theo Diez Specify … Storybook Zeroheight Backlight Supernova … “Shared Language” Design Tokens
  10. Design Tokens “A (Design) Token is an information associated with

    a name” Information: • Value* • Description • Type1 • Other Metadata * required 1 conditionally required { “Token name”: { “$value”: “#ff0000” “$type”: “color” “$description”: “...”, “$extensions”: { “io.push-based.tool-a”: {…} … } } }
  11. Other Tokens and Elements Alias Tokens: { “Token name”: {

    “$value”: “{group name.token name}” } } Groups: { “colors”: { “Token name 1”: {…}, “Token name 2”: {…}, } } Composite Tokens: { “Token name”: { “$value”: { “color”: “#ff0000” "offsetX": "0.5rem", } “$type”: “shadow” } }
  12. Design Token Types Primitive Types • Color • Dimension •

    Font Family • Font weight • Duration • Cubic Bézier • Number Composite Types • Stroke Style • Border • Transition • Shadow • Gradient • Typography Type Resolving: 1. Read type provided by value 2. Otherwise, if token is a reference, use type of reference token 3. Otherwise, use type of closest group
  13. Style Dictionary parser formatter … transforms config filter 🔎 Style

    Dictionary is a build system that allows you to transform styles you define once into platform specific deliverables in a consistent way.
  14. Component Creation - Card For a Design System we want

    to have an extensible library. Card Progress Bar (ProgressB ar) Label
  15. Building Blocks for Scalable Components ng-content ng-template ng-container *ngTemplateOutlet Type

    Checking Level 1: @ViewChild @ViewChildren @ContentChild @ContentChildren TemplateRef ViewContainerRef Level 2: Level 3: Directive Shorthands Performance
  16. Level 1 - The Basics Rule 1: Use Content Projection

    In most cases you don’t know what the user wants to put inside your component. ng-content ng-template <ng-content /> <ng-content select=”...” /> ng-container *ngTemplateOutlet
  17. Level 1 - The Basics Rule 2: Provide Defaults In

    many cases you want to provide defaults that users should be able to override. ng-content ng-template ng-container *ngTemplateOutlet
  18. Level 1 - The Basics Rule 2: Provide Defaults In

    many cases you want to provide defaults that users should be able to override. ng-content ng-template <ng-template> <img ….> </ng-template> ng-container *ngTemplateOutlet
  19. Level 1 - The Basics Rule 2: Provide Defaults In

    many cases you want to provide defaults that users should be able to override. ng-content ng-template ng-container *ngTemplateOutlet <ng-container *ngTemplateOutlet=” progressBarIconTemplate” />
  20. Level 1 - The Basics Rule 2: Provide Defaults In

    many cases you want to provide defaults that users should be able to override. ng-content ng-template ng-container *ngTemplateOutlet <ng-container *ngTemplateOutlet=” progressBarIconTemplate; context:{ $implicit: “https://…” alt: label }” /> <ng-template let-src let-alt=”alt”> <img [src]=”src” [alt]=alt> </ng-template>
  21. Level 2 - The Dynamics @ViewChild(“icon”, {read: ViewContainerRef}) iconContainer @ViewChild

    @ViewChildren @ContentChild @ContentChildren TemplateRef ViewContainerRef #icon #defaultIcon Rule 3: Check other design systems for inspiration
  22. Level 2 - The Dynamics @ViewChild(“icon”, {read: ViewContainerRef}) iconContainer @ViewChild(“defaultIcon”)

    defaultIcon @ViewChild @ViewChildren @ContentChild @ContentChildren TemplateRef ViewContainerRef #icon #defaultIcon @ContentChild(“iconTemplate”) iconTemplate #iconTemplate Rule 3: Check other design systems for inspiration
  23. Level 2 - The Dynamics @ViewChild(“icon”, {read: ViewContainerRef}) iconContainer @ViewChild(“defaultIcon”)

    defaultIcon @ViewChild @ViewChildren @ContentChild @ContentChildren TemplateRef ViewContainerRef @ContentChild(“iconTemplate”) iconTemplate *ngTemplateOutlet=”iconTemplate ?? defaultIcon” Variant 1: In Template (Level 1) Rule 3: Check other design systems for inspiration
  24. Level 2 - Dynamic Component Creation @ViewChild(“icon”, {read: ViewContainerRef}) iconContainer

    @ViewChild(“defaultIcon”) defaultIcon @ViewChild @ViewChildren @ContentChild @ContentChildren TemplateRef ViewContainerRef @ContentChild(“iconTemplate”) iconTemplate this.iconContainer.createEmbeddedView( this.iconTemplate ?? this.defaultIcon ) Variant 2: In Code Variant 1: In Template (Level 1) Rule 3: Check other design systems for inspiration *ngTemplateOutlet=”iconTemplate ?? defaultIcon”
  25. Level 2 - Dynamic Component Creation @ViewChild @ViewChildren @ContentChild @ContentChildren

    TemplateRef ViewContainerRef Rule 3: Check other design systems for inspiration Default Value User provided Content Projection Default Value
  26. Level 2 - Dynamic Component Creation @ViewChild @ViewChildren @ContentChild @ContentChildren

    TemplateRef ViewContainerRef Rule 3: Check other design systems for inspiration Child Templates
  27. Level 3 - Type Checking <ng-template let-src let-alt=”alt”> <img [src]=”src”

    [alt]=alt> </ng-template> Type Checking Directive Shorthands Performance no type checking Rule 4: Ensure Developer Experience
  28. Level 3 - Type Checking interface IconTemplateContext { $implicit: string;

    alt: string; } @Directive({selector: 'ng-template[iconTemplate]', …}) export class IconTemplateDirective { static ngTemplateContextGuard(dir: ExampleDirective, ctx: unknown): ctx is IconTemplateContext { return true;} } Type Checking Directive Shorthands Performance Rule 4: Ensure Developer Experience
  29. Level 3 - Type Checking <ng-template iconTemplate let-src let-alt=”alt”> <img

    [src]=”src” [alt]=alt> </ng-template> interface IconTemplateContext { $implicit: string; alt: string; } @Directive({selector: 'ng-template[iconTemplate]', …}) export class IconTemplateDirective { static ngTemplateContextGuard(dir: ExampleDirective, ctx: unknown): ctx is IconTemplateContext { return true;} } Type Checking Directive Shorthands Performance Rule 4: Ensure Developer Experience
  30. <div *ngFor="let item of: items; index as i; let isFirst=first;">

    Level 3- Directive Shorthands Type Checking Directive Shorthands Performance [ngForOf] let-i=”index” let-isFirst=”first” <div ngFor let-item [ngForOf]=”items” let-i=”index” let-isFirst=”first”"> Rule 5: Understand Angular Internals
  31. Use OnPush Change Detection Use efficient CSS Selectors and Measure

    them (Not all CSS Selectors have the same performance) Reduce amount of DOM Level 3 - Performance Type Checking Directive Shorthands Performance Rule 6: Make sure your component is fast
  32. Level 3 - Performance Type Example ~Cost ID, class tag

    #id .cls a ✅ Descendant .foo * .foo > * ⚠ Attribute name [foo] ⚠ Attribute value [foo=”bar”] [foo*=”bar”] 🌶 Sibling .foo ~ * .foo + * 🌶 pseudo-class :nth-child() :nth-of-type() 🌶 https://nolanlawson.github.io/css-talk-2022/#61 Type Checking Directive Shorthands Performance Rule 6: Make sure your component is fast
  33. Level 3 - Bonus Declare your CSS properties used: @property

    --property-name{ syntax: “<color>”; inherits: false; initial-value: #ff0000; } Type Checking Directive Shorthands Performance Bonus Full browser support coming soon! Rule 7: Keep up to date with web standards to improve your design system