@reach/menu-button
Advanced tools
Comparing version 0.10.3 to 0.10.4
@@ -8,3 +8,3 @@ /** | ||
* @see Docs https://reacttraining.com/reach-ui/menu-button | ||
* @see Source https://github.com/reach/reach-ui/tree/master/packages/menu-button | ||
* @see Source https://github.com/reach/reach-ui/tree/main/packages/menu-button | ||
* @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2/#menubutton | ||
@@ -11,0 +11,0 @@ * |
@@ -110,3 +110,10 @@ 'use strict'; | ||
var selectCallbacks = React.useRef([]); | ||
var selectCallbacks = React.useRef([]); // If the popover's position overlaps with an option when the popover | ||
// initially opens, the mouseup event will trigger a select. To prevent that, | ||
// we decide the menu button is only ready to make a selection if the pointer | ||
// moves first, otherwise the user is just registering the initial button | ||
// click rather than selecting an item. This is similar to a native select | ||
// on most platforms, and our menu button popover works similarly. | ||
var readyToSelect = React.useRef(false); | ||
var context = { | ||
@@ -119,2 +126,3 @@ buttonRef: buttonRef, | ||
buttonClickedRef: buttonClickedRef, | ||
readyToSelect: readyToSelect, | ||
selectCallbacks: selectCallbacks, | ||
@@ -294,4 +302,7 @@ state: state | ||
dispatch = _useContext2.dispatch, | ||
readyToSelect = _useContext2.readyToSelect, | ||
selectCallbacks = _useContext2.selectCallbacks, | ||
selectionIndex = _useContext2.state.selectionIndex; | ||
_useContext2$state = _useContext2.state, | ||
selectionIndex = _useContext2$state.selectionIndex, | ||
isExpanded = _useContext2$state.isExpanded; | ||
@@ -379,3 +390,5 @@ var ownRef = React.useRef(null); // After the ref is mounted to the DOM node, we check to see if we have an | ||
function handleMouseMove(event) { | ||
function handleMouseMove() { | ||
readyToSelect.current = true; | ||
if (!isSelected && index != null) { | ||
@@ -392,2 +405,7 @@ dispatch({ | ||
function handleMouseUp(event) { | ||
if (!readyToSelect.current) { | ||
readyToSelect.current = true; | ||
return; | ||
} | ||
if (isRightClick(event.nativeEvent)) return; | ||
@@ -407,7 +425,13 @@ | ||
} | ||
} // Any time a mouseup event occurs anywhere in the document, we reset the | ||
// mouseEventStarted ref so we can check it again when needed. | ||
} // When the menu closes, reset readyToSelect for the next interaction. | ||
React.useEffect(function () { | ||
if (!isExpanded) { | ||
readyToSelect.current = false; | ||
} | ||
}, [isExpanded, readyToSelect]); // Any time a mouseup event occurs anywhere in the document, we reset the | ||
// mouseEventStarted ref so we can check it again when needed. | ||
React.useEffect(function () { | ||
var ownerDocument = utils.getOwnerDocument(ownRef.current) || document; | ||
@@ -880,3 +904,3 @@ | ||
case CLICK_MENU_ITEM: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: false, | ||
@@ -887,3 +911,3 @@ selectionIndex: -1 | ||
case CLOSE_MENU: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: false, | ||
@@ -894,3 +918,3 @@ selectionIndex: -1 | ||
case OPEN_MENU_AT_FIRST_ITEM: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: true, | ||
@@ -901,3 +925,3 @@ selectionIndex: 0 | ||
case OPEN_MENU_CLEARED: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: true, | ||
@@ -909,3 +933,3 @@ selectionIndex: -1 | ||
if (action.payload.index >= 0) { | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
selectionIndex: action.payload.max != null ? Math.min(Math.max(action.payload.index, 0), action.payload.max) : Math.max(action.payload.index, 0) | ||
@@ -918,3 +942,3 @@ }); | ||
case CLEAR_SELECTION_INDEX: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
selectionIndex: -1 | ||
@@ -924,3 +948,3 @@ }); | ||
case SET_BUTTON_ID: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
buttonId: action.payload | ||
@@ -931,3 +955,3 @@ }); | ||
if (typeof action.payload !== "undefined") { | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
typeaheadQuery: action.payload | ||
@@ -934,0 +958,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var n=require("react"),t=e(n);require("prop-types");var r=require("@reach/auto-id"),o=e(require("@reach/popover")),a=require("@reach/descendants"),u=require("@reach/utils");function i(){return(i=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e}).apply(this,arguments)}function s(e,n){if(null==e)return{};var t,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n.indexOf(t=a[r])>=0||(o[t]=e[t]);return o}var c=a.createDescendantContext("MenuDescendantContext"),d=u.createNamedContext("MenuContext",{}),l={buttonId:null,isExpanded:!1,typeaheadQuery:"",selectionIndex:-1},f=u.forwardRefWithAs((function(e,r){var o=e.as,a=void 0===o?"button":o,i=e.onKeyDown,c=e.onMouseDown,l=e.id,f=s(e,["as","onKeyDown","onMouseDown","id"]),E=n.useContext(d),p=E.buttonRef,v=E.buttonClickedRef,x=E.menuId,_=E.state,m=_.buttonId,y=_.isExpanded,M=E.dispatch,w=u.useForkedRef(p,r);return n.useEffect((function(){var e=null!=l?l:x?u.makeId("menu-button",x):"menu-button";m!==e&&M({type:"SET_BUTTON_ID",payload:e})}),[m,M,l,x]),t.createElement(a,Object.assign({"aria-expanded":!!y||void 0,"aria-haspopup":!0,"aria-controls":x},f,{ref:w,"data-reach-menu-button":"",id:m||void 0,onKeyDown:u.wrapEvent(i,(function(e){switch(e.key){case"ArrowDown":case"ArrowUp":e.preventDefault(),M({type:"OPEN_MENU_AT_FIRST_ITEM"});break;case"Enter":case" ":M({type:"OPEN_MENU_AT_FIRST_ITEM"})}})),onMouseDown:u.wrapEvent(c,(function(e){y||(v.current=!0),I(e.nativeEvent)||M(y?{type:"CLOSE_MENU",payload:{buttonRef:p}}:{type:"OPEN_MENU_CLEARED"})})),type:"button"}))})),E=u.forwardRefWithAs((function(e,r){var o=e.as,i=e.index,l=e.isLink,f=void 0!==l&&l,E=e.onClick,p=e.onDragStart,v=e.onMouseDown,x=e.onMouseEnter,_=e.onMouseLeave,m=e.onMouseMove,w=e.onMouseUp,C=e.onSelect,T=e.valueText,h=s(e,["as","index","isLink","onClick","onDragStart","onMouseDown","onMouseEnter","onMouseLeave","onMouseMove","onMouseUp","onSelect","valueText"]),b=n.useContext(d),R=b.buttonRef,D=b.dispatch,L=b.selectCallbacks,k=b.state.selectionIndex,O=n.useRef(null),S=n.useState(T||""),N=S[0],A=S[1],g=n.useCallback((function(e){e&&(O.current=e,(!T||e.textContent&&N!==e.textContent)&&A(e.textContent))}),[N,T]),U=u.useForkedRef(r,g),P=n.useRef(!1),j=a.useDescendant({element:O.current,key:N,isLink:f},c,i),F=j===k;function K(){M(R.current),C&&C(),D({type:"CLICK_MENU_ITEM"})}return L.current[j]=C,n.useEffect((function(){var e=u.getOwnerDocument(O.current)||document,n=function(){return P.current=!1};return e.addEventListener("mouseup",n),function(){return e.removeEventListener("mouseup",n)}}),[]),t.createElement(o,Object.assign({role:"menuitem",id:y(j),tabIndex:-1},h,{ref:U,"data-reach-menu-item":"","data-selected":F?"":void 0,"data-valuetext":N,onClick:u.wrapEvent(E,(function(e){f&&!I(e.nativeEvent)&&K()})),onDragStart:u.wrapEvent(p,(function(e){f&&e.preventDefault()})),onMouseDown:u.wrapEvent(v,(function(e){I(e.nativeEvent)||(f?P.current=!0:e.preventDefault())})),onMouseEnter:u.wrapEvent(x,(function(e){F||null==j||D({type:"SELECT_ITEM_AT_INDEX",payload:{index:j}})})),onMouseLeave:u.wrapEvent(_,(function(e){D({type:"CLEAR_SELECTION_INDEX"})})),onMouseMove:u.wrapEvent(m,(function(e){F||null==j||D({type:"SELECT_ITEM_AT_INDEX",payload:{index:j}})})),onMouseUp:u.wrapEvent(w,(function(e){I(e.nativeEvent)||(f?P.current?P.current=!1:O.current&&O.current.click():K())}))}))})),p=u.forwardRefWithAs((function(e,n){var r=e.as,o=void 0===r?"div":r,a=s(e,["as"]);return t.createElement(E,Object.assign({},a,{ref:n,as:o}))})),v=u.forwardRefWithAs((function(e,r){var o=e.as,i=void 0===o?"div":o,l=e.children,f=e.onKeyDown,E=s(e,["as","children","id","onKeyDown"]),p=n.useContext(d),v=p.menuId,x=p.dispatch,_=p.buttonRef,m=p.menuRef,I=p.selectCallbacks,w=p.state,C=w.isExpanded,T=w.buttonId,h=w.selectionIndex,b=w.typeaheadQuery,R=a.useDescendants(c),D=u.useForkedRef(m,r);n.useEffect((function(){var e=function(e,n){if(void 0===n&&(n=""),!n)return null;var t=e.find((function(e){var t,r,o=e.element;return null==o||null===(t=o.dataset)||void 0===t||null===(r=t.valuetext)||void 0===r?void 0:r.toLowerCase().startsWith(n)}));return t?e.indexOf(t):null}(R,b);b&&null!=e&&x({type:"SELECT_ITEM_AT_INDEX",payload:{index:e}});var n=window.setTimeout((function(){return b&&x({type:"SEARCH_FOR_ITEM",payload:""})}),1e3);return function(){return window.clearTimeout(n)}}),[x,R,b]);var L=u.usePrevious(R.length),k=u.usePrevious(R[h]),O=u.usePrevious(h);n.useEffect((function(){h>R.length-1?x({type:"SELECT_ITEM_AT_INDEX",payload:{index:R.length-1}}):L!==R.length&&h>-1&&k&&O===h&&R[h]!==k&&x({type:"SELECT_ITEM_AT_INDEX",payload:{index:R.findIndex((function(e){return e.key===k.key}))}})}),[x,R,L,k,O,h]);var S=u.wrapEvent((function(e){var n=e.key;if(C)switch(n){case"Enter":case" ":var t=R.find((function(e){return e.index===h}));t&&(t.isLink&&t.element?t.element.click():(e.preventDefault(),M(_.current),I.current[t.index]&&I.current[t.index](),x({type:"CLICK_MENU_ITEM"})));break;case"Escape":M(_.current),x({type:"CLOSE_MENU",payload:{buttonRef:_}});break;case"Tab":e.preventDefault();break;default:if(u.isString(n)&&1===n.length){var r=b+n.toLowerCase();x({type:"SEARCH_FOR_ITEM",payload:r})}}}),a.useDescendantKeyDown(c,{currentIndex:h,orientation:"vertical",rotate:!1,callback:function(e){x({type:"SELECT_ITEM_AT_INDEX",payload:{index:e}})},key:"index"}));return t.createElement(i,Object.assign({"aria-activedescendant":y(h)||void 0,"aria-labelledby":T||void 0,role:"menu",tabIndex:-1},E,{ref:D,"data-reach-menu-items":"",id:v,onKeyDown:u.wrapEvent(f,S)}),l)})),x=u.forwardRefWithAs((function(e,n){var r=e.as,o=void 0===r?"a":r,a=e.component,i=e.onSelect,c=s(e,["as","component","onSelect"]);return a&&console.warn("[@reach/menu-button]: Please use the `as` prop instead of `component`."),t.createElement("div",{role:"none",tabIndex:-1},t.createElement(E,Object.assign({},c,{ref:n,"data-reach-menu-link":"",as:o,isLink:!0,onSelect:i||u.noop})))})),_=n.forwardRef((function(e,n){var r=e.portal,o=void 0===r||r,a=s(e,["portal"]);return t.createElement(m,{portal:o},t.createElement(v,Object.assign({},a,{ref:n,"data-reach-menu-list":""})))})),m=n.forwardRef((function(e,r){var a=e.children,c=e.portal,l=void 0===c||c,f=e.position,E=s(e,["children","portal","position"]),p=n.useContext(d),v=p.buttonRef,x=p.buttonClickedRef,_=p.dispatch,m=p.menuRef,y=p.popoverRef,I=p.state.isExpanded,M=u.useForkedRef(y,r);n.useEffect((function(){function e(e){var n;x.current?x.current=!1:I&&y.current&&((null===(n=y.current)||void 0===n?void 0:n.contains(e.relatedTarget||e.target))||_({type:"CLOSE_MENU",payload:{buttonRef:v}}))}return window.addEventListener("mousedown",e),function(){window.removeEventListener("mousedown",e)}}),[x,v,_,I,m,y]);var w=i({ref:M,"data-reach-menu":"","data-reach-menu-popover":"",hidden:!I,children:a},E);return l?t.createElement(o,Object.assign({},w,{targetRef:v,position:f})):t.createElement("div",Object.assign({},w))}));function y(e){var t=n.useContext(d);return null!=e&&e>-1?u.makeId("option-"+e,t.menuId):void 0}function I(e){return 3===e.which||2===e.button}function M(e){e&&e.focus()}function w(e,n){switch(void 0===n&&(n={}),n.type){case"CLICK_MENU_ITEM":case"CLOSE_MENU":return i(i({},e),{},{isExpanded:!1,selectionIndex:-1});case"OPEN_MENU_AT_FIRST_ITEM":return i(i({},e),{},{isExpanded:!0,selectionIndex:0});case"OPEN_MENU_CLEARED":return i(i({},e),{},{isExpanded:!0,selectionIndex:-1});case"SELECT_ITEM_AT_INDEX":return n.payload.index>=0?i(i({},e),{},{selectionIndex:null!=n.payload.max?Math.min(Math.max(n.payload.index,0),n.payload.max):Math.max(n.payload.index,0)}):e;case"CLEAR_SELECTION_INDEX":return i(i({},e),{},{selectionIndex:-1});case"SET_BUTTON_ID":return i(i({},e),{},{buttonId:n.payload});case"SEARCH_FOR_ITEM":return void 0!==n.payload?i(i({},e),{},{typeaheadQuery:n.payload}):e;default:return e}}exports.Menu=function(e){var o=e.id,i=e.children,s=n.useRef(null),f=n.useRef(null),E=n.useRef(null),p=a.useDescendantsInit(),v=p[0],x=p[1],_=n.useReducer(w,l),m=_[0],y=_[1],I=r.useId(o),C=o||u.makeId("menu",I),T=n.useRef(!1),h=n.useRef([]),b={buttonRef:s,dispatch:y,menuId:C,menuRef:f,popoverRef:E,buttonClickedRef:T,selectCallbacks:h,state:m};return n.useEffect((function(){m.isExpanded?(window.__REACH_DISABLE_TOOLTIPS=!0,window.requestAnimationFrame((function(){M(f.current)}))):window.__REACH_DISABLE_TOOLTIPS=!1}),[m.isExpanded]),n.useEffect((function(){return u.checkStyles("menu-button")}),[]),t.createElement(a.DescendantProvider,{context:c,items:v,set:x},t.createElement(d.Provider,{value:b},u.isFunction(i)?i({isExpanded:m.isExpanded,isOpen:m.isExpanded}):i))},exports.MenuButton=f,exports.MenuItem=p,exports.MenuItems=v,exports.MenuLink=x,exports.MenuList=_,exports.MenuPopover=m,exports.useMenuButtonContext=function(){var e=n.useContext(d).state.isExpanded;return n.useMemo((function(){return{isExpanded:e}}),[e])}; | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var n=require("react"),t=e(n);require("prop-types");var r=require("@reach/auto-id"),o=e(require("@reach/popover")),a=require("@reach/descendants"),u=require("@reach/utils");function i(){return(i=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e}).apply(this,arguments)}function s(e,n){if(null==e)return{};var t,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n.indexOf(t=a[r])>=0||(o[t]=e[t]);return o}var c=a.createDescendantContext("MenuDescendantContext"),d=u.createNamedContext("MenuContext",{}),l={buttonId:null,isExpanded:!1,typeaheadQuery:"",selectionIndex:-1},f=u.forwardRefWithAs((function(e,r){var o=e.as,a=void 0===o?"button":o,i=e.onKeyDown,c=e.onMouseDown,l=e.id,f=s(e,["as","onKeyDown","onMouseDown","id"]),E=n.useContext(d),p=E.buttonRef,v=E.buttonClickedRef,x=E.menuId,_=E.state,y=_.buttonId,m=_.isExpanded,M=E.dispatch,w=u.useForkedRef(p,r);return n.useEffect((function(){var e=null!=l?l:x?u.makeId("menu-button",x):"menu-button";y!==e&&M({type:"SET_BUTTON_ID",payload:e})}),[y,M,l,x]),t.createElement(a,Object.assign({"aria-expanded":!!m||void 0,"aria-haspopup":!0,"aria-controls":x},f,{ref:w,"data-reach-menu-button":"",id:y||void 0,onKeyDown:u.wrapEvent(i,(function(e){switch(e.key){case"ArrowDown":case"ArrowUp":e.preventDefault(),M({type:"OPEN_MENU_AT_FIRST_ITEM"});break;case"Enter":case" ":M({type:"OPEN_MENU_AT_FIRST_ITEM"})}})),onMouseDown:u.wrapEvent(c,(function(e){m||(v.current=!0),I(e.nativeEvent)||M(m?{type:"CLOSE_MENU",payload:{buttonRef:p}}:{type:"OPEN_MENU_CLEARED"})})),type:"button"}))})),E=u.forwardRefWithAs((function(e,r){var o=e.as,i=e.index,l=e.isLink,f=void 0!==l&&l,E=e.onClick,p=e.onDragStart,v=e.onMouseDown,x=e.onMouseEnter,_=e.onMouseLeave,y=e.onMouseMove,w=e.onMouseUp,T=e.onSelect,C=e.valueText,h=s(e,["as","index","isLink","onClick","onDragStart","onMouseDown","onMouseEnter","onMouseLeave","onMouseMove","onMouseUp","onSelect","valueText"]),R=n.useContext(d),b=R.buttonRef,D=R.dispatch,L=R.readyToSelect,k=R.selectCallbacks,S=R.state,O=S.selectionIndex,N=S.isExpanded,A=n.useRef(null),g=n.useState(C||""),U=g[0],P=g[1],j=n.useCallback((function(e){e&&(A.current=e,(!C||e.textContent&&U!==e.textContent)&&P(e.textContent))}),[U,C]),F=u.useForkedRef(r,j),K=n.useRef(!1),X=a.useDescendant({element:A.current,key:U,isLink:f},c,i),q=X===O;function B(){M(b.current),T&&T(),D({type:"CLICK_MENU_ITEM"})}return k.current[X]=T,n.useEffect((function(){N||(L.current=!1)}),[N,L]),n.useEffect((function(){var e=u.getOwnerDocument(A.current)||document,n=function(){return K.current=!1};return e.addEventListener("mouseup",n),function(){return e.removeEventListener("mouseup",n)}}),[]),t.createElement(o,Object.assign({role:"menuitem",id:m(X),tabIndex:-1},h,{ref:F,"data-reach-menu-item":"","data-selected":q?"":void 0,"data-valuetext":U,onClick:u.wrapEvent(E,(function(e){f&&!I(e.nativeEvent)&&B()})),onDragStart:u.wrapEvent(p,(function(e){f&&e.preventDefault()})),onMouseDown:u.wrapEvent(v,(function(e){I(e.nativeEvent)||(f?K.current=!0:e.preventDefault())})),onMouseEnter:u.wrapEvent(x,(function(e){q||null==X||D({type:"SELECT_ITEM_AT_INDEX",payload:{index:X}})})),onMouseLeave:u.wrapEvent(_,(function(e){D({type:"CLEAR_SELECTION_INDEX"})})),onMouseMove:u.wrapEvent(y,(function(){L.current=!0,q||null==X||D({type:"SELECT_ITEM_AT_INDEX",payload:{index:X}})})),onMouseUp:u.wrapEvent(w,(function(e){L.current?I(e.nativeEvent)||(f?K.current?K.current=!1:A.current&&A.current.click():B()):L.current=!0}))}))})),p=u.forwardRefWithAs((function(e,n){var r=e.as,o=void 0===r?"div":r,a=s(e,["as"]);return t.createElement(E,Object.assign({},a,{ref:n,as:o}))})),v=u.forwardRefWithAs((function(e,r){var o=e.as,i=void 0===o?"div":o,l=e.children,f=e.onKeyDown,E=s(e,["as","children","id","onKeyDown"]),p=n.useContext(d),v=p.menuId,x=p.dispatch,_=p.buttonRef,y=p.menuRef,I=p.selectCallbacks,w=p.state,T=w.isExpanded,C=w.buttonId,h=w.selectionIndex,R=w.typeaheadQuery,b=a.useDescendants(c),D=u.useForkedRef(y,r);n.useEffect((function(){var e=function(e,n){if(void 0===n&&(n=""),!n)return null;var t=e.find((function(e){var t,r,o=e.element;return null==o||null===(t=o.dataset)||void 0===t||null===(r=t.valuetext)||void 0===r?void 0:r.toLowerCase().startsWith(n)}));return t?e.indexOf(t):null}(b,R);R&&null!=e&&x({type:"SELECT_ITEM_AT_INDEX",payload:{index:e}});var n=window.setTimeout((function(){return R&&x({type:"SEARCH_FOR_ITEM",payload:""})}),1e3);return function(){return window.clearTimeout(n)}}),[x,b,R]);var L=u.usePrevious(b.length),k=u.usePrevious(b[h]),S=u.usePrevious(h);n.useEffect((function(){h>b.length-1?x({type:"SELECT_ITEM_AT_INDEX",payload:{index:b.length-1}}):L!==b.length&&h>-1&&k&&S===h&&b[h]!==k&&x({type:"SELECT_ITEM_AT_INDEX",payload:{index:b.findIndex((function(e){return e.key===k.key}))}})}),[x,b,L,k,S,h]);var O=u.wrapEvent((function(e){var n=e.key;if(T)switch(n){case"Enter":case" ":var t=b.find((function(e){return e.index===h}));t&&(t.isLink&&t.element?t.element.click():(e.preventDefault(),M(_.current),I.current[t.index]&&I.current[t.index](),x({type:"CLICK_MENU_ITEM"})));break;case"Escape":M(_.current),x({type:"CLOSE_MENU",payload:{buttonRef:_}});break;case"Tab":e.preventDefault();break;default:if(u.isString(n)&&1===n.length){var r=R+n.toLowerCase();x({type:"SEARCH_FOR_ITEM",payload:r})}}}),a.useDescendantKeyDown(c,{currentIndex:h,orientation:"vertical",rotate:!1,callback:function(e){x({type:"SELECT_ITEM_AT_INDEX",payload:{index:e}})},key:"index"}));return t.createElement(i,Object.assign({"aria-activedescendant":m(h)||void 0,"aria-labelledby":C||void 0,role:"menu",tabIndex:-1},E,{ref:D,"data-reach-menu-items":"",id:v,onKeyDown:u.wrapEvent(f,O)}),l)})),x=u.forwardRefWithAs((function(e,n){var r=e.as,o=void 0===r?"a":r,a=e.component,i=e.onSelect,c=s(e,["as","component","onSelect"]);return a&&console.warn("[@reach/menu-button]: Please use the `as` prop instead of `component`."),t.createElement("div",{role:"none",tabIndex:-1},t.createElement(E,Object.assign({},c,{ref:n,"data-reach-menu-link":"",as:o,isLink:!0,onSelect:i||u.noop})))})),_=n.forwardRef((function(e,n){var r=e.portal,o=void 0===r||r,a=s(e,["portal"]);return t.createElement(y,{portal:o},t.createElement(v,Object.assign({},a,{ref:n,"data-reach-menu-list":""})))})),y=n.forwardRef((function(e,r){var a=e.children,c=e.portal,l=void 0===c||c,f=e.position,E=s(e,["children","portal","position"]),p=n.useContext(d),v=p.buttonRef,x=p.buttonClickedRef,_=p.dispatch,y=p.menuRef,m=p.popoverRef,I=p.state.isExpanded,M=u.useForkedRef(m,r);n.useEffect((function(){function e(e){var n;x.current?x.current=!1:I&&m.current&&((null===(n=m.current)||void 0===n?void 0:n.contains(e.relatedTarget||e.target))||_({type:"CLOSE_MENU",payload:{buttonRef:v}}))}return window.addEventListener("mousedown",e),function(){window.removeEventListener("mousedown",e)}}),[x,v,_,I,y,m]);var w=i({ref:M,"data-reach-menu":"","data-reach-menu-popover":"",hidden:!I,children:a},E);return l?t.createElement(o,Object.assign({},w,{targetRef:v,position:f})):t.createElement("div",Object.assign({},w))}));function m(e){var t=n.useContext(d);return null!=e&&e>-1?u.makeId("option-"+e,t.menuId):void 0}function I(e){return 3===e.which||2===e.button}function M(e){e&&e.focus()}function w(e,n){switch(void 0===n&&(n={}),n.type){case"CLICK_MENU_ITEM":case"CLOSE_MENU":return i({},e,{isExpanded:!1,selectionIndex:-1});case"OPEN_MENU_AT_FIRST_ITEM":return i({},e,{isExpanded:!0,selectionIndex:0});case"OPEN_MENU_CLEARED":return i({},e,{isExpanded:!0,selectionIndex:-1});case"SELECT_ITEM_AT_INDEX":return n.payload.index>=0?i({},e,{selectionIndex:null!=n.payload.max?Math.min(Math.max(n.payload.index,0),n.payload.max):Math.max(n.payload.index,0)}):e;case"CLEAR_SELECTION_INDEX":return i({},e,{selectionIndex:-1});case"SET_BUTTON_ID":return i({},e,{buttonId:n.payload});case"SEARCH_FOR_ITEM":return void 0!==n.payload?i({},e,{typeaheadQuery:n.payload}):e;default:return e}}exports.Menu=function(e){var o=e.id,i=e.children,s=n.useRef(null),f=n.useRef(null),E=n.useRef(null),p=a.useDescendantsInit(),v=p[0],x=p[1],_=n.useReducer(w,l),y=_[0],m=_[1],I=r.useId(o),T=o||u.makeId("menu",I),C=n.useRef(!1),h=n.useRef([]),R=n.useRef(!1),b={buttonRef:s,dispatch:m,menuId:T,menuRef:f,popoverRef:E,buttonClickedRef:C,readyToSelect:R,selectCallbacks:h,state:y};return n.useEffect((function(){y.isExpanded?(window.__REACH_DISABLE_TOOLTIPS=!0,window.requestAnimationFrame((function(){M(f.current)}))):window.__REACH_DISABLE_TOOLTIPS=!1}),[y.isExpanded]),n.useEffect((function(){return u.checkStyles("menu-button")}),[]),t.createElement(a.DescendantProvider,{context:c,items:v,set:x},t.createElement(d.Provider,{value:b},u.isFunction(i)?i({isExpanded:y.isExpanded,isOpen:y.isExpanded}):i))},exports.MenuButton=f,exports.MenuItem=p,exports.MenuItems=v,exports.MenuLink=x,exports.MenuList=_,exports.MenuPopover=y,exports.useMenuButtonContext=function(){var e=n.useContext(d).state.isExpanded;return n.useMemo((function(){return{isExpanded:e}}),[e])}; | ||
//# sourceMappingURL=menu-button.cjs.production.min.js.map |
@@ -103,3 +103,10 @@ import React, { useRef, useReducer, useEffect, useContext, forwardRef, useMemo, useState, useCallback } from 'react'; | ||
var selectCallbacks = useRef([]); | ||
var selectCallbacks = useRef([]); // If the popover's position overlaps with an option when the popover | ||
// initially opens, the mouseup event will trigger a select. To prevent that, | ||
// we decide the menu button is only ready to make a selection if the pointer | ||
// moves first, otherwise the user is just registering the initial button | ||
// click rather than selecting an item. This is similar to a native select | ||
// on most platforms, and our menu button popover works similarly. | ||
var readyToSelect = useRef(false); | ||
var context = { | ||
@@ -112,2 +119,3 @@ buttonRef: buttonRef, | ||
buttonClickedRef: buttonClickedRef, | ||
readyToSelect: readyToSelect, | ||
selectCallbacks: selectCallbacks, | ||
@@ -287,4 +295,7 @@ state: state | ||
dispatch = _useContext2.dispatch, | ||
readyToSelect = _useContext2.readyToSelect, | ||
selectCallbacks = _useContext2.selectCallbacks, | ||
selectionIndex = _useContext2.state.selectionIndex; | ||
_useContext2$state = _useContext2.state, | ||
selectionIndex = _useContext2$state.selectionIndex, | ||
isExpanded = _useContext2$state.isExpanded; | ||
@@ -372,3 +383,5 @@ var ownRef = useRef(null); // After the ref is mounted to the DOM node, we check to see if we have an | ||
function handleMouseMove(event) { | ||
function handleMouseMove() { | ||
readyToSelect.current = true; | ||
if (!isSelected && index != null) { | ||
@@ -385,2 +398,7 @@ dispatch({ | ||
function handleMouseUp(event) { | ||
if (!readyToSelect.current) { | ||
readyToSelect.current = true; | ||
return; | ||
} | ||
if (isRightClick(event.nativeEvent)) return; | ||
@@ -400,7 +418,13 @@ | ||
} | ||
} // Any time a mouseup event occurs anywhere in the document, we reset the | ||
// mouseEventStarted ref so we can check it again when needed. | ||
} // When the menu closes, reset readyToSelect for the next interaction. | ||
useEffect(function () { | ||
if (!isExpanded) { | ||
readyToSelect.current = false; | ||
} | ||
}, [isExpanded, readyToSelect]); // Any time a mouseup event occurs anywhere in the document, we reset the | ||
// mouseEventStarted ref so we can check it again when needed. | ||
useEffect(function () { | ||
var ownerDocument = getOwnerDocument(ownRef.current) || document; | ||
@@ -873,3 +897,3 @@ | ||
case CLICK_MENU_ITEM: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: false, | ||
@@ -880,3 +904,3 @@ selectionIndex: -1 | ||
case CLOSE_MENU: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: false, | ||
@@ -887,3 +911,3 @@ selectionIndex: -1 | ||
case OPEN_MENU_AT_FIRST_ITEM: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: true, | ||
@@ -894,3 +918,3 @@ selectionIndex: 0 | ||
case OPEN_MENU_CLEARED: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
isExpanded: true, | ||
@@ -902,3 +926,3 @@ selectionIndex: -1 | ||
if (action.payload.index >= 0) { | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
selectionIndex: action.payload.max != null ? Math.min(Math.max(action.payload.index, 0), action.payload.max) : Math.max(action.payload.index, 0) | ||
@@ -911,3 +935,3 @@ }); | ||
case CLEAR_SELECTION_INDEX: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
selectionIndex: -1 | ||
@@ -917,3 +941,3 @@ }); | ||
case SET_BUTTON_ID: | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
buttonId: action.payload | ||
@@ -924,3 +948,3 @@ }); | ||
if (typeof action.payload !== "undefined") { | ||
return _extends(_extends({}, state), {}, { | ||
return _extends({}, state, { | ||
typeaheadQuery: action.payload | ||
@@ -927,0 +951,0 @@ }); |
{ | ||
"name": "@reach/menu-button", | ||
"version": "0.10.3", | ||
"version": "0.10.4", | ||
"description": "Accessible React button dropdown menu.", | ||
@@ -16,8 +16,8 @@ "author": "React Training <hello@reacttraining.com>", | ||
"dependencies": { | ||
"@reach/auto-id": "^0.10.3", | ||
"@reach/descendants": "^0.10.3", | ||
"@reach/popover": "^0.10.3", | ||
"@reach/utils": "^0.10.3", | ||
"@reach/auto-id": "0.10.4", | ||
"@reach/descendants": "0.10.4", | ||
"@reach/popover": "0.10.4", | ||
"@reach/utils": "0.10.4", | ||
"prop-types": "^15.7.2", | ||
"tslib": "^1.11.2" | ||
"tslib": "^2.0.0" | ||
}, | ||
@@ -36,3 +36,3 @@ "peerDependencies": { | ||
], | ||
"gitHead": "fd32b2b31a3e50265b0c274654a5e4105847d18e" | ||
"gitHead": "a0c7b3672835b2a9f84732663bb0e78992541211" | ||
} |
@@ -5,3 +5,3 @@ # @reach/menu-button | ||
[Docs](https://reacttraining.com/reach-ui/menu-button) | [Source](https://github.com/reach/reach-ui/tree/master/packages/menu-button) | [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.2/#menubutton) | ||
[Docs](https://reacttraining.com/reach-ui/menu-button) | [Source](https://github.com/reach/reach-ui/tree/main/packages/menu-button) | [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.2/#menubutton) | ||
@@ -8,0 +8,0 @@ An accessible dropdown menu for the common dropdown menu button design pattern. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
231817
1973
+ Added@reach/auto-id@0.10.4(transitive)
+ Added@reach/descendants@0.10.4(transitive)
+ Added@reach/observe-rect@1.1.0(transitive)
+ Added@reach/popover@0.10.4(transitive)
+ Added@reach/portal@0.10.4(transitive)
+ Added@reach/rect@0.10.4(transitive)
+ Added@reach/utils@0.10.4(transitive)
- Removed@reach/auto-id@0.10.5(transitive)
- Removed@reach/descendants@0.10.5(transitive)
- Removed@reach/observe-rect@1.2.0(transitive)
- Removed@reach/popover@0.10.5(transitive)
- Removed@reach/portal@0.10.5(transitive)
- Removed@reach/rect@0.10.5(transitive)
- Removed@reach/utils@0.10.5(transitive)
- Removedtslib@1.14.1(transitive)
Updated@reach/auto-id@0.10.4
Updated@reach/descendants@0.10.4
Updated@reach/popover@0.10.4
Updated@reach/utils@0.10.4
Updatedtslib@^2.0.0