How to build standalone webcomponent with VMware Clarity?

68 views Asked by At

I'm trying to build a standalone webcomponent using Angular and VMware Clarity Design System. And I have a lots of trouble.

The component is a simple menu, using cds-icons, and clr-dropdown / clr-dropdown-menu. This angular component works well in an Angular application, but I also want to use it in a legacy application that is not in Angular, and is not using Clarity Design. So, I need to build my component into a webcomponent fully standalone.

To achieve this, I use Angular Elements, but the web component embed all Clarity CSS. And it's not isolated, so my legacy application has modification from CSS of the web component. I tried to use ViewEncapsulation.ShadowDom, but it also fails.

To reproduce the steps here is a github repository contianing everything (The readme.md explain how to run http-server to test 3 use cases built from the project) : https://github.com/Rebolon/angular-clarity-webcomponent-for-stackoverflow-and-vmware-github

use case 1 :

  • no clarity css in angular.json
  • full clarity css imported in alertComponent result : Web component rendered in html, but without any style => crappy, and even if the main.js is heavy because of css (it took all clr-ui css) it doesn't work

use case 2 :

  • clarity css included in angular.json of demo project
  • no css in web component result : component is well loaded, but window has all clarity css loaded and it can not be used in legacy app. Moreover, all Clarity css is loaded whereas i only need clr-alert parts

use case 3 :

  • i use ViewEncapsulation.ShadowDom and load css only in AlertComponent result : the display is almost ok but it misses fonts. The weight is a bit lighter (1,2Mb vs 1,5Mb) but still really too heavy (x5 vs no css at all)

Code of the really simple component that only use clr-alert and will be exported as a my-alert full standalone web component :

@Component({
  selector: 'my-alert',
  encapsulation: ViewEncapsulation.ShadowDom,
  standalone: true,
  imports: [ClrAlertModule],
  template: `
      <clr-alert [clrAlertType]="alertType">
          <clr-alert-item>
              <span class="alert-text">{{alertText}}</span>
          </clr-alert-item>
      </clr-alert>
  `,
  styleUrls: [
    "../../../../node_modules/@clr/ui/clr-ui.min.css"
  ]
})
export class AlertComponent {
  @Input() alertType: "info"|"warning"|"success"|"danger" = "success";
  @Input({required: true}) alertText!: string;
}

Thanks

0

There are 0 answers