From 3fd0be65318330c3ca0fd3da5e0993bc903a1dfc Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Thu, 14 Nov 2024 08:56:03 +0400 Subject: [PATCH 1/3] fix: revert useRenderer hook to async rendering --- .../src/GridProEditColumn.tsx | 16 +++------ packages/react-components/src/Grid.tsx | 2 +- packages/react-components/src/GridColumn.tsx | 12 ++----- .../react-components/src/GridColumnGroup.tsx | 8 ++--- .../react-components/src/GridFilterColumn.tsx | 8 ++--- .../src/GridSelectionColumn.tsx | 12 ++----- .../react-components/src/GridSortColumn.tsx | 8 ++--- .../react-components/src/GridTreeColumn.tsx | 8 ++--- .../src/renderers/useRenderer.ts | 33 ++----------------- 9 files changed, 21 insertions(+), 86 deletions(-) diff --git a/packages/react-components-pro/src/GridProEditColumn.tsx b/packages/react-components-pro/src/GridProEditColumn.tsx index 3aa20bcb..98367a30 100644 --- a/packages/react-components-pro/src/GridProEditColumn.tsx +++ b/packages/react-components-pro/src/GridProEditColumn.tsx @@ -133,18 +133,10 @@ function GridProEditColumn( { children, footer, header, ...props }: GridProEditColumnProps, ref: ForwardedRef>, ): 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 diff --git a/packages/react-components/src/Grid.tsx b/packages/react-components/src/Grid.tsx index 6bc10e8a..299ad7bf 100644 --- a/packages/react-components/src/Grid.tsx +++ b/packages/react-components/src/Grid.tsx @@ -19,7 +19,7 @@ function Grid( props: GridProps, ref: ForwardedRef>, ): ReactElement | null { - const [portals, rowDetailsRenderer] = useModelRenderer(props.rowDetailsRenderer, { renderSync: true }); + const [portals, rowDetailsRenderer] = useModelRenderer(props.rowDetailsRenderer); return ( <_Grid {...props} ref={ref} rowDetailsRenderer={rowDetailsRenderer}> diff --git a/packages/react-components/src/GridColumn.tsx b/packages/react-components/src/GridColumn.tsx index a5979253..811ba89c 100644 --- a/packages/react-components/src/GridColumn.tsx +++ b/packages/react-components/src/GridColumn.tsx @@ -54,15 +54,9 @@ function GridColumn( { children, footer, header, ...props }: GridColumnProps, ref: ForwardedRef>, ): 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 diff --git a/packages/react-components/src/GridColumnGroup.tsx b/packages/react-components/src/GridColumnGroup.tsx index b7518b4e..3bd0eaa3 100644 --- a/packages/react-components/src/GridColumnGroup.tsx +++ b/packages/react-components/src/GridColumnGroup.tsx @@ -40,12 +40,8 @@ function GridColumnGroup( { children, footer, header, ...props }: GridColumnGroupProps, ref: ForwardedRef, ): 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}> diff --git a/packages/react-components/src/GridFilterColumn.tsx b/packages/react-components/src/GridFilterColumn.tsx index 8489a86c..741c3366 100644 --- a/packages/react-components/src/GridFilterColumn.tsx +++ b/packages/react-components/src/GridFilterColumn.tsx @@ -43,12 +43,8 @@ function GridFilterColumn( { footer, ...props }: GridFilterColumnProps, ref: ForwardedRef>, ): 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 {...props} footerRenderer={footerRenderer} ref={ref} renderer={bodyRenderer}> diff --git a/packages/react-components/src/GridSelectionColumn.tsx b/packages/react-components/src/GridSelectionColumn.tsx index df3913c0..223b6dcf 100644 --- a/packages/react-components/src/GridSelectionColumn.tsx +++ b/packages/react-components/src/GridSelectionColumn.tsx @@ -49,15 +49,9 @@ function GridSelectionColumn( { footer, header, ...props }: GridSelectionColumnProps, ref: ForwardedRef>, ): 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 diff --git a/packages/react-components/src/GridSortColumn.tsx b/packages/react-components/src/GridSortColumn.tsx index 3b405a40..d460c527 100644 --- a/packages/react-components/src/GridSortColumn.tsx +++ b/packages/react-components/src/GridSortColumn.tsx @@ -42,12 +42,8 @@ function GridSortColumn( { footer, ...props }: GridSortColumnProps, ref: ForwardedRef>, ): 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 {...props} footerRenderer={footerRenderer} ref={ref} renderer={bodyRenderer}> diff --git a/packages/react-components/src/GridTreeColumn.tsx b/packages/react-components/src/GridTreeColumn.tsx index 85f5aafa..fcd9cedf 100644 --- a/packages/react-components/src/GridTreeColumn.tsx +++ b/packages/react-components/src/GridTreeColumn.tsx @@ -46,12 +46,8 @@ function GridTreeColumn( { footer, header, ...props }: GridTreeColumnProps, ref: ForwardedRef>, ): 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 {...props} headerRenderer={headerRenderer} footerRenderer={footerRenderer} ref={ref}> diff --git a/packages/react-components/src/renderers/useRenderer.ts b/packages/react-components/src/renderers/useRenderer.ts index 79bb02b3..363455e8 100644 --- a/packages/react-components/src/renderers/useRenderer.ts +++ b/packages/react-components/src/renderers/useRenderer.ts @@ -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 = readonly [ @@ -24,49 +24,20 @@ function rendererReducer( return new Map(state).set(root, args as Slice, 1>); } -export type RendererConfig = { - renderSync?: boolean; -}; - export function useRenderer

( node: ReactNode, convert?: (props: Slice, 1>) => PropsWithChildren

, - config?: RendererConfig, ): UseRendererResult; export function useRenderer

( reactRenderer: ComponentType

| null | undefined, convert: (props: Slice, 1>) => PropsWithChildren

, - config?: RendererConfig, ): UseRendererResult; export function useRenderer

( reactRendererOrNode: ReactNode | ComponentType

| null | undefined, convert?: (props: Slice, 1>) => PropsWithChildren

, - config?: RendererConfig, ): UseRendererResult { const [map, update] = useReducer>(rendererReducer, initialState); - const renderer = useCallback( - ((...args: Parameters) => { - 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) => update(args)) as W, []); return reactRendererOrNode ? [ From 1cd8161c1e3dc2bd16a35be2d305239e61cdb3de Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Thu, 14 Nov 2024 09:43:25 +0400 Subject: [PATCH 2/3] fix type errors --- .../react-components/src/renderers/useModelRenderer.ts | 5 ++--- .../src/renderers/useSimpleOrChildrenRenderer.ts | 9 ++++----- .../react-components/src/renderers/useSimpleRenderer.ts | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/react-components/src/renderers/useModelRenderer.ts b/packages/react-components/src/renderers/useModelRenderer.ts index 27476bd3..cc4f71fe 100644 --- a/packages/react-components/src/renderers/useModelRenderer.ts +++ b/packages/react-components/src/renderers/useModelRenderer.ts @@ -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 = Readonly<{ item: I; @@ -27,7 +27,6 @@ export function convertModelRendererArgs, O extends HTMLEl export function useModelRenderer, O extends HTMLElement>( reactRenderer?: ComponentType> | null, - config?: RendererConfig, ): UseRendererResult> { - return useRenderer(reactRenderer, convertModelRendererArgs, config); + return useRenderer(reactRenderer, convertModelRendererArgs); } diff --git a/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts b/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts index 3131987d..34a73250 100644 --- a/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts +++ b/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts @@ -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, @@ -9,8 +9,7 @@ import { export function useSimpleOrChildrenRenderer( fnRenderer?: ComponentType> | null, - children?: ReactNode | ComponentType>, - config?: RendererConfig, + children?: ReactNode | ComponentType> ): UseRendererResult> { let _children: ReactNode | undefined; let _fnRenderer: ComponentType> | null | undefined; @@ -26,8 +25,8 @@ export function useSimpleOrChildrenRenderer( 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; } diff --git a/packages/react-components/src/renderers/useSimpleRenderer.ts b/packages/react-components/src/renderers/useSimpleRenderer.ts index d854e104..f017b32b 100644 --- a/packages/react-components/src/renderers/useSimpleRenderer.ts +++ b/packages/react-components/src/renderers/useSimpleRenderer.ts @@ -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 = Readonly<{ original: O; @@ -15,8 +15,7 @@ function convertSimpleRendererArgs([original]: Slice< } export function useSimpleRenderer( - reactRenderer?: ComponentType> | null, - config?: RendererConfig, + reactRenderer?: ComponentType> | null ): UseRendererResult> { - return useRenderer(reactRenderer, convertSimpleRendererArgs, config); + return useRenderer(reactRenderer, convertSimpleRendererArgs); } From a2e49f37af3d6281fceeb8fc1265804a7a4f8fdf Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Thu, 14 Nov 2024 09:53:06 +0400 Subject: [PATCH 3/3] run formatter --- .../src/renderers/useSimpleOrChildrenRenderer.ts | 2 +- packages/react-components/src/renderers/useSimpleRenderer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts b/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts index 34a73250..24834419 100644 --- a/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts +++ b/packages/react-components/src/renderers/useSimpleOrChildrenRenderer.ts @@ -9,7 +9,7 @@ import { export function useSimpleOrChildrenRenderer( fnRenderer?: ComponentType> | null, - children?: ReactNode | ComponentType> + children?: ReactNode | ComponentType>, ): UseRendererResult> { let _children: ReactNode | undefined; let _fnRenderer: ComponentType> | null | undefined; diff --git a/packages/react-components/src/renderers/useSimpleRenderer.ts b/packages/react-components/src/renderers/useSimpleRenderer.ts index f017b32b..14f2c5e7 100644 --- a/packages/react-components/src/renderers/useSimpleRenderer.ts +++ b/packages/react-components/src/renderers/useSimpleRenderer.ts @@ -15,7 +15,7 @@ function convertSimpleRendererArgs([original]: Slice< } export function useSimpleRenderer( - reactRenderer?: ComponentType> | null + reactRenderer?: ComponentType> | null, ): UseRendererResult> { return useRenderer(reactRenderer, convertSimpleRendererArgs); }