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

fix: revert useRenderer hook to async rendering #272

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 4 additions & 12 deletions packages/react-components-pro/src/GridProEditColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,10 @@ function GridProEditColumn<TItem = GridDefaultItem>(
{ children, footer, header, ...props }: GridProEditColumnProps<TItem>,
ref: ForwardedRef<GridProEditColumnElement<TItem>>,
): ReactElement | null {
const [editModePortals, editModeRenderer] = useModelRenderer(editColumnReactRenderer(props.editModeRenderer), {
renderSync: true,
});
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [bodyPortals, bodyRenderer] = useModelRenderer(editColumnReactRenderer(props.renderer ?? children), {
renderSync: true,
});
const [editModePortals, editModeRenderer] = useModelRenderer(editColumnReactRenderer(props.editModeRenderer));
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header);
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);
const [bodyPortals, bodyRenderer] = useModelRenderer(editColumnReactRenderer(props.renderer ?? children));

return (
<_GridProEditColumn<TItem>
Expand Down
2 changes: 1 addition & 1 deletion packages/react-components/src/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function Grid<TItem = GridDefaultItem>(
props: GridProps<TItem>,
ref: ForwardedRef<GridElement<TItem>>,
): ReactElement | null {
const [portals, rowDetailsRenderer] = useModelRenderer(props.rowDetailsRenderer, { renderSync: true });
const [portals, rowDetailsRenderer] = useModelRenderer(props.rowDetailsRenderer);

return (
<_Grid<TItem> {...props} ref={ref} rowDetailsRenderer={rowDetailsRenderer}>
Expand Down
12 changes: 3 additions & 9 deletions packages/react-components/src/GridColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,9 @@ function GridColumn<TItem = GridDefaultItem>(
{ children, footer, header, ...props }: GridColumnProps<TItem>,
ref: ForwardedRef<GridColumnElement<TItem>>,
): ReactElement | null {
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? children, {
renderSync: true,
});
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header);
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? children);

return (
<_GridColumn<TItem>
Expand Down
8 changes: 2 additions & 6 deletions packages/react-components/src/GridColumnGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@ function GridColumnGroup(
{ children, footer, header, ...props }: GridColumnGroupProps,
ref: ForwardedRef<GridColumnGroupElement>,
): ReactElement | null {
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header);
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);

return (
<_GridColumnGroup {...props} footerRenderer={footerRenderer} headerRenderer={headerRenderer} ref={ref}>
Expand Down
8 changes: 2 additions & 6 deletions packages/react-components/src/GridFilterColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,8 @@ function GridFilterColumn<TItem = GridDefaultItem>(
{ footer, ...props }: GridFilterColumnProps<TItem>,
ref: ForwardedRef<GridFilterColumnElement<TItem>>,
): ReactElement | null {
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? props.children, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? props.children);

return (
<_GridFilterColumn<TItem> {...props} footerRenderer={footerRenderer} ref={ref} renderer={bodyRenderer}>
Expand Down
12 changes: 3 additions & 9 deletions packages/react-components/src/GridSelectionColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,9 @@ function GridSelectionColumn<TItem = GridDefaultItem>(
{ footer, header, ...props }: GridSelectionColumnProps<TItem>,
ref: ForwardedRef<GridSelectionColumnElement<TItem>>,
): ReactElement | null {
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? props.children, {
renderSync: true,
});
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header);
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? props.children);

return (
<_GridSelectionColumn<TItem>
Expand Down
8 changes: 2 additions & 6 deletions packages/react-components/src/GridSortColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,8 @@ function GridSortColumn<TItem = GridDefaultItem>(
{ footer, ...props }: GridSortColumnProps<TItem>,
ref: ForwardedRef<GridSortColumnElement<TItem>>,
): ReactElement | null {
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? props.children, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);
const [bodyPortals, bodyRenderer] = useModelRenderer(props.renderer ?? props.children);

return (
<_GridSortColumn<TItem> {...props} footerRenderer={footerRenderer} ref={ref} renderer={bodyRenderer}>
Expand Down
8 changes: 2 additions & 6 deletions packages/react-components/src/GridTreeColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,8 @@ function GridTreeColumn<TItem = GridDefaultItem>(
{ footer, header, ...props }: GridTreeColumnProps<TItem>,
ref: ForwardedRef<GridTreeColumnElement<TItem>>,
): ReactElement | null {
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header, {
renderSync: true,
});
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer, {
renderSync: true,
});
const [headerPortals, headerRenderer] = useSimpleOrChildrenRenderer(props.headerRenderer, header);
const [footerPortals, footerRenderer] = useSimpleOrChildrenRenderer(props.footerRenderer, footer);

return (
<_GridTreeColumn<TItem> {...props} headerRenderer={headerRenderer} footerRenderer={footerRenderer} ref={ref}>
Expand Down
5 changes: 2 additions & 3 deletions packages/react-components/src/renderers/useModelRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ComponentType } from 'react';
import type { Slice } from './renderer.js';
import { useRenderer, type RendererConfig, type UseRendererResult } from './useRenderer.js';
import { useRenderer, type UseRendererResult } from './useRenderer.js';

export type Model<I> = Readonly<{
item: I;
Expand All @@ -27,7 +27,6 @@ export function convertModelRendererArgs<I, M extends Model<I>, O extends HTMLEl

export function useModelRenderer<I, M extends Model<I>, O extends HTMLElement>(
reactRenderer?: ComponentType<ReactModelRendererProps<I, M, O>> | null,
config?: RendererConfig,
): UseRendererResult<WebComponentModelRenderer<I, M, O>> {
return useRenderer(reactRenderer, convertModelRendererArgs, config);
return useRenderer(reactRenderer, convertModelRendererArgs);
}
33 changes: 2 additions & 31 deletions packages/react-components/src/renderers/useRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useCallback,
useReducer,
} from 'react';
import { createPortal, flushSync } from 'react-dom';
import { createPortal } from 'react-dom';
import type { Slice, WebComponentRenderer } from './renderer.js';

export type UseRendererResult<W extends WebComponentRenderer> = readonly [
Expand All @@ -24,49 +24,20 @@ function rendererReducer<W extends WebComponentRenderer>(
return new Map(state).set(root, args as Slice<Parameters<W>, 1>);
}

export type RendererConfig = {
renderSync?: boolean;
};

export function useRenderer<P extends {}, W extends WebComponentRenderer>(
node: ReactNode,
convert?: (props: Slice<Parameters<W>, 1>) => PropsWithChildren<P>,
config?: RendererConfig,
): UseRendererResult<W>;
export function useRenderer<P extends {}, W extends WebComponentRenderer>(
reactRenderer: ComponentType<P> | null | undefined,
convert: (props: Slice<Parameters<W>, 1>) => PropsWithChildren<P>,
config?: RendererConfig,
): UseRendererResult<W>;
export function useRenderer<P extends {}, W extends WebComponentRenderer>(
reactRendererOrNode: ReactNode | ComponentType<P> | null | undefined,
convert?: (props: Slice<Parameters<W>, 1>) => PropsWithChildren<P>,
config?: RendererConfig,
): UseRendererResult<W> {
const [map, update] = useReducer<typeof rendererReducer<W>>(rendererReducer, initialState);
const renderer = useCallback(
((...args: Parameters<W>) => {
if (config?.renderSync) {
// The web components may request multiple synchronous renderer calls that
// would result in flushSync logging a warning (and actually executing the
// overlapping flushSync in microtask timing). Suppress the warning and allow
// the resulting asynchronicity.
const console = globalThis.console as any;
const error = console.error;
console.error = (message: string) => {
if (message.includes('flushSync')) {
return;
}
error(message);
};
flushSync(() => update(args));
console.error = error;
} else {
update(args);
}
}) as W,
[],
);
const renderer = useCallback(((...args: Parameters<W>) => update(args)) as W, []);

return reactRendererOrNode
? [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ComponentType, ReactNode } from 'react';
import { useRenderer } from './useRenderer.js';
import type { RendererConfig, UseRendererResult } from './useRenderer.js';
import type { UseRendererResult } from './useRenderer.js';
import {
type ReactSimpleRendererProps,
useSimpleRenderer,
Expand All @@ -10,7 +10,6 @@ import {
export function useSimpleOrChildrenRenderer<O extends HTMLElement>(
fnRenderer?: ComponentType<ReactSimpleRendererProps<O>> | null,
children?: ReactNode | ComponentType<ReactSimpleRendererProps<O>>,
config?: RendererConfig,
): UseRendererResult<WebComponentSimpleRenderer<O>> {
let _children: ReactNode | undefined;
let _fnRenderer: ComponentType<ReactSimpleRendererProps<O>> | null | undefined;
Expand All @@ -26,8 +25,8 @@ export function useSimpleOrChildrenRenderer<O extends HTMLElement>(
shouldUseSimpleRendererResult = !!_fnRenderer;
}

const useChildrenRendererResult = useRenderer(_children, undefined, config);
const useSimpleRendererResult = useSimpleRenderer(_fnRenderer, config);
const useChildrenRendererResult = useRenderer(_children, undefined);
const useSimpleRendererResult = useSimpleRenderer(_fnRenderer);

return shouldUseSimpleRendererResult ? useSimpleRendererResult : useChildrenRendererResult;
}
5 changes: 2 additions & 3 deletions packages/react-components/src/renderers/useSimpleRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ComponentType, PropsWithChildren } from 'react';
import type { Slice } from './renderer.js';
import { useRenderer, type RendererConfig, type UseRendererResult } from './useRenderer.js';
import { useRenderer, type UseRendererResult } from './useRenderer.js';

export type ReactSimpleRendererProps<O extends HTMLElement> = Readonly<{
original: O;
Expand All @@ -16,7 +16,6 @@ function convertSimpleRendererArgs<O extends HTMLElement>([original]: Slice<

export function useSimpleRenderer<O extends HTMLElement>(
reactRenderer?: ComponentType<ReactSimpleRendererProps<O>> | null,
config?: RendererConfig,
): UseRendererResult<WebComponentSimpleRenderer<O>> {
return useRenderer(reactRenderer, convertSimpleRendererArgs, config);
return useRenderer(reactRenderer, convertSimpleRendererArgs);
}
Loading