UNPKG

@hypothesis/frontend-shared

Version:

Shared components, styles and utilities for Hypothesis projects

182 lines (169 loc) 5.29 kB
var _jsxFileName = "/home/runner/work/frontend-shared/frontend-shared/src/components/buttons.js"; import classnames from 'classnames'; import { SvgIcon } from './SvgIcon'; /** * @typedef ButtonProps * @prop {import('preact').Ref<HTMLButtonElement>} [buttonRef] * @prop {string} [classes] - Optional CSS class name(s) to use _in addition_ * to the button component's own clases * @prop {string} [className] - Optional CSS class name that will _replace_ * the button component's own classes * @prop {string|symbol} [icon] - Name of `SvgIcon` to render in the button * @prop {'left'|'right'} [iconPosition] - Icon positioned to left or to * right of button text * @prop {boolean} [expanded] - Is the element associated with this button * expanded (set `aria-expanded`) * @prop {never} [aria-expanded] - Use `expanded` prop instead * @prop {boolean} [pressed] - Is this button currently "active?" (set * `aria-pressed` or `aria-selected` depending on button `role`) * @prop {never} [aria-pressed] - Use `pressed` prop instead * @prop {'small'|'medium'|'large'} [size='medium'] - Relative button size: * affects padding * @prop {string} [title] - Button title; used for `aria-label` attribute * @prop {never} [aria-label] - Use `title` prop instead * @prop {'normal'|'primary'|'light'|'dark'} [variant='normal'] - For styling: element variant */ /** * Fold in HTML button prop definitions into ButtonProps, but ignore `size` because it's inherited * from HTMLElement and conflicts with the _ButtonProps.size prop above. Ignore `icon` * because it is typed to `string` only and we need to be able to accept {string|symbol} * * @typedef {Omit<import('preact').JSX.HTMLAttributes<HTMLButtonElement>, 'size' | 'icon'> } HTMLButtonElementProps * @typedef {ButtonProps & HTMLButtonElementProps} ButtonBaseProps */ /** * @typedef IconButtonBaseProps * @prop {string|symbol} icon - Icon is required for icon buttons * @prop {string} title - Title is required for icon buttons * @prop {never} [children] - children are not allowed (use LabeledButton instead) */ /** * @typedef {ButtonBaseProps & IconButtonBaseProps} IconButtonProps */ /** * @param {ButtonBaseProps} props */ import { jsxDEV as _jsxDEV } from "preact/jsx-dev-runtime"; function ButtonBase({ // Custom props. buttonRef, classes, className, icon, iconPosition = 'left', size = 'medium', variant = 'normal', expanded, pressed, // Standard <button> props. type = 'button', ...restProps }) { var _restProps$role; const role = (_restProps$role = restProps === null || restProps === void 0 ? void 0 : restProps.role) !== null && _restProps$role !== void 0 ? _restProps$role : 'button'; const ariaProps = { 'aria-label': restProps.title }; // aria-pressed and aria-expanded are not allowed for buttons with // an aria role of `tab`. Instead, the aria-selected attribute is expected. if (role === 'tab') { ariaProps['aria-selected'] = pressed; } else { ariaProps['aria-pressed'] = pressed; ariaProps['aria-expanded'] = expanded; } return _jsxDEV("button", { ref: buttonRef, className: classnames(className, `${className}--${size}`, `${className}--${variant}`, { [`${className}--icon-${iconPosition}`]: icon }, classes), type: type, ...ariaProps, ...restProps }, void 0, false, { fileName: _jsxFileName, lineNumber: 82, columnNumber: 5 }, this); } /** * An icon-only button * * @deprecated - Use re-implemented component in the input group * @param {IconButtonProps} props */ export function IconButton({ className = 'Hyp-IconButton', ...restProps }) { const { icon } = restProps; return _jsxDEV(ButtonBase, { className: className, ...restProps, children: _jsxDEV(SvgIcon, { name: icon }, void 0, false, { fileName: _jsxFileName, lineNumber: 110, columnNumber: 7 }, this) }, void 0, false, { fileName: _jsxFileName, lineNumber: 109, columnNumber: 5 }, this); } /** * A labeled button, with or without an icon * * @deprecated - Use re-implemented component in the input group * @param {ButtonBaseProps} props */ export function LabeledButton({ children, className = 'Hyp-LabeledButton', ...restProps }) { const { icon, iconPosition = 'left' } = restProps; return _jsxDEV(ButtonBase, { className: className, ...restProps, children: [icon && iconPosition === 'left' && _jsxDEV(SvgIcon, { name: icon }, void 0, false, { fileName: _jsxFileName, lineNumber: 129, columnNumber: 43 }, this), children, icon && iconPosition === 'right' && _jsxDEV(SvgIcon, { name: icon }, void 0, false, { fileName: _jsxFileName, lineNumber: 131, columnNumber: 44 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 128, columnNumber: 5 }, this); } /** * A button styled to appear as an HTML link (<a>) * * @param {ButtonBaseProps} props */ export function LinkButton(props) { return _jsxDEV(ButtonBase, { className: "Hyp-LinkButton", ...props }, void 0, false, { fileName: _jsxFileName, lineNumber: 142, columnNumber: 10 }, this); } //# sourceMappingURL=buttons.js.map