diff --git a/apps/docs/content/components/tabs.md b/apps/docs/content/components/tabs.md index ee9c74b..32a9ba0 100644 --- a/apps/docs/content/components/tabs.md +++ b/apps/docs/content/components/tabs.md @@ -6,3 +6,17 @@ description: Tabs organize content across different screens and views ## Usage + +## Props + +| Props | Type | Description | Default | +| -------------------- | ----------------------- | --------------------------- | ------------ | +| `orientation` | `horizontal` `vertical` | The orientation of the tabs | `horizontal` | +| `keyboardActivation` | `automatic` `manual` | keyboard activation | `automatic` | +| `defaultSelectedKey` | `string` \| `number` | default selected key | `undefined` | + +## Events + +| Events | Description | +| ------------------- | --------------------------- | +| `onSelectionChange` | fired when selected changed | diff --git a/apps/docs/src/usages/tabs.tsx b/apps/docs/src/usages/tabs.tsx index 19aee12..0a2fdd6 100644 --- a/apps/docs/src/usages/tabs.tsx +++ b/apps/docs/src/usages/tabs.tsx @@ -1,11 +1,21 @@ import { TabItem, Tabs } from 'actify' +import Divider from './divider' + export default () => { return ( - - actify - ngroker - taildoor - + <> + + actify + ngroker + taildoor + + + + actify + ngroker + taildoor + + ) } diff --git a/packages/actify/src/components/Tabs/TabPanel.tsx b/packages/actify/src/components/Tabs/TabPanel.tsx index 7a34c65..ed5d2cd 100644 --- a/packages/actify/src/components/Tabs/TabPanel.tsx +++ b/packages/actify/src/components/Tabs/TabPanel.tsx @@ -2,6 +2,7 @@ import { AriaTabPanelProps, useTabPanel } from 'react-aria' import React from 'react' import { TabListState } from 'react-stately' +import styles from './tabs.module.css' interface TabPanelProps extends AriaTabPanelProps { state: TabListState @@ -11,7 +12,12 @@ const TabPanel = ({ state, ...props }: TabPanelProps) => { const { tabPanelProps } = useTabPanel(props, state, ref) return ( -
+
{state.selectedItem?.props.children}
) diff --git a/packages/actify/src/components/Tabs/Tabs.tsx b/packages/actify/src/components/Tabs/Tabs.tsx index d28757f..ba34024 100644 --- a/packages/actify/src/components/Tabs/Tabs.tsx +++ b/packages/actify/src/components/Tabs/Tabs.tsx @@ -9,23 +9,31 @@ import { import React, { useEffect, useState } from 'react' import { TabListProps, useTabListState } from 'react-stately' +import { StyleProps } from '../../utils' import { Tab } from './Tab' import { TabPanel } from './TabPanel' import clsx from 'clsx' import styles from './tabs.module.css' -interface TabsProps extends AriaTabListProps, TabListProps { - style?: React.CSSProperties - className?: string -} +interface TabsProps + extends AriaTabListProps, + TabListProps, + StyleProps {} const Tabs = (props: TabsProps) => { const state = useTabListState(props) const ref = React.useRef(null) const { tabListProps } = useTabList(props, state, ref) - const [activeTabStyle, setActiveTabStyle] = useState({ + const { orientation = 'horizontal' } = props + + const [activeTabStyle, setActiveTabStyle] = useState<{ + width?: number + height?: number + transform: string + }>({ width: 0, + height: 0, transform: 'translateX(0)' }) @@ -33,26 +41,48 @@ const Tabs = (props: TabsProps) => { const activeTab = ref?.current?.querySelector( '[role="tab"][aria-selected="true"]' ) as HTMLDivElement + setActiveTabStyle({ - width: activeTab?.offsetWidth, - transform: `translateX(${activeTab?.offsetLeft}px)` + ...(orientation === 'vertical' + ? { + height: activeTab?.offsetHeight, + transform: `translateY(${activeTab?.offsetTop}px)` + } + : { + width: activeTab?.offsetWidth, + transform: `translateX(${activeTab?.offsetLeft}px)` + }) }) - }, [state.selectedKey]) + }, [state.selectedKey, orientation]) const { focusProps, isFocusVisible } = useFocusRing({ within: true }) return ( -