diff --git a/src/SettingTab.tsx b/src/SettingTab.tsx
index 94e5e20..636d0a2 100644
--- a/src/SettingTab.tsx
+++ b/src/SettingTab.tsx
@@ -125,6 +125,7 @@ export class SettingTab extends PluginSettingTab {
this.createHeader2(this.headersCopy.folderAndTagBehavior);
this._initToggleSetting("showFolderHierarchyLines");
this._initToggleSetting("showFilesCount");
+ this._initDropdownSetting("expandNodeOnClick")
this._initToggleSetting("openDestinationFolderAfterMove");
this._initToggleSetting("revealFileInExplorer");
}
diff --git a/src/components/ExpandIcon.tsx b/src/components/ExpandIcon.tsx
index 17c708a..50f830a 100644
--- a/src/components/ExpandIcon.tsx
+++ b/src/components/ExpandIcon.tsx
@@ -5,13 +5,15 @@ import { ChevronRight } from "src/assets/icons";
type Props = {
isExpanded: boolean;
hideIcon: boolean;
+ onToggle: () => void;
};
-const ExpandIcon = ({ isExpanded, hideIcon }: Props) => {
+const ExpandIcon = ({ isExpanded, hideIcon, onToggle }: Props) => {
return (
{hideIcon ? null : (
diff --git a/src/components/Folder/Content.tsx b/src/components/Folder/Content.tsx
index e6d16b3..34f01cd 100644
--- a/src/components/Folder/Content.tsx
+++ b/src/components/Folder/Content.tsx
@@ -1,10 +1,12 @@
import classNames from "classnames";
import { Menu, TFolder } from "obsidian";
-import { useEffect, useRef } from "react";
+import { MouseEvent, useEffect, useRef } from "react";
import { useShallow } from "zustand/react/shallow";
import { useExplorer } from "src/hooks/useExplorer";
+import { useExpandNodeByClick } from "src/hooks/useSettingsHandler";
import { FOLDER_OPERATION_COPY } from "src/locales";
+import { EXPAND_NODE_ON_CLICK } from "src/settings";
import { ExplorerStore } from "src/store";
import {
addCreateFileMenuItem,
@@ -22,7 +24,8 @@ import { FolderListModal } from "../FolderListModal";
import FolderContentInner from "./ContentInner";
-export type FolderInnerContentRef = {
+export type FolderNameRef = {
+ isFocusing: boolean;
setIsFocusing: (isFocusing: boolean) => void;
onStartEditingName: Noop;
};
@@ -33,40 +36,42 @@ export type FolderProps = {
type Props = FolderProps;
const FolderContent = ({ folder }: Props) => {
const { useExplorerStore, plugin } = useExplorer();
- const { language } = plugin;
+ const { language, settings } = plugin;
const {
focusedFolder,
changeFocusedFolder,
- createNewFolder,
- createFileWithDefaultName,
+ createNewFolderAndFocus,
+ createNewFileAndFocus,
pinFolder,
unpinFolder,
isFolderPinned,
trashFolder,
- expandFolder,
- isFolderExpanded
+ toggleFolder,
} = useExplorerStore(
useShallow((store: ExplorerStore) => ({
focusedFolder: store.focusedFolder,
changeFocusedFolder: store.changeFocusedFolder,
- createNewFolder: store.createNewFolder,
- createFileWithDefaultName: store.createFileWithDefaultName,
+ createNewFolderAndFocus: store.createNewFolderAndFocus,
+ createNewFileAndFocus: store.createNewFileAndFocus,
pinFolder: store.pinFolder,
unpinFolder: store.unpinFolder,
isFolderPinned: store.isFolderPinned,
trashFolder: store.trashFolder,
- expandFolder: store.expandFolder,
- isFolderExpanded: store.isFolderExpanded
+ toggleFolder: store.toggleFolder,
}))
);
- const isFocused = folder.path == focusedFolder?.path;
+ const { expandNodeByClick } = useExpandNodeByClick(
+ settings.expandNodeOnClick
+ );
const folderRef = useRef
(null);
- const innerContentRef = useRef(null);
+ const nameRef = useRef(null);
useEffect(() => {
+ nameRef.current?.setIsFocusing(false)
+
if (focusedFolder?.path !== folder.path) return;
setTimeout(() => {
folderRef.current?.scrollIntoView({
@@ -90,28 +95,11 @@ const FolderContent = ({ folder }: Props) => {
modal.open();
};
- const onCreateNewFile = async () => {
- if (folder.path !== focusedFolder?.path) {
- await changeFocusedFolder(folder);
- }
- await createFileWithDefaultName(folder);
- };
-
- const onCreateNewFolder = async () => {
- const newFolder = await createNewFolder(folder);
- if (!isFolderExpanded(folder)) {
- expandFolder(folder);
- }
- if (newFolder) {
- await changeFocusedFolder(newFolder);
- }
- };
-
const addCreateFolderMenuItem = (menu: Menu) => {
addMenuItem(menu, {
title: FOLDER_OPERATION_COPY.createFolder[language],
icon: "folder-open",
- action: onCreateNewFolder,
+ action: async () => await createNewFolderAndFocus(folder),
});
};
@@ -125,7 +113,10 @@ const FolderContent = ({ folder }: Props) => {
addPinInMenu(menu);
menu.addSeparator();
- addCreateFileMenuItem(menu, onCreateNewFile);
+ addCreateFileMenuItem(
+ menu,
+ async () => await createNewFileAndFocus(folder)
+ );
addCreateFolderMenuItem(menu);
menu.addSeparator();
@@ -134,7 +125,7 @@ const FolderContent = ({ folder }: Props) => {
addRenameMenuItem(
menu,
- innerContentRef?.current?.onStartEditingName ?? noop,
+ nameRef?.current?.onStartEditingName ?? noop,
isRootFolder
);
addDeleteMenuItem(menu, () => trashFolder(folder));
@@ -142,18 +133,29 @@ const FolderContent = ({ folder }: Props) => {
triggerMenu(plugin, menu, "folder-context-menu")(e);
};
+ const onClickFolderContent = async (e: MouseEvent) => {
+ e.stopPropagation()
+ e.preventDefault()
+ await changeFocusedFolder(folder);
+ if (expandNodeByClick === EXPAND_NODE_ON_CLICK.LABEL) {
+ toggleFolder(folder);
+ } else if (expandNodeByClick === EXPAND_NODE_ON_CLICK.SELECTED_LABEL) {
+ folderRef.current?.focus();
+ if (nameRef.current?.isFocusing) {
+ toggleFolder(folder);
+ } else {
+ nameRef.current?.setIsFocusing(true);
+ }
+ }
+ };
+
return (
{
- if (isFocused) {
- folderRef.current?.focus();
- innerContentRef.current?.setIsFocusing(true);
- }
- }}
+ onClick={onClickFolderContent}
>
-
+
);
};
diff --git a/src/components/Folder/ContentInner.tsx b/src/components/Folder/ContentInner.tsx
index 101949d..ee940aa 100644
--- a/src/components/Folder/ContentInner.tsx
+++ b/src/components/Folder/ContentInner.tsx
@@ -1,23 +1,23 @@
import { TFolder } from "obsidian";
-import { ForwardedRef, forwardRef, useRef } from "react";
+import { ForwardedRef, forwardRef, Ref } from "react";
-import { FolderInnerContentRef } from "./Content";
+import { FolderNameRef } from "./Content";
import FolderFilesCount from "./FilesCount";
import FolderIcon from "./Icon";
import FolderName from "./Name";
export type FolderProps = {
folder: TFolder;
+ nameRef: Ref
};
type Props = FolderProps;
const FolderContentInner = forwardRef(
- ({ folder }: Props, ref: ForwardedRef) => {
- const folderRef = useRef(null);
+ ({ folder, nameRef }: Props, ref: ForwardedRef) => {
return (
-
+
-
+
);
diff --git a/src/components/Folder/ExpandIcon.tsx b/src/components/Folder/ExpandIcon.tsx
index dec15de..b64f213 100644
--- a/src/components/Folder/ExpandIcon.tsx
+++ b/src/components/Folder/ExpandIcon.tsx
@@ -12,10 +12,11 @@ type Props = {
const FolderExpandIcon = ({ folder }: Props) => {
const { useExplorerStore } = useExplorer();
- const { hasSubFolder, isFolderExpanded } = useExplorerStore(
+ const { hasSubFolder, isFolderExpanded, toggleFolder } = useExplorerStore(
useShallow((store: ExplorerStore) => ({
hasSubFolder: store.hasSubFolder,
isFolderExpanded: store.isFolderExpanded,
+ toggleFolder: store.toggleFolder,
}))
);
@@ -23,6 +24,7 @@ const FolderExpandIcon = ({ folder }: Props) => {
toggleFolder(folder)}
/>
);
};
diff --git a/src/components/Folder/Name.tsx b/src/components/Folder/Name.tsx
index dbfbaba..0a4fe44 100644
--- a/src/components/Folder/Name.tsx
+++ b/src/components/Folder/Name.tsx
@@ -13,43 +13,39 @@ import { useExplorer } from "src/hooks/useExplorer";
import useRenderEditableName from "src/hooks/useRenderEditableName";
import { ExplorerStore } from "src/store";
-import { FolderInnerContentRef } from "./Content";
+import { FolderNameRef } from "./Content";
export type FolderProps = {
folder: TFolder;
};
type Props = FolderProps;
const FolderName = forwardRef(
- ({ folder }: Props, ref: ForwardedRef) => {
+ ({ folder }: Props, ref: ForwardedRef) => {
const { useExplorerStore } = useExplorer();
- const {
- renameFolder,
- getNameOfFolder,
- isLastCreatedFolder,
- } = useExplorerStore(
- useShallow((store: ExplorerStore) => ({
- renameFolder: store.renameFolder,
- getNameOfFolder: store.getNameOfFolder,
- isLastCreatedFolder: store.isLastCreatedFolder,
- }))
- );
+ const { renameFolder, getNameOfFolder, isLastCreatedFolder } =
+ useExplorerStore(
+ useShallow((store: ExplorerStore) => ({
+ renameFolder: store.renameFolder,
+ getNameOfFolder: store.getNameOfFolder,
+ isLastCreatedFolder: store.isLastCreatedFolder,
+ }))
+ );
const onSaveName = (name: string) => renameFolder(folder, name);
const folderName = getNameOfFolder(folder);
- const {
- renderEditableName: renderFolderName,
- onStartEditingName,
- } = useRenderEditableName(folderName, onSaveName, {
- className: "ffs__folder-name",
- });
+ const { renderEditableName: renderFolderName, onStartEditingName } =
+ useRenderEditableName(folderName, onSaveName, {
+ className: "ffs__folder-name",
+ });
const folderRef = useRef(null);
const [isFocusing, setIsFocusing] = useState(false);
useImperativeHandle(ref, () => ({
setIsFocusing,
- onStartEditingName
+ onStartEditingName,
+ isFocusing,
}));
const onClickOutside = (event: MouseEvent) => {
@@ -63,7 +59,7 @@ const FolderName = forwardRef(
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === "Enter" && isFocusing) {
- onStartEditingName()
+ onStartEditingName();
}
};
diff --git a/src/components/Folder/index.tsx b/src/components/Folder/index.tsx
index fb0b51b..6b8bd64 100644
--- a/src/components/Folder/index.tsx
+++ b/src/components/Folder/index.tsx
@@ -27,9 +27,7 @@ const Folder = ({
const { useExplorerStore } = useExplorer();
const {
- changeFocusedFolder,
expandFolder,
- toggleFolder,
focusedFolder,
hasSubFolder,
getFilesinFolder,
@@ -37,10 +35,8 @@ const Folder = ({
getFolderLevel,
} = useExplorerStore(
useShallow((store: ExplorerStore) => ({
- changeFocusedFolder: store.changeFocusedFolder,
hasSubFolder: store.hasSubFolder,
expandFolder: store.expandFolder,
- toggleFolder: store.toggleFolder,
focusedFolder: store.focusedFolder,
getFilesinFolder: store.getFilesInFolder,
getSubFolders: store.getSubFolders,
@@ -97,10 +93,6 @@ const Folder = ({
{
- toggleFolder(folder);
- await changeFocusedFolder(folder);
- }}
style={getIndentStyle(getFolderLevel(folder), disableHoverIndent)}
data-tooltip-position="right"
aria-label={getAriaLabel()}
diff --git a/src/components/FolderAndTagTree/index.tsx b/src/components/FolderAndTagTree/index.tsx
index 6898214..55c0800 100644
--- a/src/components/FolderAndTagTree/index.tsx
+++ b/src/components/FolderAndTagTree/index.tsx
@@ -40,9 +40,9 @@ const FolderAndTagTree = () => {
if (!showFolderView) return;
const sortedFolders = sortFolders(folders);
- return sortedFolders.map((folder) => {
- return
;
- });
+ return sortedFolders.map((folder) => (
+
+ ));
};
const renderTags = (tags: TagNode[]) => {
diff --git a/src/components/Tag/ExpandIcon.tsx b/src/components/Tag/ExpandIcon.tsx
index d7b85ef..6958831 100644
--- a/src/components/Tag/ExpandIcon.tsx
+++ b/src/components/Tag/ExpandIcon.tsx
@@ -12,10 +12,11 @@ type Props = {
const TagExpandIcon = ({ tag }: Props) => {
const { useExplorerStore } = useExplorer();
- const { hasSubTag, isTagExpanded } = useExplorerStore(
+ const { hasSubTag, isTagExpanded, toggleTag } = useExplorerStore(
useShallow((store: ExplorerStore) => ({
hasSubTag: store.hasSubTag,
isTagExpanded: store.isTagExpanded,
+ toggleTag: store.toggleTag,
}))
);
@@ -23,6 +24,7 @@ const TagExpandIcon = ({ tag }: Props) => {
toggleTag(tag)}
/>
);
};
diff --git a/src/hooks/useSettingsHandler/index.tsx b/src/hooks/useSettingsHandler/index.tsx
index 918e27f..b13b253 100644
--- a/src/hooks/useSettingsHandler/index.tsx
+++ b/src/hooks/useSettingsHandler/index.tsx
@@ -1,5 +1,6 @@
import { useAutoHideActionBar } from "./useAutoHideActionBar";
import { useBoldFileTitle } from "./useBoldFileTitle";
+import { useExpandNodeByClick } from "./useExpandNodeByClick";
import { useFileCreationDateFormat } from "./useFileCreationDateFormat";
import { useFileItemSpacing } from "./useFileItemSpacing";
import { useHideRootFolder } from "./useHideRootFolder";
@@ -42,4 +43,5 @@ export {
useIncludeSubTagFiles,
useShowTagIcon,
useShowFilesCount,
+ useExpandNodeByClick
};
diff --git a/src/hooks/useSettingsHandler/useExpandNodeByClick.tsx b/src/hooks/useSettingsHandler/useExpandNodeByClick.tsx
new file mode 100644
index 0000000..8acfcb6
--- /dev/null
+++ b/src/hooks/useSettingsHandler/useExpandNodeByClick.tsx
@@ -0,0 +1,23 @@
+import { useState } from "react";
+
+import { ExpandNodeOnClick } from "src/settings";
+
+import { useWatchSettingsChange } from "./useWatchSettingsChange";
+
+export const useExpandNodeByClick = (
+ defaultExpandNodeByClick: ExpandNodeOnClick
+): { expandNodeByClick: ExpandNodeOnClick } => {
+ const [expandNodeByClick, setExpandNodeByClick] =
+ useState(defaultExpandNodeByClick);
+
+ const onChangeExpand = (event: CustomEvent) => {
+ const { changeKey, changeValue } = event.detail;
+ if (changeKey == "expandNodeByClick") {
+ setExpandNodeByClick(changeValue);
+ }
+ };
+
+ useWatchSettingsChange(onChangeExpand);
+
+ return { expandNodeByClick };
+};
diff --git a/src/locales/settings.ts b/src/locales/settings.ts
index 4f7fd9b..74665bd 100644
--- a/src/locales/settings.ts
+++ b/src/locales/settings.ts
@@ -1,4 +1,5 @@
import {
+ EXPAND_NODE_ON_CLICK,
FILE_ITEM_SPACING,
FileDetailSettings,
FileDisplaySettings,
@@ -145,6 +146,44 @@ export const FOLDER_AND_TAG_BEHAVIOR_SETTINGS_COPY: SettingsLocaleResource): Partial {
+ const updated = { ...raw };
+
+ const legacyExpandNodeOnClick = raw.expandFolderByClickingOn;
+ if (legacyExpandNodeOnClick && !raw.expandNodeOnClick) {
+ const valueMap: Record<
+ ExpandFolderByClickingOnElement,
+ ExpandNodeOnClick
+ > = {
+ icon: "icon",
+ folder: "selected_label",
+ };
+
+ updated.expandNodeOnClick = valueMap[legacyExpandNodeOnClick];
+ }
+
+ return updated;
+ }
+
+ removeLegacySettings(
+ raw: Partial
+ ): FolderFileSplitterPluginSettings {
+ return Object.fromEntries(
+ Object.entries(raw).filter(([key]) => key in DEFAULT_SETTINGS)
+ ) as FolderFileSplitterPluginSettings;
+ }
+
async loadSettings() {
const rawData = (await this.loadData()) ?? {};
- const filteredData = Object.fromEntries(
- Object.entries(rawData).filter(([key]) => key in DEFAULT_SETTINGS)
- );
+ const migratedData = this.migrateLegacySettings(rawData);
+ const filteredData = this.removeLegacySettings(migratedData);
this.settings = Object.assign({}, DEFAULT_SETTINGS, filteredData);
}
diff --git a/src/settings.ts b/src/settings.ts
index d7aec1b..0cea89d 100644
--- a/src/settings.ts
+++ b/src/settings.ts
@@ -1,5 +1,12 @@
export type ValueOf = T[keyof T];
+export const EXPAND_NODE_ON_CLICK = {
+ ICON: "icon",
+ LABEL: "label",
+ SELECTED_LABEL: "selected_label",
+} as const;
+export type ExpandNodeOnClick = ValueOf;
+
export const LAYOUT_MODE = {
HORIZONTAL_SPLIT: "Horizontal split",
VERTICAL_SPLIT: "Vertical split",
@@ -42,6 +49,7 @@ export type LayoutSettings = {
export type FolderAndTagBehaviorSettings = {
showFolderHierarchyLines: boolean;
showFilesCount: boolean;
+ expandNodeOnClick: ExpandNodeOnClick;
openDestinationFolderAfterMove: boolean;
revealFileInExplorer: boolean;
};
@@ -96,6 +104,7 @@ export const LAYOUT_SETTINGS: LayoutSettings = {
export const FOLDER_AND_TAG_BEHAVIOR_SETTINGS: FolderAndTagBehaviorSettings = {
showFolderHierarchyLines: false,
showFilesCount: true,
+ expandNodeOnClick: EXPAND_NODE_ON_CLICK.SELECTED_LABEL,
openDestinationFolderAfterMove: false,
revealFileInExplorer: false,
};
@@ -144,3 +153,21 @@ export const DEFAULT_SETTINGS: FolderFileSplitterPluginSettings = {
...FILE_DISPLAY_SETTINGS,
...FOLDER_NOTE_SETTINGS,
};
+
+// legacy constant and type
+const EXPAND_FOLDER_BY_CLICKING_ELEMENT = {
+ ICON: "icon",
+ FOLDER: "folder",
+} as const;
+export type ExpandFolderByClickingOnElement = ValueOf<
+ typeof EXPAND_FOLDER_BY_CLICKING_ELEMENT
+>;
+
+export type LegacySettings = {
+ expandFolderByClickingOn: ExpandFolderByClickingOnElement;
+};
+export const LEGACY_SETTINGS = {
+ expandFolderByClickingOn: EXPAND_FOLDER_BY_CLICKING_ELEMENT.FOLDER,
+};
+
+export type AllSettings = FolderFileSplitterPluginSettings & LegacySettings;
diff --git a/src/store/folder/actions.ts b/src/store/folder/actions.ts
index 52886df..aa65367 100644
--- a/src/store/folder/actions.ts
+++ b/src/store/folder/actions.ts
@@ -16,6 +16,7 @@ export interface FolderActionsSlice {
createNewFolder: (parentFolder: TFolder) => Promise;
createNewFolderAndFocus: (parentFolder: TFolder) => Promise;
+ createNewFileAndFocus: (parentFolder: TFolder) => Promise;
moveFolder: (folder: TFolder, newPath: string) => Promise;
renameFolder: (folder: TFolder, newName: string) => Promise;
@@ -76,6 +77,11 @@ export const createFolderActionsSlice =
await changeFocusedFolder(newFolder);
}
},
+ createNewFileAndFocus: async (parentFolder: TFolder) => {
+ const { createFileWithDefaultName, changeFocusedFolder } = get();
+ await createFileWithDefaultName(parentFolder);
+ await changeFocusedFolder(parentFolder);
+ },
trashFolder: async (folder: TFolder) => {
const { focusedFolder, isAnscestorOf, setFocusedFolderAndSave } =
get();
diff --git a/src/store/tag/toggle.ts b/src/store/tag/toggle.ts
index 9dd533f..6586ea1 100644
--- a/src/store/tag/toggle.ts
+++ b/src/store/tag/toggle.ts
@@ -19,6 +19,7 @@ export interface ToggleTagSlice {
expandTag: (tag: TagNode) => void;
expandAllTags: () => void;
collapseTag: (tag: TagNode) => void;
+ toggleTag: (tag: TagNode) => void;
collapseAllTags: () => void;
restoreExpandedTagPaths: () => void;
@@ -72,6 +73,14 @@ export const createToggleTagSlice =
removeItemFromArray(expandedTagPaths, tag.fullPath)
);
},
+ toggleTag: (tag: TagNode) => {
+ const { isTagExpanded, expandTag, collapseTag } = get();
+ if (isTagExpanded(tag)) {
+ collapseTag(tag);
+ } else {
+ expandTag(tag);
+ }
+ },
collapseAllTags: () => {
get().changeExpandedTagPaths([]);
},