Skip to content

Commit 4e911f2

Browse files
committed
feat(props): noFooter, fontSize, pagination
1 parent 93a3734 commit 4e911f2

File tree

3 files changed

+206
-49
lines changed

3 files changed

+206
-49
lines changed

src/component/QIconPicker.js

Lines changed: 180 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Colorize from './mixins/colorize'
1010
import props from './utils/props'
1111

1212
// Quasar
13-
import { QBtn, QScrollArea, QTooltip } from 'quasar'
13+
import { QBtn, QScrollArea, QTooltip, QPagination } from 'quasar'
1414

1515
export default Vue.extend({
1616
name: 'q-icon-picker',
@@ -21,85 +21,223 @@ export default Vue.extend({
2121

2222
data () {
2323
return {
24-
iconsList: []
24+
iconsList: [],
25+
innerPagination: {
26+
page: 1,
27+
itemsPerPage: 60,
28+
totalPages: 0
29+
}
2530
}
2631
},
2732

33+
created () {
34+
this.$emit('update:pagination', { ...this.computedPagination })
35+
},
36+
2837
mounted () {
2938
if (this.iconSet) {
3039
this.loadIconSet(this.iconSet)
31-
this.$forceUpdate()
32-
}
33-
else if (this.icons !== void 0 && this.icons.length > 0) {
40+
} else if (this.icons !== void 0 && this.icons.length > 0) {
3441
this.iconsList = this.icons
3542
}
43+
this.updatePagination()
3644
},
3745

3846
computed: {
3947
displayedIcons () {
48+
let icons = []
4049
if (this.iconsList) {
4150
if (this.filter === void 0 || this.filter === null || this.filter === '') {
42-
return this.iconsList
51+
icons = this.iconsList
52+
}
53+
if (this.filter !== void 0 && this.filter !== '' && this.filter !== null) {
54+
icons = this.iconsList.filter(icon => icon.name.includes(this.filter))
55+
}
56+
57+
// should the icons be paged?
58+
if (this.pagination) {
59+
icons = icons.slice(this.firstItemIndex, this.lastItemIndex)
4360
}
44-
let icons = this.iconsList.filter(icon => icon.name.includes(this.filter))
45-
46-
// // should the icons be paged?
47-
// if (this.startIndex !== void 0) {
48-
// let count = 0
49-
// icons = icons.map((icon, index) => {
50-
// if (index < this.startIndex) {
51-
// return false
52-
// }
53-
// // should a limited number of icons be displayed?
54-
// if (this.displayCount !== void 0) {
55-
// if (count > this.displayCount) {
56-
// return false
57-
// }
58-
// ++count
59-
// }
60-
// return true
61-
// })
62-
// }
63-
// this.$emit('info', { count: icons.length, index: this.startIndex, displayCount: this.displayCount })
64-
return icons
6561
}
66-
return []
62+
return icons
63+
},
64+
65+
computedPagination () {
66+
return this.fixPagination({
67+
...this.innerPagination,
68+
...this.pagination
69+
})
70+
},
71+
72+
computedItemsNumber () {
73+
return this.iconsList.length
74+
},
75+
76+
firstItemIndex () {
77+
const { page, itemsPerPage } = this.computedPagination
78+
return (page - 1) * itemsPerPage
79+
},
80+
81+
lastItemIndex () {
82+
const { page, itemsPerPage } = this.computedPagination
83+
return page * itemsPerPage
84+
},
85+
86+
isFirstPage () {
87+
return this.computedPagination.page === 1
88+
},
89+
90+
pagesNumber () {
91+
return Math.max(
92+
1,
93+
Math.ceil(this.computedItemsNumber / this.computedPagination.itemsPerPage)
94+
)
95+
},
96+
97+
isLastPage () {
98+
return this.lastItemIndex === 0
99+
? true
100+
: this.computedPagination.page >= this.pagesNumber
67101
}
68102
},
69103

70104
watch: {
71105
iconSet (val) {
72106
this.loadIconSet(val)
107+
this.updatePagination()
73108
},
109+
74110
icons (val) {
75111
if (this.icons !== void 0 && this.icons.length > 0) {
76112
this.iconsList = this.icons
77113
}
114+
this.updatePagination()
115+
},
116+
117+
pagination (newVal, oldVal) {
118+
if (!this.samePagination(oldVal, newVal)) {
119+
this.updatePagination()
120+
}
121+
},
122+
123+
filter () {
124+
// whenever the filter changes, it resets pagination page to page 1
125+
this.setPagination({ page: 1 })
78126
}
79127
},
80128

81129
methods: {
82130
loadIconSet (set) {
83-
console.log('loadIconSet:', set)
84131
if (set) {
85-
let icons = require(`./utils/${set}.json`)
86-
this.iconsList = icons
132+
try {
133+
let icons = require(`./utils/${set}.json`)
134+
this.iconsList = icons
135+
return
136+
} catch (e) {
137+
console.error(`QIconPicker: no icon set found called: ${set}`)
138+
}
139+
}
140+
this.iconsList = []
141+
},
142+
143+
fixPagination (p) {
144+
if (p.page < 1) {
145+
p.page = 1
146+
}
147+
if (p.itemsPerPage !== void 0 && p.itemsPerPage < 1) {
148+
p.itemsPerPage = 0
149+
}
150+
return p
151+
},
152+
153+
samePagination (oldPag, newPag) {
154+
for (let prop in newPag) {
155+
if (newPag[prop] !== oldPag[prop]) {
156+
return false
157+
}
158+
}
159+
return true
160+
},
161+
162+
setPagination (val) {
163+
const newPagination = this.fixPagination({
164+
...this.computedPagination,
165+
...val
166+
})
167+
168+
if (this.pagination) {
169+
this.$emit('update:pagination', newPagination)
87170
} else {
88-
this.iconsList = []
171+
this.innerPagination = newPagination
89172
}
90173
},
91174

92-
__renderScrollArea (h) {
93-
return h(QScrollArea, {
94-
ref: 'scrollArea'
175+
prevPage () {
176+
const { page } = this.computedPagination
177+
if (page > 1) {
178+
this.setPagination({ page: page - 1 })
179+
}
180+
},
181+
182+
nextPage () {
183+
const { page, itemsPerPage } = this.computedPagination
184+
if (this.lastItemIndex > 0 && page * itemsPerPage < this.computedItemsNumber) {
185+
this.setPagination({ page: page + 1 })
186+
}
187+
},
188+
189+
updatePagination () {
190+
if (this.pagination !== void 0) {
191+
this.setPagination({ total: this.computedItemsNumber, totalPages: this.pagesNumber })
192+
}
193+
},
194+
195+
__renderBody (h) {
196+
return h('div', {
197+
staticClass: 'q-icon-picker__body'
95198
}, [
96-
this.__renderContainer(h)
199+
this.__renderScrollArea(h)
97200
])
98201
},
99202

100-
__renderBody (h) {
203+
__renderFooter (h) {
204+
const slot = this.$scopedSlots.footer
205+
206+
return h('div', {
207+
staticClass: 'q-icon-picker__footer flex flex-center'
208+
}, [
209+
slot || this.__renderPagination(h)
210+
])
211+
},
212+
213+
__renderPagination (h) {
214+
const slot = this.$scopedSlots.pagination
215+
const { page, totalPages } = this.computedPagination
216+
217+
if (slot) {
218+
return slot
219+
} else {
220+
return h(QPagination, this.setBothColors(this.color, this.backgroundColor, {
221+
staticClass: 'q-icon-picker__pagination',
222+
props: {
223+
value: page,
224+
max: totalPages,
225+
input: true,
226+
textColor: this.paginationColor
227+
},
228+
on: {
229+
'input': v => {
230+
this.setPagination({ page: v })
231+
}
232+
}
233+
}))
234+
}
235+
},
236+
237+
__renderScrollArea (h) {
101238
return h(QScrollArea, {
102-
staticClass: 'q-icon-picker__body'
239+
ref: 'scrollArea',
240+
staticClass: 'q-icon-picker__scroll-area fit'
103241
}, [
104242
this.__renderContainer(h)
105243
])
@@ -147,7 +285,7 @@ export default Vue.extend({
147285
icon: icon.name
148286
},
149287
on: {
150-
'click': () => {
288+
'click': () => {
151289
this.$emit('input', icon.name)
152290
}
153291
}
@@ -162,7 +300,8 @@ export default Vue.extend({
162300
ref: 'icon-picker',
163301
staticClass: 'q-icon-picker flex'
164302
}), [
165-
this.__renderBody(h)
303+
this.__renderBody(h),
304+
this.noFooter !== true && this.pagination !== void 0 && this.__renderFooter(h)
166305
])
167306
}
168-
})
307+
})

src/component/icon-picker.styl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,35 @@
22
background-color $grey-1
33
flex none
44
display flex
5+
flex-direction column
56
overflow hidden
67

78
&__body
89
overflow hidden
910
flex 1 1 auto
1011
position relative
12+
width 100%
1113

1214
&__scroll-area
1315
overflow hidden
1416
flex 1 1 auto
17+
width 100%
18+
height: 100%
1519
// display flex
1620
// align-items flex-start
1721

1822
&__container
1923
flex 1
2024
min-width 100%
2125
min-height 100%
26+
27+
&__header
28+
position relative
29+
width 100%
30+
31+
&__footer
32+
position relative
33+
width 100%
34+
35+
&__pagination
36+
position relative

src/component/utils/props.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@ export default {
33
value: String,
44
iconSet: {
55
type: String,
6-
validator: v => ['material-icons', 'ionicons-v4', 'mdi-v3', 'fontawesome-v5', 'eva-icons', 'themify', ''].includes(v)
6+
validator: v => ['material-icons', 'ionicons-v4', 'mdi-v3', 'fontawesome-v5', 'eva-icons', 'themify', ''].includes(v),
7+
default: ''
78
},
89
icons: Array,
910
filter: String,
1011
dense: Boolean,
1112
tooltips: Boolean,
13+
noFooter: Boolean,
14+
fontSize: {
15+
type: String,
16+
default: 'inherit'
17+
},
1218
selectedColor: {
1319
type: String,
1420
default: 'grey-1'
@@ -17,11 +23,8 @@ export default {
1723
type: String,
1824
default: 'primary'
1925
},
20-
// displayCount: [Number, String],
21-
// startIndex: [Number, String]
22-
fontSize: {
23-
type: String,
24-
default: 'inherit'
25-
}
26+
paginationColor: String,
27+
paginationBackgroundColor: String,
28+
pagination: Object
2629
}
27-
}
30+
}

0 commit comments

Comments
 (0)