fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

View File

@@ -0,0 +1,64 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { useRef, useState, useEffect, createPortal } from '@wordpress/element';
/**
* Internal dependencies
*/
import useSlot from './use-slot';
import StyleProvider from '../../style-provider';
function useForceUpdate() {
const [, setState] = useState({});
const mounted = useRef(true);
useEffect(() => {
mounted.current = true;
return () => {
mounted.current = false;
};
}, []);
return () => {
if (mounted.current) {
setState({});
}
};
}
export default function Fill(props) {
var _slot$fillProps;
const {
name,
children
} = props;
const {
registerFill,
unregisterFill,
...slot
} = useSlot(name);
const rerender = useForceUpdate();
const ref = useRef({
rerender
});
useEffect(() => {
// We register fills so we can keep track of their existence.
// Some Slot implementations need to know if there're already fills
// registered so they can choose to render themselves or not.
registerFill(ref);
return () => {
unregisterFill(ref);
};
}, [registerFill, unregisterFill]);
if (!slot.ref || !slot.ref.current) {
return null;
}
// 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 = createElement(StyleProvider, {
document: slot.ref.current.ownerDocument
}, typeof children === 'function' ? children((_slot$fillProps = slot.fillProps) !== null && _slot$fillProps !== void 0 ? _slot$fillProps : {}) : children);
return createPortal(wrappedChildren, slot.ref.current);
}
//# sourceMappingURL=fill.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useRef","useState","useEffect","createPortal","useSlot","StyleProvider","useForceUpdate","setState","mounted","current","Fill","props","_slot$fillProps","name","children","registerFill","unregisterFill","slot","rerender","ref","wrappedChildren","createElement","document","ownerDocument","fillProps"],"sources":["@wordpress/components/src/slot-fill/bubbles-virtually/fill.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useRef, useState, useEffect, createPortal } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport useSlot from './use-slot';\nimport StyleProvider from '../../style-provider';\nimport type { FillComponentProps } from '../types';\n\nfunction useForceUpdate() {\n\tconst [ , setState ] = useState( {} );\n\tconst mounted = useRef( true );\n\n\tuseEffect( () => {\n\t\tmounted.current = true;\n\t\treturn () => {\n\t\t\tmounted.current = false;\n\t\t};\n\t}, [] );\n\n\treturn () => {\n\t\tif ( mounted.current ) {\n\t\t\tsetState( {} );\n\t\t}\n\t};\n}\n\nexport default function Fill( props: FillComponentProps ) {\n\tconst { name, children } = props;\n\tconst { registerFill, unregisterFill, ...slot } = useSlot( name );\n\tconst rerender = useForceUpdate();\n\tconst ref = useRef( { rerender } );\n\n\tuseEffect( () => {\n\t\t// We register fills so we can keep track of their existence.\n\t\t// Some Slot implementations need to know if there're already fills\n\t\t// registered so they can choose to render themselves or not.\n\t\tregisterFill( ref );\n\t\treturn () => {\n\t\t\tunregisterFill( ref );\n\t\t};\n\t}, [ registerFill, unregisterFill ] );\n\n\tif ( ! slot.ref || ! slot.ref.current ) {\n\t\treturn null;\n\t}\n\n\t// When using a `Fill`, the `children` will be rendered in the document of the\n\t// `Slot`. This means that we need to wrap the `children` in a `StyleProvider`\n\t// to make sure we're referencing the right document/iframe (instead of the\n\t// context of the `Fill`'s parent).\n\tconst wrappedChildren = (\n\t\t<StyleProvider document={ slot.ref.current.ownerDocument }>\n\t\t\t{ typeof children === 'function'\n\t\t\t\t? children( slot.fillProps ?? {} )\n\t\t\t\t: children }\n\t\t</StyleProvider>\n\t);\n\n\treturn createPortal( wrappedChildren, slot.ref.current );\n}\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,YAAY,QAAQ,oBAAoB;;AAE9E;AACA;AACA;AACA,OAAOC,OAAO,MAAM,YAAY;AAChC,OAAOC,aAAa,MAAM,sBAAsB;AAGhD,SAASC,cAAcA,CAAA,EAAG;EACzB,MAAM,GAAIC,QAAQ,CAAE,GAAGN,QAAQ,CAAE,CAAC,CAAE,CAAC;EACrC,MAAMO,OAAO,GAAGR,MAAM,CAAE,IAAK,CAAC;EAE9BE,SAAS,CAAE,MAAM;IAChBM,OAAO,CAACC,OAAO,GAAG,IAAI;IACtB,OAAO,MAAM;MACZD,OAAO,CAACC,OAAO,GAAG,KAAK;IACxB,CAAC;EACF,CAAC,EAAE,EAAG,CAAC;EAEP,OAAO,MAAM;IACZ,IAAKD,OAAO,CAACC,OAAO,EAAG;MACtBF,QAAQ,CAAE,CAAC,CAAE,CAAC;IACf;EACD,CAAC;AACF;AAEA,eAAe,SAASG,IAAIA,CAAEC,KAAyB,EAAG;EAAA,IAAAC,eAAA;EACzD,MAAM;IAAEC,IAAI;IAAEC;EAAS,CAAC,GAAGH,KAAK;EAChC,MAAM;IAAEI,YAAY;IAAEC,cAAc;IAAE,GAAGC;EAAK,CAAC,GAAGb,OAAO,CAAES,IAAK,CAAC;EACjE,MAAMK,QAAQ,GAAGZ,cAAc,CAAC,CAAC;EACjC,MAAMa,GAAG,GAAGnB,MAAM,CAAE;IAAEkB;EAAS,CAAE,CAAC;EAElChB,SAAS,CAAE,MAAM;IAChB;IACA;IACA;IACAa,YAAY,CAAEI,GAAI,CAAC;IACnB,OAAO,MAAM;MACZH,cAAc,CAAEG,GAAI,CAAC;IACtB,CAAC;EACF,CAAC,EAAE,CAAEJ,YAAY,EAAEC,cAAc,CAAG,CAAC;EAErC,IAAK,CAAEC,IAAI,CAACE,GAAG,IAAI,CAAEF,IAAI,CAACE,GAAG,CAACV,OAAO,EAAG;IACvC,OAAO,IAAI;EACZ;;EAEA;EACA;EACA;EACA;EACA,MAAMW,eAAe,GACpBC,aAAA,CAAChB,aAAa;IAACiB,QAAQ,EAAGL,IAAI,CAACE,GAAG,CAACV,OAAO,CAACc;EAAe,GACvD,OAAOT,QAAQ,KAAK,UAAU,GAC7BA,QAAQ,EAAAF,eAAA,GAAEK,IAAI,CAACO,SAAS,cAAAZ,eAAA,cAAAA,eAAA,GAAI,CAAC,CAAE,CAAC,GAChCE,QACW,CACf;EAED,OAAOX,YAAY,CAAEiB,eAAe,EAAEH,IAAI,CAACE,GAAG,CAACV,OAAQ,CAAC;AACzD"}

View File

@@ -0,0 +1,29 @@
/**
* External dependencies
*/
import { proxyMap } from 'valtio/utils';
/**
* WordPress dependencies
*/
import { createContext } from '@wordpress/element';
import warning from '@wordpress/warning';
/**
* Internal dependencies
*/
const initialContextValue = {
slots: proxyMap(),
fills: proxyMap(),
registerSlot: () => {
typeof SCRIPT_DEBUG !== "undefined" && SCRIPT_DEBUG === true ? warning('Components must be wrapped within `SlotFillProvider`. ' + 'See https://developer.wordpress.org/block-editor/components/slot-fill/') : void 0;
},
updateSlot: () => {},
unregisterSlot: () => {},
registerFill: () => {},
unregisterFill: () => {},
// This helps the provider know if it's using the default context value or not.
isDefault: true
};
const SlotFillContext = createContext(initialContextValue);
export default SlotFillContext;
//# sourceMappingURL=slot-fill-context.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["proxyMap","createContext","warning","initialContextValue","slots","fills","registerSlot","SCRIPT_DEBUG","updateSlot","unregisterSlot","registerFill","unregisterFill","isDefault","SlotFillContext"],"sources":["@wordpress/components/src/slot-fill/bubbles-virtually/slot-fill-context.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport { proxyMap } from 'valtio/utils';\n/**\n * WordPress dependencies\n */\nimport { createContext } from '@wordpress/element';\nimport warning from '@wordpress/warning';\n/**\n * Internal dependencies\n */\nimport type { SlotFillBubblesVirtuallyContext } from '../types';\n\nconst initialContextValue: SlotFillBubblesVirtuallyContext = {\n\tslots: proxyMap(),\n\tfills: proxyMap(),\n\tregisterSlot: () => {\n\t\twarning(\n\t\t\t'Components must be wrapped within `SlotFillProvider`. ' +\n\t\t\t\t'See https://developer.wordpress.org/block-editor/components/slot-fill/'\n\t\t);\n\t},\n\tupdateSlot: () => {},\n\tunregisterSlot: () => {},\n\tregisterFill: () => {},\n\tunregisterFill: () => {},\n\n\t// This helps the provider know if it's using the default context value or not.\n\tisDefault: true,\n};\n\nconst SlotFillContext = createContext( initialContextValue );\n\nexport default SlotFillContext;\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC;AACA;AACA;AACA,SAASC,aAAa,QAAQ,oBAAoB;AAClD,OAAOC,OAAO,MAAM,oBAAoB;AACxC;AACA;AACA;;AAGA,MAAMC,mBAAoD,GAAG;EAC5DC,KAAK,EAAEJ,QAAQ,CAAC,CAAC;EACjBK,KAAK,EAAEL,QAAQ,CAAC,CAAC;EACjBM,YAAY,EAAEA,CAAA,KAAM;IACnB,OAAAC,YAAA,oBAAAA,YAAA,YAAAL,OAAO,CACN,wDAAwD,GACvD,wEACF,CAAC;EACF,CAAC;EACDM,UAAU,EAAEA,CAAA,KAAM,CAAC,CAAC;EACpBC,cAAc,EAAEA,CAAA,KAAM,CAAC,CAAC;EACxBC,YAAY,EAAEA,CAAA,KAAM,CAAC,CAAC;EACtBC,cAAc,EAAEA,CAAA,KAAM,CAAC,CAAC;EAExB;EACAC,SAAS,EAAE;AACZ,CAAC;AAED,MAAMC,eAAe,GAAGZ,aAAa,CAAEE,mBAAoB,CAAC;AAE5D,eAAeU,eAAe"}

View File

@@ -0,0 +1,79 @@
import { createElement } from "react";
/**
* External dependencies
*/
import { ref as valRef } from 'valtio';
import { proxyMap } from 'valtio/utils';
/**
* WordPress dependencies
*/
import { useMemo } 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();
const registerSlot = (name, ref, fillProps) => {
const slot = slots.get(name);
slots.set(name, valRef({
...slot,
ref: ref || slot?.ref,
fillProps: fillProps || slot?.fillProps || {}
}));
};
const 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);
}
};
const 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.forEach(fill => fill.current.rerender());
}
};
const registerFill = (name, ref) => {
fills.set(name, valRef([...(fills.get(name) || []), ref]));
};
const 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 = useMemo(createSlotRegistry, []);
return createElement(SlotFillContext.Provider, {
value: registry
}, children);
}
//# sourceMappingURL=slot-fill-provider.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
import { createElement } from "react";
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
import { useRef, useLayoutEffect, useContext, forwardRef } from '@wordpress/element';
import { useMergeRefs } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { View } from '../../view';
import SlotFillContext from './slot-fill-context';
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(null);
useLayoutEffect(() => {
registerSlot(name, ref, fillProps);
return () => {
unregisterSlot(name, ref);
};
// Ignore reason: We don't want to unregister and register the slot whenever
// `fillProps` change, which would cause the fill to be re-mounted. Instead,
// we can just update the slot (see hook below).
// For more context, see https://github.com/WordPress/gutenberg/pull/44403#discussion_r994415973
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [registerSlot, unregisterSlot, name]);
// fillProps may be an update that interacts with the layout, so we
// useLayoutEffect.
useLayoutEffect(() => {
registry.updateSlot(name, fillProps);
});
return createElement(View, {
as: as,
ref: useMergeRefs([forwardedRef, ref]),
...restProps
});
}
export default forwardRef(Slot);
//# sourceMappingURL=slot.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useRef","useLayoutEffect","useContext","forwardRef","useMergeRefs","View","SlotFillContext","Slot","props","forwardedRef","name","fillProps","as","children","restProps","registerSlot","unregisterSlot","registry","ref","updateSlot","createElement"],"sources":["@wordpress/components/src/slot-fill/bubbles-virtually/slot.tsx"],"sourcesContent":["/**\n * External dependencies\n */\nimport type { ForwardedRef } from 'react';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tuseRef,\n\tuseLayoutEffect,\n\tuseContext,\n\tforwardRef,\n} from '@wordpress/element';\nimport { useMergeRefs } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport { View } from '../../view';\nimport SlotFillContext from './slot-fill-context';\nimport type { WordPressComponentProps } from '../../context';\nimport type { SlotComponentProps } from '../types';\n\nfunction Slot(\n\tprops: WordPressComponentProps<\n\t\tOmit< SlotComponentProps, 'bubblesVirtually' >,\n\t\t'div'\n\t>,\n\tforwardedRef: ForwardedRef< any >\n) {\n\tconst {\n\t\tname,\n\t\tfillProps = {},\n\t\tas,\n\t\t// `children` is not allowed. However, if it is passed,\n\t\t// it will be displayed as is, so remove `children`.\n\t\t// @ts-ignore\n\t\tchildren,\n\t\t...restProps\n\t} = props;\n\n\tconst { registerSlot, unregisterSlot, ...registry } =\n\t\tuseContext( SlotFillContext );\n\tconst ref = useRef< HTMLElement >( null );\n\n\tuseLayoutEffect( () => {\n\t\tregisterSlot( name, ref, fillProps );\n\t\treturn () => {\n\t\t\tunregisterSlot( name, ref );\n\t\t};\n\t\t// Ignore reason: We don't want to unregister and register the slot whenever\n\t\t// `fillProps` change, which would cause the fill to be re-mounted. Instead,\n\t\t// we can just update the slot (see hook below).\n\t\t// For more context, see https://github.com/WordPress/gutenberg/pull/44403#discussion_r994415973\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ registerSlot, unregisterSlot, name ] );\n\t// fillProps may be an update that interacts with the layout, so we\n\t// useLayoutEffect.\n\tuseLayoutEffect( () => {\n\t\tregistry.updateSlot( name, fillProps );\n\t} );\n\n\treturn (\n\t\t<View\n\t\t\tas={ as }\n\t\t\tref={ useMergeRefs( [ forwardedRef, ref ] ) }\n\t\t\t{ ...restProps }\n\t\t/>\n\t);\n}\n\nexport default forwardRef( Slot );\n"],"mappings":";AAAA;AACA;AACA;;AAGA;AACA;AACA;AACA,SACCA,MAAM,EACNC,eAAe,EACfC,UAAU,EACVC,UAAU,QACJ,oBAAoB;AAC3B,SAASC,YAAY,QAAQ,oBAAoB;;AAEjD;AACA;AACA;AACA,SAASC,IAAI,QAAQ,YAAY;AACjC,OAAOC,eAAe,MAAM,qBAAqB;AAIjD,SAASC,IAAIA,CACZC,KAGC,EACDC,YAAiC,EAChC;EACD,MAAM;IACLC,IAAI;IACJC,SAAS,GAAG,CAAC,CAAC;IACdC,EAAE;IACF;IACA;IACA;IACAC,QAAQ;IACR,GAAGC;EACJ,CAAC,GAAGN,KAAK;EAET,MAAM;IAAEO,YAAY;IAAEC,cAAc;IAAE,GAAGC;EAAS,CAAC,GAClDf,UAAU,CAAEI,eAAgB,CAAC;EAC9B,MAAMY,GAAG,GAAGlB,MAAM,CAAiB,IAAK,CAAC;EAEzCC,eAAe,CAAE,MAAM;IACtBc,YAAY,CAAEL,IAAI,EAAEQ,GAAG,EAAEP,SAAU,CAAC;IACpC,OAAO,MAAM;MACZK,cAAc,CAAEN,IAAI,EAAEQ,GAAI,CAAC;IAC5B,CAAC;IACD;IACA;IACA;IACA;IACA;EACD,CAAC,EAAE,CAAEH,YAAY,EAAEC,cAAc,EAAEN,IAAI,CAAG,CAAC;EAC3C;EACA;EACAT,eAAe,CAAE,MAAM;IACtBgB,QAAQ,CAACE,UAAU,CAAET,IAAI,EAAEC,SAAU,CAAC;EACvC,CAAE,CAAC;EAEH,OACCS,aAAA,CAACf,IAAI;IACJO,EAAE,EAAGA,EAAI;IACTM,GAAG,EAAGd,YAAY,CAAE,CAAEK,YAAY,EAAES,GAAG,CAAG,CAAG;IAAA,GACxCJ;EAAS,CACd,CAAC;AAEJ;AAEA,eAAeX,UAAU,CAAEI,IAAK,CAAC"}

View File

@@ -0,0 +1,25 @@
/**
* External dependencies
*/
import { useSnapshot } from 'valtio';
/**
* WordPress dependencies
*/
import { useContext } from '@wordpress/element';
/**
* Internal dependencies
*/
import SlotFillContext from './slot-fill-context';
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
// only causes a re-render if the "fills" of a given slot name
// change, not any fills.
return fills.get(name);
}
//# sourceMappingURL=use-slot-fills.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useSnapshot","useContext","SlotFillContext","useSlotFills","name","registry","fills","sync","get"],"sources":["@wordpress/components/src/slot-fill/bubbles-virtually/use-slot-fills.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport { useSnapshot } from 'valtio';\n\n/**\n * WordPress dependencies\n */\nimport { useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport SlotFillContext from './slot-fill-context';\nimport type { SlotKey } from '../types';\n\nexport default function useSlotFills( name: SlotKey ) {\n\tconst registry = useContext( SlotFillContext );\n\tconst fills = useSnapshot( registry.fills, { sync: true } );\n\t// The important bit here is that this call ensures that the hook\n\t// only causes a re-render if the \"fills\" of a given slot name\n\t// change, not any fills.\n\treturn fills.get( name );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,WAAW,QAAQ,QAAQ;;AAEpC;AACA;AACA;AACA,SAASC,UAAU,QAAQ,oBAAoB;;AAE/C;AACA;AACA;AACA,OAAOC,eAAe,MAAM,qBAAqB;AAGjD,eAAe,SAASC,YAAYA,CAAEC,IAAa,EAAG;EACrD,MAAMC,QAAQ,GAAGJ,UAAU,CAAEC,eAAgB,CAAC;EAC9C,MAAMI,KAAK,GAAGN,WAAW,CAAEK,QAAQ,CAACC,KAAK,EAAE;IAAEC,IAAI,EAAE;EAAK,CAAE,CAAC;EAC3D;EACA;EACA;EACA,OAAOD,KAAK,CAACE,GAAG,CAAEJ,IAAK,CAAC;AACzB"}

View File

@@ -0,0 +1,35 @@
/**
* External dependencies
*/
import { useSnapshot } from 'valtio';
/**
* WordPress dependencies
*/
import { useMemo, useContext } from '@wordpress/element';
/**
* Internal dependencies
*/
import SlotFillContext from './slot-fill-context';
export default function useSlot(name) {
const registry = useContext(SlotFillContext);
const slots = useSnapshot(registry.slots, {
sync: true
});
// The important bit here is that the `useSnapshot` call ensures that the
// hook only causes a re-render if the slot with the given name changes,
// not any other slot.
const slot = slots.get(name);
const api = useMemo(() => ({
updateSlot: fillProps => registry.updateSlot(name, fillProps),
unregisterSlot: ref => registry.unregisterSlot(name, ref),
registerFill: ref => registry.registerFill(name, ref),
unregisterFill: ref => registry.unregisterFill(name, ref)
}), [name, registry]);
return {
...slot,
...api
};
}
//# sourceMappingURL=use-slot.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useSnapshot","useMemo","useContext","SlotFillContext","useSlot","name","registry","slots","sync","slot","get","api","updateSlot","fillProps","unregisterSlot","ref","registerFill","unregisterFill"],"sources":["@wordpress/components/src/slot-fill/bubbles-virtually/use-slot.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport { useSnapshot } from 'valtio';\n\n/**\n * WordPress dependencies\n */\nimport { useMemo, useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport SlotFillContext from './slot-fill-context';\nimport type {\n\tSlotFillBubblesVirtuallyFillRef,\n\tSlotFillBubblesVirtuallySlotRef,\n\tFillProps,\n\tSlotKey,\n} from '../types';\n\nexport default function useSlot( name: SlotKey ) {\n\tconst registry = useContext( SlotFillContext );\n\tconst slots = useSnapshot( registry.slots, { sync: true } );\n\t// The important bit here is that the `useSnapshot` call ensures that the\n\t// hook only causes a re-render if the slot with the given name changes,\n\t// not any other slot.\n\tconst slot = slots.get( name );\n\n\tconst api = useMemo(\n\t\t() => ( {\n\t\t\tupdateSlot: ( fillProps: FillProps ) =>\n\t\t\t\tregistry.updateSlot( name, fillProps ),\n\t\t\tunregisterSlot: ( ref: SlotFillBubblesVirtuallySlotRef ) =>\n\t\t\t\tregistry.unregisterSlot( name, ref ),\n\t\t\tregisterFill: ( ref: SlotFillBubblesVirtuallyFillRef ) =>\n\t\t\t\tregistry.registerFill( name, ref ),\n\t\t\tunregisterFill: ( ref: SlotFillBubblesVirtuallyFillRef ) =>\n\t\t\t\tregistry.unregisterFill( name, ref ),\n\t\t} ),\n\t\t[ name, registry ]\n\t);\n\n\treturn {\n\t\t...slot,\n\t\t...api,\n\t};\n}\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,WAAW,QAAQ,QAAQ;;AAEpC;AACA;AACA;AACA,SAASC,OAAO,EAAEC,UAAU,QAAQ,oBAAoB;;AAExD;AACA;AACA;AACA,OAAOC,eAAe,MAAM,qBAAqB;AAQjD,eAAe,SAASC,OAAOA,CAAEC,IAAa,EAAG;EAChD,MAAMC,QAAQ,GAAGJ,UAAU,CAAEC,eAAgB,CAAC;EAC9C,MAAMI,KAAK,GAAGP,WAAW,CAAEM,QAAQ,CAACC,KAAK,EAAE;IAAEC,IAAI,EAAE;EAAK,CAAE,CAAC;EAC3D;EACA;EACA;EACA,MAAMC,IAAI,GAAGF,KAAK,CAACG,GAAG,CAAEL,IAAK,CAAC;EAE9B,MAAMM,GAAG,GAAGV,OAAO,CAClB,OAAQ;IACPW,UAAU,EAAIC,SAAoB,IACjCP,QAAQ,CAACM,UAAU,CAAEP,IAAI,EAAEQ,SAAU,CAAC;IACvCC,cAAc,EAAIC,GAAoC,IACrDT,QAAQ,CAACQ,cAAc,CAAET,IAAI,EAAEU,GAAI,CAAC;IACrCC,YAAY,EAAID,GAAoC,IACnDT,QAAQ,CAACU,YAAY,CAAEX,IAAI,EAAEU,GAAI,CAAC;IACnCE,cAAc,EAAIF,GAAoC,IACrDT,QAAQ,CAACW,cAAc,CAAEZ,IAAI,EAAEU,GAAI;EACrC,CAAC,CAAE,EACH,CAAEV,IAAI,EAAEC,QAAQ,CACjB,CAAC;EAED,OAAO;IACN,GAAGG,IAAI;IACP,GAAGE;EACJ,CAAC;AACF"}