From 330675e05e39826d2412455e1e2b1ad327b15a8d Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Thu, 22 Feb 2024 14:44:04 +0800
Subject: [PATCH 1/7] feat(components): tabs component add tabPosition prop
---
apps/docs/content/components/tabs/index.ts | 2 +
.../content/components/tabs/tab-position.ts | 54 +++++++++++++++++++
apps/docs/content/docs/components/tabs.mdx | 9 +++-
packages/components/tabs/src/tabs.tsx | 24 +++++----
packages/components/tabs/src/use-tabs.ts | 18 ++++++-
.../components/tabs/stories/tabs.stories.tsx | 16 ++++++
packages/core/theme/src/components/tabs.ts | 20 +++++++
7 files changed, 130 insertions(+), 13 deletions(-)
create mode 100644 apps/docs/content/components/tabs/tab-position.ts
diff --git a/apps/docs/content/components/tabs/index.ts b/apps/docs/content/components/tabs/index.ts
index ada7d55342..9a5f616b28 100644
--- a/apps/docs/content/components/tabs/index.ts
+++ b/apps/docs/content/components/tabs/index.ts
@@ -10,6 +10,7 @@ import icons from "./icons";
import form from "./form";
import controlled from "./controlled";
import customStyles from "./custom-styles";
+import tabPosition from "./tab-position";
export const tabsContent = {
usage,
@@ -24,4 +25,5 @@ export const tabsContent = {
form,
controlled,
customStyles,
+ tabPosition,
};
diff --git a/apps/docs/content/components/tabs/tab-position.ts b/apps/docs/content/components/tabs/tab-position.ts
new file mode 100644
index 0000000000..772f89d536
--- /dev/null
+++ b/apps/docs/content/components/tabs/tab-position.ts
@@ -0,0 +1,54 @@
+const App = `import {Tabs, Tab, Card, CardBody, RadioGroup, Radio} from "@nextui-org/react";
+
+export default function App() {
+ const [position, setPosition] = React.useState("top");
+ return (
+
+
setPosition(value)}
+ >
+ top
+ bottom
+ left
+ right
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+
+
+
+
+
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+
+
+
+
+
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+
+
+
+
+
+ );
+}`;
+
+const react = {
+ "/App.jsx": App,
+};
+
+export default {
+ ...react,
+};
diff --git a/apps/docs/content/docs/components/tabs.mdx b/apps/docs/content/docs/components/tabs.mdx
index b927dda7b8..e46f88c1b8 100644
--- a/apps/docs/content/docs/components/tabs.mdx
+++ b/apps/docs/content/docs/components/tabs.mdx
@@ -73,6 +73,12 @@ You can use the `onSelectionChange` and `selectedKey` props to control the selec
+### Tab Position
+
+You can change the position of the tabs by using the `position` prop. The default value is `top`.
+
+
+
### Links
Tabs items can be rendered as links by passing the `href` prop to the `Tab` component. By
@@ -237,7 +243,8 @@ You can customize the `Tabs` component by passing custom Tailwind CSS classes to
| disableCursorAnimation | `boolean` | Whether the cursor should be hidden. | `false` |
| isDisabled | `boolean` | Whether the tab list should be disabled. | `false` |
| disableAnimation | `boolean` | Whether the tab list should be animated. | `false` |
-| classNames | `Record<"base"| "tabList"| "tab"| "tabContent"| "cursor" | "panel", string>` | Allows to set custom class names for the card slots. | - |
+| classNames | `Record<"base"| "tabList"| "tab"| "tabContent"| "cursor" | "panel", string>` | Allows to set custom class names for the card slots. | - |
+| tabPosition | `top` \| `bottom` \| `left` \| `right` | The position of the tabs. | `top` |
### Tabs Events
diff --git a/packages/components/tabs/src/tabs.tsx b/packages/components/tabs/src/tabs.tsx
index 59b8651bfe..de895de49f 100644
--- a/packages/components/tabs/src/tabs.tsx
+++ b/packages/components/tabs/src/tabs.tsx
@@ -9,7 +9,7 @@ import TabPanel from "./tab-panel";
interface Props extends UseTabsProps {}
function Tabs(props: Props, ref: ForwardedRef) {
- const {Component, values, state, getBaseProps, getTabListProps} = useTabs({
+ const {Component, values, state, getBaseProps, getTabListProps, getWrapperProps} = useTabs({
...props,
ref,
});
@@ -36,17 +36,19 @@ function Tabs(props: Props, ref: ForwardedRef
-
-
- {layoutGroupEnabled ? {tabs} : tabs}
-
+
+
+
+ {layoutGroupEnabled ? {tabs} : tabs}
+
+
+
-
>
);
}
diff --git a/packages/components/tabs/src/use-tabs.ts b/packages/components/tabs/src/use-tabs.ts
index 558d8a22df..936c5e87b9 100644
--- a/packages/components/tabs/src/use-tabs.ts
+++ b/packages/components/tabs/src/use-tabs.ts
@@ -47,6 +47,11 @@ export interface Props extends Omit
{
* ``
*/
classNames?: SlotsToClasses;
+ /**
+ * The position of the tabs.
+ * @default 'top'
+ */
+ tabPosition?: "top" | "right" | "bottom" | "left";
}
export type UseTabsProps = Props &
@@ -79,6 +84,7 @@ export function useTabs(originalProps: UseTabsProps) {
disableCursorAnimation,
shouldSelectOnPressUp = true,
motionProps,
+ tabPosition = "top",
...otherProps
} = props;
@@ -97,9 +103,10 @@ export function useTabs(originalProps: UseTabsProps) {
() =>
tabs({
...variantProps,
+ [tabPosition]: true,
className,
}),
- [...Object.values(variantProps), className],
+ [...Object.values(variantProps), className, tabPosition],
);
const baseStyles = clsx(classNames?.base, className);
@@ -143,6 +150,14 @@ export function useTabs(originalProps: UseTabsProps) {
[baseStyles, otherProps, slots],
);
+ const getWrapperProps: PropGetter = useCallback(
+ (props) => ({
+ "data-slot": "tabWrapper",
+ className: slots.wrapper({class: clsx(classNames?.wrapper, props?.className)}),
+ }),
+ [classNames, slots],
+ );
+
const getTabListProps: PropGetter = useCallback(
(props) => ({
ref: domRef,
@@ -160,6 +175,7 @@ export function useTabs(originalProps: UseTabsProps) {
values,
getBaseProps,
getTabListProps,
+ getWrapperProps,
};
}
diff --git a/packages/components/tabs/stories/tabs.stories.tsx b/packages/components/tabs/stories/tabs.stories.tsx
index 9b0ed929db..f63a7d8d1e 100644
--- a/packages/components/tabs/stories/tabs.stories.tsx
+++ b/packages/components/tabs/stories/tabs.stories.tsx
@@ -316,6 +316,22 @@ export const ManualKeyboardActivation = {
},
};
+export const TabPosition = {
+ render: StaticTemplate,
+
+ args: {
+ tabPosition: "top",
+ },
+ argTypes: {
+ tabPosition: {
+ options: ["top", "bottom", "left", "right"],
+ control: {
+ type: "inline-radio",
+ },
+ },
+ },
+};
+
export const DisabledItems = {
render: StaticTemplate,
diff --git a/packages/core/theme/src/components/tabs.ts b/packages/core/theme/src/components/tabs.ts
index 6f1d28db8f..6d169bc90b 100644
--- a/packages/core/theme/src/components/tabs.ts
+++ b/packages/core/theme/src/components/tabs.ts
@@ -71,6 +71,7 @@ const tabs = tv({
// focus ring
...dataFocusVisibleClasses,
],
+ wrapper: [],
},
variants: {
variant: {
@@ -159,6 +160,25 @@ const tabs = tv({
tabContent: "transition-none",
},
},
+ left: {
+ true: {
+ tabList: "flex-col",
+ panel: "py-0 px-3",
+ wrapper: "flex",
+ },
+ },
+ right: {
+ true: {
+ tabList: "flex-col",
+ panel: "py-0 px-3",
+ wrapper: "flex flex-row-reverse",
+ },
+ },
+ bottom: {
+ true: {
+ wrapper: "flex flex-col-reverse",
+ },
+ },
},
defaultVariants: {
color: "default",
From c430a4006e71d05f7cd6831a66364c6fa36b7e24 Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Mon, 4 Mar 2024 22:58:16 +0800
Subject: [PATCH 2/7] fix: review problem change
---
apps/docs/content/components/tabs/index.ts | 2 +
.../content/components/tabs/tab-position.ts | 4 +-
apps/docs/content/components/tabs/vertical.ts | 45 +++++++++++++++++++
apps/docs/content/docs/components/tabs.mdx | 11 ++++-
packages/components/tabs/src/use-tabs.ts | 21 ++++++---
.../components/tabs/stories/tabs.stories.tsx | 18 +++++++-
packages/core/theme/src/components/tabs.ts | 13 +++---
7 files changed, 95 insertions(+), 19 deletions(-)
create mode 100644 apps/docs/content/components/tabs/vertical.ts
diff --git a/apps/docs/content/components/tabs/index.ts b/apps/docs/content/components/tabs/index.ts
index 9a5f616b28..077c7b398c 100644
--- a/apps/docs/content/components/tabs/index.ts
+++ b/apps/docs/content/components/tabs/index.ts
@@ -11,6 +11,7 @@ import form from "./form";
import controlled from "./controlled";
import customStyles from "./custom-styles";
import tabPosition from "./tab-position";
+import vertical from "./vertical";
export const tabsContent = {
usage,
@@ -26,4 +27,5 @@ export const tabsContent = {
controlled,
customStyles,
tabPosition,
+ vertical,
};
diff --git a/apps/docs/content/components/tabs/tab-position.ts b/apps/docs/content/components/tabs/tab-position.ts
index 772f89d536..6741c7fa84 100644
--- a/apps/docs/content/components/tabs/tab-position.ts
+++ b/apps/docs/content/components/tabs/tab-position.ts
@@ -13,8 +13,8 @@ export default function App() {
>
top
bottom
- left
- right
+ start
+ end
diff --git a/apps/docs/content/components/tabs/vertical.ts b/apps/docs/content/components/tabs/vertical.ts
new file mode 100644
index 0000000000..d8b6dccc9b
--- /dev/null
+++ b/apps/docs/content/components/tabs/vertical.ts
@@ -0,0 +1,45 @@
+const App = `import {Tabs, Tab, Card, CardBody, Switch} from "@nextui-org/react";
+
+export default function App() {
+ const [vertical, setVertical] = React.useState(true);
+ return (
+
+
+ Vertical
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+
+
+
+
+
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+
+
+
+
+
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+
+
+
+
+
+ );
+}`;
+
+const react = {
+ "/App.jsx": App,
+};
+
+export default {
+ ...react,
+};
diff --git a/apps/docs/content/docs/components/tabs.mdx b/apps/docs/content/docs/components/tabs.mdx
index e46f88c1b8..fd2ba49d47 100644
--- a/apps/docs/content/docs/components/tabs.mdx
+++ b/apps/docs/content/docs/components/tabs.mdx
@@ -75,10 +75,16 @@ You can use the `onSelectionChange` and `selectedKey` props to control the selec
### Tab Position
-You can change the position of the tabs by using the `position` prop. The default value is `top`.
+You can change the position of the tabs by using the `tabPosition` prop. The default value is `top`.
+### Vertical
+
+Change the orientation of the tabs it will invalidate the tabPosition prop when the value is true.
+
+
+
### Links
Tabs items can be rendered as links by passing the `href` prop to the `Tab` component. By
@@ -244,7 +250,8 @@ You can customize the `Tabs` component by passing custom Tailwind CSS classes to
| isDisabled | `boolean` | Whether the tab list should be disabled. | `false` |
| disableAnimation | `boolean` | Whether the tab list should be animated. | `false` |
| classNames | `Record<"base"| "tabList"| "tab"| "tabContent"| "cursor" | "panel", string>` | Allows to set custom class names for the card slots. | - |
-| tabPosition | `top` \| `bottom` \| `left` \| `right` | The position of the tabs. | `top` |
+| tabPosition | `top` \| `bottom` \| `start` \| `end` | The position of the tabs. | `top` |
+| isVertical | `boolean` | Whether the tabs are vertical. | `false` |
### Tabs Events
diff --git a/packages/components/tabs/src/use-tabs.ts b/packages/components/tabs/src/use-tabs.ts
index 936c5e87b9..48d4fd381a 100644
--- a/packages/components/tabs/src/use-tabs.ts
+++ b/packages/components/tabs/src/use-tabs.ts
@@ -51,7 +51,12 @@ export interface Props extends Omit {
* The position of the tabs.
* @default 'top'
*/
- tabPosition?: "top" | "right" | "bottom" | "left";
+ tabPosition?: "top" | "bottom" | "start" | "end";
+ /**
+ * Whether the tabs are vertical it will invalidate the tabPosition prop when the value is true.
+ * @default false
+ */
+ isVertical?: boolean;
}
export type UseTabsProps = Props &
@@ -82,9 +87,9 @@ export function useTabs(originalProps: UseTabsProps) {
classNames,
children,
disableCursorAnimation,
- shouldSelectOnPressUp = true,
motionProps,
- tabPosition = "top",
+ isVertical = false,
+ shouldSelectOnPressUp = true,
...otherProps
} = props;
@@ -103,10 +108,10 @@ export function useTabs(originalProps: UseTabsProps) {
() =>
tabs({
...variantProps,
- [tabPosition]: true,
className,
+ ...(isVertical ? {tabPosition: "start"} : {}),
}),
- [...Object.values(variantProps), className, tabPosition],
+ [...Object.values(variantProps), className, isVertical],
);
const baseStyles = clsx(classNames?.base, className);
@@ -150,12 +155,16 @@ export function useTabs(originalProps: UseTabsProps) {
[baseStyles, otherProps, slots],
);
+ const tabPosition = (variantProps as Props).tabPosition ?? (isVertical ? "start" : "top");
const getWrapperProps: PropGetter = useCallback(
(props) => ({
"data-slot": "tabWrapper",
className: slots.wrapper({class: clsx(classNames?.wrapper, props?.className)}),
+ "data-position": tabPosition,
+ "data-orientation":
+ isVertical || tabPosition === "start" || tabPosition === "end" ? "vertical" : "horizontal",
}),
- [classNames, slots],
+ [classNames, slots, tabPosition, isVertical],
);
const getTabListProps: PropGetter = useCallback(
diff --git a/packages/components/tabs/stories/tabs.stories.tsx b/packages/components/tabs/stories/tabs.stories.tsx
index f63a7d8d1e..a790c415e6 100644
--- a/packages/components/tabs/stories/tabs.stories.tsx
+++ b/packages/components/tabs/stories/tabs.stories.tsx
@@ -324,11 +324,27 @@ export const TabPosition = {
},
argTypes: {
tabPosition: {
- options: ["top", "bottom", "left", "right"],
+ options: ["top", "bottom", "start", "end"],
control: {
type: "inline-radio",
},
},
+ isVertical: {
+ type: "boolean",
+ },
+ },
+};
+
+export const Vertical = {
+ render: StaticTemplate,
+
+ args: {
+ isVertical: true,
+ },
+ argTypes: {
+ isVertical: {
+ type: "boolean",
+ },
},
};
diff --git a/packages/core/theme/src/components/tabs.ts b/packages/core/theme/src/components/tabs.ts
index 6d169bc90b..e67ce00fbb 100644
--- a/packages/core/theme/src/components/tabs.ts
+++ b/packages/core/theme/src/components/tabs.ts
@@ -160,22 +160,19 @@ const tabs = tv({
tabContent: "transition-none",
},
},
- left: {
- true: {
+ tabPosition: {
+ top: {},
+ start: {
tabList: "flex-col",
panel: "py-0 px-3",
wrapper: "flex",
},
- },
- right: {
- true: {
+ end: {
tabList: "flex-col",
panel: "py-0 px-3",
wrapper: "flex flex-row-reverse",
},
- },
- bottom: {
- true: {
+ bottom: {
wrapper: "flex flex-col-reverse",
},
},
From 51a01f2221a7ee60dae1ba1f8732eaef0f29e1ae Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Mon, 4 Mar 2024 22:58:42 +0800
Subject: [PATCH 3/7] test: add tabs position vertical test
---
.../components/tabs/__tests__/tabs.test.tsx | 84 ++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/packages/components/tabs/__tests__/tabs.test.tsx b/packages/components/tabs/__tests__/tabs.test.tsx
index a1a7bc2839..544370fdb6 100644
--- a/packages/components/tabs/__tests__/tabs.test.tsx
+++ b/packages/components/tabs/__tests__/tabs.test.tsx
@@ -3,7 +3,7 @@ import {act, render} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import {focus} from "@nextui-org/test-utils";
-import {Tabs, Tab} from "../src";
+import {Tabs, Tab, TabsProps} from "../src";
type Item = {
id: string;
@@ -29,6 +29,22 @@ let tabs: Item[] = [
},
];
+function getPositionTemplate(position: TabsProps["tabPosition"]) {
+ return (
+
+
+ Content 1
+
+
+ Content 2
+
+
+ Content 3
+
+
+ );
+}
+
describe("Tabs", () => {
it("should render correctly (static)", () => {
const wrapper = render(
@@ -226,4 +242,70 @@ describe("Tabs", () => {
expect(tab2).toHaveAttribute("aria-selected", "false");
});
+
+ it("should change the position of the tabs", () => {
+ const wrapper = render(getPositionTemplate("top"));
+
+ const tabWrapper = wrapper.getByTestId("tabWrapper").parentNode;
+
+ expect(tabWrapper).toHaveAttribute("data-position", "top");
+ expect(tabWrapper).toHaveAttribute("data-orientation", "horizontal");
+
+ // Test bottom position
+ wrapper.rerender(getPositionTemplate("bottom"));
+
+ expect(tabWrapper).toHaveAttribute("data-position", "bottom");
+ expect(tabWrapper).toHaveAttribute("data-orientation", "horizontal");
+
+ // Test start position
+ wrapper.rerender(getPositionTemplate("start"));
+
+ expect(tabWrapper).toHaveAttribute("data-position", "start");
+ expect(tabWrapper).toHaveAttribute("data-orientation", "vertical");
+
+ // Test end position
+ wrapper.rerender(getPositionTemplate("end"));
+
+ expect(tabWrapper).toHaveAttribute("data-position", "end");
+ expect(tabWrapper).toHaveAttribute("data-orientation", "vertical");
+ });
+
+ it("should change the orientation of the tabs", () => {
+ const wrapper = render(
+
+
+ Content 1
+
+
+ Content 2
+
+
+ Content 3
+
+ ,
+ );
+
+ const tabWrapper = wrapper.getByTestId("tabWrapper").parentNode;
+
+ expect(tabWrapper).toHaveAttribute("data-position", "start");
+ expect(tabWrapper).toHaveAttribute("data-orientation", "vertical");
+
+ // Test horizontal orientation
+ wrapper.rerender(
+
+
+ Content 1
+
+
+ Content 2
+
+
+ Content 3
+
+ ,
+ );
+
+ expect(tabWrapper).toHaveAttribute("data-position", "top");
+ expect(tabWrapper).toHaveAttribute("data-orientation", "horizontal");
+ });
});
From af2ad53c7fd66276a96f1fae40871a37eda62993 Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Tue, 19 Mar 2024 21:55:51 +0800
Subject: [PATCH 4/7] docs: update changeset
---
.changeset/famous-panthers-know.md | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .changeset/famous-panthers-know.md
diff --git a/.changeset/famous-panthers-know.md b/.changeset/famous-panthers-know.md
new file mode 100644
index 0000000000..0d2d79231e
--- /dev/null
+++ b/.changeset/famous-panthers-know.md
@@ -0,0 +1,5 @@
+---
+"@nextui-org/tabs": patch
+---
+
+add tabPosition and isVertical prop
From 6f8fd978be2d925200fbe44d865afb7a7f0436bd Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Wed, 3 Apr 2024 22:02:45 +0800
Subject: [PATCH 5/7] fix(tabs): optimize return of tabs
---
.changeset/famous-panthers-know.md | 2 +-
packages/components/tabs/src/tabs.tsx | 30 +++++++++++++++------------
2 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/.changeset/famous-panthers-know.md b/.changeset/famous-panthers-know.md
index 0d2d79231e..c7957ce2a1 100644
--- a/.changeset/famous-panthers-know.md
+++ b/.changeset/famous-panthers-know.md
@@ -2,4 +2,4 @@
"@nextui-org/tabs": patch
---
-add tabPosition and isVertical prop
+Add tabPosition and isVertical prop
diff --git a/packages/components/tabs/src/tabs.tsx b/packages/components/tabs/src/tabs.tsx
index de895de49f..d2f8ca64ba 100644
--- a/packages/components/tabs/src/tabs.tsx
+++ b/packages/components/tabs/src/tabs.tsx
@@ -34,23 +34,27 @@ function Tabs(props: Props, ref: ForwardedRef
));
- return (
+ const renderTabs = (
<>
-
-
-
- {layoutGroupEnabled ? {tabs} : tabs}
-
-
-
+
+
+ {layoutGroupEnabled ? {tabs} : tabs}
+
+
>
);
+
+ if ("tabPosition" in props || "isVertical" in props) {
+ return
{renderTabs}
;
+ }
+
+ return renderTabs;
}
export type TabsProps
= Props & {ref?: Ref};
From 7923d85351f8ed1a9898a61884ecaa37247b8eba Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Wed, 3 Apr 2024 23:33:15 +0800
Subject: [PATCH 6/7] fix(tabs): rename orientation to placement
---
.changeset/famous-panthers-know.md | 2 +-
apps/docs/content/components/tabs/index.ts | 4 +--
.../tabs/{tab-position.ts => placement.ts} | 4 +--
apps/docs/content/docs/components/tabs.mdx | 10 +++---
.../components/tabs/__tests__/tabs.test.tsx | 36 +++++++++----------
packages/components/tabs/src/tabs.tsx | 2 +-
packages/components/tabs/src/use-tabs.ts | 18 +++++-----
.../components/tabs/stories/tabs.stories.tsx | 6 ++--
packages/core/theme/src/components/tabs.ts | 2 +-
9 files changed, 42 insertions(+), 42 deletions(-)
rename apps/docs/content/components/tabs/{tab-position.ts => placement.ts} (95%)
diff --git a/.changeset/famous-panthers-know.md b/.changeset/famous-panthers-know.md
index c7957ce2a1..6de1fd9eb7 100644
--- a/.changeset/famous-panthers-know.md
+++ b/.changeset/famous-panthers-know.md
@@ -2,4 +2,4 @@
"@nextui-org/tabs": patch
---
-Add tabPosition and isVertical prop
+Add placement and isVertical prop
diff --git a/apps/docs/content/components/tabs/index.ts b/apps/docs/content/components/tabs/index.ts
index 077c7b398c..62c77733c7 100644
--- a/apps/docs/content/components/tabs/index.ts
+++ b/apps/docs/content/components/tabs/index.ts
@@ -10,7 +10,7 @@ import icons from "./icons";
import form from "./form";
import controlled from "./controlled";
import customStyles from "./custom-styles";
-import tabPosition from "./tab-position";
+import placement from "./placement";
import vertical from "./vertical";
export const tabsContent = {
@@ -26,6 +26,6 @@ export const tabsContent = {
form,
controlled,
customStyles,
- tabPosition,
+ placement,
vertical,
};
diff --git a/apps/docs/content/components/tabs/tab-position.ts b/apps/docs/content/components/tabs/placement.ts
similarity index 95%
rename from apps/docs/content/components/tabs/tab-position.ts
rename to apps/docs/content/components/tabs/placement.ts
index 6741c7fa84..2c39e593b8 100644
--- a/apps/docs/content/components/tabs/tab-position.ts
+++ b/apps/docs/content/components/tabs/placement.ts
@@ -7,7 +7,7 @@ export default function App() {
setPosition(value)}
>
@@ -17,7 +17,7 @@ export default function App() {
end
-
+
diff --git a/apps/docs/content/docs/components/tabs.mdx b/apps/docs/content/docs/components/tabs.mdx
index fd2ba49d47..6a9c01eb61 100644
--- a/apps/docs/content/docs/components/tabs.mdx
+++ b/apps/docs/content/docs/components/tabs.mdx
@@ -73,15 +73,15 @@ You can use the `onSelectionChange` and `selectedKey` props to control the selec
-### Tab Position
+### Placement
-You can change the position of the tabs by using the `tabPosition` prop. The default value is `top`.
+You can change the position of the tabs by using the `placement` prop. The default value is `top`.
-
+
### Vertical
-Change the orientation of the tabs it will invalidate the tabPosition prop when the value is true.
+Change the orientation of the tabs it will invalidate the placement prop when the value is true.
@@ -250,7 +250,7 @@ You can customize the `Tabs` component by passing custom Tailwind CSS classes to
| isDisabled | `boolean` | Whether the tab list should be disabled. | `false` |
| disableAnimation | `boolean` | Whether the tab list should be animated. | `false` |
| classNames | `Record<"base"| "tabList"| "tab"| "tabContent"| "cursor" | "panel", string>` | Allows to set custom class names for the card slots. | - |
-| tabPosition | `top` \| `bottom` \| `start` \| `end` | The position of the tabs. | `top` |
+| placement | `top` \| `bottom` \| `start` \| `end` | The position of the tabs. | `top` |
| isVertical | `boolean` | Whether the tabs are vertical. | `false` |
### Tabs Events
diff --git a/packages/components/tabs/__tests__/tabs.test.tsx b/packages/components/tabs/__tests__/tabs.test.tsx
index f608a67687..a5117c5d6a 100644
--- a/packages/components/tabs/__tests__/tabs.test.tsx
+++ b/packages/components/tabs/__tests__/tabs.test.tsx
@@ -29,9 +29,9 @@ let tabs: Item[] = [
},
];
-function getPositionTemplate(position: TabsProps["tabPosition"]) {
+function getPlacementTemplate(position: TabsProps["placement"]) {
return (
-
+
Content 1
@@ -254,30 +254,30 @@ describe("Tabs", () => {
});
it("should change the position of the tabs", () => {
- const wrapper = render(getPositionTemplate("top"));
+ const wrapper = render(getPlacementTemplate("top"));
const tabWrapper = wrapper.getByTestId("tabWrapper").parentNode;
- expect(tabWrapper).toHaveAttribute("data-position", "top");
- expect(tabWrapper).toHaveAttribute("data-orientation", "horizontal");
+ expect(tabWrapper).toHaveAttribute("data-placement", "top");
+ expect(tabWrapper).toHaveAttribute("data-vertical", "horizontal");
// Test bottom position
- wrapper.rerender(getPositionTemplate("bottom"));
+ wrapper.rerender(getPlacementTemplate("bottom"));
- expect(tabWrapper).toHaveAttribute("data-position", "bottom");
- expect(tabWrapper).toHaveAttribute("data-orientation", "horizontal");
+ expect(tabWrapper).toHaveAttribute("data-placement", "bottom");
+ expect(tabWrapper).toHaveAttribute("data-vertical", "horizontal");
// Test start position
- wrapper.rerender(getPositionTemplate("start"));
+ wrapper.rerender(getPlacementTemplate("start"));
- expect(tabWrapper).toHaveAttribute("data-position", "start");
- expect(tabWrapper).toHaveAttribute("data-orientation", "vertical");
+ expect(tabWrapper).toHaveAttribute("data-placement", "start");
+ expect(tabWrapper).toHaveAttribute("data-vertical", "vertical");
// Test end position
- wrapper.rerender(getPositionTemplate("end"));
+ wrapper.rerender(getPlacementTemplate("end"));
- expect(tabWrapper).toHaveAttribute("data-position", "end");
- expect(tabWrapper).toHaveAttribute("data-orientation", "vertical");
+ expect(tabWrapper).toHaveAttribute("data-placement", "end");
+ expect(tabWrapper).toHaveAttribute("data-vertical", "vertical");
});
it("should change the orientation of the tabs", () => {
@@ -297,8 +297,8 @@ describe("Tabs", () => {
const tabWrapper = wrapper.getByTestId("tabWrapper").parentNode;
- expect(tabWrapper).toHaveAttribute("data-position", "start");
- expect(tabWrapper).toHaveAttribute("data-orientation", "vertical");
+ expect(tabWrapper).toHaveAttribute("data-placement", "start");
+ expect(tabWrapper).toHaveAttribute("data-vertical", "vertical");
// Test horizontal orientation
wrapper.rerender(
@@ -315,7 +315,7 @@ describe("Tabs", () => {
,
);
- expect(tabWrapper).toHaveAttribute("data-position", "top");
- expect(tabWrapper).toHaveAttribute("data-orientation", "horizontal");
+ expect(tabWrapper).toHaveAttribute("data-placement", "top");
+ expect(tabWrapper).toHaveAttribute("data-vertical", "horizontal");
});
});
diff --git a/packages/components/tabs/src/tabs.tsx b/packages/components/tabs/src/tabs.tsx
index d2f8ca64ba..a4c618ac82 100644
--- a/packages/components/tabs/src/tabs.tsx
+++ b/packages/components/tabs/src/tabs.tsx
@@ -50,7 +50,7 @@ function Tabs(props: Props, ref: ForwardedRef
);
- if ("tabPosition" in props || "isVertical" in props) {
+ if ("placement" in props || "isVertical" in props) {
return {renderTabs}
;
}
diff --git a/packages/components/tabs/src/use-tabs.ts b/packages/components/tabs/src/use-tabs.ts
index dd72fae7e1..aaea6f4c12 100644
--- a/packages/components/tabs/src/use-tabs.ts
+++ b/packages/components/tabs/src/use-tabs.ts
@@ -51,9 +51,9 @@ export interface Props extends Omit {
* The position of the tabs.
* @default 'top'
*/
- tabPosition?: "top" | "bottom" | "start" | "end";
+ placement?: "top" | "bottom" | "start" | "end";
/**
- * Whether the tabs are vertical it will invalidate the tabPosition prop when the value is true.
+ * Whether the tabs are vertical it will invalidate the placement prop when the value is true.
* @default false
*/
isVertical?: boolean;
@@ -102,14 +102,14 @@ export function useTabs(originalProps: UseTabsProps) {
children: children as CollectionChildren,
...otherProps,
});
- const {tabListProps} = useTabList(otherProps, state, domRef);
+ const {tabListProps} = useTabList(otherProps as AriaTabListProps, state, domRef);
const slots = useMemo(
() =>
tabs({
...variantProps,
className,
- ...(isVertical ? {tabPosition: "start"} : {}),
+ ...(isVertical ? {placement: "start"} : {}),
}),
[objectToDeps(variantProps), className, isVertical],
);
@@ -155,16 +155,16 @@ export function useTabs(originalProps: UseTabsProps) {
[baseStyles, otherProps, slots],
);
- const tabPosition = (variantProps as Props).tabPosition ?? (isVertical ? "start" : "top");
+ const placement = (variantProps as Props).placement ?? (isVertical ? "start" : "top");
const getWrapperProps: PropGetter = useCallback(
(props) => ({
"data-slot": "tabWrapper",
className: slots.wrapper({class: clsx(classNames?.wrapper, props?.className)}),
- "data-position": tabPosition,
- "data-orientation":
- isVertical || tabPosition === "start" || tabPosition === "end" ? "vertical" : "horizontal",
+ "data-placement": placement,
+ "data-vertical":
+ isVertical || placement === "start" || placement === "end" ? "vertical" : "horizontal",
}),
- [classNames, slots, tabPosition, isVertical],
+ [classNames, slots, placement, isVertical],
);
const getTabListProps: PropGetter = useCallback(
diff --git a/packages/components/tabs/stories/tabs.stories.tsx b/packages/components/tabs/stories/tabs.stories.tsx
index a790c415e6..eb0551872c 100644
--- a/packages/components/tabs/stories/tabs.stories.tsx
+++ b/packages/components/tabs/stories/tabs.stories.tsx
@@ -316,14 +316,14 @@ export const ManualKeyboardActivation = {
},
};
-export const TabPosition = {
+export const Placement = {
render: StaticTemplate,
args: {
- tabPosition: "top",
+ placement: "top",
},
argTypes: {
- tabPosition: {
+ placement: {
options: ["top", "bottom", "start", "end"],
control: {
type: "inline-radio",
diff --git a/packages/core/theme/src/components/tabs.ts b/packages/core/theme/src/components/tabs.ts
index e67ce00fbb..3e126deb7f 100644
--- a/packages/core/theme/src/components/tabs.ts
+++ b/packages/core/theme/src/components/tabs.ts
@@ -160,7 +160,7 @@ const tabs = tv({
tabContent: "transition-none",
},
},
- tabPosition: {
+ placement: {
top: {},
start: {
tabList: "flex-col",
From 8af8cf9b59dde9d7aab921d9ba08a384d72aadc0 Mon Sep 17 00:00:00 2001
From: winches <329487092@qq.com>
Date: Thu, 4 Apr 2024 07:23:47 +0800
Subject: [PATCH 7/7] fix(tabs): optimize description
---
apps/docs/content/components/tabs/placement.ts | 10 +++++-----
apps/docs/content/components/tabs/vertical.ts | 6 +++---
apps/docs/content/docs/components/tabs.mdx | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/apps/docs/content/components/tabs/placement.ts b/apps/docs/content/components/tabs/placement.ts
index 2c39e593b8..7f720ac41b 100644
--- a/apps/docs/content/components/tabs/placement.ts
+++ b/apps/docs/content/components/tabs/placement.ts
@@ -1,15 +1,15 @@
const App = `import {Tabs, Tab, Card, CardBody, RadioGroup, Radio} from "@nextui-org/react";
export default function App() {
- const [position, setPosition] = React.useState("top");
+ const [placement, setPlacement] = React.useState("top");
return (
setPosition(value)}
+ orientation="top"
+ value={placement}
+ onValueChange={(value) => setPlacement(value)}
>
top
bottom
@@ -17,7 +17,7 @@ export default function App() {
end
-
+
diff --git a/apps/docs/content/components/tabs/vertical.ts b/apps/docs/content/components/tabs/vertical.ts
index d8b6dccc9b..7487c22bb1 100644
--- a/apps/docs/content/components/tabs/vertical.ts
+++ b/apps/docs/content/components/tabs/vertical.ts
@@ -1,14 +1,14 @@
const App = `import {Tabs, Tab, Card, CardBody, Switch} from "@nextui-org/react";
export default function App() {
- const [vertical, setVertical] = React.useState(true);
+ const [isVertical, setIsVertical] = React.useState(true);
return (
-
+
Vertical
-
+
diff --git a/apps/docs/content/docs/components/tabs.mdx b/apps/docs/content/docs/components/tabs.mdx
index 6a9c01eb61..3a1bb195a5 100644
--- a/apps/docs/content/docs/components/tabs.mdx
+++ b/apps/docs/content/docs/components/tabs.mdx
@@ -81,7 +81,7 @@ You can change the position of the tabs by using the `placement` prop. The defau
### Vertical
-Change the orientation of the tabs it will invalidate the placement prop when the value is true.
+Change the orientation of the tabs it will invalidate the placement prop when the value is `true`.