Skip to content

Commit 3a11b23

Browse files
authored
Merge pull request #47 from beNative/codex/make-treeview-spacing-and-indent-configurable
Add settings for document tree spacing
2 parents 92e039f + 3abc791 commit 3a11b23

9 files changed

Lines changed: 421 additions & 13 deletions

File tree

App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,8 @@ const MainApp: React.FC = () => {
11361136
onRenameTemplate={handleRenameTemplate}
11371137
onNewTemplate={handleNewTemplate}
11381138
onNewFromTemplate={() => setCreateFromTemplateOpen(true)}
1139+
documentTreeIndent={settings.documentTreeIndent}
1140+
documentTreeVerticalSpacing={settings.documentTreeVerticalSpacing}
11391141
/>
11401142
</aside>
11411143
<div

components/PromptList.tsx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ interface DocumentListProps {
88
documents: DocumentOrFolder[]; // needed for the empty state check
99
selectedIds: Set<string>;
1010
focusedItemId: string | null;
11+
indentPerLevel: number;
12+
verticalSpacing: number;
1113
onSelectNode: (id: string, e: React.MouseEvent) => void;
1214
onDeleteNode: (id: string, shiftKey?: boolean) => void;
1315
onRenameNode: (id: string, newTitle: string) => void;
@@ -24,8 +26,27 @@ interface DocumentListProps {
2426
onRenameComplete: () => void;
2527
}
2628

27-
const DocumentList: React.FC<DocumentListProps> = ({
28-
tree, documents, selectedIds, focusedItemId, onSelectNode, onDeleteNode, onRenameNode, onMoveNode, onDropFiles, onCopyNodeContent, searchTerm, expandedIds, onToggleExpand, onMoveUp, onMoveDown, onContextMenu, renamingNodeId, onRenameComplete
29+
const DocumentList: React.FC<DocumentListProps> = ({
30+
tree,
31+
documents,
32+
selectedIds,
33+
focusedItemId,
34+
indentPerLevel,
35+
verticalSpacing,
36+
onSelectNode,
37+
onDeleteNode,
38+
onRenameNode,
39+
onMoveNode,
40+
onDropFiles,
41+
onCopyNodeContent,
42+
searchTerm,
43+
expandedIds,
44+
onToggleExpand,
45+
onMoveUp,
46+
onMoveDown,
47+
onContextMenu,
48+
renamingNodeId,
49+
onRenameComplete
2950
}) => {
3051
// Fix: Corrected useState declaration syntax from `=>` to `=`. This resolves all subsequent "cannot find name" errors.
3152
const [isRootDropping, setIsRootDropping] = useState(false);
@@ -95,12 +116,14 @@ const DocumentList: React.FC<DocumentListProps> = ({
95116
onDragLeave={handleRootDragLeave}
96117
onContextMenu={handleRootContextMenu}
97118
>
98-
<ul className="space-y-0 p-1">
119+
<ul className="space-y-0 p-1 m-0 list-none">
99120
{tree.map((node, index) => (
100121
<DocumentTreeItem
101122
key={node.id}
102123
node={node}
103124
level={0}
125+
indentPerLevel={indentPerLevel}
126+
verticalSpacing={verticalSpacing}
104127
selectedIds={selectedIds}
105128
focusedItemId={focusedItemId}
106129
expandedIds={displayExpandedIds}

components/PromptTreeItem.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export interface DocumentNode extends DocumentOrFolder {
1111
interface DocumentTreeItemProps {
1212
node: DocumentNode;
1313
level: number;
14+
indentPerLevel: number;
15+
verticalSpacing: number;
1416
selectedIds: Set<string>;
1517
focusedItemId: string | null;
1618
expandedIds: Set<string>;
@@ -76,7 +78,9 @@ const DocumentTreeItem: React.FC<DocumentTreeItemProps> = (props) => {
7678
canMoveDown,
7779
onContextMenu,
7880
renamingNodeId,
79-
onRenameComplete
81+
onRenameComplete,
82+
indentPerLevel,
83+
verticalSpacing
8084
} = props;
8185

8286
const [isRenaming, setIsRenaming] = useState(false);
@@ -184,6 +188,11 @@ const DocumentTreeItem: React.FC<DocumentTreeItemProps> = (props) => {
184188
onContextMenu(e, node.id);
185189
}
186190

191+
const safeIndent = Math.max(indentPerLevel, 0);
192+
const paddingTopBottom = Math.max(verticalSpacing, 0);
193+
const basePaddingLeft = 4; // matches Tailwind px-1 for consistent baseline spacing
194+
const rowPaddingLeft = basePaddingLeft + Math.max(level, 0) * safeIndent;
195+
187196
return (
188197
<li
189198
ref={itemRef}
@@ -193,14 +202,14 @@ const DocumentTreeItem: React.FC<DocumentTreeItemProps> = (props) => {
193202
onDragLeave={handleDragLeave}
194203
onDrop={handleDrop}
195204
onContextMenu={handleContextMenu}
196-
style={{ paddingLeft: `${level * 16}px` }}
197205
className="relative"
198206
data-item-id={node.id}
199207
>
200208
<div
201209
onClick={(e) => !isRenaming && onSelectNode(node.id, e)}
202210
onDoubleClick={(e) => !isRenaming && handleRenameStart(e)}
203-
className={`w-full text-left p-1 rounded-md group flex justify-between items-center transition-colors duration-150 text-xs relative focus:outline-none ${
211+
style={{ paddingTop: `${paddingTopBottom}px`, paddingBottom: `${paddingTopBottom}px`, paddingLeft: `${rowPaddingLeft}px` }}
212+
className={`w-full text-left pr-1 rounded-md group flex justify-between items-center transition-colors duration-150 text-xs relative focus:outline-none ${
204213
isSelected ? 'bg-tree-selected text-text-main' : 'hover:bg-border-color/30 text-text-secondary hover:text-text-main'
205214
} ${isFocused ? 'ring-2 ring-primary ring-offset-[-2px] ring-offset-secondary' : ''}`}
206215
>
@@ -261,13 +270,17 @@ const DocumentTreeItem: React.FC<DocumentTreeItemProps> = (props) => {
261270
{dropPosition === 'inside' && <div className="absolute inset-0 border-2 border-primary rounded-md pointer-events-none bg-primary/10" />}
262271

263272
{isFolder && isExpanded && (
264-
<ul>
273+
<ul
274+
className="m-0 pl-0 list-none space-y-0"
275+
>
265276
{node.children.map((childNode, index) => (
266-
<DocumentTreeItem
267-
key={childNode.id}
268-
{...props}
269-
node={childNode}
277+
<DocumentTreeItem
278+
key={childNode.id}
279+
{...props}
280+
node={childNode}
270281
level={level + 1}
282+
indentPerLevel={indentPerLevel}
283+
verticalSpacing={verticalSpacing}
271284
canMoveUp={index > 0}
272285
canMoveDown={index < node.children.length - 1}
273286
/>

components/SettingsView.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,36 @@ const AppearanceSettingsSection: React.FC<Pick<SectionProps, 'settings' | 'setCu
587587
<span className="font-semibold text-text-main tabular-nums min-w-[50px] text-right text-xs">{settings.uiScale}%</span>
588588
</div>
589589
</SettingRow>
590+
<SettingRow label="Document Tree Row Spacing" description="Adjust the vertical padding used for each entry in the sidebar tree.">
591+
<div className="flex items-center gap-4 w-60">
592+
<input
593+
id="documentTreeVerticalSpacing"
594+
type="range"
595+
min="0"
596+
max="16"
597+
step="1"
598+
value={settings.documentTreeVerticalSpacing}
599+
onChange={(e) => setCurrentSettings(prev => ({ ...prev, documentTreeVerticalSpacing: Number(e.target.value) }))}
600+
className="w-full h-2 bg-border-color rounded-lg appearance-none cursor-pointer range-slider"
601+
/>
602+
<span className="font-semibold text-text-main tabular-nums min-w-[50px] text-right text-xs">{settings.documentTreeVerticalSpacing}px</span>
603+
</div>
604+
</SettingRow>
605+
<SettingRow label="Document Tree Indent" description="Control how far nested folders and documents are indented.">
606+
<div className="flex items-center gap-4 w-60">
607+
<input
608+
id="documentTreeIndent"
609+
type="range"
610+
min="0"
611+
max="32"
612+
step="1"
613+
value={settings.documentTreeIndent}
614+
onChange={(e) => setCurrentSettings(prev => ({ ...prev, documentTreeIndent: Number(e.target.value) }))}
615+
className="w-full h-2 bg-border-color rounded-lg appearance-none cursor-pointer range-slider"
616+
/>
617+
<span className="font-semibold text-text-main tabular-nums min-w-[50px] text-right text-xs">{settings.documentTreeIndent}px</span>
618+
</div>
619+
</SettingRow>
590620
<SettingRow label="Icon Set" description="Customize the look of icons throughout the application.">
591621
<div className="grid grid-cols-3 gap-3 w-80">
592622
<CardButton name="Heroicons" value="heroicons" isSelected={settings.iconSet === 'heroicons'} onClick={(v) => setCurrentSettings(s => ({...s, iconSet: v}))}>

components/Sidebar.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ interface SidebarProps {
5151
onRenameTemplate: (id: string, newTitle: string) => void;
5252
onNewTemplate: () => void;
5353
onNewFromTemplate: () => void;
54+
documentTreeIndent: number;
55+
documentTreeVerticalSpacing: number;
5456
}
5557

5658
const DEFAULT_TEMPLATES_PANEL_HEIGHT = 160;
@@ -360,11 +362,13 @@ const Sidebar: React.FC<SidebarProps> = (props) => {
360362
</div>
361363
</header>
362364
<div className="flex-1 overflow-y-auto">
363-
<DocumentList
365+
<DocumentList
364366
tree={documentTree}
365367
documents={props.documents}
366368
selectedIds={props.selectedIds}
367369
focusedItemId={focusedItemId}
370+
indentPerLevel={props.documentTreeIndent}
371+
verticalSpacing={props.documentTreeVerticalSpacing}
368372
onSelectNode={props.onSelectNode}
369373
onDeleteNode={props.onDeleteNode}
370374
onRenameNode={props.onRenameNode}

constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export const DEFAULT_SETTINGS: Settings = {
2525
autoSaveLogs: false,
2626
allowPrerelease: false,
2727
uiScale: 100,
28+
documentTreeIndent: 16,
29+
documentTreeVerticalSpacing: 4,
2830
customShortcuts: {},
2931
markdownFontSize: 16,
3032
markdownLineHeight: 1.7,

0 commit comments

Comments
 (0)