renderSelect()

in src/select/select.tsx [1241:1412]


  renderSelect(activeItemId: string | undefined) {
    const dataTest = this.props['data-test'];
    const {selectedLabel} = this.props;
    const {shortcutsEnabled} = this.state;
    const classes = classNames(
      styles.select,
      'ring-js-shortcuts',
      this.props.className,
      styles[`height${this.getHeight()}`],
      {
        [styles[`size${this.props.size}`]]: this.props.type !== Type.INLINE,
        [styles.disabled]: this.props.disabled,
      },
    );

    let style: CSSProperties | undefined;
    let iconsNode;

    if (this.props.type === Type.INPUT || this.props.type === Type.BUTTON) {
      const icons = this._getIcons();
      style = getStyle(icons.length);
      iconsNode = <div className={styles.icons}>{icons}</div>;
    }

    const ariaProps = {
      role: 'combobox',
      'aria-expanded': this.state.showPopup,
      'aria-controls': this.listId,
      'aria-activedescendant': this.state.showPopup ? activeItemId : undefined,
      'aria-label': this.props.label ?? this._getPlaceholder() ?? undefined,
    };

    switch (this.props.type) {
      case Type.INPUT_WITHOUT_CONTROLS:
      case Type.INPUT:
        return (
          <>
            <div
              ref={this.nodeRef}
              className={classNames(classes, styles.inputMode)}
              data-test={dataTests('ring-select', dataTest)}
              role='presentation' // has interactive elements inside
              onMouseDown={this.mouseDownHandler}
              onMouseUp={this.mouseUpHandler}
            >
              {shortcutsEnabled && <Shortcuts map={this.getShortcutsMap()} scope={this.shortcutsScope} />}
              <Input
                {...ariaProps}
                height={this.props.height}
                autoComplete='off'
                id={this.props.id}
                onClick={this._clickHandler}
                inputRef={this.composedFilterRef(this.filterRef, this.props.filterRef)}
                disabled={this.props.disabled}
                value={this.state.filterValue}
                borderless={this.props.type === Type.INPUT_WITHOUT_CONTROLS}
                style={style}
                size={Size.FULL}
                onChange={this._filterChangeHandler}
                onFocus={this._focusHandler}
                onBlur={this._blurHandler}
                // Input with error style without description
                error={this.props.error ? '' : null}
                label={this.props.type === Type.INPUT ? this._getLabel() : null}
                placeholder={this.props.inputPlaceholder}
                onKeyDown={this.props.onKeyDown}
                data-test='ring-select__focus'
                enableShortcuts={
                  shortcutsEnabled
                    ? Object.keys({
                        ...this.getShortcutsMap(),
                        ...this._popup?.list?.shortcutsMap,
                      })
                    : undefined
                }
                icon={this.props.filterIcon}
                afterInput={iconsNode}
              />
              {this._renderPopup()}
            </div>
            {this.props.error && (
              <div className={classNames(inputStyles.errorText, inputStyles[`size${this.props.size}`])}>
                {this.props.error}
              </div>
            )}
          </>
        );
      case Type.BUTTON:
        return (
          <div
            ref={this.nodeRef}
            className={classNames(classes, styles.buttonMode)}
            data-test={dataTests('ring-select', dataTest)}
          >
            {selectedLabel && (
              <ControlLabel type={this.props.labelType} disabled={this.props.disabled} htmlFor={this.props.id}>
                {selectedLabel}
              </ControlLabel>
            )}
            {shortcutsEnabled && <Shortcuts map={this.getShortcutsMap()} scope={this.shortcutsScope} />}
            <div className={styles.buttonContainer}>
              <Button
                {...ariaProps}
                height={this.props.height}
                id={this.props.id}
                onClick={this._clickHandler}
                className={classNames(this.props.buttonClassName, styles.buttonValue, {
                  [styles.buttonValueOpen]: this.state.showPopup,
                  [styles.buttonValueEmpty]: this._selectionIsEmpty(),
                })}
                disabled={this.props.disabled}
                style={style}
                data-test='ring-select__button ring-select__focus'
              >
                {this._getAvatar()}
                {this._getPlaceholder()}
              </Button>
              {iconsNode}
            </div>
            {this._renderPopup()}
          </div>
        );

      case Type.INLINE:
        return (
          <div className={classes} ref={this.nodeRef} data-test={dataTests('ring-select', dataTest)}>
            {shortcutsEnabled && <Shortcuts map={this.getShortcutsMap()} scope={this.shortcutsScope} />}
            <Anchor
              {...ariaProps}
              className={this.props.buttonClassName ?? undefined}
              id={this.props.id}
              onClick={this._clickHandler}
              data-test='ring-select__focus'
              disabled={this.props.disabled}
              active={this.state.showPopup}
            >
              {this._getPlaceholder()}
            </Anchor>
            {this._renderPopup()}
          </div>
        );
      default:
        if (this.props.customAnchor) {
          return (
            <Fragment>
              {shortcutsEnabled && <Shortcuts map={this.getShortcutsMap()} scope={this.shortcutsScope} />}
              {this.props.customAnchor({
                wrapperProps: {
                  ref: this.nodeRef,
                  'data-test': dataTests('ring-select', dataTest),
                },
                buttonProps: {
                  ...ariaProps,
                  id: this.props.id,
                  onClick: this._clickHandler,
                  disabled: this.props.disabled,
                  children: this._getPlaceholder(),
                  'data-test': 'ring-select__focus',
                  className: this.props.buttonClassName ?? undefined,
                },
                popup: this._renderPopup(),
              })}
            </Fragment>
          );
        }
        return (
          <span id={this.props.id} ref={this.nodeRef} data-test='ring-select'>
            {this._renderPopup()}
          </span>
        );
    }
  }