SlideShare a Scribd company logo
So you want to build your (Angular)
Component Library? We can help
Carlo Bonamico - Sonia Pini
Milan | November 29 - 30, 2018
Components are the core of Web Apps
Self-contained set of UI and logic
○ encapsulate a specific behaviour
○ provide an explicit API
better than
Advantages of Components
Stronger Encapsulation
● explicit @Input and @Output bindings
● changing the component internal implementation has less
impact on the rest of the application
● more decoupling, less regressions
Reusability
● same component used in different contexts
● with different parameters or inputs
Advantages of Components
Better Collaboration
● less conflicts when team grows
● easier to test for regressions
More Clarity and Readability
● I can effectively use a component knowing only its API (the
bindings section)
● the link to other components is very clear and explict in the
HTML
Also, the component tree is very good for performance
<mail-view>
<message-list>
<nav-actions><common-star>
<message-view>
<common-star>
Why build a
Component Library?
Most of the concepts in this talk apply to any framework
although example syntax is based on Angular
Why a Component Library?
Starting point:
Provide a Uniform Visual Style
Why a Component Library?
● Higher productivity
○ Higher abstraction
○ Re-use across projects
○ Faster app build time
● Focus Documentation / Test effort
● Promote Cleaner Design and Best Practices
○ Separation of Responsibility
● Apps benefit from improvements in the Library
What kind of Component Library?
● Basic Components / Atoms
○ form labels
○ input controls
○ buttons <mat-button>
○ abstract elements: fonts, color palettes, animations, ...
http://atomicdesign.bradfrost.com/table-of-contents/
What kind of Component Library?
● Composed Components / Molecules
○ combining Base Components together
○ e.g. <lib-search-filter>
What kind of Component Library?
● Complex Components / Organisms
○ combining Basic and/or Composed Components together
○ Domain-independent es. <ht-table>, <shopping-cart>
○ Domain-specific es. <doc-sign-documents>, <contact-address-book>
Composability + Consistency = Great LIB
Functional Consistency
● Make your product more predictable
● Better UX
Visual Consistency
● Includes the colors, fonts, sizes, positions
Modularity / Composability
● the set is greater than the parts
API Consistency & Development Experience
● including Documentation and Packaging
● make developer more productive
Visual Consistency
Adopt or Provide Style Guide
Well defined colors, fonts, spacing
Davide Casali - Gestalt Design Principles for Devs
https://www.slideshare.net/folletto/gestalt-design-principles-for-developers
Adopt a naming convention for styles
● your own vs Block-Element-Modifier http://getbem.com
Use a CSS Pre-Processor (SCSS - LESS) to
● simplify uniform style definitions with @variables
● semi/automatically create themes or accessibility features
Library-level CSS should concentrate on
● variables for color palette, base font sizes, margin, padding
● page-level layout (e.g. Grid)
Component-level CSS
● encapsulation for easier maintenance
Organize Library Stylesheets
Separate Containers from content
Container Components focus on
● position/layout within the page or parent
○ <ht-sidebar-layout>, flex-based
● decorating the content
○ <ht-card>, <ht-accordion>, <ht-panel>
Component Design:
How to Configure a Component
<component>inputs outputs
Data
Config
Event
● Attributes
○ width, height, orientation
● Bindable @Inputs
○ mode, disabled <ht-button [disabled]=”!editable”>
● Library-Level Options
○ global defaults, from ConfigurationService or Injection Token
export const CONFIG = new InjectionToken<string>('config');
class DatePickerComponent {
constructor( @Inject(CONFIG) private configuration: Configuration) { }
ngOnInit() {
if (!this.dateFormat) this.dateFormat = this.configuration.defaultDateFormat;
}
Component Configuration
Component Design:
Passing Data to Components
<component>inputs outputs
Config
Data Event
Pattern: Data Flow “down”
Component bind a subset of their model to children
<mail-view>
<folder-list> <message-list>
<nav-actions><common-star>
<message-view>
<common-star>
folders
messages
currentMessage
Using @Input()
Using plain variables/arrays for @Input
● data owned by parent
● better for stateless / “dumb” components
<user-details [user]=”currentUser”>
Using Observable for @Input
● if you want to listen to changes continuously or
asynchronously
<realtime-chart [dataStream]=”stockValueStream” >
Parent Component
todoList: string[] = [ ]
Output → Push string into todoList
@Input() todos: string[]
Parent Component
todoList: Observable<string[]>
Output → Push string into todoList
@Input() todos: Observable<string[]>
Parent Component
todoList: Observable<string[]>
Output → Push string into todoList
@Input() todos: string[]
Use “| async”
Using DataSource in @Input
More complex components might need data refresh / drill-down
○ think <ht-table> with pagination, sorting, ...
Define a DataSource Interface
○ with all methods your component want use during its life
Provide an Implementation for the easier/common use-cases
○ ArrayDataSource, PagedDataSource
Document the DataSource Interface to guide developers
○ provide example of custom implementation
An Example from Angular Material
abstract DataSource<T>
○ connect(...): Observable<T[]>
○ disconnect(...): void
TableDataSource<T> extends DataSource<T>
○ page(...): Observable<T[]>
○ sort(...): Observable<T[]>
○ filter(...): Observable<T[]>
https://material.angular.io/components/table/api#MatTableDataSource
Multi-mode @Inputs
The component auto-adapts to the provided input
For example, to populate a mat-table we can use
○ a simple T[] if our data are static
○ an Observable<T[]>
○ a DataSource<T>
Component Design:
Interaction Patterns
<component>inputs outputs
Config
Data Event
Pattern: Events Flow “up”
Component pass relevant events/changes to parent
<mail-view>
<folder-list> <message-list>
<nav-actions><common-star>
<message-view>
<common-star>
onSelected()
onCurrentMsg()
onStar()
onReply()
onNext()
Never communicate directly: Publish events! key for low coupling
● towards Parent Component
@Output() selected = new EventEmitter<string>();
select(item) { this.selected.emit(item); }
● towards shared Observable Streams in a Service
○ e.g. ErrorService, AlertService
private errorSubject = new Subject<any>();
notifyError(code, message) {
this.errorSubject.next({
code: code,
message: message
});
}
Events & Common Services
In both cases, events
should express
● what's happened
● à la DDD Events
● intent, not what to
do
Separation of Responsibilities +
Component Interaction
Complex behaviour achieved through collaboration
<mail-view>
<folder-list> <message-list> <message-view>
onSelected()
onCurrentMsg()messages
currentMessage
Example: Error Modal Component
Modal
Component ErrorView
Component
ErrorModal
Component
Implement the Decorator Pattern to add cross-cutting
behaviour to a set of components
● <ht-modal>
● <ht-input-container>
○ provides label, required,
validation errors to an input
<ht-input-container>
<ht-input [(ngModel)]=...
</ht-input-container>
○ uses @ContentChild
to access the control
Decorator Component Pattern
API Design
API Design Challenges and Principles
● Your Library has two “Users”
○ End Users and Developers
○ think from both perspectives
● Joshua Block: Principle of Least Astonishment
○ How to Design Good APIs
https://www.youtube.com/watch?v=aAb7hSCtvGw
Names Matter
● Functionality should be easy to explain
○ express Intent
○ X is hard to name => symptom that X design needs refinement
■ too many responsibilities
■ unclear intent
○ Good names drive development
● Adopt Naming Conventions
○ library prefix in components name (e.g. ht-panel vs app-view)
○ prefix in property names vs HTML5 attributes (disabled, width...)
Beyond Names: Conceptual Consistency
● Same/standard APIs based on Types
○ LabelAndIcon interface
○ ControlValueAccessor for all input fields
● Same Abstractions
○ DataSources for <ht-table>, <ht-tree>, <ht-document-download>
○ conceptually similar event if cannot share same Type
Limit the amount of Mental Models that developers must learn
● Kathy Sierra on learning for effective products
https://www.youtube.com/watch?v=FKTxC9pl-WM
API Should Be As Small As Possible
● But no Smaller
○ focus on the most important use-cases
● Constant trade-off between Under and Over-Engineering
○ if in doubt, leave it out: you can add it later
● often adding an Extension Point is easier
○ less risky than a Feature
○ e.g. <ng-content> or publishing an Event on a Stream
Gather & Refine Requirements
● Extract true requirements from ‘proposed solutions’
■ Table Columns should be configured to display a Button / Link
○ becomes
■ “Table Columns supports a template to customize cell rendering”
● Think more general
● Keep the Spec short
Plan for the Future
● Expect to make mistakes
● Prepare to evolve API
○ Expand-Contract pattern
○ Deprecation / console.warn()
○ Design for Refactoring: Typescript helps!
○ Ease upgrade with tools (tslint for rxjs 5-> 6, schematics)
○ automatic tests
Documenting your
Library
Documentation Matters
Document every public component, interface, method, ...
● if it is not documented, “it does not exists” for developers
● Component, method, variable names should be as
self-explanatory as possible
● for all the rest, there is...
Compodoc
● Rich documentation with compodoc
○ https://compodoc.app/
○ compodoc -p ./tsconfig.json
-d docs
● Automatically generate docs for
○ Component, Classes
○ Routing, Modules
● MarkDown for (quick) guides
○ project setup / library import
○ Architecture - Conceptual model
○ Component LifeCycle
Document by Example
● Examples are key
○ even better if executable
● Plnkr
○ http://next.plnkr.co/
● Stackblitz
○ https://stackblitz.com/
● StoryBook
○ https://storybook.js.org/
● Angular Playground
○ http://www.angularplayground.it/
Packaging and
Distribution
A good Angular Library
● Is platform independent
○ can be consumend as UMD, FESM, ...
● Is bundled and distributed
● Works with AOT (Ahead of Time Compiler)
● Plays well with TypeScript and IDEs
○ autocompletion, compile-time checking
See Angular Package Format
Minko Gechev
@mgechev
screenshot
structure of the build
package in node
modules
Angular 6.x integrates David Herges’ ng-packagr
● workspace = apps + libs
ng generate library basiclib
ng generate app basiclib-demo
ng build basiclib
cd dist/basiclib
npm pack
npm publish basiclib.y.z.tgz
even live reload across lib & app
https://mereommig.dk/en/blog/adding-livereload-to-the-angular-cli-libraries
Creating and publishing
The Future of
(Component) Libraries
Future directions
● Angular Ivy Renderer
○ reusing a library does not require metadata processing
■ https://blog.angularindepth.com/inside-ivy-exploring-the-new-angular-compiler-ebf85141cee1
● Angular Elements
○ package Components as HTML5
Custom Elements (a.k.a. Web Components)
○ https://angular.io/guide/elements
● See also StencilJs Component Compiler
○ https://stenciljs.com/
References on Components
Codemotion 2016 Talk
https://www.slideshare.net/carlo.bonamico/angular-rebooted-components-every
where
Components in Angular 2
https://angular.io/docs/ts/latest/cookbook/component-communication.html
More on Angular
https://angularconnect.com/talks
Thank you!
● Other presentations
− http://www.slideshare.net/carlo.bonamico/presentations
● Follow us on Twitter
− @carlobonamico @nis_srl @Sonietta
● updates on Angular, Clean Code, Continuous Delivery
● Contact us
− carlo.bonamico@gmail.com / carlo.bonamico@nispro.it
− Sonia.pini@nispro.it
● Our company
− http://www.nispro.it

More Related Content

PPT
Proteus SDK
PPTX
Sharing Data Between Angular Components
PPT
4\9 SSIS 2008R2_Training - Expression and Variables
PPTX
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
PPT
6.2\9 SSIS 2008R2_Training - DataFlow Transformations
PPT
6.1\9 SSIS 2008R2_Training - DataFlow Transformations
PPTX
Il 09 T3 William Spreitzer
PPTX
Angular Presentation
Proteus SDK
Sharing Data Between Angular Components
4\9 SSIS 2008R2_Training - Expression and Variables
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
6.2\9 SSIS 2008R2_Training - DataFlow Transformations
6.1\9 SSIS 2008R2_Training - DataFlow Transformations
Il 09 T3 William Spreitzer
Angular Presentation

Similar to Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Library? We can help - Codemotion Milan 2018 (20)

PDF
Angular Rebooted: Components Everywhere
PDF
Angular Rebooted: Components Everywhere - Carlo Bonamico, Sonia Pini - Codemo...
PDF
Angular 2 introduction
PDF
Angular 2 overview in 60 minutes
PDF
Angular JS2 Training Session #2
PPT
17612235.ppt
PPTX
Ext Web Components - Dev Week 2019
PDF
Angular2 with type script
PDF
What is your money doing?
PDF
Angular 2 - The Next Framework
PPTX
Building maintainable web apps with Angular MS TechDays 2017
PPTX
Angularj2.0
PPTX
Angularjs2 presentation
PDF
Framework Engineering
PPTX
Angular js training
PPTX
Angular js Training in Hyderabad
PDF
Angular meetup 2 2019-08-29
PDF
Commit University - Exploring Angular 2
PDF
Top 7 Angular Best Practices to Organize Your Angular App
PDF
better-apps-angular-2-day1.pdf and home
Angular Rebooted: Components Everywhere
Angular Rebooted: Components Everywhere - Carlo Bonamico, Sonia Pini - Codemo...
Angular 2 introduction
Angular 2 overview in 60 minutes
Angular JS2 Training Session #2
17612235.ppt
Ext Web Components - Dev Week 2019
Angular2 with type script
What is your money doing?
Angular 2 - The Next Framework
Building maintainable web apps with Angular MS TechDays 2017
Angularj2.0
Angularjs2 presentation
Framework Engineering
Angular js training
Angular js Training in Hyderabad
Angular meetup 2 2019-08-29
Commit University - Exploring Angular 2
Top 7 Angular Best Practices to Organize Your Angular App
better-apps-angular-2-day1.pdf and home
Ad

More from Codemotion (20)

PDF
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
PDF
Pompili - From hero to_zero: The FatalNoise neverending story
PPTX
Pastore - Commodore 65 - La storia
PPTX
Pennisi - Essere Richard Altwasser
PPTX
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
PPTX
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
PPTX
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
PPTX
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
PDF
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
PDF
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
PDF
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
PDF
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
PDF
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
PDF
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
PPTX
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
PPTX
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
PDF
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
PDF
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
PDF
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
PDF
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Pompili - From hero to_zero: The FatalNoise neverending story
Pastore - Commodore 65 - La storia
Pennisi - Essere Richard Altwasser
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Ad

Recently uploaded (20)

PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
KodekX | Application Modernization Development
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Empathic Computing: Creating Shared Understanding
PPT
Teaching material agriculture food technology
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Cloud computing and distributed systems.
PPTX
Spectroscopy.pptx food analysis technology
NewMind AI Weekly Chronicles - August'25 Week I
Understanding_Digital_Forensics_Presentation.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Reach Out and Touch Someone: Haptics and Empathic Computing
MIND Revenue Release Quarter 2 2025 Press Release
Per capita expenditure prediction using model stacking based on satellite ima...
Review of recent advances in non-invasive hemoglobin estimation
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Chapter 3 Spatial Domain Image Processing.pdf
20250228 LYD VKU AI Blended-Learning.pptx
KodekX | Application Modernization Development
Network Security Unit 5.pdf for BCA BBA.
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Empathic Computing: Creating Shared Understanding
Teaching material agriculture food technology
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Cloud computing and distributed systems.
Spectroscopy.pptx food analysis technology

Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Library? We can help - Codemotion Milan 2018

  • 1. So you want to build your (Angular) Component Library? We can help Carlo Bonamico - Sonia Pini Milan | November 29 - 30, 2018
  • 2. Components are the core of Web Apps Self-contained set of UI and logic ○ encapsulate a specific behaviour ○ provide an explicit API better than
  • 3. Advantages of Components Stronger Encapsulation ● explicit @Input and @Output bindings ● changing the component internal implementation has less impact on the rest of the application ● more decoupling, less regressions Reusability ● same component used in different contexts ● with different parameters or inputs
  • 4. Advantages of Components Better Collaboration ● less conflicts when team grows ● easier to test for regressions More Clarity and Readability ● I can effectively use a component knowing only its API (the bindings section) ● the link to other components is very clear and explict in the HTML Also, the component tree is very good for performance <mail-view> <message-list> <nav-actions><common-star> <message-view> <common-star>
  • 5. Why build a Component Library? Most of the concepts in this talk apply to any framework although example syntax is based on Angular
  • 6. Why a Component Library? Starting point: Provide a Uniform Visual Style
  • 7. Why a Component Library? ● Higher productivity ○ Higher abstraction ○ Re-use across projects ○ Faster app build time ● Focus Documentation / Test effort ● Promote Cleaner Design and Best Practices ○ Separation of Responsibility ● Apps benefit from improvements in the Library
  • 8. What kind of Component Library? ● Basic Components / Atoms ○ form labels ○ input controls ○ buttons <mat-button> ○ abstract elements: fonts, color palettes, animations, ... http://atomicdesign.bradfrost.com/table-of-contents/
  • 9. What kind of Component Library? ● Composed Components / Molecules ○ combining Base Components together ○ e.g. <lib-search-filter>
  • 10. What kind of Component Library? ● Complex Components / Organisms ○ combining Basic and/or Composed Components together ○ Domain-independent es. <ht-table>, <shopping-cart> ○ Domain-specific es. <doc-sign-documents>, <contact-address-book>
  • 11. Composability + Consistency = Great LIB Functional Consistency ● Make your product more predictable ● Better UX Visual Consistency ● Includes the colors, fonts, sizes, positions Modularity / Composability ● the set is greater than the parts API Consistency & Development Experience ● including Documentation and Packaging ● make developer more productive
  • 13. Adopt or Provide Style Guide Well defined colors, fonts, spacing Davide Casali - Gestalt Design Principles for Devs https://www.slideshare.net/folletto/gestalt-design-principles-for-developers
  • 14. Adopt a naming convention for styles ● your own vs Block-Element-Modifier http://getbem.com Use a CSS Pre-Processor (SCSS - LESS) to ● simplify uniform style definitions with @variables ● semi/automatically create themes or accessibility features Library-level CSS should concentrate on ● variables for color palette, base font sizes, margin, padding ● page-level layout (e.g. Grid) Component-level CSS ● encapsulation for easier maintenance Organize Library Stylesheets
  • 15. Separate Containers from content Container Components focus on ● position/layout within the page or parent ○ <ht-sidebar-layout>, flex-based ● decorating the content ○ <ht-card>, <ht-accordion>, <ht-panel>
  • 16. Component Design: How to Configure a Component <component>inputs outputs Data Config Event
  • 17. ● Attributes ○ width, height, orientation ● Bindable @Inputs ○ mode, disabled <ht-button [disabled]=”!editable”> ● Library-Level Options ○ global defaults, from ConfigurationService or Injection Token export const CONFIG = new InjectionToken<string>('config'); class DatePickerComponent { constructor( @Inject(CONFIG) private configuration: Configuration) { } ngOnInit() { if (!this.dateFormat) this.dateFormat = this.configuration.defaultDateFormat; } Component Configuration
  • 18. Component Design: Passing Data to Components <component>inputs outputs Config Data Event
  • 19. Pattern: Data Flow “down” Component bind a subset of their model to children <mail-view> <folder-list> <message-list> <nav-actions><common-star> <message-view> <common-star> folders messages currentMessage
  • 20. Using @Input() Using plain variables/arrays for @Input ● data owned by parent ● better for stateless / “dumb” components <user-details [user]=”currentUser”> Using Observable for @Input ● if you want to listen to changes continuously or asynchronously <realtime-chart [dataStream]=”stockValueStream” >
  • 21. Parent Component todoList: string[] = [ ] Output → Push string into todoList @Input() todos: string[]
  • 22. Parent Component todoList: Observable<string[]> Output → Push string into todoList @Input() todos: Observable<string[]>
  • 23. Parent Component todoList: Observable<string[]> Output → Push string into todoList @Input() todos: string[] Use “| async”
  • 24. Using DataSource in @Input More complex components might need data refresh / drill-down ○ think <ht-table> with pagination, sorting, ... Define a DataSource Interface ○ with all methods your component want use during its life Provide an Implementation for the easier/common use-cases ○ ArrayDataSource, PagedDataSource Document the DataSource Interface to guide developers ○ provide example of custom implementation
  • 25. An Example from Angular Material abstract DataSource<T> ○ connect(...): Observable<T[]> ○ disconnect(...): void TableDataSource<T> extends DataSource<T> ○ page(...): Observable<T[]> ○ sort(...): Observable<T[]> ○ filter(...): Observable<T[]> https://material.angular.io/components/table/api#MatTableDataSource
  • 26. Multi-mode @Inputs The component auto-adapts to the provided input For example, to populate a mat-table we can use ○ a simple T[] if our data are static ○ an Observable<T[]> ○ a DataSource<T>
  • 28. Pattern: Events Flow “up” Component pass relevant events/changes to parent <mail-view> <folder-list> <message-list> <nav-actions><common-star> <message-view> <common-star> onSelected() onCurrentMsg() onStar() onReply() onNext()
  • 29. Never communicate directly: Publish events! key for low coupling ● towards Parent Component @Output() selected = new EventEmitter<string>(); select(item) { this.selected.emit(item); } ● towards shared Observable Streams in a Service ○ e.g. ErrorService, AlertService private errorSubject = new Subject<any>(); notifyError(code, message) { this.errorSubject.next({ code: code, message: message }); } Events & Common Services In both cases, events should express ● what's happened ● à la DDD Events ● intent, not what to do
  • 30. Separation of Responsibilities + Component Interaction Complex behaviour achieved through collaboration <mail-view> <folder-list> <message-list> <message-view> onSelected() onCurrentMsg()messages currentMessage
  • 31. Example: Error Modal Component Modal Component ErrorView Component ErrorModal Component
  • 32. Implement the Decorator Pattern to add cross-cutting behaviour to a set of components ● <ht-modal> ● <ht-input-container> ○ provides label, required, validation errors to an input <ht-input-container> <ht-input [(ngModel)]=... </ht-input-container> ○ uses @ContentChild to access the control Decorator Component Pattern
  • 34. API Design Challenges and Principles ● Your Library has two “Users” ○ End Users and Developers ○ think from both perspectives ● Joshua Block: Principle of Least Astonishment ○ How to Design Good APIs https://www.youtube.com/watch?v=aAb7hSCtvGw
  • 35. Names Matter ● Functionality should be easy to explain ○ express Intent ○ X is hard to name => symptom that X design needs refinement ■ too many responsibilities ■ unclear intent ○ Good names drive development ● Adopt Naming Conventions ○ library prefix in components name (e.g. ht-panel vs app-view) ○ prefix in property names vs HTML5 attributes (disabled, width...)
  • 36. Beyond Names: Conceptual Consistency ● Same/standard APIs based on Types ○ LabelAndIcon interface ○ ControlValueAccessor for all input fields ● Same Abstractions ○ DataSources for <ht-table>, <ht-tree>, <ht-document-download> ○ conceptually similar event if cannot share same Type Limit the amount of Mental Models that developers must learn ● Kathy Sierra on learning for effective products https://www.youtube.com/watch?v=FKTxC9pl-WM
  • 37. API Should Be As Small As Possible ● But no Smaller ○ focus on the most important use-cases ● Constant trade-off between Under and Over-Engineering ○ if in doubt, leave it out: you can add it later ● often adding an Extension Point is easier ○ less risky than a Feature ○ e.g. <ng-content> or publishing an Event on a Stream
  • 38. Gather & Refine Requirements ● Extract true requirements from ‘proposed solutions’ ■ Table Columns should be configured to display a Button / Link ○ becomes ■ “Table Columns supports a template to customize cell rendering” ● Think more general ● Keep the Spec short
  • 39. Plan for the Future ● Expect to make mistakes ● Prepare to evolve API ○ Expand-Contract pattern ○ Deprecation / console.warn() ○ Design for Refactoring: Typescript helps! ○ Ease upgrade with tools (tslint for rxjs 5-> 6, schematics) ○ automatic tests
  • 41. Documentation Matters Document every public component, interface, method, ... ● if it is not documented, “it does not exists” for developers ● Component, method, variable names should be as self-explanatory as possible ● for all the rest, there is...
  • 42. Compodoc ● Rich documentation with compodoc ○ https://compodoc.app/ ○ compodoc -p ./tsconfig.json -d docs ● Automatically generate docs for ○ Component, Classes ○ Routing, Modules ● MarkDown for (quick) guides ○ project setup / library import ○ Architecture - Conceptual model ○ Component LifeCycle
  • 43. Document by Example ● Examples are key ○ even better if executable ● Plnkr ○ http://next.plnkr.co/ ● Stackblitz ○ https://stackblitz.com/ ● StoryBook ○ https://storybook.js.org/ ● Angular Playground ○ http://www.angularplayground.it/
  • 45. A good Angular Library ● Is platform independent ○ can be consumend as UMD, FESM, ... ● Is bundled and distributed ● Works with AOT (Ahead of Time Compiler) ● Plays well with TypeScript and IDEs ○ autocompletion, compile-time checking See Angular Package Format Minko Gechev @mgechev screenshot structure of the build package in node modules
  • 46. Angular 6.x integrates David Herges’ ng-packagr ● workspace = apps + libs ng generate library basiclib ng generate app basiclib-demo ng build basiclib cd dist/basiclib npm pack npm publish basiclib.y.z.tgz even live reload across lib & app https://mereommig.dk/en/blog/adding-livereload-to-the-angular-cli-libraries Creating and publishing
  • 48. Future directions ● Angular Ivy Renderer ○ reusing a library does not require metadata processing ■ https://blog.angularindepth.com/inside-ivy-exploring-the-new-angular-compiler-ebf85141cee1 ● Angular Elements ○ package Components as HTML5 Custom Elements (a.k.a. Web Components) ○ https://angular.io/guide/elements ● See also StencilJs Component Compiler ○ https://stenciljs.com/
  • 49. References on Components Codemotion 2016 Talk https://www.slideshare.net/carlo.bonamico/angular-rebooted-components-every where Components in Angular 2 https://angular.io/docs/ts/latest/cookbook/component-communication.html More on Angular https://angularconnect.com/talks
  • 50. Thank you! ● Other presentations − http://www.slideshare.net/carlo.bonamico/presentations ● Follow us on Twitter − @carlobonamico @nis_srl @Sonietta ● updates on Angular, Clean Code, Continuous Delivery ● Contact us − carlo.bonamico@gmail.com / carlo.bonamico@nispro.it − Sonia.pini@nispro.it ● Our company − http://www.nispro.it