flowcloudai-ui 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +27 -60
- package/dist/index.d.ts +14 -50
- package/dist/index.js +382 -282
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -1846,6 +1846,8 @@
|
|
|
1846
1846
|
--tab-active-color: var(--fc-color-primary);
|
|
1847
1847
|
--tab-active-bg: var(--fc-color-bg);
|
|
1848
1848
|
--tab-active-indicator: var(--fc-color-primary);
|
|
1849
|
+
--tab-min-width: 8rem;
|
|
1850
|
+
--tab-max-width: 18rem;
|
|
1849
1851
|
--tab-bar-radius-tl: var(--fc-radius-md);
|
|
1850
1852
|
--tab-bar-radius-tr: var(--fc-radius-md);
|
|
1851
1853
|
--tab-bar-radius-br: 0px;
|
|
@@ -1892,27 +1894,18 @@
|
|
|
1892
1894
|
display: flex;
|
|
1893
1895
|
align-items: stretch;
|
|
1894
1896
|
}
|
|
1895
|
-
.fc-tab-bar__nav-
|
|
1896
|
-
overflow: hidden;
|
|
1897
|
-
}
|
|
1898
|
-
.fc-tab-bar__nav {
|
|
1899
|
-
flex: 1;
|
|
1900
|
-
min-width: 0;
|
|
1897
|
+
.fc-tab-bar__nav-wrap {
|
|
1901
1898
|
display: flex;
|
|
1902
1899
|
align-items: stretch;
|
|
1903
|
-
position: relative;
|
|
1904
|
-
z-index: 0;
|
|
1905
1900
|
}
|
|
1906
|
-
.fc-tab-bar__nav--scroll {
|
|
1907
|
-
|
|
1908
|
-
|
|
1901
|
+
.fc-tab-bar__nav-wrap--scroll {
|
|
1902
|
+
flex: 1;
|
|
1903
|
+
min-width: 0;
|
|
1904
|
+
overflow-x: auto;
|
|
1905
|
+
scrollbar-width: none;
|
|
1909
1906
|
}
|
|
1910
|
-
.fc-tab-bar__nav-wrap {
|
|
1911
|
-
display:
|
|
1912
|
-
gap: 0;
|
|
1913
|
-
align-items: stretch;
|
|
1914
|
-
max-width: 100%;
|
|
1915
|
-
box-sizing: border-box;
|
|
1907
|
+
.fc-tab-bar__nav-wrap--scroll::-webkit-scrollbar {
|
|
1908
|
+
display: none;
|
|
1916
1909
|
}
|
|
1917
1910
|
.fc-tab-bar__tab {
|
|
1918
1911
|
position: relative;
|
|
@@ -1929,11 +1922,13 @@
|
|
|
1929
1922
|
border: none;
|
|
1930
1923
|
user-select: none;
|
|
1931
1924
|
border-radius: var(--tab-item-radius-tl) var(--tab-item-radius-tr) var(--tab-item-radius-br) var(--tab-item-radius-bl);
|
|
1925
|
+
flex: 1 1 var(--tab-max-width);
|
|
1926
|
+
min-width: var(--tab-min-width);
|
|
1927
|
+
max-width: var(--tab-max-width);
|
|
1928
|
+
overflow: hidden;
|
|
1929
|
+
box-sizing: border-box;
|
|
1932
1930
|
}
|
|
1933
|
-
.fc-tab-
|
|
1934
|
-
justify-content: space-between;
|
|
1935
|
-
}
|
|
1936
|
-
.fc-tab-bar__tab:hover:not(.fc-tab-bar__tab--disabled):not(.fc-tab-bar__tab--dragging) {
|
|
1931
|
+
.fc-tab-bar__tab:hover:not(.fc-tab-bar__tab--disabled):not(.fc-tab-bar__tab--dragging):not(.fc-tab-bar__tab--active) {
|
|
1937
1932
|
color: var(--tab-hover-color);
|
|
1938
1933
|
background-color: var(--tab-hover-bg);
|
|
1939
1934
|
}
|
|
@@ -1946,6 +1941,13 @@
|
|
|
1946
1941
|
cursor: not-allowed;
|
|
1947
1942
|
opacity: 0.6;
|
|
1948
1943
|
}
|
|
1944
|
+
.fc-tab-bar__tab-label {
|
|
1945
|
+
flex: 1;
|
|
1946
|
+
min-width: 0;
|
|
1947
|
+
overflow: hidden;
|
|
1948
|
+
white-space: nowrap;
|
|
1949
|
+
text-overflow: ellipsis;
|
|
1950
|
+
}
|
|
1949
1951
|
.fc-tab-bar--attached {
|
|
1950
1952
|
border-bottom: 2px solid var(--fc-color-border);
|
|
1951
1953
|
}
|
|
@@ -2022,31 +2024,10 @@
|
|
|
2022
2024
|
.fc-tab-bar__add-btn {
|
|
2023
2025
|
-webkit-app-region: no-drag;
|
|
2024
2026
|
}
|
|
2025
|
-
.fc-tab-
|
|
2026
|
-
|
|
2027
|
-
min-width: 0;
|
|
2028
|
-
}
|
|
2029
|
-
.fc-tab-bar--shrink .fc-tab-bar__tab[data-compact=true] {
|
|
2030
|
-
padding-left: var(--fc-space-xs, 6px);
|
|
2031
|
-
padding-right: var(--fc-space-xs, 6px);
|
|
2032
|
-
}
|
|
2033
|
-
.fc-tab-bar--shrink .fc-tab-bar__tab-label {
|
|
2034
|
-
flex: 1;
|
|
2035
|
-
min-width: 0;
|
|
2027
|
+
.fc-tab-bar__drag-handle {
|
|
2028
|
+
flex: 0 0 0px;
|
|
2036
2029
|
overflow: hidden;
|
|
2037
|
-
|
|
2038
|
-
-webkit-mask-image:
|
|
2039
|
-
linear-gradient(
|
|
2040
|
-
to right,
|
|
2041
|
-
black 0%,
|
|
2042
|
-
black calc(100% - 20px),
|
|
2043
|
-
transparent 100%);
|
|
2044
|
-
mask-image:
|
|
2045
|
-
linear-gradient(
|
|
2046
|
-
to right,
|
|
2047
|
-
black 0%,
|
|
2048
|
-
black calc(100% - 20px),
|
|
2049
|
-
transparent 100%);
|
|
2030
|
+
-webkit-app-region: drag;
|
|
2050
2031
|
}
|
|
2051
2032
|
.fc-tab-bar__tab--draggable {
|
|
2052
2033
|
cursor: default;
|
|
@@ -2076,6 +2057,7 @@
|
|
|
2076
2057
|
align-items: center;
|
|
2077
2058
|
justify-content: center;
|
|
2078
2059
|
width: 32px;
|
|
2060
|
+
flex-shrink: 0;
|
|
2079
2061
|
margin: 0 var(--fc-space-sm, 8px);
|
|
2080
2062
|
font-size: 20px;
|
|
2081
2063
|
font-weight: bold;
|
|
@@ -2092,24 +2074,9 @@
|
|
|
2092
2074
|
.fc-tab-bar--floating .fc-tab-bar__add-btn {
|
|
2093
2075
|
border-radius: var(--fc-radius-full, 9999px);
|
|
2094
2076
|
}
|
|
2095
|
-
[data-theme=dark] .fc-tab-bar--attached {
|
|
2096
|
-
border-bottom-color: var(--fc-color-border);
|
|
2097
|
-
}
|
|
2098
|
-
[data-theme=dark] .fc-tab-bar__tab--active {
|
|
2099
|
-
background-color: var(--tab-active-bg);
|
|
2100
|
-
}
|
|
2101
|
-
[data-theme=dark] .fc-tab-bar__tab:hover:not(.fc-tab-bar__tab--disabled) {
|
|
2102
|
-
background-color: var(--tab-hover-bg);
|
|
2103
|
-
}
|
|
2104
2077
|
[data-theme=dark] .fc-tab-bar--floating .fc-tab-bar__tab--active {
|
|
2105
2078
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
2106
2079
|
}
|
|
2107
|
-
[data-theme=dark] .fc-tab-bar__add-btn:hover {
|
|
2108
|
-
background-color: var(--fc-color-bg-tertiary);
|
|
2109
|
-
}
|
|
2110
|
-
[data-theme=dark] .fc-tab-bar__tab-close:hover {
|
|
2111
|
-
background-color: var(--fc-color-border-light);
|
|
2112
|
-
}
|
|
2113
2080
|
@media (max-width: 768px) {
|
|
2114
2081
|
.fc-tab-bar__tab {
|
|
2115
2082
|
padding: var(--fc-space-xs, 6px) var(--fc-space-md, 12px);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
|
-
import React__default, { ReactNode, ComponentType, MouseEvent, CSSProperties } from 'react';
|
|
3
|
+
import React__default, { ReactNode, ComponentType, FC, MouseEvent, CSSProperties } from 'react';
|
|
4
4
|
|
|
5
5
|
type Theme = 'light' | 'dark' | 'system';
|
|
6
6
|
interface ThemeContextType {
|
|
@@ -423,87 +423,41 @@ interface CardProps {
|
|
|
423
423
|
declare const Card: ({ image, imageSlot, imageHeight, title, description, actions, extraInfo, variant, hoverable, disabled, className, style, onClick, }: CardProps) => react_jsx_runtime.JSX.Element;
|
|
424
424
|
|
|
425
425
|
interface TabItem {
|
|
426
|
-
/** 唯一标识 */
|
|
427
426
|
key: string;
|
|
428
|
-
/** 标签显示内容 */
|
|
429
427
|
label: React__default.ReactNode;
|
|
430
|
-
/** 是否禁用 */
|
|
431
428
|
disabled?: boolean;
|
|
432
|
-
/** 是否可关闭(覆盖全局 closable) */
|
|
433
429
|
closable?: boolean;
|
|
434
430
|
}
|
|
435
431
|
interface TabBarProps {
|
|
436
|
-
/** Tab 列表(受控) */
|
|
437
432
|
items: TabItem[];
|
|
438
|
-
/** 当前激活的 Tab key(受控) */
|
|
439
433
|
activeKey: string;
|
|
440
|
-
/**
|
|
441
|
-
* 布局变体
|
|
442
|
-
* - attached: 贴合模式 — 标签底部紧贴导航栏下边缘,底部线条作为激活指示器
|
|
443
|
-
* - floating: 悬浮模式 — 标签垂直居中悬浮,胶囊形态,背景填充作为激活指示器
|
|
444
|
-
* @default 'attached'
|
|
445
|
-
*/
|
|
446
434
|
variant?: 'attached' | 'floating';
|
|
447
|
-
/** TabBar 容器圆角 */
|
|
448
435
|
radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
449
|
-
/** 单个 Tab 项的圆角(仅在 floating 模式下或需要四周圆角时使用) */
|
|
450
436
|
tabRadius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
451
|
-
/** 是否显示关闭按钮 */
|
|
452
437
|
closable?: boolean;
|
|
453
|
-
/** 是否显示添加按钮 */
|
|
454
438
|
addable?: boolean;
|
|
455
|
-
/** 是否启用拖拽排序 */
|
|
456
439
|
draggable?: boolean;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
* 当均分后每个 Tab 宽度 < window.innerWidth * minWidthRatio 时,切换为横向滚动模式。
|
|
460
|
-
* @default 0.07
|
|
461
|
-
*/
|
|
462
|
-
minWidthRatio?: number;
|
|
463
|
-
/**
|
|
464
|
-
* Tab 最大宽度比例(相对 window.innerWidth)。
|
|
465
|
-
* 在固定模式下,单个 Tab 的宽度不会超过此值,防止子项很少时占满过多空间。
|
|
466
|
-
* @default 0.15
|
|
467
|
-
*/
|
|
468
|
-
maxTabWidthRatio?: number;
|
|
440
|
+
minTabWidth?: number;
|
|
441
|
+
maxTabWidth?: number;
|
|
469
442
|
onChange: (activeKey: string) => void;
|
|
470
443
|
onClose?: (key: string) => void;
|
|
471
444
|
onAdd?: () => void;
|
|
472
445
|
onReorder?: (reorderedItems: TabItem[]) => void;
|
|
473
|
-
/** 每个 Tab 的自定义 className */
|
|
474
446
|
tabClassName?: string;
|
|
475
|
-
/** 激活态 Tab 的额外 className */
|
|
476
447
|
activeTabClassName?: string;
|
|
477
|
-
/** 每个 Tab 的自定义 inline style */
|
|
478
448
|
tabStyle?: React__default.CSSProperties;
|
|
479
|
-
/** 激活态 Tab 的自定义 inline style(会合并到 tabStyle 之上) */
|
|
480
449
|
activeTabStyle?: React__default.CSSProperties;
|
|
481
|
-
/** 自定义关闭图标渲染 */
|
|
482
450
|
renderCloseIcon?: (key: string) => React__default.ReactNode;
|
|
483
|
-
/** 自定义添加按钮渲染 */
|
|
484
451
|
renderAddButton?: () => React__default.ReactNode;
|
|
485
452
|
className?: string;
|
|
486
453
|
style?: React__default.CSSProperties;
|
|
487
|
-
/** 容器背景色 */
|
|
488
454
|
background?: string;
|
|
489
|
-
/** 标签默认文字色 */
|
|
490
455
|
tabColor?: string;
|
|
491
|
-
/** 标签 hover 文字色 */
|
|
492
456
|
tabHoverColor?: string;
|
|
493
|
-
/** 标签 hover 背景色 */
|
|
494
457
|
tabHoverBackground?: string;
|
|
495
|
-
/** 激活态文字色 */
|
|
496
458
|
tabActiveColor?: string;
|
|
497
|
-
/** 激活态背景色 */
|
|
498
459
|
tabActiveBackground?: string;
|
|
499
|
-
/** 激活态指示器颜色(attached 模式底线 / floating 模式无效) */
|
|
500
460
|
activeIndicatorColor?: string;
|
|
501
|
-
/**
|
|
502
|
-
* 将 TabBar 空白区域标记为 Tauri 窗口拖拽区域。
|
|
503
|
-
* 开启后,标签之外的空白处可拖动窗口;标签、关闭、添加按钮已内置 no-drag 保护。
|
|
504
|
-
* @default false
|
|
505
|
-
*/
|
|
506
|
-
tauriDragRegion?: boolean;
|
|
507
461
|
}
|
|
508
462
|
declare const TabBar: React__default.NamedExoticComponent<TabBarProps>;
|
|
509
463
|
|
|
@@ -676,7 +630,17 @@ interface RelationProps {
|
|
|
676
630
|
enableNodeDrag?: boolean;
|
|
677
631
|
onNodeContextMenu?: (nodeId: string, nodeData: RelationNodeData) => void;
|
|
678
632
|
theme?: 'dark' | 'light';
|
|
633
|
+
edgeStyles?: {
|
|
634
|
+
defaultColor?: string;
|
|
635
|
+
hoverColor?: string;
|
|
636
|
+
selectedColor?: string;
|
|
637
|
+
};
|
|
638
|
+
nodeStyles?: {
|
|
639
|
+
borderRadius?: string;
|
|
640
|
+
minWidth?: string;
|
|
641
|
+
};
|
|
642
|
+
showHandles?: boolean;
|
|
679
643
|
}
|
|
680
|
-
declare const Relation:
|
|
644
|
+
declare const Relation: FC<RelationProps>;
|
|
681
645
|
|
|
682
646
|
export { type AlertMode, type AlertProps, AlertProvider, type AlertProviderProps, type AlertType, Avatar, type AvatarProps, type AvatarShape, Button, ButtonGroup, ButtonToolbar, Card, type CardProps, type CategoryTreeNode, Chat, type ChatProps, CheckButton, type ContextMenuAction, type ContextMenuDivider, type ContextMenuItem, ContextMenuProvider, type ContextMenuProviderProps, type Conversation, DeleteDialog, type DeleteMode, type DropPosition, type FlatCategory, type FlatToTreeResult, Input, ListGroup, ListGroupItem, type ListGroupItemProps, type ListGroupProps, MarkdownEditor, type MarkdownEditorProps, type Message, type MessageRole, OrphanDialog, type OrphanResolution, type OrphanResolutionMap, Relation, type RelationEdgeData, type RelationNodeData, type RelationProps, RollingBox, Select, SideBar, type SideBarItem, type SideBarProps, Slider, SmartMessage, type SmartMessageProps, TabBar, type TabBarProps, type TabItem, TagItem, type TagItemProps, type TagSchema, type TagValue, type Theme, ThemeProvider, Tree, type TreeProps, VirtualList, findNodeInfo, flatToTree, isDescendantOf, lazyLoad, useAlert, useContextMenu, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -2025,107 +2025,13 @@ var Card = ({
|
|
|
2025
2025
|
};
|
|
2026
2026
|
|
|
2027
2027
|
// src/components/Bar/TabBar.tsx
|
|
2028
|
-
import { useRef as
|
|
2029
|
-
|
|
2030
|
-
// src/components/Bar/useAdaptiveTabLayout.ts
|
|
2031
|
-
import { useState as useState13, useRef as useRef7, useCallback as useCallback8, useEffect as useEffect8 } from "react";
|
|
2032
|
-
function useAdaptiveTabLayout(navRef, options) {
|
|
2033
|
-
const { itemsLength, addable, minWidthRatio, maxTabWidthRatio } = options;
|
|
2034
|
-
const itemsLengthRef = useRef7(itemsLength);
|
|
2035
|
-
itemsLengthRef.current = itemsLength;
|
|
2036
|
-
const addableRef = useRef7(addable);
|
|
2037
|
-
addableRef.current = addable;
|
|
2038
|
-
const minWidthRatioRef = useRef7(minWidthRatio);
|
|
2039
|
-
minWidthRatioRef.current = minWidthRatio;
|
|
2040
|
-
const maxTabWidthRatioRef = useRef7(maxTabWidthRatio);
|
|
2041
|
-
maxTabWidthRatioRef.current = maxTabWidthRatio;
|
|
2042
|
-
const [layout, setLayout] = useState13({ scrollMode: false, tabWidth: void 0 });
|
|
2043
|
-
const calculateTimeoutRef = useRef7(null);
|
|
2044
|
-
const lastLayoutRef = useRef7({ scrollMode: false, tabWidth: void 0 });
|
|
2045
|
-
const addBtnWidthRef = useRef7(0);
|
|
2046
|
-
const lastAddableRef = useRef7(void 0);
|
|
2047
|
-
const calculate = useCallback8(() => {
|
|
2048
|
-
const navOuter = navRef.current?.parentElement;
|
|
2049
|
-
const nav = navRef.current;
|
|
2050
|
-
const currentItemsLength = itemsLengthRef.current;
|
|
2051
|
-
const currentAddable = addableRef.current;
|
|
2052
|
-
const currentMinWidthRatio = minWidthRatioRef.current;
|
|
2053
|
-
const currentMaxTabWidthRatio = maxTabWidthRatioRef.current;
|
|
2054
|
-
if (!nav || !navOuter || currentItemsLength === 0) return;
|
|
2055
|
-
if (currentAddable !== lastAddableRef.current) {
|
|
2056
|
-
lastAddableRef.current = currentAddable;
|
|
2057
|
-
if (currentAddable) {
|
|
2058
|
-
const addBtnElement = navOuter.querySelector(".fc-tab-bar__add-btn");
|
|
2059
|
-
if (addBtnElement) {
|
|
2060
|
-
const btnStyle = getComputedStyle(addBtnElement);
|
|
2061
|
-
const marginL = parseFloat(btnStyle.marginLeft) || 0;
|
|
2062
|
-
const marginR = parseFloat(btnStyle.marginRight) || 0;
|
|
2063
|
-
addBtnWidthRef.current = addBtnElement.getBoundingClientRect().width + marginL + marginR;
|
|
2064
|
-
}
|
|
2065
|
-
} else {
|
|
2066
|
-
addBtnWidthRef.current = 0;
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
const navOuterCS = getComputedStyle(navOuter);
|
|
2070
|
-
const navWrap = nav.querySelector(".fc-tab-bar__nav-wrap");
|
|
2071
|
-
const navOuterW = navOuter.clientWidth - parseFloat(navOuterCS.paddingLeft) - parseFloat(navOuterCS.paddingRight);
|
|
2072
|
-
const navW = navOuterW - addBtnWidthRef.current;
|
|
2073
|
-
const tabGap = navWrap ? parseFloat(getComputedStyle(navWrap).gap) : 0;
|
|
2074
|
-
const totalGapWidth = (currentItemsLength - 1) * tabGap;
|
|
2075
|
-
const idealW = (navW - totalGapWidth) / currentItemsLength;
|
|
2076
|
-
const threshold = window.innerWidth * currentMinWidthRatio;
|
|
2077
|
-
const maxAllowedWidth = window.innerWidth * currentMaxTabWidthRatio;
|
|
2078
|
-
const minAllowedWidth = 42;
|
|
2079
|
-
const prev = lastLayoutRef.current;
|
|
2080
|
-
const hysteresisFactor = 1.1;
|
|
2081
|
-
let newScrollMode;
|
|
2082
|
-
let newTabWidth;
|
|
2083
|
-
if (idealW < threshold) {
|
|
2084
|
-
newScrollMode = true;
|
|
2085
|
-
newTabWidth = Math.max(threshold, minAllowedWidth);
|
|
2086
|
-
} else if (prev.scrollMode && idealW < threshold * hysteresisFactor) {
|
|
2087
|
-
newScrollMode = true;
|
|
2088
|
-
newTabWidth = Math.max(threshold, minAllowedWidth);
|
|
2089
|
-
} else {
|
|
2090
|
-
newScrollMode = false;
|
|
2091
|
-
newTabWidth = Math.min(Math.max(idealW, minAllowedWidth), maxAllowedWidth);
|
|
2092
|
-
}
|
|
2093
|
-
if (prev.tabWidth !== newTabWidth || prev.scrollMode !== newScrollMode) {
|
|
2094
|
-
const newLayout = { scrollMode: newScrollMode, tabWidth: newTabWidth };
|
|
2095
|
-
lastLayoutRef.current = newLayout;
|
|
2096
|
-
setLayout(newLayout);
|
|
2097
|
-
}
|
|
2098
|
-
}, [navRef]);
|
|
2099
|
-
const calculateDebounced = useCallback8(() => {
|
|
2100
|
-
if (calculateTimeoutRef.current) clearTimeout(calculateTimeoutRef.current);
|
|
2101
|
-
calculateTimeoutRef.current = setTimeout(calculate, 50);
|
|
2102
|
-
}, [calculate]);
|
|
2103
|
-
const calculateDebouncedRef = useRef7(calculateDebounced);
|
|
2104
|
-
calculateDebouncedRef.current = calculateDebounced;
|
|
2105
|
-
useEffect8(() => {
|
|
2106
|
-
const rafId = requestAnimationFrame(calculate);
|
|
2107
|
-
const handleResize = () => calculateDebouncedRef.current();
|
|
2108
|
-
window.addEventListener("resize", handleResize);
|
|
2109
|
-
return () => {
|
|
2110
|
-
cancelAnimationFrame(rafId);
|
|
2111
|
-
window.removeEventListener("resize", handleResize);
|
|
2112
|
-
if (calculateTimeoutRef.current) clearTimeout(calculateTimeoutRef.current);
|
|
2113
|
-
};
|
|
2114
|
-
}, []);
|
|
2115
|
-
useEffect8(() => {
|
|
2116
|
-
calculate();
|
|
2117
|
-
}, [itemsLength, calculate]);
|
|
2118
|
-
return layout;
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
// src/components/Bar/TabBar.tsx
|
|
2028
|
+
import { useRef as useRef7, useCallback as useCallback8, memo as memo4, useEffect as useEffect8 } from "react";
|
|
2122
2029
|
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2123
2030
|
var TabItemView = memo4(({
|
|
2124
2031
|
item,
|
|
2125
2032
|
isActive,
|
|
2126
2033
|
closable,
|
|
2127
2034
|
draggable,
|
|
2128
|
-
tabWidth,
|
|
2129
2035
|
tabClassName,
|
|
2130
2036
|
activeTabClassName,
|
|
2131
2037
|
tabStyle,
|
|
@@ -2139,7 +2045,6 @@ var TabItemView = memo4(({
|
|
|
2139
2045
|
onDragEnd
|
|
2140
2046
|
}) => {
|
|
2141
2047
|
const showClose = item.closable !== void 0 ? item.closable : closable;
|
|
2142
|
-
const isCompact = tabWidth !== void 0 && tabWidth < 42;
|
|
2143
2048
|
const classes = [
|
|
2144
2049
|
"fc-tab-bar__tab",
|
|
2145
2050
|
isActive && "fc-tab-bar__tab--active",
|
|
@@ -2149,7 +2054,6 @@ var TabItemView = memo4(({
|
|
|
2149
2054
|
isActive && activeTabClassName
|
|
2150
2055
|
].filter(Boolean).join(" ");
|
|
2151
2056
|
const mergedStyle = {
|
|
2152
|
-
...tabWidth !== void 0 ? { width: tabWidth, boxSizing: "border-box", flexShrink: 0 } : void 0,
|
|
2153
2057
|
...tabStyle,
|
|
2154
2058
|
...isActive ? activeTabStyle : void 0
|
|
2155
2059
|
};
|
|
@@ -2158,7 +2062,6 @@ var TabItemView = memo4(({
|
|
|
2158
2062
|
{
|
|
2159
2063
|
className: classes,
|
|
2160
2064
|
style: mergedStyle,
|
|
2161
|
-
"data-compact": isCompact || void 0,
|
|
2162
2065
|
onClick: () => !item.disabled && onClick(item.key),
|
|
2163
2066
|
draggable: draggable && !item.disabled,
|
|
2164
2067
|
onDragStart: (e) => onDragStart(e, item.key),
|
|
@@ -2177,7 +2080,7 @@ var TabItemView = memo4(({
|
|
|
2177
2080
|
className: "fc-tab-bar__tab-close",
|
|
2178
2081
|
onClick: (e) => onClose(e, item.key),
|
|
2179
2082
|
role: "button",
|
|
2180
|
-
"aria-label":
|
|
2083
|
+
"aria-label": "\u5173\u95ED",
|
|
2181
2084
|
children: renderCloseIcon ? renderCloseIcon(item.key) : "\xD7"
|
|
2182
2085
|
}
|
|
2183
2086
|
)
|
|
@@ -2195,8 +2098,8 @@ var TabBar = memo4(({
|
|
|
2195
2098
|
closable = false,
|
|
2196
2099
|
addable = false,
|
|
2197
2100
|
draggable = false,
|
|
2198
|
-
|
|
2199
|
-
|
|
2101
|
+
minTabWidth = 8,
|
|
2102
|
+
maxTabWidth = 18,
|
|
2200
2103
|
onChange,
|
|
2201
2104
|
onClose,
|
|
2202
2105
|
onAdd,
|
|
@@ -2209,7 +2112,6 @@ var TabBar = memo4(({
|
|
|
2209
2112
|
renderAddButton,
|
|
2210
2113
|
className = "",
|
|
2211
2114
|
style,
|
|
2212
|
-
tauriDragRegion = false,
|
|
2213
2115
|
background,
|
|
2214
2116
|
tabColor,
|
|
2215
2117
|
tabHoverColor,
|
|
@@ -2218,135 +2120,131 @@ var TabBar = memo4(({
|
|
|
2218
2120
|
tabActiveBackground,
|
|
2219
2121
|
activeIndicatorColor
|
|
2220
2122
|
}) => {
|
|
2221
|
-
const
|
|
2123
|
+
const cssVarMap = {
|
|
2222
2124
|
"--tab-bar-bg": background,
|
|
2223
2125
|
"--tab-color": tabColor,
|
|
2224
2126
|
"--tab-hover-color": tabHoverColor,
|
|
2225
2127
|
"--tab-hover-bg": tabHoverBackground,
|
|
2226
2128
|
"--tab-active-color": tabActiveColor,
|
|
2227
2129
|
"--tab-active-bg": tabActiveBackground,
|
|
2228
|
-
"--tab-active-indicator": activeIndicatorColor
|
|
2130
|
+
"--tab-active-indicator": activeIndicatorColor,
|
|
2131
|
+
"--tab-min-width": `${minTabWidth}rem`,
|
|
2132
|
+
"--tab-max-width": `${maxTabWidth}rem`
|
|
2229
2133
|
};
|
|
2230
|
-
const
|
|
2231
|
-
for (const [
|
|
2232
|
-
if (
|
|
2233
|
-
overrideStyle[key] = value;
|
|
2234
|
-
}
|
|
2134
|
+
const cssVars = {};
|
|
2135
|
+
for (const [k, v] of Object.entries(cssVarMap)) {
|
|
2136
|
+
if (v !== void 0) cssVars[k] = v;
|
|
2235
2137
|
}
|
|
2236
|
-
const mergedStyle = { ...
|
|
2237
|
-
const
|
|
2238
|
-
const
|
|
2239
|
-
const
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2138
|
+
const mergedStyle = { ...cssVars, ...style };
|
|
2139
|
+
const navOuterRef = useRef7(null);
|
|
2140
|
+
const addBtnRef = useRef7(null);
|
|
2141
|
+
const navWrapRef = useRef7(null);
|
|
2142
|
+
const dragKeyRef = useRef7(null);
|
|
2143
|
+
useEffect8(() => {
|
|
2144
|
+
const el = navWrapRef.current;
|
|
2145
|
+
if (!el) return;
|
|
2146
|
+
const handler = (e) => {
|
|
2147
|
+
if (e.deltaY === 0 || e.deltaX !== 0) return;
|
|
2148
|
+
el.scrollLeft += e.deltaY;
|
|
2149
|
+
e.preventDefault();
|
|
2150
|
+
};
|
|
2151
|
+
el.addEventListener("wheel", handler, { passive: false });
|
|
2152
|
+
return () => el.removeEventListener("wheel", handler);
|
|
2153
|
+
}, []);
|
|
2154
|
+
const prevLenRef = useRef7(items.length);
|
|
2155
|
+
useEffect8(() => {
|
|
2156
|
+
const prev = prevLenRef.current;
|
|
2157
|
+
prevLenRef.current = items.length;
|
|
2158
|
+
if (items.length <= prev) return;
|
|
2159
|
+
const el = navWrapRef.current;
|
|
2160
|
+
if (!el) return;
|
|
2252
2161
|
requestAnimationFrame(() => {
|
|
2253
|
-
|
|
2162
|
+
el.scrollLeft = el.scrollWidth;
|
|
2254
2163
|
});
|
|
2255
|
-
}, [items.length
|
|
2256
|
-
const handleClick =
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
);
|
|
2267
|
-
const
|
|
2268
|
-
(e, key) => {
|
|
2269
|
-
dragKeyRef.current = key;
|
|
2270
|
-
e.dataTransfer.effectAllowed = "move";
|
|
2271
|
-
const target = e.currentTarget;
|
|
2272
|
-
requestAnimationFrame(() => target.classList.add("fc-tab-bar__tab--dragging"));
|
|
2273
|
-
},
|
|
2274
|
-
[]
|
|
2275
|
-
);
|
|
2276
|
-
const handleDragOver = useCallback9((e) => {
|
|
2164
|
+
}, [items.length]);
|
|
2165
|
+
const handleClick = useCallback8((key) => onChange(key), [onChange]);
|
|
2166
|
+
const handleClose = useCallback8((e, key) => {
|
|
2167
|
+
e.stopPropagation();
|
|
2168
|
+
onClose?.(key);
|
|
2169
|
+
}, [onClose]);
|
|
2170
|
+
const handleDragStart = useCallback8((e, key) => {
|
|
2171
|
+
dragKeyRef.current = key;
|
|
2172
|
+
e.dataTransfer.effectAllowed = "move";
|
|
2173
|
+
const target = e.currentTarget;
|
|
2174
|
+
requestAnimationFrame(() => target.classList.add("fc-tab-bar__tab--dragging"));
|
|
2175
|
+
}, []);
|
|
2176
|
+
const handleDragOver = useCallback8((e) => {
|
|
2277
2177
|
e.preventDefault();
|
|
2278
2178
|
e.dataTransfer.dropEffect = "move";
|
|
2279
2179
|
}, []);
|
|
2280
|
-
const handleDrop =
|
|
2281
|
-
(
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
[items, onReorder]
|
|
2294
|
-
);
|
|
2295
|
-
const handleDragEnd = useCallback9((e) => {
|
|
2180
|
+
const handleDrop = useCallback8((e, targetKey) => {
|
|
2181
|
+
e.preventDefault();
|
|
2182
|
+
const dragKey = dragKeyRef.current;
|
|
2183
|
+
if (!dragKey || dragKey === targetKey || !onReorder) return;
|
|
2184
|
+
const from = items.findIndex((i) => i.key === dragKey);
|
|
2185
|
+
const to = items.findIndex((i) => i.key === targetKey);
|
|
2186
|
+
if (from === -1 || to === -1) return;
|
|
2187
|
+
const reordered = [...items];
|
|
2188
|
+
const [moved] = reordered.splice(from, 1);
|
|
2189
|
+
reordered.splice(to, 0, moved);
|
|
2190
|
+
onReorder(reordered);
|
|
2191
|
+
}, [items, onReorder]);
|
|
2192
|
+
const handleDragEnd = useCallback8((e) => {
|
|
2296
2193
|
dragKeyRef.current = null;
|
|
2297
2194
|
e.currentTarget.classList.remove("fc-tab-bar__tab--dragging");
|
|
2298
2195
|
}, []);
|
|
2299
|
-
const { scrollMode, tabWidth } = layout;
|
|
2300
2196
|
const rootClasses = [
|
|
2301
2197
|
"fc-tab-bar",
|
|
2302
2198
|
`fc-tab-bar--${variant}`,
|
|
2303
2199
|
`fc-tab-bar--radius-${radius}`,
|
|
2304
2200
|
tabRadius && `fc-tab-bar--tab-radius-${tabRadius}`,
|
|
2305
|
-
!scrollMode && tabWidth !== void 0 && "fc-tab-bar--shrink",
|
|
2306
2201
|
className
|
|
2307
2202
|
].filter(Boolean).join(" ");
|
|
2308
|
-
const
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
"
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2203
|
+
const navWrapClasses = [
|
|
2204
|
+
"fc-tab-bar__nav-wrap",
|
|
2205
|
+
"fc-tab-bar__nav-wrap--scroll"
|
|
2206
|
+
// 始终启用滚动模式,由 CSS 控制
|
|
2207
|
+
].filter(Boolean).join(" ");
|
|
2208
|
+
return /* @__PURE__ */ jsx18("div", { className: rootClasses, style: mergedStyle, role: "tablist", children: /* @__PURE__ */ jsxs13("div", { className: "fc-tab-bar__nav-outer", ref: navOuterRef, children: [
|
|
2209
|
+
/* @__PURE__ */ jsx18("div", { className: navWrapClasses, ref: navWrapRef, children: items.map((item) => /* @__PURE__ */ jsx18(
|
|
2210
|
+
TabItemView,
|
|
2211
|
+
{
|
|
2212
|
+
item,
|
|
2213
|
+
isActive: activeKey === item.key,
|
|
2214
|
+
closable,
|
|
2215
|
+
draggable,
|
|
2216
|
+
tabClassName,
|
|
2217
|
+
activeTabClassName,
|
|
2218
|
+
tabStyle,
|
|
2219
|
+
activeTabStyle,
|
|
2220
|
+
renderCloseIcon,
|
|
2221
|
+
onClick: handleClick,
|
|
2222
|
+
onClose: handleClose,
|
|
2223
|
+
onDragStart: handleDragStart,
|
|
2224
|
+
onDragOver: handleDragOver,
|
|
2225
|
+
onDrop: handleDrop,
|
|
2226
|
+
onDragEnd: handleDragEnd
|
|
2227
|
+
},
|
|
2228
|
+
item.key
|
|
2229
|
+
)) }),
|
|
2230
|
+
addable && /* @__PURE__ */ jsx18(
|
|
2231
|
+
"div",
|
|
2232
|
+
{
|
|
2233
|
+
className: "fc-tab-bar__add-btn",
|
|
2234
|
+
ref: addBtnRef,
|
|
2235
|
+
onClick: onAdd,
|
|
2236
|
+
role: "button",
|
|
2237
|
+
"aria-label": "\u6DFB\u52A0\u6807\u7B7E",
|
|
2238
|
+
children: renderAddButton ? renderAddButton() : "+"
|
|
2239
|
+
}
|
|
2240
|
+
),
|
|
2241
|
+
/* @__PURE__ */ jsx18("div", { className: "fc-tab-bar__drag-handle", "data-tauri-drag-region": true })
|
|
2344
2242
|
] }) });
|
|
2345
2243
|
});
|
|
2346
2244
|
TabBar.displayName = "TabBar";
|
|
2347
2245
|
|
|
2348
2246
|
// src/components/Tag/TagItem.tsx
|
|
2349
|
-
import { useEffect as
|
|
2247
|
+
import { useEffect as useEffect9, useRef as useRef8, useState as useState13 } from "react";
|
|
2350
2248
|
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2351
2249
|
function TagItem({
|
|
2352
2250
|
schema,
|
|
@@ -2357,10 +2255,10 @@ function TagItem({
|
|
|
2357
2255
|
color,
|
|
2358
2256
|
borderColor
|
|
2359
2257
|
}) {
|
|
2360
|
-
const [editing, setEditing] =
|
|
2361
|
-
const [draft, setDraft] =
|
|
2362
|
-
const inputRef =
|
|
2363
|
-
|
|
2258
|
+
const [editing, setEditing] = useState13(false);
|
|
2259
|
+
const [draft, setDraft] = useState13(() => value !== void 0 ? String(value) : "");
|
|
2260
|
+
const inputRef = useRef8(null);
|
|
2261
|
+
useEffect9(() => {
|
|
2364
2262
|
if (!editing) setDraft(value !== void 0 ? String(value) : "");
|
|
2365
2263
|
}, [value, editing]);
|
|
2366
2264
|
const colorVars = {
|
|
@@ -2459,7 +2357,7 @@ function TagItem({
|
|
|
2459
2357
|
}
|
|
2460
2358
|
|
|
2461
2359
|
// src/components/MarkdownEditor/MarkdownEditor.tsx
|
|
2462
|
-
import { useState as
|
|
2360
|
+
import { useState as useState14 } from "react";
|
|
2463
2361
|
import MDEditor, { commands } from "@uiw/react-md-editor";
|
|
2464
2362
|
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2465
2363
|
function withTitle(cmd, title) {
|
|
@@ -2495,7 +2393,7 @@ function MarkdownEditor({
|
|
|
2495
2393
|
borderColor
|
|
2496
2394
|
}) {
|
|
2497
2395
|
const { resolvedTheme } = useTheme();
|
|
2498
|
-
const [showSplit, setShowSplit] =
|
|
2396
|
+
const [showSplit, setShowSplit] = useState14(false);
|
|
2499
2397
|
const colorVars = {
|
|
2500
2398
|
"--md-bg": background,
|
|
2501
2399
|
"--md-toolbar-bg": toolbarBackground,
|
|
@@ -2554,7 +2452,7 @@ function MarkdownEditor({
|
|
|
2554
2452
|
}
|
|
2555
2453
|
|
|
2556
2454
|
// src/components/ContextMenu/ContextMenuContext.tsx
|
|
2557
|
-
import { createContext as createContext4, useContext as useContext4, useEffect as
|
|
2455
|
+
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect10, useRef as useRef9, useState as useState15 } from "react";
|
|
2558
2456
|
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2559
2457
|
var ContextMenuContext = createContext4(null);
|
|
2560
2458
|
function ContextMenuProvider({
|
|
@@ -2563,13 +2461,13 @@ function ContextMenuProvider({
|
|
|
2563
2461
|
borderColor,
|
|
2564
2462
|
hoverBackground
|
|
2565
2463
|
}) {
|
|
2566
|
-
const [menu, setMenu] =
|
|
2464
|
+
const [menu, setMenu] = useState15({
|
|
2567
2465
|
visible: false,
|
|
2568
2466
|
x: 0,
|
|
2569
2467
|
y: 0,
|
|
2570
2468
|
items: []
|
|
2571
2469
|
});
|
|
2572
|
-
const menuRef =
|
|
2470
|
+
const menuRef = useRef9(null);
|
|
2573
2471
|
const showContextMenu = (e, items) => {
|
|
2574
2472
|
e.preventDefault();
|
|
2575
2473
|
e.stopPropagation();
|
|
@@ -2577,7 +2475,7 @@ function ContextMenuProvider({
|
|
|
2577
2475
|
};
|
|
2578
2476
|
const hide = () => setMenu((s) => ({ ...s, visible: false }));
|
|
2579
2477
|
useClickOutside(menuRef, hide, menu.visible);
|
|
2580
|
-
|
|
2478
|
+
useEffect10(() => {
|
|
2581
2479
|
if (!menu.visible) return;
|
|
2582
2480
|
const onKeyDown = (e) => {
|
|
2583
2481
|
if (e.key === "Escape") hide();
|
|
@@ -2646,10 +2544,10 @@ function ContextMenuProvider({
|
|
|
2646
2544
|
var useContextMenu = () => useContext4(ContextMenuContext);
|
|
2647
2545
|
|
|
2648
2546
|
// src/components/Chat/Chat.tsx
|
|
2649
|
-
import { useState as
|
|
2547
|
+
import { useState as useState17, useRef as useRef10, useEffect as useEffect11, useCallback as useCallback10, useMemo as useMemo5 } from "react";
|
|
2650
2548
|
|
|
2651
2549
|
// src/components/SmartMessage/SmartMessage.tsx
|
|
2652
|
-
import { useState as
|
|
2550
|
+
import { useState as useState16, useCallback as useCallback9 } from "react";
|
|
2653
2551
|
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2654
2552
|
var SmartMessage = ({
|
|
2655
2553
|
id,
|
|
@@ -2662,8 +2560,8 @@ var SmartMessage = ({
|
|
|
2662
2560
|
className = "",
|
|
2663
2561
|
style = {}
|
|
2664
2562
|
}) => {
|
|
2665
|
-
const [copied, setCopied] =
|
|
2666
|
-
const handleCopy =
|
|
2563
|
+
const [copied, setCopied] = useState16(false);
|
|
2564
|
+
const handleCopy = useCallback9(async () => {
|
|
2667
2565
|
try {
|
|
2668
2566
|
await navigator.clipboard.writeText(content);
|
|
2669
2567
|
setCopied(true);
|
|
@@ -2751,34 +2649,34 @@ var Chat = ({
|
|
|
2751
2649
|
height = "600px",
|
|
2752
2650
|
width
|
|
2753
2651
|
}) => {
|
|
2754
|
-
const [showHistory, setShowHistory] =
|
|
2755
|
-
const [isMinimized, setIsMinimized] =
|
|
2756
|
-
const messagesContainerRef =
|
|
2757
|
-
const messagesEndRef =
|
|
2758
|
-
const historyPanelRef =
|
|
2652
|
+
const [showHistory, setShowHistory] = useState17(false);
|
|
2653
|
+
const [isMinimized, setIsMinimized] = useState17(false);
|
|
2654
|
+
const messagesContainerRef = useRef10(null);
|
|
2655
|
+
const messagesEndRef = useRef10(null);
|
|
2656
|
+
const historyPanelRef = useRef10(null);
|
|
2759
2657
|
const currentConversation = useMemo5(
|
|
2760
2658
|
() => conversations.find((c) => c.id === currentConversationId),
|
|
2761
2659
|
[conversations, currentConversationId]
|
|
2762
2660
|
);
|
|
2763
2661
|
const currentTitle = currentConversation?.title || title;
|
|
2764
|
-
|
|
2662
|
+
useEffect11(() => {
|
|
2765
2663
|
if (autoScroll && messagesContainerRef.current && !showHistory && !isMinimized) {
|
|
2766
2664
|
messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
|
|
2767
2665
|
}
|
|
2768
2666
|
}, [messages, loading, showHistory, isMinimized, autoScroll]);
|
|
2769
2667
|
useClickOutside(historyPanelRef, () => setShowHistory(false), showHistory);
|
|
2770
|
-
const handleDeleteConversation =
|
|
2668
|
+
const handleDeleteConversation = useCallback10((conversationId) => {
|
|
2771
2669
|
onDeleteConversation?.(conversationId);
|
|
2772
2670
|
}, [onDeleteConversation]);
|
|
2773
|
-
const handleMinimize =
|
|
2671
|
+
const handleMinimize = useCallback10(() => {
|
|
2774
2672
|
setIsMinimized(true);
|
|
2775
2673
|
onMinimize?.();
|
|
2776
2674
|
}, [onMinimize]);
|
|
2777
|
-
const handleRestore =
|
|
2675
|
+
const handleRestore = useCallback10(() => {
|
|
2778
2676
|
setIsMinimized(false);
|
|
2779
2677
|
onRestore?.();
|
|
2780
2678
|
}, [onRestore]);
|
|
2781
|
-
const handleCopy =
|
|
2679
|
+
const handleCopy = useCallback10((content) => {
|
|
2782
2680
|
const message = messages.find((m) => m.content === content);
|
|
2783
2681
|
if (message) {
|
|
2784
2682
|
onMessageCopy?.(message);
|
|
@@ -2956,7 +2854,7 @@ var Chat = ({
|
|
|
2956
2854
|
};
|
|
2957
2855
|
|
|
2958
2856
|
// src/components/Relation/Relation.tsx
|
|
2959
|
-
import { useCallback as
|
|
2857
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect12, memo as memo5 } from "react";
|
|
2960
2858
|
import {
|
|
2961
2859
|
ReactFlow,
|
|
2962
2860
|
useNodesState,
|
|
@@ -2970,7 +2868,7 @@ import {
|
|
|
2970
2868
|
ReactFlowProvider
|
|
2971
2869
|
} from "@xyflow/react";
|
|
2972
2870
|
import "@xyflow/react/dist/style.css";
|
|
2973
|
-
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2871
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2974
2872
|
var getIconEmoji = (iconType) => {
|
|
2975
2873
|
const map = {
|
|
2976
2874
|
war: "\u2694\uFE0F",
|
|
@@ -2992,16 +2890,77 @@ var getStatusColor = (status) => {
|
|
|
2992
2890
|
};
|
|
2993
2891
|
return map[status || "active"];
|
|
2994
2892
|
};
|
|
2995
|
-
var
|
|
2996
|
-
const
|
|
2893
|
+
var ConnectionHandles = ({ isDark, showHandles }) => {
|
|
2894
|
+
const handleStyle = {
|
|
2895
|
+
background: isDark ? "#ff8e8e" : "#ff6b6b",
|
|
2896
|
+
width: "8px",
|
|
2897
|
+
height: "8px",
|
|
2898
|
+
borderRadius: "50%",
|
|
2899
|
+
border: `1px solid ${isDark ? "#1e293b" : "#ffffff"}`,
|
|
2900
|
+
transition: "all 0.2s ease"
|
|
2901
|
+
};
|
|
2902
|
+
const hiddenHandleStyle = {
|
|
2903
|
+
opacity: 0,
|
|
2904
|
+
width: "0px",
|
|
2905
|
+
height: "0px",
|
|
2906
|
+
pointerEvents: "none"
|
|
2907
|
+
};
|
|
2908
|
+
const actualStyle = showHandles ? handleStyle : hiddenHandleStyle;
|
|
2909
|
+
return /* @__PURE__ */ jsxs18(Fragment5, { children: [
|
|
2910
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Top, id: "top-left", style: { ...actualStyle, left: "25%" } }),
|
|
2911
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Top, id: "top-left-source", style: { ...actualStyle, left: "25%" } }),
|
|
2912
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Top, id: "top-center", style: { ...actualStyle, left: "50%" } }),
|
|
2913
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Top, id: "top-center-source", style: { ...actualStyle, left: "50%" } }),
|
|
2914
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Top, id: "top-right", style: { ...actualStyle, left: "75%" } }),
|
|
2915
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Top, id: "top-right-source", style: { ...actualStyle, left: "75%" } }),
|
|
2916
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Right, id: "right-top", style: { ...actualStyle, top: "25%" } }),
|
|
2917
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Right, id: "right-top-source", style: { ...actualStyle, top: "25%" } }),
|
|
2918
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Right, id: "right-center", style: { ...actualStyle, top: "50%" } }),
|
|
2919
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Right, id: "right-center-source", style: { ...actualStyle, top: "50%" } }),
|
|
2920
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Right, id: "right-bottom", style: { ...actualStyle, top: "75%" } }),
|
|
2921
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Right, id: "right-bottom-source", style: { ...actualStyle, top: "75%" } }),
|
|
2922
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Bottom, id: "bottom-left", style: { ...actualStyle, left: "25%" } }),
|
|
2923
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Bottom, id: "bottom-left-source", style: { ...actualStyle, left: "25%" } }),
|
|
2924
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Bottom, id: "bottom-center", style: { ...actualStyle, left: "50%" } }),
|
|
2925
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Bottom, id: "bottom-center-source", style: { ...actualStyle, left: "50%" } }),
|
|
2926
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Bottom, id: "bottom-right", style: { ...actualStyle, left: "75%" } }),
|
|
2927
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Bottom, id: "bottom-right-source", style: { ...actualStyle, left: "75%" } }),
|
|
2928
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Left, id: "left-top", style: { ...actualStyle, top: "25%" } }),
|
|
2929
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Left, id: "left-top-source", style: { ...actualStyle, top: "25%" } }),
|
|
2930
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Left, id: "left-center", style: { ...actualStyle, top: "50%" } }),
|
|
2931
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Left, id: "left-center-source", style: { ...actualStyle, top: "50%" } }),
|
|
2932
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Left, id: "left-bottom", style: { ...actualStyle, top: "75%" } }),
|
|
2933
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Left, id: "left-bottom-source", style: { ...actualStyle, top: "75%" } }),
|
|
2934
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Top, id: "corner-top-left", style: { ...actualStyle, left: "10%" } }),
|
|
2935
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Top, id: "corner-top-left-source", style: { ...actualStyle, left: "10%" } }),
|
|
2936
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Top, id: "corner-top-right", style: { ...actualStyle, left: "90%" } }),
|
|
2937
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Top, id: "corner-top-right-source", style: { ...actualStyle, left: "90%" } }),
|
|
2938
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Bottom, id: "corner-bottom-left", style: { ...actualStyle, left: "10%" } }),
|
|
2939
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Bottom, id: "corner-bottom-left-source", style: { ...actualStyle, left: "10%" } }),
|
|
2940
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Bottom, id: "corner-bottom-right", style: { ...actualStyle, left: "90%" } }),
|
|
2941
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Bottom, id: "corner-bottom-right-source", style: { ...actualStyle, left: "90%" } }),
|
|
2942
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Left, id: "corner-left-top", style: { ...actualStyle, top: "10%" } }),
|
|
2943
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Left, id: "corner-left-top-source", style: { ...actualStyle, top: "10%" } }),
|
|
2944
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Left, id: "corner-left-bottom", style: { ...actualStyle, top: "90%" } }),
|
|
2945
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Left, id: "corner-left-bottom-source", style: { ...actualStyle, top: "90%" } }),
|
|
2946
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Right, id: "corner-right-top", style: { ...actualStyle, top: "10%" } }),
|
|
2947
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Right, id: "corner-right-top-source", style: { ...actualStyle, top: "10%" } }),
|
|
2948
|
+
/* @__PURE__ */ jsx24(Handle, { type: "target", position: Position.Right, id: "corner-right-bottom", style: { ...actualStyle, top: "90%" } }),
|
|
2949
|
+
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Right, id: "corner-right-bottom-source", style: { ...actualStyle, top: "90%" } })
|
|
2950
|
+
] });
|
|
2951
|
+
};
|
|
2952
|
+
var CustomNode = memo5(({ data, theme: propTheme }) => {
|
|
2953
|
+
const isDark = (data.theme || propTheme) === "dark";
|
|
2954
|
+
const showHandles = data.showHandles !== void 0 ? data.showHandles : false;
|
|
2997
2955
|
const nodeStyle = {
|
|
2998
2956
|
background: isDark ? "linear-gradient(135deg, #1e293b 0%, #0f172a 100%)" : "linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)",
|
|
2999
|
-
border: `2px solid ${isDark ? "rgba(255, 255, 255, 0.
|
|
2957
|
+
border: `2px solid ${isDark ? "rgba(255, 255, 255, 0.15)" : "rgba(0, 0, 0, 0.08)"}`,
|
|
3000
2958
|
borderRadius: "14px",
|
|
3001
|
-
boxShadow: isDark ? "0 8px 20px rgba(0, 0, 0, 0.
|
|
2959
|
+
boxShadow: isDark ? "0 8px 20px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2)" : "0 4px 12px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.05)",
|
|
3002
2960
|
minWidth: "240px",
|
|
3003
2961
|
cursor: "pointer",
|
|
3004
|
-
transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
|
|
2962
|
+
transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
2963
|
+
position: "relative"
|
|
3005
2964
|
};
|
|
3006
2965
|
const iconStyle = {
|
|
3007
2966
|
width: "52px",
|
|
@@ -3010,8 +2969,9 @@ var CustomNode = ({ data, theme = "light" }) => {
|
|
|
3010
2969
|
display: "flex",
|
|
3011
2970
|
alignItems: "center",
|
|
3012
2971
|
justifyContent: "center",
|
|
3013
|
-
background: isDark ? "rgba(255, 255, 255, 0.
|
|
3014
|
-
transition: "all 0.3s ease"
|
|
2972
|
+
background: isDark ? "linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.05) 100%)" : "linear-gradient(135deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.02) 100%)",
|
|
2973
|
+
transition: "all 0.3s ease",
|
|
2974
|
+
boxShadow: isDark ? "inset 0 1px 1px rgba(255, 255, 255, 0.1)" : "inset 0 1px 1px rgba(0, 0, 0, 0.02)"
|
|
3015
2975
|
};
|
|
3016
2976
|
const titleStyle = {
|
|
3017
2977
|
fontWeight: 700,
|
|
@@ -3020,7 +2980,8 @@ var CustomNode = ({ data, theme = "light" }) => {
|
|
|
3020
2980
|
whiteSpace: "nowrap",
|
|
3021
2981
|
overflow: "hidden",
|
|
3022
2982
|
textOverflow: "ellipsis",
|
|
3023
|
-
color: isDark ? "#ffffff" : "#1e293b"
|
|
2983
|
+
color: isDark ? "#ffffff" : "#1e293b",
|
|
2984
|
+
letterSpacing: isDark ? "0.3px" : "normal"
|
|
3024
2985
|
};
|
|
3025
2986
|
const subtitleStyle = {
|
|
3026
2987
|
fontSize: "11px",
|
|
@@ -3036,11 +2997,18 @@ var CustomNode = ({ data, theme = "light" }) => {
|
|
|
3036
2997
|
textOverflow: "ellipsis",
|
|
3037
2998
|
color: isDark ? "rgba(255, 255, 255, 0.45)" : "#94a3b8"
|
|
3038
2999
|
};
|
|
3039
|
-
return /* @__PURE__ */ jsxs18("div", { style: nodeStyle, children: [
|
|
3040
|
-
/* @__PURE__ */ jsx24(
|
|
3000
|
+
return /* @__PURE__ */ jsxs18("div", { style: nodeStyle, className: "relation-node", children: [
|
|
3001
|
+
/* @__PURE__ */ jsx24(ConnectionHandles, { isDark, showHandles }),
|
|
3041
3002
|
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", alignItems: "center", gap: "14px", padding: "14px 18px" }, children: [
|
|
3042
3003
|
/* @__PURE__ */ jsxs18("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
3043
|
-
/* @__PURE__ */ jsx24("div", { style: iconStyle, children: data.imageUrl ? /* @__PURE__ */ jsx24(
|
|
3004
|
+
/* @__PURE__ */ jsx24("div", { style: iconStyle, children: data.imageUrl ? /* @__PURE__ */ jsx24(
|
|
3005
|
+
"img",
|
|
3006
|
+
{
|
|
3007
|
+
src: data.imageUrl,
|
|
3008
|
+
alt: data.title,
|
|
3009
|
+
style: { width: "100%", height: "100%", objectFit: "cover", borderRadius: "12px" }
|
|
3010
|
+
}
|
|
3011
|
+
) : /* @__PURE__ */ jsx24("span", { style: { fontSize: "28px", filter: isDark ? "drop-shadow(0 1px 2px rgba(0,0,0,0.2))" : "none" }, children: getIconEmoji(data.iconType) }) }),
|
|
3044
3012
|
data.status && /* @__PURE__ */ jsx24("div", { style: {
|
|
3045
3013
|
position: "absolute",
|
|
3046
3014
|
bottom: "-2px",
|
|
@@ -3049,7 +3017,9 @@ var CustomNode = ({ data, theme = "light" }) => {
|
|
|
3049
3017
|
height: "12px",
|
|
3050
3018
|
borderRadius: "50%",
|
|
3051
3019
|
border: `2px solid ${isDark ? "#1e293b" : "#ffffff"}`,
|
|
3052
|
-
backgroundColor: getStatusColor(data.status)
|
|
3020
|
+
backgroundColor: getStatusColor(data.status),
|
|
3021
|
+
animation: data.status === "warning" ? "pulse 2s infinite" : "none",
|
|
3022
|
+
boxShadow: isDark ? "0 0 0 1px rgba(0,0,0,0.2)" : "none"
|
|
3053
3023
|
} })
|
|
3054
3024
|
] }),
|
|
3055
3025
|
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
@@ -3057,13 +3027,21 @@ var CustomNode = ({ data, theme = "light" }) => {
|
|
|
3057
3027
|
/* @__PURE__ */ jsx24("div", { style: subtitleStyle, children: data.subtitle }),
|
|
3058
3028
|
data.description && /* @__PURE__ */ jsx24("div", { style: descriptionStyle, children: data.description })
|
|
3059
3029
|
] })
|
|
3060
|
-
] })
|
|
3061
|
-
/* @__PURE__ */ jsx24(Handle, { type: "source", position: Position.Bottom, isConnectable: true })
|
|
3030
|
+
] })
|
|
3062
3031
|
] });
|
|
3063
|
-
};
|
|
3032
|
+
});
|
|
3033
|
+
CustomNode.displayName = "CustomNode";
|
|
3064
3034
|
var nodeTypes = {
|
|
3065
3035
|
custom: CustomNode
|
|
3066
3036
|
};
|
|
3037
|
+
var getEdgeStyle = (theme, isHovered, isSelected) => {
|
|
3038
|
+
const baseColor = theme === "dark" ? "#7c8ba0" : "#a0aec0";
|
|
3039
|
+
const hoverColor = "#ff8e8e";
|
|
3040
|
+
const selectedColor = "#ff6b6b";
|
|
3041
|
+
if (isSelected) return { stroke: selectedColor, strokeWidth: 2.5 };
|
|
3042
|
+
if (isHovered) return { stroke: hoverColor, strokeWidth: 2.5 };
|
|
3043
|
+
return { stroke: baseColor, strokeWidth: 1.8 };
|
|
3044
|
+
};
|
|
3067
3045
|
var RelationContent = ({
|
|
3068
3046
|
nodes: propNodes,
|
|
3069
3047
|
edges: propEdges,
|
|
@@ -3087,59 +3065,84 @@ var RelationContent = ({
|
|
|
3087
3065
|
enableEdgeCreation = true,
|
|
3088
3066
|
enableNodeDrag = true,
|
|
3089
3067
|
onNodeContextMenu,
|
|
3090
|
-
theme: propTheme = "light"
|
|
3068
|
+
theme: propTheme = "light",
|
|
3069
|
+
edgeStyles = {},
|
|
3070
|
+
nodeStyles = {},
|
|
3071
|
+
showHandles = false
|
|
3091
3072
|
}) => {
|
|
3092
|
-
const [nodes, , onNodesChange] = useNodesState(propNodes || []);
|
|
3073
|
+
const [nodes, setNodes, onNodesChange] = useNodesState(propNodes || []);
|
|
3093
3074
|
const [edges, setEdges, onEdgesChange] = useEdgesState(propEdges || []);
|
|
3094
3075
|
const { fitView: fitViewFn } = useReactFlow();
|
|
3095
3076
|
const theme = propTheme;
|
|
3096
3077
|
const isDark = theme === "dark";
|
|
3097
3078
|
const bgColor = isDark ? "#0f172a" : "#f5f7fa";
|
|
3098
|
-
|
|
3079
|
+
useEffect12(() => {
|
|
3099
3080
|
if (fitView && fitViewFn && (propNodes?.length || 0) > 0) {
|
|
3100
|
-
setTimeout(() => {
|
|
3101
|
-
fitViewFn({ duration: 300, ...fitViewOptions }).catch((error) => {
|
|
3081
|
+
const timer = setTimeout(() => {
|
|
3082
|
+
fitViewFn({ duration: 300, padding: 0.2, ...fitViewOptions }).catch((error) => {
|
|
3102
3083
|
console.warn("Fit view failed:", error);
|
|
3103
3084
|
});
|
|
3104
3085
|
}, 100);
|
|
3086
|
+
return () => clearTimeout(timer);
|
|
3105
3087
|
}
|
|
3106
3088
|
}, [fitView, fitViewFn, fitViewOptions, propNodes]);
|
|
3107
|
-
|
|
3089
|
+
useEffect12(() => {
|
|
3090
|
+
if (propNodes) {
|
|
3091
|
+
setNodes(propNodes);
|
|
3092
|
+
}
|
|
3093
|
+
}, [propNodes, setNodes]);
|
|
3094
|
+
useEffect12(() => {
|
|
3095
|
+
if (propEdges) {
|
|
3096
|
+
setEdges(propEdges);
|
|
3097
|
+
}
|
|
3098
|
+
}, [propEdges, setEdges]);
|
|
3099
|
+
const handleNodesChange = useCallback11(
|
|
3108
3100
|
(changes) => {
|
|
3109
3101
|
onNodesChange(changes);
|
|
3110
3102
|
if (onNodesChangeProp) {
|
|
3111
|
-
|
|
3103
|
+
setTimeout(() => {
|
|
3104
|
+
onNodesChangeProp(nodes);
|
|
3105
|
+
}, 0);
|
|
3112
3106
|
}
|
|
3113
3107
|
},
|
|
3114
3108
|
[onNodesChange, onNodesChangeProp, nodes]
|
|
3115
3109
|
);
|
|
3116
|
-
const handleEdgesChange =
|
|
3110
|
+
const handleEdgesChange = useCallback11(
|
|
3117
3111
|
(changes) => {
|
|
3118
3112
|
onEdgesChange(changes);
|
|
3119
3113
|
if (onEdgesChangeProp) {
|
|
3120
|
-
|
|
3114
|
+
setTimeout(() => {
|
|
3115
|
+
onEdgesChangeProp(edges);
|
|
3116
|
+
}, 0);
|
|
3121
3117
|
}
|
|
3122
3118
|
},
|
|
3123
3119
|
[onEdgesChange, onEdgesChangeProp, edges]
|
|
3124
3120
|
);
|
|
3125
|
-
const onConnect =
|
|
3121
|
+
const onConnect = useCallback11(
|
|
3126
3122
|
(params) => {
|
|
3127
3123
|
const newEdge = {
|
|
3128
3124
|
...params,
|
|
3129
|
-
id: `edge-${Date.now()}-${Math.random()}`,
|
|
3130
|
-
type: "
|
|
3131
|
-
style: { stroke: "#
|
|
3132
|
-
markerEnd: {
|
|
3133
|
-
|
|
3125
|
+
id: `edge-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
|
|
3126
|
+
type: "straight",
|
|
3127
|
+
style: { stroke: edgeStyles.defaultColor || (isDark ? "#7c8ba0" : "#a0aec0"), strokeWidth: 1.8 },
|
|
3128
|
+
markerEnd: {
|
|
3129
|
+
type: MarkerType.ArrowClosed,
|
|
3130
|
+
color: edgeStyles.defaultColor || (isDark ? "#7c8ba0" : "#a0aec0"),
|
|
3131
|
+
width: 12,
|
|
3132
|
+
height: 12
|
|
3133
|
+
},
|
|
3134
|
+
label: "",
|
|
3135
|
+
labelStyle: { fill: isDark ? "#fff" : "#333", fontSize: 11, fontWeight: 400 },
|
|
3136
|
+
labelBgStyle: { fill: "transparent", fillOpacity: 0 }
|
|
3134
3137
|
};
|
|
3135
3138
|
setEdges((eds) => addEdge(newEdge, eds));
|
|
3136
3139
|
if (onConnectProp) {
|
|
3137
3140
|
onConnectProp(params);
|
|
3138
3141
|
}
|
|
3139
3142
|
},
|
|
3140
|
-
[setEdges, onConnectProp]
|
|
3143
|
+
[setEdges, onConnectProp, edgeStyles.defaultColor, isDark]
|
|
3141
3144
|
);
|
|
3142
|
-
const handleNodeClick =
|
|
3145
|
+
const handleNodeClick = useCallback11(
|
|
3143
3146
|
(_event, node) => {
|
|
3144
3147
|
if (onNodeClick && node.data) {
|
|
3145
3148
|
onNodeClick(node.id, node.data, _event);
|
|
@@ -3147,7 +3150,7 @@ var RelationContent = ({
|
|
|
3147
3150
|
},
|
|
3148
3151
|
[onNodeClick]
|
|
3149
3152
|
);
|
|
3150
|
-
const handleNodeDoubleClick =
|
|
3153
|
+
const handleNodeDoubleClick = useCallback11(
|
|
3151
3154
|
(_event, node) => {
|
|
3152
3155
|
if (onNodeDoubleClick && node.data) {
|
|
3153
3156
|
onNodeDoubleClick(node.id, node.data);
|
|
@@ -3155,7 +3158,7 @@ var RelationContent = ({
|
|
|
3155
3158
|
},
|
|
3156
3159
|
[onNodeDoubleClick]
|
|
3157
3160
|
);
|
|
3158
|
-
const handleNodeContextMenu =
|
|
3161
|
+
const handleNodeContextMenu = useCallback11(
|
|
3159
3162
|
(event, node) => {
|
|
3160
3163
|
event.preventDefault();
|
|
3161
3164
|
if (onNodeContextMenu && node.data) {
|
|
@@ -3164,7 +3167,7 @@ var RelationContent = ({
|
|
|
3164
3167
|
},
|
|
3165
3168
|
[onNodeContextMenu]
|
|
3166
3169
|
);
|
|
3167
|
-
const handleEdgeClick =
|
|
3170
|
+
const handleEdgeClick = useCallback11(
|
|
3168
3171
|
(_event, edge) => {
|
|
3169
3172
|
if (onEdgeClick) {
|
|
3170
3173
|
onEdgeClick(edge.id, edge.data);
|
|
@@ -3172,18 +3175,107 @@ var RelationContent = ({
|
|
|
3172
3175
|
},
|
|
3173
3176
|
[onEdgeClick]
|
|
3174
3177
|
);
|
|
3175
|
-
const nodesWithTheme =
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3178
|
+
const nodesWithTheme = React13.useMemo(() => {
|
|
3179
|
+
return nodes.map((node) => ({
|
|
3180
|
+
...node,
|
|
3181
|
+
data: {
|
|
3182
|
+
...node.data,
|
|
3183
|
+
theme,
|
|
3184
|
+
showHandles
|
|
3185
|
+
},
|
|
3186
|
+
className: `relation-node ${node.className || ""}`
|
|
3187
|
+
}));
|
|
3188
|
+
}, [nodes, theme, showHandles]);
|
|
3189
|
+
const edgesWithStyle = React13.useMemo(() => {
|
|
3190
|
+
return edges.map((edge) => ({
|
|
3191
|
+
...edge,
|
|
3192
|
+
type: edge.type || "straight",
|
|
3193
|
+
style: {
|
|
3194
|
+
...edge.style,
|
|
3195
|
+
...getEdgeStyle(theme)
|
|
3196
|
+
},
|
|
3197
|
+
labelStyle: {
|
|
3198
|
+
fill: isDark ? "#fff" : "#333",
|
|
3199
|
+
fontSize: 11,
|
|
3200
|
+
fontWeight: 400,
|
|
3201
|
+
...edge.labelStyle
|
|
3202
|
+
},
|
|
3203
|
+
labelBgStyle: {
|
|
3204
|
+
fill: "transparent",
|
|
3205
|
+
fillOpacity: 0,
|
|
3206
|
+
...edge.labelBgStyle
|
|
3207
|
+
},
|
|
3208
|
+
markerEnd: {
|
|
3209
|
+
type: MarkerType.ArrowClosed,
|
|
3210
|
+
color: edgeStyles.defaultColor || (isDark ? "#7c8ba0" : "#a0aec0"),
|
|
3211
|
+
width: 12,
|
|
3212
|
+
height: 12,
|
|
3213
|
+
...edge.markerEnd
|
|
3214
|
+
}
|
|
3215
|
+
}));
|
|
3216
|
+
}, [edges, theme, isDark, edgeStyles.defaultColor]);
|
|
3179
3217
|
const globalStyle = `
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3218
|
+
.relation-container {
|
|
3219
|
+
position: relative;
|
|
3220
|
+
width: 100%;
|
|
3221
|
+
height: 100%;
|
|
3222
|
+
overflow: hidden;
|
|
3223
|
+
}
|
|
3224
|
+
.react-flow__background,
|
|
3225
|
+
.react-flow__pane,
|
|
3226
|
+
.react-flow__renderer,
|
|
3227
|
+
.react-flow__viewport {
|
|
3228
|
+
background-color: ${bgColor} !important;
|
|
3229
|
+
}
|
|
3230
|
+
.relation-node {
|
|
3231
|
+
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease;
|
|
3232
|
+
}
|
|
3233
|
+
.relation-node:hover {
|
|
3234
|
+
transform: translateY(-4px) scale(1.02);
|
|
3235
|
+
box-shadow: ${isDark ? "0 12px 28px rgba(0, 0, 0, 0.4), 0 2px 4px rgba(0, 0, 0, 0.2)" : "0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.05)"};
|
|
3236
|
+
}
|
|
3237
|
+
.react-flow__edge-path {
|
|
3238
|
+
transition: stroke-width 0.2s ease, stroke 0.2s ease;
|
|
3239
|
+
}
|
|
3240
|
+
.react-flow__edge:hover .react-flow__edge-path {
|
|
3241
|
+
stroke-width: 2.5px;
|
|
3242
|
+
stroke: ${edgeStyles.hoverColor || (isDark ? "#ffa5a5" : "#ff8e8e")};
|
|
3243
|
+
}
|
|
3244
|
+
/* \u8FDE\u63A5\u70B9\u60AC\u505C\u6548\u679C */
|
|
3245
|
+
.react-flow__handle {
|
|
3246
|
+
transition: all 0.2s ease;
|
|
3247
|
+
}
|
|
3248
|
+
.react-flow__handle:hover {
|
|
3249
|
+
transform: scale(1.3);
|
|
3250
|
+
background-color: ${isDark ? "#ffa5a5" : "#ff8e8e"} !important;
|
|
3251
|
+
}
|
|
3252
|
+
@keyframes pulse {
|
|
3253
|
+
0%, 100% {
|
|
3254
|
+
opacity: 1;
|
|
3255
|
+
transform: scale(1);
|
|
3256
|
+
}
|
|
3257
|
+
50% {
|
|
3258
|
+
opacity: 0.7;
|
|
3259
|
+
transform: scale(1.2);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
/* \u7B80\u7EA6\u6EDA\u52A8\u6761 */
|
|
3263
|
+
.relation-container ::-webkit-scrollbar {
|
|
3264
|
+
width: 6px;
|
|
3265
|
+
height: 6px;
|
|
3266
|
+
}
|
|
3267
|
+
.relation-container ::-webkit-scrollbar-track {
|
|
3268
|
+
background: ${isDark ? "#1e293b" : "#e2e8f0"};
|
|
3269
|
+
border-radius: 3px;
|
|
3270
|
+
}
|
|
3271
|
+
.relation-container ::-webkit-scrollbar-thumb {
|
|
3272
|
+
background: ${isDark ? "#475569" : "#cbd5e1"};
|
|
3273
|
+
border-radius: 3px;
|
|
3274
|
+
}
|
|
3275
|
+
.relation-container ::-webkit-scrollbar-thumb:hover {
|
|
3276
|
+
background: ${isDark ? "#ff8e8e" : "#ff6b6b"};
|
|
3277
|
+
}
|
|
3278
|
+
`;
|
|
3187
3279
|
return /* @__PURE__ */ jsxs18(
|
|
3188
3280
|
"div",
|
|
3189
3281
|
{
|
|
@@ -3192,9 +3284,8 @@ var RelationContent = ({
|
|
|
3192
3284
|
width,
|
|
3193
3285
|
height,
|
|
3194
3286
|
...style,
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
backgroundColor: bgColor
|
|
3287
|
+
backgroundColor: bgColor,
|
|
3288
|
+
borderRadius: nodeStyles.borderRadius || "12px"
|
|
3198
3289
|
},
|
|
3199
3290
|
children: [
|
|
3200
3291
|
/* @__PURE__ */ jsx24("style", { children: globalStyle }),
|
|
@@ -3202,7 +3293,7 @@ var RelationContent = ({
|
|
|
3202
3293
|
ReactFlow,
|
|
3203
3294
|
{
|
|
3204
3295
|
nodes: nodesWithTheme,
|
|
3205
|
-
edges,
|
|
3296
|
+
edges: edgesWithStyle,
|
|
3206
3297
|
onNodesChange: handleNodesChange,
|
|
3207
3298
|
onEdgesChange: handleEdgesChange,
|
|
3208
3299
|
onConnect: enableEdgeCreation ? onConnect : void 0,
|
|
@@ -3220,15 +3311,24 @@ var RelationContent = ({
|
|
|
3220
3311
|
snapGrid,
|
|
3221
3312
|
nodesDraggable: enableNodeDrag,
|
|
3222
3313
|
nodesConnectable: enableEdgeCreation,
|
|
3223
|
-
connectionLineType: ConnectionLineType.
|
|
3224
|
-
connectionLineStyle: {
|
|
3314
|
+
connectionLineType: ConnectionLineType.Straight,
|
|
3315
|
+
connectionLineStyle: {
|
|
3316
|
+
stroke: edgeStyles.defaultColor || (isDark ? "#7c8ba0" : "#a0aec0"),
|
|
3317
|
+
strokeWidth: 1.8
|
|
3318
|
+
},
|
|
3225
3319
|
attributionPosition: "bottom-right",
|
|
3226
3320
|
zoomOnScroll: true,
|
|
3227
3321
|
zoomOnPinch: true,
|
|
3228
3322
|
zoomOnDoubleClick: false,
|
|
3229
3323
|
panOnScroll: false,
|
|
3230
3324
|
panOnDrag: true,
|
|
3231
|
-
proOptions: { hideAttribution: true }
|
|
3325
|
+
proOptions: { hideAttribution: true },
|
|
3326
|
+
elevateEdgesOnSelect: true,
|
|
3327
|
+
defaultEdgeOptions: {
|
|
3328
|
+
type: "straight",
|
|
3329
|
+
style: { stroke: edgeStyles.defaultColor || (isDark ? "#7c8ba0" : "#a0aec0"), strokeWidth: 1.8 },
|
|
3330
|
+
markerEnd: { type: MarkerType.ArrowClosed, width: 12, height: 12 }
|
|
3331
|
+
}
|
|
3232
3332
|
}
|
|
3233
3333
|
)
|
|
3234
3334
|
]
|