azure-devops-ui
Version:
React components for building web UI in Azure DevOps
78 lines (77 loc) • 4.95 kB
JavaScript
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;
}
});
}
}