vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
4.2 KiB
166 lines
4.2 KiB
import type { ExtractPropTypes } from 'vue'; |
|
import { defineComponent, computed, ref, watch } from 'vue'; |
|
import classNames from '../_util/classNames'; |
|
import ListItem from './ListItem'; |
|
import Pagination from '../pagination'; |
|
import PropTypes from '../_util/vue-types'; |
|
import type { TransferItem } from '.'; |
|
|
|
export const transferListBodyProps = { |
|
prefixCls: String, |
|
filteredRenderItems: PropTypes.array.def([]), |
|
selectedKeys: PropTypes.array, |
|
disabled: { type: Boolean, default: undefined }, |
|
showRemove: { type: Boolean, default: undefined }, |
|
pagination: PropTypes.any, |
|
onItemSelect: Function, |
|
onScroll: Function, |
|
onItemRemove: Function, |
|
}; |
|
|
|
export type TransferListBodyProps = Partial<ExtractPropTypes<typeof transferListBodyProps>>; |
|
|
|
function parsePagination(pagination) { |
|
if (!pagination) { |
|
return null; |
|
} |
|
|
|
const defaultPagination = { |
|
pageSize: 10, |
|
}; |
|
|
|
if (typeof pagination === 'object') { |
|
return { |
|
...defaultPagination, |
|
...pagination, |
|
}; |
|
} |
|
|
|
return defaultPagination; |
|
} |
|
|
|
const ListBody = defineComponent({ |
|
compatConfig: { MODE: 3 }, |
|
name: 'ListBody', |
|
inheritAttrs: false, |
|
props: transferListBodyProps, |
|
emits: ['itemSelect', 'itemRemove', 'scroll'], |
|
setup(props, { emit, expose }) { |
|
const current = ref(1); |
|
|
|
const handleItemSelect = (item: TransferItem) => { |
|
const { selectedKeys } = props; |
|
const checked = selectedKeys.indexOf(item.key) >= 0; |
|
emit('itemSelect', item.key, !checked); |
|
}; |
|
|
|
const handleItemRemove = (item: TransferItem) => { |
|
emit('itemRemove', item.key); |
|
}; |
|
|
|
const handleScroll = (e: Event) => { |
|
emit('scroll', e); |
|
}; |
|
|
|
const mergedPagination = computed(() => parsePagination(props.pagination)); |
|
|
|
watch( |
|
[mergedPagination, () => props.filteredRenderItems], |
|
() => { |
|
if (mergedPagination.value) { |
|
// Calculate the page number |
|
const maxPageCount = Math.ceil( |
|
props.filteredRenderItems.length / mergedPagination.value.pageSize, |
|
); |
|
|
|
if (current.value > maxPageCount) { |
|
current.value = maxPageCount; |
|
} |
|
} |
|
}, |
|
{ immediate: true }, |
|
); |
|
const items = computed(() => { |
|
const { filteredRenderItems } = props; |
|
|
|
let displayItems = filteredRenderItems; |
|
|
|
if (mergedPagination.value) { |
|
displayItems = filteredRenderItems.slice( |
|
(current.value - 1) * mergedPagination.value.pageSize, |
|
current.value * mergedPagination.value.pageSize, |
|
); |
|
} |
|
|
|
return displayItems; |
|
}); |
|
|
|
const onPageChange = (cur: number) => { |
|
current.value = cur; |
|
}; |
|
|
|
expose({ items }); |
|
|
|
return () => { |
|
const { |
|
prefixCls, |
|
filteredRenderItems, |
|
selectedKeys, |
|
disabled: globalDisabled, |
|
showRemove, |
|
} = props; |
|
|
|
let paginationNode = null; |
|
|
|
if (mergedPagination.value) { |
|
paginationNode = ( |
|
<Pagination |
|
simple |
|
size="small" |
|
disabled={globalDisabled} |
|
class={`${prefixCls}-pagination`} |
|
total={filteredRenderItems.length} |
|
pageSize={mergedPagination.value.pageSize} |
|
current={current.value} |
|
onChange={onPageChange} |
|
/> |
|
); |
|
} |
|
|
|
const itemsList = items.value.map(({ renderedEl, renderedText, item }: any) => { |
|
const { disabled } = item; |
|
const checked = selectedKeys.indexOf(item.key) >= 0; |
|
|
|
return ( |
|
<ListItem |
|
disabled={globalDisabled || disabled} |
|
key={item.key} |
|
item={item} |
|
renderedText={renderedText} |
|
renderedEl={renderedEl} |
|
checked={checked} |
|
prefixCls={prefixCls} |
|
onClick={handleItemSelect} |
|
onRemove={handleItemRemove} |
|
showRemove={showRemove} |
|
/> |
|
); |
|
}); |
|
return ( |
|
<> |
|
<ul |
|
class={classNames(`${prefixCls}-content`, { |
|
[`${prefixCls}-content-show-remove`]: showRemove, |
|
})} |
|
onScroll={handleScroll} |
|
> |
|
{itemsList} |
|
</ul> |
|
{paginationNode} |
|
</> |
|
); |
|
}; |
|
}, |
|
}); |
|
|
|
export default ListBody;
|
|
|