@toptal/picasso-tabs 2.0.9-alpha-cjs-and-esm-publish-test-99555d2ed.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-package/src/Tab/Tab.d.ts +3 -3
- package/dist-package/src/Tab/Tab.d.ts.map +1 -1
- package/dist-package/src/Tab/Tab.js +62 -14
- package/dist-package/src/Tab/Tab.js.map +1 -1
- package/dist-package/src/TabLabel/TabLabel.d.ts.map +1 -1
- package/dist-package/src/TabLabel/TabLabel.js +2 -3
- package/dist-package/src/TabLabel/TabLabel.js.map +1 -1
- package/dist-package/src/Tabs/Tabs.d.ts +19 -10
- package/dist-package/src/Tabs/Tabs.d.ts.map +1 -1
- package/dist-package/src/Tabs/Tabs.js +51 -21
- package/dist-package/src/Tabs/Tabs.js.map +1 -1
- package/dist-package/src/Tabs/index.d.ts +3 -2
- package/dist-package/src/Tabs/index.d.ts.map +1 -1
- package/dist-package/src/TabsCompound/index.d.ts +4 -2
- package/dist-package/src/TabsCompound/index.d.ts.map +1 -1
- package/dist-package/src/index.d.ts +0 -1
- package/dist-package/src/index.d.ts.map +1 -1
- package/dist-package/src/index.js +0 -1
- package/dist-package/src/index.js.map +1 -1
- package/package.json +16 -16
- package/src/Tab/Tab.tsx +100 -21
- package/src/Tab/__snapshots__/test.tsx.snap +91 -37
- package/src/Tab/story/CustomValue.example.tsx +2 -2
- package/src/Tab/test.tsx +9 -1
- package/src/TabLabel/TabLabel.tsx +10 -4
- package/src/Tabs/Tabs.tsx +114 -61
- package/src/Tabs/__snapshots__/test.tsx.snap +61 -76
- package/src/Tabs/index.ts +3 -2
- package/src/Tabs/story/Default.example.tsx +1 -1
- package/src/Tabs/story/FullWidth.example.tsx +1 -1
- package/src/Tabs/story/ScrollButtons.example.tsx +1 -1
- package/src/Tabs/story/Vertical.example.tsx +1 -1
- package/src/Tabs/test.tsx +11 -8
- package/src/index.ts +1 -2
- package/LICENSE +0 -20
- package/dist-package/src/Tab/styles.d.ts +0 -4
- package/dist-package/src/Tab/styles.d.ts.map +0 -1
- package/dist-package/src/Tab/styles.js +0 -94
- package/dist-package/src/Tab/styles.js.map +0 -1
- package/dist-package/src/TabScrollButton/TabScrollButton.d.ts +0 -12
- package/dist-package/src/TabScrollButton/TabScrollButton.d.ts.map +0 -1
- package/dist-package/src/TabScrollButton/TabScrollButton.js +0 -40
- package/dist-package/src/TabScrollButton/TabScrollButton.js.map +0 -1
- package/dist-package/src/TabScrollButton/index.d.ts +0 -5
- package/dist-package/src/TabScrollButton/index.d.ts.map +0 -1
- package/dist-package/src/TabScrollButton/index.js +0 -2
- package/dist-package/src/TabScrollButton/index.js.map +0 -1
- package/dist-package/src/TabScrollButton/styles.d.ts +0 -4
- package/dist-package/src/TabScrollButton/styles.d.ts.map +0 -1
- package/dist-package/src/TabScrollButton/styles.js +0 -35
- package/dist-package/src/TabScrollButton/styles.js.map +0 -1
- package/dist-package/src/Tabs/styles.d.ts +0 -4
- package/dist-package/src/Tabs/styles.d.ts.map +0 -1
- package/dist-package/src/Tabs/styles.js +0 -41
- package/dist-package/src/Tabs/styles.js.map +0 -1
- package/dist-package/src/Tabs/use-tab-action.d.ts +0 -5
- package/dist-package/src/Tabs/use-tab-action.d.ts.map +0 -1
- package/dist-package/src/Tabs/use-tab-action.js +0 -21
- package/dist-package/src/Tabs/use-tab-action.js.map +0 -1
- package/src/Tab/styles.ts +0 -106
- package/src/TabScrollButton/TabScrollButton.tsx +0 -64
- package/src/TabScrollButton/index.ts +0 -6
- package/src/TabScrollButton/styles.ts +0 -37
- package/src/Tabs/styles.ts +0 -45
- package/src/Tabs/use-tab-action.ts +0 -27
@@ -5,23 +5,39 @@ exports[`Tab Tab disabled tab 1`] = `
|
|
5
5
|
<div
|
6
6
|
class="Picasso-root"
|
7
7
|
>
|
8
|
-
<
|
9
|
-
class="
|
10
|
-
disabled=""
|
11
|
-
role="tab"
|
12
|
-
tabindex="-1"
|
13
|
-
type="button"
|
8
|
+
<div
|
9
|
+
class="base-Tabs base-Tabs relative min-h flex overflow-hidden overflow-x"
|
14
10
|
>
|
15
|
-
<
|
16
|
-
class="
|
11
|
+
<div
|
12
|
+
class="after:absolute after:content-[""] after:bottom-0 after:left-0 after:right-0 after:h-[1px] after:bg-gray after:z-0 flex-auto inline-block relative whitespace-nowrap"
|
17
13
|
>
|
18
14
|
<div
|
19
|
-
class="
|
15
|
+
class="base-TabsList base-TabsList flex"
|
16
|
+
role="tablist"
|
17
|
+
tabindex="-1"
|
20
18
|
>
|
21
|
-
|
19
|
+
<button
|
20
|
+
aria-disabled="true"
|
21
|
+
aria-selected="false"
|
22
|
+
class="base-Tab base- opacity-50 m-0 [&:not(:last-child)]:mr-8 pt-[0.5625rem] pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none shrink-0 max-w text-gray pointer-events min-w sm:min-w md:min-w border-0 cursor-pointer inline-flex outline-none items-center select-none align-middle appearance-none justify-center no-underline [-webkit-tap-highlight normal-case whitespace-normal leading-4 relative"
|
23
|
+
id=":r1:"
|
24
|
+
role="tab"
|
25
|
+
tabindex="0"
|
26
|
+
type="button"
|
27
|
+
>
|
28
|
+
<span
|
29
|
+
class="w-full inline-flex items-center flex-col justify-center"
|
30
|
+
>
|
31
|
+
<div
|
32
|
+
class="m-0 text-sm text-inherit font-semibold"
|
33
|
+
>
|
34
|
+
Tab Label
|
35
|
+
</div>
|
36
|
+
</span>
|
37
|
+
</button>
|
22
38
|
</div>
|
23
|
-
</
|
24
|
-
</
|
39
|
+
</div>
|
40
|
+
</div>
|
25
41
|
</div>
|
26
42
|
</div>
|
27
43
|
`;
|
@@ -31,22 +47,39 @@ exports[`Tab Tab renders 1`] = `
|
|
31
47
|
<div
|
32
48
|
class="Picasso-root"
|
33
49
|
>
|
34
|
-
<
|
35
|
-
class="
|
36
|
-
role="tab"
|
37
|
-
tabindex="0"
|
38
|
-
type="button"
|
50
|
+
<div
|
51
|
+
class="base-Tabs base-Tabs relative min-h flex overflow-hidden overflow-x"
|
39
52
|
>
|
40
|
-
<
|
41
|
-
class="
|
53
|
+
<div
|
54
|
+
class="after:absolute after:content-[""] after:bottom-0 after:left-0 after:right-0 after:h-[1px] after:bg-gray after:z-0 flex-auto inline-block relative whitespace-nowrap"
|
42
55
|
>
|
43
56
|
<div
|
44
|
-
class="
|
57
|
+
class="base-TabsList base-TabsList flex"
|
58
|
+
role="tablist"
|
59
|
+
tabindex="-1"
|
45
60
|
>
|
46
|
-
|
61
|
+
<button
|
62
|
+
aria-disabled="false"
|
63
|
+
aria-selected="false"
|
64
|
+
class="base-Tab opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-[0.5625rem] pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-inheritColor shrink-0 max-w min-w sm:min-w md:min-w border-0 cursor-pointer inline-flex outline-none items-center select-none align-middle appearance-none justify-center no-underline [-webkit-tap-highlight normal-case whitespace-normal leading-4 relative"
|
65
|
+
id=":r0:"
|
66
|
+
role="tab"
|
67
|
+
tabindex="0"
|
68
|
+
type="button"
|
69
|
+
>
|
70
|
+
<span
|
71
|
+
class="w-full inline-flex items-center flex-col justify-center"
|
72
|
+
>
|
73
|
+
<div
|
74
|
+
class="m-0 text-sm text-inherit font-semibold"
|
75
|
+
>
|
76
|
+
Tab Label
|
77
|
+
</div>
|
78
|
+
</span>
|
79
|
+
</button>
|
47
80
|
</div>
|
48
|
-
</
|
49
|
-
</
|
81
|
+
</div>
|
82
|
+
</div>
|
50
83
|
</div>
|
51
84
|
</div>
|
52
85
|
`;
|
@@ -56,25 +89,46 @@ exports[`Tab Tab tab with icon 1`] = `
|
|
56
89
|
<div
|
57
90
|
class="Picasso-root"
|
58
91
|
>
|
59
|
-
<
|
60
|
-
class="
|
61
|
-
role="tab"
|
62
|
-
tabindex="0"
|
63
|
-
type="button"
|
92
|
+
<div
|
93
|
+
class="base-Tabs base-Tabs relative min-h flex overflow-hidden overflow-x"
|
64
94
|
>
|
65
|
-
<
|
66
|
-
class="
|
95
|
+
<div
|
96
|
+
class="after:absolute after:content-[""] after:bottom-0 after:left-0 after:right-0 after:h-[1px] after:bg-gray after:z-0 flex-auto inline-block relative whitespace-nowrap"
|
67
97
|
>
|
68
98
|
<div
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
class="m-0 text-sm text-inherit font-semibold"
|
99
|
+
class="base-TabsList base-TabsList flex"
|
100
|
+
role="tablist"
|
101
|
+
tabindex="-1"
|
73
102
|
>
|
74
|
-
|
103
|
+
<button
|
104
|
+
aria-disabled="false"
|
105
|
+
aria-selected="false"
|
106
|
+
class="base-Tab opacity-70 m-0 [&:not(:last-child)]:mr-8 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-inheritColor shrink-0 max-w min-h pt-[0.5625rem] pr-6 min-w sm:min-w md:min-w border-0 cursor-pointer inline-flex outline-none items-center select-none align-middle appearance-none justify-center no-underline [-webkit-tap-highlight normal-case whitespace-normal leading-4 relative"
|
107
|
+
id=":r2:"
|
108
|
+
role="tab"
|
109
|
+
tabindex="0"
|
110
|
+
type="button"
|
111
|
+
>
|
112
|
+
<span
|
113
|
+
class="w-full inline-flex items-center flex-col justify-center"
|
114
|
+
>
|
115
|
+
<div
|
116
|
+
class="m-0 text-sm text-inherit font-semibold"
|
117
|
+
>
|
118
|
+
Tab Label
|
119
|
+
</div>
|
120
|
+
<span
|
121
|
+
class="absolute right-0 mb-0 h-4"
|
122
|
+
>
|
123
|
+
<div
|
124
|
+
id="Icon"
|
125
|
+
/>
|
126
|
+
</span>
|
127
|
+
</span>
|
128
|
+
</button>
|
75
129
|
</div>
|
76
|
-
</
|
77
|
-
</
|
130
|
+
</div>
|
131
|
+
</div>
|
78
132
|
</div>
|
79
133
|
</div>
|
80
134
|
`;
|
@@ -2,10 +2,10 @@ import React from 'react'
|
|
2
2
|
import { Container, Tabs } from '@toptal/picasso'
|
3
3
|
import { SPACING_4 } from '@toptal/picasso-utils'
|
4
4
|
|
5
|
-
type Value = number | string |
|
5
|
+
type Value = number | string | null
|
6
6
|
|
7
7
|
const Example = () => {
|
8
|
-
const [value, setValue] = React.useState<Value>(
|
8
|
+
const [value, setValue] = React.useState<Value>(0)
|
9
9
|
|
10
10
|
const handleChange = (_: React.ChangeEvent<{}>, newValue: Value) => {
|
11
11
|
setValue(newValue)
|
package/src/Tab/test.tsx
CHANGED
@@ -6,6 +6,7 @@ import type { PicassoConfig } from '@toptal/picasso-test-utils'
|
|
6
6
|
|
7
7
|
import type { Props } from './Tab'
|
8
8
|
import { Tab } from './Tab'
|
9
|
+
import { Tabs } from '../Tabs'
|
9
10
|
|
10
11
|
jest.mock('ap-style-title-case')
|
11
12
|
|
@@ -16,7 +17,14 @@ const renderTab = (
|
|
16
17
|
const { label, disabled, icon, titleCase } = props
|
17
18
|
|
18
19
|
return render(
|
19
|
-
<
|
20
|
+
<Tabs value={null}>
|
21
|
+
<Tab
|
22
|
+
label={label}
|
23
|
+
disabled={disabled}
|
24
|
+
icon={icon}
|
25
|
+
titleCase={titleCase}
|
26
|
+
/>
|
27
|
+
</Tabs>,
|
20
28
|
undefined,
|
21
29
|
picassoConfig
|
22
30
|
)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import { TypographyOverflow } from '@toptal/picasso-typography-overflow'
|
3
3
|
import { Typography } from '@toptal/picasso-typography'
|
4
|
-
import { toTitleCase } from '@toptal/picasso-utils'
|
5
4
|
|
6
5
|
interface Props {
|
7
6
|
label?: React.ReactNode
|
@@ -12,8 +11,14 @@ interface Props {
|
|
12
11
|
const TabLabel = ({ label, orientation, titleCase }: Props) => {
|
13
12
|
if (orientation === 'horizontal') {
|
14
13
|
return (
|
15
|
-
<Typography
|
16
|
-
|
14
|
+
<Typography
|
15
|
+
as='div'
|
16
|
+
size='small'
|
17
|
+
weight='semibold'
|
18
|
+
color='inherit'
|
19
|
+
titleCase={titleCase}
|
20
|
+
>
|
21
|
+
{label}
|
17
22
|
</Typography>
|
18
23
|
)
|
19
24
|
}
|
@@ -26,8 +31,9 @@ const TabLabel = ({ label, orientation, titleCase }: Props) => {
|
|
26
31
|
size='medium'
|
27
32
|
variant='body'
|
28
33
|
weight='semibold'
|
34
|
+
titleCase={titleCase}
|
29
35
|
>
|
30
|
-
{
|
36
|
+
{label}
|
31
37
|
</TypographyOverflow>
|
32
38
|
)
|
33
39
|
}
|
package/src/Tabs/Tabs.tsx
CHANGED
@@ -1,81 +1,134 @@
|
|
1
|
-
import type { ReactNode } from 'react'
|
2
|
-
import React, { forwardRef } from 'react'
|
3
|
-
import
|
4
|
-
import {
|
5
|
-
import type {
|
6
|
-
import {
|
7
|
-
import type { ButtonOrAnchorProps, BaseProps } from '@toptal/picasso-shared'
|
1
|
+
import type { ReactNode, ForwardedRef } from 'react'
|
2
|
+
import React, { forwardRef, useMemo } from 'react'
|
3
|
+
import { Tabs as MUITabs } from '@mui/base/Tabs'
|
4
|
+
import { TabsList } from '@mui/base/TabsList'
|
5
|
+
import type { BaseProps } from '@toptal/picasso-shared'
|
6
|
+
import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge'
|
8
7
|
|
9
|
-
|
10
|
-
import styles from './styles'
|
11
|
-
import useTabAction from './use-tab-action'
|
8
|
+
export type TabsValueType = string | number | null
|
12
9
|
|
13
|
-
export interface Props
|
14
|
-
extends BaseProps,
|
15
|
-
Omit<ButtonOrAnchorProps, 'onChange'> {
|
10
|
+
export interface Props<V extends TabsValueType> extends BaseProps {
|
16
11
|
/** Tabs content containing Tab components */
|
17
12
|
children: ReactNode
|
18
13
|
|
19
14
|
/** Callback fired when the value changes. */
|
20
|
-
onChange?: (event: React.ChangeEvent<{}
|
15
|
+
onChange?: (event: React.ChangeEvent<{}> | null, value: V) => void
|
21
16
|
|
22
|
-
/**
|
23
|
-
|
17
|
+
/**
|
18
|
+
* The value of the currently selected Tab.
|
19
|
+
* If you don't want any selected Tab, you can set this property to null.
|
20
|
+
*/
|
21
|
+
value: V
|
24
22
|
|
25
23
|
/** The tabs orientation (layout flow direction). */
|
26
24
|
orientation?: 'horizontal' | 'vertical'
|
27
25
|
|
28
26
|
/** Determines additional display behavior of the tabs */
|
29
|
-
variant?:
|
27
|
+
variant?: 'scrollable' | 'fullWidth'
|
30
28
|
}
|
31
29
|
|
32
|
-
const
|
33
|
-
|
34
|
-
|
30
|
+
export const TabsContext = React.createContext<{
|
31
|
+
orientation: 'horizontal' | 'vertical'
|
32
|
+
variant: 'scrollable' | 'fullWidth'
|
33
|
+
}>({ orientation: 'horizontal', variant: 'scrollable' })
|
35
34
|
|
36
|
-
|
37
|
-
'
|
38
|
-
|
35
|
+
const indicatorClasses = [
|
36
|
+
'after:absolute',
|
37
|
+
'after:content-[""]',
|
38
|
+
'after:bottom-0',
|
39
|
+
'after:left-0',
|
40
|
+
'after:right-0',
|
41
|
+
'after:h-[1px]',
|
42
|
+
'after:bg-gray-500',
|
43
|
+
'after:z-0',
|
44
|
+
]
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
variant = 'scrollable',
|
51
|
-
...rest
|
52
|
-
} = props
|
53
|
-
const classes = useStyles(props)
|
54
|
-
const action = useTabAction()
|
46
|
+
const classesByOrientation = {
|
47
|
+
vertical: {
|
48
|
+
root: 'w-[200px] m-0 flex-col',
|
49
|
+
scroller: 'pl-2',
|
50
|
+
},
|
51
|
+
horizontal: {
|
52
|
+
root: '',
|
53
|
+
scroller: indicatorClasses,
|
54
|
+
},
|
55
|
+
} as const
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
ScrollButtonComponent={TabScrollButton}
|
67
|
-
orientation={orientation}
|
68
|
-
variant={variant}
|
69
|
-
>
|
70
|
-
{children}
|
71
|
-
</MUITabs>
|
72
|
-
</TabsOrientationContext.Provider>
|
73
|
-
)
|
74
|
-
})
|
57
|
+
const classesByVariant = {
|
58
|
+
scrollable: {
|
59
|
+
root: 'overflow-x-auto',
|
60
|
+
scroller: '',
|
61
|
+
},
|
62
|
+
fullWidth: {
|
63
|
+
root: '',
|
64
|
+
scroller: 'w-full overflow-hidden',
|
65
|
+
},
|
66
|
+
} as const
|
75
67
|
|
76
|
-
Tabs
|
77
|
-
|
78
|
-
|
79
|
-
|
68
|
+
const Tabs = forwardRef(
|
69
|
+
<V extends TabsValueType = TabsValueType>(
|
70
|
+
{
|
71
|
+
children,
|
72
|
+
orientation = 'horizontal',
|
73
|
+
onChange,
|
74
|
+
value,
|
75
|
+
variant = 'scrollable',
|
76
|
+
className,
|
77
|
+
...rest
|
78
|
+
}: Props<V>,
|
79
|
+
ref: ForwardedRef<HTMLDivElement>
|
80
|
+
) => {
|
81
|
+
const contextValue = useMemo(
|
82
|
+
() => ({
|
83
|
+
orientation,
|
84
|
+
variant,
|
85
|
+
}),
|
86
|
+
[orientation, variant]
|
87
|
+
)
|
88
|
+
|
89
|
+
const isVertical = orientation === 'vertical'
|
90
|
+
|
91
|
+
return (
|
92
|
+
<TabsContext.Provider value={contextValue}>
|
93
|
+
<MUITabs
|
94
|
+
{...rest}
|
95
|
+
slotProps={{
|
96
|
+
root: {
|
97
|
+
ref,
|
98
|
+
className: twMerge(
|
99
|
+
'relative min-h-0 flex overflow-hidden',
|
100
|
+
classesByOrientation[orientation].root,
|
101
|
+
classesByVariant[variant].root,
|
102
|
+
className
|
103
|
+
),
|
104
|
+
},
|
105
|
+
}}
|
106
|
+
onChange={
|
107
|
+
onChange as (
|
108
|
+
event: React.ChangeEvent<{}> | null,
|
109
|
+
value: TabsValueType
|
110
|
+
) => void
|
111
|
+
}
|
112
|
+
value={value}
|
113
|
+
orientation={orientation}
|
114
|
+
>
|
115
|
+
<div
|
116
|
+
className={twJoin(
|
117
|
+
classesByVariant[variant].scroller,
|
118
|
+
classesByOrientation[orientation].scroller,
|
119
|
+
'flex-auto inline-block relative whitespace-nowrap'
|
120
|
+
)}
|
121
|
+
>
|
122
|
+
<TabsList className={twJoin('flex', isVertical && 'flex-col')}>
|
123
|
+
{children}
|
124
|
+
</TabsList>
|
125
|
+
</div>
|
126
|
+
</MUITabs>
|
127
|
+
</TabsContext.Provider>
|
128
|
+
)
|
129
|
+
}
|
130
|
+
) as <V extends TabsValueType = TabsValueType>(
|
131
|
+
props: Props<V> & { ref?: ForwardedRef<HTMLDivElement> }
|
132
|
+
) => ReturnType<typeof MUITabs>
|
80
133
|
|
81
134
|
export default Tabs
|