render()

in packages/eui/src/components/icon/icon.tsx [232:331]


  render() {
    const {
      type,
      size = 'm',
      color,
      className,
      tabIndex,
      title,
      onIconLoad,
      style,
      stylesMemoizer,
      ...rest
    } = this.props;

    const { isLoading, neededLoading, iconTitle } = this.state;
    const isLoaded = !isLoading && neededLoading;

    const isCustomColor = color && !isNamedColor(color);

    const optionalCustomStyles: CSSProperties | undefined = isCustomColor
      ? {
          color: color,
          ...style,
        }
      : style;

    // These icons are a little special and get some extra CSS flexibility
    const isAppIcon = getIsAppIcon(type);
    // App color styles are only applied if no color is passed or if color="default" is passed
    const appIconHasColor = color && color !== 'default';

    // The Elastic logo should be an outline in text and ghost mode
    const isElasticLogoOutline =
      type === 'logoElastic' && (color === 'ghost' || color === 'text');

    const classes = classNames('euiIcon', className);

    // Emotion styles
    const styles = stylesMemoizer(euiIconStyles);
    const cssStyles = [
      styles.euiIcon,
      styles[size],
      color && isNamedColor(color) && styles[color as NamedColor],
      isCustomColor && styles.customColor,
      isElasticLogoOutline && styles.logoElasticOutline,
      isAppIcon && !appIconHasColor && styles.app,
      isLoading && styles.isLoading,
      !isLoading && neededLoading && styles.isLoaded,
    ];

    const icon = this.state.icon || empty;

    if (typeof icon === 'string') {
      return (
        <img
          alt={title ? title : ''}
          src={icon}
          className={classes}
          css={cssStyles}
          style={style}
          tabIndex={tabIndex}
          {...(rest as ImgHTMLAttributes<HTMLImageElement>)}
        />
      );
    } else {
      const Svg = icon;

      // If there is no aria-label, aria-labelledby, or title it gets aria-hidden true
      const isAriaHidden = !(
        this.props['aria-label'] ||
        this.props['aria-labelledby'] ||
        this.props.title
      );

      // If no aria-label or aria-labelledby is provided but there's a title, a titleId is generated
      //  The svg aria-labelledby attribute gets this titleId
      //  The svg title element gets this titleId as an id
      const titleId =
        !this.props['aria-label'] && !this.props['aria-labelledby'] && title
          ? { titleId: generateId() }
          : undefined;

      return (
        <Svg
          className={classes}
          style={optionalCustomStyles}
          css={cssStyles}
          tabIndex={tabIndex}
          role="img"
          title={title}
          {...titleId}
          data-icon-type={iconTitle}
          data-is-loaded={isLoaded || undefined}
          data-is-loading={isLoading || undefined}
          {...rest}
          aria-hidden={isAriaHidden || rest['aria-hidden']}
        />
      );
    }
  }