splitButtonGroup.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import classNames from 'classnames';
  4. import { cssClasses } from '@douyinfe/semi-foundation/button/constants';
  5. import '@douyinfe/semi-foundation/button/button.scss';
  6. import BaseComponent, { BaseProps } from '../_base/baseComponent';
  7. const prefixCls = cssClasses.PREFIX;
  8. export interface SplitButtonGroupProps extends BaseProps {
  9. 'aria-label'?: React.AriaAttributes['aria-label']
  10. }
  11. export default class SplitButtonGroup extends BaseComponent<SplitButtonGroupProps> {
  12. containerRef: React.RefObject<HTMLDivElement> = React.createRef();
  13. mutationObserver: MutationObserver | null = null;
  14. static propTypes = {
  15. style: PropTypes.object,
  16. className: PropTypes.string,
  17. 'aria-label': PropTypes.string,
  18. };
  19. componentDidMount() {
  20. const addClassName = ()=>{
  21. const buttons = this.containerRef.current.querySelectorAll('button');
  22. const firstButton = buttons[0];
  23. const lastButton = buttons[buttons.length - 1];
  24. if (!firstButton?.classList.contains(`${prefixCls}-first`)) {
  25. firstButton?.classList.add(`${prefixCls}-first`);
  26. }
  27. if (!lastButton?.classList.contains(`${prefixCls}-last`)) {
  28. lastButton?.classList.add(`${prefixCls}-last`);
  29. }
  30. };
  31. if (this.containerRef.current) {
  32. addClassName();
  33. const mutationObserver = new MutationObserver((mutations, observer)=>{
  34. for (const mutation of mutations) {
  35. if ((mutation.type === "attributes" && mutation.attributeName === "class") || (mutation.type==='childList' && Array.from( mutation.addedNodes).some(node=>node.nodeName==='BUTTON'))) {
  36. addClassName();
  37. }
  38. }
  39. });
  40. mutationObserver.observe(this.containerRef.current, { attributes: true, childList: true, subtree: true });
  41. this.mutationObserver = mutationObserver;
  42. }
  43. }
  44. componentWillUnmount() {
  45. super.componentWillUnmount();
  46. this.mutationObserver?.disconnect();
  47. }
  48. render() {
  49. const { children, style, className } = this.props;
  50. const cls = classNames(`${prefixCls}-split`, className);
  51. return (
  52. <div ref={this.containerRef} className={cls} style={style} role="group"
  53. aria-label={this.props['aria-label']}>
  54. {children}
  55. </div>
  56. );
  57. }
  58. }