diff --git a/apps/web/src/components/BranchToolbarBranchSelector.tsx b/apps/web/src/components/BranchToolbarBranchSelector.tsx index 8830b6bd180134c34ecb5bd17b4a12609fe317ed..ed8f1cd1f0266037f2c2db810db6bc74c033c8f4 100644 --- a/apps/web/src/components/BranchToolbarBranchSelector.tsx +++ b/apps/web/src/components/BranchToolbarBranchSelector.tsx @@ -905,7 +905,7 @@ export function BranchToolbarBranchSelector({ className="flex cursor-pointer items-center justify-between gap-3 border-t border-border/60 px-3 py-2 text-xs" > - } > - + {isRefreshingDiff ? "Refreshing diff…" : "Refresh diff"} diff --git a/apps/web/src/components/GitActionsControl.tsx b/apps/web/src/components/GitActionsControl.tsx index 92c28560135e2bbd3d8a74bb9663dcec61101ddd..4eca7867132e188137a67d95ba6a94fd731e70ae 100644 --- a/apps/web/src/components/GitActionsControl.tsx +++ b/apps/web/src/components/GitActionsControl.tsx @@ -851,7 +851,7 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) { aria-live="polite" className="flex items-center gap-2 rounded-md border border-input bg-muted/40 px-3 py-2 text-xs text-muted-foreground dark:border-transparent dark:bg-white/[0.035]" > - + Publishing repository to {publishProviderLabel}... ) : null} @@ -938,7 +938,7 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) { ); diff --git a/apps/web/src/components/device/DeviceLoadingView.tsx b/apps/web/src/components/device/DeviceLoadingView.tsx index 332d3994cca1e072198a546451d6a30c8cf8887c..1a320c30f8b9e8941ea4d623441db3ea3bce0d06 100644 --- a/apps/web/src/components/device/DeviceLoadingView.tsx +++ b/apps/web/src/components/device/DeviceLoadingView.tsx @@ -27,7 +27,7 @@ export function DeviceLoadingView(props: { ) : null}
- {!props.error ? : null} + {!props.error ? : null} {props.message}
{props.children} diff --git a/apps/web/src/components/device/DevicePanel.tsx b/apps/web/src/components/device/DevicePanel.tsx index 130353943352970f576b7de948bffadaf4c9403c..f46a9fbf8ed7f2c3ef841a2a4ccbad456f42c67a 100644 --- a/apps/web/src/components/device/DevicePanel.tsx +++ b/apps/web/src/components/device/DevicePanel.tsx @@ -367,7 +367,7 @@ export function DevicePanel(props: { onClick={() => void selectDevice(deviceKey(device))} action={ pendingDeviceKey === deviceKey(device) ? ( - + ) : ( {device.booted ? "Open" : "Start"} diff --git a/apps/web/src/components/device/DeviceSetup.tsx b/apps/web/src/components/device/DeviceSetup.tsx index 5ef41b4cefd90cd5bbbc18c548f5c4ff7e11a465..9a77fe925715edfaa14a98eb40113f971f1b7dc9 100644 --- a/apps/web/src/components/device/DeviceSetup.tsx +++ b/apps/web/src/components/device/DeviceSetup.tsx @@ -203,7 +203,7 @@ export function DeviceHubSetupStatus({ if (!pending && state.hostStatus !== "ready") return null; return (

- {pending ? : } + {pending ? : } {pending ? state.hostStatus === "installing" ? compact @@ -235,7 +235,7 @@ function DevicePlatformSetup(props: { You can use either platform. Fixing a missing platform does not block the other one.

@@ -262,7 +262,7 @@ export function AgentDeviceSetupStatus(props: { : "Updating agent access…"; return (

- + {label}

); diff --git a/apps/web/src/components/device/DeviceToolsPanel.tsx b/apps/web/src/components/device/DeviceToolsPanel.tsx index 7f3984257ecddc5799c703d7baa3ff2ffc471b44..79f84529aebb4e399c19a37fce2c0798637de9ca 100644 --- a/apps/web/src/components/device/DeviceToolsPanel.tsx +++ b/apps/web/src/components/device/DeviceToolsPanel.tsx @@ -173,7 +173,7 @@ export function DeviceToolsPanel(props: { >
Tools - {pending ? : null} + {pending ? : null}
) : null} diff --git a/apps/web/src/components/files/FilePreviewPanel.tsx b/apps/web/src/components/files/FilePreviewPanel.tsx index 1d89d58bc67fc74d4d9ebd0054c06d5d714776e5..9e9464ca4516bcd09324e30178e96372de1dc895 100644 --- a/apps/web/src/components/files/FilePreviewPanel.tsx +++ b/apps/web/src/components/files/FilePreviewPanel.tsx @@ -169,7 +169,7 @@ function WorkspaceImagePreview(props: { ) : (
- +
); } @@ -214,7 +214,7 @@ function WorkspaceBrowserPreview(props: { if (assetUrl._tag !== "Success") { return (
- +
); } @@ -1232,7 +1232,7 @@ export default function FilePreviewPanel({ ) : relativePath && file.data === null ? (
- +
) : relativePath && file.data ? ( isMarkdown && renderMarkdown ? ( diff --git a/apps/web/src/components/files/fileSurfaceChrome.tsx b/apps/web/src/components/files/fileSurfaceChrome.tsx index 6c7c9eb284be0e06f899b8ed200cd2f89056ba44..4425ba6cd5e82ba572533dc43d80b2ab22de269e 100644 --- a/apps/web/src/components/files/fileSurfaceChrome.tsx +++ b/apps/web/src/components/files/fileSurfaceChrome.tsx @@ -131,7 +131,7 @@ export function FileSurfaceLoading(props: { readonly className?: string }) { props.className, )} > - + ); } diff --git a/apps/web/src/components/onboarding/WelcomeWizard.tsx b/apps/web/src/components/onboarding/WelcomeWizard.tsx index 5c6517e154a1a02ee6a3e7adc613915b6f146d64..7e8dea7f2dea9c38b7be17c90223896a4f647be1 100644 --- a/apps/web/src/components/onboarding/WelcomeWizard.tsx +++ b/apps/web/src/components/onboarding/WelcomeWizard.tsx @@ -1162,7 +1162,7 @@ function ImportStep({

Your projects

- +

Looking for projects from Claude Code and Codex…

@@ -1229,7 +1229,7 @@ function ImportStep({ ) : null} {scan.isPending && scan.data === null ? (
- + Looking for projects…
) : scan.error !== null ? ( diff --git a/apps/web/src/components/pullRequest/PullRequestActivityUnavailableState.tsx b/apps/web/src/components/pullRequest/PullRequestActivityUnavailableState.tsx index 2aa1413438eef6e1e1f9f6cc46373f183f404ea8..388aacaf0e815a40bc4013b95f7e45308be9ed1f 100644 --- a/apps/web/src/components/pullRequest/PullRequestActivityUnavailableState.tsx +++ b/apps/web/src/components/pullRequest/PullRequestActivityUnavailableState.tsx @@ -23,7 +23,7 @@ export function PullRequestActivityUnavailableState({

Could not load pull request activity

{error}

diff --git a/apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx b/apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx index de9a1cd03fe925b48307f1052e9e5452691d3d1c..fb36fcd087522b5251c8d119d419534ed30eb81c 100644 --- a/apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx +++ b/apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx @@ -2010,7 +2010,7 @@ export function PullRequestDetailPanel({ the spinning glyph in place of the dots: the reader sees the panel is fetching without a control appearing or the row shifting. */} {refreshing ? ( - + ) : ( )} @@ -2034,7 +2034,7 @@ export function PullRequestDetailPanel({ onPickerOpenChange={setThreadPickerOpen} /> void refreshFromHost()}> - + Refresh diff --git a/apps/web/src/components/pullRequest/PullRequestListEmptyState.tsx b/apps/web/src/components/pullRequest/PullRequestListEmptyState.tsx index 8c5f862700bc6e3970c1ae84035e87315cbbfef3..6c4fb9769b433de7cf60424e2703fc4584de6872 100644 --- a/apps/web/src/components/pullRequest/PullRequestListEmptyState.tsx +++ b/apps/web/src/components/pullRequest/PullRequestListEmptyState.tsx @@ -150,7 +150,7 @@ export function PullRequestListEmptyState({ {/* The hosts answered this query once; a pull request opened since then would answer differently, and nothing on screen says which of the two the reader is looking at. */} @@ -176,7 +176,7 @@ export function PullRequestListEmptyState({ ) : null} diff --git a/apps/web/src/components/pullRequest/PullRequestsUnavailableState.tsx b/apps/web/src/components/pullRequest/PullRequestsUnavailableState.tsx index f2f509944c46784bd253e0c9035097a3caca2f1b..364df38b3e7db5b726ec8f7bf161cf9dcca977c7 100644 --- a/apps/web/src/components/pullRequest/PullRequestsUnavailableState.tsx +++ b/apps/web/src/components/pullRequest/PullRequestsUnavailableState.tsx @@ -46,7 +46,7 @@ export function PullRequestsUnavailableState({ disabled={refreshing} aria-busy={refreshing} > - + Retry ) : null} diff --git a/apps/web/src/components/search/ProjectContentSearchDialog.tsx b/apps/web/src/components/search/ProjectContentSearchDialog.tsx index 26015c5b33933d70e261997295b4f793d628566b..f8707dbf68f3044c164fcbef4cbcca138f5be487 100644 --- a/apps/web/src/components/search/ProjectContentSearchDialog.tsx +++ b/apps/web/src/components/search/ProjectContentSearchDialog.tsx @@ -226,7 +226,7 @@ function OpenContentSearchDialog(props: {
{search.isPending ? ( - Searching… + Searching… ) : search.error ? ( {search.error} diff --git a/apps/web/src/components/settings/BrowserImportWizard.tsx b/apps/web/src/components/settings/BrowserImportWizard.tsx index 7dd5e7d266cf57c623121f5a9df05f14e1d8f33c..81d1f480d8d09c1bcbe74beb98a5ad0fd0fd7093 100644 --- a/apps/web/src/components/settings/BrowserImportWizard.tsx +++ b/apps/web/src/components/settings/BrowserImportWizard.tsx @@ -491,7 +491,7 @@ function ImportingStep() { This may take a moment. - + Importing… @@ -516,7 +516,7 @@ function CheckingStep({ - + {check === "fullDiskAccess" ? "Checking access…" : "Checking…"} diff --git a/apps/web/src/components/settings/ConnectionsSettings.tsx b/apps/web/src/components/settings/ConnectionsSettings.tsx index 1410b3b5e0e7c7f17208cf672965ef00fc1e5fe6..0adc7aed91819d427d55e44ed4056b41ddc5507d 100644 --- a/apps/web/src/components/settings/ConnectionsSettings.tsx +++ b/apps/web/src/components/settings/ConnectionsSettings.tsx @@ -3435,7 +3435,7 @@ export function ConnectionsSettings() { pendingDesktopServerExposureMode === null || isUpdatingDesktopServerExposure } > - {isUpdatingDesktopServerExposure && } + {isUpdatingDesktopServerExposure && } {isUpdatingDesktopServerExposure ? "Restarting…" @@ -3499,7 +3499,7 @@ export function ConnectionsSettings() { > {isUpdatingWslBackend ? ( <> - + Applying… ) : ( @@ -3513,7 +3513,7 @@ export function ConnectionsSettings() { > {isUpdatingWslBackend ? ( <> - + Applying… ) : ( @@ -3534,7 +3534,7 @@ export function ConnectionsSettings() { > {isUpdatingWslBackend ? ( <> - + Applying… ) : pendingWslChange?.kind === "disable" ? ( @@ -3583,7 +3583,7 @@ export function ConnectionsSettings() { > {isUpdatingTailscaleServe ? ( <> - + Restarting… ) : ( @@ -3657,7 +3657,7 @@ export function ConnectionsSettings() { > {isUpdatingTailscaleServe ? ( <> - + Restarting… ) : ( diff --git a/apps/web/src/components/settings/DeviceHostEditor.tsx b/apps/web/src/components/settings/DeviceHostEditor.tsx index 4ab03ad3c156a4131e2bbb922731d1ea075e5174..926f404be2e9a107ba902d51c2d8ce5f4dfcdf5e 100644 --- a/apps/web/src/components/settings/DeviceHostEditor.tsx +++ b/apps/web/src/components/settings/DeviceHostEditor.tsx @@ -156,7 +156,7 @@ export function DeviceHostEditor({ if (Option.isSome(input)) void testConnection(input.value); }} > - {checking ? : null} Test connection + {checking ? : null} Test connection
{results ? ( @@ -173,7 +173,7 @@ export function DeviceHostEditor({ > {result.status === "pending" ? ( <> - Checking… + Checking… ) : result.status === "local" ? ( <> @@ -215,7 +215,7 @@ export function DeviceHostEditor({ Cancel diff --git a/apps/web/src/components/settings/DeviceHostsSettings.tsx b/apps/web/src/components/settings/DeviceHostsSettings.tsx index ffed54e14643ca3a6dbebf2491f43b42a71108ef..9669a3539fd3b2fd2c9524995189c6a845ae2f9e 100644 --- a/apps/web/src/components/settings/DeviceHostsSettings.tsx +++ b/apps/web/src/components/settings/DeviceHostsSettings.tsx @@ -267,7 +267,7 @@ function DeviceHostList({ role="status" className="inline-flex items-center gap-1.5 text-xs text-muted-foreground" > - + {progress} ) : null} diff --git a/apps/web/src/components/settings/LocalEnvironmentSetting.tsx b/apps/web/src/components/settings/LocalEnvironmentSetting.tsx index d32e28030074e8937b1b7bed0062bbf5e48610f4..d8fb2e894b343ca9c00ef91c7857f50736ba5e70 100644 --- a/apps/web/src/components/settings/LocalEnvironmentSetting.tsx +++ b/apps/web/src/components/settings/LocalEnvironmentSetting.tsx @@ -86,7 +86,7 @@ export function LocalEnvironmentSetting() { > {isUpdating ? ( <> - + Restarting… ) : enabled ? ( diff --git a/apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx b/apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx index b10ed02c477ee6d05521041c82ef0ad3ae763e84..51cabd6010bc2cd8ec6979e360156f7a9e1fe06f 100644 --- a/apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx +++ b/apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx @@ -976,7 +976,7 @@ export function ResourceTelemetryDiagnostics({ onClick={telemetry.refresh} aria-label="Refresh resource telemetry" > - + } /> @@ -1087,7 +1087,7 @@ export function ResourceTelemetryDiagnostics({ headerAction={ collectorNeedsRetry ? ( ) : null @@ -1225,7 +1225,7 @@ export function ResourceTelemetryDiagnostics({ onClick={history.refresh} aria-label="Refresh resource history" > - +
} diff --git a/apps/web/src/components/settings/SettingsPanels.tsx b/apps/web/src/components/settings/SettingsPanels.tsx index a827cfe7bb26c05d939fc90172a543d80364cd68..6ea08076ad885d5236bc39e6a40e5dc6074ba055 100644 --- a/apps/web/src/components/settings/SettingsPanels.tsx +++ b/apps/web/src/components/settings/SettingsPanels.tsx @@ -3359,7 +3359,7 @@ export function ArchivedThreadsPanel() { title={ {isLoadingArchive ? ( - + ) : ( )} diff --git a/apps/web/src/components/settings/SourceControlSettings.tsx b/apps/web/src/components/settings/SourceControlSettings.tsx index 14af53fd12b432c3faae6c6b60a2d92a00360665..d7d8be98cc66cb8e3a4f1776a092c31a65f336a6 100644 --- a/apps/web/src/components/settings/SourceControlSettings.tsx +++ b/apps/web/src/components/settings/SourceControlSettings.tsx @@ -491,7 +491,7 @@ function EmptySourceControlDiscovery({ diff --git a/apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx b/apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx index 7b1d5c25fcf59f60ff0c6787b45c2055fda1c402..4e9547842353cbbb74f18202d7eb35fdcd061137 100644 --- a/apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx +++ b/apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx @@ -174,7 +174,7 @@ export function SidebarProviderUpdatePill() { onClick={openProviderSettings} > {displayedView.tone === "loading" ? ( - + ) : displayedView.tone === "success" ? ( ) : displayedView.tone === "error" ? ( diff --git a/apps/web/src/components/ui/refresh-icon.tsx b/apps/web/src/components/ui/refresh-icon.tsx index 6fbddeb365a681ebad3664dbb617679b36e73842..9d31c8b29453859a241c8fe94b9d2108e9e54563 100644 --- a/apps/web/src/components/ui/refresh-icon.tsx +++ b/apps/web/src/components/ui/refresh-icon.tsx @@ -1,19 +1,38 @@ import { RefreshCwIcon } from "lucide-react"; +import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "~/lib/utils"; import { observeVisibleAnimation } from "~/lib/visibleAnimation"; +// No default size: inside a Button the parent's svg rule sizes the glyph. +const refreshIconVariants = cva("", { + variants: { + size: { + xs: "size-3", + sm: "size-3.5", + md: "size-4", + lg: "size-5", + }, + }, +}); + /** Keep the refresh glyph in place while its owning action is running. */ export function RefreshIcon({ refreshing = false, className, + size, ...props -}: React.ComponentPropsWithoutRef & { refreshing?: boolean }) { +}: React.ComponentPropsWithoutRef & + VariantProps & { refreshing?: boolean }) { return ( ); diff --git a/apps/web/src/components/ui/spinner.tsx b/apps/web/src/components/ui/spinner.tsx index 44f0ffd5081646eb3f4d3b18e723d9af758c0b6c..f3b3035e90f8066685e8401bdf11ddc99b81e027 100644 --- a/apps/web/src/components/ui/spinner.tsx +++ b/apps/web/src/components/ui/spinner.tsx @@ -1,13 +1,36 @@ import { LoaderCircleIcon } from "lucide-react"; +import { cva, type VariantProps } from "class-variance-authority"; import { observeVisibleAnimation } from "~/lib/visibleAnimation"; import { cn } from "~/lib/utils"; -function Spinner({ className, ...props }: React.ComponentPropsWithoutRef) { +// No default size: inside a Button the parent's svg rule sizes the glyph. +const spinnerVariants = cva("motion-safe:visible-animate-spin", { + variants: { + size: { + xs: "size-3", + sm: "size-3.5", + md: "size-4", + lg: "size-5", + }, + tone: { + current: "", + muted: "text-muted-foreground", + }, + }, + defaultVariants: { tone: "current" }, +}); + +function Spinner({ + className, + size, + tone, + ...props +}: React.ComponentPropsWithoutRef & VariantProps) { return ( diff --git a/apps/web/src/components/usage/UsagePage.tsx b/apps/web/src/components/usage/UsagePage.tsx index 6e22f5ad85e664974e7d22a1ad0b7d93a58ff38c..8c2b0680d71b2384c6ff68471acbe11fe0ee80c3 100644 --- a/apps/web/src/components/usage/UsagePage.tsx +++ b/apps/web/src/components/usage/UsagePage.tsx @@ -300,7 +300,7 @@ export function UsagePage() { size="icon-sm" variant="ghost" > - +
@@ -359,7 +359,7 @@ export function UsagePage() { size="icon-sm" variant="ghost" > - +
diff --git a/apps/web/src/routes/_chat.index.tsx b/apps/web/src/routes/_chat.index.tsx index c001e52775b5189b785fc3198eabe1b3f8b5d5b1..703c0312f19df5958e1fb3246bea95348960e40e 100644 --- a/apps/web/src/routes/_chat.index.tsx +++ b/apps/web/src/routes/_chat.index.tsx @@ -99,7 +99,7 @@ function DraftStartError({ onRetry }: { readonly onRetry: () => void }) {
diff --git a/apps/web/src/routes/_chat.pull-requests.tsx b/apps/web/src/routes/_chat.pull-requests.tsx index 5ed33d27b5a63b2155bce05290294eeb6d75e1ff..ce2bd238746a2aada7ba0c6877c97d4332ac04a3 100644 --- a/apps/web/src/routes/_chat.pull-requests.tsx +++ b/apps/web/src/routes/_chat.pull-requests.tsx @@ -1830,7 +1830,7 @@ function PullRequestsRouteView() {
{loadingMore ? ( - + {sentCursors === null ? "Updating pull requests" : "Loading more"} ) : canContinue || pageSize < MAX_PAGE_SIZE ? ( @@ -2592,7 +2592,7 @@ function PullRequestRefreshControl({ onClick={onRefresh} disabled={refreshing} > - + ); } diff --git a/scripts/lint-restyle-ceiling.ts b/scripts/lint-restyle-ceiling.ts index 9c93a8d466e7a1a37ef033d018b50dbded8af0ba..30866b393a65e45cfb2f450a04b99da4d9e85c4f 100644 --- a/scripts/lint-restyle-ceiling.ts +++ b/scripts/lint-restyle-ceiling.ts @@ -8,7 +8,7 @@ import * as NodeURL from "node:url"; // components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the // count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you // migrate a file, and delete this script when the rule becomes an error. -export const RESTYLE_CEILING = 1214; +export const RESTYLE_CEILING = 1207; const RULE = "shadcn(no-restyle)";