adobe / adobe/react-spectrum

BreakpointProvider matched breakpoints do not update when Provider breakpoints change

Open
#2,912 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

# 🐛 Bug Report

When a Provider is added to the DOM, any value passed in to its breakpoints prop will be evaluated at the current settings (browser/window size) and the result (matched breakpoints in the breakpoints provider) will be cached. This appears to be "as designed" under the assumption that breakpoints won't change (see: https://github.com/adobe/react-spectrum/pull/2412#discussion_r720705953), but if they do change, then the stale breakpoints are always returned, since the `resize` method caches the "current" breakpoints handler method.

## 🤔 Expected Behavior

If the breakpoints prop changes in a Provider, the breakpoints handler method should be recomputed so that the actual active breakpoints (matched breakpoints) are returned to components beneath this Provider (in the DOM)

## 😯 Current Behavior

Any updates to the breakpoints will reflect that the Provider code has the new breakpoints, but the actual matched breakpoints will be stale (never update) - so, any components beneath this Provider will still be operating on the old set of matches

## 💁 Possible Solution

Make [the breakpointHandler in BreakpointProvider](https://github.com/adobe/react-spectrum/blob/08e1121ec5be4c5fc2777a98b22a5fdee507f816/packages/%40react-spectrum/utils/src/BreakpointProvider.tsx#L41) a callback method (useCallback) that is recomputed if the `breakpoints` value is changed.

Update [the dependency list for the resize effect](https://github.com/adobe/react-spectrum/blob/08e1121ec5be4c5fc2777a98b22a5fdee507f816/packages/%40react-spectrum/utils/src/BreakpointProvider.tsx#L81) to update the resize method when the breakpointHandler changes.

## 🔦 Context

I need to create a Provider that is able to dynamically adjust its own breakpoints, given the *actual* amount of horizontal space it has available (at the time - so, this can grow/shrink at runtime).

This "responsive" Provider is necessary to support a higher-level AngularJS component (sidebar/help drawer) that "pushes" in from the side, decreasing the amount of horizontal space *actually* afforded to the Provider (i.e. - window size minus help drawer size). Ideally, if the horizontal space shrinks, it would adjust breakpoints and reflow content given the actual amount of space available.

We are transitioning our website away from AngularJS and into React. So, we really need this piece because we can't easily go from one UI framework to another and back again. So, we have to build in React from the bottom -> up in the DOM (only ever going from an AngularJS context -> React). I mention this because we are unable to place a React component "above" this one (at this point) to manage that sidebar interaction and the overall layout (ideal solution) because there are too many other components that sit underneath it that have not been ported (yet)... and, we can't easily go AngularJS -> React -> AngularJS (again).

## 💻 Code Sample

[Here is a code sandbox illustrating a very basic approach to implementing this type of Provider](https://codesandbox.io/s/jovial-dream-pfc7pi)

## 🌍 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| react-spectrum | latest |
| Browser | all |
| Operating System | all |

## 🧢 Your Company/Team

Adobe | BPS | Admin Console

## 🕷 Tracking Issue (optional)

Not publicly available (sorry)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.