Last active
January 14, 2022 16:13
-
-
Save kerryj89/9dca6f006c08aae35c81c0480650b20f to your computer and use it in GitHub Desktop.
Boxicons in Angular
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// These are the steps I took to get <box-icon> web component to work with Angular 12, | |
// otherwise we'd fail compiling with the error '"box-icon" is not a known element'. | |
// Why does this happen? | |
// Angular prevents custom elements and attributes by default. Sadly, they don't provide an easy way | |
// of whitelisting more. It's an all or nothing affair with their options dealing with this, | |
// just like Angular's approach to sanitization. Angular's list of accepted elements and attributes: | |
// https://github.com/angular/angular/blob/master/packages/compiler/src/schema/dom_element_schema_registry.ts#L79 | |
// A popular solution to this problem is to enable "CUSTOM_ELEMENTS_SCHEMA" on the module you are importing boxicon | |
// to - this isn't the best approach as it also turns off Angular's template checking feature completely for that module. | |
// Instead we should create a "wrapper" module with "CUSTOM_ELEMENTS_SCHEMA" enabled on that and then import the wrapper | |
// module in. | |
// Voice your concern https://github.com/angular/angular/issues/12045 so that we may one day have a cleaner solution | |
// when it comes to loading web components within our Angular app. | |
// 1. In root Angular directory, install Boxicon (npm install boxicons --save) | |
// 2. Link to boxicons.js in your angular.json | |
// *** angular.json *** | |
{ | |
"projects": { | |
"your-project-name": { | |
"architect": { | |
"build": { | |
"options": { | |
"scripts": [ | |
"node_modules/boxicons/dist/boxicons.js", | |
] | |
} | |
} | |
} | |
} | |
} | |
} | |
// 3. Create a boxicon directory in src/app/modules (or wherever you store your modules) with the following files: | |
// *** src/app/modules/boxicon/boxicon.component.ts *** | |
import { Component } from '@angular/core'; | |
@Component({ | |
selector: 'box-icon', | |
template: '' | |
}) | |
export class BoxiconComponent {} | |
// *** src/app/modules/boxicon/boxicon.module.ts *** | |
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { BoxiconComponent } from './boxicon.component'; | |
@NgModule({ | |
declarations: [ BoxiconComponent ], | |
imports: [ CommonModule ], | |
exports: [ BoxiconComponent ], | |
schemas: [ CUSTOM_ELEMENTS_SCHEMA ], | |
}) | |
export class BoxiconModule {} | |
// 4. Import your BoxiconModule; SomeModule below will no longer throw an error that '"box-icon" is not a known element'. | |
// *** src/app/modules/some-module/some-module.module.ts *** | |
import { NgModule } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { fooComponent } from 'src/app/components/foo/foo.component'; | |
import { barComponent } from 'src/app/components/bar/bar.component'; | |
import { BoxiconModule } from 'src/app/modules/boxicon/boxicon.module'; | |
@NgModule({ | |
declarations: [ fooComponent, barComponent ], | |
imports: [ CommonModule, BoxiconModule ], | |
}) | |
export class SomeModule {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment