Skip to content

Commit

Permalink
💄 style(custom): 添加手机端普通搜索样式
Browse files Browse the repository at this point in the history
  • Loading branch information
master1lan committed Feb 27, 2023
1 parent bcf0987 commit 2a84717
Show file tree
Hide file tree
Showing 12 changed files with 311 additions and 23 deletions.
18 changes: 18 additions & 0 deletions src/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
@tailwind components;
@tailwind utilities;


@layer utilities {

/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}

/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
}


* {
box-sizing: border-box;
padding: 0;
Expand Down
2 changes: 0 additions & 2 deletions src/routers/layout/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { changeLoadingCauseByUrl } from "@store/loading";
import { routerNameToLoading } from "@utils/router";
import { styled } from "@mui/material";
import Search from "./search";
import RouterNav from "./routernav/index";
export default function Header() {
const dispatch = useAppDispatch(),
location = useLocation();
Expand All @@ -26,7 +25,6 @@ const ReactiveHeader = memo(() => {
<header className='border-t-2 relative z-10 max-md:border-b-2'>
{/* 手机端 */}
<div className='hidden max-sm:flex px-6 pt-2'>
<RouterNav />
<Search />
</div>
{/* pc端和平板端header部 */}
Expand Down
4 changes: 2 additions & 2 deletions src/routers/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export default function Layout() {
<Header />
<NavContent />
<Flipped flipId={"container"} spring={"veryGentle"}>
{/* <main className='feedContainer'>
<main className='feedContainer'>
<Outlet />
</main> */}
</main>
</Flipped>
</Flipper>
</>
Expand Down
5 changes: 4 additions & 1 deletion src/routers/layout/search/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Form, useLocation, useNavigate } from "react-router-dom";
import PCSearch from "./pc";
import PhoneSearch from "./phone";
// todo 增加高级搜索以及手机端的搜索
export default function Search() {
const navigate = useNavigate();
Expand All @@ -12,7 +13,9 @@ export default function Search() {
<div className='visible max-sm:hidden'>
<PCSearch />
</div>
<div className='hidden max-sm:block'></div>
<div className='hidden max-sm:block flex-grow'>
<PhoneSearch />
</div>
</>
);
}
14 changes: 14 additions & 0 deletions src/routers/layout/search/pc/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
selectSearchMode,
} from "@store/device";
import { useAppDispatch, useAppSelector } from "@store/hooks";
import { useRef, useImperativeHandle } from "react";

export const useSearchMode = () => {
const searchMode = useAppSelector(selectSearchMode);
Expand All @@ -12,3 +13,16 @@ export const useSearchMode = () => {
dispatch(changeSearchMode(name));
return { searchMode, handlerChangeSearchMode };
};
export const useBackRef = (ref: React.Ref<HTMLInputElement>) => {
const inputRef = useRef<HTMLInputElement>(null),
handerfocus = () => inputRef.current?.focus();
//@ts-ignore
useImperativeHandle(ref, () => {
return {
getValue() {
return inputRef.current?.value;
},
};
});
return { inputRef, handerfocus };
};
1 change: 0 additions & 1 deletion src/routers/layout/search/pc/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useRef } from "react";
import { useSearchFocus } from "@components/proview/searchFocus";
import styles from "../search.module.less";
import { FC, useEffect } from "react";
import SelectModeCom from "./selectModeNav";
import Search from "./search";
Expand Down
18 changes: 2 additions & 16 deletions src/routers/layout/search/pc/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { useURLParams } from "@utils/hooks/url";
import SearchIcon from "@mui/icons-material/Search";
import styles from "../search.module.less";
import pcStyles from "./pc.module.less";
import { useSearchMode } from "./hooks";
import { useBackRef, useSearchMode } from "./hooks";
import { useNavigate } from "react-router-dom";
import { FC, forwardRef, useImperativeHandle, useRef } from "react";
import { FC, forwardRef, useRef } from "react";
export default function Search() {
const [tag] = useURLParams(["tag"]);
const searchId = `pcSearch`;
Expand Down Expand Up @@ -115,20 +115,6 @@ type AdvanceItemProps = {
onSubmit: () => void;
};

const useBackRef = (ref: React.Ref<HTMLInputElement>) => {
const inputRef = useRef<HTMLInputElement>(null),
handerfocus = () => inputRef.current?.focus();
//@ts-ignore
useImperativeHandle(ref, () => {
return {
getValue() {
return inputRef.current?.value;
},
};
});
return { inputRef, handerfocus };
};

const AdvanceSearchItem = forwardRef<HTMLInputElement, AdvanceItemProps>(
(props, ref) => {
const { inputRef, handerfocus } = useBackRef(ref);
Expand Down
33 changes: 33 additions & 0 deletions src/routers/layout/search/phone/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
import RouterNav from "@routers/layout/routernav";
import SearchIcon from "@mui/icons-material/Search";
import PhotoModalSearch from "./modal";
import { useState } from "react";
export default function PhoneSearch() {
// 这个只作为因子引出真实的界面,不应该承担任何搜索功能
const [open, setModal] = useState<boolean>(false);
const SearchProps = {
open,
onClose: () => {
setTimeout(() => {
setModal(false);
}, 150);
},
};
return (
<div
className='flex w-full justify-between border-2 rounded-full items-center px-2 h-14 mb-2'
style={{ boxShadow: "0 3px 10px rgb(0 0 0 / 10%)" }}
>
{/* 点击这里向下拉取搜索栏 */}
<PhotoModalSearch {...SearchProps} />
<div
className='flex-grow flex items-center text-gray-600'
onClick={setModal.bind(null, true)}
>
<SearchIcon className='basis-14' color='inherit' />
<div className='flex flex-col'>
<span className='text-sm font-semibold text-black'>想看什么</span>
<span className='text-xs text-gray-700'>点击这里·马上看到</span>
</div>
</div>
<RouterNav />
</div>
);
}
111 changes: 111 additions & 0 deletions src/routers/layout/search/phone/item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import SearchIcon from "@mui/icons-material/Search";
import { FC, forwardRef, useState } from "react";
import { useBackRef } from "../pc/hooks";
type PhoneSearchItemProps = {
defaultOpen: boolean;
inputDefaultValue: string;
onCompleteSearch: (() => void) | false;
nextCallback: () => void;
closeTitle: string;
closeValue: string;
UrlLists: { label: string; url: string }[];
};

export const PhoneSearchItem = forwardRef<
HTMLInputElement,
PhoneSearchItemProps
>((props, ref) => {
const {
closeTitle,
closeValue,
inputDefaultValue,
onCompleteSearch,
nextCallback,
UrlLists,
} = props;
// todo 增加获取input值
const [open, setOpen] = useState(props.defaultOpen);
const isActive = (label: string) => label === inputDefaultValue;
const { inputRef } = useBackRef(ref);
const handlerImgClick = (label: string) => {
if (onCompleteSearch) {
inputRef.current!.value = label;
onCompleteSearch();
} else {
nextCallback();
}
};
return (
<div>
{!open && (
<CloseItem
title={closeTitle}
value={closeValue}
onClick={setOpen.bind(null, true)}
/>
)}
{open && (
<div className='bg-white shadow-lg p-6 rounded-3xl font-semibold overflow-hidden'>
<div className='text-xl'>哪个标签?</div>
<div className='my-4 border rounded-2xl h-14 px-5 flex items-center'>
<SearchIcon />
<input
ref={inputRef}
className='self-stretch focus-within:outline-none pl-2 font-normal '
maxLength={20}
defaultValue={inputDefaultValue}
onKeyDown={(event) => {
if (event.key === "Enter") {
onCompleteSearch && onCompleteSearch();
}
}}
/>
</div>
<div className='flex gap-3 -mx-6 overflow-x-scroll snap-proximity snap-x no-scrollbar'>
{UrlLists.map((item, index) => (
<div
className={`${!index ? "ml-6" : ""} flex-shrink-0 h-40 w-32`}
onClick={handlerImgClick.bind(null, item.label)}
key={index}
>
<img
src={item.url}
width={128}
height={128}
className={`${
isActive(item.label) ? "border-black" : "border-gray-200"
} block border rounded-xl border-solid aspect-square`}
/>
<span
className={`${
isActive(item.label)
? "font-semibold text-gray-800"
: "font-normal text-gray-600"
} text-sm`}
>
{item.label}
</span>
</div>
))}
</div>
</div>
)}
</div>
);
});

const CloseItem: FC<{ title: string; value: string; onClick: () => void }> = ({
title,
value,
onClick,
}) => {
return (
<div
className='flex flex-row justify-between bg-white shadow-lg p-6 rounded-3xl text-sm font-semibold'
onClick={onClick}
>
<p className='text-gray-600'>{title}</p>
<p>{value}</p>
</div>
);
};
112 changes: 112 additions & 0 deletions src/routers/layout/search/phone/modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Modal, Tab, Tabs } from "@mui/material";
import { FC, useRef } from "react";
import SearchIcon from "@mui/icons-material/Search";
import { useSearchMode } from "../pc/hooks";
import { PhoneSearchItem } from "./item";
import { idolNameAndFaceUrls } from "./url";
import { useURLParams } from "@utils/hooks/url";
import { useNavigate } from "react-router-dom";
type PhotoModalSearchProps = {
open: boolean;
onClose: () => void;
};
export default function PhotoModalSearch(props: PhotoModalSearchProps) {
const { open, onClose } = props;
return (
<>
<Modal {...props}>
{/* 注意modal会把滚动条隐藏 */}
<div className='w-full h-full bg-neutral-100 relative flex flex-col'>
{/* header */}
<div className='flex-shrink-0 flex justify-center pt-7 pb-2'>
<CloseSVG onClose={onClose} />
<SearchHeader />
</div>
{/* content */}
<div className='flex-grow mt-4 mx-3'>
<TagContentCom onClose={onClose} />
</div>
</div>
</Modal>
</>
);
}
type ModeComProps = {
onClose: () => void;
};
const TagContentCom: FC<ModeComProps> = ({ onClose }) => {
const inputRef = useRef<HTMLInputElement>(null);
const [tag] = useURLParams(["tag"]);
const navigate = useNavigate();
const handlerSubmit = () => {
//@ts-ignore
const value = inputRef.current!.getValue();
navigate(`/search?tag=${value}`);
onClose();
};
const { searchMode } = useSearchMode();
return (
<div
className={`transition-all duration-150 ease-in-out ${
searchMode == "搜索tag" ? "block" : "hidden"
}`}
>
<PhoneSearchItem
ref={inputRef}
defaultOpen={true}
inputDefaultValue={tag}
onCompleteSearch={handlerSubmit}
nextCallback={() => {}}
closeTitle='标签'
closeValue={tag}
UrlLists={idolNameAndFaceUrls}
/>
</div>
);
};

// 选择栏
const SearchHeader = () => {
const { searchMode, handlerChangeSearchMode } = useSearchMode();
return (
<Tabs
value={searchMode}
className='min-h-0 h-7'
textColor='inherit'
TabIndicatorProps={{
style: {
backgroundColor: "black",
},
}}
>
<Tab
label={"标签"}
value={"搜索tag"}
onClick={handlerChangeSearchMode.bind(null, "搜索tag")}
className='box-content min-w-0 w-9 p-0 min-h-0 h-6 mx-2 font-bold text-base'
/>
<Tab
label={"体验"}
value={"搜索更多"}
onClick={handlerChangeSearchMode.bind(null, "搜索更多")}
className='box-content min-w-0 w-9 p-0 min-h-0 h-6 mx-2 font-bold text-base'
/>
</Tabs>
);
};
const CloseSVG: FC<{ onClose: () => void }> = ({ onClose }) => (
<div
className='inline-flex justify-center items-center p-2.5 border rounded-full border-neutral-500 absolute left-5 top-6'
onClick={onClose}
>
<svg
viewBox='0 0 32 32'
role='presentation'
className='block fill-none h-3 w-3 stroke-black'
strokeWidth='5'
>
<path d='m6 6 20 20'></path>
<path d='m26 6-20 20'></path>
</svg>
</div>
);
Loading

0 comments on commit 2a84717

Please sign in to comment.