ToolButton.tsx 2.2 KB

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