@@ -3,6 +3,7 @@ import PT from "prop-types";
33import cn from "classnames" ;
44import { usePopper } from "react-popper" ;
55import Button from "components/Button" ;
6+ import Tooltip from "components/Tooltip" ;
67import IconArrowDown from "../../assets/images/icon-arrow-down-narrow.svg" ;
78import { useClickOutside } from "utils/hooks" ;
89import { negate , stopPropagation } from "utils/misc" ;
@@ -39,48 +40,6 @@ const ActionsMenu = ({
3940 setIsOpen ( negate ) ;
4041 } , [ ] ) ;
4142
42- const onItemClick = useCallback (
43- ( event ) => {
44- let index = + event . target . dataset . actionIndex ;
45- let item = items [ index ] ;
46- if ( ! item || item . disabled || item . separator ) {
47- return ;
48- }
49- closeMenu ( ) ;
50- item . action ?. ( ) ;
51- } ,
52- [ items , closeMenu ]
53- ) ;
54-
55- const menuItems = useMemo (
56- ( ) =>
57- items . map ( ( item , index ) => {
58- if ( item . hidden ) {
59- return null ;
60- } else if ( item . separator ) {
61- return < div key = { index } className = { compStyles . separator } /> ;
62- } else {
63- return (
64- < div
65- key = { index }
66- data-action-index = { index }
67- onClick = { onItemClick }
68- role = "button"
69- tabIndex = { 0 }
70- className = { cn (
71- compStyles . item ,
72- { [ compStyles . itemDisabled ] : item . disabled } ,
73- item . className
74- ) }
75- >
76- { item . label }
77- </ div >
78- ) ;
79- }
80- } ) ,
81- [ items , onItemClick ]
82- ) ;
83-
8443 return (
8544 < div
8645 className = { compStyles . container }
@@ -104,8 +63,8 @@ const ActionsMenu = ({
10463 </ Button >
10564 { isOpen && (
10665 < Menu
107- items = { menuItems }
108- onClickOutside = { closeMenu }
66+ close = { closeMenu }
67+ items = { items }
10968 referenceElement = { referenceElement }
11069 strategy = { popupStrategy }
11170 />
@@ -123,6 +82,7 @@ ActionsMenu.propTypes = {
12382 label : PT . string ,
12483 action : PT . func ,
12584 separator : PT . bool ,
85+ disabled : PT . bool ,
12686 hidden : PT . bool ,
12787 } )
12888 ) ,
@@ -138,7 +98,7 @@ export default ActionsMenu;
13898 * @param {Object } props component properties
13999 * @returns {JSX.Element }
140100 */
141- const Menu = ( { items , onClickOutside , referenceElement, strategy } ) => {
101+ const Menu = ( { close , items , referenceElement, strategy } ) => {
142102 const [ popperElement , setPopperElement ] = useState ( null ) ;
143103 const [ arrowElement , setArrowElement ] = useState ( null ) ;
144104 const { styles, attributes } = usePopper ( referenceElement , popperElement , {
@@ -180,7 +140,75 @@ const Menu = ({ items, onClickOutside, referenceElement, strategy }) => {
180140 ] ,
181141 } ) ;
182142
183- useClickOutside ( popperElement , onClickOutside , [ ] ) ;
143+ const onClickItem = useCallback (
144+ ( event ) => {
145+ let targetData = event . target . dataset ;
146+ let index = + targetData . actionIndex ;
147+ let item = items [ index ] ;
148+ if ( ! item || targetData . disabled || item . separator ) {
149+ return ;
150+ }
151+ close ( ) ;
152+ item . action ?. ( ) ;
153+ } ,
154+ [ close , items ]
155+ ) ;
156+
157+ useClickOutside ( popperElement , close , [ ] ) ;
158+
159+ const menuItems = useMemo ( ( ) => {
160+ return items . map ( ( item , index ) => {
161+ if ( item . hidden ) {
162+ return null ;
163+ } else if ( item . separator ) {
164+ return < div key = { index } className = { compStyles . separator } /> ;
165+ } else {
166+ let disabled = ! ! item . disabled ;
167+ let reasonsDisabled = Array . isArray ( item . disabled )
168+ ? item . disabled
169+ : null ;
170+ let attrs = {
171+ key : index ,
172+ "data-action-index" : index ,
173+ onClick : onClickItem ,
174+ role : "button" ,
175+ tabIndex : 0 ,
176+ className : cn (
177+ compStyles . item ,
178+ { [ compStyles . itemDisabled ] : disabled } ,
179+ item . className
180+ ) ,
181+ } ;
182+ if ( disabled ) {
183+ attrs [ "data-disabled" ] = true ;
184+ }
185+ return (
186+ < div { ...attrs } >
187+ { reasonsDisabled ? (
188+ < Tooltip
189+ content = {
190+ reasonsDisabled . length === 1 ? (
191+ reasonsDisabled [ 0 ]
192+ ) : (
193+ < ul >
194+ { reasonsDisabled . map ( ( text , index ) => (
195+ < li key = { index } > { text } </ li >
196+ ) ) }
197+ </ ul >
198+ )
199+ }
200+ strategy = "fixed"
201+ >
202+ { item . label }
203+ </ Tooltip >
204+ ) : (
205+ item . label
206+ ) }
207+ </ div >
208+ ) ;
209+ }
210+ } ) ;
211+ } , [ items , onClickItem ] ) ;
184212
185213 return (
186214 < div
@@ -189,7 +217,7 @@ const Menu = ({ items, onClickOutside, referenceElement, strategy }) => {
189217 style = { styles . popper }
190218 { ...attributes . popper }
191219 >
192- < div className = { compStyles . items } > { items } </ div >
220+ < div className = { compStyles . items } > { menuItems } </ div >
193221 < div
194222 ref = { setArrowElement }
195223 style = { styles . arrow }
@@ -200,8 +228,17 @@ const Menu = ({ items, onClickOutside, referenceElement, strategy }) => {
200228} ;
201229
202230Menu . propTypes = {
203- items : PT . array . isRequired ,
204- onClickOutside : PT . func . isRequired ,
231+ close : PT . func . isRequired ,
232+ items : PT . arrayOf (
233+ PT . shape ( {
234+ label : PT . string ,
235+ action : PT . func ,
236+ checkDisabled : PT . func ,
237+ disabled : PT . bool ,
238+ separator : PT . bool ,
239+ hidden : PT . bool ,
240+ } )
241+ ) ,
205242 referenceElement : PT . object ,
206243 strategy : PT . oneOf ( [ "absolute" , "fixed" ] ) ,
207244} ;
0 commit comments