add pagination
This commit is contained in:
parent
ad27e021fd
commit
03e73d5789
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "axp-ui",
|
||||
"descriiption": "My helper ui lib",
|
||||
"version": "1.7.3",
|
||||
"version": "1.8.0",
|
||||
"homepage": "https://antoxahub.ru/antoxa/axp-ui",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
17
src/App.vue
17
src/App.vue
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { cFieldsSchema } from 'axp-ts'
|
||||
import { cFieldsSchema, Pagination } from 'axp-ts'
|
||||
import { colors, icons } from '.'
|
||||
import {
|
||||
UiBtn,
|
||||
@ -20,7 +20,8 @@ import {
|
||||
UiFieldFile,
|
||||
UiTable,
|
||||
UiCard,
|
||||
UiPickerDays
|
||||
UiPickerDays,
|
||||
UiPagination
|
||||
} from './components'
|
||||
|
||||
// Test fields.
|
||||
@ -51,6 +52,9 @@ const days = ref([1, 3, 5])
|
||||
|
||||
// File.
|
||||
const testFileValue = ref<FileList | undefined>()
|
||||
|
||||
// Pagination.
|
||||
const pagination = ref(new Pagination({ page: 4, total: 93 }).toObject())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -278,8 +282,15 @@ const testFileValue = ref<FileList | undefined>()
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item pagination">
|
||||
<div class="item-title">Pagination</div>
|
||||
<div class="item-content">
|
||||
<UiPagination v-model="pagination" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item complex">
|
||||
<div class="item-title">Сложные элементы</div>
|
||||
<div class="item-title">Complex elements</div>
|
||||
<div class="item-content">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<ui-card title="Карточка">
|
||||
|
108
src/components/Pagination.vue
Normal file
108
src/components/Pagination.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<script lang="ts">
|
||||
import type { TPagination } from 'axp-ts'
|
||||
|
||||
export type TUiPaginationPage = {
|
||||
value: number
|
||||
active?: boolean
|
||||
}
|
||||
|
||||
export type TUiPaginationProps = {
|
||||
modelValue?: TPagination
|
||||
length?: number
|
||||
}
|
||||
|
||||
export type TUiPaginationEmits = {
|
||||
(e: 'update:model-value', v: TPagination): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiBtn from './Btn.vue'
|
||||
import { computed } from 'vue'
|
||||
import { Pagination } from 'axp-ts'
|
||||
|
||||
// Props.
|
||||
const props = withDefaults(defineProps<TUiPaginationProps>(), {
|
||||
// @ts-ignore
|
||||
modelValue: new Pagination().toObject(),
|
||||
length: 3
|
||||
})
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiPaginationEmits>()
|
||||
|
||||
// Data.
|
||||
const page = computed(() => props.modelValue.page || 1)
|
||||
const pages = computed(() => {
|
||||
let pages: TUiPaginationPage[] = []
|
||||
|
||||
const length = props.length
|
||||
|
||||
// Pre pages.
|
||||
for (let i = 1; i < length; i++) {
|
||||
const value = page.value - i
|
||||
if (value < 1) break
|
||||
pages.push({ value })
|
||||
}
|
||||
|
||||
pages = pages.reverse()
|
||||
|
||||
// Curren page.
|
||||
pages.push({ value: page.value, active: true })
|
||||
|
||||
// Next pages.
|
||||
for (let i = 1; i <= length; i++) {
|
||||
const value = page.value + i
|
||||
if (value > (props.modelValue.pages || 0)) break
|
||||
pages.push({ value })
|
||||
}
|
||||
// for(page in props.modelValue)
|
||||
return pages
|
||||
})
|
||||
|
||||
// Handlers.
|
||||
const updateHandler = (page: number) => {
|
||||
const pagination = new Pagination({ ...props.modelValue, page })
|
||||
emit('update:model-value', pagination.toObject())
|
||||
}
|
||||
|
||||
// Etc.
|
||||
const isShowFirst = computed(() => page.value - props.length > 0)
|
||||
const isShowLast = computed(
|
||||
() =>
|
||||
props.modelValue.pages &&
|
||||
page.value + props.length < props.modelValue.pages
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="props.modelValue.pages" class="ui-pagination">
|
||||
<div class="pages">
|
||||
<div v-if="isShowFirst" class="pages-first">
|
||||
<UiBtn
|
||||
label="1"
|
||||
class="page-item"
|
||||
@click="updateHandler(1)"
|
||||
/>
|
||||
<span class="page-separator">...</span>
|
||||
</div>
|
||||
<div class="pages-numbers">
|
||||
<UiBtn
|
||||
v-for="item in pages"
|
||||
:label="item.value.toString()"
|
||||
:class="{ 'page-item': true, active: item.active }"
|
||||
:disabled="item.active"
|
||||
@click="updateHandler(item.value)"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="isShowLast" class="pages-last">
|
||||
<span class="page-separator">...</span>
|
||||
<UiBtn
|
||||
:label="props.modelValue.pages.toString()"
|
||||
@click="updateHandler(props.modelValue.pages)"
|
||||
class="page-item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -63,3 +63,6 @@ export * from './PickerDays.vue'
|
||||
|
||||
export { default as UiForm } from './Form.vue'
|
||||
export * from './Form.vue'
|
||||
|
||||
export { default as UiPagination } from './Pagination.vue'
|
||||
export * from './Pagination.vue'
|
||||
|
@ -149,3 +149,17 @@
|
||||
&-toggle-theme
|
||||
.ui-icon
|
||||
@apply cursor-pointer
|
||||
&-pagination
|
||||
.pages
|
||||
@apply flex
|
||||
&-first,
|
||||
&-numbers,
|
||||
&-last
|
||||
@apply flex items-end
|
||||
.page-item
|
||||
@apply w-[38px] h-[38px]
|
||||
.page-separator
|
||||
@apply block mx-2
|
||||
&-numbers
|
||||
.page-item:not(:last-child)
|
||||
@apply mr-2
|
||||
|
@ -57,3 +57,8 @@
|
||||
&-field .input > *,
|
||||
&-card
|
||||
@apply rounded
|
||||
|
||||
&-pagination
|
||||
.pages
|
||||
.active
|
||||
@apply bg-primary text-white
|
||||
|
@ -6,7 +6,7 @@ const config: Config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#3c87a4',
|
||||
primary: '#6d6bff',
|
||||
accent: '#ab6dfd',
|
||||
|
||||
dark: '#363636',
|
||||
|
Loading…
Reference in New Issue
Block a user