From 18c17d6d82042d115422418a10b678aa1d94f2cf Mon Sep 17 00:00:00 2001 From: Nishan Date: Sun, 7 Mar 2021 22:54:48 +0530 Subject: [PATCH 1/7] feat: update tabs existing api --- packages/@react-aria/tabs/src/useTabs.ts | 35 +- packages/@react-spectrum/tabs/src/Tabs.tsx | 227 +++++---- .../tabs/stories/Tabs.stories.js | 429 +++++++++--------- .../@react-stately/tabs/src/useTabsState.ts | 6 +- packages/@react-types/tabs/src/index.d.ts | 40 +- 5 files changed, 383 insertions(+), 354 deletions(-) diff --git a/packages/@react-aria/tabs/src/useTabs.ts b/packages/@react-aria/tabs/src/useTabs.ts index 2684c889786..b3014cd04dd 100644 --- a/packages/@react-aria/tabs/src/useTabs.ts +++ b/packages/@react-aria/tabs/src/useTabs.ts @@ -10,12 +10,12 @@ * governing permissions and limitations under the License. */ -import {AriaTabProps, AriaTabsProps} from '@react-types/tabs'; +import {AriaTabProps, AriaTabListProps, AriaTabPanelProps} from '@react-types/tabs'; import {HTMLAttributes, Key, RefObject, useMemo} from 'react'; import {mergeProps, useId, useLabels} from '@react-aria/utils'; import {SingleSelectListState} from '@react-stately/list'; import {TabsKeyboardDelegate} from './TabsKeyboardDelegate'; -import {TabsState} from '@react-stately/tabs'; +import {TabListState} from '@react-stately/tabs'; import {useLocale} from '@react-aria/i18n'; import {usePress} from '@react-aria/interactions'; import {useSelectableCollection, useSelectableItem} from '@react-aria/selection'; @@ -23,13 +23,11 @@ import {useSelectableCollection, useSelectableItem} from '@react-aria/selection' interface TabsAria { /** Props for the tablist container. */ tabListProps: HTMLAttributes, - /** Props for the associated tabpanel element. */ - tabPanelProps: HTMLAttributes } const tabsIds = new WeakMap, string>(); -export function useTabs(props: AriaTabsProps, state: TabsState, ref): TabsAria { +export function useTabList(props: AriaTabListProps, state: TabListState, ref): TabsAria { let { orientation = 'horizontal', keyboardActivation = 'automatic' @@ -38,7 +36,6 @@ export function useTabs(props: AriaTabsProps, state: TabsState, ref): T collection, selectionManager: manager, disabledKeys, - selectedKey } = state; let {direction} = useLocale(); let delegate = useMemo(() => new TabsKeyboardDelegate( @@ -67,12 +64,6 @@ export function useTabs(props: AriaTabsProps, state: TabsState, ref): T role: 'tablist', 'aria-orientation': orientation, tabIndex: undefined - }, - tabPanelProps: { - id: generateId(state, selectedKey, 'tabpanel'), - 'aria-labelledby': generateId(state, selectedKey, 'tab'), - tabIndex: 0, - role: 'tabpanel' } }; } @@ -123,6 +114,26 @@ export function useTab( }; } +interface TabPanelAria { + /** Props for the tab panel element. */ + tabPanelProps: HTMLAttributes; +} + +export function useTabPanel( + props: AriaTabPanelProps, + state: TabListState +): TabPanelAria { + console.log("mann ", state) + return { + tabPanelProps: mergeProps(props, { + id: generateId(state, state?.selectedKey, 'tabpanel'), + 'aria-labelledby': generateId(state, state?.selectedKey, 'tab'), + tabIndex: 0, + role: 'tabpanel', + }), + }; +} + function generateId(state: SingleSelectListState, key: Key, role: string) { if (typeof key === 'string') { key = key.replace(/\s+/g, ''); diff --git a/packages/@react-spectrum/tabs/src/Tabs.tsx b/packages/@react-spectrum/tabs/src/Tabs.tsx index 75f188dbe5e..1ef64527ede 100644 --- a/packages/@react-spectrum/tabs/src/Tabs.tsx +++ b/packages/@react-spectrum/tabs/src/Tabs.tsx @@ -15,18 +15,38 @@ import {DOMProps, DOMRef, Node, Orientation} from '@react-types/shared'; import {FocusRing} from '@react-aria/focus'; import {Item, Picker} from '@react-spectrum/picker'; import {mergeProps, useId, useLayoutEffect} from '@react-aria/utils'; -import React, {HTMLAttributes, Key, MutableRefObject, ReactElement, useCallback, useEffect, useRef, useState} from 'react'; -import {SingleSelectListState} from '@react-stately/list'; +import React, {Key, MutableRefObject, ReactElement, useCallback, useEffect, useRef, useState} from 'react'; +import {ListCollection, SingleSelectListState} from '@react-stately/list'; import {SpectrumPickerProps} from '@react-types/select'; -import {SpectrumTabsProps} from '@react-types/tabs'; +import {SpectrumTabsProps, SpectrumTabListProps, SpectrumTabPanelsProps} from '@react-types/tabs'; import styles from '@adobe/spectrum-css-temp/components/tabs/vars.css'; import {Text} from '@react-spectrum/text'; import {useHover} from '@react-aria/interactions'; import {useLocale} from '@react-aria/i18n'; import {useProvider, useProviderProps} from '@react-spectrum/provider'; import {useResizeObserver} from '@react-aria/utils'; -import {useTab, useTabs} from '@react-aria/tabs'; -import {useTabsState} from '@react-stately/tabs'; +import {useTab, useTabList, useTabPanel} from '@react-aria/tabs'; +import {TabListState, useTabListState} from '@react-stately/tabs'; +import {useCollection} from '@react-stately/collections'; + +interface TabsContext { + tabProps: SpectrumTabsProps; + tabState: { + tabListState: TabListState; + setTabListState: (state: TabListState) => void; + selectedTab: HTMLElement; + collapse: boolean + }; + refs: { + wrapperRef: MutableRefObject, + tablistRef: MutableRefObject + }; + tabPanelProps: { + "aria-labelledby": string + } +} + +const TabContext = React.createContext>(null); function Tabs(props: SpectrumTabsProps, ref: DOMRef) { props = useProviderProps(props); @@ -42,24 +62,23 @@ function Tabs(props: SpectrumTabsProps, ref: DOMRef(); let wrapperRef = useRef(); - let state = useTabsState(props); let {direction} = useLocale(); let {styleProps} = useStyleProps(otherProps); - let {tabListProps, tabPanelProps} = useTabs(props, state, tablistRef); let [collapse, setCollapse] = useValueEffect(false); let [selectedTab, setSelectedTab] = useState(); + const [tabListState, setTabListState] = React.useState>(null); useEffect(() => { if (tablistRef.current) { - let selectedTab: HTMLElement = tablistRef.current.querySelector(`[data-key="${state.selectedKey}"]`); + let selectedTab: HTMLElement = tablistRef.current.querySelector(`[data-key="${tabListState?.selectedKey}"]`); if (selectedTab != null) { setSelectedTab(selectedTab); } } // collapse is in the dep array so selectedTab can be updated for TabLine positioning - }, [children, state.selectedKey, collapse, tablistRef]); + }, [children, tabListState?.selectedKey, collapse, tablistRef]); let checkShouldCollapse = useCallback(() => { let computeShouldCollapse = () => { @@ -94,48 +113,36 @@ function Tabs(props: SpectrumTabsProps, ref: DOMRef - {orientation === 'vertical' && - - } - {orientation !== 'vertical' && - - } -
- {state.selectedItem && state.selectedItem.props.children} + +
+ {props.children}
-
+ ); } @@ -238,77 +245,24 @@ function TabLine(props: TabLineProps) { return
; } -interface CollapsibleTabListProps extends TabListProps, TabPickerProps { - tabListProps?: HTMLAttributes, - wrapperRef: MutableRefObject, - collapse?: boolean, - tabListclassName?: string -} - -const CollapsibleTabList = React.forwardRef(function (props: CollapsibleTabListProps, ref: MutableRefObject) { - let { - tabListProps, - density, - isQuiet, - isDisabled, - state, - selectedTab, - wrapperRef, - collapse - } = props; - - let tabListclassName = classNames(styles, 'spectrum-TabsPanel-tabs'); - - return ( -
- {collapse && } - {!collapse && ( - - )} -
- ); -}); - -interface TabListProps { - isQuiet?: boolean, - density?: 'compact' | 'regular', - isDisabled?: boolean, - orientation?: Orientation, - state: SingleSelectListState, - selectedTab: HTMLElement, - className?: string -} - -const TabList = React.forwardRef(function (props: TabListProps, ref: MutableRefObject) { - let { - isQuiet, - density, - state, - isDisabled, - orientation, - selectedTab, - className, - ...otherProps - } = props; +export const TabList = function (props: SpectrumTabListProps) { + const tabContext = React.useContext(TabContext); + const {refs, tabState, tabProps, tabPanelProps} = tabContext; + const {isQuiet, density, isDisabled, orientation} = tabProps; + const {selectedTab, collapse, setTabListState} = tabState; + const {tablistRef, wrapperRef} = refs; + const state = useTabListState({...tabProps, children: props.children}); + const {tabListProps} = useTabList({...tabProps, ...props}, state, tablistRef); + + useEffect(() => { + // Passing back to root as useTabPanel needs the TabListState + setTabListState(state); + },[state.disabledKeys, state.selectedItem, state.selectedKey, props.children]) - return ( + const tabContent = (
(props: TabListProps, ref: Muta { 'spectrum-Tabs--quiet': isQuiet, ['spectrum-Tabs--compact']: density === 'compact' - }, - className - )}> + })} + > {[...state.collection].map((item) => ( - + ))}
+ ) + + + if (orientation === 'vertical') { + return tabContent; + } else { + let tabListclassName = classNames(styles, 'spectrum-TabsPanel-tabs'); + return ( +
+ {collapse ? : tabContent} +
+ ); + } +}; + + +export const TabPanels = function (props: SpectrumTabPanelsProps) { + const {tabState, tabProps, tabPanelProps: ctxTabPanelProps} = React.useContext(TabContext); + const {tabListState} = tabState; + const {tabPanelProps} = useTabPanel(props, tabListState); + + if(ctxTabPanelProps['aria-labelledby']){ + tabPanelProps['aria-labelledby'] = ctxTabPanelProps['aria-labelledby'] + } + + const factory = nodes => new ListCollection(nodes) + const collection = useCollection({items: tabProps.items, ...props}, factory); + const selectedItem = tabListState ? collection.getItem(tabListState.selectedKey) : null; + + return ( +
+ {selectedItem && selectedItem.props.children} +
); -}); +}; interface TabPickerProps extends SpectrumPickerProps { density?: 'compact' | 'regular', diff --git a/packages/@react-spectrum/tabs/stories/Tabs.stories.js b/packages/@react-spectrum/tabs/stories/Tabs.stories.js index 87a3ba006c4..bbf8abf5f4d 100644 --- a/packages/@react-spectrum/tabs/stories/Tabs.stories.js +++ b/packages/@react-spectrum/tabs/stories/Tabs.stories.js @@ -17,7 +17,7 @@ import {ButtonGroup} from '@react-spectrum/buttongroup'; import Calendar from '@spectrum-icons/workflow/Calendar'; import {Content, Flex, Heading, Text} from '@adobe/react-spectrum'; import Dashboard from '@spectrum-icons/workflow/Dashboard'; -import {Item, Tabs} from '..'; +import {Item, Tabs, TabList, TabPanels} from '..'; import React from 'react'; import {storiesOf} from '@storybook/react'; @@ -118,16 +118,22 @@ storiesOf('Tabs', module) () => ( - - - Hello World - - - - - Goodbye World - - + + + + + + + + Hello World + + + + + Goodbye World + + + ) @@ -155,56 +161,70 @@ storiesOf('Tabs', module) function render(props = {}) { return ( + + + + + + + + + + + + + - - Tab Body 1 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 2 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 3 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 4 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 5 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - + + Tab Body 1 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 2 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 3 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 4 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 5 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + ); } @@ -212,60 +232,52 @@ function render(props = {}) { function renderWithIcons(props = {}) { return ( - - - Dashboard - - }> - - Dashboard - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Calendar - - }> - - Calendar - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Bookmark - - }> - - Bookmark - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - + + + + Dashboard + + + + Calendar + + + + Bookmark + + + + + + Dashboard + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Calendar + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Bookmark + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + ); } @@ -273,56 +285,65 @@ function renderWithIcons(props = {}) { function renderWithFalsyKey(props = {}) { return ( - - - Tab Body 1 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 2 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 3 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 4 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - - - Tab Body 5 - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - + + + + + + + + + + + Tab Body 1 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 2 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 3 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 4 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + + + Tab Body 5 + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + ); } @@ -358,26 +379,28 @@ let DynamicTabs = (props = {}) => { return (
- {item => ( - + + {item => ( + {item.icon} {item.name} - - }> - - {item.children} - - Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. - Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. - Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. - - - - )} + + )} + + + {item => ( + + + {item.children} + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + )} +
); }; + + +let DynamicTabsWithDecoration = (props = {}) => { + + let [tabs, setTabs] = React.useState(items); + let addTab = () => { + let newTabs = [...tabs]; + newTabs.push({ + name: `Tab ${tabs.length + 1}`, + children: `Tab Body ${tabs.length + 1}` + }); + + setTabs(newTabs); + }; + + let removeTab = () => { + if (tabs.length > 1) { + let newTabs = [...tabs]; + newTabs.pop(); + setTabs(newTabs); + } + }; + + return ( +
+ + + + + {item => ( + + {item.icon} + {item.name} + + )} + + + val === 'add' ? addTab() : removeTab()}> + + Add Tab + + + Remove Tab + + + + + + {item => ( + + + {item.children} + + Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. + Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit. Do reprehenderit sit cupidatat quis laborum in do culpa nisi ipsum. Velit aliquip commodo ea ipsum incididunt culpa nostrud deserunt incididunt exercitation. In quis proident sit ad dolore tempor. Eiusmod pariatur quis commodo labore cupidatat cillum enim eiusmod voluptate laborum culpa. Laborum cupidatat incididunt velit voluptate incididunt occaecat quis do. + Consequat adipisicing irure Lorem commodo officia sint id. Velit sit magna aliquip eiusmod non id deserunt. Magna veniam ad consequat dolor cupidatat esse enim Lorem ullamco. Anim excepteur consectetur id in. Mollit laboris duis labore enim duis esse reprehenderit. + + + + )} + + + +
+ ); +}; From 6284567c4525aa111730af03984209ee18d47066 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Tue, 13 Apr 2021 16:36:08 -0700 Subject: [PATCH 7/7] Some cleanup and docs --- packages/@react-aria/tabs/src/useTab.ts | 14 ++---- packages/@react-aria/tabs/src/useTabList.ts | 12 ++--- packages/@react-spectrum/tabs/src/Tabs.tsx | 48 +++++++++++-------- .../tabs/stories/Tabs.stories.js | 3 +- .../@react-stately/tabs/src/useTabsState.ts | 10 +++- packages/@react-types/tabs/src/index.d.ts | 7 ++- 6 files changed, 51 insertions(+), 43 deletions(-) diff --git a/packages/@react-aria/tabs/src/useTab.ts b/packages/@react-aria/tabs/src/useTab.ts index a8a98550223..abac01f391f 100644 --- a/packages/@react-aria/tabs/src/useTab.ts +++ b/packages/@react-aria/tabs/src/useTab.ts @@ -21,14 +21,13 @@ interface TabAria { /** Props for the tab element. */ tabProps: HTMLAttributes } - + export function useTab( - props: AriaTabProps, + props: AriaTabProps, state: SingleSelectListState, ref: RefObject ): TabAria { - let {item, isDisabled: propsDisabled} = props; - let {key} = item; + let {key, isDisabled: propsDisabled} = props; let {selectionManager: manager, selectedKey} = state; let isSelected = key === selectedKey; @@ -45,11 +44,6 @@ export function useTab( let tabPanelId = generateId(state, key, 'tabpanel'); let {tabIndex} = pressProps; - // selected tab should have tabIndex=0, when it initializes - if (isSelected && !isDisabled) { - tabIndex = 0; - } - return { tabProps: { ...pressProps, @@ -62,4 +56,4 @@ export function useTab( } }; } - + diff --git a/packages/@react-aria/tabs/src/useTabList.ts b/packages/@react-aria/tabs/src/useTabList.ts index 50fefe22a06..386c0b9fbb6 100644 --- a/packages/@react-aria/tabs/src/useTabList.ts +++ b/packages/@react-aria/tabs/src/useTabList.ts @@ -23,7 +23,7 @@ interface TabListAria { /** Props for the tablist container. */ tabListProps: HTMLAttributes } - + export function useTabList(props: AriaTabListProps, state: TabListState, ref): TabListAria { let { orientation = 'horizontal', @@ -40,7 +40,7 @@ export function useTabList(props: AriaTabListProps, state: TabListState direction, orientation, disabledKeys), [collection, disabledKeys, orientation, direction]); - + let {collectionProps} = useSelectableCollection({ ref, selectionManager: manager, @@ -48,13 +48,13 @@ export function useTabList(props: AriaTabListProps, state: TabListState selectOnFocus: keyboardActivation === 'automatic', disallowEmptySelection: true }); - - // Compute base id for all tabs + + // Compute base id for all tabs let tabsId = useId(); tabsIds.set(state, tabsId); - + let tabListLabelProps = useLabels({...props, id: tabsId}); - + return { tabListProps: { ...mergeProps(collectionProps, tabListLabelProps), diff --git a/packages/@react-spectrum/tabs/src/Tabs.tsx b/packages/@react-spectrum/tabs/src/Tabs.tsx index 3f6246110ed..b65b270b6b9 100644 --- a/packages/@react-spectrum/tabs/src/Tabs.tsx +++ b/packages/@react-spectrum/tabs/src/Tabs.tsx @@ -16,7 +16,7 @@ import {FocusRing} from '@react-aria/focus'; import {Item, Picker} from '@react-spectrum/picker'; import {ListCollection, SingleSelectListState} from '@react-stately/list'; import {mergeProps, useId, useLayoutEffect} from '@react-aria/utils'; -import React, {Key, MutableRefObject, ReactElement, useCallback, useEffect, useRef, useState} from 'react'; +import React, {Key, MutableRefObject, ReactElement, useCallback, useContext, useEffect, useRef, useState} from 'react'; import {SpectrumPickerProps} from '@react-types/select'; import {SpectrumTabListProps, SpectrumTabPanelsProps, SpectrumTabsProps} from '@react-types/tabs'; import styles from '@adobe/spectrum-css-temp/components/tabs/vars.css'; @@ -37,7 +37,7 @@ interface TabsContext { selectedTab: HTMLElement, collapse: boolean }, - refs: { + refs: { wrapperRef: MutableRefObject, tablistRef: MutableRefObject }, @@ -65,7 +65,7 @@ function Tabs(props: SpectrumTabsProps, ref: DOMRef(); - const [tabListState, setTabListState] = React.useState>(null); + const [tabListState, setTabListState] = useState>(null); useEffect(() => { if (tablistRef.current) { @@ -121,10 +121,10 @@ function Tabs(props: SpectrumTabsProps, ref: DOMRef @@ -150,13 +150,14 @@ interface TabProps extends DOMProps { orientation?: Orientation } -export function Tab(props: TabProps) { +// @private +function Tab(props: TabProps) { let {item, state, isDisabled: propsDisabled} = props; let {key, rendered} = item; let isDisabled = propsDisabled || state.disabledKeys.has(key); let ref = useRef(); - let {tabProps} = useTab({item, isDisabled}, state, ref); + let {tabProps} = useTab({key, isDisabled}, state, ref); let {hoverProps, isHovered} = useHover({ ...props @@ -202,6 +203,7 @@ interface TabLineProps { selectedKey?: Key } +// @private function TabLine(props: TabLineProps) { let { orientation, @@ -242,20 +244,25 @@ function TabLine(props: TabLineProps) { return
; } -export const TabList = function (props: SpectrumTabListProps) { - const tabContext = React.useContext(TabContext); +/** + * A TabList is used within Tabs to group tabs that a user can switch between. + * The keys of the items within the must match up with a corresponding item inside the . + */ +export function TabList(props: SpectrumTabListProps) { + const tabContext = useContext(TabContext); const {refs, tabState, tabProps, tabPanelProps} = tabContext; const {isQuiet, density, isDisabled, orientation} = tabProps; const {selectedTab, collapse, setTabListState} = tabState; const {tablistRef, wrapperRef} = refs; // Pass original Tab props but override children to create the collection. const state = useTabListState({...tabProps, children: props.children}); - + const {tabListProps} = useTabList({...tabProps, ...props}, state, tablistRef); - + useEffect(() => { // Passing back to root as useTabPanel needs the TabListState setTabListState(state); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state.disabledKeys, state.selectedItem, state.selectedKey, props.children]); const tabContent = ( @@ -293,14 +300,17 @@ export const TabList = function (props: SpectrumTabListProps) {
); } -}; - +} -export const TabPanels = function (props: SpectrumTabPanelsProps) { - const {tabState, tabProps, tabPanelProps: ctxTabPanelProps} = React.useContext(TabContext); +/** + * TabPanels is used within Tabs as a container for the content of each tab. + * The keys of the items within the must match up with a corresponding item inside the . + */ +export function TabPanels(props: SpectrumTabPanelsProps) { + const {tabState, tabProps, tabPanelProps: ctxTabPanelProps} = useContext(TabContext); const {tabListState} = tabState; const {tabPanelProps} = useTabPanel(props, tabListState); - + if (ctxTabPanelProps['aria-labelledby']) { tabPanelProps['aria-labelledby'] = ctxTabPanelProps['aria-labelledby']; } @@ -312,9 +322,9 @@ export const TabPanels = function (props: SpectrumTabPanelsProps) { return (
{selectedItem && selectedItem.props.children} -
+
); -}; +} interface TabPickerProps extends SpectrumPickerProps { density?: 'compact' | 'regular', diff --git a/packages/@react-spectrum/tabs/stories/Tabs.stories.js b/packages/@react-spectrum/tabs/stories/Tabs.stories.js index bf0b1b9e6f3..8aaaff3d958 100644 --- a/packages/@react-spectrum/tabs/stories/Tabs.stories.js +++ b/packages/@react-spectrum/tabs/stories/Tabs.stories.js @@ -11,12 +11,11 @@ */ import {action} from '@storybook/addon-actions'; -import {ActionButton} from '@react-spectrum/button'; +import {ActionGroup, Content, Flex, Heading, Text} from '@adobe/react-spectrum'; import Bookmark from '@spectrum-icons/workflow/Bookmark'; import {Button} from '@react-spectrum/button'; import {ButtonGroup} from '@react-spectrum/buttongroup'; import Calendar from '@spectrum-icons/workflow/Calendar'; -import {ActionGroup, Content, Flex, Heading, Text} from '@adobe/react-spectrum'; import Dashboard from '@spectrum-icons/workflow/Dashboard'; import {Item, TabList, TabPanels, Tabs} from '..'; import React from 'react'; diff --git a/packages/@react-stately/tabs/src/useTabsState.ts b/packages/@react-stately/tabs/src/useTabsState.ts index 96b50ebfc05..4701194ba4c 100644 --- a/packages/@react-stately/tabs/src/useTabsState.ts +++ b/packages/@react-stately/tabs/src/useTabsState.ts @@ -21,8 +21,14 @@ export function useTabListState(props: TabListProps): TabLi useEffect(() => { // Ensure a tab is always selected (in case no selected key was specified or if selected item was deleted from collection) - if (state.selectionManager.isEmpty || !state.collection.getItem(state.selectedKey)) { - state.selectionManager.replaceSelection(state.collection.getFirstKey()); + let selectedKey = state.selectedKey; + if (state.selectionManager.isEmpty || !state.collection.getItem(selectedKey)) { + selectedKey = state.collection.getFirstKey(); + state.selectionManager.replaceSelection(selectedKey); + } + + if (state.selectionManager.focusedKey == null) { + state.selectionManager.setFocusedKey(selectedKey); } }, [state.selectionManager, state.selectedKey, state.collection]); diff --git a/packages/@react-types/tabs/src/index.d.ts b/packages/@react-types/tabs/src/index.d.ts index ada3cfd90fd..97062165775 100644 --- a/packages/@react-types/tabs/src/index.d.ts +++ b/packages/@react-types/tabs/src/index.d.ts @@ -15,16 +15,15 @@ import { CollectionBase, CollectionChildren, DOMProps, - Node, Orientation, SingleSelection, StyleProps } from '@react-types/shared'; import {Key} from 'react'; -export interface AriaTabProps { - /** Collection node for the tab. */ - item: Node, +export interface AriaTabProps { + /** The key of the tab. */ + key: Key, /** Whether the tab should be disabled. */ isDisabled?: boolean }