Public API for resolving a theme element against a parent
Nobody has claimed this yet.
- Dominant language
- R
- Stars
- 7k
- Forks
- 2.1k
- Avg merge
- 59m
- Merged PRs (30d)
- 2
Description
I'm developing a ggplot2 extension that needs to resolve a user-supplied element_*() object as if it were a child of a specific theme element. I'd like to do this without permanently registering the element in the global element tree.
Use case:
My extension, let's call it supertable, adds tables to plots. Users can customize their appearance both via the theme (through custom registered elements like supertable.value) and via inline parameters:
supertable(
value_style = element_text(size = rel(2)),
title_style = element_text(margin = margin_part(b = 6),
line_style = element_line(color = "red")
)
The inline parameter should sit "above" the theme element in the inheritance chain — i.e., rel() and margin_part() should resolve against the fully inherited theme element value, exactly as they would for any normal parent-child relationship in the element tree.
The problem:
The only way to get full resolution (including rel(), margin_part(), and any future deferred-resolution mechanisms) is through calc_element(). merge_element() seems like it should help here, but it simply overwrites fields from the new element onto the old one without resolving deferred values like rel(). So calc_element() appears to be the only option, but it requires the element to be registered in the global tree via register_theme_elements(). So my current workaround is:
calc_element_with_override <- function(override, element, theme, el_class) {
if (is.null(override)) override <- el_class()
secret_name <- paste0(element, ".__override__")
register_theme_elements(
!!secret_name := el_class(),
element_tree = rlang::list2(
!!secret_name := el_def(el_class, inherit = element)
)
)
theme[[secret_name]] <- override
calc_element(secret_name, theme)
}
This works, but it permanently alters the global element tree as a side effect, which feels wrong.
What would help:
An exported function that resolves an element object against a parent element object. This would apply the same resolution logic as calc_element (resolving rel(), margin_part(), etc.) but without requiring the element to be registered globally. It could be called resolve_element.
I suspect this could also be useful for other extension authors who need to compute derived styles at render time. Thanks for your consideration.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading calc_element(), merge_element(), and register_theme_elements(), which the issue identifies as the relevant entry points for inheritance and deferred resolution. Compare their behavior and determine the API shape needed to resolve an override against a parent without changing the global element tree; done means the requested resolution behavior works without that side effect.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- r
- Domain
- design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100