This is an exploration of how theme.json could work in the future—my dream theme.json, if you will. A tour of the new theme.json can be found in theme-v2.json. theme-v1.json is provided for reference to see where properties have moved.
The theme.json files are quite long, so it may be helpful to clone the gist and view the files in a proper editor with code folding.
This gist is more of a living document than a static thing, and there are still a lot of unanswered questions that I'm still working through. I'm pretty happy with the general structure at this point, but there are a few opportunities for things to be added or removed. This is mostly documented in the Unanswered Questions section of this README.
Excluding templates, I see three main categories of options that are available in theme.json: editor settings, presets, and styles.
Currently the settings
property contains two distinctly different types of options: presets and editor UI toggles.
Editor Settings
- enable/disable a UI feature in the editor
- Doe NOT produce any CSS
Presets:
- Generate CSS custom properties (ex.
--wp--preset--color--black
) - Generate utility classes (ex.
has-black-color
) - Provide palettes available from the UI
Styles
- Generate CSS properties
Duotone block support was added with supports.__experimentalDuotone
as a string of the selector to apply the duotone to. This extends that to work for theme.json and block supports that need a different selector than the base block selector.
I think a custom property area would be a good place for plugins to integrate with theme.json.
Filters like duotone can be quite complicated—simple strings no longer are enough for css property values. Having configurable preprocessors is a general way to allow a transformation to be done on custom settings.
I tried explaining why a structure change was needed in the theme-v2.json tour. The main goal was to fit in selectors and support generic filters, but in doing so I found a different structure for the existing settings that works better for the new selectors idea. And once I was changing the structure for that, I ended up thinking about the structure as a whole.
In my proposed structure change, I optimized for consistency first and then flexibility second. I didn't try to optimize for "ease of use" because that's not very well defined. I think consistency contributes to "ease of use", but there may be a better metric for optimization than consistency.
Consistency, in this context, means sets of properties in sections of the JSON document are identical to sets of properties in other sections of the JSON document and structures in the JSON document mirror existing CSS/HTML ideas. Flexibility is forward-thinking for ideas that have been discussed as future improvements to global styles.
We may end up just fitting selectors in to the existing structure
{customPresets,presets}.*
- Should all the values be arrays of objects with
label
,slug
, andvalue
properties? - What should an empty array mean? Should we allow empty arrays?
- If we don't use a preprocessor, would it be identical to the same thing in
customProperties
?
- Should all the values be arrays of objects with
customPresets.preprocessors
- If the structure isn't an array, how should arguments be passed?
- Should an array just be required for preprocessors?
customPresets.root.dropShadow
- How can we change the color based on the background? There's probably some intermediate CSS var that we can set that is controlled by background?
- What sort of interface will we need to combine multiple custom duotones and drop shadows?
{styles,customProperties}.selectors
- Should we allow generic CSS selectors to be created in theme.json? If so, how?
- Would we be able to name them and use them inside blocks like extending the block.json's
selectors
property? - Or (and this is probably simpler and more consistent) do we just allow generic CSS selectors as the keys and keep the values the same, much like
elements
?
selectors
- How do existing usages of
__experimentalSelector
work with the newselectors
format? core/code
__experimentalSelector
produces incorrect results when using with theme.json.
- How do existing usages of