Simplify right panel: name buttons for library, labels above options, lock at top
Made-with: Cursor
This commit is contained in:
@@ -357,9 +357,9 @@ const LIBRARY_STYLE_OPTIONS: Record<string, LibraryStyleOptions> = {
|
|||||||
|
|
||||||
function ConfigRow({ label, children }: { label: string; children: React.ReactNode }) {
|
function ConfigRow({ label, children }: { label: string; children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", alignItems: "flex-start", gap: 10, paddingBottom: 10, borderBottom: "1px solid #f0ece4" }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 7, paddingBottom: 12, borderBottom: "1px solid #f0ece4" }}>
|
||||||
<span style={{ width: 88, flexShrink: 0, fontSize: "0.65rem", fontWeight: 700, color: "#a09a90", textTransform: "uppercase", letterSpacing: "0.08em", fontFamily: "Outfit", paddingTop: 5 }}>{label}</span>
|
<span style={{ fontSize: "0.62rem", fontWeight: 700, color: "#a09a90", textTransform: "uppercase", letterSpacing: "0.1em", fontFamily: "Outfit" }}>{label}</span>
|
||||||
<div style={{ flex: 1, display: "flex", gap: 6, flexWrap: "wrap" }}>
|
<div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -612,95 +612,77 @@ function SurfaceSection({
|
|||||||
background: "#fff", overflow: "auto",
|
background: "#fff", overflow: "auto",
|
||||||
display: "flex", flexDirection: "column", gap: 0,
|
display: "flex", flexDirection: "column", gap: 0,
|
||||||
}}>
|
}}>
|
||||||
<div style={{ padding: "16px 16px", display: "flex", flexDirection: "column", gap: 14 }}>
|
<div style={{ padding: "14px 16px", display: "flex", flexDirection: "column", gap: 12 }}>
|
||||||
|
|
||||||
{/* Library capability cards — 2-col grid */}
|
{/* Lock / unlock — top of panel */}
|
||||||
<div style={{ display: "grid", gridTemplateColumns: `repeat(${Math.min(surface.themes.length, 2)}, 1fr)`, gap: 6 }}>
|
<div style={{ display: "flex", alignItems: "center", gap: 8, paddingBottom: 12, borderBottom: "1px solid #f0ece4" }}>
|
||||||
{surface.themes.map(theme => {
|
{isLocked ? (
|
||||||
const isActive = theme.id === previewId;
|
<button
|
||||||
const isThisLocked = theme.id === lockedThemeId;
|
onClick={onUnlock}
|
||||||
const dimmed = isLocked && !isThisLocked;
|
style={{
|
||||||
return (
|
flex: 1, padding: "7px 14px", borderRadius: 7, border: "1px solid #e0dcd4",
|
||||||
<button
|
background: "#fff", color: "#1a1a1a", fontSize: "0.76rem", fontWeight: 600,
|
||||||
key={theme.id}
|
fontFamily: "Outfit", cursor: "pointer", transition: "opacity 0.15s",
|
||||||
onClick={() => { if (!isLocked) { onSelect(theme.id); setSelectedColorTheme(null); } }}
|
}}
|
||||||
disabled={dimmed}
|
onMouseEnter={e => (e.currentTarget.style.opacity = "0.7")}
|
||||||
style={{
|
onMouseLeave={e => (e.currentTarget.style.opacity = "1")}
|
||||||
display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 0,
|
>✎ Change selection</button>
|
||||||
padding: "12px 14px", borderRadius: 9, textAlign: "left",
|
) : (
|
||||||
border: `1px solid ${isActive ? "#1a1a1a" : "#e8e4dc"}`,
|
<button
|
||||||
background: isActive ? "#1a1a1a" : "#fff",
|
onClick={onLock}
|
||||||
boxShadow: isActive ? "0 0 0 1px #1a1a1a" : "none",
|
disabled={!selectedThemeId || saving}
|
||||||
cursor: dimmed ? "not-allowed" : "pointer",
|
style={{
|
||||||
opacity: dimmed ? 0.35 : 1,
|
flex: 1, padding: "7px 14px", borderRadius: 7, border: "1px solid #1a1a1a",
|
||||||
transition: "all 0.12s",
|
background: !selectedThemeId || saving ? "#e0dcd4" : "#1a1a1a",
|
||||||
position: "relative",
|
color: !selectedThemeId || saving ? "#b5b0a6" : "#fff",
|
||||||
fontFamily: "Outfit, sans-serif",
|
fontSize: "0.76rem", fontWeight: 600, fontFamily: "Outfit",
|
||||||
}}
|
cursor: !selectedThemeId || saving ? "not-allowed" : "pointer",
|
||||||
onMouseEnter={e => { if (!isLocked && !isActive) { (e.currentTarget as HTMLElement).style.borderColor = "#c5c0b8"; } }}
|
transition: "opacity 0.15s",
|
||||||
onMouseLeave={e => { if (!isLocked && !isActive) { (e.currentTarget as HTMLElement).style.borderColor = "#e8e4dc"; } }}
|
}}
|
||||||
>
|
onMouseEnter={e => { if (selectedThemeId && !saving) (e.currentTarget.style.opacity = "0.8"); }}
|
||||||
{/* Top row: name + badges */}
|
onMouseLeave={e => { (e.currentTarget.style.opacity = "1"); }}
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: 6, width: "100%", marginBottom: 8 }}>
|
>{saving ? "Saving…" : "🔒 Lock in"}</button>
|
||||||
|
)}
|
||||||
|
{activeTheme && (
|
||||||
|
<a href={activeTheme.url} target="_blank" rel="noopener noreferrer"
|
||||||
|
style={{ fontSize: "0.72rem", color: "#b5b0a6", textDecoration: "none", fontFamily: "Outfit", flexShrink: 0 }}
|
||||||
|
onMouseEnter={e => (e.currentTarget.style.color = "#1a1a1a")}
|
||||||
|
onMouseLeave={e => (e.currentTarget.style.color = "#b5b0a6")}
|
||||||
|
>Docs ↗</a>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Library — simple name buttons */}
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: 7, paddingBottom: 12, borderBottom: "1px solid #f0ece4" }}>
|
||||||
|
<span style={{ fontSize: "0.62rem", fontWeight: 700, color: "#a09a90", textTransform: "uppercase", letterSpacing: "0.1em", fontFamily: "Outfit" }}>Library</span>
|
||||||
|
<div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
|
||||||
|
{surface.themes.map(theme => {
|
||||||
|
const isActive = theme.id === previewId;
|
||||||
|
const isThisLocked = theme.id === lockedThemeId;
|
||||||
|
const dimmed = isLocked && !isThisLocked;
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={theme.id}
|
||||||
|
onClick={() => { if (!isLocked) { onSelect(theme.id); setSelectedColorTheme(null); } }}
|
||||||
|
disabled={dimmed}
|
||||||
|
style={{
|
||||||
|
display: "flex", alignItems: "center", gap: 4,
|
||||||
|
padding: "4px 11px", borderRadius: 5, border: "1px solid",
|
||||||
|
fontSize: "0.72rem", fontFamily: "Outfit", cursor: dimmed ? "not-allowed" : "pointer",
|
||||||
|
transition: "all 0.1s", opacity: dimmed ? 0.35 : 1,
|
||||||
|
borderColor: isActive ? "#1a1a1a" : "#e0dcd4",
|
||||||
|
background: isActive ? "#1a1a1a" : "#fff",
|
||||||
|
color: isActive ? "#fff" : "#4a4640",
|
||||||
|
}}
|
||||||
|
onMouseEnter={e => { if (!isLocked && !isActive) (e.currentTarget as HTMLElement).style.borderColor = "#c5c0b8"; }}
|
||||||
|
onMouseLeave={e => { if (!isLocked && !isActive) (e.currentTarget as HTMLElement).style.borderColor = "#e0dcd4"; }}
|
||||||
|
>
|
||||||
{isThisLocked && <span style={{ fontSize: "0.6rem" }}>🔒</span>}
|
{isThisLocked && <span style={{ fontSize: "0.6rem" }}>🔒</span>}
|
||||||
<span style={{ fontSize: "0.8rem", fontWeight: 700, color: isActive ? "#fff" : "#1a1a1a", flex: 1 }}>
|
{theme.name}
|
||||||
{theme.name}
|
</button>
|
||||||
</span>
|
);
|
||||||
{theme.hasTemplates && (
|
})}
|
||||||
<span style={{
|
</div>
|
||||||
fontSize: "0.56rem", fontWeight: 700, padding: "1px 5px", borderRadius: 3,
|
|
||||||
background: isActive ? "rgba(255,255,255,0.15)" : "#f0ece4",
|
|
||||||
color: isActive ? "rgba(255,255,255,0.8)" : "#8a8478",
|
|
||||||
letterSpacing: "0.04em", textTransform: "uppercase", flexShrink: 0,
|
|
||||||
}}>Templates</span>
|
|
||||||
)}
|
|
||||||
{theme.darkFirst && (
|
|
||||||
<span style={{
|
|
||||||
fontSize: "0.56rem", fontWeight: 700, padding: "1px 5px", borderRadius: 3,
|
|
||||||
background: isActive ? "rgba(255,255,255,0.15)" : "#1a1a1a",
|
|
||||||
color: isActive ? "rgba(255,255,255,0.8)" : "#fff",
|
|
||||||
letterSpacing: "0.04em", textTransform: "uppercase", flexShrink: 0,
|
|
||||||
}}>Dark</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Best for */}
|
|
||||||
{theme.bestFor && (
|
|
||||||
<p style={{ fontSize: "0.68rem", color: isActive ? "rgba(255,255,255,0.55)" : "#a09a90", marginBottom: 8, lineHeight: 1.4 }}>
|
|
||||||
Best for: {theme.bestFor}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Highlights */}
|
|
||||||
{theme.highlights && theme.highlights.length > 0 && (
|
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: 4, marginBottom: 10, width: "100%" }}>
|
|
||||||
{theme.highlights.map((h, i) => (
|
|
||||||
<div key={i} style={{ display: "flex", alignItems: "flex-start", gap: 6 }}>
|
|
||||||
<span style={{ fontSize: "0.6rem", color: isActive ? "rgba(255,255,255,0.4)" : "#c5c0b8", marginTop: 2, flexShrink: 0 }}>→</span>
|
|
||||||
<span style={{ fontSize: "0.7rem", color: isActive ? "rgba(255,255,255,0.7)" : "#4a4640", lineHeight: 1.4 }}>{h}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Tags */}
|
|
||||||
<div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
|
|
||||||
{theme.tags.map(t => (
|
|
||||||
<span key={t} style={{
|
|
||||||
fontSize: "0.6rem", fontWeight: 600, padding: "2px 6px", borderRadius: 4,
|
|
||||||
background: isActive ? "rgba(255,255,255,0.1)" : "#f6f4f0",
|
|
||||||
color: isActive ? "rgba(255,255,255,0.6)" : "#8a8478",
|
|
||||||
}}>{t}</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Active indicator */}
|
|
||||||
{isActive && !isThisLocked && (
|
|
||||||
<div style={{ position: "absolute", top: 10, right: 12, fontSize: "0.7rem", color: "rgba(255,255,255,0.5)" }}>✓</div>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Design configurator — mode, background, nav, header, sections, font */}
|
{/* Design configurator — mode, background, nav, header, sections, font */}
|
||||||
@@ -741,55 +723,6 @@ function SurfaceSection({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Docs link + lock action bar */}
|
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: 12, paddingTop: 4, borderTop: "1px solid #f0ece4" }}>
|
|
||||||
{activeTheme && (
|
|
||||||
<>
|
|
||||||
<a
|
|
||||||
href={activeTheme.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
style={{ fontSize: "0.75rem", color: "#a09a90", textDecoration: "none", fontFamily: "Outfit" }}
|
|
||||||
onMouseEnter={e => (e.currentTarget.style.color = "#1a1a1a")}
|
|
||||||
onMouseLeave={e => (e.currentTarget.style.color = "#a09a90")}
|
|
||||||
>
|
|
||||||
{activeTheme.name} docs ↗
|
|
||||||
</a>
|
|
||||||
<div style={{ flex: 1 }} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{isLocked ? (
|
|
||||||
<button
|
|
||||||
onClick={onUnlock}
|
|
||||||
style={{
|
|
||||||
padding: "7px 14px", borderRadius: 7, border: "1px solid #e0dcd4",
|
|
||||||
background: "#fff", color: "#1a1a1a", fontSize: "0.76rem", fontWeight: 600,
|
|
||||||
fontFamily: "Outfit", cursor: "pointer", flexShrink: 0, transition: "opacity 0.15s",
|
|
||||||
}}
|
|
||||||
onMouseEnter={e => (e.currentTarget.style.opacity = "0.7")}
|
|
||||||
onMouseLeave={e => (e.currentTarget.style.opacity = "1")}
|
|
||||||
>
|
|
||||||
✎ Change
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
onClick={onLock}
|
|
||||||
disabled={!selectedThemeId || saving}
|
|
||||||
style={{
|
|
||||||
padding: "7px 14px", borderRadius: 7, border: "1px solid #1a1a1a",
|
|
||||||
background: !selectedThemeId || saving ? "#e0dcd4" : "#1a1a1a",
|
|
||||||
color: !selectedThemeId || saving ? "#b5b0a6" : "#fff",
|
|
||||||
fontSize: "0.76rem", fontWeight: 600, fontFamily: "Outfit",
|
|
||||||
cursor: !selectedThemeId || saving ? "not-allowed" : "pointer",
|
|
||||||
flexShrink: 0, transition: "opacity 0.15s",
|
|
||||||
}}
|
|
||||||
onMouseEnter={e => { if (selectedThemeId && !saving) (e.currentTarget.style.opacity = "0.8"); }}
|
|
||||||
onMouseLeave={e => { (e.currentTarget.style.opacity = "1"); }}
|
|
||||||
>
|
|
||||||
{saving ? "Saving…" : "🔒 Lock in"}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>{/* end inner padding div */}
|
</div>{/* end inner padding div */}
|
||||||
</div>{/* end right panel */}
|
</div>{/* end right panel */}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user