@kouji-ui/core 0.9.2 → 0.10.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.
@@ -22156,6 +22156,54 @@ class KjTable {
22156
22156
  setRowCount(n) {
22157
22157
  this._rowCount.set(n);
22158
22158
  }
22159
+ /**
22160
+ * Server-side infinite mode. When on, `kjTableData` is index-aligned with
22161
+ * the server's result set and may hold holes (`undefined` / `null`) for
22162
+ * rows that are not loaded yet: the holes are dropped before the rows reach
22163
+ * TanStack, and {@link sourceIndex} maps each loaded row back to its
22164
+ * position in the full result set. Sorting, filtering and pagination are
22165
+ * left to the server (TanStack's `manual*` flags), so a header click only
22166
+ * changes `state.sorting()` — feed it into your loader's request.
22167
+ */
22168
+ _infinite = signal(false, /* @ts-ignore */
22169
+ ...(ngDevMode ? [{ debugName: "_infinite" }] : /* istanbul ignore next */ []));
22170
+ /** Whether server-side infinite mode is on — see {@link setInfinite}. */
22171
+ infinite = this._infinite.asReadonly();
22172
+ /**
22173
+ * Turn server-side infinite mode on or off.
22174
+ * @param on `true` while the data is a sparse window of a server result set.
22175
+ */
22176
+ setInfinite(on) {
22177
+ this._infinite.set(on);
22178
+ }
22179
+ /** Rows handed to TanStack plus, in infinite mode, their positions in the full result set. */
22180
+ compacted = computed(() => {
22181
+ const data = this.kjTableData();
22182
+ if (!this._infinite())
22183
+ return { rows: data, sourceIndex: null };
22184
+ const rows = [];
22185
+ const sourceIndex = [];
22186
+ // `forEach` skips true holes, so a `new Array(total)` window costs only
22187
+ // its loaded entries.
22188
+ data.forEach((row, i) => {
22189
+ if (row == null)
22190
+ return;
22191
+ rows.push(row);
22192
+ sourceIndex.push(i);
22193
+ });
22194
+ return { rows, sourceIndex };
22195
+ }, /* @ts-ignore */
22196
+ ...(ngDevMode ? [{ debugName: "compacted" }] : /* istanbul ignore next */ []));
22197
+ /**
22198
+ * In infinite mode, the result-set position of each loaded top-level row,
22199
+ * indexed by its TanStack `row.index`; `null` otherwise.
22200
+ */
22201
+ sourceIndex = computed(() => this.compacted().sourceIndex, /* @ts-ignore */
22202
+ ...(ngDevMode ? [{ debugName: "sourceIndex" }] : /* istanbul ignore next */ []));
22203
+ /** Position of a top-level row in the full result set (its `row.index` outside infinite mode). */
22204
+ sourceIndexOf(index) {
22205
+ return this.compacted().sourceIndex?.[index] ?? index;
22206
+ }
22159
22207
  /**
22160
22208
  * Apply a TanStack updater (value or function) to a single state slice.
22161
22209
  *
@@ -22198,11 +22246,15 @@ class KjTable {
22198
22246
  ...(ngDevMode ? [{ debugName: "boundColumns" }] : /* istanbul ignore next */ []));
22199
22247
  /** The TanStack table instance. Access rows, headers, and state here. */
22200
22248
  table = createAngularTable(() => ({
22201
- data: this.kjTableData(),
22249
+ data: this.compacted().rows,
22202
22250
  columns: this.boundColumns(),
22251
+ // In infinite mode a top-level row's index is its result-set position,
22252
+ // so default ids stay stable while pages load around them.
22203
22253
  getRowId: this.kjGetRowId()
22204
- ? (row, index) => this.kjGetRowId()(row, index)
22205
- : undefined,
22254
+ ? (row, index, parent) => this.kjGetRowId()(row, parent ? index : this.sourceIndexOf(index))
22255
+ : this._infinite()
22256
+ ? (_row, index, parent) => (parent ? `${parent.id}.${index}` : String(this.sourceIndexOf(index)))
22257
+ : undefined,
22206
22258
  // `columnResizeMode: 'onEnd'` defers the actual column width write until
22207
22259
  // the user releases the resize handle. While dragging, the wrapper reads
22208
22260
  // `state.columnSizingInfo().deltaOffset` to render a vertical preview
@@ -22212,7 +22264,9 @@ class KjTable {
22212
22264
  // TanStack to manual pagination so the loader-page becomes the
22213
22265
  // visible page (no client-side slicing) and pagination controls
22214
22266
  // derive their totals from the remote count.
22215
- manualPagination: this._rowCount() !== null,
22267
+ manualPagination: this._rowCount() !== null || this._infinite(),
22268
+ manualSorting: this._infinite(),
22269
+ manualFiltering: this._infinite(),
22216
22270
  rowCount: this._rowCount() ?? undefined,
22217
22271
  state: { ...this._state(), columnSizingInfo: this._columnSizingInfo() },
22218
22272
  onSortingChange: u => this.patch('sorting', u),
@@ -22514,7 +22568,12 @@ class KjTableRow {
22514
22568
  ...(ngDevMode ? [{ debugName: "kjRow" }] : /* istanbul ignore next */ []));
22515
22569
  table = injectParent(KJ_TABLE, { child: 'KjTableRow', parent: '[kjTable]' });
22516
22570
  /** 1-based ARIA index — accounts for header row(s). */
22517
- ariaRowIndex = computed(() => this.kjRow().index + 2, /* @ts-ignore */
22571
+ ariaRowIndex = computed(() => {
22572
+ const row = this.kjRow();
22573
+ // Infinite mode: the row's place in the whole result set, not in the loaded window.
22574
+ const source = row.depth === 0 ? this.table.sourceIndex()?.[row.index] : undefined;
22575
+ return (source ?? row.index) + 2;
22576
+ }, /* @ts-ignore */
22518
22577
  ...(ngDevMode ? [{ debugName: "ariaRowIndex" }] : /* istanbul ignore next */ []));
22519
22578
  isSelectable = computed(() => Object.keys(this.table.state.rowSelection()).length >= 0, /* @ts-ignore */
22520
22579
  ...(ngDevMode ? [{ debugName: "isSelectable" }] : /* istanbul ignore next */ [])); // always true if selection enabled