mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
* Rename SlSlideChange for consistency with other events * Setup React event types for events used by Shoelace components Means that consumers of Shoelace via the React wrapper will be able to use callback methods with the correct event type, instead of having to rely on casting and friends when using Typescript. * Add docs demonstrating importing event types for React callbacks
169 lines
5.2 KiB
JavaScript
169 lines
5.2 KiB
JavaScript
import { generateCustomData } from 'cem-plugin-vs-code-custom-data-generator';
|
|
import { parse } from 'comment-parser';
|
|
import { pascalCase } from 'pascal-case';
|
|
import commandLineArgs from 'command-line-args';
|
|
import fs from 'fs';
|
|
|
|
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
const { name, description, version, author, homepage, license } = packageData;
|
|
|
|
const { outdir } = commandLineArgs([
|
|
{ name: 'litelement', type: String },
|
|
{ name: 'analyze', defaultOption: true },
|
|
{ name: 'outdir', type: String }
|
|
]);
|
|
|
|
function noDash(string) {
|
|
return string.replace(/^\s?-/, '').trim();
|
|
}
|
|
|
|
function replace(string, terms) {
|
|
terms.forEach(({ from, to }) => {
|
|
string = string?.replace(from, to);
|
|
});
|
|
|
|
return string;
|
|
}
|
|
|
|
export default {
|
|
globs: ['src/components/**/*.ts'],
|
|
exclude: ['**/*.styles.ts', '**/*.test.ts'],
|
|
plugins: [
|
|
// Append package data
|
|
{
|
|
name: 'shoelace-package-data',
|
|
packageLinkPhase({ customElementsManifest }) {
|
|
customElementsManifest.package = { name, description, version, author, homepage, license };
|
|
}
|
|
},
|
|
|
|
// Parse custom jsDoc tags
|
|
{
|
|
name: 'shoelace-custom-tags',
|
|
analyzePhase({ ts, node, moduleDoc }) {
|
|
switch (node.kind) {
|
|
case ts.SyntaxKind.ClassDeclaration: {
|
|
const className = node.name.getText();
|
|
const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
|
|
const customTags = ['animation', 'dependency', 'documentation', 'since', 'status', 'title'];
|
|
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 = parse(`${customComments}\n */`);
|
|
parsed[0].tags?.forEach(t => {
|
|
switch (t.tag) {
|
|
// Animations
|
|
case 'animation':
|
|
if (!Array.isArray(classDoc['animations'])) {
|
|
classDoc['animations'] = [];
|
|
}
|
|
classDoc['animations'].push({
|
|
name: t.name,
|
|
description: noDash(t.description)
|
|
});
|
|
break;
|
|
|
|
// Dependencies
|
|
case 'dependency':
|
|
if (!Array.isArray(classDoc['dependencies'])) {
|
|
classDoc['dependencies'] = [];
|
|
}
|
|
classDoc['dependencies'].push(t.name);
|
|
break;
|
|
|
|
// Value-only metadata tags
|
|
case 'documentation':
|
|
case 'since':
|
|
case 'status':
|
|
case 'title':
|
|
classDoc[t.tag] = 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
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
name: 'shoelace-react-event-names',
|
|
analyzePhase({ ts, node, moduleDoc }) {
|
|
switch (node.kind) {
|
|
case ts.SyntaxKind.ClassDeclaration: {
|
|
const className = node.name.getText();
|
|
const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
|
|
|
|
if (classDoc?.events) {
|
|
classDoc.events.forEach(event => {
|
|
event.reactName = `on${pascalCase(event.name)}`;
|
|
event.eventName = `${pascalCase(event.name)}Event`;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
name: 'shoelace-translate-module-paths',
|
|
packageLinkPhase({ customElementsManifest }) {
|
|
customElementsManifest?.modules?.forEach(mod => {
|
|
//
|
|
// CEM paths look like this:
|
|
//
|
|
// src/components/button/button.ts
|
|
//
|
|
// But we want them to look like this:
|
|
//
|
|
// components/button/button.js
|
|
//
|
|
const terms = [
|
|
{ from: /^src\//, to: '' }, // Strip the src/ prefix
|
|
{ from: /\.(t|j)sx?$/, to: '.js' } // Convert .ts to .js
|
|
];
|
|
|
|
mod.path = replace(mod.path, terms);
|
|
|
|
for (const ex of mod.exports ?? []) {
|
|
ex.declaration.module = replace(ex.declaration.module, terms);
|
|
}
|
|
|
|
for (const dec of mod.declarations ?? []) {
|
|
if (dec.kind === 'class') {
|
|
for (const member of dec.members ?? []) {
|
|
if (member.inheritedFrom) {
|
|
member.inheritedFrom.module = replace(member.inheritedFrom.module, terms);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
},
|
|
// Generate custom VS Code data
|
|
generateCustomData({
|
|
outdir,
|
|
cssFileName: null
|
|
})
|
|
]
|
|
};
|