Skip to content

SelectControl: Apply custom classname to the root element #70621

@t-hamano

Description

@t-hamano

What problem does this address?

The SelectControl component supports the className prop, but it applies to the inner components, not the root BaseControl component. As a result, the following HTML is rendered:

<div class="components-base-control">
  <div class="components-base-control__field">
    <div class="components-flex components-input-base components-select-control my-custom-classname">
      <div class="components-flex-item">
        <label class="components-truncate components-text components-input-control__label">Label</label>
      </div>
      <div class="components-input-control__container">
        <select class="components-select-control__input"></select>
        <div aria-hidden="true" class="components-input-control__backdrop"></div>
      </div>
    </div>
  </div>
</div>

This makes it difficult for consumers to apply styles to, for example, the root element or label of the component.

I'm not sure if this was intentional or not, but it appears that nearly five years ago, the element to which the class names apply was changed:

https://github.com/WordPress/gutenberg/pull/23802/files?diff=split&w=1#diff-1e85d353bf21af7b49143c1dc0dbf6be1a4777dfc06966f8c6c6a484b2f00ca2R89

What is your proposed solution?

Apply the .components-select-control and custom class to the root element. The HTML will look like this:

<div class="components-base-control components-select-control my-custom-classname">
  <div class="components-base-control__field">
    <div class="components-flex components-input-base">
      <div class="components-flex-item">
        <label class="components-truncate components-text components-input-control__label">Label</label>
      </div>
      <div class="components-input-control__container">
        <select class="components-select-control__input"></select>
        <div aria-hidden="true" class="components-input-control__backdrop"></div>
      </div>
    </div>
  </div>
</div>

This format is consistent with other components that have the BaseControl component as their root, but it does create backward compatibility issues.

For example, in Gutenberg, the code below uses custom classnames, so we may need to adjust CSS:

<SelectControl
__next40pxDefaultSize
__nextHasNoMarginBottom
className="block-library-video-tracks-editor__single-track-editor-kind-select"

<SelectControl
__nextHasNoMarginBottom
className="components-custom-gradient-picker__type-picker"

<SelectControl
className="components-datetime__time-field components-datetime__time-field-month" // Unused, for backwards compatibility.

<SelectControl
className="dataviews-filters__summary-operators-filter-select"

<SelectControl
className="dataviews-controls__datetime-unit"

<SelectControl
__next40pxDefaultSize
__nextHasNoMarginBottom
className="post-author-selector"

<SelectControl
__next40pxDefaultSize={ __next40pxDefaultSize }
__shouldNotWarnDeprecated36pxSize
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
className={ clsx(
className,
'block-editor-dimension-control'

If making a change would cause significant issues, we may need to decide not to fix it.

cc @WordPress/gutenberg-components

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions