Skip to content

fix: Vertical TabList Wrapping #8201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/@adobe/spectrum-css-temp/components/tabs/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,19 @@ governing permissions and limitations under the License.
}
}

/*
Allow tab labels to wrap when TabList component has minWidth set.
*/
&.spectrum-Tabs--verticalWrap:not(.spectrum-Tabs--compact) .spectrum-Tabs-item {
display: flex;
align-items: center;
white-space: normal;
line-height: normal;
word-break: break-word;
block-size: auto;
min-height: var(--spectrum-tabs-vertical-item-height);
}

&.spectrum-Tabs--compact {
.spectrum-Tabs-item {
block-size: var(--spectrum-tabs-compact-vertical-item-height);
Expand Down
7 changes: 5 additions & 2 deletions packages/@react-spectrum/tabs/src/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ function TabLine(props: TabLineProps) {
* A TabList is used within Tabs to group tabs that a user can switch between.
* The keys of the items within the <TabList> must match up with a corresponding item inside the <TabPanels>.
*/
export function TabList<T>(props: SpectrumTabListProps<T>): ReactNode {
export function TabList<T>(props: SpectrumTabListProps<T> & {wrap?: boolean}): ReactNode {
const tabContext = useContext(TabContext)!;
const {refs, tabState, tabProps, tabPanelProps} = tabContext;
const {isQuiet, density, isEmphasized, orientation} = tabProps;
Expand All @@ -288,6 +288,8 @@ export function TabList<T>(props: SpectrumTabListProps<T>): ReactNode {

let tabListclassName = classNames(styles, 'spectrum-TabsPanel-tabs');

const verticalWrap = props.wrap && orientation === 'vertical';

const tabContent = (
<div
{...stylePropsFinal}
Expand All @@ -301,7 +303,8 @@ export function TabList<T>(props: SpectrumTabListProps<T>): ReactNode {
{
'spectrum-Tabs--quiet': isQuiet,
'spectrum-Tabs--emphasized': isEmphasized,
['spectrum-Tabs--compact']: density === 'compact'
['spectrum-Tabs--compact']: density === 'compact',
'spectrum-Tabs--verticalWrap': verticalWrap
},
orientation === 'vertical' && styleProps.className
)
Expand Down
111 changes: 111 additions & 0 deletions packages/@react-spectrum/tabs/stories/Tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ OrientationVertical.story = {
name: 'orientation: vertical'
};

export const OrientationVerticalWrap = () => renderWithVerticalWrap({minWidth: 90, wrap: true});

OrientationVerticalWrap.story = {
name: 'orientation: vertical, wrap: true'
};

export const DensityCompact = () => render({density: 'compact'});

DensityCompact.story = {
Expand Down Expand Up @@ -739,6 +745,111 @@ function renderWithFalsyKey(props = {}) {
);
}

function renderWithVerticalWrap(props = {}) {
return (
<Tabs
orientation="vertical"
aria-label="Tab example"
maxWidth={500}
onSelectionChange={action('onSelectionChange')}>
<TabList {...props}>
<Item key="val1">User Profile Settings</Item>
<Item key="val2">Notification Preferences</Item>
<Item key="val3">Tab 3</Item>
<Item key="val4">Tab 4</Item>
<Item key="val5">Tab 5</Item>
</TabList>
<TabPanels>
<Item key="val1">
<Heading>Tab Body 1</Heading>
<Text>
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.
</Text>
</Item>
<Item key="val2">
<Heading>Tab Body 2</Heading>
<Text>
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.
</Text>
</Item>
<Item key="val3">
<Heading>Tab Body 3</Heading>
<Text>
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.
</Text>
</Item>
<Item key="val4">
<Heading>Tab Body 4</Heading>
<Text>
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.
</Text>
</Item>
<Item key="val5">
<Heading>Tab Body 5</Heading>
<Text>
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.
</Text>
</Item>
</TabPanels>
</Tabs>
);
}

interface DynamicTabItem {
name: string,
children: ReactNode,
Expand Down
7 changes: 6 additions & 1 deletion packages/@react-types/tabs/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ export interface SpectrumTabsProps<T> extends AriaTabListBase, Omit<SingleSelect

export interface SpectrumTabListProps<T> extends DOMProps, StyleProps {
/** The tab items to display. Item keys should match the key of the corresponding `<Item>` within the `<TabPanels>` element. */
children: CollectionChildren<T>
children: CollectionChildren<T>,
/**
* When `true`, tab labels will wrap if they exceed the TabList's width. Only supported in vertical orientation with `regular` density. For proper wrapping, set a `minWidth` on TabList.
* @default false
*/
wrap?: boolean
}

export interface SpectrumTabPanelsProps<T> extends DOMProps, StyleProps {
Expand Down