| 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 | 242 | onChange={(event) => updateCustomDimension("width", event.target.value)} |
| 243 | 243 | aria-label="Viewport width" |
| 244 | 244 | aria-invalid={!customValid} |
| 245 | className={cn( | |
| 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 | )} | |
| 245 | className={width >= 360 ? "w-14" : "w-13"} | |
| 249 | 246 | /> |
| 250 | 247 | <span className="text-xs text-muted-foreground">×</span> |
| 251 | 248 | <Input |
| ... | ... | @@ -270,10 +267,7 @@ export function BrowserDeviceToolbar({ |
| 270 | 267 | onChange={(event) => updateCustomDimension("height", event.target.value)} |
| 271 | 268 | aria-label="Viewport height" |
| 272 | 269 | aria-invalid={!customValid} |
| 273 | className={cn( | |
| 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 | )} | |
| 270 | className={width >= 360 ? "w-14" : "w-13"} | |
| 277 | 271 | /> |
| 278 | 272 | </form> |
| 279 | 273 | |
| ... | ... | @@ -281,14 +275,13 @@ export function BrowserDeviceToolbar({ |
| 281 | 275 | <TooltipTrigger |
| 282 | 276 | render={ |
| 283 | 277 | <Button |
| 284 | variant="ghost" | |
| 278 | variant={aspectRatio === null ? "ghost" : "secondary"} | |
| 285 | 279 | size="icon-xs" |
| 286 | 280 | type="button" |
| 287 | 281 | aria-label={ |
| 288 | 282 | aspectRatio === null ? "Lock viewport aspect ratio" : "Unlock viewport aspect ratio" |
| 289 | 283 | } |
| 290 | 284 | aria-pressed={aspectRatio !== null} |
| 291 | className={cn(aspectRatio !== null && "bg-accent text-foreground")} | |
| 292 | 285 | disabled={pending || !customValid} |
| 293 | 286 | onPointerDown={(event) => event.preventDefault()} |
| 294 | 287 | onClick={toggleAspectRatio} |
| ... | ... | @@ -315,19 +308,21 @@ export function BrowserDeviceToolbar({ |
| 315 | 308 | > |
| 316 | 309 | <ScreenRotationIcon /> |
| 317 | 310 | </Button> |
| 318 | <Button | |
| 319 | variant="ghost" | |
| 320 | size="icon-xs" | |
| 321 | type="button" | |
| 322 | aria-label="Close device toolbar" | |
| 323 | className="sticky right-0 ml-auto bg-background/95" | |
| 324 | disabled={pending} | |
| 325 | onClick={() => { | |
| 326 | apply({ _tag: "fill" }, null); | |
| 327 | }} | |
| 328 | > | |
| 329 | <X /> | |
| 330 | </Button> | |
| 311 | {/* Sticky backing so scrolled controls do not show through the close action. */} | |
| 312 | <span className="sticky right-0 ml-auto flex bg-background/95"> | |
| 313 | <Button | |
| 314 | variant="ghost" | |
| 315 | size="icon-xs" | |
| 316 | type="button" | |
| 317 | aria-label="Close device toolbar" | |
| 318 | disabled={pending} | |
| 319 | onClick={() => { | |
| 320 | apply({ _tag: "fill" }, null); | |
| 321 | }} | |
| 322 | > | |
| 323 | <X /> | |
| 324 | </Button> | |
| 325 | </span> | |
| 331 | 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 | 784 | render={ |
| 785 | 785 | <Button |
| 786 | 786 | type="button" |
| 787 | variant="ghost" | |
| 787 | variant={expanded ? "secondary" : "ghost-muted"} | |
| 788 | 788 | size="icon-xs" |
| 789 | className="chat-markdown-chrome-action" | |
| 790 | 789 | aria-pressed={expanded} |
| 791 | 790 | onClick={toggleExpanded} |
| 792 | 791 | aria-label={expandLabel} |
| ... | ... | @@ -805,9 +804,8 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { |
| 805 | 804 | render={ |
| 806 | 805 | <Button |
| 807 | 806 | type="button" |
| 808 | variant="ghost" | |
| 807 | variant="ghost-muted" | |
| 809 | 808 | size="icon-xs" |
| 810 | className="chat-markdown-chrome-action" | |
| 811 | 809 | aria-label={copyLabel} |
| 812 | 810 | /> |
| 813 | 811 | } |
| ... | ... | @@ -993,9 +991,8 @@ function MarkdownCodeBlock({ |
| 993 | 991 | render={ |
| 994 | 992 | <Button |
| 995 | 993 | type="button" |
| 996 | variant="ghost" | |
| 994 | variant={wrapped ? "secondary" : "ghost-muted"} | |
| 997 | 995 | size="icon-xs" |
| 998 | className="chat-markdown-chrome-action" | |
| 999 | 996 | aria-pressed={wrapped} |
| 1000 | 997 | onClick={() => setWrapped((value) => !value)} |
| 1001 | 998 | aria-label={wrapLabel} |
| ... | ... | @@ -1011,9 +1008,8 @@ function MarkdownCodeBlock({ |
| 1011 | 1008 | render={ |
| 1012 | 1009 | <Button |
| 1013 | 1010 | type="button" |
| 1014 | variant="ghost" | |
| 1011 | variant="ghost-muted" | |
| 1015 | 1012 | size="icon-xs" |
| 1016 | className="chat-markdown-chrome-action" | |
| 1017 | 1013 | onClick={handleCopy} |
| 1018 | 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 | 9991 | composerRef.current?.restoreAfterTimelineReachedEnd(); |
| 9992 | 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 | 9995 | size="xs" |
| 9996 | 9996 | variant="glass" |
| 9997 | 9997 | > |
apps/web/src/components/CommandPalette.tsx+4-8| ... | ... | @@ -1528,9 +1528,8 @@ function OpenCommandPaletteDialog(props: { |
| 1528 | 1528 | <TooltipTrigger |
| 1529 | 1529 | render={ |
| 1530 | 1530 | <Button |
| 1531 | variant="outline" | |
| 1532 | size="xs" | |
| 1533 | className="h-5 rounded-[.25rem] px-1.5 text-[10px] text-warning-foreground" | |
| 1531 | variant="warning-outline" | |
| 1532 | size="micro" | |
| 1534 | 1533 | onClick={() => { |
| 1535 | 1534 | openSourceControlSettings(); |
| 1536 | 1535 | }} |
| ... | ... | @@ -2861,7 +2860,7 @@ function OpenCommandPaletteDialog(props: { |
| 2861 | 2860 | variant="outline" |
| 2862 | 2861 | size="xs" |
| 2863 | 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 | 2864 | aria-label={`${remoteProjectButtonLabel ?? "Continue"} (Enter)`} |
| 2866 | 2865 | disabled={!canSubmitRemoteProjectFlow} |
| 2867 | 2866 | onMouseDown={(event) => { |
| ... | ... | @@ -2888,10 +2887,7 @@ function OpenCommandPaletteDialog(props: { |
| 2888 | 2887 | variant="outline" |
| 2889 | 2888 | size="xs" |
| 2890 | 2889 | tabIndex={-1} |
| 2891 | className={cn( | |
| 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 | )} | |
| 2890 | className="absolute inset-e-2.5 top-1/2 -translate-y-1/2" | |
| 2895 | 2891 | aria-label={`${submitActionLabel} (${addShortcutLabel})`} |
| 2896 | 2892 | disabled={ |
| 2897 | 2893 | !canCreateProjectInEnvironment(browseEnvironment?.connection.phase) || |
apps/web/src/components/CustomSnoozeDialog.tsx+1-1| ... | ... | @@ -119,7 +119,7 @@ function CustomSnoozeDialog() { |
| 119 | 119 | <Button |
| 120 | 120 | id={`${id}-date`} |
| 121 | 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 | 1125 | <Button |
| 1126 | 1126 | size="icon-micro" |
| 1127 | 1127 | variant="ghost" |
| 1128 | className={cn( | |
| 1129 | "-ms-0.5 [--control-icon-color:currentColor] bg-transparent hover:bg-foreground/10", | |
| 1130 | getDiffCollapseIconClassName(fileDiff), | |
| 1131 | )} | |
| 1128 | className="-ms-0.5" | |
| 1132 | 1129 | aria-label={ |
| 1133 | 1130 | collapsed ? `Expand ${filePath}` : `Collapse ${filePath}` |
| 1134 | 1131 | } |
| ... | ... | @@ -1142,9 +1139,13 @@ export default function DiffPanel({ |
| 1142 | 1139 | } |
| 1143 | 1140 | > |
| 1144 | 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 | 1150 | </TooltipTrigger> |
| 1150 | 1151 | <TooltipPopup side="top"> |
apps/web/src/components/GitActionsControl.tsx+7-16| ... | ... | @@ -646,9 +646,8 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) { |
| 646 | 646 | <TooltipTrigger |
| 647 | 647 | render={ |
| 648 | 648 | <Button |
| 649 | variant="outline" | |
| 650 | size="xs" | |
| 651 | className="h-5 rounded-[.25rem] px-1.5 text-[10px] text-warning-foreground" | |
| 649 | variant="warning-outline" | |
| 650 | size="micro" | |
| 652 | 651 | onClick={(event) => { |
| 653 | 652 | event.preventDefault(); |
| 654 | 653 | event.stopPropagation(); |
| ... | ... | @@ -1799,14 +1798,7 @@ export default function GitActionsControl({ |
| 1799 | 1798 | <Popover> |
| 1800 | 1799 | <PopoverTrigger |
| 1801 | 1800 | openOnHover |
| 1802 | render={ | |
| 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 | } | |
| 1801 | render={<Button aria-disabled="true" size="xs" variant="outline" />} | |
| 1810 | 1802 | > |
| 1811 | 1803 | <GitQuickActionIcon |
| 1812 | 1804 | quickAction={quickAction} |
| ... | ... | @@ -1824,7 +1816,6 @@ export default function GitActionsControl({ |
| 1824 | 1816 | <Button |
| 1825 | 1817 | variant="outline" |
| 1826 | 1818 | size="xs" |
| 1827 | className="ps-[8.5px]" | |
| 1828 | 1819 | disabled={isGitActionRunning || quickAction.disabled} |
| 1829 | 1820 | onClick={runQuickAction} |
| 1830 | 1821 | > |
| ... | ... | @@ -2056,16 +2047,16 @@ export default function GitActionsControl({ |
| 2056 | 2047 | Abort |
| 2057 | 2048 | </Button> |
| 2058 | 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 | 2051 | variant="outline" |
| 2061 | size="sm" | |
| 2052 | size="sm-multiline" | |
| 2062 | 2053 | onClick={continuePendingDefaultBranchAction} |
| 2063 | 2054 | > |
| 2064 | 2055 | {pendingDefaultBranchActionCopy?.continueLabel ?? "Continue"} |
| 2065 | 2056 | </Button> |
| 2066 | 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" | |
| 2068 | size="sm" | |
| 2058 | className="w-full max-w-full sm:w-auto" | |
| 2059 | size="sm-multiline" | |
| 2069 | 2060 | onClick={checkoutFeatureBranchAndContinuePendingAction} |
| 2070 | 2061 | > |
| 2071 | 2062 | Check out feature branch & continue |
apps/web/src/components/ProjectScriptsControl.tsx+23-19| ... | ... | @@ -192,24 +192,28 @@ export default function ProjectScriptsControl({ |
| 192 | 192 | <MenuShortcut className="ms-0">{shortcutLabel}</MenuShortcut> |
| 193 | 193 | </span> |
| 194 | 194 | ))} |
| 195 | <Button | |
| 196 | type="button" | |
| 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 | }} | |
| 195 | <span | |
| 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"}`} | |
| 210 | 197 | > |
| 211 | <SettingsIcon className="size-3.5" /> | |
| 212 | </Button> | |
| 198 | <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 | 217 | </span> |
| 214 | 218 | </MenuItem> |
| 215 | 219 | ); |
| ... | ... | @@ -269,7 +273,7 @@ export default function ProjectScriptsControl({ |
| 269 | 273 | <Button |
| 270 | 274 | size="xs" |
| 271 | 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 | 277 | aria-label={`Run ${primaryScript.name}`} |
| 274 | 278 | // The tooltip wrapper replaces data-slot="button", so themed |
| 275 | 279 | // toolbar styling needs its own hook. |
| ... | ... | @@ -329,7 +333,7 @@ export default function ProjectScriptsControl({ |
| 329 | 333 | <Button |
| 330 | 334 | size="xs" |
| 331 | 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 | 337 | aria-label="Add action" |
| 334 | 338 | // The tooltip wrapper replaces data-slot="button", so themed |
| 335 | 339 | // toolbar styling needs its own hook. |
apps/web/src/components/ServerUpdateAction.tsx+2-2| ... | ... | @@ -270,8 +270,8 @@ export function ServerUpdateAction({ |
| 270 | 270 | render={ |
| 271 | 271 | <Button |
| 272 | 272 | size="icon-xs" |
| 273 | variant="ghost" | |
| 274 | className={className ?? "text-muted-foreground hover:text-foreground"} | |
| 273 | variant="ghost-muted" | |
| 274 | className={className} | |
| 275 | 275 | aria-label={`${actionLabel} for ${serverLabel}`} |
| 276 | 276 | onClick={onClick} |
| 277 | 277 | /> |
apps/web/src/components/Sidebar.tsx+1-1| ... | ... | @@ -4500,7 +4500,7 @@ export default function Sidebar() { |
| 4500 | 4500 | tabIndex={-1} |
| 4501 | 4501 | aria-hidden="true" |
| 4502 | 4502 | title={`Project settings for ${project.displayName}`} |
| 4503 | className="ml-auto focus-visible:bg-accent focus-visible:text-foreground" | |
| 4503 | className="ml-auto" | |
| 4504 | 4504 | onPointerDown={(event) => event.stopPropagation()} |
| 4505 | 4505 | onClick={(event) => { |
| 4506 | 4506 | void handleProjectSettings(event, project); |
apps/web/src/components/chat/AssistantSelectionToolbar.tsx+1-1| ... | ... | @@ -134,7 +134,7 @@ export function AssistantSelectionToolbar({ |
| 134 | 134 | variant="glass" |
| 135 | 135 | disabled={tooLong} |
| 136 | 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 | 138 | style={{ left: selection.position.x, top: selection.position.y }} |
| 139 | 139 | onPointerDown={(event) => event.preventDefault()} |
| 140 | 140 | onClick={cite} |
apps/web/src/components/chat/ContextWindowMeter.tsx+1-1| ... | ... | @@ -45,7 +45,7 @@ export function ContextWindowMeter(props: { |
| 45 | 45 | <Button |
| 46 | 46 | size="icon-sm" |
| 47 | 47 | variant="ghost-muted" |
| 48 | className="size-7 rounded-full hover:text-muted-foreground data-pressed:text-muted-foreground" | |
| 48 | className="size-7" | |
| 49 | 49 | aria-label={ |
| 50 | 50 | usage.maxTokens !== null && usedPercentage |
| 51 | 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 | 193 | type="button" |
| 194 | 194 | size="icon" |
| 195 | 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 | 197 | aria-label="Previous media" |
| 198 | 198 | onClick={() => navigateImage(-1)} |
| 199 | 199 | > |
| ... | ... | @@ -252,12 +252,11 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 252 | 252 | <Button |
| 253 | 253 | aria-label={contentsLabel} |
| 254 | 254 | aria-pressed={showingAccessibilityDetails} |
| 255 | className="[--control-icon-color:currentColor] hover:bg-white/10 hover:text-white" | |
| 256 | 255 | onClick={() => |
| 257 | 256 | setAccessibilityDetailsSrc(showingAccessibilityDetails ? null : item.src) |
| 258 | 257 | } |
| 259 | 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 | 265 | <TooltipPopup side="top">{contentsLabel}</TooltipPopup> |
| 267 | 266 | </Tooltip> |
| 268 | 267 | ) : item.source ? ( |
| 269 | <SnapShotContentsButton | |
| 270 | source={item.source} | |
| 271 | side="top" | |
| 272 | className="hover:bg-white/10 hover:text-white" | |
| 273 | /> | |
| 268 | <SnapShotContentsButton source={item.source} side="top" /> | |
| 274 | 269 | ) : null} |
| 275 | 270 | </div> |
| 276 | 271 | </div> |
| ... | ... | @@ -280,7 +275,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 280 | 275 | type="button" |
| 281 | 276 | size="icon" |
| 282 | 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 | 279 | aria-label="Next media" |
| 285 | 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 | 2 | import { CopyIcon, CheckIcon } from "lucide-react"; |
| 3 | 3 | import { Button } from "../ui/button"; |
| 4 | 4 | import { useCopyToClipboard } from "~/hooks/useCopyToClipboard"; |
| 5 | import { cn } from "~/lib/utils"; | |
| 6 | 5 | import { |
| 7 | 6 | ANCHORED_COPY_TOAST_TIMEOUT_MS, |
| 8 | 7 | showAnchoredCopyErrorToast, |
| ... | ... | @@ -43,8 +42,8 @@ export const MessageCopyButton = memo(function MessageCopyButton({ |
| 43 | 42 | ref={ref} |
| 44 | 43 | type="button" |
| 45 | 44 | size={size} |
| 46 | variant={variant} | |
| 47 | className={cn("text-muted-foreground hover:text-foreground", className)} | |
| 45 | variant={variant === "ghost" ? "ghost-muted" : variant} | |
| 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 | 3956 | <Button |
| 3957 | 3957 | type="button" |
| 3958 | 3958 | size="xs" |
| 3959 | variant="ghost" | |
| 3959 | variant="ghost-muted" | |
| 3960 | 3960 | aria-expanded={expanded} |
| 3961 | 3961 | data-scroll-anchor-ignore |
| 3962 | 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 | 3965 | {expanded ? "Show less" : "Show full message"} |
| 3966 | 3966 | </Button> |
apps/web/src/components/chat/OpenInPicker.tsx-1| ... | ... | @@ -353,7 +353,6 @@ export const OpenInPicker = memo(function OpenInPicker({ |
| 353 | 353 | <Group aria-label="Open in editor"> |
| 354 | 354 | <Button |
| 355 | 355 | aria-label={compact ? "Open file in preferred editor" : undefined} |
| 356 | className="ps-[8.5px]" | |
| 357 | 356 | size="xs" |
| 358 | 357 | variant="outline" |
| 359 | 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 | 153 | className={className} |
| 154 | 154 | onClick={(event) => event.stopPropagation()} |
| 155 | 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 | 211 | <div className="min-w-0 flex-1"> |
| 212 | 212 | <div className="flex min-w-0 items-center gap-1.5 text-[11px] font-medium leading-3.5 text-white"> |
| 213 | 213 | <span className="truncate">{source.appName}</span> |
| 214 | <SnapShotContentsButton | |
| 215 | source={source} | |
| 216 | className="pointer-events-auto text-white/60 hover:bg-white/10 hover:text-white focus-visible:ring-white/70" | |
| 217 | /> | |
| 214 | <SnapShotContentsButton source={source} className="pointer-events-auto" /> | |
| 218 | 215 | </div> |
| 219 | 216 | <div className="truncate text-[9px] leading-3.5 text-white/70"> |
| 220 | 217 | {source.windowTitle || "Captured window"} |
apps/web/src/components/diffs/DiffCommentAnnotation.tsx+10-9| ... | ... | @@ -67,15 +67,16 @@ export function DiffCommentAnnotation({ |
| 67 | 67 | <MessageCircle className="mt-0.5 size-3.5 shrink-0 text-primary/70" aria-hidden="true" /> |
| 68 | 68 | <p className="min-w-0 flex-1 whitespace-pre-wrap text-[13px] leading-5">{displayedText}</p> |
| 69 | 69 | {onDelete ? ( |
| 70 | <Button | |
| 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" | |
| 72 | variant="ghost-muted" | |
| 73 | size="icon-xs" | |
| 74 | aria-label="Delete comment" | |
| 75 | onClick={onDelete} | |
| 76 | > | |
| 77 | <Trash2 className="size-3" /> | |
| 78 | </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 | <Button | |
| 72 | variant="ghost-muted" | |
| 73 | size="icon-xs" | |
| 74 | aria-label="Delete comment" | |
| 75 | onClick={onDelete} | |
| 76 | > | |
| 77 | <Trash2 className="size-3" /> | |
| 78 | </Button> | |
| 79 | </span> | |
| 79 | 80 | ) : null} |
| 80 | 81 | </div> |
| 81 | 82 | ); |
apps/web/src/components/onboarding/WelcomeWizard.tsx+5-7| ... | ... | @@ -357,12 +357,13 @@ function ConnectionStep({ |
| 357 | 357 | render={ |
| 358 | 358 | <Button |
| 359 | 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 | 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 | 367 | <ChevronRightIcon |
| 367 | 368 | className={cn("size-4 text-muted-foreground", pairingOpen && "rotate-90")} |
| 368 | 369 | /> |
| ... | ... | @@ -429,14 +430,11 @@ function ConnectAccountOption({ |
| 429 | 430 | } |
| 430 | 431 | }} |
| 431 | 432 | render={ |
| 432 | <Button | |
| 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 | /> | |
| 433 | <Button variant="ghost" size="sm-multiline" className="min-h-14 w-full justify-start" /> | |
| 436 | 434 | } |
| 437 | 435 | > |
| 438 | 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 | 438 | <span className="text-xs text-muted-foreground"> |
| 441 | 439 | {!isLoaded |
| 442 | 440 | ? "Loading sign-in…" |
apps/web/src/components/preview/PreviewMoreMenu.tsx-1| ... | ... | @@ -185,7 +185,6 @@ export function PreviewMoreMenu({ |
| 185 | 185 | type="button" |
| 186 | 186 | onClick={callTab(bridge.resetZoom)} |
| 187 | 187 | aria-label="Reset zoom" |
| 188 | className="[:hover,[data-pressed]]:bg-foreground/10" | |
| 189 | 188 | disabled={tabDisabled} |
| 190 | 189 | > |
| 191 | 190 | <RotateCcw /> |
apps/web/src/components/projectScriptEditor.tsx+1-1| ... | ... | @@ -319,7 +319,7 @@ export function ProjectScriptEditorDialog({ |
| 319 | 319 | <Button |
| 320 | 320 | type="button" |
| 321 | 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 | 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 | 785 | variant="ghost-muted" |
| 786 | 786 | aria-expanded={!collapsed} |
| 787 | 787 | aria-label={collapsed ? "Expand diff" : "Collapse diff"} |
| 788 | className="mr-1 rounded hover:bg-transparent" | |
| 788 | className="mr-1" | |
| 789 | 789 | onClick={(event) => { |
| 790 | 790 | event.stopPropagation(); |
| 791 | 791 | toggleFile(item.id); |
apps/web/src/components/pullRequest/PullRequestComposer.tsx+1-7| ... | ... | @@ -78,13 +78,7 @@ export function PullRequestComposer({ |
| 78 | 78 | }} |
| 79 | 79 | > |
| 80 | 80 | <PopoverTrigger |
| 81 | render={ | |
| 82 | <Button | |
| 83 | size="icon" | |
| 84 | variant="glass" | |
| 85 | className="rounded-full shadow-lg [--glass-opacity:50%]" | |
| 86 | /> | |
| 87 | } | |
| 81 | render={<Button size="icon" variant="glass" />} | |
| 88 | 82 | // The only label this control has, so the pending count belongs in it: the badge beside |
| 89 | 83 | // the icon is decorative and a reader who cannot see it still needs the number. |
| 90 | 84 | aria-label={ |
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx+1-2| ... | ... | @@ -2662,8 +2662,7 @@ export function PullRequestDetailPanel({ |
| 2662 | 2662 | </PullRequestMetaLine> |
| 2663 | 2663 | <Button |
| 2664 | 2664 | size="xs" |
| 2665 | variant="ghost" | |
| 2666 | className="h-7 px-2 text-[10px] text-muted-foreground" | |
| 2665 | variant="ghost-muted" | |
| 2667 | 2666 | aria-label={ |
| 2668 | 2667 | timelineOrder === "newest" |
| 2669 | 2668 | ? "Show oldest activity first" |
apps/web/src/components/pullRequest/PullRequestEditButton.tsx+6-7| ... | ... | @@ -12,16 +12,15 @@ export function PullRequestEditButton({ |
| 12 | 12 | "aria-label": string; |
| 13 | 13 | }) { |
| 14 | 14 | return ( |
| 15 | <Button | |
| 16 | {...props} | |
| 17 | size="icon-xs" | |
| 18 | variant="ghost" | |
| 15 | <span | |
| 19 | 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 | 18 | className, |
| 22 | 19 | )} |
| 23 | 20 | > |
| 24 | <PencilIcon aria-hidden className="size-3" /> | |
| 25 | </Button> | |
| 21 | <Button {...props} size="icon-xs" variant="ghost-muted"> | |
| 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 | 312 | <Button |
| 313 | 313 | size="xs" |
| 314 | 314 | variant="ghost" |
| 315 | className="px-1" | |
| 316 | 315 | disabled={loadingMore} |
| 317 | 316 | onClick={() => void loadMore()} |
| 318 | 317 | > |
| ... | ... | @@ -352,12 +351,7 @@ export function ReviewThreadCard({ |
| 352 | 351 | </div> |
| 353 | 352 | </div> |
| 354 | 353 | ) : ( |
| 355 | <Button | |
| 356 | size="xs" | |
| 357 | variant="ghost" | |
| 358 | className="mt-2 px-1" | |
| 359 | onClick={() => setReplying(true)} | |
| 360 | > | |
| 354 | <Button size="xs" variant="ghost" className="mt-2" onClick={() => setReplying(true)}> | |
| 361 | 355 | Reply |
| 362 | 356 | </Button> |
| 363 | 357 | ) |
apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx+2-2| ... | ... | @@ -922,8 +922,8 @@ export function PullRequestSummaryTab({ |
| 922 | 922 | actions={ |
| 923 | 923 | <Button |
| 924 | 924 | size="xs" |
| 925 | variant="ghost" | |
| 926 | className="h-7 shrink-0 px-2 text-[10px] text-muted-foreground" | |
| 925 | variant="ghost-muted" | |
| 926 | className="shrink-0" | |
| 927 | 927 | aria-label={ |
| 928 | 928 | commentOrder === "newest" |
| 929 | 929 | ? "Show oldest comments first" |
apps/web/src/components/settings/ConnectionsSettings.tsx+2-11| ... | ... | @@ -3680,11 +3680,7 @@ export function ConnectionsSettings() { |
| 3680 | 3680 | headerAction={ |
| 3681 | 3681 | <div className="flex items-center gap-1"> |
| 3682 | 3682 | {savedServerUpdateTargets.length > 0 ? ( |
| 3683 | <ServerUpdatesAction | |
| 3684 | targets={savedServerUpdateTargets} | |
| 3685 | variant="ghost" | |
| 3686 | className="font-normal text-muted-foreground/60 hover:text-muted-foreground" | |
| 3687 | /> | |
| 3683 | <ServerUpdatesAction targets={savedServerUpdateTargets} variant="ghost-muted" /> | |
| 3688 | 3684 | ) : null} |
| 3689 | 3685 | <Dialog |
| 3690 | 3686 | open={addBackendDialogOpen} |
| ... | ... | @@ -3700,12 +3696,7 @@ export function ConnectionsSettings() { |
| 3700 | 3696 | render={ |
| 3701 | 3697 | <DialogTrigger |
| 3702 | 3698 | render={ |
| 3703 | <Button | |
| 3704 | size="xs" | |
| 3705 | variant="ghost" | |
| 3706 | className="font-normal text-muted-foreground/60 hover:text-muted-foreground" | |
| 3707 | aria-label="Add environment" | |
| 3708 | > | |
| 3699 | <Button size="xs" variant="ghost-muted" aria-label="Add environment"> | |
| 3709 | 3700 | <PlusIcon className="size-3" /> |
| 3710 | 3701 | <span>Add environment</span> |
| 3711 | 3702 | </Button> |
apps/web/src/components/settings/KeybindingsSettings.tsx+2-2| ... | ... | @@ -891,12 +891,12 @@ function WhenClauseControl({ |
| 891 | 891 | <Button |
| 892 | 892 | variant={expression ? "ghost" : "ghost-muted"} |
| 893 | 893 | size="micro" |
| 894 | className="min-w-0 shrink font-mono" | |
| 894 | className="min-w-0 shrink" | |
| 895 | 895 | /> |
| 896 | 896 | } |
| 897 | 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 | 900 | <ChevronDownIcon className="size-3.5 shrink-0 opacity-60" /> |
| 901 | 901 | </PopoverTrigger> |
| 902 | 902 | <PopoverContent align="start" sideOffset={6}> |
apps/web/src/components/settings/ProjectActionsList.tsx+11-10| ... | ... | @@ -51,16 +51,17 @@ export function ProjectActionsList({ |
| 51 | 51 | {shortcutLabel ? ( |
| 52 | 52 | <span className="text-xs text-muted-foreground">{shortcutLabel}</span> |
| 53 | 53 | ) : null} |
| 54 | <Button | |
| 55 | size="icon-xs" | |
| 56 | variant="ghost-muted" | |
| 57 | className="shrink-0 opacity-0 group-focus-within:opacity-100 group-hover:opacity-100" | |
| 58 | aria-label={`Edit ${script.name}`} | |
| 59 | disabled={disabled} | |
| 60 | onClick={() => onEdit(script)} | |
| 61 | > | |
| 62 | <SettingsIcon className="size-3.5" /> | |
| 63 | </Button> | |
| 54 | <span className="flex shrink-0 opacity-0 group-focus-within:opacity-100 group-hover:opacity-100"> | |
| 55 | <Button | |
| 56 | size="icon-xs" | |
| 57 | variant="ghost-muted" | |
| 58 | aria-label={`Edit ${script.name}`} | |
| 59 | disabled={disabled} | |
| 60 | onClick={() => onEdit(script)} | |
| 61 | > | |
| 62 | <SettingsIcon className="size-3.5" /> | |
| 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 | 92 | /> |
| 93 | 93 | <PopoverPopup side="bottom" align="start" sideOffset={6} padding="none"> |
| 94 | 94 | <ProviderCustomColorPanel value={normalized} onCommit={props.onCommit} /> |
| 95 | <PopoverClose | |
| 96 | render={ | |
| 97 | <Button | |
| 98 | type="button" | |
| 99 | size="sm" | |
| 100 | variant="ghost" | |
| 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]" | |
| 102 | onClick={props.onClear} | |
| 103 | disabled={!props.value} | |
| 104 | > | |
| 105 | <XIcon className="size-3.5" aria-hidden /> | |
| 106 | Clear color | |
| 107 | </Button> | |
| 108 | } | |
| 109 | /> | |
| 95 | <div className="border-t border-border/60 p-1"> | |
| 96 | <PopoverClose | |
| 97 | render={ | |
| 98 | <Button | |
| 99 | type="button" | |
| 100 | size="compact" | |
| 101 | variant="ghost-muted" | |
| 102 | className="w-full justify-start" | |
| 103 | onClick={props.onClear} | |
| 104 | disabled={!props.value} | |
| 105 | > | |
| 106 | <XIcon aria-hidden /> | |
| 107 | Clear color | |
| 108 | </Button> | |
| 109 | } | |
| 110 | /> | |
| 111 | </div> | |
| 110 | 112 | </PopoverPopup> |
| 111 | 113 | </Popover> |
| 112 | 114 | ); |
apps/web/src/components/settings/SettingsSidebarNav.tsx+2-2| ... | ... | @@ -265,8 +265,8 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) { |
| 265 | 265 | <Button |
| 266 | 266 | type="button" |
| 267 | 267 | size="icon-micro" |
| 268 | variant="ghost" | |
| 269 | className="shrink-0 text-sidebar-muted-foreground hover:bg-sidebar-control-surface hover:text-sidebar-foreground" | |
| 268 | variant="ghost-muted" | |
| 269 | className="shrink-0" | |
| 270 | 270 | aria-label="Clear settings search" |
| 271 | 271 | onClick={() => { |
| 272 | 272 | clearSearch(); |
apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx+4-6| ... | ... | @@ -11,7 +11,6 @@ import { |
| 11 | 11 | type ProviderUpdateSidebarPillView, |
| 12 | 12 | } from "../ProviderUpdateLaunchNotification.logic"; |
| 13 | 13 | import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; |
| 14 | import { Button } from "../ui/button"; | |
| 15 | 14 | |
| 16 | 15 | const PROVIDER_UPDATE_PILL_STYLES = { |
| 17 | 16 | loading: |
| ... | ... | @@ -192,15 +191,14 @@ export function SidebarProviderUpdatePill() { |
| 192 | 191 | <Tooltip> |
| 193 | 192 | <TooltipTrigger |
| 194 | 193 | render={ |
| 195 | <Button | |
| 196 | size="icon-micro" | |
| 197 | variant="ghost" | |
| 194 | <button | |
| 195 | type="button" | |
| 198 | 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 | 198 | onClick={() => startExit(displayedView.key, null, displayedView.key)} |
| 201 | 199 | > |
| 202 | 200 | <XIcon className="size-3.5 shrink-0" /> |
| 203 | </Button> | |
| 201 | </button> | |
| 204 | 202 | } |
| 205 | 203 | /> |
| 206 | 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 | 108 | <Button |
| 109 | 109 | type="button" |
| 110 | 110 | size="icon-micro" |
| 111 | variant="ghost" | |
| 112 | className="shrink-0 text-sidebar-muted-foreground hover:bg-sidebar-control-surface hover:text-sidebar-foreground" | |
| 111 | variant="ghost-muted" | |
| 112 | className="shrink-0" | |
| 113 | 113 | aria-label="Clear thread search" |
| 114 | 114 | onClick={() => { |
| 115 | 115 | onClearSearch(); |
apps/web/src/components/ui/button.tsx+2-2| ... | ... | @@ -8,7 +8,7 @@ import type * as React from "react"; |
| 8 | 8 | import { cn } from "~/lib/utils"; |
| 9 | 9 | |
| 10 | 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 | 13 | defaultVariants: { |
| 14 | 14 | size: "default", |
| ... | ... | @@ -52,7 +52,7 @@ const buttonVariants = cva( |
| 52 | 52 | "ghost-destructive": |
| 53 | 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 | 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 | 56 | link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline", |
| 57 | 57 | "media-close": |
| 58 | 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 | 28 | size === "lg" && "h-9.5 leading-9.5 sm:h-8.5 sm:leading-8.5", |
| 29 | 29 | props.type === "search" && |
| 30 | 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 | 34 | props.type === "file" && |
| 32 | 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 | 1350 | background-color: transparent; |
| 1351 | 1351 | } |
| 1352 | 1352 | |
| 1353 | html[data-theme-id] .chat-markdown .chat-markdown-codeblock-header, | |
| 1354 | html[data-theme-id] .chat-markdown .chat-markdown-chrome-action { | |
| 1353 | html[data-theme-id] .chat-markdown .chat-markdown-codeblock-header { | |
| 1355 | 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 | 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 | 1379 | html[data-theme-id] [data-app-sidebar] { |
| 1386 | 1380 | --background: var(--app-theme-canvas); |
| 1387 | 1381 | --foreground: var(--app-theme-text); |
| ... | ... | @@ -1858,20 +1852,10 @@ code { |
| 1858 | 1852 | background: color-mix(in srgb, var(--contrast-border) 78%, transparent); |
| 1859 | 1853 | } |
| 1860 | 1854 | |
| 1861 | .chat-markdown .chat-markdown-codeblock-header, | |
| 1862 | .chat-markdown .chat-markdown-chrome-action { | |
| 1855 | .chat-markdown .chat-markdown-codeblock-header { | |
| 1863 | 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 | 1859 | .chat-markdown .chat-markdown-codeblock pre { |
| 1876 | 1860 | margin: 0; |
| 1877 | 1861 | border: none; |
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 = 250; | |
| 11 | export const RESTYLE_CEILING = 101; | |
| 12 | 12 | |
| 13 | 13 | const RULE = "shadcn(no-restyle)"; |
| 14 | 14 |