We have a button that we want to have enabled or disabled depending on some condition. Furthermore, we want the hover effect of the button when disabled to display a tooltip explaining why it is disabled.
Currently, we have something like this:
export class NextButton extends React.Component {
makePopover () {
return (
this.props.someCondition && <Popover>Please enter a title.</Popover>
)
}
render () {
return (
<div>
<OverlayTrigger placement='top' overlay={this.makePopover()}>
{/* wrap this in a div so when the button is disabled, the popover still works */}
<div>
<Button
onClick={() => this.props.goToNextPage()}
disabled={this.props.someCondition}
>
Next
</Button>
</div>
</OverlayTrigger>
</div>
);
}
}
Now, if we look closely at the makePopover function, if someCondition is false, Popover will not be rendered and OverlayTrigger throws an error if anything without an id is returned.
Therefore, to fix this we tried:
this.props.someCondition ? <Popover>...</Popover> : <span>...</span>
This helped but displayed other warnings:
Warning: Unknown props
placement,arrowOffsetLeft,arrowOffsetTop,positionLeft,positionTopon tag. Remove these props from the element.
Now, instead of conditionally displaying the Popover, we could wrap the conditional around the entire OverlayTrigger itself, doing something like:
this.props.someCondition
?
<OverlayTrigger>
<Button>Next</Button>
</OverlayTrigger>
:
<Button>Next</Button>
What is the best practice for how to deal with conditional tooltips? Any help would be greatly appreciated.
I was facing the same problem I thought the cleanest way to solve it is to use a conditional wrapper.
const ConditionalWrapper = ({
condition,
wrapper,
children,
}) => (condition ? wrapper(children) : children);
export class NextButton extends React.Component {
render () {
return (
<div>
<ConditionalWrapper
condition={this.props.someCondition}
wrapper={children => (
<OverlayTrigger
overlay={<Popover>Please enter a title.</Popover>}
placement='top'
>
{children}
</OverlayTrigger>
)}
>
{/* wrap this in a div so when the button is disabled, the popover still works */}
<div>
<Button
onClick={() => this.props.goToNextPage()}
disabled={this.props.someCondition}
>
Next
</Button>
</div>
</ConditionalWrapper>
</div>
);
}
}
Here is Alexus answer in Typescript (mostly):
interface IConditionalWrapperProps {
condition: boolean;
wrapper: (children: React.ReactNode) => JSX.Element;
children: JSX.Element;
}
const ConditionalWrapper = ({
condition,
wrapper,
children,
}: React.PropsWithChildren<IConditionalWrapperProps>) => (condition ? wrapper(children) : children);
export class NextButton extends React.Component {
render () {
return (
<div>
<ConditionalWrapper
condition={this.props.someCondition}
wrapper={children => (
<OverlayTrigger
overlay={<Popover>Please enter a title.</Popover>}
placement='top'
>
{children}
</OverlayTrigger>
)}
>
{/* wrap this in a div so when the button is disabled, the popover still works */}
<div>
<Button
onClick={() => this.props.goToNextPage()}
disabled={this.props.someCondition}
>
Next
</Button>
</div>
</ConditionalWrapper>
</div>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With