countdown

Countdown gives you a transition effect when you change a number between 0 to 99.

Base Countdown

The base countdown component:

Exported source
countdown = SingleValueFactory("countdown", "Countdown wrapper component for transition effect") # Countdown wrapper

Countdown Test Examples


source

test_countdown_basic_examples

 test_countdown_basic_examples ()

Test basic countdown utilities.

Exported source
def test_countdown_basic_examples():
    """Test basic countdown utilities."""
    # Basic countdown
    assert str(countdown) == "countdown"
    
    # With modifiers
    assert str(countdown.hover) == "hover:countdown"
    assert str(countdown.md) == "md:countdown"
    assert str(countdown.dark) == "dark:countdown"

# Run the tests
test_countdown_basic_examples()

source

test_countdown_basic_fasthtml_examples

 test_countdown_basic_fasthtml_examples ()

Test basic countdown and large text from daisyUI v5 documentation.

Exported source
def test_countdown_basic_fasthtml_examples():
    """Test basic countdown and large text from daisyUI v5 documentation."""
    from fasthtml.common import Span, Div
    from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color
    
    # Basic countdown
    basic_countdown = Span(
        Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
        cls=str(countdown)
    )
    assert basic_countdown.tag == "span"
    assert basic_countdown.attrs['class'] == "countdown"
    assert len(basic_countdown.children) == 1
    inner_span = basic_countdown.children[0]
    assert inner_span.tag == "span"
    assert inner_span.attrs['style'] == "--value:59;"
    assert inner_span.attrs['aria-live'] == "polite"
    assert inner_span.attrs['aria-label'] == "59"
    assert inner_span.children[0] == "59"
    
    # Large text
    large_countdown = Span(
        Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
        cls=combine_classes(countdown, font_family.mono, font_size._6xl)
    )
    assert large_countdown.tag == "span"
    assert "countdown" in large_countdown.attrs['class']
    assert "font-mono" in large_countdown.attrs['class']
    assert "text-6xl" in large_countdown.attrs['class']
    assert large_countdown.children[0].attrs['style'] == "--value:59;"
    assert large_countdown.children[0].children[0] == "59"
    
    # Return all examples in a Div
    return Div(
        basic_countdown,
        large_countdown
    )

# Run the tests
test_countdown_basic_fasthtml_examples()
<div>
<span class="countdown"><span aria-live="polite" aria-label="59" style="--value:59;">59</span></span><span class="countdown font-mono text-6xl"><span aria-live="polite" aria-label="59" style="--value:59;">59</span></span></div>
test_func = test_countdown_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_countdown_clock_fasthtml_examples

 test_countdown_clock_fasthtml_examples ()

Test clock countdown and clock countdown with colons from daisyUI v5 documentation.

Exported source
def test_countdown_clock_fasthtml_examples():
    """Test clock countdown and clock countdown with colons from daisyUI v5 documentation."""
    from fasthtml.common import Span, Div
    from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color
    
    # Clock countdown
    clock_countdown = Span(
        Span("10", style="--value:10;", aria_live="polite", aria_label="10"),
        "h",
        Span("24", style="--value:24;", aria_live="polite", aria_label="24"),
        "m",
        Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
        "s",
        cls=combine_classes(countdown, font_family.mono, font_size._2xl)
    )
    assert clock_countdown.tag == "span"
    assert "countdown" in clock_countdown.attrs['class']
    assert "font-mono" in clock_countdown.attrs['class']
    assert "text-2xl" in clock_countdown.attrs['class']
    assert len(clock_countdown.children) == 6  # 3 spans + 3 text nodes
    # First countdown span
    assert clock_countdown.children[0].tag == "span"
    assert clock_countdown.children[0].attrs['style'] == "--value:10;"
    assert clock_countdown.children[0].children[0] == "10"
    # Text separators
    assert clock_countdown.children[1] == "h"
    assert clock_countdown.children[3] == "m"
    assert clock_countdown.children[5] == "s"
    # Other countdown spans
    assert clock_countdown.children[2].attrs['style'] == "--value:24;"
    assert clock_countdown.children[2].children[0] == "24"
    assert clock_countdown.children[4].attrs['style'] == "--value:59;"
    assert clock_countdown.children[4].children[0] == "59"
    
    # Clock countdown with colons
    clock_colons = Span(
        Span("10", style="--value:10;", aria_live="polite", aria_label="10"),
        ":",
        Span("24", style="--value:24;", aria_live="polite", aria_label="24"),
        ":",
        Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
        cls=combine_classes(countdown, font_family.mono, font_size._2xl)
    )
    assert clock_colons.tag == "span"
    assert "countdown" in clock_colons.attrs['class']
    assert "font-mono" in clock_colons.attrs['class']
    assert "text-2xl" in clock_colons.attrs['class']
    assert len(clock_colons.children) == 5  # 3 spans + 2 text nodes
    # Verify colons
    assert clock_colons.children[1] == ":"
    assert clock_colons.children[3] == ":"
    # Verify countdown values
    assert clock_colons.children[0].attrs['style'] == "--value:10;"
    assert clock_colons.children[2].attrs['style'] == "--value:24;"
    assert clock_colons.children[4].attrs['style'] == "--value:59;"
    
    # Return all examples in a Div
    return Div(
        clock_countdown,
        clock_colons
    )

# Run the tests
test_countdown_clock_fasthtml_examples()
<div>
<span class="countdown font-mono text-2xl"><span aria-live="polite" aria-label="10" style="--value:10;">10</span>h<span aria-live="polite" aria-label="24" style="--value:24;">24</span>m<span aria-live="polite" aria-label="59" style="--value:59;">59</span>s</span><span class="countdown font-mono text-2xl"><span aria-live="polite" aria-label="10" style="--value:10;">10</span>:<span aria-live="polite" aria-label="24" style="--value:24;">24</span>:<span aria-live="polite" aria-label="59" style="--value:59;">59</span></span></div>
test_func = test_countdown_clock_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_countdown_labels_fasthtml_examples

 test_countdown_labels_fasthtml_examples ()

Test large text with labels and labels under from daisyUI v5 documentation.

Exported source
def test_countdown_labels_fasthtml_examples():
    """Test large text with labels and labels under from daisyUI v5 documentation."""
    from fasthtml.common import Div, Span
    from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color, text_align
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, flex_direction, auto_cols, grid_flow, flex_display, grid_display
    from cjm_fasthtml_tailwind.utilities.layout import display_tw
    
    # Large text with labels
    labels_side = Div(
        Div(
            Span(
                Span("15", style="--value:15;", aria_live="polite", aria_label="15"),
                cls=combine_classes(countdown, font_family.mono, font_size._4xl)
            ),
            "days"
        ),
        Div(
            Span(
                Span("10", style="--value:10;", aria_live="polite", aria_label="10"),
                cls=combine_classes(countdown, font_family.mono, font_size._4xl)
            ),
            "hours"
        ),
        Div(
            Span(
                Span("24", style="--value:24;", aria_live="polite", aria_label="24"),
                cls=combine_classes(countdown, font_family.mono, font_size._4xl)
            ),
            "min"
        ),
        Div(
            Span(
                Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
                cls=combine_classes(countdown, font_family.mono, font_size._4xl)
            ),
            "sec"
        ),
        cls=combine_classes(flex_display, gap._5)
    )
    assert labels_side.tag == "div"
    assert "flex" in labels_side.attrs['class']
    assert "gap-5" in labels_side.attrs['class']
    assert len(labels_side.children) == 4
    # Check each time unit
    for i, (label_text, value) in enumerate([("days", "15"), ("hours", "10"), ("min", "24"), ("sec", "59")]):
        unit_div = labels_side.children[i]
        assert unit_div.tag == "div"
        assert len(unit_div.children) == 2
        # Check countdown span
        countdown_span = unit_div.children[0]
        assert countdown_span.tag == "span"
        assert "countdown" in countdown_span.attrs['class']
        assert "font-mono" in countdown_span.attrs['class']
        assert "text-4xl" in countdown_span.attrs['class']
        assert countdown_span.children[0].attrs['style'] == f"--value:{value};"
        assert countdown_span.children[0].children[0] == value
        # Check label text
        assert unit_div.children[1] == label_text
    
    # Large text with labels under
    labels_under = Div(
        Div(
            Span(
                Span("15", style="--value:15;", aria_live="polite", aria_label="15"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "days",
            cls=combine_classes(flex_display, flex_direction.col)
        ),
        Div(
            Span(
                Span("10", style="--value:10;", aria_live="polite", aria_label="10"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "hours",
            cls=combine_classes(flex_display, flex_direction.col)
        ),
        Div(
            Span(
                Span("24", style="--value:24;", aria_live="polite", aria_label="24"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "min",
            cls=combine_classes(flex_display, flex_direction.col)
        ),
        Div(
            Span(
                Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "sec",
            cls=combine_classes(flex_display, flex_direction.col)
        ),
        cls=combine_classes(grid_display, auto_cols.max, grid_flow.col, gap._5, text_align.center)
    )
    assert labels_under.tag == "div"
    assert "grid" in labels_under.attrs['class']
    assert "auto-cols-max" in labels_under.attrs['class']
    assert "grid-flow-col" in labels_under.attrs['class']
    assert "gap-5" in labels_under.attrs['class']
    assert "text-center" in labels_under.attrs['class']
    assert len(labels_under.children) == 4
    # Check each time unit
    for i, (label_text, value) in enumerate([("days", "15"), ("hours", "10"), ("min", "24"), ("sec", "59")]):
        unit_div = labels_under.children[i]
        assert unit_div.tag == "div"
        assert "flex" in unit_div.attrs['class']
        assert "flex-col" in unit_div.attrs['class']
        # Check countdown span (text-5xl for labels under)
        countdown_span = unit_div.children[0]
        assert "text-5xl" in countdown_span.attrs['class']
        assert countdown_span.children[0].attrs['style'] == f"--value:{value};"
        # Check label text
        assert unit_div.children[1] == label_text
    
    # Return all examples in a Div
    return Div(
        labels_side,
        labels_under
    )

# Run the tests
test_countdown_labels_fasthtml_examples()
<div>
  <div class="flex gap-5">
    <div>
<span class="countdown font-mono text-4xl"><span aria-live="polite" aria-label="15" style="--value:15;">15</span></span>days    </div>
    <div>
<span class="countdown font-mono text-4xl"><span aria-live="polite" aria-label="10" style="--value:10;">10</span></span>hours    </div>
    <div>
<span class="countdown font-mono text-4xl"><span aria-live="polite" aria-label="24" style="--value:24;">24</span></span>min    </div>
    <div>
<span class="countdown font-mono text-4xl"><span aria-live="polite" aria-label="59" style="--value:59;">59</span></span>sec    </div>
  </div>
  <div class="grid auto-cols-max grid-flow-col gap-5 text-center">
    <div class="flex flex-col">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="15" style="--value:15;">15</span></span>days    </div>
    <div class="flex flex-col">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="10" style="--value:10;">10</span></span>hours    </div>
    <div class="flex flex-col">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="24" style="--value:24;">24</span></span>min    </div>
    <div class="flex flex-col">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="59" style="--value:59;">59</span></span>sec    </div>
  </div>
</div>
test_func = test_countdown_labels_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_countdown_boxes_fasthtml_examples

 test_countdown_boxes_fasthtml_examples ()

Test countdown in boxes from daisyUI v5 documentation.

Exported source
def test_countdown_boxes_fasthtml_examples():
    """Test countdown in boxes from daisyUI v5 documentation."""
    from fasthtml.common import Div, Span
    from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color, text_align
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, flex_direction, auto_cols, grid_flow, flex_display, grid_display
    from cjm_fasthtml_tailwind.utilities.layout import display_tw
    from cjm_fasthtml_tailwind.utilities.spacing import p
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui, text_dui
    from cjm_fasthtml_daisyui.utilities.border_radius import border_radius
    
    # In boxes
    in_boxes = Div(
        Div(
            Span(
                Span("15", style="--value:15;", aria_live="polite", aria_label="15"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "days",
            cls=combine_classes(bg_dui.neutral, border_radius.box, text_dui.neutral_content, flex_display, flex_direction.col, p._2)
        ),
        Div(
            Span(
                Span("10", style="--value:10;", aria_live="polite", aria_label="10"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "hours",
            cls=combine_classes(bg_dui.neutral, border_radius.box, text_dui.neutral_content, flex_display, flex_direction.col, p._2)
        ),
        Div(
            Span(
                Span("24", style="--value:24;", aria_live="polite", aria_label="24"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "min",
            cls=combine_classes(bg_dui.neutral, border_radius.box, text_dui.neutral_content, flex_display, flex_direction.col, p._2)
        ),
        Div(
            Span(
                Span("59", style="--value:59;", aria_live="polite", aria_label="59"),
                cls=combine_classes(countdown, font_family.mono, font_size._5xl)
            ),
            "sec",
            cls=combine_classes(bg_dui.neutral, border_radius.box, text_dui.neutral_content, flex_display, flex_direction.col, p._2)
        ),
        cls=combine_classes(grid_display, auto_cols.max, grid_flow.col, gap._5, text_align.center)
    )
    assert in_boxes.tag == "div"
    assert "grid" in in_boxes.attrs['class']
    assert "auto-cols-max" in in_boxes.attrs['class']
    assert "grid-flow-col" in in_boxes.attrs['class']
    assert "gap-5" in in_boxes.attrs['class']
    assert "text-center" in in_boxes.attrs['class']
    assert len(in_boxes.children) == 4
    # Check each time unit box
    for i, (label_text, value) in enumerate([("days", "15"), ("hours", "10"), ("min", "24"), ("sec", "59")]):
        unit_div = in_boxes.children[i]
        assert unit_div.tag == "div"
        assert "bg-neutral" in unit_div.attrs['class']
        assert "rounded-box" in unit_div.attrs['class']
        assert "text-neutral-content" in unit_div.attrs['class']
        assert "flex" in unit_div.attrs['class']
        assert "flex-col" in unit_div.attrs['class']
        assert "p-2" in unit_div.attrs['class']
        # Check countdown span
        countdown_span = unit_div.children[0]
        assert "countdown" in countdown_span.attrs['class']
        assert "font-mono" in countdown_span.attrs['class']
        assert "text-5xl" in countdown_span.attrs['class']
        assert countdown_span.children[0].attrs['style'] == f"--value:{value};"
        assert countdown_span.children[0].children[0] == value
        # Check label text
        assert unit_div.children[1] == label_text
    
    # Return all examples in a Div
    return Div(
        in_boxes
    )

# Run the tests
test_countdown_boxes_fasthtml_examples()
<div>
  <div class="grid auto-cols-max grid-flow-col gap-5 text-center">
    <div class="bg-neutral rounded-box text-neutral-content flex flex-col p-2">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="15" style="--value:15;">15</span></span>days    </div>
    <div class="bg-neutral rounded-box text-neutral-content flex flex-col p-2">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="10" style="--value:10;">10</span></span>hours    </div>
    <div class="bg-neutral rounded-box text-neutral-content flex flex-col p-2">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="24" style="--value:24;">24</span></span>min    </div>
    <div class="bg-neutral rounded-box text-neutral-content flex flex-col p-2">
<span class="countdown font-mono text-5xl"><span aria-live="polite" aria-label="59" style="--value:59;">59</span></span>sec    </div>
  </div>
</div>
test_func = test_countdown_boxes_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()