-
Notifications
You must be signed in to change notification settings - Fork 10
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
Framework - Explicit dropdown groups + smaller fixes #861
base: main
Are you sure you want to change the base?
Framework - Explicit dropdown groups + smaller fixes #861
Conversation
* Made text truncate * Made options use <ul> and <li> tags * Set a max-width option to avoid that the rect gets too large
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 very good! Just some minor comments from my side.
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 👍 Some comments below.
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 to me! 👍
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.
The changes look really good 👍 A few comments
@@ -59,74 +59,101 @@ type DropdownRect = { | |||
|
|||
type OptionItem<TValue> = { | |||
type: "option"; | |||
parentGroup?: string; | |||
// refference to group. Used to get the icon and adding some styling |
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.
Typo
} & DropdownOption<TValue>; | ||
|
||
type SeperatorItem<TValue> = { | ||
type: "separator"; | ||
type GroupTitle<TValue> = { |
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.
To be consistent, consider calling this GroupTitleItem
, or OptionItem
just Option
.
if (itemList[adjustedIndex].type !== "option") { | ||
if (adjustedIndex === 0) return 1; | ||
|
||
adjustedIndex += direction; | ||
adjustedIndex = _.clamp(adjustedIndex, 0, itemList.length - 1); | ||
} | ||
|
||
if (itemList[adjustedIndex].type !== "option") { | ||
throw new Error("Expected option item to follow non-option item!"); | ||
} |
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 fear this could become a pitfall as two groups following each other should preferably not cause a crash. Also, the early return in line 125 is dodging the whole check - what if there are two groups in a row at the start of the dropdown in a certain case of auto-generated options where the implementation on the consumer side is lacking functionality for filtering out empty groups? You could consider using the lodash
findIndex
method as it has an optional fromIndex
parameter - thus, you would look for the next valid option from the current index. If -1
is returned, you can start a new search from 0. With direction === -1
you could traverse a reversed array and just adjust the index afterwards (or have a utility function doing the search and just adjust the arguments and return value accordingly).
|
||
const valueWithDefault = props.value ?? null; | ||
const [prevValue, setPrevValue] = React.useState<TValue | null>(props.value ?? null); | ||
|
||
const [filter, setFilter] = React.useState<string | null>(null); | ||
const [prevFilter, setPrevFilter] = React.useState<string | null>(filter); | ||
|
||
const allOptionsWithSeperators = React.useMemo(() => makeOptionListItems(props.options), [props.options]); | ||
const allOptionsWithSeparators = React.useMemo( |
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.
Consider renaming this variable as you retired the separator
naming scheme.
function handleOptionsChangeEffect() { | ||
function handleMouseDown(event: MouseEvent) { | ||
function setupInputBlurListener() { | ||
// ! The ref is *actually* the div wrapping the input, so normal "blur" is not available |
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.
There is an inputRef
prop that is referencing the input element. You can add a ref to that to gain control over blur etc. However, I double-checked and there was something messed up with the references - I created a PR to fix the issues: #865
@@ -59,74 +59,101 @@ type DropdownRect = { | |||
|
|||
type OptionItem<TValue> = { | |||
type: "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.
Consider using an enum
as a type here as it is easier to both change/maintain the code and to explicitly find all references.
|
||
return () => { | ||
document.removeEventListener("mousedown", handleMouseDown); | ||
return function removeInputBlurListener() { |
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.
removeInputFocusOutListener
?
@@ -182,36 +217,36 @@ export function Dropdown<TValue = string>(props: DropdownProps<TValue>) { | |||
}, []); | |||
|
|||
React.useEffect( | |||
function handleOptionsChangeEffect() { | |||
function handleMouseDown(event: MouseEvent) { | |||
function setupInputBlurListener() { |
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.
...focusOut...
?
// Close the dropdown | ||
if (dropdownVisible && e.key === "Escape") { | ||
// FIXME: the ref is a div, so blur() isn't possible | ||
// inputRef.current?.blur(); | ||
closePopover(); |
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.
See above.
Fixes some issues in the Dropdown framework component:
DropdownOptionGroup
type to make grouping more explicitDropdown
grouping more explicit #816textSize
util<ul>
and<li>