From e02e61ae01a528aed57c91292fd7d6a44413fb94 Mon Sep 17 00:00:00 2001 From: lucaronin Date: Mon, 23 Feb 2026 21:55:57 +0100 Subject: [PATCH] refactor: extract wikilink utils to src/utils/wikilink.ts, fix NoteList useMemo deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move wikilinkTarget/wikilinkDisplay from InspectorPanels.tsx to src/utils/wikilink.ts (fixes react-refresh/only-export-components lint error — non-component exports must live in utility files, not component files) - Remove unused modifiedFiles from useNoteListData deps array and interface (fixes react-hooks/exhaustive-deps warning — was in dep array but not used) --- src/components/Inspector.tsx | 3 ++- src/components/InspectorPanels.tsx | 15 +-------------- src/components/NoteList.tsx | 6 +++--- src/utils/wikilink.ts | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 src/utils/wikilink.ts diff --git a/src/components/Inspector.tsx b/src/components/Inspector.tsx index f344a515..a1b5d942 100644 --- a/src/components/Inspector.tsx +++ b/src/components/Inspector.tsx @@ -4,7 +4,8 @@ import { cn } from '@/lib/utils' import { SlidersHorizontal, X } from '@phosphor-icons/react' import { parseFrontmatter } from '../utils/frontmatter' import { DynamicPropertiesPanel } from './DynamicPropertiesPanel' -import { DynamicRelationshipsPanel, BacklinksPanel, ReferencedByPanel, GitHistoryPanel, wikilinkTarget } from './InspectorPanels' +import { DynamicRelationshipsPanel, BacklinksPanel, ReferencedByPanel, GitHistoryPanel } from './InspectorPanels' +import { wikilinkTarget } from '../utils/wikilink' import type { ReferencedByItem } from './InspectorPanels' export type FrontmatterValue = string | number | boolean | string[] | null diff --git a/src/components/InspectorPanels.tsx b/src/components/InspectorPanels.tsx index 12d8be91..e32b9a44 100644 --- a/src/components/InspectorPanels.tsx +++ b/src/components/InspectorPanels.tsx @@ -1,5 +1,6 @@ import { useMemo, useCallback, useState, useRef } from 'react' import type { ComponentType, SVGAttributes } from 'react' +import { wikilinkTarget, wikilinkDisplay } from '../utils/wikilink' import type { VaultEntry, GitCommit } from '../types' import { Wrench, Flask, Target, ArrowsClockwise, @@ -24,20 +25,6 @@ function isWikilink(value: string): boolean { return /^\[\[.*\]\]$/.test(value) } -function wikilinkDisplay(ref: string): string { - const inner = ref.replace(/^\[\[|\]\]$/g, '') - const pipeIdx = inner.indexOf('|') - if (pipeIdx !== -1) return inner.slice(pipeIdx + 1) - const last = inner.split('/').pop() ?? inner - return last.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()) -} - -export function wikilinkTarget(ref: string): string { - const inner = ref.replace(/^\[\[|\]\]$/g, '') - const pipeIdx = inner.indexOf('|') - return pipeIdx !== -1 ? inner.slice(0, pipeIdx) : inner -} - function resolveRef(ref: string, entries: VaultEntry[]): VaultEntry | undefined { const target = wikilinkTarget(ref) return entries.find((e) => { diff --git a/src/components/NoteList.tsx b/src/components/NoteList.tsx index c3ccc55e..4ed2c785 100644 --- a/src/components/NoteList.tsx +++ b/src/components/NoteList.tsx @@ -182,10 +182,10 @@ function routeNoteClick( interface NoteListDataParams { entries: VaultEntry[]; selection: SidebarSelection; allContent: Record - query: string; listSort: SortOption; listDirection: SortDirection; modifiedFiles?: ModifiedFile[] + query: string; listSort: SortOption; listDirection: SortDirection } -function useNoteListData({ entries, selection, allContent, query, listSort, listDirection, modifiedFiles }: NoteListDataParams) { +function useNoteListData({ entries, selection, allContent, query, listSort, listDirection }: NoteListDataParams) { const isEntityView = selection.kind === 'entity' const isTrashView = selection.kind === 'filter' && selection.filter === 'trash' @@ -198,7 +198,7 @@ function useNoteListData({ entries, selection, allContent, query, listSort, list if (isEntityView) return [] const sorted = [...filterEntries(entries, selection)].sort(getSortComparator(listSort, listDirection)) return filterByQuery(sorted, query) - }, [entries, selection, modifiedFiles, isEntityView, listSort, listDirection, query]) + }, [entries, selection, isEntityView, listSort, listDirection, query]) const searchedGroups = useMemo(() => { if (!isEntityView) return [] diff --git a/src/utils/wikilink.ts b/src/utils/wikilink.ts new file mode 100644 index 00000000..2a499ed7 --- /dev/null +++ b/src/utils/wikilink.ts @@ -0,0 +1,17 @@ +/** Utility functions for parsing wikilink syntax: [[target|display]] */ + +/** Extracts the target path from a wikilink reference (strips [[ ]] and display text). */ +export function wikilinkTarget(ref: string): string { + const inner = ref.replace(/^\[\[|\]\]$/g, '') + const pipeIdx = inner.indexOf('|') + return pipeIdx !== -1 ? inner.slice(0, pipeIdx) : inner +} + +/** Extracts the display label from a wikilink reference. Falls back to humanised path stem. */ +export function wikilinkDisplay(ref: string): string { + const inner = ref.replace(/^\[\[|\]\]$/g, '') + const pipeIdx = inner.indexOf('|') + if (pipeIdx !== -1) return inner.slice(pipeIdx + 1) + const last = inner.split('/').pop() ?? inner + return last.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()) +}