@contentful/f36-menu 4.78.0 → 4.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/esm/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import W, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
|
|
2
2
|
import { useId, mergeRefs, useControllableState, getMenuItemStyles } from '@contentful/f36-core';
|
|
3
3
|
import { Popover } from '@contentful/f36-popover';
|
|
4
4
|
import { cx, css } from 'emotion';
|
|
5
|
-
import
|
|
5
|
+
import v from '@contentful/f36-tokens';
|
|
6
6
|
import { Caption } from '@contentful/f36-typography';
|
|
7
7
|
import { ChevronRightIcon } from '@contentful/f36-icons';
|
|
8
8
|
|
|
9
|
-
var Fe=Object.defineProperty,ke=Object.defineProperties;var We=Object.getOwnPropertyDescriptors;var
|
|
9
|
+
var Fe=Object.defineProperty,ke=Object.defineProperties;var We=Object.getOwnPropertyDescriptors;var B=Object.getOwnPropertySymbols;var ae=Object.prototype.hasOwnProperty,ce=Object.prototype.propertyIsEnumerable;var me=(e,t,o)=>t in e?Fe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,i=(e,t)=>{for(var o in t||(t={}))ae.call(t,o)&&me(e,o,t[o]);if(B)for(var o of B(t))ce.call(t,o)&&me(e,o,t[o]);return e},h=(e,t)=>ke(e,We(t));var x=(e,t)=>{var o={};for(var n in e)ae.call(e,n)&&t.indexOf(n)<0&&(o[n]=e[n]);if(e!=null&&B)for(var n of B(e))t.indexOf(n)<0&&ce.call(e,n)&&(o[n]=e[n]);return o};var pe={vertical:{prev:"ArrowUp",next:"ArrowDown"},horizontal:{prev:"ArrowLeft",next:"ArrowRight"}},le=({itemsContainerRef:e,itemsSelector:t,keyType:o="vertical"})=>{let[n,u]=useState(0),a=useCallback(s=>{let l=e.current;if(!l)return;let b=l.querySelectorAll(t);if(b.length===0)return;let c=b.length-1,S=()=>u(0),T=()=>u(c),p=()=>{n===c?S():u(n+1);},d=()=>{n===0?T():u(n-1);},g={[pe[o].next]:p,[pe[o].prev]:d}[s.key];g&&(s.preventDefault(),g());},[n,t,e,o]);return {focusedIndex:n,handleArrowsKeyDown:a,setFocusedIndex:u}};var de=W.createContext(void 0),w=()=>{let e=W.useContext(de);if(e===void 0)throw new Error("useMenuContext must be used within a MenuContextProvider");return e},ge=de.Provider;var z='[role="menuitem"]:not(:disabled)';function U(e){let ne=e,{closeOnSelect:t=!0,closeOnBlur:o=!0,closeOnEsc:n=!0,children:u,onOpen:a}=ne,s=x(ne,["closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen"]),{isOpen:l,handleOpen:b,handleClose:c,isControlled:S}=useControllableState({isOpen:e.isOpen,defaultIsOpen:e.defaultIsOpen,onOpen:a,onClose:e.onClose}),T=useRef(null),p=useRef(null),d=useId(null,"menu"),{focusedIndex:f,handleArrowsKeyDown:g,setFocusedIndex:N}=le({itemsContainerRef:p,itemsSelector:z});useEffect(()=>{if(l&&p.current){let r=p.current.querySelectorAll(z);r.length>0&&f<r.length?setTimeout(()=>{r[f].focus({preventScroll:!1});},0):setTimeout(()=>{var E;(E=p.current)==null||E.focus({preventScroll:!1});},0);}},[l,f]);let R=useCallback(r=>{let P=[...p.current.querySelectorAll(z)].findIndex(y=>r===y);P!==-1&&N(P);},[N]),m=useCallback(()=>{var r;c(),(r=T.current)==null||r.focus({preventScroll:!0});},[c]),O=useCallback(r=>{if(r.key==="Tab"){r.preventDefault(),m();return}if(r.stopPropagation(),r.key==="ArrowLeft"){r.preventDefault(),m();return}g(r);},[m,g]),M=useRef(!1),C=useMemo(()=>({isOpen:l,menuId:d,focusMenuItem:R,getTriggerProps:(r={},E=null)=>({onMouseDown:P=>{var y;M.current=!0,(y=r.onMouseDown)==null||y.call(r,P);},onMouseUp:P=>{var y;M.current=!1,(y=r.onMouseUp)==null||y.call(r,P);},onClick:P=>{var I;S&&!a||(l?c():b()),(I=r.onClick)==null||I.call(r,P);},ref:mergeRefs(T,E)}),getMenuListProps:(r={},E=null)=>({ref:mergeRefs(p,E),onKeyDown:P=>{var y;O(P),(y=r.onKeyDown)==null||y.call(r,P);},onBlur:P=>{var re,se,ie,ue;if((re=r.onBlur)==null||re.call(r,P),!o)return;let y=document.activeElement,I=P.relatedTarget||y,He=p.current===I||((se=p.current)==null?void 0:se.contains(I)),Ae=T.current===I||((ie=T.current)==null?void 0:ie.contains(I))||M.current,De=((ue=I==null?void 0:I.parentElement)==null?void 0:ue.dataset.parentMenu)===d;if(He||Ae||De){P.stopPropagation();return}c();}}),getMenuItemProps:(r={})=>({onClick:E=>{var y;(y=r.onClick)==null||y.call(r,E);let P=!!E.target.getAttribute("aria-haspopup");t&&!P&&m();}}),propsToPropagateToSubmenus:{closeOnSelect:t,closeOnBlur:o,closeOnEsc:n}}),[d,l,O,t,c,b,R,o,n,m,S,a]);return W.createElement(ge,{value:C},W.createElement(Popover,h(i({},s),{isOpen:l,onClose:c,id:d,closeOnEsc:n,autoFocus:!1,closeOnBlur:!1}),u))}var xe=W.createContext(void 0),K=()=>W.useContext(xe),Te=xe.Provider;var be=()=>css({position:"sticky",top:0,left:0,backgroundColor:v.colorWhite,borderBottom:`1px solid ${v.gray300}`,marginBottom:v.spacing2Xs,padding:`${v.spacing2Xs} 0`,zIndex:1001}),Se=()=>css({position:"sticky",bottom:0,left:0,backgroundColor:v.colorWhite,borderTop:`1px solid ${v.gray300}`,marginTop:v.spacing2Xs,padding:`${v.spacing2Xs} 0`,zIndex:1001}),he=e=>({container:css({borderRadius:"8px",overflowY:"auto",position:"relative",padding:0,paddingTop:e.hasStickyHeader?0:v.spacing2Xs,paddingBottom:e.hasStickyFooter?0:v.spacing2Xs})});var H=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-header",className:n}=s,u=x(s,["children","testId","className"]),a=be();return W.createElement("div",i({"data-test-id":o,className:cx(a,n)},u),t)};H.displayName="MenuListHeader";var A=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-footer",className:n}=s,u=x(s,["children","testId","className"]),a=Se();return W.createElement("div",i({"data-test-id":o,className:cx(a,n)},u),t)};A.displayName="MenuListFooter";function Ze(e){var t;return !!((t=e==null?void 0:e.type)!=null&&t.displayName)}var _e=(e,t)=>{let d=e,{children:o,testId:n="cf-ui-menu-list",className:u}=d,a=x(d,["children","testId","className"]),{getMenuListProps:s}=w(),l=K(),b=null,c=null,S=[];W.Children.forEach(o,f=>{let g=!0;Ze(f)&&(f.type.displayName===H.displayName?(b=f,g=!1):f.type.displayName===A.displayName&&(c=f,g=!1)),g&&S.push(f);});let T=he({hasStickyHeader:!!b,hasStickyFooter:!!c}),p=l?l.getSubmenuListProps(a):a;return W.createElement(Popover.Content,h(i(i({role:"menu"},p),s(p,t)),{className:cx(T.container,u),testId:n}),b,S,c)},Y=W.forwardRef(_e);var Ce=({isActive:e,isDisabled:t})=>cx(getMenuItemStyles({isActive:e,isDisabled:t}),css({width:`calc(100% - 2 * ${v.spacing2Xs})`,margin:`0 ${v.spacing2Xs}`,gap:v.spacingXs}));var mt="button";function Ie(e,t){let R=e,{testId:o,className:n,as:u,isActive:a=!1,isDisabled:s,isInitiallyFocused:l,icon:b}=R,c=x(R,["testId","className","as","isActive","isDisabled","isInitiallyFocused","icon"]),S=useId(void 0,"menu-item"),T=o||`cf-ui-${S}`,p=Ce({isActive:a,isDisabled:s}),{getMenuItemProps:d,focusMenuItem:f}=w(),g=useRef(null);useEffect(()=>{l&&g.current&&f(g.current);},[l,f]);let N=u!=null?u:mt;return W.createElement(N,h(i(i({role:"menuitem"},c),d(c)),{disabled:s!=null?s:e.disabled,className:cx(p,n),"data-test-id":T,ref:mergeRefs(g,t),tabIndex:-1}),b,e.children)}Ie.displayName="MenuItem";var D=W.forwardRef(Ie);var F=e=>{let t=W.Children.only(e.children),{getTriggerProps:o}=w();return W.createElement(Popover.Trigger,null,W.cloneElement(t,h(i({},o(t.props,t.ref)),{"aria-haspopup":"menu"})))};var Le=()=>css({border:"none",width:"100%",height:"1px",backgroundColor:v.gray200,margin:`${v.spacing2Xs} 0`});var J=e=>{let s=e,{children:t,testId:o="cf-ui-menu-divider",className:n}=s,u=x(s,["children","testId","className"]),a=Le();return W.createElement("hr",i({"aria-orientation":"horizontal","data-test-id":o,className:cx(a,n)},u))};var Re=()=>css({color:v.gray500,textAlign:"left",padding:`${v.spacingXs} ${v.spacingS} ${v.spacing2Xs}`,lineHeight:v.lineHeightM});var Q=e=>{let s=e,{children:t,testId:o="cf-ui-menu-section-title",className:n}=s,u=x(s,["children","testId","className"]),a=Re();return W.createElement(Caption,i({"aria-hidden":"true",as:"div",testId:o,className:cx(a,n),marginBottom:"none"},u),t)};var bt=[-8,2],_=e=>{let R=e,{onClose:t,onOpen:o,placement:n="right-start",isAutoalignmentEnabled:u=!1}=R,a=x(R,["onClose","onOpen","placement","isAutoalignmentEnabled"]),{isOpen:s,menuId:l,propsToPropagateToSubmenus:b}=w(),c=useRef(null),S=useRef(null),[T,p]=useState(!1),d=useCallback(()=>{p(!0),window.clearTimeout(S.current),o==null||o();},[o]),f=useCallback(()=>{p(!1),window.clearTimeout(S.current),t==null||t();},[t]),g=useCallback(()=>{var m;f(),(m=c.current)==null||m.focus({preventScroll:!0});},[f]);useEffect(()=>{s===!1&&p(!1);},[s]);let N=useMemo(()=>({isOpen:T,getSubmenuListProps:m=>({"data-parent-menu":l,onMouseOver:O=>{var M;d(),(M=m.onMouseOver)==null||M.call(m,O);},onMouseLeave:O=>{var M;g(),(M=m.onMouseLeave)==null||M.call(m,O);}}),getSubmenuTriggerProps:(m,O)=>({ref:mergeRefs(c,O),onKeyDown:M=>{var C;M.key==="ArrowRight"&&(M.preventDefault(),d()),(C=m.onKeyDown)==null||C.call(m,M);},onMouseOver:M=>{var C;d(),(C=m.onMouseOver)==null||C.call(m,M);},onMouseLeave:M=>{var C;S.current=window.setTimeout(g,300),(C=m.onMouseLeave)==null||C.call(m,M);}})}),[T,l,d,g]);return W.createElement(Te,{value:N},W.createElement(U,h(i(i({},b),a),{isOpen:T,onClose:f,onOpen:d,placement:n,isAutoalignmentEnabled:u,offset:bt})))};var Ne=()=>({root:({isActive:e})=>css(i({display:"flex",alignItems:"center",paddingRight:v.spacingXs},e?{backgroundColor:v.gray100}:{})),content:css({marginRight:v.spacingM}),icon:css({marginLeft:"auto",fill:"currentColor"})});var Ct=(e,t)=>{let{className:o,children:n}=e,{getSubmenuTriggerProps:u,isOpen:a}=K(),s=Ne();return W.createElement(F,null,W.createElement(D,h(i(i({},e),u(e,t)),{className:cx(s.root({isActive:a}),o)}),W.createElement("span",{className:s.content},n),W.createElement(ChevronRightIcon,{className:s.icon})))},oe=W.forwardRef(Ct);var L=U;L.List=Y;L.ListHeader=H;L.ListFooter=A;L.Item=D;L.Trigger=F;L.Divider=J;L.SectionTitle=Q;L.Submenu=_;L.SubmenuTrigger=oe;
|
|
10
10
|
|
|
11
|
-
export {
|
|
11
|
+
export { L as Menu, J as MenuDivider, D as MenuItem, Y as MenuList, Q as MenuSectionTitle, F as MenuTrigger, _ as Submenu, oe as SubmenuTrigger };
|
|
12
12
|
//# sourceMappingURL=out.js.map
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Menu.tsx","../../src/useArrowKeyNavigation.ts","../../src/MenuContext.ts","../../src/MenuList/MenuList.tsx","../../src/SubmenuContext.ts","../../src/MenuList/MenuList.styles.ts","../../src/MenuList/MenuListHeader.tsx","../../src/MenuList/MenuListFooter.tsx","../../src/MenuItem/MenuItem.tsx","../../src/MenuItem/MenuItem.styles.ts","../../src/MenuTrigger/MenuTrigger.tsx","../../src/MenuDivider/MenuDivider.tsx","../../src/MenuDivider/MenuDivider.styles.ts","../../src/MenuSectionTitle/MenuSectionTitle.tsx","../../src/MenuSectionTitle/MenuSectionTitle.styles.ts","../../src/Submenu/Submenu.tsx","../../src/SubmenuTrigger/SubmenuTrigger.tsx","../../src/SubmenuTrigger/SubmenuTrigger.styles.ts","../../src/CompoundMenu.tsx"],"names":["React","useCallback","useMemo","useRef","useEffect","mergeRefs","useId","useControllableState","Popover","useState","ARROW_KEY_TYPES","useArrowKeyNavigation","itemsContainerRef","itemsSelector","keyType","focusedIndex","setFocusedIndex","handleArrowsKeyDown","event","container","items","lastItemIndex","focusFirstItem","focusLastItem","focusNextItem","focusPrevItem","fn","MenuContext","useMenuContext","context","MenuContextProvider","MENU_ITEMS_SELECTOR","Menu","props","_a","closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen","otherProps","__objRest","isOpen","handleOpen","handleClose","isControlled","triggerRef","menuListRef","menuId","menuItems","focusMenuItem","item","itemIndex","menuItem","closeAndFocusTrigger","handleMenuListKeyDown","isMouseDown","contextValue","_props","_ref","_b","_c","_d","activeElement","relatedTarget","targetIsMenu","targetIsTrigger","targetIsSubmenu","isSubmenuTrigger","__spreadProps","__spreadValues","SubmenuContext","useSubmenuContext","SubmenuContextProvider","cx","css","tokens","getMenuHeaderStyles","getMenuFooterStyles","getMenuListStyles","MenuListHeader","testId","className","styles","MenuListFooter","assertChild","child","_MenuList","ref","getMenuListProps","submenuContext","header","footer","appendChild","extendedOtherProps","MenuList","globalGetMenuItemStyles","getMenuItemStyles","isActive","isDisabled","MENU_ITEM_DEFAULT_TAG","_MenuItem","as","isInitiallyFocused","icon","id","itemTestId","getMenuItemProps","itemRef","Element","MenuItem","MenuTrigger","getTriggerProps","getMenuDividerStyles","MenuDivider","Caption","getMenuSectionTitleStyles","MenuSectionTitle","SUBMENU_OFFSET","Submenu","onClose","isParentMenuOpen","propsToPropagateToSubmenus","mouseLeaveTimerRef","setIsOpen","ChevronRightIcon","getSubmenuTriggerStyles","_SubmenuTrigger","getSubmenuTriggerProps","SubmenuTrigger"],"mappings":"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","sourcesContent":["import React, { useCallback, useMemo, useRef, useEffect } from 'react';\nimport { mergeRefs, useId, useControllableState } from '@contentful/f36-core';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\n\nimport { useArrowKeyNavigation } from './useArrowKeyNavigation';\nimport { MenuContextProvider, MenuContextType } from './MenuContext';\n\nconst MENU_ITEMS_SELECTOR = '[role=\"menuitem\"]:not(:disabled)';\n\nexport interface MenuProps\n extends Omit<PopoverProps, 'autoFocus' | 'id' | 'closeOnBlur'> {\n /**\n * By default, the Menu is uncontrolled (manage it's expanded state by itself)\n * But you can make it controlled by providing boolean (true/false)\n */\n isOpen?: boolean;\n\n /**\n * If `true`, the Menu will be initially opened.\n */\n defaultIsOpen?: boolean;\n\n /**\n * Callback fired when the Menu opens\n */\n onOpen?: () => void;\n\n /**\n * Callback fired when the Menu closes\n */\n onClose?: () => void;\n\n /**\n * If `true`, the Menu will close when a menu item is\n * clicked\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnSelect?: boolean;\n\n /**\n * If true, the menu will close when you blur out it by clicking outside\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnBlur?: boolean;\n\n /**\n * If true, the menu will close when you hit the Esc key\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnEsc?: boolean;\n}\n\nexport function Menu(props: MenuProps) {\n const {\n closeOnSelect = true,\n closeOnBlur = true,\n closeOnEsc = true,\n children,\n onOpen,\n ...otherProps\n } = props;\n const { isOpen, handleOpen, handleClose, isControlled } =\n useControllableState({\n isOpen: props.isOpen,\n defaultIsOpen: props.defaultIsOpen,\n onOpen,\n onClose: props.onClose,\n });\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuListRef = useRef<HTMLDivElement>(null);\n\n const menuId = useId(null, 'menu');\n\n const { focusedIndex, handleArrowsKeyDown, setFocusedIndex } =\n useArrowKeyNavigation({\n itemsContainerRef: menuListRef,\n itemsSelector: MENU_ITEMS_SELECTOR,\n });\n\n useEffect(() => {\n if (isOpen && menuListRef.current) {\n const menuItems =\n menuListRef.current.querySelectorAll<HTMLElement>(MENU_ITEMS_SELECTOR);\n\n if (menuItems.length > 0 && focusedIndex < menuItems.length) {\n // timeout trick to prevent scroll from jumping\n // when the popover is not positioned correctly yet in the opening phase\n setTimeout(() => {\n menuItems[focusedIndex].focus({ preventScroll: false });\n }, 0);\n } else {\n setTimeout(() => {\n menuListRef.current?.focus({ preventScroll: false });\n }, 0);\n }\n }\n }, [isOpen, focusedIndex]);\n\n const focusMenuItem = useCallback(\n (item: HTMLElement) => {\n const menuItems =\n menuListRef.current.querySelectorAll(MENU_ITEMS_SELECTOR);\n\n const itemIndex = [...menuItems].findIndex(\n (menuItem) => item === menuItem,\n );\n\n if (itemIndex !== -1) {\n setFocusedIndex(itemIndex);\n }\n },\n [setFocusedIndex],\n );\n\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n const handleMenuListKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Tab') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n // we don't want to propagate other keydown events except `Tab`\n event.stopPropagation();\n\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n handleArrowsKeyDown(event);\n },\n [closeAndFocusTrigger, handleArrowsKeyDown],\n );\n\n // Safari has an issue with the relatedTarget that we use on the onBlur for menuListProps,\n // which was causing the menu to close and reopen when clicking on the trigger.\n // We will use the isMouseDown to prevent triggering blur in the cases where the user clicks on the trigger.\n const isMouseDown = useRef<Boolean>(false);\n\n const contextValue: MenuContextType = useMemo(\n () => ({\n isOpen,\n menuId,\n focusMenuItem,\n getTriggerProps: (_props = {}, _ref = null) => ({\n onMouseDown: (event) => {\n isMouseDown.current = true;\n _props.onMouseDown?.(event);\n },\n onMouseUp: (event) => {\n isMouseDown.current = false;\n _props.onMouseUp?.(event);\n },\n onClick: (event) => {\n // if the user made component controlled by providing isOpen prop\n // but onOpen callback is not provided, we won't add toggle logic\n // to the trigger component. So they can make any toggle logic on their own.\n const isFullyControlled = isControlled && !onOpen;\n\n if (!isFullyControlled) {\n if (isOpen) {\n handleClose();\n } else {\n handleOpen();\n }\n }\n\n _props.onClick?.(event);\n },\n ref: mergeRefs(triggerRef, _ref),\n }),\n getMenuListProps: (_props = {}, _ref = null) => ({\n ref: mergeRefs(menuListRef, _ref),\n onKeyDown: (event) => {\n handleMenuListKeyDown(event);\n _props.onKeyDown?.(event);\n },\n onBlur: (event) => {\n _props.onBlur?.(event);\n\n if (!closeOnBlur) {\n return;\n }\n\n const activeElement = document.activeElement;\n const relatedTarget = event.relatedTarget || activeElement;\n\n const targetIsMenu =\n menuListRef.current === relatedTarget ||\n menuListRef.current?.contains(relatedTarget);\n const targetIsTrigger =\n triggerRef.current === relatedTarget ||\n triggerRef.current?.contains(relatedTarget) ||\n isMouseDown.current;\n const targetIsSubmenu =\n relatedTarget?.parentElement?.dataset.parentMenu === menuId;\n\n if (targetIsMenu || targetIsTrigger || targetIsSubmenu) {\n event.stopPropagation();\n return;\n }\n\n handleClose();\n },\n }),\n getMenuItemProps: (_props = {}) => ({\n onClick: (event) => {\n _props.onClick?.(event);\n\n const isSubmenuTrigger = Boolean(\n (event.target as HTMLElement).getAttribute('aria-haspopup'),\n );\n if (closeOnSelect && !isSubmenuTrigger) {\n closeAndFocusTrigger();\n }\n },\n }),\n propsToPropagateToSubmenus: {\n closeOnSelect,\n closeOnBlur,\n closeOnEsc,\n },\n }),\n [\n menuId,\n isOpen,\n handleMenuListKeyDown,\n closeOnSelect,\n handleClose,\n handleOpen,\n focusMenuItem,\n closeOnBlur,\n closeOnEsc,\n closeAndFocusTrigger,\n isControlled,\n onOpen,\n ],\n );\n\n return (\n <MenuContextProvider value={contextValue}>\n <Popover\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n id={menuId}\n closeOnEsc={closeOnEsc}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={false}\n closeOnBlur={false}\n >\n {children}\n </Popover>\n </MenuContextProvider>\n );\n}\n","import { useState, useCallback } from 'react';\n\ninterface UseArrowKeyNavigationProps {\n itemsContainerRef: React.MutableRefObject<HTMLElement>;\n itemsSelector: string;\n keyType?: 'vertical' | 'horizontal';\n initialFocusedIndex?: number;\n}\n\nconst ARROW_KEY_TYPES = {\n vertical: {\n prev: 'ArrowUp',\n next: 'ArrowDown',\n },\n horizontal: {\n prev: 'ArrowLeft',\n next: 'ArrowRight',\n },\n};\n\nexport const useArrowKeyNavigation = ({\n itemsContainerRef,\n itemsSelector,\n keyType = 'vertical',\n}: UseArrowKeyNavigationProps) => {\n const [focusedIndex, setFocusedIndex] = useState<number>(0);\n\n const handleArrowsKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n const container = itemsContainerRef.current;\n if (!container) return;\n\n const items = container.querySelectorAll(itemsSelector);\n if (items.length === 0) return;\n\n const lastItemIndex = items.length - 1;\n\n const focusFirstItem = () => setFocusedIndex(0);\n const focusLastItem = () => setFocusedIndex(lastItemIndex);\n const focusNextItem = () => {\n if (focusedIndex === lastItemIndex) {\n focusFirstItem();\n } else {\n setFocusedIndex(focusedIndex + 1);\n }\n };\n const focusPrevItem = () => {\n if (focusedIndex === 0) {\n focusLastItem();\n } else {\n setFocusedIndex(focusedIndex - 1);\n }\n };\n\n const keyToFnMap = {\n [ARROW_KEY_TYPES[keyType].next]: focusNextItem,\n [ARROW_KEY_TYPES[keyType].prev]: focusPrevItem,\n };\n\n const fn = keyToFnMap[event.key];\n if (fn) {\n event.preventDefault();\n fn();\n }\n },\n [focusedIndex, itemsSelector, itemsContainerRef, keyType],\n );\n\n return { focusedIndex, handleArrowsKeyDown, setFocusedIndex };\n};\n","import React, { ComponentPropsWithRef } from 'react';\nimport { MenuProps } from '.';\n\nexport type MenuContextType = {\n isOpen: boolean;\n menuId: string;\n focusMenuItem: (item: HTMLElement) => void;\n getTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n getMenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n _ref: React.Ref<HTMLDivElement>,\n ) => ComponentPropsWithRef<'div'>;\n getMenuItemProps: (\n _props: ComponentPropsWithRef<'button'>,\n ) => ComponentPropsWithRef<'button'>;\n propsToPropagateToSubmenus: Pick<\n MenuProps,\n 'closeOnBlur' | 'closeOnEsc' | 'closeOnSelect'\n >;\n};\n\nconst MenuContext = React.createContext<MenuContextType | undefined>(undefined);\n\nexport const useMenuContext = () => {\n const context = React.useContext(MenuContext);\n\n if (context === undefined) {\n throw new Error('useMenuContext must be used within a MenuContextProvider');\n }\n\n return context;\n};\n\nexport const MenuContextProvider = MenuContext.Provider;\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { useMenuContext } from '../MenuContext';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { Popover } from '@contentful/f36-popover';\nimport { cx } from 'emotion';\nimport { getMenuListStyles } from './MenuList.styles';\nimport { MenuListHeader } from './MenuListHeader';\nimport { MenuListFooter } from './MenuListFooter';\n\ninterface MenuListInternalProps extends CommonProps {\n children?: React.ReactNode;\n}\n\nfunction assertChild(child: any): child is { type: { displayName: string } } {\n return Boolean(child?.type?.displayName);\n}\n\nexport type MenuListProps = PropsWithHTMLElement<MenuListInternalProps, 'div'>;\n\nconst _MenuList = (\n props: ExpandProps<MenuListProps>,\n ref: React.Ref<HTMLDivElement>,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list',\n className,\n ...otherProps\n } = props;\n\n const { getMenuListProps } = useMenuContext();\n const submenuContext = useSubmenuContext();\n\n let header: React.ReactElement | null = null;\n let footer: React.ReactElement | null = null;\n const items: React.ReactElement[] = [];\n\n React.Children.forEach(children, (child) => {\n let appendChild = true;\n if (assertChild(child)) {\n if (child.type.displayName === MenuListHeader.displayName) {\n header = child as unknown as React.ReactElement;\n appendChild = false;\n } else if (child.type.displayName === MenuListFooter.displayName) {\n footer = child as unknown as React.ReactElement;\n appendChild = false;\n }\n }\n if (appendChild) {\n items.push(child as unknown as React.ReactElement);\n }\n });\n\n const styles = getMenuListStyles({\n hasStickyHeader: Boolean(header),\n hasStickyFooter: Boolean(footer),\n });\n\n const extendedOtherProps = submenuContext\n ? submenuContext.getSubmenuListProps(otherProps)\n : otherProps;\n\n return (\n <Popover.Content\n role=\"menu\"\n {...extendedOtherProps}\n {...getMenuListProps(extendedOtherProps, ref)}\n className={cx(styles.container, className)}\n testId={testId}\n >\n {header}\n {items}\n {footer}\n </Popover.Content>\n );\n};\n\nexport const MenuList = React.forwardRef(_MenuList);\n","import React, { ComponentPropsWithRef, ComponentPropsWithoutRef } from 'react';\n\nexport type SubmenuContextType = {\n isOpen: boolean;\n getSubmenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n ) => { 'data-parent-menu': string } & ComponentPropsWithoutRef<'div'>;\n getSubmenuTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n};\n\nconst SubmenuContext = React.createContext<SubmenuContextType | undefined>(\n undefined,\n);\n\nexport const useSubmenuContext = () => {\n const context = React.useContext(SubmenuContext);\n return context;\n};\n\nexport const SubmenuContextProvider = SubmenuContext.Provider;\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuHeaderStyles = () => {\n return css({\n position: 'sticky',\n top: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderBottom: `1px solid ${tokens.gray300}`,\n marginBottom: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuFooterStyles = () => {\n return css({\n position: 'sticky',\n bottom: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderTop: `1px solid ${tokens.gray300}`,\n marginTop: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuListStyles = (props: {\n hasStickyFooter?: boolean;\n hasStickyHeader?: boolean;\n}) => ({\n container: css({\n // To get to our regular border radius for the inner menu items (6px),\n // we need to use 8px on the outer container\n borderRadius: '8px',\n overflowY: 'auto',\n position: 'relative',\n padding: 0,\n paddingTop: props.hasStickyHeader ? 0 : tokens.spacing2Xs,\n paddingBottom: props.hasStickyFooter ? 0 : tokens.spacing2Xs,\n }),\n});\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuHeaderStyles } from './MenuList.styles';\n\nexport type MenuListHeaderProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListHeader: React.FC<ExpandProps<MenuListHeaderProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-header',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuHeaderStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListHeader.displayName = 'MenuListHeader';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuFooterStyles } from './MenuList.styles';\n\nexport type MenuListFooterProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListFooter: React.FC<ExpandProps<MenuListFooterProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-footer',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuFooterStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListFooter.displayName = 'MenuListFooter';\n","import React, { useEffect, useRef } from 'react';\nimport { cx } from 'emotion';\nimport {\n mergeRefs,\n useId,\n type CommonProps,\n type PolymorphicComponent,\n type PolymorphicProps,\n type ExpandProps,\n} from '@contentful/f36-core';\n\nimport { useMenuContext } from '../MenuContext';\nimport { getMenuItemStyles } from './MenuItem.styles';\n\nconst MENU_ITEM_DEFAULT_TAG = 'button';\n\ninterface MenuItemInternalProps extends CommonProps {\n children?: React.ReactNode;\n as?: 'a' | 'button';\n\n /**\n * Marks item as active\n */\n isActive?: boolean;\n /**\n * Marks item as disabled\n */\n isDisabled?: boolean;\n /**\n * Sets focus on item\n */\n isInitiallyFocused?: boolean;\n /**\n * Expects any of the icon components. Renders the icon aligned to the start\n */\n icon?: React.ReactElement;\n}\n\nexport type MenuItemProps<\n E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG,\n> = PolymorphicProps<MenuItemInternalProps, E>;\n\nfunction _MenuItem<E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG>(\n props: MenuItemProps<E>,\n ref: React.Ref<any>,\n) {\n const {\n testId,\n className,\n as,\n isActive = false,\n isDisabled,\n isInitiallyFocused,\n icon,\n ...otherProps\n } = props;\n\n const id = useId(undefined, 'menu-item');\n const itemTestId = testId || `cf-ui-${id}`;\n const styles = getMenuItemStyles({ isActive, isDisabled });\n\n const { getMenuItemProps, focusMenuItem } = useMenuContext();\n\n const itemRef = useRef<HTMLElement>(null);\n useEffect(() => {\n if (isInitiallyFocused && itemRef.current) {\n focusMenuItem(itemRef.current);\n }\n }, [isInitiallyFocused, focusMenuItem]);\n\n const Element = (as ?? MENU_ITEM_DEFAULT_TAG) as React.ElementType;\n\n return (\n <Element\n role=\"menuitem\"\n {...otherProps}\n {...getMenuItemProps(otherProps)}\n disabled={isDisabled ?? props.disabled}\n className={cx(styles, className)}\n data-test-id={itemTestId}\n ref={mergeRefs(itemRef, ref)}\n tabIndex={-1}\n >\n {icon}\n {props.children}\n </Element>\n );\n}\n\n_MenuItem.displayName = 'MenuItem';\n\nexport const MenuItem: PolymorphicComponent<\n ExpandProps<MenuItemInternalProps>,\n typeof MENU_ITEM_DEFAULT_TAG\n> = React.forwardRef(_MenuItem);\n","import { css, cx } from 'emotion';\nimport { getMenuItemStyles as globalGetMenuItemStyles } from '@contentful/f36-core';\nimport type { MenuItemProps } from './MenuItem';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuItemStyles = ({\n isActive,\n isDisabled,\n}: {\n isActive: MenuItemProps['isActive'];\n isDisabled: MenuItemProps['isDisabled'];\n}) =>\n cx(\n globalGetMenuItemStyles({ isActive, isDisabled }),\n css({\n width: `calc(100% - 2 * ${tokens.spacing2Xs})`,\n margin: `0 ${tokens.spacing2Xs}`,\n gap: tokens.spacingXs,\n }),\n );\n","import React from 'react';\nimport { Popover } from '@contentful/f36-popover';\nimport { useMenuContext } from '../MenuContext';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nexport interface MenuTriggerProps {\n children: React.ReactNode;\n}\n\nexport const MenuTrigger = (props: ExpandProps<MenuTriggerProps>) => {\n const child = React.Children.only(props.children) as any;\n const { getTriggerProps } = useMenuContext();\n\n return (\n <Popover.Trigger>\n {React.cloneElement(child, {\n ...getTriggerProps(child.props, child.ref),\n ['aria-haspopup']: 'menu',\n })}\n </Popover.Trigger>\n );\n};\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getMenuDividerStyles } from './MenuDivider.styles';\n\nexport type MenuDividerProps = PropsWithHTMLElement<CommonProps, 'hr'>;\n\nexport const MenuDivider = (props: ExpandProps<MenuDividerProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-divider',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuDividerStyles();\n\n return (\n <hr\n aria-orientation=\"horizontal\"\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n />\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuDividerStyles = () =>\n css({\n border: 'none',\n width: '100%',\n height: '1px',\n backgroundColor: tokens.gray200,\n margin: `${tokens.spacing2Xs} 0`,\n });\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { Caption, type CaptionProps } from '@contentful/f36-typography';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nimport { getMenuSectionTitleStyles } from './MenuSectionTitle.styles';\n\nexport type MenuSectionTitleProps = CaptionProps;\n\nexport const MenuSectionTitle = (props: ExpandProps<MenuSectionTitleProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-section-title',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuSectionTitleStyles();\n\n return (\n <Caption\n // Techincally, menus cannot contain headings according to ARIA.\n // We hide the heading from assistive technology, and only use it\n // as a label\n aria-hidden=\"true\"\n as=\"div\"\n testId={testId}\n className={cx(styles, className)}\n marginBottom=\"none\"\n {...otherProps}\n >\n {children}\n </Caption>\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuSectionTitleStyles = () =>\n css({\n color: tokens.gray500,\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingS} ${tokens.spacing2Xs}`,\n lineHeight: tokens.lineHeightM,\n });\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Menu, MenuProps } from '../Menu';\nimport { useMenuContext } from '../MenuContext';\nimport { SubmenuContextProvider, SubmenuContextType } from '../SubmenuContext';\nimport { mergeRefs } from '@contentful/f36-core';\n\nconst SUBMENU_OFFSET: [number, number] = [-8, 2];\n\nexport type SubmenuProps = Omit<\n MenuProps,\n | 'placement'\n | 'offset'\n | 'usePortal'\n | 'isOpen'\n | 'isAutoalignmentEnabled'\n | 'defaultIsOpen'\n>;\n\nexport const Submenu = (props: SubmenuProps) => {\n const { onClose, onOpen, ...otherProps } = props;\n\n const {\n isOpen: isParentMenuOpen,\n menuId,\n propsToPropagateToSubmenus,\n } = useMenuContext();\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const mouseLeaveTimerRef = useRef(null);\n\n const [isOpen, setIsOpen] = useState(false);\n const handleOpen = useCallback(() => {\n setIsOpen(true);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onOpen?.();\n }, [onOpen]);\n const handleClose = useCallback(() => {\n setIsOpen(false);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onClose?.();\n }, [onClose]);\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n useEffect(() => {\n // close when parent menu closed\n if (isParentMenuOpen === false) {\n setIsOpen(false);\n }\n }, [isParentMenuOpen]);\n\n const contextValue: SubmenuContextType = useMemo(\n () => ({\n isOpen,\n getSubmenuListProps: (_props) => ({\n 'data-parent-menu': menuId,\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n closeAndFocusTrigger();\n\n _props.onMouseLeave?.(event);\n },\n }),\n getSubmenuTriggerProps: (_props, _ref) => ({\n ref: mergeRefs(triggerRef, _ref),\n onKeyDown: (event) => {\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n handleOpen();\n }\n\n _props.onKeyDown?.(event);\n },\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n mouseLeaveTimerRef.current = window.setTimeout(\n closeAndFocusTrigger,\n 300,\n );\n\n _props.onMouseLeave?.(event);\n },\n }),\n }),\n [isOpen, menuId, handleOpen, closeAndFocusTrigger],\n );\n\n return (\n <SubmenuContextProvider value={contextValue}>\n <Menu\n {...propsToPropagateToSubmenus}\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n onOpen={handleOpen}\n placement=\"right-start\"\n offset={SUBMENU_OFFSET}\n isAutoalignmentEnabled={false}\n />\n </SubmenuContextProvider>\n );\n};\n","import React from 'react';\nimport { MenuTrigger } from '../MenuTrigger/MenuTrigger';\nimport { MenuItem, MenuItemProps } from '../MenuItem/MenuItem';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { ChevronRightIcon } from '@contentful/f36-icons';\nimport type { ExpandProps } from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getSubmenuTriggerStyles } from './SubmenuTrigger.styles';\n\nexport type SubmenuTriggerProps = Omit<\n MenuItemProps<'button'>,\n 'isInitiallyFocused' | 'as'\n>;\n\nconst _SubmenuTrigger = (\n props: ExpandProps<SubmenuTriggerProps>,\n ref: React.Ref<HTMLButtonElement>,\n) => {\n const { className, children } = props;\n const { getSubmenuTriggerProps, isOpen } = useSubmenuContext();\n\n const styles = getSubmenuTriggerStyles();\n\n return (\n <MenuTrigger>\n <MenuItem\n {...props}\n {...getSubmenuTriggerProps(props, ref)}\n className={cx(styles.root({ isActive: isOpen }), className)}\n >\n <span className={styles.content}>{children}</span>\n <ChevronRightIcon className={styles.icon} />\n </MenuItem>\n </MenuTrigger>\n );\n};\n\nexport const SubmenuTrigger = React.forwardRef(_SubmenuTrigger);\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getSubmenuTriggerStyles = () => {\n return {\n root: ({ isActive }) =>\n css({\n display: 'flex',\n alignItems: 'center',\n paddingRight: tokens.spacingXs,\n ...(isActive\n ? {\n backgroundColor: tokens.gray100,\n }\n : {}),\n }),\n content: css({\n marginRight: tokens.spacingM,\n }),\n icon: css({\n marginLeft: 'auto',\n fill: 'currentColor',\n }),\n };\n};\n","import { Menu as OriginalMenu } from './Menu';\nimport { MenuList } from './MenuList/MenuList';\nimport { MenuListHeader } from './MenuList/MenuListHeader';\nimport { MenuListFooter } from './MenuList/MenuListFooter';\nimport { MenuItem } from './MenuItem/MenuItem';\nimport { MenuTrigger } from './MenuTrigger/MenuTrigger';\nimport { MenuDivider } from './MenuDivider/MenuDivider';\nimport { MenuSectionTitle } from './MenuSectionTitle/MenuSectionTitle';\nimport { Submenu } from './Submenu/Submenu';\nimport { SubmenuTrigger } from './SubmenuTrigger/SubmenuTrigger';\n\ntype CompoundMenu = typeof OriginalMenu & {\n List: typeof MenuList;\n ListHeader: typeof MenuListHeader;\n ListFooter: typeof MenuListFooter;\n Item: typeof MenuItem;\n Trigger: typeof MenuTrigger;\n Divider: typeof MenuDivider;\n SectionTitle: typeof MenuSectionTitle;\n Submenu: typeof Submenu;\n SubmenuTrigger: typeof SubmenuTrigger;\n};\n\nexport const Menu = OriginalMenu as CompoundMenu;\nMenu.List = MenuList;\nMenu.ListHeader = MenuListHeader;\nMenu.ListFooter = MenuListFooter;\nMenu.Item = MenuItem;\nMenu.Trigger = MenuTrigger;\nMenu.Divider = MenuDivider;\nMenu.SectionTitle = MenuSectionTitle;\nMenu.Submenu = Submenu;\nMenu.SubmenuTrigger = SubmenuTrigger;\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Menu.tsx","../../src/useArrowKeyNavigation.ts","../../src/MenuContext.ts","../../src/MenuList/MenuList.tsx","../../src/SubmenuContext.ts","../../src/MenuList/MenuList.styles.ts","../../src/MenuList/MenuListHeader.tsx","../../src/MenuList/MenuListFooter.tsx","../../src/MenuItem/MenuItem.tsx","../../src/MenuItem/MenuItem.styles.ts","../../src/MenuTrigger/MenuTrigger.tsx","../../src/MenuDivider/MenuDivider.tsx","../../src/MenuDivider/MenuDivider.styles.ts","../../src/MenuSectionTitle/MenuSectionTitle.tsx","../../src/MenuSectionTitle/MenuSectionTitle.styles.ts","../../src/Submenu/Submenu.tsx","../../src/SubmenuTrigger/SubmenuTrigger.tsx","../../src/SubmenuTrigger/SubmenuTrigger.styles.ts","../../src/CompoundMenu.tsx"],"names":["React","useCallback","useMemo","useRef","useEffect","mergeRefs","useId","useControllableState","Popover","useState","ARROW_KEY_TYPES","useArrowKeyNavigation","itemsContainerRef","itemsSelector","keyType","focusedIndex","setFocusedIndex","handleArrowsKeyDown","event","container","items","lastItemIndex","focusFirstItem","focusLastItem","focusNextItem","focusPrevItem","fn","MenuContext","useMenuContext","context","MenuContextProvider","MENU_ITEMS_SELECTOR","Menu","props","_a","closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen","otherProps","__objRest","isOpen","handleOpen","handleClose","isControlled","triggerRef","menuListRef","menuId","menuItems","focusMenuItem","item","itemIndex","menuItem","closeAndFocusTrigger","handleMenuListKeyDown","isMouseDown","contextValue","_props","_ref","_b","_c","_d","activeElement","relatedTarget","targetIsMenu","targetIsTrigger","targetIsSubmenu","isSubmenuTrigger","__spreadProps","__spreadValues","SubmenuContext","useSubmenuContext","SubmenuContextProvider","cx","css","tokens","getMenuHeaderStyles","getMenuFooterStyles","getMenuListStyles","MenuListHeader","testId","className","styles","MenuListFooter","assertChild","child","_MenuList","ref","getMenuListProps","submenuContext","header","footer","appendChild","extendedOtherProps","MenuList","globalGetMenuItemStyles","getMenuItemStyles","isActive","isDisabled","MENU_ITEM_DEFAULT_TAG","_MenuItem","as","isInitiallyFocused","icon","id","itemTestId","getMenuItemProps","itemRef","Element","MenuItem","MenuTrigger","getTriggerProps","getMenuDividerStyles","MenuDivider","Caption","getMenuSectionTitleStyles","MenuSectionTitle","SUBMENU_OFFSET","Submenu","onClose","placement","isAutoalignmentEnabled","isParentMenuOpen","propsToPropagateToSubmenus","mouseLeaveTimerRef","setIsOpen","ChevronRightIcon","getSubmenuTriggerStyles","_SubmenuTrigger","getSubmenuTriggerProps","SubmenuTrigger"],"mappings":"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","sourcesContent":["import React, { useCallback, useMemo, useRef, useEffect } from 'react';\nimport { mergeRefs, useId, useControllableState } from '@contentful/f36-core';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\n\nimport { useArrowKeyNavigation } from './useArrowKeyNavigation';\nimport { MenuContextProvider, MenuContextType } from './MenuContext';\n\nconst MENU_ITEMS_SELECTOR = '[role=\"menuitem\"]:not(:disabled)';\n\nexport interface MenuProps\n extends Omit<PopoverProps, 'autoFocus' | 'id' | 'closeOnBlur'> {\n /**\n * By default, the Menu is uncontrolled (manage it's expanded state by itself)\n * But you can make it controlled by providing boolean (true/false)\n */\n isOpen?: boolean;\n\n /**\n * If `true`, the Menu will be initially opened.\n */\n defaultIsOpen?: boolean;\n\n /**\n * Callback fired when the Menu opens\n */\n onOpen?: () => void;\n\n /**\n * Callback fired when the Menu closes\n */\n onClose?: () => void;\n\n /**\n * If `true`, the Menu will close when a menu item is\n * clicked\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnSelect?: boolean;\n\n /**\n * If true, the menu will close when you blur out it by clicking outside\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnBlur?: boolean;\n\n /**\n * If true, the menu will close when you hit the Esc key\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnEsc?: boolean;\n}\n\nexport function Menu(props: MenuProps) {\n const {\n closeOnSelect = true,\n closeOnBlur = true,\n closeOnEsc = true,\n children,\n onOpen,\n ...otherProps\n } = props;\n const { isOpen, handleOpen, handleClose, isControlled } =\n useControllableState({\n isOpen: props.isOpen,\n defaultIsOpen: props.defaultIsOpen,\n onOpen,\n onClose: props.onClose,\n });\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuListRef = useRef<HTMLDivElement>(null);\n\n const menuId = useId(null, 'menu');\n\n const { focusedIndex, handleArrowsKeyDown, setFocusedIndex } =\n useArrowKeyNavigation({\n itemsContainerRef: menuListRef,\n itemsSelector: MENU_ITEMS_SELECTOR,\n });\n\n useEffect(() => {\n if (isOpen && menuListRef.current) {\n const menuItems =\n menuListRef.current.querySelectorAll<HTMLElement>(MENU_ITEMS_SELECTOR);\n\n if (menuItems.length > 0 && focusedIndex < menuItems.length) {\n // timeout trick to prevent scroll from jumping\n // when the popover is not positioned correctly yet in the opening phase\n setTimeout(() => {\n menuItems[focusedIndex].focus({ preventScroll: false });\n }, 0);\n } else {\n setTimeout(() => {\n menuListRef.current?.focus({ preventScroll: false });\n }, 0);\n }\n }\n }, [isOpen, focusedIndex]);\n\n const focusMenuItem = useCallback(\n (item: HTMLElement) => {\n const menuItems =\n menuListRef.current.querySelectorAll(MENU_ITEMS_SELECTOR);\n\n const itemIndex = [...menuItems].findIndex(\n (menuItem) => item === menuItem,\n );\n\n if (itemIndex !== -1) {\n setFocusedIndex(itemIndex);\n }\n },\n [setFocusedIndex],\n );\n\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n const handleMenuListKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Tab') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n // we don't want to propagate other keydown events except `Tab`\n event.stopPropagation();\n\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n handleArrowsKeyDown(event);\n },\n [closeAndFocusTrigger, handleArrowsKeyDown],\n );\n\n // Safari has an issue with the relatedTarget that we use on the onBlur for menuListProps,\n // which was causing the menu to close and reopen when clicking on the trigger.\n // We will use the isMouseDown to prevent triggering blur in the cases where the user clicks on the trigger.\n const isMouseDown = useRef<Boolean>(false);\n\n const contextValue: MenuContextType = useMemo(\n () => ({\n isOpen,\n menuId,\n focusMenuItem,\n getTriggerProps: (_props = {}, _ref = null) => ({\n onMouseDown: (event) => {\n isMouseDown.current = true;\n _props.onMouseDown?.(event);\n },\n onMouseUp: (event) => {\n isMouseDown.current = false;\n _props.onMouseUp?.(event);\n },\n onClick: (event) => {\n // if the user made component controlled by providing isOpen prop\n // but onOpen callback is not provided, we won't add toggle logic\n // to the trigger component. So they can make any toggle logic on their own.\n const isFullyControlled = isControlled && !onOpen;\n\n if (!isFullyControlled) {\n if (isOpen) {\n handleClose();\n } else {\n handleOpen();\n }\n }\n\n _props.onClick?.(event);\n },\n ref: mergeRefs(triggerRef, _ref),\n }),\n getMenuListProps: (_props = {}, _ref = null) => ({\n ref: mergeRefs(menuListRef, _ref),\n onKeyDown: (event) => {\n handleMenuListKeyDown(event);\n _props.onKeyDown?.(event);\n },\n onBlur: (event) => {\n _props.onBlur?.(event);\n\n if (!closeOnBlur) {\n return;\n }\n\n const activeElement = document.activeElement;\n const relatedTarget = event.relatedTarget || activeElement;\n\n const targetIsMenu =\n menuListRef.current === relatedTarget ||\n menuListRef.current?.contains(relatedTarget);\n const targetIsTrigger =\n triggerRef.current === relatedTarget ||\n triggerRef.current?.contains(relatedTarget) ||\n isMouseDown.current;\n const targetIsSubmenu =\n relatedTarget?.parentElement?.dataset.parentMenu === menuId;\n\n if (targetIsMenu || targetIsTrigger || targetIsSubmenu) {\n event.stopPropagation();\n return;\n }\n\n handleClose();\n },\n }),\n getMenuItemProps: (_props = {}) => ({\n onClick: (event) => {\n _props.onClick?.(event);\n\n const isSubmenuTrigger = Boolean(\n (event.target as HTMLElement).getAttribute('aria-haspopup'),\n );\n if (closeOnSelect && !isSubmenuTrigger) {\n closeAndFocusTrigger();\n }\n },\n }),\n propsToPropagateToSubmenus: {\n closeOnSelect,\n closeOnBlur,\n closeOnEsc,\n },\n }),\n [\n menuId,\n isOpen,\n handleMenuListKeyDown,\n closeOnSelect,\n handleClose,\n handleOpen,\n focusMenuItem,\n closeOnBlur,\n closeOnEsc,\n closeAndFocusTrigger,\n isControlled,\n onOpen,\n ],\n );\n\n return (\n <MenuContextProvider value={contextValue}>\n <Popover\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n id={menuId}\n closeOnEsc={closeOnEsc}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={false}\n closeOnBlur={false}\n >\n {children}\n </Popover>\n </MenuContextProvider>\n );\n}\n","import { useState, useCallback } from 'react';\n\ninterface UseArrowKeyNavigationProps {\n itemsContainerRef: React.MutableRefObject<HTMLElement>;\n itemsSelector: string;\n keyType?: 'vertical' | 'horizontal';\n initialFocusedIndex?: number;\n}\n\nconst ARROW_KEY_TYPES = {\n vertical: {\n prev: 'ArrowUp',\n next: 'ArrowDown',\n },\n horizontal: {\n prev: 'ArrowLeft',\n next: 'ArrowRight',\n },\n};\n\nexport const useArrowKeyNavigation = ({\n itemsContainerRef,\n itemsSelector,\n keyType = 'vertical',\n}: UseArrowKeyNavigationProps) => {\n const [focusedIndex, setFocusedIndex] = useState<number>(0);\n\n const handleArrowsKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n const container = itemsContainerRef.current;\n if (!container) return;\n\n const items = container.querySelectorAll(itemsSelector);\n if (items.length === 0) return;\n\n const lastItemIndex = items.length - 1;\n\n const focusFirstItem = () => setFocusedIndex(0);\n const focusLastItem = () => setFocusedIndex(lastItemIndex);\n const focusNextItem = () => {\n if (focusedIndex === lastItemIndex) {\n focusFirstItem();\n } else {\n setFocusedIndex(focusedIndex + 1);\n }\n };\n const focusPrevItem = () => {\n if (focusedIndex === 0) {\n focusLastItem();\n } else {\n setFocusedIndex(focusedIndex - 1);\n }\n };\n\n const keyToFnMap = {\n [ARROW_KEY_TYPES[keyType].next]: focusNextItem,\n [ARROW_KEY_TYPES[keyType].prev]: focusPrevItem,\n };\n\n const fn = keyToFnMap[event.key];\n if (fn) {\n event.preventDefault();\n fn();\n }\n },\n [focusedIndex, itemsSelector, itemsContainerRef, keyType],\n );\n\n return { focusedIndex, handleArrowsKeyDown, setFocusedIndex };\n};\n","import React, { ComponentPropsWithRef } from 'react';\nimport { MenuProps } from '.';\n\nexport type MenuContextType = {\n isOpen: boolean;\n menuId: string;\n focusMenuItem: (item: HTMLElement) => void;\n getTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n getMenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n _ref: React.Ref<HTMLDivElement>,\n ) => ComponentPropsWithRef<'div'>;\n getMenuItemProps: (\n _props: ComponentPropsWithRef<'button'>,\n ) => ComponentPropsWithRef<'button'>;\n propsToPropagateToSubmenus: Pick<\n MenuProps,\n 'closeOnBlur' | 'closeOnEsc' | 'closeOnSelect'\n >;\n};\n\nconst MenuContext = React.createContext<MenuContextType | undefined>(undefined);\n\nexport const useMenuContext = () => {\n const context = React.useContext(MenuContext);\n\n if (context === undefined) {\n throw new Error('useMenuContext must be used within a MenuContextProvider');\n }\n\n return context;\n};\n\nexport const MenuContextProvider = MenuContext.Provider;\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { useMenuContext } from '../MenuContext';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { Popover } from '@contentful/f36-popover';\nimport { cx } from 'emotion';\nimport { getMenuListStyles } from './MenuList.styles';\nimport { MenuListHeader } from './MenuListHeader';\nimport { MenuListFooter } from './MenuListFooter';\n\ninterface MenuListInternalProps extends CommonProps {\n children?: React.ReactNode;\n}\n\nfunction assertChild(child: any): child is { type: { displayName: string } } {\n return Boolean(child?.type?.displayName);\n}\n\nexport type MenuListProps = PropsWithHTMLElement<MenuListInternalProps, 'div'>;\n\nconst _MenuList = (\n props: ExpandProps<MenuListProps>,\n ref: React.Ref<HTMLDivElement>,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list',\n className,\n ...otherProps\n } = props;\n\n const { getMenuListProps } = useMenuContext();\n const submenuContext = useSubmenuContext();\n\n let header: React.ReactElement | null = null;\n let footer: React.ReactElement | null = null;\n const items: React.ReactElement[] = [];\n\n React.Children.forEach(children, (child) => {\n let appendChild = true;\n if (assertChild(child)) {\n if (child.type.displayName === MenuListHeader.displayName) {\n header = child as unknown as React.ReactElement;\n appendChild = false;\n } else if (child.type.displayName === MenuListFooter.displayName) {\n footer = child as unknown as React.ReactElement;\n appendChild = false;\n }\n }\n if (appendChild) {\n items.push(child as unknown as React.ReactElement);\n }\n });\n\n const styles = getMenuListStyles({\n hasStickyHeader: Boolean(header),\n hasStickyFooter: Boolean(footer),\n });\n\n const extendedOtherProps = submenuContext\n ? submenuContext.getSubmenuListProps(otherProps)\n : otherProps;\n\n return (\n <Popover.Content\n role=\"menu\"\n {...extendedOtherProps}\n {...getMenuListProps(extendedOtherProps, ref)}\n className={cx(styles.container, className)}\n testId={testId}\n >\n {header}\n {items}\n {footer}\n </Popover.Content>\n );\n};\n\nexport const MenuList = React.forwardRef(_MenuList);\n","import React, { ComponentPropsWithRef, ComponentPropsWithoutRef } from 'react';\n\nexport type SubmenuContextType = {\n isOpen: boolean;\n getSubmenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n ) => { 'data-parent-menu': string } & ComponentPropsWithoutRef<'div'>;\n getSubmenuTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n};\n\nconst SubmenuContext = React.createContext<SubmenuContextType | undefined>(\n undefined,\n);\n\nexport const useSubmenuContext = () => {\n const context = React.useContext(SubmenuContext);\n return context;\n};\n\nexport const SubmenuContextProvider = SubmenuContext.Provider;\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuHeaderStyles = () => {\n return css({\n position: 'sticky',\n top: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderBottom: `1px solid ${tokens.gray300}`,\n marginBottom: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuFooterStyles = () => {\n return css({\n position: 'sticky',\n bottom: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderTop: `1px solid ${tokens.gray300}`,\n marginTop: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuListStyles = (props: {\n hasStickyFooter?: boolean;\n hasStickyHeader?: boolean;\n}) => ({\n container: css({\n // To get to our regular border radius for the inner menu items (6px),\n // we need to use 8px on the outer container\n borderRadius: '8px',\n overflowY: 'auto',\n position: 'relative',\n padding: 0,\n paddingTop: props.hasStickyHeader ? 0 : tokens.spacing2Xs,\n paddingBottom: props.hasStickyFooter ? 0 : tokens.spacing2Xs,\n }),\n});\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuHeaderStyles } from './MenuList.styles';\n\nexport type MenuListHeaderProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListHeader: React.FC<ExpandProps<MenuListHeaderProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-header',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuHeaderStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListHeader.displayName = 'MenuListHeader';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuFooterStyles } from './MenuList.styles';\n\nexport type MenuListFooterProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListFooter: React.FC<ExpandProps<MenuListFooterProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-footer',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuFooterStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListFooter.displayName = 'MenuListFooter';\n","import React, { useEffect, useRef } from 'react';\nimport { cx } from 'emotion';\nimport {\n mergeRefs,\n useId,\n type CommonProps,\n type PolymorphicComponent,\n type PolymorphicProps,\n type ExpandProps,\n} from '@contentful/f36-core';\n\nimport { useMenuContext } from '../MenuContext';\nimport { getMenuItemStyles } from './MenuItem.styles';\n\nconst MENU_ITEM_DEFAULT_TAG = 'button';\n\ninterface MenuItemInternalProps extends CommonProps {\n children?: React.ReactNode;\n as?: 'a' | 'button';\n\n /**\n * Marks item as active\n */\n isActive?: boolean;\n /**\n * Marks item as disabled\n */\n isDisabled?: boolean;\n /**\n * Sets focus on item\n */\n isInitiallyFocused?: boolean;\n /**\n * Expects any of the icon components. Renders the icon aligned to the start\n */\n icon?: React.ReactElement;\n}\n\nexport type MenuItemProps<\n E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG,\n> = PolymorphicProps<MenuItemInternalProps, E>;\n\nfunction _MenuItem<E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG>(\n props: MenuItemProps<E>,\n ref: React.Ref<any>,\n) {\n const {\n testId,\n className,\n as,\n isActive = false,\n isDisabled,\n isInitiallyFocused,\n icon,\n ...otherProps\n } = props;\n\n const id = useId(undefined, 'menu-item');\n const itemTestId = testId || `cf-ui-${id}`;\n const styles = getMenuItemStyles({ isActive, isDisabled });\n\n const { getMenuItemProps, focusMenuItem } = useMenuContext();\n\n const itemRef = useRef<HTMLElement>(null);\n useEffect(() => {\n if (isInitiallyFocused && itemRef.current) {\n focusMenuItem(itemRef.current);\n }\n }, [isInitiallyFocused, focusMenuItem]);\n\n const Element = (as ?? MENU_ITEM_DEFAULT_TAG) as React.ElementType;\n\n return (\n <Element\n role=\"menuitem\"\n {...otherProps}\n {...getMenuItemProps(otherProps)}\n disabled={isDisabled ?? props.disabled}\n className={cx(styles, className)}\n data-test-id={itemTestId}\n ref={mergeRefs(itemRef, ref)}\n tabIndex={-1}\n >\n {icon}\n {props.children}\n </Element>\n );\n}\n\n_MenuItem.displayName = 'MenuItem';\n\nexport const MenuItem: PolymorphicComponent<\n ExpandProps<MenuItemInternalProps>,\n typeof MENU_ITEM_DEFAULT_TAG\n> = React.forwardRef(_MenuItem);\n","import { css, cx } from 'emotion';\nimport { getMenuItemStyles as globalGetMenuItemStyles } from '@contentful/f36-core';\nimport type { MenuItemProps } from './MenuItem';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuItemStyles = ({\n isActive,\n isDisabled,\n}: {\n isActive: MenuItemProps['isActive'];\n isDisabled: MenuItemProps['isDisabled'];\n}) =>\n cx(\n globalGetMenuItemStyles({ isActive, isDisabled }),\n css({\n width: `calc(100% - 2 * ${tokens.spacing2Xs})`,\n margin: `0 ${tokens.spacing2Xs}`,\n gap: tokens.spacingXs,\n }),\n );\n","import React from 'react';\nimport { Popover } from '@contentful/f36-popover';\nimport { useMenuContext } from '../MenuContext';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nexport interface MenuTriggerProps {\n children: React.ReactNode;\n}\n\nexport const MenuTrigger = (props: ExpandProps<MenuTriggerProps>) => {\n const child = React.Children.only(props.children) as any;\n const { getTriggerProps } = useMenuContext();\n\n return (\n <Popover.Trigger>\n {React.cloneElement(child, {\n ...getTriggerProps(child.props, child.ref),\n ['aria-haspopup']: 'menu',\n })}\n </Popover.Trigger>\n );\n};\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getMenuDividerStyles } from './MenuDivider.styles';\n\nexport type MenuDividerProps = PropsWithHTMLElement<CommonProps, 'hr'>;\n\nexport const MenuDivider = (props: ExpandProps<MenuDividerProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-divider',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuDividerStyles();\n\n return (\n <hr\n aria-orientation=\"horizontal\"\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n />\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuDividerStyles = () =>\n css({\n border: 'none',\n width: '100%',\n height: '1px',\n backgroundColor: tokens.gray200,\n margin: `${tokens.spacing2Xs} 0`,\n });\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { Caption, type CaptionProps } from '@contentful/f36-typography';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nimport { getMenuSectionTitleStyles } from './MenuSectionTitle.styles';\n\nexport type MenuSectionTitleProps = CaptionProps;\n\nexport const MenuSectionTitle = (props: ExpandProps<MenuSectionTitleProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-section-title',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuSectionTitleStyles();\n\n return (\n <Caption\n // Techincally, menus cannot contain headings according to ARIA.\n // We hide the heading from assistive technology, and only use it\n // as a label\n aria-hidden=\"true\"\n as=\"div\"\n testId={testId}\n className={cx(styles, className)}\n marginBottom=\"none\"\n {...otherProps}\n >\n {children}\n </Caption>\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuSectionTitleStyles = () =>\n css({\n color: tokens.gray500,\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingS} ${tokens.spacing2Xs}`,\n lineHeight: tokens.lineHeightM,\n });\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Menu, type MenuProps } from '../Menu';\nimport { useMenuContext } from '../MenuContext';\nimport {\n SubmenuContextProvider,\n type SubmenuContextType,\n} from '../SubmenuContext';\nimport { mergeRefs } from '@contentful/f36-core';\n\nconst SUBMENU_OFFSET: [number, number] = [-8, 2];\n\nexport type SubmenuProps = Omit<\n MenuProps,\n 'offset' | 'usePortal' | 'isOpen' | 'defaultIsOpen'\n>;\n\nexport const Submenu = (props: SubmenuProps) => {\n const {\n onClose,\n onOpen,\n placement = 'right-start',\n isAutoalignmentEnabled = false,\n ...otherProps\n } = props;\n\n const {\n isOpen: isParentMenuOpen,\n menuId,\n propsToPropagateToSubmenus,\n } = useMenuContext();\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const mouseLeaveTimerRef = useRef(null);\n\n const [isOpen, setIsOpen] = useState(false);\n const handleOpen = useCallback(() => {\n setIsOpen(true);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onOpen?.();\n }, [onOpen]);\n const handleClose = useCallback(() => {\n setIsOpen(false);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onClose?.();\n }, [onClose]);\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n useEffect(() => {\n // close when parent menu closed\n if (isParentMenuOpen === false) {\n setIsOpen(false);\n }\n }, [isParentMenuOpen]);\n\n const contextValue: SubmenuContextType = useMemo(\n () => ({\n isOpen,\n getSubmenuListProps: (_props) => ({\n 'data-parent-menu': menuId,\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n closeAndFocusTrigger();\n\n _props.onMouseLeave?.(event);\n },\n }),\n getSubmenuTriggerProps: (_props, _ref) => ({\n ref: mergeRefs(triggerRef, _ref),\n onKeyDown: (event) => {\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n handleOpen();\n }\n\n _props.onKeyDown?.(event);\n },\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n mouseLeaveTimerRef.current = window.setTimeout(\n closeAndFocusTrigger,\n 300,\n );\n\n _props.onMouseLeave?.(event);\n },\n }),\n }),\n [isOpen, menuId, handleOpen, closeAndFocusTrigger],\n );\n\n return (\n <SubmenuContextProvider value={contextValue}>\n <Menu\n {...propsToPropagateToSubmenus}\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n onOpen={handleOpen}\n placement={placement}\n isAutoalignmentEnabled={isAutoalignmentEnabled}\n offset={SUBMENU_OFFSET}\n />\n </SubmenuContextProvider>\n );\n};\n","import React from 'react';\nimport { MenuTrigger } from '../MenuTrigger/MenuTrigger';\nimport { MenuItem, MenuItemProps } from '../MenuItem/MenuItem';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { ChevronRightIcon } from '@contentful/f36-icons';\nimport type { ExpandProps } from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getSubmenuTriggerStyles } from './SubmenuTrigger.styles';\n\nexport type SubmenuTriggerProps = Omit<\n MenuItemProps<'button'>,\n 'isInitiallyFocused' | 'as'\n>;\n\nconst _SubmenuTrigger = (\n props: ExpandProps<SubmenuTriggerProps>,\n ref: React.Ref<HTMLButtonElement>,\n) => {\n const { className, children } = props;\n const { getSubmenuTriggerProps, isOpen } = useSubmenuContext();\n\n const styles = getSubmenuTriggerStyles();\n\n return (\n <MenuTrigger>\n <MenuItem\n {...props}\n {...getSubmenuTriggerProps(props, ref)}\n className={cx(styles.root({ isActive: isOpen }), className)}\n >\n <span className={styles.content}>{children}</span>\n <ChevronRightIcon className={styles.icon} />\n </MenuItem>\n </MenuTrigger>\n );\n};\n\nexport const SubmenuTrigger = React.forwardRef(_SubmenuTrigger);\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getSubmenuTriggerStyles = () => {\n return {\n root: ({ isActive }) =>\n css({\n display: 'flex',\n alignItems: 'center',\n paddingRight: tokens.spacingXs,\n ...(isActive\n ? {\n backgroundColor: tokens.gray100,\n }\n : {}),\n }),\n content: css({\n marginRight: tokens.spacingM,\n }),\n icon: css({\n marginLeft: 'auto',\n fill: 'currentColor',\n }),\n };\n};\n","import { Menu as OriginalMenu } from './Menu';\nimport { MenuList } from './MenuList/MenuList';\nimport { MenuListHeader } from './MenuList/MenuListHeader';\nimport { MenuListFooter } from './MenuList/MenuListFooter';\nimport { MenuItem } from './MenuItem/MenuItem';\nimport { MenuTrigger } from './MenuTrigger/MenuTrigger';\nimport { MenuDivider } from './MenuDivider/MenuDivider';\nimport { MenuSectionTitle } from './MenuSectionTitle/MenuSectionTitle';\nimport { Submenu } from './Submenu/Submenu';\nimport { SubmenuTrigger } from './SubmenuTrigger/SubmenuTrigger';\n\ntype CompoundMenu = typeof OriginalMenu & {\n List: typeof MenuList;\n ListHeader: typeof MenuListHeader;\n ListFooter: typeof MenuListFooter;\n Item: typeof MenuItem;\n Trigger: typeof MenuTrigger;\n Divider: typeof MenuDivider;\n SectionTitle: typeof MenuSectionTitle;\n Submenu: typeof Submenu;\n SubmenuTrigger: typeof SubmenuTrigger;\n};\n\nexport const Menu = OriginalMenu as CompoundMenu;\nMenu.List = MenuList;\nMenu.ListHeader = MenuListHeader;\nMenu.ListFooter = MenuListFooter;\nMenu.Item = MenuItem;\nMenu.Trigger = MenuTrigger;\nMenu.Divider = MenuDivider;\nMenu.SectionTitle = MenuSectionTitle;\nMenu.Submenu = Submenu;\nMenu.SubmenuTrigger = SubmenuTrigger;\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -99,7 +99,7 @@ declare const MenuDivider: (props: ExpandProps<MenuDividerProps>) => JSX.Element
|
|
|
99
99
|
declare type MenuSectionTitleProps = CaptionProps;
|
|
100
100
|
declare const MenuSectionTitle: (props: ExpandProps<MenuSectionTitleProps>) => JSX.Element;
|
|
101
101
|
|
|
102
|
-
declare type SubmenuProps = Omit<MenuProps, '
|
|
102
|
+
declare type SubmenuProps = Omit<MenuProps, 'offset' | 'usePortal' | 'isOpen' | 'defaultIsOpen'>;
|
|
103
103
|
declare const Submenu: (props: SubmenuProps) => JSX.Element;
|
|
104
104
|
|
|
105
105
|
declare type SubmenuTriggerProps = Omit<MenuItemProps<'button'>, 'isInitiallyFocused' | 'as'>;
|
package/dist/index.d.ts
CHANGED
|
@@ -99,7 +99,7 @@ declare const MenuDivider: (props: ExpandProps<MenuDividerProps>) => JSX.Element
|
|
|
99
99
|
declare type MenuSectionTitleProps = CaptionProps;
|
|
100
100
|
declare const MenuSectionTitle: (props: ExpandProps<MenuSectionTitleProps>) => JSX.Element;
|
|
101
101
|
|
|
102
|
-
declare type SubmenuProps = Omit<MenuProps, '
|
|
102
|
+
declare type SubmenuProps = Omit<MenuProps, 'offset' | 'usePortal' | 'isOpen' | 'defaultIsOpen'>;
|
|
103
103
|
declare const Submenu: (props: SubmenuProps) => JSX.Element;
|
|
104
104
|
|
|
105
105
|
declare type SubmenuTriggerProps = Omit<MenuItemProps<'button'>, 'isInitiallyFocused' | 'as'>;
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var W = require('react');
|
|
4
4
|
var f36Core = require('@contentful/f36-core');
|
|
5
5
|
var f36Popover = require('@contentful/f36-popover');
|
|
6
6
|
var emotion = require('emotion');
|
|
7
|
-
var
|
|
7
|
+
var v = require('@contentful/f36-tokens');
|
|
8
8
|
var f36Typography = require('@contentful/f36-typography');
|
|
9
9
|
var f36Icons = require('@contentful/f36-icons');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
12
|
|
|
13
|
-
var
|
|
14
|
-
var
|
|
13
|
+
var W__default = /*#__PURE__*/_interopDefault(W);
|
|
14
|
+
var v__default = /*#__PURE__*/_interopDefault(v);
|
|
15
15
|
|
|
16
|
-
var Fe=Object.defineProperty,ke=Object.defineProperties;var We=Object.getOwnPropertyDescriptors;var k=Object.getOwnPropertySymbols;var me=Object.prototype.hasOwnProperty,ae=Object.prototype.propertyIsEnumerable;var ue=(e,t,o)=>t in e?Fe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,u=(e,t)=>{for(var o in t||(t={}))me.call(t,o)&&ue(e,o,t[o]);if(k)for(var o of k(t))ae.call(t,o)&&ue(e,o,t[o]);return e},h=(e,t)=>ke(e,We(t));var x=(e,t)=>{var o={};for(var n in e)me.call(e,n)&&t.indexOf(n)<0&&(o[n]=e[n]);if(e!=null&&k)for(var n of k(e))t.indexOf(n)<0&&ae.call(e,n)&&(o[n]=e[n]);return o};var ce={vertical:{prev:"ArrowUp",next:"ArrowDown"},horizontal:{prev:"ArrowLeft",next:"ArrowRight"}},pe=({itemsContainerRef:e,itemsSelector:t,keyType:o="vertical"})=>{let[n,i]=F.useState(0),a=F.useCallback(s=>{let f=e.current;if(!f)return;let T=f.querySelectorAll(t);if(T.length===0)return;let c=T.length-1,S=()=>i(0),g=()=>i(c),p=()=>{n===c?S():i(n+1);},b=()=>{n===0?g():i(n-1);},P={[ce[o].next]:p,[ce[o].prev]:b}[s.key];P&&(s.preventDefault(),P());},[n,t,e,o]);return {focusedIndex:n,handleArrowsKeyDown:a,setFocusedIndex:i}};var fe=F__default.default.createContext(void 0),O=()=>{let e=F__default.default.useContext(fe);if(e===void 0)throw new Error("useMenuContext must be used within a MenuContextProvider");return e},de=fe.Provider;var $='[role="menuitem"]:not(:disabled)';function W(e){let oe=e,{closeOnSelect:t=!0,closeOnBlur:o=!0,closeOnEsc:n=!0,children:i,onOpen:a}=oe,s=x(oe,["closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen"]),{isOpen:f,handleOpen:T,handleClose:c,isControlled:S}=f36Core.useControllableState({isOpen:e.isOpen,defaultIsOpen:e.defaultIsOpen,onOpen:a,onClose:e.onClose}),g=F.useRef(null),p=F.useRef(null),b=f36Core.useId(null,"menu"),{focusedIndex:M,handleArrowsKeyDown:P,setFocusedIndex:m}=pe({itemsContainerRef:p,itemsSelector:$});F.useEffect(()=>{if(f&&p.current){let r=p.current.querySelectorAll($);r.length>0&&M<r.length?setTimeout(()=>{r[M].focus({preventScroll:!1});},0):setTimeout(()=>{var I;(I=p.current)==null||I.focus({preventScroll:!1});},0);}},[f,M]);let C=F.useCallback(r=>{let d=[...p.current.querySelectorAll($)].findIndex(y=>r===y);d!==-1&&m(d);},[m]),l=F.useCallback(()=>{var r;c(),(r=g.current)==null||r.focus({preventScroll:!0});},[c]),E=F.useCallback(r=>{if(r.key==="Tab"){r.preventDefault(),l();return}if(r.stopPropagation(),r.key==="ArrowLeft"){r.preventDefault(),l();return}P(r);},[l,P]),U=F.useRef(!1),Ne=F.useMemo(()=>({isOpen:f,menuId:b,focusMenuItem:C,getTriggerProps:(r={},I=null)=>({onMouseDown:d=>{var y;U.current=!0,(y=r.onMouseDown)==null||y.call(r,d);},onMouseUp:d=>{var y;U.current=!1,(y=r.onMouseUp)==null||y.call(r,d);},onClick:d=>{var v;S&&!a||(f?c():T()),(v=r.onClick)==null||v.call(r,d);},ref:f36Core.mergeRefs(g,I)}),getMenuListProps:(r={},I=null)=>({ref:f36Core.mergeRefs(p,I),onKeyDown:d=>{var y;E(d),(y=r.onKeyDown)==null||y.call(r,d);},onBlur:d=>{var ne,re,se,ie;if((ne=r.onBlur)==null||ne.call(r,d),!o)return;let y=document.activeElement,v=d.relatedTarget||y,He=p.current===v||((re=p.current)==null?void 0:re.contains(v)),Ae=g.current===v||((se=g.current)==null?void 0:se.contains(v))||U.current,De=((ie=v==null?void 0:v.parentElement)==null?void 0:ie.dataset.parentMenu)===b;if(He||Ae||De){d.stopPropagation();return}c();}}),getMenuItemProps:(r={})=>({onClick:I=>{var y;(y=r.onClick)==null||y.call(r,I);let d=!!I.target.getAttribute("aria-haspopup");t&&!d&&l();}}),propsToPropagateToSubmenus:{closeOnSelect:t,closeOnBlur:o,closeOnEsc:n}}),[b,f,E,t,c,T,C,o,n,l,S,a]);return F__default.default.createElement(de,{value:Ne},F__default.default.createElement(f36Popover.Popover,h(u({},s),{isOpen:f,onClose:c,id:b,closeOnEsc:n,autoFocus:!1,closeOnBlur:!1}),i))}var ye=F__default.default.createContext(void 0),B=()=>F__default.default.useContext(ye),xe=ye.Provider;var Te=()=>emotion.css({position:"sticky",top:0,left:0,backgroundColor:L__default.default.colorWhite,borderBottom:`1px solid ${L__default.default.gray300}`,marginBottom:L__default.default.spacing2Xs,padding:`${L__default.default.spacing2Xs} 0`,zIndex:1001}),be=()=>emotion.css({position:"sticky",bottom:0,left:0,backgroundColor:L__default.default.colorWhite,borderTop:`1px solid ${L__default.default.gray300}`,marginTop:L__default.default.spacing2Xs,padding:`${L__default.default.spacing2Xs} 0`,zIndex:1001}),Se=e=>({container:emotion.css({borderRadius:"8px",overflowY:"auto",position:"relative",padding:0,paddingTop:e.hasStickyHeader?0:L__default.default.spacing2Xs,paddingBottom:e.hasStickyFooter?0:L__default.default.spacing2Xs})});var w=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-header",className:n}=s,i=x(s,["children","testId","className"]),a=Te();return F__default.default.createElement("div",u({"data-test-id":o,className:emotion.cx(a,n)},i),t)};w.displayName="MenuListHeader";var N=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-footer",className:n}=s,i=x(s,["children","testId","className"]),a=be();return F__default.default.createElement("div",u({"data-test-id":o,className:emotion.cx(a,n)},i),t)};N.displayName="MenuListFooter";function Ze(e){var t;return !!((t=e==null?void 0:e.type)!=null&&t.displayName)}var _e=(e,t)=>{let b=e,{children:o,testId:n="cf-ui-menu-list",className:i}=b,a=x(b,["children","testId","className"]),{getMenuListProps:s}=O(),f=B(),T=null,c=null,S=[];F__default.default.Children.forEach(o,M=>{let P=!0;Ze(M)&&(M.type.displayName===w.displayName?(T=M,P=!1):M.type.displayName===N.displayName&&(c=M,P=!1)),P&&S.push(M);});let g=Se({hasStickyHeader:!!T,hasStickyFooter:!!c}),p=f?f.getSubmenuListProps(a):a;return F__default.default.createElement(f36Popover.Popover.Content,h(u(u({role:"menu"},p),s(p,t)),{className:emotion.cx(g.container,i),testId:n}),T,S,c)},q=F__default.default.forwardRef(_e);var he=({isActive:e,isDisabled:t})=>emotion.cx(f36Core.getMenuItemStyles({isActive:e,isDisabled:t}),emotion.css({width:`calc(100% - 2 * ${L__default.default.spacing2Xs})`,margin:`0 ${L__default.default.spacing2Xs}`,gap:L__default.default.spacingXs}));var mt="button";function Ee(e,t){let C=e,{testId:o,className:n,as:i,isActive:a=!1,isDisabled:s,isInitiallyFocused:f,icon:T}=C,c=x(C,["testId","className","as","isActive","isDisabled","isInitiallyFocused","icon"]),S=f36Core.useId(void 0,"menu-item"),g=o||`cf-ui-${S}`,p=he({isActive:a,isDisabled:s}),{getMenuItemProps:b,focusMenuItem:M}=O(),P=F.useRef(null);F.useEffect(()=>{f&&P.current&&M(P.current);},[f,M]);let m=i!=null?i:mt;return F__default.default.createElement(m,h(u(u({role:"menuitem"},c),b(c)),{disabled:s!=null?s:e.disabled,className:emotion.cx(p,n),"data-test-id":g,ref:f36Core.mergeRefs(P,t),tabIndex:-1}),T,e.children)}Ee.displayName="MenuItem";var H=F__default.default.forwardRef(Ee);var A=e=>{let t=F__default.default.Children.only(e.children),{getTriggerProps:o}=O();return F__default.default.createElement(f36Popover.Popover.Trigger,null,F__default.default.cloneElement(t,h(u({},o(t.props,t.ref)),{"aria-haspopup":"menu"})))};var ve=()=>emotion.css({border:"none",width:"100%",height:"1px",backgroundColor:L__default.default.gray200,margin:`${L__default.default.spacing2Xs} 0`});var V=e=>{let s=e,{children:t,testId:o="cf-ui-menu-divider",className:n}=s,i=x(s,["children","testId","className"]),a=ve();return F__default.default.createElement("hr",u({"aria-orientation":"horizontal","data-test-id":o,className:emotion.cx(a,n)},i))};var Le=()=>emotion.css({color:L__default.default.gray500,textAlign:"left",padding:`${L__default.default.spacingXs} ${L__default.default.spacingS} ${L__default.default.spacing2Xs}`,lineHeight:L__default.default.lineHeightM});var J=e=>{let s=e,{children:t,testId:o="cf-ui-menu-section-title",className:n}=s,i=x(s,["children","testId","className"]),a=Le();return F__default.default.createElement(f36Typography.Caption,u({"aria-hidden":"true",as:"div",testId:o,className:emotion.cx(a,n),marginBottom:"none"},i),t)};var bt=[-8,2],Z=e=>{let P=e,{onClose:t,onOpen:o}=P,n=x(P,["onClose","onOpen"]),{isOpen:i,menuId:a,propsToPropagateToSubmenus:s}=O(),f=F.useRef(null),T=F.useRef(null),[c,S]=F.useState(!1),g=F.useCallback(()=>{S(!0),window.clearTimeout(T.current),o==null||o();},[o]),p=F.useCallback(()=>{S(!1),window.clearTimeout(T.current),t==null||t();},[t]),b=F.useCallback(()=>{var m;p(),(m=f.current)==null||m.focus({preventScroll:!0});},[p]);F.useEffect(()=>{i===!1&&S(!1);},[i]);let M=F.useMemo(()=>({isOpen:c,getSubmenuListProps:m=>({"data-parent-menu":a,onMouseOver:C=>{var l;g(),(l=m.onMouseOver)==null||l.call(m,C);},onMouseLeave:C=>{var l;b(),(l=m.onMouseLeave)==null||l.call(m,C);}}),getSubmenuTriggerProps:(m,C)=>({ref:f36Core.mergeRefs(f,C),onKeyDown:l=>{var E;l.key==="ArrowRight"&&(l.preventDefault(),g()),(E=m.onKeyDown)==null||E.call(m,l);},onMouseOver:l=>{var E;g(),(E=m.onMouseOver)==null||E.call(m,l);},onMouseLeave:l=>{var E;T.current=window.setTimeout(b,300),(E=m.onMouseLeave)==null||E.call(m,l);}})}),[c,a,g,b]);return F__default.default.createElement(xe,{value:M},F__default.default.createElement(W,h(u(u({},s),n),{isOpen:c,onClose:p,onOpen:g,placement:"right-start",offset:bt,isAutoalignmentEnabled:!1})))};var we=()=>({root:({isActive:e})=>emotion.css(u({display:"flex",alignItems:"center",paddingRight:L__default.default.spacingXs},e?{backgroundColor:L__default.default.gray100}:{})),content:emotion.css({marginRight:L__default.default.spacingM}),icon:emotion.css({marginLeft:"auto",fill:"currentColor"})});var Ct=(e,t)=>{let{className:o,children:n}=e,{getSubmenuTriggerProps:i,isOpen:a}=B(),s=we();return F__default.default.createElement(A,null,F__default.default.createElement(H,h(u(u({},e),i(e,t)),{className:emotion.cx(s.root({isActive:a}),o)}),F__default.default.createElement("span",{className:s.content},n),F__default.default.createElement(f36Icons.ChevronRightIcon,{className:s.icon})))},te=F__default.default.forwardRef(Ct);var R=W;R.List=q;R.ListHeader=w;R.ListFooter=N;R.Item=H;R.Trigger=A;R.Divider=V;R.SectionTitle=J;R.Submenu=Z;R.SubmenuTrigger=te;
|
|
16
|
+
var Fe=Object.defineProperty,ke=Object.defineProperties;var We=Object.getOwnPropertyDescriptors;var B=Object.getOwnPropertySymbols;var ae=Object.prototype.hasOwnProperty,ce=Object.prototype.propertyIsEnumerable;var me=(e,t,o)=>t in e?Fe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,i=(e,t)=>{for(var o in t||(t={}))ae.call(t,o)&&me(e,o,t[o]);if(B)for(var o of B(t))ce.call(t,o)&&me(e,o,t[o]);return e},h=(e,t)=>ke(e,We(t));var x=(e,t)=>{var o={};for(var n in e)ae.call(e,n)&&t.indexOf(n)<0&&(o[n]=e[n]);if(e!=null&&B)for(var n of B(e))t.indexOf(n)<0&&ce.call(e,n)&&(o[n]=e[n]);return o};var pe={vertical:{prev:"ArrowUp",next:"ArrowDown"},horizontal:{prev:"ArrowLeft",next:"ArrowRight"}},le=({itemsContainerRef:e,itemsSelector:t,keyType:o="vertical"})=>{let[n,u]=W.useState(0),a=W.useCallback(s=>{let l=e.current;if(!l)return;let b=l.querySelectorAll(t);if(b.length===0)return;let c=b.length-1,S=()=>u(0),T=()=>u(c),p=()=>{n===c?S():u(n+1);},d=()=>{n===0?T():u(n-1);},g={[pe[o].next]:p,[pe[o].prev]:d}[s.key];g&&(s.preventDefault(),g());},[n,t,e,o]);return {focusedIndex:n,handleArrowsKeyDown:a,setFocusedIndex:u}};var de=W__default.default.createContext(void 0),w=()=>{let e=W__default.default.useContext(de);if(e===void 0)throw new Error("useMenuContext must be used within a MenuContextProvider");return e},ge=de.Provider;var z='[role="menuitem"]:not(:disabled)';function U(e){let ne=e,{closeOnSelect:t=!0,closeOnBlur:o=!0,closeOnEsc:n=!0,children:u,onOpen:a}=ne,s=x(ne,["closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen"]),{isOpen:l,handleOpen:b,handleClose:c,isControlled:S}=f36Core.useControllableState({isOpen:e.isOpen,defaultIsOpen:e.defaultIsOpen,onOpen:a,onClose:e.onClose}),T=W.useRef(null),p=W.useRef(null),d=f36Core.useId(null,"menu"),{focusedIndex:f,handleArrowsKeyDown:g,setFocusedIndex:N}=le({itemsContainerRef:p,itemsSelector:z});W.useEffect(()=>{if(l&&p.current){let r=p.current.querySelectorAll(z);r.length>0&&f<r.length?setTimeout(()=>{r[f].focus({preventScroll:!1});},0):setTimeout(()=>{var E;(E=p.current)==null||E.focus({preventScroll:!1});},0);}},[l,f]);let R=W.useCallback(r=>{let P=[...p.current.querySelectorAll(z)].findIndex(y=>r===y);P!==-1&&N(P);},[N]),m=W.useCallback(()=>{var r;c(),(r=T.current)==null||r.focus({preventScroll:!0});},[c]),O=W.useCallback(r=>{if(r.key==="Tab"){r.preventDefault(),m();return}if(r.stopPropagation(),r.key==="ArrowLeft"){r.preventDefault(),m();return}g(r);},[m,g]),M=W.useRef(!1),C=W.useMemo(()=>({isOpen:l,menuId:d,focusMenuItem:R,getTriggerProps:(r={},E=null)=>({onMouseDown:P=>{var y;M.current=!0,(y=r.onMouseDown)==null||y.call(r,P);},onMouseUp:P=>{var y;M.current=!1,(y=r.onMouseUp)==null||y.call(r,P);},onClick:P=>{var I;S&&!a||(l?c():b()),(I=r.onClick)==null||I.call(r,P);},ref:f36Core.mergeRefs(T,E)}),getMenuListProps:(r={},E=null)=>({ref:f36Core.mergeRefs(p,E),onKeyDown:P=>{var y;O(P),(y=r.onKeyDown)==null||y.call(r,P);},onBlur:P=>{var re,se,ie,ue;if((re=r.onBlur)==null||re.call(r,P),!o)return;let y=document.activeElement,I=P.relatedTarget||y,He=p.current===I||((se=p.current)==null?void 0:se.contains(I)),Ae=T.current===I||((ie=T.current)==null?void 0:ie.contains(I))||M.current,De=((ue=I==null?void 0:I.parentElement)==null?void 0:ue.dataset.parentMenu)===d;if(He||Ae||De){P.stopPropagation();return}c();}}),getMenuItemProps:(r={})=>({onClick:E=>{var y;(y=r.onClick)==null||y.call(r,E);let P=!!E.target.getAttribute("aria-haspopup");t&&!P&&m();}}),propsToPropagateToSubmenus:{closeOnSelect:t,closeOnBlur:o,closeOnEsc:n}}),[d,l,O,t,c,b,R,o,n,m,S,a]);return W__default.default.createElement(ge,{value:C},W__default.default.createElement(f36Popover.Popover,h(i({},s),{isOpen:l,onClose:c,id:d,closeOnEsc:n,autoFocus:!1,closeOnBlur:!1}),u))}var xe=W__default.default.createContext(void 0),K=()=>W__default.default.useContext(xe),Te=xe.Provider;var be=()=>emotion.css({position:"sticky",top:0,left:0,backgroundColor:v__default.default.colorWhite,borderBottom:`1px solid ${v__default.default.gray300}`,marginBottom:v__default.default.spacing2Xs,padding:`${v__default.default.spacing2Xs} 0`,zIndex:1001}),Se=()=>emotion.css({position:"sticky",bottom:0,left:0,backgroundColor:v__default.default.colorWhite,borderTop:`1px solid ${v__default.default.gray300}`,marginTop:v__default.default.spacing2Xs,padding:`${v__default.default.spacing2Xs} 0`,zIndex:1001}),he=e=>({container:emotion.css({borderRadius:"8px",overflowY:"auto",position:"relative",padding:0,paddingTop:e.hasStickyHeader?0:v__default.default.spacing2Xs,paddingBottom:e.hasStickyFooter?0:v__default.default.spacing2Xs})});var H=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-header",className:n}=s,u=x(s,["children","testId","className"]),a=be();return W__default.default.createElement("div",i({"data-test-id":o,className:emotion.cx(a,n)},u),t)};H.displayName="MenuListHeader";var A=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-footer",className:n}=s,u=x(s,["children","testId","className"]),a=Se();return W__default.default.createElement("div",i({"data-test-id":o,className:emotion.cx(a,n)},u),t)};A.displayName="MenuListFooter";function Ze(e){var t;return !!((t=e==null?void 0:e.type)!=null&&t.displayName)}var _e=(e,t)=>{let d=e,{children:o,testId:n="cf-ui-menu-list",className:u}=d,a=x(d,["children","testId","className"]),{getMenuListProps:s}=w(),l=K(),b=null,c=null,S=[];W__default.default.Children.forEach(o,f=>{let g=!0;Ze(f)&&(f.type.displayName===H.displayName?(b=f,g=!1):f.type.displayName===A.displayName&&(c=f,g=!1)),g&&S.push(f);});let T=he({hasStickyHeader:!!b,hasStickyFooter:!!c}),p=l?l.getSubmenuListProps(a):a;return W__default.default.createElement(f36Popover.Popover.Content,h(i(i({role:"menu"},p),s(p,t)),{className:emotion.cx(T.container,u),testId:n}),b,S,c)},Y=W__default.default.forwardRef(_e);var Ce=({isActive:e,isDisabled:t})=>emotion.cx(f36Core.getMenuItemStyles({isActive:e,isDisabled:t}),emotion.css({width:`calc(100% - 2 * ${v__default.default.spacing2Xs})`,margin:`0 ${v__default.default.spacing2Xs}`,gap:v__default.default.spacingXs}));var mt="button";function Ie(e,t){let R=e,{testId:o,className:n,as:u,isActive:a=!1,isDisabled:s,isInitiallyFocused:l,icon:b}=R,c=x(R,["testId","className","as","isActive","isDisabled","isInitiallyFocused","icon"]),S=f36Core.useId(void 0,"menu-item"),T=o||`cf-ui-${S}`,p=Ce({isActive:a,isDisabled:s}),{getMenuItemProps:d,focusMenuItem:f}=w(),g=W.useRef(null);W.useEffect(()=>{l&&g.current&&f(g.current);},[l,f]);let N=u!=null?u:mt;return W__default.default.createElement(N,h(i(i({role:"menuitem"},c),d(c)),{disabled:s!=null?s:e.disabled,className:emotion.cx(p,n),"data-test-id":T,ref:f36Core.mergeRefs(g,t),tabIndex:-1}),b,e.children)}Ie.displayName="MenuItem";var D=W__default.default.forwardRef(Ie);var F=e=>{let t=W__default.default.Children.only(e.children),{getTriggerProps:o}=w();return W__default.default.createElement(f36Popover.Popover.Trigger,null,W__default.default.cloneElement(t,h(i({},o(t.props,t.ref)),{"aria-haspopup":"menu"})))};var Le=()=>emotion.css({border:"none",width:"100%",height:"1px",backgroundColor:v__default.default.gray200,margin:`${v__default.default.spacing2Xs} 0`});var J=e=>{let s=e,{children:t,testId:o="cf-ui-menu-divider",className:n}=s,u=x(s,["children","testId","className"]),a=Le();return W__default.default.createElement("hr",i({"aria-orientation":"horizontal","data-test-id":o,className:emotion.cx(a,n)},u))};var Re=()=>emotion.css({color:v__default.default.gray500,textAlign:"left",padding:`${v__default.default.spacingXs} ${v__default.default.spacingS} ${v__default.default.spacing2Xs}`,lineHeight:v__default.default.lineHeightM});var Q=e=>{let s=e,{children:t,testId:o="cf-ui-menu-section-title",className:n}=s,u=x(s,["children","testId","className"]),a=Re();return W__default.default.createElement(f36Typography.Caption,i({"aria-hidden":"true",as:"div",testId:o,className:emotion.cx(a,n),marginBottom:"none"},u),t)};var bt=[-8,2],_=e=>{let R=e,{onClose:t,onOpen:o,placement:n="right-start",isAutoalignmentEnabled:u=!1}=R,a=x(R,["onClose","onOpen","placement","isAutoalignmentEnabled"]),{isOpen:s,menuId:l,propsToPropagateToSubmenus:b}=w(),c=W.useRef(null),S=W.useRef(null),[T,p]=W.useState(!1),d=W.useCallback(()=>{p(!0),window.clearTimeout(S.current),o==null||o();},[o]),f=W.useCallback(()=>{p(!1),window.clearTimeout(S.current),t==null||t();},[t]),g=W.useCallback(()=>{var m;f(),(m=c.current)==null||m.focus({preventScroll:!0});},[f]);W.useEffect(()=>{s===!1&&p(!1);},[s]);let N=W.useMemo(()=>({isOpen:T,getSubmenuListProps:m=>({"data-parent-menu":l,onMouseOver:O=>{var M;d(),(M=m.onMouseOver)==null||M.call(m,O);},onMouseLeave:O=>{var M;g(),(M=m.onMouseLeave)==null||M.call(m,O);}}),getSubmenuTriggerProps:(m,O)=>({ref:f36Core.mergeRefs(c,O),onKeyDown:M=>{var C;M.key==="ArrowRight"&&(M.preventDefault(),d()),(C=m.onKeyDown)==null||C.call(m,M);},onMouseOver:M=>{var C;d(),(C=m.onMouseOver)==null||C.call(m,M);},onMouseLeave:M=>{var C;S.current=window.setTimeout(g,300),(C=m.onMouseLeave)==null||C.call(m,M);}})}),[T,l,d,g]);return W__default.default.createElement(Te,{value:N},W__default.default.createElement(U,h(i(i({},b),a),{isOpen:T,onClose:f,onOpen:d,placement:n,isAutoalignmentEnabled:u,offset:bt})))};var Ne=()=>({root:({isActive:e})=>emotion.css(i({display:"flex",alignItems:"center",paddingRight:v__default.default.spacingXs},e?{backgroundColor:v__default.default.gray100}:{})),content:emotion.css({marginRight:v__default.default.spacingM}),icon:emotion.css({marginLeft:"auto",fill:"currentColor"})});var Ct=(e,t)=>{let{className:o,children:n}=e,{getSubmenuTriggerProps:u,isOpen:a}=K(),s=Ne();return W__default.default.createElement(F,null,W__default.default.createElement(D,h(i(i({},e),u(e,t)),{className:emotion.cx(s.root({isActive:a}),o)}),W__default.default.createElement("span",{className:s.content},n),W__default.default.createElement(f36Icons.ChevronRightIcon,{className:s.icon})))},oe=W__default.default.forwardRef(Ct);var L=U;L.List=Y;L.ListHeader=H;L.ListFooter=A;L.Item=D;L.Trigger=F;L.Divider=J;L.SectionTitle=Q;L.Submenu=_;L.SubmenuTrigger=oe;
|
|
17
17
|
|
|
18
|
-
exports.Menu =
|
|
19
|
-
exports.MenuDivider =
|
|
20
|
-
exports.MenuItem =
|
|
21
|
-
exports.MenuList =
|
|
22
|
-
exports.MenuSectionTitle =
|
|
23
|
-
exports.MenuTrigger =
|
|
24
|
-
exports.Submenu =
|
|
25
|
-
exports.SubmenuTrigger =
|
|
18
|
+
exports.Menu = L;
|
|
19
|
+
exports.MenuDivider = J;
|
|
20
|
+
exports.MenuItem = D;
|
|
21
|
+
exports.MenuList = Y;
|
|
22
|
+
exports.MenuSectionTitle = Q;
|
|
23
|
+
exports.MenuTrigger = F;
|
|
24
|
+
exports.Submenu = _;
|
|
25
|
+
exports.SubmenuTrigger = oe;
|
|
26
26
|
//# sourceMappingURL=out.js.map
|
|
27
27
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Menu.tsx","../src/useArrowKeyNavigation.ts","../src/MenuContext.ts","../src/MenuList/MenuList.tsx","../src/SubmenuContext.ts","../src/MenuList/MenuList.styles.ts","../src/MenuList/MenuListHeader.tsx","../src/MenuList/MenuListFooter.tsx","../src/MenuItem/MenuItem.tsx","../src/MenuItem/MenuItem.styles.ts","../src/MenuTrigger/MenuTrigger.tsx","../src/MenuDivider/MenuDivider.tsx","../src/MenuDivider/MenuDivider.styles.ts","../src/MenuSectionTitle/MenuSectionTitle.tsx","../src/MenuSectionTitle/MenuSectionTitle.styles.ts","../src/Submenu/Submenu.tsx","../src/SubmenuTrigger/SubmenuTrigger.tsx","../src/SubmenuTrigger/SubmenuTrigger.styles.ts","../src/CompoundMenu.tsx"],"names":["React","useCallback","useMemo","useRef","useEffect","mergeRefs","useId","useControllableState","Popover","useState","ARROW_KEY_TYPES","useArrowKeyNavigation","itemsContainerRef","itemsSelector","keyType","focusedIndex","setFocusedIndex","handleArrowsKeyDown","event","container","items","lastItemIndex","focusFirstItem","focusLastItem","focusNextItem","focusPrevItem","fn","MenuContext","useMenuContext","context","MenuContextProvider","MENU_ITEMS_SELECTOR","Menu","props","_a","closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen","otherProps","__objRest","isOpen","handleOpen","handleClose","isControlled","triggerRef","menuListRef","menuId","menuItems","focusMenuItem","item","itemIndex","menuItem","closeAndFocusTrigger","handleMenuListKeyDown","isMouseDown","contextValue","_props","_ref","_b","_c","_d","activeElement","relatedTarget","targetIsMenu","targetIsTrigger","targetIsSubmenu","isSubmenuTrigger","__spreadProps","__spreadValues","SubmenuContext","useSubmenuContext","SubmenuContextProvider","cx","css","tokens","getMenuHeaderStyles","getMenuFooterStyles","getMenuListStyles","MenuListHeader","testId","className","styles","MenuListFooter","assertChild","child","_MenuList","ref","getMenuListProps","submenuContext","header","footer","appendChild","extendedOtherProps","MenuList","globalGetMenuItemStyles","getMenuItemStyles","isActive","isDisabled","MENU_ITEM_DEFAULT_TAG","_MenuItem","as","isInitiallyFocused","icon","id","itemTestId","getMenuItemProps","itemRef","Element","MenuItem","MenuTrigger","getTriggerProps","getMenuDividerStyles","MenuDivider","Caption","getMenuSectionTitleStyles","MenuSectionTitle","SUBMENU_OFFSET","Submenu","onClose","isParentMenuOpen","propsToPropagateToSubmenus","mouseLeaveTimerRef","setIsOpen","ChevronRightIcon","getSubmenuTriggerStyles","_SubmenuTrigger","getSubmenuTriggerProps","SubmenuTrigger"],"mappings":"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","sourcesContent":["import React, { useCallback, useMemo, useRef, useEffect } from 'react';\nimport { mergeRefs, useId, useControllableState } from '@contentful/f36-core';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\n\nimport { useArrowKeyNavigation } from './useArrowKeyNavigation';\nimport { MenuContextProvider, MenuContextType } from './MenuContext';\n\nconst MENU_ITEMS_SELECTOR = '[role=\"menuitem\"]:not(:disabled)';\n\nexport interface MenuProps\n extends Omit<PopoverProps, 'autoFocus' | 'id' | 'closeOnBlur'> {\n /**\n * By default, the Menu is uncontrolled (manage it's expanded state by itself)\n * But you can make it controlled by providing boolean (true/false)\n */\n isOpen?: boolean;\n\n /**\n * If `true`, the Menu will be initially opened.\n */\n defaultIsOpen?: boolean;\n\n /**\n * Callback fired when the Menu opens\n */\n onOpen?: () => void;\n\n /**\n * Callback fired when the Menu closes\n */\n onClose?: () => void;\n\n /**\n * If `true`, the Menu will close when a menu item is\n * clicked\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnSelect?: boolean;\n\n /**\n * If true, the menu will close when you blur out it by clicking outside\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnBlur?: boolean;\n\n /**\n * If true, the menu will close when you hit the Esc key\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnEsc?: boolean;\n}\n\nexport function Menu(props: MenuProps) {\n const {\n closeOnSelect = true,\n closeOnBlur = true,\n closeOnEsc = true,\n children,\n onOpen,\n ...otherProps\n } = props;\n const { isOpen, handleOpen, handleClose, isControlled } =\n useControllableState({\n isOpen: props.isOpen,\n defaultIsOpen: props.defaultIsOpen,\n onOpen,\n onClose: props.onClose,\n });\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuListRef = useRef<HTMLDivElement>(null);\n\n const menuId = useId(null, 'menu');\n\n const { focusedIndex, handleArrowsKeyDown, setFocusedIndex } =\n useArrowKeyNavigation({\n itemsContainerRef: menuListRef,\n itemsSelector: MENU_ITEMS_SELECTOR,\n });\n\n useEffect(() => {\n if (isOpen && menuListRef.current) {\n const menuItems =\n menuListRef.current.querySelectorAll<HTMLElement>(MENU_ITEMS_SELECTOR);\n\n if (menuItems.length > 0 && focusedIndex < menuItems.length) {\n // timeout trick to prevent scroll from jumping\n // when the popover is not positioned correctly yet in the opening phase\n setTimeout(() => {\n menuItems[focusedIndex].focus({ preventScroll: false });\n }, 0);\n } else {\n setTimeout(() => {\n menuListRef.current?.focus({ preventScroll: false });\n }, 0);\n }\n }\n }, [isOpen, focusedIndex]);\n\n const focusMenuItem = useCallback(\n (item: HTMLElement) => {\n const menuItems =\n menuListRef.current.querySelectorAll(MENU_ITEMS_SELECTOR);\n\n const itemIndex = [...menuItems].findIndex(\n (menuItem) => item === menuItem,\n );\n\n if (itemIndex !== -1) {\n setFocusedIndex(itemIndex);\n }\n },\n [setFocusedIndex],\n );\n\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n const handleMenuListKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Tab') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n // we don't want to propagate other keydown events except `Tab`\n event.stopPropagation();\n\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n handleArrowsKeyDown(event);\n },\n [closeAndFocusTrigger, handleArrowsKeyDown],\n );\n\n // Safari has an issue with the relatedTarget that we use on the onBlur for menuListProps,\n // which was causing the menu to close and reopen when clicking on the trigger.\n // We will use the isMouseDown to prevent triggering blur in the cases where the user clicks on the trigger.\n const isMouseDown = useRef<Boolean>(false);\n\n const contextValue: MenuContextType = useMemo(\n () => ({\n isOpen,\n menuId,\n focusMenuItem,\n getTriggerProps: (_props = {}, _ref = null) => ({\n onMouseDown: (event) => {\n isMouseDown.current = true;\n _props.onMouseDown?.(event);\n },\n onMouseUp: (event) => {\n isMouseDown.current = false;\n _props.onMouseUp?.(event);\n },\n onClick: (event) => {\n // if the user made component controlled by providing isOpen prop\n // but onOpen callback is not provided, we won't add toggle logic\n // to the trigger component. So they can make any toggle logic on their own.\n const isFullyControlled = isControlled && !onOpen;\n\n if (!isFullyControlled) {\n if (isOpen) {\n handleClose();\n } else {\n handleOpen();\n }\n }\n\n _props.onClick?.(event);\n },\n ref: mergeRefs(triggerRef, _ref),\n }),\n getMenuListProps: (_props = {}, _ref = null) => ({\n ref: mergeRefs(menuListRef, _ref),\n onKeyDown: (event) => {\n handleMenuListKeyDown(event);\n _props.onKeyDown?.(event);\n },\n onBlur: (event) => {\n _props.onBlur?.(event);\n\n if (!closeOnBlur) {\n return;\n }\n\n const activeElement = document.activeElement;\n const relatedTarget = event.relatedTarget || activeElement;\n\n const targetIsMenu =\n menuListRef.current === relatedTarget ||\n menuListRef.current?.contains(relatedTarget);\n const targetIsTrigger =\n triggerRef.current === relatedTarget ||\n triggerRef.current?.contains(relatedTarget) ||\n isMouseDown.current;\n const targetIsSubmenu =\n relatedTarget?.parentElement?.dataset.parentMenu === menuId;\n\n if (targetIsMenu || targetIsTrigger || targetIsSubmenu) {\n event.stopPropagation();\n return;\n }\n\n handleClose();\n },\n }),\n getMenuItemProps: (_props = {}) => ({\n onClick: (event) => {\n _props.onClick?.(event);\n\n const isSubmenuTrigger = Boolean(\n (event.target as HTMLElement).getAttribute('aria-haspopup'),\n );\n if (closeOnSelect && !isSubmenuTrigger) {\n closeAndFocusTrigger();\n }\n },\n }),\n propsToPropagateToSubmenus: {\n closeOnSelect,\n closeOnBlur,\n closeOnEsc,\n },\n }),\n [\n menuId,\n isOpen,\n handleMenuListKeyDown,\n closeOnSelect,\n handleClose,\n handleOpen,\n focusMenuItem,\n closeOnBlur,\n closeOnEsc,\n closeAndFocusTrigger,\n isControlled,\n onOpen,\n ],\n );\n\n return (\n <MenuContextProvider value={contextValue}>\n <Popover\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n id={menuId}\n closeOnEsc={closeOnEsc}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={false}\n closeOnBlur={false}\n >\n {children}\n </Popover>\n </MenuContextProvider>\n );\n}\n","import { useState, useCallback } from 'react';\n\ninterface UseArrowKeyNavigationProps {\n itemsContainerRef: React.MutableRefObject<HTMLElement>;\n itemsSelector: string;\n keyType?: 'vertical' | 'horizontal';\n initialFocusedIndex?: number;\n}\n\nconst ARROW_KEY_TYPES = {\n vertical: {\n prev: 'ArrowUp',\n next: 'ArrowDown',\n },\n horizontal: {\n prev: 'ArrowLeft',\n next: 'ArrowRight',\n },\n};\n\nexport const useArrowKeyNavigation = ({\n itemsContainerRef,\n itemsSelector,\n keyType = 'vertical',\n}: UseArrowKeyNavigationProps) => {\n const [focusedIndex, setFocusedIndex] = useState<number>(0);\n\n const handleArrowsKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n const container = itemsContainerRef.current;\n if (!container) return;\n\n const items = container.querySelectorAll(itemsSelector);\n if (items.length === 0) return;\n\n const lastItemIndex = items.length - 1;\n\n const focusFirstItem = () => setFocusedIndex(0);\n const focusLastItem = () => setFocusedIndex(lastItemIndex);\n const focusNextItem = () => {\n if (focusedIndex === lastItemIndex) {\n focusFirstItem();\n } else {\n setFocusedIndex(focusedIndex + 1);\n }\n };\n const focusPrevItem = () => {\n if (focusedIndex === 0) {\n focusLastItem();\n } else {\n setFocusedIndex(focusedIndex - 1);\n }\n };\n\n const keyToFnMap = {\n [ARROW_KEY_TYPES[keyType].next]: focusNextItem,\n [ARROW_KEY_TYPES[keyType].prev]: focusPrevItem,\n };\n\n const fn = keyToFnMap[event.key];\n if (fn) {\n event.preventDefault();\n fn();\n }\n },\n [focusedIndex, itemsSelector, itemsContainerRef, keyType],\n );\n\n return { focusedIndex, handleArrowsKeyDown, setFocusedIndex };\n};\n","import React, { ComponentPropsWithRef } from 'react';\nimport { MenuProps } from '.';\n\nexport type MenuContextType = {\n isOpen: boolean;\n menuId: string;\n focusMenuItem: (item: HTMLElement) => void;\n getTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n getMenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n _ref: React.Ref<HTMLDivElement>,\n ) => ComponentPropsWithRef<'div'>;\n getMenuItemProps: (\n _props: ComponentPropsWithRef<'button'>,\n ) => ComponentPropsWithRef<'button'>;\n propsToPropagateToSubmenus: Pick<\n MenuProps,\n 'closeOnBlur' | 'closeOnEsc' | 'closeOnSelect'\n >;\n};\n\nconst MenuContext = React.createContext<MenuContextType | undefined>(undefined);\n\nexport const useMenuContext = () => {\n const context = React.useContext(MenuContext);\n\n if (context === undefined) {\n throw new Error('useMenuContext must be used within a MenuContextProvider');\n }\n\n return context;\n};\n\nexport const MenuContextProvider = MenuContext.Provider;\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { useMenuContext } from '../MenuContext';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { Popover } from '@contentful/f36-popover';\nimport { cx } from 'emotion';\nimport { getMenuListStyles } from './MenuList.styles';\nimport { MenuListHeader } from './MenuListHeader';\nimport { MenuListFooter } from './MenuListFooter';\n\ninterface MenuListInternalProps extends CommonProps {\n children?: React.ReactNode;\n}\n\nfunction assertChild(child: any): child is { type: { displayName: string } } {\n return Boolean(child?.type?.displayName);\n}\n\nexport type MenuListProps = PropsWithHTMLElement<MenuListInternalProps, 'div'>;\n\nconst _MenuList = (\n props: ExpandProps<MenuListProps>,\n ref: React.Ref<HTMLDivElement>,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list',\n className,\n ...otherProps\n } = props;\n\n const { getMenuListProps } = useMenuContext();\n const submenuContext = useSubmenuContext();\n\n let header: React.ReactElement | null = null;\n let footer: React.ReactElement | null = null;\n const items: React.ReactElement[] = [];\n\n React.Children.forEach(children, (child) => {\n let appendChild = true;\n if (assertChild(child)) {\n if (child.type.displayName === MenuListHeader.displayName) {\n header = child as unknown as React.ReactElement;\n appendChild = false;\n } else if (child.type.displayName === MenuListFooter.displayName) {\n footer = child as unknown as React.ReactElement;\n appendChild = false;\n }\n }\n if (appendChild) {\n items.push(child as unknown as React.ReactElement);\n }\n });\n\n const styles = getMenuListStyles({\n hasStickyHeader: Boolean(header),\n hasStickyFooter: Boolean(footer),\n });\n\n const extendedOtherProps = submenuContext\n ? submenuContext.getSubmenuListProps(otherProps)\n : otherProps;\n\n return (\n <Popover.Content\n role=\"menu\"\n {...extendedOtherProps}\n {...getMenuListProps(extendedOtherProps, ref)}\n className={cx(styles.container, className)}\n testId={testId}\n >\n {header}\n {items}\n {footer}\n </Popover.Content>\n );\n};\n\nexport const MenuList = React.forwardRef(_MenuList);\n","import React, { ComponentPropsWithRef, ComponentPropsWithoutRef } from 'react';\n\nexport type SubmenuContextType = {\n isOpen: boolean;\n getSubmenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n ) => { 'data-parent-menu': string } & ComponentPropsWithoutRef<'div'>;\n getSubmenuTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n};\n\nconst SubmenuContext = React.createContext<SubmenuContextType | undefined>(\n undefined,\n);\n\nexport const useSubmenuContext = () => {\n const context = React.useContext(SubmenuContext);\n return context;\n};\n\nexport const SubmenuContextProvider = SubmenuContext.Provider;\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuHeaderStyles = () => {\n return css({\n position: 'sticky',\n top: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderBottom: `1px solid ${tokens.gray300}`,\n marginBottom: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuFooterStyles = () => {\n return css({\n position: 'sticky',\n bottom: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderTop: `1px solid ${tokens.gray300}`,\n marginTop: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuListStyles = (props: {\n hasStickyFooter?: boolean;\n hasStickyHeader?: boolean;\n}) => ({\n container: css({\n // To get to our regular border radius for the inner menu items (6px),\n // we need to use 8px on the outer container\n borderRadius: '8px',\n overflowY: 'auto',\n position: 'relative',\n padding: 0,\n paddingTop: props.hasStickyHeader ? 0 : tokens.spacing2Xs,\n paddingBottom: props.hasStickyFooter ? 0 : tokens.spacing2Xs,\n }),\n});\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuHeaderStyles } from './MenuList.styles';\n\nexport type MenuListHeaderProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListHeader: React.FC<ExpandProps<MenuListHeaderProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-header',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuHeaderStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListHeader.displayName = 'MenuListHeader';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuFooterStyles } from './MenuList.styles';\n\nexport type MenuListFooterProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListFooter: React.FC<ExpandProps<MenuListFooterProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-footer',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuFooterStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListFooter.displayName = 'MenuListFooter';\n","import React, { useEffect, useRef } from 'react';\nimport { cx } from 'emotion';\nimport {\n mergeRefs,\n useId,\n type CommonProps,\n type PolymorphicComponent,\n type PolymorphicProps,\n type ExpandProps,\n} from '@contentful/f36-core';\n\nimport { useMenuContext } from '../MenuContext';\nimport { getMenuItemStyles } from './MenuItem.styles';\n\nconst MENU_ITEM_DEFAULT_TAG = 'button';\n\ninterface MenuItemInternalProps extends CommonProps {\n children?: React.ReactNode;\n as?: 'a' | 'button';\n\n /**\n * Marks item as active\n */\n isActive?: boolean;\n /**\n * Marks item as disabled\n */\n isDisabled?: boolean;\n /**\n * Sets focus on item\n */\n isInitiallyFocused?: boolean;\n /**\n * Expects any of the icon components. Renders the icon aligned to the start\n */\n icon?: React.ReactElement;\n}\n\nexport type MenuItemProps<\n E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG,\n> = PolymorphicProps<MenuItemInternalProps, E>;\n\nfunction _MenuItem<E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG>(\n props: MenuItemProps<E>,\n ref: React.Ref<any>,\n) {\n const {\n testId,\n className,\n as,\n isActive = false,\n isDisabled,\n isInitiallyFocused,\n icon,\n ...otherProps\n } = props;\n\n const id = useId(undefined, 'menu-item');\n const itemTestId = testId || `cf-ui-${id}`;\n const styles = getMenuItemStyles({ isActive, isDisabled });\n\n const { getMenuItemProps, focusMenuItem } = useMenuContext();\n\n const itemRef = useRef<HTMLElement>(null);\n useEffect(() => {\n if (isInitiallyFocused && itemRef.current) {\n focusMenuItem(itemRef.current);\n }\n }, [isInitiallyFocused, focusMenuItem]);\n\n const Element = (as ?? MENU_ITEM_DEFAULT_TAG) as React.ElementType;\n\n return (\n <Element\n role=\"menuitem\"\n {...otherProps}\n {...getMenuItemProps(otherProps)}\n disabled={isDisabled ?? props.disabled}\n className={cx(styles, className)}\n data-test-id={itemTestId}\n ref={mergeRefs(itemRef, ref)}\n tabIndex={-1}\n >\n {icon}\n {props.children}\n </Element>\n );\n}\n\n_MenuItem.displayName = 'MenuItem';\n\nexport const MenuItem: PolymorphicComponent<\n ExpandProps<MenuItemInternalProps>,\n typeof MENU_ITEM_DEFAULT_TAG\n> = React.forwardRef(_MenuItem);\n","import { css, cx } from 'emotion';\nimport { getMenuItemStyles as globalGetMenuItemStyles } from '@contentful/f36-core';\nimport type { MenuItemProps } from './MenuItem';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuItemStyles = ({\n isActive,\n isDisabled,\n}: {\n isActive: MenuItemProps['isActive'];\n isDisabled: MenuItemProps['isDisabled'];\n}) =>\n cx(\n globalGetMenuItemStyles({ isActive, isDisabled }),\n css({\n width: `calc(100% - 2 * ${tokens.spacing2Xs})`,\n margin: `0 ${tokens.spacing2Xs}`,\n gap: tokens.spacingXs,\n }),\n );\n","import React from 'react';\nimport { Popover } from '@contentful/f36-popover';\nimport { useMenuContext } from '../MenuContext';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nexport interface MenuTriggerProps {\n children: React.ReactNode;\n}\n\nexport const MenuTrigger = (props: ExpandProps<MenuTriggerProps>) => {\n const child = React.Children.only(props.children) as any;\n const { getTriggerProps } = useMenuContext();\n\n return (\n <Popover.Trigger>\n {React.cloneElement(child, {\n ...getTriggerProps(child.props, child.ref),\n ['aria-haspopup']: 'menu',\n })}\n </Popover.Trigger>\n );\n};\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getMenuDividerStyles } from './MenuDivider.styles';\n\nexport type MenuDividerProps = PropsWithHTMLElement<CommonProps, 'hr'>;\n\nexport const MenuDivider = (props: ExpandProps<MenuDividerProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-divider',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuDividerStyles();\n\n return (\n <hr\n aria-orientation=\"horizontal\"\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n />\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuDividerStyles = () =>\n css({\n border: 'none',\n width: '100%',\n height: '1px',\n backgroundColor: tokens.gray200,\n margin: `${tokens.spacing2Xs} 0`,\n });\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { Caption, type CaptionProps } from '@contentful/f36-typography';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nimport { getMenuSectionTitleStyles } from './MenuSectionTitle.styles';\n\nexport type MenuSectionTitleProps = CaptionProps;\n\nexport const MenuSectionTitle = (props: ExpandProps<MenuSectionTitleProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-section-title',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuSectionTitleStyles();\n\n return (\n <Caption\n // Techincally, menus cannot contain headings according to ARIA.\n // We hide the heading from assistive technology, and only use it\n // as a label\n aria-hidden=\"true\"\n as=\"div\"\n testId={testId}\n className={cx(styles, className)}\n marginBottom=\"none\"\n {...otherProps}\n >\n {children}\n </Caption>\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuSectionTitleStyles = () =>\n css({\n color: tokens.gray500,\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingS} ${tokens.spacing2Xs}`,\n lineHeight: tokens.lineHeightM,\n });\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Menu, MenuProps } from '../Menu';\nimport { useMenuContext } from '../MenuContext';\nimport { SubmenuContextProvider, SubmenuContextType } from '../SubmenuContext';\nimport { mergeRefs } from '@contentful/f36-core';\n\nconst SUBMENU_OFFSET: [number, number] = [-8, 2];\n\nexport type SubmenuProps = Omit<\n MenuProps,\n | 'placement'\n | 'offset'\n | 'usePortal'\n | 'isOpen'\n | 'isAutoalignmentEnabled'\n | 'defaultIsOpen'\n>;\n\nexport const Submenu = (props: SubmenuProps) => {\n const { onClose, onOpen, ...otherProps } = props;\n\n const {\n isOpen: isParentMenuOpen,\n menuId,\n propsToPropagateToSubmenus,\n } = useMenuContext();\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const mouseLeaveTimerRef = useRef(null);\n\n const [isOpen, setIsOpen] = useState(false);\n const handleOpen = useCallback(() => {\n setIsOpen(true);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onOpen?.();\n }, [onOpen]);\n const handleClose = useCallback(() => {\n setIsOpen(false);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onClose?.();\n }, [onClose]);\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n useEffect(() => {\n // close when parent menu closed\n if (isParentMenuOpen === false) {\n setIsOpen(false);\n }\n }, [isParentMenuOpen]);\n\n const contextValue: SubmenuContextType = useMemo(\n () => ({\n isOpen,\n getSubmenuListProps: (_props) => ({\n 'data-parent-menu': menuId,\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n closeAndFocusTrigger();\n\n _props.onMouseLeave?.(event);\n },\n }),\n getSubmenuTriggerProps: (_props, _ref) => ({\n ref: mergeRefs(triggerRef, _ref),\n onKeyDown: (event) => {\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n handleOpen();\n }\n\n _props.onKeyDown?.(event);\n },\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n mouseLeaveTimerRef.current = window.setTimeout(\n closeAndFocusTrigger,\n 300,\n );\n\n _props.onMouseLeave?.(event);\n },\n }),\n }),\n [isOpen, menuId, handleOpen, closeAndFocusTrigger],\n );\n\n return (\n <SubmenuContextProvider value={contextValue}>\n <Menu\n {...propsToPropagateToSubmenus}\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n onOpen={handleOpen}\n placement=\"right-start\"\n offset={SUBMENU_OFFSET}\n isAutoalignmentEnabled={false}\n />\n </SubmenuContextProvider>\n );\n};\n","import React from 'react';\nimport { MenuTrigger } from '../MenuTrigger/MenuTrigger';\nimport { MenuItem, MenuItemProps } from '../MenuItem/MenuItem';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { ChevronRightIcon } from '@contentful/f36-icons';\nimport type { ExpandProps } from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getSubmenuTriggerStyles } from './SubmenuTrigger.styles';\n\nexport type SubmenuTriggerProps = Omit<\n MenuItemProps<'button'>,\n 'isInitiallyFocused' | 'as'\n>;\n\nconst _SubmenuTrigger = (\n props: ExpandProps<SubmenuTriggerProps>,\n ref: React.Ref<HTMLButtonElement>,\n) => {\n const { className, children } = props;\n const { getSubmenuTriggerProps, isOpen } = useSubmenuContext();\n\n const styles = getSubmenuTriggerStyles();\n\n return (\n <MenuTrigger>\n <MenuItem\n {...props}\n {...getSubmenuTriggerProps(props, ref)}\n className={cx(styles.root({ isActive: isOpen }), className)}\n >\n <span className={styles.content}>{children}</span>\n <ChevronRightIcon className={styles.icon} />\n </MenuItem>\n </MenuTrigger>\n );\n};\n\nexport const SubmenuTrigger = React.forwardRef(_SubmenuTrigger);\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getSubmenuTriggerStyles = () => {\n return {\n root: ({ isActive }) =>\n css({\n display: 'flex',\n alignItems: 'center',\n paddingRight: tokens.spacingXs,\n ...(isActive\n ? {\n backgroundColor: tokens.gray100,\n }\n : {}),\n }),\n content: css({\n marginRight: tokens.spacingM,\n }),\n icon: css({\n marginLeft: 'auto',\n fill: 'currentColor',\n }),\n };\n};\n","import { Menu as OriginalMenu } from './Menu';\nimport { MenuList } from './MenuList/MenuList';\nimport { MenuListHeader } from './MenuList/MenuListHeader';\nimport { MenuListFooter } from './MenuList/MenuListFooter';\nimport { MenuItem } from './MenuItem/MenuItem';\nimport { MenuTrigger } from './MenuTrigger/MenuTrigger';\nimport { MenuDivider } from './MenuDivider/MenuDivider';\nimport { MenuSectionTitle } from './MenuSectionTitle/MenuSectionTitle';\nimport { Submenu } from './Submenu/Submenu';\nimport { SubmenuTrigger } from './SubmenuTrigger/SubmenuTrigger';\n\ntype CompoundMenu = typeof OriginalMenu & {\n List: typeof MenuList;\n ListHeader: typeof MenuListHeader;\n ListFooter: typeof MenuListFooter;\n Item: typeof MenuItem;\n Trigger: typeof MenuTrigger;\n Divider: typeof MenuDivider;\n SectionTitle: typeof MenuSectionTitle;\n Submenu: typeof Submenu;\n SubmenuTrigger: typeof SubmenuTrigger;\n};\n\nexport const Menu = OriginalMenu as CompoundMenu;\nMenu.List = MenuList;\nMenu.ListHeader = MenuListHeader;\nMenu.ListFooter = MenuListFooter;\nMenu.Item = MenuItem;\nMenu.Trigger = MenuTrigger;\nMenu.Divider = MenuDivider;\nMenu.SectionTitle = MenuSectionTitle;\nMenu.Submenu = Submenu;\nMenu.SubmenuTrigger = SubmenuTrigger;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/Menu.tsx","../src/useArrowKeyNavigation.ts","../src/MenuContext.ts","../src/MenuList/MenuList.tsx","../src/SubmenuContext.ts","../src/MenuList/MenuList.styles.ts","../src/MenuList/MenuListHeader.tsx","../src/MenuList/MenuListFooter.tsx","../src/MenuItem/MenuItem.tsx","../src/MenuItem/MenuItem.styles.ts","../src/MenuTrigger/MenuTrigger.tsx","../src/MenuDivider/MenuDivider.tsx","../src/MenuDivider/MenuDivider.styles.ts","../src/MenuSectionTitle/MenuSectionTitle.tsx","../src/MenuSectionTitle/MenuSectionTitle.styles.ts","../src/Submenu/Submenu.tsx","../src/SubmenuTrigger/SubmenuTrigger.tsx","../src/SubmenuTrigger/SubmenuTrigger.styles.ts","../src/CompoundMenu.tsx"],"names":["React","useCallback","useMemo","useRef","useEffect","mergeRefs","useId","useControllableState","Popover","useState","ARROW_KEY_TYPES","useArrowKeyNavigation","itemsContainerRef","itemsSelector","keyType","focusedIndex","setFocusedIndex","handleArrowsKeyDown","event","container","items","lastItemIndex","focusFirstItem","focusLastItem","focusNextItem","focusPrevItem","fn","MenuContext","useMenuContext","context","MenuContextProvider","MENU_ITEMS_SELECTOR","Menu","props","_a","closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen","otherProps","__objRest","isOpen","handleOpen","handleClose","isControlled","triggerRef","menuListRef","menuId","menuItems","focusMenuItem","item","itemIndex","menuItem","closeAndFocusTrigger","handleMenuListKeyDown","isMouseDown","contextValue","_props","_ref","_b","_c","_d","activeElement","relatedTarget","targetIsMenu","targetIsTrigger","targetIsSubmenu","isSubmenuTrigger","__spreadProps","__spreadValues","SubmenuContext","useSubmenuContext","SubmenuContextProvider","cx","css","tokens","getMenuHeaderStyles","getMenuFooterStyles","getMenuListStyles","MenuListHeader","testId","className","styles","MenuListFooter","assertChild","child","_MenuList","ref","getMenuListProps","submenuContext","header","footer","appendChild","extendedOtherProps","MenuList","globalGetMenuItemStyles","getMenuItemStyles","isActive","isDisabled","MENU_ITEM_DEFAULT_TAG","_MenuItem","as","isInitiallyFocused","icon","id","itemTestId","getMenuItemProps","itemRef","Element","MenuItem","MenuTrigger","getTriggerProps","getMenuDividerStyles","MenuDivider","Caption","getMenuSectionTitleStyles","MenuSectionTitle","SUBMENU_OFFSET","Submenu","onClose","placement","isAutoalignmentEnabled","isParentMenuOpen","propsToPropagateToSubmenus","mouseLeaveTimerRef","setIsOpen","ChevronRightIcon","getSubmenuTriggerStyles","_SubmenuTrigger","getSubmenuTriggerProps","SubmenuTrigger"],"mappings":"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","sourcesContent":["import React, { useCallback, useMemo, useRef, useEffect } from 'react';\nimport { mergeRefs, useId, useControllableState } from '@contentful/f36-core';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\n\nimport { useArrowKeyNavigation } from './useArrowKeyNavigation';\nimport { MenuContextProvider, MenuContextType } from './MenuContext';\n\nconst MENU_ITEMS_SELECTOR = '[role=\"menuitem\"]:not(:disabled)';\n\nexport interface MenuProps\n extends Omit<PopoverProps, 'autoFocus' | 'id' | 'closeOnBlur'> {\n /**\n * By default, the Menu is uncontrolled (manage it's expanded state by itself)\n * But you can make it controlled by providing boolean (true/false)\n */\n isOpen?: boolean;\n\n /**\n * If `true`, the Menu will be initially opened.\n */\n defaultIsOpen?: boolean;\n\n /**\n * Callback fired when the Menu opens\n */\n onOpen?: () => void;\n\n /**\n * Callback fired when the Menu closes\n */\n onClose?: () => void;\n\n /**\n * If `true`, the Menu will close when a menu item is\n * clicked\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnSelect?: boolean;\n\n /**\n * If true, the menu will close when you blur out it by clicking outside\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnBlur?: boolean;\n\n /**\n * If true, the menu will close when you hit the Esc key\n *\n * Note: This prop will be propagated to all submenus,\n * unless you will override it with props on submenu itself\n *\n * @default true\n */\n closeOnEsc?: boolean;\n}\n\nexport function Menu(props: MenuProps) {\n const {\n closeOnSelect = true,\n closeOnBlur = true,\n closeOnEsc = true,\n children,\n onOpen,\n ...otherProps\n } = props;\n const { isOpen, handleOpen, handleClose, isControlled } =\n useControllableState({\n isOpen: props.isOpen,\n defaultIsOpen: props.defaultIsOpen,\n onOpen,\n onClose: props.onClose,\n });\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuListRef = useRef<HTMLDivElement>(null);\n\n const menuId = useId(null, 'menu');\n\n const { focusedIndex, handleArrowsKeyDown, setFocusedIndex } =\n useArrowKeyNavigation({\n itemsContainerRef: menuListRef,\n itemsSelector: MENU_ITEMS_SELECTOR,\n });\n\n useEffect(() => {\n if (isOpen && menuListRef.current) {\n const menuItems =\n menuListRef.current.querySelectorAll<HTMLElement>(MENU_ITEMS_SELECTOR);\n\n if (menuItems.length > 0 && focusedIndex < menuItems.length) {\n // timeout trick to prevent scroll from jumping\n // when the popover is not positioned correctly yet in the opening phase\n setTimeout(() => {\n menuItems[focusedIndex].focus({ preventScroll: false });\n }, 0);\n } else {\n setTimeout(() => {\n menuListRef.current?.focus({ preventScroll: false });\n }, 0);\n }\n }\n }, [isOpen, focusedIndex]);\n\n const focusMenuItem = useCallback(\n (item: HTMLElement) => {\n const menuItems =\n menuListRef.current.querySelectorAll(MENU_ITEMS_SELECTOR);\n\n const itemIndex = [...menuItems].findIndex(\n (menuItem) => item === menuItem,\n );\n\n if (itemIndex !== -1) {\n setFocusedIndex(itemIndex);\n }\n },\n [setFocusedIndex],\n );\n\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n const handleMenuListKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Tab') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n // we don't want to propagate other keydown events except `Tab`\n event.stopPropagation();\n\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n closeAndFocusTrigger();\n return;\n }\n\n handleArrowsKeyDown(event);\n },\n [closeAndFocusTrigger, handleArrowsKeyDown],\n );\n\n // Safari has an issue with the relatedTarget that we use on the onBlur for menuListProps,\n // which was causing the menu to close and reopen when clicking on the trigger.\n // We will use the isMouseDown to prevent triggering blur in the cases where the user clicks on the trigger.\n const isMouseDown = useRef<Boolean>(false);\n\n const contextValue: MenuContextType = useMemo(\n () => ({\n isOpen,\n menuId,\n focusMenuItem,\n getTriggerProps: (_props = {}, _ref = null) => ({\n onMouseDown: (event) => {\n isMouseDown.current = true;\n _props.onMouseDown?.(event);\n },\n onMouseUp: (event) => {\n isMouseDown.current = false;\n _props.onMouseUp?.(event);\n },\n onClick: (event) => {\n // if the user made component controlled by providing isOpen prop\n // but onOpen callback is not provided, we won't add toggle logic\n // to the trigger component. So they can make any toggle logic on their own.\n const isFullyControlled = isControlled && !onOpen;\n\n if (!isFullyControlled) {\n if (isOpen) {\n handleClose();\n } else {\n handleOpen();\n }\n }\n\n _props.onClick?.(event);\n },\n ref: mergeRefs(triggerRef, _ref),\n }),\n getMenuListProps: (_props = {}, _ref = null) => ({\n ref: mergeRefs(menuListRef, _ref),\n onKeyDown: (event) => {\n handleMenuListKeyDown(event);\n _props.onKeyDown?.(event);\n },\n onBlur: (event) => {\n _props.onBlur?.(event);\n\n if (!closeOnBlur) {\n return;\n }\n\n const activeElement = document.activeElement;\n const relatedTarget = event.relatedTarget || activeElement;\n\n const targetIsMenu =\n menuListRef.current === relatedTarget ||\n menuListRef.current?.contains(relatedTarget);\n const targetIsTrigger =\n triggerRef.current === relatedTarget ||\n triggerRef.current?.contains(relatedTarget) ||\n isMouseDown.current;\n const targetIsSubmenu =\n relatedTarget?.parentElement?.dataset.parentMenu === menuId;\n\n if (targetIsMenu || targetIsTrigger || targetIsSubmenu) {\n event.stopPropagation();\n return;\n }\n\n handleClose();\n },\n }),\n getMenuItemProps: (_props = {}) => ({\n onClick: (event) => {\n _props.onClick?.(event);\n\n const isSubmenuTrigger = Boolean(\n (event.target as HTMLElement).getAttribute('aria-haspopup'),\n );\n if (closeOnSelect && !isSubmenuTrigger) {\n closeAndFocusTrigger();\n }\n },\n }),\n propsToPropagateToSubmenus: {\n closeOnSelect,\n closeOnBlur,\n closeOnEsc,\n },\n }),\n [\n menuId,\n isOpen,\n handleMenuListKeyDown,\n closeOnSelect,\n handleClose,\n handleOpen,\n focusMenuItem,\n closeOnBlur,\n closeOnEsc,\n closeAndFocusTrigger,\n isControlled,\n onOpen,\n ],\n );\n\n return (\n <MenuContextProvider value={contextValue}>\n <Popover\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n id={menuId}\n closeOnEsc={closeOnEsc}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={false}\n closeOnBlur={false}\n >\n {children}\n </Popover>\n </MenuContextProvider>\n );\n}\n","import { useState, useCallback } from 'react';\n\ninterface UseArrowKeyNavigationProps {\n itemsContainerRef: React.MutableRefObject<HTMLElement>;\n itemsSelector: string;\n keyType?: 'vertical' | 'horizontal';\n initialFocusedIndex?: number;\n}\n\nconst ARROW_KEY_TYPES = {\n vertical: {\n prev: 'ArrowUp',\n next: 'ArrowDown',\n },\n horizontal: {\n prev: 'ArrowLeft',\n next: 'ArrowRight',\n },\n};\n\nexport const useArrowKeyNavigation = ({\n itemsContainerRef,\n itemsSelector,\n keyType = 'vertical',\n}: UseArrowKeyNavigationProps) => {\n const [focusedIndex, setFocusedIndex] = useState<number>(0);\n\n const handleArrowsKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n const container = itemsContainerRef.current;\n if (!container) return;\n\n const items = container.querySelectorAll(itemsSelector);\n if (items.length === 0) return;\n\n const lastItemIndex = items.length - 1;\n\n const focusFirstItem = () => setFocusedIndex(0);\n const focusLastItem = () => setFocusedIndex(lastItemIndex);\n const focusNextItem = () => {\n if (focusedIndex === lastItemIndex) {\n focusFirstItem();\n } else {\n setFocusedIndex(focusedIndex + 1);\n }\n };\n const focusPrevItem = () => {\n if (focusedIndex === 0) {\n focusLastItem();\n } else {\n setFocusedIndex(focusedIndex - 1);\n }\n };\n\n const keyToFnMap = {\n [ARROW_KEY_TYPES[keyType].next]: focusNextItem,\n [ARROW_KEY_TYPES[keyType].prev]: focusPrevItem,\n };\n\n const fn = keyToFnMap[event.key];\n if (fn) {\n event.preventDefault();\n fn();\n }\n },\n [focusedIndex, itemsSelector, itemsContainerRef, keyType],\n );\n\n return { focusedIndex, handleArrowsKeyDown, setFocusedIndex };\n};\n","import React, { ComponentPropsWithRef } from 'react';\nimport { MenuProps } from '.';\n\nexport type MenuContextType = {\n isOpen: boolean;\n menuId: string;\n focusMenuItem: (item: HTMLElement) => void;\n getTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n getMenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n _ref: React.Ref<HTMLDivElement>,\n ) => ComponentPropsWithRef<'div'>;\n getMenuItemProps: (\n _props: ComponentPropsWithRef<'button'>,\n ) => ComponentPropsWithRef<'button'>;\n propsToPropagateToSubmenus: Pick<\n MenuProps,\n 'closeOnBlur' | 'closeOnEsc' | 'closeOnSelect'\n >;\n};\n\nconst MenuContext = React.createContext<MenuContextType | undefined>(undefined);\n\nexport const useMenuContext = () => {\n const context = React.useContext(MenuContext);\n\n if (context === undefined) {\n throw new Error('useMenuContext must be used within a MenuContextProvider');\n }\n\n return context;\n};\n\nexport const MenuContextProvider = MenuContext.Provider;\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { useMenuContext } from '../MenuContext';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { Popover } from '@contentful/f36-popover';\nimport { cx } from 'emotion';\nimport { getMenuListStyles } from './MenuList.styles';\nimport { MenuListHeader } from './MenuListHeader';\nimport { MenuListFooter } from './MenuListFooter';\n\ninterface MenuListInternalProps extends CommonProps {\n children?: React.ReactNode;\n}\n\nfunction assertChild(child: any): child is { type: { displayName: string } } {\n return Boolean(child?.type?.displayName);\n}\n\nexport type MenuListProps = PropsWithHTMLElement<MenuListInternalProps, 'div'>;\n\nconst _MenuList = (\n props: ExpandProps<MenuListProps>,\n ref: React.Ref<HTMLDivElement>,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list',\n className,\n ...otherProps\n } = props;\n\n const { getMenuListProps } = useMenuContext();\n const submenuContext = useSubmenuContext();\n\n let header: React.ReactElement | null = null;\n let footer: React.ReactElement | null = null;\n const items: React.ReactElement[] = [];\n\n React.Children.forEach(children, (child) => {\n let appendChild = true;\n if (assertChild(child)) {\n if (child.type.displayName === MenuListHeader.displayName) {\n header = child as unknown as React.ReactElement;\n appendChild = false;\n } else if (child.type.displayName === MenuListFooter.displayName) {\n footer = child as unknown as React.ReactElement;\n appendChild = false;\n }\n }\n if (appendChild) {\n items.push(child as unknown as React.ReactElement);\n }\n });\n\n const styles = getMenuListStyles({\n hasStickyHeader: Boolean(header),\n hasStickyFooter: Boolean(footer),\n });\n\n const extendedOtherProps = submenuContext\n ? submenuContext.getSubmenuListProps(otherProps)\n : otherProps;\n\n return (\n <Popover.Content\n role=\"menu\"\n {...extendedOtherProps}\n {...getMenuListProps(extendedOtherProps, ref)}\n className={cx(styles.container, className)}\n testId={testId}\n >\n {header}\n {items}\n {footer}\n </Popover.Content>\n );\n};\n\nexport const MenuList = React.forwardRef(_MenuList);\n","import React, { ComponentPropsWithRef, ComponentPropsWithoutRef } from 'react';\n\nexport type SubmenuContextType = {\n isOpen: boolean;\n getSubmenuListProps: (\n _props: ComponentPropsWithRef<'div'>,\n ) => { 'data-parent-menu': string } & ComponentPropsWithoutRef<'div'>;\n getSubmenuTriggerProps: (\n _props: ComponentPropsWithRef<'button'>,\n _ref: React.Ref<HTMLButtonElement>,\n ) => ComponentPropsWithRef<'button'>;\n};\n\nconst SubmenuContext = React.createContext<SubmenuContextType | undefined>(\n undefined,\n);\n\nexport const useSubmenuContext = () => {\n const context = React.useContext(SubmenuContext);\n return context;\n};\n\nexport const SubmenuContextProvider = SubmenuContext.Provider;\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuHeaderStyles = () => {\n return css({\n position: 'sticky',\n top: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderBottom: `1px solid ${tokens.gray300}`,\n marginBottom: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuFooterStyles = () => {\n return css({\n position: 'sticky',\n bottom: 0,\n left: 0,\n backgroundColor: tokens.colorWhite,\n borderTop: `1px solid ${tokens.gray300}`,\n marginTop: tokens.spacing2Xs,\n padding: `${tokens.spacing2Xs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuListStyles = (props: {\n hasStickyFooter?: boolean;\n hasStickyHeader?: boolean;\n}) => ({\n container: css({\n // To get to our regular border radius for the inner menu items (6px),\n // we need to use 8px on the outer container\n borderRadius: '8px',\n overflowY: 'auto',\n position: 'relative',\n padding: 0,\n paddingTop: props.hasStickyHeader ? 0 : tokens.spacing2Xs,\n paddingBottom: props.hasStickyFooter ? 0 : tokens.spacing2Xs,\n }),\n});\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuHeaderStyles } from './MenuList.styles';\n\nexport type MenuListHeaderProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListHeader: React.FC<ExpandProps<MenuListHeaderProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-header',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuHeaderStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListHeader.displayName = 'MenuListHeader';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\n\nimport { getMenuFooterStyles } from './MenuList.styles';\n\nexport type MenuListFooterProps = PropsWithHTMLElement<CommonProps, 'div'>;\n\nexport const MenuListFooter: React.FC<ExpandProps<MenuListFooterProps>> = (\n props,\n) => {\n const {\n children,\n testId = 'cf-ui-menu-list-footer',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuFooterStyles();\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n};\n\nMenuListFooter.displayName = 'MenuListFooter';\n","import React, { useEffect, useRef } from 'react';\nimport { cx } from 'emotion';\nimport {\n mergeRefs,\n useId,\n type CommonProps,\n type PolymorphicComponent,\n type PolymorphicProps,\n type ExpandProps,\n} from '@contentful/f36-core';\n\nimport { useMenuContext } from '../MenuContext';\nimport { getMenuItemStyles } from './MenuItem.styles';\n\nconst MENU_ITEM_DEFAULT_TAG = 'button';\n\ninterface MenuItemInternalProps extends CommonProps {\n children?: React.ReactNode;\n as?: 'a' | 'button';\n\n /**\n * Marks item as active\n */\n isActive?: boolean;\n /**\n * Marks item as disabled\n */\n isDisabled?: boolean;\n /**\n * Sets focus on item\n */\n isInitiallyFocused?: boolean;\n /**\n * Expects any of the icon components. Renders the icon aligned to the start\n */\n icon?: React.ReactElement;\n}\n\nexport type MenuItemProps<\n E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG,\n> = PolymorphicProps<MenuItemInternalProps, E>;\n\nfunction _MenuItem<E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG>(\n props: MenuItemProps<E>,\n ref: React.Ref<any>,\n) {\n const {\n testId,\n className,\n as,\n isActive = false,\n isDisabled,\n isInitiallyFocused,\n icon,\n ...otherProps\n } = props;\n\n const id = useId(undefined, 'menu-item');\n const itemTestId = testId || `cf-ui-${id}`;\n const styles = getMenuItemStyles({ isActive, isDisabled });\n\n const { getMenuItemProps, focusMenuItem } = useMenuContext();\n\n const itemRef = useRef<HTMLElement>(null);\n useEffect(() => {\n if (isInitiallyFocused && itemRef.current) {\n focusMenuItem(itemRef.current);\n }\n }, [isInitiallyFocused, focusMenuItem]);\n\n const Element = (as ?? MENU_ITEM_DEFAULT_TAG) as React.ElementType;\n\n return (\n <Element\n role=\"menuitem\"\n {...otherProps}\n {...getMenuItemProps(otherProps)}\n disabled={isDisabled ?? props.disabled}\n className={cx(styles, className)}\n data-test-id={itemTestId}\n ref={mergeRefs(itemRef, ref)}\n tabIndex={-1}\n >\n {icon}\n {props.children}\n </Element>\n );\n}\n\n_MenuItem.displayName = 'MenuItem';\n\nexport const MenuItem: PolymorphicComponent<\n ExpandProps<MenuItemInternalProps>,\n typeof MENU_ITEM_DEFAULT_TAG\n> = React.forwardRef(_MenuItem);\n","import { css, cx } from 'emotion';\nimport { getMenuItemStyles as globalGetMenuItemStyles } from '@contentful/f36-core';\nimport type { MenuItemProps } from './MenuItem';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuItemStyles = ({\n isActive,\n isDisabled,\n}: {\n isActive: MenuItemProps['isActive'];\n isDisabled: MenuItemProps['isDisabled'];\n}) =>\n cx(\n globalGetMenuItemStyles({ isActive, isDisabled }),\n css({\n width: `calc(100% - 2 * ${tokens.spacing2Xs})`,\n margin: `0 ${tokens.spacing2Xs}`,\n gap: tokens.spacingXs,\n }),\n );\n","import React from 'react';\nimport { Popover } from '@contentful/f36-popover';\nimport { useMenuContext } from '../MenuContext';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nexport interface MenuTriggerProps {\n children: React.ReactNode;\n}\n\nexport const MenuTrigger = (props: ExpandProps<MenuTriggerProps>) => {\n const child = React.Children.only(props.children) as any;\n const { getTriggerProps } = useMenuContext();\n\n return (\n <Popover.Trigger>\n {React.cloneElement(child, {\n ...getTriggerProps(child.props, child.ref),\n ['aria-haspopup']: 'menu',\n })}\n </Popover.Trigger>\n );\n};\n","import React from 'react';\nimport type {\n CommonProps,\n PropsWithHTMLElement,\n ExpandProps,\n} from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getMenuDividerStyles } from './MenuDivider.styles';\n\nexport type MenuDividerProps = PropsWithHTMLElement<CommonProps, 'hr'>;\n\nexport const MenuDivider = (props: ExpandProps<MenuDividerProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-divider',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuDividerStyles();\n\n return (\n <hr\n aria-orientation=\"horizontal\"\n data-test-id={testId}\n className={cx(styles, className)}\n {...otherProps}\n />\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuDividerStyles = () =>\n css({\n border: 'none',\n width: '100%',\n height: '1px',\n backgroundColor: tokens.gray200,\n margin: `${tokens.spacing2Xs} 0`,\n });\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { Caption, type CaptionProps } from '@contentful/f36-typography';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nimport { getMenuSectionTitleStyles } from './MenuSectionTitle.styles';\n\nexport type MenuSectionTitleProps = CaptionProps;\n\nexport const MenuSectionTitle = (props: ExpandProps<MenuSectionTitleProps>) => {\n const {\n children,\n testId = 'cf-ui-menu-section-title',\n className,\n ...otherProps\n } = props;\n\n const styles = getMenuSectionTitleStyles();\n\n return (\n <Caption\n // Techincally, menus cannot contain headings according to ARIA.\n // We hide the heading from assistive technology, and only use it\n // as a label\n aria-hidden=\"true\"\n as=\"div\"\n testId={testId}\n className={cx(styles, className)}\n marginBottom=\"none\"\n {...otherProps}\n >\n {children}\n </Caption>\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuSectionTitleStyles = () =>\n css({\n color: tokens.gray500,\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingS} ${tokens.spacing2Xs}`,\n lineHeight: tokens.lineHeightM,\n });\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Menu, type MenuProps } from '../Menu';\nimport { useMenuContext } from '../MenuContext';\nimport {\n SubmenuContextProvider,\n type SubmenuContextType,\n} from '../SubmenuContext';\nimport { mergeRefs } from '@contentful/f36-core';\n\nconst SUBMENU_OFFSET: [number, number] = [-8, 2];\n\nexport type SubmenuProps = Omit<\n MenuProps,\n 'offset' | 'usePortal' | 'isOpen' | 'defaultIsOpen'\n>;\n\nexport const Submenu = (props: SubmenuProps) => {\n const {\n onClose,\n onOpen,\n placement = 'right-start',\n isAutoalignmentEnabled = false,\n ...otherProps\n } = props;\n\n const {\n isOpen: isParentMenuOpen,\n menuId,\n propsToPropagateToSubmenus,\n } = useMenuContext();\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n const mouseLeaveTimerRef = useRef(null);\n\n const [isOpen, setIsOpen] = useState(false);\n const handleOpen = useCallback(() => {\n setIsOpen(true);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onOpen?.();\n }, [onOpen]);\n const handleClose = useCallback(() => {\n setIsOpen(false);\n window.clearTimeout(mouseLeaveTimerRef.current);\n\n onClose?.();\n }, [onClose]);\n const closeAndFocusTrigger = useCallback(() => {\n handleClose();\n triggerRef.current?.focus({ preventScroll: true });\n }, [handleClose]);\n\n useEffect(() => {\n // close when parent menu closed\n if (isParentMenuOpen === false) {\n setIsOpen(false);\n }\n }, [isParentMenuOpen]);\n\n const contextValue: SubmenuContextType = useMemo(\n () => ({\n isOpen,\n getSubmenuListProps: (_props) => ({\n 'data-parent-menu': menuId,\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n closeAndFocusTrigger();\n\n _props.onMouseLeave?.(event);\n },\n }),\n getSubmenuTriggerProps: (_props, _ref) => ({\n ref: mergeRefs(triggerRef, _ref),\n onKeyDown: (event) => {\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n handleOpen();\n }\n\n _props.onKeyDown?.(event);\n },\n onMouseOver: (event) => {\n handleOpen();\n\n _props.onMouseOver?.(event);\n },\n onMouseLeave: (event) => {\n mouseLeaveTimerRef.current = window.setTimeout(\n closeAndFocusTrigger,\n 300,\n );\n\n _props.onMouseLeave?.(event);\n },\n }),\n }),\n [isOpen, menuId, handleOpen, closeAndFocusTrigger],\n );\n\n return (\n <SubmenuContextProvider value={contextValue}>\n <Menu\n {...propsToPropagateToSubmenus}\n {...otherProps}\n isOpen={isOpen}\n onClose={handleClose}\n onOpen={handleOpen}\n placement={placement}\n isAutoalignmentEnabled={isAutoalignmentEnabled}\n offset={SUBMENU_OFFSET}\n />\n </SubmenuContextProvider>\n );\n};\n","import React from 'react';\nimport { MenuTrigger } from '../MenuTrigger/MenuTrigger';\nimport { MenuItem, MenuItemProps } from '../MenuItem/MenuItem';\nimport { useSubmenuContext } from '../SubmenuContext';\nimport { ChevronRightIcon } from '@contentful/f36-icons';\nimport type { ExpandProps } from '@contentful/f36-core';\nimport { cx } from 'emotion';\nimport { getSubmenuTriggerStyles } from './SubmenuTrigger.styles';\n\nexport type SubmenuTriggerProps = Omit<\n MenuItemProps<'button'>,\n 'isInitiallyFocused' | 'as'\n>;\n\nconst _SubmenuTrigger = (\n props: ExpandProps<SubmenuTriggerProps>,\n ref: React.Ref<HTMLButtonElement>,\n) => {\n const { className, children } = props;\n const { getSubmenuTriggerProps, isOpen } = useSubmenuContext();\n\n const styles = getSubmenuTriggerStyles();\n\n return (\n <MenuTrigger>\n <MenuItem\n {...props}\n {...getSubmenuTriggerProps(props, ref)}\n className={cx(styles.root({ isActive: isOpen }), className)}\n >\n <span className={styles.content}>{children}</span>\n <ChevronRightIcon className={styles.icon} />\n </MenuItem>\n </MenuTrigger>\n );\n};\n\nexport const SubmenuTrigger = React.forwardRef(_SubmenuTrigger);\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getSubmenuTriggerStyles = () => {\n return {\n root: ({ isActive }) =>\n css({\n display: 'flex',\n alignItems: 'center',\n paddingRight: tokens.spacingXs,\n ...(isActive\n ? {\n backgroundColor: tokens.gray100,\n }\n : {}),\n }),\n content: css({\n marginRight: tokens.spacingM,\n }),\n icon: css({\n marginLeft: 'auto',\n fill: 'currentColor',\n }),\n };\n};\n","import { Menu as OriginalMenu } from './Menu';\nimport { MenuList } from './MenuList/MenuList';\nimport { MenuListHeader } from './MenuList/MenuListHeader';\nimport { MenuListFooter } from './MenuList/MenuListFooter';\nimport { MenuItem } from './MenuItem/MenuItem';\nimport { MenuTrigger } from './MenuTrigger/MenuTrigger';\nimport { MenuDivider } from './MenuDivider/MenuDivider';\nimport { MenuSectionTitle } from './MenuSectionTitle/MenuSectionTitle';\nimport { Submenu } from './Submenu/Submenu';\nimport { SubmenuTrigger } from './SubmenuTrigger/SubmenuTrigger';\n\ntype CompoundMenu = typeof OriginalMenu & {\n List: typeof MenuList;\n ListHeader: typeof MenuListHeader;\n ListFooter: typeof MenuListFooter;\n Item: typeof MenuItem;\n Trigger: typeof MenuTrigger;\n Divider: typeof MenuDivider;\n SectionTitle: typeof MenuSectionTitle;\n Submenu: typeof Submenu;\n SubmenuTrigger: typeof SubmenuTrigger;\n};\n\nexport const Menu = OriginalMenu as CompoundMenu;\nMenu.List = MenuList;\nMenu.ListHeader = MenuListHeader;\nMenu.ListFooter = MenuListFooter;\nMenu.Item = MenuItem;\nMenu.Trigger = MenuTrigger;\nMenu.Divider = MenuDivider;\nMenu.SectionTitle = MenuSectionTitle;\nMenu.Submenu = Submenu;\nMenu.SubmenuTrigger = SubmenuTrigger;\n"]}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/f36-menu",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.79.0",
|
|
4
4
|
"description": "Forma 36: Menu component",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsup"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@contentful/f36-core": "^4.
|
|
9
|
+
"@contentful/f36-core": "^4.79.0",
|
|
10
10
|
"@contentful/f36-icons": "^4.29.0",
|
|
11
|
-
"@contentful/f36-popover": "^4.
|
|
11
|
+
"@contentful/f36-popover": "^4.79.0",
|
|
12
12
|
"@contentful/f36-tokens": "^4.2.0",
|
|
13
|
-
"@contentful/f36-typography": "^4.
|
|
13
|
+
"@contentful/f36-typography": "^4.79.0",
|
|
14
14
|
"@contentful/f36-utils": "^4.24.3",
|
|
15
15
|
"emotion": "^10.0.17"
|
|
16
16
|
},
|