wssf-kage-ui 0.1.2 → 0.1.3
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/cjs/Alert/index.d.ts +37 -0
- package/dist/cjs/Alert/index.js +124 -0
- package/dist/cjs/Alert/style.less +248 -0
- package/dist/cjs/Drawer/index.d.ts +57 -0
- package/dist/cjs/Drawer/index.js +203 -0
- package/dist/cjs/Drawer/style.less +215 -0
- package/dist/cjs/FloatButton/index.d.ts +54 -0
- package/dist/cjs/FloatButton/index.js +119 -0
- package/dist/cjs/FloatButton/style.less +266 -0
- package/dist/cjs/Message/index.d.ts +38 -0
- package/dist/cjs/Message/index.js +292 -0
- package/dist/cjs/Message/style.less +183 -0
- package/dist/cjs/Modal/index.d.ts +63 -0
- package/dist/cjs/Modal/index.js +254 -0
- package/dist/cjs/Modal/style.less +298 -0
- package/dist/cjs/Notification/index.d.ts +48 -0
- package/dist/cjs/Notification/index.js +340 -0
- package/dist/cjs/Notification/style.less +260 -0
- package/dist/cjs/Popconfirm/index.d.ts +58 -0
- package/dist/cjs/Popconfirm/index.js +393 -0
- package/dist/cjs/Popconfirm/style.less +417 -0
- package/dist/cjs/Progress/index.d.ts +43 -0
- package/dist/cjs/Progress/index.js +213 -0
- package/dist/cjs/Progress/style.less +206 -0
- package/dist/cjs/Result/index.d.ts +25 -0
- package/dist/cjs/Result/index.js +63 -0
- package/dist/cjs/Result/style.less +111 -0
- package/dist/cjs/Skeleton/index.d.ts +88 -0
- package/dist/cjs/Skeleton/index.js +207 -0
- package/dist/cjs/Skeleton/style.less +487 -0
- package/dist/cjs/Spin/index.d.ts +25 -0
- package/dist/cjs/Spin/index.js +98 -0
- package/dist/cjs/Spin/style.less +169 -0
- package/dist/cjs/Tree/index.d.ts +82 -0
- package/dist/cjs/Tree/index.js +226 -0
- package/dist/cjs/Tree/style.less +313 -0
- package/dist/cjs/Watermark/index.d.ts +41 -0
- package/dist/cjs/Watermark/index.js +353 -0
- package/dist/cjs/Watermark/style.less +31 -0
- package/dist/cjs/index.d.ts +27 -1
- package/dist/cjs/index.js +91 -0
- package/dist/esm/Alert/index.d.ts +37 -0
- package/dist/esm/Alert/index.js +121 -0
- package/dist/esm/Alert/style.less +248 -0
- package/dist/esm/Drawer/index.d.ts +57 -0
- package/dist/esm/Drawer/index.js +202 -0
- package/dist/esm/Drawer/style.less +215 -0
- package/dist/esm/FloatButton/index.d.ts +54 -0
- package/dist/esm/FloatButton/index.js +123 -0
- package/dist/esm/FloatButton/style.less +266 -0
- package/dist/esm/Message/index.d.ts +38 -0
- package/dist/esm/Message/index.js +294 -0
- package/dist/esm/Message/style.less +183 -0
- package/dist/esm/Modal/index.d.ts +63 -0
- package/dist/esm/Modal/index.js +251 -0
- package/dist/esm/Modal/style.less +298 -0
- package/dist/esm/Notification/index.d.ts +48 -0
- package/dist/esm/Notification/index.js +345 -0
- package/dist/esm/Notification/style.less +260 -0
- package/dist/esm/Popconfirm/index.d.ts +58 -0
- package/dist/esm/Popconfirm/index.js +389 -0
- package/dist/esm/Popconfirm/style.less +417 -0
- package/dist/esm/Progress/index.d.ts +43 -0
- package/dist/esm/Progress/index.js +208 -0
- package/dist/esm/Progress/style.less +206 -0
- package/dist/esm/Result/index.d.ts +25 -0
- package/dist/esm/Result/index.js +57 -0
- package/dist/esm/Result/style.less +111 -0
- package/dist/esm/Skeleton/index.d.ts +88 -0
- package/dist/esm/Skeleton/index.js +213 -0
- package/dist/esm/Skeleton/style.less +487 -0
- package/dist/esm/Spin/index.d.ts +25 -0
- package/dist/esm/Spin/index.js +95 -0
- package/dist/esm/Spin/style.less +169 -0
- package/dist/esm/Tree/index.d.ts +82 -0
- package/dist/esm/Tree/index.js +225 -0
- package/dist/esm/Tree/style.less +313 -0
- package/dist/esm/Watermark/index.d.ts +41 -0
- package/dist/esm/Watermark/index.js +349 -0
- package/dist/esm/Watermark/style.less +31 -0
- package/dist/esm/index.d.ts +27 -1
- package/dist/esm/index.js +14 -1
- package/package.json +1 -1
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
// Tree 树形控件样式
|
|
2
|
+
|
|
3
|
+
@prefix: kage-tree;
|
|
4
|
+
|
|
5
|
+
// 颜色变量
|
|
6
|
+
@tree-bg: #fff;
|
|
7
|
+
@tree-color: rgba(0, 0, 0, 0.85);
|
|
8
|
+
@tree-border-color: #d9d9d9;
|
|
9
|
+
@tree-selected-bg: #e6f7ff;
|
|
10
|
+
@tree-selected-color: rgba(0, 0, 0, 0.85);
|
|
11
|
+
@tree-hover-bg: #f5f5f5;
|
|
12
|
+
@tree-disabled-color: rgba(0, 0, 0, 0.25);
|
|
13
|
+
|
|
14
|
+
// ============ 主容器 ============
|
|
15
|
+
.@{prefix} {
|
|
16
|
+
padding: 4px 0;
|
|
17
|
+
font-size: 14px;
|
|
18
|
+
line-height: 1.5715;
|
|
19
|
+
color: @tree-color;
|
|
20
|
+
background: @tree-bg;
|
|
21
|
+
|
|
22
|
+
* {
|
|
23
|
+
box-sizing: border-box;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ============ 树节点 ============
|
|
28
|
+
.@{prefix}-treenode {
|
|
29
|
+
position: relative;
|
|
30
|
+
padding: 0;
|
|
31
|
+
margin: 0;
|
|
32
|
+
list-style: none;
|
|
33
|
+
outline: none;
|
|
34
|
+
|
|
35
|
+
&-disabled {
|
|
36
|
+
.@{prefix}-node-content {
|
|
37
|
+
color: @tree-disabled-color;
|
|
38
|
+
cursor: not-allowed;
|
|
39
|
+
|
|
40
|
+
.@{prefix}-title {
|
|
41
|
+
color: @tree-disabled-color;
|
|
42
|
+
cursor: not-allowed;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&-block-node {
|
|
48
|
+
.@{prefix}-node-content {
|
|
49
|
+
width: 100%;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ============ 节点内容 ============
|
|
55
|
+
.@{prefix}-node-content {
|
|
56
|
+
position: relative;
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
min-height: 24px;
|
|
60
|
+
padding: 0 4px;
|
|
61
|
+
margin: 0;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
transition: background-color 0.2s, color 0.2s;
|
|
64
|
+
|
|
65
|
+
&:hover {
|
|
66
|
+
background-color: @tree-hover-bg;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ============ 选中状态 ============
|
|
71
|
+
.@{prefix}-treenode-selected {
|
|
72
|
+
> .@{prefix}-node-content {
|
|
73
|
+
background-color: @tree-selected-bg;
|
|
74
|
+
color: @tree-selected-color;
|
|
75
|
+
|
|
76
|
+
.@{prefix}-title {
|
|
77
|
+
color: @tree-selected-color;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&:hover {
|
|
81
|
+
background-color: @tree-selected-bg;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============ 展开/收起图标 ============
|
|
87
|
+
.@{prefix}-switcher {
|
|
88
|
+
display: inline-flex;
|
|
89
|
+
align-items: center;
|
|
90
|
+
justify-content: center;
|
|
91
|
+
width: 24px;
|
|
92
|
+
height: 24px;
|
|
93
|
+
margin-right: 4px;
|
|
94
|
+
color: rgba(0, 0, 0, 0.45);
|
|
95
|
+
font-size: 12px;
|
|
96
|
+
line-height: 1;
|
|
97
|
+
text-align: center;
|
|
98
|
+
vertical-align: top;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
transition: transform 0.2s, color 0.2s;
|
|
101
|
+
flex-shrink: 0;
|
|
102
|
+
|
|
103
|
+
&:hover {
|
|
104
|
+
color: rgba(0, 0, 0, 0.85);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&-open {
|
|
108
|
+
transform: rotate(90deg);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&-close {
|
|
112
|
+
transform: rotate(0deg);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&-noop {
|
|
116
|
+
cursor: default;
|
|
117
|
+
opacity: 0;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ============ 复选框 ============
|
|
122
|
+
.@{prefix}-checkbox {
|
|
123
|
+
display: inline-flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
width: 16px;
|
|
127
|
+
height: 16px;
|
|
128
|
+
margin-right: 8px;
|
|
129
|
+
color: #fff;
|
|
130
|
+
font-size: 12px;
|
|
131
|
+
line-height: 1;
|
|
132
|
+
text-align: center;
|
|
133
|
+
vertical-align: middle;
|
|
134
|
+
background-color: #fff;
|
|
135
|
+
border: 1px solid @tree-border-color;
|
|
136
|
+
border-radius: 2px;
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
transition: all 0.2s;
|
|
139
|
+
flex-shrink: 0;
|
|
140
|
+
|
|
141
|
+
&:hover {
|
|
142
|
+
border-color: #1890ff;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
&-checked {
|
|
146
|
+
color: #fff;
|
|
147
|
+
background-color: #1890ff;
|
|
148
|
+
border-color: #1890ff;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&-disabled {
|
|
152
|
+
color: rgba(0, 0, 0, 0.25);
|
|
153
|
+
background-color: #f5f5f5;
|
|
154
|
+
border-color: @tree-border-color;
|
|
155
|
+
cursor: not-allowed;
|
|
156
|
+
|
|
157
|
+
&:hover {
|
|
158
|
+
border-color: @tree-border-color;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ============ 图标 ============
|
|
164
|
+
.@{prefix}-icon {
|
|
165
|
+
display: inline-flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
margin-right: 8px;
|
|
168
|
+
font-size: 14px;
|
|
169
|
+
flex-shrink: 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ============ 标题 ============
|
|
173
|
+
.@{prefix}-title {
|
|
174
|
+
flex: 1;
|
|
175
|
+
display: inline-block;
|
|
176
|
+
padding: 0 4px;
|
|
177
|
+
overflow: hidden;
|
|
178
|
+
text-overflow: ellipsis;
|
|
179
|
+
white-space: nowrap;
|
|
180
|
+
vertical-align: top;
|
|
181
|
+
color: inherit;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ============ 子树 ============
|
|
185
|
+
.@{prefix}-child-tree {
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ============ 显示连接线 ============
|
|
190
|
+
.@{prefix}-show-line {
|
|
191
|
+
.@{prefix}-treenode {
|
|
192
|
+
position: relative;
|
|
193
|
+
|
|
194
|
+
&::before {
|
|
195
|
+
position: absolute;
|
|
196
|
+
top: 0;
|
|
197
|
+
left: 12px;
|
|
198
|
+
width: 1px;
|
|
199
|
+
height: 100%;
|
|
200
|
+
background-color: @tree-border-color;
|
|
201
|
+
content: '';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
&::after {
|
|
205
|
+
position: absolute;
|
|
206
|
+
top: 12px;
|
|
207
|
+
left: 12px;
|
|
208
|
+
width: 10px;
|
|
209
|
+
height: 1px;
|
|
210
|
+
background-color: @tree-border-color;
|
|
211
|
+
content: '';
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
&:last-child::before {
|
|
215
|
+
height: 12px;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.@{prefix}-switcher {
|
|
220
|
+
position: relative;
|
|
221
|
+
z-index: 1;
|
|
222
|
+
background-color: @tree-bg;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============ 暗色模式适配 ============
|
|
227
|
+
[data-theme='dark'],
|
|
228
|
+
[data-prefers-color-scheme='dark'],
|
|
229
|
+
[data-prefers-color='dark'],
|
|
230
|
+
html.dark,
|
|
231
|
+
body.dark,
|
|
232
|
+
.dark {
|
|
233
|
+
.@{prefix} {
|
|
234
|
+
background-color: #1f1f1f;
|
|
235
|
+
color: rgba(255, 255, 255, 0.85);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.@{prefix}-node-content {
|
|
239
|
+
&:hover {
|
|
240
|
+
background-color: rgba(255, 255, 255, 0.08);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.@{prefix}-treenode-selected {
|
|
245
|
+
> .@{prefix}-node-content {
|
|
246
|
+
background-color: rgba(24, 144, 255, 0.2);
|
|
247
|
+
color: rgba(255, 255, 255, 0.85);
|
|
248
|
+
|
|
249
|
+
.@{prefix}-title {
|
|
250
|
+
color: rgba(255, 255, 255, 0.85);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
&:hover {
|
|
254
|
+
background-color: rgba(24, 144, 255, 0.2);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.@{prefix}-treenode-disabled {
|
|
260
|
+
.@{prefix}-node-content {
|
|
261
|
+
color: rgba(255, 255, 255, 0.25);
|
|
262
|
+
|
|
263
|
+
.@{prefix}-title {
|
|
264
|
+
color: rgba(255, 255, 255, 0.25);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.@{prefix}-switcher {
|
|
270
|
+
color: rgba(255, 255, 255, 0.45);
|
|
271
|
+
|
|
272
|
+
&:hover {
|
|
273
|
+
color: rgba(255, 255, 255, 0.85);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.@{prefix}-checkbox {
|
|
278
|
+
background-color: #1f1f1f;
|
|
279
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
280
|
+
|
|
281
|
+
&:hover {
|
|
282
|
+
border-color: #1890ff;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
&-checked {
|
|
286
|
+
background-color: #1890ff;
|
|
287
|
+
border-color: #1890ff;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
&-disabled {
|
|
291
|
+
background-color: rgba(255, 255, 255, 0.08);
|
|
292
|
+
border-color: rgba(255, 255, 255, 0.15);
|
|
293
|
+
color: rgba(255, 255, 255, 0.25);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.@{prefix}-title {
|
|
298
|
+
color: rgba(255, 255, 255, 0.85);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.@{prefix}-show-line {
|
|
302
|
+
.@{prefix}-treenode {
|
|
303
|
+
&::before,
|
|
304
|
+
&::after {
|
|
305
|
+
background-color: rgba(255, 255, 255, 0.2);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.@{prefix}-switcher {
|
|
310
|
+
background-color: #1f1f1f;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { ReactNode, CSSProperties } from 'react';
|
|
2
|
+
import './style.less';
|
|
3
|
+
/** Watermark 属性 */
|
|
4
|
+
export interface WatermarkProps {
|
|
5
|
+
/** 水印内容(文字或图片 URL) */
|
|
6
|
+
content?: string | string[];
|
|
7
|
+
/** 图片地址(优先级高于 content) */
|
|
8
|
+
image?: string;
|
|
9
|
+
/** 水印宽度 */
|
|
10
|
+
width?: number;
|
|
11
|
+
/** 水印高度 */
|
|
12
|
+
height?: number;
|
|
13
|
+
/** 水印旋转角度 */
|
|
14
|
+
rotate?: number;
|
|
15
|
+
/** 水印透明度 */
|
|
16
|
+
opacity?: number;
|
|
17
|
+
/** 水印字体大小 */
|
|
18
|
+
fontSize?: number;
|
|
19
|
+
/** 水印字体颜色 */
|
|
20
|
+
fontColor?: string;
|
|
21
|
+
/** 水印字体 */
|
|
22
|
+
fontFamily?: string;
|
|
23
|
+
/** 水印之间的水平间距 */
|
|
24
|
+
gapX?: number;
|
|
25
|
+
/** 水印之间的垂直间距 */
|
|
26
|
+
gapY?: number;
|
|
27
|
+
/** 水印距离容器左边的偏移量 */
|
|
28
|
+
offsetLeft?: number;
|
|
29
|
+
/** 水印距离容器上边的偏移量 */
|
|
30
|
+
offsetTop?: number;
|
|
31
|
+
/** 水印层级 */
|
|
32
|
+
zIndex?: number;
|
|
33
|
+
/** 自定义类名 */
|
|
34
|
+
className?: string;
|
|
35
|
+
/** 自定义样式 */
|
|
36
|
+
style?: CSSProperties;
|
|
37
|
+
/** 子元素 */
|
|
38
|
+
children?: ReactNode;
|
|
39
|
+
}
|
|
40
|
+
export declare const Watermark: React.FC<WatermarkProps>;
|
|
41
|
+
export default Watermark;
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
8
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
9
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
10
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
11
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
12
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
13
|
+
import React, { useEffect, useRef, useState, useMemo, useCallback } from 'react';
|
|
14
|
+
import "./style.less";
|
|
15
|
+
|
|
16
|
+
// ============ 类型定义 ============
|
|
17
|
+
|
|
18
|
+
/** Watermark 属性 */
|
|
19
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
21
|
+
// ============ 检查颜色是否包含透明度 ============
|
|
22
|
+
var hasAlpha = function hasAlpha(color) {
|
|
23
|
+
return color.includes('rgba') || color.includes('hsla') || color.startsWith('#') && color.length === 9;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// ============ 生成水印 Canvas ============
|
|
27
|
+
var generateWatermark = function generateWatermark(content, image, options) {
|
|
28
|
+
var canvas = document.createElement('canvas');
|
|
29
|
+
var ctx = canvas.getContext('2d');
|
|
30
|
+
if (!ctx) return '';
|
|
31
|
+
var width = options.width,
|
|
32
|
+
height = options.height,
|
|
33
|
+
rotate = options.rotate,
|
|
34
|
+
opacity = options.opacity,
|
|
35
|
+
fontSize = options.fontSize,
|
|
36
|
+
fontColor = options.fontColor,
|
|
37
|
+
fontFamily = options.fontFamily;
|
|
38
|
+
canvas.width = width;
|
|
39
|
+
canvas.height = height;
|
|
40
|
+
ctx.save();
|
|
41
|
+
|
|
42
|
+
// 如果 fontColor 已经包含透明度,就不使用 globalAlpha,避免双重透明度
|
|
43
|
+
// 否则使用 globalAlpha 来控制整体透明度
|
|
44
|
+
// 注意:如果 fontColor 已经有透明度,我们仍然需要应用 opacity,但要调整
|
|
45
|
+
if (hasAlpha(fontColor)) {
|
|
46
|
+
// fontColor 已经有透明度,直接使用,不叠加 globalAlpha
|
|
47
|
+
ctx.globalAlpha = 1;
|
|
48
|
+
} else {
|
|
49
|
+
// fontColor 没有透明度,使用 globalAlpha
|
|
50
|
+
ctx.globalAlpha = opacity;
|
|
51
|
+
}
|
|
52
|
+
ctx.translate(width / 2, height / 2);
|
|
53
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
54
|
+
ctx.translate(-width / 2, -height / 2);
|
|
55
|
+
if (image) {
|
|
56
|
+
var img = new Image();
|
|
57
|
+
img.crossOrigin = 'anonymous';
|
|
58
|
+
img.src = image;
|
|
59
|
+
// 注意:这里需要等待图片加载完成,但为了简化,先返回空字符串
|
|
60
|
+
// 实际使用时应该使用 Promise 或回调
|
|
61
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
62
|
+
} else if (content) {
|
|
63
|
+
// 确保 fontColor 有效
|
|
64
|
+
if (!fontColor) {
|
|
65
|
+
ctx.restore();
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
ctx.fillStyle = fontColor;
|
|
69
|
+
ctx.font = "".concat(fontSize, "px ").concat(fontFamily);
|
|
70
|
+
ctx.textAlign = 'center';
|
|
71
|
+
ctx.textBaseline = 'middle';
|
|
72
|
+
var contents = Array.isArray(content) ? content : [content];
|
|
73
|
+
var lineHeight = fontSize * 1.2;
|
|
74
|
+
var totalHeight = contents.length * lineHeight;
|
|
75
|
+
var startY = (height - totalHeight) / 2 + lineHeight / 2;
|
|
76
|
+
contents.forEach(function (text, index) {
|
|
77
|
+
ctx.fillText(text, width / 2, startY + index * lineHeight);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
ctx.restore();
|
|
81
|
+
return canvas.toDataURL();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// ============ 检测深色模式 ============
|
|
85
|
+
var isDarkMode = function isDarkMode() {
|
|
86
|
+
if (typeof window === 'undefined') return false;
|
|
87
|
+
|
|
88
|
+
// 优先检查页面主题属性(最可靠)
|
|
89
|
+
if (document.documentElement.hasAttribute('data-theme') && document.documentElement.getAttribute('data-theme') === 'dark') {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
if (document.documentElement.hasAttribute('data-prefers-color-scheme') && document.documentElement.getAttribute('data-prefers-color-scheme') === 'dark') {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (document.documentElement.hasAttribute('data-prefers-color') && document.documentElement.getAttribute('data-prefers-color') === 'dark') {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
if (document.documentElement.classList.contains('dark') || document.body.classList.contains('dark')) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 最后检查系统偏好(可能不准确,因为页面可能是亮色但系统是深色)
|
|
103
|
+
// 如果页面没有明确的主题标识,才使用系统偏好
|
|
104
|
+
// 这里暂时注释掉,优先使用页面主题
|
|
105
|
+
// if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
106
|
+
// return true;
|
|
107
|
+
// }
|
|
108
|
+
|
|
109
|
+
return false; // 默认亮色模式
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// ============ Watermark 组件 ============
|
|
113
|
+
export var Watermark = function Watermark(_ref) {
|
|
114
|
+
var _ref$content = _ref.content,
|
|
115
|
+
content = _ref$content === void 0 ? 'Watermark' : _ref$content,
|
|
116
|
+
image = _ref.image,
|
|
117
|
+
_ref$width = _ref.width,
|
|
118
|
+
width = _ref$width === void 0 ? 120 : _ref$width,
|
|
119
|
+
_ref$height = _ref.height,
|
|
120
|
+
height = _ref$height === void 0 ? 64 : _ref$height,
|
|
121
|
+
_ref$rotate = _ref.rotate,
|
|
122
|
+
rotate = _ref$rotate === void 0 ? -22 : _ref$rotate,
|
|
123
|
+
_ref$opacity = _ref.opacity,
|
|
124
|
+
opacity = _ref$opacity === void 0 ? 1 : _ref$opacity,
|
|
125
|
+
_ref$fontSize = _ref.fontSize,
|
|
126
|
+
fontSize = _ref$fontSize === void 0 ? 16 : _ref$fontSize,
|
|
127
|
+
fontColor = _ref.fontColor,
|
|
128
|
+
_ref$fontFamily = _ref.fontFamily,
|
|
129
|
+
fontFamily = _ref$fontFamily === void 0 ? 'sans-serif' : _ref$fontFamily,
|
|
130
|
+
_ref$gapX = _ref.gapX,
|
|
131
|
+
gapX = _ref$gapX === void 0 ? 100 : _ref$gapX,
|
|
132
|
+
_ref$gapY = _ref.gapY,
|
|
133
|
+
gapY = _ref$gapY === void 0 ? 100 : _ref$gapY,
|
|
134
|
+
_ref$offsetLeft = _ref.offsetLeft,
|
|
135
|
+
offsetLeft = _ref$offsetLeft === void 0 ? 0 : _ref$offsetLeft,
|
|
136
|
+
_ref$offsetTop = _ref.offsetTop,
|
|
137
|
+
offsetTop = _ref$offsetTop === void 0 ? 0 : _ref$offsetTop,
|
|
138
|
+
_ref$zIndex = _ref.zIndex,
|
|
139
|
+
zIndex = _ref$zIndex === void 0 ? 9 : _ref$zIndex,
|
|
140
|
+
_ref$className = _ref.className,
|
|
141
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
142
|
+
style = _ref.style,
|
|
143
|
+
children = _ref.children;
|
|
144
|
+
var containerRef = useRef(null);
|
|
145
|
+
var watermarkRef = useRef(null);
|
|
146
|
+
var _useState = useState(''),
|
|
147
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
148
|
+
watermarkUrl = _useState2[0],
|
|
149
|
+
setWatermarkUrl = _useState2[1];
|
|
150
|
+
var _useState3 = useState(function () {
|
|
151
|
+
// 在客户端初始化时检测深色模式,默认为 false(亮色模式)
|
|
152
|
+
if (typeof window !== 'undefined') {
|
|
153
|
+
return isDarkMode();
|
|
154
|
+
}
|
|
155
|
+
return false; // 默认亮色模式
|
|
156
|
+
}),
|
|
157
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
158
|
+
darkMode = _useState4[0],
|
|
159
|
+
setDarkMode = _useState4[1];
|
|
160
|
+
|
|
161
|
+
// 使用默认字体颜色(如果未指定),依赖于 darkMode state
|
|
162
|
+
var finalFontColor = useMemo(function () {
|
|
163
|
+
if (fontColor) {
|
|
164
|
+
return fontColor;
|
|
165
|
+
}
|
|
166
|
+
// 提高默认透明度,确保可见性
|
|
167
|
+
// 亮色模式使用深色(黑色),深色模式使用浅色(白色)
|
|
168
|
+
// 确保在客户端环境下正确检测,如果 darkMode 未初始化,默认使用亮色模式(黑色)
|
|
169
|
+
if (typeof window === 'undefined') {
|
|
170
|
+
return 'rgba(0, 0, 0, 0.35)'; // 服务端渲染默认亮色
|
|
171
|
+
}
|
|
172
|
+
var isDark = darkMode !== null && darkMode !== void 0 ? darkMode : isDarkMode();
|
|
173
|
+
return isDark ? 'rgba(255, 255, 255, 0.4)' : 'rgba(0, 0, 0, 0.35)';
|
|
174
|
+
}, [fontColor, darkMode]);
|
|
175
|
+
|
|
176
|
+
// 监听深色模式变化
|
|
177
|
+
useEffect(function () {
|
|
178
|
+
var checkDarkMode = function checkDarkMode() {
|
|
179
|
+
var newDarkMode = isDarkMode();
|
|
180
|
+
setDarkMode(newDarkMode);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// 立即检查一次,确保初始状态正确
|
|
184
|
+
checkDarkMode();
|
|
185
|
+
|
|
186
|
+
// 延迟再检查一次,确保 DOM 已完全加载
|
|
187
|
+
var timer = setTimeout(function () {
|
|
188
|
+
checkDarkMode();
|
|
189
|
+
}, 100);
|
|
190
|
+
|
|
191
|
+
// 监听主题变化
|
|
192
|
+
var observer = new MutationObserver(checkDarkMode);
|
|
193
|
+
observer.observe(document.documentElement, {
|
|
194
|
+
attributes: true,
|
|
195
|
+
attributeFilter: ['data-theme', 'data-prefers-color-scheme', 'data-prefers-color', 'class']
|
|
196
|
+
});
|
|
197
|
+
observer.observe(document.body, {
|
|
198
|
+
attributes: true,
|
|
199
|
+
attributeFilter: ['class']
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// 监听系统偏好变化
|
|
203
|
+
var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
204
|
+
var handleChange = function handleChange() {
|
|
205
|
+
return checkDarkMode();
|
|
206
|
+
};
|
|
207
|
+
if (mediaQuery.addEventListener) {
|
|
208
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
209
|
+
} else {
|
|
210
|
+
// 兼容旧版浏览器
|
|
211
|
+
mediaQuery.addListener(handleChange);
|
|
212
|
+
}
|
|
213
|
+
return function () {
|
|
214
|
+
clearTimeout(timer);
|
|
215
|
+
observer.disconnect();
|
|
216
|
+
if (mediaQuery.removeEventListener) {
|
|
217
|
+
mediaQuery.removeEventListener('change', handleChange);
|
|
218
|
+
} else {
|
|
219
|
+
mediaQuery.removeListener(handleChange);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}, []);
|
|
223
|
+
useEffect(function () {
|
|
224
|
+
if (!content && !image) return;
|
|
225
|
+
|
|
226
|
+
// 确保 finalFontColor 已经计算好
|
|
227
|
+
if (!finalFontColor) {
|
|
228
|
+
// 如果 finalFontColor 还未计算好,使用默认的黑色(亮色模式)
|
|
229
|
+
var defaultColor = 'rgba(0, 0, 0, 0.35)';
|
|
230
|
+
var url = generateWatermark(content, undefined, {
|
|
231
|
+
width: width,
|
|
232
|
+
height: height,
|
|
233
|
+
rotate: rotate,
|
|
234
|
+
opacity: opacity,
|
|
235
|
+
fontSize: fontSize,
|
|
236
|
+
fontColor: defaultColor,
|
|
237
|
+
fontFamily: fontFamily
|
|
238
|
+
});
|
|
239
|
+
setWatermarkUrl(url);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// 如果使用图片,需要等待图片加载
|
|
244
|
+
if (image) {
|
|
245
|
+
var img = new Image();
|
|
246
|
+
img.crossOrigin = 'anonymous';
|
|
247
|
+
img.onload = function () {
|
|
248
|
+
var canvas = document.createElement('canvas');
|
|
249
|
+
var ctx = canvas.getContext('2d');
|
|
250
|
+
if (!ctx) return;
|
|
251
|
+
canvas.width = width;
|
|
252
|
+
canvas.height = height;
|
|
253
|
+
ctx.save();
|
|
254
|
+
ctx.globalAlpha = opacity;
|
|
255
|
+
ctx.translate(width / 2, height / 2);
|
|
256
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
257
|
+
ctx.translate(-width / 2, -height / 2);
|
|
258
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
259
|
+
ctx.restore();
|
|
260
|
+
setWatermarkUrl(canvas.toDataURL());
|
|
261
|
+
};
|
|
262
|
+
img.onerror = function () {
|
|
263
|
+
// 图片加载失败,使用文字
|
|
264
|
+
var url = generateWatermark(content || 'Watermark', undefined, {
|
|
265
|
+
width: width,
|
|
266
|
+
height: height,
|
|
267
|
+
rotate: rotate,
|
|
268
|
+
opacity: opacity,
|
|
269
|
+
fontSize: fontSize,
|
|
270
|
+
fontColor: finalFontColor,
|
|
271
|
+
fontFamily: fontFamily
|
|
272
|
+
});
|
|
273
|
+
setWatermarkUrl(url);
|
|
274
|
+
};
|
|
275
|
+
img.src = image;
|
|
276
|
+
} else {
|
|
277
|
+
// 使用文字
|
|
278
|
+
var _url = generateWatermark(content, undefined, {
|
|
279
|
+
width: width,
|
|
280
|
+
height: height,
|
|
281
|
+
rotate: rotate,
|
|
282
|
+
opacity: opacity,
|
|
283
|
+
fontSize: fontSize,
|
|
284
|
+
fontColor: finalFontColor,
|
|
285
|
+
fontFamily: fontFamily
|
|
286
|
+
});
|
|
287
|
+
setWatermarkUrl(_url);
|
|
288
|
+
}
|
|
289
|
+
}, [content, image, width, height, rotate, opacity, fontSize, finalFontColor, fontFamily, darkMode]);
|
|
290
|
+
|
|
291
|
+
// 更新水印位置和大小
|
|
292
|
+
var updateWatermark = useCallback(function () {
|
|
293
|
+
if (!containerRef.current || !watermarkRef.current || !watermarkUrl) return;
|
|
294
|
+
var watermark = watermarkRef.current;
|
|
295
|
+
|
|
296
|
+
// 设置背景图片
|
|
297
|
+
var backgroundSize = "".concat(width + gapX, "px ").concat(height + gapY, "px");
|
|
298
|
+
var backgroundPosition = "".concat(offsetLeft, "px ").concat(offsetTop, "px");
|
|
299
|
+
watermark.style.backgroundImage = "url(".concat(watermarkUrl, ")");
|
|
300
|
+
watermark.style.backgroundSize = backgroundSize;
|
|
301
|
+
watermark.style.backgroundPosition = backgroundPosition;
|
|
302
|
+
watermark.style.backgroundRepeat = 'repeat';
|
|
303
|
+
}, [watermarkUrl, gapX, gapY, offsetLeft, offsetTop, width, height]);
|
|
304
|
+
|
|
305
|
+
// 监听容器大小变化
|
|
306
|
+
useEffect(function () {
|
|
307
|
+
if (!containerRef.current || !watermarkRef.current) return;
|
|
308
|
+
var resizeObserver = new ResizeObserver(function () {
|
|
309
|
+
if (!containerRef.current || !watermarkRef.current) return;
|
|
310
|
+
updateWatermark();
|
|
311
|
+
});
|
|
312
|
+
resizeObserver.observe(containerRef.current);
|
|
313
|
+
return function () {
|
|
314
|
+
resizeObserver.disconnect();
|
|
315
|
+
};
|
|
316
|
+
}, [updateWatermark]);
|
|
317
|
+
useEffect(function () {
|
|
318
|
+
if (watermarkUrl) {
|
|
319
|
+
updateWatermark();
|
|
320
|
+
}
|
|
321
|
+
}, [watermarkUrl, updateWatermark]);
|
|
322
|
+
var watermarkStyle = _objectSpread({
|
|
323
|
+
position: 'absolute',
|
|
324
|
+
top: 0,
|
|
325
|
+
left: 0,
|
|
326
|
+
width: '100%',
|
|
327
|
+
height: '100%',
|
|
328
|
+
pointerEvents: 'none',
|
|
329
|
+
zIndex: zIndex,
|
|
330
|
+
opacity: 1
|
|
331
|
+
}, style);
|
|
332
|
+
var containerClassNames = ['kage-watermark', className].filter(Boolean).join(' ');
|
|
333
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
334
|
+
ref: containerRef,
|
|
335
|
+
className: containerClassNames,
|
|
336
|
+
style: {
|
|
337
|
+
position: 'relative'
|
|
338
|
+
},
|
|
339
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
340
|
+
ref: watermarkRef,
|
|
341
|
+
className: "kage-watermark-content",
|
|
342
|
+
style: watermarkStyle
|
|
343
|
+
}), children && /*#__PURE__*/_jsx("div", {
|
|
344
|
+
className: "kage-watermark-children",
|
|
345
|
+
children: children
|
|
346
|
+
})]
|
|
347
|
+
});
|
|
348
|
+
};
|
|
349
|
+
export default Watermark;
|