react-tooltip icon indicating copy to clipboard operation
react-tooltip copied to clipboard

Disabled element won't show tooltip

Open stefensuhat opened this issue 7 years ago • 15 comments

 <button
	onClick={onCheckoutPress}
     className="button primary font-14 font-400 full"
     disabled={true}
     data-tip="Disabled"
     data-for="checkout-button"
 >
     Save
 </button>

 <ReactToolTip
       id="checkout-button"
/>

The tooltip won't show if button is disabled.

stefensuhat avatar Jun 06 '17 09:06 stefensuhat

Same issue here, but it only occurs with (disabled) buttons, not all elements. As a workaround, I wrapped my disabled button inside a span element :

<span data-tip="Lorem ipsum" data-tip-disable={false}>
    <button disabled={true}>Click</button>
</span>

bost-h avatar Jun 07 '17 16:06 bost-h

I was bit by the same issue. Good idea on the workaround

WickyNilliams avatar Aug 24 '17 13:08 WickyNilliams

+1, guess i'm doing the workaround 🤕

kellyrmilligan avatar Feb 07 '18 17:02 kellyrmilligan

The workaround makes the tooltip display, but, for me, it does not follow the mouse.

mdelrossi1 avatar Apr 23 '18 18:04 mdelrossi1

Hm, don't really like the wrapping workaround, as it can mess up things like menu items etc, that rely on a certain DOM structure. I think a very common scenario is to want to show a tool-tip if a button is disabled, to explain to the user why it's disabled.

strongui avatar Sep 05 '18 15:09 strongui

Keep the button inside the <span> tags then you can get the tooltip for disabled buttons. This is the best you can do instead of using warning

<span> <button disabled> Save </button> </span>

NandySahukar avatar Feb 28 '19 15:02 NandySahukar

Hm, don't really like the wrapping workaround, as it can mess up things like menu items etc, that rely on a certain DOM structure. I think a very common scenario is to want to show a tool-tip if a button is disabled, to explain to the user why it's disabled.

can't stress this more.

YuriScarbaci avatar Oct 11 '19 17:10 YuriScarbaci

I haven't full tested it yet, but I have a situation where wrapping in ... it makes tooltip appear, but don't disappear.

jonauz avatar Apr 03 '20 14:04 jonauz

+1

rahul-desai3 avatar Dec 15 '20 22:12 rahul-desai3

If you have another tag in disabled button you can set tooltip on it as well.

tsrul avatar May 02 '21 18:05 tsrul

The workaround that worked best for me is to put the span inside the button:

<button disabled={true}>
  <span data-tip="Lorem ipsum" data-tip-disable={false}>
    Click
  </span>
</button>

benlieb avatar Jul 08 '21 14:07 benlieb

The workaround that worked best for me is to put the span inside the button:

<button disabled={true}>
  <span data-tip="Lorem ipsum" data-tip-disable={false}>
    Click
  </span>
</button>

That worked great, thanks! I also replaced 'span' with 'div', since span caused the tooltip to be visible only when hovering over the text, not the whole button.

kuba11 avatar Aug 27 '21 12:08 kuba11

^ you have to style the span though to be full height of the button, otherwise the tip will trigger only over the text.

evgenyfadeev avatar Nov 17 '21 20:11 evgenyfadeev

i've been bitten, too, and was hoping for a true solution, but...

looks like this is gonna be hard to solve without introducing some higher-level code (which i'm not sure is desired for this library); the issue stems from the native behavior of disabled elements (see this demo for an illustration of this behavior).

details:

the way that react-tooltip responds to user interaction is relying on native dom event binding (namely, mouseenter and focus) for attaching the show/hide listeners, as seen in the source code, on the main file. these events are not triggered by the user agent, if the element is marked as disabled. W3C's recommendation on this states that engines should prevent dispatching click events, but apparently vendor implementations have broadened this definition (or probably there's already a spec i'm not aware of).

eliranmal avatar Dec 08 '21 01:12 eliranmal

also, here's my current take for a workaround (source):

export default const FormControl = ({
  tag: FormControlType,
  ...props
}) => {
  const tooltipAttributes = Object.entries(props)
    .filter(([key, value]) => key.startsWith('data-'))
    .reduce((accum, [key, value]) => {
      accum[key] = value
      return accum
    }, {})

  return props.disabled && tooltipAttributes['data-tip'] ? (
    <span {...tooltipAttributes}>
      <FormControlType {...props} />
    </span>
  ) : (
    <FormControlType {...props} {...tooltipAttributes} />
  )
}

this implementation has an obvious limitation (on top of the structural limitations mentioned in earlier comments); it assumes all data-* attributes belong to react-tooltip, but other then that, it's just a convenient way to encapsulate all that wrapper shenanigans into a nice package.

example usage:

const Button = ({className = '', ...props}) => (
  <FormControl
    {...props}
    tag="button"
    className={`drifter-button ${className}`}
  />
)

it can also be used for its declarative abstraction-level of form-control components, that is - we can include CSS rules that are common to buttons, inputs, selects etc. (ever found yourself constantly repeating stuff like outline: none across form control components? i know i did..).

eliranmal avatar Dec 10 '21 00:12 eliranmal

The workaround that worked best for me is to put the span inside the button:

<button disabled={true}>
  <span data-tip="Lorem ipsum" data-tip-disable={false}>
    Click
  </span>
</button>

Works great, thanks :)

sztadii avatar Feb 08 '23 02:02 sztadii