@toptal/picasso-tabs 5.0.15-alpha-ff-7-tabs-19babbfd6.8 → 5.0.15-alpha-ff-7-tabs-2a3da7cea.16

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.
Files changed (32) hide show
  1. package/dist-package/src/Tab/Tab.d.ts +7 -10
  2. package/dist-package/src/Tab/Tab.d.ts.map +1 -1
  3. package/dist-package/src/Tab/Tab.js +32 -33
  4. package/dist-package/src/Tab/Tab.js.map +1 -1
  5. package/dist-package/src/Tab/index.d.ts +1 -4
  6. package/dist-package/src/Tab/index.d.ts.map +1 -1
  7. package/dist-package/src/Tab/index.js.map +1 -1
  8. package/dist-package/src/Tabs/Tabs.d.ts +11 -11
  9. package/dist-package/src/Tabs/Tabs.d.ts.map +1 -1
  10. package/dist-package/src/Tabs/Tabs.js +34 -17
  11. package/dist-package/src/Tabs/Tabs.js.map +1 -1
  12. package/dist-package/src/Tabs/TabsContext.d.ts +11 -0
  13. package/dist-package/src/Tabs/TabsContext.d.ts.map +1 -0
  14. package/dist-package/src/Tabs/TabsContext.js +16 -0
  15. package/dist-package/src/Tabs/TabsContext.js.map +1 -0
  16. package/dist-package/src/Tabs/index.d.ts +1 -5
  17. package/dist-package/src/Tabs/index.d.ts.map +1 -1
  18. package/dist-package/src/Tabs/index.js.map +1 -1
  19. package/dist-package/src/TabsCompound/index.d.ts +6 -2
  20. package/dist-package/src/TabsCompound/index.d.ts.map +1 -1
  21. package/package.json +12 -13
  22. package/src/Tab/Tab.tsx +103 -111
  23. package/src/Tab/__snapshots__/test.tsx.snap +29 -45
  24. package/src/Tab/index.ts +1 -6
  25. package/src/Tab/story/CustomValue.example.tsx +2 -2
  26. package/src/Tab/story/IconOrBadge.example.tsx +3 -3
  27. package/src/Tabs/Tabs.tsx +103 -69
  28. package/src/Tabs/TabsContext.tsx +27 -0
  29. package/src/Tabs/__snapshots__/test.tsx.snap +33 -49
  30. package/src/Tabs/index.ts +1 -7
  31. package/src/Tabs/story/Default.example.tsx +7 -6
  32. package/src/Tabs/test.tsx +12 -10
package/src/Tabs/Tabs.tsx CHANGED
@@ -1,36 +1,37 @@
1
- import type { ReactNode } 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'
1
+ import type { ReactNode, ChangeEvent, Ref, ReactElement } from 'react'
2
+ import React, { forwardRef, useMemo, useCallback } from 'react'
5
3
  import type { BaseProps } from '@toptal/picasso-shared'
6
4
  import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge'
7
5
 
8
- export type TabsValueType = string | number | null
6
+ import { TabsContext } from './TabsContext'
7
+ import type { TabProps } from '../Tab'
8
+ import { Tab } from '../Tab'
9
9
 
10
- export interface Props<V extends TabsValueType> extends BaseProps {
10
+ export interface TabsProps<T = number> extends BaseProps {
11
11
  /** Tabs content containing Tab components */
12
12
  children: ReactNode
13
13
 
14
14
  /** Callback fired when the value changes. */
15
- onChange?: (event: React.ChangeEvent<{}> | null, value: V) => void
15
+ onChange?: (event: ChangeEvent<{}>, value: T) => void
16
16
 
17
17
  /**
18
18
  * The value of the currently selected Tab.
19
19
  * If you don't want any selected Tab, you can set this property to null.
20
20
  */
21
- value: V
21
+ value: T
22
22
 
23
23
  /** The tabs orientation (layout flow direction). */
24
24
  orientation?: 'horizontal' | 'vertical'
25
25
 
26
26
  /** Determines additional display behavior of the tabs */
27
27
  variant?: 'scrollable' | 'fullWidth'
28
- }
29
28
 
30
- export const TabsContext = React.createContext<{
31
- orientation: 'horizontal' | 'vertical'
32
- variant: 'scrollable' | 'fullWidth'
33
- }>({ orientation: 'horizontal', variant: 'scrollable' })
29
+ /** The default value. Use when the component is not controlled. */
30
+ defaultValue?: T
31
+
32
+ /** The direction of the text. */
33
+ direction?: 'ltr' | 'rtl'
34
+ }
34
35
 
35
36
  const indicatorClasses = [
36
37
  'after:absolute',
@@ -65,66 +66,99 @@ const classesByVariant = {
65
66
  },
66
67
  }
67
68
 
68
- // eslint-disable-next-line react/display-name
69
- export const Tabs = forwardRef<HTMLDivElement, Props<TabsValueType>>(
70
- function Tabs(props, ref) {
71
- const {
72
- children,
73
- orientation = 'horizontal',
74
- onChange,
75
- value,
76
- variant = 'scrollable',
77
- className,
78
- ...rest
79
- } = props
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
- data-component-type='tabs'
96
- slotProps={{
97
- root: {
98
- ref,
99
- className: twMerge(
100
- 'relative min-h-0 flex overflow-hidden',
101
- classesByOrientation[orientation].root,
102
- classesByVariant[variant].root,
103
- className
104
- ),
105
- },
106
- }}
107
- onChange={onChange}
108
- value={value}
109
- orientation={orientation}
69
+ // eslint-disable-next-line func-style
70
+ function TabsInner<T = number>(props: TabsProps<T>, ref: Ref<HTMLDivElement>) {
71
+ const {
72
+ children,
73
+ orientation = 'horizontal',
74
+ onChange,
75
+ value: valueProp,
76
+ defaultValue,
77
+ variant = 'scrollable',
78
+ direction = 'ltr',
79
+ className,
80
+ ...rest
81
+ } = props
82
+
83
+ const [value, setValue] = React.useState<T>(defaultValue as T)
84
+ const isControlled = valueProp !== undefined
85
+ const currentValue = isControlled ? valueProp : value
86
+
87
+ const handleChange = useCallback(
88
+ (event: ChangeEvent<{}>, newValue: T) => {
89
+ if (!isControlled) {
90
+ setValue(newValue)
91
+ }
92
+ onChange?.(event, newValue)
93
+ },
94
+ [isControlled, onChange]
95
+ )
96
+
97
+ const contextValue = useMemo(
98
+ () => ({
99
+ value: currentValue,
100
+ onChange: handleChange,
101
+ orientation,
102
+ variant,
103
+ direction,
104
+ }),
105
+ [currentValue, handleChange, orientation, variant, direction]
106
+ )
107
+
108
+ const isVertical = orientation === 'vertical'
109
+
110
+ const childrenWithIndex = React.Children.map(children, (child, idx) => {
111
+ if (
112
+ React.isValidElement(child) &&
113
+ child.type === Tab &&
114
+ child.props.value === undefined
115
+ ) {
116
+ return React.cloneElement(child as React.ReactElement<TabProps<number>>, {
117
+ value: idx,
118
+ })
119
+ }
120
+
121
+ return child
122
+ })
123
+
124
+ return (
125
+ <TabsContext.Provider value={contextValue}>
126
+ <div
127
+ {...rest}
128
+ ref={ref}
129
+ data-component-type='tabs'
130
+ className={twMerge(
131
+ 'relative min-h-0 flex overflow-hidden',
132
+ classesByOrientation[orientation].root,
133
+ classesByVariant[variant].root,
134
+ className
135
+ )}
136
+ aria-orientation={orientation}
137
+ >
138
+ <div
139
+ className={twJoin(
140
+ classesByVariant[variant].scroller,
141
+ classesByOrientation[orientation].scroller,
142
+ 'flex-auto inline-block relative whitespace-nowrap'
143
+ )}
110
144
  >
111
145
  <div
112
- className={twJoin(
113
- classesByVariant[variant].scroller,
114
- classesByOrientation[orientation].scroller,
115
- 'flex-auto inline-block relative whitespace-nowrap'
116
- )}
146
+ className={twJoin('flex', isVertical && 'flex-col')}
147
+ role='tablist'
148
+ tabIndex={-1}
117
149
  >
118
- <TabsList className={twJoin('flex', isVertical && 'flex-col')}>
119
- {children}
120
- </TabsList>
150
+ {childrenWithIndex}
121
151
  </div>
122
- </MUITabs>
123
- </TabsContext.Provider>
124
- )
125
- }
126
- )
152
+ </div>
153
+ </div>
154
+ </TabsContext.Provider>
155
+ )
156
+ }
157
+
158
+ TabsInner.displayName = 'Tabs'
127
159
 
128
- Tabs.displayName = 'Tabs'
160
+ export const Tabs = forwardRef(TabsInner) as <T = number>(
161
+ props: TabsProps<T> & { ref?: Ref<HTMLDivElement> }
162
+ ) => ReactElement | null
129
163
 
130
164
  export default Tabs
@@ -0,0 +1,27 @@
1
+ import React from 'react'
2
+
3
+ export interface TabsContextValue<T> {
4
+ value: T
5
+ onChange: (event: React.ChangeEvent<{}>, value: T) => void
6
+ orientation: 'horizontal' | 'vertical'
7
+ variant: 'scrollable' | 'fullWidth'
8
+ direction?: 'ltr' | 'rtl'
9
+ }
10
+
11
+ export const TabsContext = React.createContext<TabsContextValue<any>>({
12
+ value: undefined,
13
+ onChange: () => {},
14
+ orientation: 'horizontal',
15
+ variant: 'scrollable',
16
+ direction: 'ltr',
17
+ })
18
+
19
+ export const useTabsContext = () => {
20
+ const context = React.useContext(TabsContext)
21
+
22
+ if (!context) {
23
+ throw new Error('useTabsContext must be used within a TabsProvider')
24
+ }
25
+
26
+ return context
27
+ }
@@ -6,29 +6,28 @@ exports[`Tabs renders 1`] = `
6
6
  class="Picasso-root"
7
7
  >
8
8
  <div
9
- class="MuiTabs-root Tabs-horizontal"
9
+ aria-orientation="horizontal"
10
+ class="relative min-h flex overflow-hidden overflow-x"
10
11
  data-component-type="tabs"
11
12
  >
12
13
  <div
13
14
  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"
14
15
  >
15
16
  <div
16
- class="base-TabsList base-TabsList flex"
17
+ class="flex"
17
18
  role="tablist"
18
19
  tabindex="-1"
19
20
  >
20
21
  <button
21
- aria-disabled="false"
22
22
  aria-selected="false"
23
- 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-black 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"
23
+ class="opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black 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"
24
24
  data-testid="tab-1"
25
- id=":r0:"
26
25
  role="tab"
27
26
  tabindex="0"
28
27
  type="button"
29
28
  >
30
29
  <span
31
- class="w-full inline-flex items-center flex-col justify-center"
30
+ class="w-full inline-flex flex-row items-center justify-center"
32
31
  >
33
32
  <div
34
33
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -38,17 +37,15 @@ exports[`Tabs renders 1`] = `
38
37
  </span>
39
38
  </button>
40
39
  <button
41
- aria-disabled="false"
42
40
  aria-selected="false"
43
- 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-black 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"
41
+ class="opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black 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"
44
42
  data-testid="tab-2"
45
- id=":r1:"
46
43
  role="tab"
47
44
  tabindex="0"
48
45
  type="button"
49
46
  >
50
47
  <span
51
- class="w-full inline-flex items-center flex-col justify-center"
48
+ class="w-full inline-flex flex-row items-center justify-center"
52
49
  >
53
50
  <div
54
51
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -70,29 +67,28 @@ exports[`Tabs renders in full width 1`] = `
70
67
  class="Picasso-root"
71
68
  >
72
69
  <div
73
- class="MuiTabs-root Tabs-horizontal"
70
+ aria-orientation="horizontal"
71
+ class="relative min-h flex overflow-hidden"
74
72
  data-component-type="tabs"
75
73
  >
76
74
  <div
77
75
  class="w-full overflow-hidden 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"
78
76
  >
79
77
  <div
80
- class="base-TabsList base-TabsList flex"
78
+ class="flex"
81
79
  role="tablist"
82
80
  tabindex="-1"
83
81
  >
84
82
  <button
85
- aria-disabled="false"
86
83
  aria-selected="false"
87
- 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-black shrink flex-grow basis-0 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"
84
+ class="opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black shrink flex-grow basis-0 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"
88
85
  data-testid="tab-1"
89
- id=":re:"
90
86
  role="tab"
91
87
  tabindex="0"
92
88
  type="button"
93
89
  >
94
90
  <span
95
- class="w-full inline-flex items-center flex-col justify-center"
91
+ class="w-full inline-flex flex-row items-center justify-center"
96
92
  >
97
93
  <div
98
94
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -102,17 +98,15 @@ exports[`Tabs renders in full width 1`] = `
102
98
  </span>
103
99
  </button>
104
100
  <button
105
- aria-disabled="false"
106
101
  aria-selected="false"
107
- 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-black shrink flex-grow basis-0 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"
102
+ class="opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black shrink flex-grow basis-0 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"
108
103
  data-testid="tab-2"
109
- id=":rf:"
110
104
  role="tab"
111
105
  tabindex="0"
112
106
  type="button"
113
107
  >
114
108
  <span
115
- class="w-full inline-flex items-center flex-col justify-center"
109
+ class="w-full inline-flex flex-row items-center justify-center"
116
110
  >
117
111
  <div
118
112
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -134,24 +128,22 @@ exports[`Tabs renders in vertical orientation 1`] = `
134
128
  class="Picasso-root"
135
129
  >
136
130
  <div
137
- class="MuiTabs-root Tabs-vertical MuiTabs-vertical"
131
+ aria-orientation="vertical"
132
+ class="relative min-h flex overflow-hidden w-[200px] m-0 flex-col overflow-x"
138
133
  data-component-type="tabs"
139
134
  >
140
135
  <div
141
136
  class="pl-2 flex-auto inline-block relative whitespace-nowrap"
142
137
  >
143
138
  <div
144
- aria-orientation="vertical"
145
- class="base-TabsList base-TabsList flex flex-col"
139
+ class="flex flex-col"
146
140
  role="tablist"
147
141
  tabindex="-1"
148
142
  >
149
143
  <button
150
- aria-disabled="false"
151
144
  aria-selected="false"
152
- class="base-Tab opacity-100 first:mt-4 last:mb-4 my-1 mx-0 py-2 px-4 text-left rounded-l rounded-r transition-all w-full overflow-hidden bg-gray hover:bg-gray text-graphite hover:text-black 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"
145
+ class="opacity-100 first:mt-4 last:mb-4 my-1 mx-0 py-2 px-4 text-left rounded-l rounded-r transition-all w-full overflow-hidden bg-gray hover:bg-gray text-graphite hover:text-black 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"
153
146
  data-testid="tab-1"
154
- id=":r2:"
155
147
  role="tab"
156
148
  tabindex="0"
157
149
  type="button"
@@ -167,11 +159,9 @@ exports[`Tabs renders in vertical orientation 1`] = `
167
159
  </span>
168
160
  </button>
169
161
  <button
170
- aria-disabled="false"
171
162
  aria-selected="false"
172
- class="base-Tab opacity-100 first:mt-4 last:mb-4 my-1 mx-0 py-2 px-4 text-left rounded-l rounded-r transition-all w-full overflow-hidden bg-gray hover:bg-gray text-graphite hover:text-black 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"
163
+ class="opacity-100 first:mt-4 last:mb-4 my-1 mx-0 py-2 px-4 text-left rounded-l rounded-r transition-all w-full overflow-hidden bg-gray hover:bg-gray text-graphite hover:text-black 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"
173
164
  data-testid="tab-2"
174
- id=":r3:"
175
165
  role="tab"
176
166
  tabindex="0"
177
167
  type="button"
@@ -199,29 +189,28 @@ exports[`Tabs renders with a pre-selected option 1`] = `
199
189
  class="Picasso-root"
200
190
  >
201
191
  <div
202
- class="MuiTabs-root Tabs-horizontal"
192
+ aria-orientation="horizontal"
193
+ class="relative min-h flex overflow-hidden overflow-x"
203
194
  data-component-type="tabs"
204
195
  >
205
196
  <div
206
197
  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"
207
198
  >
208
199
  <div
209
- class="base-TabsList base-TabsList flex"
200
+ class="flex"
210
201
  role="tablist"
211
202
  tabindex="-1"
212
203
  >
213
204
  <button
214
- aria-disabled="false"
215
205
  aria-selected="false"
216
- 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-black 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"
206
+ class="opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black 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"
217
207
  data-testid="tab-1"
218
- id=":r4:"
219
208
  role="tab"
220
209
  tabindex="0"
221
210
  type="button"
222
211
  >
223
212
  <span
224
- class="w-full inline-flex items-center flex-col justify-center"
213
+ class="w-full inline-flex flex-row items-center justify-center"
225
214
  >
226
215
  <div
227
216
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -231,17 +220,15 @@ exports[`Tabs renders with a pre-selected option 1`] = `
231
220
  </span>
232
221
  </button>
233
222
  <button
234
- aria-disabled="false"
235
223
  aria-selected="true"
236
- class="base-Tab base- opacity-100 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-black shadow-blue shadow-[inset_0_-2px_0] 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"
224
+ class="opacity-100 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black shadow-blue shadow-[inset_0_-2px_0] 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"
237
225
  data-testid="tab-2"
238
- id=":r5:"
239
226
  role="tab"
240
227
  tabindex="0"
241
228
  type="button"
242
229
  >
243
230
  <span
244
- class="w-full inline-flex items-center flex-col justify-center"
231
+ class="w-full inline-flex flex-row items-center justify-center"
245
232
  >
246
233
  <div
247
234
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -270,29 +257,28 @@ exports[`Tabs renders with a pre-selected option using custom value 1`] = `
270
257
  class="Picasso-root"
271
258
  >
272
259
  <div
273
- class="MuiTabs-root Tabs-horizontal"
260
+ aria-orientation="horizontal"
261
+ class="relative min-h flex overflow-hidden overflow-x"
274
262
  data-component-type="tabs"
275
263
  >
276
264
  <div
277
265
  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"
278
266
  >
279
267
  <div
280
- class="base-TabsList base-TabsList flex"
268
+ class="flex"
281
269
  role="tablist"
282
270
  tabindex="-1"
283
271
  >
284
272
  <button
285
- aria-disabled="false"
286
273
  aria-selected="true"
287
- class="base-Tab base- opacity-100 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-black shadow-blue shadow-[inset_0_-2px_0] 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"
274
+ class="opacity-100 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black shadow-blue shadow-[inset_0_-2px_0] 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"
288
275
  data-testid="tab-1"
289
- id=":r6:"
290
276
  role="tab"
291
277
  tabindex="0"
292
278
  type="button"
293
279
  >
294
280
  <span
295
- class="w-full inline-flex items-center flex-col justify-center"
281
+ class="w-full inline-flex flex-row items-center justify-center"
296
282
  >
297
283
  <div
298
284
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -302,17 +288,15 @@ exports[`Tabs renders with a pre-selected option using custom value 1`] = `
302
288
  </span>
303
289
  </button>
304
290
  <button
305
- aria-disabled="false"
306
291
  aria-selected="false"
307
- 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-black 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"
292
+ class="opacity-70 m-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0 text-center bg-transparent transition-shadow z-10 rounded-none text-black 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"
308
293
  data-testid="tab-2"
309
- id=":r7:"
310
294
  role="tab"
311
295
  tabindex="0"
312
296
  type="button"
313
297
  >
314
298
  <span
315
- class="w-full inline-flex items-center flex-col justify-center"
299
+ class="w-full inline-flex flex-row items-center justify-center"
316
300
  >
317
301
  <div
318
302
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
package/src/Tabs/index.ts CHANGED
@@ -1,7 +1 @@
1
- import type { OmitInternalProps } from '@toptal/picasso-shared'
2
-
3
- import type { Props, TabsValueType } from './Tabs'
4
-
5
- export { default as Tabs } from './Tabs'
6
- export type TabsProps = OmitInternalProps<Props<TabsValueType>>
7
- export type { TabsValueType } from './Tabs'
1
+ export { default as Tabs, type TabsProps } from './Tabs'
@@ -1,20 +1,21 @@
1
1
  import React from 'react'
2
- import { Container, Tabs } from '@toptal/picasso'
2
+ import { Container } from '@toptal/picasso'
3
+ import { Tabs, Tab } from '@toptal/picasso-tabs'
3
4
  import { SPACING_4 } from '@toptal/picasso-utils'
4
5
 
5
6
  const Example = () => {
6
- const [value, setValue] = React.useState(0)
7
+ const [value, setValue] = React.useState<number>(0)
7
8
 
8
- const handleChange = (_: React.ChangeEvent<{}> | null, newValue: number) => {
9
+ const handleChange = (_: React.ChangeEvent<{}>, newValue: number) => {
9
10
  setValue(newValue)
10
11
  }
11
12
 
12
13
  return (
13
14
  <div>
14
15
  <Tabs value={value} onChange={handleChange}>
15
- <Tabs.Tab label='Label' />
16
- <Tabs.Tab label='Label' />
17
- <Tabs.Tab label='Label' />
16
+ <Tab label='Label' />
17
+ <Tab label='Label' />
18
+ <Tab label='Label' />
18
19
  </Tabs>
19
20
 
20
21
  {value === 0 && (
package/src/Tabs/test.tsx CHANGED
@@ -4,14 +4,15 @@ import { render, fireEvent } from '@testing-library/react'
4
4
  import { TestingPicasso } from '@toptal/picasso-test-utils'
5
5
 
6
6
  import type { TabProps } from '../Tab'
7
- import type { Props, TabsValueType } from './Tabs'
7
+ import type { TabsProps } from './Tabs'
8
8
  import { TabsCompound as Tabs } from '../TabsCompound'
9
9
 
10
- const renderTabContent = (
11
- tab: TabProps,
10
+ // eslint-disable-next-line func-style
11
+ function renderTabContent<T = number>(
12
+ tab: TabProps<T>,
12
13
  index: number,
13
- value: TabsValueType
14
- ) => {
14
+ value: T
15
+ ) {
15
16
  const isTabActive = index + 1 === value || tab.value === value
16
17
  const testId = `tab-${index + 1}-content`
17
18
 
@@ -26,11 +27,12 @@ const renderTabContent = (
26
27
  return null
27
28
  }
28
29
 
29
- const renderTabs = (
30
- tabs: TabProps[],
31
- { value, onChange, variant }: Omit<Props<TabsValueType>, 'children'>,
30
+ // eslint-disable-next-line func-style
31
+ function renderTabs<T = number>(
32
+ tabs: TabProps<T>[],
33
+ { value, onChange, variant }: Omit<TabsProps<T>, 'children'>,
32
34
  orientation: 'horizontal' | 'vertical' = 'horizontal'
33
- ) => {
35
+ ) {
34
36
  return render(
35
37
  <TestingPicasso>
36
38
  <Tabs
@@ -50,7 +52,7 @@ const renderTabs = (
50
52
  ))}
51
53
  </Tabs>
52
54
 
53
- {tabs.map((tab, index) => renderTabContent(tab, index, value))}
55
+ {tabs.map((tab, index) => renderTabContent<T>(tab, index, value))}
54
56
  </TestingPicasso>
55
57
  )
56
58
  }