mirror of
https://github.com/mastodon/mastodon.git
synced 2025-11-28 10:30:49 +00:00
Add new ESLint rule requiring explicit button types (#36738)
This commit is contained in:
parent
1a31c412ca
commit
6337e036f3
|
|
@ -49,7 +49,11 @@ export const Alert: React.FC<{
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{hasAction && (
|
{hasAction && (
|
||||||
<button className='notification-bar__action' onClick={onActionClick}>
|
<button
|
||||||
|
className='notification-bar__action'
|
||||||
|
onClick={onActionClick}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
{action}
|
{action}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ export const Button: React.FC<Props> = ({
|
||||||
aria-live={loading !== undefined ? 'polite' : undefined}
|
aria-live={loading !== undefined ? 'polite' : undefined}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
title={title}
|
title={title}
|
||||||
|
// eslint-disable-next-line react/button-has-type -- set correctly via TS
|
||||||
type={type}
|
type={type}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export const ColumnBackButton: React.FC<{ onClick?: OnClickCallback }> = ({
|
||||||
const handleClick = useHandleClick(onClick);
|
const handleClick = useHandleClick(onClick);
|
||||||
|
|
||||||
const component = (
|
const component = (
|
||||||
<button onClick={handleClick} className='column-back-button'>
|
<button onClick={handleClick} className='column-back-button' type='button'>
|
||||||
<Icon
|
<Icon
|
||||||
id='chevron-left'
|
id='chevron-left'
|
||||||
icon={ArrowBackIcon}
|
icon={ArrowBackIcon}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ const BackButton: React.FC<{
|
||||||
compact: onlyIcon,
|
compact: onlyIcon,
|
||||||
})}
|
})}
|
||||||
aria-label={intl.formatMessage(messages.back)}
|
aria-label={intl.formatMessage(messages.back)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
id='chevron-left'
|
id='chevron-left'
|
||||||
|
|
@ -172,6 +173,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||||
<button
|
<button
|
||||||
className='text-btn column-header__setting-btn'
|
className='text-btn column-header__setting-btn'
|
||||||
onClick={handlePin}
|
onClick={handlePin}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='times' icon={CloseIcon} />{' '}
|
<Icon id='times' icon={CloseIcon} />{' '}
|
||||||
<FormattedMessage id='column_header.unpin' defaultMessage='Unpin' />
|
<FormattedMessage id='column_header.unpin' defaultMessage='Unpin' />
|
||||||
|
|
@ -185,6 +187,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||||
aria-label={intl.formatMessage(messages.moveLeft)}
|
aria-label={intl.formatMessage(messages.moveLeft)}
|
||||||
className='icon-button column-header__setting-btn'
|
className='icon-button column-header__setting-btn'
|
||||||
onClick={handleMoveLeft}
|
onClick={handleMoveLeft}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='chevron-left' icon={ChevronLeftIcon} />
|
<Icon id='chevron-left' icon={ChevronLeftIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -193,6 +196,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||||
aria-label={intl.formatMessage(messages.moveRight)}
|
aria-label={intl.formatMessage(messages.moveRight)}
|
||||||
className='icon-button column-header__setting-btn'
|
className='icon-button column-header__setting-btn'
|
||||||
onClick={handleMoveRight}
|
onClick={handleMoveRight}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='chevron-right' icon={ChevronRightIcon} />
|
<Icon id='chevron-right' icon={ChevronRightIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -203,6 +207,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||||
<button
|
<button
|
||||||
className='text-btn column-header__setting-btn'
|
className='text-btn column-header__setting-btn'
|
||||||
onClick={handlePin}
|
onClick={handlePin}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='plus' icon={AddIcon} />{' '}
|
<Icon id='plus' icon={AddIcon} />{' '}
|
||||||
<FormattedMessage id='column_header.pin' defaultMessage='Pin' />
|
<FormattedMessage id='column_header.pin' defaultMessage='Pin' />
|
||||||
|
|
@ -237,6 +242,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||||
collapsed ? messages.show : messages.hide,
|
collapsed ? messages.show : messages.hide,
|
||||||
)}
|
)}
|
||||||
onClick={handleToggleClick}
|
onClick={handleToggleClick}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<i className='icon-with-badge'>
|
<i className='icon-with-badge'>
|
||||||
<Icon
|
<Icon
|
||||||
|
|
@ -259,7 +265,11 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||||
<>
|
<>
|
||||||
{backButton}
|
{backButton}
|
||||||
|
|
||||||
<button onClick={handleTitleClick} className='column-header__title'>
|
<button
|
||||||
|
onClick={handleTitleClick}
|
||||||
|
className='column-header__title'
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
{!backButton && (
|
{!backButton && (
|
||||||
<Icon
|
<Icon
|
||||||
id={icon}
|
id={icon}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ export const CopyPasteText: React.FC<{ value: string }> = ({ value }) => {
|
||||||
onBlur={handleBlur}
|
onBlur={handleBlur}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button className='button' onClick={handleButtonClick}>
|
<button className='button' onClick={handleButtonClick} type='button'>
|
||||||
<Icon id='copy' icon={ContentCopyIcon} />{' '}
|
<Icon id='copy' icon={ContentCopyIcon} />{' '}
|
||||||
{copied ? (
|
{copied ? (
|
||||||
<FormattedMessage id='copypaste.copied' defaultMessage='Copied' />
|
<FormattedMessage id='copypaste.copied' defaultMessage='Copied' />
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,7 @@ export const DropdownMenu = <Item = MenuItem,>({
|
||||||
onKeyUp={handleItemKeyUp}
|
onKeyUp={handleItemKeyUp}
|
||||||
data-index={i}
|
data-index={i}
|
||||||
aria-disabled={disabled}
|
aria-disabled={disabled}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<DropdownMenuItemContent item={option} />
|
<DropdownMenuItemContent item={option} />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,12 @@ export const EditedTimestamp: React.FC<{
|
||||||
className='dropdown-menu__item edited-timestamp__history__item'
|
className='dropdown-menu__item edited-timestamp__history__item'
|
||||||
key={item.get('created_at') as string}
|
key={item.get('created_at') as string}
|
||||||
>
|
>
|
||||||
<button data-index={index} onClick={onClick} onKeyUp={onKeyUp}>
|
<button
|
||||||
|
data-index={index}
|
||||||
|
onClick={onClick}
|
||||||
|
onKeyUp={onKeyUp}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
{label}
|
{label}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -118,7 +123,7 @@ export const EditedTimestamp: React.FC<{
|
||||||
onItemClick={handleItemClick}
|
onItemClick={handleItemClick}
|
||||||
forceDropdown
|
forceDropdown
|
||||||
>
|
>
|
||||||
<button className='dropdown-menu__text-button'>
|
<button className='dropdown-menu__text-button' type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='status.edited'
|
id='status.edited'
|
||||||
defaultMessage='Edited {date}'
|
defaultMessage='Edited {date}'
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ const HashtagBar: React.FC<{
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{!expanded && hashtags.length > VISIBLE_HASHTAGS && (
|
{!expanded && hashtags.length > VISIBLE_HASHTAGS && (
|
||||||
<button className='link-button' onClick={handleClick}>
|
<button className='link-button' onClick={handleClick} type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='hashtags.and_other'
|
id='hashtags.and_other'
|
||||||
defaultMessage='…and {count, plural, other {# more}}'
|
defaultMessage='…and {count, plural, other {# more}}'
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ export const Default = {
|
||||||
the app.
|
the app.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
When a <button>Button</button> is focused,
|
When a <button type='button'>Button</button> is focused,
|
||||||
<kbd>Enter</kbd>
|
<kbd>Enter</kbd>
|
||||||
should not trigger open, but <kbd>o</kbd>
|
should not trigger open, but <kbd>o</kbd>
|
||||||
should.
|
should.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ export const LearnMoreLink: React.FC<{ children: React.ReactNode }> = ({
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
aria-controls={accessibilityId}
|
aria-controls={accessibilityId}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='learn_more_link.learn_more'
|
id='learn_more_link.learn_more'
|
||||||
|
|
@ -48,7 +49,11 @@ export const LearnMoreLink: React.FC<{ children: React.ReactNode }> = ({
|
||||||
<div className='learn-more__popout__content'>{children}</div>
|
<div className='learn-more__popout__content'>{children}</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button className='link-button' onClick={handleClick}>
|
<button
|
||||||
|
className='link-button'
|
||||||
|
onClick={handleClick}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='learn_more_link.got_it'
|
id='learn_more_link.got_it'
|
||||||
defaultMessage='Got it'
|
defaultMessage='Got it'
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ export const LoadGap = <T,>({ disabled, param, onClick }: Props<T>) => {
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-label={intl.formatMessage(messages.load_more)}
|
aria-label={intl.formatMessage(messages.load_more)}
|
||||||
title={intl.formatMessage(messages.load_more)}
|
title={intl.formatMessage(messages.load_more)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<LoadingIndicator />
|
<LoadingIndicator />
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ interface Props {
|
||||||
|
|
||||||
export const LoadPending: React.FC<Props> = ({ onClick, count }) => {
|
export const LoadPending: React.FC<Props> = ({ onClick, count }) => {
|
||||||
return (
|
return (
|
||||||
<button className='load-more load-gap' onClick={onClick}>
|
<button className='load-more load-gap' onClick={onClick} type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='load_pending'
|
id='load_pending'
|
||||||
defaultMessage='{count, plural, one {# new item} other {# new items}}'
|
defaultMessage='{count, plural, one {# new item} other {# new items}}'
|
||||||
|
|
|
||||||
|
|
@ -171,13 +171,14 @@ export const Poll: React.FC<PollProps> = ({ pollId, disabled, status }) => {
|
||||||
className='button button-secondary'
|
className='button button-secondary'
|
||||||
disabled={voteDisabled}
|
disabled={voteDisabled}
|
||||||
onClick={handleVote}
|
onClick={handleVote}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage id='poll.vote' defaultMessage='Vote' />
|
<FormattedMessage id='poll.vote' defaultMessage='Vote' />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{!showResults && (
|
{!showResults && (
|
||||||
<>
|
<>
|
||||||
<button className='poll__link' onClick={handleReveal}>
|
<button className='poll__link' onClick={handleReveal} type='button'>
|
||||||
<FormattedMessage id='poll.reveal' defaultMessage='See results' />
|
<FormattedMessage id='poll.reveal' defaultMessage='See results' />
|
||||||
</button>{' '}
|
</button>{' '}
|
||||||
·{' '}
|
·{' '}
|
||||||
|
|
@ -185,7 +186,11 @@ export const Poll: React.FC<PollProps> = ({ pollId, disabled, status }) => {
|
||||||
)}
|
)}
|
||||||
{showResults && !disabled && (
|
{showResults && !disabled && (
|
||||||
<>
|
<>
|
||||||
<button className='poll__link' onClick={handleRefresh}>
|
<button
|
||||||
|
className='poll__link'
|
||||||
|
onClick={handleRefresh}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
<FormattedMessage id='poll.refresh' defaultMessage='Refresh' />
|
<FormattedMessage id='poll.refresh' defaultMessage='Refresh' />
|
||||||
</button>{' '}
|
</button>{' '}
|
||||||
·{' '}
|
·{' '}
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,7 @@ const ReblogMenuItem: FC<ReblogMenuItemProps> = ({
|
||||||
ref={focusRefCallback}
|
ref={focusRefCallback}
|
||||||
aria-disabled={disabled}
|
aria-disabled={disabled}
|
||||||
data-index={index}
|
data-index={index}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<DropdownMenuItemContent item={item} />
|
<DropdownMenuItemContent item={item} />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ const LimitedAccountHint: React.FC<{ accountId: string }> = ({ accountId }) => {
|
||||||
defaultMessage='This account has been hidden by the moderators of {domain}.'
|
defaultMessage='This account has been hidden by the moderators of {domain}.'
|
||||||
values={{ domain }}
|
values={{ domain }}
|
||||||
/>
|
/>
|
||||||
<button onClick={reveal} className='link-button'>
|
<button onClick={reveal} className='link-button' type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='status.quote_error.limited_account_hint.action'
|
id='status.quote_error.limited_account_hint.action'
|
||||||
defaultMessage='Show anyway'
|
defaultMessage='Show anyway'
|
||||||
|
|
@ -129,7 +129,7 @@ const FilteredQuote: React.FC<{
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{message}
|
{message}
|
||||||
<button onClick={reveal} className='link-button'>
|
<button onClick={reveal} className='link-button' type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='status.quote_error.limited_account_hint.action'
|
id='status.quote_error.limited_account_hint.action'
|
||||||
defaultMessage='Show anyway'
|
defaultMessage='Show anyway'
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export const Section: FC<SectionProps> = ({
|
||||||
className='about__section__title'
|
className='about__section__title'
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
id={collapsed ? 'chevron-right' : 'chevron-down'}
|
id={collapsed ? 'chevron-right' : 'chevron-down'}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ export const DomainPill: React.FC<{
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
aria-controls={accessibilityId}
|
aria-controls={accessibilityId}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{domain}
|
{domain}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -154,6 +155,7 @@ export const DomainPill: React.FC<{
|
||||||
<button
|
<button
|
||||||
onClick={handleExpandClick}
|
onClick={handleExpandClick}
|
||||||
className='link-button'
|
className='link-button'
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{x}
|
{x}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -169,6 +171,7 @@ export const DomainPill: React.FC<{
|
||||||
<button
|
<button
|
||||||
onClick={handleExpandClick}
|
onClick={handleExpandClick}
|
||||||
className='link-button'
|
className='link-button'
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{x}
|
{x}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -489,6 +489,7 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
|
||||||
className='link-button'
|
className='link-button'
|
||||||
onClick={handleDetectClick}
|
onClick={handleDetectClick}
|
||||||
disabled={type !== 'image' || isDetecting}
|
disabled={type !== 'image' || isDetecting}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='alt_text_modal.add_text_from_image'
|
id='alt_text_modal.add_text_from_image'
|
||||||
|
|
|
||||||
|
|
@ -557,7 +557,11 @@ export const Search: React.FC<{
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
<button className='icon-button' onMouseDown={forget}>
|
<button
|
||||||
|
className='icon-button'
|
||||||
|
onMouseDown={forget}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
<Icon id='times' icon={CloseIcon} />
|
<Icon id='times' icon={CloseIcon} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -591,6 +595,7 @@ export const Search: React.FC<{
|
||||||
className={classNames('search__popout__menu__item', {
|
className={classNames('search__popout__menu__item', {
|
||||||
selected: selectedOption === i,
|
selected: selectedOption === i,
|
||||||
})}
|
})}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -617,6 +622,7 @@ export const Search: React.FC<{
|
||||||
selectedOption ===
|
selectedOption ===
|
||||||
(quickActions.length || recent.length) + i,
|
(quickActions.length || recent.length) + i,
|
||||||
})}
|
})}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ export const InlineFollowSuggestions: React.FC<{ hidden?: boolean }> = ({
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className='inline-follow-suggestions__header__actions'>
|
<div className='inline-follow-suggestions__header__actions'>
|
||||||
<button className='link-button' onClick={handleDismiss}>
|
<button className='link-button' onClick={handleDismiss} type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='follow_suggestions.dismiss'
|
id='follow_suggestions.dismiss'
|
||||||
defaultMessage="Don't show again"
|
defaultMessage="Don't show again"
|
||||||
|
|
@ -309,6 +309,7 @@ export const InlineFollowSuggestions: React.FC<{ hidden?: boolean }> = ({
|
||||||
className='inline-follow-suggestions__body__scroll-button left'
|
className='inline-follow-suggestions__body__scroll-button left'
|
||||||
onClick={handleLeftNav}
|
onClick={handleLeftNav}
|
||||||
aria-label={intl.formatMessage(messages.previous)}
|
aria-label={intl.formatMessage(messages.previous)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<div className='inline-follow-suggestions__body__scroll-button__icon'>
|
<div className='inline-follow-suggestions__body__scroll-button__icon'>
|
||||||
<Icon id='' icon={ChevronLeftIcon} />
|
<Icon id='' icon={ChevronLeftIcon} />
|
||||||
|
|
@ -321,6 +322,7 @@ export const InlineFollowSuggestions: React.FC<{ hidden?: boolean }> = ({
|
||||||
className='inline-follow-suggestions__body__scroll-button right'
|
className='inline-follow-suggestions__body__scroll-button right'
|
||||||
onClick={handleRightNav}
|
onClick={handleRightNav}
|
||||||
aria-label={intl.formatMessage(messages.next)}
|
aria-label={intl.formatMessage(messages.next)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<div className='inline-follow-suggestions__body__scroll-button__icon'>
|
<div className='inline-follow-suggestions__body__scroll-button__icon'>
|
||||||
<Icon id='' icon={ChevronRightIcon} />
|
<Icon id='' icon={ChevronRightIcon} />
|
||||||
|
|
|
||||||
|
|
@ -381,6 +381,7 @@ const LoginForm: React.FC<{
|
||||||
className={classNames('search__popout__menu__item', {
|
className={classNames('search__popout__menu__item', {
|
||||||
selected: selectedOption === i,
|
selected: selectedOption === i,
|
||||||
})}
|
})}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{option
|
{option
|
||||||
.split(domainRegExp)
|
.split(domainRegExp)
|
||||||
|
|
@ -451,7 +452,7 @@ const InteractionModal: React.FC<{
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
signupButton = (
|
signupButton = (
|
||||||
<button className='link-button' onClick={handleSignupClick}>
|
<button className='link-button' onClick={handleSignupClick} type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='sign_in_banner.create_account'
|
id='sign_in_banner.create_account'
|
||||||
defaultMessage='Create account'
|
defaultMessage='Create account'
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ export const MoreLink: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown items={menu} placement='bottom-start'>
|
<Dropdown items={menu} placement='bottom-start'>
|
||||||
<button className='column-link column-link--transparent'>
|
<button className='column-link column-link--transparent' type='button'>
|
||||||
<Icon id='' icon={MoreHorizIcon} className='column-link__icon' />
|
<Icon id='' icon={MoreHorizIcon} className='column-link__icon' />
|
||||||
|
|
||||||
<FormattedMessage id='navigation_bar.more' defaultMessage='More' />
|
<FormattedMessage id='navigation_bar.more' defaultMessage='More' />
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ export const SignInBanner: React.FC = () => {
|
||||||
<button
|
<button
|
||||||
className='button button--block'
|
className='button button--block'
|
||||||
onClick={openClosedRegistrationsModal}
|
onClick={openClosedRegistrationsModal}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='sign_in_banner.create_account'
|
id='sign_in_banner.create_account'
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ export const FilteredNotificationsIconButton: React.FC<{
|
||||||
title={intl.formatMessage(messages.filteredNotifications)}
|
title={intl.formatMessage(messages.filteredNotifications)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
className={className}
|
className={className}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='filtered-notifications' icon={InventoryIcon} />
|
<Icon id='filtered-notifications' icon={InventoryIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ export const NotificationAnnualReport: React.FC<{
|
||||||
values={{ year }}
|
values={{ year }}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<button onClick={handleClick} className='link-button'>
|
<button onClick={handleClick} className='link-button' type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.annual_report.view'
|
id='notification.annual_report.view'
|
||||||
defaultMessage='View #Wrapstodon'
|
defaultMessage='View #Wrapstodon'
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ const BarButton: React.FC<
|
||||||
className={selectedFilter === type ? 'active' : ''}
|
className={selectedFilter === type ? 'active' : ''}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
title={title}
|
title={title}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,7 @@ export const Notifications: React.FC<{
|
||||||
title={intl.formatMessage(messages.markAsRead)}
|
title={intl.formatMessage(messages.markAsRead)}
|
||||||
onClick={handleMarkAsRead}
|
onClick={handleMarkAsRead}
|
||||||
className='column-header__button'
|
className='column-header__button'
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='done-all' icon={DoneAllIcon} />
|
<Icon id='done-all' icon={DoneAllIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export const SearchSection: React.FC<{
|
||||||
<div className='search-results__section__header'>
|
<div className='search-results__section__header'>
|
||||||
<h3>{title}</h3>
|
<h3>{title}</h3>
|
||||||
{onClickMore && (
|
{onClickMore && (
|
||||||
<button onClick={onClickMore}>
|
<button onClick={onClickMore} type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='search_results.see_all'
|
id='search_results.see_all'
|
||||||
defaultMessage='See all'
|
defaultMessage='See all'
|
||||||
|
|
|
||||||
|
|
@ -232,12 +232,14 @@ export const SearchResults: React.FC<{ multiColumn: boolean }> = ({
|
||||||
<button
|
<button
|
||||||
onClick={handleSelectAll}
|
onClick={handleSelectAll}
|
||||||
className={mappedType === 'all' ? 'active' : undefined}
|
className={mappedType === 'all' ? 'active' : undefined}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage id='search_results.all' defaultMessage='All' />
|
<FormattedMessage id='search_results.all' defaultMessage='All' />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={handleSelectAccounts}
|
onClick={handleSelectAccounts}
|
||||||
className={mappedType === 'accounts' ? 'active' : undefined}
|
className={mappedType === 'accounts' ? 'active' : undefined}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='search_results.accounts'
|
id='search_results.accounts'
|
||||||
|
|
@ -247,6 +249,7 @@ export const SearchResults: React.FC<{ multiColumn: boolean }> = ({
|
||||||
<button
|
<button
|
||||||
onClick={handleSelectHashtags}
|
onClick={handleSelectHashtags}
|
||||||
className={mappedType === 'hashtags' ? 'active' : undefined}
|
className={mappedType === 'hashtags' ? 'active' : undefined}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='search_results.hashtags'
|
id='search_results.hashtags'
|
||||||
|
|
@ -256,6 +259,7 @@ export const SearchResults: React.FC<{ multiColumn: boolean }> = ({
|
||||||
<button
|
<button
|
||||||
onClick={handleSelectStatuses}
|
onClick={handleSelectStatuses}
|
||||||
className={mappedType === 'statuses' ? 'active' : undefined}
|
className={mappedType === 'statuses' ? 'active' : undefined}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='search_results.statuses'
|
id='search_results.statuses'
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,12 @@ export const ActionsModal: React.FC<{
|
||||||
|
|
||||||
if (isActionItem(option)) {
|
if (isActionItem(option)) {
|
||||||
element = (
|
element = (
|
||||||
<button onClick={onClick} data-index={i} disabled={disabled}>
|
<button
|
||||||
|
onClick={onClick}
|
||||||
|
data-index={i}
|
||||||
|
disabled={disabled}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
<DropdownMenuItemContent item={option} />
|
<DropdownMenuItemContent item={option} />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ export const BoostModal: React.FC<{
|
||||||
|
|
||||||
<div className='spacer' />
|
<div className='spacer' />
|
||||||
|
|
||||||
<button onClick={handleCancel} className='link-button'>
|
<button onClick={handleCancel} className='link-button' type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='confirmation_modal.cancel'
|
id='confirmation_modal.cancel'
|
||||||
defaultMessage='Cancel'
|
defaultMessage='Cancel'
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export const ConfirmationModal: React.FC<
|
||||||
|
|
||||||
<div className='safety-action-modal__bottom'>
|
<div className='safety-action-modal__bottom'>
|
||||||
<div className='safety-action-modal__actions'>
|
<div className='safety-action-modal__actions'>
|
||||||
<button onClick={onClose} className='link-button'>
|
<button onClick={onClose} className='link-button' type='button'>
|
||||||
{cancel ?? (
|
{cancel ?? (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='confirmation_modal.cancel'
|
id='confirmation_modal.cancel'
|
||||||
|
|
@ -70,7 +70,11 @@ export const ConfirmationModal: React.FC<
|
||||||
{secondary && (
|
{secondary && (
|
||||||
<>
|
<>
|
||||||
<div className='spacer' />
|
<div className='spacer' />
|
||||||
<button onClick={handleSecondary} className='link-button'>
|
<button
|
||||||
|
onClick={handleSecondary}
|
||||||
|
className='link-button'
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
{secondary}
|
{secondary}
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ export const DomainBlockModal: React.FC<{
|
||||||
|
|
||||||
<div className='spacer' />
|
<div className='spacer' />
|
||||||
|
|
||||||
<button onClick={handleCancel} className='link-button'>
|
<button onClick={handleCancel} className='link-button' type='button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='confirmation_modal.cancel'
|
id='confirmation_modal.cancel'
|
||||||
defaultMessage='Cancel'
|
defaultMessage='Cancel'
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,7 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||||
className='media-modal__nav media-modal__nav--prev'
|
className='media-modal__nav media-modal__nav--prev'
|
||||||
onClick={handlePrevClick}
|
onClick={handlePrevClick}
|
||||||
aria-label={intl.formatMessage(messages.previous)}
|
aria-label={intl.formatMessage(messages.previous)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='chevron-left' icon={ChevronLeftIcon} />
|
<Icon id='chevron-left' icon={ChevronLeftIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -257,6 +258,7 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||||
className='media-modal__nav media-modal__nav--next'
|
className='media-modal__nav media-modal__nav--next'
|
||||||
onClick={handleNextClick}
|
onClick={handleNextClick}
|
||||||
aria-label={intl.formatMessage(messages.next)}
|
aria-label={intl.formatMessage(messages.next)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='chevron-right' icon={ChevronRightIcon} />
|
<Icon id='chevron-right' icon={ChevronRightIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -354,6 +356,7 @@ const MediaPagination: FC<MediaPaginationProps> = ({
|
||||||
active: i === index,
|
active: i === index,
|
||||||
})}
|
})}
|
||||||
onClick={handleChangeIndex(i)}
|
onClick={handleChangeIndex(i)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
{i + 1}
|
{i + 1}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,11 @@ const LoginOrSignUp: React.FC = () => {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
signupButton = (
|
signupButton = (
|
||||||
<button className='button' onClick={openClosedRegistrationsModal}>
|
<button
|
||||||
|
className='button'
|
||||||
|
onClick={openClosedRegistrationsModal}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='sign_in_banner.create_account'
|
id='sign_in_banner.create_account'
|
||||||
defaultMessage='Create account'
|
defaultMessage='Create account'
|
||||||
|
|
@ -195,6 +199,7 @@ export const NavigationBar: React.FC = () => {
|
||||||
className={classNames('ui__navigation-bar__item', { active: open })}
|
className={classNames('ui__navigation-bar__item', { active: open })}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-label={intl.formatMessage(messages.menu)}
|
aria-label={intl.formatMessage(messages.menu)}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon id='' icon={MenuIcon} />
|
<Icon id='' icon={MenuIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -875,6 +875,7 @@ export const Video: React.FC<{
|
||||||
<button
|
<button
|
||||||
className='media-gallery__actions__pill'
|
className='media-gallery__actions__pill'
|
||||||
onClick={toggleReveal}
|
onClick={toggleReveal}
|
||||||
|
type='button'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='media_gallery.hide'
|
id='media_gallery.hide'
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ export default tseslint.config([
|
||||||
'vendor/**/*',
|
'vendor/**/*',
|
||||||
'streaming/**/*',
|
'streaming/**/*',
|
||||||
'.bundle/**/*',
|
'.bundle/**/*',
|
||||||
|
'storybook-static/**/*',
|
||||||
]),
|
]),
|
||||||
react.configs.flat.recommended,
|
react.configs.flat.recommended,
|
||||||
react.configs.flat['jsx-runtime'],
|
react.configs.flat['jsx-runtime'],
|
||||||
|
|
@ -290,6 +291,7 @@ export default tseslint.config([
|
||||||
'react/jsx-tag-spacing': 'error',
|
'react/jsx-tag-spacing': 'error',
|
||||||
'react/jsx-wrap-multilines': 'error',
|
'react/jsx-wrap-multilines': 'error',
|
||||||
'react/self-closing-comp': 'error',
|
'react/self-closing-comp': 'error',
|
||||||
|
'react/button-has-type': 'error',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user