-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Feat: New Date Picker Design #15343
Feat: New Date Picker Design #15343
Conversation
Hey! I see that you made changes to our Form component. Make sure to update the docs in FORMS.md accordingly. Cheers! |
4442a98
to
6c1d51f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good. I left some minor comments, good job 🙌
@Beamanator @mananjadhav One of you needs to copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
also tagging @shawnborton for design review |
Looking good! A couple of minor items to address: Let's use a calendar icon to the right of the date input field. You can use this svg here: For the arrows, maybe we should give them a hover color? Perhaps even just using our textSupporting color would be enough. For the year picker screen, I don't think we need to have the "Please select a year" text - I think it's pretty obvious what you need to do on that screen so that text doesn't really offer much, it just takes up space. |
Also, on the year screen, should we auto focus the search input? cc @trjExpensify not sure if we have a rule of them there. Also, I notice that the list options stretch full width so the border goes to the edge of the screen. I think we want to fix this so that the borders line up within the left edge of the text. cc @cristipaval - did we fix this globally yet? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TMisiukiewicz @ArekChr Love that we got tests here already
There is one thing I would like to raise which is I think not a great UX. The Month section arrows are positioned to the right from the month text and hence if you change the month the position of the arrows moves too. This means you cannot quickly skip through them as you wont be able to click on the arrows quickly. you can see it in the web video here https://user-images.githubusercontent.com/24796318/222424665-7e5caae7-0d5a-4696-afbb-df53806ff1eb.mov
should we put the arrows on the left? or something else @shawnborton @Beamanator
I agree with that @mountiny and I actually think @JmillsExpensify designed an updated version of this at some point where the year is on the left side so it matches the formatting we do (YYYY-MM-DD). So let's do this: Which I think solves that problem? |
@shawnborton yep, love that, thanks! |
Yep, agreed we should! Another instance of this particular list view page in production is the currency page in the |
f1c85b7
to
03c62d2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot to be improved here, first initial tests shows the date picker working well but I have few things to note for now:
- Arrows keep changing positions, making it hard to fast month switch.
- When a date is selected and you open the calendar, it will always point to last date, it should point to the current selected date.
- Clicking on year (while field is empty) will yield a form error.
- Can't clear date.
- backTo param accepts any value, not that I found a bug in that, just worth mentioning maybe we should use a whitelist to be extra safe
- The calendar (on web) is always rendered, it's just invisible (opacity is 0), so we can't use it with any other field? Is the date picker supposed to be rendered in it's separated page? does not seem to make sense.
I think for now we decided to go without an option to clear, we can see later if the user experience will be bad, essentially the dates should not be optional I believe. @s77rt great review 🙌 |
I'm planning to hold off reviewing till more of the outstanding comments get resolved 👍 Or if they're already addressed, can you please resolve them @ArekChr ? 🙏 |
@Beamanator Yes, I will finish probably tomorrow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's ship this 🎉
I think we got approvals of Carlo, s77rt and Alex's comments were addressed so I am going to ship this :shiny: |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/mountiny in version: 1.2.88-0 🚀
|
🚀 Deployed to staging by https://github.com/mountiny in version: 1.2.88-0 🚀
|
@mountiny @luacmartins This issue seems to be a regression caused by this PR. I just made a quick proposal to fix it ProposalPlease re-state the problem that we are trying to solve in this issue.Place holder date format is incorrect in Spainese What is the root cause of that problem?In this PR, we are setting the placeholder in DateOfBirthPage as a constant (YYYY-MM-DD) App/src/components/NewDatePicker/index.js Line 130 in e1e2759
What changes do you think we should make in order to solve the problem?In Expensify/App/src/components/NewDatePicker/index.js
don't forget to import new things and update the propsType
and then update the placeholder What alternative solutions did you explore? (Optional)We also can pass the translate function from the parent component instead of using withLocalize Result |
Nice, exported the issue, do you want to post the proposal there too |
@mountiny I just posted a proposal |
🚀 Deployed to production by https://github.com/AndrewGable in version: 1.2.88-2 🚀
|
🚀 Deployed to production by https://github.com/AndrewGable in version: 1.2.88-2 🚀
|
<OptionsSelector | ||
textInputLabel={this.props.translate('yearPickerPage.selectYear')} | ||
onChangeText={this.filterYearList} | ||
keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD} | ||
maxLength={4} | ||
value={this.state.inputText} | ||
sections={[{data: this.state.yearOptions, indexOffset: 0}]} | ||
onSelectRow={option => this.updateSelectedYear(option.value)} | ||
initiallyFocusedOptionKey={this.currentYear.toString()} | ||
hideSectionHeaders | ||
optionHoveredStyle={styles.hoveredComponentBG} | ||
shouldHaveOptionSeparator | ||
contentContainerStyles={[styles.ph5]} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we added a Search option but failed to handle no results case for the search.
Which lead to this issue
import getButtonState from '../../libs/getButtonState'; | ||
import * as StyleUtils from '../../styles/StyleUtils'; | ||
|
||
class CalendarPicker extends React.PureComponent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a huge amount of comment history in this PR, so apologies if I missed something, but imo this CalendarPicker
component should not have been separated from the NewDatePicker
. Doing so actually makes things a bit more complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. It would have been good to get some wider input before introducing large changes like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was separated to two components as initially we had a logic which was hiding and opening the date picker once user focused into the date input. So it was clearer from developer perspective that way I would say.
Down the road we have decided to remove this logic and the calendar is permanently shown now so it should be easier to keep it all in one component now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made an issue to track the improvements here if you want to follow along
There was a bunch of follow up PRs to this component since this PR got merged so I am sure we could use some clean up and refactoring as well.
} from '../TextInput/baseTextInputPropTypes'; | ||
import CONST from '../../CONST'; | ||
|
||
const propTypes = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These prop types are not imported anywhere except for src/components/NewDatePicker/index.js
. So they should not have been moved to their own file and instead should be in the same file as the component they're relevant to. This also means that we would no longer need src/components/NewDatePicker
to be a directory, and could just have src/components/NewDatePicker.js
.
this.showPicker = this.showPicker.bind(this); | ||
this.hidePicker = this.hidePicker.bind(this); | ||
|
||
this.opacity = new Animated.Value(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to normalize using Reanimated as the default animation library for the sake of both performance and simplicity. This could've been a bit simpler by just using default Reanimated LayoutAnimations:
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated';
...
...
<Animated.View
onMouseDown={(e) => {
// To prevent focus stealing
e.preventDefault();
}}
style={[styles.datePickerPopover, styles.border]}
entering={FadeIn}
exiting={FadeOut}
>
<CalendarPicker />
</Animated.View>
and I think that's it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think thats a great suggestion
super(props); | ||
|
||
this.monthNames = moment.localeData(props.preferredLocale).months(); | ||
this.daysOfWeek = moment.localeData(props.preferredLocale).weekdays(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This caused a regression.
Text wasn't changing when switched to a different locale through another device/tab
const hasAvailableDatesNextMonth = moment(this.props.maxDate).endOf('month').startOf('day') > moment(this.state.currentDateView).add(1, 'M'); | ||
const hasAvailableDatesPrevMonth = moment(this.props.minDate).startOf('day') < moment(this.state.currentDateView).subtract(1, 'M').endOf('month'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comparison was not accurate. More details about the root cause: #28622 (comment)
Details
This Pull Request introduces the new implementation of DatePicker. At this moment, it is implemented only in Date of Birth screen.
Fixed Issues
$ #14322
PROPOSAL: #14322 (comment)
Tests
Offline tests
No need to test offline
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
this
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)ScrollView
component to make it scrollable when more elements are added to the page.
Screenshots/Videos
Web
WEB-CHROME.mov
Mobile Web - Chrome
ANDROID-CHROME.mov
Mobile Web - Safari
IOS-SAFARI.mov
Desktop
DESKTOP.mov
iOS
IOS.mov
Android
ANDROID.mov