Skip to content

Commit

Permalink
InputBase: Simplify focus styles (#60226)
Browse files Browse the repository at this point in the history
* InputBase: Simplify focus styles in Root

* InputBase: Simplify focus styles in Backdrop

* InputField: Remove unnecessary focus handling

* SelectControl: Remove unnecessary focus handling

* Update snapshots

* Clarify intent in styles

* Add changelog

* CustomSelectControl: Simplify focus styles

* Add more affected components to changelog

* Fix changelog placement

Co-authored-by: mirka <0mirka00@git.wordpress.org>
Co-authored-by: tyxla <tyxla@git.wordpress.org>
Co-authored-by: DaniGuardiola <daniguardiola@git.wordpress.org>
  • Loading branch information
4 people authored Apr 18, 2024
1 parent e9b1eef commit db48edb
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 206 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

- Remove CSS hack for Internet Explorer 11 ([#60727](https://github.com/WordPress/gutenberg/pull/60727)).
- `CheckboxControl`: Streamline size styles ([#60475](https://github.com/WordPress/gutenberg/pull/60475)).
- `InputBase`: Simplify management of focus styles. Affects all components based on `InputControl` (e.g. `SearchControl`, `NumberControl`, `UnitControl`), as well as `SelectControl`, `CustomSelectControl`, and `TreeSelect` ([#60226](https://github.com/WordPress/gutenberg/pull/60226)).

## 27.3.0 (2024-04-03)

Expand Down
100 changes: 45 additions & 55 deletions packages/components/src/custom-select-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import classnames from 'classnames';
*/
import { Icon, check } from '@wordpress/icons';
import { __, sprintf } from '@wordpress/i18n';
import { useCallback, useState } from '@wordpress/element';
import { useCallback } from '@wordpress/element';

/**
* Internal dependencies
Expand Down Expand Up @@ -101,18 +101,6 @@ export default function CustomSelectControl( props ) {
stateReducer,
} );

const [ isFocused, setIsFocused ] = useState( false );

function handleOnFocus( e ) {
setIsFocused( true );
onFocus?.( e );
}

function handleOnBlur( e ) {
setIsFocused( false );
onBlur?.( e );
}

function getDescribedBy() {
if ( describedBy ) {
return describedBy;
Expand Down Expand Up @@ -168,16 +156,15 @@ export default function CustomSelectControl( props ) {
) }
<InputBase
__next40pxDefaultSize={ __next40pxDefaultSize }
isFocused={ isOpen || isFocused }
size={ size }
suffix={ <SelectControlChevronDown /> }
>
<SelectControlSelect
onMouseOver={ onMouseOver }
onMouseOut={ onMouseOut }
as="button"
onFocus={ handleOnFocus }
onBlur={ handleOnBlur }
onFocus={ onFocus }
onBlur={ onBlur }
selectSize={ size }
__next40pxDefaultSize={ __next40pxDefaultSize }
{ ...getToggleButtonProps( {
Expand All @@ -196,46 +183,49 @@ export default function CustomSelectControl( props ) {
</span>
) }
</SelectControlSelect>
<div className="components-custom-select-control__menu-wrapper">
{ /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ }
<ul { ...menuProps } onKeyDown={ onKeyDownHandler }>
{ isOpen &&
items.map( ( item, index ) => (
// eslint-disable-next-line react/jsx-key
<li
{ ...getItemProps( {
item,
index,
key: item.key,
className: classnames(
item.className,
'components-custom-select-control__item',
{
'is-highlighted':
index === highlightedIndex,
'has-hint':
!! item.__experimentalHint,
'is-next-40px-default-size':
__next40pxDefaultSize,
}
),
style: item.style,
} ) }
>
{ item.name }
{ item.__experimentalHint && (
<span className="components-custom-select-control__item-hint">
{ item.__experimentalHint }
</span>
) }
{ item === selectedItem && (
<Icon
icon={ check }
className="components-custom-select-control__item-icon"
/>
) }
</li>
) ) }
</ul>
</div>
</InputBase>
{ /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ }
<ul { ...menuProps } onKeyDown={ onKeyDownHandler }>
{ isOpen &&
items.map( ( item, index ) => (
// eslint-disable-next-line react/jsx-key
<li
{ ...getItemProps( {
item,
index,
key: item.key,
className: classnames(
item.className,
'components-custom-select-control__item',
{
'is-highlighted':
index === highlightedIndex,
'has-hint': !! item.__experimentalHint,
'is-next-40px-default-size':
__next40pxDefaultSize,
}
),
style: item.style,
} ) }
>
{ item.name }
{ item.__experimentalHint && (
<span className="components-custom-select-control__item-hint">
{ item.__experimentalHint }
</span>
) }
{ item === selectedItem && (
<Icon
icon={ check }
className="components-custom-select-control__item-icon"
/>
) }
</li>
) ) }
</ul>
</div>
);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/custom-select-control/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
margin-left: 10px;
}

.components-custom-select-control__menu-wrapper {
position: absolute;
min-width: 100%;
bottom: 0;
}

.components-custom-select-control__menu {
// Hide when collapsed.
&[aria-hidden="true"] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ exports[`DimensionControl rendering renders with custom sizes 1`] = `
min-height: 0;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) {
z-index: 1;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) .emotion-25 {
border-color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
box-shadow: 0 0 0 0.5px var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
outline: 2px solid transparent;
outline-offset: -2px;
}
.emotion-8 {
display: block;
max-height: 100%;
Expand Down Expand Up @@ -166,7 +177,10 @@ exports[`DimensionControl rendering renders with custom sizes 1`] = `
.emotion-24.emotion-24.emotion-24 {
box-sizing: border-box;
border-color: var(--wp-components-color-gray-600, #949494);
border-radius: inherit;
border-style: solid;
border-width: 1px;
bottom: 0;
left: 0;
margin: 0;
Expand All @@ -175,9 +189,6 @@ exports[`DimensionControl rendering renders with custom sizes 1`] = `
position: absolute;
right: 0;
top: 0;
border-color: var(--wp-components-color-gray-600, #949494);
border-style: solid;
border-width: 1px;
padding-left: 2px;
}
Expand Down Expand Up @@ -319,6 +330,17 @@ exports[`DimensionControl rendering renders with defaults 1`] = `
min-height: 0;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) {
z-index: 1;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) .emotion-25 {
border-color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
box-shadow: 0 0 0 0.5px var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
outline: 2px solid transparent;
outline-offset: -2px;
}
.emotion-8 {
display: block;
max-height: 100%;
Expand Down Expand Up @@ -438,7 +460,10 @@ exports[`DimensionControl rendering renders with defaults 1`] = `
.emotion-24.emotion-24.emotion-24 {
box-sizing: border-box;
border-color: var(--wp-components-color-gray-600, #949494);
border-radius: inherit;
border-style: solid;
border-width: 1px;
bottom: 0;
left: 0;
margin: 0;
Expand All @@ -447,9 +472,6 @@ exports[`DimensionControl rendering renders with defaults 1`] = `
position: absolute;
right: 0;
top: 0;
border-color: var(--wp-components-color-gray-600, #949494);
border-style: solid;
border-width: 1px;
padding-left: 2px;
}
Expand Down Expand Up @@ -601,6 +623,17 @@ exports[`DimensionControl rendering renders with icon and custom icon label 1`]
min-height: 0;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) {
z-index: 1;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) .emotion-25 {
border-color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
box-shadow: 0 0 0 0.5px var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
outline: 2px solid transparent;
outline-offset: -2px;
}
.emotion-8 {
display: block;
max-height: 100%;
Expand Down Expand Up @@ -720,7 +753,10 @@ exports[`DimensionControl rendering renders with icon and custom icon label 1`]
.emotion-24.emotion-24.emotion-24 {
box-sizing: border-box;
border-color: var(--wp-components-color-gray-600, #949494);
border-radius: inherit;
border-style: solid;
border-width: 1px;
bottom: 0;
left: 0;
margin: 0;
Expand All @@ -729,9 +765,6 @@ exports[`DimensionControl rendering renders with icon and custom icon label 1`]
position: absolute;
right: 0;
top: 0;
border-color: var(--wp-components-color-gray-600, #949494);
border-style: solid;
border-width: 1px;
padding-left: 2px;
}
Expand Down Expand Up @@ -895,6 +928,17 @@ exports[`DimensionControl rendering renders with icon and default icon label 1`]
min-height: 0;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) {
z-index: 1;
}
.emotion-5:focus-within:not( :has( :is( .em5sgkm7, .emotion-18 ):focus-within ) ) .emotion-25 {
border-color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
box-shadow: 0 0 0 0.5px var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));
outline: 2px solid transparent;
outline-offset: -2px;
}
.emotion-8 {
display: block;
max-height: 100%;
Expand Down Expand Up @@ -1014,7 +1058,10 @@ exports[`DimensionControl rendering renders with icon and default icon label 1`]
.emotion-24.emotion-24.emotion-24 {
box-sizing: border-box;
border-color: var(--wp-components-color-gray-600, #949494);
border-radius: inherit;
border-style: solid;
border-width: 1px;
bottom: 0;
left: 0;
margin: 0;
Expand All @@ -1023,9 +1070,6 @@ exports[`DimensionControl rendering renders with icon and default icon label 1`]
position: absolute;
right: 0;
top: 0;
border-color: var(--wp-components-color-gray-600, #949494);
border-style: solid;
border-width: 1px;
padding-left: 2px;
}
Expand Down
7 changes: 1 addition & 6 deletions packages/components/src/input-control/backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@ import { memo } from '@wordpress/element';
*/
import { BackdropUI } from './styles/input-control-styles';

function Backdrop( {
disabled = false,
isBorderless = false,
isFocused = false,
} ) {
function Backdrop( { disabled = false, isBorderless = false } ) {
return (
<BackdropUI
aria-hidden="true"
className="components-input-control__backdrop"
disabled={ disabled }
isBorderless={ isBorderless }
isFocused={ isFocused }
/>
);
}
Expand Down
7 changes: 1 addition & 6 deletions packages/components/src/input-control/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { ForwardedRef } from 'react';
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
import { useState, forwardRef } from '@wordpress/element';
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
Expand Down Expand Up @@ -57,8 +57,6 @@ export function UnforwardedInputControl(
...restProps
} = useDeprecated36pxDefaultSizeProp< InputControlProps >( props );

const [ isFocused, setIsFocused ] = useState( false );

const id = useUniqueId( idProp );
const classes = classNames( 'components-input-control', className );

Expand Down Expand Up @@ -87,7 +85,6 @@ export function UnforwardedInputControl(
gap={ 3 }
hideLabelFromVision={ hideLabelFromVision }
id={ id }
isFocused={ isFocused }
justify="left"
label={ label }
labelPosition={ labelPosition }
Expand All @@ -103,14 +100,12 @@ export function UnforwardedInputControl(
className="components-input-control__input"
disabled={ disabled }
id={ id }
isFocused={ isFocused }
isPressEnterToChange={ isPressEnterToChange }
onKeyDown={ onKeyDown }
onValidate={ onValidate }
paddingInlineStart={ prefix ? space( 2 ) : undefined }
paddingInlineEnd={ suffix ? space( 2 ) : undefined }
ref={ ref }
setIsFocused={ setIsFocused }
size={ size }
stateReducer={ stateReducer }
{ ...draftHookProps }
Expand Down
Loading

0 comments on commit db48edb

Please sign in to comment.