import * as StringUtils from "../../../Utils/StringUtils"; import { KeyCodes } from "../../../Common/Constants"; import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor"; import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants"; import CollapseChevronDownIcon from "../../../../images/QueryBuilder/CollapseChevronDown_16x.png"; /** * React component for Command button component. */ import * as React from "react"; import { ArcadiaMenuPickerProps } from "../Arcadia/ArcadiaMenuPicker"; /** * Options for this component */ export interface CommandButtonComponentProps { /** * font icon name for the button */ iconName?: string; /** * image source for the button icon */ iconSrc?: string; /** * image alt for accessibility */ iconAlt?: string; /** * Click handler for command button click */ onCommandClick: (e: React.SyntheticEvent) => void; /** * Label for the button */ commandButtonLabel?: string; /** * True if this button opens a tab or pane, false otherwise. */ hasPopup: boolean; /** * Enabled/disabled state of command button */ disabled?: boolean; /** * Whether or not the button should have the 'selectedButton' styling */ isSelected?: boolean; /** * Text to displayed in the tooltip on hover */ tooltipText?: string; /** * tabindex for the command button */ tabIndex?: number; /** * Childrens command buttons to hide in the dropdown */ children?: CommandButtonComponentProps[]; /** * Optional id */ id?: string; /** * Optional class name */ className?: string; /** * If true, display as dropdown */ isDropdown?: boolean; /** * Placeholder if dropdown */ dropdownPlaceholder?: string; /** * Dropdown selection */ dropdownSelectedKey?: string; /** * This is the key of the dropdown item * The text is commandLabel */ dropdownItemKey?: string; /** * Possible width */ dropdownWidth?: number; /** * Vertical bar to divide buttons */ isDivider?: boolean; /** * Aria-label for the button */ ariaLabel: string; //TODO: generalize customized command bar /** * If set to true, will render arcadia picker */ isArcadiaPicker?: boolean; /** * props to render arcadia picker */ arcadiaProps?: ArcadiaMenuPickerProps; } export class CommandButtonComponent extends React.Component { private dropdownElt: HTMLElement; private expandButtonElt: HTMLElement; public componentDidUpdate(): void { if (!this.dropdownElt || !this.expandButtonElt) { return; } const dropdownElt = $(this.dropdownElt).offset({ left: $(this.expandButtonElt).offset().left }); } private onKeyPress(event: React.KeyboardEvent): boolean { if (event.keyCode === KeyCodes.Space || event.keyCode === KeyCodes.Enter) { this.commandClickCallback && this.commandClickCallback(event); event.stopPropagation(); return false; } return true; } private onLauncherKeyDown(event: React.KeyboardEvent): boolean { if (event.keyCode === KeyCodes.DownArrow) { $(this.dropdownElt).hide(); $(this.dropdownElt).show().focus(); event.stopPropagation(); return false; } if (event.keyCode === KeyCodes.UpArrow) { $(this.dropdownElt).hide(); event.stopPropagation(); return false; } return true; } private getCommandButtonId(): string { if (this.props.id) { return this.props.id; } else { return `commandButton-${StringUtils.stripSpacesFromString(this.props.commandButtonLabel)}`; } } public static renderButton(options: CommandButtonComponentProps, key?: string): JSX.Element { return ; } private commandClickCallback(e: React.SyntheticEvent): void { if (this.props.disabled) { return; } // TODO Query component's parent, not document const el = document.querySelector(".commandDropdownContainer") as HTMLElement; if (el) { el.style.display = "none"; } this.props.onCommandClick(e); TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, { commandButtonClicked: this.props.commandButtonLabel, }); } private renderChildren(): JSX.Element { if (!this.props.children || this.props.children.length < 1) { return ; } return (
{ this.expandButtonElt = ref; }} onKeyDown={(e: React.KeyboardEvent) => this.onLauncherKeyDown(e)} >
{ this.dropdownElt = ref; }} >
{this.props.children.map( (c: CommandButtonComponentProps, index: number): JSX.Element => { return CommandButtonComponent.renderButton(c, `${index}`); } )}
); } public static renderLabel( props: CommandButtonComponentProps, key?: string, refct?: (input: HTMLElement) => void ): JSX.Element { if (!props.commandButtonLabel) { return ; } return ( {props.commandButtonLabel} ); } public render(): JSX.Element { let mainClassName = "commandButtonComponent"; if (this.props.disabled) { mainClassName += " commandDisabled"; } if (this.props.isSelected) { mainClassName += " selectedButton"; } let contentClassName = "commandContent"; if (this.props.children && this.props.children.length > 0) { contentClassName += " hasHiddenItems"; } return (
) => this.onKeyPress(e)} title={this.props.tooltipText} id={this.getCommandButtonId()} aria-disabled={this.props.disabled} aria-haspopup={this.props.hasPopup} aria-label={this.props.ariaLabel} onClick={(e: React.MouseEvent) => this.commandClickCallback(e)} >
{this.props.iconAlt} {CommandButtonComponent.renderLabel(this.props)}
{this.props.children && this.renderChildren()}
); } }