feat: Spinner 增加 loadingConfig 属性,控制Spinner不展示、指定挂载节点 (#5933)

This commit is contained in:
meerkat 2022-12-28 16:59:19 +08:00 committed by GitHub
parent 97534d96ae
commit a0374be192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 726 additions and 319 deletions

View File

@ -128,6 +128,10 @@ const loadingBody = {
type: 'crud',
api: '/api/mock2/sample?orderBy=id&orderDir=desc&waitSeconds=30',
syncLocation: false,
loadingConfig: {
show: true,
root: 'body'
},
columns: [
{
name: 'id',

View File

@ -1,6 +1,4 @@
{
"packages": [
"packages/*"
],
"packages": ["packages/*"],
"version": "2.5.2"
}

View File

@ -1,5 +1,6 @@
import React from 'react';
import extend from 'lodash/extend';
import {SpinnerExtraProps} from 'amis-ui';
import {Renderer, RendererProps} from '../factory';
import {FormStore, IFormStore} from '../store/form';
import {
@ -350,7 +351,8 @@ export interface FormGroupArray extends Array<FormGroupNode> {}
export interface FormProps
extends RendererProps,
Omit<FormSchemaBase, 'mode' | 'className'> {
Omit<FormSchemaBase, 'mode' | 'className'>,
SpinnerExtraProps {
data: any;
store: IFormStore;
wrapperComponent: React.ElementType;
@ -1365,7 +1367,13 @@ export default class Form extends React.Component<FormProps, object> {
}
buildActions() {
const {actions, submitText, body, translate: __} = this.props;
const {
actions,
submitText,
body,
translate: __,
loadingConfig
} = this.props;
if (
typeof actions !== 'undefined' ||
@ -1388,7 +1396,8 @@ export default class Form extends React.Component<FormProps, object> {
{
type: 'submit',
label: __(submitText),
primary: true
primary: true,
loadingConfig
}
];
}
@ -1596,7 +1605,8 @@ export default class Form extends React.Component<FormProps, object> {
columnCount,
render,
staticClassName,
static: isStatic = false
static: isStatic = false,
loadingConfig
} = this.props;
const {restError} = store;
@ -1653,7 +1663,8 @@ export default class Form extends React.Component<FormProps, object> {
{type: 'spinner'},
{
overlay: true,
show: store.loading
show: store.loading,
loadingConfig
}
)}

View File

@ -55,7 +55,7 @@
"moment": "^2.19.4",
"monaco-editor": "0.30.1",
"prop-types": "^15.6.1",
"rc-input-number": "^7.3.9",
"rc-input-number": "^7.4.0",
"rc-progress": "^3.1.4",
"react-color": "^2.19.3",
"react-hook-form": "7.39.0",

View File

@ -93,6 +93,7 @@
border-bottom: var(--Modal-body-borderTop);
border-top-left-radius: var(--Modal-content-borderRadius);
border-top-right-radius: var(--Modal-content-borderRadius);
z-index: 150; // 高于 Spinner overlay
}
&-title {

View File

@ -17,8 +17,11 @@ import ChainedSelection from './ChainedSelection';
import {Icon} from './icons';
import {localeable} from 'amis-core';
import Tree from './Tree';
import {SpinnerExtraProps} from './Spinner';
export interface AssociatedSelectionProps extends BaseSelectionProps {
export interface AssociatedSelectionProps
extends BaseSelectionProps,
SpinnerExtraProps {
leftOptions: Options;
leftDefaultValue?: any;
leftMode?: 'tree' | 'list' | 'group';
@ -122,7 +125,8 @@ export class AssociatedSelection extends BaseSelection<
itemRender,
labelField,
virtualThreshold,
itemHeight
itemHeight,
loadingConfig
} = this.props;
const selectdOption = BaseSelection.resolveSelected(
@ -145,6 +149,7 @@ export class AssociatedSelection extends BaseSelection<
onDeferLoad={this.handleLeftDeferLoad}
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}
loadingConfig={loadingConfig}
/>
) : (
<GroupedSelecton
@ -208,6 +213,7 @@ export class AssociatedSelection extends BaseSelection<
labelField={labelField}
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}
loadingConfig={loadingConfig}
/>
) : rightMode === 'chained' ? (
<ChainedSelection
@ -221,6 +227,7 @@ export class AssociatedSelection extends BaseSelection<
labelField={labelField}
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}
loadingConfig={loadingConfig}
/>
) : (
<GroupedSelection

View File

@ -7,9 +7,10 @@ import React from 'react';
import TooltipWrapper, {TooltipObject, Trigger} from './TooltipWrapper';
import {pickEventsProps} from 'amis-core';
import {ClassNamesFn, themeable} from 'amis-core';
import {Icon} from './icons';
import Spinner from './Spinner';
interface ButtonProps extends React.DOMAttributes<HTMLButtonElement> {
import Spinner, {SpinnerExtraProps} from './Spinner';
interface ButtonProps
extends React.DOMAttributes<HTMLButtonElement>,
SpinnerExtraProps {
id?: string;
className?: string;
style?: any;
@ -74,6 +75,7 @@ export class Button extends React.Component<ButtonProps> {
loading,
loadingClassName,
overrideClassName,
loadingConfig,
...rest
} = this.props;
@ -109,6 +111,7 @@ export class Button extends React.Component<ButtonProps> {
>
{loading && !disabled && (
<Spinner
loadingConfig={loadingConfig}
size="sm"
show
icon="loading-outline"

View File

@ -9,11 +9,13 @@ import Checkbox from './Checkbox';
import {Option} from './Select';
import {getTreeDepth} from 'amis-core';
import times from 'lodash/times';
import Spinner from './Spinner';
import Spinner, {SpinnerExtraProps} from './Spinner';
import {localeable} from 'amis-core';
import VirtualList, {AutoSizer} from './virtual-list';
export interface ChainedSelectionProps extends BaseSelectionProps {
export interface ChainedSelectionProps
extends BaseSelectionProps,
SpinnerExtraProps {
defaultSelectedIndex?: string;
}
@ -124,7 +126,8 @@ export class ChainedSelection extends BaseSelection<
itemClassName,
itemRender,
multiple,
labelField
labelField,
loadingConfig
} = this.props;
const valueArray = this.valueArray;
@ -153,7 +156,9 @@ export class ChainedSelection extends BaseSelection<
})}
</div>
{option.defer && option.loading ? <Spinner size="sm" show /> : null}
{option.defer && option.loading ? (
<Spinner loadingConfig={loadingConfig} size="sm" show />
) : null}
</div>
);
}

View File

@ -11,11 +11,13 @@ import {LocaleProps, localeable} from 'amis-core';
import {BaseSelectionProps} from './Selection';
import Tree from './Tree';
import TransferSearch from './TransferSearch';
import {SpinnerExtraProps} from './Spinner';
export interface ResultTreeListProps
extends ThemeProps,
LocaleProps,
BaseSelectionProps {
BaseSelectionProps,
SpinnerExtraProps {
className?: string;
title?: string;
searchable?: boolean;
@ -265,7 +267,8 @@ export class BaseResultTreeList extends React.Component<
translate: __,
placeholder,
virtualThreshold,
itemHeight
itemHeight,
loadingConfig
} = this.props;
const {treeOptions, searching, searchTreeOptions} = this.state;
@ -282,6 +285,7 @@ export class BaseResultTreeList extends React.Component<
showIcon={false}
itemRender={itemRender}
removable
loadingConfig={loadingConfig}
onDelete={(option: Option) => this.deleteTreeChecked(option)}
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}

View File

@ -36,7 +36,7 @@ import {ClassNamesFn, themeable, ThemeProps} from 'amis-core';
import Checkbox from './Checkbox';
import Input from './Input';
import {LocaleProps, localeable} from 'amis-core';
import Spinner from './Spinner';
import Spinner, {SpinnerExtraProps} from './Spinner';
import type {Option, Options} from 'amis-core';
import {RemoteOptionsProps, withRemoteConfig} from './WithRemoteConfig';
import Picker from './Picker';
@ -295,7 +295,11 @@ export function normalizeOptions(
const DownshiftChangeTypes = Downshift.stateChangeTypes;
interface SelectProps extends OptionProps, ThemeProps, LocaleProps {
interface SelectProps
extends OptionProps,
ThemeProps,
LocaleProps,
SpinnerExtraProps {
className?: string;
popoverClassName?: string;
showInvalidMatch?: boolean;
@ -1242,7 +1246,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
checkAll,
borderMode,
useMobileUI,
hasError
hasError,
loadingConfig
} = this.props;
const selection = this.state.selection;
@ -1310,6 +1315,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
icon="reload"
size="sm"
spinnerClassName={cx('Select-spinner')}
loadingConfig={loadingConfig}
/>
) : null}

View File

@ -6,6 +6,7 @@
*/
import React from 'react';
import ReactDOM from 'react-dom';
import {themeable, ThemeProps} from 'amis-core';
import Transition, {ENTERED, ENTERING} from 'react-transition-group/Transition';
import {Icon, hasIcon} from './icons';
@ -21,7 +22,7 @@ const fadeStyles: {
};
// Spinner Props
export interface SpinnerProps extends ThemeProps {
export interface SpinnerProps extends ThemeProps, SpinnerExtraProps {
show: boolean; // 控制Spinner显示与隐藏
className?: string; // 自定义最外层元素class
spinnerClassName?: string; // spin图标位置包裹元素的自定义class
@ -37,6 +38,13 @@ export interface SpinnerProps extends ThemeProps {
overlay?: boolean; // 是否显示遮罩层有children属性才生效
}
export interface SpinnerExtraProps {
loadingConfig?: {
root?: string;
show?: boolean;
};
}
const SpinnerSharedStore = types
.model('SpinnerSharedStore', {})
.volatile(self => {
@ -106,7 +114,8 @@ export class Spinner extends React.Component<
tip: '',
tipPlacement: 'bottom' as 'bottom',
delay: 0,
overlay: false
overlay: false,
loadingConfig: {} as SpinnerExtraProps
};
state = {
@ -129,7 +138,16 @@ export class Spinner extends React.Component<
};
componentDidUpdate() {
if (this.parent) {
const showLoading =
this.props.loadingConfig?.show === true ||
typeof this.props.loadingConfig?.show === 'undefined';
const root = this.props.loadingConfig?.root;
if (!this.parent && root) {
this.parent = document.querySelector(root);
}
if (this.parent && showLoading) {
if (this.props.show) {
this.loadingTriggered = true;
store.push(this.parent);
@ -167,7 +185,7 @@ export class Spinner extends React.Component<
}
);
render() {
renderBody() {
const {
classnames: cx,
className,
@ -175,78 +193,100 @@ export class Spinner extends React.Component<
size = '',
overlay,
delay,
icon,
icon: iconConfig,
tip,
tipPlacement = ''
tipPlacement = '',
loadingConfig
} = this.props;
// 调整挂载位置时使用默认loading
const icon = loadingConfig?.root ? iconConfig : '';
const isCustomIcon = icon && React.isValidElement(icon);
const timeout = {enter: delay, exit: 0};
const showOverlay = loadingConfig?.root || overlay;
return (
<Transition
mountOnEnter
unmountOnExit
in={this.state.spinning}
timeout={timeout}
>
{(status: string) => {
return (
<>
{/* 遮罩层 */}
{showOverlay ? (
<div className={cx(`Spinner-overlay`, fadeStyles[status])} />
) : null}
{/* spinner图标和文案 */}
<div
data-testid="spinner"
className={cx(
`Spinner`,
tip && {
[`Spinner-tip--${tipPlacement}`]: [
'top',
'right',
'bottom',
'left'
].includes(tipPlacement)
},
{[`Spinner--overlay`]: showOverlay},
fadeStyles[status],
className
)}
>
<div
className={cx(
`Spinner-icon`,
{
[`Spinner-icon--${size}`]: ['lg', 'sm'].includes(size),
[`Spinner-icon--default`]: !icon,
[`Spinner-icon--simple`]: !isCustomIcon && icon,
[`Spinner-icon--custom`]: isCustomIcon
},
spinnerClassName
)}
>
{icon ? (
isCustomIcon ? (
icon
) : hasIcon(icon as string) ? (
<Icon icon={icon} className="icon" />
) : (
generateIcon(cx, icon as string, 'icon')
)
) : null}
</div>
{tip ? <span className={cx(`Spinner-tip`)}>{tip}</span> : ''}
</div>
</>
);
}}
</Transition>
);
}
render() {
const {classnames: cx, loadingConfig} = this.props;
const spinnerBody = this.renderBody();
const root = loadingConfig?.root;
const doms = root ? document.querySelectorAll(root) : null;
if (doms?.length) {
// TODO: 找到准确的 元素
return ReactDOM.createPortal(spinnerBody, doms[doms.length - 1]);
}
return (
<>
{this.state.showMarker && (
<span className={cx('Spinner-mark')} ref={this.spinnerRef as any} />
)}
<Transition
mountOnEnter
unmountOnExit
in={this.state.spinning}
timeout={timeout}
>
{(status: string) => {
return (
<>
{/* 遮罩层 */}
{overlay ? (
<div className={cx(`Spinner-overlay`, fadeStyles[status])} />
) : null}
{/* spinner图标和文案 */}
<div
data-testid="spinner"
className={cx(
`Spinner`,
tip && {
[`Spinner-tip--${tipPlacement}`]: [
'top',
'right',
'bottom',
'left'
].includes(tipPlacement)
},
{[`Spinner--overlay`]: overlay},
fadeStyles[status],
className
)}
>
<div
className={cx(
`Spinner-icon`,
{
[`Spinner-icon--${size}`]: ['lg', 'sm'].includes(size),
[`Spinner-icon--default`]: !icon,
[`Spinner-icon--simple`]: !isCustomIcon && icon,
[`Spinner-icon--custom`]: isCustomIcon
},
spinnerClassName
)}
>
{icon ? (
isCustomIcon ? (
icon
) : hasIcon(icon as string) ? (
<Icon icon={icon} className="icon" />
) : (
generateIcon(cx, icon as string, 'icon')
)
) : null}
</div>
{tip ? <span className={cx(`Spinner-tip`)}>{tip}</span> : ''}
</div>
</>
);
}}
</Transition>
{spinnerBody}
</>
);
}

View File

@ -3,7 +3,6 @@ import {autobind} from 'amis-core';
import Tabs, {Tab} from './Tabs';
import InputBox from './InputBox';
import TableCheckboxes from './TableSelection';
import TreeCheckboxes from './TreeSelection';
import Tree from './Tree';
import ChainedCheckboxes from './ChainedSelection';
import ListCheckboxes from './GroupedSelection';
@ -15,17 +14,19 @@ import {localeable} from 'amis-core';
import {ItemRenderStates} from './Selection';
import {Icon} from './icons';
import debounce from 'lodash/debounce';
import {SpinnerExtraProps} from './Spinner';
export interface TabsTransferProps
extends Omit<
TransferProps,
| 'selectMode'
| 'columns'
| 'selectRender'
| 'statistics'
| 'onSearch'
| 'optionItemRender'
> {
TransferProps,
| 'selectMode'
| 'columns'
| 'selectRender'
| 'statistics'
| 'onSearch'
| 'optionItemRender'
>,
SpinnerExtraProps {
onSearch: (
term: string,
option: Option,
@ -163,7 +164,8 @@ export class TabsTransfer extends React.Component<
optionItemRender,
itemHeight,
virtualThreshold,
onlyChildren
onlyChildren,
loadingConfig
} = this.props;
const options = searchResult || [];
const mode = searchResultMode;
@ -324,7 +326,8 @@ export class TabsTransfer extends React.Component<
optionItemRender,
itemHeight,
virtualThreshold,
onlyChildren
onlyChildren,
loadingConfig
} = this.props;
return option.selectMode === 'table' ? (
@ -344,6 +347,7 @@ export class TabsTransfer extends React.Component<
/>
) : option.selectMode === 'tree' ? (
<Tree
loadingConfig={loadingConfig}
className={cx('Transfer-checkboxes')}
options={option.children || []}
value={value}
@ -405,6 +409,7 @@ export class TabsTransfer extends React.Component<
leftMode={option.leftMode}
leftOptions={option.leftOptions}
leftDefaultValue={option.leftDefaultValue}
loadingConfig={loadingConfig}
itemRender={
optionItemRender
? (item: Option, states: ItemRenderStates) =>

View File

@ -27,6 +27,7 @@ import ChainedSelection from './ChainedSelection';
import {ItemRenderStates as ResultItemRenderStates} from './ResultList';
import ResultTableList from './ResultTableList';
import ResultTreeList from './ResultTreeList';
import {SpinnerExtraProps} from './Spinner';
export type SelectMode =
| 'table'
@ -39,6 +40,7 @@ export type SelectMode =
export interface TransferProps
extends ThemeProps,
LocaleProps,
SpinnerExtraProps,
Omit<BaseSelectionProps, 'itemRender'> {
inline?: boolean;
statistics?: boolean;
@ -572,7 +574,8 @@ export class Transfer<
labelField,
virtualThreshold,
itemHeight,
virtualListHeight
virtualListHeight,
loadingConfig
} = props;
return selectMode === 'table' ? (
@ -609,6 +612,7 @@ export class Transfer<
labelField={labelField}
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}
loadingConfig={loadingConfig}
/>
) : selectMode === 'chained' ? (
<ChainedSelection
@ -625,6 +629,7 @@ export class Transfer<
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}
virtualListHeight={virtualListHeight}
loadingConfig={loadingConfig}
/>
) : selectMode === 'associated' ? (
<AssociatedSelection
@ -646,6 +651,7 @@ export class Transfer<
virtualThreshold={virtualThreshold}
itemHeight={itemHeight}
virtualListHeight={virtualListHeight}
loadingConfig={loadingConfig}
/>
) : (
<GroupedSelection
@ -685,7 +691,8 @@ export class Transfer<
translate: __,
placeholder = __('Transfer.selectFromLeft'),
virtualThreshold,
itemHeight
itemHeight,
loadingConfig
} = this.props;
const {resultSelectMode, isTreeDeferLoad} = this.state;
@ -715,6 +722,7 @@ export class Transfer<
case 'tree':
return (
<ResultTreeList
loadingConfig={loadingConfig}
classnames={cx}
className={cx('Transfer-value')}
options={options}

View File

@ -32,7 +32,7 @@ import {themeable, ThemeProps, highlight} from 'amis-core';
import {Icon, getIcon} from './icons';
import Checkbox from './Checkbox';
import {LocaleProps, localeable} from 'amis-core';
import Spinner from './Spinner';
import Spinner, {SpinnerExtraProps} from './Spinner';
import {ItemRenderStates} from './Selection';
import VirtualList from './virtual-list';
@ -50,7 +50,7 @@ export interface IDropInfo {
indicator: IDropIndicator;
}
interface TreeSelectorProps extends ThemeProps, LocaleProps {
interface TreeSelectorProps extends ThemeProps, LocaleProps, SpinnerExtraProps {
highlightTxt?: string;
onRef?: any;
@ -1029,7 +1029,8 @@ export class TreeSelector extends React.Component<
removeTip,
translate: __,
itemRender,
draggable
draggable,
loadingConfig
} = this.props;
const item = this.state.flattenedOptions[index];
@ -1104,6 +1105,7 @@ export class TreeSelector extends React.Component<
show
icon="reload"
spinnerClassName={cx('Tree-spinner')}
loadingConfig={loadingConfig}
/>
) : !isLeaf || (item.defer && !item.loaded) ? (
<div

View File

@ -5,11 +5,13 @@ import {uncontrollable} from 'amis-core';
import Checkbox from './Checkbox';
import {Option} from './Select';
import {autobind, eachTree, everyTree} from 'amis-core';
import Spinner from './Spinner';
import Spinner, {SpinnerExtraProps} from './Spinner';
import {localeable} from 'amis-core';
import {Icon} from './icons';
export interface TreeSelectionProps extends BaseSelectionProps {
export interface TreeSelectionProps
extends BaseSelectionProps,
SpinnerExtraProps {
expand?: 'all' | 'first' | 'root' | 'none';
}
@ -169,7 +171,8 @@ export class TreeSelection extends BaseSelection<
classnames: cx,
itemClassName,
itemRender,
multiple
multiple,
loadingConfig
} = this.props;
const id = indexes.join('-');
const valueArray = this.valueArray;
@ -238,7 +241,9 @@ export class TreeSelection extends BaseSelection<
</a>
) : null}
{option.defer && option.loading ? <Spinner show size="sm" /> : null}
{option.defer && option.loading ? (
<Spinner loadingConfig={loadingConfig} show size="sm" />
) : null}
{multiple && (!option.defer || option.loaded) ? (
<Checkbox
@ -261,7 +266,9 @@ export class TreeSelection extends BaseSelection<
})}
</div>
{option.defer && option.loading ? <Spinner show size="sm" /> : null}
{option.defer && option.loading ? (
<Spinner loadingConfig={loadingConfig} show size="sm" />
) : null}
</div>
{hasChildren ? (
<div className={cx('TreeSelection-sublist')}>

View File

@ -16,12 +16,15 @@ import debounce from 'lodash/debounce';
import {autobind, findTree} from 'amis-core';
import Checkbox from './Checkbox';
import {optionValueCompare, value2array} from './Select';
import Spinner from './Spinner';
import Spinner, {SpinnerExtraProps} from './Spinner';
import flatten from 'lodash/flatten';
import {findDOMNode} from 'react-dom';
import {Api, PlainObject} from 'amis-core';
export interface UserSelectProps extends ThemeProps, LocaleProps {
export interface UserSelectProps
extends ThemeProps,
LocaleProps,
SpinnerExtraProps {
showNav?: boolean;
navTitle?: string;
options: Array<any>;
@ -782,7 +785,8 @@ export class UserSelect extends React.Component<
valueField = 'value',
classnames: cx,
multiple,
translate: __
translate: __,
loadingConfig
} = this.props;
const {breadList, options, isSearch, searchList, searchLoading} =
@ -904,7 +908,7 @@ export class UserSelect extends React.Component<
{isSearch ? (
searchLoading ? (
<div className={cx(`UserSelect-searchLoadingBox`)}>
<Spinner />
<Spinner loadingConfig={loadingConfig} />
</div>
) : (
<div className={cx('UserSelect-searchResult')}>
@ -934,7 +938,7 @@ export class UserSelect extends React.Component<
this.renderList(children, option[valueField])
) : (
<div className={cx(`UserSelect-spinnerBox`)} key={index}>
<Spinner />
<Spinner loadingConfig={loadingConfig} />
</div>
);
})}

View File

@ -16,8 +16,12 @@ import {
import {Icon} from '../icons';
import SearchBox from '../SearchBox';
import TreeSelection from '../TreeSelection';
import {SpinnerExtraProps} from '../Spinner';
export interface ConditionFieldProps extends ThemeProps, LocaleProps {
export interface ConditionFieldProps
extends ThemeProps,
LocaleProps,
SpinnerExtraProps {
options: Array<any>;
value: any;
onChange: (value: any) => void;
@ -99,7 +103,8 @@ export class ConditionField extends React.Component<
translate: __,
searchable,
popOverContainer,
selectMode = 'list'
selectMode = 'list',
loadingConfig
} = this.props;
return (
@ -116,6 +121,7 @@ export class ConditionField extends React.Component<
multiple={false}
options={this.filterOptions(this.props.options)}
value={value}
loadingConfig={loadingConfig}
onChange={(value: any) => {
this.onPopClose(onClose);
onChange(value.name);

View File

@ -11,8 +11,9 @@ import type {ItemRenderStates} from '../Selection';
import type {Option} from '../Select';
import type {TabsMode} from '../Tabs';
import {Badge} from '../Badge';
import {SpinnerExtraProps} from '../Spinner';
export interface VariableListProps extends ThemeProps {
export interface VariableListProps extends ThemeProps, SpinnerExtraProps {
className?: string;
itemClassName?: string;
value?: any;
@ -46,21 +47,24 @@ function VariableList(props: VariableListProps) {
: (option: Option, states: ItemRenderStates): JSX.Element => {
return (
<span className={cx(`${classPrefix}-item`, itemClassName)}>
{option.label && (selfVariableName && option.value === selfVariableName) && (
<Badge
classnames={cx}
badge={{
mode: 'text',
text: 'self',
offset: [15, 2]
}}
>
{option.label &&
selfVariableName &&
option.value === selfVariableName && (
<Badge
classnames={cx}
badge={{
mode: 'text',
text: 'self',
offset: [15, 2]
}}
>
<label>{option.label}</label>
</Badge>
)}
{option.label &&
(!selfVariableName || option.value !== selfVariableName) && (
<label>{option.label}</label>
</Badge>
)}
{option.label && (!selfVariableName || option.value !== selfVariableName) && (
<label>{option.label}</label>
)}
)}
{option?.tag ? (
<span className={cx(`${classPrefix}-item-tag`)}>
{option.tag}

View File

@ -40,7 +40,7 @@ import Rating from './Rating';
// import RichText from './RichText';
import Select from './Select';
import SparkLine from './SparkLine';
import Spinner from './Spinner';
import {default as Spinner, type SpinnerExtraProps} from './Spinner';
import Switch from './Switch';
import Textarea from './Textarea';
import TitleBar from './TitleBar';
@ -158,6 +158,7 @@ export {
Select,
SparkLine,
Spinner,
SpinnerExtraProps,
Switch,
Textarea,
TitleBar,

View File

@ -25,7 +25,7 @@ import {
} from 'amis-core';
import {Icon} from '../icons';
import CheckBox from '../Checkbox';
import Spinner from '../Spinner';
import Spinner, {SpinnerExtraProps} from '../Spinner';
import HeadCellSort from './HeadCellSort';
import HeadCellFilter from './HeadCellFilter';
@ -117,7 +117,7 @@ export interface SortProps {
order: string;
}
export interface TableProps extends ThemeProps, LocaleProps {
export interface TableProps extends ThemeProps, LocaleProps, SpinnerExtraProps {
title: string | React.ReactNode | Function;
footer: string | React.ReactNode | Function;
className?: string;
@ -1815,10 +1815,14 @@ export class Table extends React.PureComponent<TableProps, TableState> {
}
renderLoading() {
const {classnames: cx, loading} = this.props;
const {classnames: cx, loading, loadingConfig} = this.props;
return (
<div className={cx('Table-loading')}>
{typeof loading === 'boolean' ? <Spinner></Spinner> : loading}
{typeof loading === 'boolean' ? (
<Spinner loadingConfig={loadingConfig} />
) : (
loading
)}
</div>
);
}

View File

@ -13,6 +13,7 @@ exports[`EventAction:ajax 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--primary cxd-Button--size-default"
@ -64,6 +65,7 @@ exports[`EventAction:ajax 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--primary cxd-Button--size-default"

View File

@ -13,6 +13,7 @@ exports[`EventAction:custom 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--primary cxd-Button--size-default"
@ -65,6 +66,7 @@ exports[`EventAction:custom 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--primary cxd-Button--size-default"
@ -117,6 +119,7 @@ exports[`EventAction:custom 3`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--primary cxd-Button--size-default"

View File

@ -13,6 +13,7 @@ exports[`EventAction:dialog 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -57,6 +58,7 @@ exports[`EventAction:dialog 1`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -129,6 +131,7 @@ exports[`EventAction:dialog 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -158,6 +161,7 @@ exports[`EventAction:dialog 3`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -187,6 +191,7 @@ exports[`EventAction:dialog 4`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -216,6 +221,7 @@ exports[`EventAction:dialog 5`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -245,6 +251,7 @@ exports[`EventAction:dialog 6`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -274,6 +281,7 @@ exports[`EventAction:dialog 7`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"

View File

@ -13,6 +13,7 @@ exports[`EventAction:disabled 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Button cxd-Button--default cxd-Button--size-default is-disabled"

View File

@ -13,6 +13,7 @@ exports[`EventAction:drawer 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -112,6 +113,7 @@ exports[`EventAction:drawer 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -141,6 +143,7 @@ exports[`EventAction:drawer 3`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -170,6 +173,7 @@ exports[`EventAction:drawer 4`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -199,6 +203,7 @@ exports[`EventAction:drawer 5`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -228,6 +233,7 @@ exports[`EventAction:drawer 6`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -257,6 +263,7 @@ exports[`EventAction:drawer 7`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"

View File

@ -13,6 +13,7 @@ exports[`EventAction:hidden 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"

View File

@ -13,6 +13,7 @@ exports[`EventAction:prevent 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--primary cxd-Button--size-default ml-2"
@ -57,6 +58,7 @@ exports[`EventAction:prevent 1`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<div
class="cxd-Alert cxd-Alert--warning"

View File

@ -13,6 +13,7 @@ exports[`EventAction:inputRange 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Form-item cxd-Form-item--normal"

View File

@ -292,6 +292,7 @@ exports[`Renderer:button 2`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<span
class="cxd-TplField"

View File

@ -258,6 +258,7 @@ exports[`Renderer:button-toolbar 2`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<span
class="cxd-TplField"

View File

@ -2116,6 +2116,7 @@ exports[`Renderer:checkboxes with creatable & createBtnLabel & addControls & add
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<div
class="cxd-Form cxd-Form--horizontal"
@ -2738,6 +2739,7 @@ exports[`Renderer:checkboxes with editable & editControls & editApi: dialog open
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<div
class="cxd-Form cxd-Form--horizontal"

View File

@ -13,6 +13,7 @@ exports[`Renderer:combo with addable & addattop & addBtn & addButtonText & addBu
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -560,6 +561,7 @@ exports[`Renderer:combo with canAccessSuperData & strictMode & syncFields 1`] =
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -873,6 +875,7 @@ exports[`Renderer:combo with conditions: add button open 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1193,6 +1196,7 @@ exports[`Renderer:combo with draggable 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1727,6 +1731,7 @@ exports[`Renderer:combo with minLength & maxLength: minLength error 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1898,6 +1903,7 @@ exports[`Renderer:combo with removable & deleteBtn & deleteApi & deleteConfirmTe
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -2326,6 +2332,7 @@ exports[`Renderer:combo with tabsMode 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -2629,6 +2636,7 @@ exports[`Renderer:combo with unique: unique error 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer:condition-builder 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -273,6 +273,7 @@ exports[`Form:initData:super 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<form
class="cxd-Form cxd-Form--normal"
@ -355,6 +356,7 @@ exports[`Form:initData:without-super 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<form
class="cxd-Form cxd-Form--normal"

View File

@ -13,6 +13,7 @@ exports[`Renderer:inputArray 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -233,6 +234,7 @@ exports[`Renderer:inputArray with draggable & draggableTip 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -619,6 +621,7 @@ exports[`Renderer:inputArray with minLength & maxLength 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -880,6 +883,7 @@ exports[`Renderer:inputArray with removable & addable & addButtonText: false 1`]
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1128,6 +1132,7 @@ exports[`Renderer:inputArray with removable & addable & addButtonText: false 2`]
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer:inputCity 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -250,6 +251,7 @@ exports[`Renderer:inputCity with searchable: open select 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -140,6 +140,7 @@ exports[`Renderer:inputDate with clearable: clearable false 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -295,6 +296,7 @@ exports[`Renderer:inputDate with clearable: clearable true 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -481,6 +483,7 @@ exports[`Renderer:inputDate with format & inputFormat 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer:input-formula 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -304,6 +305,7 @@ exports[`Renderer:input-formula button 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -581,6 +583,7 @@ exports[`Renderer:input-formula input-group 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer:input table 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer: chained select 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -170,6 +171,7 @@ exports[`Renderer:select associated 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -858,6 +860,7 @@ exports[`Renderer:select chained 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1474,6 +1477,7 @@ exports[`Renderer:select group 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1999,6 +2003,7 @@ exports[`Renderer:select menutpl 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -2156,6 +2161,7 @@ exports[`Renderer:select table 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -3178,6 +3184,7 @@ exports[`Renderer:select tree 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer:tabsTransfer 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -718,6 +719,7 @@ exports[`Renderer:tabsTransfer with deferApi 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -17,6 +17,7 @@ exports[`Renderer:TabsTransferPicker 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -192,6 +193,7 @@ exports[`Renderer:TabsTransferPicker: dialog open 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -13,6 +13,7 @@ exports[`Renderer:transfer 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -897,6 +898,7 @@ exports[`Renderer:transfer chained 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -1997,6 +1999,7 @@ exports[`Renderer:transfer left tree 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -2535,6 +2538,7 @@ exports[`Renderer:transfer table 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -4369,6 +4373,7 @@ exports[`Renderer:transfer tree 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -96,6 +96,7 @@ exports[`Renderers:Action all levels 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--link cxd-Button--size-default"
@ -370,6 +371,7 @@ exports[`Renderers:Action tooltip 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -467,6 +469,7 @@ exports[`Renderers:Action with confirmText & actionType ajax 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default"
@ -544,6 +547,7 @@ exports[`Renderers:Action with disabledTip 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Button cxd-Button--default cxd-Button--size-default is-disabled"

View File

@ -13,6 +13,7 @@ exports[`Renderer:alert 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Alert cxd-Alert--success"
@ -53,6 +54,7 @@ exports[`Renderer:alert var 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Alert cxd-Alert--success"

View File

@ -13,6 +13,7 @@ exports[`Renderer:anchorNav 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-AnchorNav cxd-AnchorNav--vertical"
@ -700,6 +701,7 @@ exports[`Renderer:anchorNav with horizontal 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-AnchorNav cxd-AnchorNav--horizontal"

View File

@ -13,6 +13,7 @@ exports[`Renderer:avatar fit 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-Avatar cxd-Avatar--circle"
@ -74,6 +75,7 @@ exports[`Renderer:avatar gap 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-Avatar cxd-Avatar--circle"
@ -127,6 +129,7 @@ exports[`Renderer:avatar shape 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-Avatar cxd-Avatar--square"
@ -169,6 +172,7 @@ exports[`Renderer:avatar size 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-Avatar cxd-Avatar--circle cxd-Avatar--lg"
@ -268,6 +272,7 @@ exports[`Renderer:avatar var 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-Avatar cxd-Avatar--circle"

View File

@ -13,6 +13,7 @@ exports[`Renderer:bar-code 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-BarCode"

View File

@ -172,6 +172,7 @@ exports[`Renderer:breadcrumb dropdown 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Breadcrumb"
@ -258,6 +259,7 @@ exports[`Renderer:breadcrumb separator 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Breadcrumb"
@ -337,6 +339,7 @@ exports[`Renderer:breadcrumb tooltip labelMaxLength 1`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -424,6 +427,7 @@ exports[`Renderer:breadcrumb tooltip labelMaxLength 2`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -511,6 +515,7 @@ exports[`Renderer:breadcrumb tooltip labelMaxLength 3`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -598,6 +603,7 @@ exports[`Renderer:breadcrumb tooltip labelMaxLength 4`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -684,6 +690,7 @@ exports[`Renderer:breadcrumb var 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Breadcrumb"

View File

@ -13,6 +13,7 @@ exports[`Renderer: crud keepItemSelectionOnPageChange & maxKeepItemSelectionLeng
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Crud"
@ -1373,6 +1374,7 @@ exports[`Renderer: crud sortable & orderBy & orderDir & orderField 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Crud"
@ -2135,6 +2137,7 @@ exports[`Renderer:crud basic interval headerToolbar footerToolbar 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Crud"
@ -2945,6 +2948,7 @@ exports[`Renderer:crud cards 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Crud"
@ -3825,6 +3829,7 @@ exports[`Renderer:crud list 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Crud"
@ -4227,6 +4232,7 @@ exports[`Renderer:crud source & alwaysShowPagination 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Crud"

View File

@ -13,6 +13,7 @@ exports[`Renderer:card 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Card className cxd-Card--link"
@ -94,6 +95,7 @@ exports[`Renderer:cards color 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Cards"
@ -371,6 +373,7 @@ exports[`Renderer:cards hightlight 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Card"
@ -500,6 +503,7 @@ exports[`Renderer:cards hightlight 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Card"
@ -629,6 +633,7 @@ exports[`Renderer:cards media 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Card"

View File

@ -13,6 +13,7 @@ exports[`Renderer:container 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Container bg-white"

View File

@ -52,6 +52,7 @@ exports[`Renderer:flex justify 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"

View File

@ -13,6 +13,7 @@ exports[`Renderer:gridnav 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-GridNav cxd-GridNav-top u-hairline"

View File

@ -35,6 +35,7 @@ exports[`Renderer:iframe-var 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<iframe
class="b-a"

View File

@ -48,6 +48,7 @@ exports[`Renderer:images images:basic 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-ImagesField"

View File

@ -13,6 +13,7 @@ exports[`Renderer:json 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-JsonField"

View File

@ -13,6 +13,7 @@ exports[`Renderer:list 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"

View File

@ -120,6 +120,7 @@ exports[`Renderer:Nav with itemActions 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Nav"
@ -366,6 +367,7 @@ exports[`Renderer:Nav with itemActions 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Nav"
@ -799,6 +801,7 @@ exports[`Renderer:Nav with overflow 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Nav"

View File

@ -92,6 +92,7 @@ exports[`Renderer:Page 1`] = `
</div>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -202,6 +203,7 @@ exports[`Renderer:Page classNames 1`] = `
</div>
<div
class="cxd-Page-body body-class-name"
role="page-body"
>
<span
class="cxd-TplField"
@ -242,6 +244,7 @@ exports[`Renderer:Page handleAction actionType=ajax & feedback 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -285,6 +288,7 @@ exports[`Renderer:Page handleAction actionType=ajax & feedback 1`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<span
class="cxd-TplField"
@ -344,6 +348,7 @@ exports[`Renderer:Page handleAction actionType=ajax & feedback 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -384,6 +389,7 @@ exports[`Renderer:Page handleAction actionType=ajax 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -424,6 +430,7 @@ exports[`Renderer:Page handleAction actionType=dialog default 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
/>
</div>
</div>
@ -456,6 +463,7 @@ exports[`Renderer:Page handleAction actionType=dialog default 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
/>
</div>
</div>
@ -488,6 +496,7 @@ exports[`Renderer:Page handleAction actionType=dialog mergeData 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -531,6 +540,7 @@ exports[`Renderer:Page handleAction actionType=dialog mergeData 1`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<form
class="cxd-Form cxd-Form--horizontal"
@ -623,6 +633,7 @@ exports[`Renderer:Page handleAction actionType=dialog mergeData 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -663,6 +674,7 @@ exports[`Renderer:Page handleAction actionType=drawer default 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
/>
</div>
</div>
@ -753,6 +765,7 @@ exports[`Renderer:Page handleAction actionType=drawer default 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
/>
</div>
</div>
@ -785,6 +798,7 @@ exports[`Renderer:Page handleAction actionType=drawer mergeData 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -820,6 +834,7 @@ exports[`Renderer:Page handleAction actionType=drawer mergeData 1`] = `
/>
<div
class="cxd-Drawer-body"
role="dialog-body"
>
<form
class="cxd-Form cxd-Form--horizontal"
@ -912,6 +927,7 @@ exports[`Renderer:Page handleAction actionType=drawer mergeData 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -940,6 +956,7 @@ exports[`Renderer:Page initApi 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -968,6 +985,7 @@ exports[`Renderer:Page initApi error show Message 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Alert cxd-Alert--danger"
@ -1012,6 +1030,7 @@ exports[`Renderer:Page initApi reFetch when condition changes 1`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -1054,6 +1073,7 @@ exports[`Renderer:Page initApi reFetch when condition changes 2`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -1107,6 +1127,7 @@ exports[`Renderer:Page initApi reload by Dialog action 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1147,6 +1168,7 @@ exports[`Renderer:Page initApi reload by Dialog action 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1190,6 +1212,7 @@ exports[`Renderer:Page initApi reload by Dialog action 2`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<form
class="cxd-Form cxd-Form--horizontal"
@ -1282,6 +1305,7 @@ exports[`Renderer:Page initApi reload by Dialog action 3`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1322,6 +1346,7 @@ exports[`Renderer:Page initApi reload by Drawer action 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1362,6 +1387,7 @@ exports[`Renderer:Page initApi reload by Drawer action 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1397,6 +1423,7 @@ exports[`Renderer:Page initApi reload by Drawer action 2`] = `
/>
<div
class="cxd-Drawer-body"
role="dialog-body"
>
<form
class="cxd-Form cxd-Form--horizontal"
@ -1489,6 +1516,7 @@ exports[`Renderer:Page initApi reload by Drawer action 3`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1631,6 +1659,7 @@ exports[`Renderer:Page initApi reload by Form submit 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1773,6 +1802,7 @@ exports[`Renderer:Page initApi reload by Form submit 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1813,6 +1843,7 @@ exports[`Renderer:Page initApi reload by action 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1853,6 +1884,7 @@ exports[`Renderer:Page initApi reload by action 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1881,6 +1913,7 @@ exports[`Renderer:Page initApi show loading 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Spinner-overlay in"
@ -1920,6 +1953,7 @@ exports[`Renderer:Page initApi show loading 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1948,6 +1982,7 @@ exports[`Renderer:Page initApi silentPolling 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -1976,6 +2011,7 @@ exports[`Renderer:Page initApi silentPolling 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -2005,6 +2041,7 @@ exports[`Renderer:Page initData 1`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -2047,6 +2084,7 @@ exports[`Renderer:Page initFetchOn trigger initApi fetch when condition becomes
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -2089,6 +2127,7 @@ exports[`Renderer:Page location query 1`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"
@ -2131,6 +2170,7 @@ exports[`Renderer:Page location query 2`] = `
>
<div
className="cxd-Page-body"
role="page-body"
>
<span
className="cxd-Spinner-mark"

View File

@ -13,6 +13,7 @@ exports[`Renderer:qr-code QRCode render with svg 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-QrCode"
@ -55,6 +56,7 @@ exports[`Renderer:qr-code QRCode with background/foreground color 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-QrCode"
@ -97,6 +99,7 @@ exports[`Renderer:qr-code QRCode with image 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-QrCode"

View File

@ -13,6 +13,7 @@ exports[`Renderer:status 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-StatusField cxd-StatusField--0"

View File

@ -914,6 +914,7 @@ exports[`Renderer:table children 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -2789,6 +2790,7 @@ exports[`Renderer:table combine Renderer:table combineNum only 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -3495,6 +3497,7 @@ exports[`Renderer:table combine Renderer:table combineNum with fromIndex 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -4271,6 +4274,7 @@ exports[`Renderer:table groupName-default 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -5236,6 +5240,7 @@ exports[`Renderer:table groupName-middleNoGroupName 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -6193,6 +6198,7 @@ exports[`Renderer:table groupName-startNoGroupName 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -7119,6 +7125,7 @@ exports[`Renderer:table groupName-withTpl 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"

View File

@ -13,6 +13,7 @@ exports[`Renderer:tableview 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Service"
@ -142,6 +143,7 @@ exports[`Renderer:tableview layout 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<table
class="cxd-TableView"

View File

@ -13,6 +13,7 @@ exports[`Renderer:tesks 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Table-content"

View File

@ -13,6 +13,7 @@ exports[`Tree: basic & disabled children & default check children 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
@ -386,6 +387,7 @@ exports[`Tree: showOutline 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Panel--form"

View File

@ -531,6 +531,7 @@ exports[`Renderer:Wizard dialog 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Wizard cxd-Wizard--horizontal"
@ -760,6 +761,7 @@ exports[`Renderer:Wizard dialog 1`] = `
</div>
<div
class="cxd-Modal-body"
role="dialog-body"
>
<div
class="cxd-Form cxd-Form--horizontal"
@ -848,6 +850,7 @@ exports[`Renderer:Wizard dialog 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Wizard cxd-Wizard--horizontal"
@ -1278,6 +1281,7 @@ exports[`Renderer:Wizard initApi reload 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Wizard cxd-Wizard--horizontal"
@ -1479,6 +1483,7 @@ exports[`Renderer:Wizard initApi reload 2`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Wizard cxd-Wizard--horizontal"
@ -1620,6 +1625,7 @@ exports[`Renderer:Wizard initApi reload 3`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Wizard cxd-Wizard--horizontal"
@ -2629,6 +2635,7 @@ exports[`Renderer:Wizard target 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Panel cxd-Panel--default cxd-Wizard cxd-Wizard--horizontal"

View File

@ -13,6 +13,7 @@ exports[`Renderer:calendar 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Form-item cxd-Form-item--normal"
@ -521,6 +522,7 @@ exports[`Renderer:calendar largeMode 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Form-item cxd-Form-item--normal"
@ -1177,6 +1179,7 @@ exports[`Renderer:calendar scheduleAction 1`] = `
>
<div
class="cxd-Page-body"
role="page-body"
>
<div
class="cxd-Form-item cxd-Form-item--normal"

View File

@ -25,6 +25,7 @@ exports[`api:cache 1`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"
@ -65,6 +66,7 @@ exports[`api:cache 2`] = `
</div>
<div
class="cxd-Page-body"
role="page-body"
>
<span
class="cxd-TplField"

View File

@ -7,14 +7,7 @@ import {
ThemeProps
} from 'amis-core';
import {
alert,
confirm,
setRenderSchemaFn,
toast,
ImageGallery,
Spinner
} from 'amis-ui';
import {alert, confirm, setRenderSchemaFn, toast, ImageGallery} from 'amis-ui';
import React from 'react';
extendDefaultEnv({

View File

@ -10,7 +10,7 @@ import {
ScopedContext
} from 'amis-core';
import {filter} from 'amis-core';
import {BadgeObject, Button} from 'amis-ui';
import {BadgeObject, Button, SpinnerExtraProps} from 'amis-ui';
import pick from 'lodash/pick';
import omit from 'lodash/omit';
@ -562,7 +562,8 @@ export interface ActionProps
| 'iconClassName'
| 'rightIconClassName'
| 'loadingClassName'
> {
>,
SpinnerExtraProps {
actionType: any;
onAction?: (
e: React.MouseEvent<any> | void | null,
@ -778,7 +779,8 @@ export class Action extends React.Component<ActionProps, ActionState> {
onMouseEnter,
onMouseLeave,
classnames: cx,
classPrefix: ns
classPrefix: ns,
loadingConfig
} = this.props;
if (actionType !== 'email' && body) {
@ -832,6 +834,7 @@ export class Action extends React.Component<ActionProps, ActionState> {
return (
<Button
loadingConfig={loadingConfig}
className={cx(className, {
[activeClassName || 'is-active']: isActive
})}

View File

@ -1,5 +1,5 @@
import React from 'react';
import {AsideNav, Html, NotFound, Spinner} from 'amis-ui';
import {AsideNav, Html, NotFound, Spinner, SpinnerExtraProps} from 'amis-ui';
import {Layout} from 'amis-ui';
import {Renderer, RendererProps, replaceText} from 'amis-core';
import {
@ -10,12 +10,11 @@ import {
} from '../Schema';
import {IScopedContext, ScopedContext} from 'amis-core';
import {AppStore, IAppStore} from 'amis-core';
import {Api, SchemaNode} from 'amis-core';
import {isApiOutdated, isEffectiveApi} from 'amis-core';
import {autobind} from 'amis-core';
import {generateIcon} from 'amis-core';
export interface AppPage {
export interface AppPage extends SpinnerExtraProps {
/**
*
*/
@ -84,7 +83,7 @@ export interface AppPage {
* App JSSDK
* https://baidu.gitee.io/amis/docs/components/app
*/
export interface AppSchema extends BaseSchema {
export interface AppSchema extends BaseSchema, SpinnerExtraProps {
/**
* app
*/
@ -413,12 +412,11 @@ export default class App extends React.Component<AppProps, object> {
render() {
const {
className,
size,
classnames: cx,
store,
render,
showBreadcrumb = true
showBreadcrumb = true,
loadingConfig
} = this.props;
return (
@ -461,7 +459,12 @@ export default class App extends React.Component<AppProps, object> {
<div className="text-center"></div>
</NotFound>
) : null}
<Spinner overlay show={store.loading || !store.pages} size="lg" />
<Spinner
loadingConfig={loadingConfig}
overlay
show={store.loading || !store.pages}
size="lg"
/>
</Layout>
);
}

View File

@ -16,7 +16,7 @@ import {
isArrayChildrenModified
} from 'amis-core';
import {ScopedContext, IScopedContext} from 'amis-core';
import {Button} from 'amis-ui';
import {Button, SpinnerExtraProps} from 'amis-ui';
import {Select} from 'amis-ui';
import {getExprProperties} from 'amis-core';
import pick from 'lodash/pick';
@ -27,7 +27,6 @@ import omit from 'lodash/omit';
import find from 'lodash/find';
import findIndex from 'lodash/findIndex';
import {Html} from 'amis-ui';
import {Spinner} from 'amis-ui';
import {Icon} from 'amis-ui';
import {
BaseSchema,
@ -74,7 +73,7 @@ export type CRUDToolbarObject = {
align?: 'left' | 'right';
};
export interface CRUDCommonSchema extends BaseSchema {
export interface CRUDCommonSchema extends BaseSchema, SpinnerExtraProps {
/**
* CRUD
*/
@ -326,7 +325,8 @@ export type CRUDSchema = CRUDCardsSchema | CRUDListSchema | CRUDTableSchema;
export interface CRUDProps
extends RendererProps,
Omit<CRUDCommonSchema, 'type' | 'className'> {
Omit<CRUDCommonSchema, 'type' | 'className'>,
SpinnerExtraProps {
store: ICRUDStore;
pickerMode?: boolean; // 选择模式,用做表单中的选择操作
}
@ -2247,9 +2247,6 @@ export default class CRUD extends React.Component<CRUDProps, any> {
loading: store.loading
}
)}
{/* spinner可以交给孩子处理 */}
{/* <Spinner overlay size="lg" key="info" show={store.loading} /> */}
{render(
'dialog',
{

View File

@ -21,7 +21,7 @@ import {findDOMNode} from 'react-dom';
import {evalExpression, filter} from 'amis-core';
import {isEffectiveApi, isApiOutdated} from 'amis-core';
import findIndex from 'lodash/findIndex';
import {Html} from 'amis-ui';
import {Html, SpinnerExtraProps} from 'amis-ui';
import {
BaseSchema,
SchemaApi,
@ -39,7 +39,7 @@ import {upperFirst} from 'lodash';
export type CRUDRendererEvent = 'search';
export interface CRUD2CommonSchema extends BaseSchema {
export interface CRUD2CommonSchema extends BaseSchema, SpinnerExtraProps {
/**
* CRUD2
*/
@ -187,7 +187,8 @@ export type CRUD2Schema = CRUD2CardsSchema | CRUD2ListSchema | CRUD2TableSchema;
export interface CRUD2Props
extends RendererProps,
Omit<CRUD2CommonSchema, 'type' | 'className'> {
Omit<CRUD2CommonSchema, 'type' | 'className'>,
SpinnerExtraProps {
store: ICRUDStore;
pickerMode?: boolean; // 选择模式,用做表单中的选择操作
}

View File

@ -2,7 +2,7 @@ import React, {Fragment} from 'react';
import {findDOMNode} from 'react-dom';
import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, Schema, ActionObject} from 'amis-core';
import {Button, Spinner} from 'amis-ui';
import {Button, Spinner, SpinnerExtraProps} from 'amis-ui';
import {ListStore, IListStore} from 'amis-core';
import {Action} from '../types';
import {
@ -34,7 +34,7 @@ import type {IItem} from 'amis-core/lib/store/list';
* Cards
* https://baidu.gitee.io/amis/docs/components/card
*/
export interface CardsSchema extends BaseSchema {
export interface CardsSchema extends BaseSchema, SpinnerExtraProps {
/**
* cards
*/
@ -986,7 +986,8 @@ export default class Cards extends React.Component<GridProps, object> {
itemsClassName,
classnames: cx,
translate: __,
loading = false
loading = false,
loadingConfig
} = this.props;
this.renderedToolbars = []; // 用来记录哪些 toolbar 已经渲染了,已经渲染了就不重复渲染了。
@ -1046,7 +1047,7 @@ export default class Cards extends React.Component<GridProps, object> {
)}
{footer}
<Spinner overlay show={loading} />
<Spinner loadingConfig={loadingConfig} overlay show={loading} />
</div>
);
}

View File

@ -3,7 +3,7 @@ import {ScopedContext, IScopedContext} from 'amis-core';
import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, Schema, ActionObject} from 'amis-core';
import {filter} from 'amis-core';
import {Modal} from 'amis-ui';
import {Modal, SpinnerExtraProps} from 'amis-ui';
import {
guid,
isVisible,
@ -111,7 +111,8 @@ export type DialogSchemaBase = Omit<DialogSchema, 'type'>;
export interface DialogProps
extends RendererProps,
Omit<DialogSchema, 'className'> {
Omit<DialogSchema, 'className'>,
SpinnerExtraProps {
onClose: (confirmed?: boolean) => void;
onConfirm: (
values: Array<object>,
@ -530,11 +531,12 @@ export default class Dialog extends React.Component<DialogProps> {
env,
classnames: cx,
classPrefix,
translate: __
translate: __,
loadingConfig
} = {
...this.props,
...store.schema
} as any;
} as DialogProps;
const Wrapper = wrapperComponent || Modal;
return (
@ -609,11 +611,12 @@ export default class Dialog extends React.Component<DialogProps> {
: null}
{(!store.entered && lazyRender) || (lazySchema && !body) ? (
<div className={cx('Modal-body', bodyClassName)}>
<Spinner overlay show size="lg" />
<div className={cx('Modal-body', bodyClassName)} role="dialog-body">
<Spinner overlay show size="lg" loadingConfig={loadingConfig} />
</div>
) : body ? (
<div className={cx('Modal-body', bodyClassName)}>
// dialog-body 用于在 editor 中定位元素
<div className={cx('Modal-body', bodyClassName)} role="dialog-body">
{this.renderBody(body, 'body')}
</div>
) : null}

View File

@ -2,7 +2,7 @@ import React from 'react';
import {ScopedContext, IScopedContext} from 'amis-core';
import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, Schema, ActionObject} from 'amis-core';
import {Drawer as DrawerContainer} from 'amis-ui';
import {Drawer as DrawerContainer, SpinnerExtraProps} from 'amis-ui';
import {
guid,
isVisible,
@ -140,7 +140,8 @@ export type DrawerSchemaBase = Omit<DrawerSchema, 'type'>;
export interface DrawerProps
extends RendererProps,
Omit<DrawerSchema, 'className'> {
Omit<DrawerSchema, 'className'>,
SpinnerExtraProps {
onClose: () => void;
onConfirm: (
values: Array<object>,
@ -554,11 +555,12 @@ export default class Drawer extends React.Component<DrawerProps> {
closeOnOutside,
classPrefix: ns,
classnames: cx,
drawerContainer
drawerContainer,
loadingConfig
} = {
...this.props,
...store.schema
} as any;
} as DrawerProps;
const Container = wrapperComponent || DrawerContainer;
@ -614,10 +616,11 @@ export default class Drawer extends React.Component<DrawerProps> {
{!store.entered ? (
<div className={cx('Drawer-body', bodyClassName)}>
<Spinner overlay show size="lg" />
<Spinner overlay show size="lg" loadingConfig={loadingConfig} />
</div>
) : body ? (
<div className={cx('Drawer-body', bodyClassName)}>
// dialog-body 用于在 editor 中定位元素
<div className={cx('Drawer-body', bodyClassName)} role="dialog-body">
{this.renderBody(body, 'body')}
</div>
) : null}

View File

@ -2,7 +2,14 @@ import React from 'react';
import cx from 'classnames';
import {matchSorter} from 'match-sorter';
import {FormItem, FormControlProps, autobind} from 'amis-core';
import {Modal, Button, Spinner, SearchBox, Icon} from 'amis-ui';
import {
Modal,
Button,
Spinner,
SearchBox,
Icon,
SpinnerExtraProps
} from 'amis-ui';
import debounce from 'lodash/debounce';
import {FormBaseControlSchema} from '../../Schema';
@ -20,7 +27,7 @@ export interface IconSelectControlSchema extends FormBaseControlSchema {
clearable?: boolean;
}
export interface IconSelectProps extends FormControlProps {
export interface IconSelectProps extends FormControlProps, SpinnerExtraProps {
placeholder?: string;
disabled?: boolean;
noDataTip?: string;
@ -254,7 +261,7 @@ export default class IconSelectControl extends React.PureComponent<
@autobind
renderModalContent() {
const {render, classPrefix: ns} = this.props;
const {render, classPrefix: ns, loadingConfig} = this.props;
const icons = this.getIconsByType();
@ -289,6 +296,7 @@ export default class IconSelectControl extends React.PureComponent<
<div className={cx(`${ns}IconSelectControl-Modal-content`)}>
<Spinner
size="lg"
loadingConfig={loadingConfig}
overlay
key="info"
show={this.state.isRefreshLoading}

View File

@ -6,7 +6,7 @@ import {
resolveEventData
} from 'amis-core';
import {ClassNamesFn, themeable, ThemeProps} from 'amis-core';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {Select} from 'amis-ui';
import {CityArea} from 'amis-ui';
import {autobind, isMobile, createObject} from 'amis-core';
@ -20,7 +20,9 @@ import {supportStatic} from './StaticHoc';
* City
* https://baidu.gitee.io/amis/docs/components/form/city
*/
export interface InputCityControlSchema extends FormBaseControlSchema {
export interface InputCityControlSchema
extends FormBaseControlSchema,
SpinnerExtraProps {
/**
*
*/
@ -111,7 +113,7 @@ const getCityFromCode = ({
value,
db,
delimiter = ','
}:{
}: {
value: any;
db?: CityDb;
delimiter?: string;
@ -170,11 +172,11 @@ const getCityFromCode = ({
}
return result;
}
};
const loadDb = (callback: (db: any) => void): void => {
import('amis-ui/lib/components/CityDB').then(callback);
}
};
export class CityPicker extends React.Component<
CityPickerProps,
@ -351,11 +353,13 @@ export class CityPicker extends React.Component<
return;
}
this.setState(getCityFromCode({
value,
delimiter,
db
}));
this.setState(
getCityFromCode({
value,
delimiter,
db
})
);
}
@autobind
@ -406,7 +410,8 @@ export class CityPicker extends React.Component<
allowDistrict,
allowStreet,
searchable,
translate: __
translate: __,
loadingConfig
} = this.props;
const {provinceCode, cityCode, districtCode, street, db} = this.state;
@ -466,7 +471,7 @@ export class CityPicker extends React.Component<
) : null}
</div>
) : (
<Spinner show size="sm" />
<Spinner show size="sm" loadingConfig={loadingConfig} />
);
}
}
@ -484,7 +489,7 @@ export interface LocationControlProps extends FormControlProps {
export class LocationControl extends React.Component<LocationControlProps> {
state = {
db: null
}
};
@autobind
doAction(action: ActionObject, data: object, throwErrors: boolean) {
@ -515,46 +520,33 @@ export class LocationControl extends React.Component<LocationControlProps> {
}
renderStatic(displayValue = '') {
const {value, delimiter} = this.props;
const {value, delimiter, loadingConfig} = this.props;
if (!this.state.db) {
loadDb(db => {
this.setState(
{
db: {
...db.default,
province: db.province as any,
city: db.city,
district: db.district
}
this.setState({
db: {
...db.default,
province: db.province as any,
city: db.city,
district: db.district
}
);
});
});
return <Spinner size='sm' />;
return <Spinner size="sm" show loadingConfig={loadingConfig} />;
}
if (!value) {
return <>{displayValue}</>;
}
const {
province,
city,
district,
street
} = getCityFromCode({
const {province, city, district, street} = getCityFromCode({
value,
delimiter,
db: this.state.db
});
return (
<>
{
[province, city, district, street]
.filter(v => !!v)
.join(delimiter)
}
</>
<>{[province, city, district, street].filter(v => !!v).join(delimiter)}</>
);
}

View File

@ -10,7 +10,7 @@ import find from 'lodash/find';
import isInteger from 'lodash/isInteger';
import unionWith from 'lodash/unionWith';
import {findDOMNode} from 'react-dom';
import {ResultBox} from 'amis-ui';
import {ResultBox, SpinnerExtraProps} from 'amis-ui';
import {autobind, filterTree, createObject} from 'amis-core';
import {Spinner} from 'amis-ui';
import {Overlay} from 'amis-core';
@ -73,7 +73,7 @@ export interface TagControlSchema extends FormOptionsSchema {
export type InputTagValidationType = 'max' | 'maxLength';
export interface TagProps extends OptionsControlProps {
export interface TagProps extends OptionsControlProps, SpinnerExtraProps {
placeholder?: string;
clearable: boolean;
resetValue?: any;
@ -456,7 +456,8 @@ export default class TagControl extends React.PureComponent<
optionsTip,
maxTagCount,
overflowTagPopover,
translate: __
translate: __,
loadingConfig
} = this.props;
const finnalOptions = Array.isArray(options)
@ -506,7 +507,9 @@ export default class TagControl extends React.PureComponent<
overflowTagPopover={overflowTagPopover}
allowInput
>
{loading ? <Spinner size="sm" /> : undefined}
{loading ? (
<Spinner loadingConfig={loadingConfig} size="sm" />
) : undefined}
</ResultBox>
{dropdown !== false ? (

View File

@ -12,7 +12,7 @@ import {matchSorter} from 'match-sorter';
import debouce from 'lodash/debounce';
import {filter} from 'amis-core';
import find from 'lodash/find';
import {Icon} from 'amis-ui';
import {Icon, SpinnerExtraProps} from 'amis-ui';
import {Input} from 'amis-ui';
import {autobind, createObject, setVariable, ucFirst} from 'amis-core';
import {isEffectiveApi} from 'amis-core';
@ -116,7 +116,7 @@ export type InputTextRendererEvent =
| 'change'
| 'enter';
export interface TextProps extends OptionsControlProps {
export interface TextProps extends OptionsControlProps, SpinnerExtraProps {
placeholder?: string;
addOn?: ActionObject & {
position?: 'left' | 'right';
@ -677,7 +677,8 @@ export default class TextControl extends React.PureComponent<
showCounter,
maxLength,
minLength,
translate: __
translate: __,
loadingConfig
} = this.props;
let type = this.props.type?.replace(/^(?:native|input)\-/, '');
@ -815,6 +816,7 @@ export default class TextControl extends React.PureComponent<
icon="reload"
size="sm"
spinnerClassName={cx('TextControl-spinner')}
loadingConfig={loadingConfig}
/>
) : null}

View File

@ -1,6 +1,6 @@
import React from 'react';
import cx from 'classnames';
import {Tree as TreeSelector} from 'amis-ui';
import {SpinnerExtraProps, Tree as TreeSelector} from 'amis-ui';
import {
OptionsControl,
OptionsControlProps,
@ -110,7 +110,8 @@ export interface TreeProps
| 'inputClassName'
| 'descriptionClassName'
| 'deferApi'
> {
>,
SpinnerExtraProps {
enableNodePath?: boolean;
pathSeparator?: string;
}
@ -234,7 +235,8 @@ export default class TreeControl extends React.Component<TreeProps> {
translate: __,
data,
virtualThreshold,
itemHeight
itemHeight,
loadingConfig
} = this.props;
let {highlightTxt} = this.props;
@ -246,7 +248,12 @@ export default class TreeControl extends React.Component<TreeProps> {
<div
className={cx(`${ns}TreeControl`, className, treeContainerClassName)}
>
<Spinner size="sm" key="info" show={loading} />
<Spinner
size="sm"
key="info"
show={loading}
loadingConfig={loadingConfig}
/>
{loading ? null : (
<TreeSelector
classPrefix={ns}

View File

@ -11,8 +11,8 @@ import {
resolveEventData
} from 'amis-core';
import {buildApi, isValidApi, isEffectiveApi} from 'amis-core';
import {Checkbox, Spinner} from 'amis-ui';
import {autobind, setVariable, createObject} from 'amis-core';
import {Checkbox, Spinner, SpinnerExtraProps} from 'amis-ui';
import {setVariable, createObject} from 'amis-core';
import {ApiObject, ActionObject} from 'amis-core';
import {FormBaseControlSchema, SchemaApi} from '../../Schema';
import {supportStatic} from './StaticHoc';
@ -69,7 +69,7 @@ export interface ValueItem extends Column, Row {
checked: boolean;
}
export interface MatrixProps extends FormControlProps {
export interface MatrixProps extends FormControlProps, SpinnerExtraProps {
columns: Array<Column>;
rows: Array<Row>;
multiple: boolean;
@ -349,17 +349,14 @@ export default class MatrixCheckbox extends React.Component<
const {error} = this.state;
return (
<div key="input" className={cx('MatrixControl', className || '')}>
{error
? displayValue
: this.renderInput(true)
}
{error ? displayValue : this.renderInput(true)}
</div>
);
}
@supportStatic()
render() {
const {className, style, render, classnames: cx} = this.props;
const {className, render, classnames: cx, loadingConfig} = this.props;
const {error, loading} = this.state;
return (
@ -372,7 +369,13 @@ export default class MatrixCheckbox extends React.Component<
this.renderInput()
)}
<Spinner size="lg" overlay key="info" show={loading} />
<Spinner
size="lg"
overlay
key="info"
show={loading}
loadingConfig={loadingConfig}
/>
</div>
);
}

View File

@ -1,6 +1,6 @@
import React from 'react';
import {Overlay, resolveEventData} from 'amis-core';
import {Checkbox} from 'amis-ui';
import {Checkbox, SpinnerExtraProps} from 'amis-ui';
import {PopOver} from 'amis-core';
import {PopUp} from 'amis-ui';
import {Icon} from 'amis-ui';
@ -74,7 +74,9 @@ export interface NestedSelectControlSchema extends FormOptionsSchema {
hideNodePathLabel?: boolean;
}
export interface NestedSelectProps extends OptionsControlProps {
export interface NestedSelectProps
extends OptionsControlProps,
SpinnerExtraProps {
cascade?: boolean;
noResultsText?: string;
withChildren?: boolean;
@ -879,7 +881,8 @@ export default class NestedSelectControl extends React.Component<
loading,
borderMode,
useMobileUI,
env
env,
loadingConfig
} = this.props;
const mobileUI = useMobileUI && isMobile();
@ -921,7 +924,9 @@ export default class NestedSelectControl extends React.Component<
hasDropDownArrow={true}
allowInput={searchable}
>
{loading ? <Spinner size="sm" /> : undefined}
{loading ? (
<Spinner loadingConfig={loadingConfig} size="sm" />
) : undefined}
</ResultBox>
{mobileUI ? (
<PopUp

View File

@ -15,7 +15,7 @@ import {isEffectiveApi, isApiOutdated} from 'amis-core';
import {isEmpty, createObject, autobind, isMobile} from 'amis-core';
import {FormOptionsSchema, SchemaApi} from '../../Schema';
import {Spinner, Select} from 'amis-ui';
import {Spinner, Select, SpinnerExtraProps} from 'amis-ui';
import {BaseTransferRenderer, TransferControlSchema} from './Transfer';
import {TransferDropDown} from 'amis-ui';
@ -27,7 +27,9 @@ import {supportStatic} from './StaticHoc';
* Select
* https://baidu.gitee.io/amis/docs/components/form/select
*/
export interface SelectControlSchema extends FormOptionsSchema {
export interface SelectControlSchema
extends FormOptionsSchema,
SpinnerExtraProps {
type: 'select' | 'multi-select';
/**
@ -135,7 +137,7 @@ export interface SelectControlSchema extends FormOptionsSchema {
optionClassName?: SchemaClassName;
}
export interface SelectProps extends OptionsControlProps {
export interface SelectProps extends OptionsControlProps, SpinnerExtraProps {
autoComplete?: Api;
searchable?: boolean;
showInvalidMatch?: boolean;
@ -510,7 +512,8 @@ export interface TransferDropDownProps
| 'inputClassName'
| 'className'
| 'descriptionClassName'
> {
>,
SpinnerExtraProps {
borderMode?: 'full' | 'half' | 'none';
useMobileUI?: boolean;
}
@ -548,7 +551,8 @@ class TransferDropdownRenderer extends BaseTransferRenderer<TransferDropDownProp
placeholder,
itemHeight,
virtualThreshold,
rightMode
rightMode,
loadingConfig
} = this.props;
// 目前 LeftOptions 没有接口可以动态加载
@ -601,7 +605,12 @@ class TransferDropdownRenderer extends BaseTransferRenderer<TransferDropDownProp
virtualListHeight={266}
/>
<Spinner overlay key="info" show={loading} />
<Spinner
overlay
key="info"
show={loading}
loadingConfig={loadingConfig}
/>
</>
);
}

View File

@ -1,7 +1,7 @@
import {OptionsControlProps, OptionsControl, resolveEventData} from 'amis-core';
import React from 'react';
import find from 'lodash/find';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {BaseTransferRenderer, TransferControlSchema} from './Transfer';
import {TabsTransfer} from 'amis-ui';
import {Option, optionValueCompare} from 'amis-core';
@ -24,7 +24,8 @@ import {supportStatic} from './StaticHoc';
* https://baidu.gitee.io/amis/docs/components/form/tabs-transfer
*/
export interface TabsTransferControlSchema
extends Omit<TransferControlSchema, 'type'> {
extends Omit<TransferControlSchema, 'type'>,
SpinnerExtraProps {
type: 'tabs-transfer';
}
@ -37,7 +38,8 @@ export interface TabsTransferProps
| 'inputClassName'
| 'className'
| 'descriptionClassName'
> {}
>,
SpinnerExtraProps {}
interface BaseTransferState {
activeKey: number;
@ -300,7 +302,8 @@ export class TabsTransferRenderer extends BaseTabsTransferRenderer<TabsTransferP
resultTitle,
itemHeight,
virtualThreshold,
onlyChildren
onlyChildren,
loadingConfig
} = this.props;
return (
@ -330,7 +333,12 @@ export class TabsTransferRenderer extends BaseTabsTransferRenderer<TabsTransferP
virtualThreshold={virtualThreshold}
/>
<Spinner overlay key="info" show={loading} />
<Spinner
overlay
key="info"
show={loading}
loadingConfig={loadingConfig}
/>
</div>
);
}

View File

@ -1,6 +1,6 @@
import {OptionsControlProps, OptionsControl, resolveEventData} from 'amis-core';
import React from 'react';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {BaseTabsTransferRenderer} from './TabsTransfer';
import {TabsTransferPicker} from 'amis-ui';
import {TabsTransferControlSchema} from './TabsTransfer';
@ -15,7 +15,8 @@ import {supportStatic} from './StaticHoc';
* https://baidu.gitee.io/amis/docs/components/form/tabs-transfer-picker
*/
export interface TabsTransferPickerControlSchema
extends Omit<TabsTransferControlSchema, 'type'> {
extends Omit<TabsTransferControlSchema, 'type'>,
SpinnerExtraProps {
type: 'tabs-transfer-picker';
}
@ -28,7 +29,8 @@ export interface TabsTransferProps
| 'inputClassName'
| 'className'
| 'descriptionClassName'
> {}
>,
SpinnerExtraProps {}
interface BaseTransferState {
activeKey: number;
@ -101,7 +103,8 @@ export class TabsTransferPickerRenderer extends BaseTabsTransferRenderer<TabsTra
leftMode,
leftOptions,
itemHeight,
virtualThreshold
virtualThreshold,
loadingConfig
} = this.props;
return (
@ -134,7 +137,12 @@ export class TabsTransferPickerRenderer extends BaseTabsTransferRenderer<TabsTra
virtualThreshold={virtualThreshold}
/>
<Spinner overlay key="info" show={loading} />
<Spinner
loadingConfig={loadingConfig}
overlay
key="info"
show={loading}
/>
</div>
);
}

View File

@ -7,7 +7,7 @@ import {
FormOptionsControl,
resolveEventData
} from 'amis-core';
import {Transfer} from 'amis-ui';
import {SpinnerExtraProps, Transfer} from 'amis-ui';
import type {Option} from 'amis-core';
import {
autobind,
@ -33,7 +33,9 @@ import {supportStatic} from './StaticHoc';
* Transfer
* https://baidu.gitee.io/amis/docs/components/form/transfer
*/
export interface TransferControlSchema extends FormOptionsSchema {
export interface TransferControlSchema
extends FormOptionsSchema,
SpinnerExtraProps {
type: 'transfer';
/**
@ -156,14 +158,17 @@ export interface BaseTransferProps
| 'className'
| 'descriptionClassName'
| 'inputClassName'
> {
>,
SpinnerExtraProps {
resultItemRender?: (option: Option) => JSX.Element;
virtualThreshold?: number;
itemHeight?: number;
}
type OptionsControlWithSpinnerProps = OptionsControlProps & SpinnerExtraProps;
export class BaseTransferRenderer<
T extends OptionsControlProps = BaseTransferProps
T extends OptionsControlWithSpinnerProps = BaseTransferProps
> extends React.Component<T> {
tranferRef?: any;
@ -460,7 +465,8 @@ export class BaseTransferRenderer<
statistics,
labelField,
virtualThreshold,
itemHeight
itemHeight,
loadingConfig
} = this.props;
// 目前 LeftOptions 没有接口可以动态加载
@ -517,9 +523,15 @@ export class BaseTransferRenderer<
itemHeight={
toNumber(itemHeight) > 0 ? toNumber(itemHeight) : undefined
}
loadingConfig={loadingConfig}
/>
<Spinner overlay key="info" show={loading} />
<Spinner
overlay
key="info"
loadingConfig={loadingConfig}
show={loading}
/>
</div>
);
}

View File

@ -1,6 +1,6 @@
import {OptionsControlProps, OptionsControl, resolveEventData} from 'amis-core';
import React from 'react';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {BaseTransferRenderer, TransferControlSchema} from './Transfer';
import {TransferPicker} from 'amis-ui';
import {autobind, createObject} from 'amis-core';
@ -12,7 +12,8 @@ import {supportStatic} from './StaticHoc';
* https://baidu.gitee.io/amis/docs/components/form/transfer-picker
*/
export interface TransferPickerControlSchema
extends Omit<TransferControlSchema, 'type'> {
extends Omit<TransferControlSchema, 'type'>,
SpinnerExtraProps {
type: 'transfer-picker';
/**
*
@ -81,7 +82,8 @@ export class TransferPickerRenderer extends BaseTransferRenderer<TabsTransferPro
selectMode,
borderMode,
itemHeight,
virtualThreshold
virtualThreshold,
loadingConfig
} = this.props;
// 目前 LeftOptions 没有接口可以动态加载
@ -131,7 +133,12 @@ export class TransferPickerRenderer extends BaseTransferRenderer<TabsTransferPro
virtualThreshold={virtualThreshold}
/>
<Spinner overlay key="info" show={loading} />
<Spinner
loadingConfig={loadingConfig}
overlay
key="info"
show={loading}
/>
</div>
);
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import {Overlay, resolveEventData} from 'amis-core';
import {PopOver} from 'amis-core';
import {PopUp} from 'amis-ui';
import {PopUp, SpinnerExtraProps} from 'amis-ui';
import {
OptionsControl,
@ -110,7 +110,9 @@ export interface TreeSelectControlSchema extends FormOptionsSchema {
overflowTagPopover?: TooltipWrapperSchema;
}
export interface TreeSelectProps extends OptionsControlProps {
export interface TreeSelectProps
extends OptionsControlProps,
SpinnerExtraProps {
placeholder?: any;
autoComplete?: Api;
hideNodePathLabel?: boolean;
@ -627,7 +629,8 @@ export default class TreeSelectControl extends React.Component<
maxTagCount,
overflowTagPopover,
translate: __,
env
env,
loadingConfig
} = this.props;
const {isOpened} = this.state;
@ -670,7 +673,9 @@ export default class TreeSelectControl extends React.Component<
allowInput={searchable || isEffectiveApi(autoComplete)}
hasDropDownArrow
>
{loading ? <Spinner size="sm" /> : undefined}
{loading ? (
<Spinner loadingConfig={loadingConfig} size="sm" />
) : undefined}
</ResultBox>
{!mobileUI && isOpened ? (
<Overlay

View File

@ -7,7 +7,7 @@ import {
FormOptionsControl,
resolveEventData
} from 'amis-core';
import {UserSelect} from 'amis-ui';
import {SpinnerExtraProps, UserSelect} from 'amis-ui';
import {UserTabSelect} from 'amis-ui';
import {isEffectiveApi} from 'amis-core';
import find from 'lodash/find';
@ -23,7 +23,9 @@ export interface UserSelectControlSchema extends FormOptionsSchema {
type: 'users-select';
}
export interface UserSelectProps extends OptionsControlProps {
export interface UserSelectProps
extends OptionsControlProps,
SpinnerExtraProps {
/**
*
*/
@ -241,7 +243,8 @@ export default class UserSelectControl extends React.Component<
tabMode,
data,
displayFields,
labelField
labelField,
loadingConfig
} = this.props;
tabOptions?.forEach((item: any) => {
item.deferLoad = this.deferLoad;
@ -263,6 +266,7 @@ export default class UserSelectControl extends React.Component<
/>
) : (
<UserSelect
loadingConfig={loadingConfig}
showNav={showNav}
navTitle={navTitle}
selection={selectedOptions}

View File

@ -4,7 +4,7 @@ import pick from 'lodash/pick';
import {BaseSchema, SchemaClassName, SchemaCollection} from '../Schema';
import {ucFirst} from 'amis-core';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
export const ColProps = ['lg', 'md', 'sm', 'xs'];
@ -89,7 +89,8 @@ export interface GridSchema extends BaseSchema {
export interface GridProps
extends RendererProps,
Omit<GridSchema, 'type' | 'className' | 'columnClassName'> {
Omit<GridSchema, 'type' | 'className' | 'columnClassName'>,
SpinnerExtraProps {
itemRender?: (item: any, length: number, props: any) => JSX.Element;
}
@ -191,7 +192,8 @@ export default class Grid<T> extends React.Component<GridProps & T, object> {
gap,
valign: vAlign,
align: hAlign,
loading = false
loading = false,
loadingConfig
} = this.props;
return (
<div
@ -207,7 +209,7 @@ export default class Grid<T> extends React.Component<GridProps & T, object> {
style={style}
>
{this.renderColumns(this.props.columns)}
<Spinner overlay show={loading} />
<Spinner loadingConfig={loadingConfig} overlay show={loading} />
</div>
);
}

View File

@ -2,7 +2,7 @@ import React from 'react';
import {findDOMNode} from 'react-dom';
import Sortable from 'sortablejs';
import omit from 'lodash/omit';
import {Button, Spinner, Checkbox, Icon} from 'amis-ui';
import {Button, Spinner, Checkbox, Icon, SpinnerExtraProps} from 'amis-ui';
import {
ListStore,
IListStore,
@ -233,7 +233,8 @@ export interface Column {
export interface ListProps
extends RendererProps,
Omit<ListSchema, 'type' | 'className'> {
Omit<ListSchema, 'type' | 'className'>,
SpinnerExtraProps {
store: IListStore;
selectable?: boolean;
selected?: Array<any>;
@ -1011,7 +1012,8 @@ export default class List extends React.Component<ListProps, object> {
classnames: cx,
size,
translate: __,
loading = false
loading = false,
loadingConfig
} = this.props;
this.renderedToolbars = [];
@ -1049,7 +1051,7 @@ export default class List extends React.Component<ListProps, object> {
)}
{this.renderFooter()}
<Spinner overlay show={loading} />
<Spinner overlay show={loading} loadingConfig={loadingConfig} />
</div>
);
}

View File

@ -18,7 +18,7 @@ import {
import {generateIcon} from 'amis-core';
import {isEffectiveApi} from 'amis-core';
import {themeable, ThemeProps} from 'amis-core';
import {Icon, getIcon} from 'amis-ui';
import {Icon, getIcon, SpinnerExtraProps} from 'amis-ui';
import {Badge, BadgeObject} from 'amis-ui';
import {RemoteOptionsProps, withRemoteConfig} from 'amis-ui';
import {Spinner} from 'amis-ui';
@ -222,7 +222,8 @@ export interface NavigationState {
export interface NavigationProps
extends ThemeProps,
Omit<NavSchema, 'type' | 'className'> {
Omit<NavSchema, 'type' | 'className'>,
SpinnerExtraProps {
onSelect?: (item: Link) => void | false;
onToggle?: (item: Link, forceFold?: boolean) => void;
onDragUpdate?: (dropInfo: IDropInfo) => void;
@ -636,7 +637,8 @@ export class Navigation extends React.Component<
classnames: cx,
links,
loading,
overflow
overflow,
loadingConfig
} = this.props;
const {dropIndicator} = this.state;
@ -662,7 +664,7 @@ export class Navigation extends React.Component<
? links.map((item, index) => this.renderItem(item, index))
: null}
<Spinner show={!!loading} overlay />
<Spinner show={!!loading} overlay loadingConfig={loadingConfig} />
</ul>
{dropIndicator ? (
<div className={cx('Nav-dropIndicator')} style={dropIndicator} />

View File

@ -20,7 +20,7 @@ import {
createObject
} from 'amis-core';
import {ScopedContext, IScopedContext} from 'amis-core';
import {Alert2 as Alert} from 'amis-ui';
import {Alert2 as Alert, SpinnerExtraProps} from 'amis-ui';
import {isApiOutdated, isEffectiveApi} from 'amis-core';
import {Spinner} from 'amis-ui';
import {
@ -58,7 +58,7 @@ interface CSSRule {
/**
* amis Page https://baidu.gitee.io/amis/docs/components/page
*/
export interface PageSchema extends BaseSchema {
export interface PageSchema extends BaseSchema, SpinnerExtraProps {
/**
* page
*/
@ -797,7 +797,6 @@ export default class Page extends React.Component<PageProps> {
aside,
asideClassName,
classnames: cx,
header,
showErrorMsg,
initApi,
regions,
@ -806,7 +805,8 @@ export default class Page extends React.Component<PageProps> {
asideResizor,
pullRefresh,
useMobileUI,
translate: __
translate: __,
loadingConfig
} = this.props;
const subProps = {
@ -827,8 +827,15 @@ export default class Page extends React.Component<PageProps> {
<div className={cx('Page-content')}>
<div className={cx('Page-main')}>
{this.renderHeader()}
<div className={cx(`Page-body`, bodyClassName)}>
<Spinner size="lg" overlay key="info" show={store.loading} />
{/* role 用于 editor 定位 Spinner */}
<div className={cx(`Page-body`, bodyClassName)} role="page-body">
<Spinner
size="lg"
overlay
key="info"
show={store.loading}
loadingConfig={loadingConfig}
/>
{store.error && showErrorMsg !== false ? (
<Alert

View File

@ -12,7 +12,7 @@ import {
isEffectiveApi,
str2AsyncFunction
} from 'amis-core';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {
autobind,
isObject,
@ -60,7 +60,7 @@ export type ComposedDataProvider = DataProvider | DataProviderCollection;
* Service
* https://baidu.gitee.io/amis/docs/components/service
*/
export interface ServiceSchema extends BaseSchema {
export interface ServiceSchema extends BaseSchema, SpinnerExtraProps {
/**
* Service
*/
@ -727,7 +727,8 @@ export default class Service extends React.Component<ServiceProps> {
store,
render,
classPrefix: ns,
classnames: cx
classnames: cx,
loadingConfig
} = this.props;
return (
@ -747,7 +748,13 @@ export default class Service extends React.Component<ServiceProps> {
{this.renderBody()}
<Spinner size="lg" overlay key="info" show={store.loading} />
<Spinner
size="lg"
overlay
key="info"
show={store.loading}
loadingConfig={loadingConfig}
/>
{render(
// 单独给 feedback 服务的handleAction 里面先不要处理弹窗

View File

@ -1,9 +1,9 @@
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {Renderer, RendererProps} from 'amis-core';
import React from 'react';
import {BaseSchema, SchemaCollection} from '../Schema';
export interface SpinnerSchema extends BaseSchema {
export interface SpinnerSchema extends BaseSchema, SpinnerExtraProps {
/**
*
*/

View File

@ -6,7 +6,7 @@ import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, ActionObject, Schema} from 'amis-core';
import forEach from 'lodash/forEach';
import {evalExpression, filter} from 'amis-core';
import {BadgeObject, Checkbox, Spinner} from 'amis-ui';
import {BadgeObject, Checkbox, Spinner, SpinnerExtraProps} from 'amis-ui';
import {Button} from 'amis-ui';
import {TableStore, ITableStore, padArr} from 'amis-core';
import {
@ -316,7 +316,7 @@ export interface TableSchema extends BaseSchema {
autoFillHeight?: boolean | AutoFillHeightObject;
}
export interface TableProps extends RendererProps {
export interface TableProps extends RendererProps, SpinnerExtraProps {
title?: string; // 标题
header?: SchemaNode;
footer?: SchemaNode;
@ -2819,7 +2819,8 @@ export default class Table extends React.Component<TableProps, object> {
itemActions,
dispatchEvent,
onEvent,
loading = false
loading = false,
loadingConfig
} = this.props;
// 理论上来说 store.rows 应该也行啊
@ -2878,7 +2879,7 @@ export default class Table extends React.Component<TableProps, object> {
loading={loading}
/>
<Spinner overlay show={loading} />
<Spinner loadingConfig={loadingConfig} overlay show={loading} />
</>
);
}

View File

@ -26,7 +26,7 @@ import {
IRow2,
ClassNamesFn
} from 'amis-core';
import {Icon, Table, Spinner, BadgeObject} from 'amis-ui';
import {Icon, Table, Spinner, BadgeObject, SpinnerExtraProps} from 'amis-ui';
import type {
SortProps,
ColumnProps,
@ -382,7 +382,7 @@ export type Table2RendererAction =
| 'select'
| 'expand';
export interface Table2Props extends RendererProps {
export interface Table2Props extends RendererProps, SpinnerExtraProps {
title?: string;
columns: Array<ColumnSchema | ColumnProps>;
onSelect?: Function;
@ -1498,7 +1498,7 @@ export default class Table2 extends React.Component<Table2Props, object> {
}
render() {
const {classnames: cx, style, loading = false} = this.props;
const {classnames: cx, style, loading = false, loadingConfig} = this.props;
this.renderedToolbars = []; // 用来记录哪些 toolbar 已经渲染了
@ -1510,7 +1510,7 @@ export default class Table2 extends React.Component<Table2Props, object> {
{heading}
{this.renderTable()}
<Spinner overlay show={loading} />
<Spinner overlay show={loading} loadingConfig={loadingConfig} />
</div>
);
}

View File

@ -7,7 +7,7 @@ import {Api, ApiObject, Payload} from 'amis-core';
import update from 'immutability-helper';
import {isEffectiveApi, isApiOutdated} from 'amis-core';
import {ScopedContext, IScopedContext} from 'amis-core';
import {Spinner} from 'amis-ui';
import {Spinner, SpinnerExtraProps} from 'amis-ui';
import {BaseSchema, SchemaApi, SchemaClassName, SchemaName} from '../Schema';
import {createObject} from 'amis-core';
@ -15,7 +15,7 @@ import {createObject} from 'amis-core';
* Tasks
* https://baidu.gitee.io/amis/docs/components/tasks
*/
export interface TasksSchema extends BaseSchema {
export interface TasksSchema extends BaseSchema, SpinnerExtraProps {
/** 指定为任务类型 */
type: 'tasks';
@ -369,7 +369,8 @@ export default class Task extends React.Component<TaskProps, TaskState> {
loadingStatusCode,
canRetryStatusCode,
translate: __,
render
render,
loadingConfig
} = this.props;
const items = this.state.items;
const error = this.state.error;
@ -399,6 +400,7 @@ export default class Task extends React.Component<TaskProps, TaskState> {
<td>
{item.status == loadingStatusCode ? (
<Spinner
loadingConfig={loadingConfig}
show
icon="reload"
spinnerClassName={cx('Task-spinner')}

Some files were not shown because too many files have changed in this diff Show More