ToolButton.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import "./ToolIcon.scss";
  2. import React from "react";
  3. type ToolIconSize = "s" | "m";
  4. type ToolButtonBaseProps = {
  5. icon?: React.ReactNode;
  6. "aria-label": string;
  7. "aria-keyshortcuts"?: string;
  8. "data-testid"?: string;
  9. label?: string;
  10. title?: string;
  11. name?: string;
  12. id?: string;
  13. size?: ToolIconSize;
  14. keyBindingLabel?: string;
  15. showAriaLabel?: boolean;
  16. visible?: boolean;
  17. selected?: boolean;
  18. className?: string;
  19. };
  20. type ToolButtonProps =
  21. | (ToolButtonBaseProps & {
  22. type: "button";
  23. children?: React.ReactNode;
  24. onClick?(): void;
  25. })
  26. | (ToolButtonBaseProps & {
  27. type: "radio";
  28. checked: boolean;
  29. onChange?(): void;
  30. });
  31. const DEFAULT_SIZE: ToolIconSize = "m";
  32. export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
  33. const innerRef = React.useRef(null);
  34. React.useImperativeHandle(ref, () => innerRef.current);
  35. const sizeCn = `ToolIcon_size_${props.size || DEFAULT_SIZE}`;
  36. if (props.type === "button") {
  37. return (
  38. <button
  39. className={`ToolIcon_type_button ToolIcon ${sizeCn}${
  40. props.selected ? " ToolIcon--selected" : ""
  41. } ${props.className} ${
  42. props.visible
  43. ? "ToolIcon_type_button--show"
  44. : "ToolIcon_type_button--hide"
  45. }`}
  46. title={props.title}
  47. aria-label={props["aria-label"]}
  48. type="button"
  49. onClick={props.onClick}
  50. ref={innerRef}
  51. >
  52. <div className="ToolIcon__icon" aria-hidden="true">
  53. {props.icon || props.label}
  54. </div>
  55. {props.showAriaLabel && (
  56. <div className="ToolIcon__label">{props["aria-label"]}</div>
  57. )}
  58. {props.children}
  59. </button>
  60. );
  61. }
  62. return (
  63. <label className="ToolIcon" title={props.title}>
  64. <input
  65. className={`ToolIcon_type_radio ${sizeCn}`}
  66. type="radio"
  67. name={props.name}
  68. aria-label={props["aria-label"]}
  69. aria-keyshortcuts={props["aria-keyshortcuts"]}
  70. data-testid={props["data-testid"]}
  71. id={props.id}
  72. onChange={props.onChange}
  73. checked={props.checked}
  74. ref={innerRef}
  75. />
  76. <div className="ToolIcon__icon">
  77. {props.icon}
  78. {props.keyBindingLabel && (
  79. <span className="ToolIcon__keybinding">{props.keyBindingLabel}</span>
  80. )}
  81. </div>
  82. </label>
  83. );
  84. });
  85. ToolButton.defaultProps = {
  86. visible: true,
  87. className: "",
  88. };