From e3a1d7441389b45305b46d8c0855b45c963b4ec4 Mon Sep 17 00:00:00 2001 From: drelich Date: Sat, 21 Mar 2026 08:43:58 +0100 Subject: [PATCH] feat: add collapsible settings panel and resizable notes list (v0.1.2) - Settings panel in categories sidebar now collapses/expands with toggle button - Settings collapsed by default to save space - Notes list column now resizable with drag handle (240px-600px range) - Improved UI flexibility and space management --- package.json | 2 +- src/components/CategoriesSidebar.tsx | 174 +++++++++++++++------------ src/components/NotesList.tsx | 48 +++++++- 3 files changed, 143 insertions(+), 81 deletions(-) diff --git a/package.json b/package.json index 8760d76..0b18cfa 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nextcloud-notes-tauri", "private": true, - "version": "0.1.1", + "version": "0.1.2", "type": "module", "scripts": { "dev": "vite", diff --git a/src/components/CategoriesSidebar.tsx b/src/components/CategoriesSidebar.tsx index 9ef03b7..2b6ec4c 100644 --- a/src/components/CategoriesSidebar.tsx +++ b/src/components/CategoriesSidebar.tsx @@ -58,6 +58,7 @@ export function CategoriesSidebar({ }: CategoriesSidebarProps) { const [isCreating, setIsCreating] = useState(false); const [newCategoryName, setNewCategoryName] = useState(''); + const [isSettingsCollapsed, setIsSettingsCollapsed] = useState(true); const inputRef = useRef(null); useEffect(() => { @@ -185,27 +186,40 @@ export function CategoriesSidebar({ {/* User Info and Settings */} -
-
+
+
{username.charAt(0).toUpperCase()}
{username}
- +
+ + +
- {/* Theme Toggle */} -
+ {!isSettingsCollapsed && ( +
+ {/* Theme Toggle */} +
Theme
- {/* Font Settings */} -
+ {/* Font Settings */} +
Fonts - {/* Editor Font */} -
-
- - - - Editor -
-
- - -
-
+ {/* Editor Font */} +
+
+ + + + Editor +
+
+ + +
+
- {/* Preview Font */} -
-
- - - - - Preview -
-
- - + {/* Preview Font */} +
+
+ + + + + Preview +
+
+ + +
+
-
+ )}
); diff --git a/src/components/NotesList.tsx b/src/components/NotesList.tsx index 5e9765c..2c787b7 100644 --- a/src/components/NotesList.tsx +++ b/src/components/NotesList.tsx @@ -30,6 +30,9 @@ export function NotesList({ }: NotesListProps) { const [isSyncing, setIsSyncing] = React.useState(false); const [deleteClickedId, setDeleteClickedId] = React.useState(null); + const [width, setWidth] = React.useState(320); + const [isResizing, setIsResizing] = React.useState(false); + const containerRef = React.useRef(null); const handleSync = async () => { setIsSyncing(true); @@ -37,6 +40,34 @@ export function NotesList({ setTimeout(() => setIsSyncing(false), 500); }; + React.useEffect(() => { + const handleMouseMove = (e: MouseEvent) => { + if (!isResizing) return; + const newWidth = e.clientX - (containerRef.current?.getBoundingClientRect().left || 0); + if (newWidth >= 240 && newWidth <= 600) { + setWidth(newWidth); + } + }; + + const handleMouseUp = () => { + setIsResizing(false); + }; + + if (isResizing) { + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + document.body.style.cursor = 'ew-resize'; + document.body.style.userSelect = 'none'; + } + + return () => { + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + document.body.style.cursor = ''; + document.body.style.userSelect = ''; + }; + }, [isResizing]); + const handleDeleteClick = (note: Note, e: React.MouseEvent) => { e.stopPropagation(); @@ -79,7 +110,11 @@ export function NotesList({ }; return ( -
+

Notes

@@ -207,6 +242,17 @@ export function NotesList({ )) )}
+ + {/* Resize Handle */} +
{ + e.preventDefault(); + setIsResizing(true); + }} + > +
+
); }