render()

in src/button/button.tsx [93:223]


  render() {
    const {
      overrides = {},
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      size,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      kind,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      shape,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      minHitArea,
      isLoading,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      isSelected,
      // Removing from restProps
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      startEnhancer,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      endEnhancer,
      children,
      forwardedRef,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      colors,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      backgroundSafe,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      widthType,
      'aria-label': ariaLabel,
      ...restProps
    } = this.props;

    // Get overrides.
    const isAnchor = 'href' in restProps && Boolean(restProps?.href);

    const [BaseButton, baseButtonProps] = getOverrides(
      // adding both (1) BaseButton and (2) Root
      // (1) because it's a Button under the hood
      // (2) because we want consistency with the rest of the components
      overrides.BaseButton || overrides.Root,
      isAnchor ? StyledAnchorBaseButton : StyledBaseButton
    );
    const [LoadingSpinner, loadingSpinnerProps] = getOverrides<SharedStyleProps>(
      overrides.LoadingSpinner,
      StyledLoadingSpinner
    );
    const [LoadingSpinnerContainer, loadingSpinnerContainerProps] = getOverrides<SharedStyleProps>(
      overrides.LoadingSpinnerContainer,
      StyledLoadingSpinnerContainer
    );
    const sharedProps: SharedStyleProps = {
      ...getSharedProps(this.props),
      $isFocusVisible: this.state.isFocusVisible,
      $isHovered: this.state.isHovered,
      $isPressed: this.state.isPressed,
    };
    const ariaLoadingElements = isLoading
      ? {
          ['aria-label']: ariaLabel
            ? ariaLabel
            : typeof children === 'string'
            ? `loading ${children}`
            : 'content is loading',
          ['aria-busy']: 'true',
          ['aria-live']: 'polite',
        }
      : {};

    const ariaDisabledProps = restProps?.disabled && isAnchor ? { ['aria-disabled']: true } : {};
    const ariaLabelProps = isLoading
      ? {}
      : ariaLabel
      ? { ['aria-label']: ariaLabel }
      : typeof children === 'string'
      ? { ['aria-label']: children }
      : {};
    // Only need to apply aria-pressed if it's a standalone button with isSelected prop
    const ariaPressedProps =
      // Button group component will pass aria-checked prop
      typeof baseButtonProps['aria-checked'] === 'undefined' && typeof isSelected === 'boolean'
        ? { ['aria-pressed']: isSelected }
        : {};

    return (
      <BaseButton
        ref={forwardedRef}
        data-baseweb="button"
        {...ariaLoadingElements}
        {...ariaDisabledProps}
        {...ariaLabelProps}
        {...ariaPressedProps}
        {...sharedProps}
        {...restProps}
        {...baseButtonProps}
        // Applies last to override passed in onClick
        onClick={this.internalOnClick}
        onFocus={forkFocus({ ...restProps, ...baseButtonProps }, this.handleFocus)}
        onBlur={forkBlur({ ...restProps, ...baseButtonProps }, this.handleBlur)}
        onMouseEnter={this.handleHovered}
        onMouseLeave={this.handleNotHovered}
        onMouseDown={this.handlePressed}
        onMouseUp={this.handleNotPressed}
      >
        {isLoading ? (
          <React.Fragment>
            {/* This is not meant to be overridable by users */}
            <ButtonInternals
              {...this.props}
              isHovered={this.state.isHovered}
              isPressed={this.state.isPressed}
              isFocused={this.state.isFocusVisible}
            />

            <LoadingSpinnerContainer
              {...sharedProps}
              {...loadingSpinnerContainerProps}
              aria-hidden={true}
            >
              <LoadingSpinner {...sharedProps} {...loadingSpinnerProps} />
            </LoadingSpinnerContainer>
          </React.Fragment>
        ) : (
          <ButtonInternals
            {...this.props}
            isHovered={this.state.isHovered}
            isPressed={this.state.isPressed}
            isFocused={this.state.isFocusVisible}
          />
        )}
      </BaseButton>
    );
  }