@alifd/chat 0.3.39 → 0.3.40-beta.0
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/es/html-render/index.js +94 -1
- package/es/index.js +1 -1
- package/es/text/index.js +66 -21
- package/lib/html-render/index.js +94 -1
- package/lib/index.js +1 -1
- package/lib/text/index.js +65 -20
- package/package.json +1 -1
package/es/html-render/index.js
CHANGED
|
@@ -98,7 +98,7 @@ const HTMLRenderer = memo(function HTMLRenderer({ className, children, imagePrev
|
|
|
98
98
|
})));
|
|
99
99
|
};
|
|
100
100
|
// 已替换
|
|
101
|
-
const
|
|
101
|
+
const parserOptionsOld = {
|
|
102
102
|
// @ts-ignore
|
|
103
103
|
replace: domNode => {
|
|
104
104
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -192,6 +192,99 @@ const HTMLRenderer = memo(function HTMLRenderer({ className, children, imagePrev
|
|
|
192
192
|
};
|
|
193
193
|
const element = useMemo(() => {
|
|
194
194
|
indexRef.current = 0;
|
|
195
|
+
// 已替换
|
|
196
|
+
const parserOptions = {
|
|
197
|
+
// @ts-ignore
|
|
198
|
+
replace: domNode => {
|
|
199
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
200
|
+
// 处理文本节点
|
|
201
|
+
if ((domNode.type === 'text' || domNode.nodeType === 3) && typewriterEffect) {
|
|
202
|
+
return processTextNode(domNode);
|
|
203
|
+
}
|
|
204
|
+
if (domNode instanceof Element && domNode.attribs) {
|
|
205
|
+
const { name } = domNode;
|
|
206
|
+
if (name === 'link-reference') {
|
|
207
|
+
const element = (domToReact([domNode]));
|
|
208
|
+
// link-reference 的子元素一定是 a 标签
|
|
209
|
+
const aElement = (_a = element.props) === null || _a === void 0 ? void 0 : _a.children;
|
|
210
|
+
// a 标签的子元素一定是 span 节点
|
|
211
|
+
const spanElement = (_b = aElement === null || aElement === void 0 ? void 0 : aElement.props) === null || _b === void 0 ? void 0 : _b.children;
|
|
212
|
+
const handleUrlClick = () => {
|
|
213
|
+
var _a;
|
|
214
|
+
if (!((_a = aElement === null || aElement === void 0 ? void 0 : aElement.props) === null || _a === void 0 ? void 0 : _a.href)) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (handleOpenLink) {
|
|
218
|
+
handleOpenLink === null || handleOpenLink === void 0 ? void 0 : handleOpenLink(aElement.props.href);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
defaultOpenLink(aElement.props.href);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
return (React.createElement(Balloon, { v2: true, align: "b", className: "link-reference-balloon", closable: false, offset: [0, -8], triggerType: ['hover'], trigger: React.createElement("span", { className: "link-reference-index", onClick: handleUrlClick }, (_c = spanElement === null || spanElement === void 0 ? void 0 : spanElement.props) === null || _c === void 0 ? void 0 : _c.children) },
|
|
225
|
+
React.createElement("div", { className: "link-reference-content" },
|
|
226
|
+
React.createElement("img", { className: "link-reference-source-icon", src: ((_d = element.props) === null || _d === void 0 ? void 0 : _d['data-source-icon']) || '' }),
|
|
227
|
+
React.createElement("a", { className: "link-reference-title", onClick: handleUrlClick, title: ((_e = element.props) === null || _e === void 0 ? void 0 : _e['data-title']) || '' }, ((_f = element.props) === null || _f === void 0 ? void 0 : _f['data-title']) || ''))));
|
|
228
|
+
}
|
|
229
|
+
if (name === 'a') {
|
|
230
|
+
const element = (domToReact([domNode]));
|
|
231
|
+
const { props } = element;
|
|
232
|
+
if (props.href && props.href.startsWith('message://')) {
|
|
233
|
+
const msgValue = decodeURIComponent(props.href.slice(10));
|
|
234
|
+
return React.cloneElement(element, {
|
|
235
|
+
onClick: () => {
|
|
236
|
+
if (sendTextMessage) {
|
|
237
|
+
sendTextMessage(msgValue);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
defaultSendMessage();
|
|
241
|
+
},
|
|
242
|
+
href: undefined
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
if (props.href && props.href.startsWith('copy://')) {
|
|
246
|
+
const copyValue = decodeURIComponent(props.href.slice(7));
|
|
247
|
+
return React.cloneElement(element, {
|
|
248
|
+
onClick: () => {
|
|
249
|
+
if (copyText) {
|
|
250
|
+
copyText(copyValue);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
defaultCopyText(copyValue);
|
|
254
|
+
},
|
|
255
|
+
href: undefined
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
// H5场景和钉协议场景都需要代理Click事件
|
|
259
|
+
if (props.href && (/^dtmd:\/\/dingtalkclient|^dingtalk:\/\/dingtalkclient\/action\/jumprobot|^(https?:)?\/\/qr.dingtalk.com\/action\/jumprobot|^https:\/\/applink\.dingtalk\.com\/page\/link/.test(props.href) || isMobile)) {
|
|
260
|
+
return React.cloneElement(element, {
|
|
261
|
+
onClick: () => {
|
|
262
|
+
if (handleOpenLink) {
|
|
263
|
+
handleOpenLink === null || handleOpenLink === void 0 ? void 0 : handleOpenLink(props.href);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
defaultOpenLink(props.href);
|
|
267
|
+
},
|
|
268
|
+
href: undefined
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return React.cloneElement(element, {
|
|
272
|
+
target: '_blank',
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (name === 'img') {
|
|
276
|
+
const element = (domToReact([domNode]));
|
|
277
|
+
if (renderImage) {
|
|
278
|
+
return renderImage(element.props);
|
|
279
|
+
}
|
|
280
|
+
// 换成统一的图片渲染
|
|
281
|
+
return React.createElement(Img, Object.assign({}, element.props, { imageClassName: (_g = element.props) === null || _g === void 0 ? void 0 : _g.className, enablePreview: imagePreview, onImageClick: () => {
|
|
282
|
+
handleImageClick === null || handleImageClick === void 0 ? void 0 : handleImageClick(element.props.src);
|
|
283
|
+
} }));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
195
288
|
return parse(sanitizeHtml(children || '', sanitizeHtmlOptions), parserOptions);
|
|
196
289
|
}, [children, typewriterEffect]);
|
|
197
290
|
return (React.createElement("div", { className: classnames(`markdown-body ${PREFIX_DEFAULT}html`, className, {
|
package/es/index.js
CHANGED
|
@@ -32,4 +32,4 @@ export { default as CheckboxGroup } from './checkbox-group';
|
|
|
32
32
|
export { default as Select } from './select';
|
|
33
33
|
export { default as Flip } from './flip';
|
|
34
34
|
export { default as ToolStatus } from './tool-status';
|
|
35
|
-
export const version = '0.3.
|
|
35
|
+
export const version = '0.3.40-beta.0';
|
package/es/text/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef, useLayoutEffect, useCallback, useEffect, useState,
|
|
1
|
+
import React, { useRef, useLayoutEffect, useCallback, useEffect, useState, } from 'react';
|
|
2
2
|
import { ConfigProvider } from '@alifd/next';
|
|
3
3
|
import cs from 'classnames';
|
|
4
4
|
import { PREFIX_DEFAULT, useControlable, useDebounce } from '../utils';
|
|
@@ -24,13 +24,19 @@ function useCollapseText({ enable, boxRef, textRef, maxLine, placeholder = '...'
|
|
|
24
24
|
if (lineHeight === 'normal') {
|
|
25
25
|
// 向容器里添加一段文本来测试行高
|
|
26
26
|
const span = document.createElement('span');
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
try {
|
|
28
|
+
span.style.whiteSpace = 'nowrap';
|
|
29
|
+
span.innerText = 'test';
|
|
30
|
+
span.style.visibility = 'hidden';
|
|
31
|
+
dom.appendChild(span);
|
|
32
|
+
return span.offsetHeight;
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
// 确保无论是否发生错误,都会尝试移除子节点
|
|
36
|
+
if (span.parentNode === dom) {
|
|
37
|
+
dom.removeChild(span);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
34
40
|
}
|
|
35
41
|
return parseFloat(lineHeight);
|
|
36
42
|
}, []);
|
|
@@ -183,16 +189,22 @@ function useEnsureBoxFullLine({ enableRef, boxRef, modifierRef, before, after, }
|
|
|
183
189
|
ensureTriggerEnd(box, modifier);
|
|
184
190
|
});
|
|
185
191
|
}
|
|
192
|
+
// 修改 useResize Hook
|
|
186
193
|
function useResize(domRef, onResize, shouldTriggerRef) {
|
|
187
194
|
const sizeRef = useRef();
|
|
188
195
|
const debounceOnResize = useDebounce(onResize, 50);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
196
|
+
// observer 不再使用 useMemo,而是在 useEffect 中创建和销毁
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
const dom = domRef.current;
|
|
199
|
+
if (!dom) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const observer = new ResizeObserver(() => {
|
|
203
|
+
// 回调函数逻辑不变
|
|
204
|
+
if (!domRef.current || !shouldTriggerRef.current) {
|
|
193
205
|
return;
|
|
194
206
|
}
|
|
195
|
-
const { offsetWidth, offsetHeight } =
|
|
207
|
+
const { offsetWidth, offsetHeight } = domRef.current;
|
|
196
208
|
const lastSize = sizeRef.current;
|
|
197
209
|
const newSize = { width: offsetWidth, height: offsetHeight };
|
|
198
210
|
if (!lastSize ||
|
|
@@ -202,18 +214,51 @@ function useResize(domRef, onResize, shouldTriggerRef) {
|
|
|
202
214
|
}
|
|
203
215
|
sizeRef.current = newSize;
|
|
204
216
|
});
|
|
205
|
-
}, []);
|
|
206
|
-
useEffect(() => {
|
|
207
|
-
const dom = domRef.current;
|
|
208
|
-
if (!dom) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
217
|
observer.observe(dom);
|
|
218
|
+
// 清理函数现在负责销毁 observer 实例
|
|
212
219
|
return () => {
|
|
213
|
-
|
|
220
|
+
// unobserve 不是必须的,因为 disconnect 会停止所有观察
|
|
221
|
+
observer.disconnect();
|
|
214
222
|
};
|
|
215
|
-
}, [domRef
|
|
223
|
+
}, [domRef, debounceOnResize, shouldTriggerRef]); // 依赖项也需要更新
|
|
216
224
|
}
|
|
225
|
+
// function useResizeOld(
|
|
226
|
+
// domRef: RefObject<HTMLElement>,
|
|
227
|
+
// onResize: () => void,
|
|
228
|
+
// shouldTriggerRef: MutableRefObject<boolean>
|
|
229
|
+
// ) {
|
|
230
|
+
// const sizeRef = useRef<{ width: number; height: number }>();
|
|
231
|
+
// const debounceOnResize = useDebounce(onResize, 50);
|
|
232
|
+
// const observer = useMemo(() => {
|
|
233
|
+
// return new ResizeObserver(() => {
|
|
234
|
+
// const dom = domRef.current;
|
|
235
|
+
// if (!dom || !shouldTriggerRef.current) {
|
|
236
|
+
// return;
|
|
237
|
+
// }
|
|
238
|
+
// const { offsetWidth, offsetHeight } = dom;
|
|
239
|
+
// const lastSize = sizeRef.current;
|
|
240
|
+
// const newSize = { width: offsetWidth, height: offsetHeight };
|
|
241
|
+
// if (
|
|
242
|
+
// !lastSize ||
|
|
243
|
+
// newSize.width !== lastSize.width ||
|
|
244
|
+
// newSize.height !== lastSize.height
|
|
245
|
+
// ) {
|
|
246
|
+
// debounceOnResize();
|
|
247
|
+
// }
|
|
248
|
+
// sizeRef.current = newSize;
|
|
249
|
+
// });
|
|
250
|
+
// }, []);
|
|
251
|
+
// useEffect(() => {
|
|
252
|
+
// const dom = domRef.current;
|
|
253
|
+
// if (!dom) {
|
|
254
|
+
// return;
|
|
255
|
+
// }
|
|
256
|
+
// observer?.observe(dom);
|
|
257
|
+
// return () => {
|
|
258
|
+
// observer?.unobserve(dom);
|
|
259
|
+
// };
|
|
260
|
+
// }, [domRef.current, observer]);
|
|
261
|
+
// }
|
|
217
262
|
function TextComp(props) {
|
|
218
263
|
const { className, maxLine, renderTrigger, triggerType = 'click', locale, showTrigger = true, children, } = props;
|
|
219
264
|
const collapsable = typeof maxLine === 'number' && maxLine > 0;
|
package/lib/html-render/index.js
CHANGED
|
@@ -101,7 +101,7 @@ const HTMLRenderer = (0, react_1.memo)(function HTMLRenderer({ className, childr
|
|
|
101
101
|
})));
|
|
102
102
|
};
|
|
103
103
|
// 已替换
|
|
104
|
-
const
|
|
104
|
+
const parserOptionsOld = {
|
|
105
105
|
// @ts-ignore
|
|
106
106
|
replace: domNode => {
|
|
107
107
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -195,6 +195,99 @@ const HTMLRenderer = (0, react_1.memo)(function HTMLRenderer({ className, childr
|
|
|
195
195
|
};
|
|
196
196
|
const element = (0, react_1.useMemo)(() => {
|
|
197
197
|
indexRef.current = 0;
|
|
198
|
+
// 已替换
|
|
199
|
+
const parserOptions = {
|
|
200
|
+
// @ts-ignore
|
|
201
|
+
replace: domNode => {
|
|
202
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
203
|
+
// 处理文本节点
|
|
204
|
+
if ((domNode.type === 'text' || domNode.nodeType === 3) && typewriterEffect) {
|
|
205
|
+
return processTextNode(domNode);
|
|
206
|
+
}
|
|
207
|
+
if (domNode instanceof html_react_parser_1.Element && domNode.attribs) {
|
|
208
|
+
const { name } = domNode;
|
|
209
|
+
if (name === 'link-reference') {
|
|
210
|
+
const element = ((0, html_react_parser_1.domToReact)([domNode]));
|
|
211
|
+
// link-reference 的子元素一定是 a 标签
|
|
212
|
+
const aElement = (_a = element.props) === null || _a === void 0 ? void 0 : _a.children;
|
|
213
|
+
// a 标签的子元素一定是 span 节点
|
|
214
|
+
const spanElement = (_b = aElement === null || aElement === void 0 ? void 0 : aElement.props) === null || _b === void 0 ? void 0 : _b.children;
|
|
215
|
+
const handleUrlClick = () => {
|
|
216
|
+
var _a;
|
|
217
|
+
if (!((_a = aElement === null || aElement === void 0 ? void 0 : aElement.props) === null || _a === void 0 ? void 0 : _a.href)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (handleOpenLink) {
|
|
221
|
+
handleOpenLink === null || handleOpenLink === void 0 ? void 0 : handleOpenLink(aElement.props.href);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
defaultOpenLink(aElement.props.href);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
return (react_1.default.createElement(balloon_1.default, { v2: true, align: "b", className: "link-reference-balloon", closable: false, offset: [0, -8], triggerType: ['hover'], trigger: react_1.default.createElement("span", { className: "link-reference-index", onClick: handleUrlClick }, (_c = spanElement === null || spanElement === void 0 ? void 0 : spanElement.props) === null || _c === void 0 ? void 0 : _c.children) },
|
|
228
|
+
react_1.default.createElement("div", { className: "link-reference-content" },
|
|
229
|
+
react_1.default.createElement("img", { className: "link-reference-source-icon", src: ((_d = element.props) === null || _d === void 0 ? void 0 : _d['data-source-icon']) || '' }),
|
|
230
|
+
react_1.default.createElement("a", { className: "link-reference-title", onClick: handleUrlClick, title: ((_e = element.props) === null || _e === void 0 ? void 0 : _e['data-title']) || '' }, ((_f = element.props) === null || _f === void 0 ? void 0 : _f['data-title']) || ''))));
|
|
231
|
+
}
|
|
232
|
+
if (name === 'a') {
|
|
233
|
+
const element = ((0, html_react_parser_1.domToReact)([domNode]));
|
|
234
|
+
const { props } = element;
|
|
235
|
+
if (props.href && props.href.startsWith('message://')) {
|
|
236
|
+
const msgValue = decodeURIComponent(props.href.slice(10));
|
|
237
|
+
return react_1.default.cloneElement(element, {
|
|
238
|
+
onClick: () => {
|
|
239
|
+
if (sendTextMessage) {
|
|
240
|
+
sendTextMessage(msgValue);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
defaultSendMessage();
|
|
244
|
+
},
|
|
245
|
+
href: undefined
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
if (props.href && props.href.startsWith('copy://')) {
|
|
249
|
+
const copyValue = decodeURIComponent(props.href.slice(7));
|
|
250
|
+
return react_1.default.cloneElement(element, {
|
|
251
|
+
onClick: () => {
|
|
252
|
+
if (copyText) {
|
|
253
|
+
copyText(copyValue);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
defaultCopyText(copyValue);
|
|
257
|
+
},
|
|
258
|
+
href: undefined
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
// H5场景和钉协议场景都需要代理Click事件
|
|
262
|
+
if (props.href && (/^dtmd:\/\/dingtalkclient|^dingtalk:\/\/dingtalkclient\/action\/jumprobot|^(https?:)?\/\/qr.dingtalk.com\/action\/jumprobot|^https:\/\/applink\.dingtalk\.com\/page\/link/.test(props.href) || isMobile)) {
|
|
263
|
+
return react_1.default.cloneElement(element, {
|
|
264
|
+
onClick: () => {
|
|
265
|
+
if (handleOpenLink) {
|
|
266
|
+
handleOpenLink === null || handleOpenLink === void 0 ? void 0 : handleOpenLink(props.href);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
defaultOpenLink(props.href);
|
|
270
|
+
},
|
|
271
|
+
href: undefined
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return react_1.default.cloneElement(element, {
|
|
275
|
+
target: '_blank',
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (name === 'img') {
|
|
279
|
+
const element = ((0, html_react_parser_1.domToReact)([domNode]));
|
|
280
|
+
if (renderImage) {
|
|
281
|
+
return renderImage(element.props);
|
|
282
|
+
}
|
|
283
|
+
// 换成统一的图片渲染
|
|
284
|
+
return react_1.default.createElement(img_1.default, Object.assign({}, element.props, { imageClassName: (_g = element.props) === null || _g === void 0 ? void 0 : _g.className, enablePreview: imagePreview, onImageClick: () => {
|
|
285
|
+
handleImageClick === null || handleImageClick === void 0 ? void 0 : handleImageClick(element.props.src);
|
|
286
|
+
} }));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
198
291
|
return (0, html_react_parser_1.default)((0, sanitize_html_1.default)(children || '', sanitizeHtmlOptions), parserOptions);
|
|
199
292
|
}, [children, typewriterEffect]);
|
|
200
293
|
return (react_1.default.createElement("div", { className: (0, classnames_1.default)(`markdown-body ${utils_1.PREFIX_DEFAULT}html`, className, {
|
package/lib/index.js
CHANGED
|
@@ -70,4 +70,4 @@ var flip_1 = require("./flip");
|
|
|
70
70
|
Object.defineProperty(exports, "Flip", { enumerable: true, get: function () { return tslib_1.__importDefault(flip_1).default; } });
|
|
71
71
|
var tool_status_1 = require("./tool-status");
|
|
72
72
|
Object.defineProperty(exports, "ToolStatus", { enumerable: true, get: function () { return tslib_1.__importDefault(tool_status_1).default; } });
|
|
73
|
-
exports.version = '0.3.
|
|
73
|
+
exports.version = '0.3.40-beta.0';
|
package/lib/text/index.js
CHANGED
|
@@ -27,13 +27,19 @@ function useCollapseText({ enable, boxRef, textRef, maxLine, placeholder = '...'
|
|
|
27
27
|
if (lineHeight === 'normal') {
|
|
28
28
|
// 向容器里添加一段文本来测试行高
|
|
29
29
|
const span = document.createElement('span');
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
try {
|
|
31
|
+
span.style.whiteSpace = 'nowrap';
|
|
32
|
+
span.innerText = 'test';
|
|
33
|
+
span.style.visibility = 'hidden';
|
|
34
|
+
dom.appendChild(span);
|
|
35
|
+
return span.offsetHeight;
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
// 确保无论是否发生错误,都会尝试移除子节点
|
|
39
|
+
if (span.parentNode === dom) {
|
|
40
|
+
dom.removeChild(span);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
return parseFloat(lineHeight);
|
|
39
45
|
}, []);
|
|
@@ -186,16 +192,22 @@ function useEnsureBoxFullLine({ enableRef, boxRef, modifierRef, before, after, }
|
|
|
186
192
|
ensureTriggerEnd(box, modifier);
|
|
187
193
|
});
|
|
188
194
|
}
|
|
195
|
+
// 修改 useResize Hook
|
|
189
196
|
function useResize(domRef, onResize, shouldTriggerRef) {
|
|
190
197
|
const sizeRef = (0, react_1.useRef)();
|
|
191
198
|
const debounceOnResize = (0, utils_1.useDebounce)(onResize, 50);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
199
|
+
// observer 不再使用 useMemo,而是在 useEffect 中创建和销毁
|
|
200
|
+
(0, react_1.useEffect)(() => {
|
|
201
|
+
const dom = domRef.current;
|
|
202
|
+
if (!dom) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const observer = new ResizeObserver(() => {
|
|
206
|
+
// 回调函数逻辑不变
|
|
207
|
+
if (!domRef.current || !shouldTriggerRef.current) {
|
|
196
208
|
return;
|
|
197
209
|
}
|
|
198
|
-
const { offsetWidth, offsetHeight } =
|
|
210
|
+
const { offsetWidth, offsetHeight } = domRef.current;
|
|
199
211
|
const lastSize = sizeRef.current;
|
|
200
212
|
const newSize = { width: offsetWidth, height: offsetHeight };
|
|
201
213
|
if (!lastSize ||
|
|
@@ -205,18 +217,51 @@ function useResize(domRef, onResize, shouldTriggerRef) {
|
|
|
205
217
|
}
|
|
206
218
|
sizeRef.current = newSize;
|
|
207
219
|
});
|
|
208
|
-
}, []);
|
|
209
|
-
(0, react_1.useEffect)(() => {
|
|
210
|
-
const dom = domRef.current;
|
|
211
|
-
if (!dom) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
220
|
observer.observe(dom);
|
|
221
|
+
// 清理函数现在负责销毁 observer 实例
|
|
215
222
|
return () => {
|
|
216
|
-
|
|
223
|
+
// unobserve 不是必须的,因为 disconnect 会停止所有观察
|
|
224
|
+
observer.disconnect();
|
|
217
225
|
};
|
|
218
|
-
}, [domRef
|
|
226
|
+
}, [domRef, debounceOnResize, shouldTriggerRef]); // 依赖项也需要更新
|
|
219
227
|
}
|
|
228
|
+
// function useResizeOld(
|
|
229
|
+
// domRef: RefObject<HTMLElement>,
|
|
230
|
+
// onResize: () => void,
|
|
231
|
+
// shouldTriggerRef: MutableRefObject<boolean>
|
|
232
|
+
// ) {
|
|
233
|
+
// const sizeRef = useRef<{ width: number; height: number }>();
|
|
234
|
+
// const debounceOnResize = useDebounce(onResize, 50);
|
|
235
|
+
// const observer = useMemo(() => {
|
|
236
|
+
// return new ResizeObserver(() => {
|
|
237
|
+
// const dom = domRef.current;
|
|
238
|
+
// if (!dom || !shouldTriggerRef.current) {
|
|
239
|
+
// return;
|
|
240
|
+
// }
|
|
241
|
+
// const { offsetWidth, offsetHeight } = dom;
|
|
242
|
+
// const lastSize = sizeRef.current;
|
|
243
|
+
// const newSize = { width: offsetWidth, height: offsetHeight };
|
|
244
|
+
// if (
|
|
245
|
+
// !lastSize ||
|
|
246
|
+
// newSize.width !== lastSize.width ||
|
|
247
|
+
// newSize.height !== lastSize.height
|
|
248
|
+
// ) {
|
|
249
|
+
// debounceOnResize();
|
|
250
|
+
// }
|
|
251
|
+
// sizeRef.current = newSize;
|
|
252
|
+
// });
|
|
253
|
+
// }, []);
|
|
254
|
+
// useEffect(() => {
|
|
255
|
+
// const dom = domRef.current;
|
|
256
|
+
// if (!dom) {
|
|
257
|
+
// return;
|
|
258
|
+
// }
|
|
259
|
+
// observer?.observe(dom);
|
|
260
|
+
// return () => {
|
|
261
|
+
// observer?.unobserve(dom);
|
|
262
|
+
// };
|
|
263
|
+
// }, [domRef.current, observer]);
|
|
264
|
+
// }
|
|
220
265
|
function TextComp(props) {
|
|
221
266
|
const { className, maxLine, renderTrigger, triggerType = 'click', locale, showTrigger = true, children, } = props;
|
|
222
267
|
const collapsable = typeof maxLine === 'number' && maxLine > 0;
|