[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: update to use dynamic imports for web components #210

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a327c2f
Use dynamic imports for web components
web-padawan Dec 26, 2023
e2c9422
Import from theme folder
web-padawan Jan 8, 2024
6047f1d
Fix import for chart-series and iconset
web-padawan Jan 8, 2024
b98d577
Add ts-ignore comment to dynamic imports
web-padawan Jan 8, 2024
394b639
Fix Select to not throw before defined
web-padawan Jan 8, 2024
6fbc419
Re-export types, revert some changes
web-padawan Jan 8, 2024
bc60bfa
Make column re-export from Grid type-only
web-padawan Jan 8, 2024
d68079f
Update ComboBox tests to use await
web-padawan Jan 8, 2024
51bfb3e
Use type-only imports in typings tests
web-padawan Jan 8, 2024
ba1f784
Make Dialog and VirtualList tests async
web-padawan Jan 8, 2024
d2da13a
Make MenuBar and Notification tests async
web-padawan Jan 8, 2024
539eff7
Make ContextMenu and Select tests async
web-padawan Jan 8, 2024
7e55b1f
Fix MultiSelectComboBox event spy in test
web-padawan Jan 8, 2024
77e1d43
Add TODO comment clarifying need for ts-ignore
web-padawan Jan 15, 2024
6948a00
Suppress post-finalize style warning
web-padawan Jan 15, 2024
9652fb1
Revert GridDefaultItem import change
web-padawan Jan 15, 2024
d90f5d8
Make Notification.show import the WC if needed
web-padawan Jan 15, 2024
d4b6ad1
Mark CrudEditColumn as element without theme
web-padawan Jan 15, 2024
3fbf642
Add vaadin-crud-edit to elements without theme
web-padawan Jan 15, 2024
e4533c2
Apply code review suggestion regarding render
web-padawan Jan 15, 2024
8649529
Add define option to call importFunc explicitly
web-padawan Jan 16, 2024
af6f700
Update Dialog to expose define helper
web-padawan Jan 16, 2024
c77b8ca
Fix MenuBar test suite to use type-only import
web-padawan Jan 16, 2024
acfa5ba
Update ContextMenu to expose define helper
web-padawan Jan 16, 2024
16e76c0
Update Select to expose define helper
web-padawan Jan 16, 2024
bf4b085
Update VirtualList to expose define helper
web-padawan Jan 16, 2024
2d36906
Update ComboBox to expose define helper
web-padawan Jan 16, 2024
286ec7f
Update ComboBoxLight to expose define helper
web-padawan Jan 17, 2024
b862067
Update MenuBar to expose define helper
web-padawan Jan 17, 2024
5089f60
Update MultiSelectComboBox to expose define helper
web-padawan Jan 17, 2024
edfca5b
Update Notification to expose define helper
web-padawan Jan 17, 2024
8a17135
Add define helper to components return types
web-padawan Jan 17, 2024
f801fa9
Update DateTimePicker to expose define helper
web-padawan Jan 17, 2024
fd5bc44
Update TimePicker to expose define helper
web-padawan Jan 17, 2024
ca6fbcc
Update TabSheet to expose define helper
web-padawan Jan 17, 2024
2a59862
Add define to Grid, GridPro and columns
web-padawan Jan 17, 2024
84e7dc2
Revert no longer needed generator tweaks
web-padawan Jan 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dev/kitchen-sink/Row3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ComboBox } from '../../src/ComboBox.js';
import { ContextMenu } from '../../src/ContextMenu.js';
import { CookieConsent } from '../../src/CookieConsent.js';
import { Crud, crudPath } from '../../src/Crud.js';
import { CrudEditColumn } from '../../src/CrudEditColumn.js';
import { FormLayout } from '../../src/FormLayout.js';
import { Item } from '../../src/Item.js';
import { ListBox } from '../../src/ListBox.js';
Expand All @@ -22,6 +23,7 @@ export default function Row3() {
</ContextMenu>
<CookieConsent position="bottom-right"></CookieConsent>
<Crud items={crudData}>
<CrudEditColumn></CrudEditColumn>
<FormLayout slot="form">
<TextField label="Name" {...crudPath('name')} />
<ComboBox label="Role" items={Object.values(CrudRole)} {...crudPath('role')} />
Expand Down
2 changes: 1 addition & 1 deletion dev/pages/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Grid, type GridDataProvider } from '../../src/Grid.js';
import { GridSelectionColumn } from '../../src/GridSelectionColumn.js';
import { GridTreeColumn } from '../../src/GridTreeColumn.js';
import { GridColumn, GridColumnElement } from '../../src/GridColumn.js';
import { GridColumn, type GridColumnElement } from '../../src/GridColumn.js';
import { Tooltip } from '../../src/Tooltip.js';

type Item = {
Expand Down
52 changes: 43 additions & 9 deletions scripts/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const CREATE_COMPONENT_PATH = '$CREATE_COMPONENT_PATH$';
const EVENT_MAP = '$EVENT_MAP$';
const EVENT_MAP_REF_IN_EVENTS = '$EVENT_MAP_REF_IN_EVENTS$';
const EVENTS_DECLARATION = '$EVENTS_DECLARATION$';
const PROPERTIES_DECLARATION = '$PROPERTIES_DECLARATION$';
const LIT_REACT_PATH = '@lit/react';
const MODULE_PATH = '$MODULE_PATH$';

Expand Down Expand Up @@ -89,6 +90,10 @@ function isEventListDeclaration(node: Node): node is Identifier {
return ts.isIdentifier(node) && node.text === EVENTS_DECLARATION;
}

function isPropertiesListDeclaration(node: Node): node is Identifier {
return ts.isIdentifier(node) && node.text === PROPERTIES_DECLARATION;
}

function isEventMapReferenceInEventsDeclaration(node: Node): node is Identifier {
return ts.isIdentifier(node) && node.text === EVENT_MAP_REF_IN_EVENTS;
}
Expand Down Expand Up @@ -161,6 +166,29 @@ function createEventList(elementName: string, events: readonly NamedGenericJsCon
);
}

function createPropertiesList(
elementName: string,
properties: readonly NamedGenericJsContribution[] | undefined,
): Node {
return ts.factory.createObjectLiteralExpression([
ts.factory.createPropertyAssignment(
ts.factory.createIdentifier('name'),
ts.factory.createStringLiteral(elementName),
),
ts.factory.createPropertyAssignment(
ts.factory.createIdentifier('_properties'),
ts.factory.createObjectLiteralExpression(
properties?.map((property) => {
return ts.factory.createPropertyAssignment(
ts.factory.createIdentifier(property.name),
ts.factory.createStringLiteral(''),
);
}),
),
),
]);
}

function removeAllEventRelated(node: Node, hasEvents: boolean, hasKnownEvents: boolean): Node | undefined {
if (hasEvents && hasKnownEvents) {
return node;
Expand Down Expand Up @@ -260,9 +288,9 @@ function addGenerics(node: Node, elementName: string) {

const asExpression = template(
`
${CALL_EXPRESSION} as (
${CALL_EXPRESSION} as ((
props: ${COMPONENT_NAME}Props & React.RefAttributes<${COMPONENT_NAME}Element>,
) => React.ReactElement | null
) => React.ReactElement | null) & { define: () => Promise<void> }
`,
(statements) => (statements[0] as ExpressionStatement).expression,
[
Expand Down Expand Up @@ -302,6 +330,7 @@ function generateReactComponent({ name, js }: SchemaHTMLElement, { packageName,

const hasEvents = !!js?.events && js.events.length > 0;
const events = js?.events;
const properties = js?.properties as readonly NamedGenericJsContribution[] | undefined;
const eventNameMissingLogger = () => console.error(`[${packageName}]: event name is missing`);
const namedEvents = pickNamedEvents(events, eventNameMissingLogger);
const { remove: eventsToRemove, makeUnknown: eventsToBeUnknown } = eventSettings.get(elementName) ?? {};
Expand All @@ -311,27 +340,31 @@ function generateReactComponent({ name, js }: SchemaHTMLElement, { packageName,
const ast = template(
`
import type { EventName } from "${LIT_REACT_PATH}";
import {
import type {
${COMPONENT_NAME} as ${COMPONENT_NAME}Element
type ${COMPONENT_NAME}EventMap as _${COMPONENT_NAME}EventMap,
${COMPONENT_NAME}EventMap as _${COMPONENT_NAME}EventMap,
} from "${MODULE_PATH}";
import * as React from "react";
import { createComponent, type WebComponentProps } from "${CREATE_COMPONENT_PATH}";
import { createComponent, type PolymerConstructor, type WebComponentProps } from "${CREATE_COMPONENT_PATH}";

const importFunc = () => import("${MODULE_PATH}");

export * from "${MODULE_PATH}";
export type * from "${MODULE_PATH}";

export {
export type {
${COMPONENT_NAME}Element,
};

export type ${EVENT_MAP};
const elementClass = ${PROPERTIES_DECLARATION} as unknown as PolymerConstructor<${COMPONENT_NAME}Element>;
const events = ${EVENTS_DECLARATION} as ${EVENT_MAP_REF_IN_EVENTS};
export type ${COMPONENT_NAME}Props = WebComponentProps<${COMPONENT_NAME}Element, ${EVENT_MAP}>;
export const ${COMPONENT_NAME} = createComponent({
elementClass: ${COMPONENT_NAME}Element,
elementClass,
events,
react: React,
tagName: ${COMPONENT_TAG}
tagName: ${COMPONENT_TAG},
importFunc
});
`,
(statements) => statements,
Expand All @@ -341,6 +374,7 @@ export const ${COMPONENT_NAME} = createComponent({
isEventMapDeclaration(node) ? createEventMapDeclaration(node, elementName, namedEvents) : node,
),
transform((node) => (isEventListDeclaration(node) ? createEventList(elementName, namedEvents) : node)),
transform((node) => (isPropertiesListDeclaration(node) ? createPropertiesList(elementName, properties) : node)),
transform((node) => addGenerics(node, elementName)),
transform((node) => {
if (!ts.isStringLiteral(node)) {
Expand Down
6 changes: 3 additions & 3 deletions src/ChartSeries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { HTMLAttributes, ReactElement, RefAttributes } from 'react';
import {
ChartSeriesElement,
type ChartSeriesElement,
ChartSeries as _ChartSeries,
type ChartSeriesProps as _ChartSeriesProps,
} from './generated/ChartSeries.js';
Expand All @@ -14,6 +14,6 @@ type OmittedChartSeriesHTMLAttributes = Omit<

export type ChartSeriesProps = Partial<Omit<_ChartSeriesProps, keyof OmittedChartSeriesHTMLAttributes>>;

export const ChartSeries = _ChartSeries as (
export const ChartSeries = _ChartSeries as ((
props: ChartSeriesProps & RefAttributes<ChartSeriesElement>,
) => ReactElement | null;
) => ReactElement | null) & { define: () => Promise<void> };
9 changes: 8 additions & 1 deletion src/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ function ComboBox<TItem = ComboBoxDefaultItem>(
);
}

function withDefine<T extends typeof ComboBox>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _ComboBox.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedComboBox = forwardRef(ComboBox) as <TItem = ComboBoxDefaultItem>(
props: ComboBoxProps<TItem> & RefAttributes<ComboBoxElement<TItem>>,
) => ReactElement | null;

export { ForwardedComboBox as ComboBox };
const ComboBoxWithDefine = withDefine(ForwardedComboBox);

export { ComboBoxWithDefine as ComboBox };
9 changes: 8 additions & 1 deletion src/ComboBoxLight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ function ComboBoxLight<TItem = ComboBoxDefaultItem>(
);
}

function withDefine<T extends typeof ComboBoxLight>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _ComboBoxLight.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedComboBoxLight = forwardRef(ComboBoxLight) as <TItem = ComboBoxDefaultItem>(
props: ComboBoxLightProps<TItem> & RefAttributes<ComboBoxLightElement<TItem>>,
) => ReactElement | null;

export { ForwardedComboBoxLight as ComboBoxLight };
const ComboBoxLightWithDefine = withDefine(ForwardedComboBoxLight);

export { ComboBoxLightWithDefine as ComboBoxLight };
6 changes: 3 additions & 3 deletions src/ConfirmDialog.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { HTMLAttributes, ReactElement, RefAttributes } from 'react';
import {
ConfirmDialogElement,
type ConfirmDialogElement,
ConfirmDialog as _ConfirmDialog,
type ConfirmDialogProps as _ConfirmDialogProps,
} from './generated/ConfirmDialog.js';
Expand All @@ -14,6 +14,6 @@ type OmittedConfirmDialogHTMLAttributes = Omit<

export type ConfirmDialogProps = Partial<Omit<_ConfirmDialogProps, keyof OmittedConfirmDialogHTMLAttributes>>;

export const ConfirmDialog = _ConfirmDialog as (
export const ConfirmDialog = _ConfirmDialog as ((
props: ConfirmDialogProps & RefAttributes<ConfirmDialogElement>,
) => ReactElement | null;
) => ReactElement | null) & { define: () => Promise<void> };
17 changes: 15 additions & 2 deletions src/ContextMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { type ComponentType, type ForwardedRef, forwardRef, type ReactElement } from 'react';
import {
type ComponentType,
type ForwardedRef,
type ForwardRefExoticComponent,
forwardRef,
type ReactElement,
type RefAttributes,
} from 'react';
import {
ContextMenu as _ContextMenu,
type ContextMenuRendererContext,
Expand Down Expand Up @@ -63,6 +70,12 @@ function ContextMenu(props: ContextMenuProps, ref: ForwardedRef<ContextMenuEleme
);
}

const ForwardedContextMenu = forwardRef(ContextMenu);
const ForwardedContextMenu = forwardRef(ContextMenu) as ForwardRefExoticComponent<
ContextMenuProps & RefAttributes<ContextMenuElement>
> & {
define(): Promise<void>;
};

Object.assign(ForwardedContextMenu, { define: _ContextMenu.define });

export { ForwardedContextMenu as ContextMenu };
6 changes: 3 additions & 3 deletions src/CookieConsent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { HTMLAttributes, ReactElement, RefAttributes } from 'react';
import {
CookieConsentElement,
type CookieConsentElement,
CookieConsent as _CookieConsent,
type CookieConsentProps as _CookieConsentProps,
} from './generated/CookieConsent.js';
Expand All @@ -14,6 +14,6 @@ type OmittedCookieConsentHTMLAttributes = Omit<

export type CookieConsentProps = Partial<Omit<_CookieConsentProps, keyof OmittedCookieConsentHTMLAttributes>>;

export const CookieConsent = _CookieConsent as (
export const CookieConsent = _CookieConsent as ((
props: CookieConsentProps & RefAttributes<CookieConsentElement>,
) => ReactElement | null;
) => ReactElement | null) & { define: () => Promise<void> };
12 changes: 9 additions & 3 deletions src/DateTimePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef } from 'react';
import { type ForwardRefExoticComponent, forwardRef, type RefAttributes } from 'react';
import {
DateTimePicker as _DateTimePicker,
type DateTimePickerElement,
Expand All @@ -8,6 +8,12 @@ import createComponentWithOrderedProps from './utils/createComponentWithOrderedP

export * from './generated/DateTimePicker.js';

export const DateTimePicker = forwardRef(
const ForwardedDateTimePicker = forwardRef(
createComponentWithOrderedProps<DateTimePickerProps, DateTimePickerElement>(_DateTimePicker, 'value'),
);
) as ForwardRefExoticComponent<DateTimePickerProps & RefAttributes<DateTimePickerElement>> & {
define(): Promise<void>;
};

Object.assign(ForwardedDateTimePicker, { define: _DateTimePicker.define });

export { ForwardedDateTimePicker as DateTimePicker };
8 changes: 7 additions & 1 deletion src/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
type ComponentType,
type ForwardedRef,
type ForwardRefExoticComponent,
type HTMLAttributes,
forwardRef,
type ReactElement,
type ReactNode,
type RefAttributes,
} from 'react';
import { Dialog as _Dialog, type DialogElement, type DialogProps as _DialogProps } from './generated/Dialog.js';
import { useSimpleOrChildrenRenderer } from './renderers/useSimpleOrChildrenRenderer.js';
Expand Down Expand Up @@ -48,6 +50,10 @@ function Dialog(
);
}

const ForwardedDialog = forwardRef(Dialog);
const ForwardedDialog = forwardRef(Dialog) as ForwardRefExoticComponent<DialogProps & RefAttributes<DialogElement>> & {
define(): Promise<void>;
};

Object.assign(ForwardedDialog, { define: _Dialog.define });

export { ForwardedDialog as Dialog };
13 changes: 10 additions & 3 deletions src/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { useModelRenderer } from './renderers/useModelRenderer.js';
// suggested in React context, see https://github.com/vaadin/react-components/issues/68
// Fix: use re-exports from raw "src/vaadin-grid.js" as a workaround, until
// the re-export is removed.
export * from '@vaadin/grid/src/vaadin-grid.js';
export { GridElement, type GridEventMap } from './generated/Grid.js';
export type * from '@vaadin/grid/src/vaadin-grid.js';
export type { GridElement, GridEventMap } from './generated/Grid.js';

export type GridProps<TItem> = Partial<Omit<_GridProps<TItem>, 'rowDetailsRenderer'>> &
Readonly<{
Expand All @@ -35,8 +35,15 @@ function Grid<TItem = GridDefaultItem>(
);
}

function withDefine<T extends typeof Grid>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _Grid.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedGrid = forwardRef(Grid) as <TItem = GridDefaultItem>(
props: GridProps<TItem> & RefAttributes<GridElement<TItem>>,
) => ReactElement | null;

export { ForwardedGrid as Grid };
const GridWithDefine = withDefine(ForwardedGrid);

export { GridWithDefine as Grid };
9 changes: 8 additions & 1 deletion src/GridColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,15 @@ function GridColumn<TItem = GridDefaultItem>(
);
}

function withDefine<T extends typeof GridColumn>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _GridColumn.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedGridColumn = forwardRef(GridColumn) as <TItem = GridDefaultItem>(
props: GridColumnProps<TItem> & RefAttributes<GridColumnElement<TItem>>,
) => ReactElement | null;

export { ForwardedGridColumn as GridColumn };
const GridColumnWithDefine = withDefine(ForwardedGridColumn);

export { GridColumnWithDefine as GridColumn };
9 changes: 8 additions & 1 deletion src/GridColumnGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,15 @@ function GridColumnGroup(
);
}

function withDefine<T extends typeof GridColumnGroup>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _GridColumnGroup.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedGridColumnGroup = forwardRef(GridColumnGroup) as (
props: GridColumnGroupProps & RefAttributes<GridColumnGroupElement>,
) => ReactElement | null;

export { ForwardedGridColumnGroup as GridColumnGroup };
const GridColumnGroupWithDefine = withDefine(ForwardedGridColumnGroup);

export { GridColumnGroupWithDefine as GridColumnGroup };
9 changes: 8 additions & 1 deletion src/GridFilterColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,15 @@ function GridFilterColumn<TItem = GridDefaultItem>(
);
}

function withDefine<T extends typeof GridFilterColumn>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _GridFilterColumn.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedGridFilterColumn = forwardRef(GridFilterColumn) as <TItem = GridDefaultItem>(
props: GridFilterColumnProps<TItem> & RefAttributes<GridFilterColumnElement<TItem>>,
) => ReactElement | null;

export { ForwardedGridFilterColumn as GridFilterColumn };
const GridFilterColumnWithDefine = withDefine(ForwardedGridFilterColumn);

export { GridFilterColumnWithDefine as GridFilterColumn };
9 changes: 8 additions & 1 deletion src/GridPro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ function GridPro<TItem = GridDefaultItem>(
);
}

function withDefine<T extends typeof GridPro>(component: T): T & { define: () => Promise<void> } {
Object.assign(component, { define: _GridPro.define });
return component as T & { define: () => Promise<void> };
}

const ForwardedGridPro = forwardRef(GridPro) as <TItem = GridDefaultItem>(
props: GridProProps<TItem> & RefAttributes<GridProElement<TItem>>,
) => ReactElement | null;

export { ForwardedGridPro as GridPro };
const GridProWithDefine = withDefine(ForwardedGridPro);

export { GridProWithDefine as GridPro };
Loading