fix(pagination): use toLocaleString for default text formatting (#2161)

This commit is contained in:
Eric Liu 2025-04-26 13:39:26 -07:00 committed by GitHub
commit cdf5659fa0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 85 additions and 33 deletions

View file

@ -2682,7 +2682,7 @@ None.
### Props
| Prop name | Required | Kind | Reactive | Type | Default value | Description |
| :-------------------- | :------- | :--------------- | :------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| :-------------------- | :------- | :--------------- | :------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pageSize | No | <code>let</code> | Yes | <code>number</code> | <code>10</code> | Specify the number of items to display in a page |
| page | No | <code>let</code> | Yes | <code>number</code> | <code>1</code> | Specify the current page index |
| totalItems | No | <code>let</code> | No | <code>number</code> | <code>0</code> | Specify the total number of items |
@ -2691,14 +2691,14 @@ None.
| forwardText | No | <code>let</code> | No | <code>string</code> | <code>"Next page"</code> | Specify the forward button text |
| backwardText | No | <code>let</code> | No | <code>string</code> | <code>"Previous page"</code> | Specify the backward button text |
| itemsPerPageText | No | <code>let</code> | No | <code>string</code> | <code>"Items per page:"</code> | Specify the items per page text |
| itemText | No | <code>let</code> | No | <code>(min: number, max: number) => string</code> | <code>(min, max) => \`${min}${max} item${max === 1 ? "" : "s"}\`</code> | Override the item text |
| itemRangeText | No | <code>let</code> | No | <code>(min: number, max: number, total: number) => string</code> | <code>(min, max, total) => \`${min}${max} of ${total} item${max === 1 ? "" : "s"}\`</code> | Override the item range text |
| itemText | No | <code>let</code> | No | <code>(min: number, max: number) => string</code> | <code>(min, max) => \`${min.toLocaleString()}${max.toLocaleString()} item${max === 1 ? "" : "s"}\`</code> | Override the item text |
| itemRangeText | No | <code>let</code> | No | <code>(min: number, max: number, total: number) => string</code> | <code>(min, max, total) => \`${min.toLocaleString()}${max.toLocaleString()} of ${total.toLocaleString()} item${max === 1 ? "" : "s"}\`</code> | Override the item range text |
| pageInputDisabled | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the page input |
| pageSizeInputDisabled | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the page size input |
| pageSizes | No | <code>let</code> | No | <code>ReadonlyArray<number></code> | <code>[10]</code> | Specify the available page sizes |
| pagesUnknown | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` if the number of pages is unknown |
| pageText | No | <code>let</code> | No | <code>(page: number) => string</code> | <code>(page) => \`page ${page}\`</code> | Override the page text |
| pageRangeText | No | <code>let</code> | No | <code>(current: number, total: number) => string</code> | <code>(current, total) => \`of ${total} page${total === 1 ? "" : "s"}\`</code> | Override the page range text |
| pageText | No | <code>let</code> | No | <code>(page: number) => string</code> | <code>(page) => \`page ${page.toLocaleString()}\`</code> | Override the page text |
| pageRangeText | No | <code>let</code> | No | <code>(current: number, total: number) => string</code> | <code>(current, total) => \`of ${total.toLocaleString()} page${total === 1 ? "" : "s"}\`</code> | Override the page range text |
| id | No | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the top-level element |
### Slots

View file

@ -10113,7 +10113,7 @@
"kind": "let",
"description": "Override the item text",
"type": "(min: number, max: number) => string",
"value": "(min, max) =>\n `${min}${max} item${max === 1 ? \"\" : \"s\"}`",
"value": "(min, max) =>\n `${min.toLocaleString()}${max.toLocaleString()} item${max === 1 ? \"\" : \"s\"}`",
"isFunction": true,
"isFunctionDeclaration": false,
"isRequired": false,
@ -10125,7 +10125,7 @@
"kind": "let",
"description": "Override the item range text",
"type": "(min: number, max: number, total: number) => string",
"value": "(\n min,\n max,\n total,\n) =>\n `${min}${max} of ${total} item${max === 1 ? \"\" : \"s\"}`",
"value": "(\n min,\n max,\n total,\n) =>\n `${min.toLocaleString()}${max.toLocaleString()} of ${total.toLocaleString()} item${max === 1 ? \"\" : \"s\"}`",
"isFunction": true,
"isFunctionDeclaration": false,
"isRequired": false,
@ -10197,7 +10197,7 @@
"kind": "let",
"description": "Override the page text",
"type": "(page: number) => string",
"value": "(page) => `page ${page}`",
"value": "(page) => `page ${page.toLocaleString()}`",
"isFunction": true,
"isFunctionDeclaration": false,
"isRequired": false,
@ -10209,7 +10209,7 @@
"kind": "let",
"description": "Override the page range text",
"type": "(current: number, total: number) => string",
"value": "(\n current,\n total,\n) =>\n `of ${total} page${total === 1 ? \"\" : \"s\"}`",
"value": "(\n current,\n total,\n) =>\n `of ${total.toLocaleString()} page${total === 1 ? \"\" : \"s\"}`",
"isFunction": true,
"isFunctionDeclaration": false,
"isRequired": false,

View file

@ -39,14 +39,14 @@
* @type {(min: number, max: number) => string}
*/
export let itemText = (min, max) =>
`${min}${max} item${max === 1 ? "" : "s"}`;
`${min.toLocaleString()}${max.toLocaleString()} item${max === 1 ? "" : "s"}`;
/**
* Override the item range text
* @type {(min: number, max: number, total: number) => string}
*/
export let itemRangeText = (min, max, total) =>
`${min}${max} of ${total} item${max === 1 ? "" : "s"}`;
`${min.toLocaleString()}${max.toLocaleString()} of ${total.toLocaleString()} item${max === 1 ? "" : "s"}`;
/** Set to `true` to disable the page input */
export let pageInputDisabled = false;
@ -70,14 +70,14 @@
* Override the page text
* @type {(page: number) => string}
*/
export let pageText = (page) => `page ${page}`;
export let pageText = (page) => `page ${page.toLocaleString()}`;
/**
* Override the page range text
* @type {(current: number, total: number) => string}
*/
export let pageRangeText = (current, total) =>
`of ${total} page${total === 1 ? "" : "s"}`;
`of ${total.toLocaleString()} page${total === 1 ? "" : "s"}`;
/** Set an id for the top-level element */
export let id = "ccs-" + Math.random().toString(36);

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { Pagination } from "carbon-components-svelte";
import type { ComponentProps } from "svelte";
export let page = 1;
export let totalItems = 0;
@ -10,9 +11,14 @@
export let pageInputDisabled = false;
export let pageSizeInputDisabled = false;
export let pageSize = 10;
export let pageSizes: ReadonlyArray<number> = [10];
export let pageWindow: undefined | number = undefined;
export let pageSizes: ComponentProps<Pagination>["pageSizes"] = [10];
export let pageWindow: ComponentProps<Pagination>["pageWindow"] = undefined;
export let pagesUnknown = false;
export let pageText: ComponentProps<Pagination>["pageText"] = undefined;
export let pageRangeText: ComponentProps<Pagination>["pageRangeText"] =
undefined;
export let itemRangeText: ComponentProps<Pagination>["itemRangeText"] =
undefined;
</script>
<Pagination
@ -28,6 +34,9 @@
bind:pageSize
{pageSizes}
{pagesUnknown}
{pageText}
{pageRangeText}
{itemRangeText}
on:change={(e) => {
console.log("change", e.detail);
}}

View file

@ -214,4 +214,47 @@ describe("Pagination", () => {
const pageNumbers = screen.getByLabelText(/Page number, of 10000 pages/);
expect(pageNumbers).toHaveLength(100 + 1);
});
it("formats larger numbers using `toLocaleString`", () => {
render(Pagination, {
props: { totalItems: 100_000 },
});
expect(screen.getByText(/110 of 100,000 items/)).toBeInTheDocument();
expect(screen.getByText(/of 10,000 pages/)).toBeInTheDocument();
});
it("handles custom page text", () => {
render(Pagination, {
props: {
pagesUnknown: true,
totalItems: 100_000,
pageText: (page) => `Current page ${page}`,
},
});
expect(screen.getByText(/Current page 1/)).toBeInTheDocument();
});
it("handles custom page range text", () => {
render(Pagination, {
props: {
totalItems: 100_000,
pageRangeText: (current, total) => `${current} of ${total}`,
},
});
expect(screen.getByText(/1 of 10000/)).toBeInTheDocument();
});
it("handles custom item range text", () => {
render(Pagination, {
props: {
totalItems: 100_000,
itemRangeText: (min, max, total) => `${min}${max} of ${total}`,
},
});
expect(screen.getByText(/110 of 100000/)).toBeInTheDocument();
});
});

View file

@ -53,13 +53,13 @@ type $Props = {
/**
* Override the item text
* @default (min, max) => `${min}${max} item${max === 1 ? "" : "s"}`
* @default (min, max) => `${min.toLocaleString()}${max.toLocaleString()} item${max === 1 ? "" : "s"}`
*/
itemText?: (min: number, max: number) => string;
/**
* Override the item range text
* @default (min, max, total) => `${min}${max} of ${total} item${max === 1 ? "" : "s"}`
* @default (min, max, total) => `${min.toLocaleString()}${max.toLocaleString()} of ${total.toLocaleString()} item${max === 1 ? "" : "s"}`
*/
itemRangeText?: (min: number, max: number, total: number) => string;
@ -95,13 +95,13 @@ type $Props = {
/**
* Override the page text
* @default (page) => `page ${page}`
* @default (page) => `page ${page.toLocaleString()}`
*/
pageText?: (page: number) => string;
/**
* Override the page range text
* @default (current, total) => `of ${total} page${total === 1 ? "" : "s"}`
* @default (current, total) => `of ${total.toLocaleString()} page${total === 1 ? "" : "s"}`
*/
pageRangeText?: (current: number, total: number) => string;