Repository: couds/react-bulma-components
Pull request #283 (2020-10-25 06:22:51)

Add pagination first last pages
I am looking for adding first and last page in the pagination component and i found the following pull request.
https://github.com/couds/react-bulma-components/pull/100

The code works great so i forked the latest master and open this new pull request.
Thanks @haflinger and all the authors who have been working on this great module.

haflinger: Thanks @ykyuen !
ykyuen: In addition to the first and last pages, **rounded**, **size** and **position** are also added in pagination.

Usage:
```
<Pagination
  ...
  size={ 'small' }
  rounded={ true }
  position={ 'right' }
  ...
/>
```
MrCreeper1008: @ykyuen thanks for the pr. can you merge into `next` branch instead?
ykyuen: Hi @MrCreeper1008, i am not familiar with typescript. please let me know if it works or not.
ykyuen: @MrCreeper1008 Thanks for letting me know and sorry for the miss. i have updated the code.

Patch:
diff --git a/src/components/pagination/index.d.ts b/src/components/pagination/index.d.ts
index 8759311..28a6a77 100644
--- a/src/components/pagination/index.d.ts
+++ b/src/components/pagination/index.d.ts
@@ -1,5 +1,6 @@
 import * as React from 'react';
 import { BulmaComponent } from 'src/components';
+import { Size } from 'src/modifiers';
 
 interface PaginationProps {
   current?: number;
@@ -10,6 +11,10 @@ interface PaginationProps {
   next?: React.ReactNode;
   previous?: React.ReactNode;
   showPrevNext?: boolean;
+  showFirstLast?: boolean;
+  size?: Size;
+  position?: 'centered' | 'right';
+  rounded?: boolean;
   autoHide?: boolean;
 }
 
diff --git a/src/components/pagination/pagination.js b/src/components/pagination/pagination.js
index 4b62bef..40412c0 100644
--- a/src/components/pagination/pagination.js
+++ b/src/components/pagination/pagination.js
@@ -44,9 +44,13 @@ export default class Pagination extends React.PureComponent {
       next,
       previous,
       showPrevNext,
+      showFirstLast,
       delta,
       autoHide,
       className,
+      size,
+      position,
+      rounded,
       onChange,
       ...props
     } = this.props;
@@ -66,7 +70,11 @@ export default class Pagination extends React.PureComponent {
     return (
       <Element
         {...props}
-        className={classnames('pagination', className)}
+        className={classnames('pagination', className, {
+          [`is-${size}`]: size,
+          [`is-${position}`]: position,
+          'is-rounded': rounded,
+        })}
         aria-label="pagination"
       >
         {showPrevNext && (
@@ -95,6 +103,25 @@ export default class Pagination extends React.PureComponent {
         {delta > 0 && (
           <>
             <ul className="pagination-list">
+              {showFirstLast && current !== 1 && firstPage !== 1 && (
+                <>
+                  <li key={1}>
+                    <a
+                      role="button"
+                      tabIndex={0}
+                      className="pagination-link"
+                      onClick={this.goToPage(1)}
+                      aria-label="Page 1"
+                      aria-current="page"
+                    >
+                      1
+                    </a>
+                  </li>
+                  <li>
+                    <span className="pagination-ellipsis">&hellip;</span>
+                  </li>
+                </>
+              )}
               {Array(lastPage - firstPage + 1)
                 .fill(0)
                 .map((_, i) => (
@@ -119,6 +146,25 @@ export default class Pagination extends React.PureComponent {
                     </a>
                   </li>
                 ))}
+              {showFirstLast && current !== lastPage && total !== lastPage && (
+                <>
+                  <li key={total}>
+                    <span className="pagination-ellipsis">&hellip;</span>
+                  </li>
+                  <li>
+                    <a
+                      role="button"
+                      tabIndex={0}
+                      className="pagination-link"
+                      onClick={this.goToPage(total)}
+                      aria-label={`Page ${total}`}
+                      aria-current="page"
+                    >
+                      {total}
+                    </a>
+                  </li>
+                </>
+              )}
             </ul>
           </>
         )}
@@ -143,11 +189,15 @@ Pagination.propTypes = {
   /** Text of the Previous button */
   previous: PropTypes.node,
   showPrevNext: PropTypes.bool,
+  showFirstLast: PropTypes.bool,
   autoHide: PropTypes.bool,
   /**
    * Classname of the container of the pagination, this could be used to customize the inner views
    */
   className: PropTypes.string,
+  size: PropTypes.oneOf(['small', 'medium', 'large']),
+  position: PropTypes.oneOf(['centered', 'right']),
+  rounded: PropTypes.bool,
 };
 
 Pagination.defaultProps = {
@@ -159,8 +209,12 @@ Pagination.defaultProps = {
   next: 'Next',
   previous: 'Previous',
   showPrevNext: true,
+  showFirstLast: false,
   disabled: undefined,
   autoHide: true,
   className: undefined,
+  size: undefined,
+  position: undefined,
+  rounded: false,
   renderAs: 'nav',
 };
diff --git a/src/components/pagination/pagination.story.js b/src/components/pagination/pagination.story.js
index 1d5d791..2251f44 100644
--- a/src/components/pagination/pagination.story.js
+++ b/src/components/pagination/pagination.story.js
@@ -15,4 +15,13 @@ storiesOf('Pagination', module)
   ))
   .add('With all buttons manually disabled', () => (
     <Pagination disabled current={3} total={5} />
+  ))
+  .add('With first/last pages numbers', () => (
+    <>
+      <Pagination showFirstLast current={3} total={5} delta={1} />
+      <Pagination showFirstLast current={1} total={5} delta={1} />
+      <Pagination showFirstLast current={5} total={5} delta={1} />
+      <Pagination showFirstLast current={2} total={2} delta={1} />
+      <Pagination showFirstLast current={1} total={2} delta={1} />
+    </>
   ));


Test patch:
diff --git a/src/components/pagination/__test__/__snapshots__/pagination.test.js.snap b/src/components/pagination/__test__/__snapshots__/pagination.test.js.snap
index 64efe7e..bafecfe 100644
--- a/src/components/pagination/__test__/__snapshots__/pagination.test.js.snap
+++ b/src/components/pagination/__test__/__snapshots__/pagination.test.js.snap
@@ -133,6 +133,89 @@ exports[`Pagination component Next button should be disabled 1`] = `
 
 exports[`Pagination component Pagination Should Exist 1`] = `[Function]`;
 
+exports[`Pagination component Should display first and last page number 1`] = `
+<nav
+  aria-label="pagination"
+  className="pagination"
+>
+  <a
+    className="pagination-previous"
+    disabled={true}
+    role="button"
+    tabIndex={0}
+    title="This is the first page"
+  >
+    Previous
+  </a>
+  <a
+    className="pagination-next"
+    onClick={[Function]}
+    role="button"
+    tabIndex={0}
+  >
+    Next
+  </a>
+  <ul
+    className="pagination-list"
+  >
+    <li>
+      <a
+        aria-current="page"
+        aria-label="Page 1"
+        className="pagination-link is-current"
+        role="button"
+        tabIndex={0}
+      >
+        1
+      </a>
+    </li>
+    <li>
+      <a
+        aria-current="page"
+        aria-label="Page 2"
+        className="pagination-link"
+        onClick={[Function]}
+        role="button"
+        tabIndex={0}
+      >
+        2
+      </a>
+    </li>
+    <li>
+      <a
+        aria-current="page"
+        aria-label="Page 3"
+        className="pagination-link"
+        onClick={[Function]}
+        role="button"
+        tabIndex={0}
+      >
+        3
+      </a>
+    </li>
+    <li>
+      <span
+        className="pagination-ellipsis"
+      >
+        …
+      </span>
+    </li>
+    <li>
+      <a
+        aria-current="page"
+        aria-label="Page 5"
+        className="pagination-link"
+        onClick={[Function]}
+        role="button"
+        tabIndex={0}
+      >
+        5
+      </a>
+    </li>
+  </ul>
+</nav>
+`;
+
 exports[`Pagination component Should have 3 pages and page 1 active 1`] = `
 <nav
   aria-label="pagination"
diff --git a/src/components/pagination/__test__/pagination.test.js b/src/components/pagination/__test__/pagination.test.js
index ced637d..c63746c 100644
--- a/src/components/pagination/__test__/pagination.test.js
+++ b/src/components/pagination/__test__/pagination.test.js
@@ -21,6 +21,12 @@ describe('Pagination component', () => {
     );
     expect(component.toJSON()).toMatchSnapshot();
   });
+  it('Should display first and last page number', () => {
+    const component = renderer.create(
+      <Pagination showFirstLast current={1} total={5} />,
+    );
+    expect(component.toJSON()).toMatchSnapshot();
+  });
   it('Should not display Previous/Next buttons', () => {
     const component = renderer.create(
       <Pagination showPrevNext={false} delta={3} total={5} current={2} />,