mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
feat: pages (#151)
* wip * wip * wip * wwip * wip * wip * fix(util): rmeove checking to existing in slug * wip * chore: handle create page * chore: handle page title untitled
This commit is contained in:
16
web/components/routes/page/hooks/use-column-styles.ts
Normal file
16
web/components/routes/page/hooks/use-column-styles.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { useMedia } from "react-use"
|
||||
|
||||
export const useColumnStyles = () => {
|
||||
const isTablet = useMedia("(max-width: 640px)")
|
||||
|
||||
return {
|
||||
title: {
|
||||
"--width": "69px",
|
||||
"--min-width": "200px",
|
||||
"--max-width": isTablet ? "none" : "auto"
|
||||
},
|
||||
content: { "--width": "auto", "--min-width": "200px", "--max-width": "200px" },
|
||||
topic: { "--width": "65px", "--min-width": "120px", "--max-width": "120px" },
|
||||
updated: { "--width": "82px", "--min-width": "82px", "--max-width": "82px" }
|
||||
}
|
||||
}
|
||||
69
web/components/routes/page/hooks/use-keyboard-navigation.ts
Normal file
69
web/components/routes/page/hooks/use-keyboard-navigation.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
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 }
|
||||
}
|
||||
Reference in New Issue
Block a user