@szhsin/react-menu
Advanced tools
Comparing version 4.2.0 to 4.2.1
@@ -8,7 +8,6 @@ import { useState, useReducer, useContext, useRef, useCallback, useEffect, useMemo } from 'react'; | ||
import { useItems } from '../hooks/useItems.js'; | ||
import { getScrollAncestor, floatEqual, commonProps, mergeProps, safeCall, isMenuOpen, getTransition, batchedUpdates } from '../utils/utils.js'; | ||
import { getScrollAncestor, commonProps, mergeProps, safeCall, isMenuOpen, getTransition, batchedUpdates } from '../utils/utils.js'; | ||
import { getPositionHelpers } from '../positionUtils/getPositionHelpers.js'; | ||
import { positionMenu } from '../positionUtils/positionMenu.js'; | ||
import { useLayoutEffect as useIsomorphicLayoutEffect } from '../hooks/useIsomorphicLayoutEffect.js'; | ||
import { getNormalizedClientRect } from '../positionUtils/getNormalizedClientRect.js'; | ||
import { useBEM } from '../hooks/useBEM.js'; | ||
@@ -76,7 +75,2 @@ import { useCombinedRef } from '../hooks/useCombinedRef.js'; | ||
const prevOpen = useRef(false); | ||
const latestMenuSize = useRef({ | ||
width: 0, | ||
height: 0 | ||
}); | ||
const latestHandlePosition = useRef(() => {}); | ||
const { | ||
@@ -172,3 +166,3 @@ hoverItem, | ||
} = positionHelpers; | ||
let menuHeight = menuRect.height; | ||
const menuHeight = menuRect.height; | ||
if (!noOverflowCheck && overflow !== 'visible') { | ||
@@ -180,5 +174,4 @@ const { | ||
let height, overflowAmt; | ||
const prevHeight = latestMenuSize.current.height; | ||
const bottomOverflow = getBottomOverflow(y); | ||
if (bottomOverflow > 0 || floatEqual(bottomOverflow, 0) && floatEqual(menuHeight, prevHeight)) { | ||
if (bottomOverflow > 0) { | ||
height = menuHeight - bottomOverflow; | ||
@@ -188,3 +181,3 @@ overflowAmt = bottomOverflow; | ||
const topOverflow = getTopOverflow(y); | ||
if (topOverflow < 0 || floatEqual(topOverflow, 0) && floatEqual(menuHeight, prevHeight)) { | ||
if (topOverflow < 0) { | ||
height = menuHeight + topOverflow; | ||
@@ -196,3 +189,2 @@ overflowAmt = 0 - topOverflow; | ||
if (height >= 0) { | ||
menuHeight = height; | ||
setOverflowData({ | ||
@@ -202,4 +194,2 @@ height, | ||
}); | ||
} else { | ||
setOverflowData(); | ||
} | ||
@@ -216,6 +206,2 @@ } | ||
setExpandedDirection(computedDirection); | ||
latestMenuSize.current = { | ||
width: menuRect.width, | ||
height: menuHeight | ||
}; | ||
}, [arrow, align, boundingBoxPadding, direction, gap, shift, position, overflow, anchorPoint, anchorRef, containerRef, boundingBoxRef, rootMenuRef, scrollNodes]); | ||
@@ -228,3 +214,2 @@ useIsomorphicLayoutEffect(() => { | ||
prevOpen.current = isOpen; | ||
latestHandlePosition.current = handlePosition; | ||
}, [isOpen, handlePosition, reposFlag]); | ||
@@ -274,34 +259,24 @@ useIsomorphicLayoutEffect(() => { | ||
useEffect(() => { | ||
if (typeof ResizeObserver !== 'function' || reposition === 'initial') return; | ||
const resizeObserver = new ResizeObserver(([entry]) => { | ||
const { | ||
borderBoxSize, | ||
target | ||
} = entry; | ||
let width, height; | ||
if (borderBoxSize) { | ||
const { | ||
inlineSize, | ||
blockSize | ||
} = borderBoxSize[0] || borderBoxSize; | ||
width = inlineSize; | ||
height = blockSize; | ||
if (!isOpen || typeof ResizeObserver !== 'function' || reposition === 'initial') return; | ||
const targetList = []; | ||
const resizeObserver = new ResizeObserver(entries => entries.forEach(({ | ||
target | ||
}) => { | ||
if (targetList.indexOf(target) < 0) { | ||
targetList.push(target); | ||
} else { | ||
const borderRect = getNormalizedClientRect(target); | ||
width = borderRect.width; | ||
height = borderRect.height; | ||
flushSync(() => { | ||
handlePosition(); | ||
forceReposSubmenu(); | ||
}); | ||
} | ||
if (width === 0 || height === 0) return; | ||
if (floatEqual(width, latestMenuSize.current.width, 1) && floatEqual(height, latestMenuSize.current.height, 1)) return; | ||
flushSync(() => { | ||
latestHandlePosition.current(); | ||
forceReposSubmenu(); | ||
}); | ||
}); | ||
const observeTarget = menuRef.current; | ||
resizeObserver.observe(observeTarget, { | ||
})); | ||
const resizeObserverOptions = { | ||
box: 'border-box' | ||
}); | ||
return () => resizeObserver.unobserve(observeTarget); | ||
}, [reposition]); | ||
}; | ||
resizeObserver.observe(menuRef.current, resizeObserverOptions); | ||
const anchor = anchorRef == null ? void 0 : anchorRef.current; | ||
anchor && resizeObserver.observe(anchor, resizeObserverOptions); | ||
return () => resizeObserver.disconnect(); | ||
}, [isOpen, reposition, anchorRef, handlePosition]); | ||
useEffect(() => { | ||
@@ -308,0 +283,0 @@ if (!isOpen) { |
@@ -6,3 +6,2 @@ import { unstable_batchedUpdates } from 'react-dom'; | ||
const values = Object.values || (obj => Object.keys(obj).map(key => obj[key])); | ||
const floatEqual = (a, b, diff = 0.0001) => Math.abs(a - b) < diff; | ||
const getTransition = (transition, name) => transition === true || !!(transition && transition[name]); | ||
@@ -72,2 +71,2 @@ const safeCall = (fn, arg) => typeof fn === 'function' ? fn(arg) : fn; | ||
export { batchedUpdates, commonProps, defineName, floatEqual, getName, getScrollAncestor, getTransition, indexOfNode, isMenuOpen, mergeProps, parsePadding, safeCall, values }; | ||
export { batchedUpdates, commonProps, defineName, getName, getScrollAncestor, getTransition, indexOfNode, isMenuOpen, mergeProps, parsePadding, safeCall, values }; |
@@ -146,3 +146,2 @@ 'use strict'; | ||
const values = Object.values || (obj => Object.keys(obj).map(key => obj[key])); | ||
const floatEqual = (a, b, diff = 0.0001) => Math.abs(a - b) < diff; | ||
const getTransition = (transition, name) => transition === true || !!(transition && transition[name]); | ||
@@ -939,7 +938,2 @@ const safeCall = (fn, arg) => typeof fn === 'function' ? fn(arg) : fn; | ||
const prevOpen = react.useRef(false); | ||
const latestMenuSize = react.useRef({ | ||
width: 0, | ||
height: 0 | ||
}); | ||
const latestHandlePosition = react.useRef(() => {}); | ||
const { | ||
@@ -1035,3 +1029,3 @@ hoverItem, | ||
} = positionHelpers; | ||
let menuHeight = menuRect.height; | ||
const menuHeight = menuRect.height; | ||
if (!noOverflowCheck && overflow !== 'visible') { | ||
@@ -1043,5 +1037,4 @@ const { | ||
let height, overflowAmt; | ||
const prevHeight = latestMenuSize.current.height; | ||
const bottomOverflow = getBottomOverflow(y); | ||
if (bottomOverflow > 0 || floatEqual(bottomOverflow, 0) && floatEqual(menuHeight, prevHeight)) { | ||
if (bottomOverflow > 0) { | ||
height = menuHeight - bottomOverflow; | ||
@@ -1051,3 +1044,3 @@ overflowAmt = bottomOverflow; | ||
const topOverflow = getTopOverflow(y); | ||
if (topOverflow < 0 || floatEqual(topOverflow, 0) && floatEqual(menuHeight, prevHeight)) { | ||
if (topOverflow < 0) { | ||
height = menuHeight + topOverflow; | ||
@@ -1059,3 +1052,2 @@ overflowAmt = 0 - topOverflow; | ||
if (height >= 0) { | ||
menuHeight = height; | ||
setOverflowData({ | ||
@@ -1065,4 +1057,2 @@ height, | ||
}); | ||
} else { | ||
setOverflowData(); | ||
} | ||
@@ -1079,6 +1069,2 @@ } | ||
setExpandedDirection(computedDirection); | ||
latestMenuSize.current = { | ||
width: menuRect.width, | ||
height: menuHeight | ||
}; | ||
}, [arrow, align, boundingBoxPadding, direction, gap, shift, position, overflow, anchorPoint, anchorRef, containerRef, boundingBoxRef, rootMenuRef, scrollNodes]); | ||
@@ -1091,3 +1077,2 @@ useIsomorphicLayoutEffect(() => { | ||
prevOpen.current = isOpen; | ||
latestHandlePosition.current = handlePosition; | ||
}, [isOpen, handlePosition, reposFlag]); | ||
@@ -1137,34 +1122,24 @@ useIsomorphicLayoutEffect(() => { | ||
react.useEffect(() => { | ||
if (typeof ResizeObserver !== 'function' || reposition === 'initial') return; | ||
const resizeObserver = new ResizeObserver(([entry]) => { | ||
const { | ||
borderBoxSize, | ||
target | ||
} = entry; | ||
let width, height; | ||
if (borderBoxSize) { | ||
const { | ||
inlineSize, | ||
blockSize | ||
} = borderBoxSize[0] || borderBoxSize; | ||
width = inlineSize; | ||
height = blockSize; | ||
if (!isOpen || typeof ResizeObserver !== 'function' || reposition === 'initial') return; | ||
const targetList = []; | ||
const resizeObserver = new ResizeObserver(entries => entries.forEach(({ | ||
target | ||
}) => { | ||
if (targetList.indexOf(target) < 0) { | ||
targetList.push(target); | ||
} else { | ||
const borderRect = getNormalizedClientRect(target); | ||
width = borderRect.width; | ||
height = borderRect.height; | ||
reactDom.flushSync(() => { | ||
handlePosition(); | ||
forceReposSubmenu(); | ||
}); | ||
} | ||
if (width === 0 || height === 0) return; | ||
if (floatEqual(width, latestMenuSize.current.width, 1) && floatEqual(height, latestMenuSize.current.height, 1)) return; | ||
reactDom.flushSync(() => { | ||
latestHandlePosition.current(); | ||
forceReposSubmenu(); | ||
}); | ||
}); | ||
const observeTarget = menuRef.current; | ||
resizeObserver.observe(observeTarget, { | ||
})); | ||
const resizeObserverOptions = { | ||
box: 'border-box' | ||
}); | ||
return () => resizeObserver.unobserve(observeTarget); | ||
}, [reposition]); | ||
}; | ||
resizeObserver.observe(menuRef.current, resizeObserverOptions); | ||
const anchor = anchorRef == null ? void 0 : anchorRef.current; | ||
anchor && resizeObserver.observe(anchor, resizeObserverOptions); | ||
return () => resizeObserver.disconnect(); | ||
}, [isOpen, reposition, anchorRef, handlePosition]); | ||
react.useEffect(() => { | ||
@@ -1171,0 +1146,0 @@ if (!isOpen) { |
{ | ||
"name": "@szhsin/react-menu", | ||
"version": "4.2.0", | ||
"version": "4.2.1", | ||
"description": "React component for building accessible menu, dropdown, submenu, context menu and more.", | ||
@@ -5,0 +5,0 @@ "author": "Zheng Song", |
@@ -309,3 +309,3 @@ import React = require('react'); | ||
* to explicitly reposition menu using the `repositionFlag` prop. | ||
* - 'auto' Reposition menu whenever its size has changed, using the `ResizeObserver` API. | ||
* - 'auto' Reposition menu whenever itself or the anchor has changed in size, using the `ResizeObserver` API. | ||
* @default 'auto' | ||
@@ -312,0 +312,0 @@ */ |
163023
5215