UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

99 lines (98 loc) 5.92 kB
import "../../CommonImports"; import "../../Core/core.css"; import "./Autocomplete.css"; import * as React from "react"; import * as Resources from '../../Resources.Label'; import { css, getSafeId } from '../../Util'; import { Spinner, SpinnerSize } from '../../Spinner'; import { Label } from "../Label/Label"; import { ColorPip, ColorSwatchPicker } from '../../Color'; import { Icon } from '../../Icon'; export class Suggestions extends React.Component { constructor(props) { super(props); this.currentSelectedElementRef = React.createRef(); this.onHoverNewRowEnd = () => { this.setState({ isNewRowHovered: false }); }; this.onHoverNewRowStart = () => { this.setState({ isNewRowHovered: true }); }; this.onRenderAlreadyIncludedRow = () => { const { inputAlreadyInGroupText = Resources.LabelInGroup } = this.props; return (React.createElement("div", { className: "bolt-label-suggestions-row flex-row", key: "included" }, React.createElement(Icon, { className: "bolt-label-suggestions-icon", iconName: "CheckMark" }), React.createElement("div", { className: "bolt-label-suggestions-row--content" }, inputAlreadyInGroupText))); }; this.onRenderLoadingRow = () => { return (React.createElement("div", { className: "bolt-label-suggestions-loading-row", key: "loading" }, React.createElement(Spinner, { size: SpinnerSize.small, label: Resources.LoadingSuggestions }))); }; this.onRenderNewLabelRow = (colors) => { let content; if (this.shouldDisplayColorPicker()) { content = (React.createElement(ColorSwatchPicker, { className: css(this.isNewRowSelected() && "selected"), colors: colors, onPipClick: this.props.onColorPipClick, selectedIndex: this.props.currentSelectedColorIndex })); } else { content = (React.createElement("div", { className: css("bolt-label-suggestions-row clickable flex-row", this.isNewRowSelected() && "selected"), onClick: this.props.onNewLabelClick, role: "option", tabIndex: -1 }, React.createElement(ColorPip, { color: this.props.disableColorPicker && Label.DEFAULT_COLOR }), React.createElement("div", { className: "bolt-label-suggestions-row--content" }, Resources.NewLabelSuggestionText))); } return (React.createElement("div", { className: "bolt-label-suggestions-newRow-wrapper", key: "newRow", onMouseEnter: this.onHoverNewRowStart, onMouseLeave: this.onHoverNewRowEnd }, content)); }; this.onRenderSuggestionRow = (labelModel, index) => { const isSelected = this.props.currentSelectedIndex === index; return (React.createElement("div", { "aria-selected": isSelected, className: css("bolt-label-suggestions-row clickable flex-row", isSelected && "selected"), id: getSafeId(labelModel.content), key: labelModel.content, onClick: (event) => this.props.onSuggestionClick(event, labelModel), ref: isSelected && this.currentSelectedElementRef, role: "option", tabIndex: -1 }, React.createElement(ColorPip, { color: labelModel.color }), React.createElement("div", { className: "bolt-label-suggestions-row--content" }, React.createElement("span", null, labelModel.content)))); }; this.state = { isNewRowHovered: false }; } render() { const { isCurrentInputAlreadyInGroup, isLoading, onCheckForExactMatch, suggestedItems, swatchPickerColors } = this.props; const minWidth = swatchPickerColors.length * 32; // Determine items to render const calloutItems = []; const renderLoadingRow = isLoading; const renderIncludedRow = isCurrentInputAlreadyInGroup; const renderNewLabelRow = !renderIncludedRow && (onCheckForExactMatch === undefined || !onCheckForExactMatch(suggestedItems)); if (renderLoadingRow) { calloutItems.push(this.onRenderLoadingRow()); } suggestedItems.length > 0 && calloutItems.push(React.createElement("div", { className: "bolt-label-suggestions-list", key: "suggestions" }, suggestedItems.map(this.onRenderSuggestionRow))); if (renderIncludedRow) { calloutItems.push(this.onRenderAlreadyIncludedRow()); } if (renderNewLabelRow) { calloutItems.push(this.onRenderNewLabelRow(swatchPickerColors)); } // Interleave separators as necessary const calloutContents = []; calloutItems.forEach((element, index) => { index !== 0 && calloutContents.push(React.createElement("div", { className: "bolt-suggestions-separator", key: "separator" + index })); calloutContents.push(element); }); return (React.createElement("div", { className: "bolt-label-suggestions-container flex-column", id: getSafeId("autocomplete-listbox"), role: "listbox", style: { minWidth: minWidth } }, calloutContents)); } componentDidUpdate() { if (this.currentSelectedElementRef.current && this.currentSelectedElementRef.current !== this.previousSelectedElement) { this.currentSelectedElementRef.current.scrollIntoView(false); this.previousSelectedElement = this.currentSelectedElementRef.current; } } isNewRowSelected() { return this.props.currentSelectedIndex === this.props.suggestedItems.length; } shouldDisplayColorPicker() { const { disableColorPicker = false } = this.props; return !disableColorPicker && (this.isNewRowSelected() || this.state.isNewRowHovered); } }