Add new ESLint rule requiring explicit button types (#36738)
This commit is contained in:
37 files changed
+101
-26
No files matched your search
@@ -49,7 +49,11 @@ export const Alert: React.FC<{
|
||||
</span>
|
||||
|
||||
{hasAction && (
|
||||
<button className='notification-bar__action' onClick={onActionClick}>
|
||||
<button
|
||||
className='notification-bar__action'
|
||||
onClick={onActionClick}
|
||||
type='button'
|
||||
>
|
||||
{action}
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -78,6 +78,7 @@ export const Button: React.FC<Props> = ({
|
||||
aria-live={loading !== undefined ? 'polite' : undefined}
|
||||
onClick={handleClick}
|
||||
title={title}
|
||||
// eslint-disable-next-line react/button-has-type -- set correctly via TS
|
||||
type={type}
|
||||
{...props}
|
||||
>
|
||||
|
||||
@@ -30,7 +30,7 @@ export const ColumnBackButton: React.FC<{ onClick?: OnClickCallback }> = ({
|
||||
const handleClick = useHandleClick(onClick);
|
||||
|
||||
const component = (
|
||||
<button onClick={handleClick} className='column-back-button'>
|
||||
<button onClick={handleClick} className='column-back-button' type='button'>
|
||||
<Icon
|
||||
id='chevron-left'
|
||||
icon={ArrowBackIcon}
|
||||
|
||||
@@ -53,6 +53,7 @@ const BackButton: React.FC<{
|
||||
compact: onlyIcon,
|
||||
})}
|
||||
aria-label={intl.formatMessage(messages.back)}
|
||||
type='button'
|
||||
>
|
||||
<Icon
|
||||
id='chevron-left'
|
||||
@@ -172,6 +173,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||
<button
|
||||
className='text-btn column-header__setting-btn'
|
||||
onClick={handlePin}
|
||||
type='button'
|
||||
>
|
||||
<Icon id='times' icon={CloseIcon} />{' '}
|
||||
<FormattedMessage id='column_header.unpin' defaultMessage='Unpin' />
|
||||
@@ -185,6 +187,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||
aria-label={intl.formatMessage(messages.moveLeft)}
|
||||
className='icon-button column-header__setting-btn'
|
||||
onClick={handleMoveLeft}
|
||||
type='button'
|
||||
>
|
||||
<Icon id='chevron-left' icon={ChevronLeftIcon} />
|
||||
</button>
|
||||
@@ -193,6 +196,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||
aria-label={intl.formatMessage(messages.moveRight)}
|
||||
className='icon-button column-header__setting-btn'
|
||||
onClick={handleMoveRight}
|
||||
type='button'
|
||||
>
|
||||
<Icon id='chevron-right' icon={ChevronRightIcon} />
|
||||
</button>
|
||||
@@ -203,6 +207,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||
<button
|
||||
className='text-btn column-header__setting-btn'
|
||||
onClick={handlePin}
|
||||
type='button'
|
||||
>
|
||||
<Icon id='plus' icon={AddIcon} />{' '}
|
||||
<FormattedMessage id='column_header.pin' defaultMessage='Pin' />
|
||||
@@ -237,6 +242,7 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||
collapsed ? messages.show : messages.hide,
|
||||
)}
|
||||
onClick={handleToggleClick}
|
||||
type='button'
|
||||
>
|
||||
<i className='icon-with-badge'>
|
||||
<Icon
|
||||
@@ -259,7 +265,11 @@ export const ColumnHeader: React.FC<Props> = ({
|
||||
<>
|
||||
{backButton}
|
||||
|
||||
<button onClick={handleTitleClick} className='column-header__title'>
|
||||
<button
|
||||
onClick={handleTitleClick}
|
||||
className='column-header__title'
|
||||
type='button'
|
||||
>
|
||||
{!backButton && (
|
||||
<Icon
|
||||
id={icon}
|
||||
|
||||
@@ -74,7 +74,7 @@ export const CopyPasteText: React.FC<{ value: string }> = ({ value }) => {
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
|
||||
<button className='button' onClick={handleButtonClick}>
|
||||
<button className='button' onClick={handleButtonClick} type='button'>
|
||||
<Icon id='copy' icon={ContentCopyIcon} />{' '}
|
||||
{copied ? (
|
||||
<FormattedMessage id='copypaste.copied' defaultMessage='Copied' />
|
||||
|
||||
@@ -237,6 +237,7 @@ export const DropdownMenu = <Item = MenuItem,>({
|
||||
onKeyUp={handleItemKeyUp}
|
||||
data-index={i}
|
||||
aria-disabled={disabled}
|
||||
type='button'
|
||||
>
|
||||
<DropdownMenuItemContent item={option} />
|
||||
</button>
|
||||
|
||||
@@ -98,7 +98,12 @@ export const EditedTimestamp: React.FC<{
|
||||
className='dropdown-menu__item edited-timestamp__history__item'
|
||||
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}
|
||||
</button>
|
||||
</li>
|
||||
@@ -118,7 +123,7 @@ export const EditedTimestamp: React.FC<{
|
||||
onItemClick={handleItemClick}
|
||||
forceDropdown
|
||||
>
|
||||
<button className='dropdown-menu__text-button'>
|
||||
<button className='dropdown-menu__text-button' type='button'>
|
||||
<FormattedMessage
|
||||
id='status.edited'
|
||||
defaultMessage='Edited {date}'
|
||||
|
||||
@@ -235,7 +235,7 @@ const HashtagBar: React.FC<{
|
||||
))}
|
||||
|
||||
{!expanded && hashtags.length > VISIBLE_HASHTAGS && (
|
||||
<button className='link-button' onClick={handleClick}>
|
||||
<button className='link-button' onClick={handleClick} type='button'>
|
||||
<FormattedMessage
|
||||
id='hashtags.and_other'
|
||||
defaultMessage='…and {count, plural, other {# more}}'
|
||||
|
||||
@@ -153,7 +153,7 @@ export const Default = {
|
||||
the app.
|
||||
</p>
|
||||
<p>
|
||||
When a <button>Button</button> is focused,
|
||||
When a <button type='button'>Button</button> is focused,
|
||||
<kbd>Enter</kbd>
|
||||
should not trigger open, but <kbd>o</kbd>
|
||||
should.
|
||||
|
||||
@@ -23,6 +23,7 @@ export const LearnMoreLink: React.FC<{ children: React.ReactNode }> = ({
|
||||
onClick={handleClick}
|
||||
aria-expanded={open}
|
||||
aria-controls={accessibilityId}
|
||||
type='button'
|
||||
>
|
||||
<FormattedMessage
|
||||
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>
|
||||
<button className='link-button' onClick={handleClick}>
|
||||
<button
|
||||
className='link-button'
|
||||
onClick={handleClick}
|
||||
type='button'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='learn_more_link.got_it'
|
||||
defaultMessage='Got it'
|
||||
|
||||
@@ -32,6 +32,7 @@ export const LoadGap = <T,>({ disabled, param, onClick }: Props<T>) => {
|
||||
onClick={handleClick}
|
||||
aria-label={intl.formatMessage(messages.load_more)}
|
||||
title={intl.formatMessage(messages.load_more)}
|
||||
type='button'
|
||||
>
|
||||
{loading ? (
|
||||
<LoadingIndicator />
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Props {
|
||||
|
||||
export const LoadPending: React.FC<Props> = ({ onClick, count }) => {
|
||||
return (
|
||||
<button className='load-more load-gap' onClick={onClick}>
|
||||
<button className='load-more load-gap' onClick={onClick} type='button'>
|
||||
<FormattedMessage
|
||||
id='load_pending'
|
||||
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'
|
||||
disabled={voteDisabled}
|
||||
onClick={handleVote}
|
||||
type='button'
|
||||
>
|
||||
<FormattedMessage id='poll.vote' defaultMessage='Vote' />
|
||||
</button>
|
||||
)}
|
||||
{!showResults && (
|
||||
<>
|
||||
<button className='poll__link' onClick={handleReveal}>
|
||||
<button className='poll__link' onClick={handleReveal} type='button'>
|
||||
<FormattedMessage id='poll.reveal' defaultMessage='See results' />
|
||||
</button>{' '}
|
||||
·{' '}
|
||||
@@ -185,7 +186,11 @@ export const Poll: React.FC<PollProps> = ({ pollId, disabled, status }) => {
|
||||
)}
|
||||
{showResults && !disabled && (
|
||||
<>
|
||||
<button className='poll__link' onClick={handleRefresh}>
|
||||
<button
|
||||
className='poll__link'
|
||||
onClick={handleRefresh}
|
||||
type='button'
|
||||
>
|
||||
<FormattedMessage id='poll.refresh' defaultMessage='Refresh' />
|
||||
</button>{' '}
|
||||
·{' '}
|
||||
|
||||
@@ -232,6 +232,7 @@ const ReblogMenuItem: FC<ReblogMenuItemProps> = ({
|
||||
ref={focusRefCallback}
|
||||
aria-disabled={disabled}
|
||||
data-index={index}
|
||||
type='button'
|
||||
>
|
||||
<DropdownMenuItemContent item={item} />
|
||||
</button>
|
||||
|
||||
@@ -73,7 +73,7 @@ const LimitedAccountHint: React.FC<{ accountId: string }> = ({ accountId }) => {
|
||||
defaultMessage='This account has been hidden by the moderators of {domain}.'
|
||||
values={{ domain }}
|
||||
/>
|
||||
<button onClick={reveal} className='link-button'>
|
||||
<button onClick={reveal} className='link-button' type='button'>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.limited_account_hint.action'
|
||||
defaultMessage='Show anyway'
|
||||
@@ -129,7 +129,7 @@ const FilteredQuote: React.FC<{
|
||||
return (
|
||||
<>
|
||||
{message}
|
||||
<button onClick={reveal} className='link-button'>
|
||||
<button onClick={reveal} className='link-button' type='button'>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.limited_account_hint.action'
|
||||
defaultMessage='Show anyway'
|
||||
|
||||
Reference in new issue
Block a user