mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 12:08:13 +08:00
amis-saas-6892 fix: 长文本公式输入框支持全屏
Change-Id: Ia0998f0baeaa4c9e4f359e6b87b77fbb4226d953
This commit is contained in:
parent
fa51bef367
commit
82749c63c5
@ -7,7 +7,6 @@ import {autobind, FormControlProps} from 'amis-core';
|
||||
import cx from 'classnames';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import {FormItem, Button, Icon} from 'amis';
|
||||
import {renderFormulaValue} from './textarea-formula/TextareaFormulaControl';
|
||||
import FormulaPicker from './textarea-formula/FormulaPicker';
|
||||
import {FormulaEditor} from 'amis-ui/lib/components/formula/Editor';
|
||||
import type {VariableItem} from 'amis-ui/lib/components/formula/Editor';
|
||||
@ -83,6 +82,13 @@ export default class ExpressionFormulaControl extends React.Component<
|
||||
});
|
||||
}
|
||||
|
||||
@autobind
|
||||
renderFormulaValue(item: any) {
|
||||
const html = {__html: item.html};
|
||||
// bca-disable-next-line
|
||||
return <span dangerouslySetInnerHTML={html}></span>;
|
||||
}
|
||||
|
||||
async resolveVariablesFromScope() {
|
||||
const {node, manager} = this.props.formProps || this.props;
|
||||
await manager?.getContextSchemas(node);
|
||||
@ -140,7 +146,7 @@ export default class ExpressionFormulaControl extends React.Component<
|
||||
tooltip={{
|
||||
placement: 'bottom',
|
||||
tooltipClassName: 'btn-configured-tooltip',
|
||||
children: () => renderFormulaValue(highlightValue)
|
||||
children: () => this.renderFormulaValue(highlightValue)
|
||||
}}
|
||||
onClick={this.openFormulaPickerModal}
|
||||
>
|
||||
|
@ -6,6 +6,7 @@ import React from 'react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import cx from 'classnames';
|
||||
import {
|
||||
Icon,
|
||||
render as amisRender,
|
||||
FormItem
|
||||
} from 'amis';
|
||||
@ -39,6 +40,8 @@ interface TextareaFormulaControlState {
|
||||
formulaPickerValue: string; // 公式编辑器内容
|
||||
|
||||
expressionBrace?: Array<CodeMirror.Position>; // 表达式所在位置
|
||||
|
||||
isFullscreen: boolean; //是否全屏
|
||||
}
|
||||
|
||||
export class TextareaFormulaControl extends React.Component<
|
||||
@ -46,7 +49,8 @@ export class TextareaFormulaControl extends React.Component<
|
||||
TextareaFormulaControlState
|
||||
> {
|
||||
static defaultProps: Partial<TextareaFormulaControlProps> = {
|
||||
variableMode: 'tabs'
|
||||
variableMode: 'tabs',
|
||||
height: 100
|
||||
};
|
||||
|
||||
isUnmount: boolean;
|
||||
@ -62,7 +66,8 @@ export class TextareaFormulaControl extends React.Component<
|
||||
variables: [],
|
||||
menusList: [],
|
||||
formulaPickerOpen: false,
|
||||
formulaPickerValue: ''
|
||||
formulaPickerValue: '',
|
||||
isFullscreen: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -121,7 +126,7 @@ export class TextareaFormulaControl extends React.Component<
|
||||
}
|
||||
|
||||
@autobind
|
||||
onExpressionClick(expression: string, brace: Array<CodeMirror.Position>) {
|
||||
onExpressionClick(expression: string, brace?: Array<CodeMirror.Position>) {
|
||||
this.setState({
|
||||
formulaPickerValue: expression,
|
||||
formulaPickerOpen: true,
|
||||
@ -137,7 +142,7 @@ export class TextareaFormulaControl extends React.Component<
|
||||
@autobind
|
||||
handleConfirm(value: any) {
|
||||
const {expressionBrace} = this.state;
|
||||
// // 去除可能包裹的最外层的${}
|
||||
// 去除可能包裹的最外层的${}
|
||||
value = value.replace(/^\$\{(.*)\}$/, (match: string, p1: string) => p1);
|
||||
value = value ? `\${${value}}` : value;
|
||||
this.editorPlugin?.insertContent(value, 'expression', expressionBrace);
|
||||
@ -164,6 +169,13 @@ export class TextareaFormulaControl extends React.Component<
|
||||
this.editorPlugin = new FormulaPlugin(editor, cm, () => ({...this.props, variables}), this.onExpressionClick);
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleFullscreenModeChange() {
|
||||
this.setState({
|
||||
isFullscreen: !this.state.isFullscreen
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
className,
|
||||
@ -173,7 +185,7 @@ export class TextareaFormulaControl extends React.Component<
|
||||
height,
|
||||
...rest
|
||||
} = this.props;
|
||||
const {value, menusList, formulaPickerOpen, formulaPickerValue} = this.state;
|
||||
const {value, menusList, formulaPickerOpen, formulaPickerValue, isFullscreen} = this.state;
|
||||
|
||||
const variables = rest.variables || this.state.variables || [];
|
||||
|
||||
@ -184,32 +196,49 @@ export class TextareaFormulaControl extends React.Component<
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx('ae-TextareaFormulaControl')} ref={(ref: any) => this.wrapRef = ref}>
|
||||
<div className='ae-TextareaResultBox' style={resultBoxStyle}>
|
||||
<div className="ae-TextareaResultBox-content">
|
||||
<CodeMirrorEditor
|
||||
className="ae-TextareaResultBox-editor"
|
||||
value={value}
|
||||
onChange={this.handleOnChange}
|
||||
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',
|
||||
placement: 'top',
|
||||
trigger: 'hover',
|
||||
closeOnClick: true,
|
||||
closeOnOutside: true,
|
||||
hideCaret: true,
|
||||
buttons: menusList
|
||||
})}
|
||||
<div className={cx('ae-TextareaFormulaControl', {'is-fullscreen': this.state.isFullscreen})} ref={(ref: any) => this.wrapRef = ref}>
|
||||
<div
|
||||
className={cx('ae-TextareaResultBox')}
|
||||
style={resultBoxStyle}
|
||||
>
|
||||
<CodeMirrorEditor
|
||||
className="ae-TextareaResultBox-editor"
|
||||
value={value}
|
||||
onChange={this.handleOnChange}
|
||||
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
|
||||
})}
|
||||
<div className="ae-TextareaResultBox-fullscreen">
|
||||
<a
|
||||
className={cx('Modal-fullscreen')}
|
||||
data-tooltip={
|
||||
isFullscreen
|
||||
? '退出全屏'
|
||||
: '全屏'
|
||||
}
|
||||
data-position="left"
|
||||
onClick={this.handleFullscreenModeChange}
|
||||
>
|
||||
<Icon
|
||||
icon={isFullscreen ? 'compress-alt' : 'expand-alt'}
|
||||
className="icon"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{formulaPickerOpen ? (
|
||||
|
@ -22,7 +22,7 @@ export class FormulaPlugin {
|
||||
readonly editor: CodeMirror.Editor,
|
||||
readonly cm: typeof CodeMirror,
|
||||
readonly getProps: () => TextareaFormulaControlProps,
|
||||
readonly onExpressionClick: (expression: string, brace: Array<CodeMirror.Position>) => any
|
||||
readonly onExpressionClick: (expression: string, brace?: Array<CodeMirror.Position>) => any
|
||||
) {
|
||||
const {value} = this.getProps();
|
||||
if (value) {
|
||||
@ -57,6 +57,32 @@ export class FormulaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
// 找到表达式所在的位置
|
||||
getExpressionBrace(expression: string) {
|
||||
const editor = this.editor;
|
||||
const lines = editor.lineCount();
|
||||
for (let line = 0; line < lines; line++) {
|
||||
const content = editor.getLine(line);
|
||||
const braces = this.computedBracesPosition(content);
|
||||
for (let i = 0; i < braces.length; i++) {
|
||||
// 替换每个公式表达式中的内容
|
||||
const start = braces[i].begin;
|
||||
const end = braces[i].end;
|
||||
if (expression === content.slice(start, end)) {
|
||||
return [{
|
||||
line: line,
|
||||
ch: start - 2
|
||||
},
|
||||
{
|
||||
line: line,
|
||||
ch: end + 1
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 计算 `${`、`}` 括号的位置,如 ${a}+${b}, 结果是 [ { from: 0, to: 3 }, { from: 5, to: 8 } ]
|
||||
computedBracesPosition(exp: string) {
|
||||
const braces: {begin: number; end: number}[] = [];
|
||||
@ -155,7 +181,8 @@ export class FormulaPlugin {
|
||||
text.innerText = '表达式';
|
||||
text.setAttribute('data-expression', expression);
|
||||
text.onclick = () => {
|
||||
this.onExpressionClick(expression, [from, to]);
|
||||
const brace = this.getExpressionBrace(expression);
|
||||
this.onExpressionClick(expression, brace);
|
||||
}
|
||||
const {variables} = this.getProps();
|
||||
const highlightValue = FormulaEditor.highlightValue(expression, variables) || {
|
||||
|
Loading…
Reference in New Issue
Block a user