fix(pagination-nav)!: use 1-indexing to be consistent with Pagination (#1518)

Fixes #1513
This commit is contained in:
Enrico Sacchetti 2022-12-13 13:23:04 -05:00 committed by GitHub
commit 8d55752a18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 31 deletions

View file

@ -2695,7 +2695,7 @@ None.
| Prop name | Required | Kind | Reactive | Type | Default value | Description | | Prop name | Required | Kind | Reactive | Type | Default value | Description |
| :----------- | :------- | :--------------- | :------- | -------------------- | ---------------------------- | ----------------------------------------- | | :----------- | :------- | :--------------- | :------- | -------------------- | ---------------------------- | ----------------------------------------- |
| page | No | <code>let</code> | Yes | <code>number</code> | <code>0</code> | Specify the current page index | | page | No | <code>let</code> | Yes | <code>number</code> | <code>1</code> | Specify the current page index |
| total | No | <code>let</code> | No | <code>number</code> | <code>10</code> | Specify the total number of pages | | total | No | <code>let</code> | No | <code>number</code> | <code>10</code> | Specify the total number of pages |
| shown | No | <code>let</code> | No | <code>number</code> | <code>10</code> | Specify the total number of pages to show | | shown | No | <code>let</code> | No | <code>number</code> | <code>10</code> | Specify the total number of pages to show |
| loop | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to loop the navigation | | loop | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to loop the navigation |

View file

@ -8437,7 +8437,7 @@
"kind": "let", "kind": "let",
"description": "Specify the current page index", "description": "Specify the current page index",
"type": "number", "type": "number",
"value": "0", "value": "1",
"isFunction": false, "isFunction": false,
"isFunctionDeclaration": false, "isFunctionDeclaration": false,
"isRequired": false, "isRequired": false,

View file

@ -7,8 +7,8 @@
<PaginationNav bind:page /> <PaginationNav bind:page />
<div style="margin: var(--cds-layout-01) 0"> <div style="margin: var(--cds-layout-01) 0">
<Button on:click="{() => (page = 0)}" disabled="{page === 0}"> <Button on:click="{() => (page = 1)}" disabled="{page === 0}">
Set page to 0 Set page to 1
</Button> </Button>
</div> </div>

View file

@ -1,6 +1,6 @@
<script> <script>
/** Specify the current page index */ /** Specify the current page index */
export let page = 0; export let page = 1;
/** Set to `true` to use the active state */ /** Set to `true` to use the active state */
export let active = false; export let active = false;

View file

@ -1,12 +1,12 @@
<script> <script>
/** /**
* @event {{ page: number; }} change * @event {{ page: number; }} change - fires after every user interaction
* @event {{ page: number; }} click:button--previous * @event {{ page: number; }} click:button--previous
* @event {{ page: number; }} click:button--next * @event {{ page: number; }} click:button--next
*/ */
/** Specify the current page index */ /** Specify the current page index */
export let page = 0; export let page = 1;
/** Specify the total number of pages */ /** Specify the total number of pages */
export let total = 10; export let total = 10;
@ -23,7 +23,7 @@
/** Specify the backward button text */ /** Specify the backward button text */
export let backwardText = "Previous page"; export let backwardText = "Previous page";
import { afterUpdate, createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import CaretLeft from "../icons/CaretLeft.svelte"; import CaretLeft from "../icons/CaretLeft.svelte";
import CaretRight from "../icons/CaretRight.svelte"; import CaretRight from "../icons/CaretRight.svelte";
import PaginationItem from "./PaginationItem.svelte"; import PaginationItem from "./PaginationItem.svelte";
@ -33,13 +33,13 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
const MIN = 4; const MIN = 4;
afterUpdate(() => { // number of overflow pages near the beginning of the nav
dispatch("change", { page });
});
let front = 0; let front = 0;
// number of overflow pages near the end of the nav
let back = 0; let back = 0;
// number of nav overflow or items that may appear
$: fit = shown >= MIN ? shown : MIN; $: fit = shown >= MIN ? shown : MIN;
$: startOffset = fit <= MIN && page > 1 ? 0 : 1; $: startOffset = fit <= MIN && page > 1 ? 0 : 1;
$: if (fit >= total) { $: if (fit >= total) {
@ -49,8 +49,8 @@
$: if (fit < total) { $: if (fit < total) {
const split = Math.ceil(fit / 2) - 1; const split = Math.ceil(fit / 2) - 1;
front = page - split + 1; front = page - split;
back = total - page - (fit - split) + 1; back = total - page - (fit - split) + 2;
if (front <= 1) { if (front <= 1) {
back -= front <= 0 ? Math.abs(front) + 1 : 0; back -= front <= 0 ? Math.abs(front) + 1 : 0;
@ -62,6 +62,9 @@
back = 0; back = 0;
} }
} }
// all enumerable items to render in between
// overflow menus
$: items = Array.from({ length: total }) $: items = Array.from({ length: total })
.map((e, i) => i) .map((e, i) => i)
.slice(startOffset + front, (back + 1) * -1); .slice(startOffset + front, (back + 1) * -1);
@ -75,37 +78,47 @@
tooltipAlignment="center" tooltipAlignment="center"
tooltipPosition="bottom" tooltipPosition="bottom"
iconDescription="{backwardText}" iconDescription="{backwardText}"
disabled="{!loop && page === 0}" disabled="{!loop && page === 1}"
icon="{CaretLeft}" icon="{CaretLeft}"
on:click="{() => { on:click="{() => {
if (page - 1 < 0) { if (page <= 1) {
if (loop) page = total - 1; if (loop) page = total;
} else { } else {
page--; page--;
} }
dispatch('click:button--previous', { page }); dispatch('click:button--previous', { page });
dispatch('change', { page });
}}" }}"
/> />
</li> </li>
{#if fit > MIN || (fit <= MIN && page <= 1)} {#if fit > MIN || (fit <= MIN && page <= 1)}
<PaginationItem <PaginationItem
page="{1}" page="{1}"
active="{page === 0}" active="{page === 1}"
on:click="{() => (page = 0)}" on:click="{() => {
page = 1;
dispatch('change', { page });
}}"
> >
{page === 0 ? "Active, Page" : "Page"} {page === 1 ? "Active, Page" : "Page"}
</PaginationItem> </PaginationItem>
{/if} {/if}
<PaginationOverflow <PaginationOverflow
fromIndex="{startOffset}" fromIndex="{startOffset}"
count="{front}" count="{front}"
on:select="{({ detail }) => (page = detail.index)}" on:select="{({ detail }) => {
page = detail.index;
dispatch('change', { page });
}}"
/> />
{#each items as item} {#each items as item}
<PaginationItem <PaginationItem
page="{item + 1}" page="{item + 1}"
active="{page === item}" active="{page === item + 1}"
on:click="{() => (page = item)}" on:click="{() => {
page = item + 1;
dispatch('change', { page });
}}"
> >
{page === item ? "Active, Page" : "Page"} {page === item ? "Active, Page" : "Page"}
</PaginationItem> </PaginationItem>
@ -115,15 +128,19 @@
count="{back}" count="{back}"
on:select="{({ detail }) => { on:select="{({ detail }) => {
page = detail.index; page = detail.index;
dispatch('change', { page });
}}" }}"
/> />
{#if total > 1} {#if total > 1}
<PaginationItem <PaginationItem
page="{total}" page="{total}"
active="{page === total - 1}" active="{page === total}"
on:click="{() => (page = total - 1)}" on:click="{() => {
page = total;
dispatch('change', { page });
}}"
> >
{page === total - 1 ? "Active, Page" : "Page"} {page === total ? "Active, Page" : "Page"}
</PaginationItem> </PaginationItem>
{/if} {/if}
<li class:bx--pagination-nav__list-item="{true}"> <li class:bx--pagination-nav__list-item="{true}">
@ -132,15 +149,16 @@
tooltipAlignment="center" tooltipAlignment="center"
tooltipPosition="bottom" tooltipPosition="bottom"
iconDescription="{forwardText}" iconDescription="{forwardText}"
disabled="{!loop && page === total - 1}" disabled="{!loop && page === total}"
icon="{CaretRight}" icon="{CaretRight}"
on:click="{() => { on:click="{() => {
if (page + 1 >= total) { if (page >= total) {
if (loop) page = 0; if (loop) page = 1;
} else { } else {
page++; page++;
} }
dispatch('click:button--next', { page }); dispatch('click:button--next', { page });
dispatch('change', { page });
}}" }}"
/> />
</li> </li>

View file

@ -34,7 +34,7 @@
> >
<option value="" hidden></option> <option value="" hidden></option>
{#each Array.from({ length: count }, (_, i) => i) as i} {#each Array.from({ length: count }, (_, i) => i) as i}
<option value="{fromIndex + i}" data-page="{fromIndex + i + 1}"> <option value="{fromIndex + i + 1}" data-page="{fromIndex + i + 1}">
{fromIndex + i + 1} {fromIndex + i + 1}
</option> </option>
{/each} {/each}

View file

@ -5,7 +5,7 @@ export interface PaginationNavProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["nav"]> { extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["nav"]> {
/** /**
* Specify the current page index * Specify the current page index
* @default 0 * @default 1
*/ */
page?: number; page?: number;