Countdown
A count to a fixed moment, such as a registration deadline or an application closing.
Code
The three render the same class names, the same ARIA and the same data attributes. That is checked when this site builds: a class in any of these samples that neither the markup contract nor the shipped stylesheet defines fails the build.
<div class="wsu-countdown" data-wsu-countdown data-wsu-countdown-target="2027-11-08T23:59:00-05:00" data-wsu-countdown-label="Registration">
<p class="wsu-countdown__label" id="countdown-registration-label">Registration closes in</p>
<time class="wsu-countdown__value" role="timer" aria-live="off"
aria-labelledby="countdown-registration-label" data-wsu-countdown-time datetime="P0DT0H0M0S">
<span class="wsu-countdown__segment"><span class="wsu-countdown__number" data-wsu-countdown-days>00</span><span class="wsu-countdown__unit">days</span></span>
<span class="wsu-countdown__segment"><span class="wsu-countdown__number" data-wsu-countdown-hours>00</span><span class="wsu-countdown__unit">hours</span></span>
<span class="wsu-countdown__segment"><span class="wsu-countdown__number" data-wsu-countdown-minutes>00</span><span class="wsu-countdown__unit">minutes</span></span>
<span class="wsu-countdown__segment"><span class="wsu-countdown__number" data-wsu-countdown-seconds>00</span><span class="wsu-countdown__unit">seconds</span></span>
</time>
<button type="button" class="wsu-btn wsu-btn--outline wsu-btn--sm wsu-countdown__pause" data-wsu-countdown-pause aria-pressed="false">
<span class="wsu-countdown__pause-state" data-wsu-countdown-pause-state="running">Pause</span>
<span class="wsu-countdown__pause-state" data-wsu-countdown-pause-state="paused" hidden>Resume</span>
</button>
<p class="wsu-countdown__status wsu-sr-only" role="status" data-wsu-countdown-status></p>
</div><x-wsu::countdown
target="2027-11-08T23:59:00-05:00"
label="Registration closes in"
subject="Registration" /><!-- Needs an AppShell ancestor: it calls useChromeRuntime, which is what
runs the clock. -->
<Countdown
target="2027-11-08T23:59:00-05:00"
label="Registration closes in"
subject="Registration"
/>Why it works this way
- The ticking carries no script of its own. data-wsu-countdown and the attributes beside it are read by the shared runtime in @waynestate/wayne-ui-css/theme, the same module the static, raw PHP and Blade paths load directly, so every path answers how much time is left the same way, rather than running four separate interval timers that could each round differently. On the Vue path that runtime is wired up by useChromeRuntime, which AppShell calls, so a Countdown rendered outside an AppShell shows 00 for every unit and never moves.
- The digits are cosmetic. The value a screen reader user needs is the labeled <time role="timer" aria-live="off">, read on request rather than announced on every tick, because a live region repeating itself every second would drown out the rest of the page.
- The pause button is the WCAG 2.2.2 mechanism for a display that moves on its own for more than five seconds with nothing essential riding on the motion. Pausing freezes the digits and the time text. It never freezes the target moment itself, which keeps arriving on schedule whether the display is paused or not.
Accessibility
- The value lives in a labeled time with role="timer" and aria-live="off", read on request rather than forced onto the page every second (4.1.2, 4.1.3).
- A pause control for content that moves on its own past five seconds (2.2.2).
- Pausing stops the display, never the deadline it counts to.
Success criteria in brackets refer to WCAG 2.2. Every one of them is checked by axe-core in both themes at three viewport widths before this page can be published. See Accessibility for what the gates are.
Props
Blade
| Attribute | Default | What it does |
|---|---|---|
target | required | ISO 8601 moment this counts down to. Throws if omitted. |
label | 'Time remaining' | The sentence read beside the digits. |
subject | 'Time' | The noun used once the target has passed. |
id | generated from label | id of the label paragraph, via WSU\WayneUi\Support\UniqueId. Set it to control or reuse the id. |
Vue
| Prop | Type and default | What it does |
|---|---|---|
target | String, required | ISO 8601 moment this counts down to. |
label | String, 'Time remaining' | The sentence read beside the digits. |
subject | String, 'Time' | The noun used once the target has passed. |
In the markup contract
contract/markup-contract.json is extracted from the two static templates and every package tests against it. This is what it records for .wsu-countdown.
| Template | Elements | Accessibility attributes | Uses |
|---|---|---|---|
| internal apps/examples/static-html/index.html | div | none recorded | 1 |
| public apps/examples/static-html/public-app.html | div | none recorded | 1 |