Skip to content

Commit ee8b639

Browse files
committed
feat(pagination): allow to hide next and previous buttons
1 parent d7a8e70 commit ee8b639

File tree

5 files changed

+80
-39
lines changed

5 files changed

+80
-39
lines changed

apps/website/src/routes/docs/headless/(components)/pagination/examples.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import HidePrevNextButtons from '@/apps/website/src/routes/docs/headless/(components)/pagination/examples/hidePrevNextButtons';
12
import { JSXNode, component$ } from '@builder.io/qwik';
23
import { PreviewCodeExampleTabs } from '../../../_components/preview-code-example/preview-code-example-tabs';
34

45
import Basic from './examples/basic';
56
import Interactive from './examples/interactive';
67
import basicCode from './examples/basic?raw';
78
import interactiveCode from './examples/interactive?raw';
9+
import hidePrevNextButtonsCode from './examples/hidePrevNextButtons?raw';
810

911
export type Example = {
1012
component: JSXNode;
@@ -21,6 +23,10 @@ export const examples: Record<string, Example> = {
2123
component: <Interactive />,
2224
code: interactiveCode,
2325
},
26+
hidePrevNextButtons: {
27+
component: <HidePrevNextButtons />,
28+
code: hidePrevNextButtonsCode,
29+
},
2430
};
2531

2632
export type ShowExampleProps = {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { component$, useSignal } from '@builder.io/qwik';
2+
import { Pagination } from '@qwik-ui/headless';
3+
4+
export default component$(() => {
5+
const selectedPage = useSignal(1);
6+
const totalPages = useSignal(10);
7+
8+
return (
9+
<div class="mt-4 flex flex-col gap-6">
10+
<Pagination
11+
selectedPage={selectedPage.value}
12+
totalPages={totalPages.value}
13+
onPageChange$={(page) => {
14+
selectedPage.value = page;
15+
}}
16+
hidePrevButton={true}
17+
hideNextButton={true}
18+
/>
19+
</div>
20+
);
21+
});

apps/website/src/routes/docs/headless/(components)/pagination/examples/interactive.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export default component$(() => {
66
const selectedPage = useSignal(1);
77
const totalPages = useSignal(10);
88

9-
const hideNextButton = useSignal(true);
10-
const hidePrevButton = useSignal(true);
9+
const hideNextButton = useSignal(false);
10+
const hidePrevButton = useSignal(false);
1111
const siblingCount = useSignal(1);
1212
const boundaryCount = useSignal(1);
1313

@@ -24,6 +24,8 @@ export default component$(() => {
2424
defaultClass="border-2 border-sky-400 p-4"
2525
selectedClass="border-2 border-red-500 bg-red-500 p-4"
2626
dividerClass="p-4"
27+
hidePrevButton={hidePrevButton.value}
28+
hideNextButton={hideNextButton.value}
2729
gap={'10px'}
2830
>
2931
<span q:slot="prefix">👈</span>

apps/website/src/routes/docs/headless/(components)/pagination/index.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ import testImage from '../../../../../../public/images/test-image.png'
2929
## Basic Example
3030

3131
<ShowExample example="basic" />
32+
33+
## Hide Next/Prev Buttons
34+
35+
<ShowExample example="hidePrevNextButtons" />

packages/kit-headless/src/components/pagination/pagination.tsx

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
11
import { usePagination } from '@/packages/kit-headless/src/components/pagination/use-pagination';
22
import type { PropFunction } from '@builder.io/qwik';
3-
import { component$, Slot, useSignal, useTask$ } from '@builder.io/qwik';
3+
import { component$, Slot, useSignal, useTask$, useVisibleTask$ } from '@builder.io/qwik';
44

55
/**
66
* TODO
77
* show / hide PREV / NEXT buttons
88
* customArrowTexts: { previous: '...', next: '... }
99
* disabled: enable/disable paginator
1010
*
11-
* FLUFFY THEME
12-
* size: 'sm' | 'md' | 'lg'
13-
* variant: 'primary' | 'secondary' | ...
14-
* outline
15-
* square
1611
*/
1712

1813
export interface PaginationProps {
19-
class?: string;
2014
selectedPage: number;
2115
totalPages: number;
2216
onPageChange$: PropFunction<(page: number) => void>;
2317

2418
// configuration
2519
siblingCount?: number;
2620
boundaryCount?: number;
21+
hidePrevButton?: boolean;
22+
hideNextButton?: boolean;
23+
2724
// styles
25+
class?: string;
2826
gap?: number | string;
2927
defaultClass?: string;
3028
selectedClass?: string;
@@ -33,16 +31,20 @@ export interface PaginationProps {
3331

3432
export const Pagination = component$<PaginationProps>(
3533
({
36-
class: _class,
3734
selectedPage,
3835
totalPages,
3936
onPageChange$,
37+
38+
siblingCount = 1,
39+
boundaryCount = 1,
40+
hidePrevButton = false,
41+
hideNextButton = false,
42+
43+
class: _class,
4044
gap = '10px',
4145
defaultClass,
4246
selectedClass,
4347
dividerClass,
44-
siblingCount = 1,
45-
boundaryCount = 1,
4648
}) => {
4749
const visibleItems = useSignal<(string | number)[]>([]);
4850

@@ -53,6 +55,9 @@ export const Pagination = component$<PaginationProps>(
5355
boundaryCount,
5456
);
5557

58+
const isPrevButtonVisible = () => !hidePrevButton && selectedPage > 1;
59+
const isNextButtonVisible = () => !hideNextButton && selectedPage !== totalPages;
60+
5661
return (
5762
<nav
5863
role="navigation"
@@ -61,20 +66,21 @@ export const Pagination = component$<PaginationProps>(
6166
style={{ display: 'flex', alignItems: 'center', gap: gap }}
6267
>
6368
{/* PREV BUTTON */}
64-
<button
65-
type="button"
66-
aria-label={'prevAriaLabel'}
67-
disabled={selectedPage <= 1}
68-
onClick$={() => {
69-
if (selectedPage > 1) {
70-
onPageChange$(selectedPage - 1);
71-
}
72-
}}
73-
>
74-
<Slot name="prefix" />
75-
<span>PREV</span>
76-
</button>
77-
69+
{isPrevButtonVisible() && (
70+
<button
71+
type="button"
72+
aria-label={'prevAriaLabel'}
73+
disabled={selectedPage <= 1}
74+
onClick$={() => {
75+
if (selectedPage > 1) {
76+
onPageChange$(selectedPage - 1);
77+
}
78+
}}
79+
>
80+
<Slot name="prefix" />
81+
<span>PREV</span>
82+
</button>
83+
)}
7884
{visibleItems.value.map((item: string | number, index: number) => {
7985
return (
8086
<span key={index}>
@@ -98,19 +104,21 @@ export const Pagination = component$<PaginationProps>(
98104
})}
99105

100106
{/* NEXT BUTTON */}
101-
<button
102-
type="button"
103-
aria-label={'nextAriaLabel'}
104-
disabled={selectedPage >= totalPages}
105-
onClick$={() => {
106-
if (selectedPage < totalPages) {
107-
onPageChange$(selectedPage + 1);
108-
}
109-
}}
110-
>
111-
<span>NEXT</span>
112-
<Slot name="suffix" />
113-
</button>
107+
{isNextButtonVisible() && (
108+
<button
109+
type="button"
110+
aria-label={'nextAriaLabel'}
111+
disabled={selectedPage >= totalPages}
112+
onClick$={() => {
113+
if (selectedPage < totalPages) {
114+
onPageChange$(selectedPage + 1);
115+
}
116+
}}
117+
>
118+
<span>NEXT</span>
119+
<Slot name="suffix" />
120+
</button>
121+
)}
114122
</nav>
115123
);
116124
},

0 commit comments

Comments
 (0)