Skip to content

Commit 9b7ea53

Browse files
authored
Turn on react/button-has-type lint rule and fix all (#2261)
* turn on react/button-has-type lint rule and fix all * add MiniTable.RemoveCell to reduce fiddly logic
1 parent bf97ebc commit 9b7ea53

18 files changed

+66
-64
lines changed

.eslintrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ module.exports = {
8686
radix: 'error',
8787
'react-hooks/exhaustive-deps': 'error',
8888
'react-hooks/rules-of-hooks': 'error',
89+
'react/button-has-type': 'error',
8990
'react/jsx-boolean-value': 'error',
9091
'react/display-name': 'off',
9192
'react/react-in-jsx-scope': 'off',

app/components/MswBanner.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export function MswBanner() {
3535
<label className="absolute z-topBar flex h-10 w-full items-center justify-center text-sans-md text-info-secondary bg-info-secondary [&+*]:pt-10">
3636
<Info16Icon className="mr-2" /> This is a technical preview.
3737
<button
38+
type="button"
3839
className="ml-2 flex items-center gap-0.5 text-sans-md hover:text-info"
3940
onClick={() => setIsOpen(true)}
4041
>

app/components/RefetchIntervalPicker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function useIntervalPicker({ enabled, isLoading, fn }: Props) {
6060
</div>
6161
<div className="flex">
6262
<button
63+
type="button"
6364
className={cn(
6465
'flex w-10 items-center justify-center rounded-l border-b border-l border-t border-default disabled:cursor-default',
6566
isLoading && 'hover:bg-hover',

app/components/form/fields/DisksTableField.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { useState } from 'react'
99
import { useController, type Control } from 'react-hook-form'
1010

1111
import type { DiskCreate } from '@oxide/api'
12-
import { Error16Icon } from '@oxide/design-system/icons/react'
1312

1413
import { AttachDiskSideModalForm } from '~/forms/disk-attach'
1514
import { CreateDiskSideModalForm } from '~/forms/disk-create'
@@ -77,13 +76,10 @@ export function DisksTableField({
7776
</>
7877
)}
7978
</MiniTable.Cell>
80-
<MiniTable.Cell>
81-
<button
82-
onClick={() => onChange(items.filter((i) => i.name !== item.name))}
83-
>
84-
<Error16Icon title={`remove ${item.name}`} />
85-
</button>
86-
</MiniTable.Cell>
79+
<MiniTable.RemoveCell
80+
onClick={() => onChange(items.filter((i) => i.name !== item.name))}
81+
label={`remove disk ${item.name}`}
82+
/>
8783
</MiniTable.Row>
8884
))}
8985
</MiniTable.Body>

app/components/form/fields/NetworkInterfaceField.tsx

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import type {
1212
InstanceNetworkInterfaceAttachment,
1313
InstanceNetworkInterfaceCreate,
1414
} from '@oxide/api'
15-
import { Error16Icon } from '@oxide/design-system/icons/react'
1615

1716
import type { InstanceCreateInput } from '~/forms/instance-create'
1817
import { CreateNetworkInterfaceForm } from '~/forms/network-interface-create'
@@ -94,18 +93,15 @@ export function NetworkInterfaceField({
9493
<MiniTable.Cell>{item.name}</MiniTable.Cell>
9594
<MiniTable.Cell>{item.vpcName}</MiniTable.Cell>
9695
<MiniTable.Cell>{item.subnetName}</MiniTable.Cell>
97-
<MiniTable.Cell>
98-
<button
99-
onClick={() =>
100-
onChange({
101-
type: 'create',
102-
params: value.params.filter((i) => i.name !== item.name),
103-
})
104-
}
105-
>
106-
<Error16Icon title={`remove ${item.name}`} />
107-
</button>
108-
</MiniTable.Cell>
96+
<MiniTable.RemoveCell
97+
onClick={() =>
98+
onChange({
99+
type: 'create',
100+
params: value.params.filter((i) => i.name !== item.name),
101+
})
102+
}
103+
label={`remove network interface ${item.name}`}
104+
/>
109105
</MiniTable.Row>
110106
))}
111107
</MiniTable.Body>

app/components/form/fields/TlsCertsField.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { useController, type Control } from 'react-hook-form'
1010
import type { Merge } from 'type-fest'
1111

1212
import type { CertificateCreate } from '@oxide/api'
13-
import { Error16Icon } from '@oxide/design-system/icons/react'
1413

1514
import type { SiloCreateFormValues } from '~/forms/silo-create'
1615
import { useForm } from '~/hooks'
@@ -53,13 +52,10 @@ export function TlsCertsField({ control }: { control: Control<SiloCreateFormValu
5352
key={item.name}
5453
>
5554
<MiniTable.Cell>{item.name}</MiniTable.Cell>
56-
<MiniTable.Cell>
57-
<button
58-
onClick={() => onChange(items.filter((i) => i.name !== item.name))}
59-
>
60-
<Error16Icon title={`remove ${item.name}`} />
61-
</button>
62-
</MiniTable.Cell>
55+
<MiniTable.RemoveCell
56+
onClick={() => onChange(items.filter((i) => i.name !== item.name))}
57+
label={`remove cert ${item.name}`}
58+
/>
6359
</MiniTable.Row>
6460
))}
6561
</MiniTable.Body>

app/forms/firewall-rules-create.tsx

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
type VpcFirewallRuleTarget,
1919
type VpcFirewallRuleUpdate,
2020
} from '@oxide/api'
21-
import { Error16Icon } from '@oxide/design-system/icons/react'
2221

2322
import { CheckboxField } from '~/components/form/fields/CheckboxField'
2423
import { DescriptionField } from '~/components/form/fields/DescriptionField'
@@ -317,19 +316,16 @@ export const CommonFields = ({ error, control }: CommonFieldsProps) => {
317316
<Badge variant="solid">{t.type}</Badge>
318317
</MiniTable.Cell>
319318
<MiniTable.Cell>{t.value}</MiniTable.Cell>
320-
<MiniTable.Cell>
321-
<button
322-
onClick={() =>
323-
targets.onChange(
324-
targets.value.filter(
325-
(i) => !(i.value === t.value && i.type === t.type)
326-
)
319+
<MiniTable.RemoveCell
320+
onClick={() =>
321+
targets.onChange(
322+
targets.value.filter(
323+
(i) => !(i.value === t.value && i.type === t.type)
327324
)
328-
}
329-
>
330-
<Error16Icon title={`remove ${t.value}`} />
331-
</button>
332-
</MiniTable.Cell>
325+
)
326+
}
327+
label={`remove target ${t.value}`}
328+
/>
333329
</MiniTable.Row>
334330
))}
335331
</MiniTable.Body>
@@ -399,13 +395,10 @@ export const CommonFields = ({ error, control }: CommonFieldsProps) => {
399395
{ports.value.map((p) => (
400396
<MiniTable.Row tabIndex={0} aria-label={p} key={p}>
401397
<MiniTable.Cell>{p}</MiniTable.Cell>
402-
<MiniTable.Cell>
403-
<button
404-
onClick={() => ports.onChange(ports.value.filter((p1) => p1 !== p))}
405-
>
406-
<Error16Icon title={`remove ${p}`} />
407-
</button>
408-
</MiniTable.Cell>
398+
<MiniTable.RemoveCell
399+
onClick={() => ports.onChange(ports.value.filter((p1) => p1 !== p))}
400+
label={`remove port ${p}`}
401+
/>
409402
</MiniTable.Row>
410403
))}
411404
</MiniTable.Body>
@@ -501,19 +494,16 @@ export const CommonFields = ({ error, control }: CommonFieldsProps) => {
501494
<Badge variant="solid">{h.type}</Badge>
502495
</MiniTable.Cell>
503496
<MiniTable.Cell>{h.value}</MiniTable.Cell>
504-
<MiniTable.Cell>
505-
<button
506-
onClick={() =>
507-
hosts.onChange(
508-
hosts.value.filter(
509-
(i) => !(i.value === h.value && i.type === h.type)
510-
)
497+
<MiniTable.RemoveCell
498+
onClick={() =>
499+
hosts.onChange(
500+
hosts.value.filter(
501+
(i) => !(i.value === h.value && i.type === h.type)
511502
)
512-
}
513-
>
514-
<Error16Icon title={`remove ${h.value}`} />
515-
</button>
516-
</MiniTable.Cell>
503+
)
504+
}
505+
label={`remove host ${h.value}`}
506+
/>
517507
</MiniTable.Row>
518508
))}
519509
</MiniTable.Body>

app/table/cells/LinkCell.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function LinkCell({ to, children }: { to: string; children: React.ReactNo
4040

4141
export const ButtonCell = ({ children, ...props }: React.ComponentProps<'button'>) => {
4242
return (
43-
<button className={linkClass} {...props}>
43+
<button type="button" className={linkClass} {...props}>
4444
<Pusher />
4545
<div className="relative">{children}</div>
4646
</button>

app/ui/lib/ActionMenu.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export function ActionMenu(props: ActionMenuProps) {
136136

137137
{input.length > 0 && (
138138
<button
139+
type="button"
139140
className="flex items-center py-6 pl-6 pr-4 text-secondary"
140141
onClick={() => {
141142
setInput('')
@@ -147,6 +148,7 @@ export function ActionMenu(props: ActionMenuProps) {
147148
)}
148149

149150
<button
151+
type="button"
150152
onClick={onDismiss}
151153
className="flex h-full items-center border-l px-6 align-middle text-mono-sm text-secondary border-secondary"
152154
>

app/ui/lib/Button.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
9494
'visually-disabled': isDisabled,
9595
})}
9696
ref={ref}
97+
/* eslint-disable-next-line react/button-has-type */
9798
type={type}
9899
onMouseDown={isDisabled ? noop : undefined}
99100
onClick={isDisabled ? noop : onClick}

0 commit comments

Comments
 (0)