@toptal/picasso-tabs 5.0.15-alpha-ff-7-tabs-19babbfd6.8 → 5.0.15-alpha-ff-7-tabs-17eb872bb.13

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.
@@ -1,15 +1,15 @@
1
1
  import type { ReactNode, HTMLAttributes, ReactElement } from 'react';
2
2
  import React from 'react';
3
- import type { TabProps } from '@mui/base/Tab';
4
3
  import type { BaseProps, TextLabelProps } from '@toptal/picasso-shared';
4
+ import { type TabsValueType } from '../Tabs/TabsContext';
5
5
  export interface Props extends BaseProps, TextLabelProps, Omit<HTMLAttributes<HTMLButtonElement>, 'onChange'> {
6
6
  /**
7
7
  * If true, the tab will be disabled
8
8
  * @default false
9
9
  */
10
10
  disabled?: boolean;
11
- /** You can provide your own value. Otherwise, we fallback to the child position index */
12
- value?: TabProps['value'];
11
+ /** The value of the tab */
12
+ value?: TabsValueType;
13
13
  /** The label element */
14
14
  label?: ReactNode;
15
15
  /** The Icon element */
@@ -18,9 +18,6 @@ export interface Props extends BaseProps, TextLabelProps, Omit<HTMLAttributes<HT
18
18
  avatar?: string | null;
19
19
  /** Description */
20
20
  description?: string;
21
- selected?: boolean;
22
- onChange?: TabProps['onChange'];
23
- onClick?: TabProps['onClick'];
24
21
  }
25
22
  export declare const Tab: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLButtonElement>>;
26
23
  export default Tab;
@@ -1 +1 @@
1
- {"version":3,"file":"Tab.d.ts","sourceRoot":"","sources":["../../../src/Tab/Tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,KAAiC,MAAM,OAAO,CAAA;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AASvE,MAAM,WAAW,KACf,SAAQ,SAAS,EACf,cAAc,EACd,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB,yFAAyF;IACzF,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEzB,wBAAwB;IACxB,KAAK,CAAC,EAAE,SAAS,CAAA;IAEjB,uBAAuB;IACvB,IAAI,CAAC,EAAE,YAAY,CAAA;IAEnB,gBAAgB;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAEtB,kBAAkB;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IAIpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;CAC9B;AAuDD,eAAO,MAAM,GAAG,iFA4Ed,CAAA;AAyDF,eAAe,GAAG,CAAA"}
1
+ {"version":3,"file":"Tab.d.ts","sourceRoot":"","sources":["../../../src/Tab/Tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,KAAqB,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAKvE,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAIxE,MAAM,WAAW,KACf,SAAQ,SAAS,EACf,cAAc,EACd,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,aAAa,CAAA;IAErB,wBAAwB;IACxB,KAAK,CAAC,EAAE,SAAS,CAAA;IAEjB,uBAAuB;IACvB,IAAI,CAAC,EAAE,YAAY,CAAA;IAEnB,gBAAgB;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAEtB,kBAAkB;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CAOrB;AAsDD,eAAO,MAAM,GAAG,iFA6Ed,CAAA;AAmDF,eAAe,GAAG,CAAA"}
@@ -9,12 +9,11 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import React, { forwardRef, useContext } from 'react';
13
- import { Tab as MUITab } from '@mui/base/Tab';
12
+ import React, { forwardRef } from 'react';
14
13
  import { useTitleCase } from '@toptal/picasso-shared';
15
14
  import { UserBadge } from '@toptal/picasso-user-badge';
16
15
  import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge';
17
- import { TabsContext } from '../Tabs/Tabs';
16
+ import { useTabsContext } from '../Tabs/TabsContext';
18
17
  import { TabLabel } from '../TabLabel';
19
18
  import { TabDescription } from '../TabDescription';
20
19
  const getOpacityClass = (selected, disabled, orientation) => {
@@ -27,12 +26,12 @@ const getOpacityClass = (selected, disabled, orientation) => {
27
26
  return 'opacity-70';
28
27
  };
29
28
  const wrapperClassesByOrientation = {
30
- horizontal: 'inline-flex items-center flex-col justify-center',
29
+ horizontal: 'inline-flex flex-row items-center justify-center',
31
30
  vertical: 'block',
32
31
  };
33
32
  const rootClassesByOrientation = (selected) => ({
34
33
  horizontal: [
35
- 'm-0 [&:not(:last-child)]:mr-8 pt-[0.5625rem] pb-[0.4375rem] px-0',
34
+ 'm-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0',
36
35
  'text-center bg-transparent transition-shadow z-10 rounded-none',
37
36
  'text-black',
38
37
  selected && 'shadow-blue-500 shadow-[inset_0_-2px_0]',
@@ -61,10 +60,17 @@ const classesByVariant = {
61
60
  fullWidth: 'shrink flex-grow basis-0',
62
61
  };
63
62
  export const Tab = forwardRef(function Tab(props, ref) {
64
- const { disabled, value, label, icon, onChange, onClick, titleCase: propsTitleCase, description, avatar, className } = props, rest = __rest(props, ["disabled", "value", "label", "icon", "onChange", "onClick", "titleCase", "description", "avatar", "className"]);
63
+ const { disabled, value, label, icon, titleCase: propsTitleCase, description, avatar, className, onClick } = props, rest = __rest(props, ["disabled", "value", "label", "icon", "titleCase", "description", "avatar", "className", "onClick"]);
65
64
  const titleCase = useTitleCase(propsTitleCase);
66
- const { orientation, variant } = useContext(TabsContext);
65
+ const { value: selectedValue, onChange, orientation, variant, } = useTabsContext();
67
66
  const isHorizontal = orientation === 'horizontal';
67
+ const selected = value === selectedValue;
68
+ const handleClick = (event) => {
69
+ if (!disabled && onChange) {
70
+ onChange(event, value);
71
+ }
72
+ onClick === null || onClick === void 0 ? void 0 : onClick(event);
73
+ };
68
74
  const renderLabel = getLabelComponent({
69
75
  avatar,
70
76
  description,
@@ -73,20 +79,11 @@ export const Tab = forwardRef(function Tab(props, ref) {
73
79
  orientation,
74
80
  titleCase,
75
81
  });
76
- return (React.createElement(MUITab, Object.assign({ className: '' }, rest, { ref: ref, tabIndex: 0, disabled: disabled, value: value, onChange: onChange, onClick: onClick, slotProps: {
77
- root: ownerState => {
78
- return {
79
- className: twMerge(getOpacityClass(ownerState.selected, ownerState.disabled, orientation), rootClassesByOrientation(ownerState.selected)[orientation], classesByVariant[variant], ownerState.disabled
80
- ? 'cursor-default text-gray-500'
81
- : 'cursor-pointer', ownerState.disabled && 'pointer-events-none', icon && isHorizontal && 'min-h-0 pt-[0.5625rem] pr-6', 'min-w-0 sm:min-w-[160px] md:min-w-[auto]', 'border-0 cursor-pointer inline-flex outline-none', 'items-center select-none align-middle appearance-none', 'justify-center no-underline [-webkit-tap-highlight-color:transparent]', 'normal-case whitespace-normal leading-4', 'relative ', className),
82
- };
83
- },
84
- } }),
82
+ return (React.createElement("button", Object.assign({ className: twMerge(getOpacityClass(selected, !!disabled, orientation), rootClassesByOrientation(selected)[orientation], classesByVariant[variant], disabled ? 'cursor-default text-gray-500' : 'cursor-pointer', disabled && 'pointer-events-none', icon && isHorizontal && 'min-h-0 pt-0 pr-6', 'min-w-0 sm:min-w-[160px] md:min-w-[auto]', 'border-0 cursor-pointer inline-flex outline-none', 'items-center select-none align-middle appearance-none', 'justify-center no-underline [-webkit-tap-highlight-color:transparent]', 'normal-case whitespace-normal leading-4', 'relative ', className), ref: ref, tabIndex: disabled ? -1 : 0, disabled: disabled, onClick: handleClick, role: 'tab', "aria-selected": selected, "aria-disabled": disabled, type: 'button' }, rest),
85
83
  React.createElement("span", { className: twJoin('w-full', wrapperClassesByOrientation[orientation]) },
86
84
  renderLabel,
87
- icon && React.createElement("span", { className: 'absolute right-0 mb-0 h-4' }, icon))));
85
+ icon && React.createElement("span", { className: 'absolute right-0 mb-0' }, icon))));
88
86
  });
89
- Tab.defaultProps = {};
90
87
  Tab.displayName = 'Tab';
91
88
  const getLabelComponent = ({ avatar, description, disabled, label, orientation, titleCase, }) => {
92
89
  if (!label) {
@@ -1 +1 @@
1
- {"version":3,"file":"Tab.js","sourceRoot":"","sources":["../../../src/Tab/Tab.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,EAAE,GAAG,IAAI,MAAM,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAkClD,MAAM,eAAe,GAAG,CACtB,QAAiB,EACjB,QAAiB,EACjB,WAAsC,EACtC,EAAE;IACF,IAAI,QAAQ,EAAE;QACZ,OAAO,YAAY,CAAA;KACpB;IAED,IAAI,QAAQ,IAAI,WAAW,KAAK,UAAU,EAAE;QAC1C,OAAO,cAAc,CAAA;KACtB;IAED,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,2BAA2B,GAAG;IAClC,UAAU,EAAE,kDAAkD;IAC9D,QAAQ,EAAE,OAAO;CAClB,CAAA;AAED,MAAM,wBAAwB,GAAG,CAAC,QAAiB,EAAE,EAAE,CAAC,CAAC;IACvD,UAAU,EAAE;QACV,kEAAkE;QAClE,gEAAgE;QAChE,YAAY;QACZ,QAAQ,IAAI,yCAAyC;KACtD;IACD,QAAQ,EAAE;QACR,2CAA2C;QAC3C,sDAAsD;QACtD,wBAAwB;QACxB,QAAQ,IAAI,UAAU;QACtB,QAAQ,IAAI;YACV,iBAAiB;YACjB,qBAAqB;YACrB,iBAAiB;YACjB,eAAe;YACf,cAAc;YACd,gBAAgB;YAChB,oBAAoB;SACrB;QACD,QAAQ;YACN,CAAC,CAAC,uBAAuB;YACzB,CAAC,CAAC,kEAAkE;KACvE;CACF,CAAC,CAAA;AAEF,MAAM,gBAAgB,GAAG;IACvB,UAAU,EAAE,wBAAwB;IACpC,SAAS,EAAE,0BAA0B;CACtC,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,UAAU,CAA2B,SAAS,GAAG,CAClE,KAAK,EACL,GAAG;IAEH,MAAM,EACJ,QAAQ,EACR,KAAK,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,SAAS,EAAE,cAAc,EACzB,WAAW,EACX,MAAM,EACN,SAAS,KAEP,KAAK,EADJ,IAAI,UACL,KAAK,EAZH,gHAYL,CAAQ,CAAA;IACT,MAAM,SAAS,GAAG,YAAY,CAAC,cAAc,CAAC,CAAA;IAC9C,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACxD,MAAM,YAAY,GAAG,WAAW,KAAK,YAAY,CAAA;IAEjD,MAAM,WAAW,GAAG,iBAAiB,CAAC;QACpC,MAAM;QACN,WAAW;QACX,QAAQ;QACR,KAAK;QACL,WAAW;QACX,SAAS;KACV,CAAC,CAAA;IAEF,OAAO,CACL,oBAAC,MAAM,kBACL,SAAS,EAAC,EAAE,IACR,IAAI,IACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE;YACT,IAAI,EAAE,UAAU,CAAC,EAAE;gBACjB,OAAO;oBACL,SAAS,EAAE,OAAO,CAChB,eAAe,CACb,UAAU,CAAC,QAAQ,EACnB,UAAU,CAAC,QAAQ,EACnB,WAAW,CACZ,EACD,wBAAwB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAC1D,gBAAgB,CAAC,OAAO,CAAC,EACzB,UAAU,CAAC,QAAQ;wBACjB,CAAC,CAAC,8BAA8B;wBAChC,CAAC,CAAC,gBAAgB,EACpB,UAAU,CAAC,QAAQ,IAAI,qBAAqB,EAC5C,IAAI,IAAI,YAAY,IAAI,6BAA6B,EACrD,0CAA0C,EAC1C,kDAAkD,EAClD,uDAAuD,EACvD,uEAAuE,EACvE,yCAAyC,EACzC,WAAW,EACX,SAAS,CACV;iBACF,CAAA;YACH,CAAC;SACF;QAED,8BACE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,2BAA2B,CAAC,WAAW,CAAC,CAAC;YAEpE,WAAW;YACX,IAAI,IAAI,8BAAM,SAAS,EAAC,2BAA2B,IAAE,IAAI,CAAQ,CAC7D,CACA,CACV,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,GAAG,CAAC,YAAY,GAAG,EAAE,CAAA;AAErB,GAAG,CAAC,WAAW,GAAG,KAAK,CAAA;AAUvB,MAAM,iBAAiB,GAAG,CAAC,EACzB,MAAM,EACN,WAAW,EACX,QAAQ,EACR,KAAK,EACL,WAAW,EACX,SAAS,GACc,EAAmB,EAAE;IAC5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAA;KACZ;IAED,MAAM,YAAY,GAAG,WAAW,KAAK,YAAY,CAAA;IACjD,MAAM,aAAa,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAA;IAE/C,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,CAClB,oBAAC,QAAQ,IAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,GAAI,CAC3E,CAAA;IAED,IAAI,YAAY,IAAI,aAAa,EAAE;QACjC,OAAO,oBAAC,KAAK,OAAG,CAAA;KACjB;IAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,CACL;YACE,oBAAC,KAAK,OAAG;YACR,WAAW,IAAI,CACd,oBAAC,cAAc,IAAC,QAAQ,EAAE,QAAQ,IAAG,WAAW,CAAkB,CACnE,CACA,CACJ,CAAA;KACF;IAED,OAAO,CACL,oBAAC,SAAS,IAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,IACtD,WAAW,IAAI,CACd,oBAAC,cAAc,IAAC,QAAQ,EAAE,QAAQ,IAAG,WAAW,CAAkB,CACnE,CACS,CACb,CAAA;AACH,CAAC,CAAA;AAED,eAAe,GAAG,CAAA"}
1
+ {"version":3,"file":"Tab.js","sourceRoot":"","sources":["../../../src/Tab/Tab.tsx"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
- import type { ReactNode } from 'react';
1
+ import type { ReactNode, ChangeEvent } from 'react';
2
2
  import React from 'react';
3
3
  import type { BaseProps } from '@toptal/picasso-shared';
4
- export declare type TabsValueType = string | number | null;
4
+ import { type TabsValueType } from './TabsContext';
5
5
  export interface Props<V extends TabsValueType> extends BaseProps {
6
6
  /** Tabs content containing Tab components */
7
7
  children: ReactNode;
8
8
  /** Callback fired when the value changes. */
9
- onChange?: (event: React.ChangeEvent<{}> | null, value: V) => void;
9
+ onChange?: (event: ChangeEvent<{}>, value: V) => void;
10
10
  /**
11
11
  * The value of the currently selected Tab.
12
12
  * If you don't want any selected Tab, you can set this property to null.
@@ -16,11 +16,11 @@ export interface Props<V extends TabsValueType> extends BaseProps {
16
16
  orientation?: 'horizontal' | 'vertical';
17
17
  /** Determines additional display behavior of the tabs */
18
18
  variant?: 'scrollable' | 'fullWidth';
19
+ /** The default value. Use when the component is not controlled. */
20
+ defaultValue?: V;
21
+ /** The direction of the text. */
22
+ direction?: 'ltr' | 'rtl';
19
23
  }
20
- export declare const TabsContext: React.Context<{
21
- orientation: 'horizontal' | 'vertical';
22
- variant: 'scrollable' | 'fullWidth';
23
- }>;
24
24
  export declare const Tabs: React.ForwardRefExoticComponent<Props<TabsValueType> & React.RefAttributes<HTMLDivElement>>;
25
25
  export default Tabs;
26
26
  //# sourceMappingURL=Tabs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAA8B,MAAM,OAAO,CAAA;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAGvD,oBAAY,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAElD,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,aAAa,CAAE,SAAQ,SAAS;IAC/D,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,CAAA;IAEnB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;IAElE;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAA;IAER,oDAAoD;IACpD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IAEvC,yDAAyD;IACzD,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAAA;CACrC;AAED,eAAO,MAAM,WAAW;iBACT,YAAY,GAAG,UAAU;aAC7B,YAAY,GAAG,WAAW;EACmB,CAAA;AAoCxD,eAAO,MAAM,IAAI,6FAyDhB,CAAA;AAID,eAAe,IAAI,CAAA"}
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,KAA2C,MAAM,OAAO,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAGvD,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAE/D,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,aAAa,CAAE,SAAQ,SAAS;IAC/D,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,CAAA;IAEnB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;IAErD;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAA;IAER,oDAAoD;IACpD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IAEvC,yDAAyD;IACzD,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAAA;IAEpC,mEAAmE;IACnE,YAAY,CAAC,EAAE,CAAC,CAAA;IAEhB,iCAAiC;IACjC,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;CAC1B;AAmCD,eAAO,MAAM,IAAI,6FA2FhB,CAAA;AAID,eAAe,IAAI,CAAA"}
@@ -9,11 +9,9 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import React, { forwardRef, useMemo } from 'react';
13
- import { Tabs as MUITabs } from '@mui/base/Tabs';
14
- import { TabsList } from '@mui/base/TabsList';
12
+ import React, { forwardRef, useMemo, useCallback } from 'react';
15
13
  import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge';
16
- export const TabsContext = React.createContext({ orientation: 'horizontal', variant: 'scrollable' });
14
+ import { TabsContext } from './TabsContext';
17
15
  const indicatorClasses = [
18
16
  'after:absolute',
19
17
  'after:content-[""]',
@@ -44,23 +42,40 @@ const classesByVariant = {
44
42
  scroller: 'w-full overflow-hidden',
45
43
  },
46
44
  };
47
- // eslint-disable-next-line react/display-name
48
45
  export const Tabs = forwardRef(function Tabs(props, ref) {
49
- const { children, orientation = 'horizontal', onChange, value, variant = 'scrollable', className } = props, rest = __rest(props, ["children", "orientation", "onChange", "value", "variant", "className"]);
46
+ const { children, orientation = 'horizontal', onChange, value: valueProp, defaultValue, variant = 'scrollable', direction = 'ltr', className } = props, rest = __rest(props, ["children", "orientation", "onChange", "value", "defaultValue", "variant", "direction", "className"]);
47
+ const [value, setValue] = React.useState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : null);
48
+ const isControlled = valueProp !== undefined;
49
+ const currentValue = isControlled ? valueProp : value;
50
+ const handleChange = useCallback((event, newValue) => {
51
+ if (!isControlled) {
52
+ setValue(newValue);
53
+ }
54
+ onChange === null || onChange === void 0 ? void 0 : onChange(event, newValue);
55
+ }, [isControlled, onChange]);
50
56
  const contextValue = useMemo(() => ({
57
+ value: currentValue,
58
+ onChange: handleChange,
51
59
  orientation,
52
60
  variant,
53
- }), [orientation, variant]);
61
+ direction,
62
+ }), [currentValue, handleChange, orientation, variant, direction]);
54
63
  const isVertical = orientation === 'vertical';
64
+ const childrenWithIndex = React.Children.map(children, (child, idx) => {
65
+ if (React.isValidElement(child) &&
66
+ // @ts-expect-error: type check for Picasso Tab
67
+ (child.type.displayName === 'Tab' || child.type.name === 'Tab') &&
68
+ child.props.value === undefined) {
69
+ return React.cloneElement(child, {
70
+ value: idx,
71
+ });
72
+ }
73
+ return child;
74
+ });
55
75
  return (React.createElement(TabsContext.Provider, { value: contextValue },
56
- React.createElement(MUITabs, Object.assign({}, rest, { "data-component-type": 'tabs', slotProps: {
57
- root: {
58
- ref,
59
- className: twMerge('relative min-h-0 flex overflow-hidden', classesByOrientation[orientation].root, classesByVariant[variant].root, className),
60
- },
61
- }, onChange: onChange, value: value, orientation: orientation }),
76
+ React.createElement("div", Object.assign({}, rest, { ref: ref, "data-component-type": 'tabs', className: twMerge('relative min-h-0 flex overflow-hidden', classesByOrientation[orientation].root, classesByVariant[variant].root, className), "aria-orientation": orientation }),
62
77
  React.createElement("div", { className: twJoin(classesByVariant[variant].scroller, classesByOrientation[orientation].scroller, 'flex-auto inline-block relative whitespace-nowrap') },
63
- React.createElement(TabsList, { className: twJoin('flex', isVertical && 'flex-col') }, children)))));
78
+ React.createElement("div", { className: twJoin('flex', isVertical && 'flex-col'), role: 'tablist', tabIndex: -1 }, childrenWithIndex)))));
64
79
  });
65
80
  Tabs.displayName = 'Tabs';
66
81
  export default Tabs;
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../../src/Tabs/Tabs.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAwBhE,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAG3C,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;AAExD,MAAM,gBAAgB,GAAG;IACvB,gBAAgB;IAChB,oBAAoB;IACpB,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,eAAe;IACf,mBAAmB;IACnB,WAAW;CACZ,CAAA;AAED,MAAM,oBAAoB,GAAG;IAC3B,QAAQ,EAAE;QACR,IAAI,EAAE,wBAAwB;QAC9B,QAAQ,EAAE,MAAM;KACjB;IACD,UAAU,EAAE;QACV,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,gBAAgB;KAC3B;CACF,CAAA;AAED,MAAM,gBAAgB,GAAG;IACvB,UAAU,EAAE;QACV,IAAI,EAAE,iBAAiB;QACvB,QAAQ,EAAE,EAAE;KACb;IACD,SAAS,EAAE;QACT,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,wBAAwB;KACnC;CACF,CAAA;AAED,8CAA8C;AAC9C,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAC5B,SAAS,IAAI,CAAC,KAAK,EAAE,GAAG;IACtB,MAAM,EACJ,QAAQ,EACR,WAAW,GAAG,YAAY,EAC1B,QAAQ,EACR,KAAK,EACL,OAAO,GAAG,YAAY,EACtB,SAAS,KAEP,KAAK,EADJ,IAAI,UACL,KAAK,EARH,wEAQL,CAAQ,CAAA;IAET,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CAAC,CAAC;QACL,WAAW;QACX,OAAO;KACR,CAAC,EACF,CAAC,WAAW,EAAE,OAAO,CAAC,CACvB,CAAA;IAED,MAAM,UAAU,GAAG,WAAW,KAAK,UAAU,CAAA;IAE7C,OAAO,CACL,oBAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY;QACvC,oBAAC,OAAO,oBACF,IAAI,2BACY,MAAM,EAC1B,SAAS,EAAE;gBACT,IAAI,EAAE;oBACJ,GAAG;oBACH,SAAS,EAAE,OAAO,CAChB,uCAAuC,EACvC,oBAAoB,CAAC,WAAW,CAAC,CAAC,IAAI,EACtC,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,EAC9B,SAAS,CACV;iBACF;aACF,EACD,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW;YAExB,6BACE,SAAS,EAAE,MAAM,CACf,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAClC,oBAAoB,CAAC,WAAW,CAAC,CAAC,QAAQ,EAC1C,mDAAmD,CACpD;gBAED,oBAAC,QAAQ,IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,UAAU,CAAC,IAC1D,QAAQ,CACA,CACP,CACE,CACW,CACxB,CAAA;AACH,CAAC,CACF,CAAA;AAED,IAAI,CAAC,WAAW,GAAG,MAAM,CAAA;AAEzB,eAAe,IAAI,CAAA"}
1
+ {"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../../src/Tabs/Tabs.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export declare type TabsValueType = string | number | null;
3
+ export interface TabsContextValue {
4
+ value: TabsValueType;
5
+ onChange: (event: React.ChangeEvent<{}>, value: TabsValueType) => void;
6
+ orientation: 'horizontal' | 'vertical';
7
+ variant: 'scrollable' | 'fullWidth';
8
+ }
9
+ export declare const TabsContext: React.Context<TabsContextValue>;
10
+ export declare const useTabsContext: () => TabsContextValue;
11
+ //# sourceMappingURL=TabsContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabsContext.d.ts","sourceRoot":"","sources":["../../../src/Tabs/TabsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,oBAAY,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAElD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,aAAa,CAAA;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACtE,WAAW,EAAE,YAAY,GAAG,UAAU,CAAA;IACtC,OAAO,EAAE,YAAY,GAAG,WAAW,CAAA;CACpC;AAED,eAAO,MAAM,WAAW,iCAKtB,CAAA;AAEF,eAAO,MAAM,cAAc,wBAQ1B,CAAA"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export const TabsContext = React.createContext({
3
+ value: null,
4
+ onChange: () => { },
5
+ orientation: 'horizontal',
6
+ variant: 'scrollable',
7
+ });
8
+ export const useTabsContext = () => {
9
+ const context = React.useContext(TabsContext);
10
+ if (!context) {
11
+ throw new Error('useTabsContext must be used within a TabsProvider');
12
+ }
13
+ return context;
14
+ };
15
+ //# sourceMappingURL=TabsContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabsContext.js","sourceRoot":"","sources":["../../../src/Tabs/TabsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAWzB,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAmB;IAC/D,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;IAClB,WAAW,EAAE,YAAY;IACzB,OAAO,EAAE,YAAY;CACtB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAE7C,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;KACrE;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import type { OmitInternalProps } from '@toptal/picasso-shared';
2
- import type { Props, TabsValueType } from './Tabs';
2
+ import type { Props } from './Tabs';
3
+ import type { TabsValueType } from './TabsContext';
3
4
  export { default as Tabs } from './Tabs';
4
5
  export declare type TabsProps = OmitInternalProps<Props<TabsValueType>>;
5
- export type { TabsValueType } from './Tabs';
6
+ export type { TabsValueType } from './TabsContext';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAElD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA;AACxC,oBAAY,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAA;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA;AACxC,oBAAY,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAA;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Tabs/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Tabs/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toptal/picasso-tabs",
3
- "version": "5.0.15-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
3
+ "version": "5.0.15-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
4
4
  "description": "Toptal UI components library - Tabs",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -22,14 +22,13 @@
22
22
  },
23
23
  "homepage": "https://github.com/toptal/picasso/tree/master/packages/picasso#readme",
24
24
  "dependencies": {
25
- "@mui/base": "5.0.0-beta.58",
26
- "@toptal/picasso-container": "3.1.3-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
27
- "@toptal/picasso-icons": "1.12.2-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
28
- "@toptal/picasso-shared": "15.0.1-alpha-ff-7-tabs-19babbfd6.354+19babbfd6",
29
- "@toptal/picasso-typography": "4.0.4-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
30
- "@toptal/picasso-typography-overflow": "4.0.4-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
31
- "@toptal/picasso-user-badge": "5.1.12-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
32
- "@toptal/picasso-utils": "3.1.1-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
25
+ "@toptal/picasso-container": "3.1.3-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
26
+ "@toptal/picasso-icons": "1.12.2-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
27
+ "@toptal/picasso-shared": "15.0.1-alpha-ff-7-tabs-17eb872bb.359+17eb872bb",
28
+ "@toptal/picasso-typography": "4.0.4-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
29
+ "@toptal/picasso-typography-overflow": "4.0.4-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
30
+ "@toptal/picasso-user-badge": "5.1.12-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
31
+ "@toptal/picasso-utils": "3.1.1-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
33
32
  "ap-style-title-case": "^1.1.2"
34
33
  },
35
34
  "sideEffects": [
@@ -46,14 +45,14 @@
46
45
  ".": "./dist-package/src/index.js"
47
46
  },
48
47
  "devDependencies": {
49
- "@toptal/picasso-provider": "5.0.1-alpha-ff-7-tabs-19babbfd6.275+19babbfd6",
50
- "@toptal/picasso-tailwind-merge": "2.0.4-alpha-ff-7-tabs-19babbfd6.8+19babbfd6",
51
- "@toptal/picasso-test-utils": "1.1.2-alpha-ff-7-tabs-19babbfd6.354+19babbfd6"
48
+ "@toptal/picasso-provider": "5.0.1-alpha-ff-7-tabs-17eb872bb.280+17eb872bb",
49
+ "@toptal/picasso-tailwind-merge": "2.0.4-alpha-ff-7-tabs-17eb872bb.13+17eb872bb",
50
+ "@toptal/picasso-test-utils": "1.1.2-alpha-ff-7-tabs-17eb872bb.359+17eb872bb"
52
51
  },
53
52
  "files": [
54
53
  "dist-package/**",
55
54
  "!dist-package/tsconfig.tsbuildinfo",
56
55
  "src"
57
56
  ],
58
- "gitHead": "19babbfd627b4461663b6782aa7493f16f4181bc"
57
+ "gitHead": "17eb872bb0410897243666d7cc7a58eb1479ed78"
59
58
  }
package/src/Tab/Tab.tsx CHANGED
@@ -1,13 +1,11 @@
1
1
  import type { ReactNode, HTMLAttributes, ReactElement } from 'react'
2
- import React, { forwardRef, useContext } from 'react'
3
- import type { TabProps } from '@mui/base/Tab'
4
- import { Tab as MUITab } from '@mui/base/Tab'
2
+ import React, { forwardRef } from 'react'
5
3
  import type { BaseProps, TextLabelProps } from '@toptal/picasso-shared'
6
4
  import { useTitleCase } from '@toptal/picasso-shared'
7
5
  import { UserBadge } from '@toptal/picasso-user-badge'
8
6
  import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge'
9
7
 
10
- import { TabsContext } from '../Tabs/Tabs'
8
+ import { useTabsContext, type TabsValueType } from '../Tabs/TabsContext'
11
9
  import { TabLabel } from '../TabLabel'
12
10
  import { TabDescription } from '../TabDescription'
13
11
 
@@ -21,8 +19,8 @@ export interface Props
21
19
  */
22
20
  disabled?: boolean
23
21
 
24
- /** You can provide your own value. Otherwise, we fallback to the child position index */
25
- value?: TabProps['value']
22
+ /** The value of the tab */
23
+ value?: TabsValueType
26
24
 
27
25
  /** The label element */
28
26
  label?: ReactNode
@@ -38,9 +36,9 @@ export interface Props
38
36
 
39
37
  // Properties below are managed by Tabs component
40
38
 
41
- selected?: boolean
42
- onChange?: TabProps['onChange']
43
- onClick?: TabProps['onClick']
39
+ // selected?: boolean
40
+ // onChange?: TabProps['onChange']
41
+ // onClick?: TabProps['onClick']
44
42
  }
45
43
 
46
44
  const getOpacityClass = (
@@ -51,7 +49,6 @@ const getOpacityClass = (
51
49
  if (disabled) {
52
50
  return 'opacity-50'
53
51
  }
54
-
55
52
  if (selected || orientation === 'vertical') {
56
53
  return 'opacity-100 '
57
54
  }
@@ -60,13 +57,13 @@ const getOpacityClass = (
60
57
  }
61
58
 
62
59
  const wrapperClassesByOrientation = {
63
- horizontal: 'inline-flex items-center flex-col justify-center',
60
+ horizontal: 'inline-flex flex-row items-center justify-center',
64
61
  vertical: 'block',
65
62
  }
66
63
 
67
64
  const rootClassesByOrientation = (selected: boolean) => ({
68
65
  horizontal: [
69
- 'm-0 [&:not(:last-child)]:mr-8 pt-[0.5625rem] pb-[0.4375rem] px-0',
66
+ 'm-0 [&:not(:last-child)]:mr-8 pt-0 pb-[0.4375rem] px-0',
70
67
  'text-center bg-transparent transition-shadow z-10 rounded-none',
71
68
  'text-black',
72
69
  selected && 'shadow-blue-500 shadow-[inset_0_-2px_0]',
@@ -105,17 +102,29 @@ export const Tab = forwardRef<HTMLButtonElement, Props>(function Tab(
105
102
  value,
106
103
  label,
107
104
  icon,
108
- onChange,
109
- onClick,
110
105
  titleCase: propsTitleCase,
111
106
  description,
112
107
  avatar,
113
108
  className,
109
+ onClick,
114
110
  ...rest
115
111
  } = props
116
112
  const titleCase = useTitleCase(propsTitleCase)
117
- const { orientation, variant } = useContext(TabsContext)
113
+ const {
114
+ value: selectedValue,
115
+ onChange,
116
+ orientation,
117
+ variant,
118
+ } = useTabsContext()
118
119
  const isHorizontal = orientation === 'horizontal'
120
+ const selected = value === selectedValue
121
+
122
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
123
+ if (!disabled && onChange) {
124
+ onChange(event, value as TabsValueType)
125
+ }
126
+ onClick?.(event)
127
+ }
119
128
 
120
129
  const renderLabel = getLabelComponent({
121
130
  avatar,
@@ -127,65 +136,44 @@ export const Tab = forwardRef<HTMLButtonElement, Props>(function Tab(
127
136
  })
128
137
 
129
138
  return (
130
- <MUITab
131
- className=''
132
- {...rest}
139
+ <button
140
+ className={twMerge(
141
+ getOpacityClass(selected, !!disabled, orientation),
142
+ rootClassesByOrientation(selected)[orientation],
143
+ classesByVariant[variant],
144
+ disabled ? 'cursor-default text-gray-500' : 'cursor-pointer',
145
+ disabled && 'pointer-events-none',
146
+ icon && isHorizontal && 'min-h-0 pt-0 pr-6',
147
+ 'min-w-0 sm:min-w-[160px] md:min-w-[auto]',
148
+ 'border-0 cursor-pointer inline-flex outline-none',
149
+ 'items-center select-none align-middle appearance-none',
150
+ 'justify-center no-underline [-webkit-tap-highlight-color:transparent]',
151
+ 'normal-case whitespace-normal leading-4',
152
+ 'relative ',
153
+ className
154
+ )}
133
155
  ref={ref}
134
- tabIndex={0}
156
+ tabIndex={disabled ? -1 : 0}
135
157
  disabled={disabled}
136
- value={value}
137
- onChange={onChange}
138
- onClick={onClick}
139
- slotProps={{
140
- root: ownerState => {
141
- return {
142
- className: twMerge(
143
- getOpacityClass(
144
- ownerState.selected,
145
- ownerState.disabled,
146
- orientation
147
- ),
148
- rootClassesByOrientation(ownerState.selected)[orientation],
149
- classesByVariant[variant],
150
- ownerState.disabled
151
- ? 'cursor-default text-gray-500'
152
- : 'cursor-pointer',
153
- ownerState.disabled && 'pointer-events-none',
154
- icon && isHorizontal && 'min-h-0 pt-[0.5625rem] pr-6',
155
- 'min-w-0 sm:min-w-[160px] md:min-w-[auto]',
156
- 'border-0 cursor-pointer inline-flex outline-none',
157
- 'items-center select-none align-middle appearance-none',
158
- 'justify-center no-underline [-webkit-tap-highlight-color:transparent]',
159
- 'normal-case whitespace-normal leading-4',
160
- 'relative ',
161
- className
162
- ),
163
- }
164
- },
165
- }}
158
+ onClick={handleClick}
159
+ role='tab'
160
+ aria-selected={selected}
161
+ aria-disabled={disabled}
162
+ type='button'
163
+ {...rest}
166
164
  >
167
165
  <span
168
166
  className={twJoin('w-full', wrapperClassesByOrientation[orientation])}
169
167
  >
170
168
  {renderLabel}
171
- {icon && <span className='absolute right-0 mb-0 h-4'>{icon}</span>}
169
+ {icon && <span className='absolute right-0 mb-0'>{icon}</span>}
172
170
  </span>
173
- </MUITab>
171
+ </button>
174
172
  )
175
173
  })
176
174
 
177
- Tab.defaultProps = {}
178
-
179
175
  Tab.displayName = 'Tab'
180
176
 
181
- type GetLabelComponentProps = {
182
- avatar?: string | null
183
- description?: string
184
- disabled?: boolean
185
- label?: React.ReactNode
186
- orientation: 'horizontal' | 'vertical'
187
- titleCase?: boolean
188
- }
189
177
  const getLabelComponent = ({
190
178
  avatar,
191
179
  description,
@@ -193,14 +181,19 @@ const getLabelComponent = ({
193
181
  label,
194
182
  orientation,
195
183
  titleCase,
196
- }: GetLabelComponentProps): React.ReactNode => {
184
+ }: {
185
+ avatar?: string | null
186
+ description?: string
187
+ disabled?: boolean
188
+ label?: React.ReactNode
189
+ orientation: 'horizontal' | 'vertical'
190
+ titleCase?: boolean
191
+ }): React.ReactNode => {
197
192
  if (!label) {
198
193
  return null
199
194
  }
200
-
201
195
  const isHorizontal = orientation === 'horizontal'
202
196
  const isCustomLabel = typeof label !== 'string'
203
-
204
197
  const Label = () => (
205
198
  <TabLabel titleCase={titleCase} label={label} orientation={orientation} />
206
199
  )
@@ -208,7 +201,6 @@ const getLabelComponent = ({
208
201
  if (isHorizontal || isCustomLabel) {
209
202
  return <Label />
210
203
  }
211
-
212
204
  if (typeof avatar === 'undefined') {
213
205
  return (
214
206
  <>
@@ -6,31 +6,29 @@ exports[`Tab Tab disabled tab 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
- class="MuiTabs-scrollable"
14
- style="width: 99px; height: 99px; position: absolute; top: -9999px; overflow: scroll;"
15
- />
16
- <div
17
- class="MuiTabs-scroller MuiTabs-scrollable"
18
- style="margin-bottom: 0px;"
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"
19
15
  >
20
16
  <div
21
- class="MuiTabs-flexContainer"
17
+ class="flex"
22
18
  role="tablist"
19
+ tabindex="-1"
23
20
  >
24
21
  <button
22
+ aria-disabled="true"
25
23
  aria-selected="false"
26
- class="MuiButtonBase-root MuiTab-root PicassoTab-horizontal MuiTab-textColorInherit Mui-disabled Mui-disabled"
24
+ class="opacity-50 m-0 [&:not(:last-child)]:mr-8 pt-0 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"
27
25
  disabled=""
28
26
  role="tab"
29
27
  tabindex="-1"
30
28
  type="button"
31
29
  >
32
30
  <span
33
- class="MuiTab-wrapper PicassoTab-wrapper"
31
+ class="w-full inline-flex flex-row items-center justify-center"
34
32
  >
35
33
  <div
36
34
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -40,10 +38,6 @@ exports[`Tab Tab disabled tab 1`] = `
40
38
  </span>
41
39
  </button>
42
40
  </div>
43
- <span
44
- class="PrivateTabIndicator-root PrivateTabIndicator-colorSecondary MuiTabs-indicator"
45
- style="left: 0px; width: 0px;"
46
- />
47
41
  </div>
48
42
  </div>
49
43
  </div>
@@ -56,30 +50,27 @@ exports[`Tab Tab renders 1`] = `
56
50
  class="Picasso-root"
57
51
  >
58
52
  <div
59
- class="MuiTabs-root Tabs-horizontal"
53
+ aria-orientation="horizontal"
54
+ class="relative min-h flex overflow-hidden overflow-x"
60
55
  data-component-type="tabs"
61
56
  >
62
57
  <div
63
- class="MuiTabs-scrollable"
64
- style="width: 99px; height: 99px; position: absolute; top: -9999px; overflow: scroll;"
65
- />
66
- <div
67
- class="MuiTabs-scroller MuiTabs-scrollable"
68
- style="margin-bottom: 0px;"
58
+ 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"
69
59
  >
70
60
  <div
71
- class="MuiTabs-flexContainer"
61
+ class="flex"
72
62
  role="tablist"
63
+ tabindex="-1"
73
64
  >
74
65
  <button
75
66
  aria-selected="false"
76
- class="MuiButtonBase-root MuiTab-root PicassoTab-horizontal MuiTab-textColorInherit"
67
+ 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"
77
68
  role="tab"
78
69
  tabindex="0"
79
70
  type="button"
80
71
  >
81
72
  <span
82
- class="MuiTab-wrapper PicassoTab-wrapper"
73
+ class="w-full inline-flex flex-row items-center justify-center"
83
74
  >
84
75
  <div
85
76
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
@@ -89,10 +80,6 @@ exports[`Tab Tab renders 1`] = `
89
80
  </span>
90
81
  </button>
91
82
  </div>
92
- <span
93
- class="PrivateTabIndicator-root PrivateTabIndicator-colorSecondary MuiTabs-indicator"
94
- style="left: 0px; width: 0px;"
95
- />
96
83
  </div>
97
84
  </div>
98
85
  </div>
@@ -105,46 +92,43 @@ exports[`Tab Tab tab with icon 1`] = `
105
92
  class="Picasso-root"
106
93
  >
107
94
  <div
108
- class="MuiTabs-root Tabs-horizontal"
95
+ aria-orientation="horizontal"
96
+ class="relative min-h flex overflow-hidden overflow-x"
109
97
  data-component-type="tabs"
110
98
  >
111
99
  <div
112
- class="MuiTabs-scrollable"
113
- style="width: 99px; height: 99px; position: absolute; top: -9999px; overflow: scroll;"
114
- />
115
- <div
116
- class="MuiTabs-scroller MuiTabs-scrollable"
117
- style="margin-bottom: 0px;"
100
+ 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"
118
101
  >
119
102
  <div
120
- class="MuiTabs-flexContainer"
103
+ class="flex"
121
104
  role="tablist"
105
+ tabindex="-1"
122
106
  >
123
107
  <button
124
108
  aria-selected="false"
125
- class="MuiButtonBase-root MuiTab-root PicassoTab-horizontal MuiTab-textColorInherit MuiTab-labelIcon"
109
+ class="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-black shrink-0 max-w min-h pt-0 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"
126
110
  role="tab"
127
111
  tabindex="0"
128
112
  type="button"
129
113
  >
130
114
  <span
131
- class="MuiTab-wrapper PicassoTab-wrapper"
115
+ class="w-full inline-flex flex-row items-center justify-center"
132
116
  >
133
- <div
134
- id="Icon"
135
- />
136
117
  <div
137
118
  class="m-0 text-sm text-inherit font-semibold leading-[1.1rem]"
138
119
  >
139
120
  Tab Label
140
121
  </div>
122
+ <span
123
+ class="absolute right-0 mb-0"
124
+ >
125
+ <div
126
+ id="Icon"
127
+ />
128
+ </span>
141
129
  </span>
142
130
  </button>
143
131
  </div>
144
- <span
145
- class="PrivateTabIndicator-root PrivateTabIndicator-colorSecondary MuiTabs-indicator"
146
- style="left: 0px; width: 0px;"
147
- />
148
132
  </div>
149
133
  </div>
150
134
  </div>
@@ -3,10 +3,12 @@ import { Container, Tabs, Tooltip, Badge } from '@toptal/picasso'
3
3
  import { SPACING_4 } from '@toptal/picasso-utils'
4
4
  import { Exclamation16 } from '@toptal/picasso-icons'
5
5
 
6
+ import type { TabsValueType } from '../../Tabs/TabsContext'
7
+
6
8
  const Example = () => {
7
- const [value, setValue] = React.useState(0)
9
+ const [value, setValue] = React.useState<TabsValueType>(0)
8
10
 
9
- const handleChange = (_: React.ChangeEvent<{}>, newValue: number) => {
11
+ const handleChange = (_: React.ChangeEvent<{}>, newValue: TabsValueType) => {
10
12
  setValue(newValue)
11
13
  }
12
14
 
@@ -24,7 +26,10 @@ const Example = () => {
24
26
  }
25
27
  />
26
28
  <Tabs.Tab label='Label' />
27
- <Tabs.Tab label='Label' icon={<Badge content={10} variant='white' />} />
29
+ <Tabs.Tab
30
+ label='Label'
31
+ icon={<Badge content={10} variant='white' className='mt-[1px]' />}
32
+ />
28
33
  </Tabs>
29
34
 
30
35
  {value === 0 && (
package/src/Tabs/Tabs.tsx CHANGED
@@ -1,18 +1,16 @@
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 } 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, type TabsValueType } from './TabsContext'
9
7
 
10
8
  export interface Props<V extends TabsValueType> extends BaseProps {
11
9
  /** Tabs content containing Tab components */
12
10
  children: ReactNode
13
11
 
14
12
  /** Callback fired when the value changes. */
15
- onChange?: (event: React.ChangeEvent<{}> | null, value: V) => void
13
+ onChange?: (event: ChangeEvent<{}>, value: V) => void
16
14
 
17
15
  /**
18
16
  * The value of the currently selected Tab.
@@ -25,12 +23,13 @@ export interface Props<V extends TabsValueType> extends BaseProps {
25
23
 
26
24
  /** Determines additional display behavior of the tabs */
27
25
  variant?: 'scrollable' | 'fullWidth'
28
- }
29
26
 
30
- export const TabsContext = React.createContext<{
31
- orientation: 'horizontal' | 'vertical'
32
- variant: 'scrollable' | 'fullWidth'
33
- }>({ orientation: 'horizontal', variant: 'scrollable' })
27
+ /** The default value. Use when the component is not controlled. */
28
+ defaultValue?: V
29
+
30
+ /** The direction of the text. */
31
+ direction?: 'ltr' | 'rtl'
32
+ }
34
33
 
35
34
  const indicatorClasses = [
36
35
  'after:absolute',
@@ -65,48 +64,77 @@ const classesByVariant = {
65
64
  },
66
65
  }
67
66
 
68
- // eslint-disable-next-line react/display-name
69
67
  export const Tabs = forwardRef<HTMLDivElement, Props<TabsValueType>>(
70
68
  function Tabs(props, ref) {
71
69
  const {
72
70
  children,
73
71
  orientation = 'horizontal',
74
72
  onChange,
75
- value,
73
+ value: valueProp,
74
+ defaultValue,
76
75
  variant = 'scrollable',
76
+ direction = 'ltr',
77
77
  className,
78
78
  ...rest
79
79
  } = props
80
80
 
81
+ const [value, setValue] = React.useState<TabsValueType>(
82
+ defaultValue ?? null
83
+ )
84
+ const isControlled = valueProp !== undefined
85
+ const currentValue = isControlled ? valueProp : value
86
+
87
+ const handleChange = useCallback(
88
+ (event: ChangeEvent<{}>, newValue: TabsValueType) => {
89
+ if (!isControlled) {
90
+ setValue(newValue)
91
+ }
92
+ onChange?.(event, newValue as TabsValueType)
93
+ },
94
+ [isControlled, onChange]
95
+ )
96
+
81
97
  const contextValue = useMemo(
82
98
  () => ({
99
+ value: currentValue,
100
+ onChange: handleChange,
83
101
  orientation,
84
102
  variant,
103
+ direction,
85
104
  }),
86
- [orientation, variant]
105
+ [currentValue, handleChange, orientation, variant, direction]
87
106
  )
88
107
 
89
108
  const isVertical = orientation === 'vertical'
90
109
 
110
+ const childrenWithIndex = React.Children.map(children, (child, idx) => {
111
+ if (
112
+ React.isValidElement(child) &&
113
+ // @ts-expect-error: type check for Picasso Tab
114
+ (child.type.displayName === 'Tab' || child.type.name === 'Tab') &&
115
+ child.props.value === undefined
116
+ ) {
117
+ return React.cloneElement(child as React.ReactElement<any>, {
118
+ value: idx,
119
+ })
120
+ }
121
+
122
+ return child
123
+ })
124
+
91
125
  return (
92
126
  <TabsContext.Provider value={contextValue}>
93
- <MUITabs
127
+ <div
94
128
  {...rest}
129
+ ref={ref}
95
130
  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}
131
+ className={twMerge(
132
+ 'relative min-h-0 flex overflow-hidden',
133
+ classesByOrientation[orientation].root,
134
+ classesByVariant[variant].root,
135
+ className
136
+ )}
137
+ aria-orientation={orientation}
110
138
  >
111
139
  <div
112
140
  className={twJoin(
@@ -115,11 +143,15 @@ export const Tabs = forwardRef<HTMLDivElement, Props<TabsValueType>>(
115
143
  'flex-auto inline-block relative whitespace-nowrap'
116
144
  )}
117
145
  >
118
- <TabsList className={twJoin('flex', isVertical && 'flex-col')}>
119
- {children}
120
- </TabsList>
146
+ <div
147
+ className={twJoin('flex', isVertical && 'flex-col')}
148
+ role='tablist'
149
+ tabIndex={-1}
150
+ >
151
+ {childrenWithIndex}
152
+ </div>
121
153
  </div>
122
- </MUITabs>
154
+ </div>
123
155
  </TabsContext.Provider>
124
156
  )
125
157
  }
@@ -0,0 +1,27 @@
1
+ import React from 'react'
2
+
3
+ export type TabsValueType = string | number | null
4
+
5
+ export interface TabsContextValue {
6
+ value: TabsValueType
7
+ onChange: (event: React.ChangeEvent<{}>, value: TabsValueType) => void
8
+ orientation: 'horizontal' | 'vertical'
9
+ variant: 'scrollable' | 'fullWidth'
10
+ }
11
+
12
+ export const TabsContext = React.createContext<TabsContextValue>({
13
+ value: null,
14
+ onChange: () => {},
15
+ orientation: 'horizontal',
16
+ variant: 'scrollable',
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,8 @@
1
1
  import type { OmitInternalProps } from '@toptal/picasso-shared'
2
2
 
3
- import type { Props, TabsValueType } from './Tabs'
3
+ import type { Props } from './Tabs'
4
+ import type { TabsValueType } from './TabsContext'
4
5
 
5
6
  export { default as Tabs } from './Tabs'
6
7
  export type TabsProps = OmitInternalProps<Props<TabsValueType>>
7
- export type { TabsValueType } from './Tabs'
8
+ export type { TabsValueType } from './TabsContext'
@@ -2,10 +2,12 @@ import React from 'react'
2
2
  import { Container, Tabs } from '@toptal/picasso'
3
3
  import { SPACING_4 } from '@toptal/picasso-utils'
4
4
 
5
+ import type { TabsValueType } from '../TabsContext'
6
+
5
7
  const Example = () => {
6
- const [value, setValue] = React.useState(0)
8
+ const [value, setValue] = React.useState<TabsValueType>(0)
7
9
 
8
- const handleChange = (_: React.ChangeEvent<{}> | null, newValue: number) => {
10
+ const handleChange = (_: React.ChangeEvent<{}>, newValue: TabsValueType) => {
9
11
  setValue(newValue)
10
12
  }
11
13