Skip to content

Commit d5e0897

Browse files
committed
feat(tabs): add switch variant & deprecate Switch
1 parent d689add commit d5e0897

File tree

19 files changed

+663
-82
lines changed

19 files changed

+663
-82
lines changed

packages/ods-react/src/components/switch/src/components/switch/Switch.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ToggleGroup, type ToggleGroupValueChangeDetails } from '@ark-ui/react/toggle-group';
22
import classNames from 'classnames';
3-
import { type ComponentPropsWithRef, type FC, type JSX, forwardRef } from 'react';
3+
import { type ComponentPropsWithRef, type FC, type JSX, forwardRef, useEffect } from 'react';
44
import { SWITCH_SIZE, type SwitchSize } from '../../constants/switch-size';
55
import style from './switch.module.scss';
66

@@ -40,6 +40,10 @@ const Switch: FC<SwitchProp> = forwardRef(({
4040
value,
4141
...props
4242
}, ref): JSX.Element => {
43+
useEffect(() => {
44+
console.warn('[DEPRECATED]: Switch component is not recommended anymore and will be removed in a next major release. Check the documentation for correct alternative.');
45+
}, []);
46+
4347
function onSwitchValueChange(detail: ToggleGroupValueChangeDetails): void {
4448
if (onValueChange) {
4549
onValueChange({ value: detail.value[0] });

packages/ods-react/src/components/tabs/src/components/tab-list/TabList.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { type ComponentPropsWithRef, type FC, type JSX, forwardRef, useCallback,
44
import { debounce } from '../../../../../utils/debounce';
55
import { BUTTON_SIZE, BUTTON_VARIANT, Button } from '../../../../button/src';
66
import { ICON_NAME, Icon } from '../../../../icon/src';
7+
import { TABS_VARIANT } from '../../constants/tabs-variant';
78
import { useTabs } from '../../contexts/useTabs';
89
import style from './tabList.module.scss';
910

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

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

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

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

7476
return (
7577
<div
76-
className={ classNames(style['tab-list'], className) }
78+
className={ classNames(
79+
style['tab-list'],
80+
className,
81+
)}
7782
data-ods="tab-list"
7883
ref={ ref }
7984
{ ...props }>
8085
{
8186
withArrows &&
8287
<div className={ classNames(
8388
style['tab-list__left-arrow'],
89+
style[`tab-list__left-arrow--${arrowSize}`],
8490
{ [style['tab-list__left-arrow--active']]: !isLeftButtonDisabled },
8591
)}>
8692
<Button
8793
disabled={ isLeftButtonDisabled }
8894
onClick={ onLeftScrollClick }
89-
size={ BUTTON_SIZE.xs }
95+
size={ arrowSize }
9096
tabIndex={ -1 }
9197
variant={ BUTTON_VARIANT.ghost }>
9298
<Icon name={ ICON_NAME.chevronLeft } />
@@ -95,7 +101,11 @@ const TabList: FC<TabListProp> = forwardRef(({
95101
}
96102

97103
<div
98-
className={ style['tab-list__container'] }
104+
className={ classNames(
105+
style['tab-list__container'],
106+
style[`tab-list__container--${size}`],
107+
style[`tab-list__container--${variant}`],
108+
)}
99109
onScroll={ debouncedUpdateScrollButtonState }
100110
ref={ scrollRef }
101111
tabIndex={ -1 }>
@@ -108,12 +118,13 @@ const TabList: FC<TabListProp> = forwardRef(({
108118
withArrows &&
109119
<div className={ classNames(
110120
style['tab-list__right-arrow'],
121+
style[`tab-list__right-arrow--${arrowSize}`],
111122
{ [style['tab-list__right-arrow--active']]: !isRightButtonDisabled },
112123
)}>
113124
<Button
114125
disabled={ isRightButtonDisabled }
115126
onClick={ onRightScrollClick }
116-
size={ BUTTON_SIZE.xs }
127+
size={ arrowSize }
117128
tabIndex={ -1 }
118129
variant={ BUTTON_VARIANT.ghost }>
119130
<Icon name={ ICON_NAME.chevronRight } />

packages/ods-react/src/components/tabs/src/components/tab-list/tabList.module.scss

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
@use '../../../../../style/button';
2+
@use '../../../../../style/font';
23
@use '../../../../../style/scroll';
34

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

67
@layer ods-molecules {
78
.tab-list {
9+
--ods-tab-list-background-color-switch: var(--ods-color-neutral-050);
810
--ods-tab-list-border-color: var(--ods-color-neutral-100);
11+
--ods-tab-list-border-radius-switch-md: calc(var(--ods-theme-border-radius) * 1.25);
12+
--ods-tab-list-border-radius-switch-sm: calc(var(--ods-theme-border-radius) * 0.75);
13+
--ods-tab-list-border-radius-switch-xs: calc(var(--ods-theme-border-radius) / 2);
14+
--ods-tab-list-border-width: #{$tab-list-border-bottom-size};
915

1016
display: flex;
1117
position: relative;
@@ -25,22 +31,39 @@ $tab-list-border-bottom-size: 2px;
2531
bottom: 0;
2632
transition: opacity ease .3s;
2733
opacity: 0;
28-
z-index: 1;
34+
z-index: 10;
2935
width: 60px;
3036
height: 100%;
3137
content: '';
3238
pointer-events: none;
3339
}
40+
41+
&--xs {
42+
[data-ods="button"] {
43+
font-size: font.px-to-rem(10px);
44+
}
45+
}
3446
}
3547

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

53+
&--md::after {
54+
left: button.$ods-button-size-md;
55+
}
56+
57+
&--sm::after {
58+
left: button.$ods-button-size-sm;
59+
}
60+
61+
&--xs::after {
62+
left: button.$ods-button-size-xs;
63+
}
64+
4165
&--active {
4266
&::after {
43-
left: button.$ods-button-size-xs;
4467
opacity: 1;
4568
}
4669
}
@@ -51,34 +74,66 @@ $tab-list-border-bottom-size: 2px;
5174
background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 1) 100%);
5275
}
5376

77+
&--md::after {
78+
right: button.$ods-button-size-md;
79+
}
80+
81+
&--sm::after {
82+
right: button.$ods-button-size-sm;
83+
}
84+
85+
&--xs::after {
86+
right: button.$ods-button-size-xs;
87+
}
88+
5489
&--active {
5590
&::after {
56-
right: button.$ods-button-size-xs;
5791
opacity: 1;
5892
}
5993
}
6094
}
6195

6296
&__container {
97+
$container: &;
98+
6399
@include scroll.hide-scrollbar();
64100

65101
display: inline-block;
66102
position: relative;
67-
width: 100%;
68103
overflow: auto hidden;
69104
white-space: nowrap;
70105

71-
&::after {
72-
position: absolute;
73-
right: 0;
74-
bottom: 0;
75-
left: 0;
76-
border-bottom: solid $tab-list-border-bottom-size var(--ods-tab-list-border-color);
77-
content: '';
106+
&--default {
107+
width: 100%;
108+
109+
&::after {
110+
position: absolute;
111+
right: 0;
112+
bottom: 0;
113+
left: 0;
114+
border-bottom: solid var(--ods-tab-list-border-width) var(--ods-tab-list-border-color);
115+
content: '';
116+
}
117+
}
118+
119+
&--switch {
120+
background-color: var(--ods-tab-list-background-color-switch);
121+
122+
&#{$container}--md {
123+
border-radius: var(--ods-tab-list-border-radius-switch-md);
124+
}
125+
126+
&#{$container}--sm {
127+
border-radius: var(--ods-tab-list-border-radius-switch-sm);
128+
}
129+
130+
&#{$container}--xs {
131+
border-radius: var(--ods-tab-list-border-radius-switch-xs);
132+
}
78133
}
79134

80135
&__tabs {
81-
display: flex;
136+
display: inline-flex;
82137
}
83138
}
84139
}

packages/ods-react/src/components/tabs/src/components/tab/Tab.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const Tab: FC<TabProp> = forwardRef(({
1818
...props
1919
}, ref): JSX.Element => {
2020
const { focusedValue } = useTabsContext();
21-
const { scrollContainerRef } = useTabs();
21+
const { scrollContainerRef, size, variant } = useTabs();
2222
const innerRef = useRef<HTMLButtonElement>(null);
2323

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

4444
return (
4545
<Tabs.Trigger
46-
className={ classNames(style['tab'], className) }
46+
className={ classNames(
47+
style['tab'],
48+
style[`tab--${size}`],
49+
style[`tab--${variant}`],
50+
className,
51+
)}
4752
data-ods="tab"
4853
ref={ innerRef }
4954
value={ value }

0 commit comments

Comments
 (0)