Skip to content

Instantly share code, notes, and snippets.

@dohomi
Created March 30, 2021 00:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dohomi/ccc14d935278f27b7ed352c7050d180a to your computer and use it in GitHub Desktop.
Save dohomi/ccc14d935278f27b7ed352c7050d180a to your computer and use it in GitHub Desktop.
Native Select with render prop Material-UI v5
const LmCountrySelector: FC<CountrySelectProps> = ({
options,
onChange,
onBlur,
onFocus,
...rest
}) => {
const mappedOptions = useMemo(() => {
return options
.map((item) => {
const emoji = flag(item.value)
return emoji ? (
<option key={item.value} value={item.value}>
{item.label}
</option>
) : null
})
.filter((i) => i)
}, [options])
return (
<LmNativeSelect
formControlProps={{
margin: 'normal',
variant: 'standard',
sx: {
width: '100px'
}
}}
{...{ onBlur, onChange, onFocus }}
inputProps={{
disableUnderline: true
}}
name={rest.name}
value={rest.value}
renderValue={(value) =>
value ? (
<img
className="lm-select-img__country"
alt={`country ${value}`}
src={`https://purecatamphetamine.github.io/country-flag-icons/3x2/${value}.svg`}
/>
) : (
<LmIconCustom color="secondary" />
)
}
>
{mappedOptions}
</LmNativeSelect>
)
}
import { FC, ReactNode, useState } from 'react'
import {
FormControl,
FormControlProps,
Input,
InputProps,
SelectProps
} from '@material-ui/core'
import LmIconCaretUp from '../icons/LmIconCaretUp'
type LmNativeSelectProps = {
value?: string | number
name?: string
selectProps?: SelectProps
inputProps?: InputProps
formControlProps?: FormControlProps
onChange?: (str: string) => void
onFocus?: () => void
onBlur?: () => void
renderValue?: (value: any) => ReactNode
}
const LmNativeSelect: FC<LmNativeSelectProps> = ({
value,
name,
children,
selectProps,
onFocus,
onChange,
onBlur,
renderValue,
formControlProps,
inputProps
}) => {
const [focused, setFocus] = useState<boolean>()
const RenderValue =
typeof renderValue === 'function' ? renderValue(value || '') : ''
return (
<FormControl {...formControlProps}>
<select
style={{
opacity: focused ? '1' : '0',
zIndex: 1,
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%'
}}
name={name}
value={value || ''}
onChange={(event) => {
if (typeof onChange === 'function') {
onChange(event.target.value as any)
}
}}
onBlur={() => {
setFocus(false)
if (typeof onBlur === 'function') {
onBlur()
}
}}
onFocus={() => {
if (typeof onFocus === 'function') {
onFocus()
}
}}
>
{children}
</select>
<Input
{...inputProps}
sx={{
...inputProps?.sx,
opacity: focused ? 0 : 1,
'&.MuiInput-root': {
color: 'black'
},
'& .MuiInput-input': {
opacity: 0
}
}}
onFocus={() => {
setFocus(true)
}}
endAdornment={<LmIconCaretUp customSize="xs" />}
startAdornment={RenderValue}
value={selectProps?.value || ''}
/>
</FormControl>
)
}
export default LmNativeSelect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment