From 2cdacc85886b0f2240294981838cec2f5ad45bda Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 22 Sep 2021 12:44:02 -0500
Subject: [PATCH 01/22] feat(Tab): make tab functional component

---
 packages/react/src/components/Tab/index.js    |   8 +-
 packages/react/src/components/Tab/next/Tab.js | 174 ++++++++++++++++++
 .../react/src/components/Tabs/Tabs-story.js   |   2 +-
 3 files changed, 182 insertions(+), 2 deletions(-)
 create mode 100644 packages/react/src/components/Tab/next/Tab.js

diff --git a/packages/react/src/components/Tab/index.js b/packages/react/src/components/Tab/index.js
index e664e8d8850b..83ad52cd2666 100644
--- a/packages/react/src/components/Tab/index.js
+++ b/packages/react/src/components/Tab/index.js
@@ -5,4 +5,10 @@
  * LICENSE file in the root directory of this source tree.
  */
 
-export default from './Tab';
+import * as FeatureFlags from '@carbon/feature-flags';
+import { Tab as TabNext } from './next/Tab';
+import TabClassic from './Tab';
+
+export const Tab = FeatureFlags.enabled('enable-v11-release')
+  ? TabNext
+  : TabClassic;
diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
new file mode 100644
index 000000000000..bad4ff032694
--- /dev/null
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -0,0 +1,174 @@
+/**
+ * Copyright IBM Corp. 2016, 2018
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import PropTypes from 'prop-types';
+import React from 'react';
+import classNames from 'classnames';
+import { settings } from 'carbon-components';
+import deprecate from '../../../prop-types/deprecate';
+
+const { prefix } = settings;
+
+const Tab = React.forwardRef(function Tab(
+  {
+    className,
+    disabled,
+    handleTabClick,
+    handleTabKeyDown,
+    id,
+    index,
+    label = 'provide a label',
+    onClick = () => {},
+    onKeyDown = () => {},
+    renderButton,
+    renderContent, // eslint-disable-line no-unused-vars
+    selected = false,
+    tabIndex = 0,
+    ...other
+  },
+  ref
+) {
+  const classes = classNames(className, `${prefix}--tabs__nav-link`, {
+    [`${prefix}--tabs__nav-item--disabled`]: disabled,
+    [`${prefix}--tabs__nav-item--selected`]: selected,
+  });
+
+  const buttonProps = {
+    ['aria-selected']: selected,
+    ['aria-disabled']: disabled,
+    ['aria-controls']: id && `${id}__panel`,
+    id,
+    className: `${prefix}--tabs__nav-link`,
+    tabIndex: !disabled ? tabIndex : -1,
+    ref: ref,
+  };
+
+  return (
+    <li
+      {...other}
+      className={classes}
+      onClick={(evt) => {
+        if (disabled) {
+          return;
+        }
+        if (handleTabClick) {
+          handleTabClick(index, evt);
+        }
+        onClick(evt);
+      }}
+      onKeyDown={(evt) => {
+        if (disabled) {
+          return;
+        }
+        if (handleTabKeyDown) {
+          handleTabKeyDown(index, evt);
+        }
+        onKeyDown(evt);
+      }}
+      role="presentation">
+      {renderButton ? (
+        renderButton(buttonProps)
+      ) : (
+        <button type="button" role="tab" {...buttonProps}>
+          {label}
+        </button>
+      )}
+    </li>
+  );
+});
+
+Tab.propTypes = {
+  /**
+   * Specify an optional className to be added to your Tab
+   */
+  className: PropTypes.string,
+
+  /**
+   * Whether your Tab is disabled.
+   */
+  disabled: PropTypes.bool,
+
+  /**
+   * A handler that is invoked when a user clicks on the control.
+   * Reserved for usage in Tabs
+   */
+  handleTabClick: PropTypes.func,
+
+  /**
+   * A handler that is invoked on the key down event for the control.
+   * Reserved for usage in Tabs
+   */
+  handleTabKeyDown: PropTypes.func,
+
+  /**
+   * Provide a string that represents the `href` of the Tab
+   */
+  href: deprecate(
+    PropTypes.string,
+    'The href prop has been deprecated and removed in v11.'
+  ),
+
+  /**
+   * The element ID for the top-level element.
+   */
+  id: PropTypes.string,
+
+  /**
+   * The index of your Tab in your Tabs. Reserved for usage in Tabs
+   */
+  index: PropTypes.number,
+
+  /**
+   * Provide the contents of your Tab
+   */
+  label: PropTypes.node,
+
+  /**
+   * Provide a handler that is invoked when a user clicks on the control
+   */
+  onClick: PropTypes.func.isRequired,
+
+  /**
+   * Provide a handler that is invoked on the key down event for the control
+   */
+  onKeyDown: PropTypes.func.isRequired,
+
+  /*
+   * An optional parameter to allow overriding the anchor rendering.
+   * Useful for using Tab along with react-router or other client
+   * side router libraries.
+   **/
+  renderAnchor: deprecate(
+    PropTypes.func,
+    'The renderAnchor prop has been deprecated in favor of renderButton. It has been removed in v11.'
+  ),
+  renderButton: PropTypes.func,
+
+  /*
+   * An optional parameter to allow overriding the content rendering.
+   **/
+  renderContent: PropTypes.func,
+
+  /**
+   * Provide an accessibility role for your Tab
+   */
+  role: deprecate(
+    PropTypes.string,
+    'The role prop has been deprecated and removed in v11. Role is now built into the element.'
+  ),
+
+  /**
+   * Whether your Tab is selected.
+   * Reserved for usage in Tabs
+   */
+  selected: PropTypes.bool.isRequired,
+
+  /**
+   * Specify the tab index of the `<button>` node
+   */
+  tabIndex: PropTypes.number,
+};
diff --git a/packages/react/src/components/Tabs/Tabs-story.js b/packages/react/src/components/Tabs/Tabs-story.js
index 80d5ff17289a..a2b6d5f1650c 100644
--- a/packages/react/src/components/Tabs/Tabs-story.js
+++ b/packages/react/src/components/Tabs/Tabs-story.js
@@ -20,7 +20,7 @@ import './Tabs-story.scss';
 import CodeSnippet from '../CodeSnippet';
 import Button from '../Button';
 import Tabs from '../Tabs';
-import Tab from '../Tab';
+import { Tab } from '../Tab';
 import TabsSkeleton from '../Tabs/Tabs.Skeleton';
 import mdx from './Tabs.mdx';
 

From be88f6ac236d1da24f4043e118291b833c71d519 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Fri, 1 Oct 2021 00:58:51 -0500
Subject: [PATCH 02/22] feat(Tabs): convert to functional

---
 packages/react/src/components/Tab/index.js    |   2 +-
 packages/react/src/components/Tab/next/Tab.js |   8 +-
 .../react/src/components/Tabs/Tabs-story.js   |   2 +-
 packages/react/src/components/Tabs/Tabs.js    |   6 +
 packages/react/src/components/Tabs/index.js   |  10 +-
 .../react/src/components/Tabs/next/Tabs.js    | 557 ++++++++++++++++++
 6 files changed, 578 insertions(+), 7 deletions(-)
 create mode 100644 packages/react/src/components/Tabs/next/Tabs.js

diff --git a/packages/react/src/components/Tab/index.js b/packages/react/src/components/Tab/index.js
index 83ad52cd2666..754fdd1a0a2f 100644
--- a/packages/react/src/components/Tab/index.js
+++ b/packages/react/src/components/Tab/index.js
@@ -7,7 +7,7 @@
 
 import * as FeatureFlags from '@carbon/feature-flags';
 import { Tab as TabNext } from './next/Tab';
-import TabClassic from './Tab';
+import { Tab as TabClassic } from './Tab';
 
 export const Tab = FeatureFlags.enabled('enable-v11-release')
   ? TabNext
diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index bad4ff032694..50e76b44f537 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -8,12 +8,10 @@
 import PropTypes from 'prop-types';
 import React from 'react';
 import classNames from 'classnames';
-import { settings } from 'carbon-components';
 import deprecate from '../../../prop-types/deprecate';
+import { usePrefix } from '../../../internal/usePrefix';
 
-const { prefix } = settings;
-
-const Tab = React.forwardRef(function Tab(
+export const Tab = React.forwardRef(function Tab(
   {
     className,
     disabled,
@@ -32,6 +30,8 @@ const Tab = React.forwardRef(function Tab(
   },
   ref
 ) {
+  const { prefix } = usePrefix();
+
   const classes = classNames(className, `${prefix}--tabs__nav-link`, {
     [`${prefix}--tabs__nav-item--disabled`]: disabled,
     [`${prefix}--tabs__nav-item--selected`]: selected,
diff --git a/packages/react/src/components/Tabs/Tabs-story.js b/packages/react/src/components/Tabs/Tabs-story.js
index a2b6d5f1650c..80d5ff17289a 100644
--- a/packages/react/src/components/Tabs/Tabs-story.js
+++ b/packages/react/src/components/Tabs/Tabs-story.js
@@ -20,7 +20,7 @@ import './Tabs-story.scss';
 import CodeSnippet from '../CodeSnippet';
 import Button from '../Button';
 import Tabs from '../Tabs';
-import { Tab } from '../Tab';
+import Tab from '../Tab';
 import TabsSkeleton from '../Tabs/Tabs.Skeleton';
 import mdx from './Tabs.mdx';
 
diff --git a/packages/react/src/components/Tabs/Tabs.js b/packages/react/src/components/Tabs/Tabs.js
index bd259a91b4f6..2483538d2bd2 100644
--- a/packages/react/src/components/Tabs/Tabs.js
+++ b/packages/react/src/components/Tabs/Tabs.js
@@ -170,6 +170,7 @@ export default class Tabs extends React.Component {
       scrollLeft: tablistScrollLeft,
       scrollWidth: tablistScrollWidth,
     } = this.tablist?.current || {};
+
     const tab = this.getTabAt(this.state.selected);
     const horizontalOverflow = tablistScrollWidth > tablistClientWidth;
 
@@ -187,6 +188,8 @@ export default class Tabs extends React.Component {
         this.tablist.current.scrollLeft += this.OVERFLOW_BUTTON_OFFSET * 2;
       }
     }
+
+    console.log('THIS', this);
   }
 
   componentWillUnmount() {
@@ -203,6 +206,7 @@ export default class Tabs extends React.Component {
       scrollLeft: tablistScrollLeft,
       scrollWidth: tablistScrollWidth,
     } = this.tablist.current;
+
     const {
       tablistClientWidth: currentStateClientWidth,
       tablistScrollLeft: currentStateScrollLeft,
@@ -337,6 +341,8 @@ export default class Tabs extends React.Component {
 
   setTabAt = (index, tabRef) => {
     this[`tab${index}`] = tabRef;
+    console.log(this[`tab${index}`]);
+    console.log(tabRef);
   };
 
   overflowNavInterval = null;
diff --git a/packages/react/src/components/Tabs/index.js b/packages/react/src/components/Tabs/index.js
index 531a69be74b1..60eead8232eb 100644
--- a/packages/react/src/components/Tabs/index.js
+++ b/packages/react/src/components/Tabs/index.js
@@ -5,5 +5,13 @@
  * LICENSE file in the root directory of this source tree.
  */
 
+import * as FeatureFlags from '@carbon/feature-flags';
+import { Tabs as TabsNext } from './next/Tabs';
+import { Tabs as TabsClassic } from './Tabs';
+
+export const Tabs = FeatureFlags.enabled('enable-v11-release')
+  ? TabsNext
+  : TabsClassic;
+
 export * from './Tabs.Skeleton';
-export default from './Tabs';
+// export default from './Tabs';
diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
new file mode 100644
index 000000000000..40de9f14c441
--- /dev/null
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -0,0 +1,557 @@
+/**
+ * Copyright IBM Corp. 2016, 2018
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import PropTypes from 'prop-types';
+import React, {
+  useState,
+  useRef,
+  useEffect,
+  useCallback,
+  useMemo,
+} from 'react';
+import classNames from 'classnames';
+import { ChevronLeft16, ChevronRight16 } from '@carbon/icons-react';
+import debounce from 'lodash.debounce';
+import { keys, match, matches } from '../../../internal/keyboard';
+import TabContent from '../../TabContent';
+import deprecate from '../../../prop-types/deprecate';
+import { usePrefix } from '../../../internal/usePrefix';
+
+export const Tabs = React.forwardRef(function Tabs(
+  {
+    children,
+    className,
+    leftOverflowButtonProps,
+    onSelectionChange,
+    rightOverflowButtonProps,
+    scrollIntoView = true,
+    selected = 0,
+    selectionMode = 'automatic',
+    tabContentClassName,
+    type = 'default',
+    ...other
+  },
+  ref
+) {
+  const { prefix } = usePrefix();
+
+  //refs
+  const tablist = useRef();
+  const leftOverflowNavButton = useRef();
+  const rightOverflowNavButton = useRef();
+
+  //state
+  const [horizontalOverflow, setHorizontalOverflow] = useState(false);
+  const [tablistClientWidth, setTablistClientWidth] = useState(
+    tablist.current.clientWidth
+  );
+  const [tablistScrollWidth, setTablistScrollWidth] = useState(
+    tablist.current.scrollWidth
+  );
+  const [tablistScrollLeft, setTablistScrollLeft] = useState(
+    tablist.current.scrollLeft
+  );
+
+  let tabs = useMemo(() => {}, []);
+
+  //prop + state alignment - getDerivedStateFromProps
+  const [isSelected, setIsSelected] = useState(selected);
+  const [prevSelected, setPrevSelected] = useState(isSelected);
+  if (selected !== prevSelected) {
+    setIsSelected(selected);
+    setPrevSelected(selected);
+  }
+
+  // width of the overflow buttons
+  let OVERFLOW_BUTTON_OFFSET = 40;
+
+  /**
+   * `scroll` event handler to save tablist clientWidth, scrollWidth, and
+   * scrollLeft
+   */
+  const handleScroll = () => {
+    if (!tablist?.current) {
+      return;
+    }
+    const { clientWidth, scrollLeft, scrollWidth } = tablist.current;
+
+    setTablistClientWidth(clientWidth);
+    setTablistScrollWidth(scrollWidth);
+    setTablistScrollLeft(scrollLeft);
+    setHorizontalOverflow(scrollWidth > clientWidth);
+  };
+
+  /**
+   * The debounced version of the `resize` event handler.
+   * @type {Function}
+   * @private
+   */
+  const _debouncedHandleWindowResize = debounce(_handleWindowResize, 200);
+
+  const _handleWindowResize = handleScroll();
+
+  const getEnabledTabs = () =>
+    React.Children.toArray(children).reduce(
+      (enabledTabs, tab, index) =>
+        !tab.props.disabled ? enabledTabs.concat(index) : enabledTabs,
+      []
+    );
+
+  const getNextIndex = (index, direction) => {
+    const enabledTabs = getEnabledTabs();
+    const nextIndex = Math.max(
+      enabledTabs.indexOf(index) + direction,
+      // For `tab` not found in `enabledTabs`
+      -1
+    );
+    const nextIndexLooped =
+      nextIndex >= 0 && nextIndex < enabledTabs.length
+        ? nextIndex
+        : nextIndex - Math.sign(nextIndex) * enabledTabs.length;
+    return enabledTabs[nextIndexLooped];
+  };
+
+  const getDirection = (evt) => {
+    if (match(evt, keys.ArrowLeft)) {
+      return -1;
+    }
+    if (match(evt, keys.ArrowRight)) {
+      return 1;
+    }
+    return 0;
+  };
+
+  const getTabAt = useCallback(
+    (index, useFresh) =>
+      (!useFresh && tabs[`tab${index}`]) ||
+      React.Children.toArray(children)[index],
+    [tabs, children]
+  );
+
+  const scrollTabIntoView = (event, { index }) => {
+    const tab = getTabAt(index);
+    if (
+      matches(event, [keys.ArrowLeft, keys.ArrowRight]) ||
+      event.type === 'click'
+    ) {
+      const currentScrollLeft = tablistScrollLeft;
+      tab?.tabAnchor?.scrollIntoView({
+        block: 'nearest',
+        inline: 'nearest',
+      });
+      tab?.tabAnchor?.focus();
+      const newScrollLeft = tablist.current.scrollLeft;
+      if (newScrollLeft > currentScrollLeft) {
+        tablist.current.scrollLeft += OVERFLOW_BUTTON_OFFSET;
+      }
+    }
+  };
+
+  const selectTabAt = (event, { index, onSelectionChange }) => {
+    scrollTabIntoView(event, { index });
+    if (isSelected !== index) {
+      setIsSelected(index);
+      setPrevSelected(index);
+      if (typeof onSelectionChange === 'function') {
+        onSelectionChange(index);
+      }
+    }
+  };
+
+  const handleTabKeyDown = (onSelectionChange) => {
+    return (index, evt) => {
+      if (matches(evt, [keys.Enter, keys.Space])) {
+        selectTabAt(evt, { index, onSelectionChange });
+      }
+
+      const nextIndex = (() => {
+        if (matches(evt, [keys.ArrowLeft, keys.ArrowRight])) {
+          return getNextIndex(index, getDirection(evt));
+        }
+        if (match(evt, keys.Home)) {
+          return 0;
+        }
+        if (match(evt, keys.End)) {
+          return getEnabledTabs().pop();
+        }
+      })();
+      const tab = getTabAt(nextIndex);
+
+      if (
+        matches(evt, [keys.ArrowLeft, keys.ArrowRight, keys.Home, keys.End])
+      ) {
+        evt.preventDefault();
+        if (selectionMode !== 'manual') {
+          selectTabAt(evt, { index: nextIndex, onSelectionChange });
+        } else {
+          scrollTabIntoView(evt, { index: nextIndex });
+        }
+        tab?.tabAnchor?.focus();
+      }
+    };
+  };
+
+  const getTabs = () => React.Children.map(children, (tab) => tab);
+
+  // following functions (handle*) are Props on Tab.js, see Tab.js for parameters
+  const handleTabClick = (onSelectionChange) => (index, evt) => {
+    evt.preventDefault();
+    selectTabAt(evt, { index, onSelectionChange });
+  };
+
+  const setTabAt = (index, tabRef) => {
+    tabs[`tab${index}`] = tabRef;
+  };
+
+  let overflowNavInterval = null;
+
+  const handleOverflowNavClick = (_, { direction, multiplier = 10 }) => {
+    // account for overflow button appearing and causing tablist width change
+    const { clientWidth, scrollLeft, scrollWidth } = tablist?.current;
+    if (direction === 1 && !scrollLeft) {
+      tablist.current.scrollLeft += OVERFLOW_BUTTON_OFFSET;
+    }
+
+    tablist.current.scrollLeft += direction * multiplier;
+
+    const leftEdgeReached =
+      direction === -1 && scrollLeft < OVERFLOW_BUTTON_OFFSET;
+
+    const rightEdgeReached =
+      direction === 1 &&
+      scrollLeft + clientWidth >= scrollWidth - OVERFLOW_BUTTON_OFFSET;
+
+    if (leftEdgeReached || rightEdgeReached) {
+      if (leftEdgeReached) {
+        rightOverflowNavButton?.current?.focus();
+      }
+      if (rightEdgeReached) {
+        leftOverflowNavButton?.current?.focus();
+      }
+    }
+  };
+
+  const handleOverflowNavMouseDown = (event, { direction }) => {
+    // disregard mouse buttons aside from LMB
+    if (event.buttons !== 1) {
+      return;
+    }
+
+    overflowNavInterval = setInterval(() => {
+      const { clientWidth, scrollLeft, scrollWidth } = tablist?.current;
+
+      // clear interval if scroll reaches left or right edge
+      const leftEdgeReached =
+        direction === -1 && scrollLeft < OVERFLOW_BUTTON_OFFSET;
+
+      const rightEdgeReached =
+        direction === 1 &&
+        scrollLeft + clientWidth >= scrollWidth - OVERFLOW_BUTTON_OFFSET;
+
+      if (leftEdgeReached || rightEdgeReached) {
+        clearInterval(overflowNavInterval);
+      }
+
+      // account for overflow button appearing and causing tablist width change
+      handleOverflowNavClick(event, { direction });
+    });
+  };
+
+  const handleOverflowNavMouseUp = () => {
+    clearInterval(overflowNavInterval);
+  };
+
+  //component did mount equivalent
+  useEffect(() => {
+    _handleWindowResize();
+    window.addEventListener('resize', _debouncedHandleWindowResize);
+
+    // scroll selected tab into view on mount
+    const { clientWidth, scrollLeft, scrollWidth } = tablist?.current || {};
+    const tab = getTabAt(isSelected);
+    const horizontalOverflow = scrollWidth > clientWidth;
+
+    if (horizontalOverflow) {
+      const leftOverflowNavButtonHidden =
+        tab?.tabAnchor?.getBoundingClientRect().right <
+        tab?.tabAnchor?.offsetParent.getBoundingClientRect().right;
+
+      const rightOverflowNavButtonHidden =
+        scrollLeft + clientWidth === scrollWidth;
+      scrollIntoView &&
+        tab?.tabAnchor?.scrollIntoView({
+          block: 'nearest',
+          inline: 'nearest',
+        });
+
+      // account for overflow buttons in scroll position on mount
+      if (!leftOverflowNavButtonHidden && !rightOverflowNavButtonHidden) {
+        tablist.current.scrollLeft += OVERFLOW_BUTTON_OFFSET * 2;
+      }
+    }
+
+    //component will unmount equivalent
+    return () => {
+      if (_debouncedHandleWindowResize) {
+        _debouncedHandleWindowResize.cancel();
+      }
+      window.removeEventListener('resize', _debouncedHandleWindowResize);
+    };
+  }, [
+    isSelected,
+    scrollIntoView,
+    getTabAt,
+    OVERFLOW_BUTTON_OFFSET,
+    _debouncedHandleWindowResize,
+    _handleWindowResize,
+  ]);
+
+  //component did update equivalent
+  useEffect(() => {
+    // compare current tablist properties to current state
+    const {
+      clientWidth: currentTablistClientWidth,
+      scrollLeft: currentTablistScrollLeft,
+      scrollWidth: currentTablistScrollWidth,
+    } = tablist.current;
+
+    if (
+      currentTablistClientWidth !== tablistClientWidth ||
+      currentTablistScrollLeft !== tablistScrollLeft ||
+      currentTablistScrollWidth !== tablistScrollWidth
+    ) {
+      setTablistClientWidth(currentTablistClientWidth);
+      setTablistScrollWidth(currentTablistScrollWidth);
+      setTablistScrollLeft(currentTablistScrollLeft);
+      setHorizontalOverflow(
+        currentTablistScrollWidth > currentTablistClientWidth
+      );
+    }
+
+    if (scrollIntoView && prevSelected !== isSelected) {
+      getTabAt(isSelected)?.tabAnchor?.scrollIntoView({
+        block: 'nearest',
+        inline: 'nearest',
+      });
+    }
+  }, [
+    isSelected,
+    prevSelected,
+    scrollIntoView,
+    tablistClientWidth,
+    tablistScrollLeft,
+    tablistScrollWidth,
+    getTabAt,
+  ]);
+
+  /**
+   * The tab panel acts like a tab panel when the screen is wider, but acts
+   * like a select list when the screen is narrow.  In the wide case we want
+   * to allow the user to use the tab key to set the focus in the tab panel
+   * and then use the left and right arrow keys to navigate the tabs.  In the
+   * narrow case we want to use the tab key to select different options in
+   * the list.
+   *
+   * We set the tab index based on the different states so the browser will treat
+   * the whole tab panel as a single focus component when it looks like a tab
+   * panel and separate components when it looks like a select list.
+   */
+  const tabsWithProps = getTabs().map((tab, index) => {
+    const tabIndex = index === isSelected ? 0 : -1;
+    const newTab = React.cloneElement(tab, {
+      index,
+      selected: index === isSelected,
+      handleTabClick: handleTabClick(onSelectionChange),
+      tabIndex,
+      ref: (e) => {
+        setTabAt(index, e);
+      },
+      handleTabKeyDown: handleTabKeyDown(onSelectionChange),
+    });
+
+    return newTab;
+  });
+
+  const tabContentWithProps = React.Children.map(tabsWithProps, (tab) => {
+    const {
+      id: tabId,
+      children,
+      selected,
+      renderContent: Content = TabContent,
+    } = tab.props;
+
+    return (
+      <Content
+        id={tabId && `${tabId}__panel`}
+        className={tabContentClassName}
+        hidden={!selected}
+        selected={selected}
+        aria-labelledby={tabId}>
+        {children}
+      </Content>
+    );
+  });
+
+  const leftOverflowNavButtonHidden = !horizontalOverflow || !tablistScrollLeft;
+
+  const rightOverflowNavButtonHidden =
+    !horizontalOverflow ||
+    tablistScrollLeft + tablistClientWidth === tablistScrollWidth;
+
+  const classes = {
+    tabs: classNames(className, `${prefix}--tabs`, {
+      [`${prefix}--tabs--container`]: type === 'container',
+      // [`${prefix}--tabs--light`]: light,
+    }),
+    tablist: classNames(`${prefix}--tabs__nav`),
+    leftOverflowButtonClasses: classNames({
+      [`${prefix}--tab--overflow-nav-button`]: horizontalOverflow,
+      [`${prefix}--tab--overflow-nav-button--hidden`]: leftOverflowNavButtonHidden,
+    }),
+    rightOverflowButtonClasses: classNames({
+      [`${prefix}--tab--overflow-nav-button`]: horizontalOverflow,
+      [`${prefix}--tab--overflow-nav-button--hidden`]: rightOverflowNavButtonHidden,
+    }),
+  };
+
+  return (
+    <>
+      <div
+        className={classes.tabs}
+        onScroll={handleScroll}
+        ref={ref}
+        {...other}>
+        <button
+          aria-hidden="true"
+          aria-label="Scroll left"
+          className={classes.leftOverflowButtonClasses}
+          onClick={(_) => handleOverflowNavClick(_, { direction: -1 })}
+          onMouseDown={(event) =>
+            handleOverflowNavMouseDown(event, { direction: -1 })
+          }
+          onMouseUp={handleOverflowNavMouseUp}
+          ref={leftOverflowNavButton.current}
+          tabIndex="-1"
+          type="button"
+          {...leftOverflowButtonProps}>
+          <ChevronLeft16 />
+        </button>
+        {!leftOverflowNavButtonHidden && (
+          <div className={`${prefix}--tabs__overflow-indicator--left`} />
+        )}
+        <ul
+          role="tablist"
+          tabIndex={-1}
+          className={classes.tablist}
+          ref={tablist.current}>
+          {tabsWithProps}
+        </ul>
+        {!rightOverflowNavButtonHidden && (
+          <div className={`${prefix}--tabs__overflow-indicator--right`} />
+        )}
+        <button
+          aria-hidden="true"
+          aria-label="Scroll right"
+          className={classes.rightOverflowButtonClasses}
+          onClick={(_) => handleOverflowNavClick(_, { direction: 1 })}
+          onMouseDown={(event) =>
+            handleOverflowNavMouseDown(event, { direction: 1 })
+          }
+          onMouseUp={handleOverflowNavMouseUp}
+          ref={rightOverflowNavButton.current}
+          tabIndex="-1"
+          type="button"
+          {...rightOverflowButtonProps}>
+          <ChevronRight16 />
+        </button>
+      </div>
+      {tabContentWithProps}
+    </>
+  );
+});
+
+Tabs.propTypes = {
+  /**
+   * Pass in a collection of <Tab> children to be rendered depending on the
+   * currently selected tab
+   */
+  children: PropTypes.node,
+
+  /**
+   * Provide a className that is applied to the root <div> component for the
+   * <Tabs>
+   */
+  className: PropTypes.string,
+
+  /**
+   * Specify whether the Tab content is hidden
+   */
+  hidden: PropTypes.bool,
+
+  /**
+   * Provide the props that describe the left overflow button
+   */
+  leftOverflowButtonProps: PropTypes.object,
+
+  /**
+   * Specify whether or not to use the light component variant
+   */
+  light: deprecate(
+    PropTypes.bool,
+    'The light prop has been deprecated in v11 in favor of our new layering model that uses the Layer component'
+  ),
+
+  /**
+   * Optionally provide an `onClick` handler that is invoked when a <Tab> is
+   * clicked
+   */
+  onClick: PropTypes.func,
+
+  /**
+   * Optionally provide an `onKeyDown` handler that is invoked when keyed
+   * navigation is triggered
+   */
+  onKeyDown: PropTypes.func,
+
+  /**
+   * Provide an optional handler that is called whenever the selection
+   * changes. This method is called with the index of the tab that was
+   * selected
+   */
+  onSelectionChange: PropTypes.func,
+
+  /**
+   * Provide the props that describe the right overflow button
+   */
+  rightOverflowButtonProps: PropTypes.object,
+
+  /**
+   * Choose whether or not to automatically scroll to newly selected tabs
+   * on component rerender
+   */
+  scrollIntoView: PropTypes.bool,
+
+  /**
+   * Optionally provide an index for the currently selected <Tab>
+   */
+  selected: PropTypes.number,
+
+  /**
+   * Choose whether or not to automatically change selection on focus
+   */
+  selectionMode: PropTypes.oneOf(['automatic', 'manual']),
+
+  /**
+   * Provide a className that is applied to the <TabContent> components
+   */
+  tabContentClassName: PropTypes.string,
+
+  /**
+   * Provide the type of Tab
+   */
+  type: PropTypes.oneOf(['default', 'container']),
+};

From 6d9e103819ab53e108b0ee3f571be0668221e7cc Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 4 Oct 2021 11:20:14 -0500
Subject: [PATCH 03/22] fix: remove console.logs

---
 packages/react/src/components/Tabs/Tabs.js | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/packages/react/src/components/Tabs/Tabs.js b/packages/react/src/components/Tabs/Tabs.js
index 23318658ee04..fa15fb5aba4c 100644
--- a/packages/react/src/components/Tabs/Tabs.js
+++ b/packages/react/src/components/Tabs/Tabs.js
@@ -170,7 +170,6 @@ export default class Tabs extends React.Component {
       scrollLeft: tablistScrollLeft,
       scrollWidth: tablistScrollWidth,
     } = this.tablist?.current || {};
-
     const tab = this.getTabAt(this.state.selected);
     const horizontalOverflow = tablistScrollWidth > tablistClientWidth;
 
@@ -188,7 +187,7 @@ export default class Tabs extends React.Component {
         this.tablist.current.scrollLeft += this.OVERFLOW_BUTTON_OFFSET * 2;
       }
     }
-
+    // remove this before merging!
     console.log('THIS', this);
   }
 
@@ -206,7 +205,6 @@ export default class Tabs extends React.Component {
       scrollLeft: tablistScrollLeft,
       scrollWidth: tablistScrollWidth,
     } = this.tablist.current;
-
     const {
       tablistClientWidth: currentStateClientWidth,
       tablistScrollLeft: currentStateScrollLeft,
@@ -341,8 +339,6 @@ export default class Tabs extends React.Component {
 
   setTabAt = (index, tabRef) => {
     this[`tab${index}`] = tabRef;
-    console.log(this[`tab${index}`]);
-    console.log(tabRef);
   };
 
   overflowNavInterval = null;

From 762860d40f1d39538cac70e4fe861c2ddd634853 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 4 Oct 2021 14:42:51 -0500
Subject: [PATCH 04/22] fix: export components as default

---
 packages/react/src/components/Tab/index.js      | 10 +++++-----
 packages/react/src/components/Tab/next/Tab.js   |  4 +++-
 packages/react/src/components/Tabs/index.js     |  8 +++++---
 packages/react/src/components/Tabs/next/Tabs.js |  4 +++-
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/packages/react/src/components/Tab/index.js b/packages/react/src/components/Tab/index.js
index 754fdd1a0a2f..d76f1b004194 100644
--- a/packages/react/src/components/Tab/index.js
+++ b/packages/react/src/components/Tab/index.js
@@ -6,9 +6,9 @@
  */
 
 import * as FeatureFlags from '@carbon/feature-flags';
-import { Tab as TabNext } from './next/Tab';
-import { Tab as TabClassic } from './Tab';
+import { default as TabNext } from './next/Tab';
+import { default as TabClassic } from './Tab';
 
-export const Tab = FeatureFlags.enabled('enable-v11-release')
-  ? TabNext
-  : TabClassic;
+const Tab = FeatureFlags.enabled('enable-v11-release') ? TabNext : TabClassic;
+
+export default Tab;
diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index 50e76b44f537..a728b2ffee88 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -11,7 +11,7 @@ import classNames from 'classnames';
 import deprecate from '../../../prop-types/deprecate';
 import { usePrefix } from '../../../internal/usePrefix';
 
-export const Tab = React.forwardRef(function Tab(
+const Tab = React.forwardRef(function Tab(
   {
     className,
     disabled,
@@ -172,3 +172,5 @@ Tab.propTypes = {
    */
   tabIndex: PropTypes.number,
 };
+
+export default Tab;
diff --git a/packages/react/src/components/Tabs/index.js b/packages/react/src/components/Tabs/index.js
index 60eead8232eb..ec7ffc66fae8 100644
--- a/packages/react/src/components/Tabs/index.js
+++ b/packages/react/src/components/Tabs/index.js
@@ -6,12 +6,14 @@
  */
 
 import * as FeatureFlags from '@carbon/feature-flags';
-import { Tabs as TabsNext } from './next/Tabs';
-import { Tabs as TabsClassic } from './Tabs';
+import { default as TabsNext } from './next/Tabs';
+import { default as TabsClassic } from './Tabs';
 
-export const Tabs = FeatureFlags.enabled('enable-v11-release')
+const Tabs = FeatureFlags.enabled('enable-v11-release')
   ? TabsNext
   : TabsClassic;
 
 export * from './Tabs.Skeleton';
 // export default from './Tabs';
+
+export default Tabs;
diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 40de9f14c441..535c17fe69aa 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -21,7 +21,7 @@ import TabContent from '../../TabContent';
 import deprecate from '../../../prop-types/deprecate';
 import { usePrefix } from '../../../internal/usePrefix';
 
-export const Tabs = React.forwardRef(function Tabs(
+const Tabs = React.forwardRef(function Tabs(
   {
     children,
     className,
@@ -555,3 +555,5 @@ Tabs.propTypes = {
    */
   type: PropTypes.oneOf(['default', 'container']),
 };
+
+export default Tabs;

From b9d0e4317390ce2569b622026df181528e1a1bc4 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 4 Oct 2021 16:12:00 -0500
Subject: [PATCH 05/22] fix: tabs state and refs

---
 .../react/src/components/Tabs/next/Tabs.js    | 57 +++++++++----------
 1 file changed, 28 insertions(+), 29 deletions(-)

diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 535c17fe69aa..3eb3746f9be0 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -6,13 +6,7 @@
  */
 
 import PropTypes from 'prop-types';
-import React, {
-  useState,
-  useRef,
-  useEffect,
-  useCallback,
-  useMemo,
-} from 'react';
+import React, { useState, useRef, useEffect, useCallback } from 'react';
 import classNames from 'classnames';
 import { ChevronLeft16, ChevronRight16 } from '@carbon/icons-react';
 import debounce from 'lodash.debounce';
@@ -43,20 +37,13 @@ const Tabs = React.forwardRef(function Tabs(
   const tablist = useRef();
   const leftOverflowNavButton = useRef();
   const rightOverflowNavButton = useRef();
+  const tabs = useRef([]);
 
   //state
   const [horizontalOverflow, setHorizontalOverflow] = useState(false);
-  const [tablistClientWidth, setTablistClientWidth] = useState(
-    tablist.current.clientWidth
-  );
-  const [tablistScrollWidth, setTablistScrollWidth] = useState(
-    tablist.current.scrollWidth
-  );
-  const [tablistScrollLeft, setTablistScrollLeft] = useState(
-    tablist.current.scrollLeft
-  );
-
-  let tabs = useMemo(() => {}, []);
+  const [tablistClientWidth, setTablistClientWidth] = useState(null);
+  const [tablistScrollWidth, setTablistScrollWidth] = useState(null);
+  const [tablistScrollLeft, setTablistScrollLeft] = useState(null);
 
   //prop + state alignment - getDerivedStateFromProps
   const [isSelected, setIsSelected] = useState(selected);
@@ -90,9 +77,13 @@ const Tabs = React.forwardRef(function Tabs(
    * @type {Function}
    * @private
    */
-  const _debouncedHandleWindowResize = debounce(_handleWindowResize, 200);
+  const _debouncedHandleWindowResize = useRef();
+
+  const _handleWindowResize = handleScroll;
 
-  const _handleWindowResize = handleScroll();
+  useEffect(() => {
+    _debouncedHandleWindowResize.current = debounce(_handleWindowResize, 200);
+  }, []); // eslint-disable-line react-hooks/exhaustive-deps
 
   const getEnabledTabs = () =>
     React.Children.toArray(children).reduce(
@@ -127,7 +118,7 @@ const Tabs = React.forwardRef(function Tabs(
 
   const getTabAt = useCallback(
     (index, useFresh) =>
-      (!useFresh && tabs[`tab${index}`]) ||
+      (!useFresh && tabs.current[index]) ||
       React.Children.toArray(children)[index],
     [tabs, children]
   );
@@ -204,7 +195,7 @@ const Tabs = React.forwardRef(function Tabs(
   };
 
   const setTabAt = (index, tabRef) => {
-    tabs[`tab${index}`] = tabRef;
+    tabs.current[index] = tabRef;
   };
 
   let overflowNavInterval = null;
@@ -268,10 +259,15 @@ const Tabs = React.forwardRef(function Tabs(
   //component did mount equivalent
   useEffect(() => {
     _handleWindowResize();
-    window.addEventListener('resize', _debouncedHandleWindowResize);
+    window.addEventListener('resize', _debouncedHandleWindowResize.current);
 
     // scroll selected tab into view on mount
     const { clientWidth, scrollLeft, scrollWidth } = tablist?.current || {};
+
+    setTablistClientWidth(clientWidth);
+    setTablistScrollWidth(scrollWidth);
+    setTablistScrollLeft(scrollLeft);
+
     const tab = getTabAt(isSelected);
     const horizontalOverflow = scrollWidth > clientWidth;
 
@@ -296,10 +292,13 @@ const Tabs = React.forwardRef(function Tabs(
 
     //component will unmount equivalent
     return () => {
-      if (_debouncedHandleWindowResize) {
-        _debouncedHandleWindowResize.cancel();
+      if (_debouncedHandleWindowResize.current) {
+        _debouncedHandleWindowResize.current.cancel();
       }
-      window.removeEventListener('resize', _debouncedHandleWindowResize);
+      window.removeEventListener(
+        'resize',
+        _debouncedHandleWindowResize.current
+      );
     };
   }, [
     isSelected,
@@ -434,7 +433,7 @@ const Tabs = React.forwardRef(function Tabs(
             handleOverflowNavMouseDown(event, { direction: -1 })
           }
           onMouseUp={handleOverflowNavMouseUp}
-          ref={leftOverflowNavButton.current}
+          ref={leftOverflowNavButton}
           tabIndex="-1"
           type="button"
           {...leftOverflowButtonProps}>
@@ -447,7 +446,7 @@ const Tabs = React.forwardRef(function Tabs(
           role="tablist"
           tabIndex={-1}
           className={classes.tablist}
-          ref={tablist.current}>
+          ref={tablist}>
           {tabsWithProps}
         </ul>
         {!rightOverflowNavButtonHidden && (
@@ -462,7 +461,7 @@ const Tabs = React.forwardRef(function Tabs(
             handleOverflowNavMouseDown(event, { direction: 1 })
           }
           onMouseUp={handleOverflowNavMouseUp}
-          ref={rightOverflowNavButton.current}
+          ref={rightOverflowNavButton}
           tabIndex="-1"
           type="button"
           {...rightOverflowButtonProps}>

From 047a141f06d56e677645348d0e253381683d64bd Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Tue, 5 Oct 2021 10:08:40 -0500
Subject: [PATCH 06/22] fix: use prefix

---
 packages/react/src/components/Tab/next/Tab.js   | 2 +-
 packages/react/src/components/Tabs/next/Tabs.js | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index a728b2ffee88..4a5637c5e181 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -30,7 +30,7 @@ const Tab = React.forwardRef(function Tab(
   },
   ref
 ) {
-  const { prefix } = usePrefix();
+  const prefix = usePrefix();
 
   const classes = classNames(className, `${prefix}--tabs__nav-link`, {
     [`${prefix}--tabs__nav-item--disabled`]: disabled,
diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 3eb3746f9be0..09ad4e867e59 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -31,7 +31,7 @@ const Tabs = React.forwardRef(function Tabs(
   },
   ref
 ) {
-  const { prefix } = usePrefix();
+  const prefix = usePrefix();
 
   //refs
   const tablist = useRef();

From de12b3aa3e34d21b5360e29f8201033d53d98c4e Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Tue, 5 Oct 2021 10:09:08 -0500
Subject: [PATCH 07/22] fix: add feature flag v11 story

---
 packages/carbon-react/src/components/Tabs/Tabs.stories.js | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/packages/carbon-react/src/components/Tabs/Tabs.stories.js b/packages/carbon-react/src/components/Tabs/Tabs.stories.js
index 08482fdb9108..6d740c04bd60 100644
--- a/packages/carbon-react/src/components/Tabs/Tabs.stories.js
+++ b/packages/carbon-react/src/components/Tabs/Tabs.stories.js
@@ -7,9 +7,17 @@
 
 import React from 'react';
 import { Button, Tab, Tabs, TabsSkeleton } from '../Tabs';
+import { unstable_FeatureFlags as FeatureFlags } from 'carbon-components-react';
 
 export default {
   title: 'Components/Tabs',
+  decorators: [
+    (Story) => (
+      <FeatureFlags flags={{ 'enable-v11-release': true }}>
+        <Story />
+      </FeatureFlags>
+    ),
+  ],
   parameters: {
     component: Tabs,
     subcomponents: {

From 19aaa757264f533cf4c2b83025b16a0224ef9c77 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Tue, 5 Oct 2021 23:20:51 -0500
Subject: [PATCH 08/22] fix: temp use v10 classNames

---
 .../components/src/components/tabs/_tabs.scss | 408 ++++++++++++++++++
 packages/react/src/components/Tab/next/Tab.js |  21 +-
 .../react/src/components/Tabs/next/Tabs.js    |  21 +-
 3 files changed, 440 insertions(+), 10 deletions(-)

diff --git a/packages/components/src/components/tabs/_tabs.scss b/packages/components/src/components/tabs/_tabs.scss
index 8921c57308ba..9856776d533a 100644
--- a/packages/components/src/components/tabs/_tabs.scss
+++ b/packages/components/src/components/tabs/_tabs.scss
@@ -447,6 +447,414 @@
     @include hidden;
   }
 
+  // -----------------------------
+  // v11 styles
+  // -----------------------------
+  @if feature-flag-enabled('enable-v11-release') {
+    .#{$prefix}--skeleton.#{$prefix}--tabs:not(.#{$prefix}--tabs--container)
+      .#{$prefix}--tabs__nav-item {
+      border-bottom: 2px solid $skeleton-02;
+    }
+
+    .#{$prefix}--tabs {
+      @include reset;
+      @include type-style('body-short-01');
+
+      display: flex;
+      width: 100%;
+      height: auto;
+      min-height: rem(40px);
+      color: $text-01;
+
+      &.#{$prefix}--tabs--container {
+        min-height: rem(48px);
+      }
+
+      .#{$prefix}--tabs__nav {
+        display: flex;
+        overflow: auto hidden;
+        width: auto;
+        max-width: 100%;
+        flex-direction: row;
+        padding: 0;
+        margin: 0;
+        list-style: none;
+        outline: 0;
+        // hide scrollbars
+        scrollbar-width: none;
+        transition: max-height $duration--fast-01 motion(standard, productive);
+
+        &::-webkit-scrollbar {
+          display: none;
+        }
+      }
+
+      //-----------------------------
+      // Overflow Nav Buttons
+      //-----------------------------
+      .#{$prefix}--tabs__overflow-indicator--left,
+      .#{$prefix}--tabs__overflow-indicator--right {
+        z-index: 1;
+        width: $carbon--spacing-03;
+        flex: 1 0 auto;
+      }
+
+      .#{$prefix}--tabs__overflow-indicator--left {
+        margin-right: -$carbon--spacing-03;
+        background-image: linear-gradient(to left, transparent, $ui-background);
+      }
+
+      .#{$prefix}--tabs__overflow-indicator--right {
+        margin-left: -$carbon--spacing-03;
+        background-image: linear-gradient(
+          to right,
+          transparent,
+          $ui-background
+        );
+      }
+
+      // .#{$prefix}--tabs--light
+      //   .#{$prefix}--tabs__overflow-indicator--left {
+      //   background-image: linear-gradient(to left, transparent, $ui-01);
+      // }
+
+      // .#{$prefix}--tabs--light
+      //   .#{$prefix}--tabs__overflow-indicator--right {
+      //   background-image: linear-gradient(to right, transparent, $ui-01);
+      // }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__overflow-indicator--left {
+        background-image: linear-gradient(to left, transparent, $ui-03);
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__overflow-indicator--right {
+        background-image: linear-gradient(to right, transparent, $ui-03);
+      }
+
+      // Safari-only media query
+      // won't appear correctly with CSS custom properties
+      // see: code snippet and modal overflow indicators
+      @media not all and (min-resolution: 0.001dpcm) {
+        @supports (-webkit-appearance: none) and (stroke-color: transparent) {
+          .#{$prefix}--tabs__overflow-indicator--left {
+            background-image: linear-gradient(
+              to left,
+              rgba($ui-background, 0),
+              $ui-background
+            );
+          }
+
+          .#{$prefix}--tabs__overflow-indicator--right {
+            background-image: linear-gradient(
+              to right,
+              rgba($ui-background, 0),
+              $ui-background
+            );
+          }
+
+          &.#{$prefix}--tabs--container
+            .#{$prefix}--tabs__overflow-indicator--left {
+            background-image: linear-gradient(to left, rgba($ui-03, 0), $ui-03);
+          }
+
+          &.#{$prefix}--tabs--container
+            .#{$prefix}--tabs__overflow-indicator--right {
+            background-image: linear-gradient(
+              to right,
+              rgba($ui-03, 0),
+              $ui-03
+            );
+          }
+        }
+      }
+
+      .#{$prefix}--tab--overflow-nav-button {
+        @include button-reset;
+
+        display: flex;
+        width: $carbon--spacing-08;
+        flex-shrink: 0;
+        align-items: center;
+        justify-content: center;
+
+        &:focus {
+          @include focus-outline('outline');
+        }
+      }
+
+      .#{$prefix}--tab--overflow-nav-button--hidden {
+        display: none;
+      }
+
+      &.#{$prefix}--tabs--container .#{$prefix}--tab--overflow-nav-button {
+        width: $carbon--spacing-09;
+        margin: 0;
+        background-color: $ui-03;
+      }
+
+      .#{$prefix}--tab--overflow-nav-button svg {
+        fill: $icon-01;
+      }
+
+      //-----------------------------
+      // Item
+      //-----------------------------
+      .#{$prefix}--tabs__nav-item {
+        @include reset;
+
+        display: flex;
+        padding: 0;
+        cursor: pointer;
+        transition: background-color
+          $duration--fast-01
+          motion(standard, productive);
+      }
+
+      .#{$prefix}--tabs__nav-item + .#{$prefix}--tabs__nav-item {
+        margin-left: rem(1px);
+      }
+
+      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item {
+        background-color: $ui-03;
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item
+        + .#{$prefix}--tabs__nav-item {
+        margin-left: 0;
+        // Draws the border without affecting the inner-content
+        box-shadow: rem(-1px) 0 0 0 $ui-04;
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item
+        + .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--selected,
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--selected
+        + .#{$prefix}--tabs__nav-item {
+        box-shadow: none;
+      }
+
+      .#{$prefix}--tabs__nav-item .#{$prefix}--tabs__nav-link {
+        transition: color $duration--fast-01 motion(standard, productive),
+          border-bottom-color $duration--fast-01 motion(standard, productive),
+          outline $duration--fast-01 motion(standard, productive);
+      }
+
+      //-----------------------------
+      // Item Hover
+      //-----------------------------
+      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item:hover {
+        background-color: $hover-selected-ui;
+      }
+
+      //---------------------------------------------
+      // Item Disabled
+      //---------------------------------------------
+      .#{$prefix}--tabs__nav-item--disabled,
+      .#{$prefix}--tabs__nav-item--disabled:hover {
+        background-color: transparent;
+        cursor: not-allowed;
+        outline: none;
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--disabled,
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--disabled:hover {
+        background-color: $disabled-02;
+      }
+
+      //-----------------------------
+      // Item Selected
+      //-----------------------------
+      .#{$prefix}--tabs__nav-item--selected {
+        transition: color $duration--fast-01 motion(standard, productive);
+      }
+
+      .#{$prefix}--tabs__nav-item--selected .#{$prefix}--tabs__nav-link,
+      .#{$prefix}--tabs__nav-item--selected .#{$prefix}--tabs__nav-link:focus,
+      .#{$prefix}--tabs__nav-item--selected .#{$prefix}--tabs__nav-link:active {
+        @include type-style('productive-heading-01');
+
+        border-bottom: 2px solid $interactive-04;
+        color: $text-01;
+      }
+
+      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item--selected,
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item--selected:hover {
+        background-color: $ui-01;
+
+        .#{$prefix}--tabs__nav-link:focus,
+        .#{$prefix}--tabs__nav-link:active {
+          box-shadow: none;
+        }
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item--selected
+        .#{$prefix}--tabs__nav-link {
+        // Draws the border without affecting the inner-content
+        box-shadow: inset 0 2px 0 0 $interactive-04;
+        // height - vertical padding
+        line-height: calc(#{rem(48px)} - (#{$spacing-03} * 2));
+      }
+
+      &.#{$prefix}--tabs--light.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item--selected,
+      &.#{$prefix}--tabs--light.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item--selected:hover {
+        background-color: $ui-background;
+      }
+
+      //-----------------------------
+      // Link
+      //-----------------------------
+      .#{$prefix}--tabs__nav-link {
+        @include button-reset($width: false);
+        @include focus-outline('reset');
+        @include type-style('body-short-01');
+
+        overflow: hidden;
+        width: rem(160px);
+        padding: $spacing-04 $spacing-05 $spacing-03;
+        border-bottom: $tab-underline-color;
+        color: $text-02;
+        text-align: left;
+        text-decoration: none;
+        text-overflow: ellipsis;
+        transition: border $duration--fast-01 motion(standard, productive),
+          outline $duration--fast-01 motion(standard, productive);
+        white-space: nowrap;
+
+        &:focus,
+        &:active {
+          @include focus-outline('outline');
+        }
+      }
+
+      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-link {
+        height: rem(48px);
+        padding: $spacing-03 $spacing-05;
+        border-bottom: 0;
+        // height - vertical padding
+        line-height: calc(#{rem(48px)} - (#{$spacing-03} * 2));
+      }
+
+      //-----------------------------
+      //  Link Hover
+      //-----------------------------
+      .#{$prefix}--tabs__nav-item:hover .#{$prefix}--tabs__nav-link {
+        border-bottom: $tab-underline-color-hover;
+        color: $text-01;
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item
+        .#{$prefix}--tabs__nav-link {
+        border-bottom: none;
+      }
+
+      //-----------------------------
+      //  Link Disabled
+      //-----------------------------
+      .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-link {
+        border-bottom: $tab-underline-disabled;
+        color: $tab-text-disabled;
+      }
+
+      .#{$prefix}--tabs__nav-item--disabled:hover .#{$prefix}--tabs__nav-link {
+        border-bottom: $tab-underline-disabled;
+        color: $tab-text-disabled;
+        cursor: not-allowed;
+        pointer-events: none;
+      }
+
+      .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-link:focus,
+      .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-link:active {
+        border-bottom: $tab-underline-disabled;
+        outline: none;
+      }
+
+      .#{$prefix}--tabs--light
+        .#{$prefix}--tabs__nav-item--disabled
+        .#{$prefix}--tabs__nav-link {
+        border-bottom-color: $ui-03;
+      }
+
+      .#{$prefix}--tabs--light
+        .#{$prefix}--tabs__nav-item--disabled:hover
+        .#{$prefix}--tabs__nav-link {
+        border-bottom-color: $ui-03;
+      }
+
+      .#{$prefix}--tabs--light
+        .#{$prefix}--tabs__nav-item--disabled
+        .#{$prefix}--tabs__nav-link:focus,
+      .#{$prefix}--tabs--light
+        .#{$prefix}--tabs__nav-item--disabled
+        .#{$prefix}--tabs__nav-link:active {
+        border-bottom-color: $ui-03;
+      }
+
+      &.#{$prefix}--tabs--container
+        .#{$prefix}--tabs__nav-item--disabled
+        .#{$prefix}--tabs__nav-link {
+        border-bottom: none;
+        color: $disabled-03;
+      }
+
+      //-----------------------------
+      //  Tab Content Container
+      //-----------------------------
+      .#{$prefix}--tab-content {
+        padding: $carbon--spacing-05;
+      }
+
+      //-----------------------------
+      // Skeleton state
+      //-----------------------------
+      .#{$prefix}--tabs.#{$prefix}--skeleton {
+        cursor: default;
+        pointer-events: none;
+      }
+
+      .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs__nav-link {
+        @include skeleton;
+
+        width: rem(75px);
+      }
+
+      .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs-trigger {
+        @include skeleton;
+
+        width: rem(75px);
+        margin-right: rem(1px);
+      }
+
+      .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs-trigger svg {
+        @include hidden;
+      }
+    }
+
+    // Windows HCM fix
+    .#{$prefix}--tabs__nav-item
+      .#{$prefix}--tabs__nav-item--selected
+      .#{$prefix}--tabs__nav-item--selected {
+      @include high-contrast-mode('focus');
+    }
+
+    // stylelint-disable-next-line no-duplicate-selectors
+    .#{$prefix}--tabs
+      .#{$prefix}--tabs__nav-item--disabled
+      .#{$prefix}--tabs__nav-link {
+      @include high-contrast-mode('disabled');
+    }
+  }
+
   // TODO: remove namespace and suffix in next major release
   .#{$prefix}--tabs--scrollable {
     @include reset;
diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index 4a5637c5e181..f519b6de9d9a 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -32,17 +32,28 @@ const Tab = React.forwardRef(function Tab(
 ) {
   const prefix = usePrefix();
 
-  const classes = classNames(className, `${prefix}--tabs__nav-link`, {
-    [`${prefix}--tabs__nav-item--disabled`]: disabled,
-    [`${prefix}--tabs__nav-item--selected`]: selected,
-  });
+  const classes = classNames(
+    className,
+    // TODO: remove scrollable in next major release
+    // `${prefix}--tabs__nav-item`,
+    `${prefix}--tabs--scrollable__nav-item`,
+    {
+      [`${prefix}--tabs__nav-item--disabled`]: disabled,
+      [`${prefix}--tabs__nav-item--selected`]: selected,
+      // TODO: remove scrollable in next major release
+      [`${prefix}--tabs--scrollable__nav-item--disabled`]: disabled,
+      [`${prefix}--tabs--scrollable__nav-item--selected`]: selected,
+    }
+  );
 
   const buttonProps = {
     ['aria-selected']: selected,
     ['aria-disabled']: disabled,
     ['aria-controls']: id && `${id}__panel`,
     id,
-    className: `${prefix}--tabs__nav-link`,
+    // TODO: remove scrollable in next major release
+    // className:  `${prefix}--tabs__nav-link`,
+    className: `${prefix}--tabs--scrollable__nav-link`,
     tabIndex: !disabled ? tabIndex : -1,
     ref: ref,
   };
diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 09ad4e867e59..ee9cfdea98f1 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -402,11 +402,22 @@ const Tabs = React.forwardRef(function Tabs(
     tablistScrollLeft + tablistClientWidth === tablistScrollWidth;
 
   const classes = {
-    tabs: classNames(className, `${prefix}--tabs`, {
-      [`${prefix}--tabs--container`]: type === 'container',
-      // [`${prefix}--tabs--light`]: light,
-    }),
-    tablist: classNames(`${prefix}--tabs__nav`),
+    // TODO: remove scrollable from classnames in next major release and uncomment classnames that don't contain scrollable
+    tabs: classNames(
+      className,
+      // `${prefix}--tabs`,
+      `${prefix}--tabs--scrollable`,
+      {
+        // [`${prefix}--tabs--container`]: type === 'container',
+        [`${prefix}--tabs--scrollable--container`]: type === 'container',
+        // [`${prefix}--tabs--light`]: light,
+      }
+    ),
+    // TODO: remove scrollable from classnames in next major release and uncomment classnames that don't contain scrollable
+    tablist: classNames(
+      // `${prefix}--tabs__nav`,
+      `${prefix}--tabs--scrollable__nav`
+    ),
     leftOverflowButtonClasses: classNames({
       [`${prefix}--tab--overflow-nav-button`]: horizontalOverflow,
       [`${prefix}--tab--overflow-nav-button--hidden`]: leftOverflowNavButtonHidden,

From 0442bd7917c849c9154a355a2008b3ee7bdf9ca3 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 6 Oct 2021 00:51:45 -0500
Subject: [PATCH 09/22] fix: clean up, comment, and fix select

---
 .../react/src/components/Tabs/next/Tabs.js    | 84 ++++++++++++++-----
 1 file changed, 62 insertions(+), 22 deletions(-)

diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index ee9cfdea98f1..57d079096717 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -39,19 +39,20 @@ const Tabs = React.forwardRef(function Tabs(
   const rightOverflowNavButton = useRef();
   const tabs = useRef([]);
 
-  //state
+  //states
   const [horizontalOverflow, setHorizontalOverflow] = useState(false);
   const [tablistClientWidth, setTablistClientWidth] = useState(null);
   const [tablistScrollWidth, setTablistScrollWidth] = useState(null);
   const [tablistScrollLeft, setTablistScrollLeft] = useState(null);
+  const [isSelected, setIsSelected] = useState(selected);
+  const [prevSelected, setPrevSelected] = useState(null);
 
   //prop + state alignment - getDerivedStateFromProps
-  const [isSelected, setIsSelected] = useState(selected);
-  const [prevSelected, setPrevSelected] = useState(isSelected);
-  if (selected !== prevSelected) {
-    setIsSelected(selected);
-    setPrevSelected(selected);
-  }
+  // THIS IS NOT WORKING!!!!
+  // if (selected !== prevSelected) {
+  //   setIsSelected(selected);
+  //   setPrevSelected(selected);
+  // }
 
   // width of the overflow buttons
   let OVERFLOW_BUTTON_OFFSET = 40;
@@ -81,10 +82,10 @@ const Tabs = React.forwardRef(function Tabs(
 
   const _handleWindowResize = handleScroll;
 
-  useEffect(() => {
-    _debouncedHandleWindowResize.current = debounce(_handleWindowResize, 200);
-  }, []); // eslint-disable-line react-hooks/exhaustive-deps
-
+  /**
+   * returns all tabs that are not disabled
+   * used for keyboard navigation
+   */
   const getEnabledTabs = () =>
     React.Children.toArray(children).reduce(
       (enabledTabs, tab, index) =>
@@ -92,6 +93,10 @@ const Tabs = React.forwardRef(function Tabs(
       []
     );
 
+  /**
+   * returns the index of the next tab we are going to when navigating L/R arrow keys (i.e. 0, 1, 2)
+   * used in handleTabKeyDown to get the next index after keyboard arrow evt, which then updates selected tab
+   */
   const getNextIndex = (index, direction) => {
     const enabledTabs = getEnabledTabs();
     const nextIndex = Math.max(
@@ -106,6 +111,11 @@ const Tabs = React.forwardRef(function Tabs(
     return enabledTabs[nextIndexLooped];
   };
 
+  /**
+   * used as second argument for getNextIndex(i,d)
+   * returns -1, 1 or 0 depending on arrow key
+   * number is then used in math calculations to find the index of the next tab we are navigating to
+   */
   const getDirection = (evt) => {
     if (match(evt, keys.ArrowLeft)) {
       return -1;
@@ -116,6 +126,9 @@ const Tabs = React.forwardRef(function Tabs(
     return 0;
   };
 
+  /**
+   * creates an array of all the child tab items
+   */
   const getTabAt = useCallback(
     (index, useFresh) =>
       (!useFresh && tabs.current[index]) ||
@@ -142,6 +155,11 @@ const Tabs = React.forwardRef(function Tabs(
     }
   };
 
+  /**
+   * selecting tab on click and on keyboard nav
+   * index = tab to be selected, returned in handleTabKeyDown
+   * onSelectionChange = optional prop for event handler
+   */
   const selectTabAt = (event, { index, onSelectionChange }) => {
     scrollTabIntoView(event, { index });
     if (isSelected !== index) {
@@ -153,6 +171,9 @@ const Tabs = React.forwardRef(function Tabs(
     }
   };
 
+  /**
+   *  keyboard event handler
+   */
   const handleTabKeyDown = (onSelectionChange) => {
     return (index, evt) => {
       if (matches(evt, [keys.Enter, keys.Space])) {
@@ -172,6 +193,7 @@ const Tabs = React.forwardRef(function Tabs(
       })();
       const tab = getTabAt(nextIndex);
 
+      // updating selected tab
       if (
         matches(evt, [keys.ArrowLeft, keys.ArrowRight, keys.Home, keys.End])
       ) {
@@ -188,7 +210,11 @@ const Tabs = React.forwardRef(function Tabs(
 
   const getTabs = () => React.Children.map(children, (tab) => tab);
 
-  // following functions (handle*) are Props on Tab.js, see Tab.js for parameters
+  /**
+   *  click handler
+   *  passed down to Tab children as a prop in `tabsWithProps`
+   *  following functions (handle*) are Props on Tab.js, see Tab.js for parameters
+   */
   const handleTabClick = (onSelectionChange) => (index, evt) => {
     evt.preventDefault();
     selectTabAt(evt, { index, onSelectionChange });
@@ -200,6 +226,11 @@ const Tabs = React.forwardRef(function Tabs(
 
   let overflowNavInterval = null;
 
+  /**
+   * group - overflow scroll
+   * scrolling via overflow btn click
+   * click handler for scrollable tabs L/R arrow buttons
+   */
   const handleOverflowNavClick = (_, { direction, multiplier = 10 }) => {
     // account for overflow button appearing and causing tablist width change
     const { clientWidth, scrollLeft, scrollWidth } = tablist?.current;
@@ -226,6 +257,11 @@ const Tabs = React.forwardRef(function Tabs(
     }
   };
 
+  /**
+   * group - overflow scroll
+   * scrolling w/ mouse event
+   * mousedown handler for scrollable tabs
+   */
   const handleOverflowNavMouseDown = (event, { direction }) => {
     // disregard mouse buttons aside from LMB
     if (event.buttons !== 1) {
@@ -252,12 +288,21 @@ const Tabs = React.forwardRef(function Tabs(
     });
   };
 
+  /**
+   * group - overflow scroll
+   * scrolling w/ mouse event
+   * mouseup handler for scrollable tabs
+   */
   const handleOverflowNavMouseUp = () => {
     clearInterval(overflowNavInterval);
   };
 
-  //component did mount equivalent
+  /**
+   * only run once - component did mount equivalent
+   */
   useEffect(() => {
+    _debouncedHandleWindowResize.current = debounce(_handleWindowResize, 200);
+
     _handleWindowResize();
     window.addEventListener('resize', _debouncedHandleWindowResize.current);
 
@@ -300,16 +345,11 @@ const Tabs = React.forwardRef(function Tabs(
         _debouncedHandleWindowResize.current
       );
     };
-  }, [
-    isSelected,
-    scrollIntoView,
-    getTabAt,
-    OVERFLOW_BUTTON_OFFSET,
-    _debouncedHandleWindowResize,
-    _handleWindowResize,
-  ]);
+  }, []); // eslint-disable-line react-hooks/exhaustive-deps
 
-  //component did update equivalent
+  /**
+   * component did update equivalent
+   */
   useEffect(() => {
     // compare current tablist properties to current state
     const {

From d52043ed722f7badbdd60aac2ae7a6580c77ed7b Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 6 Oct 2021 01:09:02 -0500
Subject: [PATCH 10/22] fix: keyboard navigation

---
 .../react/src/components/Tabs/next/Tabs.js    | 20 +++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 57d079096717..7df5bdf4cce2 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -45,14 +45,18 @@ const Tabs = React.forwardRef(function Tabs(
   const [tablistScrollWidth, setTablistScrollWidth] = useState(null);
   const [tablistScrollLeft, setTablistScrollLeft] = useState(null);
   const [isSelected, setIsSelected] = useState(selected);
-  const [prevSelected, setPrevSelected] = useState(null);
+  const [prevSelected, setPrevSelected] = useState(isSelected);
 
-  //prop + state alignment - getDerivedStateFromProps
-  // THIS IS NOT WORKING!!!!
-  // if (selected !== prevSelected) {
-  //   setIsSelected(selected);
-  //   setPrevSelected(selected);
-  // }
+  /**
+   * prop + state alignment - getDerivedStateFromProps
+   * only update if selected prop changes
+   */
+  useEffect(() => {
+    if (selected !== prevSelected) {
+      setIsSelected(selected);
+      setPrevSelected(selected);
+    }
+  }, [selected]); //eslint-disable-line react-hooks/exhaustive-deps
 
   // width of the overflow buttons
   let OVERFLOW_BUTTON_OFFSET = 40;
@@ -203,7 +207,7 @@ const Tabs = React.forwardRef(function Tabs(
         } else {
           scrollTabIntoView(evt, { index: nextIndex });
         }
-        tab?.tabAnchor?.focus();
+        tab?.focus();
       }
     };
   };

From dec0a57318e3d7c9dbc91991f2305c0d301eaf92 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 6 Oct 2021 01:33:55 -0500
Subject: [PATCH 11/22] fix: remove console log

---
 packages/react/src/components/Tabs/Tabs.js | 2 --
 1 file changed, 2 deletions(-)

diff --git a/packages/react/src/components/Tabs/Tabs.js b/packages/react/src/components/Tabs/Tabs.js
index fa15fb5aba4c..7ad962e509cc 100644
--- a/packages/react/src/components/Tabs/Tabs.js
+++ b/packages/react/src/components/Tabs/Tabs.js
@@ -187,8 +187,6 @@ export default class Tabs extends React.Component {
         this.tablist.current.scrollLeft += this.OVERFLOW_BUTTON_OFFSET * 2;
       }
     }
-    // remove this before merging!
-    console.log('THIS', this);
   }
 
   componentWillUnmount() {

From 9917fd252b6101d79c1660291632508d380aa27e Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 11 Oct 2021 16:25:16 -0500
Subject: [PATCH 12/22] chore: tabs comment

---
 packages/react/src/components/Tabs/next/Tabs.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 7df5bdf4cce2..07198cce2250 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -130,9 +130,6 @@ const Tabs = React.forwardRef(function Tabs(
     return 0;
   };
 
-  /**
-   * creates an array of all the child tab items
-   */
   const getTabAt = useCallback(
     (index, useFresh) =>
       (!useFresh && tabs.current[index]) ||
@@ -224,6 +221,9 @@ const Tabs = React.forwardRef(function Tabs(
     selectTabAt(evt, { index, onSelectionChange });
   };
 
+  /**
+   * creates an array of all the child tab items
+   */
   const setTabAt = (index, tabRef) => {
     tabs.current[index] = tabRef;
   };

From 22849a8e9323a785dc015e088b49ba2f5d99adca Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 11 Oct 2021 16:33:18 -0500
Subject: [PATCH 13/22] feat: add tab tests

---
 .../react/src/components/Tab/next/Tab-test.js | 206 ++++++++++++++++++
 1 file changed, 206 insertions(+)
 create mode 100644 packages/react/src/components/Tab/next/Tab-test.js

diff --git a/packages/react/src/components/Tab/next/Tab-test.js b/packages/react/src/components/Tab/next/Tab-test.js
new file mode 100644
index 000000000000..735136ed3ab8
--- /dev/null
+++ b/packages/react/src/components/Tab/next/Tab-test.js
@@ -0,0 +1,206 @@
+import React from 'react';
+import { default as Tab } from './Tab';
+import { cleanup, render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+describe('Tab', () => {
+  afterEach(cleanup);
+
+  it('adds extra classes that are passed via className', async () => {
+    render(
+      <Tab
+        className="custom-class"
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(
+      screen.getByRole('presentation').classList.contains('custom-class')
+    ).toBe(true);
+  });
+
+  it('sets tabIndex on <button> if one is passed via props', async () => {
+    render(
+      <Tab
+        label="Tab 1"
+        // eslint-disable-next-line jsx-a11y/tabindex-no-positive
+        tabIndex={2}
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(screen.getByRole('tab').tabIndex).toEqual(2);
+  });
+
+  it('renders <li> with [role="presentation"]', async () => {
+    render(
+      <Tab
+        className="custom-class"
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(screen.getByRole('presentation')).toBeTruthy();
+  });
+
+  it('renders <button> with tabindex set to 0 by default', async () => {
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(screen.getByRole('tab').tabIndex).toEqual(0);
+  });
+
+  it('renders <button> with tabindex set to -1 if disabled', async () => {
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}
+        disabled>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(screen.getByRole('tab').tabIndex).toEqual(-1);
+  });
+
+  it('uses label to set children on <button> when passed via props', async () => {
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(screen.getByRole('tab').textContent).toBe('Tab 1');
+  });
+
+  it('has aria-disabled that matches disabled', async () => {
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}
+        disabled>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    await expect(screen.getByRole('tab')).toHaveAttribute('aria-disabled');
+  });
+});
+
+describe('Click events', () => {
+  it('invokes handleTabClick from handleTabClick prop', async () => {
+    const handleTabClick = jest.fn();
+    render(
+      <Tab
+        label="Tab 1"
+        handleTabClick={handleTabClick}
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    const button = screen.getByRole('tab');
+    userEvent.click(button);
+    await expect(handleTabClick).toHaveBeenCalled();
+  });
+
+  it('invokes onClick when a function is passed to onClick prop', async () => {
+    const onClick = jest.fn();
+
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={onClick}
+        onKeyDown={() => {}}
+        selected={false}>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    const button = screen.getByRole('tab');
+    userEvent.click(button);
+    await expect(onClick).toHaveBeenCalled();
+  });
+
+  it('does not invoke click handler if tab is disabled', async () => {
+    const onClick = jest.fn();
+
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={onClick}
+        onKeyDown={() => {}}
+        selected={false}
+        disabled>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    const button = screen.getByRole('tab');
+    userEvent.click(button);
+    await expect(onClick).not.toHaveBeenCalled();
+  });
+});
+
+describe('Keyboard events', () => {
+  it('invokes onKeyDown from onKeyDown prop', async () => {
+    const onKeyDown = jest.fn();
+    render(
+      <Tab label="Tab 1" onClick={() => {}} onKeyDown={onKeyDown} selected>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    const button = screen.getByRole('tab');
+    userEvent.type(button, '[ArrowLeft]');
+
+    await expect(onKeyDown).toHaveBeenCalled();
+  });
+
+  it('invokes handleTabKeyDown from handleTabKeyDown prop', async () => {
+    const handleTabKeyDown = jest.fn();
+    render(
+      <Tab
+        label="Tab 1"
+        onClick={() => {}}
+        onKeyDown={() => {}}
+        handleTabKeyDown={handleTabKeyDown}
+        selected>
+        <p>Content for first tab goes here.</p>
+      </Tab>
+    );
+
+    const button = screen.getByRole('tab');
+    userEvent.type(button, '[ArrowRight]');
+
+    await expect(handleTabKeyDown).toHaveBeenCalled();
+  });
+});

From 024a47ebc8d8c42288dba0752a8fa35c8b977be4 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 13 Oct 2021 11:49:56 -0500
Subject: [PATCH 14/22] feat: add tabs tests

---
 packages/react/src/components/Tab/next/Tab.js |   6 +-
 .../src/components/Tabs/next/Tabs-test.js     | 264 ++++++++++++++++++
 2 files changed, 267 insertions(+), 3 deletions(-)
 create mode 100644 packages/react/src/components/Tabs/next/Tabs-test.js

diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index f519b6de9d9a..ad06cd59c92e 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -141,12 +141,12 @@ Tab.propTypes = {
   /**
    * Provide a handler that is invoked when a user clicks on the control
    */
-  onClick: PropTypes.func.isRequired,
+  onClick: PropTypes.func,
 
   /**
    * Provide a handler that is invoked on the key down event for the control
    */
-  onKeyDown: PropTypes.func.isRequired,
+  onKeyDown: PropTypes.func,
 
   /*
    * An optional parameter to allow overriding the anchor rendering.
@@ -176,7 +176,7 @@ Tab.propTypes = {
    * Whether your Tab is selected.
    * Reserved for usage in Tabs
    */
-  selected: PropTypes.bool.isRequired,
+  selected: PropTypes.bool,
 
   /**
    * Specify the tab index of the `<button>` node
diff --git a/packages/react/src/components/Tabs/next/Tabs-test.js b/packages/react/src/components/Tabs/next/Tabs-test.js
new file mode 100644
index 000000000000..c95e6731711a
--- /dev/null
+++ b/packages/react/src/components/Tabs/next/Tabs-test.js
@@ -0,0 +1,264 @@
+import React from 'react';
+import { default as Tabs } from './Tabs';
+import { default as Tab } from '../../Tab/next/Tab';
+import { render, screen } from '@testing-library/react';
+import { fireEvent } from '@testing-library/dom';
+
+describe('Tabs', () => {
+  it('adds extra classes that are passed via className prop', async () => {
+    render(
+      <Tabs className="custom-class" data-testid="tabs-test">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const tabs = screen.getByTestId('tabs-test');
+    await expect(tabs.classList.contains('custom-class')).toBe(true);
+  });
+
+  it('renders <ul> with tablist role by default', async () => {
+    render(
+      <Tabs className="custom-class">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const tablist = screen.getByRole('tablist');
+    await expect(tablist).toBeTruthy();
+  });
+});
+
+describe('Children tabs', () => {
+  it('renders children', async () => {
+    render(
+      <Tabs className="custom-class">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const tabArray = screen.getAllByRole('presentation');
+    await expect(tabArray.length).toEqual(2);
+  });
+
+  it('first tab is selected by default', async () => {
+    render(
+      <Tabs className="custom-class">
+        <Tab label="firstTab" data-testid="first-tab">
+          content1
+        </Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const firstTab = screen.getByTestId('first-tab');
+    await expect(
+      firstTab.classList.contains('bx--tabs__nav-item--selected')
+    ).toBe(true);
+  });
+
+  it('overrides default selected tab when selected prop is provided', async () => {
+    render(
+      <Tabs className="custom-class" selected={1}>
+        <Tab label="firstTab" data-testid="first-tab">
+          content1
+        </Tab>
+        <Tab label="lastTab" data-testid="second-tab">
+          content2
+        </Tab>
+      </Tabs>
+    );
+
+    const firstTab = screen.getByTestId('first-tab');
+    const secondTab = screen.getByTestId('second-tab');
+
+    await expect(
+      firstTab.classList.contains('bx--tabs__nav-item--selected')
+    ).toBe(false);
+    await expect(
+      secondTab.classList.contains('bx--tabs__nav-item--selected')
+    ).toBe(true);
+  });
+});
+
+describe('Children tab content', () => {
+  it('renders correct number of children content as expected', async () => {
+    render(
+      <Tabs className="custom-class">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const contentArray = screen.getAllByRole('tabpanel', { hidden: true });
+    await expect(contentArray.length).toEqual(2);
+  });
+
+  it('only shows one content tabpanel at a time', async () => {
+    render(
+      <Tabs className="custom-class">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="secondTab">content2</Tab>
+        <Tab label="lastTab">content3</Tab>
+      </Tabs>
+    );
+
+    const contentArray = screen.getAllByRole('tabpanel');
+    await expect(contentArray.length).toEqual(1);
+  });
+
+  it('adds extra classes that are passed via tabContentClassName prop', async () => {
+    render(
+      <Tabs tabContentClassName="content-class">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const content = screen.getByRole('tabpanel');
+    await expect(content.classList.contains('content-class')).toBe(true);
+  });
+
+  it('renders unselected tab content with hidden attribute', async () => {
+    render(
+      <Tabs className="custom-class">
+        <Tab label="firstTab">content1</Tab>
+        <Tab label="lastTab">content2</Tab>
+      </Tabs>
+    );
+
+    const contentArray = screen.getAllByRole('tabpanel', { hidden: true });
+    await expect(contentArray[1]).toHaveAttribute('hidden');
+  });
+});
+
+describe('Keyboard events', () => {
+  it('updates selected tab and content, and loops from first tab to last tab when pressing left arrow key', async () => {
+    render(
+      <Tabs>
+        <Tab label="firstTab" data-testid="tab1">
+          content1
+        </Tab>
+        <Tab label="lastTab" data-testid="tab2">
+          content2
+        </Tab>
+      </Tabs>
+    );
+
+    const tab1 = screen.getByTestId('tab1');
+    const tab2 = screen.getByTestId('tab2');
+
+    const tabContent = screen.getAllByRole('tabpanel');
+    const tab1Content = tabContent[0];
+    fireEvent.keyDown(tab1, {
+      key: 'ArrowLeft',
+      code: 'ArrowLeft',
+      charCode: 37,
+    });
+    await expect(tab2.classList.contains('bx--tabs__nav-item--selected')).toBe(
+      true
+    );
+    await expect(tab1Content).toHaveAttribute('hidden');
+  });
+
+  it('updates selected tab and content when pressing right arrow key', async () => {
+    render(
+      <Tabs>
+        <Tab label="firstTab" data-testid="tab1">
+          content1
+        </Tab>
+        <Tab label="lastTab" data-testid="tab2">
+          content2
+        </Tab>
+      </Tabs>
+    );
+
+    const tab1 = screen.getByTestId('tab1');
+    const tab2 = screen.getByTestId('tab2');
+    const tabContent = screen.getAllByRole('tabpanel');
+    const tab1Content = tabContent[0];
+
+    fireEvent.keyDown(tab1, {
+      key: 'ArrowRight',
+      code: 'ArrowRight',
+      charCode: 39,
+    });
+    await expect(tab2.classList.contains('bx--tabs__nav-item--selected')).toBe(
+      true
+    );
+    await expect(tab1Content).toHaveAttribute('hidden');
+  });
+
+  it('ignores disabled tabs', async () => {
+    render(
+      <Tabs>
+        <Tab label="firstTab" data-testid="tab1">
+          content1
+        </Tab>
+        <Tab label="lastTab" data-testid="tab2" disabled>
+          content2
+        </Tab>
+        <Tab label="thirdTab" data-testid="tab3">
+          content3
+        </Tab>
+      </Tabs>
+    );
+    const tab1 = screen.getByTestId('tab1');
+    const tab3 = screen.getByTestId('tab3');
+    fireEvent.keyDown(tab1, {
+      key: 'ArrowRight',
+      code: 'ArrowRight',
+      charCode: 39,
+    });
+
+    await expect(tab3.classList.contains('bx--tabs__nav-item--selected')).toBe(
+      true
+    );
+  });
+});
+
+describe('Click events', () => {
+  it('updates selected tab and content on click', async () => {
+    render(
+      <Tabs>
+        <Tab label="firstTab" data-testid="tab1">
+          content1
+        </Tab>
+        <Tab label="lastTab" data-testid="tab2">
+          content2
+        </Tab>
+      </Tabs>
+    );
+    const tab2 = screen.getByTestId('tab2');
+    const tabContent = screen.getAllByRole('tabpanel');
+    const tab1Content = tabContent[0];
+    fireEvent.click(tab2);
+    await expect(tab2.classList.contains('bx--tabs__nav-item--selected')).toBe(
+      true
+    );
+    await expect(tab1Content).toHaveAttribute('hidden');
+  });
+
+  it('ignores disabled tab on click', async () => {
+    render(
+      <Tabs>
+        <Tab label="firstTab" data-testid="tab1">
+          content1
+        </Tab>
+        <Tab label="lastTab" data-testid="tab2" disabled>
+          content2
+        </Tab>
+      </Tabs>
+    );
+    const tab2 = screen.getByTestId('tab2');
+    const tabContent = screen.getAllByRole('tabpanel', { hidden: true });
+    const tab2Content = tabContent[1];
+    fireEvent.click(tab2);
+    await expect(tab2.classList.contains('bx--tabs__nav-item--selected')).toBe(
+      false
+    );
+    await expect(tab2Content).toHaveAttribute('hidden');
+  });
+});

From f10bda4697717099e2dae1d76403a72b3256de79 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 13 Oct 2021 12:56:51 -0500
Subject: [PATCH 15/22] fix: add back light

---
 .../components/src/components/tabs/_tabs.scss    | 16 +++++++---------
 packages/react/src/components/Tabs/next/Tabs.js  |  2 ++
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/packages/components/src/components/tabs/_tabs.scss b/packages/components/src/components/tabs/_tabs.scss
index 9856776d533a..1815512518ed 100644
--- a/packages/components/src/components/tabs/_tabs.scss
+++ b/packages/components/src/components/tabs/_tabs.scss
@@ -513,15 +513,13 @@
         );
       }
 
-      // .#{$prefix}--tabs--light
-      //   .#{$prefix}--tabs__overflow-indicator--left {
-      //   background-image: linear-gradient(to left, transparent, $ui-01);
-      // }
-
-      // .#{$prefix}--tabs--light
-      //   .#{$prefix}--tabs__overflow-indicator--right {
-      //   background-image: linear-gradient(to right, transparent, $ui-01);
-      // }
+      .#{$prefix}--tabs--light .#{$prefix}--tabs__overflow-indicator--left {
+        background-image: linear-gradient(to left, transparent, $ui-01);
+      }
+
+      .#{$prefix}--tabs--light .#{$prefix}--tabs__overflow-indicator--right {
+        background-image: linear-gradient(to right, transparent, $ui-01);
+      }
 
       &.#{$prefix}--tabs--container
         .#{$prefix}--tabs__overflow-indicator--left {
diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index 07198cce2250..ecb54b8c2ec5 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -20,6 +20,7 @@ const Tabs = React.forwardRef(function Tabs(
     children,
     className,
     leftOverflowButtonProps,
+    light = false,
     onSelectionChange,
     rightOverflowButtonProps,
     scrollIntoView = true,
@@ -455,6 +456,7 @@ const Tabs = React.forwardRef(function Tabs(
         // [`${prefix}--tabs--container`]: type === 'container',
         [`${prefix}--tabs--scrollable--container`]: type === 'container',
         // [`${prefix}--tabs--light`]: light,
+        [`${prefix}--tabs--scrollable--light`]: light,
       }
     ),
     // TODO: remove scrollable from classnames in next major release and uncomment classnames that don't contain scrollable

From 0ef6abddb4310e3b0d9bbadea49a85902a79f63f Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Wed, 13 Oct 2021 13:15:50 -0500
Subject: [PATCH 16/22] fix: remove v11 styles

---
 .../components/src/components/tabs/_tabs.scss | 406 ------------------
 1 file changed, 406 deletions(-)

diff --git a/packages/components/src/components/tabs/_tabs.scss b/packages/components/src/components/tabs/_tabs.scss
index 1815512518ed..8921c57308ba 100644
--- a/packages/components/src/components/tabs/_tabs.scss
+++ b/packages/components/src/components/tabs/_tabs.scss
@@ -447,412 +447,6 @@
     @include hidden;
   }
 
-  // -----------------------------
-  // v11 styles
-  // -----------------------------
-  @if feature-flag-enabled('enable-v11-release') {
-    .#{$prefix}--skeleton.#{$prefix}--tabs:not(.#{$prefix}--tabs--container)
-      .#{$prefix}--tabs__nav-item {
-      border-bottom: 2px solid $skeleton-02;
-    }
-
-    .#{$prefix}--tabs {
-      @include reset;
-      @include type-style('body-short-01');
-
-      display: flex;
-      width: 100%;
-      height: auto;
-      min-height: rem(40px);
-      color: $text-01;
-
-      &.#{$prefix}--tabs--container {
-        min-height: rem(48px);
-      }
-
-      .#{$prefix}--tabs__nav {
-        display: flex;
-        overflow: auto hidden;
-        width: auto;
-        max-width: 100%;
-        flex-direction: row;
-        padding: 0;
-        margin: 0;
-        list-style: none;
-        outline: 0;
-        // hide scrollbars
-        scrollbar-width: none;
-        transition: max-height $duration--fast-01 motion(standard, productive);
-
-        &::-webkit-scrollbar {
-          display: none;
-        }
-      }
-
-      //-----------------------------
-      // Overflow Nav Buttons
-      //-----------------------------
-      .#{$prefix}--tabs__overflow-indicator--left,
-      .#{$prefix}--tabs__overflow-indicator--right {
-        z-index: 1;
-        width: $carbon--spacing-03;
-        flex: 1 0 auto;
-      }
-
-      .#{$prefix}--tabs__overflow-indicator--left {
-        margin-right: -$carbon--spacing-03;
-        background-image: linear-gradient(to left, transparent, $ui-background);
-      }
-
-      .#{$prefix}--tabs__overflow-indicator--right {
-        margin-left: -$carbon--spacing-03;
-        background-image: linear-gradient(
-          to right,
-          transparent,
-          $ui-background
-        );
-      }
-
-      .#{$prefix}--tabs--light .#{$prefix}--tabs__overflow-indicator--left {
-        background-image: linear-gradient(to left, transparent, $ui-01);
-      }
-
-      .#{$prefix}--tabs--light .#{$prefix}--tabs__overflow-indicator--right {
-        background-image: linear-gradient(to right, transparent, $ui-01);
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__overflow-indicator--left {
-        background-image: linear-gradient(to left, transparent, $ui-03);
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__overflow-indicator--right {
-        background-image: linear-gradient(to right, transparent, $ui-03);
-      }
-
-      // Safari-only media query
-      // won't appear correctly with CSS custom properties
-      // see: code snippet and modal overflow indicators
-      @media not all and (min-resolution: 0.001dpcm) {
-        @supports (-webkit-appearance: none) and (stroke-color: transparent) {
-          .#{$prefix}--tabs__overflow-indicator--left {
-            background-image: linear-gradient(
-              to left,
-              rgba($ui-background, 0),
-              $ui-background
-            );
-          }
-
-          .#{$prefix}--tabs__overflow-indicator--right {
-            background-image: linear-gradient(
-              to right,
-              rgba($ui-background, 0),
-              $ui-background
-            );
-          }
-
-          &.#{$prefix}--tabs--container
-            .#{$prefix}--tabs__overflow-indicator--left {
-            background-image: linear-gradient(to left, rgba($ui-03, 0), $ui-03);
-          }
-
-          &.#{$prefix}--tabs--container
-            .#{$prefix}--tabs__overflow-indicator--right {
-            background-image: linear-gradient(
-              to right,
-              rgba($ui-03, 0),
-              $ui-03
-            );
-          }
-        }
-      }
-
-      .#{$prefix}--tab--overflow-nav-button {
-        @include button-reset;
-
-        display: flex;
-        width: $carbon--spacing-08;
-        flex-shrink: 0;
-        align-items: center;
-        justify-content: center;
-
-        &:focus {
-          @include focus-outline('outline');
-        }
-      }
-
-      .#{$prefix}--tab--overflow-nav-button--hidden {
-        display: none;
-      }
-
-      &.#{$prefix}--tabs--container .#{$prefix}--tab--overflow-nav-button {
-        width: $carbon--spacing-09;
-        margin: 0;
-        background-color: $ui-03;
-      }
-
-      .#{$prefix}--tab--overflow-nav-button svg {
-        fill: $icon-01;
-      }
-
-      //-----------------------------
-      // Item
-      //-----------------------------
-      .#{$prefix}--tabs__nav-item {
-        @include reset;
-
-        display: flex;
-        padding: 0;
-        cursor: pointer;
-        transition: background-color
-          $duration--fast-01
-          motion(standard, productive);
-      }
-
-      .#{$prefix}--tabs__nav-item + .#{$prefix}--tabs__nav-item {
-        margin-left: rem(1px);
-      }
-
-      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item {
-        background-color: $ui-03;
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item
-        + .#{$prefix}--tabs__nav-item {
-        margin-left: 0;
-        // Draws the border without affecting the inner-content
-        box-shadow: rem(-1px) 0 0 0 $ui-04;
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item
-        + .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--selected,
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--selected
-        + .#{$prefix}--tabs__nav-item {
-        box-shadow: none;
-      }
-
-      .#{$prefix}--tabs__nav-item .#{$prefix}--tabs__nav-link {
-        transition: color $duration--fast-01 motion(standard, productive),
-          border-bottom-color $duration--fast-01 motion(standard, productive),
-          outline $duration--fast-01 motion(standard, productive);
-      }
-
-      //-----------------------------
-      // Item Hover
-      //-----------------------------
-      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item:hover {
-        background-color: $hover-selected-ui;
-      }
-
-      //---------------------------------------------
-      // Item Disabled
-      //---------------------------------------------
-      .#{$prefix}--tabs__nav-item--disabled,
-      .#{$prefix}--tabs__nav-item--disabled:hover {
-        background-color: transparent;
-        cursor: not-allowed;
-        outline: none;
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--disabled,
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--disabled:hover {
-        background-color: $disabled-02;
-      }
-
-      //-----------------------------
-      // Item Selected
-      //-----------------------------
-      .#{$prefix}--tabs__nav-item--selected {
-        transition: color $duration--fast-01 motion(standard, productive);
-      }
-
-      .#{$prefix}--tabs__nav-item--selected .#{$prefix}--tabs__nav-link,
-      .#{$prefix}--tabs__nav-item--selected .#{$prefix}--tabs__nav-link:focus,
-      .#{$prefix}--tabs__nav-item--selected .#{$prefix}--tabs__nav-link:active {
-        @include type-style('productive-heading-01');
-
-        border-bottom: 2px solid $interactive-04;
-        color: $text-01;
-      }
-
-      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item--selected,
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item--selected:hover {
-        background-color: $ui-01;
-
-        .#{$prefix}--tabs__nav-link:focus,
-        .#{$prefix}--tabs__nav-link:active {
-          box-shadow: none;
-        }
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item--selected
-        .#{$prefix}--tabs__nav-link {
-        // Draws the border without affecting the inner-content
-        box-shadow: inset 0 2px 0 0 $interactive-04;
-        // height - vertical padding
-        line-height: calc(#{rem(48px)} - (#{$spacing-03} * 2));
-      }
-
-      &.#{$prefix}--tabs--light.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item--selected,
-      &.#{$prefix}--tabs--light.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item--selected:hover {
-        background-color: $ui-background;
-      }
-
-      //-----------------------------
-      // Link
-      //-----------------------------
-      .#{$prefix}--tabs__nav-link {
-        @include button-reset($width: false);
-        @include focus-outline('reset');
-        @include type-style('body-short-01');
-
-        overflow: hidden;
-        width: rem(160px);
-        padding: $spacing-04 $spacing-05 $spacing-03;
-        border-bottom: $tab-underline-color;
-        color: $text-02;
-        text-align: left;
-        text-decoration: none;
-        text-overflow: ellipsis;
-        transition: border $duration--fast-01 motion(standard, productive),
-          outline $duration--fast-01 motion(standard, productive);
-        white-space: nowrap;
-
-        &:focus,
-        &:active {
-          @include focus-outline('outline');
-        }
-      }
-
-      &.#{$prefix}--tabs--container .#{$prefix}--tabs__nav-link {
-        height: rem(48px);
-        padding: $spacing-03 $spacing-05;
-        border-bottom: 0;
-        // height - vertical padding
-        line-height: calc(#{rem(48px)} - (#{$spacing-03} * 2));
-      }
-
-      //-----------------------------
-      //  Link Hover
-      //-----------------------------
-      .#{$prefix}--tabs__nav-item:hover .#{$prefix}--tabs__nav-link {
-        border-bottom: $tab-underline-color-hover;
-        color: $text-01;
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item
-        .#{$prefix}--tabs__nav-link {
-        border-bottom: none;
-      }
-
-      //-----------------------------
-      //  Link Disabled
-      //-----------------------------
-      .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-link {
-        border-bottom: $tab-underline-disabled;
-        color: $tab-text-disabled;
-      }
-
-      .#{$prefix}--tabs__nav-item--disabled:hover .#{$prefix}--tabs__nav-link {
-        border-bottom: $tab-underline-disabled;
-        color: $tab-text-disabled;
-        cursor: not-allowed;
-        pointer-events: none;
-      }
-
-      .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-link:focus,
-      .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-link:active {
-        border-bottom: $tab-underline-disabled;
-        outline: none;
-      }
-
-      .#{$prefix}--tabs--light
-        .#{$prefix}--tabs__nav-item--disabled
-        .#{$prefix}--tabs__nav-link {
-        border-bottom-color: $ui-03;
-      }
-
-      .#{$prefix}--tabs--light
-        .#{$prefix}--tabs__nav-item--disabled:hover
-        .#{$prefix}--tabs__nav-link {
-        border-bottom-color: $ui-03;
-      }
-
-      .#{$prefix}--tabs--light
-        .#{$prefix}--tabs__nav-item--disabled
-        .#{$prefix}--tabs__nav-link:focus,
-      .#{$prefix}--tabs--light
-        .#{$prefix}--tabs__nav-item--disabled
-        .#{$prefix}--tabs__nav-link:active {
-        border-bottom-color: $ui-03;
-      }
-
-      &.#{$prefix}--tabs--container
-        .#{$prefix}--tabs__nav-item--disabled
-        .#{$prefix}--tabs__nav-link {
-        border-bottom: none;
-        color: $disabled-03;
-      }
-
-      //-----------------------------
-      //  Tab Content Container
-      //-----------------------------
-      .#{$prefix}--tab-content {
-        padding: $carbon--spacing-05;
-      }
-
-      //-----------------------------
-      // Skeleton state
-      //-----------------------------
-      .#{$prefix}--tabs.#{$prefix}--skeleton {
-        cursor: default;
-        pointer-events: none;
-      }
-
-      .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs__nav-link {
-        @include skeleton;
-
-        width: rem(75px);
-      }
-
-      .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs-trigger {
-        @include skeleton;
-
-        width: rem(75px);
-        margin-right: rem(1px);
-      }
-
-      .#{$prefix}--tabs.#{$prefix}--skeleton .#{$prefix}--tabs-trigger svg {
-        @include hidden;
-      }
-    }
-
-    // Windows HCM fix
-    .#{$prefix}--tabs__nav-item
-      .#{$prefix}--tabs__nav-item--selected
-      .#{$prefix}--tabs__nav-item--selected {
-      @include high-contrast-mode('focus');
-    }
-
-    // stylelint-disable-next-line no-duplicate-selectors
-    .#{$prefix}--tabs
-      .#{$prefix}--tabs__nav-item--disabled
-      .#{$prefix}--tabs__nav-link {
-      @include high-contrast-mode('disabled');
-    }
-  }
-
   // TODO: remove namespace and suffix in next major release
   .#{$prefix}--tabs--scrollable {
     @include reset;

From a5d0e6550272ad42dbdde4e3da0e8d945db41634 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com>
Date: Mon, 18 Oct 2021 15:21:54 -0500
Subject: [PATCH 17/22] Update packages/react/src/components/Tabs/index.js

Co-authored-by: Taylor Jones <tay1orjones@users.noreply.github.com>
---
 packages/react/src/components/Tabs/index.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/react/src/components/Tabs/index.js b/packages/react/src/components/Tabs/index.js
index ec7ffc66fae8..989fb9845fb8 100644
--- a/packages/react/src/components/Tabs/index.js
+++ b/packages/react/src/components/Tabs/index.js
@@ -14,6 +14,5 @@ const Tabs = FeatureFlags.enabled('enable-v11-release')
   : TabsClassic;
 
 export * from './Tabs.Skeleton';
-// export default from './Tabs';
 
 export default Tabs;

From e7ab851d13a7caae89b076c9f285d375abd8cc3b Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 18 Oct 2021 16:09:00 -0500
Subject: [PATCH 18/22] fix: next tab test and deprecation

---
 .../react/src/components/Tab/next/Tab-test.js |  4 +--
 packages/react/src/components/Tab/next/Tab.js | 27 -------------------
 2 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/packages/react/src/components/Tab/next/Tab-test.js b/packages/react/src/components/Tab/next/Tab-test.js
index 735136ed3ab8..78a2f5447278 100644
--- a/packages/react/src/components/Tab/next/Tab-test.js
+++ b/packages/react/src/components/Tab/next/Tab-test.js
@@ -1,11 +1,9 @@
 import React from 'react';
 import { default as Tab } from './Tab';
-import { cleanup, render, screen } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 
 describe('Tab', () => {
-  afterEach(cleanup);
-
   it('adds extra classes that are passed via className', async () => {
     render(
       <Tab
diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index ad06cd59c92e..bc2a7705e592 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -8,7 +8,6 @@
 import PropTypes from 'prop-types';
 import React from 'react';
 import classNames from 'classnames';
-import deprecate from '../../../prop-types/deprecate';
 import { usePrefix } from '../../../internal/usePrefix';
 
 const Tab = React.forwardRef(function Tab(
@@ -23,7 +22,6 @@ const Tab = React.forwardRef(function Tab(
     onClick = () => {},
     onKeyDown = () => {},
     renderButton,
-    renderContent, // eslint-disable-line no-unused-vars
     selected = false,
     tabIndex = 0,
     ...other
@@ -115,14 +113,6 @@ Tab.propTypes = {
    */
   handleTabKeyDown: PropTypes.func,
 
-  /**
-   * Provide a string that represents the `href` of the Tab
-   */
-  href: deprecate(
-    PropTypes.string,
-    'The href prop has been deprecated and removed in v11.'
-  ),
-
   /**
    * The element ID for the top-level element.
    */
@@ -153,25 +143,8 @@ Tab.propTypes = {
    * Useful for using Tab along with react-router or other client
    * side router libraries.
    **/
-  renderAnchor: deprecate(
-    PropTypes.func,
-    'The renderAnchor prop has been deprecated in favor of renderButton. It has been removed in v11.'
-  ),
   renderButton: PropTypes.func,
 
-  /*
-   * An optional parameter to allow overriding the content rendering.
-   **/
-  renderContent: PropTypes.func,
-
-  /**
-   * Provide an accessibility role for your Tab
-   */
-  role: deprecate(
-    PropTypes.string,
-    'The role prop has been deprecated and removed in v11. Role is now built into the element.'
-  ),
-
   /**
    * Whether your Tab is selected.
    * Reserved for usage in Tabs

From 730f9d8e5c86863dcc1cd979050917a03235d40f Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 18 Oct 2021 16:10:04 -0500
Subject: [PATCH 19/22] fix: tabs deprecate unused props

---
 .../react/__tests__/__snapshots__/PublicAPI-test.js.snap | 9 ++-------
 packages/react/src/components/Tab/Tab.js                 | 5 +++--
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
index 248de768906b..071ff6d93c30 100644
--- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
+++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
@@ -5865,13 +5865,8 @@ Map {
       "renderButton": Object {
         "type": "func",
       },
-      "renderContent": Object {
-        "type": "func",
-      },
-      "role": Object {
-        "isRequired": true,
-        "type": "string",
-      },
+      "renderContent": [Function],
+      "role": [Function],
       "selected": Object {
         "isRequired": true,
         "type": "bool",
diff --git a/packages/react/src/components/Tab/Tab.js b/packages/react/src/components/Tab/Tab.js
index 1a746eb731c1..eea4669bb686 100644
--- a/packages/react/src/components/Tab/Tab.js
+++ b/packages/react/src/components/Tab/Tab.js
@@ -77,12 +77,12 @@ export default class Tab extends React.Component {
     /*
      * An optional parameter to allow overriding the content rendering.
      **/
-    renderContent: PropTypes.func,
+    renderContent: deprecate(PropTypes.func),
 
     /**
      * Provide an accessibility role for your Tab
      */
-    role: PropTypes.string.isRequired,
+    role: deprecate(PropTypes.string),
 
     /**
      * Whether your Tab is selected.
@@ -122,6 +122,7 @@ export default class Tab extends React.Component {
       renderAnchor,
       renderButton,
       renderContent, // eslint-disable-line no-unused-vars
+      role, // eslint-disable-line no-unused-vars
       ...other
     } = this.props;
 

From 2e8925ff902db1afcc00c9ea5e20085ed0ed0fa7 Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 18 Oct 2021 17:00:15 -0500
Subject: [PATCH 20/22] fix: deprecations'

---
 .../react/__tests__/__snapshots__/PublicAPI-test.js.snap    | 5 +++--
 packages/react/src/components/Tab/Tab.js                    | 3 +--
 packages/react/src/components/Tab/next/Tab.js               | 6 ++++++
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
index 35a054f26a32..6223d424aed7 100644
--- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
+++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
@@ -5905,7 +5905,6 @@ Map {
       "label": "provide a label",
       "onClick": [Function],
       "onKeyDown": [Function],
-      "role": "presentation",
       "selected": false,
     },
     "propTypes": Object {
@@ -5943,7 +5942,9 @@ Map {
       "renderButton": Object {
         "type": "func",
       },
-      "renderContent": [Function],
+      "renderContent": Object {
+        "type": "func",
+      },
       "role": [Function],
       "selected": Object {
         "isRequired": true,
diff --git a/packages/react/src/components/Tab/Tab.js b/packages/react/src/components/Tab/Tab.js
index eea4669bb686..6329e625edc0 100644
--- a/packages/react/src/components/Tab/Tab.js
+++ b/packages/react/src/components/Tab/Tab.js
@@ -77,7 +77,7 @@ export default class Tab extends React.Component {
     /*
      * An optional parameter to allow overriding the content rendering.
      **/
-    renderContent: deprecate(PropTypes.func),
+    renderContent: PropTypes.func,
 
     /**
      * Provide an accessibility role for your Tab
@@ -97,7 +97,6 @@ export default class Tab extends React.Component {
   };
 
   static defaultProps = {
-    role: 'presentation',
     label: 'provide a label',
     selected: false,
     onClick: () => {},
diff --git a/packages/react/src/components/Tab/next/Tab.js b/packages/react/src/components/Tab/next/Tab.js
index bc2a7705e592..40be07b3b1cb 100644
--- a/packages/react/src/components/Tab/next/Tab.js
+++ b/packages/react/src/components/Tab/next/Tab.js
@@ -22,6 +22,7 @@ const Tab = React.forwardRef(function Tab(
     onClick = () => {},
     onKeyDown = () => {},
     renderButton,
+    renderContent, // eslint-disable-line no-unused-vars
     selected = false,
     tabIndex = 0,
     ...other
@@ -145,6 +146,11 @@ Tab.propTypes = {
    **/
   renderButton: PropTypes.func,
 
+  /*
+   * An optional parameter to allow overriding the content rendering.
+   **/
+  renderContent: PropTypes.func,
+
   /**
    * Whether your Tab is selected.
    * Reserved for usage in Tabs

From 6be4cb3b18058bd88061104866e75620140e90cf Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Mon, 18 Oct 2021 17:11:32 -0500
Subject: [PATCH 21/22] fix: tab role presentation test

---
 packages/react/src/components/Tab/Tab-test.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/react/src/components/Tab/Tab-test.js b/packages/react/src/components/Tab/Tab-test.js
index f28a9e157f99..f84b5668a6ac 100644
--- a/packages/react/src/components/Tab/Tab-test.js
+++ b/packages/react/src/components/Tab/Tab-test.js
@@ -45,7 +45,7 @@ describe('Tab', () => {
     });
 
     it('renders <li> with [role="presentation"]', () => {
-      expect(wrapper.props().role).toEqual('presentation');
+      expect(wrapper.find('li').prop('role')).toEqual('presentation');
     });
 
     it('renders <button> with tabindex set to 0', () => {

From aa706cc31f930779d05e4fe11df7ab42aeabce9d Mon Sep 17 00:00:00 2001
From: Josefina Mancilla <josefinanoemi4@gmail.com>
Date: Tue, 19 Oct 2021 13:22:20 -0500
Subject: [PATCH 22/22] fix: remove unused arg'

---
 packages/react/src/components/Tabs/next/Tabs.js | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/packages/react/src/components/Tabs/next/Tabs.js b/packages/react/src/components/Tabs/next/Tabs.js
index ecb54b8c2ec5..c94a46d8719d 100644
--- a/packages/react/src/components/Tabs/next/Tabs.js
+++ b/packages/react/src/components/Tabs/next/Tabs.js
@@ -132,9 +132,7 @@ const Tabs = React.forwardRef(function Tabs(
   };
 
   const getTabAt = useCallback(
-    (index, useFresh) =>
-      (!useFresh && tabs.current[index]) ||
-      React.Children.toArray(children)[index],
+    (index) => tabs.current[index] || React.Children.toArray(children)[index],
     [tabs, children]
   );