<commit_before>import { Dictionary } from '../options'
import { computeClippedClientRect } from '../util/dom-geom'
import { applyStyle, elementClosest, getEventTargetViaRoot } from '../util/dom-manip'
import { createElement, ComponentChildren, Ref, createPortal } from '../vdom'
import { BaseComponent, setRef } from '../vdom-util'

export interface PopoverProps {
  elRef?: Ref<HTMLElement>
  id: string
  title: string
  extraClassNames?: string[]
  extraAttrs?: Dictionary
  parentEl: HTMLElement
  alignmentEl: HTMLElement
  alignGridTop?: boolean
  children?: ComponentChildren
  onClose?: () => void
}

const PADDING_FROM_VIEWPORT = 10

export class Popover extends BaseComponent<PopoverProps> {
  private rootEl: HTMLElement

  render() {
    let { theme } = this.context
    let { props } = this
    let classNames = [
      'fc-popover',
      theme.getClass('popover'),
    ].concat(
      props.extraClassNames || [],
    )

    return createPortal(
      <div id={props.id} className={classNames.join(' ')} {...props.extraAttrs} ref={this.handleRootEl}>
        <div className={'fc-popover-header ' + theme.getClass('popoverHeader')}>
          <span className="fc-popover-title">
            {props.title}
          </span>
          <span className={'fc-popover-close ' + theme.getIconClass('close')} onClick={this.handleCloseClick} />
        </div>
        <div className={'fc-popover-body ' + theme.getClass('popoverContent')}>
          {props.children}
        </div>
      </div>,
      props.parentEl,
    )
  }

  componentDidMount() {
    document.addEventListener('mousedown', this.handleDocumentMousedown)
    this.updateSize()
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleDocumentMousedown)
  }

  handleRootEl = (el: HTMLElement | null) => {<commit_msg>aria for popover title<commit_after>import { Dictionary } from '../options'
import { computeClippedClientRect } from '../util/dom-geom'
import { applyStyle, elementClosest, getEventTargetViaRoot, getUniqueDomId } from '../util/dom-manip'
import { createElement, ComponentChildren, Ref, createPortal } from '../vdom'
import { BaseComponent, setRef } from '../vdom-util'

export interface PopoverProps {
  elRef?: Ref<HTMLElement>
  id: string
  title: string
  extraClassNames?: string[]
  extraAttrs?: Dictionary
  parentEl: HTMLElement
  alignmentEl: HTMLElement
  alignGridTop?: boolean
  children?: ComponentChildren
  onClose?: () => void
}

const PADDING_FROM_VIEWPORT = 10

export class Popover extends BaseComponent<PopoverProps> {
  private rootEl: HTMLElement
  state = {
    titleId: getUniqueDomId(),
  }

  render() {
    let { theme } = this.context
    let { props, state } = this
    let classNames = [
      'fc-popover',
      theme.getClass('popover'),
    ].concat(
      props.extraClassNames || [],
    )

    return createPortal(
      <div
        id={props.id}
        className={classNames.join(' ')}
        aria-labeledby={state.titleId}
        {...props.extraAttrs}
        ref={this.handleRootEl}
      >
        <div className={'fc-popover-header ' + theme.getClass('popoverHeader')}>
          <span className="fc-popover-title" id={state.titleId}>
            {props.title}
          </span>
          <span className={'fc-popover-close ' + theme.getIconClass('close')} onClick={this.handleCloseClick} />
        </div>
        <div className={'fc-popover-body ' + theme.getClass('popoverContent')}>
          {props.children}
        </div>
      </div>,
      props.parentEl,
    )
  }

  componentDidMount() {
    document.addEventListener('mousedown', this.handleDocumentMousedown)
    this.updateSize()
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleDocumentMousedown)
  }

  handleRootEl = (el: HTMLElement | null) => {
{'fraction_non_alphanumeric': 0.1354602510460251, 'fraction_numerical': 0.0010460251046025104, 'mean_word_length': 3.231194690265487, 'pattern_counts': {'":': 0, '<': 25, '<?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': '5435574', 'n_tokens_mistral': 1169, 'n_tokens_neox': 1171, 'n_words': 230}