@@ -10,7 +10,7 @@ import Colorize from './mixins/colorize'
1010import props from './utils/props'
1111
1212// Quasar
13- import { QBtn , QScrollArea , QTooltip } from 'quasar'
13+ import { QBtn , QScrollArea , QTooltip , QPagination } from 'quasar'
1414
1515export 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+ } )
0 commit comments