From a48e6eff91b2fa44d5399a6e2c980194f8882354 Mon Sep 17 00:00:00 2001
From: Michael Fatemi <myfatemi04@gmail.com>
Date: Thu, 24 Jun 2021 12:44:23 -0400
Subject: [PATCH] add better availability picker ux

---
 src/components/NewUI/Availability.tsx | 90 ++++++++++++++++++---------
 1 file changed, 60 insertions(+), 30 deletions(-)

diff --git a/src/components/NewUI/Availability.tsx b/src/components/NewUI/Availability.tsx
index 75718bf..7ade014 100644
--- a/src/components/NewUI/Availability.tsx
+++ b/src/components/NewUI/Availability.tsx
@@ -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,23 +84,39 @@ export default function Availability({
 				marginTop: '1rem',
 				marginBottom: '1rem',
 			}}
+			tabIndex={0}
+			onBlur={() => setFocused(false)}
 		>
-			<Option
-				bind="going/can-bring-someone"
-				current={selected}
-				onSelected={onSelected}
-			/>
-			<Option
-				bind="going/cannot-bring-someone"
-				current={selected}
-				onSelected={onSelected}
-			/>
-			<Option bind="interested" current={selected} onSelected={onSelected} />
-			<Option
-				bind="not-interested"
-				current={selected}
-				onSelected={onSelected}
-			/>
+			{focused ? (
+				<>
+					<Option
+						bind="going/can-bring-someone"
+						current={selected}
+						onSelected={onSelected}
+					/>
+					<Option
+						bind="going/cannot-bring-someone"
+						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>
 	);
 }