fix(codebase): optimize layout paddings for code editor feel

This commit is contained in:
2026-06-14 13:32:25 -07:00
parent 3a884fe28d
commit e06ad16aab
2 changed files with 174 additions and 194 deletions

View File

@@ -50,205 +50,192 @@ export default function CodeTab() {
return ( return (
<div <div
style={{ style={{
minHeight: "100vh", height: "100vh",
background: THEME.canvasGradient, background: THEME.canvasGradient,
fontFamily: THEME.font, fontFamily: THEME.font,
padding: "24px", padding: "16px",
display: "flex",
flexDirection: "column",
}} }}
> >
<div <Card
padding={0}
style={{ style={{
maxWidth: "100%", display: "flex",
margin: "0 auto", flexDirection: "column",
height: "calc(100vh - 48px)", flex: 1,
minHeight: 0,
}} }}
> >
<Card <div style={grid}>
padding={0} {/* ── Left rail ── */}
style={{ <section style={leftCol}>
overflow: "hidden", {showLoading && (
display: "flex", <Card>
flexDirection: "column", <div
height: "100%", style={{
}} display: "flex",
> alignItems: "center",
<div style={grid}> gap: 8,
{/* ── Left rail ── */} color: THEME.mid,
<section style={leftCol}> fontSize: "0.875rem",
{showLoading && ( }}
<Card> >
<div <Loader2 size={15} className="animate-spin" /> Loading
style={{ </div>
display: "flex", </Card>
alignItems: "center", )}
gap: 8, {error && !showLoading && (
color: THEME.mid, <Card>
fontSize: "0.875rem", <div
}} style={{
> display: "flex",
<Loader2 size={15} className="animate-spin" /> Loading alignItems: "center",
</div> gap: 8,
</Card> color: THEME.danger,
)} fontSize: "0.875rem",
{error && !showLoading && ( }}
<Card> >
<div <AlertCircle size={15} /> {error}
style={{ </div>
display: "flex", </Card>
alignItems: "center", )}
gap: 8,
color: THEME.danger,
fontSize: "0.875rem",
}}
>
<AlertCircle size={15} /> {error}
</div>
</Card>
)}
{anatomy && ( {anatomy && (
<> <>
{/* Code Files */} {/* Code Files */}
<RailGroup <RailGroup
title={ title={
codebases?.length === 1 codebases?.length === 1 ? codebases[0].label : "Code files"
? codebases[0].label }
: "Code files" count={codebases?.length ?? 0}
} >
count={codebases?.length ?? 0} {codebases && codebases.length === 0 && (
> <RailEmpty>
{codebases && codebases.length === 0 && ( {reason === "no_repo" ? (
<RailEmpty> <>
{reason === "no_repo" ? ( No codebase yet.{" "}
<> <span style={nudge}>
No codebase yet.{" "} Try: &quot;Start building my app&quot;
<span style={nudge}> </span>
Try: &quot;Start building my app&quot; </>
</span> ) : (
</> <>
) : ( Repo is empty push a first commit.{" "}
<> <span style={nudge}>
Repo is empty push a first commit.{" "} Try: &quot;Scaffold a Next.js app&quot;
<span style={nudge}> </span>
Try: &quot;Scaffold a Next.js app&quot; </>
</span> )}
</> </RailEmpty>
)} )}
</RailEmpty> {codebases?.map((cb) => {
)} return (
{codebases?.map((cb) => { <article
return ( key={cb.id}
<article style={{
key={cb.id} display: "flex",
style={{ flexDirection: "column",
display: "flex", flex: 1,
flexDirection: "column", }}
flex: 1, >
}} {codebases.length > 1 && (
>
{codebases.length > 1 && (
<div
style={{
...tileHeader,
padding: "20px 24px 12px",
}}
>
<span style={chevronCell}>
<ChevronDown
size={13}
style={{ color: THEME.mid }}
/>
</span>
<Box
size={14}
style={{ color: THEME.mid, flexShrink: 0 }}
/>
<div style={{ minWidth: 0, textAlign: "left" }}>
<div
style={{
fontSize: "0.95rem",
fontWeight: 600,
color: THEME.ink,
}}
>
{cb.label}
</div>
{cb.hint && (
<div style={tileHint}>{cb.hint}</div>
)}
</div>
</div>
)}
<div <div
style={{ style={{
padding: ...tileHeader,
codebases.length > 1 padding: "16px 20px 8px",
? "0 10px 24px 10px"
: "10px 10px 24px 10px",
}} }}
> >
<GiteaFileTree <span style={chevronCell}>
projectId={projectId} <ChevronDown
rootPath={cb.path} size={13}
selectedPath={ style={{ color: THEME.mid }}
selection?.type === "file" && />
selection.codebaseId === cb.id </span>
? selection.path <Box
: undefined size={14}
} style={{ color: THEME.mid, flexShrink: 0 }}
onSelectFile={(p) =>
setSelection({
type: "file",
codebaseId: cb.id,
path: p,
})
}
/> />
<div style={{ minWidth: 0, textAlign: "left" }}>
<div
style={{
fontSize: "0.95rem",
fontWeight: 600,
color: THEME.ink,
}}
>
{cb.label}
</div>
{cb.hint && <div style={tileHint}>{cb.hint}</div>}
</div>
</div> </div>
</article> )}
); <div
})} style={{
</RailGroup> padding:
</> codebases.length > 1
)} ? "0 8px 16px 8px"
</section> : "12px 8px 16px 8px",
}}
>
<GiteaFileTree
projectId={projectId}
rootPath={cb.path}
selectedPath={
selection?.type === "file" &&
selection.codebaseId === cb.id
? selection.path
: undefined
}
onSelectFile={(p) =>
setSelection({
type: "file",
codebaseId: cb.id,
path: p,
})
}
/>
</div>
</article>
);
})}
</RailGroup>
</>
)}
</section>
{/* ── Right pane ── */} {/* ── Right pane ── */}
<aside style={rightCol}> <aside style={rightCol}>
<div <div
style={{ style={{
flex: 1, flex: 1,
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
}} }}
> >
{selection?.type === "file" && ( {selection?.type === "file" && (
<GiteaFileViewer <GiteaFileViewer projectId={projectId} path={selection.path} />
projectId={projectId} )}
path={selection.path} {!selection && (
/> <div
)} style={{
{!selection && ( flex: 1,
<div display: "flex",
style={{ alignItems: "center",
flex: 1, justifyContent: "center",
display: "flex", color: THEME.muted,
alignItems: "center", fontSize: "0.85rem",
justifyContent: "center", padding: "32px 16px",
color: THEME.muted, textAlign: "center",
fontSize: "0.85rem", }}
padding: "32px 16px", >
textAlign: "center", Pick a codebase file on the left.
}} </div>
> )}
Pick a codebase file on the left. </div>
</div> </aside>
)} </div>
</div> </Card>
</aside>
</div>
</Card>
</div>
</div> </div>
); );
} }
@@ -390,9 +377,7 @@ const leftCol: React.CSSProperties = {
minWidth: 0, minWidth: 0,
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
gap: 24,
borderRight: `1px solid ${THEME.borderSoft}`, borderRight: `1px solid ${THEME.borderSoft}`,
padding: "20px",
overflowY: "auto", overflowY: "auto",
}; };

View File

@@ -144,10 +144,6 @@ export function GiteaFileViewer({ projectId, path }: GiteaFileViewerProps) {
minHeight: 0, minHeight: 0,
position: "relative", position: "relative",
background: THEME.cardBg, background: THEME.cardBg,
border: `1px solid ${THEME.border}`,
borderRadius: THEME.radiusSm,
boxShadow: THEME.shadow,
overflow: "hidden",
}} }}
> >
<div <div
@@ -155,20 +151,19 @@ export function GiteaFileViewer({ projectId, path }: GiteaFileViewerProps) {
display: "flex", display: "flex",
justifyContent: "space-between", justifyContent: "space-between",
alignItems: "center", alignItems: "center",
padding: "8px 12px", padding: "10px 16px",
background: THEME.subtleBg, background: THEME.subtleBg,
borderBottom: `1px solid ${THEME.borderSoft}`, borderBottom: `1px solid ${THEME.borderSoft}`,
}} }}
> >
<div <div
style={{ style={{
fontSize: "0.8rem", fontSize: "0.85rem",
color: THEME.mid, color: THEME.mid,
fontFamily: "ui-monospace, monospace",
fontWeight: 500, fontWeight: 500,
}} }}
> >
{basename(path)} {path}
</div> </div>
{!isImage && ( {!isImage && (
<button <button