73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
import {html} from 'htm/preact';
|
|
import {Component} from 'preact';
|
|
|
|
type Props = {
|
|
// Extra classes to add to the button.
|
|
cssClass: string;
|
|
// The click handler to call when confirmed.
|
|
clickHandler: (event: MouseEvent) => void;
|
|
// The class to add when in the confirm state.
|
|
confirmClass: string;
|
|
// The text to use when in the confirm state.
|
|
confirmText: string;
|
|
// The text to use when in the default state.
|
|
text: string;
|
|
// The timeout for the confirm state to return back to default.
|
|
timeout: number;
|
|
// The title to add to the element.
|
|
title: string;
|
|
};
|
|
|
|
type State = {
|
|
isConfirmed: boolean;
|
|
timeoutHandle?: number;
|
|
};
|
|
|
|
export class ConfirmButton extends Component<Props, State> {
|
|
state: State = {
|
|
isConfirmed: false,
|
|
timeoutHandle: undefined,
|
|
};
|
|
|
|
onClick = (event: MouseEvent) => {
|
|
const {clickHandler, timeout} = this.props;
|
|
const {isConfirmed, timeoutHandle} = this.state;
|
|
|
|
if (isConfirmed) {
|
|
clearTimeout(timeoutHandle);
|
|
clickHandler(event);
|
|
this.setState({
|
|
isConfirmed: false,
|
|
timeoutHandle: undefined,
|
|
});
|
|
return;
|
|
}
|
|
|
|
this.setState({
|
|
isConfirmed: true,
|
|
timeoutHandle: window.setTimeout(() => {
|
|
this.setState({isConfirmed: false});
|
|
}, timeout),
|
|
});
|
|
};
|
|
|
|
render() {
|
|
const {confirmClass, confirmText, cssClass, text, title} = this.props;
|
|
const {isConfirmed} = this.state;
|
|
|
|
const confirmedClass = isConfirmed ? confirmClass : '';
|
|
const buttonText = isConfirmed ? confirmText : text;
|
|
const buttonTitle = isConfirmed ? `Confirm ${title}` : title;
|
|
|
|
return html`
|
|
<button
|
|
class="${cssClass} ${confirmedClass}"
|
|
onClick=${this.onClick}
|
|
title="${buttonTitle}"
|
|
>
|
|
${buttonText}
|
|
</button>
|
|
`;
|
|
}
|
|
}
|