<commit_before>import React, { Component, Children } from 'react';
import klass from '../cssClasses';
import { outerWidth } from '../dimensions';
import CSSTranslate from '../CSSTranslate';
// @ts-ignore
import Swipe from 'react-easy-swipe';
import getWindow from '../shims/window';

const isKeyboardEvent = (e: React.MouseEvent | React.KeyboardEvent): e is React.KeyboardEvent =>
    e.hasOwnProperty('key');

export interface Props {
    axis: 'horizontal' | 'vertical';
    children: React.ReactChild[];
    labels: {
        leftArrow: string;
        rightArrow: string;
        item: string;
    };
    onSelectItem: (index: number, item: React.ReactNode) => void;
    selectedItem: number;
    thumbWidth: number;
    transitionTime: number;
}

interface State {
    selectedItem: number;
    firstItem: number;
    itemSize?: number;
    visibleItems: number;
    lastPosition: number;
    showArrows: boolean;
    swiping: boolean;
}

export default class Thumbs extends Component<Props, State> {
    private itemsWrapperRef?: HTMLDivElement;
    private itemsListRef?: HTMLUListElement;
    private thumbsRef?: HTMLLIElement[];

    static displayName = 'Thumbs';

    static defaultProps = {
        axis: 'horizontal',
        labels: {
            leftArrow: 'previous slide / item',
            rightArrow: 'next slide / item',
            item: 'slide item',
        },
        selectedItem: 0,
        thumbWidth: 80,
        transitionTime: 350,
    };

    constructor(props: Props) {
        super(props);

        this.state = {
            selectedItem: props.selectedItem,
            swiping: false,
            showArrows: false,
            firstItem: 0,
            visibleItems: 0,
            lastPosition: 0,
        };
    }

    componentDidMount() {
        this.setupThumbs();
    }

    UNSAFE_componentWillReceiveProps(props: Props) {
        if (props.selectedItem !== this.state.selectedItem) {
            this.setState({
                selectedItem: props.selectedItem,
                firstItem: this.getFirstItem(props.selectedItem),
            });
        }
    }

    componentDidUpdate(prevProps: Props) {
        if (this.props.children === prevProps.children) {
            return;
        }

        // This will capture any size changes for arrow adjustments etc.
        // usually in the same render cycle so we don't see any flickers
        this.updateSizes();
    }

    componentWillUnmount() {
        this.destroyThumbs();
    }

    setItemsWrapperRef = (node: HTMLDivElement) => {
        this.itemsWrapperRef = node;
    };

    setItemsListRef = (node: HTMLUListElement) => {
        this.itemsListRef = node;
    };

    setThumbsRef = (node: HTMLLIElement, index: number) => {
        if (!this.thumbsRef) {
            this.thumbsRef = [];
        }
        this.thumbsRef[index] = node;
    };

    setupThumbs() {
        // as the widths are calculated, we need to resize
        // the carousel when the window is resized
        getWindow().addEventListener('resize', this.updateSizes);
        // issue #2 - image loading smaller
        getWindow().addEventListener('DOMContentLoaded', this.updateSizes);

        // when the component is rendered we need to calculate
        // the container size to adjust the responsive behaviour
        this.updateSizes();
    }

    destroyThumbs() {
        // removing listeners
        getWindow().removeEventListener('resize', this.updateSizes);
        getWindow().removeEventListener('DOMContentLoaded', this.updateSizes);
    }

    updateSizes = () => {
        if (!this.props.children || !this.itemsWrapperRef || !this.thumbsRef) {
            return;
        }

        const total = Children.count(this.props.children);
        const wrapperSize = this.itemsWrapperRef.clientWidth;
        const itemSize = this.props.thumbWidth ? this.props.thumbWidth : outerWidth(this.thumbsRef[0]);
        const visibleItems = Math.floor(wrapperSize / itemSize);
        const lastPosition = total - visibleItems;
        const showArrows = visibleItems < total;
        this.setState((_state, props) => ({
            itemSize,
            visibleItems,
            firstItem: showArrows ? this.getFirstItem(props.selectedItem) : 0,
            lastPosition,
            showArrows,
        }));
    };

    handleClickItem = (index: number, item: React.ReactNode, e: React.MouseEvent | React.KeyboardEvent) => {
        if (!isKeyboardEvent(e) || e.key === 'Enter') {
            const handler = this.props.onSelectItem;

            if (typeof handler === 'function') {
                handler(index, item);
            }
        }
    };

    onSwipeStart = () => {
        this.setState({
            swiping: true,
        });
    };

    onSwipeEnd = () => {
        this.setState({
            swiping: false,
        });
    };

    onSwipeMove = (delta: { x: number; y: number }) => {
        let deltaX = delta.x;
        if (!this.state.itemSize || !this.itemsWrapperRef) {
            return false;
        }
        const leftBoundary = 0;

        const currentPosition = -this.state.firstItem * this.state.itemSize;
        const lastLeftBoundary = -this.state.visibleItems * this.state.itemSize;

        // prevent user from swiping left out of boundaries
        if (currentPosition === leftBoundary && deltaX > 0) {
            deltaX = 0;
        }
<commit_msg>changed last left boundary and current position to percent<commit_after>import React, { Component, Children } from 'react';
import klass from '../cssClasses';
import { outerWidth } from '../dimensions';
import CSSTranslate from '../CSSTranslate';
// @ts-ignore
import Swipe from 'react-easy-swipe';
import getWindow from '../shims/window';

const isKeyboardEvent = (e: React.MouseEvent | React.KeyboardEvent): e is React.KeyboardEvent =>
    e.hasOwnProperty('key');

export interface Props {
    axis: 'horizontal' | 'vertical';
    children: React.ReactChild[];
    labels: {
        leftArrow: string;
        rightArrow: string;
        item: string;
    };
    onSelectItem: (index: number, item: React.ReactNode) => void;
    selectedItem: number;
    thumbWidth: number;
    transitionTime: number;
}

interface State {
    selectedItem: number;
    firstItem: number;
    itemSize?: number;
    visibleItems: number;
    lastPosition: number;
    showArrows: boolean;
    swiping: boolean;
}

export default class Thumbs extends Component<Props, State> {
    private itemsWrapperRef?: HTMLDivElement;
    private itemsListRef?: HTMLUListElement;
    private thumbsRef?: HTMLLIElement[];

    static displayName = 'Thumbs';

    static defaultProps = {
        axis: 'horizontal',
        labels: {
            leftArrow: 'previous slide / item',
            rightArrow: 'next slide / item',
            item: 'slide item',
        },
        selectedItem: 0,
        thumbWidth: 80,
        transitionTime: 350,
    };

    constructor(props: Props) {
        super(props);

        this.state = {
            selectedItem: props.selectedItem,
            swiping: false,
            showArrows: false,
            firstItem: 0,
            visibleItems: 0,
            lastPosition: 0,
        };
    }

    componentDidMount() {
        this.setupThumbs();
    }

    UNSAFE_componentWillReceiveProps(props: Props) {
        if (props.selectedItem !== this.state.selectedItem) {
            this.setState({
                selectedItem: props.selectedItem,
                firstItem: this.getFirstItem(props.selectedItem),
            });
        }
    }

    componentDidUpdate(prevProps: Props) {
        if (this.props.children === prevProps.children) {
            return;
        }

        // This will capture any size changes for arrow adjustments etc.
        // usually in the same render cycle so we don't see any flickers
        this.updateSizes();
    }

    componentWillUnmount() {
        this.destroyThumbs();
    }

    setItemsWrapperRef = (node: HTMLDivElement) => {
        this.itemsWrapperRef = node;
    };

    setItemsListRef = (node: HTMLUListElement) => {
        this.itemsListRef = node;
    };

    setThumbsRef = (node: HTMLLIElement, index: number) => {
        if (!this.thumbsRef) {
            this.thumbsRef = [];
        }
        this.thumbsRef[index] = node;
    };

    setupThumbs() {
        // as the widths are calculated, we need to resize
        // the carousel when the window is resized
        getWindow().addEventListener('resize', this.updateSizes);
        // issue #2 - image loading smaller
        getWindow().addEventListener('DOMContentLoaded', this.updateSizes);

        // when the component is rendered we need to calculate
        // the container size to adjust the responsive behaviour
        this.updateSizes();
    }

    destroyThumbs() {
        // removing listeners
        getWindow().removeEventListener('resize', this.updateSizes);
        getWindow().removeEventListener('DOMContentLoaded', this.updateSizes);
    }

    updateSizes = () => {
        if (!this.props.children || !this.itemsWrapperRef || !this.thumbsRef) {
            return;
        }

        const total = Children.count(this.props.children);
        const wrapperSize = this.itemsWrapperRef.clientWidth;
        const itemSize = this.props.thumbWidth ? this.props.thumbWidth : outerWidth(this.thumbsRef[0]);
        const visibleItems = Math.floor(wrapperSize / itemSize);
        const lastPosition = total - visibleItems;
        const showArrows = visibleItems < total;
        this.setState((_state, props) => ({
            itemSize,
            visibleItems,
            firstItem: showArrows ? this.getFirstItem(props.selectedItem) : 0,
            lastPosition,
            showArrows,
        }));
    };

    handleClickItem = (index: number, item: React.ReactNode, e: React.MouseEvent | React.KeyboardEvent) => {
        if (!isKeyboardEvent(e) || e.key === 'Enter') {
            const handler = this.props.onSelectItem;

            if (typeof handler === 'function') {
                handler(index, item);
            }
        }
    };

    onSwipeStart = () => {
        this.setState({
            swiping: true,
        });
    };

    onSwipeEnd = () => {
        this.setState({
            swiping: false,
        });
    };

    onSwipeMove = (delta: { x: number; y: number }) => {
        let deltaX = delta.x;
        if (!this.state.itemSize || !this.itemsWrapperRef || !this.state.visibleItems) {
            return false;
        }
        const leftBoundary = 0;
        const childrenLength = Children.count(this.props.children);

        const currentPosition = -(this.state.firstItem * 100) / this.state.visibleItems;
        const lastLeftItem = Math.max(childrenLength - this.state.visibleItems, 0);
        const lastLeftBoundary = -lastLeftItem * 100 / this.state.visibleItems;

        // prevent user from swiping left out of boundaries
        if (currentPosition === leftBoundary && deltaX > 0) {
            deltaX = 0;
        }

{'fraction_non_alphanumeric': 0.11311683599419449, 'fraction_numerical': 0.003356313497822932, 'mean_word_length': 2.1744889144831556, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, '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': '631776', 'n_tokens_mistral': 3068, 'n_tokens_neox': 3023, 'n_words': 735}