buttonGroup.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import React, { isValidElement, cloneElement } from 'react';
  2. import BaseComponent, { BaseProps } from '../_base/baseComponent';
  3. import PropTypes from 'prop-types';
  4. import classNames from 'classnames';
  5. import { cssClasses, strings } from '@douyinfe/semi-foundation/button/constants';
  6. import { Type, Size } from './Button';
  7. import '@douyinfe/semi-foundation/button/button.scss';
  8. export type Theme = 'solid' | 'borderless' | 'light';
  9. export interface ButtonGroupProps extends BaseProps {
  10. disabled?: boolean;
  11. type?: Type;
  12. size?: Size;
  13. theme?: Theme;
  14. className?: string;
  15. children?: React.ReactNode;
  16. 'aria-label'?: React.AriaAttributes['aria-label'];
  17. }
  18. const prefixCls = cssClasses.PREFIX;
  19. const btnSizes = strings.sizes;
  20. export default class ButtonGroup extends BaseComponent<ButtonGroupProps> {
  21. static propTypes = {
  22. children: PropTypes.node,
  23. disabled: PropTypes.bool,
  24. type: PropTypes.string,
  25. size: PropTypes.oneOf(btnSizes),
  26. theme: PropTypes.oneOf(strings.themes),
  27. 'aria-label': PropTypes.string,
  28. };
  29. static defaultProps = {
  30. // There are default values ​​for type and theme in Button.
  31. // In order to allow users to individually customize the type and theme of the Button through the parameters of the Button in the ButtonGroup,
  32. // the default value of type and theme is not given in the ButtonGroup。
  33. size: 'default',
  34. };
  35. render() {
  36. const { children, disabled, size, type, className, 'aria-label': ariaLabel, ...rest } = this.props;
  37. let inner;
  38. const cls = classNames(`${prefixCls}-group`, className);
  39. if (children) {
  40. inner = ((Array.isArray(children) ? children : [children])).map((itm: React.ReactNode, index) => (
  41. isValidElement(itm)
  42. ? cloneElement(itm, { disabled, size, type, ...itm.props, ...rest, key: index })
  43. : itm
  44. ));
  45. }
  46. return <div className={cls} role="group" aria-label={ariaLabel}>{inner}</div>;
  47. }
  48. }