From 5970fdae21adb475c6cdb7f1173944392a513652 Mon Sep 17 00:00:00 2001 From: Ryo Matsukawa <76232929+ryo-manba@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:25:07 +0900 Subject: [PATCH] fix(tabs): set tab panel id correctly --- .changeset/rich-shirts-turn.md | 5 +++ .../docs/content/components/tabs/placement.ts | 1 - .../components/tabs/__tests__/tabs.test.tsx | 40 +++++++++++++++++-- packages/components/tabs/src/tab-panel.tsx | 2 +- packages/components/tabs/src/tab.tsx | 4 ++ 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 .changeset/rich-shirts-turn.md diff --git a/.changeset/rich-shirts-turn.md b/.changeset/rich-shirts-turn.md new file mode 100644 index 0000000000..0bd89a13a2 --- /dev/null +++ b/.changeset/rich-shirts-turn.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/tabs": patch +--- + +Fixed set tab panel id correctly (#2809) diff --git a/apps/docs/content/components/tabs/placement.ts b/apps/docs/content/components/tabs/placement.ts index 7f720ac41b..558a4bbdb5 100644 --- a/apps/docs/content/components/tabs/placement.ts +++ b/apps/docs/content/components/tabs/placement.ts @@ -7,7 +7,6 @@ export default function App() { setPlacement(value)} > diff --git a/packages/components/tabs/__tests__/tabs.test.tsx b/packages/components/tabs/__tests__/tabs.test.tsx index cdcb042259..f412236daa 100644 --- a/packages/components/tabs/__tests__/tabs.test.tsx +++ b/packages/components/tabs/__tests__/tabs.test.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import {act, render, fireEvent} from "@testing-library/react"; +import {act, render, fireEvent, within} from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import {focus} from "@nextui-org/test-utils"; @@ -11,7 +11,7 @@ type Item = { content?: React.ReactNode; }; -let tabs: Item[] = [ +let defaultItems: Item[] = [ { id: "item1", label: "Item1 ", @@ -76,7 +76,7 @@ describe("Tabs", () => { it("should render correctly (dynamic)", () => { const wrapper = render( - + {(item) => (
{item.content}
@@ -88,6 +88,40 @@ describe("Tabs", () => { expect(() => wrapper.unmount()).not.toThrow(); }); + it("renders property", () => { + const wrapper = render( + + {defaultItems.map((item) => ( + +
{item.content}
+
+ ))} +
, + ); + const tablist = wrapper.getByRole("tablist"); + + expect(tablist).toBeTruthy(); + const tabs = within(tablist).getAllByRole("tab"); + + expect(tabs.length).toBe(3); + + for (let tab of tabs) { + expect(tab).toHaveAttribute("tabindex"); + expect(tab).toHaveAttribute("aria-selected"); + const isSelected = tab.getAttribute("aria-selected") === "true"; + + if (isSelected) { + expect(tab).toHaveAttribute("aria-controls"); + const tabpanel = document.getElementById(tab.getAttribute("aria-controls")!); + + expect(tabpanel).toBeTruthy(); + expect(tabpanel).toHaveAttribute("aria-labelledby", tab.id); + expect(tabpanel).toHaveAttribute("role", "tabpanel"); + expect(tabpanel).toHaveTextContent(defaultItems[0]?.content as string); + } + } + }); + it("ref should be forwarded", () => { const ref = React.createRef(); diff --git a/packages/components/tabs/src/tab-panel.tsx b/packages/components/tabs/src/tab-panel.tsx index f9cfaf4d23..eb54049865 100644 --- a/packages/components/tabs/src/tab-panel.tsx +++ b/packages/components/tabs/src/tab-panel.tsx @@ -47,7 +47,7 @@ const TabPanel = forwardRef<"div", TabPanelProps>((props, ref) => { const domRef = useDOMRef(ref); - const {tabPanelProps} = useTabPanel(props, state, domRef); + const {tabPanelProps} = useTabPanel({...props, id: String(tabKey)}, state, domRef); const {focusProps, isFocused, isFocusVisible} = useFocusRing(); diff --git a/packages/components/tabs/src/tab.tsx b/packages/components/tabs/src/tab.tsx index 6c68507f50..1be4868b4e 100644 --- a/packages/components/tabs/src/tab.tsx +++ b/packages/components/tabs/src/tab.tsx @@ -61,6 +61,10 @@ const Tab = forwardRef<"button", TabItemProps>((props, ref) => { isPressed, } = useTab({key, isDisabled: isDisabledProp, shouldSelectOnPressUp}, state, domRef); + if (props.children == null) { + delete tabProps["aria-controls"]; + } + const isDisabled = isDisabledProp || isDisabledItem; const {focusProps, isFocused, isFocusVisible} = useFocusRing();