@@ -20,19 +20,19 @@ const getDefaultText = (type) => {
20
20
const renderDefaultIcon = (type ) => {
21
21
switch (type) {
22
22
case ' draft' :
23
- return ` <svg class="w-4 h-4 text-gray-500 hover:opacity-80 cursor-pointer peer " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
23
+ return ` <svg class="w-4 h-4 text-gray-500 hover:opacity-80 cursor-pointer status-icon " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
24
24
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
25
25
</svg>` ;
26
26
case ' new' :
27
- return ` <svg class="w-4 h-4 text-green-500 hover:opacity-80 cursor-pointer peer " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
27
+ return ` <svg class="w-4 h-4 text-green-500 hover:opacity-80 cursor-pointer status-icon " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
28
28
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
29
29
</svg>` ;
30
30
case ' deprecated' :
31
- return ` <svg class="w-4 h-4 text-red-500 hover:opacity-80 cursor-pointer peer " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
31
+ return ` <svg class="w-4 h-4 text-red-500 hover:opacity-80 cursor-pointer status-icon " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
32
32
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
33
33
</svg>` ;
34
34
case ' updated' :
35
- return ` <svg class="w-4 h-4 text-blue-500 hover:opacity-80 cursor-pointer peer " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
35
+ return ` <svg class="w-4 h-4 text-blue-500 hover:opacity-80 cursor-pointer status-icon " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
36
36
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
37
37
</svg>` ;
38
38
default :
@@ -43,30 +43,94 @@ const renderDefaultIcon = (type) => {
43
43
44
44
<% if (item .status ? .type ) { % >
45
45
< div class = " inline-flex items-center" >
46
- < div class = " relative" >
46
+ < div data - tooltip = " <%= item.status.text || getDefaultText(item.status.type) %> " class = " relative status-container " >
47
47
< % if (item .status .type === ' custom' ) { % >
48
48
< % if (locals .siteData .feature ? .lucide ? .enable && item .status .icon ) { % >
49
49
<!-- Lucide 图标 -->
50
- < i data- lucide= " <%= item.status.icon %>" class = " w-4 h-4 text-gray-600 hover:opacity-80 cursor-pointer peer " >< / i>
50
+ < i data- lucide= " <%= item.status.icon %>" class = " w-4 h-4 text-gray-600 hover:opacity-80 cursor-pointer status-icon " >< / i>
51
51
< % } else if (item .status .icon && item .status .icon .includes (' <svg' )) { % >
52
52
<!-- 自定义 SVG 图标 -->
53
- < span class = " inline-block w-4 h-4 hover:opacity-80 cursor-pointer peer " >
53
+ < span class = " inline-block w-4 h-4 hover:opacity-80 cursor-pointer status-icon " >
54
54
< %- item .status .icon % >
55
55
< / span>
56
56
< % } else { % >
57
57
<!-- 默认图标,当没有提供有效的图标时 -->
58
- < svg class = " w-4 h-4 text-gray-500 hover:opacity-80 cursor-pointer peer " xmlns= " http://www.w3.org/2000/svg" fill= " none" viewBox= " 0 0 24 24"
58
+ < svg class = " w-4 h-4 text-gray-500 hover:opacity-80 cursor-pointer status-icon " xmlns= " http://www.w3.org/2000/svg" fill= " none" viewBox= " 0 0 24 24"
59
59
stroke= " currentColor" >
60
60
< path stroke- linecap= " round" stroke- linejoin= " round" stroke- width= " 2" d= " M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" / >
61
61
< / svg>
62
62
< % } % >
63
63
< % } else { % >
64
64
< %- renderDefaultIcon (item .status .type ) % >
65
65
< % } % >
66
-
67
- < span class = " absolute left-1/2 -translate-x-1/2 -top-8 px-2 py-1 bg-gray-900 text-white text-xs rounded scale-0 peer-hover:scale-100 transition-transform duration-100 origin-bottom pointer-events-none" >
68
- < %= item .status .text || getDefaultText (item .status .type ) % >
69
- < / span>
70
66
< / div>
71
67
< / div>
68
+
69
+ < script>
70
+ document .addEventListener (' DOMContentLoaded' , () => {
71
+ // 创建或获取 tooltips 容器
72
+ let tooltipContainer = document .getElementById (' tooltip-container' );
73
+ if (! tooltipContainer) {
74
+ tooltipContainer = document .createElement (' div' );
75
+ tooltipContainer .id = ' tooltip-container' ;
76
+ document .body .appendChild (tooltipContainer);
77
+ }
78
+
79
+ // 创建单个 tooltip 元素
80
+ const tooltip = document .createElement (' div' );
81
+ tooltip .className = ' fixed hidden px-2 py-1 bg-gray-900 text-white text-xs rounded whitespace-nowrap z-[9999] pointer-events-none transition-opacity duration-200' ;
82
+ tooltipContainer .appendChild (tooltip);
83
+
84
+ // 监听所有状态图标
85
+ document .querySelectorAll (' .status-container' ).forEach (container => {
86
+ const icon = container .querySelector (' .status-icon' );
87
+ const text = container .dataset .tooltip ;
88
+
89
+ container .addEventListener (' mouseenter' , () => {
90
+ const rect = container .getBoundingClientRect ();
91
+ tooltip .textContent = text;
92
+ tooltip .style .display = ' block' ;
93
+
94
+ // 获取 tooltip 的尺寸
95
+ const tooltipRect = tooltip .getBoundingClientRect ();
96
+
97
+ // 计算位置
98
+ let top = rect .top - tooltipRect .height - 8 ;
99
+ const left = rect .left + (rect .width - tooltipRect .width ) / 2 ;
100
+
101
+ // 如果顶部空间不足,显示在底部
102
+ if (top < 8 ) {
103
+ top = rect .bottom + 8 ;
104
+ }
105
+
106
+ tooltip .style .top = ` ${ top} px` ;
107
+ tooltip .style .left = ` ${ left} px` ;
108
+ });
109
+
110
+ container .addEventListener (' mouseleave' , () => {
111
+ tooltip .style .display = ' none' ;
112
+ });
113
+ });
114
+
115
+ // 处理页面滚动时更新位置
116
+ window .addEventListener (' scroll' , () => {
117
+ const visibleTooltip = document .querySelector (' #tooltip-container div[style*="display: block"]' );
118
+ if (visibleTooltip) {
119
+ const container = document .querySelector (' .status-container:hover' );
120
+ if (container) {
121
+ const rect = container .getBoundingClientRect ();
122
+ const tooltipRect = visibleTooltip .getBoundingClientRect ();
123
+
124
+ let top = rect .top - tooltipRect .height - 8 ;
125
+ if (top < 8 ) {
126
+ top = rect .bottom + 8 ;
127
+ }
128
+
129
+ visibleTooltip .style .top = ` ${ top} px` ;
130
+ visibleTooltip .style .left = ` ${ rect .left + (rect .width - tooltipRect .width ) / 2 } px` ;
131
+ }
132
+ }
133
+ }, {passive: true });
134
+ });
135
+ < / script>
72
136
< % } % >
0 commit comments