-
Notifications
You must be signed in to change notification settings - Fork 3k
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
[$500] Update Datepicker UX #52621
Comments
Job added to Upwork: https://www.upwork.com/jobs/~021857439292509917630 |
Triggered auto assignment to Contributor-plus team member for initial proposal review - @thesahindia ( |
@JmillsExpensify any opinion on which project makes the most sense for this? I was thinking |
Hi @dannymcclain I can't see the image and video attached. Can you reupload it, please? |
ProposalPlease re-state the problem that we are trying to solve in this issue.Update Datepicker UX What is the root cause of that problem?Feature Request What changes do you think we should make in order to solve the problem?We will:
|
@Pholenk Just re-uploaded! Hopefully that worked. Those are pretty important to be able to see 😂 |
Edited by proposal-police: This proposal was edited at 2024-11-16 08:52:21 UTC. ProposalPlease re-state the problem that we are trying to solve in this issue.What is the root cause of that problem?
What changes do you think we should make in order to solve the problem?
function DatePicker(
{
containerStyles,
defaultValue,
disabled,
errorText,
inputID,
label,
maxDate = setYear(new Date(), CONST.CALENDAR_PICKER.MAX_YEAR),
minDate = setYear(new Date(), CONST.CALENDAR_PICKER.MIN_YEAR),
onInputChange,
onTouched,
placeholder,
value,
shouldSaveDraft = false,
formID,
}: DatePickerProps,
ref: ForwardedRef<BaseTextInputRef>,
) {
const styles = useThemeStyles();
const {translate} = useLocalize();
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const [selectedDate, setSelectedDate] = useState(value || defaultValue || undefined);
const {shouldUseNarrowLayout} = useResponsiveLayout();
useEffect(() => {
// Value is provided to input via props and onChange never fires. We have to save draft manually.
if (shouldSaveDraft && !!formID) {
FormActions.setDraftValues(formID, {[inputID]: selectedDate});
}
if (selectedDate === value || !value) {
return;
}
setSelectedDate(value);
}, [formID, inputID, selectedDate, shouldSaveDraft, value]);
+ const show = useRef<() => void>();
+ const onSelected = (newValue: string) => {
+ onTouched?.();
+ onInputChange?.(newValue);
+ setSelectedDate(newValue);
+ hideTooltipRef.current?.();
+ ref?.current?.blur();
+ };
+ const hideTooltipRef = useRef<() => void>();
+ const [containerInputWidth, setContainerInputWidth] = useState();
+ const renderTooltipContent = useCallback(() => {
+ return (
+ <View
+ style={[styles.datePickerPopover, styles.border, {width: containerInputWidth, pointerEvents: 'auto', zIndex: +10000}]}
+ collapsable={false}
+ >
+ <CalendarPicker
+ minDate={minDate}
+ maxDate={maxDate}
+ value={selectedDate}
+ onSelected={onSelected}
+ />
+ </View>
+ );
+ }, [containerInputWidth, minDate, maxDate, selectedDate, onSelected]);
return (
+ <View style={styles.datePickerRoot}>
+ <GenericTooltip
+ shouldUseOverlay
+ wrapperStyle={{backgroundColor: 'transparent'}}
+ renderTooltipContent={renderTooltipContent}
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ anchorAlignment={{horizontal: 'center', vertical: 'top'}}
+ >
+ {({showTooltip, hideTooltip, updateTargetBounds}) => {
+ hideTooltipRef.current = hideTooltip;
+ return (
+ <View
+ onLayout={(e: LayoutChangeEventWithTarget) => {
+ // e.target is specific to native, use e.nativeEvent.target on web instead
+ const target = e.target || e.nativeEvent.target;
+ show.current = () => measureTooltipCoordinate(target, updateTargetBounds, showTooltip);
+ }}
+ style={[shouldUseNarrowLayout ? styles.flex2 : {}]}
+ >
+ <TextInput
+ disableKeyboard
+ onLayout={(e) => {
+ setContainerInputWidth(e.nativeEvent.layout.width);
+ }}
+ ref={ref}
+ inputID={inputID}
+ forceActiveLabel
+ icon={Expensicons.Calendar}
+ label={label}
+ accessibilityLabel={label}
+ role={CONST.ROLE.PRESENTATION}
+ value={selectedDate}
+ placeholder={placeholder ?? translate('common.dateFormat')}
+ errorText={errorText}
+ containerStyles={containerStyles}
+ disabled={disabled}
+ onFocus={() => show?.current?.()}
+ onBlur={() => hideTooltip()}
+ />
+ </View>
+ );
+ }}
+ </GenericTooltip>
+ </View>
+ );
} Explains: I am using
It will make sure the input is not blurred when we click on any button in the date picker.
<InputWrapper ref={inputCallbackRef} />
What alternative solutions did you explore? (Optional)ResultScreen.Recording.2024-11-27.at.17.28.40.mov |
Edited by proposal-police: This proposal was edited at 2024-11-21 19:23:22 UTC. ProposalPlease re-state the problem that we are trying to solve in this issue.Update Datepicker UX What is the root cause of that problem?UX enhancement What changes do you think we should make in order to solve the problem?
to this line App/src/components/DatePicker/index.tsx Line 74 in 4bb19d7
+ datePickerRoot: {
- position: 'relative',
- zIndex: 99,
+ width: '100%',
+ },
+ datePickerPopoverShow: {
+ display: 'flex',
+ },
+
+ datePickerPopoverHide: {
+ display: 'none',
+ },
- <View style={styles.datePickerRoot}>
- <View style={[shouldUseNarrowLayout ? styles.flex2 : {}, styles.pointerEventsNone]}>
+ <View style={[styles.flex0, styles.datePickerRoot, containerSize]}>
+ <View style={[shouldUseNarrowLayout ? styles.flex2 : {}]}>
<TextInput
- ref={ref}
+ ref={localRef}
inputID={inputID}
forceActiveLabel
icon={Expensicons.Calendar}
label={label}
accessibilityLabel={label}
role={CONST.ROLE.PRESENTATION}
value={selectedDate}
placeholder={placeholder ?? translate('common.dateFormat')}
errorText={errorText}
containerStyles={containerStyles}
textInputContainerStyles={[styles.borderColorFocus]}
- inputStyle={[styles.pointerEventsNone]}
disabled={disabled}
- readOnly
+ readOnly={false}
+ disableKeyboard
+ onFocus={toggleFocus}
+ onBlur={toggleFocus}
+ onLayout={onLayoutHandle}
/>
</View>
<View
- style={[styles.datePickerPopover, styles.border]}
+ style={[styles.datePickerPopover, styles.border, popoverDisplayStyle, popoverPosition]}
collapsable={false}
>
<CalendarPicker
minDate={minDate}
maxDate={maxDate}
value={selectedDate}
onSelected={onSelected}
/>
</View>
</View> ResultMobilescreencast-Genymotion-2024-11-21_23.54.13.555.mp4Websimplescreenrecorder-2024-11-22_02.14.18.mp4What alternative solutions did you explore? (Optional)Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job. |
@dannymcclain, @thesahindia Whoops! This issue is 2 days overdue. Let's get this updated quick! |
@thesahindia are you the official proposal reviewer for this one? |
Yeah, I am assigned as the C+. |
Thanks for the proposals everyone! Could you guys please share the end results? |
I've updated my proposal to add the video of the change result. cc: @thesahindia |
📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸 |
Not overdue. I think proposals are still being reviewed. |
@dannymcclain, @thesahindia Eep! 4 days overdue now. Issues have feelings too... |
So, the question here is: how should the year selection page look? Should it remain the same as before? RPReplay_Final1737650367.MP4 |
Can we see what it's like to navigate from the bottom-sheet date picker, to the RHP year selection? Maybe it won't feel so terrible? |
I definitely agree with your suggestion about the style adjustment of the calendar. As for the year, definitely curious to see the RHP prototype first. I like what you have but it does feel a little less usable for people that just want to type in the year? |
Totally agree—just wanted to offer it as an alternate. |
Currently, navigating from the bottom-sheet date picker to the year selection in RHP requires implementing modal screens through Navigation, not React Native (our current approach) |
Hmm how long until that stuff is merged? I feel like we should try to reuse the RHP because it already exists and works great, we wouldn't need to build anything new here. |
Work on implementing Navigation modal screens starts Monday (#53493)
Here's a rough proof-of-concept using modal-in-modal that we can use temporarily: 11.MP4Quick demo of potential web transition (very rough, just to illustrate the concept): Untitled.mov |
I don't mind that! On web, when you select a year, I would expect the datepicker to still be open when you get back to the original page. |
Yeah it's really not bad! Feels way less weird than I was expecting.
I agree. Since this video is just a rough mock, I'm assuming/hoping we could make that happen in the actual version. |
Sounds great, I like where this is going - thanks @perunt ! |
Not overdue Melvin. @perunt is on it. |
A small update on this. Untitled.movRPReplay_Final1738170552.MP4 |
cc @Expensify/design ☝ I think this is coming along nicely! |
Nice! I dig it. |
Very exciting to see. Great job so far @perunt |
Sorry for the delay on the reply. The modal screen PR will need some more time, so i don't think waiting on the modal screen migration would be a good idea as of right now, but i see you already went that way anyway :) |
@perunt what are your thoughts on the comment above? Are we blocked from implementing this in the way you showed in your video for now? |
No, it's not a blocker at all. In fact, I've already implemented it I noticed a reviewer’s comment suggesting that we should use this component everywhere. Should I update the other screens as well? |
I think that would be lovely. |
There were around 10 places with the calendar component. I just replaced it and removed the old component. Testing throughout the app, and it looks good. Waiting for a review, as all the places need to be checked |
@shubham1206agra @perunt What are the next steps here? How can we push this forward this week? |
Problem
Currently our datepicker inputs always show the calendar popover, and this leads to a pretty cumbersome interface in places like the search filters where we have both a before and after date input.
Solution
Coming from this thread, let’s update our datepicker so that the calendar popover only appears when the input is focused.
CleanShot.2024-11-15.at.08.49.24.mp4
Notes:
Figma file
cc @Expensify/design
Upwork Automation - Do Not Edit
Issue Owner
Current Issue Owner: @thesahindiaThe text was updated successfully, but these errors were encountered: