
CEM Inheritance
This tool maps inherited content (including class members, attributes, CSS parts, CSS variables, slots, and events) from parent components in the Custom Elements Manifest (CEM). This helps in maintaining a clear and comprehensive documentation of web components and their inheritance hierarchy and reduces the need for duplicate documentation for component with shared APIs.
Installation
To install the package, use the following command:
npm install @wc-toolkit/cem-inheritance
Usage
This package includes two ways to update the Custom Elements Manifest:
- using it in a script
- as a plugin for the Custom Element Manifest Analyzer.
Script
import { updateCemInheritance } from "@wc-toolkit/cem-inheritance";import manifest from "./path/to/custom-elements.json" with { type: 'json' };
const options = {...};
updateCemInheritance(manifest, options);
CEM Analyzer
The plugin can be added to the Custom Elements Manifest Analyzer configuration file.
import { cemInheritancePlugin } from "@wc-toolkit/cem-inheritance";
const options = {...};
export default { /** Enable this if you are extending a third-party library */ dependencies: true, plugins: [ cemInheritancePlugin(options) ],};
Configuration
There are a number of configurations you can apply to customize the output for your components.
type Options = { /** Name of the updated CEM file - default is "custom-elements.json" */ fileName?: string; /** Path to output directory */ outdir?: string; /** Class names of any components you would like to exclude from inheritance */ exclude?: string[]; /** Omit items from inheritance based on CEM Analyzer plugin config */ omitByConfig?: ClassOmit; /** Omit items from inheritance based on a custom CEM property */ omitByProperty?: OmittedProperties; /** Skip inheritance for an aspect of your components */ ignore?: string[]; /** External CEMs that your components extend */ externalManifests?: unknown[]; /** Shows process logs */ debug?: boolean; /** Prevents plugin from executing */ skip?: boolean;};
Omitting APIs
If there are any parts of your parent classes you do not want to have inherited, you can have them omitted from the component.
There are two ways to exclude them:
- setting a configuration in the options
- using custom properties in the Custom Elements Manifest
Omit By Config
The first way to omit an API is by using the omitByConfig
setting.
This allows you to specify a class name and any aspect of the inherited members can include a string array of the name of the feature to be excluded.
This is useful if you do not have direct access to the components.
const options = { omitByConfig: { MyElement: { cssProperties: ["--my-css-property"], events: ["my-event", "my-other-event"], }, },};
Omit By Property
The second way to omit an API is by using the omitByProperty
setting.
This allows you to specify a property name in the Custom Elements Manifest that contains a string array of the name of the item you would like to omit.
Here are the default property names:
const defaultOmittedProperties: OmittedProperties = { cssProperties: "omitCssProps", cssParts: "omitCssParts", cssStates: "omitCssStates", methods: "omitMethods", attributes: "omit", properties: "omit", events: "omitEvents", slots: "omitSlots",};
Using JSDoc Tags
If you are using the CEM Analyzer, you can use custom JSDoc tags to omit inherited APIs.
/** * Component where items are omitted from the JSDoc tags * * @tag my-jsdoc-omit-component * * @omit age - this will work for properties and attributes * @omit-cssprop --property-name * @omit-cssState state-name * @omit-event event-name * @omit-method methodName * @omit-part part-name * @omit-slot slot-name * */
Setting Output Targets
If you would like to add your updated Custom Elements Manifest to a specific location in your project, you can use the fileName
and outdir
setting for that.
Otherwise, the updated manifest will be default location - ./custom-elements.json
.
Excluding Components
If there are any classes you would like to exclude from inheritance, you can specify the class names in the exclude
string array.
const options = { exclude: ["MyInternalElement", "MySubElement"],};
Excluding APIs
Some CEM generators will already handle some aspects of the inheritance for you or you may want to exclude an aspect of the inheritance and manage it yourself.
If that’s the case, you can use the ignore
setting to skip an area of inheritance.
const options = { ignore: ["attributes", "members"],};
Including External Manifests
If your components are being extended from an existing library, you can import that library’s manifest and add it to the externalManifests
array.
You can add as many manifest to this as you need.
The external manifest’s components will not be added to your manifest, but only update the information for your components.
import externalCEM from "path/to/external/custom-elements.json" with { type: "json" };
const options = { externalManifests: [externalCEM],};