Skip to content

Commit

Permalink
fix: provide correct react typings (#3269)
Browse files Browse the repository at this point in the history
This removes the SSR extensions, which have not been in use by now. This
fixes an issue with the React typings.
  • Loading branch information
kyubisation authored Dec 3, 2024
1 parent 911ccdd commit 8e0be99
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 216 deletions.
1 change: 0 additions & 1 deletion src/react/core.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './core/create-component.js';
export * from './core/ssr-extensions.js';
100 changes: 0 additions & 100 deletions src/react/core/ssr-extensions.ts

This file was deleted.

28 changes: 0 additions & 28 deletions tools/manifest/custom-elements-manifest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ export function createManifestConfig(library = '') {
plugins: [
{
analyzePhase({ ts, node, moduleDoc }) {
function setSsrSlotState(classNode) {
const classDoc = moduleDoc.declarations.find(
(declaration) => declaration.name === classNode.name.getText(),
);
classDoc['_ssrslotstate'] = true;
}

function replace(typeObj, typeName, typeValue) {
if (typeObj && typeObj.text) {
typeObj.text = typeObj.text.replace(typeName, typeValue);
Expand Down Expand Up @@ -102,28 +95,7 @@ export function createManifestConfig(library = '') {
});
}

if (ts.isNewExpression(node) && node.expression.getText() === 'SbbSlotStateController') {
let classNode = node;
while (classNode) {
if (ts.isClassDeclaration(classNode)) {
setSsrSlotState(classNode);
}
classNode = classNode.parent;
}
}

if (ts.isClassDeclaration(node)) {
/**
* The usage of the `slotState` decorator breaks the logic in the previous block of code,
* since the decorated class has no explicit usage of the `SbbSlotStateController` constructor any more.
*/
const decorators = ts.getDecorators(node);
if (decorators && decorators.length > 0) {
if (decorators.find((e) => e.getText() === '@slotState()')) {
setSsrSlotState(node);
}
}

/**
* When a generic T type is used in a superclass declaration, it overrides the type defined in derived class
* during the doc generation (as the `value` property in the `SbbFormAssociatedMixinType`).
Expand Down
91 changes: 4 additions & 87 deletions tools/vite/generate-react-wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ import {
} from 'fs';
import { pathToFileURL } from 'node:url';

import type {
Package,
Export,
CustomElementDeclaration,
Module,
ClassField,
ClassDeclaration,
Declaration,
} from 'custom-elements-manifest';
import type { Package, Export, CustomElementDeclaration, Module } from 'custom-elements-manifest';
import type { PluginOption } from 'vite';

import { distDir } from './build-meta.js';
Expand Down Expand Up @@ -52,9 +44,6 @@ export function generateReactWrappers(
name: 'generate-react-wrappers',
config(config) {
const packageRoot = pathToFileURL(config.root!);
const declarations = manifest.modules
.filter((m) => m.kind === 'javascript-module' && m.declarations?.length)
.reduce((current, next) => current.concat(next.declarations ?? []), [] as Declaration[]);
const exports = manifest.modules.reduce(
(current, next) => current.concat(next.exports ?? []),
[] as Export[],
Expand All @@ -70,7 +59,6 @@ export function generateReactWrappers(
createDir(new URL('.', targetPath));
const reactTemplate = renderTemplate(
declaration,
declarations,
module,
exports,
library,
Expand Down Expand Up @@ -122,26 +110,15 @@ export function generateReactWrappers(

function renderTemplate(
declaration: CustomElementDeclaration,
declarations: Declaration[],
module: Module,
exports: Export[],
library: string,
isMainLibrary: boolean,
): string {
const extensions = findExtensionUsage(declaration, declarations);
const dirDepth = module.path.split('/').length - 1;
const coreImportPath = isMainLibrary
? `${!dirDepth ? './' : '../'.repeat(dirDepth)}core.js`
: `@sbb-esta/lyne-react/core.js`;
const extensionImport = !extensions.size
? ''
: `
import { ${Array.from(extensions.keys()).join(', ')} } from '${coreImportPath}';`;
const extension = [...extensions.values()].reduce(
(current, next) => (v) => current(next(v)),
(v: string) => v,
);
const componentsImports = new Map<string, string[]>().set(module.path, [declaration.name]);
const customEventTypes =
declaration.events
Expand Down Expand Up @@ -183,10 +160,10 @@ function renderTemplate(
${Array.from(componentsImports)
.map(([key, imports]) => `import { ${imports.join(', ')} } from '${library}/${key}';`)
.join('\n')}
import react from 'react';${extensionImport}
import react from 'react';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const ${declaration.name.replace(/Element$/, '')} = ${extension(`createComponent({
export const ${declaration.name.replace(/Element$/, '')} = createComponent({
tagName: '${
// eslint-disable-next-line lyne/local-name-rule
declaration.tagName
Expand All @@ -208,67 +185,7 @@ function renderTemplate(
`
: ''
}
})`)};
});
`;
return reactTemplate;
}

function findExtensionUsage(
declaration: ClassDeclaration,
declarations: Declaration[],
): Map<string, (_: string) => string> {
const extensions = new Map<string, (_: string) => string>();
if (usesSsrSlotState(declaration, declarations)) {
extensions.set('withSsrDataSlotNames', (v) => `withSsrDataSlotNames(${v})`);
}
const childTypes = namedSlotListElements(declaration);
if (childTypes.length) {
extensions.set(
'withSsrDataChildCount',
(v) => `withSsrDataChildCount([${childTypes.map((t) => `'${t}'`).join(', ')}], ${v})`,
);
}
return extensions;
}

// eslint-disable-next-line @typescript-eslint/naming-convention
type ClassDeclarationSSR = ClassDeclaration & { _ssrslotstate?: boolean };
const ssrSlotStateKey = '_ssrslotstate';
function usesSsrSlotState(
declaration: ClassDeclarationSSR | undefined,
declarations: Declaration[],
): boolean {
while (declaration) {
if (
declaration[ssrSlotStateKey] ||
declaration.mixins?.some((m) =>
declarations.find((d) => d.name === m.name && (d as ClassDeclarationSSR)[ssrSlotStateKey]),
)
) {
return true;
}

declaration = declarations.find(
(d): d is ClassDeclarationSSR => d.name === declaration!.superclass?.name,
);
}

return false;
}

function namedSlotListElements(declaration: ClassDeclaration): string[] {
return (
declaration.members
?.find(
(m): m is ClassField =>
m.inheritedFrom?.name === 'NamedSlotListElement' && m.name === 'listChildLocalNames',
)
?.default?.match(/([\w-]+)/g)
?.map((m) =>
m
.split('-')
.map((s) => s[0] + s.substring(1).toLowerCase())
.join(''),
) ?? []
);
}

0 comments on commit 8e0be99

Please sign in to comment.