Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ToggleGroup, type ToggleGroupValueChangeDetails } from '@ark-ui/react/toggle-group';
import classNames from 'classnames';
import { type ComponentPropsWithRef, type FC, type JSX, forwardRef } from 'react';
import { type ComponentPropsWithRef, type FC, type JSX, forwardRef, useEffect } from 'react';
import { SWITCH_SIZE, type SwitchSize } from '../../constants/switch-size';
import style from './switch.module.scss';

Expand Down Expand Up @@ -40,6 +40,10 @@ const Switch: FC<SwitchProp> = forwardRef(({
value,
...props
}, ref): JSX.Element => {
useEffect(() => {
console.warn('[DEPRECATED]: Switch component is not recommended anymore and will be removed in a next major release. Check the documentation for correct alternative.');
}, []);

function onSwitchValueChange(detail: ToggleGroupValueChangeDetails): void {
if (onValueChange) {
onValueChange({ value: detail.value[0] });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { type ComponentPropsWithRef, type FC, type JSX, forwardRef, useCallback,
import { debounce } from '../../../../../utils/debounce';
import { BUTTON_SIZE, BUTTON_VARIANT, Button } from '../../../../button/src';
import { ICON_NAME, Icon } from '../../../../icon/src';
import { TABS_VARIANT } from '../../constants/tabs-variant';
import { useTabs } from '../../contexts/useTabs';
import style from './tabList.module.scss';

Expand All @@ -14,10 +15,11 @@ const TabList: FC<TabListProp> = forwardRef(({
className,
...props
}, ref): JSX.Element => {
const { withArrows, setScrollContainerRef } = useTabs();
const { setScrollContainerRef, size, variant, withArrows } = useTabs();
const [isLeftButtonDisabled, setIsLeftButtonDisabled] = useState(false);
const [isRightButtonDisabled, setIsRightButtonDisabled] = useState(false);
const scrollRef = useRef<HTMLDivElement>(null);
const arrowSize = variant === TABS_VARIANT.default ? BUTTON_SIZE.xs : size;

useEffect(() => {
if (setScrollContainerRef) {
Expand All @@ -27,7 +29,7 @@ const TabList: FC<TabListProp> = forwardRef(({

const updateScrollButtonState = useCallback(() => {
setIsLeftButtonDisabled(scrollRef.current ? scrollRef.current.scrollLeft === 0 : false);
setIsRightButtonDisabled(scrollRef.current ? scrollRef.current.scrollLeft === scrollRef.current.scrollWidth - scrollRef.current.offsetWidth : false);
setIsRightButtonDisabled(scrollRef.current ? Math.ceil(scrollRef.current.scrollLeft) >= scrollRef.current.scrollWidth - scrollRef.current.offsetWidth : false);
}, []);

const debouncedUpdateScrollButtonState = useMemo(() => {
Expand Down Expand Up @@ -73,20 +75,24 @@ const TabList: FC<TabListProp> = forwardRef(({

return (
<div
className={ classNames(style['tab-list'], className) }
className={ classNames(
style['tab-list'],
className,
)}
data-ods="tab-list"
ref={ ref }
{ ...props }>
{
withArrows &&
<div className={ classNames(
style['tab-list__left-arrow'],
style[`tab-list__left-arrow--${arrowSize}`],
{ [style['tab-list__left-arrow--active']]: !isLeftButtonDisabled },
)}>
<Button
disabled={ isLeftButtonDisabled }
onClick={ onLeftScrollClick }
size={ BUTTON_SIZE.xs }
size={ arrowSize }
tabIndex={ -1 }
variant={ BUTTON_VARIANT.ghost }>
<Icon name={ ICON_NAME.chevronLeft } />
Expand All @@ -95,7 +101,11 @@ const TabList: FC<TabListProp> = forwardRef(({
}

<div
className={ style['tab-list__container'] }
className={ classNames(
style['tab-list__container'],
style[`tab-list__container--${size}`],
style[`tab-list__container--${variant}`],
)}
onScroll={ debouncedUpdateScrollButtonState }
ref={ scrollRef }
tabIndex={ -1 }>
Expand All @@ -108,12 +118,13 @@ const TabList: FC<TabListProp> = forwardRef(({
withArrows &&
<div className={ classNames(
style['tab-list__right-arrow'],
style[`tab-list__right-arrow--${arrowSize}`],
{ [style['tab-list__right-arrow--active']]: !isRightButtonDisabled },
)}>
<Button
disabled={ isRightButtonDisabled }
onClick={ onRightScrollClick }
size={ BUTTON_SIZE.xs }
size={ arrowSize }
tabIndex={ -1 }
variant={ BUTTON_VARIANT.ghost }>
<Icon name={ ICON_NAME.chevronRight } />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
@use '../../../../../style/button';
@use '../../../../../style/font';
@use '../../../../../style/scroll';

$tab-list-border-bottom-size: 2px;

@layer ods-molecules {
.tab-list {
--ods-tab-list-background-color-switch: var(--ods-color-neutral-050);
--ods-tab-list-border-color: var(--ods-color-neutral-100);
--ods-tab-list-border-radius-switch-md: calc(var(--ods-theme-border-radius) * 1.25);
--ods-tab-list-border-radius-switch-sm: calc(var(--ods-theme-border-radius) * 0.75);
--ods-tab-list-border-radius-switch-xs: calc(var(--ods-theme-border-radius) / 2);
--ods-tab-list-border-width: #{$tab-list-border-bottom-size};

display: flex;
position: relative;
Expand All @@ -25,22 +31,39 @@ $tab-list-border-bottom-size: 2px;
bottom: 0;
transition: opacity ease .3s;
opacity: 0;
z-index: 1;
z-index: 10;
width: 60px;
height: 100%;
content: '';
pointer-events: none;
}

&--xs {
[data-ods="button"] {
font-size: font.px-to-rem(10px);
}
}
}

&__left-arrow {
&::after {
background: linear-gradient(270deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 1) 100%);
}

&--md::after {
left: button.$ods-button-size-md;
}

&--sm::after {
left: button.$ods-button-size-sm;
}

&--xs::after {
left: button.$ods-button-size-xs;
}

&--active {
&::after {
left: button.$ods-button-size-xs;
opacity: 1;
}
}
Expand All @@ -51,34 +74,66 @@ $tab-list-border-bottom-size: 2px;
background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 1) 100%);
}

&--md::after {
right: button.$ods-button-size-md;
}

&--sm::after {
right: button.$ods-button-size-sm;
}

&--xs::after {
right: button.$ods-button-size-xs;
}

&--active {
&::after {
right: button.$ods-button-size-xs;
opacity: 1;
}
}
}

&__container {
$container: &;

@include scroll.hide-scrollbar();

display: inline-block;
position: relative;
width: 100%;
overflow: auto hidden;
white-space: nowrap;

&::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
border-bottom: solid $tab-list-border-bottom-size var(--ods-tab-list-border-color);
content: '';
&--default {
width: 100%;

&::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
border-bottom: solid var(--ods-tab-list-border-width) var(--ods-tab-list-border-color);
content: '';
}
}

&--switch {
background-color: var(--ods-tab-list-background-color-switch);

&#{$container}--md {
border-radius: var(--ods-tab-list-border-radius-switch-md);
}

&#{$container}--sm {
border-radius: var(--ods-tab-list-border-radius-switch-sm);
}

&#{$container}--xs {
border-radius: var(--ods-tab-list-border-radius-switch-xs);
}
}

&__tabs {
display: flex;
display: inline-flex;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Tab: FC<TabProp> = forwardRef(({
...props
}, ref): JSX.Element => {
const { focusedValue } = useTabsContext();
const { scrollContainerRef } = useTabs();
const { scrollContainerRef, size, variant } = useTabs();
const innerRef = useRef<HTMLButtonElement>(null);

useImperativeHandle(ref, () => innerRef.current!, [innerRef]);
Expand All @@ -43,7 +43,12 @@ const Tab: FC<TabProp> = forwardRef(({

return (
<Tabs.Trigger
className={ classNames(style['tab'], className) }
className={ classNames(
style['tab'],
style[`tab--${size}`],
style[`tab--${variant}`],
className,
)}
data-ods="tab"
ref={ innerRef }
value={ value }
Expand Down
Loading