Skip to content

Instantly share code, notes, and snippets.

@JenyaIII-sudo
Last active June 27, 2020 10:42
Show Gist options
  • Save JenyaIII-sudo/f40ad5eb2e0a8c7fb4e7b8b0a76d8d4a to your computer and use it in GitHub Desktop.
Save JenyaIII-sudo/f40ad5eb2e0a8c7fb4e7b8b0a76d8d4a to your computer and use it in GitHub Desktop.
Select component (<div>)
import React from 'react';
import _ from 'lodash';
import cx from 'classnames';
import Fetch from 'components/Fetch/Fetch';
import Dropdown, { DropdownContent } from 'components/Dropdown/Dropdown';
import { useFormControl, withFormControl } from 'components/Form/Form';
import { SelectContext } from './SelectContext';
import SelectKeyboardHandler from './SelectKeyboardHandler';
import SelectScrollToSelected from './SelectScrollToSelected';
import styles from './Select.css';
export { useSelect } from './SelectContext';
export Option from './Option';
export default withFormControl()(function Select(props) {
const {
value,
text = (optionValue) => optionValue,
showBorder = true,
unselectable = false,
unselectableKey,
placeholder,
url,
params,
cache,
className,
containerClassName,
contentClassName,
children,
onChange,
...rest
} = props;
const control = useFormControl();
function isEqual(currentValue, nextValue) {
return unselectableKey !== null
? currentValue?.[unselectableKey] === nextValue?.[unselectableKey]
: _.isEqual(value, nextValue);
}
const context = {
select(nextValue) {
if (unselectable) {
onChange(!isEqual(value, nextValue)
? nextValue
: null);
return;
}
if (!_.isEqual(value, nextValue)) {
onChange(nextValue);
}
},
isSelected(optionValue) {
return _.isEqual(optionValue, value);
},
};
const hasValue = value !== null;
const cxClassName = cx(styles.dropdown, {
[styles.hasValue]: hasValue,
}, className);
const cxContainerClassName = cx(styles.container, containerClassName);
const cxContentClassName = cx(styles.content, 'ignore-onclickoutside', contentClassName);
return (
<SelectContext.Provider value={context}>
<Dropdown
label={control.label}
error={control.error}
title={control.title}
readOnly={control.readOnly}
disabled={control.disabled}
{...rest}
showBorder={showBorder}
className={cxClassName}
openClassName={styles.open}
readOnlyClassName={styles.readOnly}
disabledClassName={styles.disabled}
>
{placeholder !== null && value == null && (
<span className={styles.placeholder}>
{placeholder}
</span>
)}
{hasValue && (
<span className={styles.displayContent}>
{text(value)}
</span>
)}
<DropdownContent
useMinWidth
className={cxContainerClassName}
contentClassName={cxContentClassName}
id={props.id}
>
<Fetch
url={url}
params={params}
cache={cache}
>
{(response) => (
<>
{_.isFunction(children)
? children(response)
: children}
<SelectKeyboardHandler />
<SelectScrollToSelected />
</>
)}
</Fetch>
</DropdownContent>
</Dropdown>
</SelectContext.Provider>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment