toolbar-button.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { memo, useCallback } from 'react'
  2. import { EditorView } from '@codemirror/view'
  3. import { useCodeMirrorViewContext } from '../codemirror-editor'
  4. import { Button } from 'react-bootstrap'
  5. import classnames from 'classnames'
  6. import Tooltip from '../../../../shared/components/tooltip'
  7. import { emitToolbarEvent } from '../../extensions/toolbar/utils/analytics'
  8. import Icon from '../../../../shared/components/icon'
  9. export const ToolbarButton = memo<{
  10. id: string
  11. className?: string
  12. label: string
  13. command?: (view: EditorView) => void
  14. active?: boolean
  15. disabled?: boolean
  16. icon: string
  17. textIcon?: boolean
  18. hidden?: boolean
  19. shortcut?: string
  20. }>(function ToolbarButton({
  21. id,
  22. className,
  23. label,
  24. command,
  25. active = false,
  26. disabled,
  27. icon,
  28. textIcon = false,
  29. hidden = false,
  30. shortcut,
  31. }) {
  32. const view = useCodeMirrorViewContext()
  33. const handleMouseDown = useCallback(event => {
  34. event.preventDefault()
  35. }, [])
  36. const handleClick = useCallback(
  37. event => {
  38. emitToolbarEvent(view, id)
  39. if (command) {
  40. event.preventDefault()
  41. command(view)
  42. view.focus()
  43. }
  44. },
  45. [command, view, id]
  46. )
  47. const button = (
  48. <Button
  49. className={classnames('ol-cm-toolbar-button', className, { hidden })}
  50. aria-label={label}
  51. onMouseDown={handleMouseDown}
  52. onClick={!disabled ? handleClick : undefined}
  53. bsStyle={null}
  54. active={active}
  55. aria-disabled={disabled}
  56. type="button"
  57. >
  58. {textIcon ? icon : <Icon type={icon} fw accessibilityLabel={label} />}
  59. </Button>
  60. )
  61. if (!label) {
  62. return button
  63. }
  64. const description = (
  65. <>
  66. <div>{label}</div>
  67. {shortcut && <div>{shortcut}</div>}
  68. </>
  69. )
  70. return (
  71. <Tooltip
  72. id={id}
  73. description={description}
  74. overlayProps={{ placement: 'bottom' }}
  75. >
  76. {button}
  77. </Tooltip>
  78. )
  79. })