@contentful/f36-menu 5.0.0 → 5.1.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/README.mdx +10 -2
- package/dist/esm/index.js +8 -7
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +121 -0
- package/dist/index.d.ts +15 -3
- package/dist/index.js +15 -16
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
package/README.mdx
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'Menu'
|
|
3
|
+
type: 'component'
|
|
4
|
+
status: 'stable'
|
|
3
5
|
slug: /components/menu/
|
|
4
6
|
github: 'https://github.com/contentful/forma-36/tree/main/packages/components/menu'
|
|
5
7
|
typescript: ./src/Menu.tsx,./src/MenuItem/MenuItem.tsx,./src/MenuList/MenuList.tsx
|
|
@@ -73,9 +75,15 @@ But if you have to provide your own toggle menu logic on the trigger component,
|
|
|
73
75
|
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
### With disabled items
|
|
78
|
+
### With active and disabled items
|
|
77
79
|
|
|
78
|
-
```jsx file=examples/
|
|
80
|
+
```jsx file=examples/MenuWithActiveAndDisabledItems.tsx
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### With icons on menu items
|
|
85
|
+
|
|
86
|
+
```jsx file=examples/MenuWithIcons.tsx
|
|
79
87
|
|
|
80
88
|
```
|
|
81
89
|
|
package/dist/esm/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useId, mergeRefs, useControllableState } from '@contentful/f36-core';
|
|
1
|
+
import W, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
|
|
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
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import v from '@contentful/f36-tokens';
|
|
6
|
+
import { Caption } from '@contentful/f36-typography';
|
|
7
|
+
import { CaretRightIcon } from '@contentful/f36-icons';
|
|
8
8
|
|
|
9
|
-
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},C=(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),h=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:h},W.createElement(Popover,C(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}),Ce=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=Ce({hasStickyHeader:!!b,hasStickyFooter:!!c}),p=l?l.getSubmenuListProps(a):a;return W.createElement(Popover.Content,C(i(i({role:"menu"},p),s(p,t)),{className:cx(T.container,u),testId:n}),b,S,c)},Y=W.forwardRef(_e);var he=({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=he({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,C(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,C(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 h;M.key==="ArrowRight"&&(M.preventDefault(),d()),(h=m.onKeyDown)==null||h.call(m,M);},onMouseOver:M=>{var h;d(),(h=m.onMouseOver)==null||h.call(m,M);},onMouseLeave:M=>{var h;S.current=window.setTimeout(g,300),(h=m.onMouseLeave)==null||h.call(m,M);}})}),[T,l,d,g]);return W.createElement(Te,{value:N},W.createElement(U,C(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 ht=(e,t)=>{let{className:o,children:n}=e,{getSubmenuTriggerProps:u,isOpen:a}=K(),s=Ne();return W.createElement(F,null,W.createElement(D,C(i(i({},e),u(e,t)),{className:cx(s.root({isActive:a}),o)}),W.createElement("span",{className:s.content},n),W.createElement(CaretRightIcon,{className:s.icon})))},oe=W.forwardRef(ht);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
|
+
//# sourceMappingURL=out.js.map
|
|
12
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","contextValue","_props","_ref","_b","_c","_d","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","getMenuItemStyles","MENU_ITEM_DEFAULT_TAG","_MenuItem","as","isInitiallyFocused","id","itemTestId","getMenuItemProps","itemRef","Element","MenuItem","MenuTrigger","getTriggerProps","getMenuDividerStyles","MenuDivider","SectionHeading","getMenuSectionTitleStyles","MenuSectionTitle","SUBMENU_OFFSET","Submenu","onClose","isParentMenuOpen","propsToPropagateToSubmenus","mouseLeaveTimerRef","setIsOpen","ChevronRightIcon","getSubmenuTriggerStyles","isActive","_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(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] as HTMLElement).focus({\n preventScroll: false,\n });\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 const contextValue: MenuContextType = useMemo(\n () => ({\n isOpen,\n menuId,\n focusMenuItem,\n getTriggerProps: (_props = {}, _ref = null) => ({\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 relatedTarget = event.relatedTarget as Node;\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 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 padding: `${tokens.spacingXs} 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 padding: `${tokens.spacingXs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuListStyles = (props: {\n hasStickyFooter?: boolean;\n hasStickyHeader?: boolean;\n}) => ({\n container: css({\n overflowY: 'auto',\n position: 'relative',\n padding: 0,\n paddingTop: props.hasStickyHeader ? 0 : tokens.spacingXs,\n paddingBottom: props.hasStickyFooter ? 0 : tokens.spacingXs,\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 * Sets focus on item\n */\n isInitiallyFocused?: boolean;\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 { testId, className, as, isInitiallyFocused, ...otherProps } = props;\n\n const id = useId(undefined, 'menu-item');\n const itemTestId = testId || `cf-ui-${id}`;\n const styles = getMenuItemStyles();\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 className={cx(styles.root, className)}\n data-test-id={itemTestId}\n ref={mergeRefs(itemRef, ref)}\n tabIndex={-1}\n >\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 } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuItemStyles = () => {\n return {\n root: css({\n display: 'block',\n width: '100%',\n background: 'none',\n border: 0,\n margin: 0,\n outline: 'none',\n fontSize: tokens.fontSizeM,\n lineHeight: tokens.lineHeightM,\n fontWeight: tokens.fontWeightNormal,\n position: 'relative',\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n wordBreak: 'break-word',\n whiteSpace: 'break-spaces',\n cursor: 'pointer',\n hyphens: 'auto',\n minWidth: '150px',\n textDecoration: 'none',\n color: tokens.gray800,\n\n '&:hover': {\n backgroundColor: tokens.gray100,\n },\n '&:focus': {\n boxShadow: `inset ${tokens.glowPrimary}`,\n // just to make boxShadow with rounded corners\n borderRadius: tokens.borderRadiusMedium,\n },\n '&:focus:not(:focus-visible)': {\n boxShadow: 'unset',\n borderRadius: 'unset',\n },\n '&:focus-visible': {\n boxShadow: `inset ${tokens.glowPrimary}`,\n borderRadius: tokens.borderRadiusMedium,\n },\n '&:active': {\n backgroundColor: tokens.gray200,\n },\n '&:disabled': {\n opacity: 0.5,\n cursor: 'auto',\n },\n }),\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 background: tokens.gray300,\n margin: `${tokens.spacingXs} 0`,\n });\n","import React from 'react';\nimport { cx } from 'emotion';\nimport {\n SectionHeading,\n type SectionHeadingProps,\n} from '@contentful/f36-typography';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nimport { getMenuSectionTitleStyles } from './MenuSectionTitle.styles';\n\nexport type MenuSectionTitleProps = SectionHeadingProps;\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 <SectionHeading\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 testId={testId}\n className={cx(styles, className)}\n marginBottom=\"none\"\n {...otherProps}\n >\n {children}\n </SectionHeading>\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuSectionTitleStyles = () =>\n css({\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n lineHeight: tokens.lineHeightM,\n\n 'hr + &': {\n marginTop: '-8px',\n },\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","CaretRightIcon","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 { CaretRightIcon } 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 <CaretRightIcon 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
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { PopoverProps } from '@contentful/f36-popover';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { PropsWithHTMLElement, CommonProps, ExpandProps, PolymorphicProps, PolymorphicComponent } from '@contentful/f36-core';
|
|
4
|
+
import { CaptionProps } from '@contentful/f36-typography';
|
|
5
|
+
|
|
6
|
+
interface MenuProps extends Omit<PopoverProps, 'autoFocus' | 'id' | 'closeOnBlur'> {
|
|
7
|
+
/**
|
|
8
|
+
* By default, the Menu is uncontrolled (manage it's expanded state by itself)
|
|
9
|
+
* But you can make it controlled by providing boolean (true/false)
|
|
10
|
+
*/
|
|
11
|
+
isOpen?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* If `true`, the Menu will be initially opened.
|
|
14
|
+
*/
|
|
15
|
+
defaultIsOpen?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Callback fired when the Menu opens
|
|
18
|
+
*/
|
|
19
|
+
onOpen?: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Callback fired when the Menu closes
|
|
22
|
+
*/
|
|
23
|
+
onClose?: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* If `true`, the Menu will close when a menu item is
|
|
26
|
+
* clicked
|
|
27
|
+
*
|
|
28
|
+
* Note: This prop will be propagated to all submenus,
|
|
29
|
+
* unless you will override it with props on submenu itself
|
|
30
|
+
*
|
|
31
|
+
* @default true
|
|
32
|
+
*/
|
|
33
|
+
closeOnSelect?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* If true, the menu will close when you blur out it by clicking outside
|
|
36
|
+
*
|
|
37
|
+
* Note: This prop will be propagated to all submenus,
|
|
38
|
+
* unless you will override it with props on submenu itself
|
|
39
|
+
*
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
closeOnBlur?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* If true, the menu will close when you hit the Esc key
|
|
45
|
+
*
|
|
46
|
+
* Note: This prop will be propagated to all submenus,
|
|
47
|
+
* unless you will override it with props on submenu itself
|
|
48
|
+
*
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
closeOnEsc?: boolean;
|
|
52
|
+
}
|
|
53
|
+
declare function Menu$1(props: MenuProps): JSX.Element;
|
|
54
|
+
|
|
55
|
+
interface MenuListInternalProps extends CommonProps {
|
|
56
|
+
children?: React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
declare type MenuListProps = PropsWithHTMLElement<MenuListInternalProps, 'div'>;
|
|
59
|
+
declare const MenuList: React.ForwardRefExoticComponent<Omit<Omit<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>>, never>, keyof MenuListInternalProps> & MenuListInternalProps & React.RefAttributes<HTMLDivElement>>;
|
|
60
|
+
|
|
61
|
+
declare type MenuListHeaderProps = PropsWithHTMLElement<CommonProps, 'div'>;
|
|
62
|
+
declare const MenuListHeader: React.FC<ExpandProps<MenuListHeaderProps>>;
|
|
63
|
+
|
|
64
|
+
declare type MenuListFooterProps = PropsWithHTMLElement<CommonProps, 'div'>;
|
|
65
|
+
declare const MenuListFooter: React.FC<ExpandProps<MenuListFooterProps>>;
|
|
66
|
+
|
|
67
|
+
declare const MENU_ITEM_DEFAULT_TAG = "button";
|
|
68
|
+
interface MenuItemInternalProps extends CommonProps {
|
|
69
|
+
children?: React.ReactNode;
|
|
70
|
+
as?: 'a' | 'button';
|
|
71
|
+
/**
|
|
72
|
+
* Marks item as active
|
|
73
|
+
*/
|
|
74
|
+
isActive?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Marks item as disabled
|
|
77
|
+
*/
|
|
78
|
+
isDisabled?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Sets focus on item
|
|
81
|
+
*/
|
|
82
|
+
isInitiallyFocused?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Expects any of the icon components. Renders the icon aligned to the start
|
|
85
|
+
*/
|
|
86
|
+
icon?: React.ReactElement;
|
|
87
|
+
}
|
|
88
|
+
declare type MenuItemProps<E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG> = PolymorphicProps<MenuItemInternalProps, E>;
|
|
89
|
+
declare const MenuItem: PolymorphicComponent<ExpandProps<MenuItemInternalProps>, typeof MENU_ITEM_DEFAULT_TAG>;
|
|
90
|
+
|
|
91
|
+
interface MenuTriggerProps {
|
|
92
|
+
children: React.ReactNode;
|
|
93
|
+
}
|
|
94
|
+
declare const MenuTrigger: (props: ExpandProps<MenuTriggerProps>) => JSX.Element;
|
|
95
|
+
|
|
96
|
+
declare type MenuDividerProps = PropsWithHTMLElement<CommonProps, 'hr'>;
|
|
97
|
+
declare const MenuDivider: (props: ExpandProps<MenuDividerProps>) => JSX.Element;
|
|
98
|
+
|
|
99
|
+
declare type MenuSectionTitleProps = CaptionProps;
|
|
100
|
+
declare const MenuSectionTitle: (props: ExpandProps<MenuSectionTitleProps>) => JSX.Element;
|
|
101
|
+
|
|
102
|
+
declare type SubmenuProps = Omit<MenuProps, 'offset' | 'usePortal' | 'isOpen' | 'defaultIsOpen'>;
|
|
103
|
+
declare const Submenu: (props: SubmenuProps) => JSX.Element;
|
|
104
|
+
|
|
105
|
+
declare type SubmenuTriggerProps = Omit<MenuItemProps<'button'>, 'isInitiallyFocused' | 'as'>;
|
|
106
|
+
declare const SubmenuTrigger: React.ForwardRefExoticComponent<SubmenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
107
|
+
|
|
108
|
+
declare type CompoundMenu = typeof Menu$1 & {
|
|
109
|
+
List: typeof MenuList;
|
|
110
|
+
ListHeader: typeof MenuListHeader;
|
|
111
|
+
ListFooter: typeof MenuListFooter;
|
|
112
|
+
Item: typeof MenuItem;
|
|
113
|
+
Trigger: typeof MenuTrigger;
|
|
114
|
+
Divider: typeof MenuDivider;
|
|
115
|
+
SectionTitle: typeof MenuSectionTitle;
|
|
116
|
+
Submenu: typeof Submenu;
|
|
117
|
+
SubmenuTrigger: typeof SubmenuTrigger;
|
|
118
|
+
};
|
|
119
|
+
declare const Menu: CompoundMenu;
|
|
120
|
+
|
|
121
|
+
export { Menu, MenuDivider, MenuDividerProps, MenuItem, MenuItemProps, MenuList, MenuListProps, MenuProps, MenuSectionTitle, MenuSectionTitleProps, MenuTrigger, MenuTriggerProps, Submenu, SubmenuProps, SubmenuTrigger, SubmenuTriggerProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PopoverProps } from '@contentful/f36-popover';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { PropsWithHTMLElement, CommonProps, ExpandProps, PolymorphicProps, PolymorphicComponent } from '@contentful/f36-core';
|
|
4
|
-
import {
|
|
4
|
+
import { CaptionProps } from '@contentful/f36-typography';
|
|
5
5
|
|
|
6
6
|
interface MenuProps extends Omit<PopoverProps, 'autoFocus' | 'id' | 'closeOnBlur'> {
|
|
7
7
|
/**
|
|
@@ -68,10 +68,22 @@ declare const MENU_ITEM_DEFAULT_TAG = "button";
|
|
|
68
68
|
interface MenuItemInternalProps extends CommonProps {
|
|
69
69
|
children?: React.ReactNode;
|
|
70
70
|
as?: 'a' | 'button';
|
|
71
|
+
/**
|
|
72
|
+
* Marks item as active
|
|
73
|
+
*/
|
|
74
|
+
isActive?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Marks item as disabled
|
|
77
|
+
*/
|
|
78
|
+
isDisabled?: boolean;
|
|
71
79
|
/**
|
|
72
80
|
* Sets focus on item
|
|
73
81
|
*/
|
|
74
82
|
isInitiallyFocused?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Expects any of the icon components. Renders the icon aligned to the start
|
|
85
|
+
*/
|
|
86
|
+
icon?: React.ReactElement;
|
|
75
87
|
}
|
|
76
88
|
declare type MenuItemProps<E extends React.ElementType = typeof MENU_ITEM_DEFAULT_TAG> = PolymorphicProps<MenuItemInternalProps, E>;
|
|
77
89
|
declare const MenuItem: PolymorphicComponent<ExpandProps<MenuItemInternalProps>, typeof MENU_ITEM_DEFAULT_TAG>;
|
|
@@ -84,10 +96,10 @@ declare const MenuTrigger: (props: ExpandProps<MenuTriggerProps>) => JSX.Element
|
|
|
84
96
|
declare type MenuDividerProps = PropsWithHTMLElement<CommonProps, 'hr'>;
|
|
85
97
|
declare const MenuDivider: (props: ExpandProps<MenuDividerProps>) => JSX.Element;
|
|
86
98
|
|
|
87
|
-
declare type MenuSectionTitleProps =
|
|
99
|
+
declare type MenuSectionTitleProps = CaptionProps;
|
|
88
100
|
declare const MenuSectionTitle: (props: ExpandProps<MenuSectionTitleProps>) => JSX.Element;
|
|
89
101
|
|
|
90
|
-
declare type SubmenuProps = Omit<MenuProps, '
|
|
102
|
+
declare type SubmenuProps = Omit<MenuProps, 'offset' | 'usePortal' | 'isOpen' | 'defaultIsOpen'>;
|
|
91
103
|
declare const Submenu: (props: SubmenuProps) => JSX.Element;
|
|
92
104
|
|
|
93
105
|
declare type SubmenuTriggerProps = Omit<MenuItemProps<'button'>, 'isInitiallyFocused' | 'as'>;
|
package/dist/index.js
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var F = require('react');
|
|
3
|
+
var W = require('react');
|
|
6
4
|
var f36Core = require('@contentful/f36-core');
|
|
7
5
|
var f36Popover = require('@contentful/f36-popover');
|
|
8
6
|
var emotion = require('emotion');
|
|
9
|
-
var
|
|
7
|
+
var v = require('@contentful/f36-tokens');
|
|
10
8
|
var f36Typography = require('@contentful/f36-typography');
|
|
11
9
|
var f36Icons = require('@contentful/f36-icons');
|
|
12
10
|
|
|
13
|
-
function
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
12
|
|
|
15
|
-
var
|
|
16
|
-
var
|
|
13
|
+
var W__default = /*#__PURE__*/_interopDefault(W);
|
|
14
|
+
var v__default = /*#__PURE__*/_interopDefault(v);
|
|
17
15
|
|
|
18
|
-
var ke=Object.defineProperty,Fe=Object.defineProperties;var Ae=Object.getOwnPropertyDescriptors;var D=Object.getOwnPropertySymbols;var ie=Object.prototype.hasOwnProperty,ue=Object.prototype.propertyIsEnumerable;var se=(e,t,o)=>t in e?ke(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,u=(e,t)=>{for(var o in t||(t={}))ie.call(t,o)&&se(e,o,t[o]);if(D)for(var o of D(t))ue.call(t,o)&&se(e,o,t[o]);return e},S=(e,t)=>Fe(e,Ae(t));var P=(e,t)=>{var o={};for(var n in e)ie.call(e,n)&&t.indexOf(n)<0&&(o[n]=e[n]);if(e!=null&&D)for(var n of D(e))t.indexOf(n)<0&&ue.call(e,n)&&(o[n]=e[n]);return o};var me={vertical:{prev:"ArrowUp",next:"ArrowDown"},horizontal:{prev:"ArrowLeft",next:"ArrowRight"}},ae=({itemsContainerRef:e,itemsSelector:t,keyType:o="vertical"})=>{let[n,i]=F.useState(0),m=F.useCallback(s=>{let f=e.current;if(!f)return;let y=f.querySelectorAll(t);if(y.length===0)return;let c=y.length-1,T=()=>i(0),d=()=>i(c),p=()=>{n===c?T():i(n+1);},x=()=>{n===0?d():i(n-1);},h={[me[o].next]:p,[me[o].prev]:x}[s.key];h&&(s.preventDefault(),h());},[n,t,e,o]);return {focusedIndex:n,handleArrowsKeyDown:m,setFocusedIndex:i}};var ce=F__default["default"].createContext(void 0),R=()=>{let e=F__default["default"].useContext(ce);if(e===void 0)throw new Error("useMenuContext must be used within a MenuContextProvider");return e},le=ce.Provider;var U='[role="menuitem"]:not(:disabled)';function W(e){let ee=e,{closeOnSelect:t=!0,closeOnBlur:o=!0,closeOnEsc:n=!0,children:i,onOpen:m}=ee,s=P(ee,["closeOnSelect","closeOnBlur","closeOnEsc","children","onOpen"]),{isOpen:f,handleOpen:y,handleClose:c,isControlled:T}=f36Core.useControllableState({isOpen:e.isOpen,defaultIsOpen:e.defaultIsOpen,onOpen:m,onClose:e.onClose}),d=F.useRef(null),p=F.useRef(null),x=f36Core.useId(null,"menu"),{focusedIndex:g,handleArrowsKeyDown:h,setFocusedIndex:a}=ae({itemsContainerRef:p,itemsSelector:U});F.useEffect(()=>{if(f&&p.current){let r=p.current.querySelectorAll(U);r.length>0&&g<r.length&&setTimeout(()=>{r[g].focus({preventScroll:!1});},0);}},[f,g]);let L=F.useCallback(r=>{let b=[...p.current.querySelectorAll(U)].findIndex(M=>r===M);b!==-1&&a(b);},[a]),l=F.useCallback(()=>{var r;c(),(r=d.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}h(r);},[l,h]),we=F.useMemo(()=>({isOpen:f,menuId:x,focusMenuItem:L,getTriggerProps:(r={},O=null)=>({onClick:b=>{var A;T&&!m||(f?c():y()),(A=r.onClick)==null||A.call(r,b);},ref:f36Core.mergeRefs(d,O)}),getMenuListProps:(r={},O=null)=>({ref:f36Core.mergeRefs(p,O),onKeyDown:b=>{var M;E(b),(M=r.onKeyDown)==null||M.call(r,b);},onBlur:b=>{var te,oe,ne,re;if((te=r.onBlur)==null||te.call(r,b),!o)return;let M=b.relatedTarget,A=p.current===M||((oe=p.current)==null?void 0:oe.contains(M)),He=d.current===M||((ne=d.current)==null?void 0:ne.contains(M)),Ne=((re=M==null?void 0:M.parentElement)==null?void 0:re.dataset.parentMenu)===x;if(A||He||Ne){b.stopPropagation();return}c();}}),getMenuItemProps:(r={})=>({onClick:O=>{var M;(M=r.onClick)==null||M.call(r,O);let b=Boolean(O.target.getAttribute("aria-haspopup"));t&&!b&&l();}}),propsToPropagateToSubmenus:{closeOnSelect:t,closeOnBlur:o,closeOnEsc:n}}),[x,f,E,t,c,y,L,o,n,l,T,m]);return F__default["default"].createElement(le,{value:we},F__default["default"].createElement(f36Popover.Popover,S(u({},s),{isOpen:f,onClose:c,id:x,closeOnEsc:n,autoFocus:!1,closeOnBlur:!1}),i))}var Pe=F__default["default"].createContext(void 0),B=()=>F__default["default"].useContext(Pe),ye=Pe.Provider;var xe=()=>emotion.css({position:"sticky",top:0,left:0,backgroundColor:C__default["default"].colorWhite,borderBottom:`1px solid ${C__default["default"].gray300}`,padding:`${C__default["default"].spacingXs} 0`,zIndex:1001}),Te=()=>emotion.css({position:"sticky",bottom:0,left:0,backgroundColor:C__default["default"].colorWhite,borderTop:`1px solid ${C__default["default"].gray300}`,padding:`${C__default["default"].spacingXs} 0`,zIndex:1001}),be=e=>({container:emotion.css({overflowY:"auto",position:"relative",padding:0,paddingTop:e.hasStickyHeader?0:C__default["default"].spacingXs,paddingBottom:e.hasStickyFooter?0:C__default["default"].spacingXs})});var w=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-header",className:n}=s,i=P(s,["children","testId","className"]),m=xe();return F__default["default"].createElement("div",u({"data-test-id":o,className:emotion.cx(m,n)},i),t)};w.displayName="MenuListHeader";var H=e=>{let s=e,{children:t,testId:o="cf-ui-menu-list-footer",className:n}=s,i=P(s,["children","testId","className"]),m=Te();return F__default["default"].createElement("div",u({"data-test-id":o,className:emotion.cx(m,n)},i),t)};H.displayName="MenuListFooter";function Je(e){var t;return Boolean((t=e==null?void 0:e.type)==null?void 0:t.displayName)}var Qe=(e,t)=>{let x=e,{children:o,testId:n="cf-ui-menu-list",className:i}=x,m=P(x,["children","testId","className"]),{getMenuListProps:s}=R(),f=B(),y=null,c=null,T=[];F__default["default"].Children.forEach(o,g=>{let h=!0;Je(g)&&(g.type.displayName===w.displayName?(y=g,h=!1):g.type.displayName===H.displayName&&(c=g,h=!1)),h&&T.push(g);});let d=be({hasStickyHeader:Boolean(y),hasStickyFooter:Boolean(c)}),p=f?f.getSubmenuListProps(m):m;return F__default["default"].createElement(f36Popover.Popover.Content,S(u(u({role:"menu"},p),s(p,t)),{className:emotion.cx(d.container,i),testId:n}),y,T,c)},z=F__default["default"].forwardRef(Qe);var he=()=>({root:emotion.css({display:"block",width:"100%",background:"none",border:0,margin:0,outline:"none",fontSize:C__default["default"].fontSizeM,lineHeight:C__default["default"].lineHeightM,fontWeight:C__default["default"].fontWeightNormal,position:"relative",textAlign:"left",padding:`${C__default["default"].spacingXs} ${C__default["default"].spacingM}`,wordBreak:"break-word",whiteSpace:"break-spaces",cursor:"pointer",hyphens:"auto",minWidth:"150px",textDecoration:"none",color:C__default["default"].gray800,"&:hover":{backgroundColor:C__default["default"].gray100},"&:focus":{boxShadow:`inset ${C__default["default"].glowPrimary}`,borderRadius:C__default["default"].borderRadiusMedium},"&:focus:not(:focus-visible)":{boxShadow:"unset",borderRadius:"unset"},"&:focus-visible":{boxShadow:`inset ${C__default["default"].glowPrimary}`,borderRadius:C__default["default"].borderRadiusMedium},"&:active":{backgroundColor:C__default["default"].gray200},"&:disabled":{opacity:.5,cursor:"auto"}})});var rt="button";function Ce(e,t){let g=e,{testId:o,className:n,as:i,isInitiallyFocused:m}=g,s=P(g,["testId","className","as","isInitiallyFocused"]),f=f36Core.useId(void 0,"menu-item"),y=o||`cf-ui-${f}`,c=he(),{getMenuItemProps:T,focusMenuItem:d}=R(),p=F.useRef(null);F.useEffect(()=>{m&&p.current&&d(p.current);},[m,d]);let x=i!=null?i:rt;return F__default["default"].createElement(x,S(u(u({role:"menuitem"},s),T(s)),{className:emotion.cx(c.root,n),"data-test-id":y,ref:f36Core.mergeRefs(p,t),tabIndex:-1}),e.children)}Ce.displayName="MenuItem";var N=F__default["default"].forwardRef(Ce);var k=e=>{let t=F__default["default"].Children.only(e.children),{getTriggerProps:o}=R();return F__default["default"].createElement(f36Popover.Popover.Trigger,null,F__default["default"].cloneElement(t,S(u({},o(t.props,t.ref)),{["aria-haspopup"]:"menu"})))};var Ie=()=>emotion.css({border:"none",width:"100%",height:"1px",background:C__default["default"].gray300,margin:`${C__default["default"].spacingXs} 0`});var q=e=>{let s=e,{children:t,testId:o="cf-ui-menu-divider",className:n}=s,i=P(s,["children","testId","className"]),m=Ie();return F__default["default"].createElement("hr",u({"aria-orientation":"horizontal","data-test-id":o,className:emotion.cx(m,n)},i))};var Le=()=>emotion.css({textAlign:"left",padding:`${C__default["default"].spacingXs} ${C__default["default"].spacingM}`,lineHeight:C__default["default"].lineHeightM,"hr + &":{marginTop:"-8px"}});var j=e=>{let s=e,{children:t,testId:o="cf-ui-menu-section-title",className:n}=s,i=P(s,["children","testId","className"]),m=Le();return F__default["default"].createElement(f36Typography.SectionHeading,u({"aria-hidden":"true",testId:o,className:emotion.cx(m,n),marginBottom:"none"},i),t)};var Pt=[-8,2],J=e=>{let h=e,{onClose:t,onOpen:o}=h,n=P(h,["onClose","onOpen"]),{isOpen:i,menuId:m,propsToPropagateToSubmenus:s}=R(),f=F.useRef(null),y=F.useRef(null),[c,T]=F.useState(!1),d=F.useCallback(()=>{T(!0),window.clearTimeout(y.current),o==null||o();},[o]),p=F.useCallback(()=>{T(!1),window.clearTimeout(y.current),t==null||t();},[t]),x=F.useCallback(()=>{var a;p(),(a=f.current)==null||a.focus({preventScroll:!0});},[p]);F.useEffect(()=>{i===!1&&T(!1);},[i]);let g=F.useMemo(()=>({isOpen:c,getSubmenuListProps:a=>({"data-parent-menu":m,onMouseOver:L=>{var l;d(),(l=a.onMouseOver)==null||l.call(a,L);},onMouseLeave:L=>{var l;x(),(l=a.onMouseLeave)==null||l.call(a,L);}}),getSubmenuTriggerProps:(a,L)=>({ref:f36Core.mergeRefs(f,L),onKeyDown:l=>{var E;l.key==="ArrowRight"&&(l.preventDefault(),d()),(E=a.onKeyDown)==null||E.call(a,l);},onMouseOver:l=>{var E;d(),(E=a.onMouseOver)==null||E.call(a,l);},onMouseLeave:l=>{var E;y.current=window.setTimeout(x,300),(E=a.onMouseLeave)==null||E.call(a,l);}})}),[c,m,d,x]);return F__default["default"].createElement(ye,{value:g},F__default["default"].createElement(W,S(u(u({},s),n),{isOpen:c,onClose:p,onOpen:d,placement:"right-start",offset:Pt,isAutoalignmentEnabled:!1})))};var Oe=()=>({root:({isActive:e})=>emotion.css(u({display:"flex",alignItems:"center",paddingRight:C__default["default"].spacingXs},e?{backgroundColor:C__default["default"].gray100}:{})),content:emotion.css({marginRight:C__default["default"].spacingM}),icon:emotion.css({marginLeft:"auto",fill:"currentColor"})});var Tt=(e,t)=>{let{className:o,children:n}=e,{getSubmenuTriggerProps:i,isOpen:m}=B(),s=Oe();return F__default["default"].createElement(k,null,F__default["default"].createElement(N,S(u(u({},e),i(e,t)),{className:emotion.cx(s.root({isActive:m}),o)}),F__default["default"].createElement("span",{className:s.content},n),F__default["default"].createElement(f36Icons.ChevronRightIcon,{className:s.icon})))},_=F__default["default"].forwardRef(Tt);var I=W;I.List=z;I.ListHeader=w;I.ListFooter=H;I.Item=N;I.Trigger=k;I.Divider=q;I.SectionTitle=j;I.Submenu=J;I.SubmenuTrigger=_;
|
|
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},C=(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),h=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:h},W__default.default.createElement(f36Popover.Popover,C(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}),Ce=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=Ce({hasStickyHeader:!!b,hasStickyFooter:!!c}),p=l?l.getSubmenuListProps(a):a;return W__default.default.createElement(f36Popover.Popover.Content,C(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 he=({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=he({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,C(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,C(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 h;M.key==="ArrowRight"&&(M.preventDefault(),d()),(h=m.onKeyDown)==null||h.call(m,M);},onMouseOver:M=>{var h;d(),(h=m.onMouseOver)==null||h.call(m,M);},onMouseLeave:M=>{var h;S.current=window.setTimeout(g,300),(h=m.onMouseLeave)==null||h.call(m,M);}})}),[T,l,d,g]);return W__default.default.createElement(Te,{value:N},W__default.default.createElement(U,C(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 ht=(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,C(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.CaretRightIcon,{className:s.icon})))},oe=W__default.default.forwardRef(ht);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;
|
|
19
17
|
|
|
20
|
-
exports.Menu =
|
|
21
|
-
exports.MenuDivider =
|
|
22
|
-
exports.MenuItem =
|
|
23
|
-
exports.MenuList =
|
|
24
|
-
exports.MenuSectionTitle =
|
|
25
|
-
exports.MenuTrigger =
|
|
26
|
-
exports.Submenu =
|
|
27
|
-
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
|
+
//# sourceMappingURL=out.js.map
|
|
28
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","contextValue","_props","_ref","_b","_c","_d","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","getMenuItemStyles","MENU_ITEM_DEFAULT_TAG","_MenuItem","as","isInitiallyFocused","id","itemTestId","getMenuItemProps","itemRef","Element","MenuItem","MenuTrigger","getTriggerProps","getMenuDividerStyles","MenuDivider","SectionHeading","getMenuSectionTitleStyles","MenuSectionTitle","SUBMENU_OFFSET","Submenu","onClose","isParentMenuOpen","propsToPropagateToSubmenus","mouseLeaveTimerRef","setIsOpen","ChevronRightIcon","getSubmenuTriggerStyles","isActive","_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(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] as HTMLElement).focus({\n preventScroll: false,\n });\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 const contextValue: MenuContextType = useMemo(\n () => ({\n isOpen,\n menuId,\n focusMenuItem,\n getTriggerProps: (_props = {}, _ref = null) => ({\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 relatedTarget = event.relatedTarget as Node;\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 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 padding: `${tokens.spacingXs} 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 padding: `${tokens.spacingXs} 0`,\n zIndex: 1001,\n });\n};\n\nexport const getMenuListStyles = (props: {\n hasStickyFooter?: boolean;\n hasStickyHeader?: boolean;\n}) => ({\n container: css({\n overflowY: 'auto',\n position: 'relative',\n padding: 0,\n paddingTop: props.hasStickyHeader ? 0 : tokens.spacingXs,\n paddingBottom: props.hasStickyFooter ? 0 : tokens.spacingXs,\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 * Sets focus on item\n */\n isInitiallyFocused?: boolean;\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 { testId, className, as, isInitiallyFocused, ...otherProps } = props;\n\n const id = useId(undefined, 'menu-item');\n const itemTestId = testId || `cf-ui-${id}`;\n const styles = getMenuItemStyles();\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 className={cx(styles.root, className)}\n data-test-id={itemTestId}\n ref={mergeRefs(itemRef, ref)}\n tabIndex={-1}\n >\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 } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuItemStyles = () => {\n return {\n root: css({\n display: 'block',\n width: '100%',\n background: 'none',\n border: 0,\n margin: 0,\n outline: 'none',\n fontSize: tokens.fontSizeM,\n lineHeight: tokens.lineHeightM,\n fontWeight: tokens.fontWeightNormal,\n position: 'relative',\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n wordBreak: 'break-word',\n whiteSpace: 'break-spaces',\n cursor: 'pointer',\n hyphens: 'auto',\n minWidth: '150px',\n textDecoration: 'none',\n color: tokens.gray800,\n\n '&:hover': {\n backgroundColor: tokens.gray100,\n },\n '&:focus': {\n boxShadow: `inset ${tokens.glowPrimary}`,\n // just to make boxShadow with rounded corners\n borderRadius: tokens.borderRadiusMedium,\n },\n '&:focus:not(:focus-visible)': {\n boxShadow: 'unset',\n borderRadius: 'unset',\n },\n '&:focus-visible': {\n boxShadow: `inset ${tokens.glowPrimary}`,\n borderRadius: tokens.borderRadiusMedium,\n },\n '&:active': {\n backgroundColor: tokens.gray200,\n },\n '&:disabled': {\n opacity: 0.5,\n cursor: 'auto',\n },\n }),\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 background: tokens.gray300,\n margin: `${tokens.spacingXs} 0`,\n });\n","import React from 'react';\nimport { cx } from 'emotion';\nimport {\n SectionHeading,\n type SectionHeadingProps,\n} from '@contentful/f36-typography';\nimport type { ExpandProps } from '@contentful/f36-core';\n\nimport { getMenuSectionTitleStyles } from './MenuSectionTitle.styles';\n\nexport type MenuSectionTitleProps = SectionHeadingProps;\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 <SectionHeading\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 testId={testId}\n className={cx(styles, className)}\n marginBottom=\"none\"\n {...otherProps}\n >\n {children}\n </SectionHeading>\n );\n};\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMenuSectionTitleStyles = () =>\n css({\n textAlign: 'left',\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n lineHeight: tokens.lineHeightM,\n\n 'hr + &': {\n marginTop: '-8px',\n },\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","CaretRightIcon","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 { CaretRightIcon } 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 <CaretRightIcon 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,21 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/f36-menu",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Forma 36: Menu component",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsup"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@contentful/f36-core": "^5.
|
|
10
|
-
"@contentful/f36-icons": "^5.
|
|
11
|
-
"@contentful/f36-popover": "^5.
|
|
12
|
-
"@contentful/f36-tokens": "^
|
|
13
|
-
"@contentful/f36-typography": "^5.
|
|
14
|
-
"@contentful/f36-utils": "^5.
|
|
9
|
+
"@contentful/f36-core": "^5.1.0",
|
|
10
|
+
"@contentful/f36-icons": "^5.1.0",
|
|
11
|
+
"@contentful/f36-popover": "^5.1.0",
|
|
12
|
+
"@contentful/f36-tokens": "^5.1.0",
|
|
13
|
+
"@contentful/f36-typography": "^5.1.0",
|
|
14
|
+
"@contentful/f36-utils": "^5.1.0",
|
|
15
15
|
"emotion": "^10.0.17"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"react": ">=16.8"
|
|
18
|
+
"react": ">=16.8",
|
|
19
|
+
"react-dom": ">=16.8"
|
|
19
20
|
},
|
|
20
21
|
"license": "MIT",
|
|
21
22
|
"files": [
|
|
@@ -29,9 +30,10 @@
|
|
|
29
30
|
"browserslist": "extends @contentful/browserslist-config",
|
|
30
31
|
"repository": {
|
|
31
32
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/contentful/forma-36"
|
|
33
|
+
"url": "git+https://github.com/contentful/forma-36.git"
|
|
33
34
|
},
|
|
34
35
|
"publishConfig": {
|
|
36
|
+
"registry": "https://npm.pkg.github.com/",
|
|
35
37
|
"access": "public"
|
|
36
38
|
}
|
|
37
39
|
}
|