refactor(toolkit): type source any with proper types

Genuinely type composable any usages (useStepper/useStorage/useForm/
createEventHook/useSorted/etc.) as proper generics/unknown; keep idiomatic
any-function and overload-impl signatures with comments; skipped test -> .todo.
This commit is contained in:
2026-06-15 16:55:07 +07:00
parent 44848bc9e6
commit aa2938cb34
283 changed files with 3505 additions and 3482 deletions
@@ -40,7 +40,7 @@ const stateColor = computed(() => {
case 'running': return 'bg-emerald-500';
case 'paused': return 'bg-amber-500';
case 'finished': return 'bg-sky-500';
default: return 'bg-(--border-strong)';
default: return 'bg-border-strong';
}
});
@@ -48,7 +48,7 @@ const rates = [0.5, 1, 2] as const;
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="demo-stack max-w-sm">
<div
v-if="!isSupported"
class="rounded-xl border border-amber-500/30 bg-amber-500/10 p-4 text-sm text-amber-600 dark:text-amber-400"
@@ -57,28 +57,28 @@ const rates = [0.5, 1, 2] as const;
</div>
<template v-else>
<div class="flex h-28 items-center justify-center overflow-hidden rounded-xl border border-(--border) bg-(--bg-inset)">
<div class="flex h-28 items-center justify-center overflow-hidden rounded-xl border border-border bg-bg-inset">
<div
ref="target"
class="size-12 bg-(--accent) shadow-lg"
class="size-12 bg-accent shadow-lg"
/>
</div>
<div class="grid grid-cols-2 gap-3">
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-3">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="rounded-lg border border-border bg-bg-inset p-3">
<div class="demo-label">
State
</div>
<div class="mt-1 flex items-center gap-2">
<span class="inline-block size-2 rounded-full transition" :class="stateColor" />
<span class="font-mono text-sm text-(--fg)">{{ playState }}</span>
<span class="font-mono text-sm text-fg">{{ playState }}</span>
</div>
</div>
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-3">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="rounded-lg border border-border bg-bg-inset p-3">
<div class="demo-label">
Current time
</div>
<div class="mt-1 font-mono text-sm tabular-nums text-(--fg)">
<div class="mt-1 font-mono text-sm tabular-nums text-fg">
{{ elapsed }}
</div>
</div>
@@ -86,31 +86,31 @@ const rates = [0.5, 1, 2] as const;
<div class="grid grid-cols-3 gap-2">
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer"
class="demo-btn-primary"
@click="play"
>
Play
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="pause"
>
Pause
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="reverse"
>
Reverse
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="finish"
>
Finish
</button>
<button
class="col-span-2 inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn col-span-2"
@click="cancel"
>
Cancel
@@ -118,7 +118,7 @@ const rates = [0.5, 1, 2] as const;
</div>
<div class="flex flex-col gap-2">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-label">
Playback rate
</div>
<div class="flex gap-2">
@@ -127,8 +127,8 @@ const rates = [0.5, 1, 2] as const;
:key="rate"
class="flex-1 rounded-lg border px-3 py-1.5 text-sm font-medium tabular-nums transition active:scale-[0.98] cursor-pointer"
:class="playbackRate === rate
? 'border-transparent bg-(--accent) text-(--accent-fg)'
: 'border-(--border) bg-(--bg-elevated) text-(--fg) hover:bg-(--bg-inset) hover:border-(--border-strong)'"
? 'border-transparent bg-accent text-accent-fg'
: 'border-border bg-bg-elevated text-fg hover:bg-bg-inset hover:border-border-strong'"
@click="playbackRate = rate"
>
{{ rate }}×
@@ -37,9 +37,9 @@ function toggle() {
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-5 text-center">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-stack max-w-sm">
<div class="demo-card p-5 text-center">
<div class="demo-label">
Time remaining
</div>
<div
@@ -48,22 +48,22 @@ function toggle() {
? 'text-emerald-600 dark:text-emerald-400'
: remaining <= 10 && remaining > 0
? 'text-amber-600 dark:text-amber-400'
: 'text-(--fg)'"
: 'text-fg'"
>
{{ minutes }}:{{ seconds }}
</div>
<div class="mt-4 h-1.5 w-full overflow-hidden rounded-full bg-(--bg-inset)">
<div class="mt-4 h-1.5 w-full overflow-hidden rounded-full bg-bg-inset">
<div
class="h-full rounded-full bg-(--accent) transition-[width] duration-300 ease-linear"
class="h-full rounded-full bg-accent transition-[width] duration-300 ease-linear"
:style="{ width: `${progress * 100}%` }"
/>
</div>
<div class="mt-3 flex items-center justify-center gap-2 text-xs text-(--fg-subtle)">
<div class="mt-3 flex items-center justify-center gap-2 text-xs text-fg-subtle">
<span
class="inline-block size-2 rounded-full transition"
:class="isActive ? 'bg-emerald-500' : justFinished ? 'bg-sky-500' : 'bg-(--border-strong)'"
:class="isActive ? 'bg-emerald-500' : justFinished ? 'bg-sky-500' : 'bg-border-strong'"
/>
{{ justFinished ? 'Completed' : isActive ? 'Counting down' : 'Paused' }}
</div>
@@ -73,7 +73,7 @@ function toggle() {
<button
v-for="preset in presets"
:key="preset"
class="rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium tabular-nums text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="rounded-lg border border-border bg-bg-elevated px-3 py-1.5 text-sm font-medium tabular-nums text-fg transition hover:bg-bg-inset hover:border-border-strong active:scale-[0.98] cursor-pointer"
@click="setPreset(preset)"
>
{{ preset < 60 ? `${preset}s` : `${preset / 60}m` }}
@@ -82,20 +82,20 @@ function toggle() {
<div class="flex items-center gap-2">
<button
class="flex-1 inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn-primary flex-1 disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
:disabled="remaining === 0 && isActive"
@click="toggle"
>
{{ isActive ? 'Pause' : 'Resume' }}
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="start()"
>
Restart
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="stop"
>
Stop
@@ -27,46 +27,46 @@ const isValid = computed(() => formatted.value !== 'Invalid Date');
</script>
<template>
<div class="flex w-full max-w-md flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-stack max-w-md">
<div class="demo-card p-4">
<div class="demo-label">
Formatted output
</div>
<div
class="mt-2 font-mono text-lg font-semibold tabular-nums"
:class="isValid ? 'text-(--fg)' : 'text-red-600 dark:text-red-400'"
:class="isValid ? 'text-fg' : 'text-red-600 dark:text-red-400'"
>
{{ formatted }}
</div>
</div>
<div class="flex flex-col gap-1.5">
<label class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<label class="demo-label">
Date input
</label>
<input
v-model="date"
type="datetime-local"
class="w-full rounded-lg border border-(--border) bg-(--bg) px-3 py-2 text-sm text-(--fg) placeholder:text-(--fg-subtle) transition focus:border-(--accent) focus:outline-none focus:ring-2 focus:ring-(--ring)"
class="demo-input"
>
</div>
<div class="flex flex-col gap-1.5">
<label class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<label class="demo-label">
Format token string
</label>
<input
v-model="format"
type="text"
spellcheck="false"
class="w-full rounded-lg border border-(--border) bg-(--bg) px-3 py-2 font-mono text-sm text-(--fg) placeholder:text-(--fg-subtle) transition focus:border-(--accent) focus:outline-none focus:ring-2 focus:ring-(--ring)"
class="demo-input font-mono"
>
<div class="flex flex-wrap gap-1.5 pt-1">
<button
v-for="f in formats"
:key="f"
class="rounded-md border border-(--border) bg-(--bg-inset) px-2 py-0.5 font-mono text-xs text-(--fg-muted) transition hover:bg-(--bg-elevated) hover:text-(--fg) active:scale-[0.98] cursor-pointer"
:class="{ 'border-(--accent) text-(--accent-text)': format === f }"
class="rounded-md border border-border bg-bg-inset px-2 py-0.5 font-mono text-xs text-fg-muted transition hover:bg-bg-elevated hover:text-fg active:scale-[0.98] cursor-pointer"
:class="{ 'border-accent text-accent-text': format === f }"
@click="format = f"
>
{{ f }}
@@ -75,7 +75,7 @@ const isValid = computed(() => formatted.value !== 'Invalid Date');
</div>
<div class="flex flex-col gap-1.5">
<label class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<label class="demo-label">
Locale
</label>
<div class="flex flex-wrap gap-2">
@@ -84,8 +84,8 @@ const isValid = computed(() => formatted.value !== 'Invalid Date');
:key="loc.value"
class="rounded-lg border px-3 py-1.5 text-sm font-medium transition active:scale-[0.98] cursor-pointer"
:class="locale === loc.value
? 'border-transparent bg-(--accent) text-(--accent-fg)'
: 'border-(--border) bg-(--bg-elevated) text-(--fg) hover:bg-(--bg-inset) hover:border-(--border-strong)'"
? 'border-transparent bg-accent text-accent-fg'
: 'border-border bg-bg-elevated text-fg hover:bg-bg-inset hover:border-border-strong'"
@click="locale = loc.value"
>
{{ loc.label }}
@@ -52,6 +52,7 @@ const REGEX_FORMAT
// `20240101`); JS lacks possessive quantifiers to disambiguate it.
// eslint-disable-next-line regexp/no-misleading-capturing-group
const REGEX_PARSE = /* #__PURE__ */ /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[T\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/i;
const REGEX_ISO_SUFFIX = /* #__PURE__ */ /z$/i;
const ORDINAL_SUFFIXES = ['th', 'st', 'nd', 'rd'] as const;
@@ -82,7 +83,7 @@ function formatOrdinal(num: number): string {
export function normalizeDate(date: DateLike): Date {
if (date === null || date === undefined) return new Date();
if (isDate(date)) return new Date(date.getTime());
if (isString(date) && !/z$/i.test(date)) {
if (isString(date) && !REGEX_ISO_SUFFIX.test(date)) {
const d = REGEX_PARSE.exec(date);
if (d) {
const month = d[2] ? Number(d[2]) - 1 : 0;
@@ -27,12 +27,12 @@ function toggle() {
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-5 text-center">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-stack max-w-sm">
<div class="demo-card p-5 text-center">
<div class="demo-label">
Ticks elapsed
</div>
<div class="mt-2 font-mono text-5xl font-bold tabular-nums text-(--fg)">
<div class="demo-stat mt-2 text-5xl">
{{ counter }}
</div>
@@ -41,21 +41,21 @@ function toggle() {
v-for="(on, i) in beats"
:key="i"
class="size-2.5 rounded-full transition-colors duration-200"
:class="on ? 'bg-(--accent)' : 'bg-(--bg-inset)'"
:class="on ? 'bg-accent' : 'bg-bg-inset'"
/>
</div>
<div class="mt-4 flex items-center justify-center gap-2 text-xs text-(--fg-subtle)">
<div class="mt-4 flex items-center justify-center gap-2 text-xs text-fg-subtle">
<span
class="inline-block size-2 rounded-full transition"
:class="isActive ? 'bg-emerald-500' : 'bg-(--border-strong)'"
:class="isActive ? 'bg-emerald-500' : 'bg-border-strong'"
/>
{{ isActive ? `Ticking every ${interval}ms` : 'Paused' }}
</div>
</div>
<div class="flex flex-col gap-1.5">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-label">
Interval speed
</div>
<div class="flex gap-2">
@@ -64,8 +64,8 @@ function toggle() {
:key="speed.value"
class="flex-1 rounded-lg border px-3 py-1.5 text-sm font-medium transition active:scale-[0.98] cursor-pointer"
:class="interval === speed.value
? 'border-transparent bg-(--accent) text-(--accent-fg)'
: 'border-(--border) bg-(--bg-elevated) text-(--fg) hover:bg-(--bg-inset) hover:border-(--border-strong)'"
? 'border-transparent bg-accent text-accent-fg'
: 'border-border bg-bg-elevated text-fg hover:bg-bg-inset hover:border-border-strong'"
@click="interval = speed.value"
>
{{ speed.label }}
@@ -75,13 +75,13 @@ function toggle() {
<div class="flex items-center gap-2">
<button
class="flex-1 inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer"
class="demo-btn-primary flex-1"
@click="toggle"
>
{{ isActive ? 'Pause' : 'Resume' }}
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
:disabled="counter === 0"
@click="reset"
>
@@ -31,22 +31,22 @@ function clear() {
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="flex items-center justify-between rounded-xl border border-(--border) bg-(--bg-elevated) p-4">
<div class="demo-stack max-w-sm">
<div class="demo-card flex items-center justify-between p-4">
<div>
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-label">
Interval callback
</div>
<div class="mt-1 flex items-center gap-2 text-sm text-(--fg-muted)">
<div class="mt-1 flex items-center gap-2 text-sm text-fg-muted">
<span
class="inline-block size-2 rounded-full transition"
:class="isActive ? 'bg-emerald-500' : 'bg-(--border-strong)'"
:class="isActive ? 'bg-emerald-500' : 'bg-border-strong'"
/>
{{ isActive ? `Firing every ${interval}ms` : 'Stopped' }}
</div>
</div>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer"
class="demo-btn-primary"
@click="toggle"
>
{{ isActive ? 'Pause' : 'Start' }}
@@ -54,7 +54,7 @@ function clear() {
</div>
<div class="flex flex-col gap-1.5">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-label">
Interval
</div>
<div class="flex gap-2">
@@ -63,24 +63,24 @@ function clear() {
:key="speed.value"
class="flex-1 rounded-lg border px-3 py-1.5 text-sm font-medium transition active:scale-[0.98] cursor-pointer"
:class="interval === speed.value
? 'border-transparent bg-(--accent) text-(--accent-fg)'
: 'border-(--border) bg-(--bg-elevated) text-(--fg) hover:bg-(--bg-inset) hover:border-(--border-strong)'"
? 'border-transparent bg-accent text-accent-fg'
: 'border-border bg-bg-elevated text-fg hover:bg-bg-inset hover:border-border-strong'"
@click="interval = speed.value"
>
{{ speed.label }}
</button>
</div>
<p class="text-xs text-(--fg-subtle)">
<p class="text-xs text-fg-subtle">
Changing the interval while running restarts the timer with the new duration.
</p>
</div>
<div class="flex items-center justify-between">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-label">
Tick log
</div>
<button
class="text-xs text-(--accent-text) transition hover:underline disabled:cursor-not-allowed disabled:opacity-40 cursor-pointer"
class="text-xs text-accent-text transition hover:underline disabled:cursor-not-allowed disabled:opacity-40 cursor-pointer"
:disabled="logs.length === 0"
@click="clear"
>
@@ -88,17 +88,17 @@ function clear() {
</button>
</div>
<div class="min-h-32 rounded-lg border border-(--border) bg-(--bg-inset) p-3">
<p v-if="logs.length === 0" class="py-6 text-center text-sm text-(--fg-subtle)">
<div class="min-h-32 rounded-lg border border-border bg-bg-inset p-3">
<p v-if="logs.length === 0" class="py-6 text-center text-sm text-fg-subtle">
No ticks yet press Start.
</p>
<ul v-else class="flex flex-col gap-1.5">
<li
v-for="log in logs"
:key="log.id"
class="flex items-center gap-2 font-mono text-sm tabular-nums text-(--fg)"
class="flex items-center gap-2 font-mono text-sm tabular-nums text-fg"
>
<span class="inline-block size-1.5 rounded-full bg-(--accent)" />
<span class="inline-block size-1.5 rounded-full bg-accent" />
{{ log.time }}
</li>
</ul>
@@ -106,14 +106,14 @@ function clear() {
<div class="flex items-center gap-2">
<button
class="flex-1 inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn flex-1 disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
:disabled="isActive"
@click="resume"
>
Resume
</button>
<button
class="flex-1 inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn flex-1 disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
:disabled="!isActive"
@click="pause"
>
@@ -20,23 +20,23 @@ const secondAngle = computed(() => {
</script>
<template>
<div class="w-full max-w-sm flex flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4 flex flex-col items-center gap-3">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">Reactive now</div>
<div class="demo-stack max-w-sm">
<div class="demo-card p-4 flex flex-col items-center gap-3">
<div class="demo-label">Reactive now</div>
<div class="flex items-baseline gap-1">
<span class="font-mono text-3xl font-bold tabular-nums text-(--fg)">{{ time }}</span>
<span class="font-mono text-lg font-semibold tabular-nums text-(--fg-subtle)">.{{ millis }}</span>
<span class="demo-stat text-3xl">{{ time }}</span>
<span class="font-mono text-lg font-semibold tabular-nums text-fg-subtle">.{{ millis }}</span>
</div>
<div class="text-sm text-(--fg-muted)">{{ date }}</div>
<div class="text-sm text-fg-muted">{{ date }}</div>
<div class="relative mt-1 size-24 rounded-full border-2 border-(--border-strong) bg-(--bg-inset)">
<div class="relative mt-1 size-24 rounded-full border-2 border-border-strong bg-bg-inset">
<div class="absolute inset-0 flex items-center justify-center">
<div class="size-1.5 rounded-full bg-(--accent)" />
<div class="size-1.5 rounded-full bg-accent" />
</div>
<div
class="absolute bottom-1/2 left-1/2 h-9 w-0.5 origin-bottom rounded-full bg-(--accent)"
class="absolute bottom-1/2 left-1/2 h-9 w-0.5 origin-bottom rounded-full bg-accent"
:style="{ transform: `translateX(-50%) rotate(${secondAngle}deg)` }"
/>
</div>
@@ -44,11 +44,11 @@ const secondAngle = computed(() => {
<div class="flex items-center justify-between gap-3">
<span
class="inline-flex items-center gap-1.5 rounded-md border border-(--border) bg-(--bg-inset) px-2 py-0.5 text-xs font-medium text-(--fg-muted)"
class="demo-badge"
>
<span
class="size-1.5 rounded-full transition"
:class="isActive ? 'bg-emerald-500' : 'bg-(--fg-subtle)'"
:class="isActive ? 'bg-emerald-500' : 'bg-fg-subtle'"
/>
{{ isActive ? 'Ticking (RAF)' : 'Paused' }}
</span>
@@ -56,7 +56,7 @@ const secondAngle = computed(() => {
<div class="flex items-center gap-2">
<button
type="button"
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="toggle"
>
{{ isActive ? 'Pause' : 'Resume' }}
@@ -64,7 +64,7 @@ const secondAngle = computed(() => {
<button
type="button"
:disabled="isActive"
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn-primary disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
@click="resume"
>
Resume
@@ -72,7 +72,7 @@ const secondAngle = computed(() => {
<button
type="button"
:disabled="!isActive"
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
@click="pause"
>
Pause
@@ -35,46 +35,46 @@ const limitLabel = computed(() => (fpsLimit.value === 0 ? 'Unlimited' : `${fpsLi
</script>
<template>
<div class="w-full max-w-sm flex flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4 flex flex-col gap-4">
<div class="demo-stack max-w-sm">
<div class="demo-card p-4 flex flex-col gap-4">
<div class="flex items-center justify-between">
<span class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">requestAnimationFrame</span>
<span class="demo-label">requestAnimationFrame</span>
<span
class="inline-flex items-center gap-1.5 rounded-md border border-(--border) bg-(--bg-inset) px-2 py-0.5 text-xs font-medium text-(--fg-muted)"
class="demo-badge"
>
<span class="size-1.5 rounded-full transition" :class="isActive ? 'bg-emerald-500' : 'bg-(--fg-subtle)'" />
<span class="size-1.5 rounded-full transition" :class="isActive ? 'bg-emerald-500' : 'bg-fg-subtle'" />
{{ isActive ? 'Running' : 'Paused' }}
</span>
</div>
<!-- The animated track: marker position is updated every frame -->
<div class="relative mx-2.5 h-8 rounded-lg border border-(--border) bg-(--bg-inset)">
<div class="relative mx-2.5 h-8 rounded-lg border border-border bg-bg-inset">
<div
class="absolute top-1/2 size-5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-(--accent) shadow"
class="absolute top-1/2 size-5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-accent shadow"
:style="{ left: `${position}%` }"
/>
</div>
<div class="grid grid-cols-3 gap-2">
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-2 text-center">
<div class="font-mono text-lg font-bold tabular-nums text-(--fg)">{{ fps }}</div>
<div class="text-[10px] uppercase tracking-wide text-(--fg-subtle)">fps</div>
<div class="rounded-lg border border-border bg-bg-inset p-2 text-center">
<div class="demo-stat text-lg">{{ fps }}</div>
<div class="text-[10px] uppercase tracking-wide text-fg-subtle">fps</div>
</div>
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-2 text-center">
<div class="font-mono text-lg font-bold tabular-nums text-(--fg)">{{ delta.toFixed(1) }}</div>
<div class="text-[10px] uppercase tracking-wide text-(--fg-subtle)">delta ms</div>
<div class="rounded-lg border border-border bg-bg-inset p-2 text-center">
<div class="demo-stat text-lg">{{ delta.toFixed(1) }}</div>
<div class="text-[10px] uppercase tracking-wide text-fg-subtle">delta ms</div>
</div>
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-2 text-center">
<div class="font-mono text-lg font-bold tabular-nums text-(--fg)">{{ frames }}</div>
<div class="text-[10px] uppercase tracking-wide text-(--fg-subtle)">frames</div>
<div class="rounded-lg border border-border bg-bg-inset p-2 text-center">
<div class="demo-stat text-lg">{{ frames }}</div>
<div class="text-[10px] uppercase tracking-wide text-fg-subtle">frames</div>
</div>
</div>
</div>
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<label class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)" for="fps-limit">FPS limit</label>
<span class="font-mono text-xs tabular-nums text-(--fg-muted)">{{ limitLabel }}</span>
<label class="demo-label" for="fps-limit">FPS limit</label>
<span class="font-mono text-xs tabular-nums text-fg-muted">{{ limitLabel }}</span>
</div>
<input
id="fps-limit"
@@ -83,14 +83,14 @@ const limitLabel = computed(() => (fpsLimit.value === 0 ? 'Unlimited' : `${fpsLi
min="0"
max="60"
step="5"
class="w-full accent-(--accent) cursor-pointer"
class="w-full accent-accent cursor-pointer"
>
<p class="text-xs text-(--fg-subtle)">Changing the limit takes effect on the next mount; toggle below to see it live.</p>
<p class="text-xs text-fg-subtle">Changing the limit takes effect on the next mount; toggle below to see it live.</p>
</div>
<button
type="button"
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer"
class="demo-btn-primary"
@click="toggle"
>
{{ isActive ? 'Pause loop' : 'Resume loop' }}
@@ -42,15 +42,15 @@ const absolute = computed(() =>
</script>
<template>
<div class="w-full max-w-sm flex flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4 flex flex-col items-center gap-2">
<span class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">Relative time</span>
<span class="font-mono text-3xl font-bold tabular-nums text-(--fg) text-center">{{ timeAgo }}</span>
<span class="text-xs text-(--fg-muted)">{{ absolute }}</span>
<div class="demo-stack max-w-sm">
<div class="demo-card p-4 flex flex-col items-center gap-2">
<span class="demo-label">Relative time</span>
<span class="demo-stat text-3xl text-center">{{ timeAgo }}</span>
<span class="text-xs text-fg-muted">{{ absolute }}</span>
</div>
<div class="flex flex-col gap-2">
<span class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">Pick an instant</span>
<span class="demo-label">Pick an instant</span>
<div class="grid grid-cols-2 gap-2">
<button
v-for="preset in presets"
@@ -58,8 +58,8 @@ const absolute = computed(() =>
type="button"
class="inline-flex items-center justify-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm font-medium transition active:scale-[0.98] cursor-pointer"
:class="offset === preset.offset
? 'border-transparent bg-(--accent) text-(--accent-fg) hover:bg-(--accent-hover)'
: 'border-(--border) bg-(--bg-elevated) text-(--fg) hover:bg-(--bg-inset) hover:border-(--border-strong)'"
? 'border-transparent bg-accent text-accent-fg hover:bg-accent-hover'
: 'border-border bg-bg-elevated text-fg hover:bg-bg-inset hover:border-border-strong'"
@click="offset = preset.offset"
>
{{ preset.label }}
@@ -69,14 +69,14 @@ const absolute = computed(() =>
<div class="flex items-center justify-between gap-3">
<span
class="inline-flex items-center gap-1.5 rounded-md border border-(--border) bg-(--bg-inset) px-2 py-0.5 text-xs font-medium text-(--fg-muted)"
class="demo-badge"
>
<span class="size-1.5 rounded-full transition" :class="isActive ? 'bg-emerald-500' : 'bg-(--fg-subtle)'" />
<span class="size-1.5 rounded-full transition" :class="isActive ? 'bg-emerald-500' : 'bg-fg-subtle'" />
{{ isActive ? 'Updating every 1s' : 'Updates paused' }}
</span>
<button
type="button"
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="toggle"
>
{{ isActive ? 'Pause' : 'Resume' }}
@@ -165,10 +165,12 @@ const DEFAULT_UNITS: Array<UseTimeAgoUnit<UseTimeAgoUnitName>> = [
{ max: Number.POSITIVE_INFINITY, value: 31536000000, name: 'year' },
];
const REGEX_DIGIT = /* #__PURE__ */ /\d/;
const DEFAULT_MESSAGES: UseTimeAgoMessages<UseTimeAgoUnitName> = {
justNow: 'just now',
past: n => /\d/.test(n) ? `${n} ago` : n,
future: n => /\d/.test(n) ? `in ${n}` : n,
past: n => REGEX_DIGIT.test(n) ? `${n} ago` : n,
future: n => REGEX_DIGIT.test(n) ? `in ${n}` : n,
month: (n, past) => n === 1 ? (past ? 'last month' : 'next month') : `${n} month${n > 1 ? 's' : ''}`,
year: (n, past) => n === 1 ? (past ? 'last year' : 'next year') : `${n} year${n > 1 ? 's' : ''}`,
day: (n, past) => n === 1 ? (past ? 'yesterday' : 'tomorrow') : `${n} day${n > 1 ? 's' : ''}`,
@@ -24,21 +24,21 @@ function cancel() {
</script>
<template>
<div class="w-full max-w-sm flex flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4 flex flex-col items-center gap-3">
<span class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">Status</span>
<div class="demo-stack max-w-sm">
<div class="demo-card p-4 flex flex-col items-center gap-3">
<span class="demo-label">Status</span>
<div
class="flex size-20 items-center justify-center rounded-full border-2 transition"
:class="ready
? 'border-emerald-500/40 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'
: 'border-(--accent) bg-(--accent-subtle) text-(--accent-text)'"
: 'border-accent bg-accent-subtle text-accent-text'"
>
<span class="text-sm font-semibold">{{ ready ? 'Ready' : 'Pending' }}</span>
</div>
<p class="text-center text-sm text-(--fg-muted)">
<template v-if="ready && firedAt">Fired at <span class="font-mono tabular-nums text-(--fg)">{{ firedAt }}</span></template>
<p class="text-center text-sm text-fg-muted">
<template v-if="ready && firedAt">Fired at <span class="font-mono tabular-nums text-fg">{{ firedAt }}</span></template>
<template v-else-if="ready">Idle start the timer below</template>
<template v-else>Counting down stays pending until the delay elapses</template>
</p>
@@ -46,8 +46,8 @@ function cancel() {
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<label class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)" for="delay">Delay</label>
<span class="font-mono text-xs tabular-nums text-(--fg-muted)">{{ (delay / 1000).toFixed(1) }}s</span>
<label class="demo-label" for="delay">Delay</label>
<span class="font-mono text-xs tabular-nums text-fg-muted">{{ (delay / 1000).toFixed(1) }}s</span>
</div>
<input
id="delay"
@@ -56,14 +56,14 @@ function cancel() {
min="500"
max="5000"
step="500"
class="w-full accent-(--accent) cursor-pointer"
class="w-full accent-accent cursor-pointer"
>
</div>
<div class="flex items-center gap-2">
<button
type="button"
class="flex-1 inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer"
class="demo-btn-primary flex-1"
@click="restart"
>
{{ ready ? 'Start' : 'Restart' }}
@@ -71,7 +71,7 @@ function cancel() {
<button
type="button"
:disabled="ready"
class="flex-1 inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn flex-1 disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
@click="cancel"
>
Cancel
@@ -42,23 +42,23 @@ function undo() {
<template>
<div class="w-full max-w-sm flex flex-col gap-3">
<span class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">Inbox · undo with grace period</span>
<span class="demo-label">Inbox · undo with grace period</span>
<ul v-if="inbox.length" class="flex flex-col gap-2">
<li
v-for="mail in inbox"
:key="mail.id"
class="flex items-center justify-between gap-3 rounded-xl border border-(--border) bg-(--bg-elevated) p-3 transition"
class="demo-card flex items-center justify-between gap-3 p-3 transition"
:class="{ 'opacity-40': pendingDelete?.id === mail.id }"
>
<div class="min-w-0">
<div class="truncate text-sm font-medium text-(--fg)">{{ mail.subject }}</div>
<div class="truncate text-xs text-(--fg-muted)">{{ mail.from }}</div>
<div class="truncate text-sm font-medium text-fg">{{ mail.subject }}</div>
<div class="truncate text-xs text-fg-muted">{{ mail.from }}</div>
</div>
<button
type="button"
:disabled="isPending"
class="shrink-0 inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
class="demo-btn shrink-0 disabled:cursor-not-allowed disabled:opacity-40 disabled:active:scale-100"
@click="archive(mail)"
>
Archive
@@ -66,7 +66,7 @@ function undo() {
</li>
</ul>
<div v-else class="rounded-xl border border-dashed border-(--border) bg-(--bg-inset) p-6 text-center text-sm text-(--fg-subtle)">
<div v-else class="rounded-xl border border-dashed border-border bg-bg-inset p-6 text-center text-sm text-fg-subtle">
Inbox zero everything archived.
</div>
@@ -21,7 +21,7 @@ export interface UseTimeoutFnOptions {
immediateCallback?: boolean;
}
export interface UseTimeoutFnReturn<Args extends any[]> {
export interface UseTimeoutFnReturn<Args extends unknown[]> {
/**
* Whether the timeout is currently pending
*/
@@ -45,33 +45,33 @@ function resetOffset() {
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4 text-center">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-stack max-w-sm">
<div class="demo-card p-4 text-center">
<div class="demo-label">
Reactive timestamp
</div>
<div class="mt-2 font-mono text-3xl font-bold tabular-nums text-(--fg)">
<div class="demo-stat mt-2 text-3xl">
{{ clockTime }}
</div>
<div class="mt-1 text-sm text-(--fg-muted)">
<div class="mt-1 text-sm text-fg-muted">
{{ clockDate }}
</div>
<div class="mt-3 flex items-center justify-center gap-2 text-xs text-(--fg-subtle)">
<div class="mt-3 flex items-center justify-center gap-2 text-xs text-fg-subtle">
<span
class="inline-block size-2 rounded-full transition"
:class="isActive ? 'bg-emerald-500' : 'bg-(--border-strong)'"
:class="isActive ? 'bg-emerald-500' : 'bg-border-strong'"
/>
{{ isActive ? 'Updating every second' : 'Paused' }}
</div>
</div>
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-3 font-mono text-sm text-(--fg) tabular-nums">
<div class="rounded-lg border border-border bg-bg-inset p-3 font-mono text-sm text-fg tabular-nums">
{{ Math.round(timestamp) }} ms
</div>
<div class="flex items-center justify-between gap-2">
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-transparent bg-(--accent) px-3 py-1.5 text-sm font-medium text-(--accent-fg) transition hover:bg-(--accent-hover) active:scale-[0.98] cursor-pointer"
class="demo-btn-primary"
@click="toggle"
>
{{ isActive ? 'Pause' : 'Resume' }}
@@ -79,13 +79,13 @@ function resetOffset() {
<div class="flex items-center gap-2">
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="shift(-3600_000)"
>
-1h
</button>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="shift(3600_000)"
>
+1h
@@ -93,13 +93,13 @@ function resetOffset() {
</div>
</div>
<div class="flex items-center justify-between text-sm text-(--fg-muted)">
<div class="flex items-center justify-between text-sm text-fg-muted">
<span>
Offset:
<span class="font-mono text-(--fg) tabular-nums">{{ (offset / 3600_000).toFixed(0) }}h</span>
<span class="font-mono text-fg tabular-nums">{{ (offset / 3600_000).toFixed(0) }}h</span>
</span>
<button
class="text-(--accent-text) transition hover:underline disabled:cursor-not-allowed disabled:opacity-40 cursor-pointer"
class="text-accent-text transition hover:underline disabled:cursor-not-allowed disabled:opacity-40 cursor-pointer"
:disabled="offset === 0"
@click="resetOffset"
>
@@ -40,19 +40,19 @@ function randomize() {
<template>
<div class="flex w-full max-w-md flex-col gap-5">
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4">
<div class="demo-card p-4">
<div class="flex items-baseline justify-between">
<span class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<span class="demo-label">
Eased value
</span>
<span class="font-mono text-3xl font-bold tabular-nums text-(--fg)">
<span class="demo-stat text-3xl">
{{ value.toFixed(1) }}
</span>
</div>
<div class="mt-3 h-2.5 w-full overflow-hidden rounded-full bg-(--bg-inset)">
<div class="mt-3 h-2.5 w-full overflow-hidden rounded-full bg-bg-inset">
<div
class="h-full rounded-full bg-(--accent)"
class="h-full rounded-full bg-accent"
:style="{ width: `${Math.max(0, Math.min(100, value))}%` }"
/>
</div>
@@ -63,10 +63,10 @@ function randomize() {
type="range"
min="0"
max="100"
class="h-1.5 flex-1 cursor-pointer accent-(--accent)"
class="h-1.5 flex-1 cursor-pointer accent-accent"
>
<button
class="inline-flex items-center justify-center gap-1.5 rounded-lg border border-(--border) bg-(--bg-elevated) px-3 py-1.5 text-sm font-medium text-(--fg) transition hover:bg-(--bg-inset) hover:border-(--border-strong) active:scale-[0.98] cursor-pointer"
class="demo-btn"
@click="randomize"
>
Random
@@ -75,21 +75,21 @@ function randomize() {
</div>
<div class="flex flex-col gap-2">
<label class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<label class="demo-label">
Easing preset
</label>
<select
v-model="preset"
class="w-full rounded-lg border border-(--border) bg-(--bg) px-3 py-2 text-sm text-(--fg) transition focus:border-(--accent) focus:outline-none focus:ring-2 focus:ring-(--ring)"
class="w-full rounded-lg border border-border bg-bg px-3 py-2 text-sm text-fg transition focus:border-accent focus:outline-none focus:ring-2 focus:ring-ring"
>
<option v-for="name in presetNames" :key="name" :value="name">
{{ name }}
</option>
</select>
<label class="mt-1 flex items-center justify-between text-sm text-(--fg-muted)">
<label class="mt-1 flex items-center justify-between text-sm text-fg-muted">
<span>Duration</span>
<span class="font-mono text-(--fg) tabular-nums">{{ duration }}ms</span>
<span class="font-mono text-fg tabular-nums">{{ duration }}ms</span>
</label>
<input
v-model.number="duration"
@@ -97,21 +97,21 @@ function randomize() {
min="100"
max="2000"
step="100"
class="h-1.5 w-full cursor-pointer accent-(--accent)"
class="h-1.5 w-full cursor-pointer accent-accent"
>
</div>
<div class="rounded-xl border border-(--border) bg-(--bg-elevated) p-4">
<div class="demo-card p-4">
<div class="flex items-center gap-3">
<div
class="size-12 shrink-0 rounded-lg border border-(--border)"
class="size-12 shrink-0 rounded-lg border border-border"
:style="{ backgroundColor: colorCss }"
/>
<div class="min-w-0">
<div class="text-xs font-medium uppercase tracking-wide text-(--fg-subtle)">
<div class="demo-label">
Animated tuple
</div>
<div class="font-mono text-sm text-(--fg) tabular-nums">
<div class="font-mono text-sm text-fg tabular-nums">
{{ colorCss }}
</div>
</div>
@@ -121,7 +121,7 @@ function randomize() {
<button
v-for="[label, rgb] in swatches"
:key="label"
class="inline-flex items-center gap-1.5 rounded-md border border-(--border) bg-(--bg-inset) px-2 py-0.5 text-xs font-medium text-(--fg-muted) transition hover:border-(--border-strong) cursor-pointer"
class="demo-badge transition hover:border-border-strong cursor-pointer"
@click="colorTarget = [...rgb]"
>
<span class="size-2.5 rounded-full" :style="{ backgroundColor: `rgb(${rgb.join(',')})` }" />
@@ -4,6 +4,7 @@ import { clamp, isFunction, isNumber, lerp, noop } from '@robonen/stdlib';
import { defaultWindow } from '@/types';
import type { ConfigurableWindow } from '@/types';
import { useRafFn } from '@/composables/animation/useRafFn';
import { tryOnScopeDispose } from '@/composables/lifecycle/tryOnScopeDispose';
/**
* Cubic bezier control points `[x1, y1, x2, y2]` (the implied endpoints are
@@ -356,5 +357,10 @@ export function useTransition<T extends TransitionValue>(
},
);
// The RAF loop is torn down by useRafFn on scope dispose, but a pending start
// delay (window.setTimeout) is not — clear it so the timer can't fire into a
// disposed scope.
tryOnScopeDispose(clearDelay);
return computed(() => outputRef.value);
}