Theme: Export ThemeProvider as alternative to private APIs#75352
Theme: Export ThemeProvider as alternative to private APIs#75352
Conversation
|
Warning: Type of PR label mismatch To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.
Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task. |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
I think we could do this now. It also simplifies the code a fair bit. Updated in f974531 . |
|
@aduth looks like |
1. This was previously needed to get correct typings when used through private APIs, not necessary now because we have the direct import option through subpath 2. This could cause future issues when we want to export ThemeProvider as the actual React component (i.e. not a type)
|
Does exposing the Can we use internal, relative paths for the time being? |
Considering that it's only accessible to npm packages, I am expecting we could use the same npm versioning approach we're adopting for |
|
Size Change: +2 B (0%) Total Size: 3 MB
ℹ️ View Unchanged
|
|
If we can introduce breaking changes, then I don't see the issue with using it as a private API? I don't remember who from @WordPress/gutenberg-components I spoke with about this, but I do remember reaching the conclusion that we couldn't introduce breaking changes. I'm probably confused with another conversation. |
I might not be following, but the problem with private APIs isn't to do with change management, it has to do with multiple copies of |
|
I tested this PR out by consuming Great work @aduth!
Just to quickly summarize, as is, the bundling of the UI package has questionable utility. The problem is that using a private API in I think this really highlights the risk of using private APIs in bundled packages in the first place. As a downstream consumer we are basically being silently opted-in to unstable internal APIs that might change and break our code without warning, despite the package we're bundling having a stable version constraint. Realistically speaking, any time you do this you're effectively making the API public in that it's called by code bundled in the consuming app rather than WordPress. |
|
I’d like to clarify my reasoning in case my previous explanation was unclear. I initially believed that the On the other hand, if To summarize:
I hope this makes things clearer! |
I don't agree that Although I think it does raise a valid point that if we're not actually shipping anything on the "built" There's a couple problems with the changes I made in #75352 (comment) :
With that in mind, I think I'm going to revert back to the original implementation which only updates |
Given that subpaths are not added to the global The long-term "fixes" are, IMO:
|
|
Yeah I think we're on the same page @ciampo 👍 The changes on the branch currently should reflect that, if you're able to give it a look. |
|
I thought |
Right, though my expectation is that with the current usage of ThemeProvider in Granted, I agree this feels entirely fragile, with the main point of trying to land something now to unblock others from using I wonder what appetite we'd have for trying to promote |
It would be fine as long as all the
I'll defer to the main folks who worked on it, but I'm actually more concerned about the stability of the design tokens themselves 😅 Breaking changes like #75054 are going to require back compat tokens to support older versions of |
|
After some more consideration, I think this approach feels pretty untenable. Packages which use components like Dialog would not have user preferences respected on inner content in a WordPress context because it would bundle its own copy of ThemeProvider and not be able to share with the global copy. Instead, I think we need to move toward stabilizing the ThemeProvider API so we can consolidate on We should be able to aim to have this happen shortly after the 7.0 beta cut-off so that it lands early in the WordPress 7.1 release cycle. |
Tracking at #76840 and closing this. |
What?
Closes #75319
Updates
@wordpress/uito remove usage of private APIs, instead exposingThemeProvideron a subpath export from@wordpress/theme/theme-provider.Why?
@wordpress/uiis a "bundled" package, meaning that it is not shipped as awp.global and is instead expected to be bundled by consumers. As described in #75319, using private APIs in bundled packages can cause issues because it can result in multiple versions of@wordpress/private-apis, causingunlockto fail. Therefore, we should avoid using private APIs within these types of bundled packages.How?
As a compromise, this creates a new
@wordpress/theme/theme-providersubpath:wp.global, but is accessible to NPM package consumers like@wordpress/uiitselfIt's worth acknowledging that this does introduce another type of "multiple versions" problem, since React context cannot be shared between two versions of the same package. This is most notable when comparing a bundled
ThemeProvidercompared to the one that would be shipped on thewp.global (via private APIs).This may be acceptable as a short-term limitation, since current usage within Gutenberg doesn't really take advantage of inherited context, and these types of workarounds are only necessary as long as the ThemeProvider API is not stable. My hope is that we could promote it to a stable API early in the WordPress 7.1 release cycle.
Some alternatives could include:
@wordpress/theme/theme-provider, which would at least avoid multiple copies in the WordPress context.Testing Instructions
Verify no regressions in the appearance or behavior of affected components (Dialog, Select, Tooltip) in Storybook:
npm run storybook:devcc @pavel-mailpoet