mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 17:30:46 +00:00
Initial Move from Azure DevOps to GitHub
This commit is contained in:
280
src/Explorer/Controls/CommandButton/CommandButtonComponent.tsx
Normal file
280
src/Explorer/Controls/CommandButton/CommandButtonComponent.tsx
Normal file
@@ -0,0 +1,280 @@
|
||||
import { StringUtils } from "../../../Utils/StringUtils";
|
||||
import { KeyCodes } from "../../../Common/Constants";
|
||||
import 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 {
|
||||
/**
|
||||
* 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<CommandButtonComponentProps> {
|
||||
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<HTMLDivElement>): 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 <CommandButtonComponent key={key} {...options} />;
|
||||
}
|
||||
|
||||
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 <React.Fragment />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="commandExpand"
|
||||
tabIndex={0}
|
||||
ref={(ref: HTMLElement) => {
|
||||
this.expandButtonElt = ref;
|
||||
}}
|
||||
onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => this.onLauncherKeyDown(e)}
|
||||
>
|
||||
<div className="commandDropdownLauncher">
|
||||
<span className="partialSplitter" />
|
||||
<span className="expandDropdown">
|
||||
<img src={CollapseChevronDownIcon} />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="commandDropdownContainer"
|
||||
ref={(ref: HTMLElement) => {
|
||||
this.dropdownElt = ref;
|
||||
}}
|
||||
>
|
||||
<div className="commandDropdown">
|
||||
{this.props.children.map(
|
||||
(c: CommandButtonComponentProps, index: number): JSX.Element => {
|
||||
return CommandButtonComponent.renderButton(c, `${index}`);
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public static renderLabel(
|
||||
props: CommandButtonComponentProps,
|
||||
key?: string,
|
||||
refct?: (input: HTMLElement) => void
|
||||
): JSX.Element {
|
||||
if (!props.commandButtonLabel) {
|
||||
return <React.Fragment />;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="commandLabel" key={key} ref={refct}>
|
||||
{props.commandButtonLabel}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<div className="commandButtonReact">
|
||||
<span
|
||||
className={mainClassName}
|
||||
role="menuitem"
|
||||
tabIndex={this.props.tabIndex}
|
||||
onKeyPress={(e: React.KeyboardEvent<HTMLSpanElement>) => 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<HTMLSpanElement>) => this.commandClickCallback(e)}
|
||||
>
|
||||
<div className={contentClassName}>
|
||||
<img className="commandIcon" src={this.props.iconSrc} alt={this.props.iconAlt} />
|
||||
{CommandButtonComponent.renderLabel(this.props)}
|
||||
</div>
|
||||
</span>
|
||||
{this.props.children && this.renderChildren()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user