@@ -2,9 +2,30 @@ import React from 'react';
22import deepmerge from 'deepmerge' ;
33import css from '@styled-system/css' ;
44import * as ReachMenu from '@reach/menu-button' ;
5- import { createGlobalStyle } from 'styled-components' ;
5+ import {
6+ createGlobalStyle ,
7+ css as styledcss ,
8+ keyframes ,
9+ } from 'styled-components' ;
610import { Element , Button , IconButton , List } from '../..' ;
711
12+ const transitions = {
13+ slide : keyframes ( {
14+ from : {
15+ opacity : 0 ,
16+ transform : 'translateY(-4px)' ,
17+ } ,
18+ } ) ,
19+ scale : keyframes ( {
20+ from : {
21+ opacity : 0 ,
22+ transform : 'scale(0.7)' ,
23+ } ,
24+ } ) ,
25+ } ;
26+
27+ const MenuContext = React . createContext ( { trigger : null } ) ;
28+
829const Menu = ( { ...props } ) => {
930 const PortalStyles = createGlobalStyle (
1031 css ( {
@@ -20,6 +41,7 @@ const Menu = ({ ...props }) => {
2041 border : '1px solid' ,
2142 borderColor : 'menuList.border' ,
2243 ':focus' : { outline : 'none' } ,
44+ transform : 'translateY(4px)' ,
2345 // override reach ui styles
2446 padding : 0 ,
2547 } ,
@@ -38,13 +60,27 @@ const Menu = ({ ...props }) => {
3860 // override reach ui styles
3961 font : 'ineherit' ,
4062 } ,
41- } )
63+ } ) ,
64+ styledcss `
65+ [data-reach-menu-list][data-trigger=MenuButton] {
66+ animation: ${ transitions . slide } 150ms ease-out;
67+ transform-origin: top;
68+ }
69+ [data-reach-menu-list][data-trigger=MenuIconButton] {
70+ animation: ${ transitions . scale } 150ms ease-out;
71+ transform-origin: top left;
72+ }
73+ `
4274 ) ;
4375
76+ const trigger = props . children [ 0 ] . type . name ;
77+
4478 return (
45- < Element as = { ReachMenu . Menu } data-component = "Menu" { ...props } >
79+ < Element as = { ReachMenu . Menu } { ...props } >
4680 < PortalStyles />
47- { props . children }
81+ < MenuContext . Provider value = { { trigger } } >
82+ { props . children }
83+ </ MenuContext . Provider >
4884 </ Element >
4985 ) ;
5086} ;
@@ -54,7 +90,15 @@ const MenuButton = props => (
5490 as = { ReachMenu . MenuButton }
5591 variant = "link"
5692 { ...props }
57- css = { deepmerge ( { width : 'auto' } , props . css || { } ) }
93+ css = { deepmerge (
94+ {
95+ width : 'auto' ,
96+ // disable scale feedback of buttons in menu
97+ // to make the menu feel less jumpy
98+ ':active:not(:disabled)' : { transform : 'scale(1)' } ,
99+ } ,
100+ props . css || { }
101+ ) }
58102 >
59103 { props . children }
60104 </ Button >
@@ -64,11 +108,19 @@ const MenuIconButton = props => (
64108 < IconButton as = { ReachMenu . MenuButton } { ...props } />
65109) ;
66110
67- const MenuList = props => (
68- < List as = { ReachMenu . MenuList } data-component = "MenuList" { ...props } >
69- { props . children }
70- </ List >
71- ) ;
111+ const MenuList = props => {
112+ const { trigger } = React . useContext ( MenuContext ) ;
113+ return (
114+ < List
115+ as = { ReachMenu . MenuList }
116+ data-component = "MenuList"
117+ data-trigger = { trigger }
118+ { ...props }
119+ >
120+ { props . children }
121+ </ List >
122+ ) ;
123+ } ;
72124
73125const MenuItem = props => (
74126 < Element as = { ReachMenu . MenuItem } data-component = "MenuItem" { ...props } />
0 commit comments