Skip to content

Commit

Permalink
Add ArrowKeyNavSelect!
Browse files Browse the repository at this point in the history
  • Loading branch information
psarando committed Mar 29, 2024
1 parent 78e7ca0 commit 4a45ca7
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 33 deletions.
76 changes: 74 additions & 2 deletions src/examples/Common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,49 @@ const DateNumberInput = (props: any) => (

const OutlinedSelect = (props: any) => <TextField select {...props} />;

const ArrowKeyNavSelect = ({
onArrowUp,
onArrowDown,
onArrowRight,
onArrowLeft,
SelectProps,
...props
}: any) => {
const [open, setOpen] = React.useState(false);

return (
<OutlinedSelect
SelectProps={{
open,
onClose: () => setOpen(false),
onOpen: (event: any) => {
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") {
setOpen(true);
}
},
...SelectProps,
}}
onKeyDown={(event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "ArrowUp" && onArrowUp) {
onArrowUp();
}
if (event.key === "ArrowDown" && onArrowDown) {
onArrowDown();
}
if (event.key === "ArrowRight" && onArrowRight) {
event.preventDefault();
onArrowRight();
}
if (event.key === "ArrowLeft" && onArrowLeft) {
event.preventDefault();
onArrowLeft();
}
}}
{...props}
/>
);
};

const DateMonthSelect = ({ monthFormat = "short", ...props }: any) => {
const monthFormatter = new Intl.DateTimeFormat("en", {
month: monthFormat,
Expand All @@ -41,7 +84,7 @@ const DateMonthSelect = ({ monthFormat = "short", ...props }: any) => {
const style = monthFormat === "long" ? { width: "8.5rem" } : undefined;

return (
<OutlinedSelect
<ArrowKeyNavSelect
label="Month"
className="gregorian-month-picker"
style={style}
Expand All @@ -52,7 +95,7 @@ const DateMonthSelect = ({ monthFormat = "short", ...props }: any) => {
{monthFormatter.format(new Date(2000, m, 1))}
</MenuItem>
))}
</OutlinedSelect>
</ArrowKeyNavSelect>
);
};

Expand Down Expand Up @@ -108,6 +151,30 @@ const DatePicker = (props: DatePickerProps) => {
onDateChanged(year, month, day);
};

const onMonthInc = () => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const day = currentDate.getDate();

onDateChanged(
month === 11 ? year + 1 : year,
month === 11 ? 0 : month + 1,
day
);
};

const onMonthDec = () => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const day = currentDate.getDate();

onDateChanged(
month === 0 ? year - 1 : year,
month === 0 ? 11 : month - 1,
day
);
};

const onDayChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
Expand Down Expand Up @@ -139,6 +206,10 @@ const DatePicker = (props: DatePickerProps) => {
value={currentDate.getMonth()}
onChange={onMonthChanged}
monthFormat="long"
onArrowUp={onMonthDec}
onArrowLeft={onMonthDec}
onArrowDown={onMonthInc}
onArrowRight={onMonthInc}
/>
<DayInput value={currentDate.getDate()} onChange={onDayChanged} />
<YearInput
Expand Down Expand Up @@ -242,5 +313,6 @@ export {
DayInput,
YearInput,
OutlinedSelect,
ArrowKeyNavSelect,
parseDatePickerChangedDate,
};
62 changes: 50 additions & 12 deletions src/examples/simulation/ShireDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import {
GondorLeapYearRuleEnum,
isGondorLeapYear,
} from "../../GondorReckoning";
import { getNextDate, getPrevDate } from "../../Utils";

import { convertShireToGregorianDate } from "./DatesOfInterest";

import { DateNumberInput, OutlinedSelect } from "../Common";
import { ArrowKeyNavSelect, DateNumberInput } from "../Common";
import "../examples.css";

interface ShireDatePickerProps {
Expand All @@ -36,18 +37,19 @@ const ShireDatePicker = (props: ShireDatePickerProps) => {

const resetDate = () => onDateChanged(new Date());

const onMonthChanged = (event: React.ChangeEvent<HTMLSelectElement>) => {
const month = parseInt(event.target.value, 10);
const onMonthChanged = (year: number, month: number) => {
let day = todayShire.day;

switch (day) {
case "1 Yule":
case "2 Yule":
case "1 Lithe":
case "Midyear's Day":
case "Overlithe":
case "2 Lithe":
day = month < todayShire.month ? 30 : 1;
day = 1;
break;
case "1 Yule":
case "1 Lithe":
case "Midyear's Day":
day = 30;
break;
default:
break;
Expand All @@ -58,11 +60,37 @@ const ShireDatePicker = (props: ShireDatePickerProps) => {
);
};

const onMonthInc = () => {
const month = todayShire.month;

onMonthChanged(
month === 11 ? year + 1 : year,
month === 11 ? 0 : month + 1
);
};

const onMonthDec = () => {
const month = todayShire.month;

onMonthChanged(
month === 0 ? year - 1 : year,
month === 0 ? 11 : month - 1
);
};

const onDayChanged = (event: React.ChangeEvent<HTMLSelectElement>) => {
const day = event.target.value;
onDateChanged(new Date(day));
};

const onDayInc = () => {
onDateChanged(getNextDate(todayShire.gregorian));
};

const onDayDec = () => {
onDateChanged(getPrevDate(todayShire.gregorian));
};

const onYearChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
const year = parseInt(event.target.value, 10) + 1600 + 3441;
const month = todayShire.month;
Expand All @@ -85,11 +113,17 @@ const ShireDatePicker = (props: ShireDatePickerProps) => {
className="simulated-shire-date-picker"
style={{ paddingLeft: 0 }}
>
<OutlinedSelect
<ArrowKeyNavSelect
className="date-time-input simulated-shire-month-picker"
label="Month"
value={todayShire.month}
onChange={onMonthChanged}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
onMonthChanged(year, parseInt(event.target.value, 10))
}
onArrowUp={onMonthDec}
onArrowLeft={onMonthDec}
onArrowDown={onMonthInc}
onArrowRight={onMonthInc}
SelectProps={{
renderValue: (value: number) => ShireMonths[value].tolkien,
}}
Expand All @@ -102,12 +136,16 @@ const ShireDatePicker = (props: ShireDatePickerProps) => {
/>
</MenuItem>
))}
</OutlinedSelect>
<OutlinedSelect
</ArrowKeyNavSelect>
<ArrowKeyNavSelect
className="date-time-input"
label="Day"
value={todayShire.gregorian.toISOString()}
onChange={onDayChanged}
onArrowUp={onDayDec}
onArrowLeft={onDayDec}
onArrowDown={onDayInc}
onArrowRight={onDayInc}
>
{calendar.dates
.filter((date) => date.month === todayShire.month)
Expand All @@ -119,7 +157,7 @@ const ShireDatePicker = (props: ShireDatePickerProps) => {
{date.day}
</MenuItem>
))}
</OutlinedSelect>
</ArrowKeyNavSelect>
<DateNumberInput
label="Year"
value={year - 1600 - 3441}
Expand Down
28 changes: 28 additions & 0 deletions src/examples/simulation/StartReckoningDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@ const StartReckoningDatePicker = (props: StartDatePickerProps) => {
onDateChanged(year, month, day);
};

const onMonthInc = () => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const day = currentDate.getDate();

onDateChanged(
month === 11 ? year + 1 : year,
month === 11 ? 0 : month + 1,
day
);
};

const onMonthDec = () => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const day = currentDate.getDate();

onDateChanged(
month === 0 ? year - 1 : year,
month === 0 ? 11 : month - 1,
day
);
};

const onDayChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
Expand Down Expand Up @@ -75,6 +99,10 @@ const StartReckoningDatePicker = (props: StartDatePickerProps) => {
}}
value={currentDate.getMonth()}
onChange={onMonthChanged}
onArrowUp={onMonthDec}
onArrowLeft={onMonthDec}
onArrowDown={onMonthInc}
onArrowRight={onMonthInc}
/>
<DayInput
style={{ width: "4rem" }}
Expand Down
Loading

0 comments on commit 4a45ca7

Please sign in to comment.