Skip to content

Commit

Permalink
feat(search): mark keywords highlight
Browse files Browse the repository at this point in the history
  • Loading branch information
xhofe committed Aug 6, 2023
1 parent f4c35dd commit 7d8a036
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 10 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"license": "MIT",
"devDependencies": {
"@crowdin/cli": "^3.7.10",
"@types/mark.js": "^8.11.8",
"@types/node": "^18.7.5",
"@types/streamsaver": "^2.0.1",
"@vitejs/plugin-legacy": "^2.0.1",
Expand Down Expand Up @@ -63,6 +64,7 @@
"flv.js": "^1.6.2",
"hls.js": "^1.2.1",
"lightgallery": "^2.5.0",
"mark.js": "^8.11.1",
"mitt": "^3.0.0",
"rehype-katex": "^6.0.3",
"rehype-raw": "^6.1.1",
Expand Down
26 changes: 26 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 98 additions & 10 deletions src/pages/home/folder/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,19 @@ import {
ModalOverlay,
Text,
VStack,
hope,
} from "@hope-ui/solid"
import { BsSearch } from "solid-icons/bs"
import { createSignal, For, Match, onCleanup, Show, Switch } from "solid-js"
import {
createSignal,
For,
Match,
onCleanup,
onMount,
Show,
Switch,
} from "solid-js"
import Mark from "mark.js"
import {
FullLoading,
LinkWithBase,
Expand All @@ -36,7 +46,85 @@ import {
import { isMac } from "~/utils/compatibility"
import { getIconByObj } from "~/utils/icon"

const SearchResult = (props: SearchNode) => {
// class MarkKeywords {
// root
// rootHTML
// style

// /**
// * Keyword highlight
// * @param root Find root elements
// * @param style The default background is highly bright yellow
// */
// constructor(config: { root: Element | null; style?: string }) {
// if (!config.root) return
// this.root = config.root
// this.rootHTML = config.root.innerHTML
// this.style = config.style ?? "background-color: #FF0"
// }

// /** mark keyword */
// light(keyword: string) {
// const handler = (root: any) => {
// if (
// root.nodeName === "#text" &&
// root.parentNode.childNodes.length === 1
// ) {
// root.parentNode.innerHTML = root.parentNode.innerHTML.replace(
// new RegExp(keyword, "g"),
// `<span class="mark" style="${this.style}">${keyword}</span>`,
// )
// } else {
// for (const node of root.childNodes) {
// handler(node)
// }
// }
// }

// if (!this.root) return

// // reset HTML
// this.root.innerHTML = this.rootHTML!

// if (!keyword) return
// handler(this.root)
// }
// }

function NodeName(props: { keywords: string; name: string }) {
let ref: HTMLSpanElement
onMount(() => {
// const highlighter = new MarkKeywords({
// root: ref!,
// style: `background-color: var(--hope-colors-info5); border-radius: var(--hope-radii-md); margin: 0 1px; padding: 0 1px;`,
// })
// highlighter.light(props.keywords)
const mark = new Mark(ref!)
mark.mark(props.keywords, {
separateWordSearch: true,
diacritics: true,
})
})
return (
<hope.span
ref={ref!}
css={{
mark: {
bg: "$info4",
rounded: "$md",
px: "1px",
// mx: "1px",
color: "$info11",
fontWeight: "$bold",
},
}}
>
{props.name}
</hope.span>
)
}

const SearchResult = (props: { node: SearchNode; keywords: string }) => {
const { setPathAs } = usePath()
return (
<HStack
Expand All @@ -49,17 +137,17 @@ const SearchResult = (props: SearchNode) => {
cursor="pointer"
px="$2"
as={LinkWithBase}
href={props.path}
href={props.node.path}
encode
onMouseEnter={() => {
setPathAs(props.path, props.is_dir)
setPathAs(props.node.path, props.node.is_dir)
}}
>
<Icon
class="icon"
boxSize="$6"
color={getMainColor()}
as={getIconByObj(props)}
as={getIconByObj(props.node)}
mr="$1"
/>
<VStack flex={1} p="$1" spacing="$1" w="$full" alignItems="start">
Expand All @@ -68,10 +156,10 @@ const SearchResult = (props: SearchNode) => {
wordBreak: "break-all",
}}
>
{props.name}
<Show when={props.size > 0 || !props.is_dir}>
<NodeName keywords={props.keywords} name={props.node.name} />
<Show when={props.node.size > 0 || !props.node.is_dir}>
<Badge colorScheme="info" ml="$2">
{getFileSize(props.size)}
{getFileSize(props.node.size)}
</Badge>
</Show>
</Text>
Expand All @@ -82,7 +170,7 @@ const SearchResult = (props: SearchNode) => {
wordBreak: "break-all",
}}
>
{props.parent}
{props.node.parent}
</Text>
</VStack>
</HStack>
Expand Down Expand Up @@ -213,7 +301,7 @@ const Search = () => {
</Switch>
<VStack w="$full">
<For each={data().content}>
{(item) => <SearchResult {...item} />}
{(item) => <SearchResult node={item} keywords={keywords()} />}
</For>
</VStack>
<Show when={data().total > 0}>
Expand Down

0 comments on commit 7d8a036

Please sign in to comment.