UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

78 lines (77 loc) 4.95 kB
import "../../CommonImports"; import "../../Core/core.css"; import * as React from "react"; import { WrappingBehavior } from "./LabelGroup.Props"; import { Label } from "../Label/Label"; import { css, getSafeId } from '../../Util'; import { FocusZone, FocusZoneDirection } from '../../FocusZone'; import { ObservableValue, ObservableLike } from '../../Core/Observable'; import { FocusWithin } from '../../FocusWithin'; import { Observer } from '../../Observer'; export class LabelGroup extends React.Component { constructor(props) { super(props); this.contentSelectionMap = {}; this.labelReferences = []; this.onLabelMouseDown = (event, model, index) => { const { disableMouseFocusOnLabels = true, onLabelMouseDown } = this.props; onLabelMouseDown && onLabelMouseDown(event, model, index); if (disableMouseFocusOnLabels) { event.preventDefault(); } }; this.onLabelsChanged = (changes) => { const selectedSet = new Set(ObservableLike.getValue(this.props.selectedLabelContents)); changes.removedItems && changes.removedItems.forEach((model) => { this.contentSelectionMap[model.content] = undefined; }); changes.addedItems && changes.addedItems.forEach((model) => { this.contentSelectionMap[model.content] = new ObservableValue(selectedSet.has(model.content)); }); return true; }; this.onSelectedKeysChanged = (newData) => { this.updateKeySelectionMap(newData.addedItems, newData.removedItems); return false; }; this.buildContentSelectionMap(ObservableLike.getValue(props.labelProps), props.selectedLabelContents ? ObservableLike.getValue(props.selectedLabelContents) : []); } focusLabel(index) { this.labelReferences[index] && this.labelReferences[index].focus(); } render() { const { className, defaultFocusElementId = "label-0", enableHoverStyles = false, fadeOutOverflow = false, id, labelProps, onLabelClick, onLabelKeyDown, selectedLabelContents, title, wrappingBehavior = WrappingBehavior.oneLine } = this.props; const wrappingClassName = wrappingBehavior == WrappingBehavior.oneLine ? "one-line" : "free-flow"; return (React.createElement("div", { className: css(className, "flex-column") }, title && React.createElement("div", { className: "bolt-labelgroup-title-wrapper body-m" }, title), React.createElement(FocusZone, { allowArrowOutOfInputs: true, direction: FocusZoneDirection.Horizontal, focusGroupProps: { defaultElementId: defaultFocusElementId } }, React.createElement("div", { className: css("bolt-labelgroup flex-row", wrappingClassName, fadeOutOverflow && "fade-out"), id: getSafeId(id) }, React.createElement(FocusWithin, null, (focusWithinStatus) => (React.createElement(React.Fragment, null, React.createElement(Observer, { labelProps: { observableValue: labelProps, filter: this.onLabelsChanged }, selectedLabelContents: { observableValue: selectedLabelContents, filter: this.onSelectedKeysChanged } }, (observerProps) => observerProps.labelProps && observerProps.labelProps.map((model, index) => (React.createElement(Label, Object.assign({}, model, { enableHover: enableHoverStyles, id: `label-${index}`, key: model.content, onBlur: focusWithinStatus.onBlur, onClick: (event) => onLabelClick && onLabelClick(event, model, index), onFocus: focusWithinStatus.onFocus, onKeyDown: (event) => onLabelKeyDown && onLabelKeyDown(event, model, index), onMouseDown: (event) => this.onLabelMouseDown(event, model, index), ref: (label) => (this.labelReferences[index] = label), selected: this.contentSelectionMap[model.content] }))))), this.props.children))))))); } buildContentSelectionMap(labelProps, selectedLabels) { this.contentSelectionMap = {}; const selectedSet = new Set(selectedLabels); labelProps.forEach((model) => { this.contentSelectionMap[model.content] = new ObservableValue(selectedSet.has(model.content)); }); } updateKeySelectionMap(newlySelectedLabels, noLongerSelectedLabels) { newlySelectedLabels && newlySelectedLabels.forEach((value) => { if (this.contentSelectionMap[value]) { this.contentSelectionMap[value].value = true; } }); noLongerSelectedLabels && noLongerSelectedLabels.forEach((value) => { if (this.contentSelectionMap[value]) { this.contentSelectionMap[value].value = false; } }); } }