@juspay/svelte-ui-components 2.88.0 → 2.89.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.
@@ -551,6 +551,7 @@
551
551
  white-space: nowrap;
552
552
  overflow: hidden;
553
553
  text-overflow: ellipsis;
554
+ text-align: var(--select-value-align, left);
554
555
  }
555
556
 
556
557
  .select-placeholder {
@@ -559,6 +560,7 @@
559
560
  white-space: nowrap;
560
561
  overflow: hidden;
561
562
  text-overflow: ellipsis;
563
+ text-align: var(--select-value-align, left);
562
564
  }
563
565
 
564
566
  .select-search {
@@ -543,6 +543,7 @@
543
543
  display: inline-flex;
544
544
  align-items: center;
545
545
  min-width: 0;
546
+ width: var(--table-interactive-width, auto);
546
547
  }
547
548
 
548
549
  .builtin-action-group {
@@ -49,7 +49,10 @@
49
49
  onSearchChange,
50
50
  pagination,
51
51
  toolbarSlot,
52
- rowNumberColumn = false
52
+ rowNumberColumn = false,
53
+ rowNumberLabel = '#',
54
+ headerTooltipIcon,
55
+ headerTooltipPosition
53
56
  }: TableProperties = $props();
54
57
 
55
58
  // ─── Keyed column model → positional projection ─────────────────────────────
@@ -111,14 +114,19 @@
111
114
  };
112
115
 
113
116
  // ─── Row click ───────────────────────────────────────────────────────────────
114
- const handleRowClick = (rowIndex: number, rowData: JSONValue[]): void => {
115
- onRowClick?.(rowIndex, rowData);
117
+ const handleRowClick = (rowIndex: number, rowData: JSONValue[], originalIndex: number): void => {
118
+ onRowClick?.(rowIndex, rowData, originalIndex);
116
119
  };
117
120
 
118
- const handleRowKeydown = (event: KeyboardEvent, rowIndex: number, rowData: JSONValue[]): void => {
121
+ const handleRowKeydown = (
122
+ event: KeyboardEvent,
123
+ rowIndex: number,
124
+ rowData: JSONValue[],
125
+ originalIndex: number
126
+ ): void => {
119
127
  if (event.key === 'Enter' || event.key === ' ') {
120
128
  event.preventDefault();
121
- onRowClick?.(rowIndex, rowData);
129
+ onRowClick?.(rowIndex, rowData, originalIndex);
122
130
  }
123
131
  };
124
132
 
@@ -329,9 +337,10 @@
329
337
  const resolveRowId = (
330
338
  cfg: TableCheckboxSelectionConfig,
331
339
  row: JSONValue[],
332
- rowIndex: number
340
+ rowIndex: number,
341
+ originalIndex: number
333
342
  ): string => {
334
- return cfg.getRowId ? cfg.getRowId(row, rowIndex) : String(rowIndex);
343
+ return cfg.getRowId ? cfg.getRowId(row, rowIndex, originalIndex) : String(rowIndex);
335
344
  };
336
345
 
337
346
  let internalSelectedIds = new SvelteSet<string>();
@@ -374,7 +383,12 @@
374
383
  const originalIndex = indexMap.get(row) ?? -1;
375
384
  const stableIndex = originalIndex === -1 ? fallbackIndex : originalIndex;
376
385
  if (checkboxSelection && checkboxSelection.enabled !== false) {
377
- return resolveRowId(checkboxSelection, row, stableIndex);
386
+ return resolveRowId(
387
+ checkboxSelection,
388
+ row,
389
+ stableIndex,
390
+ originalIndexByRow.get(row) ?? stableIndex
391
+ );
378
392
  }
379
393
  return String(stableIndex);
380
394
  });
@@ -601,7 +615,7 @@
601
615
  {/if}
602
616
  {#if rowNumberColumn}
603
617
  <th class="table-header table-row-number-col" class:table-header-sticky={isStickyHeader}
604
- >#</th
618
+ >{rowNumberLabel}</th
605
619
  >
606
620
  {/if}
607
621
  {#each effectiveHeaders as header, colIndex (colIndex)}
@@ -622,8 +636,16 @@
622
636
  : null}
623
637
  >
624
638
  {#if headerColumn?.tooltip}
625
- <Tooltip text={headerColumn.tooltip}>
626
- <span class="table-header-label">{header}</span>
639
+ <Tooltip
640
+ text={headerColumn.tooltip}
641
+ position={headerTooltipPosition}
642
+ icon={headerTooltipIcon}
643
+ iconPosition="trailing"
644
+ >
645
+ <span
646
+ class="table-header-label"
647
+ class:table-header-label-plain={headerTooltipIcon}>{header}</span
648
+ >
627
649
  </Tooltip>
628
650
  {:else}
629
651
  {header}
@@ -725,9 +747,9 @@
725
747
  class:table-row-clickable={isRowClickable}
726
748
  class:table-row-selected={rowSelected}
727
749
  data-pw={typeof getRowTestId === 'function' ? getRowTestId(row, rowIndex) : null}
728
- onclick={isRowClickable ? () => handleRowClick(rowIndex, row) : null}
750
+ onclick={isRowClickable ? () => handleRowClick(rowIndex, row, originalIndex) : null}
729
751
  onkeydown={isRowClickable
730
- ? (keyboardEvent) => handleRowKeydown(keyboardEvent, rowIndex, row)
752
+ ? (keyboardEvent) => handleRowKeydown(keyboardEvent, rowIndex, row, originalIndex)
731
753
  : null}
732
754
  tabindex={isRowClickable ? 0 : null}
733
755
  >
@@ -979,12 +1001,14 @@
979
1001
  letter-spacing: var(--table-header-letter-spacing, 0.02em);
980
1002
  text-transform: var(--table-header-text-transform);
981
1003
  color: var(--table-header-color, var(--table-header-font-color, #6b7280));
1004
+ border-bottom: var(--table-header-border, var(--table-inner-border, none));
982
1005
  }
983
1006
 
984
1007
  .table-header-content {
985
1008
  display: flex;
986
1009
  align-items: center;
987
1010
  gap: 4px;
1011
+ justify-content: var(--table-header-justify, flex-start);
988
1012
  }
989
1013
 
990
1014
  .table-header-label {
@@ -993,6 +1017,10 @@
993
1017
  cursor: help;
994
1018
  }
995
1019
 
1020
+ .table-header-label-plain {
1021
+ text-decoration: none;
1022
+ }
1023
+
996
1024
  .table-header-filter {
997
1025
  display: inline-flex;
998
1026
  align-items: center;
@@ -1245,6 +1273,7 @@
1245
1273
  width: var(--table-row-number-col-width, 48px);
1246
1274
  color: var(--table-row-number-color, #6b7280);
1247
1275
  font-variant-numeric: tabular-nums;
1276
+ text-align: var(--table-row-number-align, var(--table-text-align, left));
1248
1277
  }
1249
1278
 
1250
1279
  /* ── Accessibility ──────────────────────────────────────────────────────── */
@@ -1,5 +1,6 @@
1
1
  import type { JSONValue } from 'type-decoder';
2
2
  import type { Snippet } from 'svelte';
3
+ import type { TooltipPosition } from '../Tooltip/properties';
3
4
  export type SortDirection = 'asc' | 'desc';
4
5
  /**
5
6
  * Built-in cell renderer vocabulary for the keyed column model.
@@ -244,7 +245,7 @@ export type TableCheckboxSelectionConfig = {
244
245
  enabled?: boolean;
245
246
  selectionMode?: 'single' | 'multiple';
246
247
  onSelectionChange?: (selectedIds: Set<string>) => void;
247
- getRowId?: (row: JSONValue[], rowIndex: number) => string;
248
+ getRowId?: (row: JSONValue[], rowIndex: number, originalIndex: number) => string;
248
249
  disabledRowIds?: Set<string>;
249
250
  /**
250
251
  * Controlled-selection overlay. Omitted: today's uncontrolled behavior via
@@ -335,6 +336,16 @@ export type OptionalTableProperties = {
335
336
  }]>;
336
337
  /** Prepends a sequential row-number column (1-based, pagination-aware). */
337
338
  rowNumberColumn?: boolean;
339
+ /** Header label for the row-number column. Defaults to `'#'`. */
340
+ rowNumberLabel?: string;
341
+ /**
342
+ * Icon snippet shown after each header label that has a `tooltip` — the
343
+ * consumer supplies the glyph; the table places it trailing inside the tooltip
344
+ * trigger. When set, the default underline affordance on those labels is dropped.
345
+ */
346
+ headerTooltipIcon?: Snippet;
347
+ /** Placement of every header tooltip bubble. Defaults to `'top'`. */
348
+ headerTooltipPosition?: TooltipPosition;
338
349
  sortable?: boolean;
339
350
  sortableColumns?: number[];
340
351
  stickyHeader?: boolean;
@@ -367,7 +378,7 @@ export type OptionalTableProperties = {
367
378
  searchConfig?: TableSearchConfig;
368
379
  };
369
380
  export type TableEventProperties = {
370
- onRowClick?: (rowIndex: number, rowData: JSONValue[]) => void;
381
+ onRowClick?: (rowIndex: number, rowData: JSONValue[], originalIndex: number) => void;
371
382
  onSort?: (columnIndex: number, direction: SortDirection) => void;
372
383
  /**
373
384
  * C2-2: Callback invoked when a cell value changes via an editable element
@@ -11,6 +11,7 @@
11
11
  classes,
12
12
  children,
13
13
  icon,
14
+ iconPosition = 'leading',
14
15
  content,
15
16
  usePortal = false
16
17
  }: TooltipProperties = $props();
@@ -355,10 +356,13 @@
355
356
  onfocusout={hideTooltip}
356
357
  data-pw={testId}
357
358
  >
358
- {#if typeof icon === 'function'}
359
+ {#if typeof icon === 'function' && iconPosition === 'leading'}
359
360
  <span class="tooltip-icon" aria-hidden="true">{@render icon()}</span>
360
361
  {/if}
361
362
  {@render children()}
363
+ {#if typeof icon === 'function' && iconPosition === 'trailing'}
364
+ <span class="tooltip-icon" aria-hidden="true">{@render icon()}</span>
365
+ {/if}
362
366
  {#if visible && !usePortal}
363
367
  <div
364
368
  use:clampInlineBubble
@@ -9,8 +9,10 @@ export type OptionalTooltipProperties = {
9
9
  delay?: number;
10
10
  testId?: string | null;
11
11
  classes?: string;
12
- /** Snippet rendered as a leading icon in the trigger wrapper. No default glyph is provided — consumers supply their own. */
12
+ /** Snippet rendered as an icon in the trigger wrapper, beside the content. No default glyph is provided — consumers supply their own. Placement is controlled by `iconPosition`. */
13
13
  icon?: Snippet;
14
+ /** Which side of the trigger content the `icon` sits on. Defaults to `'leading'`. */
15
+ iconPosition?: 'leading' | 'trailing';
14
16
  /** Snippet rendered as the bubble body. When provided, replaces the plain `text` string inside the tooltip bubble. */
15
17
  content?: Snippet;
16
18
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "2.88.0",
3
+ "version": "2.89.1",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",