azure-devops-ui
Version:
React components for building web UI in Azure DevOps
1 lines • 11 kB
JavaScript
import"../../CommonImports";import"../../Core/core.css";import"./Dropdown.css";import*as React from"react";import{ObservableArray,ObservableLike,ObservableValue}from"../../Core/Observable";import{TimerManagement}from"../../Core/TimerManagement";import*as Utils_Accessibility from"../../Core/Util/Accessibility";import{format}from"../../Core/Util/String";import{FilteredListSelection,renderListCell}from"../../List";import{getListBoxItemsValue,getUnselectableRanges,ListBoxItemType,wrapListBoxItems}from"../../ListBox";import{ItemsObserver,Observer}from"../../Observer";import*as Resources from"../../Resources.Dropdown";import{SimpleTableCell}from"../../Table";import{css}from"../../Util";import{DropdownSelection}from"../../Utilities/DropdownSelection";import{getItemsValue}from"../../Utilities/Provider";import{DropdownCallout}from"./DropdownCallout";import{DropdownExpandableTextField}from"./DropdownExpandableTextField";class Dropdown extends React.Component{constructor(e){super(e),this.expandable=React.createRef(),this.expandableContainer=React.createRef(),this.filterText=new ObservableValue(""),this.collapse=()=>{this.expandable.current&&this.expandable.current.collapse()},this.expand=()=>{this.expandable.current&&this.expandable.current.expand()},this.onDismiss=()=>{this.expandable.current&&this.expandable.current.collapse()},this.onExpand=()=>{this.props.onExpand&&this.props.onExpand(),this.updateFilteredItems(),this.state.expanded.value=!0},this.onCollapse=()=>{this.props.onCollapse&&this.props.onCollapse(),this.state.expanded.value=!1},this.onActivate=(e,t)=>{var r;e.defaultPrevented||"keydown"!==e.type||((r=!this.props.enforceSingleSelect&&this.state.filteredSelection.multiSelect)?this.state.filteredSelection.toggle(this.state.filteredItems.value.indexOf(t),this.state.filteredSelection.alwaysMerge,r):this.state.filteredSelection.select(this.state.filteredItems.value.indexOf(t),1,this.state.filteredSelection.alwaysMerge,r),this.onSelect(e,t))},this.onFilterTextChanged=(e,t)=>{this.filterText.value=t,this.debouncedUpdateFilteredItems()},this.onSelect=(e,t)=>{var{dismissOnSelect:r,onSelect:s}=this.props,i=this.parentSelection;s&&s(e,t),(void 0!==r?r:0<i.value.length&&(this.props.enforceSingleSelect||!i.multiSelect)&&!i.selectOnFocus)&&(this.filterText.value="",this.onDismiss())},this.selectionChanged=(e,t)=>(this.state.filteredSelection.selectionChanged(e,t),!0),this.renderCallout=(e,t,r,s,i,l,o)=>{const{actions:a,ariaLabel:n,calloutContentClassName:d,columns:p,containerClassName:h,filterPlaceholderText:c,filteredNoResultsText:m,getUnselectableRanges:u,items:x,loading:f,noItemsText:I,onFilterTextChanged:g,onToggle:b,portalProps:T,renderItem:y,renderBeforeContent:v,searching:S,showChecksColumn:C,showFilterBox:L,showItemsWhileSearching:w,showTree:B,startsWithSort:F,userFilteredItems:R}=this.props;let D=this.props.width;void 0===D&&this.expandableContainer.current&&(O=null!=(O=this.props.minCalloutWidth)?O:100,D=Math.max(this.expandableContainer.current.clientWidth,O));var{filteredItems:O,filterText:A,filteredSelection:M}=this.state,r={actions:a,anchorElement:r,anchorOffset:s,anchorOrigin:i,anchorPoint:l,ariaLabel:n,calloutContentClassName:d,columns:p,containerClassName:h,dropdownOrigin:o,filteredItems:O,filteredNoResultsText:m,selection:M,filterPlaceholderText:c,filterText:A,getUnselectableRanges:u,id:t,items:x,loading:f,noItemsText:I,onActivate:this.onActivate,onFilterTextChanged:(e,t)=>{g&&g(e,t),this.onFilterTextChanged&&this.onFilterTextChanged(e,t)},onDismiss:this.onDismiss,onSelect:this.onSelect,onToggle:b,portalProps:T,renderBeforeContent:v,renderItem:y,searching:S,showChecksColumn:C,showItemsWhileSearching:w,showFilterBox:L,showTree:B,startsWithSort:F,updateFilteredItems:this.updateFilteredItems,userFilteredItems:R,width:D};return this.props.renderCallout(r)},this.updateFilteredItems=()=>(updateFilteredItems(this.props,this.state),!0),this.debouncedUpdateFilteredItems=()=>{updateFilteredItems(this.props,this.state)},this.parentSelection=e.selection||new DropdownSelection;var t=wrapListBoxItems(e.items),r=getListBoxItemsValue(t||e.items);this.timerManagement=new TimerManagement,this.state={expanded:new ObservableValue(!1),filteredItems:new ObservableArray([...r]),filteredSelection:new FilteredListSelection(this.parentSelection),filterText:this.filterText,props:e,wrappedItems:t}}static getDerivedStateFromProps(e,t){return e.userFilteredItems===t.props.userFilteredItems&&e.items===t.props.items||updateFilteredItems(e,t),Object.assign(Object.assign({},t),{props:e,wrappedItems:wrapListBoxItems(e.items)})}componentDidMount(){this.props.filterThrottleWait&&(this.debouncedUpdateFilteredItems=this.timerManagement.debounce(this.debouncedUpdateFilteredItems,this.props.filterThrottleWait))}render(){const{ariaLabel:e,ariaLabelledBy:t,ariaDescribedBy:r,autoSelect:s,className:i,disableAutocomplete:l,disabled:o,enforceSingleSelect:a,excludeTabStop:n,inputId:d,items:p,placeholder:h,renderExpandable:c,renderSelectedItems:m,role:u,showPrefix:x,required:f}=this.props;var I={observableValue:this.parentSelection,filter:this.selectionChanged};return React.createElement(ItemsObserver,{getUnselectableRanges:this.props.getUnselectableRanges,items:p,selection:this.parentSelection},React.createElement(Observer,{selection:I},()=>c({ariaLabel:e,ariaLabelledBy:t,ariaDescribedBy:r,autoSelect:s,className:css(i,"bolt-dropdown-expandable"),containerRef:this.expandableContainer,disabled:o,disableAutocomplete:l,enforceSingleSelect:a,excludeTabStop:n,inputId:d,placeholder:h,onCollapse:this.onCollapse,onExpand:this.onExpand,expandableRef:this.expandable,renderCallout:this.renderCallout,items:getListBoxItemsValue(this.state.wrappedItems||p),role:u,renderSelectedItems:m,selection:this.parentSelection,showPrefix:x,required:f})))}focus(){this.expandable.current&&this.expandable.current.focus()}}function filterItemByText(e,t){return!(!t.text||t.type===ListBoxItemType.Header||t.type===ListBoxItemType.Divider||t.type===ListBoxItemType.Loading)&&-1!==t.text.toLowerCase().indexOf(e.toLowerCase())}function filterItemByTextStartsWith(e,t){return!(!t.text||t.type===ListBoxItemType.Header||t.type===ListBoxItemType.Divider||t.type===ListBoxItemType.Loading)&&t.text.toLowerCase().startsWith(e.toLowerCase())}function renderDropdownSelectedItemText(e,t){t=t[e.value[0].beginIndex];let r=t&&t.text||"";return r=1<e.selectedCount?`${r} (+${e.selectedCount-1})`:r}Dropdown.defaultProps={filterByText:!0,filterItem:filterItemByText,getUnselectableRanges:getUnselectableRanges,renderCallout:DropdownCallout,renderExpandable:DropdownExpandableTextField,renderSelectedItems:renderDropdownSelectedItemText};let announcementInterval;function updateFilteredItems(r,e){announcementInterval&&clearTimeout(announcementInterval);const{filteredSelection:t,filterText:s}=e;let i=[];var l=getListBoxItemsValue(e.wrappedItems||r.items);let o=l;if(r.userFilteredItems){o=getItemsValue(r.userFilteredItems);var a=r.userFilteredItemsIndexMap&&r.userFilteredItemsIndexMap.value;if(a)i=a;else for(let t=0;t<r.userFilteredItems.length;t++){var n=l.findIndex(e=>e.id===o[t].id);i.push(n)}}for(r.filterByText&&s.value&&(a=filterItems(o,s.value,i,r.filterItem,r.startsWithSort),o=a.filteredItems,i=a.filteredIndexMap);o.length&&o[0].type===ListBoxItemType.Divider;)o.shift(),i.shift();return announcementInterval=setTimeout(()=>{if(!ObservableLike.getValue(r.searching)&&!ObservableLike.getValue(r.loading)&&e.expanded.value)if(s.value){let e=Resources.NoFilterResults;r.filteredNoResultsText&&(e=ObservableLike.getValue(r.filteredNoResultsText)),Utils_Accessibility.announce(0<o.length?format(Resources.AnnounceFilterResultCount,o.length):e,!0)}else 0===o.length&&r.noItemsText?Utils_Accessibility.announce(r.noItemsText,!0):0<o.length&&Utils_Accessibility.announce(format(Resources.AnnounceItemCount,o.length))},500),t.updateFilteredSelection(i,!r.enforceSingleSelect&&void 0),e.filteredItems.value=o,!0}function filterItems(p,h,c=[],m=filterItemByText,e=!1){var u=[],x=[],f=[];if(h){let o,a=-1,n,d=-1;if(e){let r=[],s=[],i=[],l=[];for(let e=0,t=p.length;e<t;e++){var I,g=p[e],b=c.length?c[e]:e;g.type===ListBoxItemType.Header||g.type===ListBoxItemType.Divider?((r.length||s.length)&&(u.push(...r),u.push(...s),x.push(...i),x.push(...l),r=[],s=[],i=[],l=[]),g.type===ListBoxItemType.Header?(o=g,a=b):g.type===ListBoxItemType.Divider&&(n=g,d=b)):(I=filterItemByTextStartsWith(h,g))?(n&&n.groupId===g.groupId&&(r.push(n),i.push(d),n=void 0),o&&o.groupId===g.groupId&&(r.push(o),i.push(a),o=void 0),r.push(g),i.push(b),f.push(Array.isArray(I)?I:[])):!(I=m(h,g,p))&&g.type!==ListBoxItemType.Loading||(n&&n.groupId===g.groupId&&(r.push(n),i.push(d),n=void 0),o&&o.groupId===g.groupId&&(r.push(o),i.push(a),o=void 0),s.push(g),l.push(b),f.push(Array.isArray(I)?I:[]))}u.push(...r),u.push(...s),x.push(...i),x.push(...l)}else for(let e=0,t=p.length;e<t;e++){var r,s=p[e],i=c.length?c[e]:e;s.type===ListBoxItemType.Header?(o=s,a=i):s.type===ListBoxItemType.Divider?(n=s,d=i):!(r=m(h,s,p))&&s.type!==ListBoxItemType.Loading||(n&&n.groupId===s.groupId&&(u.push(n),x.push(d),n=void 0),o&&o.groupId===s.groupId&&(u.push(o),x.push(a),o=void 0),u.push(s),x.push(i),f.push(Array.isArray(r)?r:[]))}}return{filteredItems:u,filteredIndexMap:x,filterMatches:f}}function filterTreeItems(t,e,r=[],s=filterItemByText,i=filterMatchedItemByListboxType){var e=filterItems(t,e,r,s),r=e.filteredIndexMap,s=e.filteredItems.find(i),l={};for(const h of r){var o=t[h];let e=o.parent;for(;e;)(l[t.indexOf(e)]=e).expanded=!0,e=e.parent;l[h]=o}var a=[],n=[];for(const c of Object.keys(l)){var d=Number(c),p=l[d];a.push(d),n.push(p)}return[{filteredIndexMap:a,filteredItems:n,filterMatches:[]},s?t.indexOf(s):-1]}function filterMatchedItemByListboxType(e){return!e.type||e.type===ListBoxItemType.Row}function renderHighlightedText(e,t,r,s,i){let l=s;return i&&s.text&&(l=Object.assign(Object.assign({},s),{textNode:getHighlightedText(s.text,i)})),React.createElement(SimpleTableCell,{className:css(r.className,s.className,s.type===ListBoxItemType.Header&&"bolt-list-box-header"),columnIndex:t,key:t,tableColumn:r},React.createElement("div",{id:s.type===ListBoxItemType.Header?"header-"+s.id:void 0,"aria-label":s.type===ListBoxItemType.Header?format(Resources.HeaderAriaLabel,s.text):void 0},renderListCell(l)))}function getHighlightedText(t,r,e){var s=[];let i=-1;for(let e=0;e<t.length;e++)-1!==r.indexOf(e)?s&&s[s.length-1]&&s[s.length-1].bold?s[i].text+=t.charAt(e):s[++i]={text:t.charAt(e),bold:!0}:s&&s[s.length-1]&&!s[s.length-1].bold?s[i].text+=t.charAt(e):s[++i]={text:t.charAt(e),bold:!1};var l=[];for(let e=0;e<s.length;e++){var o=s[e];o.bold?l.push(React.createElement("span",{className:"font-weight-heavy",key:t+"-"+e},o.text)):l.push(o.text)}return React.createElement("span",{className:e},l)}export{Dropdown,filterItemByText,filterItemByTextStartsWith,renderDropdownSelectedItemText,filterItems,filterTreeItems,filterMatchedItemByListboxType,renderHighlightedText,getHighlightedText};