labb 0.5.0 is out

Countdown

<c-lb.countdown /> Markdown

Countdown component for Django: animate a rolling number for timers, clocks, and counters. Built with django-cotton, Tailwind CSS, and daisyUI 5.

Countdown renders a single number (0–999) that rolls smoothly when it changes. The roll is pure CSS; something has to change the value. Bind value to a signal and it counts on its own. With a static value it renders one number and ships no JavaScript.

Compose several to build a clock, and set the type size with a class.

Basic Countdown

59
<c-lb.countdown value="59" class="text-4xl" />

Counting down

Bind value to a signal and drive it from an interval. The :10 after the signal name is the server-rendered fallback.

10
<c-lbr.signals $timer.left="10" />

<div class="flex flex-col items-start gap-4">

    <c-lb.countdown value="$timer.left:10" class="text-5xl" />

    <div data-on-interval__duration.1s="$timer.left = $timer.left > 0 ? $timer.left - 1 : 0"></div>

    <c-lb.button size="sm" data-on:click="$timer.left = 10">Reset</c-lb.button>

</div>

Clock

Static digits. Renders once, no JavaScript.

10 : 24 : 59
<div class="flex items-center gap-1 font-mono text-3xl">
  <c-lb.countdown value="10" />
  <span>:</span>
  <c-lb.countdown value="24" />
  <span>:</span>
  <c-lb.countdown value="59" />
</div>

Reactive clock

The same composition with each unit bound to its own signal. Use digits="2" to reserve a fixed width so the row does not jump as numbers change.

1 : 59 : 45
<c-lbr.signals $clock.h="1" $clock.m="59" $clock.s="45" />

<div class="flex flex-col items-start gap-4">

    <div class="flex items-center gap-1 font-mono text-3xl">
        <c-lb.countdown value="$clock.h:1" digits="2" />
        <span>:</span>
        <c-lb.countdown value="$clock.m:59" digits="2" />
        <span>:</span>
        <c-lb.countdown value="$clock.s:45" digits="2" />
    </div>

    <div data-on-interval__duration.1s="
        $clock.s = $clock.s > 0 ? $clock.s - 1 : 59;
        if ($clock.s === 59) { $clock.m = $clock.m > 0 ? $clock.m - 1 : 59 }
        if ($clock.m === 59 && $clock.s === 59) { $clock.h = $clock.h > 0 ? $clock.h - 1 : 0 }
    "></div>

</div>

With Labels

15 days
10 hours
24 min
59 sec
<div class="flex gap-5 text-center">
  <div class="flex flex-col">
    <c-lb.countdown value="15" class="text-4xl" />
    <span class="text-xs text-base-content/60">days</span>
  </div>
  <div class="flex flex-col">
    <c-lb.countdown value="10" class="text-4xl" />
    <span class="text-xs text-base-content/60">hours</span>
  </div>
  <div class="flex flex-col">
    <c-lb.countdown value="24" class="text-4xl" />
    <span class="text-xs text-base-content/60">min</span>
  </div>
  <div class="flex flex-col">
    <c-lb.countdown value="59" class="text-4xl" />
    <span class="text-xs text-base-content/60">sec</span>
  </div>
</div>

API Reference

c-lb.countdown

Property Type Default Required Description
class string - No Additional CSS classes to apply
value string 0 No Current number to display (0-999); animate by re-rendering with a new value
digits string - No Reserve a fixed width for this many digits (blank = auto-size)
ariaLabel string - No Accessible label for the value (defaults to the value)