09/18/202609/20/202610/18/2026
1import { DueBadge } from "@/components/features/pxl/tasks/due-badge";2
3const formatDate = (date: Date) => {4 return date.toISOString().split("T")[0];5};6
7
8const addDays = (date: Date, days: number) => {9 const result = new Date(date);10 result.setDate(result.getDate() + days);11 return result;12};13
14export default function DueBadgeDemo() {15 const today = new Date();16
17 return (18 <div className="flex flex-col gap-4">19 <DueBadge value={formatDate(today)} />20
21 <DueBadge value={formatDate(addDays(today, 2))} />22
23 <DueBadge value={formatDate(addDays(today, 30))} />24 </div>25 );26}Installation
Section titled “Installation”pnpm dlx shadcn@latest add pxl-ui/registry/tasks/due-badge
Copy and paste the following code into your project.
1import type { ComponentProps } from "react";2
3import { Badge } from "@/components/ui/pxl/badge";4import type { TaskNotes } from "@/lib/schemas/pxl/tasknotes";5
6const dueVariants: Record<7 "default" | "incoming" | "expired",8 NonNullable<ComponentProps<typeof Badge>["variant"]>9> = {10 default: "muted",11 incoming: "warning",12 expired: "danger"13}14
15function formatDue(date: string | Date | number, locale?: string): string {16 if (typeof date === "string" && /^\d{4}-\d{2}-\d{2}$/.test(date)) {17 const [year, month, day] = date.split("-").map(Number);18
19 return new Intl.DateTimeFormat(locale, {20 day: "2-digit",21 month: "2-digit",22 year: "numeric",23 }).format(new Date(year, month - 1, day));24 }25
26 const value = new Date(date);27
28 if (Number.isNaN(value.getTime())) {29 return "";30 }31
32 return new Intl.DateTimeFormat(locale, {33 day: "2-digit",34 month: "2-digit",35 year: "numeric",36 hour: "2-digit",37 minute: "2-digit",38 }).format(value);39}40
41function getDueVariant(42 date: string | Date | number,43): ComponentProps<typeof Badge>["variant"] {44 const scheduled = new Date(date).getTime();45 const now = Date.now();46
47 if (Number.isNaN(scheduled)) {48 return dueVariants.default;49 }50
51 if (scheduled < now) {52 return dueVariants.expired;53 }54
55 const threeDays = 3 * 24 * 60 * 60 * 1000;56
57 if (scheduled <= now + threeDays) {58 return dueVariants.incoming;59 }60
61 return dueVariants.default;62}63
64function DueBadge({65 locale,66 value,67 ...props68}: ComponentProps<typeof Badge> & {69 locale?: string;70 value: string | Date | number;71}) {72 return (73 <Badge variant={getDueVariant(value)} {...props}>74 <svg75 xmlns="http://www.w3.org/2000/svg"76 fill="currentColor"77 viewBox="0 0 24 24"78 className="size-3 mr-1"79 >80 <path d="M13 22H5v-2h8v2Zm6 0h-2v-2h2v2ZM5 8h14V6h2v4H5v10H3V6h2v2Zm12 12h-2v-2h2v2Zm4 0h-2v-2h2v2Zm-6-2h-2v-2h2v2Zm8 0h-2v-2h2v2Zm-6-2h-2v-2h2v2Zm4 0h-2v-2h2v2ZM9 14H7v-2h2v2Zm4 0h-2v-2h2v2Zm6 0h-2v-2h2v2ZM9 4h6V2h2v2h2v2H5V4h2V2h2v2Z"></path>81 </svg>82 {formatDue(value, locale)}83 </Badge>84 );85}86
87function TaskNotesDueBadge({88 task,89 ...props90}: ComponentProps<typeof Badge> & {91 locale?: string;92 task: TaskNotes.Task;93}) {94 return task.due && <DueBadge {...props} value={task.due} />;95}96DueBadge.TaskNotes = TaskNotesDueBadge;97
98export { DueBadge };Update the import paths to match your project setup.
import { DueBadge } from "@/components/features/pxl/tasks/due-badge";<DueBadge value="2026-09-21" />