<commit_before>import * as React from 'react';
import * as ReactDOM from 'react-dom';


export default class Selection extends React.Component {
  constructor() {
    super();
    this.state = {};
  }

  componentDidMount() {
    this.clickListener = event => this.handleClick(event)
    document.addEventListener('click', this.clickListener);
  }

  componentWillUnmount() {
    document.removeEventListener('click', this.clickListener);
  }

  handleClick(event) {
    const node = ReactDOM.findDOMNode(this);
    const { left, right, top, bottom } = node.getBoundingClientRect();
    const { pageX: x, pageY: y } = event;

    if (x < left || x > right || y < top || y > bottom)
      this.cancel();
    else
      event.preventDefault();
  }

  handleMouseEnter(event) {
    this.focus();
  }

  handleKeyDown(event) {
    const { key, keyCode } = event;

    if (key == 'ArrowLeft' || key == 'ArrowUp' ||
        keyCode == 37 || keyCode == 38)
    {
      event.preventDefault();
      this.previous();
    }
    else if (key == 'ArrowRight' || key == 'ArrowDown' ||
             keyCode == 39 || keyCode == 40)
    {
      event.preventDefault();
      this.next();
    }
    else if (key == 'Enter' || keyCode == 13) {
      event.preventDefault();
      this.select();
    }
    else if (key == 'Escape' || keyCode == 27) {
      event.preventDefault();
      this.cancel();
    }
    else if (key == 'Tab' || keyCode == 9) {
      this.select();
    }
  }

  focus() {
    this.refs.container.focus();
  }

  highlight(i) {
    this.focus();
    this.setState({ highlighted: i });
    if (this.props.onHighlight)
      this.props.onHighlight(i);
  }

  next() {
    const n = this.props.children.length;
    const i = this.state.highlighted + 1;

    if (i < n)
      this.highlight(i);
    else if (this.props.onMenuLeave) {
      this.highlight(null);
      this.props.onMenuLeave();
    } else
      this.highlight(0);
  }

  previous() {
    const n = this.props.children.length;
    const i = this.state.highlighted - 1;

    if (i >= 0)
      this.highlight(i);
    else if (this.props.onMenuLeave) {
      this.highlight(null);
      this.props.onMenuLeave();
    } else
      this.highlight(n-1);
  }

  select(i) {
    const selected = i == null ? this.state.highlighted : i;
    this.setState({ selected: selected, highlighted: selected });
    if (this.props.onSelect)
      this.props.onSelect(selected);
  }

  cancel() {
    if (this.props.onCancel)
      this.props.onCancel();
  }

  render() {
    const baseClass = this.props.className || 'Selection';

    const classes = i => {
      const t = [ [`${baseClass}Item`     , true],
                  [`${baseClass}Highlight`, this.state.highlighted == i],
                  [`${baseClass}Selected` , this.state.selected == i] ];

      return t.filter(([_, val]) => !!val)
              .map(([cl, _]) => cl)
              .join(' ');
    };

    const wrapItem = (item, i) => (
      <li key          = {i}
          className    = {classes(i)}
          onMouseEnter = {event => this.highlight(i)}
          onClick      = {event => this.select(i)}
          >
        {item}
      </li>
    );

    return (
      <ul className = {baseClass}
          tabIndex     = {0}
          ref          = "container"
          onMouseEnter = {event => this.handleMouseEnter(event)}
          onKeyDown    = {event => this.handleKeyDown(event)}>
        {this.props.children.map(wrapItem)}
      </ul>
    );
  }
}<commit_msg>close submenus and remove highlighting on mouse leave and actions<commit_after>import * as React from 'react';
import * as ReactDOM from 'react-dom';


export default class Selection extends React.Component {
  constructor() {
    super();
    this.state = {};
  }

  componentDidMount() {
    this.clickListener = event => this.handleClick(event)
    document.addEventListener('click', this.clickListener);
  }

  componentWillUnmount() {
    document.removeEventListener('click', this.clickListener);
  }

  handleClick(event) {
    const node = ReactDOM.findDOMNode(this);
    const { left, right, top, bottom } = node.getBoundingClientRect();
    const { pageX: x, pageY: y } = event;

    if (x < left || x > right || y < top || y > bottom)
      this.cancel();
    else
      event.preventDefault();
  }

  handleMouseEnter(event) {
    this.focus();
  }

  handleKeyDown(event) {
    const { key, keyCode } = event;

    if (key == 'ArrowLeft' || key == 'ArrowUp' ||
        keyCode == 37 || keyCode == 38)
    {
      event.preventDefault();
      this.previous();
    }
    else if (key == 'ArrowRight' || key == 'ArrowDown' ||
             keyCode == 39 || keyCode == 40)
    {
      event.preventDefault();
      this.next();
    }
    else if (key == 'Enter' || keyCode == 13) {
      event.preventDefault();
      this.select();
    }
    else if (key == 'Escape' || keyCode == 27) {
      event.preventDefault();
      this.cancel();
    }
    else if (key == 'Tab' || keyCode == 9) {
      this.select();
    }
  }

  focus() {
    this.refs.container.focus();
  }

  highlight(i) {
    if (i != null)
      this.focus();

    this.setState({ highlighted: i });
    if (this.props.onHighlight)
      this.props.onHighlight(i);
  }

  next() {
    const n = this.props.children.length;
    const i = this.state.highlighted + 1;

    if (i < n)
      this.highlight(i);
    else if (this.props.onMenuLeave) {
      this.highlight(null);
      this.props.onMenuLeave();
    } else
      this.highlight(0);
  }

  previous() {
    const n = this.props.children.length;
    const i = this.state.highlighted - 1;

    if (i >= 0)
      this.highlight(i);
    else if (this.props.onMenuLeave) {
      this.highlight(null);
      this.props.onMenuLeave();
    } else
      this.highlight(n-1);
  }

  select(i) {
    const selected = i == null ? this.state.highlighted : i;
    this.setState({ selected: selected, highlighted: null });
    if (this.props.onSelect)
      this.props.onSelect(selected);
  }

  cancel() {
    if (this.props.onCancel)
      this.props.onCancel();
  }

  render() {
    const baseClass = this.props.className || 'Selection';

    const classes = i => {
      const t = [ [`${baseClass}Item`     , true],
                  [`${baseClass}Highlight`, this.state.highlighted == i],
                  [`${baseClass}Selected` , this.state.selected == i] ];

      return t.filter(([_, val]) => !!val)
              .map(([cl, _]) => cl)
              .join(' ');
    };

    const wrapItem = (item, i) => (
      <li key          = {i}
          className    = {classes(i)}
          onMouseEnter = {event => this.highlight(i)}
          onMouseLeave = {event => this.highlight(null)}
          onClick      = {event => this.select(i)}
          >
        {item}
      </li>
    );

    return (
      <ul className = {baseClass}
          tabIndex     = {0}
          ref          = "container"
          onMouseEnter = {event => this.handleMouseEnter(event)}
          onKeyDown    = {event => this.handleKeyDown(event)}>
        {this.props.children.map(wrapItem)}
      </ul>
    );
  }
}
{'fraction_non_alphanumeric': 0.15901109706419442, 'fraction_numerical': 0.0053378283466779045, 'mean_word_length': 2.1407146007940008, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 36, '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': '879197', 'n_tokens_mistral': 2330, 'n_tokens_neox': 2245, 'n_words': 483}