| author | |
| committer | |
| log | 83bbfa7e87e16a3c21413fe55524c1d05ce88dab |
| tree | d4d6fc2ec60a35b3a97f1db47f30676c40585814 |
| parent | 1c2f933892cce833823fcfbf3099a51813ba67fb |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>12 files changed, 52 insertions(+), 71 deletions(-)
apps/web/src/components/CommandPalette.tsx+2-2| ... | ... | @@ -2874,7 +2874,7 @@ function OpenCommandPaletteDialog(props: { |
| 2874 | 2874 | } |
| 2875 | 2875 | > |
| 2876 | 2876 | <span>{isRemoteProjectPending ? "Working" : remoteProjectButtonLabel}</span> |
| 2877 | <KbdGroup className="pointer-events-none -me-0.5 items-center gap-1"> | |
| 2877 | <KbdGroup className="pointer-events-none -me-0.5"> | |
| 2878 | 2878 | <Kbd>Enter</Kbd> |
| 2879 | 2879 | </KbdGroup> |
| 2880 | 2880 | </TooltipTrigger> |
| ... | ... | @@ -2917,7 +2917,7 @@ function OpenCommandPaletteDialog(props: { |
| 2917 | 2917 | <span> |
| 2918 | 2918 | {isCloneDestinationStep && isRemoteProjectPending ? "Cloning" : submitActionLabel} |
| 2919 | 2919 | </span> |
| 2920 | <KbdGroup className="pointer-events-none -me-0.5 items-center gap-1"> | |
| 2920 | <KbdGroup className="pointer-events-none -me-0.5"> | |
| 2921 | 2921 | <Kbd>{hasHighlightedBrowseItem ? `${submitModifierLabel} Enter` : "Enter"}</Kbd> |
| 2922 | 2922 | </KbdGroup> |
| 2923 | 2923 | </TooltipTrigger> |
apps/web/src/components/CommandPaletteContent.tsx+4-4| ... | ... | @@ -52,7 +52,7 @@ export function CommandPaletteContent({ |
| 52 | 52 | <CommandPanel className={panelClassName}>{children}</CommandPanel> |
| 53 | 53 | <CommandFooter className="gap-3 max-sm:flex-col max-sm:items-start"> |
| 54 | 54 | <div className="flex items-center gap-3"> |
| 55 | <KbdGroup className="items-center gap-1.5"> | |
| 55 | <KbdGroup> | |
| 56 | 56 | <Kbd> |
| 57 | 57 | <ArrowUpIcon /> |
| 58 | 58 | </Kbd> |
| ... | ... | @@ -62,18 +62,18 @@ export function CommandPaletteContent({ |
| 62 | 62 | <span>Navigate</span> |
| 63 | 63 | </KbdGroup> |
| 64 | 64 | {footerActionLabel !== undefined ? ( |
| 65 | <KbdGroup className="items-center gap-1.5"> | |
| 65 | <KbdGroup> | |
| 66 | 66 | <Kbd>Enter</Kbd> |
| 67 | 67 | <span>{footerActionLabel}</span> |
| 68 | 68 | </KbdGroup> |
| 69 | 69 | ) : null} |
| 70 | 70 | {showBackHint ? ( |
| 71 | <KbdGroup className="items-center gap-1.5"> | |
| 71 | <KbdGroup> | |
| 72 | 72 | <Kbd>Backspace</Kbd> |
| 73 | 73 | <span>Back</span> |
| 74 | 74 | </KbdGroup> |
| 75 | 75 | ) : null} |
| 76 | <KbdGroup className="items-center gap-1.5"> | |
| 76 | <KbdGroup> | |
| 77 | 77 | <Kbd>Esc</Kbd> |
| 78 | 78 | <span>{escapeLabel}</span> |
| 79 | 79 | </KbdGroup> |
apps/web/src/components/LegacySidebar.tsx+5-14| ... | ... | @@ -2673,18 +2673,13 @@ function LocalSecondaryStatus() { |
| 2673 | 2673 | return ( |
| 2674 | 2674 | <SidebarGroup> |
| 2675 | 2675 | {connecting.length > 0 ? ( |
| 2676 | <Alert | |
| 2677 | variant="default" | |
| 2678 | className="rounded-2xl border-border/40 bg-accent/40 text-muted-foreground" | |
| 2679 | > | |
| 2676 | <Alert variant="sidebar"> | |
| 2680 | 2677 | <Spinner /> |
| 2681 | <AlertTitle className="text-xs font-medium text-foreground"> | |
| 2682 | Connecting {connecting.join(", ")} | |
| 2683 | </AlertTitle> | |
| 2678 | <AlertTitle>Connecting {connecting.join(", ")}</AlertTitle> | |
| 2684 | 2679 | </Alert> |
| 2685 | 2680 | ) : null} |
| 2686 | 2681 | {failed.length > 0 ? ( |
| 2687 | <Alert variant="warning" className="rounded-2xl border-warning/40 bg-warning/8"> | |
| 2682 | <Alert variant="warning"> | |
| 2688 | 2683 | <TriangleAlertIcon /> |
| 2689 | 2684 | <AlertTitle>Couldn't connect {failed.map((entry) => entry.label).join(", ")}</AlertTitle> |
| 2690 | 2685 | <AlertDescription> |
| ... | ... | @@ -2980,11 +2975,7 @@ const SidebarProjectsContent = memo(function SidebarProjectsContent( |
| 2980 | 2975 | > |
| 2981 | 2976 | <SearchIcon /> |
| 2982 | 2977 | <span className="flex-1 truncate">Search</span> |
| 2983 | {commandPaletteShortcutLabel ? ( | |
| 2984 | <Kbd className="h-4 min-w-0 rounded-sm px-1.5 text-[10px]"> | |
| 2985 | {commandPaletteShortcutLabel} | |
| 2986 | </Kbd> | |
| 2987 | ) : null} | |
| 2978 | {commandPaletteShortcutLabel ? <Kbd>{commandPaletteShortcutLabel}</Kbd> : null} | |
| 2988 | 2979 | </CommandDialogTrigger> |
| 2989 | 2980 | </SidebarMenuItem> |
| 2990 | 2981 | </SidebarMenu> |
| ... | ... | @@ -2993,7 +2984,7 @@ const SidebarProjectsContent = memo(function SidebarProjectsContent( |
| 2993 | 2984 | > |
| 2994 | 2985 | {showArm64IntelBuildWarning && arm64IntelBuildWarningDescription ? ( |
| 2995 | 2986 | <SidebarGroup> |
| 2996 | <Alert variant="warning" className="rounded-2xl border-warning/40 bg-warning/8"> | |
| 2987 | <Alert variant="warning"> | |
| 2997 | 2988 | <TriangleAlertIcon /> |
| 2998 | 2989 | <AlertTitle>Intel build on Apple Silicon</AlertTitle> |
| 2999 | 2990 | <AlertDescription>{arm64IntelBuildWarningDescription}</AlertDescription> |
apps/web/src/components/chat/ModelListRow.tsx+1-3| ... | ... | @@ -98,9 +98,7 @@ export const ModelListRow = memo(function ModelListRow(props: { |
| 98 | 98 | {props.showSelection && props.isSelected ? ( |
| 99 | 99 | <CheckIcon className="size-3.5" aria-hidden="true" /> |
| 100 | 100 | ) : null} |
| 101 | {props.jumpLabel ? ( | |
| 102 | <Kbd className="h-4 min-w-0 rounded-sm px-1.5 text-[10px]">{props.jumpLabel}</Kbd> | |
| 103 | ) : null} | |
| 101 | {props.jumpLabel ? <Kbd>{props.jumpLabel}</Kbd> : null} | |
| 104 | 102 | <Tooltip> |
| 105 | 103 | <TooltipTrigger |
| 106 | 104 | render={ |
apps/web/src/components/chat/ProviderStatusBanner.tsx+24-35| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | import { type ProviderInstanceId, type ServerProvider } from "@t3tools/contracts"; |
| 2 | 2 | import { memo } from "react"; |
| 3 | 3 | import { InfoIcon, XIcon } from "lucide-react"; |
| 4 | import { cn } from "~/lib/utils"; | |
| 5 | import { Button } from "../ui/button"; | |
| 4 | import { Alert, AlertAction, AlertDescription, AlertTitle } from "../ui/alert"; | |
| 5 | import { Button, InlineButton } from "../ui/button"; | |
| 6 | 6 | import { formatProviderDriverKindLabel } from "../../providerModels"; |
| 7 | 7 | import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; |
| 8 | 8 | |
| ... | ... | @@ -83,48 +83,37 @@ export const ProviderStatusBanner = memo(function ProviderStatusBanner({ |
| 83 | 83 | |
| 84 | 84 | return ( |
| 85 | 85 | <div className="pointer-events-auto mx-auto w-fit max-w-[calc(100%-2rem)] pt-3"> |
| 86 | <div | |
| 87 | className={cn( | |
| 88 | "alert-glass relative inline-flex items-center gap-3 rounded-xl border py-3 ps-3.5 pe-10 text-card-foreground text-sm", | |
| 89 | status.status === "warning" | |
| 90 | ? "border-warning/32 [&_svg]:text-warning" | |
| 91 | : "border-destructive/32 text-destructive-foreground [&_svg]:text-destructive", | |
| 92 | )} | |
| 93 | data-variant={status.status === "warning" ? "warning" : "error"} | |
| 94 | role="alert" | |
| 86 | <Alert | |
| 87 | variant={status.status === "warning" ? "warning" : "error"} | |
| 88 | surface="glass" | |
| 89 | controlAlignment="first-line" | |
| 95 | 90 | > |
| 96 | <InfoIcon className="size-4 shrink-0" aria-hidden /> | |
| 97 | <div className="flex min-w-0 flex-col gap-1"> | |
| 98 | <div className="font-medium">{title}</div> | |
| 91 | <InfoIcon /> | |
| 92 | <AlertTitle>{title}</AlertTitle> | |
| 93 | <AlertDescription> | |
| 99 | 94 | <Tooltip> |
| 100 | <TooltipTrigger | |
| 101 | render={<div className="line-clamp-3 text-muted-foreground">{message}</div>} | |
| 102 | /> | |
| 95 | <TooltipTrigger render={<div className="line-clamp-3" />}>{message}</TooltipTrigger> | |
| 103 | 96 | <TooltipPopup side="top" className="whitespace-pre-wrap"> |
| 104 | 97 | {message} |
| 105 | 98 | </TooltipPopup> |
| 106 | 99 | </Tooltip> |
| 107 | 100 | {onOpenProviderSetup && hasProviderSetup(status) ? ( |
| 108 | <Button | |
| 109 | className="self-start px-0 text-foreground" | |
| 110 | onClick={() => onOpenProviderSetup(status.instanceId)} | |
| 111 | size="xs" | |
| 112 | variant="link" | |
| 113 | > | |
| 101 | <InlineButton onClick={() => onOpenProviderSetup(status.instanceId)}> | |
| 114 | 102 | Open provider setup |
| 115 | </Button> | |
| 103 | </InlineButton> | |
| 116 | 104 | ) : null} |
| 117 | </div> | |
| 118 | <Button | |
| 119 | aria-label={`Dismiss ${providerName} provider ${status.status}`} | |
| 120 | className="absolute top-2 right-2 size-6" | |
| 121 | onClick={onDismiss} | |
| 122 | size="icon-xs" | |
| 123 | variant="ghost-muted" | |
| 124 | > | |
| 125 | <XIcon aria-hidden className="size-3.5" /> | |
| 126 | </Button> | |
| 127 | </div> | |
| 105 | </AlertDescription> | |
| 106 | <AlertAction> | |
| 107 | <Button | |
| 108 | aria-label={`Dismiss ${providerName} provider ${status.status}`} | |
| 109 | onClick={onDismiss} | |
| 110 | size="icon-xs" | |
| 111 | variant="ghost-muted" | |
| 112 | > | |
| 113 | <XIcon /> | |
| 114 | </Button> | |
| 115 | </AlertAction> | |
| 116 | </Alert> | |
| 128 | 117 | </div> |
| 129 | 118 | ); |
| 130 | 119 | }); |
apps/web/src/components/chat/ThreadErrorBanner.tsx+1-6| ... | ... | @@ -43,12 +43,7 @@ export const ThreadErrorBanner = memo(function ThreadErrorBanner({ |
| 43 | 43 | if (!error) return null; |
| 44 | 44 | return ( |
| 45 | 45 | <div className="pointer-events-auto mx-auto w-fit max-w-[min(48rem,calc(100%-2rem))] pt-3"> |
| 46 | <Alert | |
| 47 | variant="error" | |
| 48 | controlAlignment="first-line" | |
| 49 | className="alert-glass" | |
| 50 | data-variant="error" | |
| 51 | > | |
| 46 | <Alert variant="error" surface="glass" controlAlignment="first-line"> | |
| 52 | 47 | <CircleAlertIcon /> |
| 53 | 48 | <AlertDescription> |
| 54 | 49 | <Tooltip> |
apps/web/src/components/desktop/SnapShotShortcutKeys.tsx+1-1| ... | ... | @@ -16,7 +16,7 @@ export function SnapShotShortcutKeys({ |
| 16 | 16 | const seen = seenLabels.get(label) ?? 0; |
| 17 | 17 | seenLabels.set(label, seen + 1); |
| 18 | 18 | return ( |
| 19 | <Kbd aria-hidden className="min-w-6 justify-center px-1.5" key={`${label}-${seen}`}> | |
| 19 | <Kbd aria-hidden key={`${label}-${seen}`}> | |
| 20 | 20 | {label} |
| 21 | 21 | </Kbd> |
| 22 | 22 | ); |
apps/web/src/components/settings/KeybindingsSettings.tsx+2-2| ... | ... | @@ -79,9 +79,9 @@ function KeybindingPill({ value }: { value: string }) { |
| 79 | 79 | return { part, key: seen === 0 ? part : `${part}-${seen}` }; |
| 80 | 80 | }); |
| 81 | 81 | return ( |
| 82 | <KbdGroup className="bg-transparent p-0 shadow-none"> | |
| 82 | <KbdGroup> | |
| 83 | 83 | {parts.map(({ part, key }) => ( |
| 84 | <Kbd key={key} className="min-w-6 justify-center px-1.5"> | |
| 84 | <Kbd key={key}> | |
| 85 | 85 | {part === "mod" |
| 86 | 86 | ? navigator.platform.toLowerCase().includes("mac") |
| 87 | 87 | ? "⌘" |
apps/web/src/components/settings/SettingsSidebarNav.tsx+1-1| ... | ... | @@ -275,7 +275,7 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) { |
| 275 | 275 | <XIcon className="size-3" /> |
| 276 | 276 | </Button> |
| 277 | 277 | ) : ( |
| 278 | <Kbd className="h-4 min-w-0 rounded-sm px-1.5 text-[10px]">/</Kbd> | |
| 278 | <Kbd>/</Kbd> | |
| 279 | 279 | )} |
| 280 | 280 | </div> |
| 281 | 281 | {isSearching && results.length === 0 ? ( |
apps/web/src/components/sidebar/SidebarUpdatePill.tsx+1-1| ... | ... | @@ -100,7 +100,7 @@ function SidebarUpdateArchitectureWarningContent() { |
| 100 | 100 | if (!visible || !description) return null; |
| 101 | 101 | |
| 102 | 102 | return ( |
| 103 | <Alert variant="warning" className="rounded-2xl border-warning/40 bg-warning/8 text-xs"> | |
| 103 | <Alert variant="warning"> | |
| 104 | 104 | <TriangleAlertIcon /> |
| 105 | 105 | <AlertTitle>Intel build on Apple Silicon</AlertTitle> |
| 106 | 106 | <AlertDescription>{description}</AlertDescription> |
apps/web/src/components/ui/alert.tsx+9-1| ... | ... | @@ -6,9 +6,15 @@ import { cn } from "~/lib/utils"; |
| 6 | 6 | |
| 7 | 7 | const alertVariants = cva("relative rounded-xl border px-3.5 py-3 text-card-foreground text-sm", { |
| 8 | 8 | defaultVariants: { |
| 9 | surface: "default", | |
| 9 | 10 | variant: "default", |
| 10 | 11 | }, |
| 11 | 12 | variants: { |
| 13 | // "glass" floats the alert over content; alert-glass tints from data-variant. | |
| 14 | surface: { | |
| 15 | default: "", | |
| 16 | glass: "alert-glass", | |
| 17 | }, | |
| 12 | 18 | variant: { |
| 13 | 19 | default: "bg-transparent dark:bg-input/32 [&_svg]:text-muted-foreground", |
| 14 | 20 | sidebar: |
| ... | ... | @@ -45,6 +51,7 @@ function alertChildSlot(child: React.ReactElement): string | undefined { |
| 45 | 51 | function Alert({ |
| 46 | 52 | className, |
| 47 | 53 | variant, |
| 54 | surface, | |
| 48 | 55 | controlAlignment = "center", |
| 49 | 56 | children, |
| 50 | 57 | ...props |
| ... | ... | @@ -73,8 +80,9 @@ function Alert({ |
| 73 | 80 | |
| 74 | 81 | return ( |
| 75 | 82 | <div |
| 76 | className={cn(alertVariants({ variant }), className)} | |
| 83 | className={cn(alertVariants({ surface, variant }), className)} | |
| 77 | 84 | data-slot="alert" |
| 85 | data-variant={variant ?? "default"} | |
| 78 | 86 | role="alert" |
| 79 | 87 | {...props} |
| 80 | 88 | > |
scripts/lint-restyle-ceiling.ts+1-1| ... | ... | @@ -8,7 +8,7 @@ import * as NodeURL from "node:url"; |
| 8 | 8 | // components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the |
| 9 | 9 | // count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you |
| 10 | 10 | // migrate a file, and delete this script when the rule becomes an error. |
| 11 | export const RESTYLE_CEILING = 668; | |
| 11 | export const RESTYLE_CEILING = 628; | |
| 12 | 12 | |
| 13 | 13 | const RULE = "shadcn(no-restyle)"; |
| 14 | 14 |