BreakpointProvider matched breakpoints do not update when Provider breakpoints change
- 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
Assessment
This issue has not been assessed yet.