feat: copy 支持富文本 (#2695)

This commit is contained in:
吴多益 2021-10-13 11:41:43 +08:00 committed by GitHub
parent 303c5a3a62
commit 6dca72d875
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 68 deletions

View File

@ -555,6 +555,18 @@ icon 也可以是 url 地址,比如
}
```
可以通过 `copyFormat` 设置复制的格式,默认是文本
```schema: scope="body"
{
"label": "复制一段富文本",
"type": "button",
"actionType": "copy",
"copyFormat": "text/html",
"content": "<a href='http://www.baidu.com'>link</a> <b>bold</b>"
}
```
**属性表**
| 属性名 | 类型 | 默认值 | 说明 |

View File

@ -664,10 +664,10 @@ class MyComponent extends React.Component<any, any> {
##### copy
```ts
(contents: string, options?: {shutup: boolean})
(contents: string, options?: {silent: boolean, format?: string})
```
用来实现内容复制
用来实现内容复制,其中 `format` 可以为 text/html或 text/plain
##### session

View File

@ -190,8 +190,8 @@ export default class PlayGround extends React.Component {
toast[type] ? toast[type](msg) : console.warn('[Notify]', type, msg),
alert,
confirm,
copy: content => {
copy(content);
copy: (content, options) => {
copy(content, options);
toast.success(__('System.copy'));
}
};

View File

@ -116,8 +116,8 @@ export default function (schema, showCode, envOverrides) {
return axios[method](url, data, config);
},
isCancel: value => axios.isCancel(value),
copy: content => {
copy(content);
copy: (content, options) => {
copy(content, options);
toast.success('内容已复制到粘贴板');
},
blockRouting: fn => {

View File

@ -176,7 +176,7 @@ export function embed(
const amisEnv = {
getModalContainer: () =>
env?.getModalContainer?.() || document.querySelector('.amis-scope'),
notify: (type: string, msg: string) =>
notify: (type: 'success' | 'error' | 'warning' | 'info', msg: string) =>
toast[type] ? toast[type](msg) : console.warn('[Notify]', type, msg),
alert,
confirm,
@ -283,7 +283,7 @@ export function embed(
}
// 支持返回各种报错信息
config.validateStatus = function (status) {
config.validateStatus = function () {
return true;
};
@ -320,8 +320,8 @@ export function embed(
},
isCancel: (value: any) => (axios as any).isCancel(value),
copy: (contents: string, options: any = {}) => {
const ret = copy(contents, options);
ret && options.shutup !== true && toast.info(__('System.copy'));
const ret = copy(contents);
ret && options.silent !== true && toast.info(__('System.copy'));
return ret;
},
richTextToken: '',

View File

@ -39,7 +39,7 @@ class AMISComponent extends React.Component {
responseType,
config, //
headers //
}: any) => {
}) => {
config = {
dataType: 'json',
...config
@ -52,7 +52,7 @@ class AMISComponent extends React.Component {
}
//
config.validateStatus = function (status) {
config.validateStatus = function () {
return true;
};
@ -77,9 +77,9 @@ class AMISComponent extends React.Component {
}
return response;
},
isCancel: (value: any) => (axios as any).isCancel(value),
copy: content => {
copy(content);
isCancel: value => axios.isCancel(value),
copy: (content, optinos) => {
copy(content, optinos);
toast.success('内容已复制到粘贴板');
}
})}
@ -88,6 +88,6 @@ class AMISComponent extends React.Component {
}
}
export function bootstrap(mountTo, initalState) {
export function bootstrap(mountTo) {
render(<AMISComponent />, mountTo);
}

View File

@ -116,12 +116,14 @@ export class RootRenderer extends React.Component<RootRendererProps> {
);
} else if (action.actionType === 'email') {
const mailTo = filter(action.to, ctx);
const mailInfo = mapValues(pick(action, 'to', 'cc', 'bcc', 'subject', 'body'), val => filter(val, ctx));
const mailInfo = mapValues(
pick(action, 'to', 'cc', 'bcc', 'subject', 'body'),
val => filter(val, ctx)
);
const mailStr = qs.stringify(mailInfo);
const mailto = `mailto:${mailTo}?${mailStr}`;
window.open(mailto);
} else if (action.actionType === 'dialog') {
store.setCurrentAction(action);
store.openDialog(ctx);
@ -159,7 +161,10 @@ export class RootRenderer extends React.Component<RootRendererProps> {
action.actionType === 'copy' &&
(action.content || action.copy)
) {
env.copy && env.copy(filter(action.content || action.copy, ctx, '| raw'));
env.copy &&
env.copy(filter(action.content || action.copy, ctx, '| raw'), {
format: action.copyFormat
});
}
}

View File

@ -41,7 +41,7 @@ export interface RendererEnv {
schema: Schema,
props: any
) => null | RendererConfig;
copy?: (contents: string) => void;
copy?: (contents: string, format?: any) => void;
getModalContainer?: () => HTMLElement;
theme: ThemeInstance;
affixOffsetTop: number;

View File

@ -99,7 +99,7 @@ export interface RenderOptions {
schema: Schema,
props: any
) => null | RendererConfig;
copy?: (contents: string) => void;
copy?: (contents: string, options?: any) => void;
getModalContainer?: () => HTMLElement;
loadRenderer?: (
schema: Schema,

View File

@ -347,6 +347,7 @@ const ActionProps = [
'mergeData',
'index',
'copy',
'copyFormat',
'payload',
'requireSelected'
];

View File

@ -32,54 +32,56 @@ export interface CopyableProps extends RendererProps {
copyable: SchemaCopyable;
}
export const HocCopyable = () => (Component: React.ComponentType<any>): any => {
class QuickEditComponent extends React.PureComponent<CopyableProps, any> {
static ComposedComponent = Component;
handleClick(content: string) {
const {env} = this.props;
env.copy && env.copy(content);
}
render() {
const {
copyable,
name,
className,
data,
noHoc,
classnames: cx,
translate: __
} = this.props;
if (copyable && !noHoc) {
const content = filter(
(copyable as SchemaCopyableObject).content ||
'${' + name + ' | raw }',
data
);
if (content) {
return (
<Component
{...this.props}
className={cx(`Field--copyable`, className)}
>
<Component {...this.props} wrapperComponent={''} noHoc />
<a
key="edit-btn"
data-tooltip={__('Copyable.tip')}
className={cx('Field-copyBtn')}
onClick={this.handleClick.bind(this, content)}
>
<Icon icon="copy" className="icon" />
</a>
</Component>
);
}
export const HocCopyable =
() =>
(Component: React.ComponentType<any>): any => {
class QuickEditComponent extends React.PureComponent<CopyableProps, any> {
static ComposedComponent = Component;
handleClick(content: string) {
const {env, copyFormat} = this.props;
env.copy && env.copy(content, {format: copyFormat});
}
render() {
const {
copyable,
name,
className,
data,
noHoc,
classnames: cx,
translate: __
} = this.props;
if (copyable && !noHoc) {
const content = filter(
(copyable as SchemaCopyableObject).content ||
'${' + name + ' | raw }',
data
);
if (content) {
return (
<Component
{...this.props}
className={cx(`Field--copyable`, className)}
>
<Component {...this.props} wrapperComponent={''} noHoc />
<a
key="edit-btn"
data-tooltip={__('Copyable.tip')}
className={cx('Field-copyBtn')}
onClick={this.handleClick.bind(this, content)}
>
<Icon icon="copy" className="icon" />
</a>
</Component>
);
}
}
return <Component {...this.props} />;
}
return <Component {...this.props} />;
}
}
hoistNonReactStatic(QuickEditComponent, Component);
return QuickEditComponent;
};
hoistNonReactStatic(QuickEditComponent, Component);
return QuickEditComponent;
};
export default HocCopyable;