Fix Event Bubbling on Select Component from Shandcn/ui

2023-12-07
By: O. Wolfson
  1. Understanding the Issue: Event bubbling occurs when an event is fired on a DOM element and propagates up the DOM tree, potentially triggering event handlers on parent elements. On mobile devices, this can lead to unwanted behaviors, like activating links under a dropdown menu when an item is selected.

  2. Solution Overview: The solution involves attaching an ontouchstart event handler directly to the SelectContent component, in the implementation. This handler will prevent the default action of the touch event and stop it from propagating.

Link to original solution found here.

  1. Implementing the Fix:

    • Use a ref callback on the SelectContent component.
    • In the callback, check if the ref is not null.
    • Assign an ontouchstart handler to the ref that calls e.preventDefault().
  2. Code Example:

    javascript
    <Select value={sortBy} onValueChange={handleChangeSort}>
      <SelectTrigger className="">
        <SelectValue placeholder="Sort By" />
      </SelectTrigger>
      {/* add the event handler here */}
      <SelectContent
        ref={(ref) => {
          if (!ref) return;
          ref.ontouchstart = (e) => {
            e.preventDefault();
          };
        }}
      >
        <SelectItem value="date">
          <span className="sm:text-sm text-lg">Date</span>
        </SelectItem>
        <SelectItem value="title">
          <span className="sm:text-sm text-lg">Title</span>
        </SelectItem>
      </SelectContent>
    </Select>
    
  3. Explanation: The ref callback is a function that receives the DOM element as its argument. By setting the ontouchstart property on this element, you directly manipulate the DOM to control the touch event's behavior, preventing it from bubbling up.

This approach ensures that when a user interacts with the SelectContent component on a mobile device, the touch event does not unintentionally trigger other elements positioned behind or near the dropdown.

For more about Shadcn/UI components, you can visit Shadcn/UI.