UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

1 lines 6.75 kB
import"../../CommonImports";import"../../Core/core.css";import"./Dropdown.css";import*as React from"react";import{ObservableLike}from"../../Core/Observable";import{format}from"../../Core/Util/String";import{Button}from"../../Button";import{Callout,ContentSize}from"../../Callout";import{FocusZone,FocusZoneDirection,FocusZoneKeyStroke}from"../../FocusZone";import{IconSize}from"../../Icon";import{ListBox}from"../../ListBox";import{Observer}from"../../Observer";import*as Resources from"../../Resources.Dropdown";import{TextField}from"../../TextField";import{css,getSafeIdSelector,KeyCode,preventDefault}from"../../Util";const ItemsForFilter=10,DefaultWidth=256,FilterBarPadding=16,FilterBarIconWidth=27;function DropdownCallout(e){return React.createElement(DropdownCalloutComponent,Object.assign({},e))}class DropdownCalloutComponent extends React.Component{constructor(e){super(e),this.callout=React.createRef(),this.calloutContent=React.createRef(),this.filterBox=React.createRef(),this.initFocusElement=React.createRef(),this.hasFocused=!1,this.updateLayout=()=>(setTimeout(()=>{this.callout.current&&this.callout.current.updateLayout()},0),!0),this.onMouseDown=e=>{this.props.ignoreMouseDown&&"INPUT"!==e.target.tagName&&preventDefault(e)},this.listBoxDidUpdate=()=>{this.getScrollWidth()},this.getScrollWidth=()=>{window.requestAnimationFrame(()=>{var e;this.calloutContent.current&&0<=this.props.width&&(e=this.calloutContent.current.offsetWidth-this.props.width,1<Math.abs(e))&&this.setState({scrollBarWidth:e+this.state.scrollBarWidth})})},this.state={scrollBarWidth:0}}componentDidMount(){this.getScrollWidth()}componentDidUpdate(e){!this.shouldShowFilterBox()||e.loading===this.props.loading||this.props.loading||this.hasFocused||(this.focus(),this.hasFocused=!0)}shouldShowFilterBox(){var e;return null!=(e=this.props.showFilterBox)?e:this.props.items.length>ItemsForFilter}focus(){this.filterBox.current?this.filterBox.current.focus():this.initFocusElement.current&&this.initFocusElement.current.focus()}render(){const{actions:e,anchorElement:t,anchorOffset:o,anchorOrigin:r,anchorPoint:s,ariaLabel:l,blurDismiss:n=!0,calloutContentClassName:i,columns:a,containerClassName:c,contentLocation:d,dropdownOrigin:u,enforceSingleSelect:h,excludeFocusZone:m,excludeTabStop:p,filteredItems:f,filteredNoResultsText:w,filteredResultsLoadingText:b,filterPlaceholderText:g,filterText:x,focusOnMount:R,getUnselectableRanges:C,id:v,items:F,lightDismiss:S,listBoxClassName:k,listBoxRef:Z,loading:M,onActivate:U,onFilterKeyDown:z,onFilterTextChanged:D,onSelect:K,onToggle:A,portalProps:V,renderBeforeContent:B,renderItem:j,searching:I,selection:q,showCloseButton:E,showChecksColumn:N,showItemsWhileSearching:G,showTree:H,title:T,updateFilteredItems:O,userFilteredItems:J}=this.props;let{width:L=DefaultWidth}=this.props;0<L&&(L-=this.state.scrollBarWidth);const P="bolt-dropdown-textfield-"+v,W=()=>{x.value="",D&&D(null,""),O&&O()},y=()=>{this.props.onDismiss&&this.props.onDismiss(),W()};return React.createElement(Callout,{anchorElement:t,anchorOffset:o,anchorOrigin:r,anchorPoint:s,role:"presentation",blurDismiss:n,calloutOrigin:u,contentClassName:css(i,"bolt-dropdown flex-column custom-scrollbar v-scroll-auto h-scroll-hidden"),contentLocation:d,contentRef:this.calloutContent,contentShadow:!0,contentSize:ContentSize.Auto,escDismiss:!0,id:v,portalProps:V,lightDismiss:S,focuszoneProps:{postprocessKeyStroke:e=>e.which!==KeyCode.tab||e.defaultPrevented?FocusZoneKeyStroke.IgnoreNone:(e.preventDefault(),y(),FocusZoneKeyStroke.IgnoreAll)},onDismiss:y,ref:this.callout},React.createElement(FocusZone,{circularNavigation:!0,defaultActiveElement:this.shouldShowFilterBox()?getSafeIdSelector(P):".bolt-dropdown-init-focus",direction:FocusZoneDirection.Vertical,focusOnMount:void 0===R||R,preventScrollOnFocus:window.self!==window.top},React.createElement("div",{className:"bolt-dropdown-container no-outline",onMouseDown:this.onMouseDown,onKeyDown:z,style:{width:0<=L?L:void 0}},React.createElement("div",{"aria-hidden":"true","aria-roledescription":Resources.DropdownCalloutRoleDescription,className:"bolt-dropdown-init-focus no-outline",tabIndex:p?void 0:-1,ref:this.initFocusElement,role:"menuitem"}),React.createElement(Observer,{items:{observableValue:F,filter:this.updateLayout}},()=>{var e=this.shouldShowFilterBox();return e||T||E?React.createElement("div",{className:"bolt-dropdown-header-container"},(T||E)&&React.createElement("div",{className:"bolt-dropdown-header flex-row flex-center"},React.createElement("div",{className:"bolt-dropdown-header-text flex-grow font-weight-semibold"},T),E&&React.createElement(Button,{className:"bolt-dropdown-header-button",ariaLabel:Resources.Close,iconProps:{iconName:"Cancel"},onClick:y,subtle:!0})),e&&React.createElement("div",{key:"bolt-dropdown-filter-container",className:"bolt-dropdown-filter-container"},React.createElement(Observer,{filterText:x},e=>React.createElement(TextField,{key:"bolt-dropdown-filter",ariaLabel:Resources.SearchAriaLabel,className:"bolt-dropdown-filter",excludeTabStop:!0,inputId:P,onChange:D,placeholder:g,prefixIconProps:{iconName:"Search"},ref:this.filterBox,value:x,maxWidth:this.props.width-FilterBarPadding-FilterBarIconWidth,suffixIconProps:0<e.filterText.length?{ariaLabel:Resources.ClearText,iconName:"ChromeClose",onClick:W,size:IconSize.small,tooltipProps:{text:Resources.ClearText},role:"button"}:void 0})))):null}),B&&B(),React.createElement(Observer,{filteredItems:f,filteredNoResultsText:w,listBoxItems:{observableValue:F,filter:O},userFilteredItems:{observableValue:J,filter:O}},e=>{let t=null;return(f&&0===f.length||0===F.length)&&!I&&(e=""===x.value?this.props.noItemsText:format(e.filteredNoResultsText||Resources.NoFilterResults,x.value))&&(t=React.createElement("div",{className:"bolt-dropdown-no-items"},e)),React.createElement(React.Fragment,null,t,React.createElement(ListBox,{ariaLabel:l,className:k,columns:a,containerClassName:css("bolt-dropdown-list-box-container",c),didUpdate:this.listBoxDidUpdate,enforceSingleSelect:h,excludeFocusZone:m,excludeTabStop:!0,searchResultsLoadingText:b,focuszoneProps:null,getUnselectableRanges:C,items:f?f.value:F,loading:M,onActivate:U,onSelect:K,onToggle:A,renderItem:j,ref:Z,searching:I,selection:q,showChecksColumn:void 0===N||N,showItemsWhileSearching:G,showTree:H}))}),React.createElement(Observer,{actions:e},e=>{var t=this.props.actions;return t&&t.length?React.createElement("div",{className:"bolt-actions-container flex-column"},ObservableLike.getValue(t).map((e,t)=>React.createElement(Button,Object.assign({key:e.id||t,subtle:!0,excludeTabStop:!0},e)))):null}))))}}DropdownCalloutComponent.defaultProps={width:DefaultWidth,ignoreMouseDown:!0};export{DropdownCallout,DropdownCalloutComponent};