stat

Stat is used to show numbers and data in a block.

Base Stat Components

The base stat components:

Exported source
stats = SingleValueFactory("stats", "Container of multiple stat items") # Stats container
stat = SingleValueFactory("stat", "A block to display stat data about a topic") # Stat block
stat_title = SingleValueFactory("stat-title", "Title part of a stat") # Stat title
stat_value = SingleValueFactory("stat-value", "Value part of a stat") # Stat value
stat_desc = SingleValueFactory("stat-desc", "Description part of a stat") # Stat description
stat_figure = SingleValueFactory("stat-figure", "Figure part for icon, etc") # Stat figure
stat_actions = SingleValueFactory("stat-actions", "Actions part for button, etc") # Stat actions

Stat Direction

Stat direction modifiers:

Exported source
stats_direction = SimpleFactory(
    {
        "horizontal": "stats-horizontal",
        "vertical": "stats-vertical"
    },
    "Stats direction modifiers (horizontal is default)"
) # Stats direction

Stat Test Examples


source

test_stat_basic_examples

 test_stat_basic_examples ()

Test basic stat utilities.

Exported source
def test_stat_basic_examples():
    """Test basic stat utilities."""
    # Basic components
    assert str(stats) == "stats"
    assert str(stat) == "stat"
    assert str(stat_title) == "stat-title"
    assert str(stat_value) == "stat-value"
    assert str(stat_desc) == "stat-desc"
    assert str(stat_figure) == "stat-figure"
    assert str(stat_actions) == "stat-actions"
    
    # With modifiers
    assert str(stats.hover) == "hover:stats"
    assert str(stat.md) == "md:stat"
    assert str(stat_value.dark) == "dark:stat-value"

# Run the tests
test_stat_basic_examples()

source

test_stat_direction_examples

 test_stat_direction_examples ()

Test stat direction modifiers.

Exported source
def test_stat_direction_examples():
    """Test stat direction modifiers."""
    assert str(stats_direction.horizontal) == "stats-horizontal"
    assert str(stats_direction.vertical) == "stats-vertical"
    
    # With responsive modifiers
    assert str(stats_direction.vertical.lg) == "lg:stats-vertical"

# Run the tests
test_stat_direction_examples()

source

test_stat_basic_fasthtml_examples

 test_stat_basic_fasthtml_examples ()

Test basic stat examples from daisyUI v5 documentation.

Exported source
def test_stat_basic_fasthtml_examples():
    """Test basic stat examples from daisyUI v5 documentation."""
    from fasthtml.common import Div
    from cjm_fasthtml_tailwind.core.base import combine_classes
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    
    # Basic stat
    basic_stat = Div(
        Div(
            Div("Total Page Views", cls=str(stat_title)),
            Div("89,400", cls=str(stat_value)),
            Div("21% more than last month", cls=str(stat_desc)),
            cls=str(stat)
        ),
        cls=combine_classes(str(stats), shadow())
    )
    
    # Verify structure
    assert basic_stat.tag == "div"
    assert "stats" in basic_stat.attrs['class']
    assert "shadow" in basic_stat.attrs['class']
    
    # Check stat container
    stat_container = basic_stat.children[0]
    assert stat_container.tag == "div"
    assert "stat" in stat_container.attrs['class']
    assert len(stat_container.children) == 3
    
    # Check stat title
    title = stat_container.children[0]
    assert title.tag == "div"
    assert "stat-title" in title.attrs['class']
    assert title.children[0] == "Total Page Views"
    
    # Check stat value
    value = stat_container.children[1]
    assert value.tag == "div"
    assert "stat-value" in value.attrs['class']
    assert value.children[0] == "89,400"
    
    # Check stat desc
    desc = stat_container.children[2]
    assert desc.tag == "div"
    assert "stat-desc" in desc.attrs['class']
    assert desc.children[0] == "21% more than last month"
    
    # Return the created element
    return Div(basic_stat)

# Run the test
test_stat_basic_fasthtml_examples()
<div>
  <div class="stats shadow">
    <div class="stat">
      <div class="stat-title">Total Page Views</div>
      <div class="stat-value">89,400</div>
      <div class="stat-desc">21% more than last month</div>
    </div>
  </div>
</div>
test_func = test_stat_basic_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_stat_with_icons_fasthtml_examples

 test_stat_with_icons_fasthtml_examples ()

Test stat with icons or image examples from daisyUI v5 documentation.

Exported source
def test_stat_with_icons_fasthtml_examples():
    """Test stat with icons or image examples from daisyUI v5 documentation."""
    from fasthtml.common import Div, Img
    from fasthtml.svg import Svg, Path
    from cjm_fasthtml_tailwind.utilities.borders import rounded
    from cjm_fasthtml_tailwind.utilities.sizing import w, h
    from cjm_fasthtml_tailwind.utilities.layout import display_tw
    from cjm_fasthtml_tailwind.utilities.svg import stroke
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.core.base import combine_classes
    from cjm_fasthtml_daisyui.utilities.semantic_colors import text_dui
    from cjm_fasthtml_daisyui.components.data_display.avatar import avatar, avatar_modifiers
    
    # Define reusable SVG icons
    heart_icon = Svg(
        Path(
            d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z",
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2"
        ),
        xmlns="http://www.w3.org/2000/svg",
        fill="none",
        viewBox="0 0 24 24",
        cls=combine_classes(display_tw.inline_block, h(8), w(8), stroke.current)
    )
    
    lightning_icon = Svg(
        Path(
            d="M13 10V3L4 14h7v7l9-11h-7z",
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2"
        ),
        xmlns="http://www.w3.org/2000/svg",
        fill="none",
        viewBox="0 0 24 24",
        cls=combine_classes(display_tw.inline_block, h(8), w(8), stroke.current)
    )
    
    # Stats container with icons
    stats_with_icons = Div(
        # First stat - Total Likes
        Div(
            Div(
                heart_icon,
                cls=combine_classes(stat_figure, text_dui.primary)
            ),
            Div("Total Likes", cls=str(stat_title)),
            Div("25.6K", cls=combine_classes(stat_value, text_dui.primary)),
            Div("21% more than last month", cls=str(stat_desc)),
            cls=str(stat)
        ),
        # Second stat - Page Views
        Div(
            Div(
                lightning_icon,
                cls=combine_classes(stat_figure, text_dui.secondary)
            ),
            Div("Page Views", cls=str(stat_title)),
            Div("2.6M", cls=combine_classes(stat_value, text_dui.secondary)),
            Div("21% more than last month", cls=str(stat_desc)),
            cls=stat
        ),
        # Third stat - Tasks done with avatar
        Div(
            Div(
                Div(
                    Div(
                        Img(src="https://img.daisyui.com/images/profile/demo/anakeen@192.webp"),
                        cls=combine_classes(w(16), rounded.full)
                    ),
                    cls=combine_classes(avatar, avatar_modifiers.online)
                ),
                cls=combine_classes(stat_figure, text_dui.secondary)
            ),
            Div("86%", cls=str(stat_value)),
            Div("Tasks done", cls=str(stat_title)),
            Div("31 tasks remaining", cls=combine_classes(stat_desc, text_dui.secondary)),
            cls=str(stat)
        ),
        cls=combine_classes(stats, shadow())
    )
    
    # Verify structure
    assert stats_with_icons.tag == "div"
    assert "stats" in stats_with_icons.attrs['class']
    assert "shadow" in stats_with_icons.attrs['class']
    assert len(stats_with_icons.children) == 3
    
    # Check first stat (Total Likes)
    first_stat = stats_with_icons.children[0]
    assert "stat" in first_stat.attrs['class']
    assert len(first_stat.children) == 4
    
    # Check stat figure with heart icon
    figure1 = first_stat.children[0]
    assert "stat-figure" in figure1.attrs['class']
    assert "text-primary" in figure1.attrs['class']
    assert figure1.children[0].tag == "svg"
    
    # Check primary colored value
    value1 = first_stat.children[2]
    assert "stat-value" in value1.attrs['class']
    assert "text-primary" in value1.attrs['class']
    assert value1.children[0] == "25.6K"
    
    # Check third stat (with avatar)
    third_stat = stats_with_icons.children[2]
    assert "stat" in third_stat.attrs['class']
    
    # Check avatar structure
    avatar_figure = third_stat.children[0]
    assert "stat-figure" in avatar_figure.attrs['class']
    avatar_container = avatar_figure.children[0]
    assert "avatar" in avatar_container.attrs['class']
    assert "avatar-online" in avatar_container.attrs['class']
    
    # Check image
    img_container = avatar_container.children[0]
    assert "w-16" in img_container.attrs['class']
    assert "rounded-full" in img_container.attrs['class']
    img = img_container.children[0]
    assert img.tag == "img"
    assert img.attrs['src'] == "https://img.daisyui.com/images/profile/demo/anakeen@192.webp"
    
    # Check order of value and title (reversed in this stat)
    assert third_stat.children[1].children[0] == "86%"
    assert "stat-value" in third_stat.children[1].attrs['class']
    assert third_stat.children[2].children[0] == "Tasks done"
    assert "stat-title" in third_stat.children[2].attrs['class']
    
    # Return the created element
    return Div(stats_with_icons)

# Run the test
test_stat_with_icons_fasthtml_examples()
<div>
  <div class="stats shadow">
    <div class="stat">
      <div class="stat-figure text-primary">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" class="inline-block h-8 w-8 stroke-current"><path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>      </div>
      <div class="stat-title">Total Likes</div>
      <div class="stat-value text-primary">25.6K</div>
      <div class="stat-desc">21% more than last month</div>
    </div>
    <div class="stat">
      <div class="stat-figure text-secondary">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" class="inline-block h-8 w-8 stroke-current"><path d="M13 10V3L4 14h7v7l9-11h-7z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>      </div>
      <div class="stat-title">Page Views</div>
      <div class="stat-value text-secondary">2.6M</div>
      <div class="stat-desc">21% more than last month</div>
    </div>
    <div class="stat">
      <div class="stat-figure text-secondary">
        <div class="avatar avatar-online">
          <div class="w-16 rounded-full">
<img src="https://img.daisyui.com/images/profile/demo/anakeen@192.webp">          </div>
        </div>
      </div>
      <div class="stat-value">86%</div>
      <div class="stat-title">Tasks done</div>
      <div class="stat-desc text-secondary">31 tasks remaining</div>
    </div>
  </div>
</div>
test_func = test_stat_with_icons_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_stat_detailed_fasthtml_examples

 test_stat_detailed_fasthtml_examples ()

Test detailed stat examples with different icons from daisyUI v5 documentation.

Exported source
def test_stat_detailed_fasthtml_examples():
    """Test detailed stat examples with different icons from daisyUI v5 documentation."""
    from fasthtml.common import Div
    from fasthtml.svg import Svg, Path
    from cjm_fasthtml_tailwind.utilities.sizing import w, h
    from cjm_fasthtml_tailwind.utilities.layout import display_tw
    from cjm_fasthtml_tailwind.utilities.svg import stroke
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.core.base import combine_classes
    from cjm_fasthtml_daisyui.utilities.semantic_colors import text_dui
    
    # Define reusable SVG icons
    info_icon = Svg(
        Path(
            d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z",
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2"
        ),
        xmlns="http://www.w3.org/2000/svg",
        fill="none",
        viewBox="0 0 24 24",
        cls=combine_classes(display_tw.inline_block, h(8), w(8), stroke.current)
    )
    
    settings_icon = Svg(
        Path(
            d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4",
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2"
        ),
        xmlns="http://www.w3.org/2000/svg",
        fill="none",
        viewBox="0 0 24 24",
        cls=combine_classes(display_tw.inline_block, h(8), w(8), stroke.current)
    )
    
    archive_icon = Svg(
        Path(
            d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4",
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2"
        ),
        xmlns="http://www.w3.org/2000/svg",
        fill="none",
        viewBox="0 0 24 24",
        cls=combine_classes(display_tw.inline_block, h(8), w(8), stroke.current)
    )
    
    # Stats container with detailed information
    detailed_stats = Div(
        # Downloads stat
        Div(
            Div(
                info_icon,
                cls=combine_classes(stat_figure, text_dui.secondary)
            ),
            Div("Downloads", cls=str(stat_title)),
            Div("31K", cls=str(stat_value)),
            Div("Jan 1st - Feb 1st", cls=str(stat_desc)),
            cls=str(stat)
        ),
        # New Users stat
        Div(
            Div(
                settings_icon,
                cls=combine_classes(stat_figure, text_dui.secondary)
            ),
            Div("New Users", cls=str(stat_title)),
            Div("4,200", cls=str(stat_value)),
            Div("↗︎ 400 (22%)", cls=str(stat_desc)),
            cls=str(stat)
        ),
        # New Registers stat
        Div(
            Div(
                archive_icon,
                cls=combine_classes(stat_figure, text_dui.secondary)
            ),
            Div("New Registers", cls=str(stat_title)),
            Div("1,200", cls=str(stat_value)),
            Div("↘︎ 90 (14%)", cls=str(stat_desc)),
            cls=str(stat)
        ),
        cls=combine_classes(stats, shadow())
    )
    
    # Verify structure
    assert detailed_stats.tag == "div"
    assert "stats" in detailed_stats.attrs['class']
    assert "shadow" in detailed_stats.attrs['class']
    assert len(detailed_stats.children) == 3
    
    # Check each stat has the correct structure
    for i, (expected_title, expected_value, expected_desc) in enumerate([
        ("Downloads", "31K", "Jan 1st - Feb 1st"),
        ("New Users", "4,200", "↗︎ 400 (22%)"),
        ("New Registers", "1,200", "↘︎ 90 (14%)")
    ]):
        stat_elem = detailed_stats.children[i]
        assert "stat" in stat_elem.attrs['class']
        assert len(stat_elem.children) == 4
        
        # Check figure
        figure = stat_elem.children[0]
        assert "stat-figure" in figure.attrs['class']
        assert "text-secondary" in figure.attrs['class']
        assert figure.children[0].tag == "svg"
        
        # Check title
        title = stat_elem.children[1]
        assert "stat-title" in title.attrs['class']
        assert title.children[0] == expected_title
        
        # Check value
        value = stat_elem.children[2]
        assert "stat-value" in value.attrs['class']
        assert value.children[0] == expected_value
        
        # Check desc
        desc = stat_elem.children[3]
        assert "stat-desc" in desc.attrs['class']
        assert desc.children[0] == expected_desc
    
    # Return the created element
    return Div(detailed_stats)

# Run the test
test_stat_detailed_fasthtml_examples()
<div>
  <div class="stats shadow">
    <div class="stat">
      <div class="stat-figure text-secondary">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" class="inline-block h-8 w-8 stroke-current"><path d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>      </div>
      <div class="stat-title">Downloads</div>
      <div class="stat-value">31K</div>
      <div class="stat-desc">Jan 1st - Feb 1st</div>
    </div>
    <div class="stat">
      <div class="stat-figure text-secondary">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" class="inline-block h-8 w-8 stroke-current"><path d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>      </div>
      <div class="stat-title">New Users</div>
      <div class="stat-value">4,200</div>
      <div class="stat-desc">↗︎ 400 (22%)</div>
    </div>
    <div class="stat">
      <div class="stat-figure text-secondary">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" class="inline-block h-8 w-8 stroke-current"><path d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>      </div>
      <div class="stat-title">New Registers</div>
      <div class="stat-value">1,200</div>
      <div class="stat-desc">↘︎ 90 (14%)</div>
    </div>
  </div>
</div>
test_func = test_stat_detailed_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_stat_centered_fasthtml_examples

 test_stat_centered_fasthtml_examples ()

Test centered stat items examples from daisyUI v5 documentation.

Exported source
def test_stat_centered_fasthtml_examples():
    """Test centered stat items examples from daisyUI v5 documentation."""
    from fasthtml.common import Div
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import place_items
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.core.base import combine_classes
    from cjm_fasthtml_daisyui.utilities.semantic_colors import text_dui
    
    # Centered stats
    centered_stats = Div(
        # Downloads stat
        Div(
            Div("Downloads", cls=str(stat_title)),
            Div("31K", cls=str(stat_value)),
            Div("From January 1st to February 1st", cls=str(stat_desc)),
            cls=combine_classes(stat, place_items.center)
        ),
        # Users stat
        Div(
            Div("Users", cls=str(stat_title)),
            Div("4,200", cls=combine_classes(stat_value, text_dui.secondary)),
            Div("↗︎ 40 (2%)", cls=combine_classes(stat_desc, text_dui.secondary)),
            cls=combine_classes(stat, place_items.center)
        ),
        # New Registers stat
        Div(
            Div("New Registers", cls=str(stat_title)),
            Div("1,200", cls=str(stat_value)),
            Div("↘︎ 90 (14%)", cls=str(stat_desc)),
            cls=combine_classes(stat, place_items.center)
        ),
        cls=combine_classes(stats, shadow())
    )
    
    # Verify structure
    assert centered_stats.tag == "div"
    assert "stats" in centered_stats.attrs['class']
    assert "shadow" in centered_stats.attrs['class']
    assert len(centered_stats.children) == 3
    
    # Check first stat (Downloads)
    first_stat = centered_stats.children[0]
    assert "stat" in first_stat.attrs['class']
    assert "place-items-center" in first_stat.attrs['class']
    assert len(first_stat.children) == 3
    
    # Check elements order and content
    assert first_stat.children[0].children[0] == "Downloads"
    assert "stat-title" in first_stat.children[0].attrs['class']
    assert first_stat.children[1].children[0] == "31K"
    assert "stat-value" in first_stat.children[1].attrs['class']
    assert first_stat.children[2].children[0] == "From January 1st to February 1st"
    assert "stat-desc" in first_stat.children[2].attrs['class']
    
    # Check second stat (Users) with secondary color
    second_stat = centered_stats.children[1]
    assert "stat" in second_stat.attrs['class']
    assert "place-items-center" in second_stat.attrs['class']
    
    # Check secondary colored value and desc
    value = second_stat.children[1]
    assert "stat-value" in value.attrs['class']
    assert "text-secondary" in value.attrs['class']
    assert value.children[0] == "4,200"
    
    desc = second_stat.children[2]
    assert "stat-desc" in desc.attrs['class']
    assert "text-secondary" in desc.attrs['class']
    assert desc.children[0] == "↗︎ 40 (2%)"
    
    # Check third stat
    third_stat = centered_stats.children[2]
    assert "stat" in third_stat.attrs['class']
    assert "place-items-center" in third_stat.attrs['class']
    assert third_stat.children[1].children[0] == "1,200"
    assert third_stat.children[2].children[0] == "↘︎ 90 (14%)"
    
    # Return the created element
    return Div(centered_stats)

# Run the test
test_stat_centered_fasthtml_examples()
<div>
  <div class="stats shadow">
    <div class="stat place-items-center">
      <div class="stat-title">Downloads</div>
      <div class="stat-value">31K</div>
      <div class="stat-desc">From January 1st to February 1st</div>
    </div>
    <div class="stat place-items-center">
      <div class="stat-title">Users</div>
      <div class="stat-value text-secondary">4,200</div>
      <div class="stat-desc text-secondary">↗︎ 40 (2%)</div>
    </div>
    <div class="stat place-items-center">
      <div class="stat-title">New Registers</div>
      <div class="stat-value">1,200</div>
      <div class="stat-desc">↘︎ 90 (14%)</div>
    </div>
  </div>
</div>
test_func = test_stat_centered_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_stat_vertical_fasthtml_examples

 test_stat_vertical_fasthtml_examples ()

Test vertical and responsive stat examples from daisyUI v5 documentation.

Exported source
def test_stat_vertical_fasthtml_examples():
    """Test vertical and responsive stat examples from daisyUI v5 documentation."""
    from fasthtml.common import Div
    from cjm_fasthtml_tailwind.core.base import combine_classes
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    
    # Vertical stats
    vertical_stats = Div(
        Div(
            Div("Downloads", cls=str(stat_title)),
            Div("31K", cls=str(stat_value)),
            Div("Jan 1st - Feb 1st", cls=str(stat_desc)),
            cls=str(stat)
        ),
        Div(
            Div("New Users", cls=str(stat_title)),
            Div("4,200", cls=str(stat_value)),
            Div("↗︎ 400 (22%)", cls=str(stat_desc)),
            cls=str(stat)
        ),
        Div(
            Div("New Registers", cls=str(stat_title)),
            Div("1,200", cls=str(stat_value)),
            Div("↘︎ 90 (14%)", cls=str(stat_desc)),
            cls=str(stat)
        ),
        cls=combine_classes(stats, stats_direction.vertical, shadow())
    )
    
    # Verify vertical stats
    assert vertical_stats.tag == "div"
    assert "stats" in vertical_stats.attrs['class']
    assert "stats-vertical" in vertical_stats.attrs['class']
    assert "shadow" in vertical_stats.attrs['class']
    assert len(vertical_stats.children) == 3
    
    # Check stat content
    for i, (expected_title, expected_value, expected_desc) in enumerate([
        ("Downloads", "31K", "Jan 1st - Feb 1st"),
        ("New Users", "4,200", "↗︎ 400 (22%)"),
        ("New Registers", "1,200", "↘︎ 90 (14%)")
    ]):
        stat_elem = vertical_stats.children[i]
        assert "stat" in stat_elem.attrs['class']
        assert stat_elem.children[0].children[0] == expected_title
        assert stat_elem.children[1].children[0] == expected_value
        assert stat_elem.children[2].children[0] == expected_desc
    
    # Responsive stats (vertical on small, horizontal on large)
    responsive_stats = Div(
        Div(
            Div("Downloads", cls=stat_title),
            Div("31K", cls=stat_value),
            Div("Jan 1st - Feb 1st", cls=stat_desc),
            cls=stat
        ),
        Div(
            Div("New Users", cls=stat_title),
            Div("4,200", cls=stat_value),
            Div("↗︎ 400 (22%)", cls=stat_desc),
            cls=stat
        ),
        Div(
            Div("New Registers", cls=stat_title),
            Div("1,200", cls=stat_value),
            Div("↘︎ 90 (14%)", cls=stat_desc),
            cls=stat
        ),
        cls=combine_classes(stats, stats_direction.vertical, stats_direction.horizontal.lg, shadow())
    )
    
    # Verify responsive stats
    assert responsive_stats.tag == "div"
    assert "stats" in responsive_stats.attrs['class']
    assert "stats-vertical" in responsive_stats.attrs['class']
    assert "lg:stats-horizontal" in responsive_stats.attrs['class']
    assert "shadow" in responsive_stats.attrs['class']
    assert len(responsive_stats.children) == 3
    
    # Return both examples in a container
    return Div(
        vertical_stats,
        responsive_stats
    )

# Run the test
test_stat_vertical_fasthtml_examples()
<div>
  <div class="stats stats-vertical shadow">
    <div class="stat">
      <div class="stat-title">Downloads</div>
      <div class="stat-value">31K</div>
      <div class="stat-desc">Jan 1st - Feb 1st</div>
    </div>
    <div class="stat">
      <div class="stat-title">New Users</div>
      <div class="stat-value">4,200</div>
      <div class="stat-desc">↗︎ 400 (22%)</div>
    </div>
    <div class="stat">
      <div class="stat-title">New Registers</div>
      <div class="stat-value">1,200</div>
      <div class="stat-desc">↘︎ 90 (14%)</div>
    </div>
  </div>
  <div class="stats stats-vertical lg:stats-horizontal shadow">
    <div class="stat">
      <div class="stat-title">Downloads</div>
      <div class="stat-value">31K</div>
      <div class="stat-desc">Jan 1st - Feb 1st</div>
    </div>
    <div class="stat">
      <div class="stat-title">New Users</div>
      <div class="stat-value">4,200</div>
      <div class="stat-desc">↗︎ 400 (22%)</div>
    </div>
    <div class="stat">
      <div class="stat-title">New Registers</div>
      <div class="stat-value">1,200</div>
      <div class="stat-desc">↘︎ 90 (14%)</div>
    </div>
  </div>
</div>
test_func = test_stat_vertical_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_stat_with_actions_fasthtml_examples

 test_stat_with_actions_fasthtml_examples ()

Test stat with custom colors and button actions from daisyUI v5 documentation.

Exported source
def test_stat_with_actions_fasthtml_examples():
    """Test stat with custom colors and button actions from daisyUI v5 documentation."""
    from fasthtml.common import Div, Button
    from cjm_fasthtml_tailwind.core.base import combine_classes
    from cjm_fasthtml_tailwind.utilities.borders import border
    from cjm_fasthtml_daisyui.components.actions.button import btn, btn_sizes, btn_colors
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui, border_dui
    
    # Stats with custom colors and buttons
    stats_with_actions = Div(
        # Account balance with single button
        Div(
            Div("Account balance", cls=str(stat_title)),
            Div("$89,400", cls=str(stat_value)),
            Div(
                Button("Add funds", cls=combine_classes(btn, btn_sizes.xs, btn_colors.success)),
                cls=str(stat_actions)
            ),
            cls=str(stat)
        ),
        # Current balance with multiple buttons
        Div(
            Div("Current balance", cls=str(stat_title)),
            Div("$89,400", cls=(stat_value)),
            Div(
                Button("Withdrawal", cls=combine_classes(btn, btn_sizes.xs)),
                Button("Deposit", cls=combine_classes(btn, btn_sizes.xs)),
                cls=str(stat_actions)
            ),
            cls=str(stat)
        ),
        cls=combine_classes(stats, bg_dui.base_100, border_dui.base_300, border())
    )
    
    # Verify structure
    assert stats_with_actions.tag == "div"
    assert "stats" in stats_with_actions.attrs['class']
    assert "bg-base-100" in stats_with_actions.attrs['class']
    assert "border-base-300" in stats_with_actions.attrs['class']
    assert "border" in stats_with_actions.attrs['class']
    assert len(stats_with_actions.children) == 2
    
    # Check first stat (Account balance)
    first_stat = stats_with_actions.children[0]
    assert "stat" in first_stat.attrs['class']
    assert len(first_stat.children) == 3
    
    # Check title and value
    assert first_stat.children[0].children[0] == "Account balance"
    assert "stat-title" in first_stat.children[0].attrs['class']
    assert first_stat.children[1].children[0] == "$89,400"
    assert "stat-value" in first_stat.children[1].attrs['class']
    
    # Check actions with single button
    actions1 = first_stat.children[2]
    assert "stat-actions" in actions1.attrs['class']
    assert len(actions1.children) == 1
    button1 = actions1.children[0]
    assert button1.tag == "button"
    assert "btn" in button1.attrs['class']
    assert "btn-xs" in button1.attrs['class']
    assert "btn-success" in button1.attrs['class']
    assert button1.children[0] == "Add funds"
    
    # Check second stat (Current balance)
    second_stat = stats_with_actions.children[1]
    assert "stat" in second_stat.attrs['class']
    assert len(second_stat.children) == 3
    
    # Check actions with multiple buttons
    actions2 = second_stat.children[2]
    assert "stat-actions" in actions2.attrs['class']
    assert len(actions2.children) == 2
    
    # Check both buttons
    withdrawal_btn = actions2.children[0]
    assert withdrawal_btn.tag == "button"
    assert "btn" in withdrawal_btn.attrs['class']
    assert "btn-xs" in withdrawal_btn.attrs['class']
    assert withdrawal_btn.children[0] == "Withdrawal"
    
    deposit_btn = actions2.children[1]
    assert deposit_btn.tag == "button"
    assert "btn" in deposit_btn.attrs['class']
    assert "btn-xs" in deposit_btn.attrs['class']
    assert deposit_btn.children[0] == "Deposit"
    
    # Return the created element
    return Div(stats_with_actions)

# Run the test
test_stat_with_actions_fasthtml_examples()
<div>
  <div class="stats bg-base-100 border-base-300 border">
    <div class="stat">
      <div class="stat-title">Account balance</div>
      <div class="stat-value">$89,400</div>
      <div class="stat-actions">
<button class="btn btn-xs btn-success">Add funds</button>      </div>
    </div>
    <div class="stat">
      <div class="stat-title">Current balance</div>
      <div class="stat-value">$89,400</div>
      <div class="stat-actions">
<button class="btn btn-xs">Withdrawal</button><button class="btn btn-xs">Deposit</button>      </div>
    </div>
  </div>
</div>
test_func = test_stat_with_actions_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()