forked from p96170835/amis
Images 样式调整
This commit is contained in:
parent
44f966e791
commit
a5befaf368
|
@ -0,0 +1,67 @@
|
||||||
|
.#{$ns}Images {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: -$gap-xs;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
display: flex;
|
||||||
|
margin: $gap-xs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Image {
|
||||||
|
display: inline-block;
|
||||||
|
border: $borderWidth solid $borderColor;
|
||||||
|
padding: $gap-xs;
|
||||||
|
|
||||||
|
&-thumb {
|
||||||
|
width: px2rem(108px);
|
||||||
|
height: px2rem(108px);
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwMCIgaGVpZ2h0PSI0MDAiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdHRlcm4gaWQ9ImdyaWQiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgICAgICAgIDxyZWN0IGZpbGw9ImJsYWNrIiB4PSIwIiB5PSIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIG9wYWNpdHk9IjAuMSIgLz4KICAgICAgICAgICAgPHJlY3QgZmlsbD0id2hpdGUiIHg9IjEwIiB5PSIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+CiAgICAgICAgICAgIDxyZWN0IGZpbGw9ImJsYWNrIiB4PSIxMCIgeT0iMTAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgb3BhY2l0eT0iMC4xIiAvPgogICAgICAgICAgICA8cmVjdCBmaWxsPSJ3aGl0ZSIgeD0iMCIgeT0iMTAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz4KICAgICAgICA8L3BhdHRlcm4+CiAgICA8L2RlZnM+CiAgICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWQpIiB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiAvPgo8L3N2Zz4=');
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-thumb--w-full > img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (object-fit: contain) {
|
||||||
|
&-thumb--contain > img {
|
||||||
|
position: static;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (object-fit: cover) {
|
||||||
|
&-thumb--cover > img {
|
||||||
|
position: static;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}ImageField {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
|
@ -70,28 +70,19 @@
|
||||||
&-item {
|
&-item {
|
||||||
border: $borderWidth solid $borderColor;
|
border: $borderWidth solid $borderColor;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
padding: px2rem(5px);
|
padding: $gap-xs;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: px2rem(15px);
|
margin-right: $gap-base;
|
||||||
margin-bottom: px2rem(15px);
|
margin-bottom: $gap-base;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-itemImageWrap {
|
&-image {
|
||||||
width: px2rem(108px);
|
width: 100%;
|
||||||
height: px2rem(108px);
|
height: 100%;
|
||||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwMCIgaGVpZ2h0PSI0MDAiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdHRlcm4gaWQ9ImdyaWQiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgICAgICAgIDxyZWN0IGZpbGw9ImJsYWNrIiB4PSIwIiB5PSIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIG9wYWNpdHk9IjAuMSIgLz4KICAgICAgICAgICAgPHJlY3QgZmlsbD0id2hpdGUiIHg9IjEwIiB5PSIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+CiAgICAgICAgICAgIDxyZWN0IGZpbGw9ImJsYWNrIiB4PSIxMCIgeT0iMTAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgb3BhY2l0eT0iMC4xIiAvPgogICAgICAgICAgICA8cmVjdCBmaWxsPSJ3aGl0ZSIgeD0iMCIgeT0iMTAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz4KICAgICAgICA8L3BhdHRlcm4+CiAgICA8L2RlZnM+CiAgICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWQpIiB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiAvPgo8L3N2Zz4=');
|
padding: 0;
|
||||||
overflow: hidden;
|
border: none;
|
||||||
position: relative;
|
display: block;
|
||||||
|
|
||||||
> img {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
height: 100%;
|
|
||||||
width: auto;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-itemOverlay {
|
&-itemOverlay {
|
||||||
|
|
|
@ -534,6 +534,7 @@ $Card-actions-onChecked-onHover-bg: $white;
|
||||||
@import '../components/wrapper';
|
@import '../components/wrapper';
|
||||||
@import '../components/status';
|
@import '../components/status';
|
||||||
@import '../components/carousel';
|
@import '../components/carousel';
|
||||||
|
@import '../components/images';
|
||||||
|
|
||||||
@import '../components/form/fieldset';
|
@import '../components/form/fieldset';
|
||||||
@import '../components/form/group';
|
@import '../components/form/group';
|
||||||
|
|
|
@ -200,6 +200,7 @@ pre {
|
||||||
@import '../components/wrapper';
|
@import '../components/wrapper';
|
||||||
@import '../components/status';
|
@import '../components/status';
|
||||||
@import '../components/carousel';
|
@import '../components/carousel';
|
||||||
|
@import '../components/images';
|
||||||
|
|
||||||
@import '../components/form/fieldset';
|
@import '../components/form/fieldset';
|
||||||
@import '../components/form/group';
|
@import '../components/form/group';
|
||||||
|
|
|
@ -65,6 +65,7 @@ $Form-input-borderColor: #cfdadd;
|
||||||
@import '../components/wrapper';
|
@import '../components/wrapper';
|
||||||
@import '../components/status';
|
@import '../components/status';
|
||||||
@import '../components/carousel';
|
@import '../components/carousel';
|
||||||
|
@import '../components/images';
|
||||||
|
|
||||||
@import '../components/form/fieldset';
|
@import '../components/form/fieldset';
|
||||||
@import '../components/form/group';
|
@import '../components/form/group';
|
||||||
|
|
|
@ -136,6 +136,7 @@ import './renderers/Grid';
|
||||||
import './renderers/HBox';
|
import './renderers/HBox';
|
||||||
import './renderers/VBox';
|
import './renderers/VBox';
|
||||||
import './renderers/Image';
|
import './renderers/Image';
|
||||||
|
import './renderers/Images';
|
||||||
import './renderers/List';
|
import './renderers/List';
|
||||||
import './renderers/Operation';
|
import './renderers/Operation';
|
||||||
import './renderers/Page';
|
import './renderers/Page';
|
||||||
|
|
|
@ -14,6 +14,7 @@ import Button from '../../components/Button';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import accepts from 'attr-accept';
|
import accepts from 'attr-accept';
|
||||||
import {getNameFromUrl} from './File';
|
import {getNameFromUrl} from './File';
|
||||||
|
import ImageComponent from '../Image';
|
||||||
|
|
||||||
let preventEvent = (e: any) => e.stopPropagation();
|
let preventEvent = (e: any) => e.stopPropagation();
|
||||||
|
|
||||||
|
@ -990,19 +991,17 @@ export default class ImageControl extends React.Component<
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div
|
<ImageComponent
|
||||||
key="image"
|
key="image"
|
||||||
className={cx('ImageControl-itemImageWrap')}
|
className={cx('ImageControl-image')}
|
||||||
>
|
onLoad={this.handleImageLoaded.bind(
|
||||||
<img
|
this,
|
||||||
onLoad={this.handleImageLoaded.bind(
|
key
|
||||||
this,
|
)}
|
||||||
key
|
src={file.preview || file.url}
|
||||||
)}
|
alt={file.name}
|
||||||
src={file.preview || file.url}
|
thumbMode="contain"
|
||||||
alt={file.name}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
key="overlay"
|
key="overlay"
|
||||||
|
|
|
@ -1,24 +1,78 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Renderer, RendererProps} from '../factory';
|
import {Renderer, RendererProps} from '../factory';
|
||||||
import {ServiceStore, IServiceStore} from '../store/service';
|
|
||||||
import {Api, SchemaNode} from '../types';
|
|
||||||
import {filter} from '../utils/tpl';
|
import {filter} from '../utils/tpl';
|
||||||
import cx from 'classnames';
|
import {ClassNamesFn, themeable} from '../theme';
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
export interface ImageProps extends RendererProps {
|
export interface ImageProps {
|
||||||
|
src: string;
|
||||||
|
title?: string;
|
||||||
|
alt?: string;
|
||||||
|
className?: string;
|
||||||
|
imageClassName?: string;
|
||||||
|
description?: string;
|
||||||
|
thumbMode?: 'w-full' | 'h-full' | 'contain' | 'cover';
|
||||||
|
classnames: ClassNamesFn;
|
||||||
|
classPrefix: string;
|
||||||
|
onLoad?: React.EventHandler<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Image extends React.Component<ImageProps> {
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
classnames: cx,
|
||||||
|
className,
|
||||||
|
imageClassName,
|
||||||
|
thumbMode,
|
||||||
|
src,
|
||||||
|
alt,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
onLoad
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('Image', className)}>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
'Image-thumb',
|
||||||
|
thumbMode ? `Image-thumb--${thumbMode}` : ''
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
onLoad={onLoad}
|
||||||
|
className={cx(imageClassName)}
|
||||||
|
src={src}
|
||||||
|
alt={alt}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{title || description ? (
|
||||||
|
<div key="caption" className={cx('Image-caption')}>
|
||||||
|
{title ? <div className={cx('Image-title')}>{title}</div> : null}
|
||||||
|
{description ? (
|
||||||
|
<div className={cx('Image-description')}>{description}</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const ThemedImage = themeable(Image);
|
||||||
|
export default ThemedImage;
|
||||||
|
|
||||||
|
export interface ImageFieldProps extends RendererProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
imageClassName?: string;
|
imageClassName?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
thumbMode: 'w-full' | 'h-full' | 'contain' | 'cover';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ImageField extends React.Component<ImageProps, object> {
|
export class ImageField extends React.Component<ImageFieldProps, object> {
|
||||||
static defaultProps: Partial<ImageProps> = {
|
static defaultProps: Pick<ImageFieldProps, 'defaultImage' | 'thumbMode'> = {
|
||||||
className: 'thumb-lg',
|
|
||||||
imageClassName: 'r',
|
|
||||||
defaultImage:
|
defaultImage:
|
||||||
'https://fex.bdstatic.com/n/static/amis/renderers/crud/field/placeholder_cfad9b1.png'
|
'https://fex.bdstatic.com/n/static/amis/renderers/crud/field/placeholder_cfad9b1.png',
|
||||||
|
thumbMode: 'contain'
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -27,11 +81,11 @@ export class ImageField extends React.Component<ImageProps, object> {
|
||||||
defaultImage,
|
defaultImage,
|
||||||
description,
|
description,
|
||||||
title,
|
title,
|
||||||
render,
|
|
||||||
data,
|
data,
|
||||||
imageClassName,
|
imageClassName,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
src
|
src,
|
||||||
|
thumbMode
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const finnalSrc = src ? filter(src, data, '| raw') : '';
|
const finnalSrc = src ? filter(src, data, '| raw') : '';
|
||||||
|
@ -39,18 +93,13 @@ export class ImageField extends React.Component<ImageProps, object> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('ImageField', className)}>
|
<div className={cx('ImageField', className)}>
|
||||||
<img
|
<ThemedImage
|
||||||
className={imageClassName}
|
imageClassName={imageClassName}
|
||||||
src={finnalSrc || value || defaultImage}
|
src={finnalSrc || value || defaultImage}
|
||||||
|
title={filter(title, data)}
|
||||||
|
description={filter(description, data)}
|
||||||
|
thumbMode={thumbMode}
|
||||||
/>
|
/>
|
||||||
{title || description ? (
|
|
||||||
<div key="caption" className={cx('ImageField-caption')}>
|
|
||||||
{title ? (
|
|
||||||
<div className="text-md">{filter(title, data)}</div>
|
|
||||||
) : null}
|
|
||||||
{render('description', description as string)}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -61,18 +110,3 @@ export class ImageField extends React.Component<ImageProps, object> {
|
||||||
name: 'image'
|
name: 'image'
|
||||||
})
|
})
|
||||||
export class ImageFieldRenderer extends ImageField {}
|
export class ImageFieldRenderer extends ImageField {}
|
||||||
|
|
||||||
@Renderer({
|
|
||||||
test: /(^|\/)images$/
|
|
||||||
})
|
|
||||||
export class ImagesFieldRenderer extends ImageField {
|
|
||||||
static defaultProps: Partial<ImageProps> = {
|
|
||||||
...ImageField.defaultProps,
|
|
||||||
multiple: true,
|
|
||||||
delimiter: ','
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <p>Todo</p>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Renderer, RendererProps} from '../factory';
|
||||||
|
import {filter} from '../utils/tpl';
|
||||||
|
import {resolveVariable, isPureVariable} from '../utils/tpl-builtin';
|
||||||
|
import Image from './Image';
|
||||||
|
|
||||||
|
export interface ImagesProps extends RendererProps {
|
||||||
|
className: string;
|
||||||
|
defaultImage: string;
|
||||||
|
placeholder: string;
|
||||||
|
delimiter: string;
|
||||||
|
thumbMode: 'w-full' | 'h-full' | 'contain' | 'cover';
|
||||||
|
name?: string;
|
||||||
|
value?: any;
|
||||||
|
source?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ImagesField extends React.Component<ImagesProps> {
|
||||||
|
static defaultProps: Pick<
|
||||||
|
ImagesProps,
|
||||||
|
'className' | 'delimiter' | 'defaultImage' | 'placehoder' | 'thumbMode'
|
||||||
|
> = {
|
||||||
|
className: '',
|
||||||
|
delimiter: ',',
|
||||||
|
defaultImage:
|
||||||
|
'https://fex.bdstatic.com/n/static/amis/renderers/crud/field/placeholder_cfad9b1.png',
|
||||||
|
placehoder: '-',
|
||||||
|
thumbMode: 'contain'
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
className,
|
||||||
|
defaultImage,
|
||||||
|
thumbMode,
|
||||||
|
data,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
placeholder,
|
||||||
|
classnames: cx,
|
||||||
|
source,
|
||||||
|
delimiter
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
let list: any;
|
||||||
|
|
||||||
|
if (typeof source === 'string' && isPureVariable(source)) {
|
||||||
|
list = resolveVariable(source, data) || undefined;
|
||||||
|
} else if (Array.isArray(value)) {
|
||||||
|
list = value;
|
||||||
|
} else if (name && data[name]) {
|
||||||
|
list = data[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof list === 'string') {
|
||||||
|
list = list.split(delimiter);
|
||||||
|
} else if (list && !Array.isArray(list)) {
|
||||||
|
list = [list];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('ImagesField', className)}>
|
||||||
|
{Array.isArray(list) ? (
|
||||||
|
<div className={cx('Images')}>
|
||||||
|
{list.map((item: any, index: number) => (
|
||||||
|
<Image
|
||||||
|
className={cx('Images-item')}
|
||||||
|
key={index}
|
||||||
|
src={(item && item.image) || item}
|
||||||
|
title={item && item.title}
|
||||||
|
description={item && item.description}
|
||||||
|
thumbMode={thumbMode}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : defaultImage ? (
|
||||||
|
<Image
|
||||||
|
className={cx('Images-item')}
|
||||||
|
src={defaultImage}
|
||||||
|
thumbMode={thumbMode}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
placeholder
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Renderer({
|
||||||
|
test: /(^|\/)images$/
|
||||||
|
})
|
||||||
|
export class ImagesFieldRenderer extends ImagesField {}
|
|
@ -12,7 +12,7 @@ export function reigsterTplEnginer(name: string, enginer: Enginer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filter(
|
export function filter(
|
||||||
tpl: string,
|
tpl?: string,
|
||||||
data: object = {},
|
data: object = {},
|
||||||
...rest: Array<any>
|
...rest: Array<any>
|
||||||
): string {
|
): string {
|
||||||
|
|
Loading…
Reference in New Issue