toolbar-button.tsx 1.9 KB

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