| author | |
| committer | |
| log | 21079391c72d1eeaa3c40f1cc5eb3e78abf0a846 |
| tree | 9357229f586b780c41e9de0ed7922b2d2533ac89 |
| parent | 866fc907592c9746b407484087d66c409e8034fa |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>24 files changed, 72 insertions(+), 90 deletions(-)
apps/web/src/browser/BrowserDeviceToolbar.tsx+9-10| ... | @@ -189,10 +189,7 @@ export function BrowserDeviceToolbar({ | ... | @@ -189,10 +189,7 @@ export function BrowserDeviceToolbar({ |
| 189 | <SelectTrigger | 189 | <SelectTrigger |
| 190 | variant="ghost" | 190 | variant="ghost" |
| 191 | size="xs" | 191 | size="xs" |
| 192 | className={cn( | 192 | className={cn("shrink-0 justify-between", width >= 440 ? "w-36" : "w-24")} |
| 193 | "shrink-0 justify-between px-1.5 font-medium", | ||
| 194 | width >= 440 ? "w-36" : "w-24", | ||
| 195 | )} | ||
| 196 | aria-label="Browser device preset" | 193 | aria-label="Browser device preset" |
| 197 | > | 194 | > |
| 198 | <SelectValue /> | 195 | <SelectValue /> |
| ... | @@ -227,7 +224,8 @@ export function BrowserDeviceToolbar({ | ... | @@ -227,7 +224,8 @@ export function BrowserDeviceToolbar({ |
| 227 | nativeInput | 224 | nativeInput |
| 228 | type="number" | 225 | type="number" |
| 229 | inputMode="numeric" | 226 | inputMode="numeric" |
| 230 | size="sm" | 227 | size="compact" |
| 228 | font="mono" | ||
| 231 | min={PREVIEW_VIEWPORT_MIN_DIMENSION} | 229 | min={PREVIEW_VIEWPORT_MIN_DIMENSION} |
| 232 | max={PREVIEW_VIEWPORT_MAX_DIMENSION} | 230 | max={PREVIEW_VIEWPORT_MAX_DIMENSION} |
| 233 | value={presentedSize.width} | 231 | value={presentedSize.width} |
| ... | @@ -245,8 +243,8 @@ export function BrowserDeviceToolbar({ | ... | @@ -245,8 +243,8 @@ export function BrowserDeviceToolbar({ |
| 245 | aria-label="Viewport width" | 243 | aria-label="Viewport width" |
| 246 | aria-invalid={!customValid} | 244 | aria-invalid={!customValid} |
| 247 | className={cn( | 245 | className={cn( |
| 248 | "h-6 rounded-md text-center tabular-nums [&_[data-slot=input]]:h-full [&_[data-slot=input]]:px-1 [&_[data-slot=input]]:text-xs [&_[data-slot=input]]:leading-none [&_[data-slot=input]::-webkit-inner-spin-button]:appearance-none [&_[data-slot=input]]:[appearance:textfield]", | 246 | "text-center [&_[data-slot=input]::-webkit-inner-spin-button]:appearance-none [&_[data-slot=input]]:[appearance:textfield]", |
| 249 | width >= 360 ? "w-14" : "w-11", | 247 | width >= 360 ? "w-14" : "w-13", |
| 250 | )} | 248 | )} |
| 251 | /> | 249 | /> |
| 252 | <span className="text-xs text-muted-foreground">×</span> | 250 | <span className="text-xs text-muted-foreground">×</span> |
| ... | @@ -254,7 +252,8 @@ export function BrowserDeviceToolbar({ | ... | @@ -254,7 +252,8 @@ export function BrowserDeviceToolbar({ |
| 254 | nativeInput | 252 | nativeInput |
| 255 | type="number" | 253 | type="number" |
| 256 | inputMode="numeric" | 254 | inputMode="numeric" |
| 257 | size="sm" | 255 | size="compact" |
| 256 | font="mono" | ||
| 258 | min={PREVIEW_VIEWPORT_MIN_DIMENSION} | 257 | min={PREVIEW_VIEWPORT_MIN_DIMENSION} |
| 259 | max={PREVIEW_VIEWPORT_MAX_DIMENSION} | 258 | max={PREVIEW_VIEWPORT_MAX_DIMENSION} |
| 260 | value={presentedSize.height} | 259 | value={presentedSize.height} |
| ... | @@ -272,8 +271,8 @@ export function BrowserDeviceToolbar({ | ... | @@ -272,8 +271,8 @@ export function BrowserDeviceToolbar({ |
| 272 | aria-label="Viewport height" | 271 | aria-label="Viewport height" |
| 273 | aria-invalid={!customValid} | 272 | aria-invalid={!customValid} |
| 274 | className={cn( | 273 | className={cn( |
| 275 | "h-6 rounded-md text-center tabular-nums [&_[data-slot=input]]:h-full [&_[data-slot=input]]:px-1 [&_[data-slot=input]]:text-xs [&_[data-slot=input]]:leading-none [&_[data-slot=input]::-webkit-inner-spin-button]:appearance-none [&_[data-slot=input]]:[appearance:textfield]", | 274 | "text-center [&_[data-slot=input]::-webkit-inner-spin-button]:appearance-none [&_[data-slot=input]]:[appearance:textfield]", |
| 276 | width >= 360 ? "w-14" : "w-11", | 275 | width >= 360 ? "w-14" : "w-13", |
| 277 | )} | 276 | )} |
| 278 | /> | 277 | /> |
| 279 | </form> | 278 | </form> |
apps/web/src/components/BranchToolbarBranchSelector.tsx+2-5| ... | @@ -704,7 +704,6 @@ export function BranchToolbarBranchSelector({ | ... | @@ -704,7 +704,6 @@ export function BranchToolbarBranchSelector({ |
| 704 | key={itemValue} | 704 | key={itemValue} |
| 705 | index={index} | 705 | index={index} |
| 706 | value={itemValue} | 706 | value={itemValue} |
| 707 | className="pe-2" | ||
| 708 | onClick={() => selectPickerItem(itemValue)} | 707 | onClick={() => selectPickerItem(itemValue)} |
| 709 | > | 708 | > |
| 710 | <div className="flex min-w-0 items-center gap-2 py-1"> | 709 | <div className="flex min-w-0 items-center gap-2 py-1"> |
| ... | @@ -726,7 +725,6 @@ export function BranchToolbarBranchSelector({ | ... | @@ -726,7 +725,6 @@ export function BranchToolbarBranchSelector({ |
| 726 | key={itemValue} | 725 | key={itemValue} |
| 727 | index={index} | 726 | index={index} |
| 728 | value={itemValue} | 727 | value={itemValue} |
| 729 | className="pe-1.5" | ||
| 730 | onClick={() => selectPickerItem(itemValue)} | 728 | onClick={() => selectPickerItem(itemValue)} |
| 731 | > | 729 | > |
| 732 | <span className="truncate">Create new ref &quot;{newRefName}&quot;</span> | 730 | <span className="truncate">Create new ref &quot;{newRefName}&quot;</span> |
| ... | @@ -754,7 +752,6 @@ export function BranchToolbarBranchSelector({ | ... | @@ -754,7 +752,6 @@ export function BranchToolbarBranchSelector({ |
| 754 | key={itemValue} | 752 | key={itemValue} |
| 755 | index={index} | 753 | index={index} |
| 756 | value={itemValue} | 754 | value={itemValue} |
| 757 | className="pe-1.5" | ||
| 758 | onClick={() => selectPickerItem(itemValue)} | 755 | onClick={() => selectPickerItem(itemValue)} |
| 759 | onContextMenu={(event) => handleBranchContextMenu(event, itemValue)} | 756 | onContextMenu={(event) => handleBranchContextMenu(event, itemValue)} |
| 760 | > | 757 | > |
| ... | @@ -809,10 +806,10 @@ export function BranchToolbarBranchSelector({ | ... | @@ -809,10 +806,10 @@ export function BranchToolbarBranchSelector({ |
| 809 | onContextMenu={(event) => handleBranchContextMenu(event, resolvedActiveBranch)} | 806 | onContextMenu={(event) => handleBranchContextMenu(event, resolvedActiveBranch)} |
| 810 | > | 807 | > |
| 811 | <ComboboxTrigger | 808 | <ComboboxTrigger |
| 812 | render={<Button variant="ghost" size="xs" />} | 809 | render={<ComposerControl size="xs" />} |
| 813 | // No press-scale: the popup aligns live to this trigger, so a | 810 | // No press-scale: the popup aligns live to this trigger, so a |
| 814 | // momentary 0.97 shrink would drag the open popup ~3px sideways. | 811 | // momentary 0.97 shrink would drag the open popup ~3px sideways. |
| 815 | className="min-w-0 max-w-full font-normal text-muted-foreground/70 text-xs! hover:text-foreground/80 active:scale-100" | 812 | className="min-w-0 max-w-full active:scale-100" |
| 816 | disabled={isInitialBranchesLoadPending || isBranchActionPending} | 813 | disabled={isInitialBranchesLoadPending || isBranchActionPending} |
| 817 | > | 814 | > |
| 818 | <GitBranchIcon className="size-3 shrink-0 opacity-70" /> | 815 | <GitBranchIcon className="size-3 shrink-0 opacity-70" /> |
apps/web/src/components/BranchToolbarEnvModeSelector.tsx+1-1| ... | @@ -110,7 +110,7 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe | ... | @@ -110,7 +110,7 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe |
| 110 | <SelectTrigger | 110 | <SelectTrigger |
| 111 | variant="ghost" | 111 | variant="ghost" |
| 112 | size="xs" | 112 | size="xs" |
| 113 | className="min-w-0 shrink font-normal text-xs!" | 113 | className="min-w-0 shrink" |
| 114 | aria-label="Workspace" | 114 | aria-label="Workspace" |
| 115 | data-composer-shortcut="composer.workspace" | 115 | data-composer-shortcut="composer.workspace" |
| 116 | data-composer-context-control | 116 | data-composer-context-control |
apps/web/src/components/BranchToolbarEnvironmentSelector.tsx+1-1| ... | @@ -102,7 +102,7 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir | ... | @@ -102,7 +102,7 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir |
| 102 | <SelectTrigger | 102 | <SelectTrigger |
| 103 | variant="ghost" | 103 | variant="ghost" |
| 104 | size="xs" | 104 | size="xs" |
| 105 | className="min-w-0 max-w-full font-normal text-xs!" | 105 | className="min-w-0 max-w-full" |
| 106 | aria-label="Run on" | 106 | aria-label="Run on" |
| 107 | data-composer-shortcut="composer.host" | 107 | data-composer-shortcut="composer.host" |
| 108 | data-composer-context-control | 108 | data-composer-context-control |
apps/web/src/components/CommandPalette.tsx+1-1| ... | @@ -650,7 +650,7 @@ function CommandPaletteDialog(props: { | ... | @@ -650,7 +650,7 @@ function CommandPaletteDialog(props: { |
| 650 | ? "Search project contents" | 650 | ? "Search project contents" |
| 651 | : "Command palette" | 651 | : "Command palette" |
| 652 | } | 652 | } |
| 653 | className={cn("overflow-hidden p-0", props.mode === "content" && "h-105")} | 653 | className={cn("overflow-hidden", props.mode === "content" && "h-105")} |
| 654 | data-command-palette="true" | 654 | data-command-palette="true" |
| 655 | data-palette-mode={props.mode} | 655 | data-palette-mode={props.mode} |
| 656 | data-testid="command-palette" | 656 | data-testid="command-palette" |
apps/web/src/components/CommandPaletteContent.tsx+1-1| ... | @@ -50,7 +50,7 @@ export function CommandPaletteContent({ | ... | @@ -50,7 +50,7 @@ export function CommandPaletteContent({ |
| 50 | {inputAccessory} | 50 | {inputAccessory} |
| 51 | </div> | 51 | </div> |
| 52 | <CommandPanel className={panelClassName}>{children}</CommandPanel> | 52 | <CommandPanel className={panelClassName}>{children}</CommandPanel> |
| 53 | <CommandFooter className="gap-3 max-sm:flex-col max-sm:items-start"> | 53 | <CommandFooter className="max-sm:flex-col max-sm:items-start"> |
| 54 | <div className="flex items-center gap-3"> | 54 | <div className="flex items-center gap-3"> |
| 55 | <KbdGroup> | 55 | <KbdGroup> |
| 56 | <Kbd> | 56 | <Kbd> |
apps/web/src/components/CommandPaletteResults.tsx+1-2| ... | @@ -41,7 +41,7 @@ export function CommandPaletteResults(props: CommandPaletteResultsProps) { | ... | @@ -41,7 +41,7 @@ export function CommandPaletteResults(props: CommandPaletteResultsProps) { |
| 41 | <CommandList> | 41 | <CommandList> |
| 42 | {props.groups.map((group) => ( | 42 | {props.groups.map((group) => ( |
| 43 | <CommandGroup items={group.items} key={group.value}> | 43 | <CommandGroup items={group.items} key={group.value}> |
| 44 | <CommandGroupLabel className="ps-[9px]">{group.label}</CommandGroupLabel> | 44 | <CommandGroupLabel>{group.label}</CommandGroupLabel> |
| 45 | <CommandCollection> | 45 | <CommandCollection> |
| 46 | {(item) => | 46 | {(item) => |
| 47 | item.disabled ? ( | 47 | item.disabled ? ( |
| ... | @@ -109,7 +109,6 @@ function CommandPaletteResultRow(props: { | ... | @@ -109,7 +109,6 @@ function CommandPaletteResultRow(props: { |
| 109 | <CommandItem | 109 | <CommandItem |
| 110 | value={props.item.value} | 110 | value={props.item.value} |
| 111 | active={props.isActive} | 111 | active={props.isActive} |
| 112 | className="gap-2" | ||
| 113 | onMouseDown={(event) => { | 112 | onMouseDown={(event) => { |
| 114 | event.preventDefault(); | 113 | event.preventDefault(); |
| 115 | }} | 114 | }} |
apps/web/src/components/CustomSnoozeDialog.tsx-1| ... | @@ -169,7 +169,6 @@ function CustomSnoozeDialog() { | ... | @@ -169,7 +169,6 @@ function CustomSnoozeDialog() { |
| 169 | ) : ( | 169 | ) : ( |
| 170 | <div className="grid grid-cols-1 gap-3 sm:grid-cols-2"> | 170 | <div className="grid grid-cols-1 gap-3 sm:grid-cols-2"> |
| 171 | <NumberField | 171 | <NumberField |
| 172 | className="gap-1.5" | ||
| 173 | id={`${id}-amount`} | 172 | id={`${id}-amount`} |
| 174 | min={0} | 173 | min={0} |
| 175 | step="any" | 174 | step="any" |
apps/web/src/components/DiffPanel.tsx+2-1| ... | @@ -749,7 +749,8 @@ export default function DiffPanel({ | ... | @@ -749,7 +749,8 @@ export default function DiffPanel({ |
| 749 | }} | 749 | }} |
| 750 | > | 750 | > |
| 751 | <ComboboxTrigger | 751 | <ComboboxTrigger |
| 752 | className="inline-flex min-w-0 max-w-48 items-center gap-1 overflow-hidden rounded-md px-1.5 py-1 outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring" | 752 | render={<Button variant="ghost-muted" size="xs" />} |
| 753 | className="min-w-0 max-w-48" | ||
| 753 | aria-label={`Change comparison target. Currently ${selectedGitSource.baseRef}`} | 754 | aria-label={`Change comparison target. Currently ${selectedGitSource.baseRef}`} |
| 754 | > | 755 | > |
| 755 | <span className="min-w-0 truncate">{selectedGitSource.baseRef}</span> | 756 | <span className="min-w-0 truncate">{selectedGitSource.baseRef}</span> |
apps/web/src/components/LegacySidebar.tsx+4-5| ... | @@ -2784,7 +2784,7 @@ function ProjectSortMenu({ | ... | @@ -2784,7 +2784,7 @@ function ProjectSortMenu({ |
| 2784 | <div className="px-2 py-1"> | 2784 | <div className="px-2 py-1"> |
| 2785 | <NumberField | 2785 | <NumberField |
| 2786 | aria-label="Visible thread count" | 2786 | aria-label="Visible thread count" |
| 2787 | className="w-28 gap-0" | 2787 | className="w-28" |
| 2788 | max={MAX_SIDEBAR_THREAD_PREVIEW_COUNT} | 2788 | max={MAX_SIDEBAR_THREAD_PREVIEW_COUNT} |
| 2789 | min={MIN_SIDEBAR_THREAD_PREVIEW_COUNT} | 2789 | min={MIN_SIDEBAR_THREAD_PREVIEW_COUNT} |
| 2790 | onValueChange={handleThreadPreviewCountChange} | 2790 | onValueChange={handleThreadPreviewCountChange} |
| ... | @@ -2792,14 +2792,13 @@ function ProjectSortMenu({ | ... | @@ -2792,14 +2792,13 @@ function ProjectSortMenu({ |
| 2792 | step={1} | 2792 | step={1} |
| 2793 | value={threadPreviewCount} | 2793 | value={threadPreviewCount} |
| 2794 | > | 2794 | > |
| 2795 | <NumberFieldGroup className="h-7 rounded-md sm:h-6.5"> | 2795 | <NumberFieldGroup> |
| 2796 | <NumberFieldDecrement | 2796 | <NumberFieldDecrement |
| 2797 | aria-label="Decrease visible thread count" | 2797 | aria-label="Decrease visible thread count" |
| 2798 | className="px-2 sm:px-2 [&_svg]:size-3.5" | 2798 | className="[&_svg]:size-3.5" |
| 2799 | /> | 2799 | /> |
| 2800 | <NumberFieldInput | 2800 | <NumberFieldInput |
| 2801 | aria-label="Visible thread count" | 2801 | aria-label="Visible thread count" |
| 2802 | className="h-7 w-9 grow-0 px-0 text-xs leading-7 sm:h-6.5 sm:leading-6.5" | ||
| 2803 | inputMode="numeric" | 2802 | inputMode="numeric" |
| 2804 | onKeyDownCapture={(event) => { | 2803 | onKeyDownCapture={(event) => { |
| 2805 | event.stopPropagation(); | 2804 | event.stopPropagation(); |
| ... | @@ -2807,7 +2806,7 @@ function ProjectSortMenu({ | ... | @@ -2807,7 +2806,7 @@ function ProjectSortMenu({ |
| 2807 | /> | 2806 | /> |
| 2808 | <NumberFieldIncrement | 2807 | <NumberFieldIncrement |
| 2809 | aria-label="Increase visible thread count" | 2808 | aria-label="Increase visible thread count" |
| 2810 | className="px-2 sm:px-2 [&_svg]:size-3.5" | 2809 | className="[&_svg]:size-3.5" |
| 2811 | /> | 2810 | /> |
| 2812 | </NumberFieldGroup> | 2811 | </NumberFieldGroup> |
| 2813 | </NumberField> | 2812 | </NumberField> |
apps/web/src/components/Sidebar.tsx-1| ... | @@ -4483,7 +4483,6 @@ export default function Sidebar() { | ... | @@ -4483,7 +4483,6 @@ export default function Sidebar() { |
| 4483 | key={item.value} | 4483 | key={item.value} |
| 4484 | hideIndicator | 4484 | hideIndicator |
| 4485 | value={item} | 4485 | value={item} |
| 4486 | className="font-medium" | ||
| 4487 | onContextMenu={(event) => { | 4486 | onContextMenu={(event) => { |
| 4488 | if (project) handleProjectSettings(event, project); | 4487 | if (project) handleProjectSettings(event, project); |
| 4489 | }} | 4488 | }} |
apps/web/src/components/chat/ComposerCommandMenu.tsx-1| ... | @@ -162,7 +162,6 @@ const ComposerCommandMenuItem = memo(function ComposerCommandMenuItem(props: { | ... | @@ -162,7 +162,6 @@ const ComposerCommandMenuItem = memo(function ComposerCommandMenuItem(props: { |
| 162 | value={props.item.id} | 162 | value={props.item.id} |
| 163 | data-composer-item-id={props.item.id} | 163 | data-composer-item-id={props.item.id} |
| 164 | active={props.isActive} | 164 | active={props.isActive} |
| 165 | className="gap-3 rounded-lg px-3 py-2!" | ||
| 166 | onMouseMove={() => { | 165 | onMouseMove={() => { |
| 167 | if (!props.isActive) props.onHighlight(props.item.id); | 166 | if (!props.isActive) props.onHighlight(props.item.id); |
| 168 | }} | 167 | }} |
apps/web/src/components/preview/PreviewChromeRow.tsx+20-25| ... | @@ -181,11 +181,6 @@ export function PreviewChromeRow({ | ... | @@ -181,11 +181,6 @@ export function PreviewChromeRow({ |
| 181 | <InputGroupInput | 181 | <InputGroupInput |
| 182 | ref={inputRef} | 182 | ref={inputRef} |
| 183 | value={inputFocused ? draft : url} | 183 | value={inputFocused ? draft : url} |
| 184 | className={cn( | ||
| 185 | onOpenInBrowser && | ||
| 186 | !inputFocused && | ||
| 187 | "group-hover/address:pe-7 transition-[padding]", | ||
| 188 | )} | ||
| 189 | onChange={(event) => setDraft(event.target.value)} | 184 | onChange={(event) => setDraft(event.target.value)} |
| 190 | onFocus={() => { | 185 | onFocus={() => { |
| 191 | setDraft(url); | 186 | setDraft(url); |
| ... | @@ -213,26 +208,26 @@ export function PreviewChromeRow({ | ... | @@ -213,26 +208,26 @@ export function PreviewChromeRow({ |
| 213 | /> | 208 | /> |
| 214 | </Tooltip> | 209 | </Tooltip> |
| 215 | {onOpenInBrowser && !inputFocused ? ( | 210 | {onOpenInBrowser && !inputFocused ? ( |
| 216 | <InputGroupAddon | 211 | <InputGroupAddon align="inline-end"> |
| 217 | align="inline-end" | 212 | {/* Revealed on hover so a resting address bar reads as plain text. */} |
| 218 | className="pointer-events-none absolute inset-y-0 right-0 opacity-0 transition-opacity group-hover/address:pointer-events-auto group-hover/address:opacity-100" | 213 | <span className="pointer-events-none flex opacity-0 transition-opacity focus-within:pointer-events-auto focus-within:opacity-100 group-hover/address:pointer-events-auto group-hover/address:opacity-100"> |
| 219 | > | 214 | <Tooltip> |
| 220 | <Tooltip> | 215 | <TooltipTrigger |
| 221 | <TooltipTrigger | 216 | render={ |
| 222 | render={ | 217 | <Button |
| 223 | <Button | 218 | variant="ghost" |
| 224 | variant="ghost" | 219 | size="icon-xs" |
| 225 | size="icon-xs" | 220 | onClick={onOpenInBrowser} |
| 226 | onClick={onOpenInBrowser} | 221 | aria-label="Open in system browser" |
| 227 | aria-label="Open in system browser" | 222 | type="button" |
| 228 | type="button" | 223 | /> |
| 229 | /> | 224 | } |
| 230 | } | 225 | > |
| 231 | > | 226 | <ExternalLink /> |
| 232 | <ExternalLink /> | 227 | </TooltipTrigger> |
| 233 | </TooltipTrigger> | 228 | <TooltipPopup>Open in system browser</TooltipPopup> |
| 234 | <TooltipPopup>Open in system browser</TooltipPopup> | 229 | </Tooltip> |
| 235 | </Tooltip> | 230 | </span> |
| 236 | </InputGroupAddon> | 231 | </InputGroupAddon> |
| 237 | ) : null} | 232 | ) : null} |
| 238 | </InputGroup> | 233 | </InputGroup> |
apps/web/src/components/search/ProjectContentSearchDialog.tsx+4-2| ... | @@ -89,11 +89,13 @@ function EmptyContentSearchDialog() { | ... | @@ -89,11 +89,13 @@ function EmptyContentSearchDialog() { |
| 89 | footerActionLabel="Open file" | 89 | footerActionLabel="Open file" |
| 90 | inputProps={{ disabled: true, placeholder: "Search project contents…" }} | 90 | inputProps={{ disabled: true, placeholder: "Search project contents…" }} |
| 91 | mode="none" | 91 | mode="none" |
| 92 | panelClassName="flex min-h-0 flex-1 items-center justify-center px-6 text-center text-sm text-muted-foreground" | 92 | panelClassName="flex min-h-0 flex-1 items-center justify-center" |
| 93 | testId="project-content-search" | 93 | testId="project-content-search" |
| 94 | value="" | 94 | value="" |
| 95 | > | 95 | > |
| 96 | Open a project to search its files. | 96 | <p className="px-6 text-center text-muted-foreground text-sm"> |
| 97 | Open a project to search its files. | ||
| 98 | </p> | ||
| 97 | </CommandPaletteContent> | 99 | </CommandPaletteContent> |
| 98 | ); | 100 | ); |
| 99 | } | 101 | } |
apps/web/src/components/settings/AddProviderInstanceDialog.tsx-2| ... | @@ -306,7 +306,6 @@ export function AddProviderInstanceDialog({ | ... | @@ -306,7 +306,6 @@ export function AddProviderInstanceDialog({ |
| 306 | <label className={cn("grid gap-2", wizardStep !== 1 && "hidden")}> | 306 | <label className={cn("grid gap-2", wizardStep !== 1 && "hidden")}> |
| 307 | <span className="text-xs font-medium text-foreground">Label</span> | 307 | <span className="text-xs font-medium text-foreground">Label</span> |
| 308 | <Input | 308 | <Input |
| 309 | className="bg-background" | ||
| 310 | placeholder="e.g. Work" | 309 | placeholder="e.g. Work" |
| 311 | value={label} | 310 | value={label} |
| 312 | onChange={(event) => setLabel(event.target.value)} | 311 | onChange={(event) => setLabel(event.target.value)} |
| ... | @@ -319,7 +318,6 @@ export function AddProviderInstanceDialog({ | ... | @@ -319,7 +318,6 @@ export function AddProviderInstanceDialog({ |
| 319 | <label className={cn("grid gap-2", wizardStep !== 1 && "hidden")}> | 318 | <label className={cn("grid gap-2", wizardStep !== 1 && "hidden")}> |
| 320 | <span className="text-xs font-medium text-foreground">Instance ID</span> | 319 | <span className="text-xs font-medium text-foreground">Instance ID</span> |
| 321 | <Input | 320 | <Input |
| 322 | className="bg-background" | ||
| 323 | placeholder={`${driver}_work`} | 321 | placeholder={`${driver}_work`} |
| 324 | value={instanceId} | 322 | value={instanceId} |
| 325 | onChange={(event) => { | 323 | onChange={(event) => { |
apps/web/src/components/settings/ConnectionsSettings.tsx+2-3| ... | @@ -833,7 +833,6 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ | ... | @@ -833,7 +833,6 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ |
| 833 | readOnly | 833 | readOnly |
| 834 | value={revealValue} | 834 | value={revealValue} |
| 835 | rows={isRevealValueUrl ? 4 : 3} | 835 | rows={isRevealValueUrl ? 4 : 3} |
| 836 | className="text-xs leading-relaxed" | ||
| 837 | onFocus={(event) => event.currentTarget.select()} | 836 | onFocus={(event) => event.currentTarget.select()} |
| 838 | onClick={(event) => event.currentTarget.select()} | 837 | onClick={(event) => event.currentTarget.select()} |
| 839 | /> | 838 | /> |
| ... | @@ -2734,7 +2733,7 @@ export function ConnectionsSettings() { | ... | @@ -2734,7 +2733,7 @@ export function ConnectionsSettings() { |
| 2734 | <AutocompleteItem | 2733 | <AutocompleteItem |
| 2735 | key={`${target.alias}:${target.hostname}:${target.port ?? ""}`} | 2734 | key={`${target.alias}:${target.hostname}:${target.port ?? ""}`} |
| 2736 | value={target} | 2735 | value={target} |
| 2737 | className="h-8 min-h-8 gap-2 whitespace-nowrap" | 2736 | className="h-8 min-h-8 whitespace-nowrap" |
| 2738 | > | 2737 | > |
| 2739 | <span className="min-w-0 truncate text-sm font-medium"> | 2738 | <span className="min-w-0 truncate text-sm font-medium"> |
| 2740 | {target.alias} | 2739 | {target.alias} |
| ... | @@ -2754,7 +2753,7 @@ export function ConnectionsSettings() { | ... | @@ -2754,7 +2753,7 @@ export function ConnectionsSettings() { |
| 2754 | })} | 2753 | })} |
| 2755 | </AutocompleteList> | 2754 | </AutocompleteList> |
| 2756 | ) : ( | 2755 | ) : ( |
| 2757 | <AutocompleteEmpty className="break-all px-3 py-2 text-xs"> | 2756 | <AutocompleteEmpty className="break-all"> |
| 2758 | No hosts match "{savedBackendSshHost.trim()}". | 2757 | No hosts match "{savedBackendSshHost.trim()}". |
| 2759 | </AutocompleteEmpty> | 2758 | </AutocompleteEmpty> |
| 2760 | )} | 2759 | )} |
apps/web/src/components/settings/KeybindingsSettings.tsx+17-18| ... | @@ -42,6 +42,7 @@ import { useSettingsScope } from "./SettingsScopeContext"; | ... | @@ -42,6 +42,7 @@ import { useSettingsScope } from "./SettingsScopeContext"; |
| 42 | import { Badge } from "../ui/badge"; | 42 | import { Badge } from "../ui/badge"; |
| 43 | import { Button } from "../ui/button"; | 43 | import { Button } from "../ui/button"; |
| 44 | import { Input } from "../ui/input"; | 44 | import { Input } from "../ui/input"; |
| 45 | import { InputGroup, InputGroupAddon, InputGroupInput } from "../ui/input-group"; | ||
| 45 | import { Kbd, KbdGroup } from "../ui/kbd"; | 46 | import { Kbd, KbdGroup } from "../ui/kbd"; |
| 46 | import { Menu, MenuItem, MenuPopup, MenuTrigger } from "../ui/menu"; | 47 | import { Menu, MenuItem, MenuPopup, MenuTrigger } from "../ui/menu"; |
| 47 | import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; | 48 | import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; |
| ... | @@ -143,9 +144,11 @@ function ExpandableHeaderSearch({ | ... | @@ -143,9 +144,11 @@ function ExpandableHeaderSearch({ |
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | return ( | 146 | return ( |
| 146 | <div className="relative"> | 147 | <InputGroup className="w-44"> |
| 147 | <SearchIcon className="pointer-events-none absolute top-1/2 left-2 size-3 -translate-y-1/2 text-muted-foreground" /> | 148 | <InputGroupAddon> |
| 148 | <Input | 149 | <SearchIcon aria-hidden className="size-3" /> |
| 150 | </InputGroupAddon> | ||
| 151 | <InputGroupInput | ||
| 149 | ref={inputRef} | 152 | ref={inputRef} |
| 150 | autoFocus | 153 | autoFocus |
| 151 | type="search" | 154 | type="search" |
| ... | @@ -163,10 +166,9 @@ function ExpandableHeaderSearch({ | ... | @@ -163,10 +166,9 @@ function ExpandableHeaderSearch({ |
| 163 | }} | 166 | }} |
| 164 | placeholder="Search keybindings" | 167 | placeholder="Search keybindings" |
| 165 | aria-label="Search keybindings" | 168 | aria-label="Search keybindings" |
| 166 | className="w-44 [&_[data-slot=input]]:pl-7" | ||
| 167 | size="sm" | 169 | size="sm" |
| 168 | /> | 170 | /> |
| 169 | </div> | 171 | </InputGroup> |
| 170 | ); | 172 | ); |
| 171 | } | 173 | } |
| 172 | 174 | ||
| ... | @@ -319,7 +321,7 @@ function WhenVariableSelect({ | ... | @@ -319,7 +321,7 @@ function WhenVariableSelect({ |
| 319 | return ( | 321 | return ( |
| 320 | <Select value={value} onValueChange={(nextValue) => nextValue && onChange(nextValue)}> | 322 | <Select value={value} onValueChange={(nextValue) => nextValue && onChange(nextValue)}> |
| 321 | <SelectTrigger size="compact" className="min-w-0 flex-1"> | 323 | <SelectTrigger size="compact" className="min-w-0 flex-1"> |
| 322 | <SelectValue placeholder="Condition" className="leading-7" /> | 324 | <SelectValue placeholder="Condition" /> |
| 323 | {unknownIdentifiers && unknownIdentifiers.length > 0 ? ( | 325 | {unknownIdentifiers && unknownIdentifiers.length > 0 ? ( |
| 324 | <UnknownWhenVariableWarning identifiers={unknownIdentifiers} focusable={false} /> | 326 | <UnknownWhenVariableWarning identifiers={unknownIdentifiers} focusable={false} /> |
| 325 | ) : null} | 327 | ) : null} |
| ... | @@ -649,25 +651,22 @@ function WhenExpressionBuilder({ | ... | @@ -649,25 +651,22 @@ function WhenExpressionBuilder({ |
| 649 | </div> | 651 | </div> |
| 650 | 652 | ||
| 651 | <div className="space-y-1.5"> | 653 | <div className="space-y-1.5"> |
| 652 | <div className="relative"> | 654 | <InputGroup> |
| 653 | <Input | 655 | <InputGroupInput |
| 654 | value={expressionDraft} | 656 | value={expressionDraft} |
| 655 | onChange={(event) => updateExpressionDraft(event.currentTarget.value)} | 657 | onChange={(event) => updateExpressionDraft(event.currentTarget.value)} |
| 656 | placeholder="Always" | 658 | placeholder="Always" |
| 657 | aria-invalid={Boolean(parseError)} | 659 | aria-invalid={Boolean(parseError)} |
| 658 | aria-label="When expression" | 660 | aria-label="When expression" |
| 659 | className={cn( | 661 | size="compact" |
| 660 | "h-7 rounded-md font-mono text-[12px] leading-7 sm:h-7 sm:leading-7", | 662 | font="mono" |
| 661 | unknownIdentifiers.length > 0 && "pr-9", | ||
| 662 | parseError && "border-destructive/70 focus-visible:border-destructive", | ||
| 663 | )} | ||
| 664 | /> | 663 | /> |
| 665 | {unknownIdentifiers.length > 0 ? ( | 664 | {unknownIdentifiers.length > 0 ? ( |
| 666 | <span className="absolute inset-y-0 right-2 flex items-center"> | 665 | <InputGroupAddon align="inline-end"> |
| 667 | <UnknownWhenVariableWarning identifiers={unknownIdentifiers} /> | 666 | <UnknownWhenVariableWarning identifiers={unknownIdentifiers} /> |
| 668 | </span> | 667 | </InputGroupAddon> |
| 669 | ) : null} | 668 | ) : null} |
| 670 | </div> | 669 | </InputGroup> |
| 671 | {parseError ? ( | 670 | {parseError ? ( |
| 672 | <div className="flex items-center gap-1.5 text-[11px] text-destructive"> | 671 | <div className="flex items-center gap-1.5 text-[11px] text-destructive"> |
| 673 | <CircleXIcon className="size-3.5" /> | 672 | <CircleXIcon className="size-3.5" /> |
| ... | @@ -858,7 +857,7 @@ function KeybindingKeyControl({ | ... | @@ -858,7 +857,7 @@ function KeybindingKeyControl({ |
| 858 | placeholder={isRecording ? "Press shortcut" : "Unassigned"} | 857 | placeholder={isRecording ? "Press shortcut" : "Unassigned"} |
| 859 | size="sm" | 858 | size="sm" |
| 860 | font="mono" | 859 | font="mono" |
| 861 | className={cn("w-44", isRecording && "border-primary/70 bg-primary/5")} | 860 | className="w-44" |
| 862 | onFocus={() => setDraft({ isRecording: true })} | 861 | onFocus={() => setDraft({ isRecording: true })} |
| 863 | onBlur={() => setDraft({ isRecording: false })} | 862 | onBlur={() => setDraft({ isRecording: false })} |
| 864 | onChange={(event) => setDraft({ keyDraft: event.currentTarget.value })} | 863 | onChange={(event) => setDraft({ keyDraft: event.currentTarget.value })} |
| ... | @@ -1168,7 +1167,7 @@ function NewKeybindingKeyInput({ | ... | @@ -1168,7 +1167,7 @@ function NewKeybindingKeyInput({ |
| 1168 | placeholder={draft.isRecording ? "Press shortcut" : "Unassigned"} | 1167 | placeholder={draft.isRecording ? "Press shortcut" : "Unassigned"} |
| 1169 | size="sm" | 1168 | size="sm" |
| 1170 | font="mono" | 1169 | font="mono" |
| 1171 | className={cn(draft.isRecording && "border-primary/70 bg-primary/5", className)} | 1170 | className={className} |
| 1172 | onFocus={() => draft.setDraft({ isRecording: true })} | 1171 | onFocus={() => draft.setDraft({ isRecording: true })} |
| 1173 | onBlur={() => draft.setDraft({ isRecording: false })} | 1172 | onBlur={() => draft.setDraft({ isRecording: false })} |
| 1174 | onChange={(event) => draft.setDraft({ keyDraft: event.currentTarget.value })} | 1173 | onChange={(event) => draft.setDraft({ keyDraft: event.currentTarget.value })} |
apps/web/src/components/settings/ProjectFaviconPickerDialog.tsx+1-1| ... | @@ -71,7 +71,7 @@ export function ProjectFaviconPickerDialog(props: { | ... | @@ -71,7 +71,7 @@ export function ProjectFaviconPickerDialog(props: { |
| 71 | {props.open ? ( | 71 | {props.open ? ( |
| 72 | <CommandDialogPopup | 72 | <CommandDialogPopup |
| 73 | aria-label="Choose project icon" | 73 | aria-label="Choose project icon" |
| 74 | className="overflow-hidden p-0" | 74 | className="overflow-hidden" |
| 75 | onBackdropPointerDown={() => props.onOpenChange(false)} | 75 | onBackdropPointerDown={() => props.onOpenChange(false)} |
| 76 | > | 76 | > |
| 77 | <CommandPaletteContent | 77 | <CommandPaletteContent |
apps/web/src/components/settings/ProviderAccentColorPicker.tsx+1-2| ... | @@ -46,7 +46,7 @@ function ProviderCustomColorPanel(props: { | ... | @@ -46,7 +46,7 @@ function ProviderCustomColorPanel(props: { |
| 46 | /> | 46 | /> |
| 47 | <Input | 47 | <Input |
| 48 | nativeInput | 48 | nativeInput |
| 49 | size="sm" | 49 | size="compact" |
| 50 | value={hexDraft ?? currentColor} | 50 | value={hexDraft ?? currentColor} |
| 51 | onChange={(event) => { | 51 | onChange={(event) => { |
| 52 | const nextColor = event.currentTarget.value; | 52 | const nextColor = event.currentTarget.value; |
| ... | @@ -57,7 +57,6 @@ function ProviderCustomColorPanel(props: { | ... | @@ -57,7 +57,6 @@ function ProviderCustomColorPanel(props: { |
| 57 | }} | 57 | }} |
| 58 | onBlur={() => setHexDraft(null)} | 58 | onBlur={() => setHexDraft(null)} |
| 59 | font="mono" | 59 | font="mono" |
| 60 | className="text-xs" | ||
| 61 | aria-label="Custom hex accent color" | 60 | aria-label="Custom hex accent color" |
| 62 | spellCheck={false} | 61 | spellCheck={false} |
| 63 | /> | 62 | /> |
apps/web/src/components/settings/ProviderSettingsForm.tsx-1| ... | @@ -388,7 +388,6 @@ function ProviderSettingsFieldRow({ | ... | @@ -388,7 +388,6 @@ function ProviderSettingsFieldRow({ |
| 388 | ) : ( | 388 | ) : ( |
| 389 | <Input | 389 | <Input |
| 390 | id={inputId} | 390 | id={inputId} |
| 391 | className="bg-background" | ||
| 392 | type={type} | 391 | type={type} |
| 393 | autoComplete={field.control === "password" ? "off" : undefined} | 392 | autoComplete={field.control === "password" ? "off" : undefined} |
| 394 | value={readProviderConfigString(value, field.key)} | 393 | value={readProviderConfigString(value, field.key)} |
apps/web/src/components/settings/StorageSettings.tsx+1-1| ... | @@ -62,7 +62,7 @@ function RetentionControl({ | ... | @@ -62,7 +62,7 @@ function RetentionControl({ |
| 62 | <NumberFieldInput | 62 | <NumberFieldInput |
| 63 | aria-label={`${label} in days`} | 63 | aria-label={`${label} in days`} |
| 64 | size={new Intl.NumberFormat().format(draft ?? value).length} | 64 | size={new Intl.NumberFormat().format(draft ?? value).length} |
| 65 | className="field-sizing-content w-auto min-w-[1ch] grow-0 text-right in-data-[size=sm]:px-1" | 65 | className="field-sizing-content w-auto min-w-[1ch] grow-0 text-right" |
| 66 | /> | 66 | /> |
| 67 | <span aria-hidden="true" className="self-center pr-2 text-xs"> | 67 | <span aria-hidden="true" className="self-center pr-2 text-xs"> |
| 68 | days | 68 | days |
apps/web/src/components/settings/ThemeColorPicker.tsx+2-3| ... | @@ -353,15 +353,14 @@ export const ThemeColorField = memo(function ThemeColorField({ | ... | @@ -353,15 +353,14 @@ export const ThemeColorField = memo(function ThemeColorField({ |
| 353 | <Input | 353 | <Input |
| 354 | aria-invalid={!isColorValue} | 354 | aria-invalid={!isColorValue} |
| 355 | aria-label={`${label} hex value`} | 355 | aria-label={`${label} hex value`} |
| 356 | className="w-28 shrink-0 rounded-md border-0 bg-black/10 text-xs text-foreground shadow-none focus-within:bg-black/15 focus-within:ring-0 dark:bg-black/20 dark:focus-within:bg-black/25 [&_[data-slot=input]]:text-right" | 356 | className="w-28 shrink-0 [&_[data-slot=input]]:text-right" |
| 357 | font="mono" | 357 | font="mono" |
| 358 | id={`${role}-hex`} | 358 | id={`${role}-hex`} |
| 359 | nativeInput | 359 | nativeInput |
| 360 | onChange={(event) => onChange(role, event.currentTarget.value)} | 360 | onChange={(event) => onChange(role, event.currentTarget.value)} |
| 361 | onFocus={() => onSelect?.(role)} | 361 | onFocus={() => onSelect?.(role)} |
| 362 | onPointerDown={() => onSelect?.(role)} | 362 | onPointerDown={() => onSelect?.(role)} |
| 363 | size="sm" | 363 | size="compact" |
| 364 | unstyled | ||
| 365 | value={editorValue} | 364 | value={editorValue} |
| 366 | /> | 365 | /> |
| 367 | </div> | 366 | </div> |
apps/web/src/components/ui/autocomplete.tsx+1-1| ... | @@ -125,7 +125,7 @@ function AutocompleteItem({ className, children, ...props }: AutocompletePrimiti | ... | @@ -125,7 +125,7 @@ function AutocompleteItem({ className, children, ...props }: AutocompletePrimiti |
| 125 | return ( | 125 | return ( |
| 126 | <AutocompletePrimitive.Item | 126 | <AutocompletePrimitive.Item |
| 127 | className={cn( | 127 | className={cn( |
| 128 | "flex min-h-8 cursor-default select-none items-center rounded-sm px-2 py-1 text-base outline-none hover:bg-accent data-disabled:pointer-events-none data-selected:bg-accent/50 data-selected:text-foreground data-highlighted:bg-accent data-highlighted:text-accent-foreground [&[data-highlighted][data-selected]]:bg-accent [&[data-highlighted][data-selected]]:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='text-'])]:text-muted-foreground", | 128 | "flex min-h-8 cursor-default select-none items-center gap-2 rounded-sm px-2 py-1 text-base outline-none hover:bg-accent data-disabled:pointer-events-none data-selected:bg-accent/50 data-selected:text-foreground data-highlighted:bg-accent data-highlighted:text-accent-foreground [&[data-highlighted][data-selected]]:bg-accent [&[data-highlighted][data-selected]]:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='text-'])]:text-muted-foreground", |
| 129 | className, | 129 | className, |
| 130 | )} | 130 | )} |
| 131 | data-slot="autocomplete-item" | 131 | data-slot="autocomplete-item" |
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 = 499; | 11 | export const RESTYLE_CEILING = 402; |
| 12 | 12 | ||
| 13 | const RULE = "shadcn(no-restyle)"; | 13 | const RULE = "shadcn(no-restyle)"; |
| 14 | 14 |