Files
inkling/src/renderer/inbox/components/NotebookList.tsx

80 lines
3.3 KiB
TypeScript

import React, { useState } from 'react';
import type { Notebook } from '@shared/types';
interface Props {
notebooks: Notebook[];
selectedId: string | null;
onSelect: (id: string) => void;
onCreate: () => void;
onReorder?: (id: string, direction: 'up' | 'down') => Promise<void>;
}
export function NotebookList({ notebooks, selectedId, onSelect, onCreate, onReorder }: Props): React.ReactElement {
const [hoverId, setHoverId] = useState<string | null>(null);
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
{notebooks.map((nb, idx) => {
const active = nb.id === selectedId;
const hover = nb.id === hoverId;
const isFirst = idx === 0;
const isLast = idx === notebooks.length - 1;
return (
<div
key={nb.id}
onMouseEnter={() => setHoverId(nb.id)}
onMouseLeave={() => setHoverId(null)}
style={{ position: 'relative', display: 'flex' }}
>
<button
onClick={() => onSelect(nb.id)}
style={{
display: 'flex', alignItems: 'center', gap: 8,
padding: '6px 12px', background: active ? '#eaf3ff' : 'transparent',
border: 'none', cursor: 'pointer', textAlign: 'left',
color: active ? '#0a4b80' : '#333', fontSize: 13, flex: 1
}}
>
<span style={{
width: 8, height: 8, borderRadius: '50%',
background: nb.color ?? '#bbb', flexShrink: 0
}} />
<span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{nb.name}
</span>
<span style={{ fontSize: 11, color: '#888' }}>{nb.noteCount}</span>
</button>
{hover && onReorder && notebooks.length > 1 && (
<div style={{ position: 'absolute', right: 4, top: 2, display: 'flex', gap: 2 }}>
<button
onClick={(e) => { e.stopPropagation(); if (!isFirst) void onReorder(nb.id, 'up'); }}
disabled={isFirst}
aria-label={`${nb.name} 위로`}
title="위로"
style={{ background: 'rgba(255,255,255,0.9)', border: '1px solid #ccc', borderRadius: 3, fontSize: 10, padding: '0 4px', cursor: isFirst ? 'not-allowed' : 'pointer', opacity: isFirst ? 0.3 : 1 }}
></button>
<button
onClick={(e) => { e.stopPropagation(); if (!isLast) void onReorder(nb.id, 'down'); }}
disabled={isLast}
aria-label={`${nb.name} 아래로`}
title="아래로"
style={{ background: 'rgba(255,255,255,0.9)', border: '1px solid #ccc', borderRadius: 3, fontSize: 10, padding: '0 4px', cursor: isLast ? 'not-allowed' : 'pointer', opacity: isLast ? 0.3 : 1 }}
></button>
</div>
)}
</div>
);
})}
<button
onClick={onCreate}
style={{
padding: '6px 12px', background: 'transparent', border: 'none',
cursor: 'pointer', textAlign: 'left', color: '#888', fontSize: 12
}}
>
+
</button>
</div>
);
}