azure-devops-ui
Version:
React components for building web UI in Azure DevOps
1 lines • 6.5 kB
JavaScript
import"../../CommonImports";import"../../Core/core.css";import"./Autocomplete.css";import*as React from"react";import{ObservableValue,ObservableLike}from"../../Core/Observable";import{Callout}from"../../Callout";import{Label}from"../Label/Label";import{KeyCode,getSafeId}from"../../Util";import{Suggestions}from"./Suggestions";import{Location}from"../../Utilities/Position";import{FocusZoneContext}from"../../FocusZone";class Autocomplete extends React.Component{constructor(e){super(e),this.currentSelectedColorIndex=new ObservableValue(0),this.inputRef=React.createRef(),this.onBlur=e=>{this.setState({displayPlaceholderText:!1})},this.onCheckForExactSuggestionMatches=e=>-1!=e.findIndex(e=>e.content===ObservableLike.getValue(this.props.value)),this.onFocus=e=>{this.props.onFocus&&this.props.onFocus(e),this.setState({displayPlaceholderText:!0})},this.onInputChange=e=>{this.props.onInputValueChange(e.currentTarget.value)},this.onKeyDown=e=>{if(this.props.onKeyDown&&this.props.onKeyDown(e),!e.isDefaultPrevented()){var t=ObservableLike.getValue(this.props.value),o=this.props.onCheckForDuplicateInParent(t),s=this.state.currentSuggestions[this.state.currentSuggestionIndex];if(this.state.displayCallout)if(e.which===KeyCode.tab&&s)this.props.onInputValueChange(s.content),e.preventDefault();else if(e.which===KeyCode.downArrow){var i=o?this.state.currentSuggestions.length-1:this.state.currentSuggestions.length,n=this.state.currentSuggestionIndex+1;this.setState({currentSuggestionIndex:i<n?0:n}),e.preventDefault()}else if(e.which===KeyCode.upArrow){i=o?this.state.currentSuggestions.length-1:this.state.currentSuggestions.length,n=this.state.currentSuggestionIndex-1;this.setState({currentSuggestionIndex:n<0?i:n}),e.preventDefault()}else{if(o)return;e.which===KeyCode.rightArrow&&this.isNewRowSelected()?(this.currentSelectedColorIndex.value=Math.min(this.currentSelectedColorIndex.value+1,Autocomplete.DEFAULT_COLORS.length-1),e.preventDefault()):e.which===KeyCode.leftArrow&&this.isNewRowSelected()&&(this.currentSelectedColorIndex.value=Math.max(this.currentSelectedColorIndex.value-1,0),e.preventDefault())}i=t.trim(),n=""!==i&&this.props.onSubmit&&!o;e.which===KeyCode.enter&&n?s?this.submit(s):this.submit({content:i,color:!this.props.disableColorPicker&&Autocomplete.DEFAULT_COLORS[this.currentSelectedColorIndex.value]}):e.which===KeyCode.comma&&(n&&this.submit({content:i,color:!this.props.disableColorPicker&&Autocomplete.DEFAULT_COLORS[this.currentSelectedColorIndex.value]}),e.preventDefault())}},this.onPipClick=(e,t,o)=>{this.props.onSubmit&&this.props.onSubmit({content:ObservableLike.getValue(this.props.value),color:t})},this.onNewLabelClick=e=>{this.props.onSubmit&&this.props.onSubmit({content:ObservableLike.getValue(this.props.value)})},this.onSuggestionClick=(e,t)=>{this.submit(t)},this.onValueChange=t=>{if(clearTimeout(this.loadingDelayTimeoutId),""===t.trim())this.setState({displayCallout:!1,currentSuggestions:[]});else{const e=()=>this.setState({isLoading:!0,displayCallout:!0});this.state.displayCallout?e():this.loadingDelayTimeoutId=setTimeout(()=>{e()},200),this.props.suggestionProvider(t).then(e=>{t===ObservableLike.getValue(this.props.value)&&(clearTimeout(this.loadingDelayTimeoutId),this.setState({currentSuggestions:e,isLoading:!1,displayCallout:!0,displayTypeAhead:!0}))})}this.setState({displayTypeAhead:!1,currentSuggestionIndex:0,currentSuggestions:[]})},this.state={currentSuggestionIndex:0,currentSuggestions:[],displayCallout:!1,displayPlaceholderText:!1,displayTypeAhead:!1,isLoading:!1}}render(){const{ariaDescribedBy:t,className:o,customColors:e,disableColorPicker:s=!1,onCheckForDuplicateInParent:i,onDuplicateInParentText:n,placeholder:r,value:a}=this.props,{currentSuggestions:l,currentSuggestionIndex:u,displayCallout:c,isLoading:h,displayTypeAhead:p,displayPlaceholderText:d}=this.state,g=ObservableLike.getValue(a);var b=l[u]?l[u].content:"";const m=this.getTypeAheadValue(g,b,p),C=e||Autocomplete.DEFAULT_COLORS,S=this.state.currentSuggestions[this.state.currentSuggestionIndex];return React.createElement(FocusZoneContext.Consumer,null,e=>React.createElement("div",{"aria-expanded":c,"aria-haspopup":"listbox","aria-owns":getSafeId("autocomplete-listbox"),className:"bolt-label-autocomplete",role:"combobox"},React.createElement("input",{"aria-activedescendant":c&&S&&S.content,"aria-autocomplete":"both","aria-controls":getSafeId("autocomplete-listbox"),"aria-describedby":getSafeId(t),className:o,"data-focuszone":e.focuszoneId,onBlur:this.onBlur,onChange:this.onInputChange,onFocus:this.onFocus,onKeyDown:this.onKeyDown,placeholder:d?r:void 0,ref:this.inputRef,tabIndex:0,type:"text",value:g}),React.createElement("input",{type:"text",className:"suggestion",value:m,disabled:!0}),c&&React.createElement(Callout,{anchorElement:this.inputRef.current,anchorOffset:{horizontal:0,vertical:10},anchorOrigin:{horizontal:Location.start,vertical:Location.end},calloutOrigin:{horizontal:Location.start,vertical:Location.start},className:"bolt-label-suggestions-callout",contentShadow:!0},React.createElement(Suggestions,{currentSelectedColorIndex:this.currentSelectedColorIndex,currentSelectedIndex:u,disableColorPicker:s,inputAlreadyInGroupText:n,isCurrentInputAlreadyInGroup:i(g),isLoading:h,onCheckForExactMatch:this.onCheckForExactSuggestionMatches,onColorPipClick:this.onPipClick,onNewLabelClick:this.onNewLabelClick,onSuggestionClick:this.onSuggestionClick,suggestedItems:l,swatchPickerColors:C}))))}componentDidMount(){ObservableLike.subscribe(this.props.value,this.onValueChange)}componentWillUnmount(){clearTimeout(this.loadingDelayTimeoutId),ObservableLike.unsubscribe(this.props.value,this.onValueChange)}UNSAFE_componentWillReceiveProps(e){ObservableLike.unsubscribe(this.props.value,this.onValueChange),ObservableLike.subscribe(e.value,this.onValueChange)}focus(){this.inputRef.current.focus()}getTypeAheadValue(e,t,o){return o?e.concat(t.substr(e.length)):""}isNewRowSelected(){return this.state.currentSuggestionIndex===this.state.currentSuggestions.length&&""!=ObservableLike.getValue(this.props.value)}submit(e){this.props.onSubmit&&this.props.onSubmit(e),clearTimeout(this.loadingDelayTimeoutId),this.currentSelectedColorIndex.value=0,this.setState({currentSuggestions:[]})}}Autocomplete.DEFAULT_COLORS=[Label.DEFAULT_COLOR,{red:255,green:255,blue:0},{red:235,green:257,blue:128},{red:229,green:150,blue:182},{red:191,green:165,blue:221},{red:168,green:191,blue:243},{red:153,green:207,blue:198}];export{Autocomplete};