| author | |
| committer | |
| log | 71c9b693137c070b4887b365c68659f1a2fb7aed |
| tree | dec1bc67aab13caf78a8a3b757aeb262401aa4bf |
| parent | f46522777372be1705e3b7a1ab08756f236db5d2 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>38 files changed, 156 insertions(+), 220 deletions(-)
apps/web/src/browser/BrowserDeviceToolbar.tsx+18-23| ... | @@ -242,10 +242,7 @@ export function BrowserDeviceToolbar({ | ... | @@ -242,10 +242,7 @@ export function BrowserDeviceToolbar({ |
| 242 | onChange={(event) => updateCustomDimension("width", event.target.value)} | 242 | onChange={(event) => updateCustomDimension("width", event.target.value)} |
| 243 | aria-label="Viewport width" | 243 | aria-label="Viewport width" |
| 244 | aria-invalid={!customValid} | 244 | aria-invalid={!customValid} |
| 245 | className={cn( | 245 | className={width >= 360 ? "w-14" : "w-13"} |
| 246 | "text-center [&_[data-slot=input]::-webkit-inner-spin-button]:appearance-none [&_[data-slot=input]]:[appearance:textfield]", | ||
| 247 | width >= 360 ? "w-14" : "w-13", | ||
| 248 | )} | ||
| 249 | /> | 246 | /> |
| 250 | <span className="text-xs text-muted-foreground">×</span> | 247 | <span className="text-xs text-muted-foreground">×</span> |
| 251 | <Input | 248 | <Input |
| ... | @@ -270,10 +267,7 @@ export function BrowserDeviceToolbar({ | ... | @@ -270,10 +267,7 @@ export function BrowserDeviceToolbar({ |
| 270 | onChange={(event) => updateCustomDimension("height", event.target.value)} | 267 | onChange={(event) => updateCustomDimension("height", event.target.value)} |
| 271 | aria-label="Viewport height" | 268 | aria-label="Viewport height" |
| 272 | aria-invalid={!customValid} | 269 | aria-invalid={!customValid} |
| 273 | className={cn( | 270 | className={width >= 360 ? "w-14" : "w-13"} |
| 274 | "text-center [&_[data-slot=input]::-webkit-inner-spin-button]:appearance-none [&_[data-slot=input]]:[appearance:textfield]", | ||
| 275 | width >= 360 ? "w-14" : "w-13", | ||
| 276 | )} | ||
| 277 | /> | 271 | /> |
| 278 | </form> | 272 | </form> |
| 279 | 273 | ||
| ... | @@ -281,14 +275,13 @@ export function BrowserDeviceToolbar({ | ... | @@ -281,14 +275,13 @@ export function BrowserDeviceToolbar({ |
| 281 | <TooltipTrigger | 275 | <TooltipTrigger |
| 282 | render={ | 276 | render={ |
| 283 | <Button | 277 | <Button |
| 284 | variant="ghost" | 278 | variant={aspectRatio === null ? "ghost" : "secondary"} |
| 285 | size="icon-xs" | 279 | size="icon-xs" |
| 286 | type="button" | 280 | type="button" |
| 287 | aria-label={ | 281 | aria-label={ |
| 288 | aspectRatio === null ? "Lock viewport aspect ratio" : "Unlock viewport aspect ratio" | 282 | aspectRatio === null ? "Lock viewport aspect ratio" : "Unlock viewport aspect ratio" |
| 289 | } | 283 | } |
| 290 | aria-pressed={aspectRatio !== null} | 284 | aria-pressed={aspectRatio !== null} |
| 291 | className={cn(aspectRatio !== null && "bg-accent text-foreground")} | ||
| 292 | disabled={pending || !customValid} | 285 | disabled={pending || !customValid} |
| 293 | onPointerDown={(event) => event.preventDefault()} | 286 | onPointerDown={(event) => event.preventDefault()} |
| 294 | onClick={toggleAspectRatio} | 287 | onClick={toggleAspectRatio} |
| ... | @@ -315,19 +308,21 @@ export function BrowserDeviceToolbar({ | ... | @@ -315,19 +308,21 @@ export function BrowserDeviceToolbar({ |
| 315 | > | 308 | > |
| 316 | <ScreenRotationIcon /> | 309 | <ScreenRotationIcon /> |
| 317 | </Button> | 310 | </Button> |
| 318 | <Button | 311 | {/* Sticky backing so scrolled controls do not show through the close action. */} |
| 319 | variant="ghost" | 312 | <span className="sticky right-0 ml-auto flex bg-background/95"> |
| 320 | size="icon-xs" | 313 | <Button |
| 321 | type="button" | 314 | variant="ghost" |
| 322 | aria-label="Close device toolbar" | 315 | size="icon-xs" |
| 323 | className="sticky right-0 ml-auto bg-background/95" | 316 | type="button" |
| 324 | disabled={pending} | 317 | aria-label="Close device toolbar" |
| 325 | onClick={() => { | 318 | disabled={pending} |
| 326 | apply({ _tag: "fill" }, null); | 319 | onClick={() => { |
| 327 | }} | 320 | apply({ _tag: "fill" }, null); |
| 328 | > | 321 | }} |
| 329 | <X /> | 322 | > |
| 330 | </Button> | 323 | <X /> |
| 324 | </Button> | ||
| 325 | </span> | ||
| 331 | </div> | 326 | </div> |
| 332 | ); | 327 | ); |
| 333 | } | 328 | } |
apps/web/src/components/ChatMarkdown.tsx+4-8| ... | @@ -784,9 +784,8 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { | ... | @@ -784,9 +784,8 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { |
| 784 | render={ | 784 | render={ |
| 785 | <Button | 785 | <Button |
| 786 | type="button" | 786 | type="button" |
| 787 | variant="ghost" | 787 | variant={expanded ? "secondary" : "ghost-muted"} |
| 788 | size="icon-xs" | 788 | size="icon-xs" |
| 789 | className="chat-markdown-chrome-action" | ||
| 790 | aria-pressed={expanded} | 789 | aria-pressed={expanded} |
| 791 | onClick={toggleExpanded} | 790 | onClick={toggleExpanded} |
| 792 | aria-label={expandLabel} | 791 | aria-label={expandLabel} |
| ... | @@ -805,9 +804,8 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { | ... | @@ -805,9 +804,8 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { |
| 805 | render={ | 804 | render={ |
| 806 | <Button | 805 | <Button |
| 807 | type="button" | 806 | type="button" |
| 808 | variant="ghost" | 807 | variant="ghost-muted" |
| 809 | size="icon-xs" | 808 | size="icon-xs" |
| 810 | className="chat-markdown-chrome-action" | ||
| 811 | aria-label={copyLabel} | 809 | aria-label={copyLabel} |
| 812 | /> | 810 | /> |
| 813 | } | 811 | } |
| ... | @@ -993,9 +991,8 @@ function MarkdownCodeBlock({ | ... | @@ -993,9 +991,8 @@ function MarkdownCodeBlock({ |
| 993 | render={ | 991 | render={ |
| 994 | <Button | 992 | <Button |
| 995 | type="button" | 993 | type="button" |
| 996 | variant="ghost" | 994 | variant={wrapped ? "secondary" : "ghost-muted"} |
| 997 | size="icon-xs" | 995 | size="icon-xs" |
| 998 | className="chat-markdown-chrome-action" | ||
| 999 | aria-pressed={wrapped} | 996 | aria-pressed={wrapped} |
| 1000 | onClick={() => setWrapped((value) => !value)} | 997 | onClick={() => setWrapped((value) => !value)} |
| 1001 | aria-label={wrapLabel} | 998 | aria-label={wrapLabel} |
| ... | @@ -1011,9 +1008,8 @@ function MarkdownCodeBlock({ | ... | @@ -1011,9 +1008,8 @@ function MarkdownCodeBlock({ |
| 1011 | render={ | 1008 | render={ |
| 1012 | <Button | 1009 | <Button |
| 1013 | type="button" | 1010 | type="button" |
| 1014 | variant="ghost" | 1011 | variant="ghost-muted" |
| 1015 | size="icon-xs" | 1012 | size="icon-xs" |
| 1016 | className="chat-markdown-chrome-action" | ||
| 1017 | onClick={handleCopy} | 1013 | onClick={handleCopy} |
| 1018 | aria-label={copyLabel} | 1014 | aria-label={copyLabel} |
| 1019 | /> | 1015 | /> |
apps/web/src/components/ChatView.tsx+1-1| ... | @@ -9991,7 +9991,7 @@ export default function ChatView(props: ChatViewProps) { | ... | @@ -9991,7 +9991,7 @@ export default function ChatView(props: ChatViewProps) { |
| 9991 | composerRef.current?.restoreAfterTimelineReachedEnd(); | 9991 | composerRef.current?.restoreAfterTimelineReachedEnd(); |
| 9992 | scrollToEnd(true); | 9992 | scrollToEnd(true); |
| 9993 | }} | 9993 | }} |
| 9994 | className="pointer-events-auto gap-1.5 rounded-full px-3 text-muted-foreground hover:text-foreground" | 9994 | className="pointer-events-auto" |
| 9995 | size="xs" | 9995 | size="xs" |
| 9996 | variant="glass" | 9996 | variant="glass" |
| 9997 | > | 9997 | > |
apps/web/src/components/CommandPalette.tsx+4-8| ... | @@ -1528,9 +1528,8 @@ function OpenCommandPaletteDialog(props: { | ... | @@ -1528,9 +1528,8 @@ function OpenCommandPaletteDialog(props: { |
| 1528 | <TooltipTrigger | 1528 | <TooltipTrigger |
| 1529 | render={ | 1529 | render={ |
| 1530 | <Button | 1530 | <Button |
| 1531 | variant="outline" | 1531 | variant="warning-outline" |
| 1532 | size="xs" | 1532 | size="micro" |
| 1533 | className="h-5 rounded-[.25rem] px-1.5 text-[10px] text-warning-foreground" | ||
| 1534 | onClick={() => { | 1533 | onClick={() => { |
| 1535 | openSourceControlSettings(); | 1534 | openSourceControlSettings(); |
| 1536 | }} | 1535 | }} |
| ... | @@ -2861,7 +2860,7 @@ function OpenCommandPaletteDialog(props: { | ... | @@ -2861,7 +2860,7 @@ function OpenCommandPaletteDialog(props: { |
| 2861 | variant="outline" | 2860 | variant="outline" |
| 2862 | size="xs" | 2861 | size="xs" |
| 2863 | tabIndex={-1} | 2862 | tabIndex={-1} |
| 2864 | className="absolute inset-e-2.5 top-1/2 gap-1.5 pe-1 ps-2 -translate-y-1/2" | 2863 | className="absolute inset-e-2.5 top-1/2 -translate-y-1/2" |
| 2865 | aria-label={`${remoteProjectButtonLabel ?? "Continue"} (Enter)`} | 2864 | aria-label={`${remoteProjectButtonLabel ?? "Continue"} (Enter)`} |
| 2866 | disabled={!canSubmitRemoteProjectFlow} | 2865 | disabled={!canSubmitRemoteProjectFlow} |
| 2867 | onMouseDown={(event) => { | 2866 | onMouseDown={(event) => { |
| ... | @@ -2888,10 +2887,7 @@ function OpenCommandPaletteDialog(props: { | ... | @@ -2888,10 +2887,7 @@ function OpenCommandPaletteDialog(props: { |
| 2888 | variant="outline" | 2887 | variant="outline" |
| 2889 | size="xs" | 2888 | size="xs" |
| 2890 | tabIndex={-1} | 2889 | tabIndex={-1} |
| 2891 | className={cn( | 2890 | className="absolute inset-e-2.5 top-1/2 -translate-y-1/2" |
| 2892 | "absolute inset-e-2.5 top-1/2 pe-1 ps-2 -translate-y-1/2", | ||
| 2893 | hasHighlightedBrowseItem ? "gap-1" : "gap-1.5", | ||
| 2894 | )} | ||
| 2895 | aria-label={`${submitActionLabel} (${addShortcutLabel})`} | 2891 | aria-label={`${submitActionLabel} (${addShortcutLabel})`} |
| 2896 | disabled={ | 2892 | disabled={ |
| 2897 | !canCreateProjectInEnvironment(browseEnvironment?.connection.phase) || | 2893 | !canCreateProjectInEnvironment(browseEnvironment?.connection.phase) || |
apps/web/src/components/CustomSnoozeDialog.tsx+1-1| ... | @@ -119,7 +119,7 @@ function CustomSnoozeDialog() { | ... | @@ -119,7 +119,7 @@ function CustomSnoozeDialog() { |
| 119 | <Button | 119 | <Button |
| 120 | id={`${id}-date`} | 120 | id={`${id}-date`} |
| 121 | variant="outline" | 121 | variant="outline" |
| 122 | className="w-full justify-between font-normal" | 122 | className="w-full justify-between" |
| 123 | /> | 123 | /> |
| 124 | } | 124 | } |
| 125 | > | 125 | > |
apps/web/src/components/DiffPanel.tsx+7-6| ... | @@ -1125,10 +1125,7 @@ export default function DiffPanel({ | ... | @@ -1125,10 +1125,7 @@ export default function DiffPanel({ |
| 1125 | <Button | 1125 | <Button |
| 1126 | size="icon-micro" | 1126 | size="icon-micro" |
| 1127 | variant="ghost" | 1127 | variant="ghost" |
| 1128 | className={cn( | 1128 | className="-ms-0.5" |
| 1129 | "-ms-0.5 [--control-icon-color:currentColor] bg-transparent hover:bg-foreground/10", | ||
| 1130 | getDiffCollapseIconClassName(fileDiff), | ||
| 1131 | )} | ||
| 1132 | aria-label={ | 1129 | aria-label={ |
| 1133 | collapsed ? `Expand ${filePath}` : `Collapse ${filePath}` | 1130 | collapsed ? `Expand ${filePath}` : `Collapse ${filePath}` |
| 1134 | } | 1131 | } |
| ... | @@ -1142,9 +1139,13 @@ export default function DiffPanel({ | ... | @@ -1142,9 +1139,13 @@ export default function DiffPanel({ |
| 1142 | } | 1139 | } |
| 1143 | > | 1140 | > |
| 1144 | {collapsed ? ( | 1141 | {collapsed ? ( |
| 1145 | <ChevronRightIcon className="size-4" /> | 1142 | <ChevronRightIcon |
| 1143 | className={cn("size-4", getDiffCollapseIconClassName(fileDiff))} | ||
| 1144 | /> | ||
| 1146 | ) : ( | 1145 | ) : ( |
| 1147 | <ChevronDownIcon className="size-4" /> | 1146 | <ChevronDownIcon |
| 1147 | className={cn("size-4", getDiffCollapseIconClassName(fileDiff))} | ||
| 1148 | /> | ||
| 1148 | )} | 1149 | )} |
| 1149 | </TooltipTrigger> | 1150 | </TooltipTrigger> |
| 1150 | <TooltipPopup side="top"> | 1151 | <TooltipPopup side="top"> |
apps/web/src/components/GitActionsControl.tsx+7-16| ... | @@ -646,9 +646,8 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) { | ... | @@ -646,9 +646,8 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) { |
| 646 | <TooltipTrigger | 646 | <TooltipTrigger |
| 647 | render={ | 647 | render={ |
| 648 | <Button | 648 | <Button |
| 649 | variant="outline" | 649 | variant="warning-outline" |
| 650 | size="xs" | 650 | size="micro" |
| 651 | className="h-5 rounded-[.25rem] px-1.5 text-[10px] text-warning-foreground" | ||
| 652 | onClick={(event) => { | 651 | onClick={(event) => { |
| 653 | event.preventDefault(); | 652 | event.preventDefault(); |
| 654 | event.stopPropagation(); | 653 | event.stopPropagation(); |
| ... | @@ -1799,14 +1798,7 @@ export default function GitActionsControl({ | ... | @@ -1799,14 +1798,7 @@ export default function GitActionsControl({ |
| 1799 | <Popover> | 1798 | <Popover> |
| 1800 | <PopoverTrigger | 1799 | <PopoverTrigger |
| 1801 | openOnHover | 1800 | openOnHover |
| 1802 | render={ | 1801 | render={<Button aria-disabled="true" size="xs" variant="outline" />} |
| 1803 | <Button | ||
| 1804 | aria-disabled="true" | ||
| 1805 | className="cursor-not-allowed rounded-e-none border-e-0 ps-[8.5px] opacity-64 before:rounded-e-none" | ||
| 1806 | size="xs" | ||
| 1807 | variant="outline" | ||
| 1808 | /> | ||
| 1809 | } | ||
| 1810 | > | 1802 | > |
| 1811 | <GitQuickActionIcon | 1803 | <GitQuickActionIcon |
| 1812 | quickAction={quickAction} | 1804 | quickAction={quickAction} |
| ... | @@ -1824,7 +1816,6 @@ export default function GitActionsControl({ | ... | @@ -1824,7 +1816,6 @@ export default function GitActionsControl({ |
| 1824 | <Button | 1816 | <Button |
| 1825 | variant="outline" | 1817 | variant="outline" |
| 1826 | size="xs" | 1818 | size="xs" |
| 1827 | className="ps-[8.5px]" | ||
| 1828 | disabled={isGitActionRunning || quickAction.disabled} | 1819 | disabled={isGitActionRunning || quickAction.disabled} |
| 1829 | onClick={runQuickAction} | 1820 | onClick={runQuickAction} |
| 1830 | > | 1821 | > |
| ... | @@ -2056,16 +2047,16 @@ export default function GitActionsControl({ | ... | @@ -2056,16 +2047,16 @@ export default function GitActionsControl({ |
| 2056 | Abort | 2047 | Abort |
| 2057 | </Button> | 2048 | </Button> |
| 2058 | <Button | 2049 | <Button |
| 2059 | className="min-h-8 w-full max-w-full whitespace-normal py-1.5 leading-snug sm:min-h-7 sm:w-auto" | 2050 | className="w-full max-w-full sm:w-auto" |
| 2060 | variant="outline" | 2051 | variant="outline" |
| 2061 | size="sm" | 2052 | size="sm-multiline" |
| 2062 | onClick={continuePendingDefaultBranchAction} | 2053 | onClick={continuePendingDefaultBranchAction} |
| 2063 | > | 2054 | > |
| 2064 | {pendingDefaultBranchActionCopy?.continueLabel ?? "Continue"} | 2055 | {pendingDefaultBranchActionCopy?.continueLabel ?? "Continue"} |
| 2065 | </Button> | 2056 | </Button> |
| 2066 | <Button | 2057 | <Button |
| 2067 | className="min-h-8 w-full max-w-full whitespace-normal py-1.5 leading-snug sm:min-h-7 sm:w-auto" | 2058 | className="w-full max-w-full sm:w-auto" |
| 2068 | size="sm" | 2059 | size="sm-multiline" |
| 2069 | onClick={checkoutFeatureBranchAndContinuePendingAction} | 2060 | onClick={checkoutFeatureBranchAndContinuePendingAction} |
| 2070 | > | 2061 | > |
| 2071 | Check out feature branch & continue | 2062 | Check out feature branch & continue |
apps/web/src/components/ProjectScriptsControl.tsx+23-19| ... | @@ -192,24 +192,28 @@ export default function ProjectScriptsControl({ | ... | @@ -192,24 +192,28 @@ export default function ProjectScriptsControl({ |
| 192 | <MenuShortcut className="ms-0">{shortcutLabel}</MenuShortcut> | 192 | <MenuShortcut className="ms-0">{shortcutLabel}</MenuShortcut> |
| 193 | </span> | 193 | </span> |
| 194 | ))} | 194 | ))} |
| 195 | <Button | 195 | <span |
| 196 | type="button" | 196 | className={`absolute right-0 top-1/2 flex -translate-y-1/2 ${presentation === "menu" ? "" : "opacity-0 pointer-events-none transition-opacity group-hover:opacity-100 group-hover:pointer-events-auto group-focus-visible:opacity-100 group-focus-visible:pointer-events-auto"}`} |
| 197 | variant="ghost" | ||
| 198 | size="icon-xs" | ||
| 199 | className={`absolute right-0 top-1/2 size-6 -translate-y-1/2 ${presentation === "menu" ? "" : "opacity-0 pointer-events-none transition-opacity group-hover:opacity-100 group-hover:pointer-events-auto group-focus-visible:opacity-100 group-focus-visible:pointer-events-auto"}`} | ||
| 200 | aria-label={`Edit ${script.name}`} | ||
| 201 | onPointerDown={(event) => { | ||
| 202 | event.preventDefault(); | ||
| 203 | event.stopPropagation(); | ||
| 204 | }} | ||
| 205 | onClick={(event) => { | ||
| 206 | event.preventDefault(); | ||
| 207 | event.stopPropagation(); | ||
| 208 | openEditDialog(script); | ||
| 209 | }} | ||
| 210 | > | 197 | > |
| 211 | <SettingsIcon className="size-3.5" /> | 198 | <Button |
| 212 | </Button> | 199 | type="button" |
| 200 | variant="ghost" | ||
| 201 | size="icon-xs" | ||
| 202 | className="size-6" | ||
| 203 | aria-label={`Edit ${script.name}`} | ||
| 204 | onPointerDown={(event) => { | ||
| 205 | event.preventDefault(); | ||
| 206 | event.stopPropagation(); | ||
| 207 | }} | ||
| 208 | onClick={(event) => { | ||
| 209 | event.preventDefault(); | ||
| 210 | event.stopPropagation(); | ||
| 211 | openEditDialog(script); | ||
| 212 | }} | ||
| 213 | > | ||
| 214 | <SettingsIcon className="size-3.5" /> | ||
| 215 | </Button> | ||
| 216 | </span> | ||
| 213 | </span> | 217 | </span> |
| 214 | </MenuItem> | 218 | </MenuItem> |
| 215 | ); | 219 | ); |
| ... | @@ -269,7 +273,7 @@ export default function ProjectScriptsControl({ | ... | @@ -269,7 +273,7 @@ export default function ProjectScriptsControl({ |
| 269 | <Button | 273 | <Button |
| 270 | size="xs" | 274 | size="xs" |
| 271 | variant="outline" | 275 | variant="outline" |
| 272 | className="w-7 px-0 sm:w-6 @3xl/header-actions:w-auto! @3xl/header-actions:px-[calc(--spacing(2)-1px)]" | 276 | className="w-7 sm:w-6 @3xl/header-actions:w-auto!" |
| 273 | aria-label={`Run ${primaryScript.name}`} | 277 | aria-label={`Run ${primaryScript.name}`} |
| 274 | // The tooltip wrapper replaces data-slot="button", so themed | 278 | // The tooltip wrapper replaces data-slot="button", so themed |
| 275 | // toolbar styling needs its own hook. | 279 | // toolbar styling needs its own hook. |
| ... | @@ -329,7 +333,7 @@ export default function ProjectScriptsControl({ | ... | @@ -329,7 +333,7 @@ export default function ProjectScriptsControl({ |
| 329 | <Button | 333 | <Button |
| 330 | size="xs" | 334 | size="xs" |
| 331 | variant="outline" | 335 | variant="outline" |
| 332 | className="w-7 px-0 sm:w-6 @3xl/header-actions:w-auto! @3xl/header-actions:px-[calc(--spacing(2)-1px)]" | 336 | className="w-7 sm:w-6 @3xl/header-actions:w-auto!" |
| 333 | aria-label="Add action" | 337 | aria-label="Add action" |
| 334 | // The tooltip wrapper replaces data-slot="button", so themed | 338 | // The tooltip wrapper replaces data-slot="button", so themed |
| 335 | // toolbar styling needs its own hook. | 339 | // toolbar styling needs its own hook. |
apps/web/src/components/ServerUpdateAction.tsx+2-2| ... | @@ -270,8 +270,8 @@ export function ServerUpdateAction({ | ... | @@ -270,8 +270,8 @@ export function ServerUpdateAction({ |
| 270 | render={ | 270 | render={ |
| 271 | <Button | 271 | <Button |
| 272 | size="icon-xs" | 272 | size="icon-xs" |
| 273 | variant="ghost" | 273 | variant="ghost-muted" |
| 274 | className={className ?? "text-muted-foreground hover:text-foreground"} | 274 | className={className} |
| 275 | aria-label={`${actionLabel} for ${serverLabel}`} | 275 | aria-label={`${actionLabel} for ${serverLabel}`} |
| 276 | onClick={onClick} | 276 | onClick={onClick} |
| 277 | /> | 277 | /> |
apps/web/src/components/Sidebar.tsx+1-1| ... | @@ -4500,7 +4500,7 @@ export default function Sidebar() { | ... | @@ -4500,7 +4500,7 @@ export default function Sidebar() { |
| 4500 | tabIndex={-1} | 4500 | tabIndex={-1} |
| 4501 | aria-hidden="true" | 4501 | aria-hidden="true" |
| 4502 | title={`Project settings for ${project.displayName}`} | 4502 | title={`Project settings for ${project.displayName}`} |
| 4503 | className="ml-auto focus-visible:bg-accent focus-visible:text-foreground" | 4503 | className="ml-auto" |
| 4504 | onPointerDown={(event) => event.stopPropagation()} | 4504 | onPointerDown={(event) => event.stopPropagation()} |
| 4505 | onClick={(event) => { | 4505 | onClick={(event) => { |
| 4506 | void handleProjectSettings(event, project); | 4506 | void handleProjectSettings(event, project); |
apps/web/src/components/chat/AssistantSelectionToolbar.tsx+1-1| ... | @@ -134,7 +134,7 @@ export function AssistantSelectionToolbar({ | ... | @@ -134,7 +134,7 @@ export function AssistantSelectionToolbar({ |
| 134 | variant="glass" | 134 | variant="glass" |
| 135 | disabled={tooLong} | 135 | disabled={tooLong} |
| 136 | aria-label={tooLong ? "Selection is too long to cite" : "Cite selection in composer"} | 136 | aria-label={tooLong ? "Selection is too long to cite" : "Cite selection in composer"} |
| 137 | className="fixed z-50 max-w-[calc(100vw-1rem)] rounded-full px-2.5" | 137 | className="fixed z-50 max-w-[calc(100vw-1rem)]" |
| 138 | style={{ left: selection.position.x, top: selection.position.y }} | 138 | style={{ left: selection.position.x, top: selection.position.y }} |
| 139 | onPointerDown={(event) => event.preventDefault()} | 139 | onPointerDown={(event) => event.preventDefault()} |
| 140 | onClick={cite} | 140 | onClick={cite} |
apps/web/src/components/chat/ContextWindowMeter.tsx+1-1| ... | @@ -45,7 +45,7 @@ export function ContextWindowMeter(props: { | ... | @@ -45,7 +45,7 @@ export function ContextWindowMeter(props: { |
| 45 | <Button | 45 | <Button |
| 46 | size="icon-sm" | 46 | size="icon-sm" |
| 47 | variant="ghost-muted" | 47 | variant="ghost-muted" |
| 48 | className="size-7 rounded-full hover:text-muted-foreground data-pressed:text-muted-foreground" | 48 | className="size-7" |
| 49 | aria-label={ | 49 | aria-label={ |
| 50 | usage.maxTokens !== null && usedPercentage | 50 | usage.maxTokens !== null && usedPercentage |
| 51 | ? `Context window ${usedPercentage} used` | 51 | ? `Context window ${usedPercentage} used` |
apps/web/src/components/chat/ExpandedImageDialog.tsx+4-9| ... | @@ -193,7 +193,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ | ... | @@ -193,7 +193,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 193 | type="button" | 193 | type="button" |
| 194 | size="icon" | 194 | size="icon" |
| 195 | variant="media-navigation" | 195 | variant="media-navigation" |
| 196 | className="left-0 top-auto -bottom-12 translate-y-0 rounded-full bg-white/10 sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2" | 196 | className="left-0 top-auto -bottom-12 translate-y-0 sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2" |
| 197 | aria-label="Previous media" | 197 | aria-label="Previous media" |
| 198 | onClick={() => navigateImage(-1)} | 198 | onClick={() => navigateImage(-1)} |
| 199 | > | 199 | > |
| ... | @@ -252,12 +252,11 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ | ... | @@ -252,12 +252,11 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 252 | <Button | 252 | <Button |
| 253 | aria-label={contentsLabel} | 253 | aria-label={contentsLabel} |
| 254 | aria-pressed={showingAccessibilityDetails} | 254 | aria-pressed={showingAccessibilityDetails} |
| 255 | className="[--control-icon-color:currentColor] hover:bg-white/10 hover:text-white" | ||
| 256 | onClick={() => | 255 | onClick={() => |
| 257 | setAccessibilityDetailsSrc(showingAccessibilityDetails ? null : item.src) | 256 | setAccessibilityDetailsSrc(showingAccessibilityDetails ? null : item.src) |
| 258 | } | 257 | } |
| 259 | size="icon-micro" | 258 | size="icon-micro" |
| 260 | variant="ghost-muted" | 259 | variant="overlay" |
| 261 | /> | 260 | /> |
| 262 | } | 261 | } |
| 263 | > | 262 | > |
| ... | @@ -266,11 +265,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ | ... | @@ -266,11 +265,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 266 | <TooltipPopup side="top">{contentsLabel}</TooltipPopup> | 265 | <TooltipPopup side="top">{contentsLabel}</TooltipPopup> |
| 267 | </Tooltip> | 266 | </Tooltip> |
| 268 | ) : item.source ? ( | 267 | ) : item.source ? ( |
| 269 | <SnapShotContentsButton | 268 | <SnapShotContentsButton source={item.source} side="top" /> |
| 270 | source={item.source} | ||
| 271 | side="top" | ||
| 272 | className="hover:bg-white/10 hover:text-white" | ||
| 273 | /> | ||
| 274 | ) : null} | 269 | ) : null} |
| 275 | </div> | 270 | </div> |
| 276 | </div> | 271 | </div> |
| ... | @@ -280,7 +275,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ | ... | @@ -280,7 +275,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 280 | type="button" | 275 | type="button" |
| 281 | size="icon" | 276 | size="icon" |
| 282 | variant="media-navigation" | 277 | variant="media-navigation" |
| 283 | className="right-0 top-auto -bottom-12 translate-y-0 rounded-full bg-white/10 sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2" | 278 | className="right-0 top-auto -bottom-12 translate-y-0 sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2" |
| 284 | aria-label="Next media" | 279 | aria-label="Next media" |
| 285 | onClick={() => navigateImage(1)} | 280 | onClick={() => navigateImage(1)} |
| 286 | > | 281 | > |
apps/web/src/components/chat/MessageCopyButton.tsx+2-3| ... | @@ -2,7 +2,6 @@ import { memo, useRef } from "react"; | ... | @@ -2,7 +2,6 @@ import { memo, useRef } from "react"; |
| 2 | import { CopyIcon, CheckIcon } from "lucide-react"; | 2 | import { CopyIcon, CheckIcon } from "lucide-react"; |
| 3 | import { Button } from "../ui/button"; | 3 | import { Button } from "../ui/button"; |
| 4 | import { useCopyToClipboard } from "~/hooks/useCopyToClipboard"; | 4 | import { useCopyToClipboard } from "~/hooks/useCopyToClipboard"; |
| 5 | import { cn } from "~/lib/utils"; | ||
| 6 | import { | 5 | import { |
| 7 | ANCHORED_COPY_TOAST_TIMEOUT_MS, | 6 | ANCHORED_COPY_TOAST_TIMEOUT_MS, |
| 8 | showAnchoredCopyErrorToast, | 7 | showAnchoredCopyErrorToast, |
| ... | @@ -43,8 +42,8 @@ export const MessageCopyButton = memo(function MessageCopyButton({ | ... | @@ -43,8 +42,8 @@ export const MessageCopyButton = memo(function MessageCopyButton({ |
| 43 | ref={ref} | 42 | ref={ref} |
| 44 | type="button" | 43 | type="button" |
| 45 | size={size} | 44 | size={size} |
| 46 | variant={variant} | 45 | variant={variant === "ghost" ? "ghost-muted" : variant} |
| 47 | className={cn("text-muted-foreground hover:text-foreground", className)} | 46 | className={className} |
| 48 | /> | 47 | /> |
| 49 | } | 48 | } |
| 50 | > | 49 | > |
apps/web/src/components/chat/MessagesTimeline.tsx+2-2| ... | @@ -3956,11 +3956,11 @@ const CollapsibleUserMessageBody = memo(function CollapsibleUserMessageBody(prop | ... | @@ -3956,11 +3956,11 @@ const CollapsibleUserMessageBody = memo(function CollapsibleUserMessageBody(prop |
| 3956 | <Button | 3956 | <Button |
| 3957 | type="button" | 3957 | type="button" |
| 3958 | size="xs" | 3958 | size="xs" |
| 3959 | variant="ghost" | 3959 | variant="ghost-muted" |
| 3960 | aria-expanded={expanded} | 3960 | aria-expanded={expanded} |
| 3961 | data-scroll-anchor-ignore | 3961 | data-scroll-anchor-ignore |
| 3962 | onClick={() => setExpanded((value) => !value)} | 3962 | onClick={() => setExpanded((value) => !value)} |
| 3963 | className="-ml-1 h-6 rounded-md px-1.5 text-secondary-label text-xs hover:bg-muted/55 hover:text-message-foreground" | 3963 | className="-ml-1" |
| 3964 | > | 3964 | > |
| 3965 | {expanded ? "Show less" : "Show full message"} | 3965 | {expanded ? "Show less" : "Show full message"} |
| 3966 | </Button> | 3966 | </Button> |
apps/web/src/components/chat/OpenInPicker.tsx-1| ... | @@ -353,7 +353,6 @@ export const OpenInPicker = memo(function OpenInPicker({ | ... | @@ -353,7 +353,6 @@ export const OpenInPicker = memo(function OpenInPicker({ |
| 353 | <Group aria-label="Open in editor"> | 353 | <Group aria-label="Open in editor"> |
| 354 | <Button | 354 | <Button |
| 355 | aria-label={compact ? "Open file in preferred editor" : undefined} | 355 | aria-label={compact ? "Open file in preferred editor" : undefined} |
| 356 | className="ps-[8.5px]" | ||
| 357 | size="xs" | 356 | size="xs" |
| 358 | variant="outline" | 357 | variant="outline" |
| 359 | disabled={!preferredEditor || !openInCwd || remote.mode === "remote-unavailable"} | 358 | disabled={!preferredEditor || !openInCwd || remote.mode === "remote-unavailable"} |
apps/web/src/components/chat/SnapShotAttachmentDetails.tsx+2-5| ... | @@ -153,7 +153,7 @@ export function SnapShotContentsButton({ | ... | @@ -153,7 +153,7 @@ export function SnapShotContentsButton({ |
| 153 | className={className} | 153 | className={className} |
| 154 | onClick={(event) => event.stopPropagation()} | 154 | onClick={(event) => event.stopPropagation()} |
| 155 | size="icon-micro" | 155 | size="icon-micro" |
| 156 | variant="ghost-muted" | 156 | variant="overlay" |
| 157 | /> | 157 | /> |
| 158 | } | 158 | } |
| 159 | /> | 159 | /> |
| ... | @@ -211,10 +211,7 @@ export function SnapShotAttachmentDetails({ | ... | @@ -211,10 +211,7 @@ export function SnapShotAttachmentDetails({ |
| 211 | <div className="min-w-0 flex-1"> | 211 | <div className="min-w-0 flex-1"> |
| 212 | <div className="flex min-w-0 items-center gap-1.5 text-[11px] font-medium leading-3.5 text-white"> | 212 | <div className="flex min-w-0 items-center gap-1.5 text-[11px] font-medium leading-3.5 text-white"> |
| 213 | <span className="truncate">{source.appName}</span> | 213 | <span className="truncate">{source.appName}</span> |
| 214 | <SnapShotContentsButton | 214 | <SnapShotContentsButton source={source} className="pointer-events-auto" /> |
| 215 | source={source} | ||
| 216 | className="pointer-events-auto text-white/60 hover:bg-white/10 hover:text-white focus-visible:ring-white/70" | ||
| 217 | /> | ||
| 218 | </div> | 215 | </div> |
| 219 | <div className="truncate text-[9px] leading-3.5 text-white/70"> | 216 | <div className="truncate text-[9px] leading-3.5 text-white/70"> |
| 220 | {source.windowTitle || "Captured window"} | 217 | {source.windowTitle || "Captured window"} |
apps/web/src/components/diffs/DiffCommentAnnotation.tsx+10-9| ... | @@ -67,15 +67,16 @@ export function DiffCommentAnnotation({ | ... | @@ -67,15 +67,16 @@ export function DiffCommentAnnotation({ |
| 67 | <MessageCircle className="mt-0.5 size-3.5 shrink-0 text-primary/70" aria-hidden="true" /> | 67 | <MessageCircle className="mt-0.5 size-3.5 shrink-0 text-primary/70" aria-hidden="true" /> |
| 68 | <p className="min-w-0 flex-1 whitespace-pre-wrap text-[13px] leading-5">{displayedText}</p> | 68 | <p className="min-w-0 flex-1 whitespace-pre-wrap text-[13px] leading-5">{displayedText}</p> |
| 69 | {onDelete ? ( | 69 | {onDelete ? ( |
| 70 | <Button | 70 | <span className="-my-1 -mr-1 flex shrink-0 opacity-0 transition-opacity group-hover/comment:opacity-100 focus-within:opacity-100 max-sm:opacity-100"> |
| 71 | className="-my-1 -mr-1 shrink-0 opacity-0 transition-opacity group-hover/comment:opacity-100 focus-visible:opacity-100 max-sm:opacity-100" | 71 | <Button |
| 72 | variant="ghost-muted" | 72 | variant="ghost-muted" |
| 73 | size="icon-xs" | 73 | size="icon-xs" |
| 74 | aria-label="Delete comment" | 74 | aria-label="Delete comment" |
| 75 | onClick={onDelete} | 75 | onClick={onDelete} |
| 76 | > | 76 | > |
| 77 | <Trash2 className="size-3" /> | 77 | <Trash2 className="size-3" /> |
| 78 | </Button> | 78 | </Button> |
| 79 | </span> | ||
| 79 | ) : null} | 80 | ) : null} |
| 80 | </div> | 81 | </div> |
| 81 | ); | 82 | ); |
apps/web/src/components/onboarding/WelcomeWizard.tsx+5-7| ... | @@ -357,12 +357,13 @@ function ConnectionStep({ | ... | @@ -357,12 +357,13 @@ function ConnectionStep({ |
| 357 | render={ | 357 | render={ |
| 358 | <Button | 358 | <Button |
| 359 | variant="ghost" | 359 | variant="ghost" |
| 360 | className="h-auto min-h-14 w-full justify-start gap-3 px-3 py-3 text-left whitespace-normal sm:h-auto" | 360 | size="sm-multiline" |
| 361 | className="min-h-14 w-full justify-start" | ||
| 361 | /> | 362 | /> |
| 362 | } | 363 | } |
| 363 | > | 364 | > |
| 364 | <LinkIcon className="size-4 text-muted-foreground" /> | 365 | <LinkIcon className="size-4 text-muted-foreground" /> |
| 365 | <span className="flex-1">Add a computer</span> | 366 | <span className="flex-1 text-left">Add a computer</span> |
| 366 | <ChevronRightIcon | 367 | <ChevronRightIcon |
| 367 | className={cn("size-4 text-muted-foreground", pairingOpen && "rotate-90")} | 368 | className={cn("size-4 text-muted-foreground", pairingOpen && "rotate-90")} |
| 368 | /> | 369 | /> |
| ... | @@ -429,14 +430,11 @@ function ConnectAccountOption({ | ... | @@ -429,14 +430,11 @@ function ConnectAccountOption({ |
| 429 | } | 430 | } |
| 430 | }} | 431 | }} |
| 431 | render={ | 432 | render={ |
| 432 | <Button | 433 | <Button variant="ghost" size="sm-multiline" className="min-h-14 w-full justify-start" /> |
| 433 | variant="ghost" | ||
| 434 | className="h-auto min-h-14 w-full justify-start gap-3 px-3 py-3 text-left whitespace-normal sm:h-auto" | ||
| 435 | /> | ||
| 436 | } | 434 | } |
| 437 | > | 435 | > |
| 438 | <CloudIcon className="size-4 text-muted-foreground" /> | 436 | <CloudIcon className="size-4 text-muted-foreground" /> |
| 439 | <span className="flex-1">T3 Connect</span> | 437 | <span className="flex-1 text-left">T3 Connect</span> |
| 440 | <span className="text-xs text-muted-foreground"> | 438 | <span className="text-xs text-muted-foreground"> |
| 441 | {!isLoaded | 439 | {!isLoaded |
| 442 | ? "Loading sign-in…" | 440 | ? "Loading sign-in…" |
apps/web/src/components/preview/PreviewMoreMenu.tsx-1| ... | @@ -185,7 +185,6 @@ export function PreviewMoreMenu({ | ... | @@ -185,7 +185,6 @@ export function PreviewMoreMenu({ |
| 185 | type="button" | 185 | type="button" |
| 186 | onClick={callTab(bridge.resetZoom)} | 186 | onClick={callTab(bridge.resetZoom)} |
| 187 | aria-label="Reset zoom" | 187 | aria-label="Reset zoom" |
| 188 | className="[:hover,[data-pressed]]:bg-foreground/10" | ||
| 189 | disabled={tabDisabled} | 188 | disabled={tabDisabled} |
| 190 | > | 189 | > |
| 191 | <RotateCcw /> | 190 | <RotateCcw /> |
apps/web/src/components/projectScriptEditor.tsx+1-1| ... | @@ -319,7 +319,7 @@ export function ProjectScriptEditorDialog({ | ... | @@ -319,7 +319,7 @@ export function ProjectScriptEditorDialog({ |
| 319 | <Button | 319 | <Button |
| 320 | type="button" | 320 | type="button" |
| 321 | variant="outline" | 321 | variant="outline" |
| 322 | className="size-9 shrink-0 hover:bg-popover active:bg-popover data-pressed:bg-popover data-pressed:shadow-xs/5 data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:border-transparent dark:bg-white/[0.035] dark:data-pressed:before:shadow-none" | 322 | className="size-9 shrink-0" |
| 323 | aria-label="Choose icon" | 323 | aria-label="Choose icon" |
| 324 | /> | 324 | /> |
| 325 | } | 325 | } |
apps/web/src/components/pullRequest/PullRequestCodeTab.tsx+1-1| ... | @@ -785,7 +785,7 @@ function PullRequestCodeTab({ | ... | @@ -785,7 +785,7 @@ function PullRequestCodeTab({ |
| 785 | variant="ghost-muted" | 785 | variant="ghost-muted" |
| 786 | aria-expanded={!collapsed} | 786 | aria-expanded={!collapsed} |
| 787 | aria-label={collapsed ? "Expand diff" : "Collapse diff"} | 787 | aria-label={collapsed ? "Expand diff" : "Collapse diff"} |
| 788 | className="mr-1 rounded hover:bg-transparent" | 788 | className="mr-1" |
| 789 | onClick={(event) => { | 789 | onClick={(event) => { |
| 790 | event.stopPropagation(); | 790 | event.stopPropagation(); |
| 791 | toggleFile(item.id); | 791 | toggleFile(item.id); |
apps/web/src/components/pullRequest/PullRequestComposer.tsx+1-7| ... | @@ -78,13 +78,7 @@ export function PullRequestComposer({ | ... | @@ -78,13 +78,7 @@ export function PullRequestComposer({ |
| 78 | }} | 78 | }} |
| 79 | > | 79 | > |
| 80 | <PopoverTrigger | 80 | <PopoverTrigger |
| 81 | render={ | 81 | render={<Button size="icon" variant="glass" />} |
| 82 | <Button | ||
| 83 | size="icon" | ||
| 84 | variant="glass" | ||
| 85 | className="rounded-full shadow-lg [--glass-opacity:50%]" | ||
| 86 | /> | ||
| 87 | } | ||
| 88 | // The only label this control has, so the pending count belongs in it: the badge beside | 82 | // The only label this control has, so the pending count belongs in it: the badge beside |
| 89 | // the icon is decorative and a reader who cannot see it still needs the number. | 83 | // the icon is decorative and a reader who cannot see it still needs the number. |
| 90 | aria-label={ | 84 | aria-label={ |
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx+1-2| ... | @@ -2662,8 +2662,7 @@ export function PullRequestDetailPanel({ | ... | @@ -2662,8 +2662,7 @@ export function PullRequestDetailPanel({ |
| 2662 | </PullRequestMetaLine> | 2662 | </PullRequestMetaLine> |
| 2663 | <Button | 2663 | <Button |
| 2664 | size="xs" | 2664 | size="xs" |
| 2665 | variant="ghost" | 2665 | variant="ghost-muted" |
| 2666 | className="h-7 px-2 text-[10px] text-muted-foreground" | ||
| 2667 | aria-label={ | 2666 | aria-label={ |
| 2668 | timelineOrder === "newest" | 2667 | timelineOrder === "newest" |
| 2669 | ? "Show oldest activity first" | 2668 | ? "Show oldest activity first" |
apps/web/src/components/pullRequest/PullRequestEditButton.tsx+6-7| ... | @@ -12,16 +12,15 @@ export function PullRequestEditButton({ | ... | @@ -12,16 +12,15 @@ export function PullRequestEditButton({ |
| 12 | "aria-label": string; | 12 | "aria-label": string; |
| 13 | }) { | 13 | }) { |
| 14 | return ( | 14 | return ( |
| 15 | <Button | 15 | <span |
| 16 | {...props} | ||
| 17 | size="icon-xs" | ||
| 18 | variant="ghost" | ||
| 19 | className={cn( | 16 | className={cn( |
| 20 | "shrink-0 text-muted-foreground opacity-0 transition-opacity pointer-coarse:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100 focus-visible:opacity-100 motion-reduce:transition-none", | 17 | "flex shrink-0 opacity-0 transition-opacity pointer-coarse:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100 focus-within:opacity-100 motion-reduce:transition-none", |
| 21 | className, | 18 | className, |
| 22 | )} | 19 | )} |
| 23 | > | 20 | > |
| 24 | <PencilIcon aria-hidden className="size-3" /> | 21 | <Button {...props} size="icon-xs" variant="ghost-muted"> |
| 25 | </Button> | 22 | <PencilIcon aria-hidden className="size-3" /> |
| 23 | </Button> | ||
| 24 | </span> | ||
| 26 | ); | 25 | ); |
| 27 | } | 26 | } |
apps/web/src/components/pullRequest/PullRequestReviewAnnotation.tsx+1-7| ... | @@ -312,7 +312,6 @@ export function ReviewThreadCard({ | ... | @@ -312,7 +312,6 @@ export function ReviewThreadCard({ |
| 312 | <Button | 312 | <Button |
| 313 | size="xs" | 313 | size="xs" |
| 314 | variant="ghost" | 314 | variant="ghost" |
| 315 | className="px-1" | ||
| 316 | disabled={loadingMore} | 315 | disabled={loadingMore} |
| 317 | onClick={() => void loadMore()} | 316 | onClick={() => void loadMore()} |
| 318 | > | 317 | > |
| ... | @@ -352,12 +351,7 @@ export function ReviewThreadCard({ | ... | @@ -352,12 +351,7 @@ export function ReviewThreadCard({ |
| 352 | </div> | 351 | </div> |
| 353 | </div> | 352 | </div> |
| 354 | ) : ( | 353 | ) : ( |
| 355 | <Button | 354 | <Button size="xs" variant="ghost" className="mt-2" onClick={() => setReplying(true)}> |
| 356 | size="xs" | ||
| 357 | variant="ghost" | ||
| 358 | className="mt-2 px-1" | ||
| 359 | onClick={() => setReplying(true)} | ||
| 360 | > | ||
| 361 | Reply | 355 | Reply |
| 362 | </Button> | 356 | </Button> |
| 363 | ) | 357 | ) |
apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx+2-2| ... | @@ -922,8 +922,8 @@ export function PullRequestSummaryTab({ | ... | @@ -922,8 +922,8 @@ export function PullRequestSummaryTab({ |
| 922 | actions={ | 922 | actions={ |
| 923 | <Button | 923 | <Button |
| 924 | size="xs" | 924 | size="xs" |
| 925 | variant="ghost" | 925 | variant="ghost-muted" |
| 926 | className="h-7 shrink-0 px-2 text-[10px] text-muted-foreground" | 926 | className="shrink-0" |
| 927 | aria-label={ | 927 | aria-label={ |
| 928 | commentOrder === "newest" | 928 | commentOrder === "newest" |
| 929 | ? "Show oldest comments first" | 929 | ? "Show oldest comments first" |
apps/web/src/components/settings/ConnectionsSettings.tsx+2-11| ... | @@ -3680,11 +3680,7 @@ export function ConnectionsSettings() { | ... | @@ -3680,11 +3680,7 @@ export function ConnectionsSettings() { |
| 3680 | headerAction={ | 3680 | headerAction={ |
| 3681 | <div className="flex items-center gap-1"> | 3681 | <div className="flex items-center gap-1"> |
| 3682 | {savedServerUpdateTargets.length > 0 ? ( | 3682 | {savedServerUpdateTargets.length > 0 ? ( |
| 3683 | <ServerUpdatesAction | 3683 | <ServerUpdatesAction targets={savedServerUpdateTargets} variant="ghost-muted" /> |
| 3684 | targets={savedServerUpdateTargets} | ||
| 3685 | variant="ghost" | ||
| 3686 | className="font-normal text-muted-foreground/60 hover:text-muted-foreground" | ||
| 3687 | /> | ||
| 3688 | ) : null} | 3684 | ) : null} |
| 3689 | <Dialog | 3685 | <Dialog |
| 3690 | open={addBackendDialogOpen} | 3686 | open={addBackendDialogOpen} |
| ... | @@ -3700,12 +3696,7 @@ export function ConnectionsSettings() { | ... | @@ -3700,12 +3696,7 @@ export function ConnectionsSettings() { |
| 3700 | render={ | 3696 | render={ |
| 3701 | <DialogTrigger | 3697 | <DialogTrigger |
| 3702 | render={ | 3698 | render={ |
| 3703 | <Button | 3699 | <Button size="xs" variant="ghost-muted" aria-label="Add environment"> |
| 3704 | size="xs" | ||
| 3705 | variant="ghost" | ||
| 3706 | className="font-normal text-muted-foreground/60 hover:text-muted-foreground" | ||
| 3707 | aria-label="Add environment" | ||
| 3708 | > | ||
| 3709 | <PlusIcon className="size-3" /> | 3700 | <PlusIcon className="size-3" /> |
| 3710 | <span>Add environment</span> | 3701 | <span>Add environment</span> |
| 3711 | </Button> | 3702 | </Button> |
apps/web/src/components/settings/KeybindingsSettings.tsx+2-2| ... | @@ -891,12 +891,12 @@ function WhenClauseControl({ | ... | @@ -891,12 +891,12 @@ function WhenClauseControl({ |
| 891 | <Button | 891 | <Button |
| 892 | variant={expression ? "ghost" : "ghost-muted"} | 892 | variant={expression ? "ghost" : "ghost-muted"} |
| 893 | size="micro" | 893 | size="micro" |
| 894 | className="min-w-0 shrink font-mono" | 894 | className="min-w-0 shrink" |
| 895 | /> | 895 | /> |
| 896 | } | 896 | } |
| 897 | aria-label={`Edit when clause for ${label}`} | 897 | aria-label={`Edit when clause for ${label}`} |
| 898 | > | 898 | > |
| 899 | <span className="truncate">{expression || "Always"}</span> | 899 | <span className="truncate font-mono">{expression || "Always"}</span> |
| 900 | <ChevronDownIcon className="size-3.5 shrink-0 opacity-60" /> | 900 | <ChevronDownIcon className="size-3.5 shrink-0 opacity-60" /> |
| 901 | </PopoverTrigger> | 901 | </PopoverTrigger> |
| 902 | <PopoverContent align="start" sideOffset={6}> | 902 | <PopoverContent align="start" sideOffset={6}> |
apps/web/src/components/settings/ProjectActionsList.tsx+11-10| ... | @@ -51,16 +51,17 @@ export function ProjectActionsList({ | ... | @@ -51,16 +51,17 @@ export function ProjectActionsList({ |
| 51 | {shortcutLabel ? ( | 51 | {shortcutLabel ? ( |
| 52 | <span className="text-xs text-muted-foreground">{shortcutLabel}</span> | 52 | <span className="text-xs text-muted-foreground">{shortcutLabel}</span> |
| 53 | ) : null} | 53 | ) : null} |
| 54 | <Button | 54 | <span className="flex shrink-0 opacity-0 group-focus-within:opacity-100 group-hover:opacity-100"> |
| 55 | size="icon-xs" | 55 | <Button |
| 56 | variant="ghost-muted" | 56 | size="icon-xs" |
| 57 | className="shrink-0 opacity-0 group-focus-within:opacity-100 group-hover:opacity-100" | 57 | variant="ghost-muted" |
| 58 | aria-label={`Edit ${script.name}`} | 58 | aria-label={`Edit ${script.name}`} |
| 59 | disabled={disabled} | 59 | disabled={disabled} |
| 60 | onClick={() => onEdit(script)} | 60 | onClick={() => onEdit(script)} |
| 61 | > | 61 | > |
| 62 | <SettingsIcon className="size-3.5" /> | 62 | <SettingsIcon className="size-3.5" /> |
| 63 | </Button> | 63 | </Button> |
| 64 | </span> | ||
| 64 | </> | 65 | </> |
| 65 | } | 66 | } |
| 66 | /> | 67 | /> |
apps/web/src/components/settings/ProviderAccentColorPicker.tsx+17-15| ... | @@ -92,21 +92,23 @@ function ProviderCustomColorPicker(props: { | ... | @@ -92,21 +92,23 @@ function ProviderCustomColorPicker(props: { |
| 92 | /> | 92 | /> |
| 93 | <PopoverPopup side="bottom" align="start" sideOffset={6} padding="none"> | 93 | <PopoverPopup side="bottom" align="start" sideOffset={6} padding="none"> |
| 94 | <ProviderCustomColorPanel value={normalized} onCommit={props.onCommit} /> | 94 | <ProviderCustomColorPanel value={normalized} onCommit={props.onCommit} /> |
| 95 | <PopoverClose | 95 | <div className="border-t border-border/60 p-1"> |
| 96 | render={ | 96 | <PopoverClose |
| 97 | <Button | 97 | render={ |
| 98 | type="button" | 98 | <Button |
| 99 | size="sm" | 99 | type="button" |
| 100 | variant="ghost" | 100 | size="compact" |
| 101 | className="h-8 w-full justify-start rounded-none border-t border-border/60 px-3 text-xs text-muted-foreground [--control-icon-color:currentColor]" | 101 | variant="ghost-muted" |
| 102 | onClick={props.onClear} | 102 | className="w-full justify-start" |
| 103 | disabled={!props.value} | 103 | onClick={props.onClear} |
| 104 | > | 104 | disabled={!props.value} |
| 105 | <XIcon className="size-3.5" aria-hidden /> | 105 | > |
| 106 | Clear color | 106 | <XIcon aria-hidden /> |
| 107 | </Button> | 107 | Clear color |
| 108 | } | 108 | </Button> |
| 109 | /> | 109 | } |
| 110 | /> | ||
| 111 | </div> | ||
| 110 | </PopoverPopup> | 112 | </PopoverPopup> |
| 111 | </Popover> | 113 | </Popover> |
| 112 | ); | 114 | ); |
apps/web/src/components/settings/SettingsSidebarNav.tsx+2-2| ... | @@ -265,8 +265,8 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) { | ... | @@ -265,8 +265,8 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) { |
| 265 | <Button | 265 | <Button |
| 266 | type="button" | 266 | type="button" |
| 267 | size="icon-micro" | 267 | size="icon-micro" |
| 268 | variant="ghost" | 268 | variant="ghost-muted" |
| 269 | className="shrink-0 text-sidebar-muted-foreground hover:bg-sidebar-control-surface hover:text-sidebar-foreground" | 269 | className="shrink-0" |
| 270 | aria-label="Clear settings search" | 270 | aria-label="Clear settings search" |
| 271 | onClick={() => { | 271 | onClick={() => { |
| 272 | clearSearch(); | 272 | clearSearch(); |
apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx+4-6| ... | @@ -11,7 +11,6 @@ import { | ... | @@ -11,7 +11,6 @@ import { |
| 11 | type ProviderUpdateSidebarPillView, | 11 | type ProviderUpdateSidebarPillView, |
| 12 | } from "../ProviderUpdateLaunchNotification.logic"; | 12 | } from "../ProviderUpdateLaunchNotification.logic"; |
| 13 | import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; | 13 | import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; |
| 14 | import { Button } from "../ui/button"; | ||
| 15 | 14 | ||
| 16 | const PROVIDER_UPDATE_PILL_STYLES = { | 15 | const PROVIDER_UPDATE_PILL_STYLES = { |
| 17 | loading: | 16 | loading: |
| ... | @@ -192,15 +191,14 @@ export function SidebarProviderUpdatePill() { | ... | @@ -192,15 +191,14 @@ export function SidebarProviderUpdatePill() { |
| 192 | <Tooltip> | 191 | <Tooltip> |
| 193 | <TooltipTrigger | 192 | <TooltipTrigger |
| 194 | render={ | 193 | render={ |
| 195 | <Button | 194 | <button |
| 196 | size="icon-micro" | 195 | type="button" |
| 197 | variant="ghost" | ||
| 198 | aria-label="Dismiss provider update notice" | 196 | aria-label="Dismiss provider update notice" |
| 199 | className="relative z-[1] mr-1 [--control-icon-color:currentColor] rounded-md text-inherit opacity-70 hover:bg-transparent hover:opacity-100" | 197 | className="relative z-[1] mr-1 flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-md opacity-70 outline-none hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring" |
| 200 | onClick={() => startExit(displayedView.key, null, displayedView.key)} | 198 | onClick={() => startExit(displayedView.key, null, displayedView.key)} |
| 201 | > | 199 | > |
| 202 | <XIcon className="size-3.5 shrink-0" /> | 200 | <XIcon className="size-3.5 shrink-0" /> |
| 203 | </Button> | 201 | </button> |
| 204 | } | 202 | } |
| 205 | /> | 203 | /> |
| 206 | <TooltipPopup side="top">Dismiss until provider status changes</TooltipPopup> | 204 | <TooltipPopup side="top">Dismiss until provider status changes</TooltipPopup> |
apps/web/src/components/sidebar/SidebarThreadHeader.tsx+2-2| ... | @@ -108,8 +108,8 @@ export function SidebarThreadHeader({ | ... | @@ -108,8 +108,8 @@ export function SidebarThreadHeader({ |
| 108 | <Button | 108 | <Button |
| 109 | type="button" | 109 | type="button" |
| 110 | size="icon-micro" | 110 | size="icon-micro" |
| 111 | variant="ghost" | 111 | variant="ghost-muted" |
| 112 | className="shrink-0 text-sidebar-muted-foreground hover:bg-sidebar-control-surface hover:text-sidebar-foreground" | 112 | className="shrink-0" |
| 113 | aria-label="Clear thread search" | 113 | aria-label="Clear thread search" |
| 114 | onClick={() => { | 114 | onClick={() => { |
| 115 | onClearSearch(); | 115 | onClearSearch(); |
apps/web/src/components/ui/button.tsx+2-2| ... | @@ -8,7 +8,7 @@ import type * as React from "react"; | ... | @@ -8,7 +8,7 @@ import type * as React from "react"; |
| 8 | import { cn } from "~/lib/utils"; | 8 | import { cn } from "~/lib/utils"; |
| 9 | 9 | ||
| 10 | const buttonVariants = cva( | 10 | const buttonVariants = cva( |
| 11 | "[--control-icon-color:currentColor] [&_svg]:-mx-0.5 relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-[var(--control-radius)] border font-medium text-base outline-none transition-[box-shadow,scale] [&:active:not([aria-haspopup])]:scale-[0.97] before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--control-radius)-1px)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 sm:text-sm [&_svg:not([class*='text-'])]:text-[var(--control-icon-color)] [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", | 11 | "[--control-icon-color:currentColor] [&_svg]:-mx-0.5 relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-[var(--control-radius)] border font-medium text-base outline-none transition-[box-shadow,scale] [&:active:not([aria-haspopup])]:scale-[0.97] before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--control-radius)-1px)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 aria-disabled:cursor-not-allowed aria-disabled:opacity-64 sm:text-sm [&_svg:not([class*='text-'])]:text-[var(--control-icon-color)] [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", |
| 12 | { | 12 | { |
| 13 | defaultVariants: { | 13 | defaultVariants: { |
| 14 | size: "default", | 14 | size: "default", |
| ... | @@ -52,7 +52,7 @@ const buttonVariants = cva( | ... | @@ -52,7 +52,7 @@ const buttonVariants = cva( |
| 52 | "ghost-destructive": | 52 | "ghost-destructive": |
| 53 | "[--control-icon-color:currentColor] border-transparent text-muted-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent [:hover,[data-pressed]]:text-destructive", | 53 | "[--control-icon-color:currentColor] border-transparent text-muted-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent [:hover,[data-pressed]]:text-destructive", |
| 54 | glass: | 54 | glass: |
| 55 | "surface-glass [--control-icon-color:var(--contrast-muted-foreground)] border-border/60 text-foreground shadow-sm [:hover,[data-pressed]]:border-border", | 55 | "surface-glass [--control-icon-color:var(--contrast-muted-foreground)] rounded-full border-border/60 text-foreground shadow-sm before:rounded-full [:hover,[data-pressed]]:border-border", |
| 56 | link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline", | 56 | link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline", |
| 57 | "media-close": | 57 | "media-close": |
| 58 | "[--control-icon-color:currentColor] border-transparent bg-black/65 text-white shadow-sm ring-1 ring-white/20 [:hover,[data-pressed]]:bg-black/80 focus-visible:ring-white", | 58 | "[--control-icon-color:currentColor] border-transparent bg-black/65 text-white shadow-sm ring-1 ring-white/20 [:hover,[data-pressed]]:bg-black/80 focus-visible:ring-white", |
apps/web/src/components/ui/input.tsx+3| ... | @@ -28,6 +28,9 @@ function Input({ | ... | @@ -28,6 +28,9 @@ function Input({ |
| 28 | size === "lg" && "h-9.5 leading-9.5 sm:h-8.5 sm:leading-8.5", | 28 | size === "lg" && "h-9.5 leading-9.5 sm:h-8.5 sm:leading-8.5", |
| 29 | props.type === "search" && | 29 | props.type === "search" && |
| 30 | "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none [&::-webkit-search-results-button]:appearance-none [&::-webkit-search-results-decoration]:appearance-none", | 30 | "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none [&::-webkit-search-results-button]:appearance-none [&::-webkit-search-results-decoration]:appearance-none", |
| 31 | // Number fields are typed into; browser spin buttons crowd narrow fields and step by 1. | ||
| 32 | props.type === "number" && | ||
| 33 | "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none", | ||
| 31 | props.type === "file" && | 34 | props.type === "file" && |
| 32 | "text-muted-foreground file:me-3 file:bg-transparent file:font-medium file:text-foreground file:text-sm", | 35 | "text-muted-foreground file:me-3 file:bg-transparent file:font-medium file:text-foreground file:text-sm", |
| 33 | ); | 36 | ); |
apps/web/src/index.css+2-18| ... | @@ -1350,8 +1350,7 @@ html[data-theme-id] .chat-markdown .chat-markdown-codeblock pre { | ... | @@ -1350,8 +1350,7 @@ html[data-theme-id] .chat-markdown .chat-markdown-codeblock pre { |
| 1350 | background-color: transparent; | 1350 | background-color: transparent; |
| 1351 | } | 1351 | } |
| 1352 | 1352 | ||
| 1353 | html[data-theme-id] .chat-markdown .chat-markdown-codeblock-header, | 1353 | html[data-theme-id] .chat-markdown .chat-markdown-codeblock-header { |
| 1354 | html[data-theme-id] .chat-markdown .chat-markdown-chrome-action { | ||
| 1355 | color: color-mix(in srgb, var(--code-foreground) 72%, transparent); | 1354 | color: color-mix(in srgb, var(--code-foreground) 72%, transparent); |
| 1356 | } | 1355 | } |
| 1357 | 1356 | ||
| ... | @@ -1377,11 +1376,6 @@ html[data-theme-id="t3-chat"] { | ... | @@ -1377,11 +1376,6 @@ html[data-theme-id="t3-chat"] { |
| 1377 | } | 1376 | } |
| 1378 | } | 1377 | } |
| 1379 | 1378 | ||
| 1380 | html[data-theme-id] .chat-markdown .chat-markdown-chrome-action:hover, | ||
| 1381 | html[data-theme-id] .chat-markdown .chat-markdown-chrome-action[aria-pressed="true"] { | ||
| 1382 | color: var(--code-foreground); | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | html[data-theme-id] [data-app-sidebar] { | 1379 | html[data-theme-id] [data-app-sidebar] { |
| 1386 | --background: var(--app-theme-canvas); | 1380 | --background: var(--app-theme-canvas); |
| 1387 | --foreground: var(--app-theme-text); | 1381 | --foreground: var(--app-theme-text); |
| ... | @@ -1858,20 +1852,10 @@ code { | ... | @@ -1858,20 +1852,10 @@ code { |
| 1858 | background: color-mix(in srgb, var(--contrast-border) 78%, transparent); | 1852 | background: color-mix(in srgb, var(--contrast-border) 78%, transparent); |
| 1859 | } | 1853 | } |
| 1860 | 1854 | ||
| 1861 | .chat-markdown .chat-markdown-codeblock-header, | 1855 | .chat-markdown .chat-markdown-codeblock-header { |
| 1862 | .chat-markdown .chat-markdown-chrome-action { | ||
| 1863 | color: color-mix(in srgb, var(--contrast-foreground) 72%, transparent); | 1856 | color: color-mix(in srgb, var(--contrast-foreground) 72%, transparent); |
| 1864 | } | 1857 | } |
| 1865 | 1858 | ||
| 1866 | .chat-markdown .chat-markdown-chrome-action:hover { | ||
| 1867 | color: var(--contrast-foreground); | ||
| 1868 | } | ||
| 1869 | |||
| 1870 | .chat-markdown .chat-markdown-chrome-action[aria-pressed="true"] { | ||
| 1871 | color: var(--contrast-foreground); | ||
| 1872 | background: color-mix(in srgb, var(--contrast-foreground) 8%, transparent); | ||
| 1873 | } | ||
| 1874 | |||
| 1875 | .chat-markdown .chat-markdown-codeblock pre { | 1859 | .chat-markdown .chat-markdown-codeblock pre { |
| 1876 | margin: 0; | 1860 | margin: 0; |
| 1877 | border: none; | 1861 | border: none; |
scripts/lint-restyle-ceiling.ts+1-1| ... | @@ -8,7 +8,7 @@ import * as NodeURL from "node:url"; | ... | @@ -8,7 +8,7 @@ import * as NodeURL from "node:url"; |
| 8 | // components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the | 8 | // components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the |
| 9 | // count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you | 9 | // count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you |
| 10 | // migrate a file, and delete this script when the rule becomes an error. | 10 | // migrate a file, and delete this script when the rule becomes an error. |
| 11 | export const RESTYLE_CEILING = 250; | 11 | export const RESTYLE_CEILING = 101; |
| 12 | 12 | ||
| 13 | const RULE = "shadcn(no-restyle)"; | 13 | const RULE = "shadcn(no-restyle)"; |
| 14 | 14 |