fix(build): verify radix dismissable layer patch
This commit is contained in:
parent
b0b2fa2d13
commit
63cbce7d78
3 changed files with 107 additions and 11 deletions
|
|
@ -439,7 +439,8 @@
|
|||
],
|
||||
"patchedDependencies": {
|
||||
"@radix-ui/react-presence@1.1.5": "patches/@radix-ui__react-presence@1.1.5.patch",
|
||||
"@radix-ui/react-focus-scope@1.1.7": "patches/@radix-ui__react-focus-scope@1.1.7.patch"
|
||||
"@radix-ui/react-focus-scope@1.1.7": "patches/@radix-ui__react-focus-scope@1.1.7.patch",
|
||||
"@radix-ui/react-dismissable-layer@1.1.11": "patches/@radix-ui__react-dismissable-layer@1.1.11.patch"
|
||||
}
|
||||
},
|
||||
"knip": {
|
||||
|
|
|
|||
70
patches/@radix-ui__react-dismissable-layer@1.1.11.patch
Normal file
70
patches/@radix-ui__react-dismissable-layer@1.1.11.patch
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
diff --git a/dist/index.js b/dist/index.js
|
||||
--- a/dist/index.js
|
||||
+++ b/dist/index.js
|
||||
@@ -71,9 +71,30 @@ var DismissableLayer = React.forwardRef(
|
||||
} = props;
|
||||
const context = React.useContext(DismissableLayerContext);
|
||||
const [node, setNode] = React.useState(null);
|
||||
+ const nodeRef = React.useRef(null);
|
||||
+ const nodeCleanupGenerationRef = React.useRef(0);
|
||||
const ownerDocument = node?.ownerDocument ?? globalThis?.document;
|
||||
const [, force] = React.useState({});
|
||||
- const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node2) => setNode(node2));
|
||||
+ const setNodeRef = React.useCallback((node2) => {
|
||||
+ const syncNode = (nextNode) => {
|
||||
+ if (nodeRef.current === nextNode) return;
|
||||
+ nodeRef.current = nextNode;
|
||||
+ setNode(nextNode);
|
||||
+ };
|
||||
+ nodeCleanupGenerationRef.current += 1;
|
||||
+ const cleanupGeneration = nodeCleanupGenerationRef.current;
|
||||
+ if (node2) {
|
||||
+ syncNode(node2);
|
||||
+ return;
|
||||
+ }
|
||||
+ queueMicrotask(() => {
|
||||
+ if (nodeCleanupGenerationRef.current !== cleanupGeneration) {
|
||||
+ return;
|
||||
+ }
|
||||
+ syncNode(null);
|
||||
+ });
|
||||
+ }, []);
|
||||
+ const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, setNodeRef);
|
||||
const layers = Array.from(context.layers);
|
||||
const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
|
||||
const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
|
||||
diff --git a/dist/index.mjs b/dist/index.mjs
|
||||
--- a/dist/index.mjs
|
||||
+++ b/dist/index.mjs
|
||||
@@ -33,9 +33,30 @@ var DismissableLayer = React.forwardRef(
|
||||
} = props;
|
||||
const context = React.useContext(DismissableLayerContext);
|
||||
const [node, setNode] = React.useState(null);
|
||||
+ const nodeRef = React.useRef(null);
|
||||
+ const nodeCleanupGenerationRef = React.useRef(0);
|
||||
const ownerDocument = node?.ownerDocument ?? globalThis?.document;
|
||||
const [, force] = React.useState({});
|
||||
- const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
|
||||
+ const setNodeRef = React.useCallback((node2) => {
|
||||
+ const syncNode = (nextNode) => {
|
||||
+ if (nodeRef.current === nextNode) return;
|
||||
+ nodeRef.current = nextNode;
|
||||
+ setNode(nextNode);
|
||||
+ };
|
||||
+ nodeCleanupGenerationRef.current += 1;
|
||||
+ const cleanupGeneration = nodeCleanupGenerationRef.current;
|
||||
+ if (node2) {
|
||||
+ syncNode(node2);
|
||||
+ return;
|
||||
+ }
|
||||
+ queueMicrotask(() => {
|
||||
+ if (nodeCleanupGenerationRef.current !== cleanupGeneration) {
|
||||
+ return;
|
||||
+ }
|
||||
+ syncNode(null);
|
||||
+ });
|
||||
+ }, []);
|
||||
+ const composedRefs = useComposedRefs(forwardedRef, setNodeRef);
|
||||
const layers = Array.from(context.layers);
|
||||
const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
|
||||
const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
|
||||
|
|
@ -4,26 +4,51 @@ import { dirname, join } from 'node:path';
|
|||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const entrypointPath = require.resolve('@radix-ui/react-presence');
|
||||
const packageRoot = dirname(dirname(entrypointPath));
|
||||
const filesToCheck = ['dist/index.js', 'dist/index.mjs'];
|
||||
const patchChecks = [
|
||||
{
|
||||
packageName: '@radix-ui/react-presence',
|
||||
requiredMarkers: ['nodeCleanupGenerationRef', 'syncNode(null)'],
|
||||
},
|
||||
{
|
||||
packageName: '@radix-ui/react-focus-scope',
|
||||
resolverFromPackage: '@radix-ui/react-dialog',
|
||||
requiredMarkers: ['containerCleanupGenerationRef', 'syncContainer(null)'],
|
||||
},
|
||||
{
|
||||
packageName: '@radix-ui/react-dismissable-layer',
|
||||
resolverFromPackage: '@radix-ui/react-dialog',
|
||||
requiredMarkers: ['nodeCleanupGenerationRef', 'syncNode(null)'],
|
||||
},
|
||||
];
|
||||
|
||||
function resolvePackageRoot({ packageName, resolverFromPackage }) {
|
||||
const packageRequire = resolverFromPackage
|
||||
? createRequire(require.resolve(resolverFromPackage))
|
||||
: require;
|
||||
const entrypointPath = packageRequire.resolve(packageName);
|
||||
return dirname(dirname(entrypointPath));
|
||||
}
|
||||
|
||||
const requiredMarkers = ['nodeCleanupGenerationRef', 'syncNode(null)'];
|
||||
const missing = [];
|
||||
|
||||
for (const relativePath of filesToCheck) {
|
||||
const filePath = join(packageRoot, relativePath);
|
||||
const source = readFileSync(filePath, 'utf8');
|
||||
const missingMarkers = requiredMarkers.filter((marker) => !source.includes(marker));
|
||||
if (missingMarkers.length > 0) {
|
||||
missing.push(`${relativePath}: ${missingMarkers.join(', ')}`);
|
||||
for (const check of patchChecks) {
|
||||
const packageRoot = resolvePackageRoot(check);
|
||||
|
||||
for (const relativePath of filesToCheck) {
|
||||
const filePath = join(packageRoot, relativePath);
|
||||
const source = readFileSync(filePath, 'utf8');
|
||||
const missingMarkers = check.requiredMarkers.filter((marker) => !source.includes(marker));
|
||||
if (missingMarkers.length > 0) {
|
||||
missing.push(`${check.packageName}/${relativePath}: ${missingMarkers.join(', ')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing.length > 0) {
|
||||
console.error(
|
||||
[
|
||||
'@radix-ui/react-presence is installed without the local React 19 Presence patch.',
|
||||
'Radix is installed without one or more local React 19 ref-cleanup patches.',
|
||||
'Run `pnpm install --force` before building production artifacts.',
|
||||
'',
|
||||
...missing,
|
||||
|
|
|
|||
Loading…
Reference in a new issue