Skip to content

Add options prop to <SelectField> #1342

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

Merged
merged 7 commits into from
Feb 17, 2022
Merged

Add options prop to <SelectField> #1342

merged 7 commits into from
Feb 17, 2022

Conversation

joebuono
Copy link
Contributor

@joebuono joebuono commented Feb 16, 2022

Description of changes

The added options prop accepts an array of strings which maps to the value, label and children of each <option> in a SelectField.

If there are children and an options prop is set, then the children will win but there will be a warning in the console.

This requirement will help Amplify Studio's Codegen team create a SelectField easier, plus it has a nice DX if the customer just wants a simple SelectField.

Issue #, if available

Description of how you validated changes

Added a test and confirmed that a new options example in the docs works correctly.

Checklist

  • PR description included
  • yarn test passes
  • Tests are updated
  • Relevant documentation is changed or added (and PR referenced)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2022

🦋 Changeset detected

Latest commit: 7802de5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@aws-amplify/ui-react Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@joebuono joebuono temporarily deployed to ci February 16, 2022 21:34 Inactive
@joebuono joebuono temporarily deployed to ci February 16, 2022 21:34 Inactive
@joebuono joebuono temporarily deployed to ci February 16, 2022 21:34 Inactive
@joebuono joebuono temporarily deployed to ci February 16, 2022 21:34 Inactive
Copy link
Contributor

@reesscot reesscot 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, just a few comments below

console.warn(
'Amplify UI: <SelectField> component defaults to rendering children over `options`. When using the `options` prop, do not also pass children.'
);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think of doing an early return for the children, since children takes precedence?

  if (children) {
    if (options?.length) {
          console.warn(
             'Amplify UI: <SelectField> component  defaults to rendering children over `options`. When using the `options` prop, omit children.'
          );
    }
    return children;
  }
  
  return options.map((option, index) => (
        <option label={option} value={option} key={index}>
          {option}
        </option>
  ));

IMO, else statements are usually a code smell that the logic should be simplified (often using an early return).

Copy link
Contributor Author

@joebuono joebuono Feb 16, 2022

Choose a reason for hiding this comment

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

Good point. The reason I wrote it this way is because I wanted to handle the case where there are neither children nor options. By default, I think we want it to return children.

@joebuono joebuono requested a review from reesscot February 17, 2022 00:15
@joebuono joebuono temporarily deployed to ci February 17, 2022 00:25 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 00:25 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 00:25 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 00:25 Inactive
Copy link
Contributor

@dbanksdesign dbanksdesign left a comment

Choose a reason for hiding this comment

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

Great job!

great job

"@aws-amplify/ui-react": patch
---

Add `options` prop to <SelectField>
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice to add an example in here too.

options,
}: SelectFieldChildrenProps) => {
if (children) {
if (options?.length) {
Copy link
Contributor

Choose a reason for hiding this comment

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

https://caniuse.com/mdn-javascript_operators_optional_chaining

Oh we can use javascript optional chaining??

clap

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, and I believe TypeScript should handle the conversion to ES5 if not.

@joebuono joebuono temporarily deployed to ci February 17, 2022 17:04 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 17:04 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 17:04 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 17:04 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 18:37 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 18:37 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 18:37 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 18:37 Inactive
Copy link
Contributor

@reesscot reesscot left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -0,0 +1,10 @@
---
"@aws-amplify/ui-react": patch
Copy link
Contributor

@zchenwei zchenwei Feb 17, 2022

Choose a reason for hiding this comment

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

Should we mark it as a minor bump? IMO, patch is for small bug fixes 🤣

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, good idea

@joebuono joebuono temporarily deployed to ci February 17, 2022 19:03 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 19:03 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 19:03 Inactive
@joebuono joebuono temporarily deployed to ci February 17, 2022 19:03 Inactive
Comment on lines +22 to +23
if (children) {
if (options?.length) {
Copy link
Contributor

@zchenwei zchenwei Feb 17, 2022

Choose a reason for hiding this comment

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

Suggested change
if (children) {
if (options?.length) {
if (children) {
if (Array.isArray(options)) {
....
}

nit: do you think this would be better?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there's a way to handle all four of these cases without nested if...else blocks, then yes:

  1. There are children, but no options
  2. There are children and options
  3. There are no children and no options
  4. There are no children, but there are options

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, my bad. I missed something there and I updated the comment there :)

@joebuono joebuono merged commit 7a675ac into main Feb 17, 2022
@joebuono joebuono deleted the selecfield-options branch February 17, 2022 19:21
}

return options?.map((option, index) => (
<option label={option} value={option} key={`${option}-${index}`}>
Copy link
Contributor

@zchenwei zchenwei Feb 17, 2022

Choose a reason for hiding this comment

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

Just think out loud, I think appending index will somehow affect React's diff algorithm negatively. This can work well if the items are never reordered, but reorders will be slow. For example, if I have an option <option label="amplify" value="amplify" key={'amplify-2'}> at index 2, and I make updates later to the option array, where I get the exact same option <option label="amplify" value="amplify" key={'amplify-1'}> move to index 1. However, React will think they are different because their keys are affected by the index and thus re-created it versus keeping the original one

Copy link
Contributor

Choose a reason for hiding this comment

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

@github-actions github-actions bot mentioned this pull request Feb 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants