Skip to content

Commit

Permalink
Accessibility: Fix custom color palette (#62753)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: afercia <afercia@git.wordpress.org>
Co-authored-by: joedolson <joedolson@git.wordpress.org>
  • Loading branch information
4 people committed Jun 25, 2024
1 parent 25aa1b8 commit e618232
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 52 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Enhancements

- `DropZone`: rewrite animation without depending on framer-motion. ([#62044](https://github.com/WordPress/gutenberg/pull/62044))
- `__experimentalPaletteEdit`: improve the accessibility. ([#62753](https://github.com/WordPress/gutenberg/pull/62753))

### Internal

Expand Down
78 changes: 33 additions & 45 deletions packages/components/src/palette-edit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ import {
} from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { lineSolid, moreVertical, plus } from '@wordpress/icons';
import {
__experimentalUseFocusOutside as useFocusOutside,
useDebounce,
} from '@wordpress/compose';
import { useDebounce } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -174,16 +171,13 @@ function Option< T extends Color | Gradient >( {
canOnlyChangeValues,
element,
onChange,
isEditing,
onStartEditing,
onRemove,
onStopEditing,
popoverProps: receivedPopoverProps,
slugPrefix,
isGradient,
}: OptionProps< T > ) {
const focusOutsideProps = useFocusOutside( onStopEditing );
const value = isGradient ? element.gradient : element.color;
const [ isEditingColor, setIsEditingColor ] = useState( false );

// Use internal state instead of a ref to make sure that the component
// re-renders when the popover's anchor updates.
Expand All @@ -198,26 +192,23 @@ function Option< T extends Color | Gradient >( {
);

return (
<PaletteItem
className={ isEditing ? 'is-selected' : undefined }
as={ isEditing ? 'div' : 'button' }
onClick={ onStartEditing }
aria-label={
isEditing
? undefined
: sprintf(
// translators: %s is a color or gradient name, e.g. "Red".
__( 'Edit: %s' ),
element.name.trim().length ? element.name : value
)
}
ref={ setPopoverAnchor }
{ ...( isEditing ? { ...focusOutsideProps } : {} ) }
>
<PaletteItem ref={ setPopoverAnchor } as="div">
<HStack justify="flex-start">
<IndicatorStyled colorValue={ value } />
<Button
onClick={ () => {
setIsEditingColor( true );
} }
aria-label={ sprintf(
// translators: %s is a color or gradient name, e.g. "Red".
__( 'Edit: %s' ),
element.name.trim().length ? element.name : value
) }
style={ { padding: 0 } }
>
<IndicatorStyled colorValue={ value } />
</Button>
<FlexItem>
{ isEditing && ! canOnlyChangeValues ? (
{ ! canOnlyChangeValues ? (
<NameInput
label={
isGradient
Expand All @@ -244,23 +235,30 @@ function Option< T extends Color | Gradient >( {
</NameContainer>
) }
</FlexItem>
{ isEditing && ! canOnlyChangeValues && (
{ ! canOnlyChangeValues && (
<FlexItem>
<RemoveButton
size="small"
icon={ lineSolid }
label={ __( 'Remove color' ) }
label={ sprintf(
// translators: %s is a color or gradient name, e.g. "Red".
__( 'Remove color: %s' ),
element.name.trim().length
? element.name
: value
) }
onClick={ onRemove }
/>
</FlexItem>
) }
</HStack>
{ isEditing && (
{ isEditingColor && (
<ColorPickerPopover
isGradient={ isGradient }
onChange={ onChange }
element={ element }
popoverProps={ popoverProps }
onClose={ () => setIsEditingColor( false ) }
/>
) }
</PaletteItem>
Expand All @@ -270,12 +268,11 @@ function Option< T extends Color | Gradient >( {
function PaletteEditListView< T extends Color | Gradient >( {
elements,
onChange,
editingElement,
setEditingElement,
canOnlyChangeValues,
slugPrefix,
isGradient,
popoverProps,
addColorRef,
}: PaletteEditListViewProps< T > ) {
// When unmounting the component if there are empty elements (the user did not complete the insertion) clean them.
const elementsReference = useRef< typeof elements >();
Expand All @@ -294,11 +291,6 @@ function PaletteEditListView< T extends Color | Gradient >( {
canOnlyChangeValues={ canOnlyChangeValues }
key={ index }
element={ element }
onStartEditing={ () => {
if ( editingElement !== index ) {
setEditingElement( index );
}
} }
onChange={ ( newElement ) => {
debounceOnChange(
elements.map(
Expand All @@ -312,7 +304,6 @@ function PaletteEditListView< T extends Color | Gradient >( {
);
} }
onRemove={ () => {
setEditingElement( null );
const newElements = elements.filter(
( _currentElement, currentIndex ) => {
if ( currentIndex === index ) {
Expand All @@ -324,12 +315,7 @@ function PaletteEditListView< T extends Color | Gradient >( {
onChange(
newElements.length ? newElements : undefined
);
} }
isEditing={ index === editingElement }
onStopEditing={ () => {
if ( index === editingElement ) {
setEditingElement( null );
}
addColorRef.current?.focus();
} }
slugPrefix={ slugPrefix }
popoverProps={ popoverProps }
Expand Down Expand Up @@ -408,6 +394,8 @@ export function PaletteEdit( {
[ isGradient, elements ]
);

const addColorRef = useRef< HTMLButtonElement | null >( null );

return (
<PaletteEditStyles>
<HStack>
Expand All @@ -428,6 +416,7 @@ export function PaletteEdit( {
) }
{ ! canOnlyChangeValues && (
<Button
ref={ addColorRef }
size="small"
isPressed={ isAdding }
icon={ plus }
Expand Down Expand Up @@ -551,11 +540,10 @@ export function PaletteEdit( {
elements={ elements }
// @ts-expect-error TODO: Don't know how to resolve
onChange={ onChange }
editingElement={ editingElement }
setEditingElement={ setEditingElement }
slugPrefix={ slugPrefix }
isGradient={ isGradient }
popoverProps={ popoverProps }
addColorRef={ addColorRef }
/>
) }
{ ! isEditing && editingElement !== null && (
Expand Down
6 changes: 2 additions & 4 deletions packages/components/src/palette-edit/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe( 'PaletteEdit', () => {
await click( screen.getByRole( 'button', { name: 'Edit: Primary' } ) );
await click(
screen.getByRole( 'button', {
name: 'Remove color',
name: 'Remove color: Primary',
} )
);

Expand Down Expand Up @@ -337,9 +337,7 @@ describe( 'PaletteEdit', () => {
} )
);
await click( screen.getByRole( 'button', { name: 'Edit: Primary' } ) );
const nameInput = screen.getByRole( 'textbox', {
name: 'Color name',
} );
const nameInput = screen.getByDisplayValue( 'Primary' );

await clearInput( nameInput as HTMLInputElement );

Expand Down
4 changes: 1 addition & 3 deletions packages/components/src/palette-edit/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,8 @@ export type OptionProps< T extends Color | Gradient > = {
onChange: ( newElement: T ) => void;
isGradient: T extends Gradient ? true : false;
canOnlyChangeValues: PaletteEditProps[ 'canOnlyChangeValues' ];
isEditing: boolean;
key: Key;
onRemove: MouseEventHandler< HTMLButtonElement >;
onStartEditing: () => void;
onStopEditing: () => void;
popoverProps?: PaletteEditProps[ 'popoverProps' ];
slugPrefix: string;
};
Expand All @@ -130,6 +127,7 @@ export type PaletteEditListViewProps< T extends Color | Gradient > = {
onChange: ( newElements?: T[] ) => void;
isGradient: T extends Gradient ? true : false;
canOnlyChangeValues: PaletteEditProps[ 'canOnlyChangeValues' ];
addColorRef: React.RefObject< HTMLButtonElement >;
editingElement?: EditingElement;
popoverProps?: PaletteEditProps[ 'popoverProps' ];
setEditingElement: ( newEditingElement?: EditingElement ) => void;
Expand Down

1 comment on commit e618232

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in e618232.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/9660990784
📝 Reported issues:

Please sign in to comment.