refactor: list (#4242)
parent
31ed5c68d1
commit
22141e74de
|
@ -1,5 +1,5 @@
|
|||
import { RequiredMark } from '../../form/Form';
|
||||
import { computed, ComputedRef, inject, UnwrapRef } from 'vue';
|
||||
import { computed, ComputedRef, inject, UnwrapRef, VNodeChild } from 'vue';
|
||||
import {
|
||||
ConfigProviderProps,
|
||||
defaultConfigProvider,
|
||||
|
@ -21,6 +21,7 @@ export default (
|
|||
form?: ComputedRef<{
|
||||
requiredMark?: RequiredMark;
|
||||
}>;
|
||||
renderEmpty?: ComputedRef<(componentName?: string) => VNodeChild | JSX.Element>;
|
||||
} => {
|
||||
const configProvider = inject<UnwrapRef<ConfigProviderProps>>(
|
||||
'configProvider',
|
||||
|
@ -28,6 +29,7 @@ export default (
|
|||
);
|
||||
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
|
||||
const direction = computed(() => configProvider.direction);
|
||||
const renderEmpty = computed(() => configProvider.renderEmpty);
|
||||
const space = computed(() => configProvider.space);
|
||||
const pageHeader = computed(() => configProvider.pageHeader);
|
||||
const form = computed(() => configProvider.form);
|
||||
|
@ -42,5 +44,6 @@ export default (
|
|||
space,
|
||||
pageHeader,
|
||||
form,
|
||||
renderEmpty,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,80 +1,36 @@
|
|||
import PropTypes from '../_util/vue-types';
|
||||
import classNames from '../_util/classNames';
|
||||
import { getComponent, isStringElement, isEmptyElement, getSlot } from '../_util/props-util';
|
||||
import { isStringElement, isEmptyElement, flattenChildren } from '../_util/props-util';
|
||||
import { Col } from '../grid';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import { defineComponent, ExtractPropTypes, FunctionalComponent, inject } from 'vue';
|
||||
import { defineComponent, inject, ref } from 'vue';
|
||||
import ItemMeta from './ItemMeta';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import { ListContextKey } from '.';
|
||||
|
||||
export const ListItemProps = {
|
||||
prefixCls: PropTypes.string,
|
||||
extra: PropTypes.any,
|
||||
actions: PropTypes.array,
|
||||
grid: PropTypes.any,
|
||||
colStyle: PropTypes.style,
|
||||
};
|
||||
|
||||
export const ListItemMetaProps = {
|
||||
avatar: PropTypes.any,
|
||||
description: PropTypes.any,
|
||||
prefixCls: PropTypes.string,
|
||||
title: PropTypes.any,
|
||||
};
|
||||
|
||||
export const ListItemMeta: FunctionalComponent<Partial<
|
||||
ExtractPropTypes<typeof ListItemMetaProps>
|
||||
>> = (props, { slots }) => {
|
||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||
const { getPrefixCls } = configProvider;
|
||||
const { prefixCls: customizePrefixCls } = props;
|
||||
const prefixCls = getPrefixCls('list', customizePrefixCls);
|
||||
const avatar = props.avatar || slots.avatar?.();
|
||||
const title = props.title || slots.title?.();
|
||||
const description = props.description || slots.description?.();
|
||||
const content = (
|
||||
<div class={`${prefixCls}-item-meta-content`}>
|
||||
{title && <h4 class={`${prefixCls}-item-meta-title`}>{title}</h4>}
|
||||
{description && <div class={`${prefixCls}-item-meta-description`}>{description}</div>}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div class={`${prefixCls}-item-meta`}>
|
||||
{avatar && <div class={`${prefixCls}-item-meta-avatar`}>{avatar}</div>}
|
||||
{(title || description) && content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Object.assign(ListItemMeta, {
|
||||
props: ListItemMetaProps,
|
||||
__ANT_LIST_ITEM_META: true,
|
||||
displayName: 'AListItemMeta',
|
||||
});
|
||||
|
||||
function getGrid(grid, t) {
|
||||
return grid[t] && Math.floor(24 / grid[t]);
|
||||
}
|
||||
|
||||
export interface ListContext {
|
||||
grid?: any;
|
||||
itemLayout?: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AListItem',
|
||||
inheritAttrs: false,
|
||||
Meta: ListItemMeta,
|
||||
Meta: ItemMeta,
|
||||
props: ListItemProps,
|
||||
setup() {
|
||||
const listContext = inject<ListContext>('listContext', {});
|
||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||
return {
|
||||
listContext,
|
||||
configProvider,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isItemContainsTextNodeAndNotSingular() {
|
||||
const children = getSlot(this) || [];
|
||||
slots: ['actions', 'extra'],
|
||||
setup(props, { slots, attrs }) {
|
||||
const { itemLayout, grid } = inject(ListContextKey, {
|
||||
grid: ref(),
|
||||
itemLayout: ref(),
|
||||
});
|
||||
const { prefixCls } = useConfigInject('list', props);
|
||||
|
||||
const isItemContainsTextNodeAndNotSingular = () => {
|
||||
const children = slots.default?.() || [];
|
||||
let result;
|
||||
children.forEach(element => {
|
||||
if (isStringElement(element) && !isEmptyElement(element)) {
|
||||
|
@ -82,75 +38,65 @@ export default defineComponent({
|
|||
}
|
||||
});
|
||||
return result && children.length > 1;
|
||||
},
|
||||
};
|
||||
|
||||
isFlexMode() {
|
||||
const extra = getComponent(this, 'extra');
|
||||
const { itemLayout } = this.listContext;
|
||||
if (itemLayout === 'vertical') {
|
||||
const isFlexMode = () => {
|
||||
const extra = props.extra ?? slots.extra?.();
|
||||
if (itemLayout.value === 'vertical') {
|
||||
return !!extra;
|
||||
}
|
||||
return !this.isItemContainsTextNodeAndNotSingular();
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const { grid, itemLayout } = this.listContext;
|
||||
const { prefixCls: customizePrefixCls, $attrs } = this;
|
||||
const { class: _className, ...restAttrs } = $attrs;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('list', customizePrefixCls);
|
||||
const extra = getComponent(this, 'extra');
|
||||
let actions = getComponent(this, 'actions');
|
||||
actions = actions && !Array.isArray(actions) ? [actions] : actions;
|
||||
const actionsContent = actions && actions.length > 0 && (
|
||||
<ul class={`${prefixCls}-item-action`} key="actions">
|
||||
{actions.map((action, i) => (
|
||||
<li key={`${prefixCls}-item-action-${i}`}>
|
||||
{action}
|
||||
{i !== actions.length - 1 && <em class={`${prefixCls}-item-action-split`} />}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
const children = getSlot(this);
|
||||
const Tag = grid ? 'div' : 'li';
|
||||
const itemChildren = (
|
||||
<Tag
|
||||
{...restAttrs}
|
||||
class={classNames(`${prefixCls}-item`, _className, {
|
||||
[`${prefixCls}-item-no-flex`]: !this.isFlexMode(),
|
||||
})}
|
||||
>
|
||||
{itemLayout === 'vertical' && extra
|
||||
? [
|
||||
<div class={`${prefixCls}-item-main`} key="content">
|
||||
{children}
|
||||
{actionsContent}
|
||||
</div>,
|
||||
<div class={`${prefixCls}-item-extra`} key="extra">
|
||||
{extra}
|
||||
</div>,
|
||||
]
|
||||
: [children, actionsContent, cloneElement(extra, { key: 'extra' })]}
|
||||
</Tag>
|
||||
);
|
||||
return !isItemContainsTextNodeAndNotSingular();
|
||||
};
|
||||
|
||||
const mainContent = grid ? (
|
||||
<Col
|
||||
span={getGrid(grid, 'column')}
|
||||
xs={getGrid(grid, 'xs')}
|
||||
sm={getGrid(grid, 'sm')}
|
||||
md={getGrid(grid, 'md')}
|
||||
lg={getGrid(grid, 'lg')}
|
||||
xl={getGrid(grid, 'xl')}
|
||||
xxl={getGrid(grid, 'xxl')}
|
||||
>
|
||||
{itemChildren}
|
||||
</Col>
|
||||
) : (
|
||||
itemChildren
|
||||
);
|
||||
|
||||
return mainContent;
|
||||
return () => {
|
||||
const { class: className, ...restAttrs } = attrs;
|
||||
const pre = prefixCls.value;
|
||||
const extra = props.extra ?? slots.extra?.();
|
||||
const children = slots.default?.();
|
||||
let actions = props.actions ?? flattenChildren(slots.actions?.());
|
||||
actions = actions && !Array.isArray(actions) ? [actions] : actions;
|
||||
const actionsContent = actions && actions.length > 0 && (
|
||||
<ul class={`${pre}-item-action`} key="actions">
|
||||
{actions.map((action, i) => (
|
||||
<li key={`${pre}-item-action-${i}`}>
|
||||
{action}
|
||||
{i !== actions.length - 1 && <em class={`${pre}-item-action-split`} />}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
const Element = grid.value ? 'div' : 'li';
|
||||
const itemChildren = (
|
||||
<Element
|
||||
{...(restAttrs as any)} // `li` element `onCopy` prop args is not same as `div`
|
||||
class={classNames(
|
||||
`${pre}-item`,
|
||||
{
|
||||
[`${pre}-item-no-flex`]: !isFlexMode(),
|
||||
},
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{itemLayout.value === 'vertical' && extra
|
||||
? [
|
||||
<div class={`${pre}-item-main`} key="content">
|
||||
{children}
|
||||
{actionsContent}
|
||||
</div>,
|
||||
<div class={`${pre}-item-extra`} key="extra">
|
||||
{extra}
|
||||
</div>,
|
||||
]
|
||||
: [children, actionsContent, cloneElement(extra, { key: 'extra' })]}
|
||||
</Element>
|
||||
);
|
||||
return grid.value ? (
|
||||
<Col flex={1} style={props.colStyle}>
|
||||
{itemChildren}
|
||||
</Col>
|
||||
) : (
|
||||
itemChildren
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import { defineComponent, ExtractPropTypes } from 'vue';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
|
||||
export const listItemMetaProps = {
|
||||
avatar: PropTypes.any,
|
||||
description: PropTypes.any,
|
||||
prefixCls: PropTypes.string,
|
||||
title: PropTypes.any,
|
||||
};
|
||||
|
||||
export type ListItemMetaProps = Partial<ExtractPropTypes<typeof listItemMetaProps>>;
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AListItemMeta',
|
||||
props: listItemMetaProps,
|
||||
displayName: 'AListItemMeta', // 兼容历史函数式组件
|
||||
__ANT_LIST_ITEM_META: true,
|
||||
slots: ['avatar', 'description', 'title'],
|
||||
setup(props, { slots }) {
|
||||
const { prefixCls } = useConfigInject('list', props);
|
||||
return () => {
|
||||
const classString = `${prefixCls.value}-item-meta`;
|
||||
const title = props.title ?? slots.title?.();
|
||||
const description = props.description ?? slots.description?.();
|
||||
const avatar = props.avatar ?? slots.avatar?.();
|
||||
const content = (
|
||||
<div class={`${prefixCls.value}-item-meta-content`}>
|
||||
{title && <h4 class={`${prefixCls.value}-item-meta-title`}>{title}</h4>}
|
||||
{description && (
|
||||
<div class={`${prefixCls.value}-item-meta-description`}>{description}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div class={classString}>
|
||||
{avatar && <div class={`${prefixCls.value}-item-meta-avatar`}>{avatar}</div>}
|
||||
{(title || description) && content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
|
@ -1,51 +1,65 @@
|
|||
import { provide, inject, defineComponent, App, Plugin, ExtractPropTypes } from 'vue';
|
||||
import omit from 'omit.js';
|
||||
import {
|
||||
provide,
|
||||
defineComponent,
|
||||
App,
|
||||
Plugin,
|
||||
ExtractPropTypes,
|
||||
PropType,
|
||||
ref,
|
||||
watch,
|
||||
computed,
|
||||
InjectionKey,
|
||||
toRef,
|
||||
Ref,
|
||||
} from 'vue';
|
||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import classNames from '../_util/classNames';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { RenderEmptyHandler } from '../config-provider';
|
||||
|
||||
import Spin from '../spin';
|
||||
import Pagination, { PaginationConfig } from '../pagination';
|
||||
import Pagination, { PaginationConfig, paginationConfig } from '../pagination';
|
||||
import { Row } from '../grid';
|
||||
|
||||
import Item, { ListItemMeta } from './Item';
|
||||
import { getComponent, getSlot } from '../_util/props-util';
|
||||
import Item from './Item';
|
||||
import { flattenChildren } from '../_util/props-util';
|
||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import { tuple } from '../_util/type';
|
||||
import ItemMeta from './ItemMeta';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import useBreakpoint from '../_util/hooks/useBreakpoint';
|
||||
import { Breakpoint, responsiveArray } from '../_util/responsiveObserve';
|
||||
|
||||
export { ListItemProps, ListItemMetaProps, ListItemMeta } from './Item';
|
||||
export { ListItemProps } from './Item';
|
||||
export { ListItemMetaProps } from './ItemMeta';
|
||||
export const ListItemMeta = ItemMeta;
|
||||
|
||||
export const ColumnCount = ['', 1, 2, 3, 4, 6, 8, 12, 24];
|
||||
|
||||
export const ColumnType = ['gutter', 'column', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'];
|
||||
export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
|
||||
|
||||
export const ListGridType = {
|
||||
gutter: PropTypes.number,
|
||||
column: PropTypes.oneOf(ColumnCount),
|
||||
xs: PropTypes.oneOf(ColumnCount),
|
||||
sm: PropTypes.oneOf(ColumnCount),
|
||||
md: PropTypes.oneOf(ColumnCount),
|
||||
lg: PropTypes.oneOf(ColumnCount),
|
||||
xl: PropTypes.oneOf(ColumnCount),
|
||||
xxl: PropTypes.oneOf(ColumnCount),
|
||||
column: PropTypes.number,
|
||||
xs: PropTypes.number,
|
||||
sm: PropTypes.number,
|
||||
md: PropTypes.number,
|
||||
lg: PropTypes.number,
|
||||
xl: PropTypes.number,
|
||||
xxl: PropTypes.number,
|
||||
};
|
||||
|
||||
export const ListSize = tuple('small', 'default', 'large');
|
||||
|
||||
const paginationProps = PaginationConfig();
|
||||
export type ListItemLayout = 'horizontal' | 'vertical';
|
||||
|
||||
export const ListProps = () => ({
|
||||
export const listProps = {
|
||||
bordered: PropTypes.looseBool,
|
||||
dataSource: PropTypes.array,
|
||||
extra: PropTypes.any,
|
||||
grid: PropTypes.shape(ListGridType).loose,
|
||||
itemLayout: PropTypes.string,
|
||||
itemLayout: PropTypes.oneOf(tuple('horizontal', 'vertical')),
|
||||
loading: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object])),
|
||||
loadMore: PropTypes.any,
|
||||
pagination: withUndefined(
|
||||
PropTypes.oneOfType([
|
||||
PropTypes.shape<Partial<ExtractPropTypes<typeof paginationProps>>>(paginationProps).loose,
|
||||
PropTypes.shape<PaginationConfig>(paginationConfig()).loose,
|
||||
PropTypes.looseBool,
|
||||
]),
|
||||
),
|
||||
|
@ -56,79 +70,186 @@ export const ListProps = () => ({
|
|||
split: PropTypes.looseBool,
|
||||
header: PropTypes.any,
|
||||
footer: PropTypes.any,
|
||||
locale: PropTypes.object,
|
||||
});
|
||||
locale: {
|
||||
type: Object as PropType<ListLocale>,
|
||||
},
|
||||
};
|
||||
|
||||
export interface ListLocale {
|
||||
emptyText: any;
|
||||
}
|
||||
|
||||
export type ListProps = Partial<ExtractPropTypes<typeof listProps>>;
|
||||
|
||||
export interface ListContext {
|
||||
grid?: Ref<any>;
|
||||
itemLayout?: Ref<string>;
|
||||
}
|
||||
|
||||
export const ListContextKey: InjectionKey<ListContext> = Symbol('ListContextKey');
|
||||
|
||||
const List = defineComponent({
|
||||
name: 'AList',
|
||||
inheritAttrs: false,
|
||||
Item,
|
||||
props: initDefaultProps(ListProps(), {
|
||||
props: initDefaultProps(listProps, {
|
||||
dataSource: [],
|
||||
bordered: false,
|
||||
split: true,
|
||||
loading: false,
|
||||
pagination: false,
|
||||
}),
|
||||
setup() {
|
||||
return {
|
||||
keys: [],
|
||||
defaultPaginationProps: {},
|
||||
onPaginationChange: null,
|
||||
onPaginationShowSizeChange: null,
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
};
|
||||
},
|
||||
|
||||
data() {
|
||||
const { pagination } = this.$props;
|
||||
const paginationObj: Partial<typeof pagination> =
|
||||
pagination && typeof pagination === 'object' ? pagination : {};
|
||||
return {
|
||||
paginationCurrent: paginationObj.defaultCurrent || 1,
|
||||
paginationSize: paginationObj.defaultPageSize || 10,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
provide('listContext', this);
|
||||
this.defaultPaginationProps = {
|
||||
slots: ['extra', 'loadMore', 'renderItem', 'header', 'footer'],
|
||||
setup(props, { slots }) {
|
||||
provide(ListContextKey, {
|
||||
grid: toRef(props, 'grid'),
|
||||
itemLayout: toRef(props, 'itemLayout'),
|
||||
});
|
||||
const defaultPaginationProps = {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
onChange: (page: number, pageSize: number) => {
|
||||
const { pagination } = this;
|
||||
this.paginationCurrent = page;
|
||||
if (pagination && (pagination as any).onChange) {
|
||||
(pagination as any).onChange(page, pageSize);
|
||||
}
|
||||
},
|
||||
total: 0,
|
||||
};
|
||||
this.onPaginationChange = this.triggerPaginationEvent('onChange');
|
||||
this.onPaginationShowSizeChange = this.triggerPaginationEvent('onShowSizeChange');
|
||||
},
|
||||
methods: {
|
||||
triggerPaginationEvent(eventName) {
|
||||
return (page, pageSize) => {
|
||||
const { pagination } = this.$props;
|
||||
this.paginationCurrent = page;
|
||||
this.paginationSize = pageSize;
|
||||
if (pagination && pagination[eventName]) {
|
||||
pagination[eventName](page, pageSize);
|
||||
}
|
||||
const { prefixCls, direction, renderEmpty } = useConfigInject('list', props);
|
||||
const paginationObj = computed(() =>
|
||||
props.pagination && typeof props.pagination === 'object' ? props.pagination : {},
|
||||
);
|
||||
const paginationCurrent = ref(paginationObj.value.defaultCurrent ?? 1);
|
||||
const paginationSize = ref(paginationObj.value.defaultPageSize ?? 10);
|
||||
watch(paginationObj, () => {
|
||||
if ('current' in paginationObj.value) {
|
||||
paginationCurrent.value = paginationObj.value.current;
|
||||
}
|
||||
if ('pageSize' in paginationObj.value) {
|
||||
paginationSize.value = paginationObj.value.pageSize;
|
||||
}
|
||||
});
|
||||
|
||||
const triggerPaginationEvent = (eventName: string) => (page: number, pageSize: number) => {
|
||||
paginationCurrent.value = page;
|
||||
paginationSize.value = pageSize;
|
||||
if (paginationObj.value[eventName]) {
|
||||
paginationObj.value[eventName](page, pageSize);
|
||||
}
|
||||
};
|
||||
|
||||
const onPaginationChange = triggerPaginationEvent('onChange');
|
||||
|
||||
const onPaginationShowSizeChange = triggerPaginationEvent('onShowSizeChange');
|
||||
|
||||
const renderEmptyFunc = (renderEmptyHandler: RenderEmptyHandler) => (
|
||||
<div class={`${prefixCls.value}-empty-text`}>
|
||||
{props.locale?.emptyText || renderEmptyHandler('List')}
|
||||
</div>
|
||||
);
|
||||
|
||||
const loadingProp = computed(() => {
|
||||
if (typeof props.loading === 'boolean') {
|
||||
return {
|
||||
spinning: props.loading,
|
||||
};
|
||||
} else {
|
||||
return props.loading;
|
||||
}
|
||||
});
|
||||
|
||||
const isLoading = computed(() => loadingProp.value && loadingProp.value.spinning);
|
||||
|
||||
const sizeCls = computed(() => {
|
||||
let size = '';
|
||||
switch (props.size) {
|
||||
case 'large':
|
||||
size = 'lg';
|
||||
break;
|
||||
case 'small':
|
||||
size = 'sm';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
});
|
||||
|
||||
const classObj = computed(() => ({
|
||||
[`${prefixCls.value}`]: true,
|
||||
[`${prefixCls.value}-vertical`]: props.itemLayout === 'vertical',
|
||||
[`${prefixCls.value}-${sizeCls.value}`]: sizeCls.value,
|
||||
[`${prefixCls.value}-split`]: props.split,
|
||||
[`${prefixCls.value}-bordered`]: props.bordered,
|
||||
[`${prefixCls.value}-loading`]: isLoading.value,
|
||||
[`${prefixCls.value}-grid`]: !!props.grid,
|
||||
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
|
||||
}));
|
||||
|
||||
const paginationProps = computed(() => {
|
||||
const pp = {
|
||||
...defaultPaginationProps,
|
||||
total: props.dataSource.length,
|
||||
current: paginationCurrent.value,
|
||||
pageSize: paginationSize.value,
|
||||
...((props.pagination as PaginationConfig) || {}),
|
||||
};
|
||||
},
|
||||
innerRenderItem(item, index) {
|
||||
const {
|
||||
$slots: { renderItem },
|
||||
rowKey,
|
||||
} = this;
|
||||
const renderer = this.renderItem || renderItem;
|
||||
if (!renderer) return null;
|
||||
|
||||
const largestPage = Math.ceil(pp.total / pp.pageSize);
|
||||
if (pp.current > largestPage) {
|
||||
pp.current = largestPage;
|
||||
}
|
||||
return pp;
|
||||
});
|
||||
|
||||
const splitDataSource = computed(() => {
|
||||
let dd = [...props.dataSource];
|
||||
if (props.pagination) {
|
||||
if (
|
||||
props.dataSource.length >
|
||||
(paginationProps.value.current - 1) * paginationProps.value.pageSize
|
||||
) {
|
||||
dd = [...props.dataSource].splice(
|
||||
(paginationProps.value.current - 1) * paginationProps.value.pageSize,
|
||||
paginationProps.value.pageSize,
|
||||
);
|
||||
}
|
||||
}
|
||||
return dd;
|
||||
});
|
||||
|
||||
const screens = useBreakpoint();
|
||||
|
||||
const currentBreakpoint = computed(() => {
|
||||
for (let i = 0; i < responsiveArray.length; i += 1) {
|
||||
const breakpoint: Breakpoint = responsiveArray[i];
|
||||
if (screens.value[breakpoint]) {
|
||||
return breakpoint;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const colStyle = computed(() => {
|
||||
if (!props.grid) {
|
||||
return undefined;
|
||||
}
|
||||
const columnCount =
|
||||
currentBreakpoint.value && props.grid[currentBreakpoint.value]
|
||||
? props.grid[currentBreakpoint.value]
|
||||
: props.grid.column;
|
||||
if (columnCount) {
|
||||
return {
|
||||
width: `${100 / columnCount}%`,
|
||||
maxWidth: `${100 / columnCount}%`,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const renderInnerItem = (keys: number[], item: any, index: number) => {
|
||||
const renderItem = props.renderItem ?? slots.renderItem;
|
||||
if (!renderItem) return null;
|
||||
|
||||
let key;
|
||||
if (typeof rowKey === 'function') {
|
||||
key = rowKey(item);
|
||||
} else if (typeof rowKey === 'string') {
|
||||
key = item[rowKey];
|
||||
|
||||
if (typeof props.rowKey === 'function') {
|
||||
key = props.rowKey(item);
|
||||
} else if (typeof props.rowKey === 'string') {
|
||||
key = item[props.rowKey];
|
||||
} else {
|
||||
key = item.key;
|
||||
}
|
||||
|
@ -137,155 +258,67 @@ const List = defineComponent({
|
|||
key = `list-item-${index}`;
|
||||
}
|
||||
|
||||
this.keys[index] = key;
|
||||
keys[index] = key;
|
||||
|
||||
return renderer({ item, index });
|
||||
},
|
||||
return renderItem({ item, index });
|
||||
};
|
||||
|
||||
isSomethingAfterLastItem() {
|
||||
const { pagination } = this;
|
||||
const loadMore = getComponent(this, 'loadMore');
|
||||
const footer = getComponent(this, 'footer');
|
||||
return !!(loadMore || pagination || footer);
|
||||
},
|
||||
return () => {
|
||||
const loadMore = props.loadMore ?? slots.loadMore?.();
|
||||
const footer = props.footer ?? slots.footer?.();
|
||||
const header = props.header ?? slots.header?.();
|
||||
const children = flattenChildren(slots.default?.());
|
||||
const keys = [];
|
||||
const isSomethingAfterLastItem = !!(loadMore || props.pagination || footer);
|
||||
const classString = {
|
||||
...classObj.value,
|
||||
[`${prefixCls.value}-something-after-last-item`]: isSomethingAfterLastItem,
|
||||
};
|
||||
const paginationContent = props.pagination ? (
|
||||
<div class={`${prefixCls.value}-pagination`}>
|
||||
<Pagination
|
||||
{...paginationProps.value}
|
||||
onChange={onPaginationChange}
|
||||
onShowSizeChange={onPaginationShowSizeChange}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
renderEmpty(prefixCls, renderEmpty) {
|
||||
const { locale } = this;
|
||||
let childrenContent = isLoading.value && <div style={{ minHeight: '53px' }} />;
|
||||
if (splitDataSource.value.length > 0) {
|
||||
const items = splitDataSource.value.map((item: any, index: number) =>
|
||||
renderInnerItem(keys, item, index),
|
||||
);
|
||||
const childrenList = items.map((child: any, index) => (
|
||||
<div key={keys[index]} style={colStyle.value}>
|
||||
{child}
|
||||
</div>
|
||||
));
|
||||
childrenContent = props.grid ? (
|
||||
<Row gutter={props.grid.gutter}>{childrenList}</Row>
|
||||
) : (
|
||||
<ul class={`${prefixCls.value}-items`}>{items}</ul>
|
||||
);
|
||||
} else if (!children.length && !isLoading.value) {
|
||||
childrenContent = renderEmptyFunc(renderEmpty.value);
|
||||
}
|
||||
|
||||
const paginationPosition = paginationProps.value.position || 'bottom';
|
||||
return (
|
||||
<div class={`${prefixCls}-empty-text`}>
|
||||
{(locale && locale.emptyText) || renderEmpty('List')}
|
||||
<div class={classString}>
|
||||
{(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent}
|
||||
{header && <div class={`${prefixCls.value}-header`}>{header}</div>}
|
||||
<Spin {...loadingProp.value}>
|
||||
{childrenContent}
|
||||
{children}
|
||||
</Spin>
|
||||
{footer && <div class={`${prefixCls.value}-footer`}>{footer}</div>}
|
||||
{loadMore ||
|
||||
((paginationPosition === 'bottom' || paginationPosition === 'both') &&
|
||||
paginationContent)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
bordered,
|
||||
split,
|
||||
itemLayout,
|
||||
pagination,
|
||||
grid,
|
||||
dataSource = [],
|
||||
size,
|
||||
loading,
|
||||
paginationCurrent,
|
||||
paginationSize,
|
||||
$attrs,
|
||||
} = this;
|
||||
const { getPrefixCls } = this.configProvider;
|
||||
const prefixCls = getPrefixCls('list', customizePrefixCls);
|
||||
const { class: className, ...restAttrs } = $attrs;
|
||||
const loadMore = getComponent(this, 'loadMore');
|
||||
const footer = getComponent(this, 'footer');
|
||||
const header = getComponent(this, 'header');
|
||||
const children = getSlot(this);
|
||||
let loadingProp = loading;
|
||||
if (typeof loadingProp === 'boolean') {
|
||||
loadingProp = {
|
||||
spinning: loadingProp,
|
||||
};
|
||||
}
|
||||
const isLoading = loadingProp && loadingProp.spinning;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
let sizeCls = '';
|
||||
switch (size) {
|
||||
case 'large':
|
||||
sizeCls = 'lg';
|
||||
break;
|
||||
case 'small':
|
||||
sizeCls = 'sm';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const classString = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-vertical`]: itemLayout === 'vertical',
|
||||
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
||||
[`${prefixCls}-split`]: split,
|
||||
[`${prefixCls}-bordered`]: bordered,
|
||||
[`${prefixCls}-loading`]: isLoading,
|
||||
[`${prefixCls}-grid`]: grid,
|
||||
[`${prefixCls}-something-after-last-item`]: this.isSomethingAfterLastItem(),
|
||||
},
|
||||
className,
|
||||
);
|
||||
const paginationProps = {
|
||||
...this.defaultPaginationProps,
|
||||
total: dataSource.length,
|
||||
current: paginationCurrent,
|
||||
pageSize: paginationSize,
|
||||
...((pagination as any) || {}),
|
||||
};
|
||||
classString;
|
||||
const largestPage = Math.ceil(paginationProps.total / paginationProps.pageSize);
|
||||
if (paginationProps.current > largestPage) {
|
||||
paginationProps.current = largestPage;
|
||||
}
|
||||
const { class: cls, style, ...restProps } = paginationProps;
|
||||
const paginationContent = pagination ? (
|
||||
<div class={`${prefixCls}-pagination`}>
|
||||
<Pagination
|
||||
{...{
|
||||
...omit(restProps, ['onChange']),
|
||||
class: cls,
|
||||
style,
|
||||
onChange: this.onPaginationChange,
|
||||
onShowSizeChange: this.onPaginationShowSizeChange,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
let splitDataSource = [...dataSource];
|
||||
if (pagination) {
|
||||
if (dataSource.length > (paginationProps.current - 1) * paginationProps.pageSize) {
|
||||
splitDataSource = [...dataSource].splice(
|
||||
(paginationProps.current - 1) * paginationProps.pageSize,
|
||||
paginationProps.pageSize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let childrenContent;
|
||||
childrenContent = isLoading && <div style={{ minHeight: 53 }} />;
|
||||
if (splitDataSource.length > 0) {
|
||||
const items = splitDataSource.map((item, index) => this.innerRenderItem(item, index));
|
||||
const childrenList = items.map((child, index) =>
|
||||
cloneElement(child, {
|
||||
key: this.keys[index],
|
||||
}),
|
||||
);
|
||||
|
||||
childrenContent = grid ? (
|
||||
<Row gutter={grid.gutter}>{childrenList}</Row>
|
||||
) : (
|
||||
<ul class={`${prefixCls}-items`}>{childrenList}</ul>
|
||||
);
|
||||
} else if (!children.length && !isLoading) {
|
||||
const renderEmpty = this.configProvider.renderEmpty;
|
||||
childrenContent = this.renderEmpty(prefixCls, renderEmpty);
|
||||
}
|
||||
const paginationPosition = paginationProps.position || 'bottom';
|
||||
|
||||
return (
|
||||
<div class={classString} {...restAttrs}>
|
||||
{(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent}
|
||||
{header && <div class={`${prefixCls}-header`}>{header}</div>}
|
||||
<Spin {...loadingProp}>
|
||||
{childrenContent}
|
||||
{children}
|
||||
</Spin>
|
||||
{footer && <div class={`${prefixCls}-footer`}>{footer}</div>}
|
||||
{loadMore ||
|
||||
((paginationPosition === 'bottom' || paginationPosition === 'both') && paginationContent)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -293,13 +326,13 @@ const List = defineComponent({
|
|||
List.install = function(app: App) {
|
||||
app.component(List.name, List);
|
||||
app.component(List.Item.name, List.Item);
|
||||
app.component(List.Item.Meta.displayName, List.Item.Meta);
|
||||
app.component(List.Item.Meta.name, List.Item.Meta);
|
||||
return app;
|
||||
};
|
||||
|
||||
export default List as typeof List &
|
||||
Plugin & {
|
||||
readonly Item: typeof Item & {
|
||||
readonly Meta: typeof ListItemMeta;
|
||||
readonly Meta: typeof ItemMeta;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,41 +1,44 @@
|
|||
@import '../../style/themes/index';
|
||||
|
||||
.@{list-prefix-cls}-bordered {
|
||||
border: 1px solid @border-color-base;
|
||||
border-radius: @border-radius-base;
|
||||
.@{list-prefix-cls}-header {
|
||||
padding-right: 24px;
|
||||
padding-left: 24px;
|
||||
padding-right: @padding-lg;
|
||||
padding-left: @padding-lg;
|
||||
}
|
||||
|
||||
.@{list-prefix-cls}-footer {
|
||||
padding-right: 24px;
|
||||
padding-left: 24px;
|
||||
padding-right: @padding-lg;
|
||||
padding-left: @padding-lg;
|
||||
}
|
||||
|
||||
.@{list-prefix-cls}-item {
|
||||
padding-right: 24px;
|
||||
padding-left: 24px;
|
||||
border-bottom: 1px solid @border-color-split;
|
||||
padding-right: @padding-lg;
|
||||
padding-left: @padding-lg;
|
||||
}
|
||||
|
||||
.@{list-prefix-cls}-pagination {
|
||||
margin: 16px 24px;
|
||||
margin: @margin-md @margin-lg;
|
||||
}
|
||||
|
||||
&.@{list-prefix-cls}-sm {
|
||||
.@{list-prefix-cls}-item {
|
||||
padding-right: 16px;
|
||||
padding-left: 16px;
|
||||
padding: @list-item-padding-sm;
|
||||
}
|
||||
.@{list-prefix-cls}-header,
|
||||
.@{list-prefix-cls}-footer {
|
||||
padding: 8px 16px;
|
||||
padding: @list-item-padding-sm;
|
||||
}
|
||||
}
|
||||
|
||||
&.@{list-prefix-cls}-lg {
|
||||
.@{list-prefix-cls}-item {
|
||||
padding: @list-item-padding-lg;
|
||||
}
|
||||
.@{list-prefix-cls}-header,
|
||||
.@{list-prefix-cls}-footer {
|
||||
padding: 16px 24px;
|
||||
padding: @list-item-padding-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
@import './index.less';
|
||||
|
||||
@card-prefix-cls: ~'@{ant-prefix}-card';
|
||||
|
||||
.@{list-prefix-cls} {
|
||||
// =================== Dard Hook Components ===================
|
||||
.@{card-prefix-cls} {
|
||||
& when (@theme = dark) {
|
||||
background: @list-customize-card-bg;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import './customize.less';
|
||||
|
||||
@list-prefix-cls: ~'@{ant-prefix}-list';
|
||||
|
||||
|
@ -13,7 +14,7 @@
|
|||
}
|
||||
|
||||
&-pagination {
|
||||
margin-top: 24px;
|
||||
margin-top: @margin-lg;
|
||||
text-align: right;
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/20037
|
||||
|
@ -23,7 +24,7 @@
|
|||
}
|
||||
|
||||
&-more {
|
||||
margin-top: 12px;
|
||||
margin-top: @margin-sm;
|
||||
text-align: center;
|
||||
button {
|
||||
padding-right: 32px;
|
||||
|
@ -54,27 +55,27 @@
|
|||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: @list-item-padding;
|
||||
|
||||
&-content {
|
||||
color: @text-color;
|
||||
}
|
||||
color: @text-color;
|
||||
|
||||
&-meta {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: flex-start;
|
||||
font-size: 0;
|
||||
max-width: 100%;
|
||||
|
||||
&-avatar {
|
||||
margin-right: @list-item-meta-avatar-margin-right;
|
||||
}
|
||||
&-content {
|
||||
flex: 1 0;
|
||||
width: 0;
|
||||
color: @text-color;
|
||||
}
|
||||
&-title {
|
||||
margin-bottom: 4px;
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
line-height: 22px;
|
||||
line-height: @line-height-base;
|
||||
> a {
|
||||
color: @text-color;
|
||||
transition: all 0.3s;
|
||||
|
@ -85,8 +86,8 @@
|
|||
}
|
||||
&-description {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
line-height: 22px;
|
||||
font-size: @list-item-meta-description-font-size;
|
||||
line-height: @line-height-base;
|
||||
}
|
||||
}
|
||||
&-action {
|
||||
|
@ -95,19 +96,21 @@
|
|||
padding: 0;
|
||||
font-size: 0;
|
||||
list-style: none;
|
||||
|
||||
& > li {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
padding: 0 @padding-xs;
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
line-height: 22px;
|
||||
line-height: @line-height-base;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
& > li:first-child {
|
||||
padding-left: 0;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-split {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
@ -130,12 +133,12 @@
|
|||
|
||||
&-header,
|
||||
&-footer {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
padding-top: @padding-sm;
|
||||
padding-bottom: @padding-sm;
|
||||
}
|
||||
|
||||
&-empty {
|
||||
padding: 16px 0;
|
||||
padding: @padding-md 0;
|
||||
color: @text-color-secondary;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
|
@ -152,22 +155,24 @@
|
|||
border-bottom: 1px solid @border-color-split;
|
||||
}
|
||||
|
||||
&-split&-empty &-footer {
|
||||
border-top: 1px solid @border-color-split;
|
||||
}
|
||||
|
||||
&-loading &-spin-nested-loading {
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
&-something-after-last-item .@{ant-prefix}-spin-container > &-items > &-item:last-child {
|
||||
&-split&-something-after-last-item .@{ant-prefix}-spin-container > &-items > &-item:last-child {
|
||||
border-bottom: 1px solid @border-color-split;
|
||||
}
|
||||
|
||||
&-lg &-item {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
padding: @list-item-padding-lg;
|
||||
}
|
||||
|
||||
&-sm &-item {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
padding: @list-item-padding-sm;
|
||||
}
|
||||
|
||||
&-vertical &-item {
|
||||
|
@ -198,7 +203,7 @@
|
|||
margin-left: auto;
|
||||
|
||||
> li {
|
||||
padding: 0 16px;
|
||||
padding: 0 @padding-md;
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
@ -209,7 +214,7 @@
|
|||
&-grid .@{ant-prefix}-col > &-item {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: @margin-md;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
|
@ -232,3 +237,4 @@
|
|||
|
||||
@import './bordered';
|
||||
@import './responsive';
|
||||
@import './rtl';
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import './customize.less';
|
||||
|
||||
@list-prefix-cls: ~'@{ant-prefix}-list';
|
||||
|
||||
.@{list-prefix-cls} {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
|
||||
// fix for virtual scroll style attribute > (direction:ltr)
|
||||
.ReactVirtualized__List .@{list-prefix-cls}-item {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
||||
|
||||
&-pagination {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
&-item {
|
||||
&-meta {
|
||||
&-avatar {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
margin-right: 0;
|
||||
margin-left: @list-item-meta-avatar-margin-right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-action {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
margin-right: 48px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
& > li:first-child {
|
||||
.@{list-prefix-cls}.@{list-prefix-cls}-rtl & {
|
||||
padding-right: 0;
|
||||
padding-left: @padding-md;
|
||||
}
|
||||
}
|
||||
|
||||
&-split {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical &-item {
|
||||
&-extra {
|
||||
.@{list-prefix-cls}-rtl& {
|
||||
margin-right: 40px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-action {
|
||||
.@{list-prefix-cls}-rtl& {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
> li {
|
||||
&:first-child {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
padding-right: 0;
|
||||
padding-left: @padding-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
&:not(.@{list-prefix-cls}-vertical) {
|
||||
.@{list-prefix-cls}-item-no-flex {
|
||||
.@{list-prefix-cls}-item-action {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// responsive
|
||||
@media screen and (max-width: @screen-md) {
|
||||
.@{list-prefix-cls} {
|
||||
&-item {
|
||||
&-action {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
margin-right: 24px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{list-prefix-cls}-vertical {
|
||||
.@{list-prefix-cls}-item {
|
||||
&-extra {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
margin-right: 24px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-sm) {
|
||||
.@{list-prefix-cls} {
|
||||
&-item {
|
||||
&-action {
|
||||
.@{list-prefix-cls}-rtl & {
|
||||
margin-right: 22px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{list-prefix-cls}-vertical {
|
||||
.@{list-prefix-cls}-item {
|
||||
&-extra {
|
||||
// to override margins on rtl view
|
||||
.@{list-prefix-cls}-rtl& {
|
||||
margin: auto auto 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { defineComponent, inject } from 'vue';
|
||||
import { defineComponent, ExtractPropTypes, inject } from 'vue';
|
||||
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
|
||||
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
|
||||
import DoubleLeftOutlined from '@ant-design/icons-vue/DoubleLeftOutlined';
|
||||
|
@ -14,7 +14,7 @@ import enUS from '../vc-pagination/locale/en_US';
|
|||
import { defaultConfigProvider } from '../config-provider';
|
||||
import classNames from '../_util/classNames';
|
||||
|
||||
export const PaginationProps = () => ({
|
||||
export const paginationProps = () => ({
|
||||
total: PropTypes.number,
|
||||
defaultCurrent: PropTypes.number,
|
||||
disabled: PropTypes.looseBool,
|
||||
|
@ -42,16 +42,19 @@ export const PaginationProps = () => ({
|
|||
'onUpdate:pageSize': PropTypes.func,
|
||||
});
|
||||
|
||||
export const PaginationConfig = () => ({
|
||||
...PaginationProps(),
|
||||
export const paginationConfig = () => ({
|
||||
...paginationProps(),
|
||||
position: PropTypes.oneOf(tuple('top', 'bottom', 'both')),
|
||||
});
|
||||
|
||||
export type PaginationProps = Partial<ExtractPropTypes<ReturnType<typeof paginationProps>>>;
|
||||
export type PaginationConfig = Partial<ExtractPropTypes<ReturnType<typeof paginationConfig>>>;
|
||||
|
||||
export default defineComponent({
|
||||
name: 'APagination',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
...PaginationProps(),
|
||||
...paginationProps(),
|
||||
},
|
||||
emits: ['change', 'showSizeChange', 'update:current', 'update:pageSize'],
|
||||
setup() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Pagination from './Pagination';
|
||||
import { withInstall } from '../_util/type';
|
||||
|
||||
export { PaginationProps, PaginationConfig } from './Pagination';
|
||||
export { paginationProps, PaginationProps, PaginationConfig, paginationConfig } from './Pagination';
|
||||
|
||||
export default withInstall(Pagination);
|
||||
|
|
|
@ -803,9 +803,13 @@
|
|||
@list-footer-background: transparent;
|
||||
@list-empty-text-padding: @padding-md;
|
||||
@list-item-padding: @padding-sm 0;
|
||||
@list-item-padding-sm: @padding-xs @padding-md;
|
||||
@list-item-padding-lg: 16px 24px;
|
||||
@list-item-meta-margin-bottom: @padding-md;
|
||||
@list-item-meta-avatar-margin-right: @padding-md;
|
||||
@list-item-meta-title-margin-bottom: @padding-sm;
|
||||
@list-customize-card-bg: @component-background;
|
||||
@list-item-meta-description-font-size: @font-size-base;
|
||||
|
||||
// Statistic
|
||||
// ---
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ExtractPropTypes, PropType, UnwrapRef } from 'vue';
|
||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import { PaginationProps as getPaginationProps, PaginationConfig } from '../pagination';
|
||||
import { paginationProps as getPaginationProps, paginationConfig } from '../pagination';
|
||||
import { getSpinProps } from '../spin';
|
||||
import { tuple } from '../_util/type';
|
||||
|
||||
|
@ -103,7 +103,7 @@ export const tableRowSelection = {
|
|||
|
||||
export type SortOrder = 'descend' | 'ascend';
|
||||
|
||||
const paginationProps = PaginationConfig();
|
||||
const paginationProps = paginationConfig();
|
||||
|
||||
export const tableProps = {
|
||||
prefixCls: PropTypes.string,
|
||||
|
|
Loading…
Reference in New Issue