基本上我想创建 3 个堆叠在一起的模态,如下图所示。 单击“创建生态系统”将打开另一个 shadcn 对话框,如下面的第二张图片
我面临的问题是如何有效地将其堆叠在一起 所以有 3 个情态动词,
喜欢搜索模式 -> 关注列表模式 -> 添加生态系统模式。
用现在的
onFocus
onBlur
实在是没有效果,那我该如何进行呢?
下面是代码片段,完整代码链接在最底部
SearchBar.tsx
"use client";
import { useEffect, useState } from "react";
import SearchResult from "./SearchResult";
export default function SearchBar() {
const [results, setResults] = useState([]);
const [isVisible, setIsVisible] = useState(false);
const stockMapping = [
{
StockId: 2,
StockName: "Tata Consultancy Services Limited",
Ecosystem: [
{
EcosystemName: "Eco1",
EcosystemId: 21,
},
{
EcosystemName: "Eco2",
EcosystemId: 22,
},
],
},
{
StockId: 4,
StockName: "ICICI Bank Limited",
Ecosystem: [
{
EcosystemName: "ddfs",
EcosystemId: 13,
},
],
},
{
StockId: 1,
StockName: "Reliance Industries Limited",
Ecosystem: [],
},
{
StockId: 5,
StockName: "State Bank of India",
Ecosystem: [],
},
];
const [searchInput, setSearchInput] = useState("");
const handleChange = async (value) => {
setSearchInput(value);
};
useEffect(() => {
const filteredStocks = stockMapping.filter((stock) =>
stock.StockName.toLowerCase().includes(searchInput.toLowerCase())
);
setResults(filteredStocks);
}, [searchInput]);
const handleFocus = () => {
setIsVisible(true);
};
const handleBlur = () => {
// Adding a small delay to allow time for the click event on the results to trigger before hiding them
setTimeout(() => {
setIsVisible(false);
}, 100);
};
return (
<div className="bg-gray-200 flex w-[600px] mr-32 ">
<div className=" bg-white rounded-md w-full relative z-0">
<div className="flex items-center border rounded-md h-full px-4">
<input
placeholder="Search for stocks"
value={searchInput}
onChange={(e) => handleChange(e.target.value)}
className="bg-transparent border-none h-full ml-2 w-full focus:outline-none"
onFocus={handleFocus}
onBlur={handleBlur}
/>
</div>
{results && results.length > 0 && (
<div
className={`inset w-full absolute inset-x-0 z-10 top-8 rounded-md bg-white shadow-md mt-4 max-h-300 overflow-y-auto ${
isVisible ? `block` : `hidden`
}`}
>
{results
? results
.slice(0, 5)
.map((result, id) => (
<SearchResult result={result} key={id} />
))
: isVisible && <div>No results found</div>}
</div>
)}
</div>
</div>
);
}
搜索结果
const SearchResult = ({ result }) => {
return (
<div className="search-result p-2 ml-5 flex justify-between hover:bg-gray-300 ">
{result.StockName}
{result.Ecosystem.length > 0 ? (
<div className="cursor-pointer">Added</div>
) : (
<div className="cursor-pointer">Add now</div>
)}
</div>
);
};
export default SearchResult;
在此处获取完整代码链接:https://github.com/krishnaacharyaa/search-nextjs-modal
一种方法是让每个模态实际上是两个 div:一个“背景”div,如果单击,将关闭模态,另一个实际的 div 用于模态内容。
在下图中,红色将是您的主页。
第一个模态框将包含一个 div,其大小与红色矩形相同,如果单击它,模态框将关闭;实际的模态内容将是橙色矩形。
第二个模态框将包含一个与红色矩形大小相同的 div,如果单击它,第二个模态框将关闭;实际的模态内容将是黄色矩形。
第三个模态框将包含一个与红色矩形大小相同的 div,如果单击它,第三个模态框将关闭;实际的模态内容将是绿色矩形。
如果您愿意,您还可以在“背景”div 上设置背景颜色和不透明度,以使模式后面的内容变灰。
此外,请考虑将每个模式设为平行路线。这是在 next.js 中完成模态的标准方式,因为它允许您将它们全部作为服务器组件,因为您不使用反应状态来处理打开/关闭