Skip to content

Commit 67ef1e2

Browse files
feat: DLT-2419 hideEdges + watcher on active page prop (#675)
1 parent 8c0c6ea commit 67ef1e2

File tree

10 files changed

+252
-32
lines changed

10 files changed

+252
-32
lines changed

packages/dialtone-vue2/components/pagination/pagination.stories.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const argsData = {
1010
totalPages: 5,
1111
activePage: 1,
1212
maxVisible: 5,
13+
hideEdges: false,
1314
ariaLabel: 'pagination',
1415
prevAriaLabel: 'previous',
1516
nextAriaLabel: 'next',
@@ -33,6 +34,11 @@ export const argTypesData = {
3334
type: 'number',
3435
},
3536
},
37+
hideEdges: {
38+
control: {
39+
type: 'boolean',
40+
},
41+
},
3642
ariaLabel: {
3743
control: {
3844
type: 'text',

packages/dialtone-vue2/components/pagination/pagination.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,51 @@ describe('DtPagination Tests', () => {
129129
expect(pages.length).toBe(7);
130130
});
131131
});
132+
133+
describe('When hideEdges is true', () => {
134+
it('shouldn\'t render hidden pages which are the first and last when in middle', () => {
135+
mockProps = {
136+
totalPages: 15,
137+
activePage: 7,
138+
maxVisible: 5,
139+
hideEdges: true,
140+
};
141+
142+
updateWrapper();
143+
144+
expect(pages.length).toBe(7);
145+
expect(pages.at(1).text()).toBe('5');
146+
expect(pages.at(5).text()).toBe('9');
147+
});
148+
149+
it('shouldn\'t render hidden pages which is the last page when at start', () => {
150+
mockProps = {
151+
totalPages: 15,
152+
activePage: 1,
153+
maxVisible: 5,
154+
hideEdges: true,
155+
};
156+
157+
updateWrapper();
158+
159+
expect(pages.length).toBe(7);
160+
expect(pages.at(6).text()).not.toBe('15');
161+
});
162+
163+
it('shouldn\'t render hidden pages which is the first page when at end', () => {
164+
mockProps = {
165+
totalPages: 15,
166+
activePage: 14,
167+
maxVisible: 5,
168+
hideEdges: true,
169+
};
170+
171+
updateWrapper();
172+
173+
expect(pages.length).toBe(7);
174+
expect(pages.at(0).text()).not.toBe('1');
175+
});
176+
});
132177
});
133178

134179
describe('Interactivity Tests', () => {

packages/dialtone-vue2/components/pagination/pagination.vue

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@ export default {
142142
type: Number,
143143
default: 5,
144144
},
145+
146+
/**
147+
* Sometimes you may need to hide start and end page number buttons when moving in between.
148+
* This prop will be used to hide the first and last page buttons when not near the edges.
149+
* This is useful when your backend does not support offset and you can only use cursor based pagination.
150+
*/
151+
hideEdges: {
152+
type: Boolean,
153+
default: false,
154+
},
145155
},
146156
147157
emits: [
@@ -177,23 +187,57 @@ export default {
177187
return this.range(1, this.totalPages);
178188
}
179189
180-
const start = this.maxVisible - 1;
181-
const end = this.totalPages - start + 1;
190+
let start = this.maxVisible - 1;
191+
let end = this.totalPages - start + 1;
192+
193+
// if hideEdges is true, modify the start and
194+
// end to account for the hidden pages
195+
if (this.hideEdges) {
196+
start = start + 1;
197+
end = end - 1;
198+
}
182199
183200
if (this.currentPage < start) {
184-
return [...this.range(1, start), '...', this.totalPages];
201+
const pages = [...this.range(1, start), '...'];
202+
if (!this.hideEdges) {
203+
// add last page to the end
204+
pages.push(this.totalPages);
205+
}
206+
return pages;
185207
}
186208
187209
if (this.currentPage > end) {
188-
return [1, '...', ...this.range(end, this.totalPages)];
210+
const pages = ['...', ...this.range(end, this.totalPages)];
211+
if (!this.hideEdges) {
212+
// add first page to the beginning
213+
pages.unshift(1);
214+
}
215+
return pages;
189216
}
190217
191218
// rounding to the nearest odd according to the maxlength to always show the page number in the middle.
192219
const total = this.maxVisible - (3 - this.maxVisible % 2);
193220
const centerIndex = Math.floor(total / 2);
194-
const left = this.currentPage - centerIndex;
195-
const right = this.currentPage + centerIndex;
196-
return [1, '...', ...this.range(left, right), '...', this.totalPages];
221+
let left = this.currentPage - centerIndex;
222+
let right = this.currentPage + centerIndex;
223+
224+
// if hideEdge is true, modify the left and right to account for the hidden pages
225+
if (this.hideEdges) {
226+
left = left - 1;
227+
right = right + 1;
228+
}
229+
230+
const pages = ['...', ...this.range(left, right), '...'];
231+
if (!this.hideEdges) {
232+
return [1, ...pages, this.totalPages];
233+
}
234+
return pages;
235+
},
236+
},
237+
238+
watch: {
239+
activePage () {
240+
this.currentPage = this.activePage;
197241
},
198242
},
199243

packages/dialtone-vue2/components/pagination/pagination_default.story.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
:total-pages="$attrs.totalPages"
44
:active-page="$attrs.activePage"
55
:max-visible="$attrs.maxVisible"
6+
:hide-edges="$attrs.hideEdges"
67
:aria-label="$attrs.ariaLabel"
78
:prev-aria-label="$attrs.prevAriaLabel"
89
:next-aria-label="$attrs.nextAriaLabel"

packages/dialtone-vue2/components/pagination/pagination_variants.story.vue

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
</p>
77
<dt-pagination
88
:total-pages="10"
9-
:aria-label="'pagination with separator in the end'"
10-
:prev-aria-label="'previous'"
11-
:next-aria-label="'next'"
9+
aria-label="pagination with separator in the end"
10+
prev-aria-label="previous"
11+
next-aria-label="next"
1212
:page-number-aria-label="getPageNumberAriaLabel"
1313
/>
1414
</div>
@@ -19,9 +19,9 @@
1919
<dt-pagination
2020
:total-pages="15"
2121
:active-page="13"
22-
:aria-label="'pagination with separator in the beginning'"
23-
:prev-aria-label="'previous'"
24-
:next-aria-label="'next'"
22+
aria-label="pagination with separator in the beginning"
23+
prev-aria-label="previous"
24+
next-aria-label="next"
2525
:page-number-aria-label="getPageNumberAriaLabel"
2626
/>
2727
</div>
@@ -32,12 +32,26 @@
3232
<dt-pagination
3333
:total-pages="10"
3434
:active-page="5"
35-
:aria-label="'pagination with separator on both sides'"
36-
:prev-aria-label="'previous'"
37-
:next-aria-label="'next'"
35+
aria-label="pagination with separator on both sides"
36+
prev-aria-label="previous"
37+
next-aria-label="next"
3838
:page-number-aria-label="getPageNumberAriaLabel"
3939
/>
4040
</div>
41+
<div class="d-m32">
42+
<p class="d-my16 d-fs-200 d-fw-bold">
43+
Hide edges
44+
</p>
45+
<dt-pagination
46+
:total-pages="10"
47+
:active-page="5"
48+
aria-label="pagination with separator on both sides"
49+
prev-aria-label="previous"
50+
next-aria-label="next"
51+
:page-number-aria-label="getPageNumberAriaLabel"
52+
:hide-edges="true"
53+
/>
54+
</div>
4155
</div>
4256
</template>
4357

packages/dialtone-vue3/components/pagination/pagination.stories.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export const argTypesData = {
3333
type: 'number',
3434
},
3535
},
36+
hideEdges: {
37+
control: {
38+
type: 'boolean',
39+
},
40+
},
3641
ariaLabel: {
3742
control: {
3843
type: 'text',

packages/dialtone-vue3/components/pagination/pagination.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,51 @@ describe('DtPagination Tests', () => {
123123
expect(pages.length).toBe(7);
124124
});
125125
});
126+
127+
describe('When hideEdges is true', () => {
128+
it('shouldn\'t render hidden pages which are the first and last when in middle', () => {
129+
mockProps = {
130+
totalPages: 15,
131+
activePage: 7,
132+
maxVisible: 5,
133+
hideEdges: true,
134+
};
135+
136+
updateWrapper();
137+
138+
expect(pages.length).toBe(7);
139+
expect(pages.at(1).text()).toBe('5');
140+
expect(pages.at(5).text()).toBe('9');
141+
});
142+
143+
it('shouldn\'t render hidden pages which is the last page when at start', () => {
144+
mockProps = {
145+
totalPages: 15,
146+
activePage: 1,
147+
maxVisible: 5,
148+
hideEdges: true,
149+
};
150+
151+
updateWrapper();
152+
153+
expect(pages.length).toBe(7);
154+
expect(pages.at(6).text()).not.toBe('15');
155+
});
156+
157+
it('shouldn\'t render hidden pages which is the first page when at end', () => {
158+
mockProps = {
159+
totalPages: 15,
160+
activePage: 14,
161+
maxVisible: 5,
162+
hideEdges: true,
163+
};
164+
165+
updateWrapper();
166+
167+
expect(pages.length).toBe(7);
168+
expect(pages.at(0).text()).not.toBe('1');
169+
});
170+
});
126171
});
127172

128173
describe('Interactivity Tests', () => {

packages/dialtone-vue3/components/pagination/pagination.vue

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ export default {
143143
type: Number,
144144
default: 5,
145145
},
146+
147+
/**
148+
* Sometimes you may need to hide start and end page number buttons when moving in between.
149+
* This prop will be used to hide the first and last page buttons when not near the edges.
150+
* This is useful when your backend does not support offset and you can only use cursor based pagination.
151+
*/
152+
hideEdges: {
153+
type: Boolean,
154+
default: false,
155+
},
146156
},
147157
148158
emits: [
@@ -178,23 +188,58 @@ export default {
178188
return this.range(1, this.totalPages);
179189
}
180190
181-
const start = this.maxVisible - 1;
182-
const end = this.totalPages - start + 1;
191+
let start = this.maxVisible - 1;
192+
let end = this.totalPages - start + 1;
193+
194+
// if hideEdges is true, modify the start and
195+
// end to account for the hidden pages
196+
if (this.hideEdges) {
197+
start = start + 1;
198+
end = end - 1;
199+
}
183200
184201
if (this.currentPage < start) {
185-
return [...this.range(1, start), '...', this.totalPages];
202+
const pages = [...this.range(1, start), '...'];
203+
if (!this.hideEdges) {
204+
// add last page to the end
205+
pages.push(this.totalPages);
206+
}
207+
return pages;
186208
}
187209
188210
if (this.currentPage > end) {
189-
return [1, '...', ...this.range(end, this.totalPages)];
211+
console.log('END=', end);
212+
const pages = ['...', ...this.range(end, this.totalPages)];
213+
if (!this.hideEdges) {
214+
// add first page to the beginning
215+
pages.unshift(1);
216+
}
217+
return pages;
190218
}
191219
192220
// rounding to the nearest odd according to the maxlength to always show the page number in the middle.
193221
const total = this.maxVisible - (3 - this.maxVisible % 2);
194222
const centerIndex = Math.floor(total / 2);
195-
const left = this.currentPage - centerIndex;
196-
const right = this.currentPage + centerIndex;
197-
return [1, '...', ...this.range(left, right), '...', this.totalPages];
223+
let left = this.currentPage - centerIndex;
224+
let right = this.currentPage + centerIndex;
225+
226+
// if hideEdge is true, modify the left and right to account for the hidden pages
227+
if (this.hideEdges) {
228+
left = left - 1;
229+
right = right + 1;
230+
}
231+
232+
const pages = ['...', ...this.range(left, right), '...'];
233+
if (!this.hideEdges) {
234+
return [1, ...pages, this.totalPages];
235+
}
236+
return pages;
237+
},
238+
},
239+
240+
watch: {
241+
activePage () {
242+
this.currentPage = this.activePage;
198243
},
199244
},
200245

packages/dialtone-vue3/components/pagination/pagination_default.story.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
:total-pages="$attrs.totalPages"
55
:active-page="$attrs.activePage"
66
:max-visible="$attrs.maxVisible"
7+
:hide-edges="$attrs.hideEdges"
78
:prev-aria-label="$attrs.prevAriaLabel"
89
:next-aria-label="$attrs.nextAriaLabel"
910
:page-number-aria-label="getPageNumberAriaLabel"

0 commit comments

Comments
 (0)