-
Notifications
You must be signed in to change notification settings - Fork 324
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
Conversation
🦋 Changeset detectedLatest commit: 7802de5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
docs/src/pages/components/selectfield/examples/SelectFieldOptionsExample.tsx
Show resolved
Hide resolved
There was a problem hiding this 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 { |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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
.
packages/react/src/primitives/SelectField/__tests__/SelectField.test.tsx
Show resolved
Hide resolved
docs/src/pages/components/selectfield/examples/SelectFieldOptionsExample.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"@aws-amplify/ui-react": patch | ||
--- | ||
|
||
Add `options` prop to <SelectField> |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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??
There was a problem hiding this comment.
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.
packages/react/src/primitives/SelectField/__tests__/SelectField.test.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
.changeset/silent-queens-guess.md
Outdated
@@ -0,0 +1,10 @@ | |||
--- | |||
"@aws-amplify/ui-react": patch |
There was a problem hiding this comment.
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 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good idea
if (children) { | ||
if (options?.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (children) { | |
if (options?.length) { | |
if (children) { | |
if (Array.isArray(options)) { | |
.... | |
} |
nit: do you think this would be better?
There was a problem hiding this comment.
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:
- There are
children
, but nooptions
- There are
children
andoptions
- There are no
children
and nooptions
- There are no
children
, but there areoptions
There was a problem hiding this comment.
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 :)
} | ||
|
||
return options?.map((option, index) => ( | ||
<option label={option} value={option} key={`${option}-${index}`}> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good reading <- https://reactjs.org/docs/reconciliation.html
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
yarn test
passesBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.