@dr.pogodin/react-utils
Version:
Collection of generic ReactJS components and utils
94 lines (92 loc) • 4.36 kB
JavaScript
// Implements dropdown based on the native HTML <select> element.
import themed from '@dr.pogodin/react-themes';
import { optionValueName } from "../common.js";
const defaultTheme = {
"context": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___context___WbwY1Y",
"ad": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___ad___AP5hsY",
"hoc": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___hoc___ODAJeW",
"dropdown": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___dropdown___wabw76",
"arrow": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___arrow___WFSB9z",
"container": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___container___vE9M8Z",
"active": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___active___sfLSJA",
"label": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___label___bQLBhS",
"option": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___option___wgCtdC",
"hiddenOption": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___hiddenOption___ty19C2",
"select": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___select___ntbzPR",
"invalid": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___invalid___3CzMM4"
};
/**
* Implements a themeable dropdown list. Internally it is rendered with help of
* the standard HTML `<select>` element, thus the styling support is somewhat
* limited.
* @param [props] Component properties.
* @param [props.filter] Options filter function. If provided, only
* those elements of `options` list will be used by the dropdown, for which this
* filter returns `true`.
* @param [props.label] Dropdown label.
* @param [props.onChange] Selection event handler.
* @param [props.options=[]] Array of dropdown
* options. For string elements the option value and name will be the same.
* It is allowed to mix DropdownOption and string elements in the same option
* list.
* @param [props.theme] _Ad hoc_ theme.
* @param [props.value] Currently selected value.
* @param [props....]
* [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)
*/
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const Dropdown = ({
filter,
label,
onChange,
options,
testId,
theme,
value
}) => {
let isValidValue = false;
const optionElements = [];
for (const option of options) {
if (!filter || filter(option)) {
const [iValue, iName] = optionValueName(option);
isValidValue ||= iValue === value;
optionElements.push(/*#__PURE__*/_jsx("option", {
className: theme.option,
value: iValue,
children: iName
}, iValue));
}
}
// NOTE: This element represents the current `value` when it does not match
// any valid option. In Chrome, and some other browsers, we are able to hide
// it from the opened dropdown; in others, e.g. Safari, the best we can do is
// to show it as disabled.
const hiddenOption = isValidValue ? null : /*#__PURE__*/_jsx("option", {
className: theme.hiddenOption,
disabled: true,
value: value,
children: value
}, "__reactUtilsHiddenOption");
let selectClassName = theme.select;
if (!isValidValue) selectClassName += ` ${theme.invalid}`;
return /*#__PURE__*/_jsxs("div", {
className: theme.container,
children: [label === undefined ? null : /*#__PURE__*/_jsx("div", {
className: theme.label,
children: label
}), /*#__PURE__*/_jsxs("div", {
className: theme.dropdown,
children: [/*#__PURE__*/_jsxs("select", {
className: selectClassName,
"data-testid": process.env.NODE_ENV === 'production' ? undefined : testId,
onChange: onChange,
value: value,
children: [hiddenOption, optionElements]
}), /*#__PURE__*/_jsx("div", {
className: theme.arrow
})]
})]
});
};
export default themed(Dropdown, 'Dropdown', defaultTheme);
//# sourceMappingURL=index.js.map