如何在nexjts/react中有效地重叠模态

问题描述 投票:0回答:1

基本上我想创建 3 个堆叠在一起的模态,如下图所示。 单击“创建生态系统”将打开另一个 shadcn 对话框,如下面的第二张图片

我面临的问题是如何有效地将其堆叠在一起 所以有 3 个情态动词,

  1. 搜索模式
  2. 观察列表模态
  3. 添加生态系统模式
  • 当只有 1 个模态(搜索模态)时,单击外部应关闭模态
  • 当有2个模态(观察列表模态和搜索模态)时,单击外部应首先关闭监视列表模态(堆栈顶部),然后再次单击外部应关闭搜索模态
  • 与添加生态系统模态类似的故事,它需要正确堆叠,

喜欢搜索模式 -> 关注列表模式 -> 添加生态系统模式。

用现在的

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

reactjs next.js search dialog modal-dialog
1个回答
0
投票

一种方法是让每个模态实际上是两个 div:一个“背景”div,如果单击,将关闭模态,另一个实际的 div 用于模态内容。

在下图中,红色将是您的主页。

第一个模态框将包含一个 div,其大小与红色矩形相同,如果单击它,模态框将关闭;实际的模态内容将是橙色矩形。

第二个模态框将包含一个与红色矩形大小相同的 div,如果单击它,第二个模态框将关闭;实际的模态内容将是黄色矩形。

第三个模态框将包含一个与红色矩形大小相同的 div,如果单击它,第三个模态框将关闭;实际的模态内容将是绿色矩形。

如果您愿意,您还可以在“背景”div 上设置背景颜色和不透明度,以使模式后面的内容变灰。

此外,请考虑将每个模式设为平行路线。这是在 next.js 中完成模态的标准方式,因为它允许您将它们全部作为服务器组件,因为您不使用反应状态来处理打开/关闭

© www.soinside.com 2019 - 2024. All rights reserved.