Skip to content

Commit

Permalink
[feat] add permalinks on libfuncs
Browse files Browse the repository at this point in the history
  • Loading branch information
Rémy Baranx committed Feb 27, 2024
1 parent d26b37b commit 5f30243
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 17 deletions.
12 changes: 0 additions & 12 deletions components/LibFuncTable/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ const Filters = ({ onSetFilter }: Props) => {
setSearchFilter(option)
}

const handleAltK = (event: KeyboardEvent) => {
if (event.altKey && event.key.toLowerCase() === 'k') {
inputRef.current?.focus()
inputRef.current?.value && inputRef.current.select()
}
}

// Change filter and search opcode according to query param
useEffect(() => {
const query = router.query
Expand All @@ -61,10 +54,6 @@ const Filters = ({ onSetFilter }: Props) => {
router.push(router)
}

// Register and clean up Alt+K event listener
window.addEventListener('keydown', handleAltK)
return () => window.removeEventListener('keydown', handleAltK)

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady])

Expand All @@ -88,7 +77,6 @@ const Filters = ({ onSetFilter }: Props) => {

<Input
ref={inputRef}
searchable
value={searchKeyword}
onChange={(e) => {
setSearchKeyword(e.target.value)
Expand Down
107 changes: 102 additions & 5 deletions components/LibFuncTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { useMemo, Fragment } from 'react'
import { useMemo, Fragment, useRef, useState, useEffect } from 'react'

import { RiArrowUpSLine, RiArrowDownSLine } from '@remixicon/react'
import {
RiCheckLine,
RiLinksLine,
RiArrowUpSLine,
RiArrowDownSLine,
} from '@remixicon/react'
import cn from 'classnames'
import { useRouter } from 'next/router'
import {
useTable,
useExpanded,
useFilters,
Row,
Cell,
UseExpandedRowProps,
} from 'react-table'
import { ILibFuncDocs, ILibFuncDoc } from 'types'
Expand All @@ -18,6 +25,8 @@ import DocRowDetail from './DocRowDetail'
import Filters from './Filters'

const LibFuncTable = ({ docs }: { docs: ILibFuncDocs }) => {
const router = useRouter()

const data = useMemo(() => docs, [docs])
const columns = useMemo(() => columnDefinition, [])

Expand All @@ -39,6 +48,55 @@ const LibFuncTable = ({ docs }: { docs: ILibFuncDocs }) => {
setFilter,
} = table

const rowRefs = useRef<HTMLTableRowElement[]>([])
const [focusedLibFuncIndex, setFocusedLibFuncIndex] = useState<
number | null
>()

const [clickedPermalinks, setClickedPermalinks] = useState<{
[key: string]: boolean
}>(docs.reduce((state, current) => ({ ...state, [current.name]: false }), {}))

const handlePermalink = (libFuncName: string) => {
const pageUrl = `${window.location.origin}${window.location.pathname}`
const permalink = `${pageUrl}#${libFuncName}`

navigator.clipboard.writeText(permalink)

// make the permalinks temporary "clicked" to show a specific icon/message
setClickedPermalinks((previous) => ({
...previous,
[libFuncName]: true,
}))
setTimeout(
() =>
setClickedPermalinks((previous) => ({
...previous,
[libFuncName]: false,
})),
1000,
)
}

// Focus and expand anchored reference
useEffect(() => {
if (docs && rowRefs?.current) {
const libFuncIndex = docs.findIndex((item) => {
const re = new RegExp(`#${item.name}`, 'gi')
return router.asPath.match(re)
})

if (libFuncIndex >= 0) {
setFocusedLibFuncIndex(libFuncIndex)
setTimeout(() => {
if (rowRefs.current[libFuncIndex]) {
rowRefs.current[libFuncIndex].scrollIntoView({ behavior: 'smooth' })
}
}, 300)
}
}
}, [docs, router.asPath])

const renderExpandButton = () => {
return (
<div className="hidden md:block">
Expand Down Expand Up @@ -98,6 +156,35 @@ const LibFuncTable = ({ docs }: { docs: ILibFuncDocs }) => {
</thead>
)
}

const renderPermalinkCell = (
listFuncName: string,
cell: Cell<ILibFuncDoc>,
) => {
return (
<div className="flex flex-row items-center gap-x-2">
{clickedPermalinks[listFuncName] ? (
<>
<RiCheckLine className="text-green-500" size="16" />
<span> copied !</span>
</>
) : (
<>
<RiLinksLine
className="text-indigo-500"
size="16"
onClick={(e) => {
handlePermalink(listFuncName)
e.stopPropagation()
}}
/>
{cell.render('Cell')}
</>
)}
</div>
)
}

const renderBody = () => {
return (
<tbody {...getTableBodyProps()} className="text-sm">
Expand All @@ -106,12 +193,20 @@ const LibFuncTable = ({ docs }: { docs: ILibFuncDocs }) => {

const expandedRow = row as Row<ILibFuncDoc> &
UseExpandedRowProps<ILibFuncDoc>
const rowId = parseInt(row.id)
const rowObject = row.original
const isExpanded = expandedRow.isExpanded
const isExpanded =
expandedRow.isExpanded || focusedLibFuncIndex === rowId

return (
<Fragment key={row.getRowProps().key}>
<tr
id={`rowObject.name`}
ref={(el) => {
if (el) {
rowRefs.current[row.index] = el
}
}}
className={cn('border-t cursor-pointer', {
'border-gray-200 dark:border-black-500 hover:bg-gray-100 dark:hover:bg-black-600':
!isExpanded,
Expand All @@ -122,14 +217,16 @@ const LibFuncTable = ({ docs }: { docs: ILibFuncDocs }) => {
onClick={() => row.toggleRowExpanded()}
style={{ scrollMarginTop: '96px' }}
>
{row.cells.map((cell) => (
{row.cells.map((cell, cellIndex) => (
<td
key={cell.getCellProps().key}
// FIXME: See: https://github.com/tannerlinsley/react-table/issues/3064
// @ts-ignore: Waiting for 8.x of react-table to have better types
className="py-2 pr-6"
>
{cell.render('Cell')}
{cellIndex === 0
? renderPermalinkCell(rowObject.name, cell)
: cell.render('Cell')}
</td>
))}
</tr>
Expand Down

0 comments on commit 5f30243

Please sign in to comment.