افزودن سیستم Motion به تمام بخشهای رابط کاربری
واژگان مشترک حرکت در globals.css: شش @keyframes و شش کلاس .anim-* بههمراه .anim-stagger برای ورود آبشاری. همهٔ مدتزمانها پشت custom property هستند تا یک override کل اپ را تنظیم کند. - packages/ui: Button، Card، Stat، Loading/Empty/ErrorState، UsageBar، Timeline، Modal، Drawer، Table، ToastStack و ArtifactViewer - ریشهٔ هر صفحهٔ (app) با .anim-stagger وارد میشود - AppShell: محتوا fade، منوی کنار stagger، منوهای کشویی slide-up - prefers-reduced-motion مدتزمانها را به ۰.۰۱ms میرساند تا وضعیت پایانی حفظ شود - قرارداد motion در src/test/motion.test.tsx تست میشود تا بازنویسی بعدی آن را بیصدا حذف نکند - تستهای فرانتاند: ۳۵ ← ۴۵
This commit is contained in:
@@ -66,7 +66,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
<span className="text-sm font-medium text-slate-100">Smart Organization</span>
|
||||
</div>
|
||||
|
||||
<nav className="flex flex-1 flex-col gap-1 p-3">
|
||||
<nav className="anim-stagger flex flex-1 flex-col gap-1 p-3">
|
||||
{NAV_ITEMS.map((item) => {
|
||||
const active = pathname === item.href || pathname.startsWith(`${item.href}/`);
|
||||
return (
|
||||
@@ -126,7 +126,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
{activeOrganization?.name ?? "بدون سازمان"}
|
||||
</Button>
|
||||
{menuOpen && (
|
||||
<div className="absolute right-0 top-10 z-40 w-64 rounded-lg border border-surface-border bg-surface-overlay p-1.5">
|
||||
<div className="anim-slide-up absolute right-0 top-10 z-40 w-64 rounded-lg border border-surface-border bg-surface-overlay p-1.5">
|
||||
{organizations.length === 0 && (
|
||||
<p className="px-2 py-2 text-xs text-slate-400">هنوز سازمانی نساختهاید.</p>
|
||||
)}
|
||||
@@ -179,7 +179,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
{user?.is_platform_owner && <Badge tone="info">مالک سامانه</Badge>}
|
||||
</button>
|
||||
{userMenuOpen && (
|
||||
<div className="absolute end-0 top-11 z-40 w-56 rounded-lg border border-surface-border bg-surface-overlay p-1.5">
|
||||
<div className="anim-slide-up absolute end-0 top-11 z-40 w-56 rounded-lg border border-surface-border bg-surface-overlay p-1.5">
|
||||
<div className="px-2 py-1.5">
|
||||
<p className="truncate text-xs text-slate-200">
|
||||
{user?.name || "کاربر"}
|
||||
@@ -215,7 +215,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="min-w-0 flex-1 p-5">{children}</main>
|
||||
<main className="anim-fade-in min-w-0 flex-1 p-5">{children}</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -173,7 +173,7 @@ export function CommandPalette({ isPlatformOwner = false }: { isPlatformOwner?:
|
||||
<EmptyState title="نتیجهای پیدا نشد" description="عبارت دیگری را امتحان کنید." />
|
||||
) : (
|
||||
filteredGroups.map((group) => (
|
||||
<div key={group.title} className="flex flex-col gap-1">
|
||||
<div key={group.title} className="anim-stagger flex flex-col gap-1">
|
||||
<p className="px-1 text-[11px] font-medium text-slate-500">{group.title}</p>
|
||||
{group.items.map((item) => {
|
||||
const index = visible.indexOf(item);
|
||||
|
||||
Reference in New Issue
Block a user