mirror of
https://github.com/linsa-io/linsa.git
synced 2026-04-23 16:58:38 +02:00
fix(page): Add item scroll, fix display issues, refactor nav, and improve perf (#166)
* feat: add item scroll to active * fix: reset enterkey and scroll to view * fix: link item displayName * refactor: remove keyboard page nav * chore: fix scrolling, perf, keys, highlight active item etc * chore: use new hook for create a page * chore: disabled auto delete page
This commit is contained in:
@@ -1,69 +0,0 @@
|
||||
import React, { useEffect, useRef, useCallback } from "react"
|
||||
import { PersonalPage, PersonalPageLists } from "@/lib/schema"
|
||||
|
||||
interface UseKeyboardNavigationProps {
|
||||
personalPages?: PersonalPageLists | null
|
||||
activeItemIndex: number | null
|
||||
setActiveItemIndex: React.Dispatch<React.SetStateAction<number | null>>
|
||||
isCommandPaletteOpen: boolean
|
||||
disableEnterKey: boolean
|
||||
onEnter?: (selectedPage: PersonalPage) => void
|
||||
}
|
||||
|
||||
export const useKeyboardNavigation = ({
|
||||
personalPages,
|
||||
activeItemIndex,
|
||||
setActiveItemIndex,
|
||||
isCommandPaletteOpen,
|
||||
disableEnterKey,
|
||||
onEnter
|
||||
}: UseKeyboardNavigationProps) => {
|
||||
const listRef = useRef<HTMLDivElement>(null)
|
||||
const itemRefs = useRef<(HTMLAnchorElement | null)[]>([])
|
||||
const itemCount = personalPages?.length || 0
|
||||
|
||||
const scrollIntoView = useCallback((index: number) => {
|
||||
if (itemRefs.current[index]) {
|
||||
itemRefs.current[index]?.scrollIntoView({
|
||||
block: "nearest"
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (activeItemIndex !== null) {
|
||||
scrollIntoView(activeItemIndex)
|
||||
}
|
||||
}, [activeItemIndex, scrollIntoView])
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
if (isCommandPaletteOpen) return
|
||||
|
||||
if (e.key === "ArrowUp" || e.key === "ArrowDown") {
|
||||
e.preventDefault()
|
||||
setActiveItemIndex(prevIndex => {
|
||||
if (prevIndex === null) return 0
|
||||
const newIndex = e.key === "ArrowUp" ? (prevIndex - 1 + itemCount) % itemCount : (prevIndex + 1) % itemCount
|
||||
return newIndex
|
||||
})
|
||||
} else if (e.key === "Enter" && !disableEnterKey && activeItemIndex !== null && personalPages) {
|
||||
e.preventDefault()
|
||||
const selectedPage = personalPages[activeItemIndex]
|
||||
if (selectedPage) onEnter?.(selectedPage)
|
||||
}
|
||||
},
|
||||
[itemCount, isCommandPaletteOpen, activeItemIndex, setActiveItemIndex, disableEnterKey, personalPages, onEnter]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", handleKeyDown)
|
||||
return () => window.removeEventListener("keydown", handleKeyDown)
|
||||
}, [handleKeyDown])
|
||||
|
||||
const setItemRef = useCallback((el: HTMLAnchorElement | null, index: number) => {
|
||||
itemRefs.current[index] = el
|
||||
}, [])
|
||||
|
||||
return { listRef, setItemRef }
|
||||
}
|
||||
@@ -4,6 +4,15 @@ import { LaAccount, PersonalPage } from "@/lib/schema"
|
||||
import { ID } from "jazz-tools"
|
||||
|
||||
export const usePageActions = () => {
|
||||
const newPage = useCallback((me: LaAccount): PersonalPage => {
|
||||
const newPersonalPage = PersonalPage.create(
|
||||
{ public: false, createdAt: new Date(), updatedAt: new Date() },
|
||||
{ owner: me._owner }
|
||||
)
|
||||
me.root?.personalPages?.push(newPersonalPage)
|
||||
return newPersonalPage
|
||||
}, [])
|
||||
|
||||
const deletePage = useCallback((me: LaAccount, pageId: ID<PersonalPage>): void => {
|
||||
if (!me.root?.personalPages) return
|
||||
|
||||
@@ -32,5 +41,5 @@ export const usePageActions = () => {
|
||||
}
|
||||
}, [])
|
||||
|
||||
return { deletePage }
|
||||
return { newPage, deletePage }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user