<commit_before>import React, { Component, PropTypes } from 'react';
import EventListener from 'react-event-listener';
import isEqual from 'lodash.isequal';

const styles = {
	width: '100px',
	height: '100px',
	position: 'absolute',
	top: '-100000px',
	overflow: 'scroll',
	msOverflowStyle: 'scrollbar',
};

class ScrollbarSizer extends Component {
	static propTypes = {
		onLoad: PropTypes.func,
		onChange: PropTypes.func,
		resizeInterval: PropTypes.number,
	}

	static defaultProps = {
		onLoad: () => {},
		onChange: () => {},
		resizeInterval: 166, // Corresponds to 10 frames at 60 Hz.
	}

	componentDidMount() {
		const {
			onLoad,
		} = this.props;

		this.setMeasurements();
		onLoad(this.measurements);
	}

	componentWillUnmount() {
		clearTimeout(this.deferTimer);
	}

	setMeasurements = () => {
		this.measurements = {
			scrollbarHeight: (this.node.offsetHeight - this.node.clientHeight),
			scrollbarWidth: (this.node.offsetWidth - this.node.clientWidth),
		};
	}

	handleResize = () => {
		clearTimeout(this.deferTimer);
		this.deferTimer = setTimeout(() => {
			const {
				onChange,
			} = this.props;

			const prevMeasurements = this.measurements;
			this.setMeasurements();

			if (!isEqual(prevMeasurements, this.measurements)) {
				onChange(this.measurements);
			}
		}, this.props.resizeInterval);
	}

	render() {
		return (
			<EventListener
				target="window"
				onResize={this.handleResize}
			>
				<div
					style={styles}
					ref={(node) => { this.node = node; }}
				/>
			</EventListener>
		);
	}
}

export default ScrollbarSizer;<commit_msg>Optional callbacks Truly made the callbacks each optional.  Do not render event handlers unless onChange is specified.<commit_after>import React, { Component, PropTypes } from 'react';
import EventListener from 'react-event-listener';
import isEqual from 'lodash.isequal';

const styles = {
	width: '100px',
	height: '100px',
	position: 'absolute',
	top: '-100000px',
	overflow: 'scroll',
	msOverflowStyle: 'scrollbar',
};

class ScrollbarSize extends Component {
	static propTypes = {
		onLoad: PropTypes.func,
		onChange: PropTypes.func,
		resizeInterval: PropTypes.number,
	}

	static defaultProps = {
		onLoad: null,
		onChange: null,
		resizeInterval: 166, // Corresponds to 10 frames at 60 Hz.
	}

	componentDidMount() {
		const {
			onLoad,
		} = this.props;

		if (onLoad) {
			this.setMeasurements();
			onLoad(this.measurements);
		}
	}

	componentWillUnmount() {
		clearTimeout(this.deferTimer);
	}

	setMeasurements = () => {
		this.measurements = {
			scrollbarHeight: (this.node.offsetHeight - this.node.clientHeight),
			scrollbarWidth: (this.node.offsetWidth - this.node.clientWidth),
		};
	}

	handleResize = () => {
		const {
			onChange,
		} = this.props;

		if (onChange) {
			clearTimeout(this.deferTimer);
			this.deferTimer = setTimeout(() => {
				const prevMeasurements = this.measurements;
				this.setMeasurements();

				if (!isEqual(prevMeasurements, this.measurements)) {
					onChange(this.measurements);
				}
			}, this.props.resizeInterval);
		}
	}

	render() {
		const {
			onChange,
		} = this.props;

		return (
			<div>
				{onChange ?
					<EventListener
						target="window"
						onResize={this.handleResize}
					/> :
					null
				}
				<div
					style={styles}
					ref={(node) => { this.node = node; }}
				/>
			</div>
		);
	}
}

export default ScrollbarSize;
{'fraction_non_alphanumeric': 0.13977541371158392, 'fraction_numerical': 0.011229314420803783, 'mean_word_length': 3.4715984147952446, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 20, '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': '5071923', 'n_tokens_mistral': 1334, 'n_tokens_neox': 1116, 'n_words': 225}