diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 980dcd62a..a5aa66e26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,9 @@ jobs: - name: Plugin license policy (0196) run: pnpm check:plugin-licenses + - name: Motion vocabulary (0199) + run: pnpm check:motion-vocab + # The heavy half of the old lint job: build the workspace and typecheck it. # typecheck genuinely needs `^build` (turbo builds dependencies first), so it # stays coupled to the build. Runs in parallel with `lint`, `test`, and diff --git a/apps/web/src/components/DataWorkspaceView.tsx b/apps/web/src/components/DataWorkspaceView.tsx index 69aa33760..1dfe37518 100644 --- a/apps/web/src/components/DataWorkspaceView.tsx +++ b/apps/web/src/components/DataWorkspaceView.tsx @@ -701,7 +701,7 @@ function SocialImportJobsPanel({ jobs }: { jobs: SocialImportJobProgress[] }): J aria-label={`Import progress for ${job.archiveName}`} >
diff --git a/apps/web/src/components/StorageWarningBanner.tsx b/apps/web/src/components/StorageWarningBanner.tsx index 627208a1f..2ca08e0a0 100644 --- a/apps/web/src/components/StorageWarningBanner.tsx +++ b/apps/web/src/components/StorageWarningBanner.tsx @@ -1,3 +1,4 @@ +import { Presence } from '@xnetjs/ui' import { AlertTriangle, CheckCircle2, Info, ShieldCheck, X } from 'lucide-react' import { useEffect, useRef, useState } from 'react' @@ -126,14 +127,13 @@ export function StorageWarningBanner({ ? `${formatBytes(usageBytes)} used of ${formatBytes(quotaBytes)} available` : null - if (dismissed) return null - return ( -
-
+
@@ -204,6 +204,6 @@ export function StorageWarningBanner({
-
+ ) } diff --git a/apps/web/src/components/UndoToast.tsx b/apps/web/src/components/UndoToast.tsx index 498d7ee87..7aedc178f 100644 --- a/apps/web/src/components/UndoToast.tsx +++ b/apps/web/src/components/UndoToast.tsx @@ -7,6 +7,7 @@ * keyboard hint reminds users the action is reversible. */ import { useGlobalUndo } from '@xnetjs/react' +import { Presence } from '@xnetjs/ui' import { createContext, useCallback, @@ -57,28 +58,40 @@ export function UndoToastProvider({ children }: { children: ReactNode }): JSX.El await undo() }, [undo]) + // Latch the last toast so its text survives the exit animation, when + // `toast` has already flipped to null but is still animating out. + // Horizontal centering uses auto-margins (not -translate-x-1/2) so the + // slide-up keyframe's translateY animates cleanly without fighting a static + // transform. + const lastToastRef = useRef<{ id: number; message: string } | null>(null) + if (toast) lastToastRef.current = toast + const shown = toast ?? lastToastRef.current + return ( {children} - {toast ? ( -
- {toast.message} - - - ⌘Z - -
- ) : null} + + {shown ? ( +
+ {shown.message} + + + ⌘Z + +
+ ) : null} +
) } diff --git a/apps/web/src/routes/social-import.tsx b/apps/web/src/routes/social-import.tsx index b7a63cf12..d88dd87c8 100644 --- a/apps/web/src/routes/social-import.tsx +++ b/apps/web/src/routes/social-import.tsx @@ -1032,7 +1032,7 @@ function CommitProgressPanel({ progress }: { progress: CommitProgress }): React. aria-label="Commit progress" >
diff --git a/apps/web/src/workbench/TabBreadcrumb.tsx b/apps/web/src/workbench/TabBreadcrumb.tsx index cc192d3a8..95622faa9 100644 --- a/apps/web/src/workbench/TabBreadcrumb.tsx +++ b/apps/web/src/workbench/TabBreadcrumb.tsx @@ -11,6 +11,7 @@ */ import { FolderSchema } from '@xnetjs/data' import { useQuery } from '@xnetjs/react' +import { useViewTransition } from '@xnetjs/ui' import { FolderClosed, Users } from 'lucide-react' import { Fragment, useMemo } from 'react' import { useSpaces } from '../hooks/useSpaces' @@ -53,6 +54,7 @@ export function TabBreadcrumb({ tab }: { tab: WorkbenchTab | null }) { const { folderNames, spaceId } = useBreadcrumb(tab) const { getSpace } = useSpaces() const setCurrentSpace = useWorkbench((state) => state.setCurrentSpace) + const withTransition = useViewTransition() const space = getSpace(spaceId) if (!space && folderNames.length === 0) return null @@ -62,7 +64,7 @@ export function TabBreadcrumb({ tab }: { tab: WorkbenchTab | null }) { {space ? (