Skip to content

Commit c5f6302

Browse files
committed
refactor(ThemeBrand): Separate into smaller methods
1 parent 792af38 commit c5f6302

File tree

1 file changed

+84
-62
lines changed

1 file changed

+84
-62
lines changed

shiny/ui/_theme_brand.py

Lines changed: 84 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -189,81 +189,99 @@ def __init__(
189189
preset=brand_bootstrap.preset,
190190
include_paths=include_paths,
191191
)
192+
192193
self.brand = brand
193194

194-
# brand.color -----------------------------------------------------------------
195+
# Prep Sass and CSS Variables -------------------------------------------------
196+
sass_vars_colors, css_vars_colors = self._prepare_color_vars()
197+
sass_vars_typography = self._prepare_typography_vars()
198+
199+
# Theme -----------------------------------------------------------------------
200+
# Defaults are added in reverse order, so each chunk appears above the next
201+
# layer of defaults. The intended order in the final output is:
202+
# 1. Brand Sass color and typography vars
203+
# 2. Brand's Bootstrap Sass vars
204+
# 3. Gray scale variables from Brand fg/bg or black/white
205+
# 4. Fallback vars needed by additional Brand rules
206+
207+
self._add_sass_ensure_variables()
208+
self._add_sass_brand_grays()
209+
self.add_defaults(**brand_bootstrap.defaults)
210+
self.add_defaults(**sass_vars_colors, **sass_vars_typography)
211+
# Brand Rules ----
212+
self.add_rules(":root {", *css_vars_colors, "}")
213+
self._add_sass_brand_rules()
214+
215+
def _prepare_color_vars(self) -> tuple[dict[str, str], list[str]]:
216+
if not self.brand.color:
217+
return {}, []
218+
195219
sass_vars_colors: dict[str, str] = {}
196220
sass_vars_brand_colors: dict[str, str] = {}
197221
css_vars_brand_colors: list[str] = []
198222

199-
if brand.color:
200-
# Map values in colors to their Sass variable counterparts
201-
for thm_name, thm_color in brand.color.to_dict(include="theme").items():
202-
if thm_name not in color_map:
203-
self._handle_unmapped_variable(f"color.{thm_name}")
204-
continue
223+
# Map values in colors to their Sass variable counterparts
224+
for thm_name, thm_color in self.brand.color.to_dict(include="theme").items():
225+
if thm_name not in color_map:
226+
self._handle_unmapped_variable(f"color.{thm_name}")
227+
continue
205228

206-
for sass_var in color_map[thm_name]:
207-
sass_vars_colors[sass_var] = thm_color
229+
for sass_var in color_map[thm_name]:
230+
sass_vars_colors[sass_var] = thm_color
208231

209-
brand_color_palette = brand.color.to_dict(include="palette")
232+
brand_color_palette = self.brand.color.to_dict(include="palette")
210233

211-
# Map the brand color palette to Bootstrap's named colors, e.g. $red, $blue.
212-
for pal_name, pal_color in brand_color_palette.items():
213-
if pal_name in bootstrap_colors:
214-
sass_vars_colors[pal_name] = pal_color
234+
# Map the brand color palette to Bootstrap's named colors, e.g. $red, $blue.
235+
for pal_name, pal_color in brand_color_palette.items():
236+
if pal_name in bootstrap_colors:
237+
sass_vars_colors[pal_name] = pal_color
215238

216-
# Create Sass and CSS variables for the brand color palette
217-
color_var = sanitize_sass_var_name(pal_name)
239+
# Create Sass and CSS variables for the brand color palette
240+
color_var = sanitize_sass_var_name(pal_name)
218241

219-
# => Sass var: `$brand-{name}: {value}`
220-
sass_vars_brand_colors.update({f"brand-{color_var}": pal_color})
221-
# => CSS var: `--brand-{name}: {value}`
222-
css_vars_brand_colors.append(f"--brand-{color_var}: {pal_color};")
242+
# => Sass var: `$brand-{name}: {value}`
243+
sass_vars_brand_colors.update({f"brand-{color_var}": pal_color})
244+
# => CSS var: `--brand-{name}: {value}`
245+
css_vars_brand_colors.append(f"--brand-{color_var}: {pal_color};")
223246

224-
# brand.typography ------------------------------------------------------------
247+
return {**sass_vars_brand_colors, **sass_vars_colors}, css_vars_brand_colors
248+
249+
def _prepare_typography_vars(self) -> dict[str, str]:
225250
sass_vars_typography: dict[str, str] = {}
226-
if brand.typography:
227-
brand_typography = brand.typography.model_dump(
228-
exclude={"fonts"},
229-
exclude_none=True,
230-
)
231251

232-
for typ_field, typ_value in brand_typography.items():
233-
if typ_field not in typography_map:
234-
self._handle_unmapped_variable(f"typography.{typ_field}")
235-
continue
236-
237-
for typ_field_key, typ_field_value in typ_value.items():
238-
if typ_field_key in typography_map[typ_field]:
239-
if typ_field == "base" and typ_field_key == "size":
240-
typ_field_value = str(
241-
maybe_convert_font_size_to_rem(typ_field_value)
242-
)
243-
244-
typo_sass_vars = typography_map[typ_field][typ_field_key]
245-
for typo_sass_var in typo_sass_vars:
246-
sass_vars_typography[typo_sass_var] = typ_field_value
247-
else:
248-
self._handle_unmapped_variable(
249-
f"typography.{typ_field}.{typ_field_key}"
252+
if not self.brand.typography:
253+
return sass_vars_typography
254+
255+
brand_typography = self.brand.typography.model_dump(
256+
exclude={"fonts"},
257+
exclude_none=True,
258+
)
259+
260+
for typ_field, typ_value in brand_typography.items():
261+
if typ_field not in typography_map:
262+
self._handle_unmapped_variable(f"typography.{typ_field}")
263+
continue
264+
265+
for typ_field_key, typ_field_value in typ_value.items():
266+
if typ_field_key in typography_map[typ_field]:
267+
if typ_field == "base" and typ_field_key == "size":
268+
typ_field_value = str(
269+
maybe_convert_font_size_to_rem(typ_field_value)
250270
)
251271

252-
# Theme -----------------------------------------------------------------------
253-
sass_vars_brand: dict[str, str] = {
254-
**sass_vars_brand_colors,
255-
**sass_vars_colors,
256-
**sass_vars_typography,
257-
}
258-
sass_vars_brand = {k: v for k, v in sass_vars_brand.items()}
272+
typo_sass_vars = typography_map[typ_field][typ_field_key]
273+
for typo_sass_var in typo_sass_vars:
274+
sass_vars_typography[typo_sass_var] = typ_field_value
275+
else:
276+
self._handle_unmapped_variable(
277+
f"typography.{typ_field}.{typ_field_key}"
278+
)
259279

260-
# Defaults are added in reverse order, so each chunk appears above the next
261-
# layer of defaults. The intended order in the final output is:
262-
# 1. Brand Sass vars (colors, typography)
263-
# 2. Brand Bootstrap Sass vars
264-
# 3. Fallback vars needed by additional Brand rules
280+
return sass_vars_typography
281+
282+
def _add_sass_ensure_variables(self):
283+
"""Ensure the variables we create to augment Bootstrap's variables exist"""
265284
self.add_defaults(
266-
# Variables we create to augment Bootstrap's variables
267285
**{
268286
"code-font-weight": None,
269287
"code-inline-font-weight": None,
@@ -275,6 +293,12 @@ def __init__(
275293
"link-weight": None,
276294
}
277295
)
296+
297+
def _add_sass_brand_grays(self):
298+
"""
299+
Adds functions and defaults to handle creating a gray scale palette from the
300+
brand color palette, or the brand's foreground/background colors.
301+
"""
278302
self.add_functions(
279303
"""
280304
@function brand-choose-white-black($foreground, $background) {
@@ -348,11 +372,9 @@ def __init__(
348372
}
349373
"""
350374
)
351-
self.add_defaults(**brand_bootstrap.defaults)
352-
self.add_defaults(**sass_vars_brand)
353-
# Brand Rules ----
354-
self.add_rules(":root {", *css_vars_brand_colors, "}")
355-
# Additional rules to fill in Bootstrap styles for Brand parameters
375+
376+
def _add_sass_brand_rules(self):
377+
"""Additional rules to fill in Bootstrap styles for Brand parameters"""
356378
self.add_rules(
357379
"""
358380
// https://github.com/twbs/bootstrap/blob/5c2f2e7e/scss/_root.scss#L82

0 commit comments

Comments
 (0)