@gridkitjs/core 0.13.0 → 0.14.1

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/dist/index.js CHANGED
@@ -102,6 +102,13 @@ function accessDotted(obj, path) {
102
102
  return path.split(".").reduce((value, key) => isNested(value) ? value[key] : void 0, obj);
103
103
  }
104
104
 
105
+ // src/util/position.ts
106
+ function renumberRows(entries) {
107
+ return entries.map(
108
+ (entry, index) => entry.rowIndex === index && entry.datasetIndex === index ? entry : { ...entry, rowIndex: index, datasetIndex: index }
109
+ );
110
+ }
111
+
105
112
  // src/util/sorting.ts
106
113
  function isEmpty(value) {
107
114
  return value === null || value === void 0;
@@ -189,9 +196,7 @@ function sortRows(rows, sort, columns) {
189
196
  }
190
197
  return 0;
191
198
  });
192
- return sorted.map(
193
- (row, index) => row.rowIndex === index ? row : { ...row, rowIndex: index }
194
- );
199
+ return renumberRows(sorted);
195
200
  }
196
201
 
197
202
  // src/util/grouping.ts
@@ -263,9 +268,7 @@ function buildLevel(rows, levels, parentPath, expansion, byId, out) {
263
268
  path,
264
269
  expanded,
265
270
  count: group.rows.length,
266
- // Renumbered globally once `groupRows` has the whole flattened array —
267
- // a header has no row of its own to carry a dataset position, so
268
- // `datasetIndex` takes the same renumbered value `rowIndex` does.
271
+ // Both set by `groupRows` once it has the whole flattened array.
269
272
  rowIndex: -1,
270
273
  datasetIndex: -1,
271
274
  // Set by `withGroupAggregates`, downstream of grouping — empty here
@@ -289,12 +292,7 @@ function groupRows(rows, groupBy, expansion, columns) {
289
292
  }
290
293
  const out = [];
291
294
  buildLevel(rows, active, [], expansion, byId, out);
292
- return out.map((entry, index) => {
293
- if ("kind" in entry) {
294
- return entry.rowIndex === index && entry.datasetIndex === index ? entry : { ...entry, rowIndex: index, datasetIndex: index };
295
- }
296
- return entry.rowIndex === index ? entry : { ...entry, rowIndex: index };
297
- });
295
+ return renumberRows(out);
298
296
  }
299
297
  function toggleGroupExpansion(expansion, groupId) {
300
298
  return expansion.includes(groupId) ? expansion.filter((id) => id !== groupId) : [...expansion, groupId];
@@ -985,12 +983,7 @@ function withGroupAggregates(displayRows, flatRows, groupBy, specs, columns, dis
985
983
  display,
986
984
  out
987
985
  );
988
- return out.map((entry, position) => {
989
- if ("kind" in entry) {
990
- return entry.rowIndex === position && entry.datasetIndex === position ? entry : { ...entry, rowIndex: position, datasetIndex: position };
991
- }
992
- return entry.rowIndex === position ? entry : { ...entry, rowIndex: position };
993
- });
986
+ return renumberRows(out);
994
987
  }
995
988
 
996
989
  // src/util/filtering.ts
@@ -1151,9 +1144,7 @@ function filterRows(rows, filter, columns) {
1151
1144
  return rows;
1152
1145
  }
1153
1146
  const filtered = rows.filter((row) => test(row.row));
1154
- return filtered.map(
1155
- (row, index) => row.rowIndex === index ? row : { ...row, rowIndex: index }
1156
- );
1147
+ return renumberRows(filtered);
1157
1148
  }
1158
1149
 
1159
1150
  // src/util/rows.ts
@@ -3030,21 +3021,37 @@ function resolveColumnFilterMenu(options, column) {
3030
3021
  }
3031
3022
 
3032
3023
  // src/messages.ts
3033
- function columnCount(count, change) {
3034
- return count === 1 ? `1 column ${change}` : `${String(count)} columns ${change}`;
3024
+ function localeKey2(locale) {
3025
+ return typeof locale === "string" ? locale : locale?.join(",") ?? "";
3026
+ }
3027
+ var countFormats = /* @__PURE__ */ new Map();
3028
+ function countFormat(locale) {
3029
+ const key = localeKey2(locale);
3030
+ let format = countFormats.get(key);
3031
+ if (format === void 0) {
3032
+ const numberFormat = new Intl.NumberFormat(locale, {
3033
+ maximumFractionDigits: 0
3034
+ });
3035
+ format = (count) => numberFormat.format(count);
3036
+ countFormats.set(key, format);
3037
+ }
3038
+ return format;
3035
3039
  }
3036
- function searchResults(count) {
3040
+ function columnCount(n, count, change) {
3041
+ return count === 1 ? `1 column ${change}` : `${n(count)} columns ${change}`;
3042
+ }
3043
+ function searchResults(n, count) {
3037
3044
  if (count === 0) {
3038
3045
  return "No rows found";
3039
3046
  }
3040
- return count === 1 ? "1 row found" : `${String(count)} rows found`;
3047
+ return count === 1 ? "1 row found" : `${n(count)} rows found`;
3041
3048
  }
3042
- function selectedCount(count, target) {
3049
+ function selectedCount(n, count, target) {
3043
3050
  const noun = target === "rows" ? "row" : "column";
3044
3051
  if (count === 0) {
3045
3052
  return `No ${noun}s selected`;
3046
3053
  }
3047
- return count === 1 ? `1 ${noun} selected` : `${String(count)} ${noun}s selected`;
3054
+ return count === 1 ? `1 ${noun} selected` : `${n(count)} ${noun}s selected`;
3048
3055
  }
3049
3056
  var operatorLabels = {
3050
3057
  eq: "Equals",
@@ -3071,11 +3078,11 @@ var dateOperatorLabels = {
3071
3078
  function filterOperatorLabel(operator, family) {
3072
3079
  return (family === "date" ? dateOperatorLabels[operator] : void 0) ?? operatorLabels[operator];
3073
3080
  }
3074
- function filterSearchFirst(total) {
3075
- return total === 1 ? "Type to search 1 value" : `Type to search ${String(total)} values`;
3081
+ function filterSearchFirst(n, total) {
3082
+ return total === 1 ? "Type to search 1 value" : `Type to search ${n(total)} values`;
3076
3083
  }
3077
- function filterResults(shown, total) {
3078
- return `${String(shown)} of ${String(total)} ${total === 1 ? "row" : "rows"}`;
3084
+ function filterResults(n, shown, total) {
3085
+ return `${n(shown)} of ${n(total)} ${total === 1 ? "row" : "rows"}`;
3079
3086
  }
3080
3087
  var filterValueRequests = {
3081
3088
  text: "Enter a value",
@@ -3089,117 +3096,137 @@ var filterOperatorMenus = {
3089
3096
  date: "Date filters",
3090
3097
  boolean: "Boolean filters"
3091
3098
  };
3092
- function copied(count, unit) {
3093
- return count === 1 ? `1 ${unit.slice(0, -1)} copied` : `${String(count)} ${unit} copied`;
3094
- }
3095
- var defaultMessages = {
3096
- pagerLabel: "Pagination",
3097
- previousPage: "Previous",
3098
- nextPage: "Next",
3099
- pageSizeLabel: "Rows per page",
3100
- pageButtonLabel: (page) => `Page ${String(page)}`,
3101
- pageStatus: (page, pageCount) => `Page ${String(page)} of ${String(pageCount)}`,
3102
- loadingMore: "Loading more\u2026",
3103
- booleanTrue: "true",
3104
- booleanFalse: "false",
3105
- blankGroupValue: "(blank)",
3106
- groupByBarLabel: "Grouped by",
3107
- groupByBarPlaceholder: "Drag a column here to group by it",
3108
- groupByChipLabel: (columnName2, level, levelCount) => levelCount > 1 ? `${columnName2}, level ${String(level)} of ${String(levelCount)}` : columnName2,
3109
- removeGroupBy: (columnName2) => `Stop grouping by ${columnName2}`,
3110
- columnResized: (columnName2, width) => `${columnName2}, ${String(width)} pixels wide`,
3111
- columnMoved: (columnName2, position, columnCount2) => `${columnName2}, column ${String(position)} of ${String(columnCount2)}`,
3112
- columnSorted: (columnName2, direction, key, keyCount) => {
3113
- const sorted = `${columnName2} sorted ${direction === "asc" ? "ascending" : "descending"}`;
3114
- return keyCount > 1 ? `${sorted}, key ${String(key)} of ${String(keyCount)}` : sorted;
3115
- },
3116
- sortCleared: (columnName2) => `${columnName2}, sort cleared`,
3117
- groupedBy: (columnName2, level, levelCount) => levelCount > 1 ? `Grouped by ${columnName2}, level ${String(level)} of ${String(levelCount)}` : `Grouped by ${columnName2}`,
3118
- groupingRemoved: (columnName2) => `${columnName2}, grouping removed`,
3119
- groupExpanded: "Group expanded",
3120
- groupCollapsed: "Group collapsed",
3121
- allGroupsExpanded: "All groups expanded",
3122
- allGroupsCollapsed: "All groups collapsed",
3123
- selectedCount,
3124
- cellSelected: (columnName2, rowNumber) => `${columnName2}, row ${String(rowNumber)}, selected`,
3125
- columnHidden: (columnName2) => `${columnName2}, column hidden`,
3126
- columnShown: (columnName2) => `${columnName2}, column shown`,
3127
- columnsHidden: (count) => columnCount(count, "hidden"),
3128
- columnsShown: (count) => columnCount(count, "shown"),
3129
- columnsAutoFitted: (count) => columnCount(count, "autofitted"),
3130
- headerMenuLabel: (columnName2) => `${columnName2} column menu`,
3131
- cellMenuLabel: "Row menu",
3132
- groupMenuLabel: "Group menu",
3133
- bodyMenuLabel: "Grid menu",
3134
- sortAscending: "Sort ascending",
3135
- sortDescending: "Sort descending",
3136
- clearSort: "Clear sort",
3137
- clearAllSorting: "Clear all sorting",
3138
- groupByColumn: (columnName2) => `Group by ${columnName2}`,
3139
- ungroupAll: "Ungroup all",
3140
- expandAllGroups: "Expand all groups",
3141
- collapseAllGroups: "Collapse all groups",
3142
- hideColumn: "Hide column",
3143
- autoFitColumn: "Autofit column",
3144
- autoFitAllColumns: "Autofit all columns",
3145
- selectAllRows: "Select all rows",
3146
- clearSelection: "Clear selection",
3147
- clearFilters: "Clear filters",
3148
- chooseColumns: "Choose columns",
3149
- toolbarLabel: "Grid toolbar",
3150
- searchLabel: "Search",
3151
- searchPlaceholder: "Search\u2026",
3152
- moreToolbarItems: "More",
3153
- searchResults,
3154
- columnChooserLabel: "Columns",
3155
- columnChooserSearchLabel: "Search columns",
3156
- showAllColumns: "Show all",
3157
- noMatchingColumns: "No matching columns",
3158
- filterOperatorLabel,
3159
- filterBlanks: "(Blanks)",
3160
- filterSearchFirst,
3161
- filterMoreValues: (count) => `${String(count)} more, refine the search`,
3162
- openFilter: "Filter\u2026",
3163
- clearColumnFilter: "Clear filter",
3164
- filterMenuLabel: (columnName2) => `${columnName2} filter`,
3165
- columnFiltered: "Filtered",
3166
- applyFilter: "OK",
3167
- cancelFilter: "Cancel",
3168
- customFilter: "Custom filter",
3169
- filterResults,
3170
- filterConditionLabel: (position) => `Condition ${String(position)}`,
3171
- filterOperatorFieldLabel: "Operator",
3172
- filterValueLabel: "Value",
3173
- filterFromLabel: "From",
3174
- filterToLabel: "To",
3175
- filterCombinatorLabel: "Combine conditions",
3176
- filterAnd: "And",
3177
- filterOr: "Or",
3178
- filterValueInvalid: (family) => filterValueRequests[family],
3179
- filterSearchLabel: "Search values",
3180
- filterSelectAll: "Select all",
3181
- filterValuesLabel: "Values",
3182
- filterByCondition: "Filtered by condition",
3183
- filterOperatorMenu: (family) => filterOperatorMenus[family],
3184
- filterBackToValues: "Back to values",
3185
- exportMenu: "Export",
3186
- exportCsv: "Export to CSV",
3187
- exportJson: "Export to JSON",
3188
- exportXlsx: "Export to Excel",
3189
- exportPdf: "Export to PDF",
3190
- exportSelectionCsv: "Export selection to CSV",
3191
- exportSelectionJson: "Export selection to JSON",
3192
- exportSelectionXlsx: "Export selection to Excel",
3193
- exportFailed: "Export failed",
3194
- copyCell: "Copy cell",
3195
- copyRow: "Copy row",
3196
- copySelection: "Copy selection",
3197
- copied,
3198
- copyFailed: "Copy failed",
3199
- print: "Print"
3200
- };
3201
- function resolveMessages(messages) {
3202
- return messages === void 0 ? defaultMessages : { ...defaultMessages, ...messages };
3099
+ function copied(n, count, unit) {
3100
+ return count === 1 ? `1 ${unit.slice(0, -1)} copied` : `${n(count)} ${unit} copied`;
3101
+ }
3102
+ function createDefaultMessages(locale) {
3103
+ const n = countFormat(locale);
3104
+ return {
3105
+ pagerLabel: "Pagination",
3106
+ firstPage: "First",
3107
+ previousPage: "Previous",
3108
+ nextPage: "Next",
3109
+ lastPage: "Last",
3110
+ pageSizeLabel: "Rows per page",
3111
+ pageButtonLabel: (page) => `Page ${n(page)}`,
3112
+ pageStatus: (page, pageCount) => `Page ${n(page)} of ${n(pageCount)}`,
3113
+ loadingMore: "Loading more\u2026",
3114
+ booleanTrue: "true",
3115
+ booleanFalse: "false",
3116
+ blankGroupValue: "(blank)",
3117
+ groupByBarLabel: "Grouped by",
3118
+ groupByBarPlaceholder: "Drag a column here to group by it",
3119
+ groupByChipLabel: (columnName2, level, levelCount) => levelCount > 1 ? `${columnName2}, level ${n(level)} of ${n(levelCount)}` : columnName2,
3120
+ removeGroupBy: (columnName2) => `Stop grouping by ${columnName2}`,
3121
+ columnResized: (columnName2, width) => `${columnName2}, ${n(width)} pixels wide`,
3122
+ columnMoved: (columnName2, position, columnCount2) => `${columnName2}, column ${n(position)} of ${n(columnCount2)}`,
3123
+ columnSorted: (columnName2, direction, key, keyCount) => {
3124
+ const sorted = `${columnName2} sorted ${direction === "asc" ? "ascending" : "descending"}`;
3125
+ return keyCount > 1 ? `${sorted}, key ${n(key)} of ${n(keyCount)}` : sorted;
3126
+ },
3127
+ sortCleared: (columnName2) => `${columnName2}, sort cleared`,
3128
+ groupedBy: (columnName2, level, levelCount) => levelCount > 1 ? `Grouped by ${columnName2}, level ${n(level)} of ${n(levelCount)}` : `Grouped by ${columnName2}`,
3129
+ groupingRemoved: (columnName2) => `${columnName2}, grouping removed`,
3130
+ groupExpanded: "Group expanded",
3131
+ groupCollapsed: "Group collapsed",
3132
+ allGroupsExpanded: "All groups expanded",
3133
+ allGroupsCollapsed: "All groups collapsed",
3134
+ selectedCount: (count, target) => selectedCount(n, count, target),
3135
+ cellSelected: (columnName2, rowNumber) => `${columnName2}, row ${n(rowNumber)}, selected`,
3136
+ columnHidden: (columnName2) => `${columnName2}, column hidden`,
3137
+ columnShown: (columnName2) => `${columnName2}, column shown`,
3138
+ columnsHidden: (count) => columnCount(n, count, "hidden"),
3139
+ columnsShown: (count) => columnCount(n, count, "shown"),
3140
+ columnsAutoFitted: (count) => columnCount(n, count, "autofitted"),
3141
+ headerMenuLabel: (columnName2) => `${columnName2} column menu`,
3142
+ cellMenuLabel: "Row menu",
3143
+ groupMenuLabel: "Group menu",
3144
+ bodyMenuLabel: "Grid menu",
3145
+ sortAscending: "Sort ascending",
3146
+ sortDescending: "Sort descending",
3147
+ clearSort: "Clear sort",
3148
+ clearAllSorting: "Clear all sorting",
3149
+ groupByColumn: (columnName2) => `Group by ${columnName2}`,
3150
+ ungroupAll: "Ungroup all",
3151
+ expandAllGroups: "Expand all groups",
3152
+ collapseAllGroups: "Collapse all groups",
3153
+ hideColumn: "Hide column",
3154
+ autoFitColumn: "Autofit column",
3155
+ autoFitAllColumns: "Autofit all columns",
3156
+ selectAllRows: "Select all rows",
3157
+ clearSelection: "Clear selection",
3158
+ clearFilters: "Clear filters",
3159
+ chooseColumns: "Choose columns",
3160
+ toolbarLabel: "Grid toolbar",
3161
+ searchLabel: "Search",
3162
+ searchPlaceholder: "Search\u2026",
3163
+ moreToolbarItems: "More",
3164
+ searchResults: (count) => searchResults(n, count),
3165
+ columnChooserLabel: "Columns",
3166
+ columnChooserSearchLabel: "Search columns",
3167
+ showAllColumns: "Show all",
3168
+ noMatchingColumns: "No matching columns",
3169
+ filterOperatorLabel,
3170
+ filterBlanks: "(Blanks)",
3171
+ filterSearchFirst: (total) => filterSearchFirst(n, total),
3172
+ filterMoreValues: (count) => `${n(count)} more, refine the search`,
3173
+ openFilter: "Filter\u2026",
3174
+ clearColumnFilter: "Clear filter",
3175
+ filterMenuLabel: (columnName2) => `${columnName2} filter`,
3176
+ columnFiltered: "Filtered",
3177
+ applyFilter: "OK",
3178
+ cancelFilter: "Cancel",
3179
+ customFilter: "Custom filter",
3180
+ filterResults: (shown, total) => filterResults(n, shown, total),
3181
+ filterConditionLabel: (position) => `Condition ${n(position)}`,
3182
+ filterOperatorFieldLabel: "Operator",
3183
+ filterValueLabel: "Value",
3184
+ filterFromLabel: "From",
3185
+ filterToLabel: "To",
3186
+ filterCombinatorLabel: "Combine conditions",
3187
+ filterAnd: "And",
3188
+ filterOr: "Or",
3189
+ filterValueInvalid: (family) => filterValueRequests[family],
3190
+ filterSearchLabel: "Search values",
3191
+ filterSelectAll: "Select all",
3192
+ filterValuesLabel: "Values",
3193
+ filterByCondition: "Filtered by condition",
3194
+ filterOperatorMenu: (family) => filterOperatorMenus[family],
3195
+ filterBackToValues: "Back to values",
3196
+ exportMenu: "Export",
3197
+ exportCsv: "Export to CSV",
3198
+ exportJson: "Export to JSON",
3199
+ exportXlsx: "Export to Excel",
3200
+ exportPdf: "Export to PDF",
3201
+ exportSelectionCsv: "Export selection to CSV",
3202
+ exportSelectionJson: "Export selection to JSON",
3203
+ exportSelectionXlsx: "Export selection to Excel",
3204
+ exportFailed: "Export failed",
3205
+ copyCell: "Copy cell",
3206
+ copyRow: "Copy row",
3207
+ copySelection: "Copy selection",
3208
+ copied: (count, unit) => copied(n, count, unit),
3209
+ copyFailed: "Copy failed",
3210
+ print: "Print"
3211
+ };
3212
+ }
3213
+ var defaultMessages = createDefaultMessages();
3214
+ var localeDefaults = /* @__PURE__ */ new Map();
3215
+ function defaultsFor(locale) {
3216
+ if (locale === void 0) {
3217
+ return defaultMessages;
3218
+ }
3219
+ const key = localeKey2(locale);
3220
+ let defaults = localeDefaults.get(key);
3221
+ if (defaults === void 0) {
3222
+ defaults = createDefaultMessages(locale);
3223
+ localeDefaults.set(key, defaults);
3224
+ }
3225
+ return defaults;
3226
+ }
3227
+ function resolveMessages(messages, locale) {
3228
+ const defaults = defaultsFor(locale);
3229
+ return messages === void 0 ? defaults : { ...defaults, ...messages };
3203
3230
  }
3204
3231
 
3205
3232
  // src/util/filterEditor.ts
@@ -3283,7 +3310,7 @@ function columnValueOptions(rows, dataColumns, filter, columnId, query = {}) {
3283
3310
  }
3284
3311
  }
3285
3312
  const { search = "", limit, locale } = query;
3286
- const messages = resolveMessages(query.messages);
3313
+ const messages = resolveMessages(query.messages, locale);
3287
3314
  const options = [...buckets.values()].sort((a, b) => compareValues(a.value, b.value, column.type)).map(({ value, row, count }) => ({
3288
3315
  value,
3289
3316
  label: formatCellValue(value, column, locale, row, messages),
@@ -4342,32 +4369,31 @@ function paginationWindow(currentPage, pageCount, options) {
4342
4369
  if (pageCount <= 0) {
4343
4370
  return [];
4344
4371
  }
4345
- const boundaryCount = Math.max(0, options?.boundaryCount ?? 1);
4346
- const siblingCount = Math.max(0, options?.siblingCount ?? 1);
4347
- const current = Math.min(Math.max(currentPage, 1), pageCount);
4348
- const pages = /* @__PURE__ */ new Set();
4349
- for (let page = 1; page <= Math.min(boundaryCount, pageCount); page++) {
4350
- pages.add(page);
4372
+ const boundaryCount = Math.max(0, Math.floor(options?.boundaryCount ?? 1));
4373
+ const siblingCount = Math.max(0, Math.floor(options?.siblingCount ?? 1));
4374
+ const slotCount = 2 * boundaryCount + 2 * siblingCount + 3;
4375
+ if (pageCount <= slotCount) {
4376
+ return Array.from({ length: pageCount }, (_, index) => index + 1);
4351
4377
  }
4352
- for (let page = Math.max(pageCount - boundaryCount + 1, 1); page <= pageCount; page++) {
4353
- pages.add(page);
4378
+ const current = Math.min(Math.max(currentPage, 1), pageCount);
4379
+ const runStart = Math.min(
4380
+ Math.max(current - siblingCount, boundaryCount + 2),
4381
+ pageCount - boundaryCount - 1 - 2 * siblingCount
4382
+ );
4383
+ const runEnd = runStart + 2 * siblingCount;
4384
+ const entries = [];
4385
+ for (let page = 1; page <= boundaryCount; page++) {
4386
+ entries.push(page);
4354
4387
  }
4355
- for (let page = Math.max(current - siblingCount, 1); page <= Math.min(current + siblingCount, pageCount); page++) {
4356
- pages.add(page);
4388
+ entries.push(runStart === boundaryCount + 2 ? boundaryCount + 1 : "ellipsis");
4389
+ for (let page = runStart; page <= runEnd; page++) {
4390
+ entries.push(page);
4357
4391
  }
4358
- const sorted = Array.from(pages).sort((a, b) => a - b);
4359
- const entries = [];
4360
- let previous;
4361
- for (const page of sorted) {
4362
- if (previous !== void 0) {
4363
- if (page - previous === 2) {
4364
- entries.push(previous + 1);
4365
- } else if (page - previous > 2) {
4366
- entries.push("ellipsis");
4367
- }
4368
- }
4392
+ entries.push(
4393
+ runEnd === pageCount - boundaryCount - 1 ? pageCount - boundaryCount : "ellipsis"
4394
+ );
4395
+ for (let page = pageCount - boundaryCount + 1; page <= pageCount; page++) {
4369
4396
  entries.push(page);
4370
- previous = page;
4371
4397
  }
4372
4398
  return entries;
4373
4399
  }
@@ -4627,6 +4653,7 @@ export {
4627
4653
  copyContent,
4628
4654
  createColumnValueOptionsCache,
4629
4655
  createCommandContext,
4656
+ createDefaultMessages,
4630
4657
  createGridController,
4631
4658
  createGridViewResolver,
4632
4659
  csvWriter,