diff --git a/packages/lib/src/accordion/Accordion.test.tsx b/packages/lib/src/accordion/Accordion.test.tsx
index 4aab152c14..c121ceb984 100644
--- a/packages/lib/src/accordion/Accordion.test.tsx
+++ b/packages/lib/src/accordion/Accordion.test.tsx
@@ -131,4 +131,18 @@ describe("Accordion component tests", () => {
fireEvent.click(getByText("Accordion"));
expect(onChange).not.toHaveBeenCalled();
});
+ test("Accordion does not trigger onSubmit when inside a form", () => {
+ const onSubmit = jest.fn();
+ const { getByText } = render(
+
+ );
+ fireEvent.click(getByText("Accordion"));
+ expect(onSubmit).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/lib/src/accordion/AccordionItem.tsx b/packages/lib/src/accordion/AccordionItem.tsx
index cbae646b33..5d1b132128 100644
--- a/packages/lib/src/accordion/AccordionItem.tsx
+++ b/packages/lib/src/accordion/AccordionItem.tsx
@@ -174,6 +174,7 @@ const AccordionItem = ({
tabIndex={disabled ? -1 : tabIndex}
aria-expanded={isItemExpanded}
aria-controls={`accordion-panel-${id}`}
+ type="button"
>
diff --git a/packages/lib/src/date-input/Calendar.tsx b/packages/lib/src/date-input/Calendar.tsx
index 6e27e6f398..3e2b61b387 100644
--- a/packages/lib/src/date-input/Calendar.tsx
+++ b/packages/lib/src/date-input/Calendar.tsx
@@ -283,6 +283,7 @@ const Calendar = ({
today.get("month") === date.month &&
today.get("year") === innerDate.get("year")
}
+ type="button"
>
{date.day}
diff --git a/packages/lib/src/date-input/DateInput.test.tsx b/packages/lib/src/date-input/DateInput.test.tsx
index 8212575bf2..27655dcfa6 100644
--- a/packages/lib/src/date-input/DateInput.test.tsx
+++ b/packages/lib/src/date-input/DateInput.test.tsx
@@ -497,4 +497,20 @@ describe("DateInput component tests", () => {
userEvent.click(calendarAction);
expect(getByText("October 2080")).toBeTruthy();
});
+ test("Form onSubmit is not called when interacting with the calendar and pressing enter", () => {
+ const onSubmit = jest.fn();
+ const { getByRole, getAllByText } = render(
+
+ );
+ const calendarAction = getByRole("combobox");
+ userEvent.click(calendarAction);
+ const day1 = getAllByText("1")[0];
+ if (day1 != null) {
+ userEvent.click(day1);
+ }
+ userEvent.type(calendarAction, "{enter}");
+ expect(onSubmit).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/lib/src/date-input/DatePicker.tsx b/packages/lib/src/date-input/DatePicker.tsx
index fb5b8f45c4..723d8b4bd9 100644
--- a/packages/lib/src/date-input/DatePicker.tsx
+++ b/packages/lib/src/date-input/DatePicker.tsx
@@ -107,6 +107,7 @@ const DatePicker = ({ date, onDateSelect, id }: DatePickerPropsType): JSX.Elemen
handleMonthChange(innerDate.set("month", innerDate.get("month") - 1))}
+ type="button"
>
@@ -114,6 +115,7 @@ const DatePicker = ({ date, onDateSelect, id }: DatePickerPropsType): JSX.Elemen
setContent((currentContent) => (currentContent === "yearPicker" ? "calendar" : "yearPicker"))}
+ type="button"
>
{translatedLabels.calendar.months[innerDate.get("month")]} {innerDate.format("YYYY")}
@@ -124,6 +126,7 @@ const DatePicker = ({ date, onDateSelect, id }: DatePickerPropsType): JSX.Elemen
handleMonthChange(innerDate.set("month", innerDate.get("month") + 1))}
+ type="button"
>
diff --git a/packages/lib/src/date-input/YearPicker.tsx b/packages/lib/src/date-input/YearPicker.tsx
index b08f0cd547..d32ecc103c 100644
--- a/packages/lib/src/date-input/YearPicker.tsx
+++ b/packages/lib/src/date-input/YearPicker.tsx
@@ -109,6 +109,7 @@ const YearPicker = ({ onYearSelect, selectedDate, today }: YearPickerPropsType):
onYearSelect(year);
}}
role="option"
+ type="button"
>
{year}
diff --git a/packages/lib/src/dropdown/Dropdown.test.tsx b/packages/lib/src/dropdown/Dropdown.test.tsx
index ba2290eb71..de333c8ebe 100644
--- a/packages/lib/src/dropdown/Dropdown.test.tsx
+++ b/packages/lib/src/dropdown/Dropdown.test.tsx
@@ -411,4 +411,15 @@ describe("Dropdown component tests", () => {
});
expect(queryByRole("menu")).toBeFalsy();
});
+ test("Dropdown does not trigger form submission when inside a form", () => {
+ const onSubmit = jest.fn();
+ const { getByRole } = render(
+
+ );
+ const dropdown = getByRole("button");
+ userEvent.click(dropdown);
+ expect(onSubmit).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/lib/src/dropdown/Dropdown.tsx b/packages/lib/src/dropdown/Dropdown.tsx
index f9d75012a4..c67357e45b 100644
--- a/packages/lib/src/dropdown/Dropdown.tsx
+++ b/packages/lib/src/dropdown/Dropdown.tsx
@@ -283,6 +283,7 @@ const DxcDropdown = ({
aria-label="Show options"
tabIndex={tabIndex}
ref={triggerRef}
+ type="button"
>
{icon && (
diff --git a/packages/lib/src/tabs/Tabs.test.tsx b/packages/lib/src/tabs/Tabs.test.tsx
index 66f4f4815c..430d3172d7 100644
--- a/packages/lib/src/tabs/Tabs.test.tsx
+++ b/packages/lib/src/tabs/Tabs.test.tsx
@@ -331,4 +331,29 @@ describe("Tabs component tests", () => {
expect(tabs[1]?.getAttribute("aria-selected")).toBe("false");
expect(tabs[2]?.getAttribute("aria-selected")).toBe("true");
});
+ test("Tabs should not trigger onSubmit inside a form", () => {
+ const onSubmit = jest.fn();
+ const onTabClick = [jest.fn(), jest.fn(), jest.fn()];
+ const { getAllByRole } = render(
+
+ );
+ const tabs = getAllByRole("tab");
+ if (tabs[0]) {
+ fireEvent.click(tabs[0]);
+ }
+ expect(onTabClick[0]).toHaveBeenCalled();
+ expect(onSubmit).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/lib/src/tabs/Tabs.tsx b/packages/lib/src/tabs/Tabs.tsx
index 1d137cf0f4..4d96e056ba 100644
--- a/packages/lib/src/tabs/Tabs.tsx
+++ b/packages/lib/src/tabs/Tabs.tsx
@@ -208,6 +208,7 @@ const DxcTabs = ({ children, iconPosition = "left", margin, tabIndex = 0 }: Tabs
disabled={!scrollLeftEnabled}
onClick={scrollLeft}
tabIndex={scrollLeftEnabled ? tabIndex : -1}
+ type="button"
>
@@ -229,6 +230,7 @@ const DxcTabs = ({ children, iconPosition = "left", margin, tabIndex = 0 }: Tabs
disabled={!scrollRightEnabled}
onClick={scrollRight}
tabIndex={scrollRightEnabled ? tabIndex : -1}
+ type="button"
>
diff --git a/packages/lib/src/toggle-group/ToggleGroup.test.tsx b/packages/lib/src/toggle-group/ToggleGroup.test.tsx
index 2aa58d02c2..88f916a7c8 100644
--- a/packages/lib/src/toggle-group/ToggleGroup.test.tsx
+++ b/packages/lib/src/toggle-group/ToggleGroup.test.tsx
@@ -160,4 +160,21 @@ describe("Toggle group component tests", () => {
fireEvent.click(getByRole("button", { name: "Ebay" }));
expect(handleChange).toHaveBeenCalledWith([1, 2]);
});
+
+ test("Togglegroup should not trigger onSubmit when inside a form", () => {
+ const handleSubmit = jest.fn();
+ const handleChange = jest.fn();
+ const options = [
+ { value: 1, label: "Amazon" },
+ { value: 2, label: "Ebay" },
+ ];
+ const { getByRole } = render(
+
+ );
+ fireEvent.click(getByRole("button", { name: "Ebay" }));
+ expect(handleChange).toHaveBeenCalledWith([1, 2]);
+ expect(handleSubmit).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/lib/src/toggle-group/ToggleGroup.tsx b/packages/lib/src/toggle-group/ToggleGroup.tsx
index db80c10de5..ec1ddd85f9 100644
--- a/packages/lib/src/toggle-group/ToggleGroup.tsx
+++ b/packages/lib/src/toggle-group/ToggleGroup.tsx
@@ -120,6 +120,7 @@ export default function DxcToggleGroup({
onlyIcon={!option.label && !!option.icon}
selected={selected}
tabIndex={!option.disabled ? tabIndex : -1}
+ type="button"
>
{option.icon && (
diff --git a/packages/lib/src/wizard/Wizard.test.tsx b/packages/lib/src/wizard/Wizard.test.tsx
index 83d14e9777..cd2dce2113 100644
--- a/packages/lib/src/wizard/Wizard.test.tsx
+++ b/packages/lib/src/wizard/Wizard.test.tsx
@@ -140,4 +140,25 @@ describe("Wizard components tests", () => {
expect(onClick).toHaveBeenNthCalledWith(1, 1);
expect(onClick).toHaveBeenNthCalledWith(2, 0);
});
+
+ test("Wizard should not trigger onSubmit when inside a form", () => {
+ const onSubmit = jest.fn();
+ const { getByText } = render(
+
+ );
+ const step = getByText("second-step");
+ fireEvent.click(step);
+ expect(onSubmit).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/lib/src/wizard/Wizard.tsx b/packages/lib/src/wizard/Wizard.tsx
index aa15ebfb89..fb0799b368 100644
--- a/packages/lib/src/wizard/Wizard.tsx
+++ b/packages/lib/src/wizard/Wizard.tsx
@@ -190,6 +190,7 @@ export default function DxcWizard({
}}
tabIndex={tabIndex}
unvisited={i > (currentStep ?? innerCurrent)}
+ type="button"
>