Skip to content

Commit ae5bc1b

Browse files
author
Luke Bowerman
authored
fix: Correct issue where components that output DOM button w/o type="button" inadvetedly submit HTML forms (#2096)
Updates the following components to explicitly include `type="button"` to prevent accidentily triggering form submission: - ButtonItem - IconButton - ListItem (MenuItem & TreeItem come along for the ride here) - Tab
1 parent aa53fe0 commit ae5bc1b

File tree

7 files changed

+25
-6
lines changed

7 files changed

+25
-6
lines changed

packages/components/src/Button/ButtonItem.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ const ButtonLayout = forwardRef(
9999

100100
ButtonLayout.displayName = 'ButtonLayout'
101101

102-
const ButtonOuter = styled.button<ButtonItemProps>`
102+
const ButtonOuter = styled.button.attrs(({ type = 'button' }) => ({
103+
type,
104+
}))<ButtonItemProps>`
103105
${(props) =>
104106
props.focusVisible &&
105107
`box-shadow: 0 0 0.5px 1px ${props.theme.colors.keyFocus}`}

packages/components/src/Button/IconButton.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,13 @@ export interface IconButtonProps
119119
tooltipTextAlign?: Property.TextAlign
120120
}
121121

122-
export const IconButtonStyle = styled.button.withConfig({
123-
shouldForwardProp,
124-
})<IconButtonProps>`
122+
export const IconButtonStyle = styled.button
123+
.withConfig({
124+
shouldForwardProp,
125+
})
126+
.attrs(({ type = 'button' }) => ({
127+
type,
128+
}))<IconButtonProps>`
125129
${({ focusVisible }) => buttonCSS('neutral', focusVisible)}
126130
height: auto;
127131
`

packages/components/src/Button/__snapshots__/ButtonGroup.test.tsx.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,23 @@ exports[`ButtonGroup controlled 1`] = `
107107
<button
108108
aria-pressed="false"
109109
class="ButtonItem__ButtonOuter-sc-22szay-0 c2 c3"
110+
type="button"
110111
value="Apples"
111112
>
112113
Apples
113114
</button>
114115
<button
115116
aria-pressed="false"
116117
class="ButtonItem__ButtonOuter-sc-22szay-0 c2 c3"
118+
type="button"
117119
value="Oranges"
118120
>
119121
Oranges
120122
</button>
121123
<button
122124
aria-pressed="true"
123125
class="ButtonItem__ButtonOuter-sc-22szay-0 c2 c3"
126+
type="button"
124127
value="Bananas"
125128
>
126129
Bananas

packages/components/src/Button/__snapshots__/ButtonToggle.test.tsx.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,20 +146,23 @@ exports[`ButtonToggle controlled 1`] = `
146146
<button
147147
aria-pressed="false"
148148
class="ButtonItem__ButtonOuter-sc-22szay-0 c2 c3"
149+
type="button"
149150
value="Apples"
150151
>
151152
Apples
152153
</button>
153154
<button
154155
aria-pressed="false"
155156
class="ButtonItem__ButtonOuter-sc-22szay-0 c2 c3"
157+
type="button"
156158
value="Oranges"
157159
>
158160
Oranges
159161
</button>
160162
<button
161163
aria-pressed="true"
162164
class="ButtonItem__ButtonOuter-sc-22szay-0 c2 c3"
165+
type="button"
163166
value="Bananas"
164167
>
165168
Bananas

packages/components/src/List/ListItem.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ export const ListItemLabel = styled.div
119119
.withConfig<ListItemLabelProps>({
120120
shouldForwardProp: (prop) => prop !== 'itemRole',
121121
})
122-
.attrs<ListItemLabelProps>(({ disabled, itemRole }) => ({
122+
.attrs<ListItemLabelProps>(({ disabled, itemRole = 'button' }) => ({
123123
as: !disabled && itemRole === 'link' ? 'a' : 'button',
124+
type: itemRole === 'button' || disabled ? 'button' : undefined,
124125
}))<ListItemLabelProps>``
125126

126127
const ListItemInternal = forwardRef(

packages/components/src/Tabs/Tab.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ export interface TabProps
5151
onSelect?: () => void
5252
}
5353

54-
const TabStyle = styled.button.withConfig({ shouldForwardProp })<TabProps>`
54+
const TabStyle = styled.button
55+
.withConfig({ shouldForwardProp })
56+
.attrs(({ type = 'button' }) => ({
57+
type,
58+
}))<TabProps>`
5559
${reset}
5660
${layout}
5761
${padding}

packages/components/src/Tabs/__snapshots__/Tabs.test.tsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ exports[`focus behavior Tab Focus: does not render focus ring after click 1`] =
4949
id="tab-0"
5050
role="tab"
5151
tabindex="-1"
52+
type="button"
5253
>
5354
tab1
5455
</button>
@@ -104,6 +105,7 @@ exports[`focus behavior Tab Focus: renders focus ring for keyboard navigation 1`
104105
id="tab-1"
105106
role="tab"
106107
tabindex="-1"
108+
type="button"
107109
>
108110
tab2
109111
</button>

0 commit comments

Comments
 (0)