Skip to content

Commit 2723267

Browse files
authored
feat: add search component on sidebar (#405)
1 parent 361486c commit 2723267

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

.dumi/theme/slots/Sidebar/index.scss

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
@import "../../style/const.scss";
22

3+
@media only screen and (max-width: 767px) {
4+
.dt-theme-filter {
5+
display: none;
6+
}
7+
}
8+
39
@media only screen and (min-width: 767px) {
10+
.dt-theme-filter {
11+
width: calc(100% - 24px);
12+
margin: 0 12px;
13+
height: 40px;
14+
padding: 16px;
15+
color: #30363F;
16+
font-size: 14px;
17+
border: 1px solid #D0D5D8;
18+
border-radius: 20px;
19+
outline: none;
20+
transition: all 0.3s;
21+
background-color: transparent;
22+
}
423
.dumi-default-sidebar {
524
height: 100vh;
625
max-height: calc(100vh - 64px);

.dumi/theme/slots/Sidebar/index.tsx

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,64 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { Tooltip } from 'antd';
33
import { NavLink, useSidebarData } from 'dumi';
44

55
import { useMobile } from '../../hooks';
66
import 'dumi/theme-default/slots/Sidebar/index.less';
77
import './index.scss';
88

9+
function filterSideBar(arr: ReturnType<typeof useSidebarData>, search: string) {
10+
if (!search) return arr;
11+
return arr
12+
.map((item) => {
13+
const children = item.children.filter((child) =>
14+
child.title.toLocaleLowerCase().includes(search.toLocaleLowerCase())
15+
);
16+
return { ...item, children };
17+
})
18+
.filter((i) => i.children.length);
19+
}
20+
921
export default function Sidebar() {
1022
const sidebar = useSidebarData();
1123
const isMobile = useMobile();
24+
const [search, setSearch] = useState('');
25+
26+
const isRenderSearch = sidebar.some((s) => s.title === '组件');
1227

1328
if (!sidebar) return null;
1429

1530
return (
1631
<div className="dumi-default-sidebar">
17-
{sidebar.map((item, i) => (
32+
{isRenderSearch && (
33+
<input
34+
className="dt-theme-filter"
35+
placeholder="搜索组件..."
36+
value={search}
37+
onChange={(e) => setSearch(e.target.value)}
38+
onKeyDown={(e) => {
39+
if (e.key === 'Enter') {
40+
const firstLink = document.querySelector(
41+
'.dumi-default-sidebar-group dd a'
42+
);
43+
if (firstLink) {
44+
(firstLink as HTMLAnchorElement).click();
45+
}
46+
}
47+
}}
48+
/>
49+
)}
50+
{filterSideBar(sidebar, isRenderSearch ? search : '').map((item, i) => (
1851
<dl className="dumi-default-sidebar-group" key={String(i)}>
1952
{item.title && <dt>{item.title}</dt>}
2053
{item.children.map((child) => {
2154
const link = (
2255
<dd key={child.link}>
23-
<NavLink to={child.link} title={child.title} end>
56+
<NavLink
57+
to={child.link}
58+
title={child.title}
59+
end
60+
onClick={() => setSearch('')}
61+
>
2462
{child.title}
2563
</NavLink>
2664
</dd>

0 commit comments

Comments
 (0)