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

Dropdown component label search #2110

Merged
merged 10 commits into from
Jul 13, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ Dropdown.propTypes = {
* see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title
*/
title: PropTypes.string,

/**
* Optional search value for the option, to use if the label
* is a component or provide a custom search value different
* from the label. If no search value and the label is a
* component, the `value` will be used for search.
*/
search: PropTypes.string,
})
),
]),
Expand Down
18 changes: 16 additions & 2 deletions components/dash-core-components/src/fragments/Dropdown.react.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {isNil, pluck, without, pick} from 'ramda';
import {isNil, pluck, without, pick, head} from 'ramda';
import React, {useState, useCallback, useEffect, useMemo} from 'react';
import ReactDropdown from 'react-virtualized-select';
import createFilterOptions from 'react-select-fast-filter-options';
Expand Down Expand Up @@ -47,12 +47,26 @@ const Dropdown = props => {
} = props;
const [optionsCheck, setOptionsCheck] = useState(null);
const [sanitizedOptions, filterOptions] = useMemo(() => {
const sanitized = sanitizeOptions(options);
let sanitized = sanitizeOptions(options);
const firstOption = sanitized ? head(sanitized) : null;
let labelKey = 'label';
if (firstOption && firstOption.search) {
labelKey = 'search';
} else if (firstOption && React.isValidElement(firstOption.label)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I can see people using strings for some options and components for others - like if they want a few options to have custom font color but others just use the default behavior. So just looking at the first one may not be robust. Also wondering if there's a way to pull the text out of a component for the same use case, particularly when the value is encoded in a way that isn't useful for searching (matching names to ID numbers or something). But it could still be nice to search on value too, especially if the search would match EITHER label or value. Is that possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it could still be nice to search on value too, especially if the search would match EITHER label or value. Is that possible?

It's possible to add field indexes to the search, maybe we should add a new prop search_indexes, then it could match any field in a dictionary of options ?

// Auto put the value as search
labelKey = 'search';
sanitized = sanitized.map(option => ({
...option,
search: `${option.value}`,
}));
}

return [
sanitized,
createFilterOptions({
options: sanitized,
tokenizer: TOKENIZER,
labelKey,
}),
];
}, [options]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,10 @@ def test_mdcap001_dcc_components_as_props(dash_dcc):
dash_dcc.find_element("#dropdown").click()
dash_dcc.wait_for_text_to_equal("#dropdown h4", "h4")
dash_dcc.wait_for_text_to_equal("#dropdown h6", "h6")

search_input = dash_dcc.find_element("#dropdown input")
search_input.send_keys("4")
options = dash_dcc.find_elements("#dropdown .VirtualizedSelectOption")

assert len(options) == 1
assert options[0].text == "h4"
2 changes: 1 addition & 1 deletion requires-testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ lxml>=4.6.2
percy>=2.0.2
pytest>=6.0.2
requests[security]>=2.21.0
selenium>=3.141.0
selenium>=3.141.0,<=4.2.0
waitress>=1.4.4