add better availability picker ux

This commit is contained in:
Michael Fatemi 2021-06-24 12:44:23 -04:00
parent e422fec6f5
commit a48e6eff91

View File

@ -1,5 +1,5 @@
import { CSSProperties } from '@material-ui/styles';
import { useCallback, useMemo } from 'react';
import { MouseEventHandler, useCallback, useState } from 'react';
export type AvailabilityKind =
| 'going/can-bring-someone'
@ -18,10 +18,19 @@ const optionStyle: CSSProperties = {
height: '3rem',
backgroundColor: 'white',
display: 'flex',
flexDirection: 'column',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
cursor: 'pointer',
transition: 'background-color 100ms cubic-bezier',
userSelect: 'none',
position: 'relative',
fontWeight: 'normal',
};
const selectedOptionStyle = {
...optionStyle,
fontWeight: 600,
};
function Option({
@ -33,20 +42,17 @@ function Option({
current: AvailabilityKind;
onSelected: (kind: AvailabilityKind) => void;
}) {
const style = useMemo(
() =>
current === bind
? { ...optionStyle, backgroundColor: '#5080f0', color: 'white' }
: optionStyle,
[bind, current]
const selected = current === bind;
const select: MouseEventHandler<HTMLDivElement> = useCallback(
(event) => {
onSelected(bind);
},
[onSelected, bind]
);
const select = useCallback(() => {
onSelected(bind);
}, [onSelected, bind]);
return (
<div style={style} onClick={select}>
<div style={selected ? selectedOptionStyle : optionStyle} onClick={select}>
{availabilityNames[bind]}
</div>
);
@ -54,11 +60,19 @@ function Option({
export default function Availability({
selected,
onSelected,
onSelected: onSelectedInner,
}: {
selected: AvailabilityKind;
onSelected: (kind: AvailabilityKind) => void;
}) {
const [focused, setFocused] = useState(false);
const onSelected = useCallback(
(kind: AvailabilityKind) => {
setFocused(false);
onSelectedInner(kind);
},
[onSelectedInner]
);
return (
<div
style={{
@ -70,7 +84,11 @@ export default function Availability({
marginTop: '1rem',
marginBottom: '1rem',
}}
tabIndex={0}
onBlur={() => setFocused(false)}
>
{focused ? (
<>
<Option
bind="going/can-bring-someone"
current={selected}
@ -81,12 +99,24 @@ export default function Availability({
current={selected}
onSelected={onSelected}
/>
<Option bind="interested" current={selected} onSelected={onSelected} />
<Option
bind="interested"
current={selected}
onSelected={onSelected}
/>
<Option
bind="not-interested"
current={selected}
onSelected={onSelected}
/>
</>
) : (
<Option
bind={selected}
current={selected}
onSelected={() => setFocused(true)}
/>
)}
</div>
);
}