diff --git a/frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx b/frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx index b684e67..ee87d00 100644 --- a/frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx +++ b/frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx @@ -1,4 +1,4 @@ -import { Fragment, useCallback, useRef, useState } from 'react' +import { Fragment, useCallback, useEffect, useRef, useState } from 'react' import Button from '/src/components/Button/Button' import Content from '/src/components/Content/Content' @@ -36,13 +36,33 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av // Create the colour palette const palette = usePalette(2) + // Selection control + const selectAll = useCallback(() => onChange(times), [onChange, times]) + const selectNone = useCallback(() => onChange([]), [onChange]) + const selectInvert = useCallback(() => onChange(times.filter(t => !value.includes(t))), [onChange, times, value]) + + // Selection keyboard shortcuts + useEffect(() => { + const handleKeydown = (e: KeyboardEvent) => { + if ((e.metaKey || e.ctrlKey) && (e.key === 'a' || e.key === 'i')) { + e.preventDefault() + if (e.shiftKey && e.key === 'a') selectNone() + else if (e.key === 'a') selectAll() + else selectInvert() + } + } + + document.addEventListener('keydown', handleKeydown) + return () => document.removeEventListener('keydown', handleKeydown) + }, [selectAll, selectNone, selectInvert]) + return <> {t('you.info')} - onChange(times)}>{t('you.select_all')} - onChange([])}>{t('you.select_none')} - onChange(times.filter(t => !value.includes(t)))}>{t('you.select_invert')} + {t('you.select_all')} + {t('you.select_none')} + {t('you.select_invert')} {times[0].length === 13 &&