Writing components
This guide provides several guidelines when writing Angular components in the project. Please follow them unless you have a good reason not to do so!
Standalone components
Standalone components have become the norm in Angular. Components in the project should all be made standalone over time; this means that new components must be standalone and that existing components should be made standalone when modified if it is possible (i.e. when that does not represent a disproportionate amount of work compared to the original task).
Standalone components have the following differences with legacy "non-standalone" ones:
- Standalone components are not declared in Angular Modules; instead, they act as their own module, declaring their own dependencies and providers
- Standalone components can import either Angular modules or other standalone components
This is the progression status of the Standalone Component migration:
64% done
52 applications components remaining. 38 libraries components remaining. Total component count is 247.
36% remaining
Storybook entry
All presentation components should appear in Storybook (launched through npm run storybook
). This applies to any component in the ui/*
libs, as well as any other component that might benefit from an isolated live testing environment.
An introduction to creating Storybook entries for Angular components can be found here.
A typical Storybook entry should:
- let the user manipulate all inputs in all ways possible in order to see how the component reacts
- let the user see all outputs emitted by the component
- let the user resize the container in which the component sits in order to see how the component handles its size; this can be done like so:ts
export default { // ... decorators: [ // ... componentWrapperDecorator( (story) => ` <div class="border border-gray-300" style="width: 450px; height: 100px; resize: both; overflow: auto"> ${story} </div>` ), ], } as Meta<MyComponent>
This is the progression status of creating Storybook entries for all presentation (UI) components:
75% done
70 UI components have a Storybook entry. 94 UI components in total.
25% remaining
Storybook entries for standalone components
Storybook entries for standalone components are usually straightforward to set up:
export default {
title: 'Category/MyStandaloneComponent',
component: MyStandaloneComponent,
decorators: [
// module imports may not be required since the component should already import everything it needs
applicationConfig({
providers: [
// provide here what's needed; for translation this is:
importProvidersFrom(UtilI18nModule),
importProvidersFrom(TranslateModule.forRoot(TRANSLATE_DEFAULT_CONFIG)),
],
}),
],
} as Meta<MyStandaloneComponent>
Stories for legacy non-standalone components
Legacy components will often rely on other modules. These should be imported like so:
export default {
title: 'Category/MyComponent',
component: MyComponent,
decorators: [
moduleMetadata({
imports: [
// import whatever module is required
// ...
// note: these are required if the module needs translations:
UtilI18nModule,
TranslateModule.forRoot(TRANSLATE_DEFAULT_CONFIG),
],
}),
applicationConfig({
providers: [
// provider wheter is needed here
],
}),
],
} as Meta<MyComponent>