-
Notifications
You must be signed in to change notification settings - Fork 3
XS⚠️ ◾ Replace Loader2 icon usages with LoadingState component #986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,28 @@ | ||
| import { Spinner } from "../ui/spinner"; | ||
|
|
||
| export function LoadingState() { | ||
| interface LoadingStateProps { | ||
| /** | ||
| * Extra classes applied to the spinner icon itself (e.g. "mr-2 h-4 w-4") so callers that | ||
| * previously rendered a bare `Loader2` icon inline can preserve their sizing/margin. | ||
| */ | ||
| className?: string; | ||
| /** | ||
| * When set, skips the default centered block wrapper (`flex items-center justify-center | ||
| * py-8`) so the spinner sits inline next to a label instead of taking over a full block. | ||
| * Callers migrating a small inline `Loader2` (inside a button, next to text, etc.) should | ||
| * pass `true`; full-page/section loaders should leave this unset to keep prior behaviour. | ||
| */ | ||
| inline?: boolean; | ||
| } | ||
|
|
||
| export function LoadingState({ className, inline = false }: LoadingStateProps = {}) { | ||
| if (inline) { | ||
| return <Spinner className={className} />; | ||
| } | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] Nothing enforces that an inline-sized flagged by: codex-rescue |
||
|
|
||
| return ( | ||
| <div className="flex items-center justify-center py-8"> | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] LoadingState conflates two visual roles behind a silent boolean default
flagged by: codex-rescue
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] New No test file exists for Suggested fix: a small dedicated test rendering flagged by: codex-rescue (fallback lens) |
||
| <Spinner /> | ||
| <Spinner className={className} /> | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] Inline vs block branches duplicate the Spinner render The two branches ( const spinner = <Spinner className={className} />;
return inline ? spinner : <div className="flex items-center justify-center py-8">{spinner}</div>;Purely stylistic — current form is also perfectly readable. flagged by: code-review |
||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,8 @@ | ||
| import type { LLMConfigV2, OrchestrationBackend, OrchestratorReadiness } from "@shared/types/llm"; | ||
| import { DEFAULT_ORCHESTRATION_BACKEND } from "@shared/types/llm"; | ||
| import { Loader2 } from "lucide-react"; | ||
| import { useCallback, useEffect, useState } from "react"; | ||
| import { toast } from "sonner"; | ||
| import { LoadingState } from "@/components/common/LoadingState"; | ||
| import { Button } from "@/components/ui/button"; | ||
| import { | ||
| Select, | ||
|
|
@@ -207,7 +207,7 @@ export function OrchestratorBackendSetting({ isActive }: OrchestratorBackendSett | |
| onClick={() => void checkReadiness()} | ||
| disabled={isCheckingReadiness} | ||
| > | ||
| {isCheckingReadiness && <Loader2 className="mr-1.5 h-3 w-3 animate-spin" />} | ||
| {isCheckingReadiness && <LoadingState inline className="mr-1.5 h-3 w-3" />} | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] Nested
Not blocking, but worth a look — consider suppressing flagged by: code-review lens |
||
| Re-check | ||
| </Button> | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,9 @@ | ||
| import { Copy, ExternalLink, Loader2 } from "lucide-react"; | ||
| import { Copy, ExternalLink } from "lucide-react"; | ||
| import { toast } from "sonner"; | ||
| import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; | ||
| import { useClipboard } from "../../hooks/useClipboard"; | ||
| import { UploadStatus, type VideoUploadResult } from "../../types"; | ||
| import { LoadingState } from "../common/LoadingState"; | ||
| import { Badge } from "../ui/badge"; | ||
| import { Button } from "../ui/button"; | ||
|
|
||
|
|
@@ -16,7 +17,7 @@ const openUrl = (url: string | null) => { | |
|
|
||
| const UploadingBadge = () => ( | ||
| <span className="text-sm font-medium px-3 py-1.5 rounded-full bg-white/10 text-white/80 border border-white/20 flex items-center gap-2"> | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] Loading spinner now announces redundant "Loading" to screen readers
flagged by: codex-rescue
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] Migrated inline spinners now announce role="status"/aria-label="Loading" next to visible text Both review lenses independently flagged this. This is arguably a net accessibility improvement over having no ARIA semantics at all, so it's not a regression worth blocking on — but it's a real, untested-for behavioral change the PR description doesn't call out (acceptance criteria only address visual/animate-spin parity). Worth a conscious decision: keep as-is (accept the duplication as an intentional improvement), or let flagged by: code-review + codex-rescue |
||
| <Loader2 className="w-3 h-3 animate-spin" /> | ||
| <LoadingState inline className="w-3 h-3" /> | ||
| Uploading | ||
| </span> | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,6 @@ import { | |
| CheckCircle2, | ||
| ChevronDown, | ||
| ChevronRight, | ||
| Loader2, | ||
| RefreshCw, | ||
| Sparkles, | ||
| XCircle, | ||
|
|
@@ -15,6 +14,7 @@ import { cn } from "@/lib/utils"; | |
| import { formatErrorMessage, isErrorStep } from "@/utils"; | ||
| import { ipcClient } from "../../services/ipc-client"; | ||
| import type { MCPStep } from "../../types"; | ||
| import { LoadingState } from "../common/LoadingState"; | ||
| import { Badge } from "../ui/badge"; | ||
| import { Button } from "../ui/button"; | ||
| import { Card, CardContent } from "../ui/card"; | ||
|
|
@@ -60,8 +60,8 @@ function OrchestratorBadge({ backend }: { backend: OrchestratorBackend }) { | |
|
|
||
| const STATUS_CONFIG = { | ||
| in_progress: { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor]
Suggested fix: drop the flagged by: both lenses independently (code-review + codex-rescue) |
||
| icon: Loader2, | ||
| iconClass: "animate-spin text-zinc-300", | ||
| icon: null, | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] STATUS_CONFIG.in_progress.icon is now dead/unused
flagged independently by both lenses: code-review + codex-rescue |
||
| iconClass: "text-zinc-300", | ||
| containerClass: "border-gray-500/30 bg-gray-500/5", | ||
| textClass: "text-white/90", | ||
| }, | ||
|
|
@@ -87,6 +87,11 @@ const STATUS_CONFIG = { | |
|
|
||
| function StatusIcon({ status, className }: { status: WorkflowStep["status"]; className?: string }) { | ||
| const config = STATUS_CONFIG[status as keyof typeof STATUS_CONFIG] || STATUS_CONFIG.not_started; | ||
|
|
||
| if (status === "in_progress") { | ||
| return <LoadingState inline className={cn("size-5", config.iconClass, className)} />; | ||
| } | ||
|
|
||
| const Icon = config.icon; | ||
|
|
||
| if (!Icon) { | ||
|
|
@@ -271,7 +276,7 @@ export function WorkflowStepCard({ step, label, shaveId }: WorkflowStepCardProps | |
| className="bg-white/[0.08] border border-white/[0.15] hover:bg-white/[0.12] text-white/80 shrink-0" | ||
| > | ||
| {isRetrying ? ( | ||
| <Loader2 className="size-3.5 animate-spin" /> | ||
| <LoadingState inline className="size-3.5" /> | ||
| ) : ( | ||
| <> | ||
| <RefreshCw className="size-3.5 mr-1.5" /> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Design note: this relocates rather than root-causes the loading-indicator inconsistency
Issue #708's presumed intent is that loading indicators are visually/behaviourally inconsistent across the app. This PR is a real improvement — it centralizes the icon and default
animate-spinbehaviour intoSpinner/LoadingState— but by adding two open-ended escape hatches (classNamefree-forms size/margin/colour per callsite,inlinetoggles layout), every callsite still hand-picks its own size (h-5 w-5/h-4 w-4/h-3 w-3/w-3 h-3/size-3.5/size-5) and colour (text-white/50,text-purple-200,text-zinc-300, unstyled). The visual inconsistency is preserved, just expressed throughclassNameprops on a shared component instead of rawLoader2props.Not blocking — worth naming as a follow-up if #708's real goal was visual consistency rather than code reuse: consider a
size/variantprop enum instead of openclassNameforwarding.flagged by: codex-rescue (fallback lens)