Skip to content

Commit

Permalink
Improve navigation tabs
Browse files Browse the repository at this point in the history
Animations! And remove the annoying outline that is always triggered on
on press
  • Loading branch information
ivarnakken committed Dec 18, 2024
1 parent b5ac4ed commit 3c6741f
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
align-items: center;
width: fit-content;
margin-bottom: var(--spacing-sm);
outline: none;
}

span.backLabel {
Expand All @@ -22,6 +23,7 @@
transition: transform var(--easing-medium);
}

.back:focus > .backIcon,
.back:hover > .backIcon {
transform: translateX(calc(-1 * var(--spacing-xs)));
}
Expand Down
25 changes: 19 additions & 6 deletions packages/lego-bricks/src/components/Tabs/Tab.module.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
.tabContainer {
position: relative;
display: inline-flex;
flex-direction: column;
}

.tab {
display: inline-block;
color: var(--lego-font-color);
padding: var(--spacing-sm) var(--spacing-md);
border-bottom: 2px solid var(--border-gray);
}

.tab.active {
border-bottom: 2px solid var(--color-black);
cursor: pointer;
outline: none;
}

.tab.disabled {
color: var(--border-gray);
opacity: 0.5;
pointer-events: none;
}

.tabIndicator {
position: absolute;
bottom: -2px;
height: 2px;
background-color: var(--color-black);
transition:
transform var(--easing-medium),
width var(--easing-medium);
}
48 changes: 24 additions & 24 deletions packages/lego-bricks/src/components/Tabs/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,31 @@ type Props = {
};

export const Tab = ({ active, disabled, onPress, href, children }: Props) => {
const className = cx(
styles.tab,
active && styles.active,
disabled && styles.disabled,
);
const className = cx(styles.tab, disabled && styles.disabled);

return href ? (
<Link
href={href}
isDisabled={disabled}
onPress={onPress}
className={className}
data-test-id="tab"
>
{children}
</Link>
) : (
<Button
isDisabled={disabled}
onPress={onPress}
className={className}
data-test-id="tab"
>
{children}
</Button>
return (
<div className={styles.tabContainer} data-active={active}>
{href ? (
<Link
href={href}
isDisabled={disabled}
onPress={onPress}
className={className}
data-test-id="tab"
>
{children}
</Link>
) : (
<Button
isDisabled={disabled}
onPress={onPress}
className={className}
data-test-id="tab"
>
{children}
</Button>
)}
</div>
);
};

Expand Down
20 changes: 18 additions & 2 deletions packages/lego-bricks/src/components/Tabs/TabContainer.module.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
.container {
margin: var(--spacing-sm) 0 var(--spacing-md);
position: relative;
display: flex;
flex-wrap: wrap;
}

.spacer {
flex-grow: 1;
.tabList {
display: flex;
position: relative;
border-bottom: 2px solid var(--border-gray);
width: 100%;
}

.indicator {
position: absolute;
bottom: -2px;
left: 0;
height: 2px;
background-color: var(--color-black);
transition:
transform var(--easing-medium),
width var(--easing-medium);
}
34 changes: 27 additions & 7 deletions packages/lego-bricks/src/components/Tabs/TabContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cx from 'classnames';
import { Flex } from '../Layout';
import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import styles from './TabContainer.module.css';
import type { ReactNode } from 'react';

Expand All @@ -9,9 +10,28 @@ type Props = {
children?: ReactNode;
};

export const TabContainer = ({ className, lineColor, children }: Props) => (
<Flex wrap className={cx(styles.container, className)}>
{children}
<div className={styles.spacer} style={{ borderColor: lineColor }} />
</Flex>
);
export const TabContainer = ({ className, lineColor, children }: Props) => {
const [indicatorStyle, setIndicatorStyle] = useState<React.CSSProperties>({});
const location = useLocation();

useEffect(() => {
const activeTab = document.querySelector('[data-active="true"]');
if (activeTab) {
const width = activeTab.clientWidth;
const left = (activeTab as HTMLElement).offsetLeft;
setIndicatorStyle({
width: `${width}px`,
transform: `translateX(${left}px)`,
});
}
}, [children, location.pathname]);

return (
<div className={cx(styles.container, className)}>
<div className={styles.tabList} style={{ borderColor: lineColor }}>
{children}
<div className={styles.indicator} style={indicatorStyle} />
</div>
</div>
);
};

0 comments on commit 3c6741f

Please sign in to comment.