refactor(components): 重构 playground组件
- 移除 Data、Scene 和 IodRelevant 组件中的 Drawer - 优化 Data、Scene 和 IodRelevant 组件的结构 - 添加 Header 组件用于展示标题和关闭按钮 - 使用 Main 组件替代原来的 ShowCard 组件 - 调整样式和布局,提高组件的可复用性和可维护性
This commit is contained in:
@@ -1,25 +1,121 @@
|
||||
import React from "react"
|
||||
import React, { createContext, useContext, useState } from "react"
|
||||
|
||||
import { AnimatePresence, motion } from "framer-motion"
|
||||
|
||||
import { PlaygroundIodRelevant } from "@/components/Common/Playground/IodRelevant.tsx"
|
||||
import { PlaygroundData } from "@/components/Common/Playground/Data.tsx"
|
||||
import { PlaygroundScene } from "@/components/Common/Playground/Scene.tsx"
|
||||
import { PlaygroundTeam } from "@/components/Common/Playground/Team.tsx"
|
||||
import { Card } from "antd"
|
||||
import { CloseOutlined } from "@ant-design/icons"
|
||||
|
||||
// 定义 Context 类型
|
||||
interface IodPlaygroundContextType {
|
||||
showPlayground: boolean
|
||||
setShowPlayground: React.Dispatch<React.SetStateAction<boolean>>
|
||||
detailHeader: React.ReactNode
|
||||
setDetailHeader: React.Dispatch<React.SetStateAction<React.ReactNode>>
|
||||
detailMain: React.ReactNode
|
||||
setDetailMain: React.Dispatch<React.SetStateAction<React.ReactNode>>
|
||||
}
|
||||
|
||||
// 创建 Context
|
||||
const PlaygroundContext = createContext<IodPlaygroundContextType | undefined>(
|
||||
undefined
|
||||
)
|
||||
|
||||
// 创建自定义 hook 以便子组件使用
|
||||
export const useIodPlaygroundContext = () => {
|
||||
const context = useContext(PlaygroundContext)
|
||||
if (context === undefined) {
|
||||
throw new Error(
|
||||
"usePlaygroundContext must be used within a PlaygroundProvider"
|
||||
)
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
export const PlaygroundIod = () => {
|
||||
const [showPlayground, setShowPlayground] = useState<boolean>(true)
|
||||
const [detailHeader, setDetailHeader] = useState(<></>)
|
||||
const [detailMain, setDetailMain] = useState(<></>)
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-[36%] h-full grid grid-rows-12 gap-3 pt-16 pr-5 pb-0"
|
||||
style={{ paddingTop: "4rem" }}>
|
||||
<div className="w-full row-span-5">
|
||||
<PlaygroundIodRelevant />
|
||||
<PlaygroundContext.Provider
|
||||
value={{
|
||||
showPlayground,
|
||||
setShowPlayground,
|
||||
detailMain,
|
||||
setDetailMain,
|
||||
detailHeader,
|
||||
setDetailHeader
|
||||
}}>
|
||||
<div className="w-[36%] h-full pt-16 pr-5 pb-0">
|
||||
<PlaygroundContent />
|
||||
</div>
|
||||
<div className="w-full row-span-4 grid grid-cols-2 gap-3 custom-scrollbar">
|
||||
<PlaygroundData />
|
||||
<PlaygroundScene />
|
||||
</div>
|
||||
<div className="w-full row-span-3 pb-3">
|
||||
<PlaygroundTeam />
|
||||
</div>
|
||||
</div>
|
||||
</PlaygroundContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
// 子组件使用修改card的默认样式
|
||||
const classNames =
|
||||
"h-full [&_.ant-card-body]:h-full [&_.ant-card-body]:!p-[20px] overflow-y-hidden !bg-[rgba(240,245,255,0.3)] backdrop-blur-sm border border-white/30 shadow-xl rounded-2xl"
|
||||
// 将原来的返回内容移到这个组件中
|
||||
const PlaygroundContent = () => {
|
||||
const { showPlayground, detailMain, detailHeader, setShowPlayground } =
|
||||
useIodPlaygroundContext()
|
||||
|
||||
|
||||
return (
|
||||
<AnimatePresence mode="popLayout">
|
||||
{showPlayground ? (
|
||||
<motion.div
|
||||
key="playground"
|
||||
initial={{ x: "100%" }}
|
||||
animate={{ x: 0 }}
|
||||
exit={{ x: "100%" }}
|
||||
transition={{
|
||||
duration: 0.6,
|
||||
ease: "easeInOut"
|
||||
}}
|
||||
className="h-full grid grid-rows-12 gap-3">
|
||||
<div className="w-full row-span-5">
|
||||
<PlaygroundIodRelevant className={classNames.replace('!bg-[rgba(240,245,255,0.3)]', '')} />
|
||||
</div>
|
||||
<div className="w-full row-span-4 grid grid-cols-2 gap-3 custom-scrollbar">
|
||||
<PlaygroundData className={classNames} />
|
||||
<PlaygroundScene className={classNames} />
|
||||
</div>
|
||||
<div className="w-full row-span-3 pb-3">
|
||||
<PlaygroundTeam className={classNames} />
|
||||
</div>
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="alternative"
|
||||
initial={{ x: "100%" }}
|
||||
animate={{ x: 0 }}
|
||||
exit={{ x: "100%" }}
|
||||
transition={{
|
||||
duration: 0.6,
|
||||
ease: "easeInOut"
|
||||
}}
|
||||
className="h-full pb-5">
|
||||
<Card className="h-full shadow-xl shadow-gray-500/20 [&_.ant-card-body]:h-full">
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="pb-6 flex items-center justify-between">
|
||||
<div>{detailHeader}</div>
|
||||
<CloseOutlined
|
||||
size={30}
|
||||
className="hover:text-red-500 cursor-pointer transition-colors duration-200 text-xl"
|
||||
onClick={() => setShowPlayground(true)}
|
||||
/>
|
||||
</div>
|
||||
{detailMain}
|
||||
</div>
|
||||
</Card>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user