carbon-components-svelte 0.89.0 → 0.89.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Design systems facilitate design and development through reuse, consistency, and
|
|
|
14
14
|
The Carbon Svelte portfolio also includes:
|
|
15
15
|
|
|
16
16
|
- **[Carbon Icons Svelte](https://github.com/carbon-design-system/carbon-icons-svelte)**: 2,400+ Carbon icons as Svelte components
|
|
17
|
-
- **[Carbon Pictograms Svelte](https://github.com/carbon-design-system/carbon-pictograms-svelte)**: 1,
|
|
17
|
+
- **[Carbon Pictograms Svelte](https://github.com/carbon-design-system/carbon-pictograms-svelte)**: 1,300+ Carbon pictograms as Svelte components
|
|
18
18
|
- **[Carbon Charts Svelte](https://github.com/carbon-design-system/carbon-charts/tree/master/packages/svelte)**: 25+ charts, powered by d3
|
|
19
19
|
- **[Carbon Preprocess Svelte](https://github.com/carbon-design-system/carbon-preprocess-svelte)**: Collection of Svelte preprocessors for Carbon
|
|
20
20
|
|
package/package.json
CHANGED
|
@@ -46,15 +46,39 @@
|
|
|
46
46
|
*/
|
|
47
47
|
export let ref = null;
|
|
48
48
|
|
|
49
|
-
import { tick, getContext } from "svelte";
|
|
49
|
+
import { tick, getContext, afterUpdate, onMount } from "svelte";
|
|
50
50
|
import Search from "../Search/Search.svelte";
|
|
51
51
|
|
|
52
52
|
const ctx = getContext("DataTable") ?? {};
|
|
53
53
|
|
|
54
|
+
let rows = null;
|
|
55
|
+
let unsubscribe = null;
|
|
56
|
+
|
|
54
57
|
$: if (shouldFilterRows) {
|
|
55
|
-
|
|
58
|
+
unsubscribe = ctx?.tableRows.subscribe((tableRows) => {
|
|
59
|
+
// Only update if the rows have actually changed.
|
|
60
|
+
// This approach works in both Svelte 4 and Svelte 5.
|
|
61
|
+
if (JSON.stringify(tableRows) !== JSON.stringify(rows)) {
|
|
62
|
+
rows = tableRows;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
rows = null;
|
|
56
67
|
}
|
|
57
68
|
|
|
69
|
+
onMount(() => {
|
|
70
|
+
return () => {
|
|
71
|
+
unsubscribe?.();
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
afterUpdate(() => {
|
|
76
|
+
// Only filter rows in a callback to avoid an infinite update loop.
|
|
77
|
+
if (rows !== null) {
|
|
78
|
+
filteredRowIds = ctx?.filterRows(value, shouldFilterRows);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
58
82
|
async function expandSearch() {
|
|
59
83
|
await tick();
|
|
60
84
|
if (disabled || persistent || expanded) return;
|
|
@@ -12,6 +12,16 @@
|
|
|
12
12
|
/** Specify the total number of items */
|
|
13
13
|
export let totalItems = 0;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* If `totalItems` is a large number, it can affect the
|
|
17
|
+
* rendering performance of this component since its value
|
|
18
|
+
* is used to calculate the number of pages in the native
|
|
19
|
+
* select dropdown. This value creates a small window of
|
|
20
|
+
* pages rendered around the current page. By default,
|
|
21
|
+
* a maximum of 1000 select items are rendered.
|
|
22
|
+
*/
|
|
23
|
+
export let pageWindow = 1000;
|
|
24
|
+
|
|
15
25
|
/** Set to `true` to disable the pagination */
|
|
16
26
|
export let disabled = false;
|
|
17
27
|
|
|
@@ -29,14 +39,14 @@
|
|
|
29
39
|
* @type {(min: number, max: number) => string}
|
|
30
40
|
*/
|
|
31
41
|
export let itemText = (min, max) =>
|
|
32
|
-
`${min}–${max} item${max === 1 ? "" : "s"}`;
|
|
42
|
+
`${min.toLocaleString()}–${max.toLocaleString()} item${max === 1 ? "" : "s"}`;
|
|
33
43
|
|
|
34
44
|
/**
|
|
35
45
|
* Override the item range text
|
|
36
46
|
* @type {(min: number, max: number, total: number) => string}
|
|
37
47
|
*/
|
|
38
48
|
export let itemRangeText = (min, max, total) =>
|
|
39
|
-
`${min}–${max} of ${total} item${max === 1 ? "" : "s"}`;
|
|
49
|
+
`${min.toLocaleString()}–${max.toLocaleString()} of ${total.toLocaleString()} item${max === 1 ? "" : "s"}`;
|
|
40
50
|
|
|
41
51
|
/** Set to `true` to disable the page input */
|
|
42
52
|
export let pageInputDisabled = false;
|
|
@@ -60,14 +70,14 @@
|
|
|
60
70
|
* Override the page text
|
|
61
71
|
* @type {(page: number) => string}
|
|
62
72
|
*/
|
|
63
|
-
export let pageText = (page) => `page ${page}`;
|
|
73
|
+
export let pageText = (page) => `page ${page.toLocaleString()}`;
|
|
64
74
|
|
|
65
75
|
/**
|
|
66
76
|
* Override the page range text
|
|
67
77
|
* @type {(current: number, total: number) => string}
|
|
68
78
|
*/
|
|
69
79
|
export let pageRangeText = (current, total) =>
|
|
70
|
-
`of ${total} page${total === 1 ? "" : "s"}`;
|
|
80
|
+
`of ${total.toLocaleString()} page${total === 1 ? "" : "s"}`;
|
|
71
81
|
|
|
72
82
|
/** Set an id for the top-level element */
|
|
73
83
|
export let id = "ccs-" + Math.random().toString(36);
|
|
@@ -81,6 +91,21 @@
|
|
|
81
91
|
|
|
82
92
|
const dispatch = createEventDispatcher();
|
|
83
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Returns a subset of page numbers centered around the current page to prevent
|
|
96
|
+
* performance issues with large datasets. Creates a capped window of pages
|
|
97
|
+
* instead of potentially thousands, improving render speed and memory usage.
|
|
98
|
+
* @param {number} currentPage - The current page number
|
|
99
|
+
* @param {number} totalPages - Total number of pages
|
|
100
|
+
* @param {number} window - How many pages to show before/after current page
|
|
101
|
+
* @returns {number[]} Array of page numbers to display
|
|
102
|
+
*/
|
|
103
|
+
function getWindowedPages(currentPage, totalPages, window) {
|
|
104
|
+
const start = Math.max(1, currentPage - window);
|
|
105
|
+
const end = Math.min(totalPages, currentPage + window);
|
|
106
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
107
|
+
}
|
|
108
|
+
|
|
84
109
|
afterUpdate(() => {
|
|
85
110
|
if (page > totalPages) {
|
|
86
111
|
page = totalPages;
|
|
@@ -89,7 +114,7 @@
|
|
|
89
114
|
|
|
90
115
|
$: dispatch("update", { pageSize, page });
|
|
91
116
|
$: totalPages = Math.max(Math.ceil(totalItems / pageSize), 1);
|
|
92
|
-
$: selectItems =
|
|
117
|
+
$: selectItems = getWindowedPages(page, totalPages, pageWindow);
|
|
93
118
|
$: backButtonDisabled = disabled || page === 1;
|
|
94
119
|
$: forwardButtonDisabled = disabled || page === totalPages;
|
|
95
120
|
</script>
|
|
@@ -146,7 +171,7 @@
|
|
|
146
171
|
bind:selected={page}
|
|
147
172
|
>
|
|
148
173
|
{#each selectItems as size, i (size)}
|
|
149
|
-
<SelectItem value={size
|
|
174
|
+
<SelectItem value={size} text={size.toString()} />
|
|
150
175
|
{/each}
|
|
151
176
|
</Select>
|
|
152
177
|
<span class:bx--pagination__text={true}>
|
package/src/utils/toHierarchy.js
CHANGED
|
@@ -13,22 +13,35 @@
|
|
|
13
13
|
export function toHierarchy(flatArray, getParentId) {
|
|
14
14
|
/** @type {NodeLike[]} */
|
|
15
15
|
const tree = [];
|
|
16
|
-
const
|
|
16
|
+
const childrenOf = new Map();
|
|
17
|
+
const itemsMap = new Map(flatArray.map((item) => [item.id, item]));
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
flatArray.forEach((item) => {
|
|
19
20
|
const parentId = getParentId(item);
|
|
20
|
-
nodeMap.set(item.id, item);
|
|
21
21
|
|
|
22
|
-
if
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
// Only create nodes array if we have children.
|
|
23
|
+
const children = childrenOf.get(item.id);
|
|
24
|
+
if (children) {
|
|
25
|
+
item.nodes = children;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check if parentId exists using Map instead of array lookup.
|
|
29
|
+
const parentExists = parentId && itemsMap.has(parentId);
|
|
30
|
+
|
|
31
|
+
if (parentId && parentExists) {
|
|
32
|
+
if (!childrenOf.has(parentId)) {
|
|
33
|
+
childrenOf.set(parentId, []);
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
childrenOf.get(parentId).push(item);
|
|
36
|
+
|
|
37
|
+
const parent = itemsMap.get(parentId);
|
|
38
|
+
if (parent) {
|
|
39
|
+
parent.nodes = childrenOf.get(parentId);
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
tree.push(item);
|
|
30
43
|
}
|
|
31
|
-
}
|
|
44
|
+
});
|
|
32
45
|
|
|
33
46
|
return tree;
|
|
34
47
|
}
|
|
@@ -16,6 +16,17 @@ type $Props = {
|
|
|
16
16
|
*/
|
|
17
17
|
totalItems?: number;
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* If `totalItems` is a large number, it can affect the
|
|
21
|
+
* rendering performance of this component since its value
|
|
22
|
+
* is used to calculate the number of pages in the native
|
|
23
|
+
* select dropdown. This value creates a small window of
|
|
24
|
+
* pages rendered around the current page. By default,
|
|
25
|
+
* a maximum of 1000 select items are rendered.
|
|
26
|
+
* @default 1000
|
|
27
|
+
*/
|
|
28
|
+
pageWindow?: number;
|
|
29
|
+
|
|
19
30
|
/**
|
|
20
31
|
* Set to `true` to disable the pagination
|
|
21
32
|
* @default false
|
|
@@ -42,13 +53,13 @@ type $Props = {
|
|
|
42
53
|
|
|
43
54
|
/**
|
|
44
55
|
* Override the item text
|
|
45
|
-
* @default (min, max) => `${min}–${max} item${max === 1 ? "" : "s"}`
|
|
56
|
+
* @default (min, max) => `${min.toLocaleString()}–${max.toLocaleString()} item${max === 1 ? "" : "s"}`
|
|
46
57
|
*/
|
|
47
58
|
itemText?: (min: number, max: number) => string;
|
|
48
59
|
|
|
49
60
|
/**
|
|
50
61
|
* Override the item range text
|
|
51
|
-
* @default (min, max, total) => `${min}–${max} of ${total} item${max === 1 ? "" : "s"}`
|
|
62
|
+
* @default (min, max, total) => `${min.toLocaleString()}–${max.toLocaleString()} of ${total.toLocaleString()} item${max === 1 ? "" : "s"}`
|
|
52
63
|
*/
|
|
53
64
|
itemRangeText?: (min: number, max: number, total: number) => string;
|
|
54
65
|
|
|
@@ -84,13 +95,13 @@ type $Props = {
|
|
|
84
95
|
|
|
85
96
|
/**
|
|
86
97
|
* Override the page text
|
|
87
|
-
* @default (page) => `page ${page}`
|
|
98
|
+
* @default (page) => `page ${page.toLocaleString()}`
|
|
88
99
|
*/
|
|
89
100
|
pageText?: (page: number) => string;
|
|
90
101
|
|
|
91
102
|
/**
|
|
92
103
|
* Override the page range text
|
|
93
|
-
* @default (current, total) => `of ${total} page${total === 1 ? "" : "s"}`
|
|
104
|
+
* @default (current, total) => `of ${total.toLocaleString()} page${total === 1 ? "" : "s"}`
|
|
94
105
|
*/
|
|
95
106
|
pageRangeText?: (current: number, total: number) => string;
|
|
96
107
|
|