Files
Momento/memento-note/lib/use-scroll-to-block.ts
Antigravity 261eee2953
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 6m6s
CI / Deploy production (on server) (push) Successful in 26s
refactor: factorisation peek panel — NotePeekPanel réutilisable
Architecture:
- components/note-peek/use-note-peek.ts: hook (fetch + state + events)
- components/note-peek/note-peek-content.tsx: rendu markdown/richtext/KaTeX
- components/note-peek/note-peek-panel.tsx: panel (overlay + inline modes)
- components/note-peek/index.ts: exports
- lib/use-scroll-to-block.ts: utilitaire scroll vers data-id

insights/page.tsx:
- ~95 lignes (state + fetch + KaTeX useEffect + AnimatePresence) → 10 lignes
- peek.open(noteId) remplace handleNoteClick complexe
- <NotePeekPanel mode=overlay /> remplace tout le JSX du panel

NotePeekPanel gère:
- markdown (MarkdownContent) + richtext (DOMPurify + KaTeX lazy)
- RTL (slide gauche pour fa/ar)
- prefers-reduced-motion
- role=dialog + aria-modal (overlay mode)
- loading spinner
- bouton Maximize2 + X
- renderContent prop pour custom (éditeur read-only)
2026-07-04 23:37:37 +00:00

20 lines
707 B
TypeScript

import { useEffect, useRef } from 'react'
export function useScrollToBlock(
scrollRef: React.RefObject<HTMLElement | null>,
blockId: string | undefined,
deps: React.DependencyList,
delay = 450,
) {
useEffect(() => {
if (!blockId || !scrollRef.current) return
const timer = window.setTimeout(() => {
const escaped = typeof CSS !== 'undefined' && CSS.escape ? CSS.escape(blockId) : blockId
const el = scrollRef.current?.querySelector(`[data-id="${escaped}"]`)
el?.scrollIntoView({ behavior: 'smooth', block: 'center' })
}, delay)
return () => window.clearTimeout(timer)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [blockId, delay, ...deps])
}