azure-devops-ui
Version:
React components for building web UI in Azure DevOps
1 lines • 10.8 kB
JavaScript
import"../../CommonImports";import"../../Core/core.css";import"./Splitter.css";import*as React from"react";import{EventManagement}from"../../Core/EventManagement";import{ObservableLike,ObservableValue}from"../../Core/Observable";import{announce}from"../../Core/Util/Accessibility";import{format}from"../../Core/Util/String";import{Button}from"../../Button";import{Observer}from"../../Observer";import*as Resources from"../../Resources.Splitter";import{css,getSafeId,KeyCode}from"../../Util";import{FixedSizeLimitsFormat,SplitterDirection,SplitterElementPosition}from"../../Components/Splitter/Splitter.Props";const DIVIDER_MOVE_INCREMENT=20,DIVIDER_WIDTH=4,COLLAPSED_PANE_SIZE=38;let idCount=0;class Splitter extends React.Component{constructor(e,t){super(e,t),this._cachedNearElement=null,this._cachedFarElement=null,this.events=new EventManagement,this.uncontrolledFixedSize=new ObservableValue(void 0),this.placeholderPosition=new ObservableValue(void 0),this.collapse=()=>{this.isCollapsed()||(this.props.onCollapsedChanged&&this.props.onCollapsedChanged(!0),announce(Resources.SplitterCollapsed))},this.expand=()=>{this.isCollapsed()&&(this.props.onCollapsedChanged&&this.props.onCollapsedChanged(!1),announce(Resources.SplitterExpanded))},this._onDividerKeyDown=e=>{var{disabled:t,splitterDirection:i}=this.props;if(!t&&!this._isDragging()){switch(e.keyCode){case KeyCode.leftArrow:i===SplitterDirection.Vertical&&this._moveDivider(-DIVIDER_MOVE_INCREMENT);break;case KeyCode.rightArrow:i===SplitterDirection.Vertical&&this._moveDivider(DIVIDER_MOVE_INCREMENT);break;case KeyCode.upArrow:i===SplitterDirection.Horizontal&&this._moveDivider(-DIVIDER_MOVE_INCREMENT);break;case KeyCode.downArrow:i===SplitterDirection.Horizontal&&this._moveDivider(DIVIDER_MOVE_INCREMENT);break;default:return}e.preventDefault(),e.stopPropagation()}},this._onDividerMouseDown=e=>{this._onDividerDown(e,e.clientX,e.clientY),this._attachMouseWindowEvents()},this._onDividerTouchDown=e=>{1===e.touches.length&&(this._onDividerDown(e,e.touches[0].clientX,e.touches[0].clientY),this._attachTouchWindowEvents())},this._onDividerDown=(e,t,i)=>{this._fixedRef&&!this.props.disabled&&(e.preventDefault(),e.stopPropagation(),this._dragAnchorPos=this._getEventBoundedClientPos(t,i),this._previousFixedSize=this._getElementSize(this._fixedRef),void 0!==this.placeholderPosition.value&&(this.placeholderPosition.value=void 0),this._handleDragEvent(e,t,i))},this._onDividerMouseMove=e=>{this._handleDragEvent(e,e.clientX,e.clientY)},this._onDividerTouchMove=e=>{1===e.touches.length&&this._handleDragEvent(e,e.touches[0].clientX,e.touches[0].clientY)},this._onDividerMouseUp=e=>{this._detachMouseWindowEvents(),this._onDividerEnd(e.clientX,e.clientY)},this._onDividerTouchEnd=e=>{this._detachTouchWindowEvents(),this._onDividerEnd(e.changedTouches[0].clientX,e.changedTouches[0].clientY)},this._onDividerEnd=(e,t)=>{e=this._getEventBoundedClientPos(e,t),t=this._getNewFixedSize(this._previousFixedSize,e-this._dragAnchorPos);this.placeholderPosition.value=void 0,this._setFixedSize(t),this._fireWindowResize()},this.refresh=()=>{this.forceUpdate()},this.uncontrolledFixedSize.value=e.initialFixedSize,this.fixedPaneId="splitter-fixed-pane"+idCount++}get maxFixedSize(){return this._getSizeLimitValue(this.props.maxFixedSize)}get minFixedSize(){return this._getSizeLimitValue(this.props.minFixedSize)}componentDidMount(){this._fireWindowResize(),this.props.fixedSizeLimitsFormat===FixedSizeLimitsFormat.Percentage&&(window.addEventListener("resize",this.refresh),this.refresh())}componentWillUnmount(){this.events.removeAllListeners(),window.removeEventListener("resize",this.refresh)}render(){const{className:e,collapsed:t,fixedElement:i,onRenderFarElement:r,onRenderNearElement:s,splitterDirection:n}=this.props,o=i===SplitterElementPosition.Near?!!s:!!r;return React.createElement(Observer,{collapsed:t,fixedSize:void 0===this.props.fixedSize?this.uncontrolledFixedSize:this.props.fixedSize,placeholderPosition:this.placeholderPosition},t=>{let i;var r=this.maxFixedSize,s=this.minFixedSize;if(t.collapsed)i=COLLAPSED_PANE_SIZE;else if(t.fixedSize){i=Math.max(t.fixedSize,s||0);let e=r;(e=!e&&this._splitterContainer?this._getElementSize(this._splitterContainer):e)&&i>e&&(i=e)}else void 0!==s?i=s:void 0!==r&&(i=r);return React.createElement("div",{className:css(e,"vss-Splitter--container",n===SplitterDirection.Vertical&&"vss-Splitter--container-row",n===SplitterDirection.Horizontal&&"vss-Splitter--container-column",this._isDragging()&&"vss-Splitter--container-dragging"),ref:e=>this._splitterContainer=e},this._renderNearElement(i),o?this._renderDivider(i):null,this._renderDragPlaceHolder(),this._renderFarElement(i))})}_renderNearElement(e){var{fixedElement:t,onRenderNearElement:i,nearElementClassName:r}=this.props;return this._isDragging()&&this._cachedNearElement||(i?(i=i(),this._cachedNearElement=t===SplitterElementPosition.Near?this._renderFixedPane(i,r,e):this._renderFlexiblePane(i,r)):this._cachedNearElement=null),this._cachedNearElement}_renderFarElement(e){var{fixedElement:t,onRenderFarElement:i,farElementClassName:r}=this.props;return this._isDragging()&&this._cachedFarElement||(i?(i=i(),this._cachedFarElement=t===SplitterElementPosition.Far?this._renderFixedPane(i,r,e):this._renderFlexiblePane(i,r)):this._cachedFarElement=null),this._cachedFarElement}_renderFixedPane(e,t,i){var{expandTooltip:r,splitterDirection:s}=this.props,n=this.isCollapsed(),s={[s===SplitterDirection.Vertical?"width":"height"]:void 0===i?"50%":i-DIVIDER_WIDTH-1};return e?React.createElement("div",{className:css("vss-Splitter--pane-fixed",n?"flex-column collapsed":t),id:getSafeId(this.fixedPaneId),style:s,ref:e=>this._fixedRef=e},n?React.createElement(Button,{className:"vss-splitter-expand-button",iconProps:{iconName:this.getCollapsedButtonIconName()},onClick:this.expand,subtle:!0,tooltipProps:{text:r||Resources.ExpandTooltip}}):e):null}getCollapsedButtonIconName(){var e=this.props.fixedElement===SplitterElementPosition.Far;return this.props.splitterDirection===SplitterDirection.Vertical?e?"DoubleChevronLeft":"DoubleChevronRight":e?"DoubleChevronUp":"DoubleChevronDown"}_renderFlexiblePane(e,t){return React.createElement("div",{className:css("vss-Splitter--pane-flexible",t)},e)}_renderDivider(e){var{startBound:t,endBound:i}=this._getSplitterBoundaries();let r=0;return this._fixedRef&&(r=this._getElementSize(this._fixedRef)),React.createElement("div",{"aria-valuemin":t,"aria-valuemax":i-DIVIDER_WIDTH-1,"aria-label":this.props.ariaLabel,"aria-labelledby":this.props.ariaLabel?void 0:this.props.ariaLabelledBy||getSafeId(this.fixedPaneId),"aria-orientation":this.props.splitterDirection===SplitterDirection.Horizontal?"horizontal":"vertical","aria-valuenow":e?e-DIVIDER_WIDTH-1:r,"aria-valuetext":format(Resources.SplitterValueText,e?e-DIVIDER_WIDTH-1:r),role:"separator",tabIndex:0,className:css("vss-Splitter--divider",this._isDragging()&&"vss-Splitter--divider-dragging"),onKeyDown:this._onDividerKeyDown,onMouseDown:this._onDividerMouseDown,onTouchStart:this._onDividerTouchDown})}_renderDragPlaceHolder(){var e;return this._isDragging()?(e={[this.props.splitterDirection===SplitterDirection.Vertical?"left":"top"]:this.placeholderPosition.value},React.createElement("div",{className:"vss-Splitter--drag-placeholder",style:e})):null}_handleDragEvent(e,t,i){var r=this.props["fixedElement"],e=(e.preventDefault(),e.stopPropagation(),this._getEventBoundedClientPos(t,i)),t=this._getNewFixedSize(this._previousFixedSize,e-this._dragAnchorPos),i=t.collapsed?0:t.fixedSize,e=r===SplitterElementPosition.Near?i:this._getElementSize(this._splitterContainer)-i-DIVIDER_WIDTH;e!==this.placeholderPosition.value&&(this.placeholderPosition.value=e)}_setFixedSize(e){var t=this.props["onFixedSizeChanged"];e.collapsed?this.collapse():(e=e.fixedSize,this.uncontrolledFixedSize.value=e,t&&t(e),this.isCollapsed()&&this.expand())}_moveDivider(e){var t=this._getElementSize(this._fixedRef),t=this._getNewFixedSize(t,e);this._setFixedSize(t),this._fireWindowResize()}_attachMouseWindowEvents(){this.events.addEventListener(window,"mousemove",this._onDividerMouseMove),this.events.addEventListener(window,"mouseup",this._onDividerMouseUp)}_detachMouseWindowEvents(){this.events.removeEventListener(window,"mousemove",this._onDividerMouseMove),this.events.removeEventListener(window,"mouseup",this._onDividerMouseUp)}_attachTouchWindowEvents(){this.events.addEventListener(window,"touchmove",this._onDividerTouchMove),this.events.addEventListener(window,"touchend",this._onDividerTouchEnd)}_detachTouchWindowEvents(){this.events.removeEventListener(window,"touchmove",this._onDividerTouchMove),this.events.removeEventListener(window,"touchend",this._onDividerTouchEnd)}_getEventBoundedClientPos(e,t){var i=this.props["splitterDirection"];let r;switch(i){case SplitterDirection.Vertical:r=e;break;case SplitterDirection.Horizontal:r=t;break;default:r=0}return this._getBoundedClientPos(r)}_getBoundedClientPos(e){var{startBound:t,endBound:i}=this._getSplitterBoundaries(!!this.props.onCollapsedChanged);return Math.max(t,Math.min(e,i))-this._getElementStartPos(this._splitterContainer)}_getSplitterBoundaries(e=!1){var t=this.props.fixedElement;let i=this.minFixedSize;var r=this.maxFixedSize;if(!this._splitterContainer)return{startBound:0,endBound:0};e&&(i=0);var e=this._getElementStartPos(this._splitterContainer),s=e+this._getElementSize(this._splitterContainer);return{startBound:t===SplitterElementPosition.Near?i?e+i:e:r?s-r:e,endBound:t===SplitterElementPosition.Near?r?e+r:s:i?s-i:s}}_getNewFixedSize(e,t){var{fixedElement:i,onCollapsedChanged:r}=this.props;let s=this.maxFixedSize;var n=this.minFixedSize||0;void 0===s&&(s=this._getElementSize(this._splitterContainer));let o=t,l=(i===SplitterElementPosition.Far&&(o*=-1),e+o),a=(l>s&&(l=s),this.isCollapsed());return r&&(a=l<COLLAPSED_PANE_SIZE||!this.isCollapsed()&&l<n),{fixedSize:l=l<n?n:l,collapsed:a}}isCollapsed(){return!!ObservableLike.getValue(this.props.collapsed)}_isDragging(){return void 0!==this.placeholderPosition.value}_getElementSize(e){return this.props.splitterDirection===SplitterDirection.Vertical?e.clientWidth:e.clientHeight}_getElementStartPos(e){e=e.getBoundingClientRect();return this.props.splitterDirection===SplitterDirection.Vertical?e.left:e.top}_fireWindowResize(){var e=document.createEvent("Event");e.initEvent("resize",!1,!0),window.dispatchEvent(e)}_getSizeLimitValue(e){return this.props.fixedSizeLimitsFormat!==FixedSizeLimitsFormat.Percentage?e:e&&this._splitterContainer?e*this._getElementSize(this._splitterContainer):void 0}}Splitter.defaultProps={fixedElement:SplitterElementPosition.Far,splitterDirection:SplitterDirection.Vertical,fixedSizeLimitsFormat:FixedSizeLimitsFormat.Pixels};export{Splitter};