Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CustomSelectControl: support generic props type #63985

Merged
merged 7 commits into from
Jul 29, 2024

Conversation

meteorlxy
Copy link
Contributor

What?

Fixes #63984

Why?

It would be helpful to infer the option type

How?

  • Making the CustomSelectProps a generic type
  • Exporting CustomSelectOption and CustomSelectChangeObject type

Testing Instructions

Using the following snippet to see if the selectedItem type is inferred correctly:

import { CustomSelectControl } from '@wordpress/components';
import type { CustomSelectOption } from '@wordpress/components/build-types/custom-select-control/types';

type MyOption = CustomSelectOption & {
  foo: string;
};

const options: MyOption[] = [
  {
    key: 'none',
    name: 'None',
    foo: 'bar',
  },
  {
    key: 'foo',
    name: 'Foo',
    foo: 'bar',
  },
];

const render = () => (
  <CustomSelectControl
    label="foo"
    onChange={({ selectedItem }) => {
      console.log(selectedItem.foo);
    }}
    options={options}
    value={options[0]}
  />
);

Testing Instructions for Keyboard

N/A

Screenshots or screencast

Before

image

After

image

@meteorlxy meteorlxy changed the title CustomSelectControl: support generic option type CustomSelectControl: support generic props type Jul 26, 2024
Copy link

github-actions bot commented Jul 26, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: meteorlxy <meteorlxy@git.wordpress.org>
Co-authored-by: tyxla <tyxla@git.wordpress.org>
Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: mirka <0mirka00@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @meteorlxy! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@github-actions github-actions bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Jul 26, 2024
@meteorlxy meteorlxy force-pushed the meteorlxy/custom-select-option-type branch from c3d5dc4 to 4f5c724 Compare July 26, 2024 09:56
@mirka mirka requested a review from a team July 29, 2024 11:18
@mirka mirka added [Type] Enhancement A suggestion for improvement. [Package] Components /packages/components labels Jul 29, 2024
@@ -6,6 +6,10 @@

- `CustomSelectControl`: Restore `describedBy` functionality ([#63957](https://github.com/WordPress/gutenberg/pull/63957)).

### Enhancements
Copy link
Member

Choose a reason for hiding this comment

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

Since this is a type change, I believe it should be under Internal instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cuz the type will be used by user, and will improve the developer experience, I think it's more of an improvement / enhancement?

Copy link
Member

Choose a reason for hiding this comment

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

IMHO, types and type changes are an internal kind of enhancement, and we have this "Internal" group to distinguish them. General Enhancements would usually be targeted towards end users.

@@ -51,7 +51,9 @@ function getDescribedBy( currentValue: string, describedBy?: string ) {
return sprintf( __( 'Currently selected: %s' ), currentValue );
}

function CustomSelectControl( props: CustomSelectProps ) {
function CustomSelectControl< T extends CustomSelectOption >(
Copy link
Member

Choose a reason for hiding this comment

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

Should we add a default to the generic so any existing consumers will continue working without changing anything?

The same question applies to all instances where we're adding a generic and there wasn't one before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The generic param is not going to be set manually by user. It's used for type inferring. To be specific, it will use the item type of the options prop automatically. So consumers would not need to change anything.

You could checkout this branch and test with the snippets that pasted in the "Testing Instructions" section.

Copy link
Member

Choose a reason for hiding this comment

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

TypeScript should always be able to infer the T type. CustomSelectProps have a mandatory options: Array<T> field, so T is always the type of whatever you pass as options, it's easy to infer. TypeScript will merely check if that type is compatible with CustomSelectOption.

Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

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

This looks good and tests well in my editor, thanks for the contribution @meteorlxy 🙌

The only thing I'd change would be to move the CHANGELOG entry to "Internal".

@meteorlxy
Copy link
Contributor Author

@tyxla updated

@meteorlxy meteorlxy requested review from tyxla and jsnajdr July 29, 2024 14:52
@@ -24,15 +24,15 @@ type Option = {
/**
* The object returned from the onChange event.
*/
type ChangeObject = {
export type CustomSelectChangeObject< T extends CustomSelectOption > = {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to export this one? Seems like we don't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would be useful if user want to get the ChangeObject type, otherwise we have to use the following snippet to get the type:

image

Copy link
Member

Choose a reason for hiding this comment

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

Right 👍

Exporting it here doesn't export it from the package, though. And if we're not importing it inside the package, then it's effectively unnecessary to export it, IMHO. We can always start exporting it if we need to in the future.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, at the moment we are avoiding public type exports as much as possible, thanks 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, removed

@meteorlxy meteorlxy requested review from tyxla and mirka July 29, 2024 16:30
Copy link
Member

@mirka mirka left a comment

Choose a reason for hiding this comment

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

Looks good, thank you! 🚀

@mirka mirka enabled auto-merge (squash) July 29, 2024 16:44
@mirka mirka merged commit ef1ee6b into WordPress:trunk Jul 29, 2024
63 checks passed
@github-actions github-actions bot added this to the Gutenberg 19.0 milestone Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Package] Components /packages/components [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CustomSelectControl: Support generic props type
4 participants