mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 10:29:19 +08:00
chore: page 的 style 里针对 backgroundImage 自动加上 url (#3581)
This commit is contained in:
parent
2a5fbc588c
commit
97820a1075
23
__mocks__/monaco.ts
Normal file
23
__mocks__/monaco.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* monaco 加载没搞定,可能后续会先 mock
|
||||
*/
|
||||
|
||||
export const languages = {
|
||||
register: function (language: any) {},
|
||||
setMonarchTokensProvider: function (name: any, tokens: any) {},
|
||||
registerCompletionItemProvider: function (name: any, provider: any) {}
|
||||
};
|
||||
|
||||
export const editor = {
|
||||
defineTheme: function (name: any, theme: any) {},
|
||||
create: function (name: any, theme: any) {
|
||||
return {
|
||||
onDidChangeModelDecorations: () => {
|
||||
return {
|
||||
dispose: () => {}
|
||||
};
|
||||
},
|
||||
dispose: () => {}
|
||||
};
|
||||
}
|
||||
};
|
@ -4,7 +4,6 @@ exports[`Renderer:Page 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -89,7 +88,6 @@ exports[`Renderer:Page classNames 1`] = `
|
||||
<div
|
||||
className="cxd-Page cxd-Page--withSidebar"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-aside cxd-Page-aside--withWidth aside-class-name"
|
||||
@ -1056,7 +1054,6 @@ exports[`Renderer:Page initApi 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -1090,7 +1087,6 @@ exports[`Renderer:Page initApi error show Message 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -1140,7 +1136,6 @@ exports[`Renderer:Page initApi reFetch when condition changes 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -1174,7 +1169,6 @@ exports[`Renderer:Page initApi reFetch when condition changes 2`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2120,7 +2114,6 @@ exports[`Renderer:Page initApi show loading 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2154,7 +2147,6 @@ exports[`Renderer:Page initApi show loading 2`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2188,7 +2180,6 @@ exports[`Renderer:Page initApi silentPolling 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2222,7 +2213,6 @@ exports[`Renderer:Page initApi silentPolling 2`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2256,7 +2246,6 @@ exports[`Renderer:Page initApi silentPolling 3`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2284,7 +2273,6 @@ exports[`Renderer:Page initApi silentPolling 4`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2312,7 +2300,6 @@ exports[`Renderer:Page initData 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2340,7 +2327,6 @@ exports[`Renderer:Page initFetchOn trigger initApi fetch when condition becomes
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2374,7 +2360,6 @@ exports[`Renderer:Page location query 1`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
@ -2402,7 +2387,6 @@ exports[`Renderer:Page location query 2`] = `
|
||||
<div
|
||||
className="cxd-Page"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="cxd-Page-content"
|
||||
|
41
__tests__/utils/style.test.ts
Normal file
41
__tests__/utils/style.test.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import '../../src/utils/tpl.ts';
|
||||
import '../../src/utils/tpl-builtin';
|
||||
import '../../src/utils/tpl-lodash';
|
||||
|
||||
import {buildStyle} from '../../src/utils/style';
|
||||
|
||||
test('style var background', () => {
|
||||
expect(
|
||||
buildStyle('${style}', {
|
||||
style: {
|
||||
backgroundImage: 'http://www.example.com/a.png'
|
||||
}
|
||||
})
|
||||
).toEqual({
|
||||
backgroundImage: 'url("http://www.example.com/a.png")'
|
||||
});
|
||||
|
||||
expect(
|
||||
buildStyle(
|
||||
{
|
||||
backgroundImage: 'http://www.example.com/a.png'
|
||||
},
|
||||
{}
|
||||
)
|
||||
).toEqual({
|
||||
backgroundImage: 'url("http://www.example.com/a.png")'
|
||||
});
|
||||
});
|
||||
|
||||
test('style case', () => {
|
||||
expect(
|
||||
buildStyle(
|
||||
{
|
||||
'font-size': '10'
|
||||
},
|
||||
{}
|
||||
)
|
||||
).toEqual({
|
||||
fontSize: '10'
|
||||
});
|
||||
});
|
@ -8,6 +8,7 @@ import {BaseSchema, SchemaExpression} from '../Schema';
|
||||
import {evalExpression} from '../utils/tpl';
|
||||
import {resolveVariable, resolveVariableAndFilter} from '../utils/tpl-builtin';
|
||||
import {ClassNamesFn} from '../theme';
|
||||
import {buildStyle} from '../utils/style';
|
||||
|
||||
/**
|
||||
* Badge 角标。
|
||||
@ -91,6 +92,8 @@ export class Badge extends React.Component<BadgeProps, object> {
|
||||
const {classnames: cx, badge, data} = this.props;
|
||||
let {mode = 'dot', level = 'danger', style} = badge as BadgeSchema;
|
||||
|
||||
const customStyle = buildStyle(style, data);
|
||||
|
||||
if (typeof level === 'string' && level[0] === '$') {
|
||||
level = resolveVariableAndFilter(level, data);
|
||||
}
|
||||
@ -100,7 +103,7 @@ export class Badge extends React.Component<BadgeProps, object> {
|
||||
return (
|
||||
<span
|
||||
className={cx('Badge-dot', `Badge--${position}`, `Badge--${level}`)}
|
||||
style={{...offsetStyle, ...sizeStyle, ...style}}
|
||||
style={{...offsetStyle, ...sizeStyle, ...customStyle}}
|
||||
>
|
||||
{animationElement}
|
||||
</span>
|
||||
@ -113,7 +116,7 @@ export class Badge extends React.Component<BadgeProps, object> {
|
||||
`Badge--${position}`,
|
||||
`Badge--${level}`
|
||||
)}
|
||||
style={{...offsetStyle, ...sizeStyle, ...style}}
|
||||
style={{...offsetStyle, ...sizeStyle, ...customStyle}}
|
||||
>
|
||||
{text}
|
||||
{animationElement}
|
||||
@ -132,7 +135,7 @@ export class Badge extends React.Component<BadgeProps, object> {
|
||||
`Badge-ribbon--${position}`,
|
||||
`Badge--${level}`
|
||||
)}
|
||||
style={{...sizeStyle, ...style}}
|
||||
style={{...sizeStyle, ...customStyle}}
|
||||
>
|
||||
{text}
|
||||
{animationElement}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import {isClickOnInput} from '../utils/helper';
|
||||
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||
import {buildStyle} from '../utils/style';
|
||||
export interface CardProps extends ThemeProps {
|
||||
className?: string;
|
||||
headerClassName?: string;
|
||||
@ -29,6 +30,7 @@ export interface CardProps extends ThemeProps {
|
||||
secondary?: string | JSX.Element;
|
||||
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||
classnames: ClassNamesFn;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export class Card extends React.Component<CardProps> {
|
||||
@ -88,7 +90,8 @@ export class Card extends React.Component<CardProps> {
|
||||
descriptionPlaceholder,
|
||||
secondary,
|
||||
avatar,
|
||||
avatarText
|
||||
avatarText,
|
||||
data
|
||||
} = this.props;
|
||||
|
||||
let heading = null;
|
||||
@ -111,7 +114,7 @@ export class Card extends React.Component<CardProps> {
|
||||
) : avatarText ? (
|
||||
<span
|
||||
className={cx('Card-avtarText', avatarTextClassName)}
|
||||
style={avatarTextStyle}
|
||||
style={buildStyle(avatarTextStyle, data)}
|
||||
>
|
||||
{avatarText}
|
||||
</span>
|
||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import {Renderer, RendererProps} from '../factory';
|
||||
import {BaseSchema, SchemaClassName, SchemaCollection} from '../Schema';
|
||||
import {SchemaNode} from '../types';
|
||||
import {buildStyle} from '../utils/style';
|
||||
|
||||
/**
|
||||
* Container 容器渲染器。
|
||||
@ -80,14 +81,18 @@ export default class Container<T> extends React.Component<
|
||||
wrapperComponent,
|
||||
size,
|
||||
classnames: cx,
|
||||
style
|
||||
style,
|
||||
data
|
||||
} = this.props;
|
||||
|
||||
const Component =
|
||||
(wrapperComponent as keyof JSX.IntrinsicElements) || 'div';
|
||||
|
||||
return (
|
||||
<Component className={cx('Container', className)} style={style}>
|
||||
<Component
|
||||
className={cx('Container', className)}
|
||||
style={buildStyle(style, data)}
|
||||
>
|
||||
{this.renderBody()}
|
||||
</Component>
|
||||
);
|
||||
|
@ -31,6 +31,7 @@ import {SchemaRemark} from './Remark';
|
||||
import {onAction} from 'mobx-state-tree';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import {resolveVariable} from '../utils/tpl-builtin';
|
||||
import {buildStyle} from '../utils/style';
|
||||
|
||||
/**
|
||||
* 样式属性名及值
|
||||
@ -722,10 +723,7 @@ export default class Page extends React.Component<PageProps> {
|
||||
? ~regions.indexOf('aside')
|
||||
: aside && (!Array.isArray(aside) || aside.length);
|
||||
|
||||
let styleVar =
|
||||
typeof style === 'string'
|
||||
? resolveVariable(style, data) || {}
|
||||
: mapValues(style, s => resolveVariable(s, data) || s);
|
||||
const styleVar = buildStyle(style, data);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -7,6 +7,7 @@ import {Renderer, RendererProps} from '../factory';
|
||||
import {BaseSchema, SchemaExpression, SchemaObject, SchemaTpl} from '../Schema';
|
||||
import {resolveVariableAndFilter} from '../utils/tpl-builtin';
|
||||
import {visibilityFilter} from '../utils/helper';
|
||||
import {buildStyle} from '../utils/style';
|
||||
|
||||
export type PropertyItemProps = {
|
||||
/**
|
||||
@ -167,7 +168,8 @@ export default class Property extends React.Component<PropertyProps, object> {
|
||||
contentStyle,
|
||||
labelStyle,
|
||||
separator = ': ',
|
||||
mode = 'table'
|
||||
mode = 'table',
|
||||
data
|
||||
} = this.props;
|
||||
return rows.map((row, key) => {
|
||||
return (
|
||||
@ -175,10 +177,12 @@ export default class Property extends React.Component<PropertyProps, object> {
|
||||
{row.map((property, index) => {
|
||||
return mode === 'table' ? (
|
||||
<React.Fragment key={`item-${index}`}>
|
||||
<th style={labelStyle}>{render('label', property.label)}</th>
|
||||
<th style={buildStyle(labelStyle, data)}>
|
||||
{render('label', property.label)}
|
||||
</th>
|
||||
<td
|
||||
colSpan={property.span + property.span - 1} // 需要再补上 th 所占的列数
|
||||
style={contentStyle}
|
||||
style={buildStyle(contentStyle, data)}
|
||||
>
|
||||
{render('content', property.content)}
|
||||
</td>
|
||||
@ -186,10 +190,10 @@ export default class Property extends React.Component<PropertyProps, object> {
|
||||
) : (
|
||||
<td
|
||||
colSpan={property.span}
|
||||
style={contentStyle}
|
||||
style={buildStyle(contentStyle, data)}
|
||||
key={`item-${index}`}
|
||||
>
|
||||
<span style={labelStyle}>
|
||||
<span style={buildStyle(labelStyle, data)}>
|
||||
{render('label', property.label)}
|
||||
</span>
|
||||
{separator}
|
||||
@ -210,6 +214,7 @@ export default class Property extends React.Component<PropertyProps, object> {
|
||||
classnames: cx,
|
||||
className,
|
||||
titleStyle,
|
||||
data,
|
||||
mode = 'table'
|
||||
} = this.props;
|
||||
|
||||
@ -218,7 +223,7 @@ export default class Property extends React.Component<PropertyProps, object> {
|
||||
return (
|
||||
<div
|
||||
className={cx('Property', `Property--${mode}`, className)}
|
||||
style={style}
|
||||
style={buildStyle(style, data)}
|
||||
>
|
||||
<table>
|
||||
{title ? (
|
||||
@ -226,7 +231,7 @@ export default class Property extends React.Component<PropertyProps, object> {
|
||||
<tr>
|
||||
<th
|
||||
colSpan={mode === 'table' ? column + column : column}
|
||||
style={titleStyle}
|
||||
style={buildStyle(titleStyle, data)}
|
||||
>
|
||||
{title}
|
||||
</th>
|
||||
|
@ -6,6 +6,7 @@ import {anyChanged, getPropValue} from '../utils/helper';
|
||||
import {escapeHtml} from '../utils/tpl-builtin';
|
||||
import {BaseSchema, SchemaTpl} from '../Schema';
|
||||
import {BadgeSchema, withBadge} from '../components/Badge';
|
||||
import {buildStyle} from '../utils/style';
|
||||
|
||||
/**
|
||||
* tpl 渲染器
|
||||
@ -115,7 +116,8 @@ export class Tpl extends React.Component<TplProps, object> {
|
||||
wrapperComponent,
|
||||
inline,
|
||||
classnames: cx,
|
||||
style
|
||||
style,
|
||||
data
|
||||
} = this.props;
|
||||
const Component = wrapperComponent || (inline ? 'span' : 'div');
|
||||
|
||||
@ -123,7 +125,7 @@ export class Tpl extends React.Component<TplProps, object> {
|
||||
<Component
|
||||
ref={this.htmlRef}
|
||||
className={cx('TplField', className)}
|
||||
style={style}
|
||||
style={buildStyle(style, data)}
|
||||
>
|
||||
<span>{this.getContent()}</span>
|
||||
</Component>
|
||||
|
@ -4,6 +4,7 @@ import {BaseSchema, SchemaCollection} from '../Schema';
|
||||
import {resolveVariable} from '../utils/tpl-builtin';
|
||||
import {SchemaNode} from '../types';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import {buildStyle} from '../utils/style';
|
||||
|
||||
/**
|
||||
* Wrapper 容器渲染器。
|
||||
@ -65,11 +66,6 @@ export default class Wrapper extends React.Component<WrapperProps, object> {
|
||||
return this.renderBody();
|
||||
}
|
||||
|
||||
let styleVar =
|
||||
typeof style === 'string'
|
||||
? resolveVariable(style, data) || {}
|
||||
: mapValues(style, s => resolveVariable(s, data) || s);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
@ -77,7 +73,7 @@ export default class Wrapper extends React.Component<WrapperProps, object> {
|
||||
size && size !== 'none' ? `Wrapper--${size}` : '',
|
||||
className
|
||||
)}
|
||||
style={styleVar}
|
||||
style={buildStyle(style, data)}
|
||||
>
|
||||
{this.renderBody()}
|
||||
</div>
|
||||
|
56
src/utils/style.ts
Normal file
56
src/utils/style.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 处理样式相关的工具方法,不放 helper 里是为了避免循环依赖
|
||||
*/
|
||||
|
||||
import {resolveVariableAndFilter} from './tpl-builtin';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import camelCase from 'lodash/camelCase';
|
||||
|
||||
function autoAddImageURL(image: string) {
|
||||
// 只支持单个的情况,并简单滤掉 linear-gradient 等情况
|
||||
if (
|
||||
typeof image === 'string' &&
|
||||
image.indexOf(',') === -1 &&
|
||||
image.indexOf('(') === -1
|
||||
) {
|
||||
return `url("${image}")`;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理配置中的 style,主要做三件事:
|
||||
* 1. 变量解析
|
||||
* 2. 将 font-size 之类的错误写法转成 fontSize
|
||||
* 3. 针对 image 自动加 url
|
||||
*/
|
||||
export function buildStyle(style: any, data: any) {
|
||||
if (!style) {
|
||||
return style;
|
||||
}
|
||||
let styleVar =
|
||||
typeof style === 'string'
|
||||
? resolveVariableAndFilter(style, data, '| raw') || {}
|
||||
: mapValues(style, s => resolveVariableAndFilter(s, data, '| raw') || s);
|
||||
|
||||
Object.keys(styleVar).forEach((key: string) => {
|
||||
if (key.indexOf('-') !== -1) {
|
||||
styleVar[camelCase(key)] = styleVar[key];
|
||||
delete styleVar[key];
|
||||
}
|
||||
});
|
||||
|
||||
if (styleVar.backgroundImage) {
|
||||
styleVar.backgroundImage = autoAddImageURL(styleVar.backgroundImage);
|
||||
}
|
||||
|
||||
if (styleVar.borderImage) {
|
||||
styleVar.borderImage = autoAddImageURL(styleVar.borderImage);
|
||||
}
|
||||
|
||||
if (styleVar.listStyleImage) {
|
||||
styleVar.listStyleImage = autoAddImageURL(styleVar.listStyleImage);
|
||||
}
|
||||
|
||||
return styleVar;
|
||||
}
|
Loading…
Reference in New Issue
Block a user