Skip to content

Commit

Permalink
fix: remove bottom border animation and remove close button padding
Browse files Browse the repository at this point in the history
  • Loading branch information
r-mulder committed May 24, 2024
1 parent 4fedd4d commit e83337f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 66 deletions.
29 changes: 9 additions & 20 deletions packages/libs/react-ui/src/components/Tabs/Tabs.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,13 @@ export const tabListClass = style([
},
]);

export const selectorLine = style([
atoms({
position: 'absolute',
bottom: 0,
borderStyle: 'solid',
}),
{
width: 0,
height: 0,
zIndex: 4,
borderWidth: 0,
borderBottomWidth: token('border.width.normal'),
borderColor: token('color.border.tint.@focus'),
transition: 'transform .4s ease, width .4s ease',
transform: `translateX(0)`,
},
]);
// Prevent button from increasing the tab size and having the outline conflict with label
globalStyle(`${tabListClass} button`, {
paddingBlock: 0,
});

// To prevent overlapping with the focus ring, we hide the line when the tab is focused
globalStyle(`${tabListClass}.focusVisible ${selectorLine}`, {
opacity: 0,
globalStyle(`${tabListClass} span`, {
paddingInline: 0,
});

export const tabItemClass = recipe({
Expand Down Expand Up @@ -167,6 +153,9 @@ export const tabItemClass = recipe({
},
bottom: {
selectors: {
'&[data-selected="true"]': {
borderBottom: `2px solid ${token('color.border.tint.@focus')}`,
},
'&[data-hovered="true"]:not(&[data-selected="true"])': {
borderBottom: `2px solid ${token('color.border.tint.outline')}`,
},
Expand Down
56 changes: 10 additions & 46 deletions packages/libs/react-ui/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
'use client';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import React, { useEffect, useLayoutEffect, useRef } from 'react';
import type { ComponentProps, ReactNode } from 'react';
import React, { useEffect, useRef } from 'react';
import type { AriaTabListProps } from 'react-aria';
import { mergeProps, useFocusRing, useTabList } from 'react-aria';
import type { Node } from 'react-stately';
import { Item as TabItem, useTabListState } from 'react-stately';
import { Tab } from './Tab';
import { TabPanel } from './TabPanel';
import {
scrollContainer,
selectorLine,
tabListClass,
tabsContainerClass,
} from './Tabs.css';
import { scrollContainer, tabListClass, tabsContainerClass } from './Tabs.css';
import { TabsPagination } from './TabsPagination';

export { TabItem };

export type ITabItemProps = React.ComponentProps<typeof TabItem>;
export type ITabItemProps = ComponentProps<typeof TabItem>;

export interface ITabsProps
extends Omit<AriaTabListProps<object>, 'orientation' | 'items'> {
Expand All @@ -40,7 +35,6 @@ export const Tabs = ({
const state = useTabListState(props);
const containerRef = useRef<HTMLDivElement | null>(null);
const scrollRef = useRef<HTMLDivElement | null>(null);
const selectedUnderlineRef = useRef<HTMLSpanElement | null>(null);

const { focusProps, isFocusVisible } = useFocusRing({
within: true,
Expand All @@ -52,22 +46,18 @@ export const Tabs = ({
containerRef,
);

const getSelectedTab = () => {
// set Selected as first tab if the tab isn't visible
useEffect(() => {
let selected = containerRef.current?.querySelector(
'[data-selected="true"]',
);
) as HTMLElement | undefined;

if (selected === undefined || selected === null) {
selected = containerRef.current?.querySelectorAll('div[role="tab"]')[0];
selected = containerRef.current?.querySelectorAll(
'div[role="tab"]',
)[0] as HTMLElement;
}

return selected as HTMLElement | undefined;
};

// set Selected as first tab if the tab isn't visible
useEffect(() => {
let selected = getSelectedTab();

if (
selected &&
scrollRef.current &&
Expand All @@ -78,29 +68,6 @@ export const Tabs = ({
}
}, []);

// handle underline animation
useLayoutEffect(() => {
if (!containerRef.current || !selectedUnderlineRef.current) {
return;
}

const selected = getSelectedTab();

if (!selected) {
return;
}

selectedUnderlineRef.current.style.setProperty(
'transform',
`translateX(${selected.offsetLeft}px)`,
);

selectedUnderlineRef.current.style.setProperty(
'width',
`${selected.getBoundingClientRect().width}px`,
);
}, [state.selectedItem?.key]);

return (
<div className={classNames(tabsContainerClass, className)}>
<TabsPagination
Expand All @@ -126,9 +93,6 @@ export const Tabs = ({
isCompact={isCompact}
/>
))}
{borderPosition === 'bottom' && (
<span ref={selectedUnderlineRef} className={selectorLine}></span>
)}
</div>
</div>
</TabsPagination>
Expand Down

0 comments on commit e83337f

Please sign in to comment.