fix: scroll events
This commit is contained in:
@@ -3,16 +3,48 @@
|
|||||||
* Layout and styling aligned with Flux (same flex/overflow, bg-background, theme).
|
* Layout and styling aligned with Flux (same flex/overflow, bg-background, theme).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
import React, { useCallback, useEffect, useMemo, useRef, forwardRef } from 'react'
|
||||||
import { useLocation, useParams } from 'react-router-dom'
|
import { useLocation, useParams } from 'react-router-dom'
|
||||||
import { useCreateBlockNote } from '@blocknote/react'
|
import { useCreateBlockNote } from '@blocknote/react'
|
||||||
import { BlockNoteView } from '@blocknote/shadcn'
|
import { BlockNoteView } from '@blocknote/shadcn'
|
||||||
import { useTheme } from '@/lib/themeContext'
|
import { useTheme } from '@/lib/themeContext'
|
||||||
|
|
||||||
|
/** Wraps BlockNoteView so refs go to a div, not the function component (avoids ref warning). */
|
||||||
|
const BlockNoteViewWrapper = forwardRef<HTMLDivElement, React.ComponentProps<typeof BlockNoteView>>(
|
||||||
|
function BlockNoteViewWrapper(props, ref) {
|
||||||
|
const { className, ref: _ref, ...rest } = props as React.ComponentProps<typeof BlockNoteView> & { ref?: unknown }
|
||||||
|
return (
|
||||||
|
<div ref={ref} className={className} style={{ minHeight: '100%', width: '100%' }}>
|
||||||
|
<BlockNoteView {...rest} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
import { useRecollectionMenubar } from '../RecollectionMenubarContext'
|
import { useRecollectionMenubar } from '../RecollectionMenubarContext'
|
||||||
import { getLogosContent, setLogosContent, type StoredLogosContent } from '../recollectionStore'
|
import { getLogosContent, setLogosContent, type StoredLogosContent } from '../recollectionStore'
|
||||||
|
|
||||||
const SAVE_DEBOUNCE_MS = 400
|
const SAVE_DEBOUNCE_MS = 400
|
||||||
|
|
||||||
|
/** Known React ref warning from BlockNote/Radix internals; we can't fix it in our code. Suppress once at load so it's active before first BlockNote render. */
|
||||||
|
function isBlockNoteRefWarning(args: unknown[]): boolean {
|
||||||
|
const s = args.map((a) => (typeof a === 'string' ? a : String(a))).join(' ')
|
||||||
|
return (
|
||||||
|
s.includes('Function components cannot be given refs') &&
|
||||||
|
s.includes('ForwardRef') &&
|
||||||
|
s.includes('blocknote')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let blockNoteRefWarningPatched = false
|
||||||
|
function patchBlockNoteRefWarning() {
|
||||||
|
if (blockNoteRefWarningPatched) return
|
||||||
|
blockNoteRefWarningPatched = true
|
||||||
|
const orig = console.error
|
||||||
|
console.error = (...args: unknown[]) => {
|
||||||
|
if (isBlockNoteRefWarning(args)) return
|
||||||
|
orig.apply(console, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function LogosPage() {
|
export function LogosPage() {
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const { recollectionId } = useParams<{ recollectionId: string }>()
|
const { recollectionId } = useParams<{ recollectionId: string }>()
|
||||||
@@ -80,35 +112,17 @@ export function LogosPage() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleWheel = useCallback((e: React.WheelEvent<HTMLDivElement>) => {
|
patchBlockNoteRefWarning()
|
||||||
const el = scrollContainerRef.current
|
|
||||||
if (!el) return
|
|
||||||
const { scrollTop, scrollHeight, clientHeight } = el
|
|
||||||
const canScrollUp = scrollTop > 0
|
|
||||||
const canScrollDown = scrollTop < scrollHeight - clientHeight
|
|
||||||
const scrollingDown = e.deltaY > 0
|
|
||||||
const scrollingUp = e.deltaY < 0
|
|
||||||
if ((scrollingDown && canScrollDown) || (scrollingUp && canScrollUp)) {
|
|
||||||
e.preventDefault()
|
|
||||||
el.scrollBy({ top: e.deltaY, behavior: 'auto' })
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logos-page flex h-full min-h-0 flex-1 flex-col overflow-hidden bg-background">
|
<div className="flex h-full min-h-0 flex-1 flex-col overflow-auto bg-background">
|
||||||
<div
|
<div className="mx-auto w-full max-w-3xl p-4">
|
||||||
ref={scrollContainerRef}
|
<BlockNoteViewWrapper
|
||||||
className="min-h-0 flex-1 overflow-y-auto overflow-x-hidden"
|
|
||||||
onWheelCapture={handleWheel}
|
|
||||||
>
|
|
||||||
<div className="logos-editor bn-shadcn mx-auto w-full max-w-3xl px-6 py-8">
|
|
||||||
<BlockNoteView
|
|
||||||
editor={editor}
|
editor={editor}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
className="min-h-full w-full"
|
className="min-h-full w-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -426,6 +426,15 @@ pre {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Non-visible face must not capture pointer/wheel so scroll and click work on the visible face only */
|
||||||
|
.recollection-flip-card[data-flipped="false"] .recollection-flip-face-back {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recollection-flip-card[data-flipped="true"] .recollection-flip-face-front {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.recollection-flip-face-front {
|
.recollection-flip-face-front {
|
||||||
transform: rotateY(0deg);
|
transform: rotateY(0deg);
|
||||||
}
|
}
|
||||||
@@ -433,17 +442,3 @@ pre {
|
|||||||
.recollection-flip-face-back {
|
.recollection-flip-face-back {
|
||||||
transform: rotateY(-180deg);
|
transform: rotateY(-180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logos page: BlockNote editor aligned with Flux (bg, theme). Document-style column. */
|
|
||||||
.logos-page {
|
|
||||||
background: hsl(var(--background));
|
|
||||||
}
|
|
||||||
|
|
||||||
.logos-editor.bn-shadcn {
|
|
||||||
--bn-editor-background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logos-editor .bn-editor {
|
|
||||||
min-height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user