-
Notifications
You must be signed in to change notification settings - Fork 5
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
Add MultiSelectSearch component #919
Conversation
Note that this component is being improved in #920 . I'm looking for tips and opinions |
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.
Most of the stuff is not that important, but I would consider fixing at least the ones that are straightforward and quick to fix.
By far the most important comment is the one regarding the double state management. If there's no need to duplicate it, I would change the implementation. Marking as request changes because of this issue, but I can probably be swayed with good arguments.
apps/cyberstorm-storybook/stories/components/MultiSelectSearch.stories.tsx
Show resolved
Hide resolved
apps/cyberstorm-storybook/stories/components/MultiSelectSearch.stories.tsx
Outdated
Show resolved
Hide resolved
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.module.css
Show resolved
Hide resolved
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.module.css
Outdated
Show resolved
Hide resolved
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.tsx
Outdated
Show resolved
Hide resolved
</Icon> | ||
</button> | ||
</div> | ||
<div |
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.
I can't recall how selects normally handle this but it looks a bit awkward if the dropdown is open but filteredOptions
show no options to choose from
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.
Decided to go with showing an empty dropdown instead of hiding it. Found a little less confusing to have an empty list, instead of nothing happening on screen. In the end designs decide though.
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.tsx
Outdated
Show resolved
Hide resolved
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.tsx
Outdated
Show resolved
Hide resolved
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.tsx
Outdated
Show resolved
Hide resolved
packages/cyberstorm/src/components/MultiSelectSearch/MultiSelectSearch.tsx
Outdated
Show resolved
Hide resolved
94c0e37
to
c2ff54f
Compare
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.
I've understood there's some pressure to get this merged so I'll mark this as approved, but I think the two usability problems reproducable on Storybook/FF should be fixed ASAP.
}; | ||
|
||
const Template: StoryFn<typeof MultiSelectSearch> = (args) => { | ||
const [selected, setSelected] = useState(options); |
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.
This now sets all options selected initially, so the user has nothing to choose from before they unselect something. Not the best demo case.
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.
Changed selected to empty list 👍
<div style={{ color: "white" }}> | ||
Value in state:{" "} | ||
{selected | ||
.map((s) => { |
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.
Nitpick: .map((s) => s.label)
return ( | ||
<div className={styles.root} ref={ref}> | ||
<div className={styles.selected}> | ||
{value.map((option) => { |
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.
Currently the options are listed in the order they are selected. IDK if it would be more user friendly if they were ordered alphabetically? Something to think about e.g. when fixing the other TODOs later on?
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.
Added sorting 👍
ref={menuRef} | ||
> | ||
<div className={styles.inputContainer} data-color={color}> | ||
<input |
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.
On Storybook, at least with Firefox, the tab navigation will now get stuck into this input, not moving forward no matter how many times I tab.
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.
Fixed this issue, but I'll keep the keyboard navigation todo there, because I'm not 100% what is the best practice, so we need to fully fix the keyboard nav later.
</button> | ||
<div className={styles.inputButtonDivider}></div> | ||
<button | ||
onClick={(e) => { |
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.
On Storybook, at least with Firefox, when the menu is invisible, I'd expect clicking this would make it visible. But the menu stays visible only for a fraction of a second, then it closes and the focus moves into the input.
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.
Probably was broken because of the focus fuckery in the last comment you made, should be fixed now 👍
@@ -3,3 +3,10 @@ export const isRecord = (obj: unknown): obj is Record<string, unknown> => | |||
|
|||
export const isStringArray = (arr: unknown): arr is string[] => | |||
Array.isArray(arr) && arr.every((s) => typeof s === "string"); | |||
|
|||
export const isNode = (e: EventTarget | null): e is Node => { | |||
if (!e || !("nodeType" in e)) { |
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.
Nitpick. I suspect you've fallen victim to one of the classic blunders, namely only fixing the line mentioned in a comment and disregarding the context. Now that this no longer throws an error, it would make more sense to be just
export const isNode = (e: EventTarget | null): e is Node =>
e !== null && "nodeType" in e;
Add ordering to selected Half-fix onFocus / Tab event interractions Cleanup isNode refs TS-1968
TS-1968