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