WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.46k stars 4.18k forks source link

Publicly expose `useGlobalStyle` hook #63796

Open fabiankaegy opened 2 months ago

fabiankaegy commented 2 months ago

The useGlobalStyle hook has been available in the Plugin for quite some time now. But extenders cannot use it because it currently is a private API.

It would be great to be able to use this hook in external plugins however to store custom settings in global styles. I for example have a custom theme that makes a lot of use of settings.custom to define a ton of css custom properties. It would be super powerful if I could extend the site editor / a custom settings screen to visually manage these custom properties. Instead of just being limited by what's in core.

fabiankaegy commented 2 months ago

@youknowriad @ellatrix I'd love to get your take on this. Happy to work on the PR etc. But want to see whether there are reasons you would be against exposing the hook publicly.

youknowriad commented 2 months ago

@fabiankaegy Do we already have slots or things like that to extend the Global styles sidebar?

fabiankaegy commented 2 months ago

@youknowriad We do not have the UI Slots for it no. But we can make use of it in there areas of the site like on custom plugin screens or even setting sidebars that get rendered in the site / post editor

youknowriad commented 2 months ago

I don't think we should be exposing the hook without having a good story how to use it.

The hook depends on a provider GlobalStylesContext to work and I'm not sure that it would work in all contexts (for instance it doesn't really work in the post editor and this is why we recently introduced globalStylesDataKey into the block editor setting.

I wonder if we should double down on this and instead have a hook that rely on globalStylesDataKey instead. I think this is going to be needed for some on-going work (showing inherited values in the block editor). Not sure who's working on that exactly though, maybe @ramonjd

That said, I think given all these things are in flux, I'm not confident about opening such APIs today.

fabiankaegy commented 2 months ago

Thanks for all those insights ❤️

From my perspective the UI and the API could be handled separately. If we don't feel we are ready to open up the site editor / global styles for custom UI because it is still moving around too much that's fine. But I believe it would still be very valuable to expose the underlying API to allow for experimentation & exploration outside of the gutenberg plugin.

Without the UI slots it won't be nearly as useful and will probably not get used super widely. But thing like enabling more powerful developer oriented global styles UI built into the Create Block Theme plugin would be possible if the API here would be exposed.

And yeah that custom implementation would also need to be able to use the GlobalStylesContext provider etc to set it up. But it at least would be possible :)

youknowriad commented 2 months ago

From my perspective the UI and the API could be handled separately. If we don't feel we are ready to open up the site editor / global styles for custom UI because it is still moving around too much that's fine. But I believe it would still be very valuable to expose the underlying API to allow for experimentation & exploration outside of the gutenberg plugin.

I wonder if the API is more in flux than the UI at this point, I'd love to see a design exploration about what extensibility slots/hooks we want to enable in the global styles sidebar. I'm not at all against opening the UI for extensibility.

ramonjd commented 2 months ago

I wonder if we should double down on this and instead have a hook that rely on globalStylesDataKey instead. I think this is going to be needed for some on-going work (showing inherited values in the block editor). Not sure who's working on that exactly though, maybe @ramonjd

Thanks for the ping!

My toes have definitely been dipped in this area 😄 as part of the recent background image work, but not in any general sense.

Here's an issue that directly relates to displaying inherited values:

Just so I understand, is the main thrust of this issue that extenders would like to set global styles settings (and/or styles)?

I haven't looked very closely, but from instinct, relying on the globalStylesDataKey as the source of truth is a sound idea.

I suppose then, any hook in the editor package would update the entity record, similar to useGlobalStylesUserConfig.

globalStylesDataKey returns the styles property of global styles, and __experimentalFeatures contains the settings. Maybe it's time to deprecate __experimentalFeatures and think about a more intuitive data model.

What do folks think?

See related discussion: https://github.com/WordPress/gutenberg/pull/60100#discussion_r1687165325

youknowriad commented 2 months ago

I think the first question I would like to answer here personally is whether we think "editing the theme" (which is what this thing is about) is something that the "block-editor" package should be able to do or not.

The globalStylesDataKey is about providing a "theme", so block editor can have awareness of the existence of a theme but not be able to edit it.

Now, if we start thinking about editing the theme as well, which we kind of already have with (apply styles globally). I think we need to conceptualize this a bit better rather than jump quickly to solutions.

I wonder if a better architecture is to try to decouple "block-editor" from "theme" (or global-styles). So we have:

The remaining question is how these two should communicate between each other.

Should they communicate. Should block-editor have a dependency towards global-styles. It seems like we want the different block style panels to access global styles... so maybe we can make it an optional dependency. If there's a provider in the context, we can access and edit these values, if there's no provider in the context the panels and blocks should hide any global-style related control.

Who injects the GlobalStylesProvider, for WordPress, it seems like the EditorProvider in the editor package would be the right place.

The last question is whether we should automatically "output" the style of the GlobalStylesProvider in the iframe/previews... (auto augment the BlockEditorProvider styles property). It's unclear at this point to me and it's probably something we can change afterwards.

Any other ideas / feedback?