Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve input mask UX and a11y #1661

Merged
merged 16 commits into from
Apr 21, 2020
Merged

Improve input mask UX and a11y #1661

merged 16 commits into from
Apr 21, 2020

Conversation

dmtrKovalenko
Copy link
Member

@dmtrKovalenko dmtrKovalenko commented Apr 15, 2020

Linked issues:

Breaking changes

  • Remove maskChar prop, because it is not visible for users anymore and need only to generate and parse mask pattern.

Features

Change the logic of the input mask to be more accessible and less noisy.

  1. It is not rendering the whole mask from now (12/1_/____) for partial input it will show only typed part and the next delimiter (12/12/). And still does not allow to enter invalid symbols and type outside of date format.
  2. Generate user-readable placeholder and helper text thanks to Introduce new getFormatHelperText method dmtrKovalenko/date-io#340. This should significantly increase UX for keyboard input

Screen Recording 2020-04-15 at 17 38 50

@dmtrKovalenko dmtrKovalenko added the enhancement New feature or request label Apr 15, 2020
@vercel
Copy link

vercel bot commented Apr 15, 2020

This pull request is being automatically deployed with ZEIT Now (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://zeit.co/mui-org/material-ui-pickers/22ekls0i1
✅ Preview: https://material-ui-pickers-git-feature-better-mask-input.mui-org.now.sh

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the implication with rifm, does it mean we no longer need it?

@@ -83,7 +80,7 @@ export const KeyboardDateInput: React.FC<DateInputProps & DateInputRefs> = ({
if ((rawValue === null || utils.isValid(rawValue)) && !isFocused) {
setInnerInputValue(getInputValue());
}
}, [rawValue]); // eslint-disable-line
}, [rawValue, utils, inputFormat]); // eslint-disable-line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}, [rawValue, utils, inputFormat]); // eslint-disable-line
}, [rawValue, utils, inputFormat]);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a side-effect vakye isFocused which should not be used as a dependency. Do you think we need to move it to refs?

Copy link
Member

@oliviertassinari oliviertassinari Apr 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow. If we use isFocused in the logic, why not include it in the dependency? If it doesn't have a negative side effect, and if it allows us to removes eslint-disable-line. Then, it could help us catch issues after a future refactoring?

Copy link
Member Author

@dmtrKovalenko dmtrKovalenko Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to run effect if the input is changed state from focus to blur. We only need to handle it differently by the fact of focused state.

So this focused state does not need to be state actually. It can be a ref

const isFocusedRef = React.useRef(false) 

onFocus={() => isFocusedRef.current = true} 
onBlur={() => isFocusedRef.current = false} 

And I am actually thinking about making it a ref...

Copy link
Member

@oliviertassinari oliviertassinari Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for using a ref if we don't need to rerender.

I can see emptyInputText as a dependency that is also ignored. Is this a dead prop?

@@ -44,7 +44,7 @@ export function usePickerState<TInput, TDateValue>(
if (!valueManager.areValuesEqual(pickerDate, date)) {
setPickerDate(date);
}
}, [value]); // eslint-disable-line
}, [value, utils]); // eslint-disable-line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}, [value, utils]); // eslint-disable-line
}, [value, utils]);

@dmtrKovalenko
Copy link
Member Author

The logic of masked input is still working through the rifm, it is actually a tool for this (saving cursor position during input formats).

@cypress
Copy link

cypress bot commented Apr 15, 2020



Test summary

69 0 1 0


Run details

Project material-ui-pickers
Status Passed
Commit 26843b3
Started Apr 21, 2020 10:18 AM
Ended Apr 21, 2020 10:19 AM
Duration 01:12 💡
OS Linux Debian - 9.11
Browser Chrome 78

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@codecov
Copy link

codecov bot commented Apr 16, 2020

Codecov Report

Merging #1661 into next will decrease coverage by 0.49%.
The diff coverage is 75.60%.

Impacted file tree graph

@@            Coverage Diff             @@
##             next    #1661      +/-   ##
==========================================
- Coverage   89.76%   89.26%   -0.50%     
==========================================
  Files          73       73              
  Lines        2315     2320       +5     
  Branches      402      423      +21     
==========================================
- Hits         2078     2071       -7     
- Misses        190      198       +8     
- Partials       47       51       +4     
Impacted Files Coverage Δ
lib/src/_shared/PureDateInput.tsx 100.00% <ø> (ø)
lib/src/DateRangePicker/DateRangePickerInput.tsx 68.18% <33.33%> (-1.66%) ⬇️
lib/src/DateRangePicker/DateRangePickerView.tsx 81.70% <66.66%> (-0.80%) ⬇️
lib/src/_shared/KeyboardDateInput.tsx 92.20% <75.00%> (-1.13%) ⬇️
lib/src/_shared/hooks/usePickerState.ts 85.71% <80.00%> (+0.52%) ⬆️
lib/src/_helpers/text-field-helper.ts 86.48% <93.33%> (-13.52%) ⬇️
lib/src/_helpers/utils.ts 73.33% <0.00%> (+6.66%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bd53c63...26843b3. Read the comment docs.

@@ -81,15 +86,23 @@ export const DateRangePickerInput: React.FC<DateRangeInputProps> = ({
}
}, [currentlySelectingRangeEnd, open]);

// TODO: rethink this approach. We do not need to wait for calendar to be updated to rerender input (looks like freezing)
// TODO: so simply break 1 react's commit phase in 2 (first for input and second for calendars) by executing onChange in the next tick
const lazyHandleChangeCallback = React.useCallback(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Described more in this twitter thread

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the underlying issue that the calendar (containing ~30 days instances) too slow to update?

Copy link
Member Author

@dmtrKovalenko dmtrKovalenko Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it is slow, cause actually 70+ days for standard desktop calendar.

Moreover it is working like throttle but on the react level. User doesn’t expect to see January of 0002 year when input is 01/01/2

@dmtrKovalenko dmtrKovalenko changed the title Better mask input Improve input mask UX and a11y Apr 16, 2020
@dmtrKovalenko dmtrKovalenko merged commit b223777 into next Apr 21, 2020
@dmtrKovalenko dmtrKovalenko deleted the feature/better-mask-input branch April 24, 2020 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
2 participants