Skip to content

Commit

Permalink
feat: update @ui5/webcomponents to ~1.22.0 (#5219)
Browse files Browse the repository at this point in the history
And create a new (private) `cli` package which exposes our wrapper creation script to third-party web component libraries mid term.

---------

Co-authored-by: Lukas Harbarth <lukas.harbarth@sap.com>
  • Loading branch information
MarcusNotheis and Lukas742 authored Feb 5, 2024
1 parent c148f42 commit 250ad0d
Show file tree
Hide file tree
Showing 422 changed files with 5,673 additions and 5,109 deletions.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ packages/base/types
# build results for charts package
packages/charts/dist

# build results for cli package
packages/cli/dist

# build results for main package
packages/main/dist
packages/main/ssr
Expand Down
34 changes: 0 additions & 34 deletions .github/workflows/test-web-components.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .storybook/components/DocsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ export const DocsHeader = ({ since }) => {
</FlexBox>
<Subtitle />
<InfoTable since={since} />
<Description />
<TableOfContent />
<Description />
</ThemeProvider>
);
};
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"prettier:all": "prettier --write --config ./prettier.config.cjs \"packages/**/*.{js,jsx,ts,tsx,mdx,json,md}\"",
"lint": "eslint packages --ext .ts,.tsx",
"lerna:version-dryrun": "lerna version --conventional-graduate --no-git-tag-version --no-push",
"create-webcomponents-wrapper": "node --experimental-json-modules ./packages/main/scripts/create-web-components-wrapper.mjs && node --experimental-json-modules ./scripts/generate-theming-parameters.js",
"wrappers:main": "WITH_WEB_COMPONENT_IMPORT_PATH='../../internal/withWebComponent.js' INTERFACES_IMPORT_PATH='../../types/index.js' node packages/cli/dist/bin/index.js create-wrappers --packageName @ui5/webcomponents --out ./packages/main/src/webComponents --additionalComponentNote 'This is a UI5 Web Component! [Repository](https://github.com/SAP/ui5-webcomponents) | [Documentation](https://sap.github.io/ui5-webcomponents/playground/)'",
"wrappers:fiori": "WITH_WEB_COMPONENT_IMPORT_PATH='../../internal/withWebComponent.js' INTERFACES_IMPORT_PATH='../../types/index.js' node packages/cli/dist/bin/index.js create-wrappers --packageName @ui5/webcomponents-fiori --out ./packages/main/src/webComponents --additionalComponentNote 'This is a UI5 Web Component! [Repository](https://github.com/SAP/ui5-webcomponents) | [Documentation](https://sap.github.io/ui5-webcomponents/playground/)'",
"create-webcomponents-wrapper": "yarn run wrappers:main && yarn run wrappers:fiori && prettier --log-level silent --write ./packages/main/src/webComponents && eslint --fix ./packages/main/src/webComponents/*/index.tsx",
"chromatic": "cross-env STORYBOOK_ENV=chromatic npx chromatic --build-script-name build:storybook",
"postinstall": "husky && yarn prepare",
"create-cypress-commands-docs": "typedoc && rimraf temp/typedoc"
Expand All @@ -35,9 +37,9 @@
"@storybook/react": "7.6.12",
"@storybook/react-vite": "7.6.12",
"@storybook/theming": "7.6.12",
"@ui5/webcomponents": "1.21.2",
"@ui5/webcomponents-fiori": "1.21.2",
"@ui5/webcomponents-icons": "1.21.2",
"@ui5/webcomponents": "1.22.0",
"@ui5/webcomponents-fiori": "1.22.0",
"@ui5/webcomponents-icons": "1.22.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"remark-gfm": "^3.0.1",
Expand All @@ -55,9 +57,10 @@
"@types/node": "^20.0.0",
"@types/react": "^18.2.23",
"@types/react-dom": "^18.2.7",
"@types/turndown": "^5.0.4",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@ui5/webcomponents-tools": "1.21.2",
"@ui5/webcomponents-tools": "1.22.0",
"@vitejs/plugin-react": "^4.2.0",
"chromatic": "^10.0.0",
"cssnano": "^6.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"peerDependencies": {
"@types/react": "*",
"@ui5/webcomponents-base": "~1.21.0",
"@ui5/webcomponents-base": "~1.22.0",
"react": "^16.14.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
Expand Down
4 changes: 2 additions & 2 deletions packages/charts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"recharts": "2.11.0"
},
"peerDependencies": {
"@ui5/webcomponents-react": "~1.24.0",
"@ui5/webcomponents-react-base": "~1.24.0",
"@ui5/webcomponents-react": "~1.25.0",
"@ui5/webcomponents-react-base": "~1.25.0",
"react": "^16.14.0 || ^17.0.0 || ^18.0.0",
"react-jss": "^10.10.0"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
test
39 changes: 39 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@ui5/webcomponents-react-cli",
"private": true,
"description": "CLI for UI5 Web Components for React",
"author": "SAP SE (https://www.sap.com)",
"license": "Apache-2.0",
"version": "1.22.0",
"type": "module",
"types": "./dist/index.d.ts",
"main": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"bin": {
"ui5-wcr": "./dist/bin/index.js"
},
"repository": {
"type": "git",
"url": "https://github.com/SAP/ui5-webcomponents-react",
"directory": "packages/cli"
},
"scripts": {
"clean": "rimraf dist"
},
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"dependencies": {
"dedent": "^1.5.1",
"turndown": "^7.1.2"
}
}
55 changes: 55 additions & 0 deletions packages/cli/src/bin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env node
import { resolve } from 'node:path';
import { parseArgs } from 'node:util';
import * as process from 'process';

const options = {
packageName: {
type: 'string' as const
},
out: {
type: 'string' as const,
short: 'o'
},
additionalComponentNote: {
type: 'string' as const
}
};
const { values, positionals } = parseArgs({ options, allowPositionals: true });

const [command] = positionals;

console.log(command);

switch (command) {
case 'create-wrappers':
const { packageName, out, additionalComponentNote } = values;
const missingParameters = [];
if (!packageName) {
missingParameters.push('--packageName');
}
if (!out) {
missingParameters.push('--out');
}

if (missingParameters.length > 0) {
console.error(`
Missing parameters: ${missingParameters.join(', ')}
Example: ui5-wcr create-wrappers --packageName @ui5/webcomponents --out ./src/components
Please add the missing parameters and try again.
`);
process.exit(1);
}

const createWrapperModule = await import('../scripts/create-wrappers/main.js');

const outDir = resolve(process.cwd(), values.out!);
// eslint-disable-next-line @typescript-eslint/await-thenable
await createWrapperModule.default(packageName!, outDir, { additionalComponentNote });
process.exit(0);
break;
default:
console.warn('Unknown command', command);
process.exit(1);
}
19 changes: 19 additions & 0 deletions packages/cli/src/scripts/create-wrappers/AbstractRenderer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { WebComponentWrapper } from './WebComponentWrapper.js';

export enum RenderingPhase {
imports = 'imports',
attributes = 'attributes',
props = 'props',
domRef = 'domRef',
component = 'component',
exports = 'exports'
}

export abstract class AbstractRenderer {
public readonly phase!: RenderingPhase;

public prepare(context: WebComponentWrapper) {
// optional
}
abstract render(context: WebComponentWrapper): string;
}
102 changes: 102 additions & 0 deletions packages/cli/src/scripts/create-wrappers/AttributesRenderer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import type * as CEM from '@ui5/webcomponents-tools/lib/cem/types-internal.d.ts';
import dedent from 'dedent';
import {
mapWebComponentTypeToPrimitive,
propDescriptionFormatter,
snakeCaseToCamelCase
} from '../../util/formatters.js';
import { resolveReferenceImports } from '../../util/referenceResolver.js';
import { AbstractRenderer, RenderingPhase } from './AbstractRenderer.js';
import { WebComponentWrapper } from './WebComponentWrapper.js';

const loggedTypes = new Set<string>();

function mapWebComponentTypeToTsType(type: string) {
const primitive = mapWebComponentTypeToPrimitive(type);
if (primitive) {
return primitive;
}
switch (type) {
case 'HTMLElement | string | undefined':
case 'HTMLElement | string':
// opener props only accept strings as prop types
return 'string';

default:
if (!loggedTypes.has(type)) {
console.log('-> Attributes type', type);
loggedTypes.add(type);
}
return type;
}
}

export class AttributesRenderer extends AbstractRenderer {
public phase = RenderingPhase.attributes;

private _attributes: CEM.ClassField[] = [];

setAttributes(value: CEM.Attribute[]) {
this._attributes = value.toSorted((a, b) => a.name.localeCompare(b.name)) as CEM.ClassField[];
return this;
}

private descriptionBuilder(attribute: CEM.ClassField) {
const parts: string[] = [];

parts.push(` * ${propDescriptionFormatter(attribute.description ?? '')}`);
if (attribute.default && attribute.default.length > 0 && attribute.default !== '""') {
parts.push(` * @default ${attribute.default}`);
}

if (attribute.deprecated) {
parts.push(` * @deprecated ${attribute.deprecated}`);
}

return `/**\n${parts.join('\n')}\n */`;
}

private propTyping(attribute: CEM.ClassField, context: WebComponentWrapper) {
let type = attribute.type?.text ?? 'unknown';
type = mapWebComponentTypeToTsType(type);

const references = attribute.type?.references;
const isEnum = references != null && references?.length > 0;

if (isEnum) {
type += ` | keyof typeof ${type}`;
}
if (attribute._ui5validator === 'CSSColor') {
type = `CSSProperties['color']`;
} else if (attribute._ui5validator === 'CSSSize') {
type = `CSSProperties['width'] | CSSProperties['height']`;
}

context.addAttribute(snakeCaseToCamelCase(attribute.name), type);

return `${snakeCaseToCamelCase(attribute.name)}?: ${type};`;
}

prepare(context: WebComponentWrapper) {
for (const attribute of this._attributes) {
// special css handling
if (attribute._ui5validator === 'CSSSize' || attribute._ui5validator === 'CSSColor') {
context.addTypeImport('react', 'CSSProperties');
} else {
resolveReferenceImports(attribute.type?.references ?? [], context);
}
}
}

render(context: WebComponentWrapper): string {
return dedent`
interface ${context.componentName}Attributes {
${this._attributes
.map((attribute) => {
return `${this.descriptionBuilder(attribute)}\n${this.propTyping(attribute, context)}`;
})
.join('\n\n')}
}
`;
}
}
Loading

0 comments on commit 250ad0d

Please sign in to comment.