ToggleButtonGroup.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import React, { SFC, ReactNode, PureComponent, ReactElement } from 'react';
  2. interface ToggleButtonGroupProps {
  3. onChange: (value) => void;
  4. value?: any;
  5. label?: string;
  6. render: (props) => void;
  7. }
  8. export default class ToggleButtonGroup extends PureComponent<ToggleButtonGroupProps> {
  9. getValues() {
  10. const { children } = this.props;
  11. return React.Children.toArray(children).map((c: ReactElement<any>) => c.props.value);
  12. }
  13. smallChildren() {
  14. const { children } = this.props;
  15. return React.Children.toArray(children).every((c: ReactElement<any>) => c.props.className.includes('small'));
  16. }
  17. handleToggle(toggleValue) {
  18. const { value, onChange } = this.props;
  19. if (value && value === toggleValue) {
  20. return;
  21. }
  22. onChange(toggleValue);
  23. }
  24. render() {
  25. const { value, label } = this.props;
  26. const values = this.getValues();
  27. const selectedValue = value || values[0];
  28. const labelClassName = `gf-form-label ${this.smallChildren() ? 'small' : ''}`;
  29. return (
  30. <div className="gf-form">
  31. <div className="toggle-button-group">
  32. {label && <label className={labelClassName}>{label}</label>}
  33. {this.props.render({ selectedValue, onChange: this.handleToggle.bind(this) })}
  34. </div>
  35. </div>
  36. );
  37. }
  38. }
  39. interface ToggleButtonProps {
  40. onChange?: (value) => void;
  41. selected?: boolean;
  42. value: any;
  43. className?: string;
  44. children: ReactNode;
  45. title?: string;
  46. }
  47. export const ToggleButton: SFC<ToggleButtonProps> = ({
  48. children,
  49. selected,
  50. className = '',
  51. title = null,
  52. value,
  53. onChange,
  54. }) => {
  55. const handleChange = event => {
  56. event.stopPropagation();
  57. if (onChange) {
  58. onChange(value);
  59. }
  60. };
  61. const btnClassName = `btn ${className} ${selected ? 'active' : ''}`;
  62. return (
  63. <button className={btnClassName} onClick={handleChange} title={title}>
  64. <span>{children}</span>
  65. </button>
  66. );
  67. };