Skip to content

Conversation

chad1008
Copy link
Contributor

@chad1008 chad1008 commented Jan 4, 2023

What?

Related to #46358

Update ColorPalette's onChange prop to require a string for its newColor parameter, rather than optionally accepting one.

Why?

While working on the above refactor, I encountered type conflicts with ColorPalette's onChange, because this method's newColor parameter was optional, and could therefor be undefined. Within ColorListPicker the related onChange values are all strings or arrays of strings.

While we could type the parameters in ColorListPicker's onChange as string | undefined I thought it was worth revisiting why ColorPalette introduces and optional/undefined value in the first place.

It appears this parameter is optional to accommodate ColorPalette's clearColor method, which passes undefined as the new color value.

That works fine, but I do wonder if "optional" is the best approach for the parameter... there is a second parameter (index, also optional) for the onChange - so omitting newColor while including index would cause a collision, the index would be interpreted as newColor and chaos would ensue. This probably isn't likely to occur in practice, but it does look like a potential issue/edge case that could slip past TypeScript.

That logic leads me to think that string | undefined would be more appropriate than an optional newColor parameter.

Going back to the refactor that initially triggered this however, I do think we can eliminate the undefined option altogether and have clearColor pass an empty string instead. This doesn't appear to break any functionality or tests that I can see, and will simplify the typing of both components.

Curious what others think (cc @mirka @ciampo)

How?

First, update the newColor parameter's type from an optional string to a required one, then replace the use of undefined when clearColor is invoked with an empty string.

Testing Instructions

  1. Open the ColorPalette component in Storybook
  2. Select any color, and then click it again to deselect it, which will invoke the clearColor method we've updated
  3. Select and deselect other colors
  4. Confirm there are no console errors, and all selections/deselections work as expected
  5. Test in the editor using any block with a color palette (selecting and deselecting text color on a paragraph block, for example).

Testing Instructions for Keyboard

In the editor, with a paragraph block focused, press Tab five times, which will navigate you to the font color option.
Press Space
Press Tabat least once to navigate to a color.
Press Space to select the color. Press Space again to deselect it.

@chad1008 chad1008 added [Type] Code Quality Issues or PRs that relate to code quality [Package] Components /packages/components labels Jan 4, 2023
@chad1008 chad1008 requested review from mirka and ciampo January 4, 2023 18:37
@chad1008 chad1008 requested a review from ajitbohra as a code owner January 4, 2023 18:37
@chad1008 chad1008 self-assigned this Jan 4, 2023
@@ -228,7 +228,7 @@ function UnforwardedColorPalette(
__experimentalIsRenderedInSidebar = false,
...otherProps
} = props;
const clearColor = useCallback( () => onChange( undefined ), [ onChange ] );
const clearColor = useCallback( () => onChange( '' ), [ onChange ] );
Copy link
Member

Choose a reason for hiding this comment

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

This may break third-party component users that on the onChange handler may have logic relying on the onChange parameter being undefined. I think it would be better to say the type is string | undefined.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point! I'll leave it as-is and update types elsewhere accordingly, thank you!

@chad1008 chad1008 closed this Jan 9, 2023
@ciampo
Copy link
Contributor

ciampo commented Jan 12, 2023

That works fine, but I do wonder if "optional" is the best approach for the parameter... there is a second parameter (index, also optional) for the onChange - so omitting newColor while including index would cause a collision, the index would be interpreted as newColor and chaos would ensue. This probably isn't likely to occur in practice, but it does look like a potential issue/edge case that could slip past TypeScript.

We could definitely bolster the code by trying to parse the first argument and understand if it's a newColor or an index — we could also first write tests around this case to understand if / how severely it would break when that happens.

@johnbillion johnbillion deleted the fix/ColorPalette-onchange-arg branch April 22, 2025 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants