Skip to content

Commit

Permalink
chore(react): improve react event types & revert lazy loading (#711)
Browse files Browse the repository at this point in the history
* Revert back the lazy loading from #709 
* Separate event types for better DX

Co-authored-by: Aykut Saraç <[email protected]>
  • Loading branch information
AykutSarac and Aykut Saraç authored Sep 27, 2023
1 parent ac32586 commit a3c803e
Showing 1 changed file with 29 additions and 32 deletions.
61 changes: 29 additions & 32 deletions scripts/generate-react-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ const __dirname = path.dirname(__filename);

const importStatements = [
'import React from "react";',
'import { type EventName, createComponent } from "@lit-labs/react";',
'import { type EventName, createComponent, ReactWebComponent } from "@lit-labs/react";',

// FIXME: These types should be determined automatically
'import { ISelectOption } from "./components/select/bl-select"',
];

const exportStatements = [];
const eventStatements = [];

const customElements = fs.readJSONSync(`${__dirname}/../dist/custom-elements.json`);
const customElementsModules = customElements.modules;
Expand All @@ -24,45 +25,40 @@ const baklavaReactFileParts = [];
for (const module of customElementsModules) {
const { declarations, path } = module;
const componentDeclaration = declarations.find(declaration => declaration.customElement === true);

const { events, name: componentName, tagName: fileName, jsDoc } = componentDeclaration;

const eventNames = events
? events.reduce((acc, curr) => {
acc[getReactEventName(curr.name)] = curr.name;
return acc;
}, {})
: {};

const eventTypes = events
? `, {${events
.map(
event =>
`${getReactEventName(event.name)}: EventName<${cleanGenericTypes(
componentDeclaration.typeParameters,
event.type.text
)}>`
)
.join(", ")}}`
: "";
const eventNames = events?.reduce((acc, curr) => {
acc[getReactEventName(curr.name)] = curr.name;
return acc;
}, {}) || {};

const eventTypes = events?.map(event => {
const eventName = getReactEventName(event.name);
const eventType = cleanGenericTypes(componentDeclaration.typeParameters, event.type.text);
const predefinedEventName = `${componentName}${eventName.split("onBl")[1]}`;

eventStatements.push(`export declare type ${predefinedEventName} = ${eventType};`);
return `${eventName}: EventName<${predefinedEventName}>`;
}) || [];

const importPath = path.replace(/^src\//, "").replace(/\.ts$/, "");
const typeName = componentName + "Type";
const componentType = `${typeName}${eventTypes}`;
const formattedEventTypes = eventTypes.length ? `, {${eventTypes.join(", ")}}` : "";
const componentType = `${typeName}${formattedEventTypes}`;

importStatements.push(`import type ${typeName} from "./${importPath}";`);
exportStatements.push(`export declare type ${componentName} = ${typeName}`);

const source = `
${jsDoc}
export const ${componentName}: import("@lit-labs/react").ReactWebComponent<${componentType}> = (
() => createComponent<${componentType}>({
react: React,
displayName: "${componentName}",
tagName: "${fileName}",
elementClass: customElements.get("${fileName}"),
events: ${JSON.stringify(eventNames)},
}));
export const ${componentName}: React.LazyExoticComponent<ReactWebComponent<${componentType}>> =
customElements.whenDefined('${fileName}').then(() => createComponent<${componentType}>({
react: React,
displayName: "${componentName}",
tagName: "${fileName}",
elementClass: customElements.get("${fileName}"),
events: ${JSON.stringify(eventNames)},
}));
`;

baklavaReactFileParts.push(source);
Expand All @@ -79,6 +75,7 @@ function writeBaklavaReactFile(fileContentParts) {
`/* eslint-disable @typescript-eslint/ban-ts-comment */`,
`// @ts-nocheck`,
...importStatements,
...eventStatements,
...exportStatements,
...fileContentParts,
].join("\n\n");
Expand All @@ -92,8 +89,8 @@ function cleanGenericTypes(typeParameters, eventType) {
if (!typeParameters?.length || typeParameters.length === 0) return eventType;

const paramNames = typeParameters.map(param => param.name);
const paramNamesPattern = paramNames.map(name => `<${name}>|${name} \\| | \\| ${name}`).join('|');
const regex = new RegExp(paramNamesPattern, 'g');
const paramNamesPattern = paramNames.map(name => `<${name}>|${name} \\| | \\| ${name}`).join("|");
const regex = new RegExp(paramNamesPattern, "g");

return eventType.replace(regex, '');
return eventType.replace(regex, "");
}

0 comments on commit a3c803e

Please sign in to comment.