UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

97 lines (96 loc) 6.71 kB
import "../../CommonImports"; import "../../Core/core.css"; import "./ColorPicker.css"; import * as React from "react"; import { wait } from '../../Core/Util/Promise'; import { Button } from '../../Button'; import { Callout, ContentSize } from '../../Callout'; import { FocusZone, FocusZoneDirection, FocusZoneKeyStroke } from '../../FocusZone'; import { SimpleTableCell, Table } from '../../Table'; import { css, KeyCode } from '../../Util'; import { colorItems, colorRowProvider } from "./Utils"; export class ColorDropdownCalloutComponent extends React.Component { constructor() { super(...arguments); this._focusedColumn = 0; this.renderCell = (rowIndex, columnIndex, tableColumn, tableRow, ariaRowIndex) => { var _a; const cell = tableRow.cells[columnIndex]; const selectedIdx = (_a = this.props.selection) === null || _a === void 0 ? void 0 : _a.value[0].beginIndex; const selected = cell === colorItems[selectedIdx !== null && selectedIdx !== void 0 ? selectedIdx : 0]; return (React.createElement(SimpleTableCell, { ariaRowIndex: ariaRowIndex, columnIndex: columnIndex, key: columnIndex, tableColumn: tableColumn }, React.createElement(Button, { id: `${rowIndex}-${columnIndex}`, className: css(selected && "bolt-dropdown-init-focus", "color-button flex-grow"), style: { backgroundColor: "#" + cell.id }, tooltipProps: { text: cell.text }, onClick: e => { var _a; const idx = colorItems.findIndex(ci => ci.id === cell.id); if (idx >= 0) { (_a = this.props.selection) === null || _a === void 0 ? void 0 : _a.select(idx); this.props.onSelect && this.props.onSelect(e, colorItems[idx]); this.props.onDismiss(); } }, onFocus: () => (this._focusedColumn = columnIndex), // hack to prevent <tr> from getting focused onKeyDown: e => { if (columnIndex === 0 && e.which === KeyCode.leftArrow) { e.preventDefault(); } } }))); }; this.columns = [ { id: "c1", renderCell: this.renderCell, width: -100 / 11 }, { id: "c2", renderCell: this.renderCell, width: -100 / 11 }, { id: "c3", renderCell: this.renderCell, width: -100 / 11 }, { id: "c4", renderCell: this.renderCell, width: -100 / 11 }, { id: "c5", renderCell: this.renderCell, width: -100 / 11 }, { id: "c6", renderCell: this.renderCell, width: -100 / 11 }, { id: "c7", renderCell: this.renderCell, width: -100 / 11 }, { id: "c8", renderCell: this.renderCell, width: -100 / 11 }, { id: "c9", renderCell: this.renderCell, width: -100 / 11 }, { id: "c10", renderCell: this.renderCell, width: -100 / 11 }, { id: "c11", renderCell: this.renderCell, width: -100 / 11 } ]; } render() { const { anchorElement, anchorOffset, anchorOrigin, anchorPoint, blurDismiss = true, calloutContentClassName, contentLocation, dropdownOrigin, excludeTabStop, id, lightDismiss, onFilterKeyDown } = this.props; const focusOnMount = true; const onDismiss = () => { if (this.props.onDismiss) { this.props.onDismiss(); } }; return (React.createElement(Callout, { anchorElement: anchorElement, anchorOffset: anchorOffset, anchorOrigin: anchorOrigin, anchorPoint: anchorPoint, blurDismiss: blurDismiss, calloutOrigin: dropdownOrigin, contentClassName: css(calloutContentClassName, "bolt-dropdown flex-column custom-scrollbar v-scroll-auto h-scroll-hidden color-dropdown-callout"), contentLocation: contentLocation, contentShadow: true, contentSize: ContentSize.Auto, escDismiss: true, id: id, lightDismiss: lightDismiss, focuszoneProps: { postprocessKeyStroke: event => { // dismiss the callout on tab key instead of letting the // browser handle the tab key, since with React.portals it // will move to the body, instead of the next tabbable element after // the dropdown. if (event.which === KeyCode.tab && !event.defaultPrevented) { event.preventDefault(); onDismiss(); return FocusZoneKeyStroke.IgnoreAll; } return FocusZoneKeyStroke.IgnoreNone; } }, onDismiss: onDismiss }, React.createElement(FocusZone, { circularNavigation: true, defaultActiveElement: ".bolt-dropdown-init-focus", direction: FocusZoneDirection.Vertical, focusOnMount: focusOnMount !== undefined ? focusOnMount : true }, React.createElement("div", { className: "bolt-dropdown-container no-outline", onKeyDown: onFilterKeyDown }, React.createElement("div", { "aria-hidden": "true", className: "no-outline", tabIndex: !excludeTabStop ? -1 : undefined, role: "listbox" }), React.createElement(Table, { columns: this.columns, containerClassName: "color-dropdown-table-container", itemProvider: colorRowProvider, onFocus: async (reactEvent, r) => { // when the table is focused, try to focus the correct button const evt = reactEvent.nativeEvent; // Sometimes FocusZone correctly focuses the right button. If we also focus it, that // screws up FocusZone's counting. So we have to wait a sec and check to see if the // button is already focused to avoid double focusing. await wait(0); if (evt.target.tagName === "TR") { const row = evt.target; // tslint:disable-next-line: no-unnecessary-type-assertion the type assertion is necessary, tslint const button = row.querySelector(`td[data-column-index="${this._focusedColumn}"] button`); if (button && button !== document.activeElement) { button.focus(); } } } }))))); } }