mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 06:04:43 +00:00
Refine Foundry UI layout and styling (#235)
* feat: modernize chat UI and rename handoff to task - Remove agent message bubbles, keep user bubbles (right-aligned) - Rename "Handoffs" to "Tasks" with ListChecks icon in sidebar - Move model picker inside composer, add renderFooter to ChatComposer SDK - Make project sections collapsible with hover-only chevrons - Remove divider between chat and composer - Update model picker chevron to flip on open/close - Replace all user-visible "handoff" strings with "task" across frontend Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: real org mock data, model picker styling, project icons, task minutes indicator - Replace fake acme/* mock data with real rivet-dev GitHub org repos and PRs - Fix model picker popover: dark gray surface with backdrop blur instead of pure black - Add colored letter icons to project section headers (swap to chevron on hover) - Add "847 min used" indicator in transcript header - Rename browser tab title from OpenHandoff to Foundry - Reduce transcript header title font weight to 500 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: refine Foundry UI — single-line task cards, dark user bubbles, curved panel corners, send icon - Collapse task sidebar cards to single-line layout (title, number, diffs, timestamp) - Dark-themed user message bubbles matching site theme - Curved top-left corner on center chat panel with border line - Subtle focus border on composer input - Replace ArrowUpFromLine with SendHorizonal icon - Tab strip gaps, padding, and divider alignment fixes - Plus button with visible background - Right sidebar header color matching Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
20082512a3
commit
e792a720a0
9 changed files with 201 additions and 123 deletions
|
|
@ -4,15 +4,15 @@ export const appTheme: Theme = createDarkTheme({
|
||||||
colors: {
|
colors: {
|
||||||
primary: "#e4e4e7", // zinc-200
|
primary: "#e4e4e7", // zinc-200
|
||||||
accent: "#ff4f00", // orange accent (inspector)
|
accent: "#ff4f00", // orange accent (inspector)
|
||||||
backgroundPrimary: "#000000", // pure black (inspector --bg)
|
backgroundPrimary: "#09090b", // darkest — chat center panel
|
||||||
backgroundSecondary: "#0a0a0b", // near-black panels (inspector --bg-panel)
|
backgroundSecondary: "#0f0f11", // slightly lighter — sidebars
|
||||||
backgroundTertiary: "#0a0a0b", // same as panel (border provides separation)
|
backgroundTertiary: "#0c0c0e", // center + right panel headers
|
||||||
backgroundInversePrimary: "#fafafa",
|
backgroundInversePrimary: "#fafafa",
|
||||||
contentPrimary: "#ffffff", // white (inspector --text)
|
contentPrimary: "#ffffff", // white (inspector --text)
|
||||||
contentSecondary: "#a1a1aa", // zinc-400 (inspector --muted)
|
contentSecondary: "#a1a1aa", // zinc-400 (inspector --muted)
|
||||||
contentTertiary: "#71717a", // zinc-500
|
contentTertiary: "#71717a", // zinc-500
|
||||||
contentInversePrimary: "#000000",
|
contentInversePrimary: "#000000",
|
||||||
borderOpaque: "rgba(255, 255, 255, 0.18)", // inspector --border
|
borderOpaque: "rgba(255, 255, 255, 0.10)", // inspector --border
|
||||||
borderTransparent: "rgba(255, 255, 255, 0.14)", // inspector --border-2
|
borderTransparent: "rgba(255, 255, 255, 0.07)", // inspector --border-2
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -455,6 +455,7 @@ const TranscriptPanel = memo(function TranscriptPanel({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", backgroundColor: "#09090b", borderTopLeftRadius: "12px", borderLeft: "1px solid rgba(255, 255, 255, 0.10)", borderTop: "1px solid rgba(255, 255, 255, 0.10)", overflow: "hidden" }}>
|
||||||
<TabStrip
|
<TabStrip
|
||||||
handoff={handoff}
|
handoff={handoff}
|
||||||
activeTabId={activeTabId}
|
activeTabId={activeTabId}
|
||||||
|
|
@ -510,8 +511,8 @@ const TranscriptPanel = memo(function TranscriptPanel({
|
||||||
border: 0,
|
border: 0,
|
||||||
borderRadius: "999px",
|
borderRadius: "999px",
|
||||||
padding: "10px 18px",
|
padding: "10px 18px",
|
||||||
background: "#ff4f00",
|
background: "rgba(255, 255, 255, 0.12)",
|
||||||
color: "#fff",
|
color: "#e4e4e7",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
}}
|
}}
|
||||||
|
|
@ -554,6 +555,7 @@ const TranscriptPanel = memo(function TranscriptPanel({
|
||||||
onSetDefaultModel={setDefaultModel}
|
onSetDefaultModel={setDefaultModel}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
</div>
|
||||||
</SPanel>
|
</SPanel>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -723,7 +725,23 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
handoffWorkbenchClient.getSnapshot.bind(handoffWorkbenchClient),
|
handoffWorkbenchClient.getSnapshot.bind(handoffWorkbenchClient),
|
||||||
);
|
);
|
||||||
const handoffs = viewModel.handoffs ?? [];
|
const handoffs = viewModel.handoffs ?? [];
|
||||||
const projects = viewModel.projects ?? [];
|
const rawProjects = viewModel.projects ?? [];
|
||||||
|
const [projectOrder, setProjectOrder] = useState<string[] | null>(null);
|
||||||
|
const projects = useMemo(() => {
|
||||||
|
if (!projectOrder) return rawProjects;
|
||||||
|
const byId = new Map(rawProjects.map((p) => [p.id, p]));
|
||||||
|
const ordered = projectOrder.map((id) => byId.get(id)).filter(Boolean) as typeof rawProjects;
|
||||||
|
for (const p of rawProjects) {
|
||||||
|
if (!projectOrder.includes(p.id)) ordered.push(p);
|
||||||
|
}
|
||||||
|
return ordered;
|
||||||
|
}, [rawProjects, projectOrder]);
|
||||||
|
const reorderProjects = useCallback((fromIndex: number, toIndex: number) => {
|
||||||
|
const ids = projects.map((p) => p.id);
|
||||||
|
const [moved] = ids.splice(fromIndex, 1);
|
||||||
|
ids.splice(toIndex, 0, moved!);
|
||||||
|
setProjectOrder(ids);
|
||||||
|
}, [projects]);
|
||||||
const [activeTabIdByHandoff, setActiveTabIdByHandoff] = useState<Record<string, string | null>>({});
|
const [activeTabIdByHandoff, setActiveTabIdByHandoff] = useState<Record<string, string | null>>({});
|
||||||
const [lastAgentTabIdByHandoff, setLastAgentTabIdByHandoff] = useState<Record<string, string | null>>({});
|
const [lastAgentTabIdByHandoff, setLastAgentTabIdByHandoff] = useState<Record<string, string | null>>({});
|
||||||
const [openDiffsByHandoff, setOpenDiffsByHandoff] = useState<Record<string, string[]>>({});
|
const [openDiffsByHandoff, setOpenDiffsByHandoff] = useState<Record<string, string[]>>({});
|
||||||
|
|
@ -1027,34 +1045,35 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: "min(520px, 100%)",
|
width: "min(440px, 100%)",
|
||||||
border: "1px solid rgba(255, 255, 255, 0.14)",
|
border: "1px solid rgba(255, 255, 255, 0.10)",
|
||||||
borderRadius: "18px",
|
borderRadius: "12px",
|
||||||
background: "#111113",
|
background: "rgba(24, 24, 27, 0.98)",
|
||||||
boxShadow: "0 32px 80px rgba(0, 0, 0, 0.45)",
|
backdropFilter: "blur(16px)",
|
||||||
padding: "24px",
|
boxShadow: "0 24px 64px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.04)",
|
||||||
|
padding: "28px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: "16px",
|
gap: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: "10px" }}>
|
||||||
<div style={{ fontSize: "12px", letterSpacing: "0.08em", textTransform: "uppercase", color: "rgba(255, 255, 255, 0.5)" }}>Onboarding</div>
|
<div style={{ fontSize: "11px", letterSpacing: "0.06em", textTransform: "uppercase", fontWeight: 600, color: "rgba(255, 255, 255, 0.4)" }}>Welcome to Foundry</div>
|
||||||
<h2 style={{ margin: 0, fontSize: "24px", lineHeight: 1.1 }}>Give us support for sandbox agent</h2>
|
<h2 style={{ margin: 0, fontSize: "18px", fontWeight: 500, lineHeight: 1.3 }}>Support Sandbox Agent</h2>
|
||||||
<p style={{ margin: 0, color: "rgba(255, 255, 255, 0.72)", lineHeight: 1.5 }}>
|
<p style={{ margin: 0, color: "rgba(255, 255, 255, 0.55)", fontSize: "13px", lineHeight: 1.6 }}>
|
||||||
Before you keep going, give us support for sandbox agent and star the repo right here in the app.
|
Star the repo to help us grow and stay up to date with new releases.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{starRepoError ? (
|
{starRepoError ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
borderRadius: "12px",
|
borderRadius: "8px",
|
||||||
border: "1px solid rgba(255, 110, 110, 0.32)",
|
border: "1px solid rgba(255, 110, 110, 0.24)",
|
||||||
background: "rgba(255, 110, 110, 0.08)",
|
background: "rgba(255, 110, 110, 0.06)",
|
||||||
padding: "12px 14px",
|
padding: "10px 12px",
|
||||||
color: "#ffb4b4",
|
color: "#ff9b9b",
|
||||||
fontSize: "13px",
|
fontSize: "12px",
|
||||||
}}
|
}}
|
||||||
data-testid="onboarding-star-repo-error"
|
data-testid="onboarding-star-repo-error"
|
||||||
>
|
>
|
||||||
|
|
@ -1062,18 +1081,20 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div style={{ display: "flex", justifyContent: "flex-end", gap: "10px" }}>
|
<div style={{ display: "flex", justifyContent: "flex-end", gap: "8px" }}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={dismissStarRepoPrompt}
|
onClick={dismissStarRepoPrompt}
|
||||||
style={{
|
style={{
|
||||||
border: "1px solid rgba(255, 255, 255, 0.14)",
|
border: "1px solid rgba(255, 255, 255, 0.10)",
|
||||||
borderRadius: "999px",
|
borderRadius: "6px",
|
||||||
padding: "10px 16px",
|
padding: "8px 14px",
|
||||||
background: "transparent",
|
background: "rgba(255, 255, 255, 0.05)",
|
||||||
color: "#e4e4e7",
|
color: "rgba(255, 255, 255, 0.7)",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
fontWeight: 600,
|
fontSize: "12px",
|
||||||
|
fontWeight: 500,
|
||||||
|
transition: "all 160ms ease",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Maybe later
|
Maybe later
|
||||||
|
|
@ -1084,16 +1105,18 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
disabled={starRepoPending}
|
disabled={starRepoPending}
|
||||||
style={{
|
style={{
|
||||||
border: 0,
|
border: 0,
|
||||||
borderRadius: "999px",
|
borderRadius: "6px",
|
||||||
padding: "10px 16px",
|
padding: "8px 14px",
|
||||||
background: starRepoPending ? "#7f5539" : "#ff4f00",
|
background: starRepoPending ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.12)",
|
||||||
color: "#fff",
|
color: "#e4e4e7",
|
||||||
cursor: starRepoPending ? "progress" : "pointer",
|
cursor: starRepoPending ? "progress" : "pointer",
|
||||||
fontWeight: 700,
|
fontSize: "12px",
|
||||||
|
fontWeight: 600,
|
||||||
|
transition: "all 160ms ease",
|
||||||
}}
|
}}
|
||||||
data-testid="onboarding-star-repo-submit"
|
data-testid="onboarding-star-repo-submit"
|
||||||
>
|
>
|
||||||
{starRepoPending ? "Starring..." : "Star the sandbox agent repo"}
|
{starRepoPending ? "Starring..." : "Star the repo"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1112,8 +1135,9 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
onMarkUnread={markHandoffUnread}
|
onMarkUnread={markHandoffUnread}
|
||||||
onRenameHandoff={renameHandoff}
|
onRenameHandoff={renameHandoff}
|
||||||
onRenameBranch={renameBranch}
|
onRenameBranch={renameBranch}
|
||||||
|
onReorderProjects={reorderProjects}
|
||||||
/>
|
/>
|
||||||
<SPanel>
|
<SPanel $style={{ backgroundColor: "#09090b" }}>
|
||||||
<ScrollBody>
|
<ScrollBody>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
@ -1148,8 +1172,8 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
border: 0,
|
border: 0,
|
||||||
borderRadius: "999px",
|
borderRadius: "999px",
|
||||||
padding: "10px 18px",
|
padding: "10px 18px",
|
||||||
background: viewModel.repos.length > 0 ? "#ff4f00" : "#444",
|
background: viewModel.repos.length > 0 ? "rgba(255, 255, 255, 0.12)" : "#444",
|
||||||
color: "#fff",
|
color: "#e4e4e7",
|
||||||
cursor: viewModel.repos.length > 0 ? "pointer" : "not-allowed",
|
cursor: viewModel.repos.length > 0 ? "pointer" : "not-allowed",
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
}}
|
}}
|
||||||
|
|
@ -1178,6 +1202,7 @@ export function MockLayout({ workspaceId, selectedHandoffId, selectedSessionId }
|
||||||
onMarkUnread={markHandoffUnread}
|
onMarkUnread={markHandoffUnread}
|
||||||
onRenameHandoff={renameHandoff}
|
onRenameHandoff={renameHandoff}
|
||||||
onRenameBranch={renameBranch}
|
onRenameBranch={renameBranch}
|
||||||
|
onReorderProjects={reorderProjects}
|
||||||
/>
|
/>
|
||||||
<TranscriptPanel
|
<TranscriptPanel
|
||||||
handoff={activeHandoff}
|
handoff={activeHandoff}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ const TranscriptMessageBody = memo(function TranscriptMessageBody({
|
||||||
borderTopRightRadius: "16px",
|
borderTopRightRadius: "16px",
|
||||||
...(isUser
|
...(isUser
|
||||||
? {
|
? {
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "rgba(255, 255, 255, 0.10)",
|
||||||
color: "#000000",
|
color: "#e4e4e7",
|
||||||
borderBottomLeftRadius: "16px",
|
borderBottomLeftRadius: "16px",
|
||||||
borderBottomRightRadius: "4px",
|
borderBottomRightRadius: "4px",
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +107,7 @@ const TranscriptMessageBody = memo(function TranscriptMessageBody({
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Copy size={11} />
|
<Copy size={11} />
|
||||||
{isCopied ? "Copied" : "Copy"}
|
{isCopied ? "Copied" : null}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { memo, type Ref } from "react";
|
import { memo, type Ref } from "react";
|
||||||
import { useStyletron } from "baseui";
|
import { useStyletron } from "baseui";
|
||||||
import { ChatComposer, type ChatComposerClassNames } from "@sandbox-agent/react";
|
import { ChatComposer, type ChatComposerClassNames } from "@sandbox-agent/react";
|
||||||
import { ArrowUpFromLine, FileCode, Square, X } from "lucide-react";
|
import { FileCode, SendHorizonal, Square, X } from "lucide-react";
|
||||||
|
|
||||||
import { ModelPicker } from "./model-picker";
|
import { ModelPicker } from "./model-picker";
|
||||||
import { PROMPT_TEXTAREA_MAX_HEIGHT, PROMPT_TEXTAREA_MIN_HEIGHT } from "./ui";
|
import { PROMPT_TEXTAREA_MAX_HEIGHT, PROMPT_TEXTAREA_MIN_HEIGHT } from "./ui";
|
||||||
|
|
@ -45,7 +45,7 @@ export const PromptComposer = memo(function PromptComposer({
|
||||||
borderRadius: "16px",
|
borderRadius: "16px",
|
||||||
minHeight: `${PROMPT_TEXTAREA_MIN_HEIGHT + 36}px`,
|
minHeight: `${PROMPT_TEXTAREA_MIN_HEIGHT + 36}px`,
|
||||||
transition: "border-color 200ms ease",
|
transition: "border-color 200ms ease",
|
||||||
":focus-within": { borderColor: "rgba(255, 255, 255, 0.3)" },
|
":focus-within": { borderColor: "rgba(255, 255, 255, 0.15)" },
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
}),
|
}),
|
||||||
|
|
@ -82,9 +82,9 @@ export const PromptComposer = memo(function PromptComposer({
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
color: theme.colors.contentPrimary,
|
color: theme.colors.contentPrimary,
|
||||||
transition: "background 200ms ease",
|
transition: "background 200ms ease",
|
||||||
backgroundColor: isRunning ? "rgba(255, 255, 255, 0.06)" : "#ff4f00",
|
backgroundColor: isRunning ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.12)",
|
||||||
":hover": {
|
":hover": {
|
||||||
backgroundColor: isRunning ? "rgba(255, 255, 255, 0.12)" : "#ff6a00",
|
backgroundColor: isRunning ? "rgba(255, 255, 255, 0.12)" : "rgba(255, 255, 255, 0.20)",
|
||||||
},
|
},
|
||||||
":disabled": {
|
":disabled": {
|
||||||
cursor: "not-allowed",
|
cursor: "not-allowed",
|
||||||
|
|
@ -157,7 +157,7 @@ export const PromptComposer = memo(function PromptComposer({
|
||||||
allowEmptySubmit={isRunning}
|
allowEmptySubmit={isRunning}
|
||||||
submitLabel={isRunning ? "Stop" : "Send"}
|
submitLabel={isRunning ? "Stop" : "Send"}
|
||||||
classNames={composerClassNames}
|
classNames={composerClassNames}
|
||||||
renderSubmitContent={() => (isRunning ? <Square size={16} /> : <ArrowUpFromLine size={16} />)}
|
renderSubmitContent={() => (isRunning ? <Square size={16} /> : <SendHorizonal size={16} />)}
|
||||||
renderFooter={() => (
|
renderFooter={() => (
|
||||||
<div className={css({ padding: "0 10px 8px" })}>
|
<div className={css({ padding: "0 10px 8px" })}>
|
||||||
<ModelPicker
|
<ModelPicker
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,8 @@ export const RightSidebar = memo(function RightSidebar({
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SPanel>
|
<SPanel $style={{ backgroundColor: "#09090b" }}>
|
||||||
<PanelHeaderBar>
|
<PanelHeaderBar $style={{ backgroundColor: "#0f0f11", borderBottom: "none" }}>
|
||||||
<div className={css({ flex: 1 })} />
|
<div className={css({ flex: 1 })} />
|
||||||
{!isTerminal ? (
|
{!isTerminal ? (
|
||||||
<div className={css({ display: "flex", alignItems: "center", gap: "4px" })}>
|
<div className={css({ display: "flex", alignItems: "center", gap: "4px" })}>
|
||||||
|
|
@ -208,12 +208,14 @@ export const RightSidebar = memo(function RightSidebar({
|
||||||
) : null}
|
) : null}
|
||||||
</PanelHeaderBar>
|
</PanelHeaderBar>
|
||||||
|
|
||||||
|
<div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", borderTop: `1px solid rgba(255, 255, 255, 0.10)` }}>
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "stretch",
|
alignItems: "stretch",
|
||||||
|
gap: "4px",
|
||||||
borderBottom: `1px solid ${theme.colors.borderOpaque}`,
|
borderBottom: `1px solid ${theme.colors.borderOpaque}`,
|
||||||
backgroundColor: theme.colors.backgroundSecondary,
|
backgroundColor: "#09090b",
|
||||||
height: "41px",
|
height: "41px",
|
||||||
minHeight: "41px",
|
minHeight: "41px",
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
|
|
@ -226,19 +228,21 @@ export const RightSidebar = memo(function RightSidebar({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "6px",
|
gap: "6px",
|
||||||
height: "100%",
|
padding: "4px 12px",
|
||||||
padding: "0 16px",
|
marginTop: "6px",
|
||||||
|
marginBottom: "6px",
|
||||||
|
marginLeft: "6px",
|
||||||
|
borderRadius: "8px",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
fontWeight: 600,
|
fontWeight: 500,
|
||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
color: rightTab === "changes" ? theme.colors.contentPrimary : theme.colors.contentSecondary,
|
color: rightTab === "changes" ? theme.colors.contentPrimary : theme.colors.contentSecondary,
|
||||||
borderBottom: `2px solid ${rightTab === "changes" ? "#ff4f00" : "transparent"}`,
|
backgroundColor: rightTab === "changes" ? "rgba(255, 255, 255, 0.06)" : "transparent",
|
||||||
marginBottom: "-1px",
|
transitionProperty: "color, background-color",
|
||||||
transitionProperty: "color, border-color",
|
|
||||||
transitionDuration: "200ms",
|
transitionDuration: "200ms",
|
||||||
transitionTimingFunction: "ease",
|
transitionTimingFunction: "ease",
|
||||||
":hover": { color: "#e4e4e7" },
|
":hover": { color: "#e4e4e7", backgroundColor: rightTab === "changes" ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.04)" },
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
Changes
|
Changes
|
||||||
|
|
@ -268,19 +272,20 @@ export const RightSidebar = memo(function RightSidebar({
|
||||||
all: "unset",
|
all: "unset",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
height: "100%",
|
padding: "4px 12px",
|
||||||
padding: "0 16px",
|
marginTop: "6px",
|
||||||
|
marginBottom: "6px",
|
||||||
|
borderRadius: "8px",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
fontWeight: 600,
|
fontWeight: 500,
|
||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
color: rightTab === "files" ? theme.colors.contentPrimary : theme.colors.contentSecondary,
|
color: rightTab === "files" ? theme.colors.contentPrimary : theme.colors.contentSecondary,
|
||||||
borderBottom: `2px solid ${rightTab === "files" ? "#ff4f00" : "transparent"}`,
|
backgroundColor: rightTab === "files" ? "rgba(255, 255, 255, 0.06)" : "transparent",
|
||||||
marginBottom: "-1px",
|
transitionProperty: "color, background-color",
|
||||||
transitionProperty: "color, border-color",
|
|
||||||
transitionDuration: "200ms",
|
transitionDuration: "200ms",
|
||||||
transitionTimingFunction: "ease",
|
transitionTimingFunction: "ease",
|
||||||
":hover": { color: "#e4e4e7" },
|
":hover": { color: "#e4e4e7", backgroundColor: rightTab === "files" ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.04)" },
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
All Files
|
All Files
|
||||||
|
|
@ -360,6 +365,7 @@ export const RightSidebar = memo(function RightSidebar({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</ScrollBody>
|
</ScrollBody>
|
||||||
|
</div>
|
||||||
{contextMenu.menu ? <ContextMenuOverlay menu={contextMenu.menu} onClose={contextMenu.close} /> : null}
|
{contextMenu.menu ? <ContextMenuOverlay menu={contextMenu.menu} onClose={contextMenu.close} /> : null}
|
||||||
</SPanel>
|
</SPanel>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { memo, useState } from "react";
|
import { memo, useRef, useState } from "react";
|
||||||
import { useStyletron } from "baseui";
|
import { useStyletron } from "baseui";
|
||||||
import { LabelSmall, LabelXSmall } from "baseui/typography";
|
import { LabelSmall, LabelXSmall } from "baseui/typography";
|
||||||
import { ChevronDown, ChevronUp, CloudUpload, GitPullRequestDraft, ListChecks, Plus } from "lucide-react";
|
import { ChevronDown, ChevronUp, CloudUpload, GitPullRequestDraft, ListChecks, Plus } from "lucide-react";
|
||||||
|
|
@ -30,6 +30,7 @@ export const Sidebar = memo(function Sidebar({
|
||||||
onMarkUnread,
|
onMarkUnread,
|
||||||
onRenameHandoff,
|
onRenameHandoff,
|
||||||
onRenameBranch,
|
onRenameBranch,
|
||||||
|
onReorderProjects,
|
||||||
}: {
|
}: {
|
||||||
projects: ProjectSection[];
|
projects: ProjectSection[];
|
||||||
activeId: string;
|
activeId: string;
|
||||||
|
|
@ -38,10 +39,13 @@ export const Sidebar = memo(function Sidebar({
|
||||||
onMarkUnread: (id: string) => void;
|
onMarkUnread: (id: string) => void;
|
||||||
onRenameHandoff: (id: string) => void;
|
onRenameHandoff: (id: string) => void;
|
||||||
onRenameBranch: (id: string) => void;
|
onRenameBranch: (id: string) => void;
|
||||||
|
onReorderProjects: (fromIndex: number, toIndex: number) => void;
|
||||||
}) {
|
}) {
|
||||||
const [css, theme] = useStyletron();
|
const [css, theme] = useStyletron();
|
||||||
const contextMenu = useContextMenu();
|
const contextMenu = useContextMenu();
|
||||||
const [collapsedProjects, setCollapsedProjects] = useState<Record<string, boolean>>({});
|
const [collapsedProjects, setCollapsedProjects] = useState<Record<string, boolean>>({});
|
||||||
|
const dragIndexRef = useRef<number | null>(null);
|
||||||
|
const [dragOverIndex, setDragOverIndex] = useState<number | null>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SPanel>
|
<SPanel>
|
||||||
|
|
@ -53,10 +57,10 @@ export const Sidebar = memo(function Sidebar({
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
<PanelHeaderBar>
|
<PanelHeaderBar $style={{ backgroundColor: "transparent", borderBottom: "none" }}>
|
||||||
<LabelSmall
|
<LabelSmall
|
||||||
color={theme.colors.contentPrimary}
|
color={theme.colors.contentPrimary}
|
||||||
$style={{ fontWeight: 600, flex: 1, fontSize: "13px", display: "flex", alignItems: "center", gap: "6px" }}
|
$style={{ fontWeight: 500, flex: 1, fontSize: "13px", display: "flex", alignItems: "center", gap: "6px" }}
|
||||||
>
|
>
|
||||||
<ListChecks size={14} />
|
<ListChecks size={14} />
|
||||||
Tasks
|
Tasks
|
||||||
|
|
@ -65,17 +69,17 @@ export const Sidebar = memo(function Sidebar({
|
||||||
onClick={onCreate}
|
onClick={onCreate}
|
||||||
className={css({
|
className={css({
|
||||||
all: "unset",
|
all: "unset",
|
||||||
width: "24px",
|
width: "26px",
|
||||||
height: "24px",
|
height: "26px",
|
||||||
borderRadius: "4px",
|
borderRadius: "8px",
|
||||||
backgroundColor: "#ff4f00",
|
backgroundColor: "rgba(255, 255, 255, 0.12)",
|
||||||
color: "#ffffff",
|
color: "#e4e4e7",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
transition: "background 200ms ease",
|
transition: "background 200ms ease",
|
||||||
":hover": { backgroundColor: "#ff6a00" },
|
":hover": { backgroundColor: "rgba(255, 255, 255, 0.20)" },
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Plus size={14} />
|
<Plus size={14} />
|
||||||
|
|
@ -83,11 +87,48 @@ export const Sidebar = memo(function Sidebar({
|
||||||
</PanelHeaderBar>
|
</PanelHeaderBar>
|
||||||
<ScrollBody>
|
<ScrollBody>
|
||||||
<div className={css({ padding: "8px", display: "flex", flexDirection: "column", gap: "4px" })}>
|
<div className={css({ padding: "8px", display: "flex", flexDirection: "column", gap: "4px" })}>
|
||||||
{projects.map((project) => {
|
{projects.map((project, projectIndex) => {
|
||||||
const isCollapsed = collapsedProjects[project.id] === true;
|
const isCollapsed = collapsedProjects[project.id] === true;
|
||||||
|
const isDragOver = dragOverIndex === projectIndex && dragIndexRef.current !== projectIndex;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={project.id} className={css({ display: "flex", flexDirection: "column", gap: "4px" })}>
|
<div
|
||||||
|
key={project.id}
|
||||||
|
draggable
|
||||||
|
onDragStart={(event) => {
|
||||||
|
dragIndexRef.current = projectIndex;
|
||||||
|
event.dataTransfer.effectAllowed = "move";
|
||||||
|
event.dataTransfer.setData("text/plain", String(projectIndex));
|
||||||
|
}}
|
||||||
|
onDragOver={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = "move";
|
||||||
|
setDragOverIndex(projectIndex);
|
||||||
|
}}
|
||||||
|
onDragLeave={() => {
|
||||||
|
setDragOverIndex((current) => (current === projectIndex ? null : current));
|
||||||
|
}}
|
||||||
|
onDrop={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const fromIndex = dragIndexRef.current;
|
||||||
|
if (fromIndex != null && fromIndex !== projectIndex) {
|
||||||
|
onReorderProjects(fromIndex, projectIndex);
|
||||||
|
}
|
||||||
|
dragIndexRef.current = null;
|
||||||
|
setDragOverIndex(null);
|
||||||
|
}}
|
||||||
|
onDragEnd={() => {
|
||||||
|
dragIndexRef.current = null;
|
||||||
|
setDragOverIndex(null);
|
||||||
|
}}
|
||||||
|
className={css({
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "4px",
|
||||||
|
borderTop: isDragOver ? "2px solid #ff4f00" : "2px solid transparent",
|
||||||
|
transition: "border-color 150ms ease",
|
||||||
|
})}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setCollapsedProjects((current) => ({
|
setCollapsedProjects((current) => ({
|
||||||
|
|
@ -102,7 +143,7 @@ export const Sidebar = memo(function Sidebar({
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
padding: "10px 8px 4px",
|
padding: "10px 8px 4px",
|
||||||
gap: "8px",
|
gap: "8px",
|
||||||
cursor: "pointer",
|
cursor: "grab",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
":hover": { opacity: 0.8 },
|
":hover": { opacity: 0.8 },
|
||||||
})}
|
})}
|
||||||
|
|
@ -150,9 +191,11 @@ export const Sidebar = memo(function Sidebar({
|
||||||
{project.label}
|
{project.label}
|
||||||
</LabelSmall>
|
</LabelSmall>
|
||||||
</div>
|
</div>
|
||||||
<LabelXSmall color={theme.colors.contentTertiary}>
|
{isCollapsed ? (
|
||||||
{formatRelativeAge(project.updatedAtMs)}
|
<LabelXSmall color={theme.colors.contentTertiary}>
|
||||||
</LabelXSmall>
|
{formatRelativeAge(project.updatedAtMs)}
|
||||||
|
</LabelXSmall>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!isCollapsed && project.handoffs.map((handoff) => {
|
{!isCollapsed && project.handoffs.map((handoff) => {
|
||||||
|
|
@ -177,7 +220,7 @@ export const Sidebar = memo(function Sidebar({
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
className={css({
|
className={css({
|
||||||
padding: "12px",
|
padding: "8px 12px",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
border: "1px solid transparent",
|
border: "1px solid transparent",
|
||||||
backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "transparent",
|
backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "transparent",
|
||||||
|
|
@ -204,35 +247,17 @@ export const Sidebar = memo(function Sidebar({
|
||||||
</div>
|
</div>
|
||||||
<LabelSmall
|
<LabelSmall
|
||||||
$style={{
|
$style={{
|
||||||
fontWeight: 600,
|
fontWeight: hasUnread ? 600 : 400,
|
||||||
flex: 1,
|
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
textOverflow: "ellipsis",
|
textOverflow: "ellipsis",
|
||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
|
minWidth: 0,
|
||||||
|
flexShrink: 1,
|
||||||
}}
|
}}
|
||||||
color={isDim ? theme.colors.contentSecondary : theme.colors.contentPrimary}
|
color={hasUnread ? "#ffffff" : theme.colors.contentSecondary}
|
||||||
>
|
>
|
||||||
{handoff.title}
|
{handoff.title}
|
||||||
</LabelSmall>
|
</LabelSmall>
|
||||||
{hasDiffs ? (
|
|
||||||
<div className={css({ display: "flex", gap: "4px", flexShrink: 0 })}>
|
|
||||||
<span className={css({ fontSize: "11px", color: "#7ee787" })}>+{totalAdded}</span>
|
|
||||||
<span className={css({ fontSize: "11px", color: "#ffa198" })}>-{totalRemoved}</span>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
<div className={css({ display: "flex", alignItems: "center", marginTop: "4px", gap: "6px" })}>
|
|
||||||
<LabelXSmall
|
|
||||||
color={theme.colors.contentTertiary}
|
|
||||||
$style={{
|
|
||||||
overflow: "hidden",
|
|
||||||
textOverflow: "ellipsis",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
flexShrink: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{handoff.repoName}
|
|
||||||
</LabelXSmall>
|
|
||||||
{handoff.pullRequest != null ? (
|
{handoff.pullRequest != null ? (
|
||||||
<span className={css({ display: "inline-flex", alignItems: "center", gap: "4px", flexShrink: 0 })}>
|
<span className={css({ display: "inline-flex", alignItems: "center", gap: "4px", flexShrink: 0 })}>
|
||||||
<LabelXSmall color={theme.colors.contentSecondary} $style={{ fontWeight: 600 }}>
|
<LabelXSmall color={theme.colors.contentSecondary} $style={{ fontWeight: 600 }}>
|
||||||
|
|
@ -243,7 +268,13 @@ export const Sidebar = memo(function Sidebar({
|
||||||
) : (
|
) : (
|
||||||
<GitPullRequestDraft size={11} color={theme.colors.contentTertiary} />
|
<GitPullRequestDraft size={11} color={theme.colors.contentTertiary} />
|
||||||
)}
|
)}
|
||||||
<LabelXSmall color={theme.colors.contentTertiary} $style={{ marginLeft: "auto", flexShrink: 0 }}>
|
{hasDiffs ? (
|
||||||
|
<div className={css({ display: "flex", gap: "4px", flexShrink: 0, marginLeft: "auto" })}>
|
||||||
|
<span className={css({ fontSize: "11px", color: "#7ee787" })}>+{totalAdded}</span>
|
||||||
|
<span className={css({ fontSize: "11px", color: "#ffa198" })}>-{totalRemoved}</span>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<LabelXSmall color={theme.colors.contentTertiary} $style={{ flexShrink: 0, marginLeft: hasDiffs ? undefined : "auto" }}>
|
||||||
{formatRelativeAge(handoff.updatedAtMs)}
|
{formatRelativeAge(handoff.updatedAtMs)}
|
||||||
</LabelXSmall>
|
</LabelXSmall>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,18 @@ export const TabStrip = memo(function TabStrip({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<style>{`
|
||||||
|
[data-tab]:hover [data-tab-close] { opacity: 0.5 !important; }
|
||||||
|
[data-tab]:hover [data-tab-close]:hover { opacity: 1 !important; }
|
||||||
|
`}</style>
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "stretch",
|
alignItems: "stretch",
|
||||||
borderBottom: `1px solid ${theme.colors.borderOpaque}`,
|
borderBottom: `1px solid ${theme.colors.borderOpaque}`,
|
||||||
backgroundColor: theme.colors.backgroundSecondary,
|
gap: "4px",
|
||||||
|
backgroundColor: "#09090b",
|
||||||
|
paddingLeft: "6px",
|
||||||
height: "41px",
|
height: "41px",
|
||||||
minHeight: "41px",
|
minHeight: "41px",
|
||||||
overflowX: "auto",
|
overflowX: "auto",
|
||||||
|
|
@ -79,16 +85,20 @@ export const TabStrip = memo(function TabStrip({
|
||||||
...(handoff.tabs.length > 1 ? [{ label: "Close tab", onClick: () => onCloseTab(tab.id) }] : []),
|
...(handoff.tabs.length > 1 ? [{ label: "Close tab", onClick: () => onCloseTab(tab.id) }] : []),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
data-tab
|
||||||
className={css({
|
className={css({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "6px",
|
gap: "6px",
|
||||||
padding: "0 14px",
|
padding: "4px 12px",
|
||||||
borderBottom: isActive ? "2px solid #ff4f00" : "2px solid transparent",
|
marginTop: "6px",
|
||||||
|
marginBottom: "6px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "transparent",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
transition: "color 200ms ease, border-color 200ms ease",
|
transition: "color 200ms ease, background-color 200ms ease",
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
":hover": { color: "#e4e4e7" },
|
":hover": { color: "#e4e4e7", backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.04)" },
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
@ -130,7 +140,7 @@ export const TabStrip = memo(function TabStrip({
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<LabelXSmall color={isActive ? theme.colors.contentPrimary : theme.colors.contentSecondary} $style={{ fontWeight: 600 }}>
|
<LabelXSmall color={isActive ? theme.colors.contentPrimary : theme.colors.contentSecondary} $style={{ fontWeight: 500 }}>
|
||||||
{tab.sessionName}
|
{tab.sessionName}
|
||||||
</LabelXSmall>
|
</LabelXSmall>
|
||||||
)}
|
)}
|
||||||
|
|
@ -138,7 +148,8 @@ export const TabStrip = memo(function TabStrip({
|
||||||
<X
|
<X
|
||||||
size={11}
|
size={11}
|
||||||
color={theme.colors.contentTertiary}
|
color={theme.colors.contentTertiary}
|
||||||
className={css({ cursor: "pointer", opacity: 0.5, ":hover": { opacity: 1 } })}
|
data-tab-close
|
||||||
|
className={css({ cursor: "pointer", opacity: 0 })}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
onCloseTab(tab.id);
|
onCloseTab(tab.id);
|
||||||
|
|
@ -161,29 +172,34 @@ export const TabStrip = memo(function TabStrip({
|
||||||
onCloseDiffTab(path);
|
onCloseDiffTab(path);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
data-tab
|
||||||
className={css({
|
className={css({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "6px",
|
gap: "6px",
|
||||||
padding: "0 14px",
|
padding: "4px 12px",
|
||||||
borderBottom: "2px solid transparent",
|
marginTop: "6px",
|
||||||
|
marginBottom: "6px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "transparent",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
transition: "color 200ms ease, border-color 200ms ease",
|
transition: "color 200ms ease, background-color 200ms ease",
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
":hover": { color: "#e4e4e7" },
|
":hover": { color: "#e4e4e7", backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.04)" },
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<FileCode size={12} color={isActive ? theme.colors.contentPrimary : theme.colors.contentSecondary} />
|
<FileCode size={12} color={isActive ? theme.colors.contentPrimary : theme.colors.contentSecondary} />
|
||||||
<LabelXSmall
|
<LabelXSmall
|
||||||
color={isActive ? theme.colors.contentPrimary : theme.colors.contentSecondary}
|
color={isActive ? theme.colors.contentPrimary : theme.colors.contentSecondary}
|
||||||
$style={{ fontWeight: 600, fontFamily: '"IBM Plex Mono", monospace' }}
|
$style={{ fontWeight: 500, fontFamily: '"IBM Plex Mono", monospace' }}
|
||||||
>
|
>
|
||||||
{fileName(path)}
|
{fileName(path)}
|
||||||
</LabelXSmall>
|
</LabelXSmall>
|
||||||
<X
|
<X
|
||||||
size={11}
|
size={11}
|
||||||
color={theme.colors.contentTertiary}
|
color={theme.colors.contentTertiary}
|
||||||
className={css({ cursor: "pointer", opacity: 0.5, ":hover": { opacity: 1 } })}
|
data-tab-close
|
||||||
|
className={css({ cursor: "pointer", opacity: 0 })}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
onCloseDiffTab(path);
|
onCloseDiffTab(path);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export const TranscriptHeader = memo(function TranscriptHeader({
|
||||||
const [css, theme] = useStyletron();
|
const [css, theme] = useStyletron();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelHeaderBar>
|
<PanelHeaderBar $style={{ backgroundColor: "#0f0f11", borderBottom: "none" }}>
|
||||||
{editingField === "title" ? (
|
{editingField === "title" ? (
|
||||||
<input
|
<input
|
||||||
autoFocus
|
autoFocus
|
||||||
|
|
@ -58,7 +58,7 @@ export const TranscriptHeader = memo(function TranscriptHeader({
|
||||||
<LabelSmall
|
<LabelSmall
|
||||||
title="Rename"
|
title="Rename"
|
||||||
color={theme.colors.contentPrimary}
|
color={theme.colors.contentPrimary}
|
||||||
$style={{ fontWeight: 500, whiteSpace: "nowrap", cursor: "pointer", ":hover": { textDecoration: "underline" } }}
|
$style={{ fontWeight: 400, whiteSpace: "nowrap", cursor: "pointer", ":hover": { textDecoration: "underline" } }}
|
||||||
onClick={() => onStartEditingField("title", handoff.title)}
|
onClick={() => onStartEditingField("title", handoff.title)}
|
||||||
>
|
>
|
||||||
{handoff.title}
|
{handoff.title}
|
||||||
|
|
|
||||||
|
|
@ -178,8 +178,8 @@ export const Shell = styled("div", ({ $theme }) => ({
|
||||||
display: "grid",
|
display: "grid",
|
||||||
gap: "1px",
|
gap: "1px",
|
||||||
height: "100dvh",
|
height: "100dvh",
|
||||||
backgroundColor: $theme.colors.borderOpaque,
|
backgroundColor: $theme.colors.backgroundSecondary,
|
||||||
gridTemplateColumns: "280px minmax(0, 1fr) 380px",
|
gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1.5fr) 380px",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue