Skip to content

Commit

Permalink
refactor: Use add methods for brand Sass inclusion
Browse files Browse the repository at this point in the history
Removes the `_insert_sass()` method to use standard `ui.Theme()` methods
  • Loading branch information
gadenbuie committed Dec 4, 2024
1 parent 39e6390 commit 4ddf0f5
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 70 deletions.
112 changes: 47 additions & 65 deletions shiny/ui/_theme_brand.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ def __init__(
mixins: Any = None,
rules: Any = None,
):

# TODO: Remove `path` and handle in try/except block in caller
self._path = path
self.version = version
Expand Down Expand Up @@ -183,7 +182,6 @@ def __init__(
*,
include_paths: Optional[str | Path | list[str | Path]] = None,
):

name = self._get_theme_name(brand)
brand_bootstrap = BrandBootstrapConfig.from_brand(brand)

Expand All @@ -208,17 +206,25 @@ def __init__(

brand_typography_defaults = ThemeBrand._prepare_typography_vars(brand)

brand_bootstrap_defaults = (
"\n".join(Theme._combine_args_kwargs(kwargs=brand_bootstrap.defaults))
if brand_bootstrap.defaults
else ""
)
# Defaults ----
# Final order is reverse-insertion:
# * brand.color.palette
# * brand.defaults (Brand-defined Bootstrap defaults)
# * brand.color
# * brand.typography

self._add_defaults_hdr("typography", **brand_typography_defaults)
self._add_defaults_hdr("color", **brand_color_defaults)

if brand_bootstrap.defaults:
self._add_defaults_hdr("defaults (bootstrap)", **(brand_bootstrap.defaults))

self._add_defaults_hdr("color.palette", **brand_color_palette_defaults)

self._insert_sass("brand.color.palette:defaults", brand_color_palette_defaults)
self._insert_sass("brand.defaults:defaults", brand_bootstrap_defaults)
self._insert_sass("brand.color:defaults", brand_color_defaults)
self._insert_sass("brand.typography:defaults", brand_typography_defaults)
self._insert_sass("brand.color.palette:rules", brand_color_palette_rules)
# Rules ----
self.add_rules(*brand_color_palette_rules)

# Bootstrap extras: functions, mixins, rules (defaults handled above)
self._add_brand_bootstrap_other(brand_bootstrap)

def _get_theme_name(self, brand: "Brand") -> str:
Expand All @@ -227,39 +233,18 @@ def _get_theme_name(self, brand: "Brand") -> str:

return brand.meta.name.short or brand.meta.name.full or "brand"

def _insert_sass(self, name: str, code: str):
name_parts = name.split(":")
if len(name_parts) != 2:
raise ValueError(
f"Invalid name format. Expected 'name:layer', got '{name}'"
)

layer = name_parts[1]
layer_attr = f"_{layer}"
if not hasattr(self, layer_attr):
raise ValueError(f"Invalid layer: {layer}")

layer_content = getattr(self, layer_attr)
insert_marker = f"/*-- insert({name}) --*/"

new_layer_content = [
chunk.replace(insert_marker, code) for chunk in layer_content
]

setattr(self, layer_attr, new_layer_content)

@staticmethod
def _prepare_color_vars(
brand: "Brand",
) -> tuple[str, str, str]:
) -> tuple[dict[str, YamlScalarType], dict[str, YamlScalarType], list[str]]:
"""
Colors: Create a dictionaries of Sass and CSS variables
"""
if not brand.color:
return "", "", ""
return {}, {}, []

defaults_dict: dict[str, str | float | int | bool | None] = {}
palette_defaults_dict: dict[str, str | float | int | bool | None] = {}
defaults_dict: dict[str, YamlScalarType] = {}
palette_defaults_dict: dict[str, YamlScalarType] = {}
palette_css_vars: list[str] = []

for thm_name, thm_color in brand.color.to_dict(include="theme").items():
Expand Down Expand Up @@ -289,34 +274,21 @@ def _prepare_color_vars(
# => CSS var: `--brand-{name}: {value}`
palette_css_vars.append(f" --brand-{pal_name}: {pal_color};")

palette_defaults = [
"",
"// *---- brand.color.palette ----* //",
*Theme._combine_args_kwargs(kwargs=palette_defaults_dict, is_default=True),
]

defaults = [
"",
"// *---- brand.color ----* //",
*Theme._combine_args_kwargs(kwargs=defaults_dict, is_default=True),
]

palette_rules = [
"",
"// *---- brand.color.palette ----* //",
":root {",
*palette_css_vars,
"}",
]

return (
"\n".join(palette_defaults), # brand.color.palette:defaults
"\n".join(defaults), # brand.color:defaults
"\n".join(palette_rules), # brand.color.palette:rules
palette_defaults_dict, # brand.color.palette:defaults
defaults_dict, # brand.color:defaults
palette_rules, # brand.color.palette:rules
)

@staticmethod
def _prepare_typography_vars(brand: "Brand") -> str:
def _prepare_typography_vars(brand: "Brand") -> dict[str, YamlScalarType]:
"""
Typography: Create a list of brand Sass variables
Expand All @@ -329,10 +301,10 @@ def _prepare_typography_vars(brand: "Brand") -> str:
$brand_typography_base_line-height: 1.25;
```
"""
mapped: dict[str, str | float | int | bool | None] = {}
mapped: dict[str, YamlScalarType] = {}

if not brand.typography:
return ""
return {}

brand_typography = brand.typography.model_dump(
exclude={"fonts"},
Expand All @@ -347,21 +319,31 @@ def _prepare_typography_vars(brand: "Brand") -> str:
typo_sass_var = f"brand_typography_{field}_{prop_key}"
mapped[typo_sass_var] = prop_value

ret = [
"",
"// *---- brand.typography ----* //",
*Theme._combine_args_kwargs(kwargs=mapped, is_default=True),
]
return mapped

return "\n".join(ret)
def _add_defaults_hdr(self, header: str, **kwargs: YamlScalarType):
self.add_defaults(**kwargs)
self.add_defaults(f"\n// *---- brand: {header} ----* //")

def _add_brand_bootstrap_other(self, bootstrap: BrandBootstrapConfig):
if bootstrap.functions:
self.add_functions(bootstrap.functions)
self.add_functions(
*[
"// *---- brand.defaults: bootstrap.functions ----* //",
bootstrap.functions,
]
)
if bootstrap.mixins:
self.add_mixins(bootstrap.mixins)
self.add_mixins(
*[
"// *---- brand.defaults: bootstrap.mixins ----* //",
bootstrap.mixins,
]
)
if bootstrap.rules:
self.add_rules(bootstrap.rules)
self.add_rules(
*["// *---- brand.defaults: bootstrap.rules ----* //", bootstrap.rules]
)

def _html_dependencies(self) -> list[HTMLDependency]:
theme_deps = super()._html_dependencies()
Expand Down
10 changes: 5 additions & 5 deletions shiny/www/py-shiny/brand/_brand-yml.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@

/*-- scss:defaults --*/

/*-- insert(brand.color.palette:defaults) --*/
/*-- insert(brand.defaults:defaults) --*/
/*-- insert(brand.color:defaults) --*/
/*-- insert(brand.typography:defaults) --*/
// Sass variables from `brand` will be inserted (above) here in this order:
// * brand.color.palette
// * brand.defaults
// * brand.color
// * brand.typography

//*-- brand: initial defaults --*//
$brand_color_foreground: null !default;
Expand Down Expand Up @@ -166,7 +167,6 @@ $link-bg: null !default;
$link-weight: null !default;

/*-- scss:rules --*/
/*-- insert(brand.color.palette:rules) --*/

// *---- brand: brand rules to augment Bootstrap rules ----* //
// https://github.com/twbs/bootstrap/blob/5c2f2e7e/scss/_root.scss#L82
Expand Down

0 comments on commit 4ddf0f5

Please sign in to comment.