From 002b55c3c00776c649a81dd27db3a2ad2b5fcae2 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Fri, 29 May 2026 07:12:31 -0700 Subject: [PATCH] feat(tracker-web): reduced-motion-aware motion polish (UX-7) Add @bytelyst/motion (workspace:* + minimal lockfile importer entry). Apply Reveal to the dashboard overview cards/charts (staggered) and the items DataTable, and NumberFlow to the overview KPI totals. All motion primitives no-op under prefers-reduced-motion. The public /roadmap is intentionally left without entrance motion: the offline @axe-core gate scans the page synchronously and the Reveal transient sub-1 opacity trips color-contrast (a hard CC.4 a11y gate). The dashboard/items surfaces are auth-gated and not axe-scanned, so they keep the motion. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- dashboards/tracker-web/package.json | 1 + .../src/app/dashboard/items/page.tsx | 25 +++++++++++-------- .../tracker-web/src/app/dashboard/page.tsx | 19 ++++++++++---- pnpm-lock.yaml | 3 +++ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/dashboards/tracker-web/package.json b/dashboards/tracker-web/package.json index d06e2bad..b0bf308e 100644 --- a/dashboards/tracker-web/package.json +++ b/dashboards/tracker-web/package.json @@ -37,6 +37,7 @@ "@bytelyst/notifications-ui": "workspace:*", "@bytelyst/telemetry-client": "workspace:*", "@bytelyst/logger": "workspace:*", + "@bytelyst/motion": "workspace:*", "@bytelyst/ui": "workspace:*", "clsx": "^2.1.1", "next": "16.1.6", diff --git a/dashboards/tracker-web/src/app/dashboard/items/page.tsx b/dashboards/tracker-web/src/app/dashboard/items/page.tsx index fa8f4539..0e28fb21 100644 --- a/dashboards/tracker-web/src/app/dashboard/items/page.tsx +++ b/dashboards/tracker-web/src/app/dashboard/items/page.tsx @@ -4,6 +4,7 @@ import { useEffect, useState, useCallback, useMemo } from 'react'; import Link from 'next/link'; import { DataTable, type ColumnDef } from '@bytelyst/data-table'; import { PageHeader, LoadingSpinner } from '@bytelyst/dashboard-components'; +import { Reveal } from '@bytelyst/motion'; import { Button, Input, @@ -290,17 +291,19 @@ export default function ItemsListPage() { ) : ( - item.id} - enableFilter={false} - enableSorting - enablePagination - pageSize={15} - emptyState="No items found. Create one to get started." - /> + + item.id} + enableFilter={false} + enableSorting + enablePagination + pageSize={15} + emptyState="No items found. Create one to get started." + /> + )} {/* Create modal */} diff --git a/dashboards/tracker-web/src/app/dashboard/page.tsx b/dashboards/tracker-web/src/app/dashboard/page.tsx index fd5f54e7..7087f1a8 100644 --- a/dashboards/tracker-web/src/app/dashboard/page.tsx +++ b/dashboards/tracker-web/src/app/dashboard/page.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from 'react'; import dynamic from 'next/dynamic'; import { PageHeader, LoadingSpinner } from '@bytelyst/dashboard-components'; import { KpiCard } from '@bytelyst/data-viz'; +import { Reveal, NumberFlow } from '@bytelyst/motion'; import { Skeleton, toast } from '@/components/ui/Primitives'; import { useAuth } from '@/lib/auth-context'; import { getStats, type TrackerStats } from '@/lib/tracker-client'; @@ -39,14 +40,22 @@ export default function DashboardOverview() {
{/* KPI row */}
- - - - + {[ + { label: `Total · ${stats.productId}`, value: kpis.total }, + { label: 'Open', value: kpis.open }, + { label: 'In Progress', value: kpis.inProgress }, + { label: 'Done', value: kpis.done }, + ].map((k, i) => ( + + } /> + + ))}
{/* Charts */} - + + +
) : (
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a77938e9..d71b9f33 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -273,6 +273,9 @@ importers: '@bytelyst/logger': specifier: workspace:* version: link:../../packages/logger + '@bytelyst/motion': + specifier: workspace:* + version: link:../../packages/motion '@bytelyst/notifications-ui': specifier: workspace:* version: link:../../packages/notifications-ui