Pass classname to material ui date-picker dialog - reactjs

Is there a way to pass classname to matererial-ui datepicker's dialog.
http://www.material-ui.com/#/components/date-picker
Material-ui's datepicker accepts classname as a prop. But, this gets applied to the text-field upon which we want to trigger the date-dialog.
I want to pass a class attribute to the date-popup itself. Something like:
dialogClassName
The need is I want to access if the click was done somewhere inside the date-dialog and manage some other part of my code based on that. I can't figure out how to make the date-dialog accept a classname.
This issue was a bit boosting,https://github.com/mui-org/material-ui/issues/5329 but passing a dialogClassName doesn't get applied.

There is a solution which I came across by going through the DatePicker Code. You can pass the following props to the DatePicker
<DatePicker>
PopperProps={{
className: classes.desktopView,
}}
DialogProps={{
className: classes.mobileView,
}}
</DatePicker>

I'm afraid you cannot do that without modifying the DatePicket component ( at least not without some wild hacks).
If you really need this functionality you can fork material-ui repository, make the changes and submit a pull request. Or, in you project, create a local DatePicker component and do the changes there, but this approach requires you to update your version in case material-ui's version is updated.

There is no solution as of yet. However there is a workaround to pass a css class name to popup/dialog container.
Pass an img tag for rightArrowIcon props of datepicker with onload function to call its parent and inject css class.
<DatePicker
disableToolbar={true}
variant="inline"
inputVariant="outlined"
rightArrowIcon={<img src="/images/chevron-right_1.svg" id="datepicker-arrow-right" onLoad={injectTheme}/>}
leftArrowIcon={<img src="/images/chevron-right_1.svg" style={{transform:"rotate(180deg)"}}/>}
....
....
....
/>
const injectTheme=()=>{
let node = document.getElementById("datepicker-arrow-right").parentNode.parentNode.parentNode.parentNode.parentNode.parentElement;
node.classList.add("Css-Class-Name");
}

Related

Material-UI slider not exposing name prop to Formik

I'm using react,formik and material-ui to build out an application that I'm trying to add a slider to. For some reason, it appears that the Material-UI slider component is not exposing the name prop to formik which causes formik to through a warning and not use the value from the slider. The warning says that you've called handleChange but not provided id or name
I've created a CodeSandbox that shows the issue I'm having. I managed to find 1 issue on GitHub but Material UII closed it saying that they aren't fixing it and that it has to be handled in userland.
I'm wondering if anyone else has come across this and managed a workaround for it.
I figured it out. Changed the onChange prop from onChange={handleChange} to onChange={(event, value) => setFieldValue('slider', value)}
As for now, it already provides a name attribute.
https://mui.com/material-ui/api/slide/#props

How can I focus on a react-select component at will?

Using react-select v2, I want to show and focus on the Select element when the user hits a certain key. Following are some things I've tried or paths I've gone down.
When I set a ref to the Select element and try to call .focus on it, it says no focus function is found. Perhaps I should somehow get a child element of it and then call focus on that?
There doesn't seem to be any prop I can pass that will trigger a focus function. There is an openOnFocus but not a focusOnOpen. The only thing I can think of would be to enable autoFocus and then somehow trigger a remount but there doesn't seem to be a simple way to do this and it feels hacky. Alternatively, I could enable just create the Select component each time the key is pressed instead of showing it, then unmount it instead of hiding it.
How can I properly get the react-select element to gain focus when I want it to?
I'm using a wrapper component around my component. Here's the render method for my wrapper:
render() {
return (
<Select
options={this.props.options}
value={this.state.value}
ref={this.selectRef}
/>
);
}
And here's where I'm calling that wrapper:
<Wrapper
options={this.props.labelOptions}
ref={this.wrapperRef}
/>
I then try calling focus using either this.dropdownNode.focus() or this.dropdownNode.current.focus() and both say no focus method is found.
Because you're wrapping the Select component, you can't call Select's .focus() function from the ref you're giving to the wrapper. Since ref is a special kind of prop, the ref for that wrapper is only referring to Wrapper itself, not the component it wraps (Select).
To access the actual Select component's ref, you have to pass a ref down to it as a prop with a different, non-magic name, like innerRef (react-select code actually gives a good example of this as it's accessing the actual input element and focusing on that).
Here's the change that fixed it. Here is the wrapper component where Select is actually used (and it's taking in the ref passed to it):
render() {
return (
<Select
options={this.props.options}
value={this.state.value}
ref={this.props.innerRef}
/>
);
}
And here's the component that's calling that wrapper. In the constructor I'm creating the ref with this.selectRef = React.createRef() then I pass it in as a prop in this render method:
<Wrapper
options={this.props.labelOptions}
innerRef={this.selectRef}
/>
Then I can call focus on the Select component itself by running this.selectRef.current.focus() anywhere I want to.
Notes: Thanks to BoyWithSilverWings answer. This question pertains to React 16.3. There is also a new React.ForwardRefs method but this way seems simpler to me.

How to add data- attributes in Checkbox component via inputProps

I use Fabric components written in React + Typescript and when using Checkbox component I can add custom attributes such as data-id and so on - this is written also on documentation: https://developer.microsoft.com/en-us/fabric#/components/checkbox
Whats the problem ? I do not know how to add one by passing it to inputProps.
Interface of React HTMLAttribute for field data require string value.
From what I see there interface of React's HTMLAttribute is generic one and Checkbox component passes this interfaces there: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/global.d.ts - They are empty.
Does somebody know how to implement the data- attributes there ?
In most cases where an interface extends React.ButtonAttributes we filter out all the valid button props (aria included) and pipe them in. Seems this component never got updated to use that approach and is still using an older approach where we put all of those props into 'inputProps'.
<Checkbox
label="Standard checkbox"
inputProps={{'data-foo': 'bar'}}
ariaDescribedBy={'descriptionID'} />
https://codepen.io/micahgodbolt/pen/djNGQv

Fire same bootstrap tooltip for all disabled inputs / ReactJS

What's the best way to intialize Tooltip in a react component and have it fire on all disabled inputs, like a global single call.
i.e. "This cannot be edited" any time you hover over ANY disabled input.
My goal is to NOT have to wrap each of hundreds of inputs individually like this:
<Tooltip>
<input/>
</Tooltip>
Make an Input component, pass in a bool prop, something like showValidationMessageAsTooltip, and, inside Input comp., if showValidationMessageAsTooltip is true, wrap the Input comp. with Tooltip.
Code example:
return (
showValidationMessageAsTooltip ? <Tooltip><input {...props}/></Tooltip> : <input {...props} />
);
This way, you'll only have to pass in an extra bool prop.
P.S.: There are other, even more efficient ways, especially if you have a form config where each form field has a component defined for it and each form field can have multiple HOC (higher-order comps.) defined in the form config (an array of objects, basically) as well.
But, for now, until you dive deeper into things like redux-form, etc., I suggest to stick to the simpler solution.

react willReceiveProps workaround for external library

I'm using a react datepicker component that can be found here. The component is pretty great except for what appears to be an oversight: it does not implement willReceiveProps.
To expound, I create the datpicker as below:
<DateField
dateFormat= { dateFormat}
forceValidDate={true}
defaultValue={startDate || ''}
onChange={this.handleChange.bind(null, 'start_date')}
id="start"
>
<DatePicker
navigation={true}
locale="en"
forceValidDate={true}
highlightWeekends={true}
highlightToday={true}
weekNumbers={true}
weekStartDay={0}
/>
</DateField>
Note above that there is a prop defaultValue which I pass startDate. Now, startDate can and does change for reasons that are sometimes external to the component. That value is passed during a new render() action as per usual. According to react philosophy this shouldn't be a problem.
However, it appears to me as if the value from defaultValue is only ever read once inside DateField. It is read as this.props.defaultValue. Anyone who has ever built a component relying on props should quickly recognize this is a problem. It means that when the prop is changed the new value will not be used.
Because this is a library, I cannot simply implement willReceiveProps. Does anyone know of a good workaround to get this component to either completely reset on a render or some other strategy to deal with what seems to be a big design problem?
They follow the same standards as the <input> component. defaultValue is read only once but there is also value that can be set externally. There is no need for them to use willReceiveProps.
In short, use value instead of defaultValue.
See Uncontrolled Components in React
PS: I am looking a bit into the code and it seems there are also properties text and date apart from value. Since the code (and documentation) has been removed from github, I won't inspect what is the difference between those props.

Resources