<commit_before>import * as React from 'react';
import classnames from 'classnames';
import TabScroller from '@material/react-tab-scroller';
import Tab, {TabProps} from '@material/react-tab'; // eslint-disable-line no-unused-vars
// @ts-ignore No mdc .d.ts files
import {MDCTabBarFoundation} from '@material/tab-bar/dist/mdc.tabBar';

export interface TabBarProps extends React.HTMLAttributes<HTMLDivElement> {
  indexInView?: number;
  activeIndex: number;
  handleActiveIndexUpdate?: (index: number) => void;
  className?: string;
  isRtl?: boolean;
  children: React.ReactElement<TabProps> | React.ReactElement<TabProps>[];
};

interface TabBarState {
  previousActiveIndex: number;
};

class TabBar extends React.Component<
  TabBarProps, TabBarState
  > {
  tabBarRef: React.RefObject<HTMLDivElement> = React.createRef();
  tabScrollerRef: React.RefObject<TabScroller> = React.createRef();
  tabList: Tab[] = [];
  foundation?: MDCTabBarFoundation;

  constructor(props: TabBarProps) {
    super(props);
    this.state = {
      previousActiveIndex: props.activeIndex,
    };
  }

  static defaultProps: Partial<TabBarProps> = {
    indexInView: 0,
    activeIndex: 0,
    handleActiveIndexUpdate: () => {},
    className: '',
    children: [],
    isRtl: false,
  };

  componentDidMount() {
    this.foundation = new MDCTabBarFoundation(this.adapter);
    this.foundation.init();
    const {activeIndex, indexInView} = this.props;
    if (this.tabList[activeIndex]) {
      this.tabList[activeIndex].activate({} /* previousIndicatorClientRect */);
    }
    this.foundation.scrollIntoView(indexInView);
  }

  componentDidUpdate(prevProps: TabBarProps) {
    if (this.props.activeIndex !== prevProps.activeIndex) {
      this.setState({previousActiveIndex: prevProps.activeIndex}, () =>
        this.foundation.activateTab(this.props.activeIndex)
      );
    }
    if (this.props.indexInView !== prevProps.indexInView) {
      this.foundation.scrollIntoView(this.props.indexInView);
    }
  }

  componentWillUnmount() {
    this.foundation.destroy();
  }

  get classes() {
    return classnames('mdc-tab-bar', this.props.className);
  }

  get adapter() {
    return {
      scrollTo: (scrollX: number) => {
        this.tabScrollerRef.current && this.tabScrollerRef.current.scrollTo(scrollX);
      },
      incrementScroll: (scrollXIncrement: number) => {
        this.tabScrollerRef.current && this.tabScrollerRef.current.incrementScroll(scrollXIncrement);
      },
      getScrollPosition: () => {
        if (!this.tabScrollerRef.current) return;
        return this.tabScrollerRef.current.getScrollPosition();
      },
      getScrollContentWidth: () => {
        if (!this.tabScrollerRef.current) return;
        this.tabScrollerRef.current.getScrollContentWidth();
      },
      getOffsetWidth: () => {
        if (this.tabBarRef.current === null) return;
        return this.tabBarRef.current.offsetWidth;
      },
      isRTL: () => !!this.props.isRtl,
      setActiveTab: (index: number) => {
        if (!this.props.handleActiveIndexUpdate) return;
        this.props.handleActiveIndexUpdate(index);
      },
      activateTabAtIndex: (index: number, clientRect: ClientRect) =>
        this.tabList[index].activate(clientRect),
      deactivateTabAtIndex: (index: number) => this.tabList[index].deactivate(),
      focusTabAtIndex: (index: number) => this.tabList[index].focus(),
      getTabIndicatorClientRectAtIndex: (index: number) =>
        this.tabList[index].computeIndicatorClientRect(),
      getTabDimensionsAtIndex: (index: number) =>
        this.tabList[index].computeDimensions(),
      getPreviousActiveTabIndex: () => this.state.previousActiveIndex,
      getFocusedTabIndex: () => {<commit_msg>fix(tab): return ScrollContentWidth (#633)<commit_after>import * as React from 'react';
import classnames from 'classnames';
import TabScroller from '@material/react-tab-scroller';
import Tab, {TabProps} from '@material/react-tab'; // eslint-disable-line no-unused-vars
// @ts-ignore No mdc .d.ts files
import {MDCTabBarFoundation} from '@material/tab-bar/dist/mdc.tabBar';

export interface TabBarProps extends React.HTMLAttributes<HTMLDivElement> {
  indexInView?: number;
  activeIndex: number;
  handleActiveIndexUpdate?: (index: number) => void;
  className?: string;
  isRtl?: boolean;
  children: React.ReactElement<TabProps> | React.ReactElement<TabProps>[];
};

interface TabBarState {
  previousActiveIndex: number;
};

class TabBar extends React.Component<
  TabBarProps, TabBarState
  > {
  tabBarRef: React.RefObject<HTMLDivElement> = React.createRef();
  tabScrollerRef: React.RefObject<TabScroller> = React.createRef();
  tabList: Tab[] = [];
  foundation?: MDCTabBarFoundation;

  constructor(props: TabBarProps) {
    super(props);
    this.state = {
      previousActiveIndex: props.activeIndex,
    };
  }

  static defaultProps: Partial<TabBarProps> = {
    indexInView: 0,
    activeIndex: 0,
    handleActiveIndexUpdate: () => {},
    className: '',
    children: [],
    isRtl: false,
  };

  componentDidMount() {
    this.foundation = new MDCTabBarFoundation(this.adapter);
    this.foundation.init();
    const {activeIndex, indexInView} = this.props;
    if (this.tabList[activeIndex]) {
      this.tabList[activeIndex].activate({} /* previousIndicatorClientRect */);
    }
    this.foundation.scrollIntoView(indexInView);
  }

  componentDidUpdate(prevProps: TabBarProps) {
    if (this.props.activeIndex !== prevProps.activeIndex) {
      this.setState({previousActiveIndex: prevProps.activeIndex}, () =>
        this.foundation.activateTab(this.props.activeIndex)
      );
    }
    if (this.props.indexInView !== prevProps.indexInView) {
      this.foundation.scrollIntoView(this.props.indexInView);
    }
  }

  componentWillUnmount() {
    this.foundation.destroy();
  }

  get classes() {
    return classnames('mdc-tab-bar', this.props.className);
  }

  get adapter() {
    return {
      scrollTo: (scrollX: number) => {
        this.tabScrollerRef.current && this.tabScrollerRef.current.scrollTo(scrollX);
      },
      incrementScroll: (scrollXIncrement: number) => {
        this.tabScrollerRef.current && this.tabScrollerRef.current.incrementScroll(scrollXIncrement);
      },
      getScrollPosition: () => {
        if (!this.tabScrollerRef.current) return;
        return this.tabScrollerRef.current.getScrollPosition();
      },
      getScrollContentWidth: () => {
        if (!this.tabScrollerRef.current) return;
        return this.tabScrollerRef.current.getScrollContentWidth();
      },
      getOffsetWidth: () => {
        if (this.tabBarRef.current === null) return;
        return this.tabBarRef.current.offsetWidth;
      },
      isRTL: () => !!this.props.isRtl,
      setActiveTab: (index: number) => {
        if (!this.props.handleActiveIndexUpdate) return;
        this.props.handleActiveIndexUpdate(index);
      },
      activateTabAtIndex: (index: number, clientRect: ClientRect) =>
        this.tabList[index].activate(clientRect),
      deactivateTabAtIndex: (index: number) => this.tabList[index].deactivate(),
      focusTabAtIndex: (index: number) => this.tabList[index].focus(),
      getTabIndicatorClientRectAtIndex: (index: number) =>
        this.tabList[index].computeIndicatorClientRect(),
      getTabDimensionsAtIndex: (index: number) =>
        this.tabList[index].computeDimensions(),
      getPreviousActiveTabIndex: () => this.state.previousActiveIndex,
      getFocusedTabIndex: () => {
{'fraction_non_alphanumeric': 0.13432835820895522, 'fraction_numerical': 0.0009328358208955224, 'mean_word_length': 3.7171590194846007, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1522522', 'n_tokens_mistral': 2274, 'n_tokens_neox': 2262, 'n_words': 374}