Tighten sidebar flow layout

This commit is contained in:
2026-06-24 08:58:42 +09:00
parent a721ebf286
commit 0c494c9bee

View File

@@ -524,6 +524,7 @@ function FlowRow({
}; };
const isRowClickable = Boolean(onLabelClick) && !isEditing; const isRowClickable = Boolean(onLabelClick) && !isEditing;
const isWrappedStepLayout = steps.length > 5; const isWrappedStepLayout = steps.length > 5;
const isSingleStepLayout = steps.length === 1;
const stepRows = isWrappedStepLayout const stepRows = isWrappedStepLayout
? steps.reduce((rows, step, index) => { ? steps.reduce((rows, step, index) => {
const rowIndex = Math.floor(index / 4); const rowIndex = Math.floor(index / 4);
@@ -691,7 +692,7 @@ function FlowRow({
{stepRows.map((row, rowIndex) => ( {stepRows.map((row, rowIndex) => (
<div <div
key={rowIndex} key={rowIndex}
className="relative flex flex-col gap-3 xl:grid xl:grid-cols-[minmax(0,1fr)_36px_minmax(0,1fr)_36px_minmax(0,1fr)_36px_minmax(0,1fr)] xl:gap-0 xl:items-stretch" className="relative flex flex-col gap-3 xl:grid xl:grid-cols-[minmax(0,1fr)_28px_minmax(0,1fr)_28px_minmax(0,1fr)_28px_minmax(0,1fr)] xl:gap-0 xl:items-stretch"
> >
{row.map(({ step, index }, itemIndex) => ( {row.map(({ step, index }, itemIndex) => (
<React.Fragment key={step.id}> <React.Fragment key={step.id}>
@@ -715,9 +716,9 @@ function FlowRow({
<div className="relative flex flex-col gap-3 xl:flex-row xl:items-stretch"> <div className="relative flex flex-col gap-3 xl:flex-row xl:items-stretch">
{steps.map((step, index) => ( {steps.map((step, index) => (
<React.Fragment key={step.id}> <React.Fragment key={step.id}>
{renderStepCard(step, index, 'min-w-[230px] flex-1')} {renderStepCard(step, index, isSingleStepLayout ? 'w-full max-w-[320px]' : 'min-w-0 flex-1')}
{index < steps.length - 1 && ( {index < steps.length - 1 && (
<div className="flex items-center justify-center xl:w-9"> <div className="flex items-center justify-center xl:w-7">
<ArrowRight className={`hidden h-5 w-5 xl:block ${accent.arrowText}`} /> <ArrowRight className={`hidden h-5 w-5 xl:block ${accent.arrowText}`} />
<ArrowDown className={`h-5 w-5 xl:hidden ${accent.arrowText}`} /> <ArrowDown className={`h-5 w-5 xl:hidden ${accent.arrowText}`} />
</div> </div>
@@ -1380,6 +1381,8 @@ function RelationTreePanel({ programs, onProgramClick, onOpenRelationPopup }) {
const nextVisitedIds = new Set(visitedIds); const nextVisitedIds = new Set(visitedIds);
nextVisitedIds.add(program.id); nextVisitedIds.add(program.id);
const indent = Math.min(depth, 5) * 13;
return ( return (
<div key={`${program.id}-${depth}-${[...visitedIds].join('-')}`} className="relative"> <div key={`${program.id}-${depth}-${[...visitedIds].join('-')}`} className="relative">
{depth > 0 && ( {depth > 0 && (
@@ -1390,7 +1393,7 @@ function RelationTreePanel({ programs, onProgramClick, onOpenRelationPopup }) {
)} )}
<div <div
className="relative flex items-center gap-2 py-1.5" className="relative flex items-center gap-2 py-1.5"
style={{ paddingLeft: `${depth * 18}px` }} style={{ paddingLeft: `${indent}px` }}
> >
{hasChildren && !isRepeated ? ( {hasChildren && !isRepeated ? (
<button <button
@@ -1407,7 +1410,7 @@ function RelationTreePanel({ programs, onProgramClick, onOpenRelationPopup }) {
<button <button
type="button" type="button"
onClick={() => onProgramClick(program.id)} onClick={() => onProgramClick(program.id)}
className="min-w-0 flex-1 rounded-xl bg-white/85 px-3 py-2 text-left shadow-sm ring-1 ring-slate-100 transition hover:-translate-y-0.5 hover:bg-white hover:shadow" className="min-w-0 flex-1 overflow-hidden rounded-xl bg-white/85 px-3 py-2 text-left shadow-sm ring-1 ring-slate-100 transition hover:-translate-y-0.5 hover:bg-white hover:shadow"
> >
<span className="block truncate text-[13px] font-black text-slate-900"> <span className="block truncate text-[13px] font-black text-slate-900">
{program.name} {program.name}
@@ -1432,7 +1435,7 @@ function RelationTreePanel({ programs, onProgramClick, onOpenRelationPopup }) {
}; };
return ( return (
<aside className="sticky top-5 max-h-[calc(100vh-40px)] overflow-y-auto rounded-[28px] border border-white/75 bg-white/75 p-4 shadow-sm backdrop-blur"> <aside className="sticky top-5 max-h-[calc(100vh-40px)] overflow-y-auto overflow-x-hidden rounded-[26px] border border-white/75 bg-white/75 p-3.5 shadow-sm backdrop-blur">
<div className="mb-4 flex items-start justify-between gap-3"> <div className="mb-4 flex items-start justify-between gap-3">
<div> <div>
<p className="text-[11px] font-black uppercase tracking-wide text-blue-700">Program Map</p> <p className="text-[11px] font-black uppercase tracking-wide text-blue-700">Program Map</p>
@@ -2102,7 +2105,7 @@ export default function App() {
return ( return (
<main className="min-h-screen bg-[radial-gradient(circle_at_top_left,#dffcf4_0,#f7f8fa_34%,#eef2ff_100%)] text-slate-900"> <main className="min-h-screen bg-[radial-gradient(circle_at_top_left,#dffcf4_0,#f7f8fa_34%,#eef2ff_100%)] text-slate-900">
<div className="mx-auto max-w-[1600px] space-y-5 px-6 py-6"> <div className="mx-auto max-w-[1760px] space-y-4 px-3 py-4">
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
<button <button
type="button" type="button"
@@ -2118,7 +2121,7 @@ export default function App() {
</button> </button>
</div> </div>
<div className="grid gap-5 xl:grid-cols-[310px_minmax(0,1fr)] xl:items-start"> <div className="grid gap-4 xl:grid-cols-[280px_minmax(0,1fr)] xl:items-start">
<RelationTreePanel <RelationTreePanel
programs={programs} programs={programs}
onProgramClick={openProgramWindow} onProgramClick={openProgramWindow}