Skip to content

Commit

Permalink
Revert "SlotFill: Migrate to Typescript. (#51350)"
Browse files Browse the repository at this point in the history
This reverts commit 3cca31c.
  • Loading branch information
mikachan committed Jan 5, 2024
1 parent a5e5d98 commit 1010c9f
Show file tree
Hide file tree
Showing 21 changed files with 377 additions and 682 deletions.
3 changes: 0 additions & 3 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
- `Tooltip`, `Shortcut`: Remove unused `ui/` components from the codebase ([#54573](https://github.com/WordPress/gutenberg/pull/54573))
- Update `uuid` package to 9.0.1 ([#54725](https://github.com/WordPress/gutenberg/pull/54725)).
- `ContextSystemProvider`: Move out of `ui/` ([#54847](https://github.com/WordPress/gutenberg/pull/54847)).
- `SlotFill`: Migrate to TypeScript and Convert to Functional Component `<Slot bubblesVirtually />`. ([#51350](https://github.com/WordPress/gutenberg/pull/51350)).


## 25.8.0 (2023-09-20)

Expand Down Expand Up @@ -132,7 +130,6 @@

- `ColorPalette`, `BorderControl`: Don't hyphenate hex value in `aria-label` ([#52932](https://github.com/WordPress/gutenberg/pull/52932)).
- `MenuItemsChoice`, `MenuItem`: Support a `disabled` prop on a menu item ([#52737](https://github.com/WordPress/gutenberg/pull/52737)).
- `TabPanel`: Introduce a new version of `TabPanel` with updated internals and improved adherence to ARIA guidance on `tabpanel` focus behavior while maintaining the same functionality and API surface.([#52133](https://github.com/WordPress/gutenberg/pull/52133)).

### Bug Fix

Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/dropdown-menu-v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,5 @@ export type DropdownMenuPrivateContext = Pick<
DropdownMenuInternalContext,
'variant'
> & {
portalContainer?: HTMLElement | null;
portalContainer: HTMLElement | null;
};
1 change: 1 addition & 0 deletions packages/components/src/popover/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ function PopoverSlot(
) {
return (
<Slot
// @ts-expect-error Need to type `SlotFill`
bubblesVirtually
name={ name }
className="popover-slot"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
/**
* WordPress dependencies
*/
Expand All @@ -8,7 +9,6 @@ import { useRef, useState, useEffect, createPortal } from '@wordpress/element';
*/
import useSlot from './use-slot';
import StyleProvider from '../../style-provider';
import type { FillComponentProps } from '../types';

function useForceUpdate() {
const [ , setState ] = useState( {} );
Expand All @@ -28,8 +28,7 @@ function useForceUpdate() {
};
}

export default function Fill( props: FillComponentProps ) {
const { name, children } = props;
export default function Fill( { name, children } ) {
const { registerFill, unregisterFill, ...slot } = useSlot( name );
const rerender = useForceUpdate();
const ref = useRef( { rerender } );
Expand All @@ -48,15 +47,17 @@ export default function Fill( props: FillComponentProps ) {
return null;
}

if ( typeof children === 'function' ) {
children = children( slot.fillProps );
}

// When using a `Fill`, the `children` will be rendered in the document of the
// `Slot`. This means that we need to wrap the `children` in a `StyleProvider`
// to make sure we're referencing the right document/iframe (instead of the
// context of the `Fill`'s parent).
const wrappedChildren = (
<StyleProvider document={ slot.ref.current.ownerDocument }>
{ typeof children === 'function'
? children( slot.fillProps ?? {} )
: children }
{ children }
</StyleProvider>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
/**
* External dependencies
*/
Expand All @@ -7,12 +8,8 @@ import { proxyMap } from 'valtio/utils';
*/
import { createContext } from '@wordpress/element';
import warning from '@wordpress/warning';
/**
* Internal dependencies
*/
import type { SlotFillBubblesVirtuallyContext } from '../types';

const initialContextValue: SlotFillBubblesVirtuallyContext = {
const SlotFillContext = createContext( {
slots: proxyMap(),
fills: proxyMap(),
registerSlot: () => {
Expand All @@ -28,8 +25,6 @@ const initialContextValue: SlotFillBubblesVirtuallyContext = {

// This helps the provider know if it's using the default context value or not.
isDefault: true,
};

const SlotFillContext = createContext( initialContextValue );
} );

export default SlotFillContext;
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// @ts-nocheck
/**
* External dependencies
*/
import { ref as valRef } from 'valtio';
import { proxyMap } from 'valtio/utils';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import isShallowEqual from '@wordpress/is-shallow-equal';

/**
* Internal dependencies
*/
import SlotFillContext from './slot-fill-context';

function createSlotRegistry() {
const slots = proxyMap();
const fills = proxyMap();

function registerSlot( name, ref, fillProps ) {
const slot = slots.get( name ) || {};
slots.set(
name,
valRef( {
...slot,
ref: ref || slot.ref,
fillProps: fillProps || slot.fillProps || {},
} )
);
}

function unregisterSlot( name, ref ) {
// Make sure we're not unregistering a slot registered by another element
// See https://github.com/WordPress/gutenberg/pull/19242#issuecomment-590295412
if ( slots.get( name )?.ref === ref ) {
slots.delete( name );
}
}

function updateSlot( name, fillProps ) {
const slot = slots.get( name );
if ( ! slot ) {
return;
}

if ( isShallowEqual( slot.fillProps, fillProps ) ) {
return;
}

slot.fillProps = fillProps;
const slotFills = fills.get( name );
if ( slotFills ) {
// Force update fills.
slotFills.map( ( fill ) => fill.current.rerender() );
}
}

function registerFill( name, ref ) {
fills.set( name, valRef( [ ...( fills.get( name ) || [] ), ref ] ) );
}

function unregisterFill( name, ref ) {
const fillsForName = fills.get( name );
if ( ! fillsForName ) {
return;
}

fills.set(
name,
valRef( fillsForName.filter( ( fillRef ) => fillRef !== ref ) )
);
}

return {
slots,
fills,
registerSlot,
updateSlot,
unregisterSlot,
registerFill,
unregisterFill,
};
}

export default function SlotFillProvider( { children } ) {
const [ registry ] = useState( createSlotRegistry );
return (
<SlotFillContext.Provider value={ registry }>
{ children }
</SlotFillContext.Provider>
);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/**
* External dependencies
*/
import type { ForwardedRef } from 'react';

// @ts-nocheck
/**
* WordPress dependencies
*/
Expand All @@ -19,30 +15,21 @@ import { useMergeRefs } from '@wordpress/compose';
*/
import { View } from '../../view';
import SlotFillContext from './slot-fill-context';
import type { WordPressComponentProps } from '../../context';
import type { SlotComponentProps } from '../types';

function Slot(
props: WordPressComponentProps<
Omit< SlotComponentProps, 'bubblesVirtually' >,
'div'
>,
forwardedRef: ForwardedRef< any >
) {
function Slot( props, forwardedRef ) {
const {
name,
fillProps = {},
as,
// `children` is not allowed. However, if it is passed,
// it will be displayed as is, so remove `children`.
// @ts-ignore
children,
...restProps
} = props;

const { registerSlot, unregisterSlot, ...registry } =
useContext( SlotFillContext );
const ref = useRef< HTMLElement >( null );
const ref = useRef();

useLayoutEffect( () => {
registerSlot( name, ref, fillProps );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
/**
* External dependencies
*/
Expand All @@ -12,9 +13,8 @@ import { useContext } from '@wordpress/element';
* Internal dependencies
*/
import SlotFillContext from './slot-fill-context';
import type { SlotKey } from '../types';

export default function useSlotFills( name: SlotKey ) {
export default function useSlotFills( name ) {
const registry = useContext( SlotFillContext );
const fills = useSnapshot( registry.fills, { sync: true } );
// The important bit here is that this call ensures that the hook
Expand Down
Loading

0 comments on commit 1010c9f

Please sign in to comment.