<commit_before>import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (
        <div {...restProps} ref={ref}>
          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >
            <div>
              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>
            </div>
          </Popover>
        </div>
      )}
    </ClickOutside>
  )
}<commit_msg>[components] Add escape handler to menu button<commit_after>import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import Escapable from 'part:@sanity/components/utilities/escapable'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (
        <div {...restProps} ref={ref}>
          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >
            <div>
              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>
            </div>
          </Popover>

          {open && <Escapable onEscape={handleClose} />}
        </div>
      )}
    </ClickOutside>
  )
}
{'fraction_non_alphanumeric': 0.12799729821006417, 'fraction_numerical': 0.0, 'mean_word_length': 2.7351828499369484, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 34, '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': '1788755', 'n_tokens_mistral': 849, 'n_tokens_neox': 827, 'n_words': 193}