UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

1 lines 13.7 kB
import{__assign,__extends}from"tslib";import"../../CommonImports";import"../../Core/core.css";import"./Menu.css";import"./MenuButton.css";import*as React from"react";import{ObservableCollection,ObservableLike,ObservableValue}from"../../Core/Observable";import{Callout}from"../../Callout";import{Checkbox}from"../../Checkbox";import{FocusWithin}from"../../FocusWithin";import{FocusZone,FocusZoneContext,FocusZoneDirection,FocusZoneKeyStroke}from"../../FocusZone";import{Icon,IconSize}from"../../Icon";import{List}from"../../List";import{MouseWithin}from"../../MouseWithin";import{Observer}from"../../Observer";import{css,getSafeId,getSafeIdSelector,isArrowKey,KeyCode,preventDefault,setFocusVisible}from"../../Util";import{Location}from"../../Utilities/Position";import{ArrayItemProvider}from"../../Utilities/Provider";import{MenuCell,MenuItemType}from"./Menu.Props";function groupMenuItems(e,t){var n={},o=0,r=[],t=t||[];if(0<t.length)for(var o=t.reduce(function(e,t){return t.rank||e<0?t.rank:e},0)||0,i=0,a=t;i<a.length;i++){var l=a[i];n[l.key]={key:l.key,rank:void 0===l.rank?++o:l.rank,items:[]}}for(var s=0,c=e;s<c.length;s++){var u=c[s];u.groupKey?n[u.groupKey]?n[u.groupKey].items.push(u):n[u.groupKey]={key:u.groupKey,rank:++o,items:[u]}:r.push(u)}for(var t=Object.keys(n).map(function(e){return n[e]}),m=(t.sort(function(e,t){return(e.rank||Number.MAX_VALUE)-(t.rank||Number.MAX_VALUE)}),t.push({key:"ungrouped",rank:++o,items:r}),t.forEach(function(e){for(var t=e.items;0<t.length&&t[0].itemType===MenuItemType.Divider;)t.shift();for(;0<t.length&&t[t.length-1].itemType===MenuItemType.Divider;)t.pop()}),e=[],!0),p=0,d=t;p<d.length;p++)0!==(l=d[p]).items.length&&(m||e.push({id:"divider_".concat(l.key),itemType:MenuItemType.Divider}),m=m&&!1,e=e.concat(l.items));return e}var MenuItemProvider=function(m){function e(e,t){var n=m.call(this,e)||this,o=(n.positions=[],[]);if(e){for(var r=!1,i=!1,a=MenuItemType.Divider,l=void 0,s=0,c=e;s<c.length;s++){var u=c[s];if(!u.hidden){if(u.itemType===MenuItemType.Divider){if(u.itemType===a)continue;l=u}else l&&(o.push(l),l=void 0),o.push(u);a=u.itemType||MenuItemType.Normal,r=!!u.groupKey||r,i=0<=u.rank||i}}i&&o.sort(function(e,t){return(e.rank||Number.MAX_VALUE)-(t.rank||Number.MAX_VALUE)}),r&&(o=groupMenuItems(o,t))}return n.items=o,n}return __extends(e,m),e.prototype.getCount=function(){if(void 0===this.count)for(var e=this.count=0,t=this.items;e<t.length;e++){var n=t[e];n.itemType===MenuItemType.Divider||n.itemType===MenuItemType.Header?this.positions.push(-1):this.positions.push(++this.count)}return this.count},e.prototype.getItem=function(e){return this.items[e]},e.prototype.getPosition=function(e){return this.positions.length||this.getCount(),this.positions[e]},e}(ArrayItemProvider),Menu=function(t){function e(e){var i=t.call(this,e)||this;return i.containerElement=React.createRef(),i.expandItem=function(e,t){if((e=e||-1===i.state.expandedIndex.value?e:i.itemProvider.getItem(i.state.expandedIndex.value))&&e.subMenuProps)for(var n=0;n<i.itemProvider.length;n++)if(e===i.itemProvider.getItem(n)){i.state.expandedIndex.value=t?n:-1;break}},i.focus=function(){i.containerElement.current&&i.containerElement.current.focus()},i.getParent=function(){return i.props.parentMenu},i.onActivate=function(e,t){i.props.onActivate&&i.props.onActivate(e,t)},i.renderMenuItem=function(e,t,n){var n=n.onFocusItem,o={expandedIndex:i.state.expandedIndex,menu:i,menuProps:i.props,onActivate:i.onActivate,onFocusItem:n,position:i.itemProvider.getPosition(e),setSize:i.itemProvider.getCount()};if(t.renderMenuItem)return t.renderMenuItem(e,t,o);var r=t.id;switch(t.itemType){case MenuItemType.Divider:return MenuDivider(e,t);case MenuItemType.Header:return MenuHeader(e,t);default:return React.createElement(MenuItem,{key:r,index:e,menuItem:t,details:o})}},i.state={expandedIndex:new ObservableValue(-1)},i}return __extends(e,t),e.prototype.render=function(){var t=this;return React.createElement(Observer,{items:this.props.items},function(e){return t.itemProvider=new MenuItemProvider(e.items,t.props.groups),t.renderList()})},e.prototype.renderList=function(){return React.createElement("div",{className:"bolt-menu-container no-outline",ref:this.containerElement,tabIndex:-1},0<this.itemProvider.length&&React.createElement(React.Fragment,null,React.createElement("div",{className:"bolt-menu-spacer",onMouseDown:preventDefault}),React.createElement(List,{ariaLabel:this.props.ariaLabel,className:css(this.props.className,"bolt-menu"),columnCount:7,focuszoneProps:null,id:this.props.id,itemProvider:this.itemProvider,renderRow:this.renderMenuItem,role:"menu",virtualize:!1}),React.createElement("div",{className:"bolt-menu-spacer",onMouseDown:preventDefault})))},e}(React.Component);function MenuDivider(e,t){return React.createElement("tr",{"aria-hidden":"true",className:css(t.className,"bolt-menuitem-row bolt-list-row bolt-menuitem-divider"),key:t.id||"divider-"+e,onMouseDown:preventDefault},React.createElement("td",{className:"bolt-menuitem-cell bolt-list-cell"}),React.createElement("td",{className:"bolt-menuitem-cell bolt-list-cell bolt-menuitem-divider-column",colSpan:5},React.createElement("div",{className:"bolt-menuitem-divider-content"})),React.createElement("td",{className:"bolt-menuitem-cell bolt-list-cell"}))}function MenuHeader(e,t){return React.createElement("tr",{"aria-level":1,className:css(t.className,"bolt-menuitem-row bolt-list-row bolt-menuitem-header"),key:t.id||"header-"+e,onMouseDown:preventDefault,role:"heading"},React.createElement("td",{className:"bolt-menuitem-cell bolt-list-cell"}),React.createElement("td",{className:"bolt-menuitem-cell bolt-list-cell",colSpan:3},React.createElement("div",{className:"bolt-menuitem-cell-content bolt-menuitem-cell-text"},t.text)),React.createElement("td",{className:"bolt-menuitem-cell bolt-list-cell",colSpan:3}))}var MenuItem=function(e){function t(){var o=null!==e&&e.apply(this,arguments)||this;return o.localKeyStroke=!1,o.expanded=!1,o.element=React.createRef(),o.handleClick=function(e){var t,n=o.props.menuItem;n.disabled?e.preventDefault():o.expanded||(t=void 0,t=n.onActivate?n.onActivate(n,e):t)||(n.href||e.preventDefault(),n.subMenuProps?o.props.details.menu.expandItem(n,!0):(n.href||void 0===n.checked||n.readonly)&&o.props.details.onActivate(n,e))},o.onClick=function(e){e.defaultPrevented||o.handleClick(e)},o.onDismissSubMenu=function(e){!e&&o.element.current&&o.props.details.menu.expandItem(o.props.menuItem,!1)},o.onExpandedChange=function(e){return o.expanded&&e!==o.props.index||!o.expanded&&e===o.props.index},o.onFocus=function(e){o.element.current===document.activeElement&&o.props.details.onFocusItem(o.props.index,e)},o.onKeyDown=function(e){var t;o.localKeyStroke=!0,e.defaultPrevented||(t=o.props.menuItem,e.which===KeyCode.tab||e.which===KeyCode.space?e.preventDefault():e.which===KeyCode.rightArrow&&t.subMenuProps&&(e.preventDefault(),o.props.details.menu.expandItem(t,!0)))},o.onKeyUp=function(e){!o.localKeyStroke||e.defaultPrevented||e.which!==KeyCode.enter&&e.which!==KeyCode.space||o.handleClick(e)},o.onMouseDown=function(e){e.defaultPrevented||!o.props.menuItem.disabled&&o.props.details.expandedIndex.value!==o.props.index||e.preventDefault()},o.onMouseEnter=function(){o.props.menuItem.disabled||(o.element.current&&o.element.current.focus(),o.props.details.menu.expandItem(o.props.menuItem,!0),setFocusVisible(!1))},o.onMouseLeave=function(){o.onDismissSubMenu(!1)},o}return __extends(t,e),t.prototype.render=function(){var r=this,e=this.props,t=e.index,i=e.menuItem,a=e.details,l=a.menu,s=a.position,c=a.setSize,u=i.ariaLabel,e=i.checked,m=i.className,p=i.disabled,d=i.href,v=i.iconProps,f=i.readonly,h=i.secondaryText,b=i.subMenuProps,M=i.target,y=i.id,x=i.rel,I=i.text,E=d?"div":"td",g=d?"a":"tr";return d&&M&&!x&&(x="noopener"),React.createElement(Observer,{checked:e,expandedIndex:{observableValue:this.props.details.expandedIndex,filter:this.onExpandedChange}},function(o){return r.expanded=o.expandedIndex===t,React.createElement(MouseWithin,{enterDelay:250,leaveDelay:250,onMouseEnter:r.onMouseEnter,onMouseLeave:r.onMouseLeave},function(n){return React.createElement(FocusZoneContext.Consumer,null,function(t){return React.createElement(FocusWithin,{onFocus:r.onFocus},function(e){return React.createElement(FocusZone,{direction:FocusZoneDirection.Horizontal},React.createElement(g,{"aria-label":u,"aria-checked":!0===o.checked||void 0,"aria-controls":r.expanded&&b?getSafeId(b.id):void 0,"aria-disabled":p?"true":void 0,"aria-expanded":b?r.expanded:void 0,"aria-haspopup":!!b||void 0,"aria-posinset":s,"aria-setsize":c,className:css(m,"bolt-menuitem-row bolt-list-row bolt-menuitem-row-normal cursor-pointer",p&&"disabled",r.expanded&&"expanded",e.hasFocus&&"focused"),"data-focuszone":p?void 0:t.focuszoneId,href:d,id:getSafeId(y),role:void 0!==o.checked?"menuitemcheckbox":"menuitem",onBlur:e.onBlur,onClick:r.onClick,onFocus:e.onFocus,onKeyDown:r.onKeyDown,onKeyUp:r.onKeyUp,onMouseDown:r.onMouseDown,onMouseEnter:n.onMouseEnter,onMouseLeave:n.onMouseLeave,ref:r.element,rel:x,tabIndex:p?void 0:-1,target:M},React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},React.createElement("div",{className:"bolt-menuitem-cell-content flex-row"})),React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},void 0!==o.checked&&(i.renderMenuCell&&i.renderMenuCell(MenuCell.State,i,a)||React.createElement("div",{className:"bolt-menuitem-cell-content bolt-menuitem-cell-state flex-row"},!0===f?Icon({className:css(!o.checked&&"invisible"),iconName:"CheckMark"}):React.createElement(Checkbox,{checked:o.checked,disabled:p,excludeFocusZone:!0,excludeTabStop:!0,onChange:r.onClick})))),React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},i.renderMenuCell&&i.renderMenuCell(MenuCell.Icon,i,a)||v&&React.createElement("div",{className:"bolt-menuitem-cell-content bolt-menuitem-cell-icon flex-row"},Icon(v))),React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},i.renderMenuCell&&i.renderMenuCell(MenuCell.PrimaryText,i,a)||React.createElement("div",{id:getSafeId(y+"-text"),className:"bolt-menuitem-cell-content bolt-menuitem-cell-text flex-row"},I?React.createElement(React.Fragment,null," ",I," "):React.createElement("div",null," "))),React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},i.renderMenuCell&&i.renderMenuCell(MenuCell.SecondaryText,i,a)||h&&React.createElement("div",{className:"bolt-menuitem-cell-content bolt-menuitem-cell-secondary flex-row"},h)),React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},i.renderMenuCell&&i.renderMenuCell(MenuCell.Action,i,a)||b&&React.createElement("div",{className:"bolt-menuitem-cell-content bolt-menuitem-cell-submenu flex-row"},Icon({iconName:"ChevronRightMed",size:IconSize.small}),r.expanded&&r.element.current&&React.createElement(ContextualMenu,{anchorElement:r.element.current,anchorOffset:{horizontal:0,vertical:-8},anchorOrigin:{horizontal:Location.end,vertical:Location.start},subMenu:!0,menuOrigin:{horizontal:Location.start,vertical:Location.start},menuProps:b,onActivate:r.props.details.onActivate,onDismiss:r.onDismissSubMenu,parentMenu:l}))),React.createElement(E,{className:"bolt-menuitem-cell bolt-list-cell"},React.createElement("div",{className:"bolt-menuitem-cell-content flex-row"}))))})})})})},t}(React.Component),ContextualMenu=function(e){function t(){var n=null!==e&&e.apply(this,arguments)||this;return n.calloutRef=React.createRef(),n.onDismiss=function(){n.props.onDismiss&&n.props.onDismiss(!1)},n.onKeyDown=function(e){e.defaultPrevented||(e.which===KeyCode.escape||e.which===KeyCode.tab||e.which===KeyCode.leftArrow&&n.props.subMenu)&&(e.preventDefault(),n.props.onDismiss)&&n.props.onDismiss(!1)},n.onActivate=function(e,t){n.props.menuProps.onActivate&&n.props.menuProps.onActivate(e,t),n.props.onActivate&&n.props.onActivate(e,t),n.props.onDismiss&&n.props.onDismiss(!0)},n.preprocessKeyStroke=function(e){return isArrowKey(e)?FocusZoneKeyStroke.IgnoreParents:FocusZoneKeyStroke.IgnoreNone},n}return __extends(t,e),t.prototype.render=function(){for(var t=this,e=".bolt-menu-container",n=ObservableLike.getValue(this.props.menuProps.items),o=(n=this.props.menuProps.items instanceof ObservableCollection?n.slice():n).sort(function(e,t){return(e.rank||Number.MAX_VALUE)-(t.rank||Number.MAX_VALUE)}),r=0;r<o.length;r++)if(o[r].itemType===MenuItemType.Normal||void 0===o[r].itemType){var i=o[r].id;if(i&&!o[r].disabled){e=getSafeIdSelector(i);break}}return React.createElement(Observer,{menuItems:{observableValue:this.props.menuProps.items,filter:function(){var e;return null!=(e=t.calloutRef.current)&&e.updateLayout(),!1}}},function(){return React.createElement(Callout,{ref:t.calloutRef,anchorElement:t.props.anchorElement,anchorOffset:t.props.anchorOffset,anchorOrigin:t.props.anchorOrigin,anchorPoint:t.props.anchorPoint,blurDismiss:!0,calloutOrigin:t.props.menuOrigin,className:t.props.className,contentClassName:css("bolt-contextual-menu flex-column custom-scrollbar depth-8",t.props.subMenu&&"bolt-contextual-submenu"),contentShadow:!0,onDismiss:t.onDismiss,fixedLayout:t.props.fixedLayout,focuszoneProps:{defaultActiveElement:e,direction:FocusZoneDirection.Vertical,focusOnMount:!0,preprocessKeyStroke:t.preprocessKeyStroke,circularNavigation:!0},id:t.props.menuProps.id+"-callout",portalProps:{className:"bolt-menu-portal"}},React.createElement("div",{className:"bolt-contextualmenu-container",onKeyDown:t.onKeyDown},React.createElement(Menu,__assign({},t.props.menuProps,{onActivate:t.onActivate,parentMenu:t.props.parentMenu}))))})},t}(React.Component);export{groupMenuItems,Menu,MenuDivider,MenuHeader,MenuItem,ContextualMenu};