render()

in packages/eui/src/components/form/range/dual_range.tsx [401:783]


  render() {
    const { defaultFullWidth } = this.context as FormContextValue;
    const {
      className,
      css: customCss,
      compressed,
      disabled,
      fullWidth = defaultFullWidth,
      isLoading,
      readOnly,
      id: propsId,
      max: maxProps,
      min: minProps,
      name,
      step,
      showLabels,
      showInput,
      showTicks,
      tickInterval,
      ticks,
      levels,
      onBlur,
      onChange,
      onFocus,
      showRange,
      value,
      isInvalid,
      append,
      prepend,
      minInputProps,
      maxInputProps,
      inputPopoverProps,
      isDraggable,
      theme,
      ...rest
    } = this.props;
    const min = minProps!;
    const max = maxProps!;

    const { id } = this.state;

    const showInputOnly = this.isInPopover;
    const canShowDropdown = showInputOnly && !readOnly && !disabled;

    const rangeStyles = euiRangeStyles(theme);

    const minInput = !!showInput ? (
      <EuiRangeInput
        // Overridable props
        aria-describedby={this.props['aria-describedby']}
        aria-label={this.props['aria-label']}
        disabled={disabled}
        isInvalid={isInvalid}
        name={`${name}-minValue`}
        value={this.lowerValue}
        readOnly={readOnly}
        {...minInputProps}
        // Non-overridable props
        side="min"
        min={min}
        max={this.upperValue === '' ? max : Number(this.upperValue)}
        step={step}
        compressed={compressed}
        autoSize={!showInputOnly}
        fullWidth={!!showInputOnly && fullWidth}
        controlOnly={showInputOnly}
        onChange={(event) => {
          this.handleLowerInputChange(event);
          minInputProps?.onChange?.(event);
        }}
        onKeyDown={(event) => {
          this.handleInputKeyDown(event);
          minInputProps?.onKeyDown?.(event);
        }}
        onFocus={(event) => {
          if (canShowDropdown) {
            this.onInputFocus(event);
          } else {
            onFocus?.(event);
          }

          minInputProps?.onFocus?.(event);
        }}
        onBlur={(event) => {
          if (canShowDropdown) {
            this.onInputBlur(event);
          } else {
            onBlur?.(event);
          }

          minInputProps?.onBlur?.(event);
        }}
        onMouseDown={(event) => {
          if (showInputOnly) {
            this.preventPopoverClose = true;
          }

          minInputProps?.onMouseDown?.(event);
        }}
      />
    ) : undefined;

    const maxInput = !!showInput ? (
      <EuiRangeInput
        // Overridable props
        aria-describedby={this.props['aria-describedby']}
        aria-label={this.props['aria-label']}
        disabled={disabled}
        isInvalid={isInvalid}
        name={`${name}-maxValue`}
        value={this.upperValue}
        readOnly={readOnly}
        {...maxInputProps}
        // Non-overridable props
        side="max"
        min={this.lowerValue === '' ? min : Number(this.lowerValue)}
        max={max}
        step={step}
        compressed={compressed}
        autoSize={!showInputOnly}
        fullWidth={!!showInputOnly && fullWidth}
        controlOnly={showInputOnly}
        onChange={(event) => {
          this.handleUpperInputChange(event);
          maxInputProps?.onChange?.(event);
        }}
        onKeyDown={(event) => {
          this.handleInputKeyDown(event);
          maxInputProps?.onKeyDown?.(event);
        }}
        onFocus={(event) => {
          if (canShowDropdown) {
            this.onInputFocus(event);
          } else {
            onFocus?.(event);
          }

          maxInputProps?.onFocus?.(event);
        }}
        onBlur={(event) => {
          if (canShowDropdown) {
            this.onInputBlur(event);
          } else {
            onBlur?.(event);
          }

          maxInputProps?.onBlur?.(event);
        }}
        onMouseDown={(event) => {
          if (showInputOnly) {
            this.preventPopoverClose = true;
          }

          maxInputProps?.onMouseDown?.(event);
        }}
      />
    ) : undefined;

    const classes = classNames('euiDualRange', className);
    const dualRangeStyles = euiDualRangeStyles();
    const cssStyles = [dualRangeStyles.euiDualRange, customCss];

    const leftThumbPosition = this.state.rangeWidth
      ? this.calculateThumbPositionStyle(
          Number(this.lowerValue) || min,
          this.state.rangeWidth
        )
      : { left: '0' };
    const rightThumbPosition = this.state.rangeWidth
      ? this.calculateThumbPositionStyle(
          Number(this.upperValue) || max,
          this.state.rangeWidth
        )
      : { left: '0' };
    const leftThumbColor =
      levels && getLevelColor(levels, Number(this.lowerValue));
    const rightThumbColor =
      levels && getLevelColor(levels, Number(this.upperValue));
    const leftThumbStyles = leftThumbColor
      ? {
          ...leftThumbPosition,
          '--euiRangeThumbColor': euiRangeLevelColor(leftThumbColor, theme),
        }
      : leftThumbPosition;
    const rightThumbStyles = rightThumbColor
      ? {
          ...rightThumbPosition,
          '--euiRangeThumbColor': euiRangeLevelColor(rightThumbColor, theme),
        }
      : rightThumbPosition;

    const dualSliderScreenReaderInstructions = (
      <EuiI18n
        token="euiDualRange.sliderScreenReaderInstructions"
        default="You are in a custom range slider. Use the Up and Down arrow keys to change the minimum value. Press Tab to interact with the maximum value."
      />
    );

    const theRange = (
      <EuiRangeWrapper
        css={cssStyles}
        className={classes}
        fullWidth={fullWidth}
        compressed={compressed}
      >
        {showInput && !showInputOnly && (
          <>
            {minInput}
            <div
              className={
                showTicks || ticks
                  ? 'euiRange__slimHorizontalSpacer'
                  : 'euiRange__horizontalSpacer'
              }
              css={
                showTicks || ticks
                  ? rangeStyles.euiRange__slimHorizontalSpacer
                  : rangeStyles.euiRange__horizontalSpacer
              }
            />
          </>
        )}
        {showLabels && (
          <EuiRangeLabel side="min" disabled={disabled}>
            {min}
          </EuiRangeLabel>
        )}
        <EuiRangeTrack
          trackWidth={this.state.rangeWidth}
          compressed={compressed}
          disabled={disabled}
          max={max}
          min={min}
          step={step}
          showTicks={showTicks}
          tickInterval={tickInterval}
          ticks={ticks}
          levels={levels}
          onChange={this.handleSliderChange}
          value={value}
          aria-hidden={showInput === true}
          showRange={showRange}
        >
          <EuiRangeSlider
            className="euiDualRange__slider"
            css={dualRangeStyles.euiDualRange__slider}
            id={id}
            name={name}
            min={min}
            max={max}
            step={step}
            disabled={disabled}
            onChange={this.handleSliderChange}
            showTicks={showTicks}
            aria-hidden={true}
            tabIndex={-1}
            showRange={showRange}
            onFocus={onFocus}
            onBlur={onBlur}
            {...rest}
            onResize={this.setRangeWidth}
          />

          {isDraggable && this.isValid && (
            <EuiRangeDraggable
              min={min}
              max={max}
              value={[this.lowerValue, this.upperValue]}
              disabled={disabled}
              lowerPosition={leftThumbPosition.left}
              upperPosition={rightThumbPosition.left}
              showTicks={showTicks}
              onChange={this.handleDrag}
              onFocus={this.onThumbFocus}
              onBlur={this.onThumbBlur}
              onKeyDown={this.handleDraggableKeyDown}
              aria-describedby={
                showInputOnly ? undefined : this.props['aria-describedby']
              }
              aria-label={showInputOnly ? undefined : this.props['aria-label']}
            />
          )}

          <EuiRangeThumb
            min={min}
            max={Number(this.upperValue)}
            value={this.lowerValue}
            disabled={disabled}
            showTicks={showTicks}
            showInput={!!showInput}
            onKeyDown={this.handleLowerKeyDown}
            onFocus={this.onThumbFocus}
            onBlur={this.onThumbBlur}
            style={logicalStyles(leftThumbStyles)}
            aria-describedby={
              showInputOnly ? undefined : this.props['aria-describedby']
            }
            aria-label={showInputOnly ? undefined : this.props['aria-label']}
          />

          <EuiRangeThumb
            min={Number(this.lowerValue)}
            max={max}
            value={this.upperValue}
            disabled={disabled}
            showTicks={showTicks}
            showInput={!!showInput}
            onKeyDown={this.handleUpperKeyDown}
            onFocus={this.onThumbFocus}
            onBlur={this.onThumbBlur}
            style={logicalStyles(rightThumbStyles)}
            aria-describedby={
              showInputOnly ? undefined : this.props['aria-describedby']
            }
            aria-label={showInputOnly ? undefined : this.props['aria-label']}
          />

          {showRange && this.isValid && (
            <EuiRangeHighlight
              showTicks={showTicks}
              min={Number(min)}
              max={Number(max)}
              lowerValue={Number(this.lowerValue)}
              upperValue={Number(this.upperValue)}
              levels={levels}
              trackWidth={this.state.rangeWidth}
            />
          )}
        </EuiRangeTrack>
        {showLabels && <EuiRangeLabel disabled={disabled}>{max}</EuiRangeLabel>}
        {showInput && !showInputOnly && (
          <>
            <div
              className={
                showTicks || ticks
                  ? 'euiRange__slimHorizontalSpacer'
                  : 'euiRange__horizontalSpacer'
              }
              css={
                showTicks || ticks
                  ? rangeStyles.euiRange__slimHorizontalSpacer
                  : rangeStyles.euiRange__horizontalSpacer
              }
            />
            {maxInput}
          </>
        )}
      </EuiRangeWrapper>
    );

    const thePopover = showInputOnly ? (
      <EuiInputPopover
        {...inputPopoverProps}
        className={classNames(
          'euiDualRange__popover',
          inputPopoverProps?.className
        )}
        input={
          <EuiFormControlLayoutDelimited
            startControl={minInput!}
            endControl={maxInput!}
            isDisabled={disabled}
            fullWidth={fullWidth}
            compressed={compressed}
            readOnly={readOnly}
            append={append}
            prepend={prepend}
            isLoading={isLoading}
            isInvalid={isInvalid}
          />
        }
        fullWidth={fullWidth}
        isOpen={this.state.isPopoverOpen}
        closePopover={this.closePopover}
        disableFocusTrap={true}
        popoverScreenReaderText={dualSliderScreenReaderInstructions}
      >
        {theRange}
      </EuiInputPopover>
    ) : undefined;

    return thePopover || theRange;
  }