改成 svg icon

This commit is contained in:
2betop 2020-06-08 16:53:52 +08:00
parent 777bbe30bc
commit 40c1ad2646
13 changed files with 102 additions and 47 deletions

View File

@ -58,6 +58,13 @@
} }
transition: ease-out all 0.3s; transition: ease-out all 0.3s;
&--icon {
background: transparent;
animation: spin 2s linear infinite;
width: auto;
height: auto;
}
} }
// 当启用 overlay 的时候应该是居中模式 // 当启用 overlay 的时候应该是居中模式

View File

@ -34,6 +34,11 @@
} }
} }
svg.#{$ns}Status-icon {
width: 16px;
height: 16px;
}
.#{$ns}Status-icon { .#{$ns}Status-icon {
&--danger, &--danger,
&--primary, &--primary,

View File

@ -741,4 +741,9 @@
> .#{$ns}Button--disabled-wrap > .#{$ns}Button { > .#{$ns}Button--disabled-wrap > .#{$ns}Button {
margin: px2rem(3px); margin: px2rem(3px);
} }
> .#{$ns}Button--link {
padding: 0;
margin-right: px2rem(10px);
}
} }

View File

@ -24,6 +24,7 @@ import Checkbox from './Checkbox';
import Input from './Input'; import Input from './Input';
import {Api} from '../types'; import {Api} from '../types';
import {LocaleProps, localeable} from '../locale'; import {LocaleProps, localeable} from '../locale';
import Spinner from './Spinner';
export interface Option { export interface Option {
label?: string; label?: string;
@ -330,7 +331,6 @@ export class Select extends React.Component<SelectProps, SelectState> {
placeholder: '请选择', placeholder: '请选择',
valueField: 'value', valueField: 'value',
labelField: 'label', labelField: 'label',
spinnerClassName: 'fa fa-spinner fa-spin fa-1x fa-fw',
inline: false, inline: false,
disabled: false, disabled: false,
checkAll: false, checkAll: false,
@ -871,7 +871,6 @@ export class Select extends React.Component<SelectProps, SelectState> {
className, className,
value, value,
loading, loading,
spinnerClassName,
clearable, clearable,
labelField, labelField,
disabled, disabled,
@ -927,9 +926,11 @@ export class Select extends React.Component<SelectProps, SelectState> {
</a> </a>
) : null} ) : null}
{loading ? ( {loading ? (
<span className={cx('Select-spinner')}> <Spinner
<i className={spinnerClassName} /> show
</span> icon="reload"
spinnerClassName={cx('Select-spinner')}
/>
) : null} ) : null}
<span className={cx('Select-arrow')} /> <span className={cx('Select-arrow')} />

View File

@ -6,8 +6,9 @@
*/ */
import React from 'react'; import React from 'react';
import {ClassNamesFn, themeable} from '../theme'; import {themeable, ThemeProps} from '../theme';
import Transition, {ENTERED, ENTERING} from 'react-transition-group/Transition'; import Transition, {ENTERED, ENTERING} from 'react-transition-group/Transition';
import {Icon} from './icons';
const fadeStyles: { const fadeStyles: {
[propName: string]: string; [propName: string]: string;
@ -16,25 +17,21 @@ const fadeStyles: {
[ENTERED]: 'in' [ENTERED]: 'in'
}; };
interface SpinnerProps { interface SpinnerProps extends ThemeProps {
overlay: boolean; overlay: boolean;
spinnerClassName: string; spinnerClassName: string;
mode: string; mode: string;
size: 'sm' | 'lg' | ''; size: 'sm' | 'lg' | '';
classPrefix: string;
classnames: ClassNamesFn;
show: boolean; show: boolean;
icon?: string;
} }
export class Spinner extends React.Component<SpinnerProps, object> { export class Spinner extends React.Component<SpinnerProps, object> {
static defaultProps: Pick< static defaultProps = {
SpinnerProps,
'overlay' | 'spinnerClassName' | 'size' | 'mode' | 'show'
> = {
overlay: false, overlay: false,
spinnerClassName: '', spinnerClassName: '',
mode: '', mode: '',
size: '', size: '' as '',
show: true show: true
}; };
@ -48,7 +45,8 @@ export class Spinner extends React.Component<SpinnerProps, object> {
spinnerClassName, spinnerClassName,
mode, mode,
size, size,
overlay overlay,
icon
} = this.props; } = this.props;
return ( return (
<Transition mountOnEnter unmountOnExit in={show} timeout={350}> <Transition mountOnEnter unmountOnExit in={show} timeout={350}>
@ -75,9 +73,12 @@ export class Spinner extends React.Component<SpinnerProps, object> {
className={cx(`Spinner`, spinnerClassName, fadeStyles[status], { className={cx(`Spinner`, spinnerClassName, fadeStyles[status], {
[`Spinner--${mode}`]: mode, [`Spinner--${mode}`]: mode,
[`Spinner--overlay`]: overlay, [`Spinner--overlay`]: overlay,
[`Spinner--${size}`]: size [`Spinner--${size}`]: size,
[`Spinner--icon`]: icon
})} })}
/> >
{icon ? <Icon icon={icon} className="icon" /> : null}
</div>
</> </>
); );
}} }}

View File

@ -143,6 +143,7 @@ registerIcon('prev', LeftArrowIcon);
registerIcon('next', RightArrowIcon); registerIcon('next', RightArrowIcon);
registerIcon('check', CheckIcon); registerIcon('check', CheckIcon);
registerIcon('plus', PlusIcon); registerIcon('plus', PlusIcon);
registerIcon('add', PlusIcon);
registerIcon('minus', MinusIcon); registerIcon('minus', MinusIcon);
registerIcon('pencil', PencilIcon); registerIcon('pencil', PencilIcon);
registerIcon('view', ViewIcon); registerIcon('view', ViewIcon);

View File

@ -1,4 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" version="1.1">
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" version="1.1" p-id="1463"> <g fill="currentColor" fill-rule="nonzero">
<path d="M11.496,1.834 L14.168,4.506 C14.48,4.818 14.48,5.322 14.168,5.634 L11.904,7.898 L5.4,14.402 L1.6,14.402 L1.6,10.602 L8.848,3.354 L8.848,3.354 L10.368,1.834 C10.68,1.522 11.184,1.522 11.496,1.834 Z M8.67,4.663 L2.4,10.9333708 L2.4,13.602 L5.06862915,13.602 L11.338,7.331 L8.67,4.663 Z M10.932,2.40137085 L9.23537085,4.098 L11.904,6.76662915 L13.6006292,5.07 L10.932,2.40137085 Z M8,13.6 L12.8,13.6 L12.8,14.4 L8,14.4 L8,13.6 Z" id="path-1"></path> <path d="M11.496,1.834 L14.168,4.506 C14.48,4.818 14.48,5.322 14.168,5.634 L11.904,7.898 L5.4,14.402 L1.6,14.402 L1.6,10.602 L8.848,3.354 L8.848,3.354 L10.368,1.834 C10.68,1.522 11.184,1.522 11.496,1.834 Z M8.67,4.663 L2.4,10.9333708 L2.4,13.602 L5.06862915,13.602 L11.338,7.331 L8.67,4.663 Z M10.932,2.40137085 L9.23537085,4.098 L11.904,6.76662915 L13.6006292,5.07 L10.932,2.40137085 Z M8,13.6 L12.8,13.6 L12.8,14.4 L8,14.4 L8,13.6 Z">
</svg> </path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 601 B

After

Width:  |  Height:  |  Size: 625 B

View File

@ -11,6 +11,7 @@ import {resolveVariableAndFilter, isPureVariable} from '../utils/tpl-builtin';
import {isApiOutdated, isEffectiveApi} from '../utils/api'; import {isApiOutdated, isEffectiveApi} from '../utils/api';
import {ScopedContext, IScopedContext} from '../Scoped'; import {ScopedContext, IScopedContext} from '../Scoped';
import {createObject} from '../utils/helper'; import {createObject} from '../utils/helper';
import Spinner from '../components/Spinner';
export interface ChartProps extends RendererProps { export interface ChartProps extends RendererProps {
chartRef?: (echart: any) => void; chartRef?: (echart: any) => void;
@ -238,7 +239,11 @@ export class Chart extends React.Component<ChartProps> {
placeholder={ placeholder={
<div className={cx(`${ns}Chart`, className)} style={style}> <div className={cx(`${ns}Chart`, className)} style={style}>
<div className={`${ns}Chart-placeholder`}> <div className={`${ns}Chart-placeholder`}>
<i key="loading" className="fa fa-spinner fa-spin fa-2x fa-fw" /> <Spinner
show
icon="reload"
spinnerClassName={cx('Chart-spinner')}
/>
</div> </div>
</div> </div>
} }

View File

@ -11,6 +11,7 @@ import {dataMapping} from '../../utils/tpl-builtin';
import findIndex from 'lodash/findIndex'; import findIndex from 'lodash/findIndex';
import memoize from 'lodash/memoize'; import memoize from 'lodash/memoize';
import {SimpleMap} from '../../utils/SimpleMap'; import {SimpleMap} from '../../utils/SimpleMap';
import {Icon} from '../../components/icons';
export interface TableProps extends FormControlProps { export interface TableProps extends FormControlProps {
placeholder?: string; placeholder?: string;
@ -48,11 +49,11 @@ export default class FormTable extends React.Component<TableProps, TableState> {
static defaultProps = { static defaultProps = {
placeholder: '空', placeholder: '空',
scaffold: {}, scaffold: {},
addBtnIcon: 'fa fa-plus', addBtnIcon: 'plus',
updateBtnIcon: 'fa fa-pencil', updateBtnIcon: 'pencil',
deleteBtnIcon: 'fa fa-minus', deleteBtnIcon: 'minus',
confirmBtnIcon: 'fa fa-check', confirmBtnIcon: 'check',
cancelBtnIcon: 'fa fa-times', cancelBtnIcon: 'close',
valueField: '' valueField: ''
}; };
@ -376,7 +377,9 @@ export default class FormTable extends React.Component<TableProps, TableState> {
onClick={this.addItem.bind(this, rowIndex, undefined)} onClick={this.addItem.bind(this, rowIndex, undefined)}
> >
{props.addBtnLabel ? <span>{props.addBtnLabel}</span> : null} {props.addBtnLabel ? <span>{props.addBtnLabel}</span> : null}
{props.addBtnIcon ? <i className={props.addBtnIcon} /> : null} {props.addBtnIcon ? (
<Icon icon={props.addBtnIcon} className="icon" />
) : null}
</Button> </Button>
) )
}); });
@ -428,7 +431,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
<span>{props.updateBtnLabel}</span> <span>{props.updateBtnLabel}</span>
) : null} ) : null}
{props.updateBtnIcon ? ( {props.updateBtnIcon ? (
<i className={props.updateBtnIcon} /> <Icon icon={props.updateBtnIcon} className="icon" />
) : null} ) : null}
</Button> </Button>
) )
@ -452,7 +455,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
<span>{props.confirmBtnLabel}</span> <span>{props.confirmBtnLabel}</span>
) : null} ) : null}
{props.confirmBtnIcon ? ( {props.confirmBtnIcon ? (
<i className={props.confirmBtnIcon} /> <Icon icon={props.confirmBtnIcon} className="icon" />
) : null} ) : null}
</Button> </Button>
) : null ) : null
@ -476,7 +479,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
<span>{props.cancelBtnLabel}</span> <span>{props.cancelBtnLabel}</span>
) : null} ) : null}
{props.cancelBtnIcon ? ( {props.cancelBtnIcon ? (
<i className={props.cancelBtnIcon} /> <Icon icon={props.cancelBtnIcon} className="icon" />
) : null} ) : null}
</Button> </Button>
) : null ) : null
@ -510,7 +513,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
<span>{props.deleteBtnLabel}</span> <span>{props.deleteBtnLabel}</span>
) : null} ) : null}
{props.deleteBtnIcon ? ( {props.deleteBtnIcon ? (
<i className={props.deleteBtnIcon} /> <Icon icon={props.deleteBtnIcon} className="icon" />
) : null} ) : null}
</Button> </Button>
) )

View File

@ -12,6 +12,7 @@ import {Icon} from '../../components/icons';
import Input from '../../components/Input'; import Input from '../../components/Input';
import {autobind, createObject, setVariable} from '../../utils/helper'; import {autobind, createObject, setVariable} from '../../utils/helper';
import {isEffectiveApi} from '../../utils/api'; import {isEffectiveApi} from '../../utils/api';
import Spinner from '../../components/Spinner';
// declare function matchSorter(items:Array<any>, input:any, options:any): Array<any>; // declare function matchSorter(items:Array<any>, input:any, options:any): Array<any>;
@ -74,8 +75,7 @@ export default class TextControl extends React.PureComponent<
labelField: 'label', labelField: 'label',
valueField: 'value', valueField: 'value',
placeholder: '', placeholder: '',
allowInputText: true, allowInputText: true
spinnerClassName: 'fa fa-spinner fa-spin fa-1x fa-fw'
}; };
componentWillReceiveProps(nextProps: TextProps) { componentWillReceiveProps(nextProps: TextProps) {
@ -415,7 +415,6 @@ export default class TextControl extends React.PureComponent<
labelField, labelField,
valueField, valueField,
multiple, multiple,
spinnerClassName,
translate: __ translate: __
} = this.props; } = this.props;
@ -523,7 +522,11 @@ export default class TextControl extends React.PureComponent<
</a> </a>
) : null} ) : null}
{loading ? ( {loading ? (
<i className={cx(`TextControl-spinner`, spinnerClassName)} /> <Spinner
show
icon="reload"
spinnerClassName={cx('TextControl-spinner')}
/>
) : null} ) : null}
{isOpen && filtedOptions.length ? ( {isOpen && filtedOptions.length ? (
<div className={cx('TextControl-sugs')}> <div className={cx('TextControl-sugs')}>

View File

@ -12,6 +12,7 @@ import debouce from 'lodash/debounce';
import find from 'lodash/find'; import find from 'lodash/find';
import {Api} from '../../types'; import {Api} from '../../types';
import {isEffectiveApi} from '../../utils/api'; import {isEffectiveApi} from '../../utils/api';
import Spinner from '../../components/Spinner';
export interface TreeSelectProps extends OptionsControlProps { export interface TreeSelectProps extends OptionsControlProps {
placeholder?: any; placeholder?: any;
@ -39,8 +40,7 @@ export default class TreeSelectControl extends React.Component<
joinValues: true, joinValues: true,
extractValue: false, extractValue: false,
delimiter: ',', delimiter: ',',
resetValue: '', resetValue: ''
spinnerClassName: 'fa fa-spinner fa-spin fa-1x fa-fw'
}; };
container: React.RefObject<HTMLDivElement>; container: React.RefObject<HTMLDivElement>;
@ -456,7 +456,6 @@ export default class TreeSelectControl extends React.Component<
const { const {
className, className,
disabled, disabled,
spinnerClassName,
inline, inline,
loading, loading,
multiple, multiple,
@ -521,9 +520,11 @@ export default class TreeSelectControl extends React.Component<
) : null} ) : null}
{loading ? ( {loading ? (
<span className={cx('TreeSelect-spinner')}> <Spinner
<i className={spinnerClassName} /> show
</span> icon="reload"
spinnerClassName={cx('TreeSelect-spinner')}
/>
) : null} ) : null}
<span className={cx('TreeSelect-arrow')} /> <span className={cx('TreeSelect-arrow')} />
</div> </div>

View File

@ -4,6 +4,7 @@ import {ServiceStore, IServiceStore} from '../store/service';
import {Api, SchemaNode, PlainObject} from '../types'; import {Api, SchemaNode, PlainObject} from '../types';
import {filter} from '../utils/tpl'; import {filter} from '../utils/tpl';
import cx from 'classnames'; import cx from 'classnames';
import {Icon} from '../components/icons';
export interface StatusProps extends RendererProps { export interface StatusProps extends RendererProps {
className?: string; className?: string;
@ -15,8 +16,8 @@ export class StatusField extends React.Component<StatusProps, object> {
static defaultProps: Partial<StatusProps> = { static defaultProps: Partial<StatusProps> = {
placeholder: '-', placeholder: '-',
map: { map: {
0: 'fa fa-times text-danger', 0: 'svg-success',
1: 'fa fa-check text-success' 1: 'svg-fail'
}, },
labelMap: { labelMap: {
// 0: '失败', // 0: '失败',
@ -47,10 +48,25 @@ export class StatusField extends React.Component<StatusProps, object> {
} }
wrapClassName = `StatusField--${value}`; wrapClassName = `StatusField--${value}`;
viewValue = ( let itemClassName = map[value];
<i className={cx('StatusField-icon', map[value])} key="icon" /> let svgIcon: string = '';
itemClassName = itemClassName.replace(
/\bsvg-(.*)\b/,
(_: string, icon: string) => {
svgIcon = icon;
return 'icon';
}
); );
if (svgIcon) {
viewValue = (
<Icon icon={svgIcon} className={cx('Status-icon', itemClassName)} />
);
} else {
viewValue = <i className={cx('Status-icon', map[value])} key="icon" />;
}
if (labelMap && labelMap[value]) { if (labelMap && labelMap[value]) {
viewValue = [ viewValue = [
viewValue, viewValue,

View File

@ -7,6 +7,7 @@ import {Api, ApiObject, Payload} from '../types';
import update from 'react-addons-update'; import update from 'react-addons-update';
import {isEffectiveApi, isApiOutdated} from '../utils/api'; import {isEffectiveApi, isApiOutdated} from '../utils/api';
import {ScopedContext, IScopedContext} from '../Scoped'; import {ScopedContext, IScopedContext} from '../Scoped';
import Spinner from '../components/Spinner';
export interface TaskProps extends RendererProps { export interface TaskProps extends RendererProps {
className?: string; className?: string;
@ -297,7 +298,11 @@ export default class Task extends React.Component<TaskProps, TaskState> {
<td>{item.label}</td> <td>{item.label}</td>
<td> <td>
{item.status == loadingStatusCode ? ( {item.status == loadingStatusCode ? (
<i className="fa fa-spinner fa-spin fa-2x fa-fw" /> <Spinner
show
icon="reload"
spinnerClassName={cx('Task-spinner')}
/>
) : item.status == canRetryStatusCode ? ( ) : item.status == canRetryStatusCode ? (
<a <a
onClick={() => this.submitTask(item, key, true)} onClick={() => this.submitTask(item, key, true)}