update: pinned panel 添加展开和收缩动画

This commit is contained in:
LittleBoy 2024-12-23 20:38:31 +08:00
parent ae132cb274
commit a5b8e9cd87
2 changed files with 59 additions and 24 deletions

View File

@ -1,13 +1,13 @@
import {Input} from "antd";
import {useBoolean, useLocalStorageState, useSetState} from "ahooks";
import {useMemo, useState} from "react";
import {useBoolean, useLocalStorageState, useSetState,useClickAway} from "ahooks";
import {useCallback, useMemo, useRef, useState} from "react";
import {clsx} from "clsx";
import useArticleTags from "@/hooks/useArticleTags.ts";
import {CloseOutlined, MenuOutlined, SearchOutlined} from "@ant-design/icons";
import {UpOutlined, MenuOutlined, SearchOutlined} from "@ant-design/icons";
import TimeSelect from "@/components/form/time-select.tsx";
import styles from './style.module.scss'
import {clsx} from "clsx";
import {IconPin} from "@/components/icons";
type SearchPanelProps = {
@ -23,7 +23,7 @@ const DEFAULT_STATE = {
}
export default function SearchPanel({onSearch}: SearchPanelProps) {
const tags = useArticleTags();
const [panelVisible, {setTrue, setFalse}] = useBoolean(false)
const [panelVisible, {set}] = useBoolean(false)
const [params, setParams] = useSetState<ApiArticleSearchParams>({
pagination,
time_flag:1
@ -89,6 +89,29 @@ export default function SearchPanel({onSearch}: SearchPanelProps) {
}
return [] as OptionItem[];
}, [pinnedTag, tags])
const pinnedManagePanel = useRef<HTMLDivElement|null>(null)
const togglePinnedManagePanel = useCallback((visible: boolean) => {
if(!pinnedManagePanel.current){
return;
}
const _target = pinnedManagePanel.current!;
if(visible){
_target.style.height = 'auto'
const {height} = _target.getBoundingClientRect()
_target.style.height = '38px'
requestAnimationFrame(()=>{
_target.style.height = `${height}px`
})
}else{
requestAnimationFrame(()=>{
_target.style.height = '0'
})
}
},[pinnedManagePanel])
const setTrue = ()=> togglePinnedManagePanel(true)
const setFalse = ()=>togglePinnedManagePanel(false)
useClickAway(() => setFalse(), pinnedManagePanel)
return (<div className={`${styles.searchPanel} pt-8 pb-2`}>
<div className="flex justify-between items-center">
@ -109,18 +132,17 @@ export default function SearchPanel({onSearch}: SearchPanelProps) {
/>
</div>
</div>
<div className="filter-container mt-5 h-[40px]">
<div className="filter-container mt-5">
<div className="list-container relative">
<div className="justify-between flex items-center border-b pb-2 overflow-hidden">
<div
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == -1 ? 'selected' : ''}`}
onClick={() => {
handleFilter({tag_level_1_id: -1, tag_level_2_id: -1})
setSubOptions([])
}}>
</div>
<div className="pinned-tag-list flex flex-wrap overflow-hidden flex-1 min-w-0 h-[32px]">
<div className="justify-between flex items-start border-b pb-2 overflow-hidden">
<div className="pinned-tag-list flex flex-wrap flex-1 min-w-0">
<div
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == -1 ? 'selected' : ''}`}
onClick={() => {
handleFilter({tag_level_1_id: -1, tag_level_2_id: -1})
setSubOptions([])
}}>
</div>
{pinnedList.filter(s => (Number(s.value) !== 999999)).map(it => (
<span
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == it.value ? 'selected' : ''}`}
@ -131,18 +153,25 @@ export default function SearchPanel({onSearch}: SearchPanelProps) {
}}>{it.label}</span>)
)}
</div>
<div className="pinned-menu ">
<span className={'cursor-pointer block hover:text-blue-500'} onClick={setTrue}>
<div className="pinned-menu mt-2">
<span className={'cursor-pointer block hover:text-blue-500'} onClick={e=>{
e.stopPropagation();
e.preventDefault();
setTrue();
}}>
<MenuOutlined style={{fontSize: 20}}/>
</span>
</div>
</div>
<div ref={pinnedManagePanel} className={clsx(styles.pinnedManagePanelContainer)}>
{/* 固定新闻来源 */}
<div className={clsx(styles.pinnedManagePanel, panelVisible ? 'block' : 'hidden')}>
<div className={clsx(styles.pinnedManagePanel)}>
<div className="header flex justify-between">
<div className="title font-bold"></div>
<span className={'cursor-pointer block hover:text-blue-500'} onClick={setFalse}><CloseOutlined
style={{fontSize: 20}}/></span>
<div className={'cursor-pointer block hover:text-blue-500'} onClick={setFalse}>
<UpOutlined style={{fontSize: 20}}/>
</div>
</div>
<div className="tags-list-container">
{
@ -166,6 +195,7 @@ export default function SearchPanel({onSearch}: SearchPanelProps) {
}
</div>
</div>
</div>
{/* 二级目录 */}
{state.tag_level_1_id != -1 && subOptions.length > 0 &&
<div

View File

@ -14,10 +14,15 @@
}
}
}
.pinnedManagePanel {
@apply absolute bg-white top-0 px-4 pt-2 pb-4 rounded shadow-md z-10;
.pinnedManagePanelContainer {
@apply absolute bg-white top-0 rounded shadow-md z-10;
height: 0;
overflow: hidden;
transition: height 0.2s ease-in-out;
inset-inline: -20px;
}
.pinnedManagePanel {
@apply px-4 pt-2 pb-4 grid;
:global {
.btn-panel {