lodash-es#flatMap TypeScript Examples
The following examples show how to use
lodash-es#flatMap.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Select.tsx From UUI with MIT License | 4 votes |
BaseSelect = UUIFunctionComponent({
name: 'Select',
nodes: SelectNodes,
propTypes: SelectPropTypes,
}, (props: SelectFeatureProps<boolean | undefined>, { nodes, NodeDataProps }) => {
const {
Root, Dropdown, DropdownIcon,
Activator, Result, Placeholder,
TagInputContainer,
ActionBox,
OptionList, Section, Option,
SearchList, SearchInput, SearchIcon,
LoadingSpinner,
Tag,
} = nodes
const finalProps = {
disabled: props.disabled === undefined ? false : props.disabled,
searchable: props.searchable === undefined ? false : props.searchable,
placeholder: props.placeholder || 'select options...',
searchPlaceholder: props.searchPlaceholder || 'Search options...',
dropdownPlacement: props.dropdownPlacement === undefined ? 'bottom-start' : props.dropdownPlacement
}
const [active, setActive] = useState<boolean>(false)
const [searchInputValue, setSearchInputValue] = useState('')
const ref = useRef<any>(null)
const allOptions = useMemo(() => {
if (isNormalOptions(props)) return props.options
if (isSectionedOptions(props)) {
return flatMap(props.sections, (i) => i.options)
}
return []
}, [props])
const openDropdown = useCallback(() => {
setActive(true)
}, [])
const closeDropdown = useCallback(() => {
setActive(false)
setSearchInputValue('')
}, [])
/**
* ListBox
*/
const displayResult = useMemo(() => {
return props.value && props.value.length > 0
? (
<Result>
{isMultipleValue(props) ? (
<TagInputContainer>
{
props.value &&
props.value.length > 0 &&
compact(props.value.map((v) => allOptions?.find((i) => i.value === v)))
.map((option) => {
return (
<Tag key={option.key}>{option.label}</Tag>
)
})
}
</TagInputContainer>
) : (
allOptions?.find((i) => i.value === props.value)?.label
)}
</Result>
)
: (
<Placeholder>{finalProps.placeholder}</Placeholder>
)
}, [Placeholder, Result, Tag, TagInputContainer, allOptions, finalProps.placeholder, props])
const optionListItems = useMemo<ListBoxItem[]>(() => {
const getOptionData = (i: SelectOption) => ({
id: i.key,
content: <Option>{i.content || i.label}</Option>,
})
const getSectionData = (i: {
key: string | number;
label?: React.ReactNode;
options: SelectOption[];
}) => {
return [
{ id: i.key, content: <Section>{i.label}</Section>, disabled: true },
...i.options.map(getOptionData),
]
}
if (isNormalOptions(props)) {
return props.options.map(getOptionData) as any[]
} else if (isSectionedOptions(props)) {
return flatMap(props.sections.map(getSectionData)) as any[]
} else {
return [] as any[]
}
}, [Option, Section, props])
const optionListSelectedIds = useMemo(() => {
if (!props.value) return []
if (isMultipleValue(props)) {
return compact(props.value.map((i) => allOptions && allOptions.find((j) => j.value === i)?.key))
} else {
return compact([allOptions && allOptions.find((j) => j.value === props.value)?.key])
}
}, [props, allOptions])
const optionListHandleOnSelect = useCallback((selectedIds: string[]) => {
if (isMultipleValue(props)) {
if (selectedIds.length === 0) {
props.onChange([])
} else {
props.onChange(compact(selectedIds.map((i) => allOptions && allOptions.find((j) => j.key === i)?.value)))
}
}
if (isSingleValue(props)) {
if (selectedIds.length === 0) {
props.onChange(null)
} else {
props.onChange((allOptions && allOptions.find((j) => j.key === selectedIds[0])?.value) || null)
}
closeDropdown()
}
}, [allOptions, closeDropdown, props])
const searchListItems = useMemo(() => {
if (!searchInputValue) return null
const matchedOptions = searchInOptions(searchInputValue, allOptions, props.onSearch)
return matchedOptions.map((option) => {
return {
id: option.key,
content: (
<Option>{option.label}</Option>
),
}
})
}, [Option, allOptions, props.onSearch, searchInputValue])
const searchListSelectedIds = useMemo(() => {
return optionListSelectedIds.filter((id) => {
return !!searchListItems?.find((item) => item.id === id)
})
}, [optionListSelectedIds, searchListItems])
const searchListHandleOnSelect = useCallback((selectedId: string) => {
if (!searchInputValue) return
const option = allOptions.find((i) => i.key === selectedId)
if (option) {
if (isMultipleValue(props)) {
const newValue = Array.from(props.value || [])
newValue.push(option.value)
props.onChange(newValue)
}
if (isSingleValue(props)) {
props.onChange(option.value)
}
}
}, [allOptions, props, searchInputValue])
const searchListHandleOnUnselect = useCallback((selectedId: string) => {
if (!searchInputValue) return
const option = allOptions.find((i) => i.key === selectedId)
if (option) {
if (isMultipleValue(props) && props.value) {
const index = props.value.findIndex((i) => i === selectedId)
const newValue = Array.from(props.value)
newValue.splice(index, 1)
props.onChange(newValue)
} else {
props.onChange(null)
}
}
}, [allOptions, props, searchInputValue])
return (
<Root
ref={ref}
role="select"
tabIndex={finalProps.disabled ? -1 : 0}
{...NodeDataProps({
'disabled': !!finalProps.disabled,
'active': !!active,
'loading': !!props.loading,
'searchable': !!finalProps.searchable,
})}
onKeyDown={(event) => {
if (finalProps.disabled) return;
switch (event.keyCode) {
case KeyCode.Enter:
case KeyCode.SpaceBar:
if (!active) {
openDropdown()
}
break
case KeyCode.Escape:
closeDropdown()
break
default:
// do nothing
}
}}
onFocus={props.onFocus}
onBlur={props.onBlur}
>
<Dropdown
usePortal={props.usePortal}
portalContainer={props.portalContainer}
active={active}
placement={finalProps.dropdownPlacement}
referenceElement={ref.current}
onClickAway={() => {
if (finalProps.disabled) return;
closeDropdown()
}}
// modifiers for fix dropdown dynamic offset update
modifiers={[{
name: "dynamic_offset",
enabled: true,
phase: "beforeWrite",
requires: ["computeStyles"],
fn: () => { /** */ },
effect: () => { return () => { /** */ } },
}]}
activator={
<Activator
onClick={() => {
if (finalProps.disabled) return;
if (!active) openDropdown()
else closeDropdown()
}}
>
{displayResult}
{props.loading && (
<LoadingSpinner width={16} height={16} />
)}
<DropdownIcon width={20} height={20} svgrProps={{ strokeWidth: 1 }} />
</Activator>
}
>
<ActionBox>
{props.searchable && (
<SearchInput
value={searchInputValue}
onChange={(value) => { setSearchInputValue(value) }}
placeholder={finalProps.searchPlaceholder}
customize={{
Root: {
extendChildrenBefore: (
<SearchIcon />
)
}
}}
/>
)}
{(searchListItems) ? (
<SearchList
items={searchListItems}
selectedIds={searchListSelectedIds}
onSelect={searchListHandleOnSelect}
onUnselect={searchListHandleOnUnselect}
multiple={props.multiple}
/>
) : (
<OptionList
items={optionListItems}
disabled={!active}
selectedIds={optionListSelectedIds}
onSelected={optionListHandleOnSelect}
multiple={props.multiple}
/>
)}
</ActionBox>
</Dropdown>
</Root>
)
})