= {}) => (
-
-
-
- row header
- header1
- header2
- header3
-
-
-
-
- row header
- cell1
- cell2
- cell3
-
-
- row header
- cell1
-
-
-
-);
-
-function renderFlatTable(props = {}) {
- return mount();
-}
-
-function renderFlatTableWithDiv(props = {}) {
- return mount(
-
-
-
-
- row header
- header1
- header2
- header3
-
-
-
-
- row header
- cell1
- cell2
- cell3
-
-
- row header
- cell1
-
-
-
-
- );
-}
-
-describe("FlatTable", () => {
- beforeAll(() => {
- loggerSpy.mockImplementation(() => {});
- });
-
- afterAll(() => {
- loggerSpy.mockRestore();
- });
-
- it("ariaDescribedby prop should have been propagated to the table", () => {
- const customId = "foo";
- const wrapper = renderFlatTable({ ariaDescribedby: customId });
-
- expect(wrapper.find(StyledFlatTable).prop("aria-describedby")).toBe(
- customId
- );
- });
-
- describe("when a data prop is added", () => {
- it("should be added to the root element", () => {
- const wrapper = renderFlatTable({ "data-role": "test" });
-
- expect(wrapper.find(StyledFlatTableWrapper).props()["data-role"]).toEqual(
- "test"
- );
- });
- });
-
- describe('when rendered with proper table data and "hasStickyHead" prop set to true', () => {
- let wrapper: ReactWrapper;
-
- beforeEach(() => {
- wrapper = renderFlatTable({ hasStickyHead: true });
- });
-
- it("should have the overflow-y css property set to to auto", () => {
- expect(wrapper.find(StyledFlatTableWrapper)).toHaveStyleRule(
- "overflow-y",
- "auto"
- );
- });
-
- it("should set position sticky on all th inside the table head", () => {
- assertStyleMatch(
- {
- position: "sticky",
- top: "0",
- left: "0",
- zIndex: "1005",
- },
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `${StyledFlatTableHead}` }
- );
- });
-
- it('then all Headers should have proper styling if `colorTheme="dark"`', () => {
- wrapper = renderFlatTable({ colorTheme: "dark" });
-
- assertStyleMatch(
- {
- backgroundColor: "var(--colorsUtilityMajor400)",
- borderRight: "1px solid var(--colorsUtilityMajor300)",
- color: "var(--colorsUtilityYang100)",
- borderBottomColor: "var(--colorsUtilityMajor300)",
- },
-
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `${StyledFlatTableHeader}` }
- );
- });
-
- it('then all Headers should have proper styling if `colorTheme="light"`', () => {
- wrapper = renderFlatTable({ colorTheme: "light" });
-
- assertStyleMatch(
- {
- backgroundColor: "var(--colorsUtilityMajor100)",
- borderRight: "1px solid var(--colorsUtilityMajor150)",
- borderBottomColor: "var(--colorsUtilityMajor150)",
- },
-
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `${StyledFlatTableHeader}` }
- );
- });
-
- it('then all Headers should have proper styling if `colorTheme="transparent-base"`', () => {
- wrapper = renderFlatTable({ colorTheme: "transparent-base" });
-
- assertStyleMatch(
- {
- backgroundColor: "var(--colorsUtilityMajor025)",
- borderBottomColor: "var(--colorsUtilityMajor100)",
- },
-
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `${StyledFlatTableHeader}` }
- );
- });
-
- it('then all Headers should have proper styling if `colorTheme="transparent-white"`', () => {
- wrapper = renderFlatTable({ colorTheme: "transparent-white" });
-
- assertStyleMatch(
- {
- backgroundColor: "var(--colorsUtilityYang100)",
- borderBottomColor: "var(--colorsUtilityMajor100)",
- },
-
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `${StyledFlatTableHeader}` }
- );
- });
- });
-
- describe("when FlatTable is a child of Sidebar", () => {
- let wrapper: ReactWrapper;
- beforeEach(() => {
- wrapper = mount(
-
-
-
-
- foo |
-
-
-
-
- );
- });
-
- it.each([
- ["StyledFlatTableHeader", StyledFlatTableHeader],
- ["StyledFlatTableRowHeader", StyledFlatTableRowHeader],
- ["StyledFlatTableCheckbox", StyledFlatTableCheckbox],
- ])("should override the styles for %s", (id, el) => {
- const modifierString =
- id === "StyledFlatTableHeader" ? el : `${StyledFlatTableHead} ${el}`;
- assertStyleMatch(
- {
- backgroundColor: "var(--colorsUtilityMajor040)",
- borderRight: "2px solid var(--colorsUtilityMajor040)",
- color: "var(--colorsUtilityYin090)",
- },
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `${modifierString}` }
- );
- });
- });
-
- describe.each(["dark", "light", "transparent-base", "transparent-base"])(
- "when isZebra prop is set to true and colorTheme is %s",
- (colorTheme) => {
- it("should apply hover styling to any FlatTableCheckbox not rendered as a th element", () => {
- const wrapper = renderFlatTable({ isZebra: true, colorTheme });
-
- assertStyleMatch(
- {
- backgroundColor: "var(--colorsUtilityMajor025)",
- },
- wrapper.find(StyledFlatTable),
- {
- modifier: `${StyledFlatTableRow}:hover ${StyledFlatTableCheckbox}:not(th)`,
- }
- );
- });
- }
- );
-
- describe("when the caption prop is set", () => {
- it("then that caption should be rendered in the table", () => {
- const captionText = "foo";
- const wrapper = renderFlatTable({ caption: captionText });
-
- expect(wrapper.find("caption").exists()).toBe(true);
- expect(wrapper.find("caption").text()).toBe(captionText);
- });
- });
-
- describe.each(FLAT_TABLE_SIZES)("when the size prop is set to %s", (size) => {
- const { fontSize, paddingSize } = cellSizes[size];
- const expectedStyles = {
- fontSize,
- paddingLeft: paddingSize,
- paddingRight: paddingSize,
- };
-
- it("then expected styles should be applied to table cells underlying div", () => {
- const wrapper = renderFlatTable({ size });
-
- assertStyleMatch(expectedStyles, wrapper.find(StyledFlatTable), {
- modifier: `${StyledFlatTableCell} > div`,
- });
- });
-
- it("then expected styles should be applied to table headers underlying div", () => {
- const wrapper = renderFlatTable({ size });
-
- assertStyleMatch(expectedStyles, wrapper.find(StyledFlatTable), {
- modifier: `${StyledFlatTableHeader} > div`,
- });
- });
-
- it("then expected styles should be applied to row headers underlying div", () => {
- const wrapper = renderFlatTable({ size });
-
- assertStyleMatch(expectedStyles, wrapper.find(StyledFlatTable), {
- modifier: `${StyledFlatTableRowHeader} > div`,
- });
- });
-
- it("then the Table Rows should have expected height", () => {
- const wrapper = renderFlatTable({ size });
-
- assertStyleMatch(
- {
- height: cellSizes[size].height,
- },
- wrapper.find(StyledFlatTable),
- {
- modifier: `${StyledFlatTableRow}`,
- }
- );
- });
- });
-
- describe("StyledFlatTableWrapper", () => {
- let wrapper;
- const Footer = () => foo
;
- it("applies correct styles when a div is larger than the FlatTable", () => {
- wrapper = renderFlatTableWithDiv({ footer: });
- assertStyleMatch(
- {
- boxSizing: "border-box",
- },
- wrapper.find(StyledFlatTableWrapper)
- );
- });
-
- it("applies correct styles when hasMaxHeight is true", () => {
- wrapper = renderFlatTableWithDiv({
- footer: ,
- hasMaxHeight: true,
- });
- assertStyleMatch(
- {
- maxHeight: "100%",
- },
- wrapper.find(StyledFlatTableWrapper)
- );
- });
-
- it("applies correct styles when hasMaxHeight is false", () => {
- wrapper = renderFlatTableWithDiv({
- footer: ,
- hasMaxHeight: false,
- });
- assertStyleMatch(
- {
- maxHeight: undefined,
- },
- wrapper.find(StyledFlatTableWrapper)
- );
- });
- });
-
- describe("when FlatTableHead rows have only one child", () => {
- it("does not throw an error", () => {
- expect(() => {
- mount(
-
-
-
- Name
-
-
- City
-
-
-
-
- John Doe
-
-
- John Doe
-
-
-
- );
- }).not.toThrow();
- });
- });
-
- describe("footer", () => {
- let wrapper;
-
- const Footer = () => foo
;
-
- it("renders when content is passed in", () => {
- wrapper = renderFlatTable({ footer: });
- expect(wrapper.find(Footer).exists()).toEqual(true);
- });
-
- it("renders when content is passed in and hasStickyFooter is true", () => {
- wrapper = renderFlatTable({ footer: , hasStickyFooter: true });
- assertStyleMatch(
- {
- position: "sticky",
- bottom: "0px",
- zIndex: "1001",
- },
- wrapper.find(StyledFlatTableFooter)
- );
- });
-
- it("sets the wrapper flex css props as expected", () => {
- wrapper = renderFlatTable({ footer: , hasStickyFooter: true });
- expect(
- wrapper.find(StyledFlatTableWrapper).prop("justifyContent")
- ).toEqual("space-between");
- });
- });
-
- describe("styled system", () => {
- testStyledSystemMargin(RenderComponent);
- });
-
- describe("when width prop is set", () => {
- it("should apply the correct styles to StyledFlatTableWrapper and StyledTableContainer", () => {
- const wrapper = renderFlatTable({ width: "300px" });
-
- assertStyleMatch(
- {
- width: "300px",
- },
- wrapper.find(StyledFlatTableWrapper)
- );
-
- assertStyleMatch(
- {
- width: "300px",
- },
- wrapper.find(StyledTableContainer)
- );
- });
-
- describe("when overflowX prop is also set", () => {
- it("should apply the correct styles to StyledFlatTableWrapper and StyledTableContainer", () => {
- const wrapper = renderFlatTable({ width: "300px", overflowX: "auto" });
-
- assertStyleMatch(
- {
- overflowX: "hidden",
- },
- wrapper.find(StyledFlatTableWrapper)
- );
-
- assertStyleMatch(
- {
- overflowX: "auto",
- },
- wrapper.find(StyledTableContainer)
- );
- });
- });
- });
-
- describe("z-indexes", () => {
- let wrapper: ReactWrapper;
- const modifiers = [
- [`${StyledFlatTableHead} ${StyledFlatTableRowHeader}`, "1005"],
- [`${StyledFlatTableHeader}.isSticky`, "1005"],
- [`${StyledFlatTableHead} ${StyledFlatTableCheckbox}.isSticky`, "1005"],
- [`${StyledFlatTableHeader}`, "1003"],
- [`${StyledFlatTableCheckbox}`, "1003"],
- [`tbody ${StyledFlatTableRowHeader}`, "1000"],
- [`${StyledFlatTableCell}.isSticky`, "1000"],
- [`tbody ${StyledFlatTableCheckbox}.isSticky`, "1000"],
- ];
-
- beforeEach(() => {
- wrapper = mount(
-
-
-
- heading one
- heading two
- heading three
-
-
-
-
- name
- unique id
- city
-
-
-
- );
- });
-
- it.each(modifiers)(
- "should apply the expected value to elements rendered in thead",
- (modifier, zIndex) => {
- assertStyleMatch(
- {
- zIndex,
- },
- wrapper,
- { modifier }
- );
- }
- );
- });
-
- describe("rounded corners", () => {
- it("has the expected border radius styling when no footer rendered", () => {
- const wrapper = mount(
-
-
-
- heading one
-
-
-
-
- child one
-
-
-
- );
-
- assertStyleMatch(
- {
- borderTopLeftRadius: "var(--borderRadius100)",
- borderTopRightRadius: "var(--borderRadius100)",
- borderBottomLeftRadius: "var(--borderRadius100)",
- borderBottomRightRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper)
- );
-
- assertStyleMatch(
- {
- borderTopLeftRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper),
- {
- modifier: `thead ${StyledFlatTableRow}:first-of-type th:first-of-type`,
- }
- );
-
- assertStyleMatch(
- {
- borderTopRightRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper),
- {
- modifier: `thead ${StyledFlatTableRow}:first-of-type th:last-of-type`,
- }
- );
-
- assertStyleMatch(
- {
- borderBottomLeftRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper),
- {
- modifier: `tbody ${StyledFlatTableRow}:last-of-type td:first-child`,
- }
- );
-
- assertStyleMatch(
- {
- borderBottomRightRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper),
- { modifier: `tbody ${StyledFlatTableRow}:last-of-type td:last-child` }
- );
- });
-
- it("when table's footer contains a Pager, override Pager's top border styling so it connects to the table", () => {
- rtlRender(
- {}} />}>
-
-
- heading one |
-
-
-
-
- item one
-
-
-
- );
-
- const pager = screen.getByTestId("pager");
- expect(pager).toHaveStyle({
- borderTop: "none",
- borderTopLeftRadius: 0,
- borderTopRightRadius: 0,
- });
- });
-
- it("when table's sticky footer contains a Pager, neither the table nor Pager has bottom rounded corners", () => {
- rtlRender(
- {}} />}
- >
-
-
- heading one
-
-
-
-
- child one
-
-
-
- );
-
- const tableWrapper = screen.getByRole("region");
- const pager = screen.getByTestId("pager");
-
- expect(tableWrapper).toHaveStyle({
- borderBottomLeftRadius: undefined,
- borderBottomRightRadius: undefined,
- });
- expect(pager).toHaveStyle({
- borderBottomLeftRadius: 0,
- borderBottomRightRadius: 0,
- });
- });
-
- it("has the expected border radius styling when the first column has rowspan that spans over bottom row", () => {
- const wrapper = mount(
-
-
-
- heading one
-
-
-
-
- child one
- child two
-
-
- child one
-
-
-
- );
-
- assertStyleMatch(
- {
- borderBottomLeftRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper),
- {
- modifier: `tbody ${StyledFlatTableRow}:nth-of-type(1) td:first-child`,
- }
- );
- });
-
- it("has the expected border radius styling when the last column has rowspan that spans over bottom row", () => {
- const wrapper = mount(
-
-
-
- heading one
-
-
-
-
- child one
- child two
-
-
- child one
-
-
-
- );
-
- assertStyleMatch(
- {
- borderBottomRightRadius: "var(--borderRadius100)",
- },
- wrapper.find(StyledFlatTableWrapper),
- {
- modifier: `tbody ${StyledFlatTableRow}:nth-of-type(1) td:last-child`,
- }
- );
- });
- });
-
- describe("keyboard navigation", () => {
- const preventDefault = jest.fn();
- const arrowDown = { key: "ArrowDown", preventDefault };
- const arrowUp = { key: "ArrowUp", preventDefault };
- const arrowLeft = { key: "ArrowLeft" };
-
- describe("when rows are clickable", () => {
- it("should not move focus to first row when down arrow pressed and table wrapper focused when focusRedesignOptOut is not set", async () => {
- const { container } = rtlRender(
-
-
- {}}>
- one
- two
-
- {}}>
- three
- four
-
-
-
- );
- const tableWrapper = container.querySelectorAll(
- "div"
- )[1] as HTMLElement;
- tableWrapper?.focus();
- expect(tableWrapper).toHaveFocus();
- expect(await screen.findByRole("region")).toHaveStyle({
- outline: "transparent 3px solid",
- "box-shadow":
- "0px 0px 0px var(--borderWidth300) var(--colorsSemanticFocus500),0px 0px 0px var(--borderWidth600) var(--colorsUtilityYin090)",
- });
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(tableWrapper).toHaveFocus();
- });
-
- it("should not move focus to first row when down arrow pressed and table wrapper focused when focusRedesignOptOut is set", async () => {
- const { container } = rtlRender(
-
-
-
- {}}>
- one
- two
-
- {}}>
- three
- four
-
-
-
-
- );
- const tableWrapper = container.querySelectorAll(
- "div"
- )[2] as HTMLElement;
- tableWrapper?.focus();
- expect(tableWrapper).toHaveFocus();
- expect(await screen.findByRole("region")).toHaveStyle({
- outline: "2px solid var(--colorsSemanticFocus500)",
- });
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(tableWrapper).toHaveFocus();
- });
-
- it("should set the first row's tabindex to 0 if no other rows are selected or highlighted", async () => {
- rtlRender(
-
-
- {}}>
- one
- two
-
- {}}>
- three
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("0");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("-1");
- });
- });
-
- it("should set the a row's tabindex to 0 when it is selected", () => {
- const wrapper = mount(
-
-
- {}}>
- one
- two
-
- {}} selected>
- three
- four
-
-
-
- );
-
- expect(
- wrapper.update().find(StyledFlatTableRow).at(0).prop("tabIndex")
- ).toBe(-1);
- expect(
- wrapper.update().find(StyledFlatTableRow).at(1).prop("tabIndex")
- ).toBe(0);
- });
-
- it("should set a row's tabindex to 0 when it is highlighted", () => {
- const wrapper = mount(
-
-
- {}}>
- one
- two
-
- {}} highlighted>
- three
- four
-
-
-
- );
-
- expect(
- wrapper.update().find(StyledFlatTableRow).at(0).prop("tabIndex")
- ).toBe(-1);
- expect(
- wrapper.update().find(StyledFlatTableRow).at(1).prop("tabIndex")
- ).toBe(0);
- });
-
- it("should move focus to the next row with an onClick when the down arrow key is pressed but not loop to the first when last reached", async () => {
- rtlRender(
-
-
- {}}>
- one
- two
-
- {}}>
- three
- four
-
- {}}>
- five
- six
-
- {}}>
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstRow = await screen.findByTestId("one");
- const secondRow = await screen.findByTestId("two");
- const thirdRow = await screen.findByTestId("three");
- const fourthRow = await screen.findByTestId("four");
- firstRow?.focus();
- expect(firstRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(secondRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(thirdRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(fourthRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(fourthRow).toHaveFocus();
- });
-
- it("should move focus to the previous row with an onClick when the up arrow key is pressed but not loop to the last when first reached", async () => {
- rtlRender(
-
-
- {}}>
- one
- two
-
- {}}>
- three
- four
-
- {}}>
- five
- six
-
- {}}>
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstRow = await screen.findByTestId("one");
- const secondRow = await screen.findByTestId("two");
- const thirdRow = await screen.findByTestId("three");
- const fourthRow = await screen.findByTestId("four");
- fourthRow?.focus();
- expect(fourthRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(thirdRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(secondRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstRow).toHaveFocus();
- });
-
- it("should not move focus from currently focused row when left arrow key pressed", async () => {
- rtlRender(
-
-
- {}}>
- one
- two
-
- {}}>
- three
- four
-
- {}}>
- five
- six
-
- {}}>
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const fourthRow = await screen.findByTestId("four");
- fourthRow?.focus();
- expect(fourthRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowLeft);
- expect(fourthRow).toHaveFocus();
- });
-
- it("should move focus to the next expandable row when the down arrow key is pressed but not loop to the first when last reached", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
- five
- six
-
-
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstRow = await screen.findByTestId("one");
- const secondRow = await screen.findByTestId("two");
- const thirdRow = await screen.findByTestId("three");
- const fourthRow = await screen.findByTestId("four");
- firstRow?.focus();
- expect(firstRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(secondRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(thirdRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(fourthRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(fourthRow).toHaveFocus();
- });
-
- it("should move focus to the previous expandable row when the up arrow key is pressed but not loop to the last when first reached", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
- five
- six
-
-
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstRow = await screen.findByTestId("one");
- const secondRow = await screen.findByTestId("two");
- const thirdRow = await screen.findByTestId("three");
- const fourthRow = await screen.findByTestId("four");
- fourthRow?.focus();
- expect(fourthRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(thirdRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(secondRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstRow).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstRow).toHaveFocus();
- });
-
- it("should move focus to the next row when the down arrow key is pressed whilst a checkbox input child is focused", async () => {
- rtlRender(
-
-
- {}}>
-
- two
-
- {}}>
- three
- four
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const secondRow = await screen.findByTestId("two");
- const checkbox = await screen.findByRole("checkbox");
- checkbox.focus();
- expect(checkbox).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(secondRow).toHaveFocus();
- });
-
- it("should move focus to the previous row when the up arrow key is pressed whilst a checkbox input child is focused", async () => {
- rtlRender(
-
-
- {}}>
- one
- two
-
- {}}>
-
- four
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstRow = await screen.findByTestId("one");
- const checkbox = await screen.findByRole("checkbox");
- checkbox.focus();
- expect(checkbox).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstRow).toHaveFocus();
- });
- });
-
- describe("when the first column is expandable", () => {
- it("should set the first cell's tabindex to 0", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("0");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("-1");
- });
- });
-
- it("should tabindex to 0 on the first cell in a highlighted row", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("-1");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("0");
- });
- });
-
- it("should tabindex to 0 on the first cell in a selected row", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("-1");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("0");
- });
- });
-
- it("should set the first row header's tabindex to 0", async () => {
- rtlRender(
-
-
-
-
- one
-
- two
-
-
-
- three
-
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("0");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("-1");
- });
- });
-
- it("should tabindex to 0 on the first row header in a highlighted row", async () => {
- rtlRender(
-
-
-
-
- one
-
- two
-
-
-
- three
-
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("-1");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("0");
- });
- });
-
- it("should tabindex to 0 on the first row header in a selected row", async () => {
- rtlRender(
-
-
-
-
- one
-
- two
-
-
-
- three
-
- four
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("one").getAttribute("tabindex")).toBe("-1");
- expect(screen.getByTestId("two").getAttribute("tabindex")).toBe("0");
- });
- });
-
- it("should move focus to the next focusable cell when the down arrow key is pressed but not loop to the first when last reached", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
- five
- six
-
-
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstFocusableCell = await screen.findByTestId("one");
- const secondFocusableCell = await screen.findByTestId("two");
- const thirdFocusableCell = await screen.findByTestId("three");
- const fourthFocusableCell = await screen.findByTestId("four");
- firstFocusableCell.focus();
- expect(firstFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(secondFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(thirdFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(fourthFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowDown);
- expect(fourthFocusableCell).toHaveFocus();
- });
-
- it("should move focus to the previous focusable cell when the up arrow key is pressed but not loop to the last when first reached", async () => {
- rtlRender(
-
-
-
- one
- two
-
-
- three
- four
-
-
- five
- six
-
-
- seven
- eight
-
-
-
- );
-
- const tableWrapper = await screen.findByRole("region");
- const firstFocusableCell = await screen.findByTestId("one");
- const secondFocusableCell = await screen.findByTestId("two");
- const thirdFocusableCell = await screen.findByTestId("three");
- const fourthFocusableCell = await screen.findByTestId("four");
- fourthFocusableCell.focus();
- expect(fourthFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(thirdFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(secondFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstFocusableCell).toHaveFocus();
- fireEvent.keyDown(tableWrapper, arrowUp);
- expect(firstFocusableCell).toHaveFocus();
- });
- });
- });
-});
-
-test("hides the leftmost and rightmost table borders when `hasOuterVerticalBorders` is false", () => {
- rtlRender(
-
-
-
- Fruit
- Colour
- Planet
-
-
-
-
- Apple
- Purple
- Pluto
-
-
-
- );
-
- expect(screen.getByTestId("flat-table-wrapper")).toHaveStyleRule(
- "border-left-color",
- "var(--colorsUtilityMajorTransparent)",
- {
- modifier: `${StyledFlatTableRow} > ${StyledFlatTableCell}:first-child`,
- }
- );
-
- expect(screen.getByTestId("flat-table-wrapper")).toHaveStyleRule(
- "border-right-color",
- "var(--colorsUtilityMajorTransparent)",
- {
- modifier: `${StyledFlatTableRow} > ${StyledFlatTableCell}:last-child`,
- }
- );
-});
-
-test("uses `bottomBorderRadius` prop to change the bottom left and right border radius of the table", () => {
- rtlRender(
-
-
-
- Fruit
- Colour
- Planet
-
-
-
-
- Apple
- Purple
- Pluto
-
-
- Durian
- Green
- Mars
-
-
-
- );
-
- expect(screen.getByTestId("flat-table-wrapper")).toHaveStyleRule(
- "border-bottom-left-radius",
- "var(--borderRadius000)",
- {
- modifier: `tbody ${StyledFlatTableRow}:last-of-type td:first-child`,
- }
- );
-
- expect(screen.getByTestId("flat-table-wrapper")).toHaveStyleRule(
- "border-bottom-right-radius",
- "var(--borderRadius000)",
- {
- modifier: `tbody ${StyledFlatTableRow}:last-of-type td:last-child`,
- }
- );
-});
diff --git a/src/components/flat-table/flat-table.test.tsx b/src/components/flat-table/flat-table.test.tsx
new file mode 100644
index 0000000000..9b7ec9c132
--- /dev/null
+++ b/src/components/flat-table/flat-table.test.tsx
@@ -0,0 +1,1440 @@
+import React from "react";
+
+import { render, screen, waitFor } from "@testing-library/react";
+
+import userEvent from "@testing-library/user-event";
+import FlatTable from "./flat-table.component";
+import FlatTableHead from "./flat-table-head/flat-table-head.component";
+import FlatTableBody from "./flat-table-body/flat-table-body.component";
+import FlatTableRow from "./flat-table-row/flat-table-row.component";
+import FlatTableHeader from "./flat-table-header/flat-table-header.component";
+import FlatTableCell from "./flat-table-cell/flat-table-cell.component";
+import FlatTableCheckbox from "./flat-table-checkbox/flat-table-checkbox.component";
+import FlatTableRowHeader from "./flat-table-row-header/flat-table-row-header.component";
+import { testStyledSystemMargin } from "../../__spec_helper__/__internal__/test-utils";
+import StyledFlatTableHeader from "./flat-table-header/flat-table-header.style";
+import StyledFlatTableCheckbox from "./flat-table-checkbox/flat-table-checkbox.style";
+import DrawerSidebarContext from "../drawer/__internal__/drawer-sidebar.context";
+import { StyledFlatTableCell } from "./flat-table-cell/flat-table-cell.style";
+import StyledFlatTableRow from "./flat-table-row/flat-table-row.style";
+import Pager from "../pager/pager.component";
+import CarbonProvider from "../carbon-provider";
+
+testStyledSystemMargin((props) => (
+
+
+
+ row header
+ header1
+ header2
+ header3
+
+
+
+
+ row header
+ cell1
+ cell2
+ cell3
+
+
+
+));
+
+describe("when rows are interactive", () => {
+ it("should apply the expected focus styling to the wrapper element when it is focused and `focusRedesignOptOut` is not set", () => {
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+
+
+ );
+ const tableWrapper = screen.getByRole("region");
+ const focusableTableContainer = screen.getByTestId("flat-table-container");
+ focusableTableContainer.focus();
+
+ expect(focusableTableContainer).toHaveFocus();
+ expect(tableWrapper).toHaveStyleRule("outline", "transparent 3px solid");
+ expect(tableWrapper).toHaveStyleRule(
+ "box-shadow",
+ "0px 0px 0px var(--borderWidth300) var(--colorsSemanticFocus500),0px 0px 0px var(--borderWidth600) var(--colorsUtilityYin090)"
+ );
+ });
+
+ it("should apply the expected focus styling to the wrapper element when it is focused and `focusRedesignOptOut` is set", () => {
+ render(
+
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+
+
+
+ );
+ const tableWrapper = screen.getByRole("region");
+ const focusableTableContainer = screen.getByTestId("flat-table-container");
+ focusableTableContainer.focus();
+
+ expect(focusableTableContainer).toHaveFocus();
+ expect(tableWrapper).toHaveStyleRule(
+ "outline",
+ "2px solid var(--colorsSemanticFocus500)"
+ );
+ });
+
+ it("should not move focus to first row with `onClick` when down arrow pressed and table wrapper focused", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+
+
+ );
+ const focusableTableContainer = screen.getByTestId("flat-table-container");
+ focusableTableContainer.focus();
+
+ expect(focusableTableContainer).toHaveFocus();
+
+ await user.keyboard("ArrowDown");
+
+ expect(focusableTableContainer).toHaveFocus();
+ expect(screen.getByRole("row", { name: "one two" })).not.toHaveFocus();
+ });
+
+ it("should set the first row's tabindex to 0 if no other rows are `selected` or `highlighted` but has `onClick`", async () => {
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+
+
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("row", { name: "one two" })).toHaveAttribute(
+ "tabindex",
+ "0"
+ );
+ });
+
+ await waitFor(() => {
+ expect(screen.getByRole("row", { name: "three four" })).toHaveAttribute(
+ "tabindex",
+ "-1"
+ );
+ });
+ });
+
+ it("should move focus to the next row with `onClick` when the down arrow key is pressed but not loop to the first when last reached", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+ {}}>
+ five
+ six
+
+ {}}>
+ seven
+ eight
+
+
+
+ );
+ const focusableTableContainer = screen.getByTestId("flat-table-container");
+ const firstRow = screen.getByRole("row", { name: "one two" });
+ const secondRow = screen.getByRole("row", { name: "three four" });
+ const thirdRow = screen.getByRole("row", { name: "five six" });
+ const fourthRow = screen.getByRole("row", { name: "seven eight" });
+ focusableTableContainer?.focus();
+
+ await user.keyboard("{Tab}");
+ expect(firstRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(secondRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(thirdRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(fourthRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(fourthRow).toHaveFocus();
+ });
+
+ it("should move focus to the previous row with `onClick` when the up arrow key is pressed but not loop to the last when first reached", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+ {}}>
+ five
+ six
+
+ {}}>
+ seven
+ eight
+
+
+
+ );
+ const firstRow = screen.getByRole("row", { name: "one two" });
+ const secondRow = screen.getByRole("row", { name: "three four" });
+ const thirdRow = screen.getByRole("row", { name: "five six" });
+ const fourthRow = screen.getByRole("row", { name: "seven eight" });
+ fourthRow?.focus();
+
+ expect(fourthRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(thirdRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(secondRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstRow).toHaveFocus();
+ });
+
+ it("should not move focus from currently focused row with `onClick` when left arrow key pressed", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ three
+ four
+
+ {}}>
+ five
+ six
+
+ {}}>
+ seven
+ eight
+
+
+
+ );
+ const fourthRow = screen.getByRole("row", { name: "seven eight" });
+ fourthRow?.focus();
+
+ expect(fourthRow).toHaveFocus();
+ await user.keyboard("{ArrowLeft}");
+ expect(fourthRow).toHaveFocus();
+ });
+
+ it("should move focus to the next `expandable` row when the down arrow key is pressed but not loop to the first when last reached", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+ five
+ six
+
+
+ seven
+ eight
+
+
+
+ );
+ const firstRow = screen.getByRole("row", { name: "one two" });
+ const secondRow = screen.getByRole("row", { name: "three four" });
+ const thirdRow = screen.getByRole("row", { name: "five six" });
+ const fourthRow = screen.getByRole("row", { name: "seven eight" });
+ firstRow?.focus();
+
+ expect(firstRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(secondRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(thirdRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(fourthRow).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(fourthRow).toHaveFocus();
+ });
+
+ it("should move focus to the previous `expandable` row when the up arrow key is pressed but not loop to the last when first reached", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+ five
+ six
+
+
+ seven
+ eight
+
+
+
+ );
+ const firstRow = screen.getByRole("row", { name: "one two" });
+ const secondRow = screen.getByRole("row", { name: "three four" });
+ const thirdRow = screen.getByRole("row", { name: "five six" });
+ const fourthRow = screen.getByRole("row", { name: "seven eight" });
+ fourthRow?.focus();
+
+ expect(fourthRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(thirdRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(secondRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstRow).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstRow).toHaveFocus();
+ });
+
+ it("should move focus to the next row with `onClick` when the down arrow key is pressed whilst a checkbox input child is focused", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ {}}>
+ {}} />
+ two
+
+ {}}>
+ three
+ four
+
+
+
+ );
+ const secondRow = screen.getByRole("row", { name: "three four" });
+ const checkbox = screen.getByRole("checkbox");
+ checkbox.focus();
+
+ expect(checkbox).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(secondRow).toHaveFocus();
+ });
+
+ it("should move focus to the previous row with `onClick` when the up arrow key is pressed whilst a checkbox input child is focused", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ {}}>
+ one
+ two
+
+ {}}>
+ {}} />
+ four
+
+
+
+ );
+ const firstRow = screen.getByRole("row", { name: "one two" });
+ const checkbox = screen.getByRole("checkbox");
+ checkbox.focus();
+
+ expect(checkbox).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstRow).toHaveFocus();
+ });
+});
+
+describe("when the first column is expandable", () => {
+ it("should set the first cell's tabindex to 0", async () => {
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+
+ );
+ await waitFor(() => {
+ expect(screen.getByTestId("one")).toHaveAttribute("tabindex", "0");
+ });
+
+ await waitFor(() => {
+ expect(screen.getByTestId("two")).toHaveAttribute("tabindex", "-1");
+ });
+ });
+
+ it("should set tabindex to 0 on the first cell in a `highlighted` row", async () => {
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("cell", { name: "one" })).toHaveAttribute(
+ "tabindex",
+ "-1"
+ );
+ });
+
+ await waitFor(() => {
+ expect(screen.getByRole("cell", { name: "three" })).toHaveAttribute(
+ "tabindex",
+ "0"
+ );
+ });
+ });
+
+ it("should set tabindex to 0 on the first cell in a `selected` row", async () => {
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("cell", { name: "one" })).toHaveAttribute(
+ "tabindex",
+ "-1"
+ );
+ });
+
+ await waitFor(() => {
+ expect(screen.getByRole("cell", { name: "three" })).toHaveAttribute(
+ "tabindex",
+ "0"
+ );
+ });
+ });
+
+ it("should set the first row header's tabindex to 0", async () => {
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("columnheader", { name: "one" })).toHaveAttribute(
+ "tabindex",
+ "0"
+ );
+ });
+
+ await waitFor(() => {
+ expect(
+ screen.getByRole("columnheader", { name: "three" })
+ ).toHaveAttribute("tabindex", "-1");
+ });
+ });
+
+ it("should set tabindex to 0 on the first row header in a `highlighted` row", async () => {
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("columnheader", { name: "one" })).toHaveAttribute(
+ "tabindex",
+ "-1"
+ );
+ });
+
+ await waitFor(() => {
+ expect(
+ screen.getByRole("columnheader", { name: "three" })
+ ).toHaveAttribute("tabindex", "0");
+ });
+ });
+
+ it("should set tabindex to 0 on the first row header in a `selected` row", async () => {
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("columnheader", { name: "one" })).toHaveAttribute(
+ "tabindex",
+ "-1"
+ );
+ });
+
+ await waitFor(() => {
+ expect(
+ screen.getByRole("columnheader", { name: "three" })
+ ).toHaveAttribute("tabindex", "0");
+ });
+ });
+
+ it("should move focus to the next focusable cell when the down arrow key is pressed but not loop to the first when last reached", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+ five
+ six
+
+
+ seven
+ eight
+
+
+
+ );
+ const firstFocusableCell = screen.getByRole("cell", { name: "one" });
+ const secondFocusableCell = screen.getByRole("cell", { name: "three" });
+ const thirdFocusableCell = screen.getByRole("cell", { name: "five" });
+ const fourthFocusableCell = screen.getByRole("cell", { name: "seven" });
+ firstFocusableCell.focus();
+
+ expect(firstFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(secondFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(thirdFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(fourthFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowDown}");
+ expect(fourthFocusableCell).toHaveFocus();
+ });
+
+ it("should move focus to the previous focusable cell when the up arrow key is pressed but not loop to the last when first reached", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+ five
+ six
+
+
+ seven
+ eight
+
+
+
+ );
+ const firstFocusableCell = screen.getByRole("cell", { name: "one" });
+ const secondFocusableCell = screen.getByRole("cell", { name: "three" });
+ const thirdFocusableCell = screen.getByRole("cell", { name: "five" });
+ const fourthFocusableCell = screen.getByRole("cell", { name: "seven" });
+ fourthFocusableCell.focus();
+
+ expect(fourthFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(thirdFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(secondFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowUp}");
+ expect(firstFocusableCell).toHaveFocus();
+ });
+
+ it("should not move focus from currently focused cell when left arrow key pressed", async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+ one
+ two
+
+
+ three
+ four
+
+
+ five
+ six
+
+
+ seven
+ eight
+
+
+
+ );
+ const fourthFocusableCell = screen.getByRole("cell", { name: "seven" });
+ fourthFocusableCell.focus();
+
+ expect(fourthFocusableCell).toHaveFocus();
+ await user.keyboard("{ArrowLeft}");
+ expect(fourthFocusableCell).toHaveFocus();
+ });
+});
+
+test("should ensure the table has an accessible desctription when `ariaDescribedby` prop is passed", () => {
+ render(
+ <>
+ here is some text to describe the table
+
+
+
+ heading one
+
+
+
+
+ child one
+
+
+
+ >
+ );
+ expect(screen.getByRole("table")).toHaveAccessibleDescription(
+ "here is some text to describe the table"
+ );
+});
+
+test("should set the `data-` attributes on the root element when the props are passed", () => {
+ render(
+
+
+
+ heading one
+
+
+
+
+ child one
+
+
+
+ );
+ const tableWrapper = screen.getByTestId("ft-data-role");
+
+ expect(tableWrapper).toHaveAttribute("data-component", "flat-table-wrapper");
+ expect(tableWrapper).toHaveAttribute("data-element", "ft-data-element");
+});
+
+describe("when `hasStickyHead` is set", () => {
+ it("should set the expected overflow styling on the wrapper element", () => {
+ render(
+
+
+
+ one
+
+
+
+ );
+ const tableWrapper = screen.getByTestId("ft-wrapper");
+
+ expect(tableWrapper).toHaveStyle("overflow-y: auto");
+ });
+
+ it("should set position sticky on all th inside the table head", () => {
+ render(
+
+
+
+ one
+
+
+
+ );
+
+ expect(screen.getByRole("rowgroup")).toHaveStyle({
+ position: "sticky",
+ top: "0",
+ left: "0",
+ zIndex: "1005",
+ });
+ });
+});
+
+test("should render the `caption` element and set the accessible name of the table when prop is passed", () => {
+ render(
+
+
+
+ heading one
+
+
+
+
+ child one
+
+
+
+ );
+
+ expect(screen.getByRole("table")).toHaveAccessibleName("this is a caption");
+});
+
+test("should apply the expeced box sizing styling to the wrapper element when it's height exceeds it's parent", () => {
+ render(
+
+ foo
}>
+
+
+ one
+
+
+ two
+
+
+ three
+
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyle(
+ "box-sizing: border-box"
+ );
+});
+
+test("should apply the expected max height on the wrapper element when the `hasMaxHeight` prop is set", () => {
+ render(
+ foo}>
+
+
+ one
+
+
+ two
+
+
+ three
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyle("max-height: 100%");
+});
+
+test("should not apply max height styling on the wrapper element when the `hasMaxHeight` prop is not set", () => {
+ render(
+ foo}>
+
+
+ one
+
+
+ two
+
+
+ three
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).not.toHaveStyle("max-height: 100%");
+});
+
+test("should render the `footer` element when prop is passed", () => {
+ render(
+ foo}>
+
+
+ one
+
+
+
+ );
+
+ expect(screen.getByText("foo")).toBeVisible();
+});
+
+test("should render the `footer` element with the expected styling when `hasStickyFooter` prop is also set", () => {
+ render(
+ foo} hasStickyFooter>
+
+
+ one
+
+
+
+ );
+
+ expect(screen.getByTestId("flat-table-footer")).toHaveStyle({
+ position: "sticky",
+ bottom: "0px",
+ zIndex: "1001",
+ });
+});
+
+test("should set the expected flex styling on the wrapper when `footer` and `hasStickyFooter` props are both passed", () => {
+ render(
+ foo} hasStickyFooter data-role="ft-wrapper">
+
+
+ one
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyle(
+ "justify-content: space-between"
+ );
+});
+
+test("should apply the expected `width` styling to the wrapper and container elements when the prop is passed", () => {
+ render(
+
+
+
+ one
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyle("width: 300px");
+ expect(screen.getByTestId("flat-table-container")).toHaveStyle(
+ "width: 300px"
+ );
+});
+
+test("should apply the expected `overflowX` styling to the wrapper and container elements when the prop is passed along with `width`", () => {
+ render(
+
+
+
+ one
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyle("overflow-x: hidden");
+ expect(screen.getByTestId("flat-table-container")).toHaveStyle(
+ "overflow-x: auto"
+ );
+});
+
+describe("rounded corners are enabled", () => {
+ it("should have the expected border radius styling when no footer is rendered", () => {
+ render(
+
+
+
+ heading one
+
+
+
+
+ child one
+
+
+
+ );
+ const wrapper = screen.getByTestId("ft-wrapper");
+
+ expect(wrapper).toHaveStyleRule(
+ "border-top-left-radius",
+ "var(--borderRadius100)"
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-top-right-radius",
+ "var(--borderRadius100)"
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-bottom-left-radius",
+ "var(--borderRadius100)"
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-bottom-right-radius",
+ "var(--borderRadius100)"
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-top-left-radius",
+ "var(--borderRadius100)",
+ {
+ modifier: `thead ${StyledFlatTableRow}:first-of-type th:first-of-type`,
+ }
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-top-right-radius",
+ "var(--borderRadius100)",
+ {
+ modifier: `thead ${StyledFlatTableRow}:first-of-type th:last-of-type`,
+ }
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-bottom-left-radius",
+ "var(--borderRadius100)",
+ {
+ modifier: `tbody ${StyledFlatTableRow}:last-of-type td:first-child`,
+ }
+ );
+ expect(wrapper).toHaveStyleRule(
+ "border-bottom-right-radius",
+ "var(--borderRadius100)",
+ {
+ modifier: `tbody ${StyledFlatTableRow}:last-of-type td:last-child`,
+ }
+ );
+ });
+
+ it("should override Pager's top border styling so it connects to the table when passed in `footer`,", () => {
+ render(
+ {}} />}>
+
+
+ heading one |
+
+
+
+
+ item one
+
+
+
+ );
+ const pager = screen.getByTestId("pager");
+
+ expect(pager).toHaveStyle({
+ borderTop: "none",
+ borderTopLeftRadius: 0,
+ borderTopRightRadius: 0,
+ });
+ });
+
+ it("should not apply any border-radius on the table wrapper an set to 0 on Pager when passed as `footer` and `hasStickyFooter` set,", () => {
+ render(
+ {}} />}
+ >
+
+
+ heading one
+
+
+
+
+ child one
+
+
+
+ );
+ const tableWrapper = screen.getByRole("region");
+ const pager = screen.getByTestId("pager");
+
+ expect(tableWrapper).toHaveStyle({
+ borderBottomLeftRadius: undefined,
+ borderBottomRightRadius: undefined,
+ });
+ expect(pager).toHaveStyle({
+ borderBottomLeftRadius: 0,
+ borderBottomRightRadius: 0,
+ });
+ });
+
+ it("should apply the expected border radius styling when the first column has rowspan that spans over bottom row", () => {
+ render(
+
+
+
+ heading one
+
+
+
+
+ child one
+ child two
+
+
+ child one
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyleRule(
+ "border-bottom-left-radius",
+ "var(--borderRadius100)",
+ {
+ modifier: `tbody ${StyledFlatTableRow}:nth-of-type(1) td:first-child`,
+ }
+ );
+ });
+
+ it("should apply the expected border radius styling when the last column has rowspan that spans over bottom row", () => {
+ render(
+
+
+
+ heading one
+
+
+
+
+ child one
+ child two
+
+
+ child one
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyleRule(
+ "border-bottom-right-radius",
+ "var(--borderRadius100)",
+ {
+ modifier: `tbody ${StyledFlatTableRow}:nth-of-type(1) td:last-child`,
+ }
+ );
+ });
+});
+
+test("should apply the exected min-width styling when rendered inside the drawer sidebar", () => {
+ render(
+
+
+
+
+ heading one
+
+
+
+
+ child one
+
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyle(
+ "min-width: fit-content"
+ );
+});
+
+test("should set the expected background colour on the rows hover when `isZebra` prop is set", () => {
+ render(
+
+
+
+ heading one
+
+
+
+
+ child one
+
+
+ child one
+
+
+ child one
+
+
+
+ );
+
+ expect(screen.getByRole("table")).toHaveStyleRule(
+ "background-color",
+ "var(--colorsUtilityMajor025)",
+ {
+ modifier: `${StyledFlatTableRow}:hover ${StyledFlatTableCheckbox}:not(th)`,
+ }
+ );
+});
+
+test("should set the expected background colour on the header cells when `colorTheme` is 'dark'", () => {
+ render(
+
+
+
+ row header
+ header1
+ header2
+ header3
+
+
+
+
+ row header
+ cell1
+ cell2
+ cell3
+
+
+ row header
+ cell1
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyleRule(
+ "background-color",
+ "var(--colorsUtilityMajor400)",
+ {
+ modifier: `${StyledFlatTableHeader}`,
+ }
+ );
+});
+
+test("should set the expected background colour on the header cells when `colorTheme` is 'light'", () => {
+ render(
+
+
+
+ row header
+ header1
+ header2
+ header3
+
+
+
+
+ row header
+ cell1
+ cell2
+ cell3
+
+
+ row header
+ cell1
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyleRule(
+ "background-color",
+ "var(--colorsUtilityMajor100)",
+ {
+ modifier: `${StyledFlatTableHeader}`,
+ }
+ );
+});
+
+test("should set the expected background colour on the header cells when `colorTheme` is 'transparent-base'", () => {
+ render(
+
+
+
+ row header
+ header1
+ header2
+ header3
+
+
+
+
+ row header
+ cell1
+ cell2
+ cell3
+
+
+ row header
+ cell1
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyleRule(
+ "background-color",
+ "var(--colorsUtilityMajor025)",
+ {
+ modifier: `${StyledFlatTableHeader}`,
+ }
+ );
+});
+
+test("should set the expected background colour on the header cells when `colorTheme` is 'transparent-white'", () => {
+ render(
+
+
+
+ row header
+ header1
+ header2
+ header3
+
+
+
+
+ row header
+ cell1
+ cell2
+ cell3
+
+
+ row header
+ cell1
+
+
+
+ );
+
+ expect(screen.getByTestId("ft-wrapper")).toHaveStyleRule(
+ "background-color",
+ "var(--colorsUtilityYang100)",
+ {
+ modifier: `${StyledFlatTableHeader}`,
+ }
+ );
+});
+
+test("hides the leftmost and rightmost table borders when `hasOuterVerticalBorders` is false", () => {
+ render(
+
+
+
+ Fruit
+ Colour
+ Planet
+
+
+
+
+ Apple
+ Purple
+ Pluto
+
+
+
+ );
+
+ expect(screen.getByTestId("flat-table-wrapper")).toHaveStyleRule(
+ "border-left-color",
+ "var(--colorsUtilityMajorTransparent)",
+ {
+ modifier: `${StyledFlatTableRow} > ${StyledFlatTableCell}:first-child`,
+ }
+ );
+
+ expect(screen.getByTestId("flat-table-wrapper")).toHaveStyleRule(
+ "border-right-color",
+ "var(--colorsUtilityMajorTransparent)",
+ {
+ modifier: `${StyledFlatTableRow} > ${StyledFlatTableCell}:last-child`,
+ }
+ );
+});
+
+test("should apply the expected class name to elements preceding left aligned sticky columns", () => {
+ render(
+
+
+
+ heading one
+ heading two
+ heading three
+
+
+
+
+ body one
+ body two
+ body three
+
+
+
+ );
+ const firstHeaderCell = screen.getByRole("columnheader", {
+ name: "heading one",
+ });
+ const secondHeaderCell = screen.getByRole("columnheader", {
+ name: "heading two",
+ });
+
+ expect(firstHeaderCell).toHaveClass("isSticky");
+ expect(secondHeaderCell).toHaveAttribute("data-sticky-align", "left");
+});
+
+test("should apply the expected class name to elements following right aligned sticky columns", () => {
+ render(
+
+
+
+ heading one
+
+ heading two
+
+ heading three
+
+
+
+
+ body one
+
+ body two
+
+ body three
+
+
+
+ );
+ const secondHeaderCell = screen.getByRole("columnheader", {
+ name: "heading two",
+ });
+ const thirdHeaderCell = screen.getByRole("columnheader", {
+ name: "heading three",
+ });
+
+ expect(secondHeaderCell).toHaveAttribute("data-sticky-align", "right");
+ expect(thirdHeaderCell).toHaveClass("isSticky");
+});
+
+test("should not throw an error when FlatTableHead rows have only one child", () => {
+ expect(() => {
+ render(
+
+
+
+ Name
+
+
+ City
+
+
+
+
+ John Doe
+
+
+ John Doe
+
+
+
+ );
+ }).not.toThrow();
+});