From 3b7cb1ea80f6c54be491ef491e2c33f60bcaacec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Bou=C3=A9?= Date: Thu, 7 May 2026 18:38:33 +0200 Subject: [PATCH 1/3] docs: init v22 --- README.md | 3 +- TODO.md | 6 +- VERSIONING.md | 14 +- docs/component/_category_.yml | 3 +- docs/component/change-detection.mdx | 3 +- docs/component/styling.mdx | 3 +- docs/component/template.mdx | 2 +- docs/component/typescript-class.mdx | 2 +- docs/contributing.mdx | 2 +- docs/dependency-injection.mdx | 2 +- docs/form.mdx | 25 +- docs/general/code-style.mdx | 4 +- docs/general/configuration.mdx | 4 +- docs/getting-started.mdx | 4 +- docs/i18n.mdx | 2 +- docs/performance.mdx | 7 +- docs/reactivity.mdx | 20 +- docs/testing.mdx | 1 - docs/ui-libraries/angular-material.mdx | 4 +- docs/ui-libraries/index.mdx | 4 +- docs/upgrading/index.mdx | 33 ++ docs/upgrading/upcoming.mdx | 35 ++ docs/upgrading/whats-new.mdx | 74 ++++ docusaurus.config.ts | 9 +- .../version-21/component/_category_.yml | 5 + .../version-21/component/change-detection.mdx | 64 +++ .../version-21/component/styling.mdx | 225 ++++++++++ .../version-21/component/template.mdx | 241 +++++++++++ .../version-21/component/typescript-class.mdx | 162 +++++++ versioned_docs/version-21/contributing.mdx | 45 ++ .../version-21/dependency-injection.mdx | 118 ++++++ versioned_docs/version-21/form.mdx | 90 ++++ .../version-21/general/_category_.yml | 4 + .../version-21/general/code-style.mdx | 191 +++++++++ .../version-21/general/configuration.mdx | 264 ++++++++++++ .../version-21/general/folder-structure.mdx | 176 ++++++++ .../general/third-party-libraries.mdx | 56 +++ versioned_docs/version-21/general/typing.mdx | 190 +++++++++ versioned_docs/version-21/getting-started.mdx | 49 +++ .../version-21/http/access-control.mdx | 304 ++++++++++++++ versioned_docs/version-21/http/api-design.mdx | 151 +++++++ .../version-21/http/api-specification.mdx | 84 ++++ .../version-21/http/error-handling.mdx | 30 ++ versioned_docs/version-21/http/index.mdx | 51 +++ versioned_docs/version-21/i18n.mdx | 64 +++ versioned_docs/version-21/performance.mdx | 287 +++++++++++++ versioned_docs/version-21/reactivity.mdx | 395 ++++++++++++++++++ versioned_docs/version-21/routing.mdx | 247 +++++++++++ .../version-21/state-management.mdx | 70 ++++ versioned_docs/version-21/testing.mdx | 47 +++ .../ui-libraries/angular-material.mdx | 142 +++++++ .../version-21/ui-libraries/index.mdx | 94 +++++ .../version-21}/upgrading.mdx | 16 +- versioned_sidebars/version-21-sidebars.json | 8 + versions.json | 1 + 55 files changed, 4075 insertions(+), 62 deletions(-) create mode 100644 docs/upgrading/index.mdx create mode 100644 docs/upgrading/upcoming.mdx create mode 100644 docs/upgrading/whats-new.mdx create mode 100644 versioned_docs/version-21/component/_category_.yml create mode 100644 versioned_docs/version-21/component/change-detection.mdx create mode 100644 versioned_docs/version-21/component/styling.mdx create mode 100644 versioned_docs/version-21/component/template.mdx create mode 100644 versioned_docs/version-21/component/typescript-class.mdx create mode 100644 versioned_docs/version-21/contributing.mdx create mode 100644 versioned_docs/version-21/dependency-injection.mdx create mode 100644 versioned_docs/version-21/form.mdx create mode 100644 versioned_docs/version-21/general/_category_.yml create mode 100644 versioned_docs/version-21/general/code-style.mdx create mode 100644 versioned_docs/version-21/general/configuration.mdx create mode 100644 versioned_docs/version-21/general/folder-structure.mdx create mode 100644 versioned_docs/version-21/general/third-party-libraries.mdx create mode 100644 versioned_docs/version-21/general/typing.mdx create mode 100644 versioned_docs/version-21/getting-started.mdx create mode 100644 versioned_docs/version-21/http/access-control.mdx create mode 100644 versioned_docs/version-21/http/api-design.mdx create mode 100644 versioned_docs/version-21/http/api-specification.mdx create mode 100644 versioned_docs/version-21/http/error-handling.mdx create mode 100644 versioned_docs/version-21/http/index.mdx create mode 100644 versioned_docs/version-21/i18n.mdx create mode 100644 versioned_docs/version-21/performance.mdx create mode 100644 versioned_docs/version-21/reactivity.mdx create mode 100644 versioned_docs/version-21/routing.mdx create mode 100644 versioned_docs/version-21/state-management.mdx create mode 100644 versioned_docs/version-21/testing.mdx create mode 100644 versioned_docs/version-21/ui-libraries/angular-material.mdx create mode 100644 versioned_docs/version-21/ui-libraries/index.mdx rename {docs => versioned_docs/version-21}/upgrading.mdx (84%) create mode 100644 versioned_sidebars/version-21-sidebars.json diff --git a/README.md b/README.md index 7674e45..680bb0b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ | Supported Angular versions | |-----------------------------| -| [v21](https://ngtips.com) | +| [v22](https://ngtips.com) | +| [v21](https://ngtips.com/21)| | [v20](https://ngtips.com/20)| | [v19](https://ngtips.com/19)| diff --git a/TODO.md b/TODO.md index 6d505f9..defa50d 100644 --- a/TODO.md +++ b/TODO.md @@ -73,6 +73,10 @@ - zoneless - v22 - ChangeDetectionStrategy: Default -> Eager - - Default change detection will be Eager + - Default change detection will be OnPush - @Service decorator + - stable signal forms + - stable resource signals + - remove jest and web test runner supports + - remove ngIf, ngFor and ngSwitch directives \ No newline at end of file diff --git a/VERSIONING.md b/VERSIONING.md index 3d484da..28de927 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -12,15 +12,19 @@ When a new version of Angular is released, a new version of Angular Tips is crea ## Create a new version To create a new version of Angular Tips: -1. Run: `npm run docusaurus docs:version ` +1. Run: `npm run docusaurus docs:version `. + - Make sure versions are in the correct order in [versions.json](./versions.json). 2. Replace occurences of previous version with the new version number in `docs` folder, especially: - Links to Angular doc: `https://vX.angular.dev` - Links to Angular Material doc: `https://vX.material.angular.dev` - - [Getting started > Angular Version](./docs/getting-started.md#angular-version) + - [Getting started > Angular Version](./docs/getting-started.mdx#angular-version) + - Other occurences of ``. 3. Update [docusaurus.config.ts](./docusaurus.config.ts): - Set `presets > docs > versions > current > label` to the new version number. - Add a new entry in `presets > docs > versions` for the previous version. 4. Delete `draft: true` pages in the new `versioned_docs/version-vX` folder if any. -5. Update 'Supported Angular Versions' table in [README.md](./README.md). -6. Test the new version locally and make sure it builds correctly. -7. Commit and push the changes. +5. Remove `sidebar_class_name: new` and `sidebar_class_name: updated` in `docs` folder. +6. Update 'Supported Angular Versions' table in [README.md](./README.md). +7. Update `announcementBar` in [docusaurus.config.ts](./docusaurus.config.ts) if necessary. +8. Update [What's new](./docs/upgrading/whats-new.mdx) and [Upcoming](./docs/upgrading/upcoming.mdx) pages. +9. Test the new version locally and make sure it builds correctly. diff --git a/docs/component/_category_.yml b/docs/component/_category_.yml index b7b0e02..d997133 100644 --- a/docs/component/_category_.yml +++ b/docs/component/_category_.yml @@ -1,5 +1,4 @@ label: Component position: 3 link: - type: generated-index -className: new \ No newline at end of file + type: generated-index \ No newline at end of file diff --git a/docs/component/change-detection.mdx b/docs/component/change-detection.mdx index 15b50d2..bfde8dd 100644 --- a/docs/component/change-detection.mdx +++ b/docs/component/change-detection.mdx @@ -1,6 +1,5 @@ --- sidebar_position: 4 -sidebar_class_name: new --- # Change detection @@ -42,7 +41,7 @@ See [Reactivity](../reactivity.mdx) for more details. Zoneless mode represents a major shift in Angular’s change detection strategy. Historically, Angular relied on Zone.js, a patching library that intercepted asynchronous tasks—timers, promises, events—to automatically trigger UI updates. With zoneless, this implicit mechanism is gone. Angular no longer monitors every async operation; instead, updates happen only when the framework knows something changed. -**Consider** using [Zoneless](https://v21.angular.dev/guide/zoneless). +**Consider** using [Zoneless](https://v22.angular.dev/guide/zoneless). :::info[Why?] Opting for Zoneless mode is a future-proof choice as Angular is moving towards this direction. While the performance enhancement is minimal (especially if you have already followed best practices, e.g. [`OnPush` change detection](../component/typescript-class#change-detection)), it can improve developer experience by providing clearer stack traces. Additionally, it'll help reduce bundle size and startup time. diff --git a/docs/component/styling.mdx b/docs/component/styling.mdx index f3009ad..aa620c8 100644 --- a/docs/component/styling.mdx +++ b/docs/component/styling.mdx @@ -1,6 +1,5 @@ --- sidebar_position: 3 -sidebar_class_name: updated --- # Styling This page covers best practices for styling in Angular, including structuring styles, using variables, scoping component styles, and avoiding common pitfalls. @@ -217,7 +216,7 @@ While it's not a bad thing to use a CSS framework, it shouldn't be automatic. Th ✅ **[Tailwind CSS](https://tailwindcss.com/)**: utility-first CSS framework that provides low-level utility classes to build custom designs. :::note -Since Angular v21, Tailwind CSS is natively supported and integrated with the Angular CLI, see [Angular guide](https://v21.angular.dev/guide/tailwind). +Since Angular v21, Tailwind CSS is natively supported and integrated with the Angular CLI, see [Angular guide](https://v22.angular.dev/guide/tailwind). ::: ✅ **[Bootstrap](https://getbootstrap.com/)**: CSS framework that provides a set of pre-designed components and utilities. diff --git a/docs/component/template.mdx b/docs/component/template.mdx index 1adce4c..8f973f6 100644 --- a/docs/component/template.mdx +++ b/docs/component/template.mdx @@ -178,7 +178,7 @@ It also indicates that the component does not have projectable content. ``` :::tip -You can run the [schematic migration](https://v21.angular.dev/reference/migrations/control-flow) to automatically replace directives above by control flow syntax. +You can run the [schematic migration](https://v22.angular.dev/reference/migrations/control-flow) to automatically replace directives above by control flow syntax. ::: **Do** use class binding instead of `ngClass` directive. diff --git a/docs/component/typescript-class.mdx b/docs/component/typescript-class.mdx index d13e5ec..75fb74b 100644 --- a/docs/component/typescript-class.mdx +++ b/docs/component/typescript-class.mdx @@ -75,7 +75,7 @@ export class UserPage { **Do** use `input()` signal and `output()` function instead of `@Input()` and `@Ouput()` decorators. :::tip -You can run [schematic migrations](https://v21.angular.dev/reference/migrations) to automatically transform decorators to signals. +You can run [schematic migrations](https://v22.angular.dev/reference/migrations) to automatically transform decorators to signals. ::: **Do** type inputs and outputs. diff --git a/docs/contributing.mdx b/docs/contributing.mdx index 0c1b25d..1ff8d52 100644 --- a/docs/contributing.mdx +++ b/docs/contributing.mdx @@ -33,7 +33,7 @@ To submit a pull request: When adding a new tip: - It must be Angular related. -- It must add value to the [official Angular documentation](https://v21.angular.dev/). +- It must add value to the [official Angular documentation](https://v22.angular.dev/). - It must follow the [vocabulary](./getting-started.mdx#vocabulary). - If possible, provide bad and good examples. - Bad examples must be prefixed with "❌" diff --git a/docs/dependency-injection.mdx b/docs/dependency-injection.mdx index 1322020..2cac27a 100644 --- a/docs/dependency-injection.mdx +++ b/docs/dependency-injection.mdx @@ -114,5 +114,5 @@ export function injectBody(): HTMLElement { - ❌ Lifecycle hook :::info[Why?] -Calling `inject()` or `assertInInjectionContext()` outside an injection context throws [error NG0203](https://v21.angular.dev/errors/NG0203). Make sure to call these functions only during construction or initialization phases. +Calling `inject()` or `assertInInjectionContext()` outside an injection context throws [error NG0203](https://v22.angular.dev/errors/NG0203). Make sure to call these functions only during construction or initialization phases. ::: diff --git a/docs/form.mdx b/docs/form.mdx index 7cf131c..cb17a26 100644 --- a/docs/form.mdx +++ b/docs/form.mdx @@ -4,15 +4,19 @@ sidebar_class_name: updated --- # Form -Forms are a fundamental part of most web applications, enabling users to input data, submit information, and interact with your application. Angular provides two primary approaches to handling forms, each with robust solutions for validation, data binding, and state management, designed to address different use cases and levels of complexity. +:::warning +Angular v22 introduced Signal forms, this page will be updated to reflect this new form solution and its differences with reactive and template-driven forms. +::: + +Forms are a fundamental part of most web applications, enabling users to input data, submit information, and interact with your application. +Angular provides multiple approaches to handling forms, each with robust solutions for validation, data binding, and state management, designed to address different use cases and levels of complexity. + +[Signal forms](#signal-forms) is the latest option based on Angular's signals. [Template-Driven form](#template-driven-forms) is the simplest approach that relies on directives in the template, suitable for simple forms with minimal complexity. -[Reactive form](#reactive-forms) is a more structured and flexible solution, but verbose, it is ideal for complex forms with programmatic control. +[Reactive form](#reactive-forms) is a more structured and flexible solution, but verbose, ideal for complex forms with programmatic control. -:::warning -Both approaches are expected to be superseded by [Signal Forms](#signal-forms) in future Angular versions, which will leverage Angular's signal-based reactivity system for improved performance and developer experience. -::: ## General guidelines @@ -39,11 +43,16 @@ Both approaches are expected to be superseded by [Signal Forms](#signal-forms) i ## Signal forms -**Consider** not using signal forms, yet. +**Consider** using signal forms. +- ✅ Signal forms +- ❌ Reactive forms +- ❌ Template-driven forms :::info[Why?] -Signal forms are experimental features in Angular v21 and are not recommended for production use as they may change in future releases. -Use [Reactive forms](#reactive-forms) or [Template-driven forms](#template-driven-forms) instead. +Signal forms is the new form solution leveraging Angular's signal-based reactivity system. It provides improved performance, developer experience and new features compared to other solutions. +It was introduced to replace both reactive and template-driven forms. + +For compatibility reasons, using reactive and template-driven forms in existing code is fine, but prefer signal forms for new code. ::: ## Template-driven forms diff --git a/docs/general/code-style.mdx b/docs/general/code-style.mdx index f4915b2..0a5798c 100644 --- a/docs/general/code-style.mdx +++ b/docs/general/code-style.mdx @@ -6,7 +6,7 @@ sidebar_position: 1 This page covers best practices and common mistakes when writing TypeScript code, focusing on those with the highest impact. It includes naming conventions, code clarity, consistency and more. -The following guidelines are a complement to the [Angular official coding style guide](https://v21.angular.dev/style-guide) that we recommend to read first. +The following guidelines are a complement to the [Angular official coding style guide](https://v22.angular.dev/style-guide) that we recommend to read first. ## General guidelines @@ -57,7 +57,7 @@ The following guidelines are a complement to the [Angular official coding style :::warning[Exceptions] Avoid using `#` if you're targeting browsers that don't natively support them, as the downleveling can impact performance and bundle size. -You're not concerned if you use [Angular's default browserlist](https://v21.angular.dev/reference/versions#browser-support). +You're not concerned if you use [Angular's default browserlist](https://v22.angular.dev/reference/versions#browser-support). ::: **Do** use plural form in names for iterables (array, set, ...). diff --git a/docs/general/configuration.mdx b/docs/general/configuration.mdx index 16c4fbb..a01a350 100644 --- a/docs/general/configuration.mdx +++ b/docs/general/configuration.mdx @@ -15,7 +15,7 @@ Standalone components are self-contained which is much easier to manage, and rem ::: :::tip -You can run the [schematic migration](https://v21.angular.dev/reference/migrations/standalone) to automatically convert your project to standalone. +You can run the [schematic migration](https://v22.angular.dev/reference/migrations/standalone) to automatically convert your project to standalone. ::: ## Git @@ -106,7 +106,7 @@ Committing run configurations ensures that all team members have access to the s For example, running `npm run build` will first run the `prebuild` script, then `build`, and finally `postbuild`. ::: -**Do** use the [`application` builder](https://v21.angular.dev/tools/cli/build-system-migration). +**Do** use the [`application` builder](https://v22.angular.dev/tools/cli/build-system-migration). ```json title="✅ angular.json" { "projects": { diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index a046b36..e22aae6 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -20,12 +20,12 @@ This guide will give you thoughtful opinions on Angular's features, you may not ## Angular version -This documentation assumes that you are using the latest minor version of **Angular v21**. +This documentation assumes that you are using the latest minor version of **Angular v22**. :::note Angular Tips follows the same major versioning as Angular itself, starting with v19. -If you're using an older version of Angular, we recommend you read Angular Tips v19. While many of the recommendations remain relevant, some may not be applicable to your specific version. Refer to the official [changelog](https://github.com/angular/angular/releases), [update guide](https://v21.angular.dev/update-guide) and [API reference](https://v21.angular.dev/api) to identify unstable and missing features. +If you're using an older version of Angular, we recommend you read Angular Tips v19. While many of the recommendations remain relevant, some may not be applicable to your specific version. Refer to the official [changelog](https://github.com/angular/angular/releases), [update guide](https://v22.angular.dev/update-guide) and [API reference](https://v22.angular.dev/api) to identify unstable and missing features. ::: ## Vocabulary diff --git a/docs/i18n.mdx b/docs/i18n.mdx index dd547a7..74c9c88 100644 --- a/docs/i18n.mdx +++ b/docs/i18n.mdx @@ -47,7 +47,7 @@ Angular will use `LOCALE_ID` by default for everything related to internationali **Consider** using one of the following: -✅ **[Angular built-in i18n](https://v21.angular.dev/guide/i18n)**: compile-time internationalization library that is part of Angular. +✅ **[Angular built-in i18n](https://v22.angular.dev/guide/i18n)**: compile-time internationalization library that is part of Angular. - ❌ Does not support runtime language switching (needs window refresh) diff --git a/docs/performance.mdx b/docs/performance.mdx index b2926e2..a5e150f 100644 --- a/docs/performance.mdx +++ b/docs/performance.mdx @@ -1,6 +1,5 @@ --- sidebar_position: 13 -sidebar_class_name: new --- # Performance @@ -106,7 +105,7 @@ Do not overuse lazy loading at route level. In particular, avoid having nested l `@loading` block is displayed while the deferred content is being loaded. - More about deferred loading in the [Angular documentation](https://v21.angular.dev/guide/templates/defer). + More about deferred loading in the [Angular documentation](https://v22.angular.dev/guide/templates/defer). ```html title="✅ defer" @@ -134,7 +133,7 @@ This can be useful for components that are not immediately visible and non essen Incremental hydration occurs on the initial page load only, it does not apply to subsequent navigations which are handled on the client-side. - More about incremental hydration in the [Angular documentation](https://v21.angular.dev/guide/incremental-hydration). + More about incremental hydration in the [Angular documentation](https://v22.angular.dev/guide/incremental-hydration). ```html title="✅ incremental hydration" @@ -240,7 +239,7 @@ If your application does not have strict SEO requirements (e.g. a private app no Event replay is the process of capturing and replaying user interactions that occur before the Angular application is fully bootstrapped on the client. This ensures that any user actions, such as clicks or form inputs, are not lost during the hydration process, between the time the server-rendered HTML is displayed and the time the Angular application becomes interactive. - More about hydration and event replay in the [Angular documentation](https://v21.angular.dev/guide/hydration). + More about hydration and event replay in the [Angular documentation](https://v22.angular.dev/guide/hydration). ```ts title="✅ app.config.ts" diff --git a/docs/reactivity.mdx b/docs/reactivity.mdx index ec8686d..2a5655e 100644 --- a/docs/reactivity.mdx +++ b/docs/reactivity.mdx @@ -1,5 +1,6 @@ --- sidebar_position: 6 +sidebar_class_name: updated --- # Reactivity @@ -76,7 +77,7 @@ nbDevelopersInTeam = computed(() => this.teamDevelopers().length); ### Writable and derived state -**Do** use [`linkedSignal()`](https://v21.angular.dev/guide/signals/linked-signal) for writable state that depends on another signal. +**Do** use [`linkedSignal()`](https://v22.angular.dev/guide/signals/linked-signal) for writable state that depends on another signal. ```ts title="✅ Selecting an item from a reactive array" // Reactive array of users (could also be a computed(), input() or other). @@ -133,15 +134,10 @@ constructor() { ### Fetching data -**Consider** not using `resource()`, `rxResource()` or `httpResource()` signals, yet. - -:::info[Why?] -`resource()`, `rxResource()` and `httpResource()` are experimental features in Angular v21 and are not recommended for production use as they may change in future releases. -::: - -:::warning[Exceptions] -Since these new tools will most likely become the future of Angular, and that they are an important missing piece, you can make an exception here and use them now. But be careful though, there's a high risk that the API may change as it's not stable yet. -::: +**Consider** using resource signals to fetch data. +- ✅ `resource()` +- ✅ `httpResource()` +- ✅ `rxResource()` ## RxJs @@ -151,6 +147,10 @@ Since these new tools will most likely become the future of Angular, and that th - ✅ Complex event handling (e.g. debounce, throttle, etc.) - ... +:::info[Why?] +Resource signals are reactive and integrate seamlessly with signals. They provide additional features compared to RxJS, such as automatic refetching, loading and error state management and manual reload. +::: + **Consider** using [signals](#signals) instead of RxJs `BehaviorSubject`. ### Interoperability with signals diff --git a/docs/testing.mdx b/docs/testing.mdx index 94cff76..00fbc70 100644 --- a/docs/testing.mdx +++ b/docs/testing.mdx @@ -1,6 +1,5 @@ --- sidebar_position: 10 -sidebar_class_name: updated --- # Testing diff --git a/docs/ui-libraries/angular-material.mdx b/docs/ui-libraries/angular-material.mdx index 40925fe..113e87e 100644 --- a/docs/ui-libraries/angular-material.mdx +++ b/docs/ui-libraries/angular-material.mdx @@ -38,7 +38,7 @@ CSS classes, HTML structure and private CSS variables are Material's internal im } ``` -**Do** override CSS [system variables](https://v21.material.angular.dev/guide/system-variables). +**Do** override CSS [system variables](https://v22.material.angular.dev/guide/system-variables). ```css title="✅ System variables" @include mat.theme-overrides(( primary-container: green @@ -51,7 +51,7 @@ Angular Material provides public and stable APIs to customize the look of compon ## Custom components -**Consider** using [Angular CDK](https://v21.material.angular.dev/cdk). +**Consider** using [Angular CDK](https://v22.material.angular.dev/cdk). - ❌ Work around the limitations of Angular Material's components - ✅ Build custom components with CDK utilities diff --git a/docs/ui-libraries/index.mdx b/docs/ui-libraries/index.mdx index 3ca8e55..c7d6a49 100644 --- a/docs/ui-libraries/index.mdx +++ b/docs/ui-libraries/index.mdx @@ -19,7 +19,7 @@ Headless UI libraries are not so popular and advanced in the Angular ecosystem c **Consider** using one of the following: -✅ **[Angular Material](https://v21.material.angular.dev/)**: the official Angular component library that implements Material Design. It provides essential UI components and is well-maintained by the Angular team. +✅ **[Angular Material](https://v22.material.angular.dev/)**: the official Angular component library that implements Material Design. It provides essential UI components and is well-maintained by the Angular team. - ✅ High quality components - ✅ Always up to date with Angular releases @@ -55,7 +55,7 @@ Other popular libraries that have not yet been evaluated: **Consider** using the following: -✅ **[Angular CDK](https://v21.material.angular.dev/cdk)**: a set of low-level and unstyled primitives for building UI components. +✅ **[Angular CDK](https://v22.material.angular.dev/cdk)**: a set of low-level and unstyled primitives for building UI components. - ✅ High quality primitives - ✅ Well-maintained by the Angular team diff --git a/docs/upgrading/index.mdx b/docs/upgrading/index.mdx new file mode 100644 index 0000000..1a8b9a9 --- /dev/null +++ b/docs/upgrading/index.mdx @@ -0,0 +1,33 @@ +--- +title: Upgrading +sidebar_position: 15 +sidebar_class_name: new +--- +# Upgrading Angular + +**Consider** keeping up to date with the latest Angular release. + +:::info[Why?] +Staying up to date with Angular versions enhances maintainability and security while providing access to the latest features and performance improvements. Regular upgrades are easier to manage than to upgrade several versions at once. + +Angular limits breaking changes, new features are always opt-in and obsolete features are deprecated for several major versions before being removed. +Angular releases a major version every six months, you can anticipate and plan for upcoming version upgrades. Third party libraries are often the most painful to upgrade, not Angular itself. +::: + +**Consider** using Long-Term Support (LTS) versions. + +:::note +Angular provides Long-Term Support (LTS) for each major release for 18 months, see [Angular support policy and schedule](https://v22.angular.dev/reference/releases#support-policy-and-schedule). +::: + +**Do** upgrade one major version at a time. +- ❌ From v18 to v20 +- ✅ From v18 to v19, then from v19 to v20 + +**Do** verify your dependencies compatibility with the target Angular version. + +**Do** use [migrations schematics](https://v22.angular.dev/reference/migrations) to automate the upgrade process. + +**Do** use the [Angular Update Guide](https://v22.angular.dev/update-guide). + +**Consider** reading the [changelogs](https://github.com/angular/angular/releases). diff --git a/docs/upgrading/upcoming.mdx b/docs/upgrading/upcoming.mdx new file mode 100644 index 0000000..c03f448 --- /dev/null +++ b/docs/upgrading/upcoming.mdx @@ -0,0 +1,35 @@ +--- +title: Upcoming +sidebar_position: 2 +sidebar_class_name: updated +--- +# Upcoming in Angular + +This section provides an overview of upcoming features, improvements, and deprecations that developers can expect in future versions of Angular. + +### In preview or experimental stage + +The most impactful experimental and developer preview features that will soon be stable: + +- [Angular Aria](https://v22.angular.dev/guide/aria): a headless library for building accessible components in Angular. + +For more details, refer to the complete list of [unstable APIs](https://v22.angular.dev/api?status=6). + +### Under development or consideration + +The most impactful features planned for future versions of Angular: + +- **Signal integration**: deeper integration of signals into Angular's core features (e.g. Router or HTTP). +- **Selectorless**: using components and directives with their names instead of selectors. +- **AI integration**: leveraging AI to enhance developer experience and productivity. + +For more details, refer to the [Angular roadmap](https://v22.angular.dev/roadmap). + +### Deprecations + +The most impactful features currently deprecated that will be removed in future versions of Angular: + +- **`@angular/animations` package**: set to be removed in v23. +- **Karma and Jasmine support**: unknown removal date. + +For more details, refer to the complete list of [deprecated APIs](https://v22.angular.dev/api?status=8). \ No newline at end of file diff --git a/docs/upgrading/whats-new.mdx b/docs/upgrading/whats-new.mdx new file mode 100644 index 0000000..470959e --- /dev/null +++ b/docs/upgrading/whats-new.mdx @@ -0,0 +1,74 @@ +--- +title: What's new? +sidebar_position: 1 +sidebar_class_name: new +--- +# What's new in Angular? +Below are the **most impactful changes** in Angular major versions. + +For a complete list of changes, refer to the [changelog](https://github.com/angular/angular/releases) and [Angular blog](https://blog.angular.dev). + +## v22 +- Signal forms are now stable. +- Resource signals are now stable. +- `@Service` decorator is introduced. +- Change detection strategy `Default` is renamed to `Eager`. +- Default change detection strategy is now `OnPush`. +- Jest and Web Test Runner supports are removed. +- `ngIf`, `ngFor` and `ngSwitch` directives are removed. + + +## v21 +- Vitest support is now stable and becomes the default test runner for new applications, replacing Karma. +- Zoneless change detection is now the default for new applications. +- Angular Aria is introduced in developer preview. +- Signal forms are introduced as experimental. + +## v20 +- Zoneless change detection is now stable. +- `effect`, `linkedSignal`, `toSignal` and `toObservable` are now stable. +- Route-level render mode is now stable. +- Incremental hydration is now stable. +- Angular MCP server is introduced. +- Vitest support is introduced as experimental. + +## v19 +- `resource`, `httpResource` and `rxResource` are introduced as experimental. +- `linkedSignal` is introduced as experimental. +- `input`, `output` and `model` are now stable. +- `viewChild` and `viewChildren` signal queries are now stable. +- `@let` is now stable. +- Event replay is now stable and enabled by default. +- Standalone components is now the default. + +## v18 +- `@if`, `@for` and `@switch` control flow are now stable. +- `@defer` deferrable views are now stable. +- `@let` is introduced as developer preview. +- Zoneless change detection is introduced as experimental. +- Event replay is introduced as developer preview. + +## v17 +- `signal` and `computed` signals are now stable. +- `@if`, `@for` and `@switch` control flow are introduced as developer preview. +- `input`, `output` and `model` are introduced as developer preview. +- `viewChild` and `viewChildren` signal queries are introduced as developer preview. +- `@defer` deferrable views are introduced as developer preview. +- Vite application builder is now stable and enabled by default for new applications. +- Hydration is now stable and enabled by default for new applications using SSR. + +## v16 +- Signals are introduced as developer preview. +- `toSignal` and `toObservable` are introduced as developer preview. +- Vite application builder is introduced as developer preview. +- Hydration is introduced as developer preview. + +## v15 +- Standalone components are now stable. +- Functional guards, resolvers and interceptors are now stable. + +## v14 +- Typed reactive forms are introduced. +- Standalone components are introduced as experimental. + +For older versions, refer to the [changelog](https://github.com/angular/angular/releases). \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index a8513ae..94af098 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -60,7 +60,10 @@ const config: Config = { lastVersion: 'current', versions: { current: { - label: '21', + label: '22', + }, + '21': { + banner: 'none', }, '20': { banner: 'none', @@ -172,8 +175,8 @@ const config: Config = { additionalLanguages: ['scss', 'ignore'] }, announcementBar: { - id: 'v21-released', - content: `🎉 Angular Tips now supports Angular v21! Consider starring it on GitHub ⭐`, + id: 'v22-released', + content: `🎉 Angular Tips v22 is here! Show your support by starring it on GitHub ⭐`, }, } satisfies Preset.ThemeConfig, }; diff --git a/versioned_docs/version-21/component/_category_.yml b/versioned_docs/version-21/component/_category_.yml new file mode 100644 index 0000000..b7b0e02 --- /dev/null +++ b/versioned_docs/version-21/component/_category_.yml @@ -0,0 +1,5 @@ +label: Component +position: 3 +link: + type: generated-index +className: new \ No newline at end of file diff --git a/versioned_docs/version-21/component/change-detection.mdx b/versioned_docs/version-21/component/change-detection.mdx new file mode 100644 index 0000000..a3c1517 --- /dev/null +++ b/versioned_docs/version-21/component/change-detection.mdx @@ -0,0 +1,64 @@ +--- +sidebar_position: 4 +sidebar_class_name: new +--- +# Change detection + +Change detection is a core concept in Angular that ensures the UI stays in sync with the application state. This guide explores best practices for managing change detection effectively, including strategies for optimizing performance and leveraging Angular's built-in mechanisms. + +## General guidelines + +**Consider** using `ChangeDetectionStrategy.OnPush` for every components. +- ❌ unspecified change detection strategy +- ❌ `changeDetection: ChangeDetectionStrategy.Default` +- ✅ `changeDetection: ChangeDetectionStrategy.OnPush` + +:::info[Why?] +The main reason is sustainability. Angular is heading towards better reactivity with signals and Zoneless application, and using `OnPush` now will make migration to future major releases easier. + +In addition, `OnPush` strategy improves performances by reducing the number of change detection cycles, which is particularly interesting for large projects. +::: + +:::tip +You can set the default change detection strategy to `OnPush` in your `angular.json` file for components generated with Angular CLI. +::: + +**Do** rely on reactive primitives to trigger change detection. + +- ✅ [Signals](../reactivity#signals) - reading a signal in a template registers it for updates, and calling `set()` or `update()` marks the view dirty. +- ✅ [Async Pipe](../reactivity#managing-subscriptions) - it subscribes to an Observable and triggers view checks on each emission. +- ✅ Event handlers, e.g. `(click)` or `(keydown)`. +- ✅ Input property changes from parent to child components. +- ❌ Timers, e.g. `setTimeout()` or `setInterval()`. +- ❌ HTTP requests + +:::tip +As a last resort, you can use `markForCheck()` method from `ChangeDetectorRef` to manually trigger change detection. +::: + +See [Reactivity](../reactivity.mdx) for more details. + +## Zoneless + +Zoneless mode represents a major shift in Angular’s change detection strategy. Historically, Angular relied on Zone.js, a patching library that intercepted asynchronous tasks—timers, promises, events—to automatically trigger UI updates. With zoneless, this implicit mechanism is gone. Angular no longer monitors every async operation; instead, updates happen only when the framework knows something changed. + +**Consider** using [Zoneless](https://v22.angular.dev/guide/zoneless). + +:::info[Why?] +Opting for Zoneless mode is a future-proof choice as Angular is moving towards this direction. While the performance enhancement is minimal (especially if you have already followed best practices, e.g. [`OnPush` change detection](../component/typescript-class#change-detection)), it can improve developer experience by providing clearer stack traces. Additionally, it'll help reduce bundle size and startup time. +::: + +:::tip +To migrate existing code to Zoneless mode, check for legacy code using `NgZone` or relying on implicit change detection after timers, HTTP calls, or event handlers. The most encountered problem is a piece of UI that does not reflect a state change until you interact with it. If state changes but the DOM stays stale, you can use debugging tools or logs to confirmand reactive patterns mentioned above to fix it. +::: + +:::warning[Exceptions] +When using third-party libraries that depend on `zone.js`, you may need to keep zone-based change detection enabled. Some libraries or tools might not function correctly without it, so evaluate compatibility before switching to Zoneless mode. +::: + +### Testing + +**Do** provide zoneless change detection in tests. +- ✅ `provideZonelessChangeDetection()` in `TestBed.configureTestingModule()` +- ❌ `fixture.detectChanges()` + diff --git a/versioned_docs/version-21/component/styling.mdx b/versioned_docs/version-21/component/styling.mdx new file mode 100644 index 0000000..07d3b7f --- /dev/null +++ b/versioned_docs/version-21/component/styling.mdx @@ -0,0 +1,225 @@ +--- +sidebar_position: 3 +sidebar_class_name: updated +--- +# Styling +This page covers best practices for styling in Angular, including structuring styles, using variables, scoping component styles, and avoiding common pitfalls. + +## General guidelines + +**Avoid** repeating CSS styles. + +:::info[Why?] +If you do, it usually means that you need to make a component out of it. +::: + +**Do** use SASS (.scss). + +**Avoid** inline styles. +```html title="❌ user-page.html" +
...
+``` + +```scss title="✅ user-page.scss" +div { + margin-top: 20px; +} +``` + +**Do** use kebab-case for class and id names. +- ❌ `class="selectedItem"` +- ✅ `class="selected-item"` +- ❌ `id="add_button"` +- ✅ `id="add-button"` + +## Variables + +**Do** use variables for theme related values. + +### SASS variables + +**Do** use SASS variables for static values. +```scss +$color-danger: #FF0000; + +p { + color: $color-danger; +} +``` + +**Do** add extra base path to import global SASS variables. + +```scss title="❌ user-page.scss" +@use '../../../../../theme'; +h1 { + color: theme.$primary; +} +``` + +```json title="✅ angular.json" +{ + "projects": { + "my-app": { + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "stylePreprocessorOptions": { + // highlight-start + "includePaths": ["src"] + // highlight-end + } + } + } + } + } + } +} +``` + +```scss title="✅ user-page.scss" +@use 'theme'; +h1 { + color: theme.$primary; +} +``` + +### CSS variables + +**Do** use CSS variables for dynamic values that can change at runtime. +```scss +:root { + --app-font-size: 16px; +} + +p { + font-size: var(--app-font-size); +} + +.big-text-area { + --app-font-size: 24px; +} +``` + +## Component styles + +**Do** keep default style scoping. +- ❌ `encapsulation: ViewEncapsulation.None` +- ✅ `encapsulation: ViewEncapsulation.Emulated` + +**Consider** using component style instead of global styles. + +```scss title="❌ styles.scss" +.selected p > span { + color: $primary; +} +``` + +```scss title="✅ user-card.scss" +.selected p > span { + color: $primary; +} +``` + +:::info[Why?] +Global styles often leads to unintended side effects. The larger the project, the more difficult it will be to modify these global styles, +forcing you to override them in several places. +::: + +**Do** use `:host` to apply styles to the component root element. +```scss title="✅ user-page.scss" +:host { + display: flex; +} +``` + +**Consider** defining component's CSS variables within the `:host` selector. + +**Do** prefix component's CSS variable names with the component name. + +```scss title="✅ user-page.scss" +:host { + --user-title-color: theme.$primary; +} +``` + +**Do** use style binding instead of `ngStyle` directive. +- ❌ `[ngStyle]="{ 'width': '200px' }"` +- ✅ `[style]="{ 'width': '200px' }"` +- ✅ `[style.width.px]="200"` + +## Global styles + +**Do** split global styles in partial SCSS files. +- `styles.scss` as the entrypoint. +- `_default.scss` for overriding default browsers styles. +- `_typography.scss` for fonts and headings. +- `_form.scss` for form fields. +- ... + +**Consider** defining global CSS variables within the `:root` selector. + +**Do** prefix global CSS variable names by `app-`. + +```scss title="✅ user-page.scss" +:root { + --app-text-color: #131218; +} +``` + + +## Overriding styles + +**Consider** CSS variables or component inputs to override your components styles. + +**Avoid** using `::ng-deep`. + +```scss title="❌ user-page.ts" +:host ::ng-deep .mat-mdc-chip-action > .mdc-evolution-chip__graphic { + padding: 0; +} +``` + +:::info[Why?] +If you are trying to override your own component, use CSS variables or inputs instead. + +If you are trying to override an external component, you'll need to rely on private implementation details that may change at any time (without being mentioned in a changelog). +So there's a good chance you app will break after a dependency update, which will result in either a painful migration and bugs, or no update at all. + +External libraries often provide theming features to customise their components, try to use them. Use `::ng-deep` only as a last resort. +::: + +**Avoid** using `!important`. + +:::info[Why?] +It usually means that you are trying to override either global styles or private implementation details. +Try another technique mentioned above or use a more specific selector instead. +::: + +## Responsive design + +**Do** use `MediaMatcher` to listen for window width changes. +```ts title="✅ Checking screen width" +this.mobileQuery = this.media.matchMedia('(max-width: 900px)'); +const isMobile = this.mobileQuery.matches; +``` + +## Libraries + +**Consider** not using a CSS framework. + +:::info[Why?] +While it's not a bad thing to use a CSS framework, it shouldn't be automatic. These frameworks are more complex than regular CSS and can harm your code readability and maintanability. Choose knowingly before integrating it deeply into your project. +::: + +**Consider** using one the following: + +✅ **[Tailwind CSS](https://tailwindcss.com/)**: utility-first CSS framework that provides low-level utility classes to build custom designs. + +:::note +Since Angular v21, Tailwind CSS is natively supported and integrated with the Angular CLI, see [Angular guide](https://v22.angular.dev/guide/tailwind). +::: + +✅ **[Bootstrap](https://getbootstrap.com/)**: CSS framework that provides a set of pre-designed components and utilities. + +❌ **[PrimeFlex](https://primeflex.org/)**: project has stopped and no longer receive development or maintenance. diff --git a/versioned_docs/version-21/component/template.mdx b/versioned_docs/version-21/component/template.mdx new file mode 100644 index 0000000..8f973f6 --- /dev/null +++ b/versioned_docs/version-21/component/template.mdx @@ -0,0 +1,241 @@ +--- +sidebar_position: 2 +--- +# Template + +This page outlines best practices for Angular component's templates, focusing on organization, readability, accessibilty and performance. By following these guidelines, you'll ensure your templates are maintainable, readable, and aligned with Angular's recommended patterns. + +## General guidelines + +**Do** use as few tags as possible. + +**Consider** using meaningful semantic HTML elements instead of non-semantic ones. + +```html title="❌ app.html" +
+
Welcome to my Website
+
+
+
+
Some important text
+
More details here in this description.
+
+
+ +``` + +```html title="✅ app.html" +
+

Welcome to my Website

+
+
+
+

Some important text

+

More details here in this description.

+
+
+
...
+``` + +:::tip +Use `
` or `` as last resort if no more suitable element exists, a few examples: +- `