toolbar-button.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 '@/shared/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: React.MouseEvent) => {
  33. event.preventDefault()
  34. }, [])
  35. const handleClick = useCallback(
  36. (event: React.MouseEvent) => {
  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>
  71. {label}
  72. {shortcut && <span> ({shortcut})</span>}
  73. </div>
  74. </>
  75. )
  76. return (
  77. <OLTooltip
  78. id={id}
  79. description={description}
  80. overlayProps={{ placement: 'bottom' }}
  81. >
  82. {button}
  83. </OLTooltip>
  84. )
  85. })