1

I have a requirement to add tooltip on hover to disabled options in a dropdown in React fluent UI.

I am able to add tooltip to singular component using https://www.npmjs.com/package/@fluentui/react-tooltip

<Tooltipcontent="Example tooltip">
  <Button/>
</Tooltip>

but how to add similar behaviour to dropdown options and only for disabled options like: "Disabled cause of non avilability" sample dropdown fluent ui code

const options: IDropdownOption[] = [
  { key: 'fruitsHeader', text: 'Fruits', itemType: DropdownMenuItemType.Header },
  { key: 'apple', text: 'Apple' },
  { key: 'banana', text: 'Banana' },
  { key: 'orange', text: 'Orange', disabled: true },
];

export const DropdownBasicExample: React.FunctionComponent = () => {
  return (
    <Stack tokens={stackTokens}>
      <Dropdown
        placeholder="Select an option"
        label="Basic uncontrolled example"
        options={options}
        styles={dropdownStyles}
      />

    </Stack>
  );
};

Thanks

giorno
  • 65
  • 7

1 Answers1

1

Fluent UI renders every disabled option as a button element with the disabled attribute, which makes it non-interactive by default.

Here's a method to solve this that I believe is also fairly accessible:

First, define your array of IDropdownOption items so that they conditionally set the disabled and title properties:

const options: IDropdownOption[] = [
  { key: 'apple', text: 'Apple' },
  { key: 'orange',
    text: 'Orange',
    disabled: isOrangeDisabled,
    title: isOrangeDisabled ? "This is a disabled tooltip" : ""
  },
];

You're also going to need to define a custom rendering function for the items in order to apply a nice tooltip:

<Dropdown onRenderOption={onRenderOption} />

and then define a function like this in your component:

const onRenderOption = (option: IDropdownOption): JSX.Element => {
  return (
    <>
      {option?.disabled && (
        <div className="interactive">
          <TooltipHost content={option.title}>
            <span>{option.text}</span>
          </TooltipHost>
        </div>
      )}
      {!option?.disabled && (
        <span>{option.text}</span>
      )}
    </>
  );
};

Finally, that interactive CSS class needs to be defined in your CSS file. This will override the browser's default behaviour of making disabled elements non-interactive:

.interactive {
  pointer-events: auto;
}

Some things to note:

  • The reason the title is set to an empty string when the option is not disabled is so that it doesn't have a string value when the interactive item is rendered. Without this, the browser will render the tooltip when you hover on a selectable item, which looks ugly.
  • Using the title attribute should make the component pretty usable for screen readers and other assistive technology (though I am far from an expert)
  • The template only renders the TooltipHost and interactive class when the object is disabled, so that the tooltip and that behaviour only kick in when the option is disabled. Because the underlying option is still disabled, you still won't be able to select it.
Stefan Mohr
  • 2,170
  • 2
  • 23
  • 35