Skip to content

Commit 3f992bc

Browse files
committed
feat: added tiny-pagination package
1 parent 6a883d7 commit 3f992bc

File tree

2 files changed

+228
-0
lines changed

2 files changed

+228
-0
lines changed

packages/TinyPagination/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import TinyPagination from './src/main.vue';
2+
3+
TinyPagination.install = (Vue) => {
4+
Vue.component(TinyPagination.name, TinyPagination);
5+
};
6+
7+
export default TinyPagination;

packages/TinyPagination/src/main.vue

+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
<template>
2+
<div class="vue-tiny-pagination">
3+
<ul class="tiny-pagination" :class="customClass">
4+
<li class="page-item" :class="classFirstPage">
5+
<a class="btn-prev-page" href="#" @click.prevent="lastPage">{{translation.prev}}</a>
6+
</li>
7+
<li class="page-item">
8+
<span>{{titlePage}}</span>
9+
</li>
10+
<li class="page-item" :class="classLastPage">
11+
<a class="btn-next-page" href="#" @click.prevent="nextPage">{{translation.next}}</a>
12+
</li>
13+
<li v-if="showLimit" class="page-item">
14+
<select class="tiny-form-select" v-model="currentLimit" @change="onLimitChange">
15+
<option
16+
v-for="(limit, index) in limits"
17+
:value="limit"
18+
:key="index">{{limit}}/{{translation.title}}</option>
19+
</select>
20+
</li>
21+
</ul>
22+
</div>
23+
</template>
24+
25+
<script>
26+
export default {
27+
name: 'TinyPagination',
28+
props: {
29+
total: {
30+
type: Number,
31+
required: true,
32+
},
33+
page: {
34+
type: Number,
35+
default: 1,
36+
},
37+
lang: {
38+
type: String,
39+
default: 'en',
40+
},
41+
customClass: {
42+
type: String,
43+
},
44+
limits: {
45+
type: Array,
46+
default () {
47+
return [10, 15, 20, 50, 100];
48+
},
49+
},
50+
showLimit: {
51+
type: Boolean,
52+
default: true,
53+
}
54+
},
55+
data () {
56+
return {
57+
version: '0.2.1',
58+
currentPage: 1,
59+
currentLimit: 10,
60+
translations: {
61+
en: {
62+
prev: 'Previous',
63+
title: 'Page',
64+
next: 'Next',
65+
},
66+
es: {
67+
prev: 'Anterior',
68+
title: 'Página',
69+
next: 'Siguiente',
70+
}
71+
},
72+
availableLanguages: ['en', 'es'],
73+
};
74+
},
75+
created () {
76+
this.currentPage = this.page
77+
},
78+
computed: {
79+
translation () {
80+
return (this.availableLanguages.includes(this.lang)) ?
81+
this.translations[this.lang]
82+
: this.translations['en']
83+
},
84+
totalPages () {
85+
return Math.ceil(this.total/this.currentLimit)
86+
},
87+
titlePage () {
88+
return `${this.translation.title} ${this.currentPage}`
89+
},
90+
classFirstPage () {
91+
return {
92+
disabled: (this.currentPage === 1),
93+
'c-not-allowed': true
94+
}
95+
},
96+
classLastPage () {
97+
return {
98+
disabled: (this.currentPage === this.totalPages),
99+
'c-not-allowed': true
100+
}
101+
}
102+
},
103+
methods: {
104+
nextPage () {
105+
if (this.currentPage !== this.totalPages) {
106+
this.currentPage += 1
107+
}
108+
},
109+
lastPage () {
110+
if (this.currentPage > 1) {
111+
this.currentPage -= 1
112+
}
113+
},
114+
onLimitChange () {
115+
this.currentPage = 1
116+
}
117+
},
118+
watch: {
119+
currentPage (value) {
120+
this.$emit('tiny:change-page', {
121+
page: value
122+
})
123+
},
124+
currentLimit (value) {
125+
this.$emit('tiny:change-limit', {
126+
limit: value
127+
})
128+
}
129+
}
130+
}
131+
</script>
132+
133+
<style lang="scss">
134+
// Pagination
135+
.tiny-pagination {
136+
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
137+
display: flex;
138+
list-style: none;
139+
margin: .2rem 0;
140+
padding: .2rem 0;
141+
142+
.page-item {
143+
margin: .2rem .05rem;
144+
145+
span {
146+
display: inline-block;
147+
padding: .2rem .2rem;
148+
}
149+
150+
a {
151+
border-radius: .1rem;
152+
color: #667189;
153+
display: inline-block;
154+
padding: .2rem .4rem;
155+
text-decoration: none;
156+
&:focus,
157+
&:hover {
158+
color: #5755d9;
159+
}
160+
}
161+
162+
&.disabled {
163+
a {
164+
cursor: default;
165+
opacity: .5;
166+
pointer-events: none;
167+
}
168+
}
169+
170+
&.active {
171+
a {
172+
background: #5755d9;
173+
color: #fff;
174+
}
175+
}
176+
177+
&.page-prev,
178+
&.page-next {
179+
flex: 1 0 50%;
180+
}
181+
182+
&.page-next {
183+
text-align: right;
184+
}
185+
186+
.page-item-title {
187+
margin: 0;
188+
}
189+
190+
.page-item-subtitle {
191+
margin: 0;
192+
opacity: .5;
193+
}
194+
}
195+
196+
.tiny-form-select {
197+
-webkit-appearance: none;
198+
-moz-appearance: none;
199+
appearance: none;
200+
text-transform: lowercase;
201+
border: .05rem solid #caced7;
202+
border-radius: .1rem;
203+
font-size: .8rem;
204+
height: 1.8rem;
205+
line-height: 1rem;
206+
outline: none;
207+
padding: .35rem .4rem;
208+
vertical-align: middle;
209+
width: 100%;
210+
&:focus {
211+
border-color: #5755d9;
212+
box-shadow: 0 0 0 0.1rem rgba(87, 85, 217, .2)
213+
}
214+
}
215+
216+
.tiny-form-select:not([multiple]):not([size]) {
217+
background: #fff url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns="http://www.w3.org/2000/svg"…path%20fill="%23667189"%20d="M2%200L0%202h4zm0%205L0%203h4z"/%3E%3C/svg%3E') no-repeat right .35rem center/.4rem .5rem;
218+
padding-right: 1.2rem;
219+
}
220+
}
221+
</style>

0 commit comments

Comments
 (0)