Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin
commit
1b31dde36a
@ -0,0 +1,2 @@
|
||||
export type { PaginationProps as VbenPaginationProps } from './pagination';
|
||||
export { default as VbenPagination } from './pagination.vue';
|
||||
@ -0,0 +1,111 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Button } from '../ui/button';
|
||||
import {
|
||||
Pagination,
|
||||
PaginationEllipsis,
|
||||
PaginationFirst,
|
||||
PaginationLast,
|
||||
PaginationList,
|
||||
PaginationListItem,
|
||||
PaginationNext,
|
||||
PaginationPrev,
|
||||
} from '../ui/pagination';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '../ui/select';
|
||||
import { type PaginationProps, SIZE_CLASS_MAP } from './pagination';
|
||||
|
||||
interface Props extends PaginationProps {}
|
||||
|
||||
const {
|
||||
disabled = false,
|
||||
pageSizeOptions = [10, 20, 30, 50, 100, 200],
|
||||
showEdges = true,
|
||||
showRowsPerPage = true,
|
||||
showTotalText = true,
|
||||
siblingCount = 1,
|
||||
size = 'default',
|
||||
total = 500,
|
||||
} = defineProps<Props>();
|
||||
|
||||
const currentPage = defineModel<number>('currentPage', { default: 1 });
|
||||
const itemPerPage = defineModel<number>('itemPerPage', { default: 20 });
|
||||
|
||||
const itemSize = computed(() => {
|
||||
return SIZE_CLASS_MAP[size];
|
||||
});
|
||||
|
||||
const options = computed(() => {
|
||||
return pageSizeOptions.map((item) => ({
|
||||
label: `${item} 条/页`,
|
||||
value: `${item}`,
|
||||
}));
|
||||
});
|
||||
|
||||
function handleUpdateModelValue(value: string) {
|
||||
itemPerPage.value = Number(value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Pagination
|
||||
v-model:page="currentPage"
|
||||
:disabled="disabled"
|
||||
:items-per-page="itemPerPage"
|
||||
:show-edges="showEdges"
|
||||
:sibling-count="siblingCount"
|
||||
:total="total"
|
||||
>
|
||||
<PaginationList
|
||||
v-slot="{ items }"
|
||||
class="flex w-full items-center justify-end gap-1"
|
||||
>
|
||||
<span v-if="showTotalText" class="mr-2">共 {{ total }} 条</span>
|
||||
|
||||
<Select
|
||||
v-if="showRowsPerPage"
|
||||
:model-value="`${itemPerPage}`"
|
||||
@update:model-value="handleUpdateModelValue"
|
||||
>
|
||||
<SelectTrigger class="w-30 mr-auto h-8">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<template v-for="item in options" :key="item.value">
|
||||
<SelectItem :value="item.value"> {{ item.label }} </SelectItem>
|
||||
</template>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<PaginationFirst :class="cn('size-8', itemSize)" />
|
||||
<PaginationPrev :class="cn('size-8', itemSize)" />
|
||||
<template v-for="(item, index) in items">
|
||||
<PaginationListItem
|
||||
v-if="item.type === 'page'"
|
||||
:key="index"
|
||||
:value="item.value"
|
||||
as-child
|
||||
>
|
||||
<Button
|
||||
:class="cn('size-8 p-0 shadow-none', itemSize)"
|
||||
:variant="item.value === currentPage ? 'default' : 'outline'"
|
||||
>
|
||||
{{ item.value }}
|
||||
</Button>
|
||||
</PaginationListItem>
|
||||
<PaginationEllipsis v-else :key="item.type" :index="index" />
|
||||
</template>
|
||||
|
||||
<PaginationNext :class="cn('size-8', itemSize)" />
|
||||
<PaginationLast :class="cn('size-8', itemSize)" />
|
||||
</PaginationList>
|
||||
</Pagination>
|
||||
</template>
|
||||
@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { MoreHorizontal } from 'lucide-vue-next';
|
||||
import { PaginationEllipsis, type PaginationEllipsisProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & PaginationEllipsisProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PaginationEllipsis
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('flex size-8 items-center justify-center', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<MoreHorizontal class="size-4" />
|
||||
</slot>
|
||||
</PaginationEllipsis>
|
||||
</template>
|
||||
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronsLeft } from 'lucide-vue-next';
|
||||
import { PaginationFirst, type PaginationFirstProps } from 'radix-vue';
|
||||
|
||||
import { Button } from '../button';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ class?: any } & PaginationFirstProps>(),
|
||||
{
|
||||
asChild: true,
|
||||
},
|
||||
);
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PaginationFirst v-bind="delegatedProps">
|
||||
<Button :class="cn('size-8 p-0', props.class)" variant="outline">
|
||||
<slot>
|
||||
<ChevronsLeft class="size-4" />
|
||||
</slot>
|
||||
</Button>
|
||||
</PaginationFirst>
|
||||
</template>
|
||||
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronsRight } from 'lucide-vue-next';
|
||||
import { PaginationLast, type PaginationLastProps } from 'radix-vue';
|
||||
|
||||
import { Button } from '../button';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ class?: any } & PaginationLastProps>(),
|
||||
{
|
||||
asChild: true,
|
||||
},
|
||||
);
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PaginationLast v-bind="delegatedProps">
|
||||
<Button :class="cn('size-8 p-0', props.class)" variant="outline">
|
||||
<slot>
|
||||
<ChevronsRight class="size-4" />
|
||||
</slot>
|
||||
</Button>
|
||||
</PaginationLast>
|
||||
</template>
|
||||
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronRight } from 'lucide-vue-next';
|
||||
import { PaginationNext, type PaginationNextProps } from 'radix-vue';
|
||||
|
||||
import { Button } from '../button';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ class?: any } & PaginationNextProps>(),
|
||||
{
|
||||
asChild: true,
|
||||
},
|
||||
);
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PaginationNext v-bind="delegatedProps">
|
||||
<Button :class="cn('size-8 p-0', props.class)" variant="outline">
|
||||
<slot>
|
||||
<ChevronRight class="size-4" />
|
||||
</slot>
|
||||
</Button>
|
||||
</PaginationNext>
|
||||
</template>
|
||||
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronLeft } from 'lucide-vue-next';
|
||||
import { PaginationPrev, type PaginationPrevProps } from 'radix-vue';
|
||||
|
||||
import { Button } from '../button';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ class?: any } & PaginationPrevProps>(),
|
||||
{
|
||||
asChild: true,
|
||||
},
|
||||
);
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PaginationPrev v-bind="delegatedProps">
|
||||
<Button :class="cn('size-8 p-0', props.class)" variant="outline">
|
||||
<slot>
|
||||
<ChevronLeft class="size-4" />
|
||||
</slot>
|
||||
</Button>
|
||||
</PaginationPrev>
|
||||
</template>
|
||||
@ -0,0 +1,10 @@
|
||||
export { default as PaginationEllipsis } from './PaginationEllipsis.vue';
|
||||
export { default as PaginationFirst } from './PaginationFirst.vue';
|
||||
export { default as PaginationLast } from './PaginationLast.vue';
|
||||
export { default as PaginationNext } from './PaginationNext.vue';
|
||||
export { default as PaginationPrev } from './PaginationPrev.vue';
|
||||
export {
|
||||
PaginationList,
|
||||
PaginationListItem,
|
||||
PaginationRoot as Pagination,
|
||||
} from 'radix-vue';
|
||||
Loading…
Reference in new issue