mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-15 17:31:18 +08:00
amis-saas-6892 fix: 长文本下拉菜单hover移出后未消失问题
Change-Id: I89042270212884be77a79e63b7c74b2e3fe7c646
This commit is contained in:
parent
4e34fe7ae7
commit
95f49e6862
73
packages/amis-editor/src/renderer/textarea-formula/Menu.tsx
Normal file
73
packages/amis-editor/src/renderer/textarea-formula/Menu.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @file 下拉菜单
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import {Button} from 'amis';
|
||||
import {Overlay, PopOver, generateIcon} from 'amis-core';
|
||||
|
||||
export interface MenuItem {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
interface MenuProps {
|
||||
className?: string;
|
||||
menus: MenuItem[];
|
||||
}
|
||||
|
||||
const Menu: React.FC<MenuProps> = props => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const domRef = React.useRef<HTMLDivElement>(null);
|
||||
const iconElement = generateIcon(cx, 'fa fa-plus');
|
||||
const {menus, className} = props;
|
||||
|
||||
function handleOpen(show: boolean) {
|
||||
setOpen(!show);
|
||||
}
|
||||
|
||||
function handleClick(item: MenuItem) {
|
||||
item.onClick();
|
||||
setOpen(false);
|
||||
}
|
||||
|
||||
function renderButtons() {
|
||||
return (
|
||||
<ul className={cx('textarea-formula-menu-outer')}>
|
||||
{menus.map((item, i) => {
|
||||
return (
|
||||
<li key={i} onClick={() => handleClick(item)}>
|
||||
<a>{item.label}</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx('textarea-formula-menu', className)}
|
||||
onMouseEnter={() => handleOpen(open)}
|
||||
onMouseLeave={() => setOpen(false)}
|
||||
>
|
||||
<div ref={domRef}>
|
||||
<Button iconOnly level="link" onClick={() => handleOpen(open)}>
|
||||
{iconElement}
|
||||
</Button>
|
||||
</div>
|
||||
{open ? (
|
||||
<Overlay
|
||||
target={() => domRef.current}
|
||||
container={() => domRef.current}
|
||||
show
|
||||
>
|
||||
<PopOver>{renderButtons()}</PopOver>
|
||||
</Overlay>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Menu;
|
@ -5,7 +5,7 @@
|
||||
import React from 'react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import cx from 'classnames';
|
||||
import {Icon, render as amisRender, FormItem} from 'amis';
|
||||
import {Icon, FormItem} from 'amis';
|
||||
import {autobind, FormControlProps, Schema} from 'amis-core';
|
||||
import CodeMirrorEditor from 'amis-ui/lib/components/CodeMirror';
|
||||
import {FormulaPlugin, editorFactory} from './plugin';
|
||||
@ -14,6 +14,7 @@ import FormulaPicker from './FormulaPicker';
|
||||
import debounce from 'lodash/debounce';
|
||||
import CodeMirror from 'codemirror';
|
||||
import {resolveVariablesFromScope} from './utils';
|
||||
import Menu from './Menu';
|
||||
|
||||
export interface TextareaFormulaControlProps extends FormControlProps {
|
||||
height?: number; // 输入框的高度
|
||||
@ -22,7 +23,10 @@ export interface TextareaFormulaControlProps extends FormControlProps {
|
||||
|
||||
variableMode?: 'tree' | 'tabs';
|
||||
|
||||
additionalMenus?: Array<Schema>; // 附加底部按钮菜单项
|
||||
additionalMenus?: Array<{
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}>; // 附加底部按钮菜单项
|
||||
}
|
||||
|
||||
interface TextareaFormulaControlState {
|
||||
@ -30,7 +34,10 @@ interface TextareaFormulaControlState {
|
||||
|
||||
variables: any; // 变量数据
|
||||
|
||||
menusList: Schema[]; // 底部按钮菜单
|
||||
menusList: Array<{
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}>; // 底部按钮菜单
|
||||
|
||||
formulaPickerOpen: boolean; // 是否打开公式编辑器
|
||||
|
||||
@ -52,8 +59,6 @@ export class TextareaFormulaControl extends React.Component<
|
||||
|
||||
isUnmount: boolean;
|
||||
|
||||
wrapRef: any;
|
||||
|
||||
editorPlugin?: FormulaPlugin;
|
||||
|
||||
constructor(props: TextareaFormulaControlProps) {
|
||||
@ -72,7 +77,6 @@ export class TextareaFormulaControl extends React.Component<
|
||||
const {additionalMenus = [], value} = this.props;
|
||||
const menusList = [
|
||||
{
|
||||
type: 'button',
|
||||
label: '表达式',
|
||||
onClick: () => {
|
||||
this.setState({
|
||||
@ -187,7 +191,6 @@ export class TextareaFormulaControl extends React.Component<
|
||||
className={cx('ae-TextareaFormulaControl', {
|
||||
'is-fullscreen': this.state.isFullscreen
|
||||
})}
|
||||
ref={(ref: any) => (this.wrapRef = ref)}
|
||||
>
|
||||
<div className={cx('ae-TextareaResultBox')} style={resultBoxStyle}>
|
||||
<CodeMirrorEditor
|
||||
@ -197,21 +200,7 @@ export class TextareaFormulaControl extends React.Component<
|
||||
editorFactory={this.editorFactory}
|
||||
editorDidMount={this.handleEditorMounted}
|
||||
/>
|
||||
{amisRender({
|
||||
type: 'dropdown-button',
|
||||
className: 'ae-TextareaResultBox-dropdown',
|
||||
menuClassName: 'ae-TextareaResultBox-menus',
|
||||
popOverContainer: this.wrapRef,
|
||||
label: '',
|
||||
level: 'link',
|
||||
size: 'md',
|
||||
icon: 'fa fa-plus',
|
||||
trigger: 'hover',
|
||||
closeOnClick: true,
|
||||
closeOnOutside: true,
|
||||
hideCaret: true,
|
||||
buttons: menusList
|
||||
})}
|
||||
<Menu menus={menusList} />
|
||||
<div className="ae-TextareaResultBox-fullscreen">
|
||||
<a
|
||||
className={cx('Modal-fullscreen')}
|
||||
|
@ -13,7 +13,7 @@ export function editorFactory(
|
||||
) {
|
||||
return cm(dom, {
|
||||
value: props.value || '',
|
||||
autofocus: true,
|
||||
autofocus: false,
|
||||
lineWrapping: true
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user