feat: 导航/侧边栏菜单脱敏 + 圆桌会商各步输入框自适应高度
- 菜单标签展示层脱敏:useSidebarMenuItems 直接用 /api/sensitive-words 结果构造脱敏器,覆盖导航栏/三套侧边栏皮肤/三级子导航;菜单管理页用原始树不受影响 - 新增可复用 AutoGrowTextarea(自适应高度多行框),替换圆桌 Step1/2/3 输入框: 多行时自动扩展、到上限框内滚动;Step2 两个单行 input 改多行;统一 Enter 发送/Shift+Enter 换行 - 各步输入框最大展开高度翻倍(Step1 320 / Step2 280 / Step3 224) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
25e4e3dbc9
commit
6746fe4a78
9 files changed
+141
-29
No files matched your search
@@ -0,0 +1,59 @@
|
||||
import * as React from "react";
|
||||
|
||||
export interface AutoGrowTextareaProps
|
||||
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
/** 内容增长高度上限(px),超过后框内滚动。默认 200。 */
|
||||
maxHeight?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自适应高度的多行输入框。
|
||||
*
|
||||
* 内容增多时自动扩展高度(输入框处于底部布局时即「向上扩展」),到 `maxHeight` 后框内滚动。
|
||||
* 体验对齐通用问答页(`/page/strategy/qa/general`)的 tdesign `autosize` 输入框,但保留原生
|
||||
* `<textarea>`,从而沿用各调用处自带的 Tailwind 样式 / 边框 / 占位色,无需 TDesign 包裹层。
|
||||
*
|
||||
* 用法:当成普通受控 `<textarea>` 用(传 `value` + `onChange`)。高度在布局阶段随 `value` 重算,
|
||||
* 也在 `onChange` 时即时重算(兼顾非受控/输入法场景)。最小高度交给调用方的 `min-h-*` className
|
||||
* 或 `rows` 控制——本组件不强加最小高度。换行/发送(Enter/Shift+Enter)逻辑由调用方的
|
||||
* `onKeyDown` 决定。
|
||||
*/
|
||||
export const AutoGrowTextarea = React.forwardRef<
|
||||
HTMLTextAreaElement,
|
||||
AutoGrowTextareaProps
|
||||
>(function AutoGrowTextarea(
|
||||
{ maxHeight = 200, value, onChange, onInput, style, rows = 1, ...rest },
|
||||
ref,
|
||||
) {
|
||||
const innerRef = React.useRef<HTMLTextAreaElement | null>(null);
|
||||
React.useImperativeHandle(ref, () => innerRef.current as HTMLTextAreaElement);
|
||||
|
||||
const resize = React.useCallback(() => {
|
||||
const el = innerRef.current;
|
||||
if (!el) return;
|
||||
el.style.height = "auto";
|
||||
const next = Math.min(el.scrollHeight, maxHeight);
|
||||
el.style.height = `${next}px`;
|
||||
el.style.overflowY = el.scrollHeight > maxHeight ? "auto" : "hidden";
|
||||
}, [maxHeight]);
|
||||
|
||||
// 受控值变化(含外部清空、粘贴大段文本)后在布局阶段重算,避免闪烁。
|
||||
React.useLayoutEffect(() => {
|
||||
resize();
|
||||
}, [resize, value]);
|
||||
|
||||
return (
|
||||
<textarea
|
||||
ref={innerRef}
|
||||
rows={rows}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onInput={(e) => {
|
||||
onInput?.(e);
|
||||
resize();
|
||||
}}
|
||||
style={{ resize: "none", ...style }}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user