@marianmeres/stuic 3.166.0 → 3.167.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.
package/API.md CHANGED
@@ -1087,19 +1087,20 @@ Swap visibility between N states with opacity transitions. Commonly used for ham
1087
1087
 
1088
1088
  Responsive data table with paging, row selection, batch actions, and mobile card view.
1089
1089
 
1090
- | Prop | Type | Default | Description |
1091
- | ------------------ | --------------------------------------------- | -------- | --------------------------------------------------- |
1092
- | `columns` | `DataTableColumn<T>[]` | required | Column definitions |
1093
- | `data` | `T[]` | required | Row data objects |
1094
- | `getRowId` | `(row: T, index: number) => string \| number` | index | Unique row ID extractor |
1095
- | `paging` | `PagingCalcResult` | — | Paging calculation from `@marianmeres/paging-store` |
1096
- | `onPageChange` | `(offset: number) => void` | — | Page navigation callback |
1097
- | `selectable` | `boolean` | `false` | Enable row selection checkboxes |
1098
- | `selected` | `Set<string \| number>` | | Bindable set of selected row IDs |
1099
- | `selectOnRowClick` | `boolean` | `false` | Toggle selection on row click |
1100
- | `onRowClick` | `(row: T, index: number) => void` | — | Row click callback |
1101
- | `loading` | `boolean` | `false` | Show loading overlay |
1102
- | `t` | `TranslateFn` | built-in | Translation function for i18n |
1090
+ | Prop | Type | Default | Description |
1091
+ | ------------------ | --------------------------------------------- | -------- | ------------------------------------------------------------ |
1092
+ | `columns` | `DataTableColumn<T>[]` | required | Column definitions |
1093
+ | `data` | `T[]` | required | Row data objects |
1094
+ | `getRowId` | `(row: T, index: number) => string \| number` | index | Unique row ID extractor |
1095
+ | `paging` | `PagingCalcResult` | — | Paging calculation from `@marianmeres/paging-store` |
1096
+ | `onPageChange` | `(offset: number) => void` | — | Page navigation callback |
1097
+ | `showPager` | `boolean` | `true` | Render the built-in pager (`false` keeps `paging` data only) |
1098
+ | `selectable` | `boolean` | `false` | Enable row selection checkboxes |
1099
+ | `selected` | `Set<string \| number>` | | Bindable set of selected row IDs |
1100
+ | `selectOnRowClick` | `boolean` | `false` | Toggle selection on row click |
1101
+ | `onRowClick` | `(row: T, index: number) => void` | | Row click callback |
1102
+ | `loading` | `boolean` | `false` | Show loading overlay |
1103
+ | `t` | `TranslateFn` | built-in | Translation function for i18n |
1103
1104
 
1104
1105
  **Snippets:** `cell`, `batchActions`, `empty`, `mobileRow`
1105
1106
 
@@ -41,6 +41,18 @@
41
41
  paging?: PagingCalcResult;
42
42
  /** Callback when the user navigates to a different page (receives new offset) */
43
43
  onPageChange?: (offset: number) => void;
44
+ /**
45
+ * Render the built-in pager. Set `false` to keep feeding `paging` -- which the
46
+ * select-all-across-pages banner, `effectiveCount` and `totalCount` need -- while
47
+ * paging the data from your own control elsewhere on the page.
48
+ *
49
+ * With the pager hidden `onPageChange` never fires (nothing else calls it), so the
50
+ * caller's own control is the single thing driving the offset -- don't wire both.
51
+ *
52
+ * Orthogonal to the existing "one page of results needs no pager" rule: a single-page
53
+ * `paging` renders no pager either way.
54
+ */
55
+ showPager?: boolean;
44
56
 
45
57
  /** Enable row selection checkboxes */
46
58
  selectable?: boolean;
@@ -231,6 +243,7 @@
231
243
  getRowId = (_row: T, index: number) => index,
232
244
  paging,
233
245
  onPageChange,
246
+ showPager = true,
234
247
  selectable = false,
235
248
  selected = $bindable(new Set()),
236
249
  selectOnRowClick = false,
@@ -265,7 +278,9 @@
265
278
  let isDesktop = $derived(small ? false : bp.md);
266
279
 
267
280
  // --- Paging ---
268
- let showPaging = $derived(paging != null && paging.pageCount > 1);
281
+ // The prop only ADDs to the existing rule -- a single-page result still renders no
282
+ // pager, regardless of `showPager`.
283
+ let renderPager = $derived(showPager && paging != null && paging.pageCount > 1);
269
284
 
270
285
  // --- Selection ---
271
286
  let allRowIds = $derived(data.map((row, i) => getRowId(row, i)));
@@ -752,7 +767,7 @@
752
767
  {/if}
753
768
 
754
769
  <!-- Paging -->
755
- {#if showPaging && paging}
770
+ {#if renderPager && paging}
756
771
  <div class={!unstyled ? "stuic-data-table-paging" : undefined}>
757
772
  <Button
758
773
  variant="ghost"
@@ -32,6 +32,18 @@ export interface Props<T = Record<string, any>> extends Omit<HTMLAttributes<HTML
32
32
  paging?: PagingCalcResult;
33
33
  /** Callback when the user navigates to a different page (receives new offset) */
34
34
  onPageChange?: (offset: number) => void;
35
+ /**
36
+ * Render the built-in pager. Set `false` to keep feeding `paging` -- which the
37
+ * select-all-across-pages banner, `effectiveCount` and `totalCount` need -- while
38
+ * paging the data from your own control elsewhere on the page.
39
+ *
40
+ * With the pager hidden `onPageChange` never fires (nothing else calls it), so the
41
+ * caller's own control is the single thing driving the offset -- don't wire both.
42
+ *
43
+ * Orthogonal to the existing "one page of results needs no pager" rule: a single-page
44
+ * `paging` renders no pager either way.
45
+ */
46
+ showPager?: boolean;
35
47
  /** Enable row selection checkboxes */
36
48
  selectable?: boolean;
37
49
  /** Set of selected row IDs (bindable) */
@@ -46,6 +46,35 @@ DataTable integrates with [`@marianmeres/paging-store`](https://github.com/maria
46
46
  />
47
47
  ```
48
48
 
49
+ A single-page result renders no pager -- there is nothing to page through.
50
+
51
+ #### Bringing your own pager
52
+
53
+ `paging` does two unrelated jobs: it renders the built-in pager, and it feeds the
54
+ select-all-across-pages banner, `effectiveCount` and `totalCount`. `showPager={false}`
55
+ asks for the second without the first, for a page that already pages the data from its own
56
+ control (one with a rows-per-page selector, say):
57
+
58
+ ```svelte
59
+ <DataTable
60
+ {columns}
61
+ {data}
62
+ paging={pagingResult}
63
+ showPager={false}
64
+ selectable
65
+ allowSelectAllPages
66
+ />
67
+
68
+ <MyOwnPager … />
69
+ ```
70
+
71
+ The pager node is then absent from the DOM, not hidden -- it takes no space and holds no
72
+ focusable buttons. `onPageChange` never fires while it is hidden (nothing else calls it),
73
+ so your own control is the single thing driving the offset; don't wire both.
74
+
75
+ (The node's class stays `.stuic-data-table-paging` and its `--stuic-data-table-paging-*`
76
+ tokens are unchanged -- `showPager` names the control, the CSS names the region.)
77
+
49
78
  ### With Selection
50
79
 
51
80
  ```svelte
@@ -311,39 +340,40 @@ Replace the entire `<tr>` on desktop. When this snippet is provided, DataTable d
311
340
 
312
341
  ## Props
313
342
 
314
- | Prop | Type | Default | Description |
315
- | --------------------- | ------------------------------------- | ------------- | -------------------------------------------------------------------------- |
316
- | `columns` | `DataTableColumn<T>[]` | required | Column definitions |
317
- | `data` | `T[]` | required | Array of row data |
318
- | `getRowId` | `(row, index) => string \| number` | `(_, i) => i` | Row ID extractor |
319
- | `paging` | `PagingCalcResult` | - | Paging state (from `@marianmeres/paging-store`) |
320
- | `onPageChange` | `(offset: number) => void` | - | Called with the new offset when the user navigates pages |
321
- | `selectable` | `boolean` | `false` | Enable selection checkboxes |
322
- | `selected` | `Set<string \| number>` | `new Set()` | Selected row IDs (bindable) |
323
- | `selectOnRowClick` | `boolean` | `false` | Clicking anywhere on a row toggles its selection |
324
- | `selectDisabledBy` | `(row, index) => boolean` | - | Return `true` to disable selection for a specific row |
325
- | `allowSelectAllPages` | `boolean` | `false` | Show a banner offering "select all results" across paged data |
326
- | `selectedAll` | `boolean` | `false` | All-pages mode flag (bindable). In this mode `excluded` drives selection |
327
- | `excluded` | `Set<string \| number>` | `new Set()` | Deselected row IDs while in all-pages mode (bindable) |
328
- | `reserveBatchBar` | `boolean` | `true` | Keep the selection bar in the layout while nothing is selected |
329
- | `onRowClick` | `(row, index) => void` | - | Row click callback |
330
- | `rowHref` | `(row, index) => string \| undefined` | - | Wrap the lead cell's content in an `<a href>` (keyboard/⌘-click reachable) |
331
- | `rowHrefColumn` | `string` | first column | Which column is the lead cell for `rowHref` |
332
- | `classRowLink` | `string` | - | Extra classes for the `rowHref` anchor |
333
- | `rowActivatable` | `boolean` | `false` | Make the desktop `<tr>` focusable + `Enter`-activatable (no `role`) |
334
- | `rowLabel` | `(row, index) => string \| undefined` | - | Accessible name for an activatable row |
335
- | `loading` | `boolean` | `false` | Show loading overlay |
336
- | `small` | `boolean` | `false` | Force mobile/card layout regardless of viewport |
337
- | `t` | `TranslateFn` | built-in | Optional translation function |
338
- | `cell` | `Snippet` | - | Custom cell renderer (desktop + mobile) |
339
- | `row` | `Snippet` | - | Custom desktop `<tr>` renderer (overrides default row) |
340
- | `mobileRow` | `Snippet` | - | Custom mobile card renderer |
341
- | `batchActions` | `Snippet` | - | Selection bar content while something is selected |
342
- | `selectAllBanner` | `Snippet` | - | Override default "select all across pages" offer |
343
- | `empty` | `Snippet` | - | Custom empty state |
344
- | `unstyled` | `boolean` | `false` | Skip default styling |
345
- | `class` | `string` | - | Additional CSS classes |
346
- | `el` | `HTMLDivElement` | - | Bindable element ref |
343
+ | Prop | Type | Default | Description |
344
+ | --------------------- | ------------------------------------- | ------------- | ------------------------------------------------------------------------------------ |
345
+ | `columns` | `DataTableColumn<T>[]` | required | Column definitions |
346
+ | `data` | `T[]` | required | Array of row data |
347
+ | `getRowId` | `(row, index) => string \| number` | `(_, i) => i` | Row ID extractor |
348
+ | `paging` | `PagingCalcResult` | - | Paging state (from `@marianmeres/paging-store`) |
349
+ | `onPageChange` | `(offset: number) => void` | - | Called with the new offset when the user navigates pages |
350
+ | `showPager` | `boolean` | `true` | Render the built-in pager. `false` keeps `paging` feeding the select-all banner only |
351
+ | `selectable` | `boolean` | `false` | Enable selection checkboxes |
352
+ | `selected` | `Set<string \| number>` | `new Set()` | Selected row IDs (bindable) |
353
+ | `selectOnRowClick` | `boolean` | `false` | Clicking anywhere on a row toggles its selection |
354
+ | `selectDisabledBy` | `(row, index) => boolean` | - | Return `true` to disable selection for a specific row |
355
+ | `allowSelectAllPages` | `boolean` | `false` | Show a banner offering "select all results" across paged data |
356
+ | `selectedAll` | `boolean` | `false` | All-pages mode flag (bindable). In this mode `excluded` drives selection |
357
+ | `excluded` | `Set<string \| number>` | `new Set()` | Deselected row IDs while in all-pages mode (bindable) |
358
+ | `reserveBatchBar` | `boolean` | `true` | Keep the selection bar in the layout while nothing is selected |
359
+ | `onRowClick` | `(row, index) => void` | - | Row click callback |
360
+ | `rowHref` | `(row, index) => string \| undefined` | - | Wrap the lead cell's content in an `<a href>` (keyboard/⌘-click reachable) |
361
+ | `rowHrefColumn` | `string` | first column | Which column is the lead cell for `rowHref` |
362
+ | `classRowLink` | `string` | - | Extra classes for the `rowHref` anchor |
363
+ | `rowActivatable` | `boolean` | `false` | Make the desktop `<tr>` focusable + `Enter`-activatable (no `role`) |
364
+ | `rowLabel` | `(row, index) => string \| undefined` | - | Accessible name for an activatable row |
365
+ | `loading` | `boolean` | `false` | Show loading overlay |
366
+ | `small` | `boolean` | `false` | Force mobile/card layout regardless of viewport |
367
+ | `t` | `TranslateFn` | built-in | Optional translation function |
368
+ | `cell` | `Snippet` | - | Custom cell renderer (desktop + mobile) |
369
+ | `row` | `Snippet` | - | Custom desktop `<tr>` renderer (overrides default row) |
370
+ | `mobileRow` | `Snippet` | - | Custom mobile card renderer |
371
+ | `batchActions` | `Snippet` | - | Selection bar content while something is selected |
372
+ | `selectAllBanner` | `Snippet` | - | Override default "select all across pages" offer |
373
+ | `empty` | `Snippet` | - | Custom empty state |
374
+ | `unstyled` | `boolean` | `false` | Skip default styling |
375
+ | `class` | `string` | - | Additional CSS classes |
376
+ | `el` | `HTMLDivElement` | - | Bindable element ref |
347
377
 
348
378
  ### Snippet signatures
349
379
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "3.166.0",
3
+ "version": "3.167.0",
4
4
  "packageManager": "pnpm@11.5.0",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -162,12 +162,12 @@
162
162
  "prettier": "^3.9.6",
163
163
  "prettier-plugin-svelte": "^3.5.2",
164
164
  "publint": "^0.3.24",
165
- "svelte": "^5.56.10",
165
+ "svelte": "^5.57.0",
166
166
  "svelte-check": "^4.7.6",
167
167
  "tailwindcss": "^4.3.3",
168
- "tsx": "^4.23.12",
168
+ "tsx": "^4.23.13",
169
169
  "typescript": "^5.9.3",
170
- "typescript-eslint": "^8.67.0",
170
+ "typescript-eslint": "^8.68.0",
171
171
  "vite": "^7.3.6",
172
172
  "vitest": "^4.1.11",
173
173
  "vitest-browser-svelte": "^2.2.1"
@@ -183,7 +183,7 @@
183
183
  "@marianmeres/parse-boolean": "^2.1.0",
184
184
  "@marianmeres/ticker": "^1.17.1",
185
185
  "@marianmeres/tree": "^2.3.0",
186
- "libphonenumber-js": "^1.13.11",
186
+ "libphonenumber-js": "^1.13.12",
187
187
  "runed": "^0.23.4",
188
188
  "tailwind-merge": "^3.6.0"
189
189
  }