1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 15:37:51 +02:00

common: button typings improvements (#2139)

This commit is contained in:
Alexander Skvortsov
2020-04-30 17:09:43 -04:00
committed by GitHub
parent 91522f84c5
commit a7937edac7
2 changed files with 43 additions and 25 deletions

View File

@@ -5,46 +5,64 @@ import extractText from '../utils/extractText';
import LoadingIndicator from './LoadingIndicator'; import LoadingIndicator from './LoadingIndicator';
export interface ButtonProps extends ComponentProps { export interface ButtonProps extends ComponentProps {
/**
* A tooltip for the button.
*/
title?: string; title?: string;
/**
* An html type attribute for the button.
*/
type?: string; type?: string;
/**
* The name of the icon class. If specified, the button will be given a
* 'has-icon' class name.
*/
icon?: string; icon?: string;
/**
* Whether or not the button should be in a disabled loading state.
*/
loading?: boolean; loading?: boolean;
/**
* Whether or not the button is disabled. If truthy, the button
* will be given a 'disabled' class name, and any `onclick` handler will be
* removed.
*/
disabled?: boolean; disabled?: boolean;
/**
* A callback to run when the button is clicked.
*/
onclick?: Function; onclick?: Function;
} }
/** /**
* The `Button` component defines an element which, when clicked, performs an * The `Button` component defines an element which, when clicked, performs an
* action. The button may have the following special props: * action.
*
* - `icon` The name of the icon class. If specified, the button will be given a
* 'has-icon' class name.
* - `disabled` Whether or not the button is disabled. If truthy, the button
* will be given a 'disabled' class name, and any `onclick` handler will be
* removed.
* - `loading` Whether or not the button should be in a disabled loading state.
*
* All other props will be assigned as attributes on the button element.
* *
* Note that a Button has no default class names. This is because a Button can * Note that a Button has no default class names. This is because a Button can
* be used to represent any generic clickable control, like a menu item. * be used to represent any generic clickable control, like a menu item.
*/ */
export default class Button<T extends ButtonProps = ButtonProps> extends Component<T> { export default class Button<T extends ButtonProps = ButtonProps> extends Component<T> {
view() { view() {
const { children, ...attrs } = this.props; const attrs: T = { ...this.props };
const children = extract(attrs, 'children');
attrs.className = attrs.className || ''; attrs.className = attrs.className || '';
attrs.type = attrs.type || 'button'; attrs.type = attrs.type || 'button';
// If a tooltip was provided for buttons without additional content, we also // If a tooltip was provided for buttons without additional content, we also
// use this tooltip as text for screen readers // use this tooltip as text for screen readers
if (attrs.title && !this.props.children) { if (attrs.title && !children) {
attrs['aria-label'] = attrs.title; attrs['aria-label'] = attrs.title;
} }
// If nothing else is provided, we use the textual button content as tooltip // If nothing else is provided, we use the textual button content as tooltip
if (!attrs.title && this.props.children) { if (!attrs.title && children) {
attrs.title = extractText(this.props.children); attrs.title = extractText(this.props.children);
} }

View File

@@ -1,24 +1,24 @@
import Button, { ButtonProps } from './Button'; import Button, { ButtonProps } from './Button';
interface LinkButtonProps extends ButtonProps { export interface LinkButtonProps extends ButtonProps {
/**
* Whether or not the page that this button links to is currently active.
*/
active?: boolean; active?: boolean;
oncreate?: Function;
/**
* The URL to link to. If the current URL `m.route()` matches this,
* the `active` prop will automatically be set to true.
*/
href?: string; href?: string;
oncreate?: Function;
} }
/** /**
* The `LinkButton` component defines a `Button` which links to a route. * The `LinkButton` component defines a `Button` which links to a route.
*
* ### Props
*
* All of the props accepted by `Button`, plus:
*
* - `active` Whether or not the page that this button links to is currently
* active.
* - `href` The URL to link to. If the current URL `m.route()` matches this,
* the `active` prop will automatically be set to true.
*/ */
export default class LinkButton extends Button<LinkButtonProps> { export default class LinkButton<T extends LinkButtonProps = LinkButtonProps> extends Button<T> {
static initProps(props: LinkButtonProps) { static initProps(props: LinkButtonProps) {
props.active = this.isActive(props); props.active = this.isActive(props);
} }