@juspay/svelte-ui-components 2.87.0 → 2.89.0
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.
|
@@ -33,11 +33,13 @@
|
|
|
33
33
|
let {
|
|
34
34
|
column,
|
|
35
35
|
value,
|
|
36
|
-
rowIndex
|
|
36
|
+
rowIndex,
|
|
37
|
+
originalIndex
|
|
37
38
|
}: {
|
|
38
39
|
column: TableColumn;
|
|
39
40
|
value: TableCellValue;
|
|
40
41
|
rowIndex: number;
|
|
42
|
+
originalIndex: number;
|
|
41
43
|
} = $props();
|
|
42
44
|
|
|
43
45
|
let copied = $state(false);
|
|
@@ -226,7 +228,7 @@
|
|
|
226
228
|
<Toggle
|
|
227
229
|
checked={isChecked}
|
|
228
230
|
text=""
|
|
229
|
-
onclick={(newChecked) => column.onToggle?.(rowIndex, newChecked)}
|
|
231
|
+
onclick={(newChecked) => column.onToggle?.(rowIndex, newChecked, originalIndex)}
|
|
230
232
|
/>
|
|
231
233
|
</span>
|
|
232
234
|
{:else if column.type === 'select'}
|
|
@@ -247,7 +249,7 @@
|
|
|
247
249
|
itemTestId={selectData.itemTestId}
|
|
248
250
|
onchange={(selectedIds) => {
|
|
249
251
|
if (selectedIds.length > 0) {
|
|
250
|
-
column.onSelect?.(rowIndex, selectedIds[0]);
|
|
252
|
+
column.onSelect?.(rowIndex, selectedIds[0], originalIndex);
|
|
251
253
|
}
|
|
252
254
|
}}
|
|
253
255
|
/>
|
|
@@ -275,7 +277,7 @@
|
|
|
275
277
|
: null}
|
|
276
278
|
onErrorMessage={inputData.onErrorMessage ?? null}
|
|
277
279
|
actionInput={false}
|
|
278
|
-
onInput={(newValue) => column.onInput?.(rowIndex, newValue)}
|
|
280
|
+
onInput={(newValue) => column.onInput?.(rowIndex, newValue, originalIndex)}
|
|
279
281
|
/>
|
|
280
282
|
</span>
|
|
281
283
|
{:else}
|
|
@@ -295,7 +297,7 @@
|
|
|
295
297
|
disabled={buttonData.disabled ?? false}
|
|
296
298
|
classes={buttonData.classes ?? ''}
|
|
297
299
|
testId={buttonData.testId}
|
|
298
|
-
onclick={() => column.onButtonClick?.(rowIndex)}
|
|
300
|
+
onclick={() => column.onButtonClick?.(rowIndex, originalIndex)}
|
|
299
301
|
/>
|
|
300
302
|
</span>
|
|
301
303
|
{:else}
|
|
@@ -317,7 +319,7 @@
|
|
|
317
319
|
disabled={primary.disabled ?? false}
|
|
318
320
|
classes={primary.classes ?? ''}
|
|
319
321
|
testId={primary.testId}
|
|
320
|
-
onclick={() => column.onPrimaryAction?.(rowIndex)}
|
|
322
|
+
onclick={() => column.onPrimaryAction?.(rowIndex, originalIndex)}
|
|
321
323
|
/>
|
|
322
324
|
{/if}
|
|
323
325
|
{#if actionData.menuItems && actionData.menuItems.length > 0}
|
|
@@ -329,7 +331,7 @@
|
|
|
329
331
|
separator: item.separator
|
|
330
332
|
}))}
|
|
331
333
|
testId={column.testId && `${column.testId}-menu-${rowIndex}`}
|
|
332
|
-
onselect={(menuItem) => column.onMenuAction?.(rowIndex, menuItem.value)}
|
|
334
|
+
onselect={(menuItem) => column.onMenuAction?.(rowIndex, menuItem.value, originalIndex)}
|
|
333
335
|
>
|
|
334
336
|
{#snippet trigger()}
|
|
335
337
|
<span class="builtin-icon-button">
|
|
@@ -367,7 +369,7 @@
|
|
|
367
369
|
separator: item.separator
|
|
368
370
|
}))}
|
|
369
371
|
testId={column.testId && `${column.testId}-popup-${rowIndex}`}
|
|
370
|
-
onselect={(menuItem) => column.onMenuAction?.(rowIndex, menuItem.value)}
|
|
372
|
+
onselect={(menuItem) => column.onMenuAction?.(rowIndex, menuItem.value, originalIndex)}
|
|
371
373
|
>
|
|
372
374
|
{#snippet trigger()}
|
|
373
375
|
<span class="builtin-icon-button">
|
package/dist/Table/Table.svelte
CHANGED
|
@@ -59,6 +59,10 @@
|
|
|
59
59
|
let normalized = $derived(columns ? normalizeColumns(columns, rows ?? []) : null);
|
|
60
60
|
let effectiveHeaders = $derived(normalized ? normalized.tableHeaders : tableHeaders);
|
|
61
61
|
let effectiveData = $derived(normalized ? normalized.tableData : tableData);
|
|
62
|
+
// Maps each row reference back to its index in the consumer-supplied `rows`
|
|
63
|
+
// (pre-sort/pre-filter). Row refs are preserved through sort/filter/paginate,
|
|
64
|
+
// so cell callbacks can hand consumers a sort-stable `originalIndex`.
|
|
65
|
+
let originalIndexByRow = $derived(new Map(effectiveData.map((row, index) => [row, index])));
|
|
62
66
|
let effectiveSortableColumns = $derived(
|
|
63
67
|
normalized ? normalized.sortableColumns : sortableColumns
|
|
64
68
|
);
|
|
@@ -107,14 +111,19 @@
|
|
|
107
111
|
};
|
|
108
112
|
|
|
109
113
|
// ─── Row click ───────────────────────────────────────────────────────────────
|
|
110
|
-
const handleRowClick = (rowIndex: number, rowData: JSONValue[]): void => {
|
|
111
|
-
onRowClick?.(rowIndex, rowData);
|
|
114
|
+
const handleRowClick = (rowIndex: number, rowData: JSONValue[], originalIndex: number): void => {
|
|
115
|
+
onRowClick?.(rowIndex, rowData, originalIndex);
|
|
112
116
|
};
|
|
113
117
|
|
|
114
|
-
const handleRowKeydown = (
|
|
118
|
+
const handleRowKeydown = (
|
|
119
|
+
event: KeyboardEvent,
|
|
120
|
+
rowIndex: number,
|
|
121
|
+
rowData: JSONValue[],
|
|
122
|
+
originalIndex: number
|
|
123
|
+
): void => {
|
|
115
124
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
116
125
|
event.preventDefault();
|
|
117
|
-
onRowClick?.(rowIndex, rowData);
|
|
126
|
+
onRowClick?.(rowIndex, rowData, originalIndex);
|
|
118
127
|
}
|
|
119
128
|
};
|
|
120
129
|
|
|
@@ -325,9 +334,10 @@
|
|
|
325
334
|
const resolveRowId = (
|
|
326
335
|
cfg: TableCheckboxSelectionConfig,
|
|
327
336
|
row: JSONValue[],
|
|
328
|
-
rowIndex: number
|
|
337
|
+
rowIndex: number,
|
|
338
|
+
originalIndex: number
|
|
329
339
|
): string => {
|
|
330
|
-
return cfg.getRowId ? cfg.getRowId(row, rowIndex) : String(rowIndex);
|
|
340
|
+
return cfg.getRowId ? cfg.getRowId(row, rowIndex, originalIndex) : String(rowIndex);
|
|
331
341
|
};
|
|
332
342
|
|
|
333
343
|
let internalSelectedIds = new SvelteSet<string>();
|
|
@@ -370,7 +380,12 @@
|
|
|
370
380
|
const originalIndex = indexMap.get(row) ?? -1;
|
|
371
381
|
const stableIndex = originalIndex === -1 ? fallbackIndex : originalIndex;
|
|
372
382
|
if (checkboxSelection && checkboxSelection.enabled !== false) {
|
|
373
|
-
return resolveRowId(
|
|
383
|
+
return resolveRowId(
|
|
384
|
+
checkboxSelection,
|
|
385
|
+
row,
|
|
386
|
+
stableIndex,
|
|
387
|
+
originalIndexByRow.get(row) ?? stableIndex
|
|
388
|
+
);
|
|
374
389
|
}
|
|
375
390
|
return String(stableIndex);
|
|
376
391
|
});
|
|
@@ -712,6 +727,7 @@
|
|
|
712
727
|
{:else}
|
|
713
728
|
{#each paginatedTableData as row, pageRowIndex (rowIdByRow.get(row) ?? pageRowIndex)}
|
|
714
729
|
{@const rowIndex = pageRowIndex + rowIndexOffset}
|
|
730
|
+
{@const originalIndex = originalIndexByRow.get(row) ?? rowIndex}
|
|
715
731
|
{@const rowId = rowIdByRow.get(row) ?? String(rowIndex)}
|
|
716
732
|
{@const rowDisabled = isCheckboxMode && isRowDisabled(rowId)}
|
|
717
733
|
{@const rowSelected = isCheckboxMode && isRowSelected(rowId)}
|
|
@@ -720,9 +736,9 @@
|
|
|
720
736
|
class:table-row-clickable={isRowClickable}
|
|
721
737
|
class:table-row-selected={rowSelected}
|
|
722
738
|
data-pw={typeof getRowTestId === 'function' ? getRowTestId(row, rowIndex) : null}
|
|
723
|
-
onclick={isRowClickable ? () => handleRowClick(rowIndex, row) : null}
|
|
739
|
+
onclick={isRowClickable ? () => handleRowClick(rowIndex, row, originalIndex) : null}
|
|
724
740
|
onkeydown={isRowClickable
|
|
725
|
-
? (keyboardEvent) => handleRowKeydown(keyboardEvent, rowIndex, row)
|
|
741
|
+
? (keyboardEvent) => handleRowKeydown(keyboardEvent, rowIndex, row, originalIndex)
|
|
726
742
|
: null}
|
|
727
743
|
tabindex={isRowClickable ? 0 : null}
|
|
728
744
|
>
|
|
@@ -781,9 +797,14 @@
|
|
|
781
797
|
class:table-cell-clamp={keyedColumn?.maxWidth && isScalarCell}
|
|
782
798
|
>
|
|
783
799
|
{#if keyedColumn && typeof keyedColumn.cell === 'function' && keyedRow}
|
|
784
|
-
{@render keyedColumn.cell(keyedRow, rowIndex)}
|
|
800
|
+
{@render keyedColumn.cell(keyedRow, rowIndex, originalIndex)}
|
|
785
801
|
{:else if keyedColumn?.type && keyedColumn.type !== 'text' && keyedColumn.type !== 'custom'}
|
|
786
|
-
<BuiltinCell
|
|
802
|
+
<BuiltinCell
|
|
803
|
+
column={keyedColumn}
|
|
804
|
+
value={cellValue}
|
|
805
|
+
{rowIndex}
|
|
806
|
+
{originalIndex}
|
|
807
|
+
/>
|
|
787
808
|
{:else if typeof cell === 'function'}
|
|
788
809
|
{@render cell(cellValue, rowIndex, colIndex)}
|
|
789
810
|
{:else}
|
|
@@ -172,9 +172,9 @@ export type TableRow = Record<string, TableCellValue>;
|
|
|
172
172
|
* `sortable` prop. Equivalent to listing/omitting the column's index in
|
|
173
173
|
* `sortableColumns`.
|
|
174
174
|
* - `testId` — `data-pw` attribute emitted on this column's header cell.
|
|
175
|
-
* - `cell` — column-scoped renderer snippet receiving the full keyed row
|
|
176
|
-
*
|
|
177
|
-
* this column; required when `type` is `'custom'`.
|
|
175
|
+
* - `cell` — column-scoped renderer snippet receiving the full keyed row, the
|
|
176
|
+
* display row index, and the original (pre-sort) row index. Takes precedence
|
|
177
|
+
* over the table-wide `cell` snippet for this column; required when `type` is `'custom'`.
|
|
178
178
|
* - `onToggle`/`onSelect`/`onInput`/`onButtonClick`/`onPrimaryAction`/`onMenuAction`
|
|
179
179
|
* — change/action handlers for the matching interactive cell types. Behavior
|
|
180
180
|
* lives on the column so row data stays plain JSON.
|
|
@@ -185,7 +185,7 @@ export type TableColumn = {
|
|
|
185
185
|
type?: TableColumnType;
|
|
186
186
|
sortable?: boolean;
|
|
187
187
|
testId?: string;
|
|
188
|
-
cell?: Snippet<[TableRow, number]>;
|
|
188
|
+
cell?: Snippet<[TableRow, number, number]>;
|
|
189
189
|
/** Header tooltip text, shown on hover over the column label. */
|
|
190
190
|
tooltip?: string;
|
|
191
191
|
/**
|
|
@@ -207,13 +207,19 @@ export type TableColumn = {
|
|
|
207
207
|
* the cell value itself.
|
|
208
208
|
*/
|
|
209
209
|
getSortValue?: (row: TableRow, rowIndex: number) => string | number | boolean;
|
|
210
|
-
/**
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Row-action handlers. `rowIndex` is the row's position in the CURRENT
|
|
212
|
+
* (sorted/filtered/paginated) view; `originalIndex` is its position in the
|
|
213
|
+
* consumer-supplied `rows` array, stable under sort/filter — index your own
|
|
214
|
+
* source array with `originalIndex` so actions hit the correct row when the
|
|
215
|
+
* table is sorted. `checked` is the NEW state after the flip, not the pre-click value.
|
|
216
|
+
*/
|
|
217
|
+
onToggle?: (rowIndex: number, checked: boolean, originalIndex: number) => void;
|
|
218
|
+
onSelect?: (rowIndex: number, selectedId: string, originalIndex: number) => void;
|
|
219
|
+
onInput?: (rowIndex: number, value: string, originalIndex: number) => void;
|
|
220
|
+
onButtonClick?: (rowIndex: number, originalIndex: number) => void;
|
|
221
|
+
onPrimaryAction?: (rowIndex: number, originalIndex: number) => void;
|
|
222
|
+
onMenuAction?: (rowIndex: number, itemId: string, originalIndex: number) => void;
|
|
217
223
|
};
|
|
218
224
|
/**
|
|
219
225
|
* Configuration for row checkbox selection (C2-1).
|
|
@@ -238,7 +244,7 @@ export type TableCheckboxSelectionConfig = {
|
|
|
238
244
|
enabled?: boolean;
|
|
239
245
|
selectionMode?: 'single' | 'multiple';
|
|
240
246
|
onSelectionChange?: (selectedIds: Set<string>) => void;
|
|
241
|
-
getRowId?: (row: JSONValue[], rowIndex: number) => string;
|
|
247
|
+
getRowId?: (row: JSONValue[], rowIndex: number, originalIndex: number) => string;
|
|
242
248
|
disabledRowIds?: Set<string>;
|
|
243
249
|
/**
|
|
244
250
|
* Controlled-selection overlay. Omitted: today's uncontrolled behavior via
|
|
@@ -361,7 +367,7 @@ export type OptionalTableProperties = {
|
|
|
361
367
|
searchConfig?: TableSearchConfig;
|
|
362
368
|
};
|
|
363
369
|
export type TableEventProperties = {
|
|
364
|
-
onRowClick?: (rowIndex: number, rowData: JSONValue[]) => void;
|
|
370
|
+
onRowClick?: (rowIndex: number, rowData: JSONValue[], originalIndex: number) => void;
|
|
365
371
|
onSort?: (columnIndex: number, direction: SortDirection) => void;
|
|
366
372
|
/**
|
|
367
373
|
* C2-2: Callback invoked when a cell value changes via an editable element
|