ToolButton.tsx 2.5 KB

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