rail-action-element.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import MaterialIcon, {
  2. AvailableUnfilledIcon,
  3. } from '@/shared/components/material-icon'
  4. import { forwardRef, ReactElement, useCallback } from 'react'
  5. import {
  6. Dropdown,
  7. DropdownToggle,
  8. } from '@/shared/components/dropdown/dropdown-menu'
  9. import OLTooltip from '@/shared/components/ol/ol-tooltip'
  10. import { DropdownToggle as BS5DropdownToggle } from 'react-bootstrap'
  11. type RailActionButton = {
  12. key: string
  13. icon: AvailableUnfilledIcon
  14. title: string
  15. action: () => void
  16. hide?: boolean
  17. ref?: React.Ref<HTMLButtonElement>
  18. }
  19. type RailDropdown = {
  20. key: string
  21. icon: AvailableUnfilledIcon
  22. title: string
  23. dropdown: ReactElement
  24. hide?: boolean
  25. ref?: React.Ref<HTMLButtonElement>
  26. }
  27. export type RailAction = RailDropdown | RailActionButton
  28. const RailActionElement = forwardRef<HTMLButtonElement, { action: RailAction }>(
  29. ({ action }, ref) => {
  30. const onActionClick = useCallback(() => {
  31. if ('action' in action) {
  32. action.action()
  33. }
  34. }, [action])
  35. if (action.hide) {
  36. return null
  37. }
  38. if ('dropdown' in action) {
  39. return (
  40. <Dropdown align="end" drop="end">
  41. <OLTooltip
  42. id={`rail-dropdown-tooltip-${action.key}`}
  43. description={action.title}
  44. overlayProps={{ delay: 0, placement: 'right' }}
  45. >
  46. <span>
  47. <DropdownToggle
  48. ref={ref as React.ForwardedRef<typeof BS5DropdownToggle>}
  49. id={`rail-dropdown-btn-${action.key}`}
  50. className="ide-rail-tab-link ide-rail-tab-button ide-rail-tab-dropdown"
  51. as="button"
  52. aria-label={action.title}
  53. >
  54. <MaterialIcon
  55. className="ide-rail-tab-link-icon"
  56. type={action.icon}
  57. unfilled
  58. />
  59. </DropdownToggle>
  60. </span>
  61. </OLTooltip>
  62. {action.dropdown}
  63. </Dropdown>
  64. )
  65. } else {
  66. return (
  67. <OLTooltip
  68. id={`rail-tab-tooltip-${action.key}`}
  69. description={action.title}
  70. overlayProps={{ delay: 0, placement: 'right' }}
  71. >
  72. <button
  73. ref={ref}
  74. onClick={onActionClick}
  75. className="ide-rail-tab-link ide-rail-tab-button"
  76. aria-label={action.title}
  77. >
  78. <MaterialIcon
  79. className="ide-rail-tab-link-icon"
  80. type={action.icon}
  81. unfilled
  82. />
  83. </button>
  84. </OLTooltip>
  85. )
  86. }
  87. }
  88. )
  89. RailActionElement.displayName = 'RailActionElement'
  90. export default RailActionElement