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

✨(react) rework the behavior of the Select component #166

Merged
merged 1 commit into from Sep 22, 2023

Conversation

NathanVss
Copy link
Member

We decided to change a bit the behavior of the Select:

  • Do not trigger onChange on first render if value is defined
  • Show all options on searchable select menu opening even if there is an existing value.
  • Clear the input field if no choice are selected
  • Clear the added text to the input field when a value is already selected

@changeset-bot
Copy link

changeset-bot bot commented Sep 19, 2023

🦋 Changeset detected

Latest commit: 5119875

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

This PR includes changesets to release 1 package
Name Type
@openfun/cunningham-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

@NathanVss NathanVss mentioned this pull request Sep 19, 2023
14 tasks
Copy link
Contributor

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

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

It works perfect.

Just an observation, if I type "Pa" and click enter on the keyboard, the input stay on "Pa" even when I click somewhere else, but onChange is not trigger so it is ok, I don't know if you should do something or not.

Just a few comment then we are good.

@@ -317,7 +456,10 @@ describe("<Select/>", () => {
},
]}
value={value}
onChange={(e) => setValue(e.target.value as string)}
onChange={(e) => {
setValue(e.target.value as string);
Copy link
Contributor

Choose a reason for hiding this comment

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

A bit out of the scope, but I can see value can be from type string | number | string[] | undefined when Option.value can only be with string | undefined(https://github.com/openfun/cunningham/blob/main/packages/react/src/components/Forms/Select/mono.tsx#L9), I suppose they should have the same type and if possible infer from each other to avoid casting, what do you think ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I agree with you, we took the constraint to have the exact type as the native <select/> which uses this union. However I agree that there is maybe something to work on on this.

  • I think having value that could only be of type string is a mistake has it could be useful to allow number too

setOptionsToDisplay(props.options);
}
}, [downshiftReturn.isOpen]);

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}, [downshiftReturn.isOpen, props.options]);

Copy link
Member Author

Choose a reason for hiding this comment

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

Doing this will cause:
-> If options change when typing for filtering it will display all options totally ignoring the filter. Which is a non-sense

WDYT?

Copy link
Contributor

@AntoLC AntoLC Sep 20, 2023

Choose a reason for hiding this comment

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

If the options change when the select is open, the new options will not pass in setOptionsToDisplay, so actually if the user clicks on one of the option proposed, it will send back in onChange an old value who could be not part of the new options. Depend the case it could potentially create a bug.

Copy link
Member Author

@NathanVss NathanVss Sep 21, 2023

Choose a reason for hiding this comment

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

imo this is out the scope of this useEffect which is role is "Display all options only once when isOpen turns true". Adding here this new dep would result in the bug I described. It is some sort of event emitter "onOpen".

Regarding your use case we could do another PR to treat this potential issue which needs to be done in another part of the code, because this was existing before this PR.

In reality imo we cannot always apply the "add all used variables to the deps", in most cases the called methods use lots of other hidden variables that we never add as deps and that's ok. Sometimes it could cause bugs like the one I described.

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 have been nice to fix directly these 2 issues when we could do it directly:

-> If options change when typing for filtering it will display all options totally ignoring the filter.

If the options change when the select is open, the new options will not pass in setOptionsToDisplay, so actually if the user clicks on one of the option proposed, it will send back in onChange an old value who could be not part of the new options. Depend the case it could potentially create a bug.

But let's create another PR if you feel more confortable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I want to be able to make a release in between 😬

@NathanVss
Copy link
Member Author

It works perfect.

Just an observation, if I type "Pa" and click enter on the keyboard, the input stay on "Pa" even when I click somewhere else, but onChange is not trigger so it is ok, I don't know if you should do something or not.

Just a few comment then we are good.

Really good catch! This was caused by the blur event not triggered by downshift in this situation which makes no sense as the user still have focus on input ... so to overcome this issue I added a straightforward fix-up after having tried to use the reducer 😅

Copy link
Contributor

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

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

About the enter it is good.

setOptionsToDisplay(props.options);
}
}, [downshiftReturn.isOpen]);

Copy link
Contributor

@AntoLC AntoLC Sep 20, 2023

Choose a reason for hiding this comment

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

If the options change when the select is open, the new options will not pass in setOptionsToDisplay, so actually if the user clicks on one of the option proposed, it will send back in onChange an old value who could be not part of the new options. Depend the case it could potentially create a bug.

We decided to change a bit the behavior of the Select:
- Do not trigger onChange on first render if value is defined
- Show all options on searchable select menu  opening even if there is an
  existing value.
- Clear the input field if no choice are selected
- Clear the added text to the input field when a value is already selected
@NathanVss NathanVss merged commit 4e1d0f0 into main Sep 22, 2023
5 checks passed
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.

None yet

2 participants