diff --git a/package.json b/package.json index 1718229..35838b0 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@radix-ui/react-menubar": "^1.1.1", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.1", + "@radix-ui/react-tooltip": "^1.1.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^1.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4cd936..052e4f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@radix-ui/react-toast': specifier: ^1.2.1 version: 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -851,6 +854,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-tooltip@1.1.2': + resolution: {integrity: sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-use-callback-ref@1.0.1': resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: @@ -3617,6 +3633,26 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-tooltip@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8 @@ -3975,7 +4011,7 @@ snapshots: app-builder-bin@4.0.0: {} - app-builder-lib@24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)): + app-builder-lib@24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)): dependencies: '@develar/schema-utils': 2.6.5 '@electron/notarize': 2.2.1 @@ -3989,7 +4025,7 @@ snapshots: builder-util-runtime: 9.2.4 chromium-pickle-js: 0.2.0 debug: 4.3.5 - dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) + dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3) ejs: 3.1.10 electron-builder-squirrel-windows: 24.13.3(dmg-builder@24.13.3) electron-publish: 24.13.1 @@ -4361,9 +4397,9 @@ snapshots: dlv@1.1.3: {} - dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)): + dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) + app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) builder-util: 24.13.1 builder-util-runtime: 9.2.4 fs-extra: 10.1.0 @@ -4403,7 +4439,7 @@ snapshots: electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) + app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) archiver: 5.3.2 builder-util: 24.13.1 fs-extra: 10.1.0 @@ -4413,11 +4449,11 @@ snapshots: electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) + app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) builder-util: 24.13.1 builder-util-runtime: 9.2.4 chalk: 4.1.2 - dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) + dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3) fs-extra: 10.1.0 is-ci: 3.0.1 lazy-val: 1.0.5 diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx new file mode 100644 index 0000000..9e74821 --- /dev/null +++ b/src/components/ui/tooltip.tsx @@ -0,0 +1,30 @@ +"use client" + +import * as React from "react" +import * as TooltipPrimitive from "@radix-ui/react-tooltip" + +import { cn } from "@/lib/utils" + +const TooltipProvider = TooltipPrimitive.Provider + +const Tooltip = TooltipPrimitive.Root + +const TooltipTrigger = TooltipPrimitive.Trigger + +const TooltipContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + +)) +TooltipContent.displayName = TooltipPrimitive.Content.displayName + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } diff --git a/src/pages/FlexLayoutDemo.tsx b/src/pages/FlexLayoutDemo.tsx index c03e620..7ecd7d4 100644 --- a/src/pages/FlexLayoutDemo.tsx +++ b/src/pages/FlexLayoutDemo.tsx @@ -1,14 +1,23 @@ import React from "react"; -import { IJsonModel, Layout, Model, TabNode } from "flexlayout-react"; +import { Actions, BorderNode, DockLocation, IJsonModel, ITabRenderValues, ITabSetRenderValues, Layout, Model, TabNode, TabSetNode } from "flexlayout-react"; import "flexlayout-react/style/light.css"; import "./Layout.css"; +import { Button } from "@/components/ui/button" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" const json: IJsonModel = { global: { tabEnableFloat: false, tabSetMinWidth: 100, - tabSetMinHeight: 100, + tabSetMinHeight: 200, + tabSetTabStripHeight: 48,//tab栏高度 borderMinSize: 100, + splitterSize: 2, }, borders: [], layout: { @@ -21,8 +30,10 @@ const json: IJsonModel = { children: [ { type: "tab", + id: 'tab1', name: "One", - component: "button", + component: "tabComponent", + config: { icon: "📘" } }, ], }, @@ -32,8 +43,10 @@ const json: IJsonModel = { children: [ { type: "tab", + id: 'tab2', name: "Two", - component: "button", + component: "tabComponent", + config: { icon: "📘" } }, ], }, @@ -41,22 +54,68 @@ const json: IJsonModel = { }, }; -const model = Model.fromJson(json); + const FlexLayoutComponent: React.FC = () => { + + const model = Model.fromJson(json); + const factory = (node: TabNode) => { const component = node.getComponent(); - - if (component === "button") { - return ; + if (component === "tabComponent") { + return
{node.getName()}11
; } }; + const renderTab = (node: TabNode, renderValues: ITabRenderValues) => { + renderValues.content = ( +
+ {node.getConfig().icon} + {renderValues.content} +
+ ); + }; + + const addTab = (node: TabSetNode | BorderNode) => { + // 创建一个新的 tab 对象 + const newTab = { + type: "tab", + name: "New Tab", + component: "tabComponent", + config: { icon: '' } + }; + + // 使用 FlexLayout 的 addAction 执行添加 tab 的动作 + const addAction = Actions.addNode(newTab, node.getId(), DockLocation.CENTER, -1); + node.getModel().doAction(addAction); + }; + + const onRenderTabSet = (node: TabSetNode | BorderNode, renderValues: ITabSetRenderValues) => { + + const createTabButton = + + + addTab(node)} + key={node.getId() + 'create'}> + + + + +

新建标签页

+
+
+
+ renderValues.stickyButtons.push(createTabButton) + }; + return ( `${defaultClass} custom-layout-class`} + onRenderTab={renderTab} + onRenderTabSet={onRenderTabSet} /> ); }; diff --git a/src/pages/Layout.css b/src/pages/Layout.css index d855003..132d18e 100644 --- a/src/pages/Layout.css +++ b/src/pages/Layout.css @@ -1,9 +1,7 @@ /* Layout.css */ .custom-layout-class .flexlayout__tab_button { - background-color: #4caf50; - color: white; - border-radius: 5px; + border-radius: 10px 10px 0 0; padding: 5px; margin-right: 5px; cursor: pointer; @@ -11,4 +9,15 @@ .custom-layout-class .flexlayout__tab_button:hover { background-color: #45a049; +} + +/* 覆盖默认的 FlexLayout 分割线选中颜色 */ +.custom-layout-class .flexlayout__splitter_drag { + background-color: blue; + /* 选中时的颜色 */ +} + +.custom-layout-class .flexlayout__splitter:hover { + background-color: lightblue; + /* 鼠标悬停时的颜色 */ } \ No newline at end of file