import * as React from "react"; import { classList, ContainerProps, fireClickOnEnter } from "../util"; export interface ButtonViewProps extends ContainerProps { buttonRef?: (ref: HTMLElement) => void; title: string; label?: string | JSX.Element; labelClassName?: string; leftIcon?: string; rightIcon?: string; disabled?: boolean; // Disables the button in an accessible-friendly way. hardDisabled?: boolean; // Disables the button and prevents clicks. Not recommended. Use `disabled` instead. href?: string; target?: string; tabIndex?: number; style?: React.CSSProperties; /** Miscellaneous aria pass-through props */ ariaControls?: string; ariaExpanded?: boolean; ariaHasPopup?: string; ariaPosInSet?: number; ariaSetSize?: number; ariaSelected?: boolean; ariaPressed?: boolean | "mixed"; } export interface ButtonProps extends ButtonViewProps { onClick: () => void; onClickEvent?: (e: React.MouseEvent) => void; onRightClick?: () => void; onBlur?: () => void; onFocus?: () => void; onKeydown?: (e: React.KeyboardEvent) => void; } export const Button = (props: ButtonProps) => { const inflated = inflateButtonProps(props); return ( ); } export const ButtonBody = (props: ButtonViewProps) => { const { label, labelClassName, leftIcon, rightIcon, children } = props; return ( <> {(leftIcon || rightIcon || label) && ( {leftIcon && } {label} {rightIcon && } )} {children} ) } export function inflateButtonProps(props: ButtonProps) { const { id, className, style, ariaLabel, ariaHidden, ariaDescribedBy, ariaControls, ariaExpanded, ariaHasPopup, ariaPosInSet, ariaSetSize, ariaSelected, ariaPressed, role, onClick, onClickEvent, onRightClick, onKeydown, onBlur, onFocus, buttonRef, title, hardDisabled, href, target, tabIndex, } = props; let { disabled } = props; disabled = disabled || hardDisabled; const classes = classList( "common-button", className, disabled && "disabled" ); let clickHandler = (ev: React.MouseEvent) => { if (onClickEvent) onClickEvent(ev); if (onClick) onClick(); if (href) window.open(href, target || "_blank", "noopener,noreferrer") ev.stopPropagation(); ev.preventDefault(); } let rightClickHandler = (ev: React.MouseEvent) => { if (onRightClick) { onRightClick(); ev.stopPropagation(); ev.preventDefault(); } } return { "id": id, "className": classes, "style": style, "title": title, "ref": buttonRef, "onClick": !disabled ? clickHandler : undefined, "onContextMenu": rightClickHandler, "onKeyDown": onKeydown || fireClickOnEnter, "onBlur": onBlur, "onFocus": onFocus, "role": role || "button", "tabIndex": tabIndex || (disabled ? -1 : 0), "disabled": hardDisabled, "aria-label": ariaLabel, "aria-hidden": ariaHidden, "aria-controls": ariaControls, "aria-expanded": ariaExpanded, "aria-haspopup": ariaHasPopup as any, "aria-posinset": ariaPosInSet, "aria-setsize": ariaSetSize, "aria-describedby": ariaDescribedBy, "aria-selected": ariaSelected, "aria-pressed": ariaPressed, }; }