11from __future__ import annotations
22
33import numbers
4+ import typing
45from typing import Callable , Optional
56
67from htmltools import Tag , TagAttrs , TagAttrValue , TagChild , css , div
1011from ._css import CssUnit , validate_css_unit
1112from ._fill import bind_fill_role
1213from ._layout import layout_column_wrap
13- from ._utils import is_01_scalar
14+ from ._utils import consolidate_attrs , is_01_scalar
1415
1516
1617# It seems to be to use % over fr here since there is no gap on the grid
@@ -39,9 +40,11 @@ def value_box(
3940 height : Optional [CssUnit ] = None ,
4041 max_height : Optional [CssUnit ] = None ,
4142 fill : bool = True ,
42- class_ : Optional [str ] = None , # Applies after `bind_fill_role()` inside `card()`
43+ class_ : Optional [str ] = None ,
4344 ** kwargs : TagAttrValue ,
4445) -> Tag :
46+ attrs , children = consolidate_attrs (* args , ** kwargs )
47+
4548 if showcase_layout is None :
4649 showcase_layout = showcase_left_center ()
4750 if isinstance (title , str ) or isinstance (title , numbers .Number ):
@@ -52,7 +55,7 @@ def value_box(
5255 contents = div (
5356 title ,
5457 value ,
55- * args ,
58+ * children ,
5659 class_ = "value-box-area" ,
5760 )
5861 contents = bind_fill_role (contents , container = True , item = True )
@@ -66,12 +69,17 @@ def value_box(
6669
6770 return card (
6871 contents ,
72+ # Must be before `attrs` so that `class_` is applied before any `attrs` values
73+ {"class" : f"bslib-value-box border-0{ theme_class_str } " },
74+ # TODO-barret: Why is `TagAttrDict` not accepted here as a `TagAttrs` object?
75+ # TagAttrDict: Dict[str, str]
76+ # TagAttrs: Dict[str, str | float | bool | None]
77+ typing .cast (TagAttrs , attrs ),
6978 class_ = f"bslib-value-box border-0{ theme_class_str } { class_str } " ,
7079 full_screen = full_screen ,
7180 height = height ,
7281 max_height = max_height ,
7382 fill = fill ,
74- ** kwargs ,
7583 )
7684
7785
0 commit comments