diff --git a/README.md b/README.md
index ecd87abd8..95f64cd92 100644
--- a/README.md
+++ b/README.md
@@ -51,9 +51,7 @@ Once you've cloned the repo, run the following command.
npm start
```
-This will spin up the Shoelace dev server. After the initial build, a browser will open automatically.
-
-There is currently no hot module reloading (HMR), as browser's don't provide a way to reregister custom elements, but most changes to the source will reload the browser automatically. The exception is component metadata used by the docs, which is generated by TypeDoc. This tool takes a few seconds to run so, to prevent long reload delays, it only runs once at startup.
+This will spin up the Shoelace dev server. After the initial build, a browser will open automatically. There is currently no hot module reloading (HMR), as browser's don't provide a way to reregister custom elements, but most changes to the source will reload the browser automatically.
The documentation is powered by Docsify, which uses raw markdown files to generate pages. As such, no static files are built for the docs.
diff --git a/custom-elements-manifest.config.js b/custom-elements-manifest.config.js
new file mode 100644
index 000000000..692e1e42a
--- /dev/null
+++ b/custom-elements-manifest.config.js
@@ -0,0 +1,74 @@
+import fs from 'fs';
+import commentParser from 'comment-parser';
+
+const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
+const { name, description, version, author, homepage, license } = packageData;
+
+export default {
+ globs: ['src/components/**/*.ts'],
+ exclude: ['**/*.test.ts'],
+ dev: true,
+ watch: true,
+ plugins: [
+ // Append package data
+ {
+ name: 'shoelace-package-data',
+ packageLinkPhase({ customElementsManifest, context }) {
+ customElementsManifest.package = { name, description, version, author, homepage, license };
+ }
+ },
+ // Parse custom jsDoc tags
+ {
+ name: 'shoelace-custom-tags',
+ analyzePhase({ ts, node, moduleDoc, context }) {
+ switch (node.kind) {
+ case ts.SyntaxKind.ClassDeclaration:
+ const hasDefaultModifier = node?.modifiers?.some(mod => ts.SyntaxKind.DefaultKeyword === mod.kind);
+ const className = hasDefaultModifier ? 'default' : node?.name?.getText();
+ const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
+ const customTags = ['animation', 'dependency', 'since', 'status'];
+ let customComments = '/**';
+
+ node.jsDoc?.forEach(jsDoc => {
+ jsDoc?.tags?.forEach(tag => {
+ const tagName = tag.tagName.getText();
+
+ if (customTags.includes(tagName)) {
+ customComments += `\n * @${tagName} ${tag.comment}`;
+ }
+ });
+ });
+
+ const parsed = commentParser.parse(customComments + '\n */');
+ parsed[0].tags?.map(t => {
+ switch (t.tag) {
+ case 'since':
+ case 'status':
+ classDoc[t.tag] = t.name;
+ break;
+
+ case 'dependency':
+ if (!Array.isArray(classDoc['dependencies'])) {
+ classDoc['dependencies'] = [];
+ }
+ classDoc['dependencies'].push(t.name);
+ break;
+
+ // All other tags
+ default:
+ if (!Array.isArray(classDoc[t.tag])) {
+ classDoc[t.tag] = [];
+ }
+
+ classDoc[t.tag].push({
+ name: t.name,
+ description: t.description,
+ type: t.type || undefined
+ });
+ }
+ });
+ }
+ }
+ }
+ ]
+};
diff --git a/docs/assets/plugins/metadata/metadata.js b/docs/assets/plugins/metadata/metadata.js
index cdf7c3757..63c61f638 100644
--- a/docs/assets/plugins/metadata/metadata.js
+++ b/docs/assets/plugins/metadata/metadata.js
@@ -7,6 +7,7 @@
Property
+ Attribute
Description
Type
Default
@@ -17,23 +18,11 @@
.map(prop => {
return `
-
`;
})
@@ -51,7 +40,7 @@
-
+ ${escapeHtml(prop.name)}
- ${
- prop.attribute && prop.name !== prop.attribute
- ? `
-
-
- ${escapeHtml(prop.attribute)}
-
+ ${escapeHtml(prop.name)}${prop.attribute ? `
${escapeHtml(prop.attribute)}` : '-'}${escapeHtml(prop.description)}
-
- ${escapeHtml(prop.type)}
+ ${escapeHtml(prop.defaultValue)}${prop.type?.text ? `
+ ${escapeHtml(prop.type?.text || '')}` : '-'}${prop.default ? `
${escapeHtml(prop.default)}` : '-'}
Event
Description
- Details
+ Event Detail
${escapeHtml(event.name)}${escapeHtml(event.name)}${escapeHtml(event.details)}${escapeHtml(event.type?.text)}` : '-'}${escapeHtml(method.name)}${escapeHtml(method.name)}${escapeHtml(
- method.params
- .map(param => `${param.name}${param.isOptional ? '?' : ''}: ${param.type}`)
- .join(', ')
+ ${escapeHtml(
+ method.parameters.map(param => `${param.name}: ${param.type.text}`).join(', ')
)}
`
- : ''
+ : '-'
}
${slot.name ? escapeHtml(slot.name) : '(default)'}${escapeHtml(slot.name)}${escapeHtml(part.name)}${escapeHtml(part.name)}${escapeHtml(animation.name)}${escapeHtml(animation.name)}$1');
}
+ function getAllComponents(metadata) {
+ const allComponents = [];
+
+ metadata.modules.map(module => {
+ module.exports.find(ex => {
+ if (ex.kind === 'custom-element-definition') {
+ allComponents.push(getComponent(metadata, ex.name));
+ }
+ });
+ });
+
+ return allComponents;
+ }
+
+ function getComponent(metadata, tagName) {
+ const module = metadata.modules.find(module => {
+ return module.exports.find(ex => {
+ return ex.kind === 'custom-element-definition' && ex.name === tagName;
+ });
+ });
+ const component = module?.declarations.find(dec => dec.name === 'default');
+ const tag = module.exports.filter(ex => ex.kind === 'custom-element-definition' && ex.name === tagName)[0]?.name;
+
+ return Object.assign({ tag }, component);
+ }
+
function getMetadata() {
return new Promise((resolve, reject) => {
// Simple caching to prevent multiple XHR requests
@@ -262,7 +275,7 @@
return resolve(metadataStore);
}
- fetch('/dist/metadata.json')
+ fetch('/dist/custom-elements.json')
.then(res => res.json())
.then(data => {
metadataStore = data;
@@ -284,7 +297,7 @@
// Add version
const version = document.createElement('div');
version.classList.add('sidebar-version');
- version.textContent = metadata.version;
+ version.textContent = metadata.package.version;
target.appendChild(version);
// Add repo buttons
@@ -309,11 +322,11 @@
const metadata = await getMetadata();
// Replace %VERSION% placeholders
- content = content.replace(/%VERSION%/g, metadata.version);
+ content = content.replace(/%VERSION%/g, metadata.package.version);
// Handle [component-header] tags
content = content.replace(/\[component-header:([a-z-]+)\]/g, (match, tag) => {
- const component = metadata.components.filter(data => data.tag === tag)[0];
+ const component = getComponent(metadata, tag);
let result = '';
if (!component) {
@@ -350,7 +363,7 @@
// Handle [component-metadata] tags
content = content.replace(/\[component-metadata:([a-z-]+)\]/g, (match, tag) => {
- const component = metadata.components.filter(data => data.tag === tag)[0];
+ const component = getComponent(metadata, tag);
let result = '';
if (!component) {
@@ -358,49 +371,67 @@
return next(content);
}
- if (component.props.length) {
+ // Remove members that don't have a description
+ const members = component.members?.filter(member => member.description);
+ const props = members?.filter(prop => {
+ // Look for a corresponding attribute
+ const attribute = component.attributes?.find(attr => attr.fieldName === prop.name);
+ if (attribute) {
+ prop.attribute = attribute.name;
+ }
+
+ return prop.kind === 'field' && prop.privacy !== 'private';
+ });
+
+ // .map(prop => {
+ // const attribute = component.attributes?.find(attr => attr.fieldName === prop);
+ // prop.attribute = attribute;
+ // });
+ const methods = members?.filter(prop => prop.kind === 'method' && prop.privacy !== 'private');
+
+ if (props?.length) {
result += `
## Properties
- ${createPropsTable(component.props)}
+ ${createPropsTable(props)}
`;
}
- if (component.events.length) {
+ if (component.events?.length) {
result += `
## Events
${createEventsTable(component.events)}
`;
}
- if (component.methods.length) {
+ if (methods?.length) {
result += `
- ## Methods
- ${createMethodsTable(component.methods)}
+ ## Methods
+ ${createMethodsTable(methods)}
`;
}
- if (component.slots.length) {
+ if (component.slots?.length) {
result += `
## Slots
${createSlotsTable(component.slots)}
`;
}
- if (component.cssCustomProperties.length) {
+ if (component.cssProperties?.length) {
result += `
## CSS Custom Properties
- ${createCustomPropertiesTable(component.cssCustomProperties)}
+ ${createCustomPropertiesTable(component.cssProperties)}
`;
}
- if (component.parts.length) {
+ if (component.cssParts?.length) {
result += `
## CSS Parts
- ${createPartsTable(component.parts)}
+ ${createPartsTable(component.cssParts)}
`;
}
- if (component.animations.length) {
+ if (component.animations?.length) {
result += `
## Animations
${createAnimationsTable(component.animations)}
@@ -409,14 +440,14 @@
`;
}
- if (component.dependencies.length) {
+ if (component.dependencies?.length) {
result += `
## Dependencies
This component has the following dependencies so, if you're [cherry picking](/getting-started/installation#cherry-picking),
be sure to import these components in addition to <${tag}>.
- ${createDependenciesList(component.tag, metadata.components)}
+ ${createDependenciesList(component.tag, getAllComponents(metadata))}
`;
}
diff --git a/docs/assets/styles/docs-dark.css b/docs/assets/styles/docs-dark.css
index cf570b478..d280e22ce 100644
--- a/docs/assets/styles/docs-dark.css
+++ b/docs/assets/styles/docs-dark.css
@@ -85,10 +85,6 @@
border-bottom-color: var(--sl-color-gray-800);
}
-.sl-theme-dark .markdown-section table .attribute-tooltip {
- border-bottom-color: var(--sl-color-gray-700);
-}
-
/* Tips & warnings */
.sl-theme-dark .markdown-section p.tip,
.sl-theme-dark .markdown-section p.warn {
diff --git a/docs/assets/styles/docs.css b/docs/assets/styles/docs.css
index e8c81115a..5ebc2ca60 100644
--- a/docs/assets/styles/docs.css
+++ b/docs/assets/styles/docs.css
@@ -433,6 +433,7 @@ strong {
/* Tables */
.markdown-section table {
+ display: table;
margin-bottom: 1.5rem;
}
@@ -446,7 +447,7 @@ strong {
.markdown-section th {
border: none;
- font-weight: inherit;
+ font-weight: var(--sl-font-weight-semibold);
text-align: left;
}
@@ -457,16 +458,10 @@ strong {
border-right: none;
}
-.markdown-section td code {
+.markdown-section table .nowrap {
white-space: nowrap;
}
-.markdown-section table .attribute-tooltip {
- background: none;
- border-bottom: dashed 1px var(--sl-color-gray-200);
- cursor: help;
-}
-
/* Iframes */
.markdown-section iframe {
border: none;
diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md
index 08345bc58..2629c820e 100644
--- a/docs/getting-started/overview.md
+++ b/docs/getting-started/overview.md
@@ -113,9 +113,10 @@ Designing, developing, and supporting this library requires a lot of time, effor
## Attribution
-Special thanks to the following projects and individuals that helped make Shoelace possible.
+Special thanks to the following projects and individuals that help make Shoelace possible.
- Components are built with [LitElement](https://lit-element.polymer-project.org/)
+- Component metadata is generated by the [Custom Elements Manifest Analyzer](https://github.com/open-wc/custom-elements-manifest)
- Documentation is powered by [Docsify](https://docsify.js.org/)
- CDN services are provided by [jsDelivr](https://www.jsdelivr.com/)
- The default theme is based on color palettes from [Tailwind](https://tailwindcss.com/)
diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md
index 4c6b8e0ef..ee0cd995b 100644
--- a/docs/resources/changelog.md
+++ b/docs/resources/changelog.md
@@ -8,10 +8,19 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
## Next
+This release changes the way component metadata is generated. Previously, TypeDoc was used to generate a very large file with type data for all components. The data was then parsed and converted to an easier-to-consume file called `metadata.json`. Alas, TypeDoc is expensive to run and the metadata format wasn't standard.
+
+Thanks to an amazing effort by [Pascal Schilp](https://twitter.com/passle_), the world has a simpler, faster way to gather metadata using the [Custom Elements Manifest Analyzer](https://github.com/open-wc/custom-elements-manifest). Not only is this tool faster, but the data follows the evolving `custom-elements.json` format. This is exciting because a standard format for custom elements opens the door for many potential uses, including documentation generation, framework adapters, IDE integrations, third-party uses, and more. [Check out Pascal's great article](https://dev.to/open-wc/introducing-custom-elements-manifest-gkk) for more info about `custom-elements.json` and the new analyzer.
+
+The docs have been updated to use `custom-elements.json`. If you're relying on the old `metadata.json` file for any purpose, this will be a breaking change for you.
+
- 🚨 BREAKING: removed the `sl-overlay-click` event from `sl-dialog` and `sl-drawer` (use `sl-request-close` instead) [#471](https://github.com/shoelace-style/shoelace/discussions/471)
+- 🚨 BREAKING: removed `metadata.json` (use `custom-elements.json` instead)
+- Added `custom-elements.json` for component metadata
- Added `sl-request-close` event to `sl-dialog` and `sl-drawer`
- Added `dialog.denyClose` and `drawer.denyClose` animations
- Fixed a bug in `sl-color-picker` where setting `value` immediately wouldn't trigger an update
+- Updated the docs to use the new `custom-elements.json` for component metadata
## 2.0.0-beta.44
diff --git a/docs/resources/contributing.md b/docs/resources/contributing.md
index 0b6b03a08..434fa1163 100644
--- a/docs/resources/contributing.md
+++ b/docs/resources/contributing.md
@@ -104,7 +104,7 @@ This will generate a source file, a stylesheet, and a docs page for you. When yo
Component development occurs _within_ the local docs site. I've found that offering common variations _in the docs_ is more beneficial for users than segmenting demos and code examples into separate tools such as Storybook. This encourages more thorough documentation, streamlines development for maintainers, and simplifies how the project is built. It also reduces installation and startup times significantly.
-There is currently no hot module reloading (HMR), as browsers don't provide a way to unregister custom elements. However, most changes to the source will reload the browser automatically. The exception is component metadata, which is generated by TypeDoc. TypeDoc takes a few seconds to run so, to prevent long reload delays, it only runs once at startup.
+There is currently no hot module reloading (HMR), as browsers don't provide a way to unregister custom elements. However, most changes to the source will reload the browser automatically.
For more information about running and building the project locally, refer to `README.md` in the project's root.
@@ -224,8 +224,8 @@ Then use the following syntax for comments so they appear in the generated docs.
```js
/**
- * @customProperty --color: The component's text color.
- * @customProperty --background-color: The component's background color.
+ * @cssproperty --color: The component's text color.
+ * @cssproperty --background-color: The component's background color.
*/
@customElement('sl-example')
export default class SlExample {
diff --git a/package-lock.json b/package-lock.json
index c1978efb3..b8552b679 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "2.0.0-beta.44",
"license": "MIT",
"dependencies": {
+ "@custom-elements-manifest/analyzer": "^0.3.4",
"@popperjs/core": "^2.7.0",
"@shoelace-style/animations": "^1.1.0",
"color": "^3.1.3",
@@ -28,6 +29,7 @@
"browser-sync": "^2.26.14",
"chalk": "^4.1.0",
"command-line-args": "^5.1.1",
+ "comment-parser": "^1.1.5",
"concurrently": "^5.3.0",
"del": "^6.0.0",
"download": "^8.0.0",
@@ -43,7 +45,6 @@
"sass": "^1.32.7",
"sinon": "^11.1.1",
"tslib": "^2.2.0",
- "typedoc": "^0.20.28",
"typescript": "^4.2.4",
"wait-on": "^5.2.1"
},
@@ -138,6 +139,25 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@custom-elements-manifest/analyzer": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.3.4.tgz",
+ "integrity": "sha512-wgLe4p2PYsDWxgrustrr4dUcg0qkfTjydo9lQJ5eAFX+Xz0TSaNnfOx87UZ/qdbYlDHIw8fm2pXxx0sgtJ5ApQ==",
+ "dependencies": {
+ "@web/config-loader": "^0.1.3",
+ "chokidar": "^3.5.2",
+ "command-line-args": "^5.1.1",
+ "comment-parser": "^1.1.5",
+ "custom-elements-manifest": "^1.0.0",
+ "debounce": "^1.2.1",
+ "globby": "^11.0.1",
+ "typescript": "^4.3.2"
+ },
+ "bin": {
+ "cem": "index.js",
+ "custom-elements-manifest": "index.js"
+ }
+ },
"node_modules/@hapi/hoek": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz",
@@ -821,7 +841,6 @@
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz",
"integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==",
- "dev": true,
"dependencies": {
"semver": "^7.3.4"
},
@@ -833,7 +852,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -845,7 +863,6 @@
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
- "dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -856,12 +873,6 @@
"node": ">=10"
}
},
- "node_modules/@web/config-loader/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/@web/dev-server": {
"version": "0.1.17",
"resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.17.tgz",
@@ -954,12 +965,6 @@
"node": ">=10"
}
},
- "node_modules/@web/dev-server-core/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/@web/dev-server-esbuild": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-0.2.12.tgz",
@@ -1323,10 +1328,9 @@
"dev": true
},
"node_modules/anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
- "dev": true,
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -1396,7 +1400,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
"integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -1632,7 +1635,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -2085,24 +2087,23 @@
}
},
"node_modules/chokidar": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
- "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
- "dev": true,
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
"dependencies": {
- "anymatch": "~3.1.1",
+ "anymatch": "~3.1.2",
"braces": "~3.0.2",
- "glob-parent": "~5.1.0",
+ "glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
- "readdirp": "~3.5.0"
+ "readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"optionalDependencies": {
- "fsevents": "~2.3.1"
+ "fsevents": "~2.3.2"
}
},
"node_modules/chownr": {
@@ -2420,20 +2421,10 @@
"simple-swizzle": "^0.2.2"
}
},
- "node_modules/colors": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
- "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
- "dev": true,
- "engines": {
- "node": ">=0.1.90"
- }
- },
"node_modules/command-line-args": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
"integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
- "dev": true,
"dependencies": {
"array-back": "^3.0.1",
"find-replace": "^3.0.0",
@@ -2530,6 +2521,14 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
+ "node_modules/comment-parser": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.5.tgz",
+ "integrity": "sha512-RePCE4leIhBlmrqiYTvaqEeGYg7qpSl4etaIabKtdOQVi+mSTIBBklGUwIr79GXYnl3LpMwmDw4KeR2stNc6FA==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/compare-versions": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
@@ -2989,6 +2988,11 @@
"node": ">=8.0.0"
}
},
+ "node_modules/custom-elements-manifest": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz",
+ "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A=="
+ },
"node_modules/date-fns": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.17.0.tgz",
@@ -3001,8 +3005,7 @@
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
- "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
- "dev": true
+ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
},
"node_modules/debug": {
"version": "3.1.0",
@@ -4244,7 +4247,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
"integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
- "dev": true,
"dependencies": {
"array-back": "^3.0.1"
},
@@ -4574,7 +4576,6 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
"optional": true,
"os": [
"darwin"
@@ -5353,7 +5354,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
@@ -6281,8 +6281,7 @@
"node_modules/lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
- "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
- "dev": true
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
},
"node_modules/lodash.get": {
"version": "4.4.2",
@@ -6465,21 +6464,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/lunr": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
- "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
- "dev": true
- },
"node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@@ -6535,18 +6519,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/marked": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz",
- "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==",
- "dev": true,
- "bin": {
- "marked": "bin/marked"
- },
- "engines": {
- "node": ">= 8.16.2"
- }
- },
"node_modules/marky": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/marky/-/marky-1.2.2.tgz",
@@ -7190,7 +7162,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -7459,15 +7430,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/onigasm": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz",
- "integrity": "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^5.1.1"
- }
- },
"node_modules/only": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz",
@@ -8460,10 +8422,9 @@
"dev": true
},
"node_modules/readdirp": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
- "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
- "dev": true,
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dependencies": {
"picomatch": "^2.2.1"
},
@@ -9150,33 +9111,6 @@
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
"dev": true
},
- "node_modules/shelljs": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
- "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
- "dev": true,
- "dependencies": {
- "glob": "^7.0.0",
- "interpret": "^1.0.0",
- "rechoir": "^0.6.2"
- },
- "bin": {
- "shjs": "bin/shjs"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/shiki": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.3.tgz",
- "integrity": "sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==",
- "dev": true,
- "dependencies": {
- "onigasm": "^2.2.5",
- "vscode-textmate": "^5.2.0"
- }
- },
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -10307,82 +10241,10 @@
"node": ">= 0.6"
}
},
- "node_modules/typedoc": {
- "version": "0.20.36",
- "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.20.36.tgz",
- "integrity": "sha512-qFU+DWMV/hifQ9ZAlTjdFO9wbUIHuUBpNXzv68ZyURAP9pInjZiO4+jCPeAzHVcaBCHER9WL/+YzzTt6ZlN/Nw==",
- "dev": true,
- "dependencies": {
- "colors": "^1.4.0",
- "fs-extra": "^9.1.0",
- "handlebars": "^4.7.7",
- "lodash": "^4.17.21",
- "lunr": "^2.3.9",
- "marked": "^2.0.3",
- "minimatch": "^3.0.0",
- "progress": "^2.0.3",
- "shelljs": "^0.8.4",
- "shiki": "^0.9.3",
- "typedoc-default-themes": "^0.12.10"
- },
- "bin": {
- "typedoc": "bin/typedoc"
- },
- "engines": {
- "node": ">= 10.8.0"
- },
- "peerDependencies": {
- "typescript": "3.9.x || 4.0.x || 4.1.x || 4.2.x"
- }
- },
- "node_modules/typedoc-default-themes": {
- "version": "0.12.10",
- "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz",
- "integrity": "sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/typedoc/node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "dev": true,
- "dependencies": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/typedoc/node_modules/jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.6",
- "universalify": "^2.0.0"
- }
- },
- "node_modules/typedoc/node_modules/universalify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
- "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
- "dev": true,
- "engines": {
- "node": ">= 10.0.0"
- }
- },
"node_modules/typescript": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
- "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
- "dev": true,
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
+ "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -10395,7 +10257,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
"integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -10694,12 +10555,6 @@
"node": ">= 0.8"
}
},
- "node_modules/vscode-textmate": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.4.0.tgz",
- "integrity": "sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w==",
- "dev": true
- },
"node_modules/wait-on": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.2.1.tgz",
@@ -11009,10 +10864,9 @@
}
},
"node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
"version": "1.10.0",
@@ -11439,6 +11293,21 @@
"regenerator-runtime": "^0.13.4"
}
},
+ "@custom-elements-manifest/analyzer": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.3.4.tgz",
+ "integrity": "sha512-wgLe4p2PYsDWxgrustrr4dUcg0qkfTjydo9lQJ5eAFX+Xz0TSaNnfOx87UZ/qdbYlDHIw8fm2pXxx0sgtJ5ApQ==",
+ "requires": {
+ "@web/config-loader": "^0.1.3",
+ "chokidar": "^3.5.2",
+ "command-line-args": "^5.1.1",
+ "comment-parser": "^1.1.5",
+ "custom-elements-manifest": "^1.0.0",
+ "debounce": "^1.2.1",
+ "globby": "^11.0.1",
+ "typescript": "^4.3.2"
+ }
+ },
"@hapi/hoek": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz",
@@ -12102,7 +11971,6 @@
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz",
"integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==",
- "dev": true,
"requires": {
"semver": "^7.3.4"
},
@@ -12111,7 +11979,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"requires": {
"yallist": "^4.0.0"
}
@@ -12120,16 +11987,9 @@
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
- "dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
}
}
},
@@ -12210,12 +12070,6 @@
"requires": {
"yallist": "^4.0.0"
}
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
}
}
},
@@ -12492,10 +12346,9 @@
"dev": true
},
"anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
- "dev": true,
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -12548,8 +12401,7 @@
"array-back": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
- "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
- "dev": true
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q=="
},
"array-differ": {
"version": "1.0.0",
@@ -12726,8 +12578,7 @@
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"bl": {
"version": "1.2.3",
@@ -13109,19 +12960,18 @@
"dev": true
},
"chokidar": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
- "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
- "dev": true,
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
"requires": {
- "anymatch": "~3.1.1",
+ "anymatch": "~3.1.2",
"braces": "~3.0.2",
- "fsevents": "~2.3.1",
- "glob-parent": "~5.1.0",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
- "readdirp": "~3.5.0"
+ "readdirp": "~3.6.0"
}
},
"chownr": {
@@ -13387,17 +13237,10 @@
"simple-swizzle": "^0.2.2"
}
},
- "colors": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
- "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
- "dev": true
- },
"command-line-args": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
"integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
- "dev": true,
"requires": {
"array-back": "^3.0.1",
"find-replace": "^3.0.0",
@@ -13472,6 +13315,11 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
+ "comment-parser": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.5.tgz",
+ "integrity": "sha512-RePCE4leIhBlmrqiYTvaqEeGYg7qpSl4etaIabKtdOQVi+mSTIBBklGUwIr79GXYnl3LpMwmDw4KeR2stNc6FA=="
+ },
"compare-versions": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
@@ -13852,6 +13700,11 @@
"source-map": "^0.6.1"
}
},
+ "custom-elements-manifest": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz",
+ "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A=="
+ },
"date-fns": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.17.0.tgz",
@@ -13861,8 +13714,7 @@
"debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
- "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
- "dev": true
+ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
},
"debug": {
"version": "3.1.0",
@@ -14875,7 +14727,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
"integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
- "dev": true,
"requires": {
"array-back": "^3.0.1"
}
@@ -15147,7 +14998,6 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
"optional": true
},
"function-bind": {
@@ -15756,7 +15606,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
@@ -16469,8 +16318,7 @@
"lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
- "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
- "dev": true
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
},
"lodash.get": {
"version": "4.4.2",
@@ -16615,21 +16463,6 @@
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"dev": true
},
- "lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "requires": {
- "yallist": "^3.0.2"
- }
- },
- "lunr": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
- "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
- "dev": true
- },
"make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@@ -16672,12 +16505,6 @@
"object-visit": "^1.0.0"
}
},
- "marked": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz",
- "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==",
- "dev": true
- },
"marky": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/marky/-/marky-1.2.2.tgz",
@@ -17209,8 +17036,7 @@
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"normalize-url": {
"version": "2.0.1",
@@ -17416,15 +17242,6 @@
"mimic-fn": "^2.1.0"
}
},
- "onigasm": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz",
- "integrity": "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==",
- "dev": true,
- "requires": {
- "lru-cache": "^5.1.1"
- }
- },
"only": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz",
@@ -18216,10 +18033,9 @@
}
},
"readdirp": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
- "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
- "dev": true,
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"requires": {
"picomatch": "^2.2.1"
}
@@ -18786,27 +18602,6 @@
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
"dev": true
},
- "shelljs": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
- "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
- "dev": true,
- "requires": {
- "glob": "^7.0.0",
- "interpret": "^1.0.0",
- "rechoir": "^0.6.2"
- }
- },
- "shiki": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.3.tgz",
- "integrity": "sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==",
- "dev": true,
- "requires": {
- "onigasm": "^2.2.5",
- "vscode-textmate": "^5.2.0"
- }
- },
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -19749,72 +19544,15 @@
"mime-types": "~2.1.24"
}
},
- "typedoc": {
- "version": "0.20.36",
- "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.20.36.tgz",
- "integrity": "sha512-qFU+DWMV/hifQ9ZAlTjdFO9wbUIHuUBpNXzv68ZyURAP9pInjZiO4+jCPeAzHVcaBCHER9WL/+YzzTt6ZlN/Nw==",
- "dev": true,
- "requires": {
- "colors": "^1.4.0",
- "fs-extra": "^9.1.0",
- "handlebars": "^4.7.7",
- "lodash": "^4.17.21",
- "lunr": "^2.3.9",
- "marked": "^2.0.3",
- "minimatch": "^3.0.0",
- "progress": "^2.0.3",
- "shelljs": "^0.8.4",
- "shiki": "^0.9.3",
- "typedoc-default-themes": "^0.12.10"
- },
- "dependencies": {
- "fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "dev": true,
- "requires": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- }
- },
- "jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.6",
- "universalify": "^2.0.0"
- }
- },
- "universalify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
- "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
- "dev": true
- }
- }
- },
- "typedoc-default-themes": {
- "version": "0.12.10",
- "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz",
- "integrity": "sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==",
- "dev": true
- },
"typescript": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
- "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
- "dev": true
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
+ "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew=="
},
"typical": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
- "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
- "dev": true
+ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw=="
},
"ua-parser-js": {
"version": "0.7.24",
@@ -20045,12 +19783,6 @@
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
"dev": true
},
- "vscode-textmate": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.4.0.tgz",
- "integrity": "sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w==",
- "dev": true
- },
"wait-on": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.2.1.tgz",
@@ -20291,10 +20023,9 @@
"dev": true
},
"yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"yaml": {
"version": "1.10.0",
diff --git a/package.json b/package.json
index 8c4b77d37..b308f6c0b 100644
--- a/package.json
+++ b/package.json
@@ -7,9 +7,11 @@
"license": "MIT",
"main": "dist/shoelace.js",
"module": "dist/shoelace.js",
+ "customElements": "dist/custom-elements.json",
"type": "module",
"types": "dist/shoelace.d.ts",
"files": [
+ "custom-elements.json",
"dist"
],
"keywords": [
@@ -38,6 +40,7 @@
"test:watch": "web-test-runner \"src/**/*.test.ts\" --node-resolve --puppeteer --watch"
},
"dependencies": {
+ "@custom-elements-manifest/analyzer": "^0.3.4",
"@popperjs/core": "^2.7.0",
"@shoelace-style/animations": "^1.1.0",
"color": "^3.1.3",
@@ -57,6 +60,7 @@
"browser-sync": "^2.26.14",
"chalk": "^4.1.0",
"command-line-args": "^5.1.1",
+ "comment-parser": "^1.1.5",
"concurrently": "^5.3.0",
"del": "^6.0.0",
"download": "^8.0.0",
@@ -72,7 +76,6 @@
"sass": "^1.32.7",
"sinon": "^11.1.1",
"tslib": "^2.2.0",
- "typedoc": "^0.20.28",
"typescript": "^4.2.4",
"wait-on": "^5.2.1"
},
diff --git a/scripts/build.js b/scripts/build.js
index 05cb228a6..d0c078a2e 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -5,15 +5,17 @@ import browserSync from 'browser-sync';
import chalk from 'chalk';
import commandLineArgs from 'command-line-args';
import copy from 'recursive-copy';
+import crypto from 'crypto';
import del from 'del';
import esbuild from 'esbuild';
-import { execSync } from 'child_process';
+import fs from 'fs';
import getPort from 'get-port';
import glob from 'globby';
import inlineImportPlugin from 'esbuild-plugin-inline-import';
import path from 'path';
import sass from 'sass';
import sassPlugin from 'esbuild-plugin-sass';
+import { execSync } from 'child_process';
const build = esbuild.build;
const bs = browserSync.create();
@@ -23,6 +25,7 @@ del.sync('./dist');
if (!dev) execSync('tsc', { stdio: 'inherit' }); // for type declarations
execSync('node scripts/make-metadata.js', { stdio: 'inherit' });
+execSync('node scripts/make-vscode-data.js', { stdio: 'inherit' });
execSync('node scripts/make-icons.js', { stdio: 'inherit' });
(async () => {
@@ -83,21 +86,21 @@ execSync('node scripts/make-icons.js', { stdio: 'inherit' });
process.exit(1);
});
- // Create the docs distribution by copying dist into docs/dist. This is what powers the website. It can't exist in dev
- // because it will conflict with browser sync's routing to the actual dist dir.
+ // Create the docs distribution by copying dist into the docs folder. This is what powers the website. It doesn't need
+ // to exist in dev because Browser Sync routes it virtually.
await del('./docs/dist');
if (!dev) {
- await copy('./dist', './docs/dist');
+ await Promise.all([copy('./dist', './docs/dist')]);
}
- console.log(chalk.green('The build has finished! 📦'));
+ console.log(chalk.green('The build has finished! 📦\n'));
if (dev) {
const port = await getPort({
port: getPort.makeRange(4000, 4999)
});
- console.log(chalk.cyan(`\nLaunching the Shoelace dev server at http://localhost:${port}! 🥾\n`));
+ console.log(chalk.cyan(`Launching the Shoelace dev server at http://localhost:${port}! 🥾\n`));
// Launch browser sync
bs.init({
@@ -118,11 +121,10 @@ execSync('node scripts/make-icons.js', { stdio: 'inherit' });
// Rebuild and reload when source files change
bs.watch(['src/**/!(*.test).*']).on('change', async filename => {
console.log(`Source file changed - ${filename}`);
-
- // NOTE: we don't run TypeDoc on every change because it's quite heavy, so changes to the docs won't be included
- // until the next time the build script runs.
buildResult
+ // Rebuild and reload
.rebuild()
+ .then(() => execSync('node scripts/make-metadata.js', { stdio: 'inherit' }))
.then(() => bs.reload())
.catch(err => console.error(chalk.red(err)));
});
diff --git a/scripts/make-icons.js b/scripts/make-icons.js
index 2cdeb4a96..b7af4c833 100644
--- a/scripts/make-icons.js
+++ b/scripts/make-icons.js
@@ -25,15 +25,15 @@ let numIcons = 0;
try {
await stat(`${srcPath}/LICENSE.md`);
- console.log(chalk.cyan('Generating icons from cache'));
+ console.log('Generating icons from cache');
} catch {
// Download the source from GitHub (since not everything is published to NPM)
- console.log(chalk.cyan(`Downloading and extracting Bootstrap Icons ${version} 📦`));
+ console.log(`Downloading and extracting Bootstrap Icons ${version} 📦`);
await download(url, './.cache/icons', { extract: true });
}
// Copy icons
- console.log(chalk.cyan(`Copying icons and license`));
+ console.log(`Copying icons and license`);
await del([iconDir]);
await mkdirp(iconDir);
await Promise.all([
@@ -43,7 +43,7 @@ let numIcons = 0;
]);
// Generate metadata
- console.log(chalk.cyan(`Generating icon metadata`));
+ console.log(`Generating icon metadata`);
const files = await glob(`${srcPath}/docs/content/icons/**/*.md`);
const metadata = await Promise.map(files, async file => {
@@ -61,7 +61,7 @@ let numIcons = 0;
await writeFile(path.join(iconDir, 'icons.json'), JSON.stringify(metadata, null, 2), 'utf8');
- console.log(chalk.green(`Successfully processed ${numIcons} icons ✨\n`));
+ console.log(chalk.cyan(`Successfully processed ${numIcons} icons ✨\n`));
} catch (err) {
console.error(err);
}
diff --git a/scripts/make-metadata.js b/scripts/make-metadata.js
index 8235ec596..c5ca02ab6 100644
--- a/scripts/make-metadata.js
+++ b/scripts/make-metadata.js
@@ -1,290 +1,13 @@
//
-// This script runs TypeDoc and uses its output to generate metadata files used by the docs
+// This script runs the Custom Elements Manifest analyzer to generate custom-elements.json
//
import chalk from 'chalk';
-import { execSync } from 'child_process';
-import fs from 'fs';
import mkdirp from 'mkdirp';
-import path from 'path';
+import { execSync } from 'child_process';
-const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
+mkdirp.sync('./dist');
-function getTagName(className) {
- return className.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`).replace(/^-/, '');
-}
-
-// Takes a prop or param and returns type info as a string and, if applicable, an array of possible values
-function getTypeInfo(item) {
- const values = [];
- let type = item.type.name || '';
-
- if (item.type.type === 'union') {
- const types = item.type.types.map(t => {
- if (t.type === 'literal' || t.type === 'reference') {
- values.push(t.value);
- type = `'${item.type.types.map(t => t.value).join(`' | '`)}'`;
- }
-
- if (t.type === 'intrinsic') {
- values.push(t.name);
- type = item.type.types.map(t => t.name).join(' | ');
- }
- });
- }
-
- if (item.type.type === 'reflection' && item.type.declaration?.children) {
- const args = item.type.declaration.children.map(prop => {
- const name = prop.name;
- const type = prop.type.name;
- const isOptional = prop.flags.isOptional === true;
- return `${name}${isOptional ? '?' : ''}: ${type}`;
- });
-
- // Display as an object
- type += `{ ${args.join(', ')} }`;
- }
-
- return {
- type,
- values: values.length ? values : undefined
- };
-}
-
-// Splits a string of tag text into a { name, description } object
-function splitText(text) {
- const shouldSplit = text.indexOf(' - ') > -1;
- let name = '';
- let description = '';
-
- if (shouldSplit) {
- const split = text.split(' - ');
- name = split[0].trim();
- description = split.slice(1).join(' - ').replace(/^- /, '');
- } else {
- description = text.trim().replace(/^-\s/, '');
- }
-
- return { name, description };
-}
-
-// Run typedoc
-console.log(chalk.cyan('Generating type data with TypeDoc'));
-mkdirp.sync('./.cache');
-execSync(
- 'typedoc --json .cache/typedoc.json --entryPoints src/shoelace.ts --exclude "**/*+(index|.spec|.e2e).ts" --excludeExternals --excludeProtected --excludeInternal',
- { stdio: 'inherit' }
-);
-
-const data = JSON.parse(fs.readFileSync('.cache/typedoc.json', 'utf8'));
-const modules = data.children;
-const components = modules.filter(module => module.kindString === 'Class');
-const metadata = {
- name: packageData.name,
- description: packageData.description,
- version: packageData.version,
- author: packageData.author,
- homepage: packageData.homepage,
- license: packageData.license,
- components: []
-};
-
-components.map(async component => {
- const api = {
- className: component.name,
- tag: getTagName(component.name),
- file: component.sources[0].fileName,
- since: '',
- status: '',
- props: [],
- methods: [],
- events: [],
- slots: [],
- cssCustomProperties: [],
- parts: [],
- dependencies: []
- };
-
- // Metadata
- if (component.comment) {
- const tags = component.comment.tags;
- const dependencies = tags.filter(item => item.tag === 'dependency');
- const slots = tags.filter(item => item.tag === 'slot');
- const parts = tags.filter(item => item.tag === 'part');
- const customProperties = tags.filter(item => item.tag === 'customproperty');
- const animations = tags.filter(item => item.tag === 'animation');
-
- api.since = tags.find(item => item.tag === 'since').text.trim();
- api.status = tags.find(item => item.tag === 'status').text.trim();
- api.dependencies = dependencies.map(tag => tag.text.trim());
- api.slots = slots.map(tag => splitText(tag.text));
- api.parts = parts.map(tag => splitText(tag.text));
- api.cssCustomProperties = customProperties.map(tag => splitText(tag.text));
- api.animations = animations.map(tag => splitText(tag.text));
- } else {
- console.error(chalk.yellow(`Missing comment block for ${component.name} - skipping metadata`));
- }
-
- // Props
- const props = component.children
- .filter(child => child.kindString === 'Property' && !child.flags.isStatic)
- .filter(child => child.type.name !== 'EventEmitter')
- .filter(child => child.comment && child.comment.shortText); // only with comments
-
- props.map(prop => {
- const { type, values } = getTypeInfo(prop);
- let attribute;
-
- // Look for an attribute in the @property decorator
- if (Array.isArray(prop.decorators)) {
- const decorator = prop.decorators.find(d => d.name === 'property');
- if (decorator) {
- try {
- // We trust TypeDoc <3
- const options = eval(`(${decorator.arguments.options})`);
-
- // If an attribute is specified, it will always be a string
- if (options && typeof options.attribute === 'string') {
- attribute = options.attribute;
- }
- } catch (err) {
- console.log(err);
- }
- }
- }
-
- api.props.push({
- name: prop.name,
- attribute: attribute,
- description: prop.comment.shortText,
- type,
- values,
- defaultValue: prop.defaultValue
- });
- });
-
- // Events
- const events = component.children
- .filter(child => child.kindString === 'Property' && !child.flags.isStatic)
- .filter(child => child.type.name === 'EventEmitter')
- .filter(child => child.comment && child.comment.shortText); // only with comments
-
- events.map(event => {
- const decorator = event.decorators.filter(dec => dec.name === 'event')[0];
- const name = (decorator ? decorator.arguments.eventName : event.name).replace(/['"`]/g, '');
-
- // TODO: This logic is used to gather event details in a developer-friendly format. It could be improved as it may
- // not cover all types yet. The output is used to populate the Events table of each component in the docs.
- const params = event.type.typeArguments.map(param => {
- if (param.type === 'intrinsic') {
- return param.name;
- }
-
- if (param.type === 'literal') {
- return param.value;
- }
-
- if (param.type === 'reflection') {
- return (
- '{ ' +
- param.declaration.children
- .map(child => {
- // Component exports aren't named, so they appear as "default" in the type data. However, we can use the
- // id to link them to the right class.
- if (child.type.name === 'default') {
- const component = components.find(component => component.id === child.type.id);
- if (component) {
- child.type.name = component.name;
- } else {
- child.type.name = 'unknown';
- }
- }
-
- if (child.type.type === 'intrinsic' || child.type.type === 'reference') {
- return `${child.name}: ${child.type.name}`;
- } else if (child.name) {
- if (child.type.type === 'array') {
- return `${child.name}: ${child.type.elementType.name}[]`;
- } else {
- return `${child.name}: ${child.type.elementType.name} (${child.type.type})`;
- }
- } else {
- return child.type.type;
- }
- })
- .join(', ') +
- ' }'
- );
- }
-
- return '';
- });
-
- const details = params.join(', ');
-
- api.events.push({
- name,
- description: event.comment.shortText,
- details
- });
- });
-
- // Methods
- const methods = component.children
- .filter(child => child.kindString === 'Method' && !child.flags.isStatic)
- .filter(child => child.signatures[0].comment && child.signatures[0].comment.shortText); // only with comments
-
- methods.map(method => {
- const signature = method.signatures[0];
- const params = Array.isArray(signature.parameters)
- ? signature.parameters.map(param => {
- const { type, values } = getTypeInfo(param);
- return {
- name: param.name,
- type,
- values,
- isOptional: param.flags?.isOptional,
- defaultValue: param.defaultValue
- };
- })
- : [];
-
- api.methods.push({
- name: method.name,
- description: signature.comment.shortText,
- params
- });
- });
-
- metadata.components.push(api);
-});
-
-// Generate metadata.json
-(async () => {
- const filename = path.join('./dist/metadata.json');
- const json = JSON.stringify(metadata, null, 2);
-
- await mkdirp(path.dirname(filename));
- fs.writeFileSync(filename, json, 'utf8');
-})();
-
-// Generate vscode.html-custom-data.json (for IntelliSense)
-(async () => {
- const filename = path.join('./dist/vscode.html-custom-data.json');
- const customData = {
- tags: metadata.components.map(component => ({
- name: component.tag,
- description: component.description,
- attributes: component.props.map(prop => ({
- name: prop.name,
- description: prop.description,
- values: prop.values ? prop.values.map(value => ({ name: value })) : undefined
- }))
- }))
- };
- const json = JSON.stringify(customData, null, 2);
-
- await mkdirp(path.dirname(filename));
- fs.writeFileSync(filename, json, 'utf8');
-})();
-
-console.log(chalk.green(`Successfully generated metadata 🏷\n`));
+// Run the analyzer
+console.log('Generating component metadata');
+execSync('cem analyze --litelement --outdir dist', { stdio: 'inherit' });
+console.log(chalk.cyan(`Successfully generated metadata 🏷\n`));
diff --git a/scripts/make-vscode-data.js b/scripts/make-vscode-data.js
new file mode 100644
index 000000000..3903db707
--- /dev/null
+++ b/scripts/make-vscode-data.js
@@ -0,0 +1,86 @@
+//
+// This script generates vscode.html-custom-data.json (for IntelliSense).
+//
+// You must generate dist/custom-elements.json before running this script.
+//
+import chalk from 'chalk';
+import fs from 'fs';
+import mkdirp from 'mkdirp';
+
+const metadata = JSON.parse(fs.readFileSync('./dist/custom-elements.json', 'utf8'));
+
+function getAllComponents() {
+ const allComponents = [];
+ const getComponent = tagName => {
+ const module = metadata.modules.find(module => {
+ return module.exports.find(ex => {
+ return ex.kind === 'custom-element-definition' && ex.name === tagName;
+ });
+ });
+
+ const component = module?.declarations.find(dec => dec.name === 'default');
+ const tag = module.exports.filter(ex => ex.kind === 'custom-element-definition' && ex.name === tagName)[0]?.name;
+
+ return Object.assign({ tag }, component);
+ };
+
+ metadata.modules.map(module => {
+ module.exports.find(ex => {
+ if (ex.kind === 'custom-element-definition') {
+ if (typeof ex.name === 'string') {
+ allComponents.push(getComponent(ex.name));
+ }
+ }
+ });
+ });
+
+ return allComponents;
+}
+
+console.log('Generating IntelliSense data for VS Code');
+
+const components = getAllComponents();
+const vscode = { tags: [] };
+
+components.map(component => {
+ const name = component.tag;
+ const attributes = component.attributes?.map(attr => {
+ const type = attr.type?.text;
+ let values = [];
+
+ if (type) {
+ type.split('|').map(val => {
+ val = val.trim();
+
+ // Only accept values that are strings and numbers
+ const isString = val.startsWith(`'`);
+ const isNumber = Number(val).toString() === val;
+
+ if (isString) {
+ // Remove quotes
+ val = val.replace(/^'/, '').replace(/'$/, '');
+ }
+
+ if (isNumber || isString) {
+ values.push({ name: val });
+ }
+ });
+ }
+
+ if (values.length === 0) {
+ values = undefined;
+ }
+
+ return {
+ name: attr.name,
+ description: attr.description,
+ values
+ };
+ });
+
+ vscode.tags.push({ name, attributes });
+});
+
+fs.writeFileSync('./dist/vscode.html-custom-data.json', JSON.stringify(vscode, null, 2), 'utf8');
+
+console.log(chalk.cyan(`Successfully generated IntelliSense data for VS Code 🔮\n`));
diff --git a/scripts/plop/templates/component/component.hbs b/scripts/plop/templates/component/component.hbs
index be1d8284e..d9fc8e4b4 100644
--- a/scripts/plop/templates/component/component.hbs
+++ b/scripts/plop/templates/component/component.hbs
@@ -1,6 +1,7 @@
import { LitElement, html, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js';
-import { event, EventEmitter } from '../../internal/decorators';
+import { emit } from '../../internal/event';
+import { watch } from '../../internal/watch';
import styles from 'sass:./{{ tagWithoutPrefix tag }}.scss';
/**
@@ -9,10 +10,14 @@ import styles from 'sass:./{{ tagWithoutPrefix tag }}.scss';
*
* @dependency sl-example
*
- * @slot - The default slot.
- * @slot example - An example slot.
+ * @event sl-event-name Emitted as an example.
*
- * @part base - The component's base wrapper.
+ * @slot default The default slot.
+ * @slot example An example slot.
+ *
+ * @csspart base The component's base wrapper.
+ *
+ * @cssproperty --example An example CSS custom property.
*/
@customElement('{{ tag }}')
export default class {{ properCase tag }} extends LitElement {
@@ -21,8 +26,11 @@ export default class {{ properCase tag }} extends LitElement {
/** An example property. */
@property() prop = 'example';
- /** An example event. */
- @event('sl-event') slEvent: EventEmitter