diff --git a/app/javascript/flavours/glitch/components/button.jsx b/app/javascript/flavours/glitch/components/button.jsx
deleted file mode 100644
index bdeeeac999..0000000000
--- a/app/javascript/flavours/glitch/components/button.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import classNames from 'classnames';
-
-export default class Button extends PureComponent {
-
- static propTypes = {
- text: PropTypes.node,
- onClick: PropTypes.func,
- disabled: PropTypes.bool,
- block: PropTypes.bool,
- secondary: PropTypes.bool,
- className: PropTypes.string,
- title: PropTypes.string,
- children: PropTypes.node,
- };
-
- handleClick = (e) => {
- if (!this.props.disabled) {
- this.props.onClick(e);
- }
- };
-
- setRef = (c) => {
- this.node = c;
- };
-
- focus() {
- this.node.focus();
- }
-
- render () {
- let attrs = {
- className: classNames('button', this.props.className, {
- 'button-secondary': this.props.secondary,
- 'button--block': this.props.block,
- }),
- disabled: this.props.disabled,
- onClick: this.handleClick,
- ref: this.setRef,
- };
-
- if (this.props.title) attrs.title = this.props.title;
-
- return (
-
- );
- }
-
-}
diff --git a/app/javascript/flavours/glitch/components/button.tsx b/app/javascript/flavours/glitch/components/button.tsx
new file mode 100644
index 0000000000..0b6a0f267e
--- /dev/null
+++ b/app/javascript/flavours/glitch/components/button.tsx
@@ -0,0 +1,58 @@
+import { useCallback } from 'react';
+
+import classNames from 'classnames';
+
+interface BaseProps extends React.ButtonHTMLAttributes {
+ block?: boolean;
+ secondary?: boolean;
+ text?: JSX.Element;
+}
+
+interface PropsWithChildren extends BaseProps {
+ text?: never;
+}
+
+interface PropsWithText extends BaseProps {
+ text: JSX.Element;
+ children: never;
+}
+
+type Props = PropsWithText | PropsWithChildren;
+
+export const Button: React.FC = ({
+ text,
+ type = 'button',
+ onClick,
+ disabled,
+ block,
+ secondary,
+ className,
+ title,
+ children,
+ ...props
+}) => {
+ const handleClick = useCallback>(
+ (e) => {
+ if (!disabled && onClick) {
+ onClick(e);
+ }
+ },
+ [disabled, onClick],
+ );
+
+ return (
+
+ );
+};
diff --git a/app/javascript/flavours/glitch/features/account/components/header.jsx b/app/javascript/flavours/glitch/features/account/components/header.jsx
index 9a20eaf6ea..486d66c2a2 100644
--- a/app/javascript/flavours/glitch/features/account/components/header.jsx
+++ b/app/javascript/flavours/glitch/features/account/components/header.jsx
@@ -10,7 +10,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { Avatar } from 'flavours/glitch/components/avatar';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { Icon } from 'flavours/glitch/components/icon';
import { IconButton } from 'flavours/glitch/components/icon_button';
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/limited_account_hint.jsx b/app/javascript/flavours/glitch/features/account_timeline/components/limited_account_hint.jsx
index 5ea37a5d31..d28ad77c55 100644
--- a/app/javascript/flavours/glitch/features/account_timeline/components/limited_account_hint.jsx
+++ b/app/javascript/flavours/glitch/features/account_timeline/components/limited_account_hint.jsx
@@ -6,7 +6,7 @@ import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { revealAccount } from 'flavours/glitch/actions/accounts';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { domain } from 'flavours/glitch/initial_state';
const mapDispatchToProps = (dispatch, { accountId }) => ({
diff --git a/app/javascript/flavours/glitch/features/compose/components/publisher.jsx b/app/javascript/flavours/glitch/features/compose/components/publisher.jsx
index b509ed3473..67e17401d2 100644
--- a/app/javascript/flavours/glitch/features/compose/components/publisher.jsx
+++ b/app/javascript/flavours/glitch/features/compose/components/publisher.jsx
@@ -8,7 +8,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { length } from 'stringz';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { Icon } from 'flavours/glitch/components/icon';
import { maxChars } from 'flavours/glitch/initial_state';
diff --git a/app/javascript/flavours/glitch/features/directory/components/account_card.jsx b/app/javascript/flavours/glitch/features/directory/components/account_card.jsx
index 10dc7b6262..92fa84201e 100644
--- a/app/javascript/flavours/glitch/features/directory/components/account_card.jsx
+++ b/app/javascript/flavours/glitch/features/directory/components/account_card.jsx
@@ -16,7 +16,7 @@ import {
} from 'flavours/glitch/actions/accounts';
import { openModal } from 'flavours/glitch/actions/modal';
import { Avatar } from 'flavours/glitch/components/avatar';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { DisplayName } from 'flavours/glitch/components/display_name';
import { IconButton } from 'flavours/glitch/components/icon_button';
import Permalink from 'flavours/glitch/components/permalink';
diff --git a/app/javascript/flavours/glitch/features/filters/added_to_filter.jsx b/app/javascript/flavours/glitch/features/filters/added_to_filter.jsx
index 743d379474..25615b662a 100644
--- a/app/javascript/flavours/glitch/features/filters/added_to_filter.jsx
+++ b/app/javascript/flavours/glitch/features/filters/added_to_filter.jsx
@@ -6,7 +6,7 @@ import { FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { toServerSideType } from 'flavours/glitch/utils/filters';
const mapStateToProps = (state, { filterId }) => ({
diff --git a/app/javascript/flavours/glitch/features/follow_recommendations/index.jsx b/app/javascript/flavours/glitch/features/follow_recommendations/index.jsx
index 037794e18b..04fc2b06bc 100644
--- a/app/javascript/flavours/glitch/features/follow_recommendations/index.jsx
+++ b/app/javascript/flavours/glitch/features/follow_recommendations/index.jsx
@@ -13,7 +13,7 @@ import { requestBrowserPermission } from 'flavours/glitch/actions/notifications'
import { changeSetting, saveSettings } from 'flavours/glitch/actions/settings';
import { fetchSuggestions } from 'flavours/glitch/actions/suggestions';
import { markAsPartial } from 'flavours/glitch/actions/timelines';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import Column from 'flavours/glitch/features/ui/components/column';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
import imageGreeting from 'mastodon/../images/elephant_ui_greeting.svg';
diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx b/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx
index 986bf80b51..47854d72be 100644
--- a/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx
+++ b/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx
@@ -4,7 +4,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { ShortNumber } from 'flavours/glitch/components/short_number';
const messages = defineMessages({
diff --git a/app/javascript/flavours/glitch/features/interaction_modal/index.jsx b/app/javascript/flavours/glitch/features/interaction_modal/index.jsx
index 1afa852cfb..ce5219e352 100644
--- a/app/javascript/flavours/glitch/features/interaction_modal/index.jsx
+++ b/app/javascript/flavours/glitch/features/interaction_modal/index.jsx
@@ -11,7 +11,7 @@ import { throttle, escapeRegExp } from 'lodash';
import { openModal, closeModal } from 'flavours/glitch/actions/modal';
import api from 'flavours/glitch/api';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { Icon } from 'flavours/glitch/components/icon';
import { registrationsOpen, sso_redirect } from 'flavours/glitch/initial_state';
diff --git a/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.jsx b/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.jsx
index b088935285..25d71467d3 100644
--- a/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.jsx
+++ b/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.jsx
@@ -7,7 +7,7 @@ import { connect } from 'react-redux';
import { requestBrowserPermission } from 'flavours/glitch/actions/notifications';
import { changeSetting } from 'flavours/glitch/actions/settings';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { Icon } from 'flavours/glitch/components/icon';
import { IconButton } from 'flavours/glitch/components/icon_button';
diff --git a/app/javascript/flavours/glitch/features/report/category.jsx b/app/javascript/flavours/glitch/features/report/category.jsx
index e734058fac..9a3cc549e1 100644
--- a/app/javascript/flavours/glitch/features/report/category.jsx
+++ b/app/javascript/flavours/glitch/features/report/category.jsx
@@ -7,7 +7,7 @@ import { List as ImmutableList } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import Option from './components/option';
diff --git a/app/javascript/flavours/glitch/features/report/comment.jsx b/app/javascript/flavours/glitch/features/report/comment.jsx
index a7305e8f3e..81efa7b5f7 100644
--- a/app/javascript/flavours/glitch/features/report/comment.jsx
+++ b/app/javascript/flavours/glitch/features/report/comment.jsx
@@ -11,7 +11,7 @@ import { createSelector } from 'reselect';
import Toggle from 'react-toggle';
import { fetchAccount } from 'flavours/glitch/actions/accounts';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
const messages = defineMessages({
diff --git a/app/javascript/flavours/glitch/features/report/rules.jsx b/app/javascript/flavours/glitch/features/report/rules.jsx
index 7a2aa59bd8..96903f1dec 100644
--- a/app/javascript/flavours/glitch/features/report/rules.jsx
+++ b/app/javascript/flavours/glitch/features/report/rules.jsx
@@ -6,7 +6,7 @@ import { FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import Option from './components/option';
diff --git a/app/javascript/flavours/glitch/features/report/statuses.jsx b/app/javascript/flavours/glitch/features/report/statuses.jsx
index c1650c8dce..181b561625 100644
--- a/app/javascript/flavours/glitch/features/report/statuses.jsx
+++ b/app/javascript/flavours/glitch/features/report/statuses.jsx
@@ -7,7 +7,7 @@ import { OrderedSet } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
import StatusCheckBox from 'flavours/glitch/features/report/containers/status_check_box_container';
diff --git a/app/javascript/flavours/glitch/features/report/thanks.jsx b/app/javascript/flavours/glitch/features/report/thanks.jsx
index fb16e6c80a..7782022b77 100644
--- a/app/javascript/flavours/glitch/features/report/thanks.jsx
+++ b/app/javascript/flavours/glitch/features/report/thanks.jsx
@@ -11,7 +11,7 @@ import {
muteAccount,
blockAccount,
} from 'flavours/glitch/actions/accounts';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
const mapStateToProps = () => ({});
diff --git a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx
index 9905301e79..c0268fbeb8 100644
--- a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx
+++ b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx
@@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { followAccount } from 'flavours/glitch/actions/accounts';
-import Button from 'flavours/glitch/components/button';
+import { Button } from 'flavours/glitch/components/button';
import { IconButton } from 'flavours/glitch/components/icon_button';
import Option from 'flavours/glitch/features/report/components/option';
import { languages as preloadedLanguages } from 'flavours/glitch/initial_state';
diff --git a/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx
index c2965d6173..af444a3ddb 100644
--- a/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx
@@ -8,7 +8,7 @@ import { connect } from 'react-redux';
import { blockAccount } from '../../../actions/accounts';
import { closeModal } from '../../../actions/modal';
import { initReport } from '../../../actions/reports';
-import Button from '../../../components/button';
+import { Button } from '../../../components/button';
import { makeGetAccount } from '../../../selectors';
@@ -52,10 +52,6 @@ class BlockModal extends PureComponent {
intl: PropTypes.object.isRequired,
};
- componentDidMount() {
- this.button.focus();
- }
-
handleClick = () => {
this.props.onClose();
this.props.onConfirm(this.props.account);
@@ -70,10 +66,6 @@ class BlockModal extends PureComponent {
this.props.onClose();
};
- setRef = (c) => {
- this.button = c;
- };
-
render () {
const { account } = this.props;
@@ -96,7 +88,7 @@ class BlockModal extends PureComponent {
-