At Halodoc, we're always looking for innovative ways to solve patient problems and adopt the necessary technologies for the same. As we all know, in the ever-changing digital world, user interface (UI) design plays an important role in the development of web applications. A well-designed and user-friendly UI can significantly enhance user experience and boost user engagement. Material Design Components (MDC) is a contemporary CSS framework that focuses on high performance and scalability. The MDC based components in Angular Material 15 are up-to-date, while the legacy components are deprecated.
In this blog, we will talk about the MDC framework, its benefits, our migration approach and our observations during the migration.
What is MDC:
MDC are a set of reliable, reusable, and user-friendly web components that adhere to the Material Design specification. MDC components are based on Web Components, which means that they are platform-agnostic and can be used in any web framework, including Angular. The modularity and composability of MDC components surpasses that of traditional Angular Material components. The Angular Material UI component library is based on MDC to provide a unified set of components implemented in accordance with Google's Material Design principles.
There are several advantages to the refactored components over the legacy implementations such as:
- Improving accessibility
- Easier maintenance
- Smaller bundle size
- Faster load times
Why MDC migration:
Halodoc is currently using Angular v15 with legacy material components, in this angular version, the new components such as button, dialog & form field have different internal DOM structure and CSS styles. In view of a new DOM and CSS, we have noticed that some styles in our application need to be modified, especially if our CSS overrides the style on internal elements for any moved components.
We also attempt to integrate both existing and new components within the same Angular application, but there are a number of challenges that arise, such as:
- Inconsistent styling: Legacy material components may use a different design system than new material components. This can lead to inconsistencies in the look and feel of the application.
- Versioning conflicts: It can be difficult to manage different versions of the material library in the same application. This can lead to compatibility issues and unexpected behavior.
- Upgrade paths: It can be difficult to upgrade from legacy material components to new material components. This is because the APIs and behavior of the components may have changed.
It is also important to note that in Angular 17, the legacy material components are going to be removed and we will not be able to update our Angular version. Hence, we decided to prioritise the MDC migration for our angular based web application.
How to migrate:
The process of migrating to MDC in Angular v15 is relatively straightforward. Here are the steps involved:
Update to Angular Material v15:
Angular Material includes a schematic to help migrate applications to use the new MDC-based components. First we upgraded our application to Angular Material 15 with the help of below command:
As part of this update, a schematic will run to automatically move our application to use the legacy imports containing the old component implementations. This is a quick way to run our application on v15 with minimal changes
Run the migration tool:
After upgrading to v15, we have to run the migration tool to switch from the
legacy component implementations to the new MDC-based ones with the help
of below command:
The above command automatically updates the typescript, styles and template of the new implementation. This command offers a partial migration of new implementation in the application.
Check for TODOs left by the migration tool:
In cases, where the migration tool is not able to automatically update our code, it will attempt to add comments for a human to follow up. These TODO
comments follow a common format, so they can be easily identified.
Verify Your Application:
After running the migration command and addressing the TODOs, we can perform a quick check to make sure the application is running as expected.
Comprehensive List of Changes:
This involved a significant transformation of our design and underlying codebase. Here's a summary of the high-level categories of changes we made:
- Updated component sizes, spacing and layouts to align with the latest Material Design guidelines.
- Refined the color palette to enhance accessibility and provide a more consistent visual experience.
DOM Structure Changes:
- Optimized the DOM structure of components for improved accessibility.
- Updated component markup to reflect their semantic meaning.
Internal Component Changes:
- Library-wide Changes:
1. All of the components are slightly different across the board, their dimensions, color, orientation, shadows and animations. These changes generally improve the standard compliance and accessibility.
2. Now all the components have CSS style prefix is
For example, the button host class is
3. The styles associated with the
mat-typographyclass are no longer generated automatically. We have to include them using the
For Example: Button DOM structure
1. Default typography levels defined by
mat.define-typography-confighave been updated to reflect changes to the Material Design specification.
2. There's a themeable density to all the components but the default density level(0) will be inserted as normal.
If we prefer a different default density level, we have to set it in our theme config:
- Form Field:
1. The legacy and standard form-field appearance settings no longer exist, as these have been dropped from the Material Design spec.
2. The removed legacy appearance promoted
input placeholdersto the floating label if the label was not specified. All newer appearance settings require explicitly specifying a
<mat-label>if this was not provided before. This change addresses an accessibility best practice of not using labels and placeholders interchangeably.
3. By default, MatFormField still reserves exactly one line of space below the field for hint or error text. However, there is a new option
@Input() subscriptSizing: 'fixed'|'dynamic'. When this setting is set to
fixed (default), the form-field reserves enough space in the layout to show one line of hint or error text. When set to
dynamic, the form-field expands and contracts the amount of space it takes in the layout to fit the error / hint that is currently shown.
4. While the previous form-field had a single directive for prefixes i.e.
matPrefix and a single directive for suffixes i.e.
matSuffix, the MDC-based form-field distinguishes between text prefix/suffixes which are baseline aligned with the input text, and icon prefix/suffixes which are center aligned in the form-field. Use
matTextSuffix to indicate a text prefix/suffix, and
matIconSuffix to indicate an icon prefix/suffix. The old
matPrefix APIs will behave like icons, though they are now deprecated.
Common issues during migration:
We are using form fields in several places in our application and one of the common problems we have encountered is that the input field has background color i.e.
The above issue is occurring because the DOM structure of MDC components is different from the DOM structure of Angular Material components. Therefore, some CSS classes that we used to style our form field in Angular Material might not be compatible with our MDC components.
For example, the
mat-form-field class in Angular Material has been replaced with the
mdc-form-field class in MDC.
The MDC component theme is different from the Angular Material component theme. As a result, the form fields' color and style appear different when migrating to the MDC version. To address this issue, we have modified the below styles of the new MDC components in a global file, i.e.
third-party-overide.scss to resolve the above issue across all places in our application.
During migration, we found the common issue related to tab i.e. tab content overlapping or not being displayed at all.
MDC tabs uses Shadow DOM to encapsulate and isolate their components. This means that we will not be able to directly access the DOM elements of MDC tabs from outside of the component.
Apart from DOM structure, there are specific changes to the new MDC tabs over legacy tabs i.e.
- The new MDC tabs use a flexbox layout, while the legacy tabs used a table layout.
- The new MDC tabs have a new ripple effect when they are clicked.
- The new MDC tabs can be used to create scrollable tabs, which was not possible with the legacy tabs.
Due to above reasons we are facing the content overlapping in tabs and to resolve the above issue we have modified below styles in respective files.
Migrating our web application to Angular MDC has significantly improved our visual quality and user experience, as well as its cross-platform compatibility. MDC is a new set of component implementations that are built on top of modern web standards and offer a number of advantages over the previous Angular Material components such as performance, bundle size and so on. This migration allowed developers to construct user interfaces in a more extensible and modular manner. It also helped us acquire a lot of knowledge about MDC framework and improve our code base. We also discovered and fixed many errors in our code base such as console errors, extra function call and so on.
If you are a web developer who is currently working on angular framework (v15 or above), you will benefit from exploring and implementing MDC framework in your code base in order to improve your web page performance for your end-users.
- Angular documentation: https://material.angular.io/guide/mdc-migration
If you would like to learn more about topics related to Angular, here are some of the Halodoc blog posts:
Scalability, reliability, and maintainability are the three pillars that govern what we build at Halodoc Tech. We are actively looking for engineers at all levels and if solving hard problems with challenging requirements is your forte, please reach out to us with your resumé at firstname.lastname@example.org
Halodoc is the number 1 all around Healthcare application in Indonesia. Our mission is to simplify and bring quality healthcare across Indonesia, from Sabang to Merauke. We connect 20,000+ doctors with patients in need through our Tele-consultation service. We partner with 3500+ pharmacies in 100+ cities to bring medicine to your doorstep. We've also partnered with Indonesia's largest lab provider to provide lab home services, and to top it off we have recently launched a premium appointment service that partners with 500+ hospitals that allow patients to book a doctor appointment inside our application. We are extremely fortunate to be trusted by our investors, such as the Bill & Melinda Gates Foundation, Singtel, UOB Ventures, Allianz, GoJek, Astra, Temasek, and many more. We recently closed our Series D round and in total have raised around USD$100+ million for our mission. Our team works tirelessly to make sure that we create the best healthcare solution personalised for all of our patient's needs, and are continuously on a path to simplify healthcare for Indonesia..