-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Customize DayPickerKeyboardShortcuts with renderKeyboardShortcutsButton #1576
Customize DayPickerKeyboardShortcuts with renderKeyboardShortcutsButton #1576
Conversation
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.
Looks good, but it's hard to test. Could you add a variant w/ this enabled to storybook?
topLeft && styles.DayPickerKeyboardShortcuts_showSpan__topLeft, | ||
)} | ||
> | ||
{ renderKeyboardShortcutsButton |
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 is a nit, but I think that the code style in react-dates is to avoid ternaries by creating two conditions instead?
{ renderKeyboardShortcutsButton && .... }
{ renderKeyboardShortcutsButton || .... }
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.
(in jsx in general)
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.
also, jsx curlies should have no bounding spaces inside them
topLeft && styles.DayPickerKeyboardShortcuts_show__topLeft, | ||
)} | ||
type="button" | ||
aria-label={toggleButtonText} |
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.
In order to pass in aria-label
from custom button, I might have to change this to this.getToggleButtonText()
and bind to this scope since it relies on state change in DayPicker.jsx
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'm confused, what is being referred to as "custom button" here? Seems like aria-label
would work here unless I misunderstand?
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.
@monokrome toggleButtonText
here relies on showKeyboardShortcuts
which is a state variable set in the parent DayPicker.jsx
. At first, I didn't think there was a way for me to pass in a similar variable through renderKeyboardsShortcutsButton
that can read the state of DayPicker.jsx
unless I bound it somehow.
But actually though, I just realized that I can pass in toggleButtonText
as a param into the renderKeyboardShortcutsButton()
here and drill that back into the render logic. Turns out I don't need to change any logic here. Hope that made sense!
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.
Cool! Thanks so much for explaining to me 😺
topLeft && styles.DayPickerKeyboardShortcuts_showSpan__topLeft, | ||
)} | ||
> | ||
{ renderKeyboardShortcutsButton |
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.
also, jsx curlies should have no bounding spaces inside them
it('renders the provided button', () => { | ||
const props = { renderKeyboardShortcutsButton: () => (<button type="button">Success!</button>) }; | ||
const wrapper = shallow(<DayPickerKeyboardShortcuts {...props} />).dive(); | ||
const buttonWrapper = wrapper.children().find('button'); |
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.
possibly a more robust test would be to render a custom component, and expect(wrapper.find(Custom)).to.have.lengthOf(1))
, rather than duplicating the text and element name here?
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.
The use case for renderKeyboardShortcutsButton is to literally send in a <button>
though, should I still create a spec for a React Component? @ljharb
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.
@kypan i mean, the purpose is to ensure that whatever renderKeyboardShortcutsButton
returns is what's rendered; the only way to guarantee that is to use an unforgeable sentinel value - which would thus be a custom component.
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.
@ljharb That definitely makes sense. I've updated it. Thanks!
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’d be good to also add test coverage for DayPicker and DayPickerRangeController - ie, just ensuring that the props are passed down.
stories/DayPickerRangeController.js
Outdated
@@ -68,6 +68,49 @@ const TestCustomInfoPanel = () => ( | |||
</div> | |||
); | |||
|
|||
function renderKeyboardShortcutsButton(buttonProps) { | |||
const { ref, onClick, ariaLabel } = buttonProps || {}; |
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.
Why would buttonProps need to be optional here?
If it is, it should be defaulted in the signature, no?
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.
@ljharb I think when I wrote this I copied code from monorail. I intended to make buttonProps optional to avoid future implementations breaking, and so I used the defaulting pattern I saw in monorail. But if it's cool with the react-dates
squad I can just make it required
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.
Seems better to require everything until it needs to be optional.
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.
Cool, I made it required
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.
Looks good after Jordan's requests are implemented 😺
@ljharb Added specs for DayPicker and DayPickerRangeController |
Sick! This looks awesome. Thank you for the thorough reviews @monokrome and @ljharb |
Introducing a functional prop renderKeyboardShortcutsButton to render a custom styled button.