From eb8bf0f24a623818be457cb650924ad7e802997f Mon Sep 17 00:00:00 2001 From: Dmitriy Kovalenko Date: Mon, 17 Feb 2020 17:44:04 +0200 Subject: [PATCH] (chore) Better focus displaying (#1517) * Remvoe focusRipple and better selected + focus state managment * Do not show outline on touch devices * Do not focus current day and year by default in static mode * Render better date for placeholder by default --- lib/src/_helpers/text-field-helper.ts | 2 +- lib/src/_shared/KeyboardDateInput.tsx | 4 ++-- lib/src/_shared/ModalDialog.tsx | 3 +++ lib/src/views/Calendar/Calendar.tsx | 6 ++---- lib/src/views/Calendar/CalendarView.tsx | 5 ++++- lib/src/views/Calendar/Day.tsx | 23 +++++++++++++++++++---- lib/src/views/Calendar/Year.tsx | 6 ++++-- lib/src/views/Calendar/YearSelection.tsx | 3 ++- lib/src/wrappers/DesktopWrapper.tsx | 3 +++ 9 files changed, 40 insertions(+), 15 deletions(-) diff --git a/lib/src/_helpers/text-field-helper.ts b/lib/src/_helpers/text-field-helper.ts index 4df04a2a5aadd3..386a3b55bf39a9 100644 --- a/lib/src/_helpers/text-field-helper.ts +++ b/lib/src/_helpers/text-field-helper.ts @@ -156,7 +156,7 @@ export function pick12hOr24hFormat( return ampm ? formats['12h'] : formats['24h']; } -const staticDateWith2DigitTokens = new Date('2019-11-21T22:30:00.000'); +export const staticDateWith2DigitTokens = new Date('2019-11-21T22:30:00.000'); export const staticDateWith1DigitTokens = new Date('2019-01-01T09:00:00.000'); export function checkMaskIsValidForCurrentFormat( mask: string, diff --git a/lib/src/_shared/KeyboardDateInput.tsx b/lib/src/_shared/KeyboardDateInput.tsx index caf758329f1809..7eccf497e01e01 100644 --- a/lib/src/_shared/KeyboardDateInput.tsx +++ b/lib/src/_shared/KeyboardDateInput.tsx @@ -7,11 +7,11 @@ import { useUtils } from './hooks/useUtils'; import { DateInputProps } from './PureDateInput'; import { KeyboardIcon } from './icons/KeyboardIcon'; import { - staticDateWith1DigitTokens, maskedDateFormatter, getDisplayDate, checkMaskIsValidForCurrentFormat, getTextFieldAriaText, + staticDateWith2DigitTokens, } from '../_helpers/text-field-helper'; export const KeyboardDateInput: React.FC = ({ @@ -58,7 +58,7 @@ export const KeyboardDateInput: React.FC = ({ if (!mask || disableMaskedInput) { return { isMaskValid: false, - placeholder: utils.formatByString(staticDateWith1DigitTokens, format), + placeholder: utils.formatByString(staticDateWith2DigitTokens, format), }; } diff --git a/lib/src/_shared/ModalDialog.tsx b/lib/src/_shared/ModalDialog.tsx index 24c09a5a952150..1ae0fc7143eb4c 100644 --- a/lib/src/_shared/ModalDialog.tsx +++ b/lib/src/_shared/ModalDialog.tsx @@ -33,6 +33,9 @@ export const useStyles = makeStyles( dialogContainer: { '&:focus > $dialogRoot': { outline: 'auto', + '@media (pointer:coarse)': { + outline: 0, + }, }, }, dialog: { diff --git a/lib/src/views/Calendar/Calendar.tsx b/lib/src/views/Calendar/Calendar.tsx index 0227827d739695..788fab3d309707 100644 --- a/lib/src/views/Calendar/Calendar.tsx +++ b/lib/src/views/Calendar/Calendar.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import Day from './Day'; import DayWrapper from './DayWrapper'; import SlideTransition, { SlideDirection } from './SlideTransition'; -import { WrapperVariant } from '../../wrappers/Wrapper'; import { MaterialUiPickersDate } from '../../typings/date'; import { useUtils, useNow } from '../../_shared/hooks/useUtils'; import { PickerOnChangeFn } from '../../_shared/hooks/useViews'; @@ -52,7 +51,6 @@ export interface CalendarProps extends ExportedCalendarProps { changeFocusedDay: (newFocusedDay: MaterialUiPickersDate) => void; isMonthSwitchingAnimating: boolean; onMonthSwitchingAnimationEnd: () => void; - wrapperVariant: WrapperVariant | null; } export const useStyles = makeStyles(theme => ({ @@ -110,7 +108,6 @@ export const Calendar: React.FC = ({ renderDay, reduceAnimations, allowKeyboardControl, - wrapperVariant, isDateDisabled, }) => { const now = useNow(); @@ -142,7 +139,7 @@ export const Calendar: React.FC = ({ }, []); // eslint-disable-line const nowFocusedDay = focusedDay || date; - useGlobalKeyDown(Boolean(allowKeyboardControl ?? wrapperVariant !== 'static'), { + useGlobalKeyDown(Boolean(allowKeyboardControl), { [keycode.ArrowUp]: () => changeFocusedDay(utils.addDays(nowFocusedDay, -7)), [keycode.ArrowDown]: () => changeFocusedDay(utils.addDays(nowFocusedDay, 7)), [keycode.ArrowLeft]: () => @@ -191,6 +188,7 @@ export const Calendar: React.FC = ({ day={day} isAnimating={isMonthSwitchingAnimating} disabled={disabled} + allowKeyboardControl={allowKeyboardControl} focused={Boolean(focusedDay) && utils.isSameDay(day, focusedDay)} onFocus={() => changeFocusedDay(day)} focusable={ diff --git a/lib/src/views/Calendar/CalendarView.tsx b/lib/src/views/Calendar/CalendarView.tsx index c2746ea3faa6fa..63cbf0cae3e223 100644 --- a/lib/src/views/Calendar/CalendarView.tsx +++ b/lib/src/views/Calendar/CalendarView.tsx @@ -153,6 +153,7 @@ export const CalendarView: React.FC = ({ reduceAnimations = typeof window !== 'undefined' && /(android)/i.test(window.navigator.userAgent), loadingIndicator = , shouldDisableDate, + allowKeyboardControl: allowKeyboardControlProp, ...other }) => { const now = useNow(); @@ -161,6 +162,7 @@ export const CalendarView: React.FC = ({ const minDate = useParsedDate(unparsedMinDate); const maxDate = useParsedDate(unparsedMaxDate); const wrapperVariant = React.useContext(WrapperVariantContext); + const allowKeyboardControl = allowKeyboardControlProp ?? wrapperVariant !== 'static'; const [ { currentMonth, isMonthSwitchingAnimating, focusedDay, loadingQueue, slideDirection }, @@ -264,6 +266,7 @@ export const CalendarView: React.FC = ({ minDate={minDate} maxDate={maxDate} isDateDisabled={isDateDisabled} + allowKeyboardControl={allowKeyboardControl} /> )} @@ -304,8 +307,8 @@ export const CalendarView: React.FC = ({ onChange={onChange} minDate={minDate} maxDate={maxDate} - wrapperVariant={wrapperVariant} isDateDisabled={isDateDisabled} + allowKeyboardControl={allowKeyboardControl} /> ))} diff --git a/lib/src/views/Calendar/Day.tsx b/lib/src/views/Calendar/Day.tsx index 60b4af34394b41..a7ac0d96cebde8 100644 --- a/lib/src/views/Calendar/Day.tsx +++ b/lib/src/views/Calendar/Day.tsx @@ -20,6 +20,13 @@ export const useStyles = makeStyles( '&:hover': { backgroundColor: fade(theme.palette.action.active, theme.palette.action.hoverOpacity), }, + '&:focus': { + backgroundColor: fade(theme.palette.action.active, theme.palette.action.hoverOpacity), + '&$daySelected': { + willChange: 'background-color', + backgroundColor: theme.palette.primary.dark, + }, + }, }, hidden: { opacity: 0, @@ -70,6 +77,8 @@ export interface DayProps extends ButtonBaseProps { disabled?: boolean; /** Selected? */ selected?: boolean; + /** Is keyboard control and focus management enabled */ + allowKeyboardControl?: boolean; } export const Day: React.FC = ({ @@ -82,6 +91,7 @@ export const Day: React.FC = ({ focusable = false, isAnimating, onFocus, + allowKeyboardControl, ...other }) => { const ref = React.useRef(null); @@ -95,18 +105,23 @@ export const Day: React.FC = ({ }); React.useEffect(() => { - if (focused && !isAnimating && !disabled && isInCurrentMonth && ref.current) { + if ( + focused && + !isAnimating && + !disabled && + isInCurrentMonth && + ref.current && + allowKeyboardControl + ) { ref.current.focus(); } - }, [disabled, focused, isAnimating, isInCurrentMonth]); + }, [allowKeyboardControl, disabled, focused, isAnimating, isInCurrentMonth]); return ( ; } @@ -62,6 +63,7 @@ export const Year: React.FC = ({ disabled, children, focused, + allowKeyboardControl, ...other }) => { const classes = useStyles(); @@ -69,10 +71,10 @@ export const Year: React.FC = ({ const wrapperVariant = React.useContext(WrapperVariantContext); React.useEffect(() => { - if (focused && ref.current) { + if (focused && ref.current && !disabled && allowKeyboardControl) { ref.current.focus(); } - }, [focused]); + }, [allowKeyboardControl, disabled, focused]); return (
= ({ const yearsInRow = wrapperVariant === 'desktop' ? 4 : 3; const nowFocusedYear = focusedYear || currentYear; - useGlobalKeyDown(Boolean(allowKeyboardControl ?? wrapperVariant !== 'static'), { + useGlobalKeyDown(Boolean(allowKeyboardControl), { [keys.ArrowUp]: () => setFocused(nowFocusedYear - yearsInRow), [keys.ArrowDown]: () => setFocused(nowFocusedYear + yearsInRow), [keys.ArrowLeft]: () => setFocused(nowFocusedYear + (theme.direction === 'ltr' ? -1 : 1)), @@ -102,6 +102,7 @@ export const YearSelection: React.FC = ({ selected={selected} value={yearNumber} onSelect={handleYearSelection} + allowKeyboardControl={allowKeyboardControl} focused={yearNumber === focusedYear} ref={selected ? selectedYearRef : undefined} disabled={Boolean( diff --git a/lib/src/wrappers/DesktopWrapper.tsx b/lib/src/wrappers/DesktopWrapper.tsx index 01a78a3fb02908..1c73792ff35ad7 100644 --- a/lib/src/wrappers/DesktopWrapper.tsx +++ b/lib/src/wrappers/DesktopWrapper.tsx @@ -21,6 +21,9 @@ const useStyles = makeStyles({ popover: { '&:focus': { outline: 'auto', + '@media (pointer:coarse)': { + outline: 0, + }, }, }, });