diff --git a/packages/kitchen-sink/src/examples/context.tsx b/packages/kitchen-sink/src/examples/context.tsx index ac5eea19cb..ae339a8715 100644 --- a/packages/kitchen-sink/src/examples/context.tsx +++ b/packages/kitchen-sink/src/examples/context.tsx @@ -56,7 +56,7 @@ const App_1 = _compiledBlock(_props2 =>
, { name: "App_1", portals: ["v0"], - scoped: ['Context_1'] + scoped: ["v0"], }); const App = () => { const [theme, setTheme] = useState('light'); diff --git a/packages/react/block.ts b/packages/react/block.ts index 6a196ac50c..359549a97a 100644 --- a/packages/react/block.ts +++ b/packages/react/block.ts @@ -16,7 +16,6 @@ import { cloneNode$ } from '../million/dom'; experimental_options.noSlot = true; export const mountContext = createContext> | null>(null) -export const scopedContext = createContext([]) export const block =

( fn: ComponentType

| null, diff --git a/packages/react/compiled-block.ts b/packages/react/compiled-block.ts index e4364d34b9..48169f30b0 100644 --- a/packages/react/compiled-block.ts +++ b/packages/react/compiled-block.ts @@ -9,8 +9,8 @@ import { } from 'react'; import { createPortal } from 'react-dom'; import type { MillionPortal, MillionProps, Options } from '../types'; -import { block, mountContext, scopedContext } from './block'; -import { renderReactScope } from './utils'; +import { block, mountContext } from './block'; +import { renderReactScope, scopedContext } from './utils'; import { experimental_options } from '../million/experimental'; function isEqual(a: unknown, b: unknown): boolean { @@ -44,19 +44,17 @@ export function compiledBlock( const blockName = `CompiledBlock(Inner(${options.name}))`; const RenderBlock = block((props) => render(props), { ...options, + scoped: undefined, name: blockName, shouldUpdate: shouldCompiledBlockUpdate, }); - const scopedBlocks = options.scoped ?? []; const portalCount = portals?.length || 0; const Component: ComponentType = portals && portalCount > 0 ? (props: MillionProps) => { - const scoped = options?.name - ? useContext(scopedContext).includes(options.name) - : false; + const scoped = useContext(scopedContext); const [current] = useState(() => []); const [mounted, mount] = useState(false); @@ -68,11 +66,10 @@ export function compiledBlock( derived[index] as JSX.Element, false, current, - i + i, + options.scoped?.includes(index) ); - // if (!noSlot) { derived[index] = scope; - // } } const targets: ReactPortal[] = []; @@ -82,14 +79,10 @@ export function compiledBlock( } return createElement( - scopedContext.Provider, - { value: scopedBlocks }, - createElement( - mountContext.Provider, - { value: mount }, - createElement(RenderBlock, derived), - mounted ? targets : null - ) + mountContext.Provider, + { value: mount }, + createElement(RenderBlock, derived), + mounted ? targets : null ); } : (props: MillionProps) => createElement(RenderBlock, props); diff --git a/packages/react/utils.ts b/packages/react/utils.ts index de23383929..efea4d6dc5 100644 --- a/packages/react/utils.ts +++ b/packages/react/utils.ts @@ -1,15 +1,17 @@ -import { Fragment, createElement, isValidElement } from 'react'; +import { Fragment, createContext, createElement, isValidElement } from 'react'; import { createPortal } from 'react-dom'; import type { ComponentProps, ReactNode, Ref } from 'react'; import type { VNode } from '../million'; import type { MillionPortal } from '../types'; import { REGISTRY, RENDER_SCOPE } from './constants'; +export const scopedContext = createContext(false) + // TODO: access perf impact of this export const processProps = ( props: ComponentProps, ref: Ref, - portals: MillionPortal[], + portals: MillionPortal[] ): ComponentProps => { const processedProps: ComponentProps = { ref }; @@ -25,7 +27,7 @@ export const processProps = ( value, false, portals, - currentIndex++, + currentIndex++ ); continue; @@ -45,6 +47,7 @@ export const renderReactScope = ( unstable: boolean, portals: MillionPortal[] | undefined, currentIndex: number, + scoped?: boolean ) => { const el = portals?.[currentIndex]?.current; @@ -75,7 +78,10 @@ export const renderReactScope = ( } const current = el ?? document.createElement(RENDER_SCOPE); - const reactPortal = createPortal(vnode, current); + const reactPortal = createPortal( + createElement(scopedContext.Provider, { value: scoped }, vnode), + current + ); const millionPortal = { foreign: true as const, @@ -115,7 +121,7 @@ export const unwrap = (vnode: JSX.Element | null): VNode => { const children = vnode.props?.children; if (children !== undefined && children !== null) { props.children = flatten(vnode.props.children).map((child) => - unwrap(child), + unwrap(child) ); }