@svelte-lean/table 0.2.0 → 0.3.2
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/CHANGELOG.md +20 -0
- package/dist/style.css +31 -0
- package/dist/table/data-table.svelte +64 -14
- package/dist/types.d.ts +8 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @svelte-lean/table
|
|
2
2
|
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Grid layout: content drawn straight into a cell (a badge, a chip, a link) keeps its own width instead of stretching across the cell; the selection and expand columns center their control. A click on a disabled `data-action` control reports no `onAction`.
|
|
8
|
+
|
|
9
|
+
## 0.3.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- The selection count moves out of the toolbar: with a pager it ends the pager's status line (`Page 1 of 15 · 144 rows · 3 selected`), without one it stays in the toolbar; either way it shows only while rows are selected, never as "0 selected". A table with selection and nothing else in its toolbar no longer draws an empty band above its header row.
|
|
14
|
+
|
|
15
|
+
## 0.3.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- `pageSizeSelect="custom"` draws the page-size control with the Select primitive of `@svelte-lean/primitives`: a trigger button and a listbox popup drawn from the design tokens in every engine, around the same native `<select>`, which keeps the value and works without scripts. The application imports `@svelte-lean/primitives/select/register` and `@svelte-lean/styles/select.css`. `native` (a plain `<select>`) stays the default.
|
|
20
|
+
|
|
21
|
+
The ids that tie the control's label, trigger and listbox come from `$props.id()`, so the peer dependency is now `svelte ^5.20.0`.
|
|
22
|
+
|
|
3
23
|
## 0.2.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
package/dist/style.css
CHANGED
|
@@ -700,6 +700,13 @@
|
|
|
700
700
|
gap: 0.5rem;
|
|
701
701
|
white-space: nowrap;
|
|
702
702
|
}
|
|
703
|
+
/* The Select primitive as the page-size control (`pageSizeSelect="custom"`): as tall as the
|
|
704
|
+
pager's buttons, as wide as its longest option. */
|
|
705
|
+
:where(.slean-table-page-select) {
|
|
706
|
+
--slean-control-height-sm: var(--slean-table-control-height);
|
|
707
|
+
min-inline-size: 4.75rem;
|
|
708
|
+
font-size: inherit;
|
|
709
|
+
}
|
|
703
710
|
:where(.slean-table-pager, .slean-table-pages) {
|
|
704
711
|
display: flex;
|
|
705
712
|
align-items: center;
|
|
@@ -851,12 +858,36 @@
|
|
|
851
858
|
align-items: center;
|
|
852
859
|
min-width: 0;
|
|
853
860
|
}
|
|
861
|
+
/* The renderer's own boxes in a cell fill it; content drawn straight into a cell (a badge, a
|
|
862
|
+
chip, a link in a plain grid cell, a control) keeps its own width. */
|
|
854
863
|
:where(
|
|
855
864
|
.slean-table[data-layout='grid'] > .slean-table-scroll > table > * > tr > :is(th, td) > *
|
|
865
|
+
) {
|
|
866
|
+
flex: 0 1 auto;
|
|
867
|
+
}
|
|
868
|
+
:where(
|
|
869
|
+
.slean-table[data-layout='grid']
|
|
870
|
+
> .slean-table-scroll
|
|
871
|
+
> table
|
|
872
|
+
> *
|
|
873
|
+
> tr
|
|
874
|
+
> :is(th, td)
|
|
875
|
+
> :is(.slean-table-cell, .slean-table-heading, .slean-table-editor)
|
|
856
876
|
) {
|
|
857
877
|
flex: 1 1 auto;
|
|
858
878
|
min-width: 0;
|
|
859
879
|
}
|
|
880
|
+
/* The selection and expand columns center their one control. */
|
|
881
|
+
:where(
|
|
882
|
+
.slean-table[data-layout='grid']
|
|
883
|
+
> .slean-table-scroll
|
|
884
|
+
> table
|
|
885
|
+
> *
|
|
886
|
+
> tr
|
|
887
|
+
> :is(.slean-table-selection, .slean-table-expander)
|
|
888
|
+
) {
|
|
889
|
+
justify-content: center;
|
|
890
|
+
}
|
|
860
891
|
:where(
|
|
861
892
|
.slean-table[data-layout='grid'] > .slean-table-scroll > table > * > tr > .slean-table-full
|
|
862
893
|
) {
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
progressive = false,
|
|
120
120
|
pagination = true,
|
|
121
121
|
pageSizeOptions = [10, 20, 50, 100],
|
|
122
|
+
pageSizeSelect = 'native',
|
|
122
123
|
placeholder = '',
|
|
123
124
|
rowHoverable = true,
|
|
124
125
|
dir,
|
|
@@ -136,6 +137,15 @@
|
|
|
136
137
|
onCellRangeChange,
|
|
137
138
|
class: className = ''
|
|
138
139
|
}: TableProps<T> = $props();
|
|
140
|
+
/** Ids of this instance's own relationships (the page-size label and listbox); SSR-stable. */
|
|
141
|
+
const uid = $props.id();
|
|
142
|
+
/**
|
|
143
|
+
* The Select primitive's root marker, spread rather than written: @svelte-lean/vite registers
|
|
144
|
+
* the behavior of every marker it reads in markup, and a marker here would put the select
|
|
145
|
+
* behavior in every application that renders a table. The application that sets
|
|
146
|
+
* `pageSizeSelect="custom"` imports `@svelte-lean/primitives/select/register` itself.
|
|
147
|
+
*/
|
|
148
|
+
const SELECT_ROOT = { 'data-slean': 'select' } as const;
|
|
139
149
|
/**
|
|
140
150
|
* One engine. Props are handed over as getters so the engine follows every prop change.
|
|
141
151
|
* `getSubRows` and `searchText` must stay `undefined` when absent (grouping rejects tree input;
|
|
@@ -855,6 +865,8 @@
|
|
|
855
865
|
}
|
|
856
866
|
/** The page status: a manual table without `rowCount` does not know its total. */
|
|
857
867
|
const rowsKnown = $derived(!manual || rowCount !== undefined);
|
|
868
|
+
/** Without a pager the toolbar carries the selection count, and only while something is chosen. */
|
|
869
|
+
const selectedInToolbar = $derived(Boolean(selection) && !pagination && s.selection.length > 0);
|
|
858
870
|
const headerRowCount = $derived(showHeader ? table.headers.length + (filters ? 1 : 0) : 0);
|
|
859
871
|
/** A manual page is part of a known total: `aria-rowcount` and `aria-rowindex` say where. */
|
|
860
872
|
const ariaRowCount = $derived(
|
|
@@ -1053,7 +1065,10 @@
|
|
|
1053
1065
|
const target = e.target as HTMLElement;
|
|
1054
1066
|
const action = target.closest<HTMLElement>('[data-action]');
|
|
1055
1067
|
if (action && cell.contains(action)) {
|
|
1056
|
-
|
|
1068
|
+
// A disabled control reports nothing (a click can still be dispatched on one).
|
|
1069
|
+
if (!action.matches(':disabled, [aria-disabled="true"]')) {
|
|
1070
|
+
onAction?.(action.dataset.action ?? '', row, action, index);
|
|
1071
|
+
}
|
|
1057
1072
|
return;
|
|
1058
1073
|
}
|
|
1059
1074
|
const control = target.closest(NOT_ROW_CLICK);
|
|
@@ -1465,7 +1480,11 @@
|
|
|
1465
1480
|
<!-- The toolbar exists only when something goes in it: an empty flex row would still paint its
|
|
1466
1481
|
padding as a blank band above the header row (Svelte keeps a text node between the blocks,
|
|
1467
1482
|
so `:empty` cannot hide it). -->
|
|
1468
|
-
|
|
1483
|
+
<!-- The selection count sits in the pager's status line when there is a pager, and in the
|
|
1484
|
+
toolbar only without one; either way it shows while something is selected, never "0". -->
|
|
1485
|
+
{#if searchable || toolbar || selectedInToolbar || columnControls}<div
|
|
1486
|
+
class="slean-table-toolbar"
|
|
1487
|
+
>
|
|
1469
1488
|
{#if searchable}<input
|
|
1470
1489
|
class="slean-table-search slean-table-input"
|
|
1471
1490
|
type="search"
|
|
@@ -1475,7 +1494,7 @@
|
|
|
1475
1494
|
oninput={(e) => delayed('search', e.currentTarget.value, (v) => table.setSearch(v))}
|
|
1476
1495
|
/>{/if}
|
|
1477
1496
|
{#if toolbar}{@render toolbar(model)}{/if}
|
|
1478
|
-
{#if
|
|
1497
|
+
{#if selectedInToolbar}<span class="slean-table-selected" aria-live="polite"
|
|
1479
1498
|
>{m.selected(s.selection.length)}</span
|
|
1480
1499
|
>{/if}
|
|
1481
1500
|
{#if columnControls}<details class="slean-table-columns">
|
|
@@ -1716,17 +1735,48 @@
|
|
|
1716
1735
|
</div>
|
|
1717
1736
|
{#if pagination}<div class="slean-table-pagination">
|
|
1718
1737
|
<span class="slean-table-page-status" aria-live="polite"
|
|
1719
|
-
>{m.page(
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1738
|
+
>{m.page(
|
|
1739
|
+
model.pageIndex + 1,
|
|
1740
|
+
model.pageCount,
|
|
1741
|
+
rowsKnown ? model.total : undefined
|
|
1742
|
+
)}{#if selection && s.selection.length > 0}
|
|
1743
|
+
· <span class="slean-table-selected">{m.selected(s.selection.length)}</span>{/if}</span
|
|
1744
|
+
>{#if pageSizeSelect === 'custom'}<span class="slean-table-page-size"
|
|
1745
|
+
><span id="{uid}-page-size">{m.pageSize}</span>
|
|
1746
|
+
<div class="slean-table-page-select" {...SELECT_ROOT} data-size="sm">
|
|
1747
|
+
<select
|
|
1748
|
+
data-slean-part="native"
|
|
1749
|
+
aria-labelledby="{uid}-page-size"
|
|
1750
|
+
value={s.pageSize}
|
|
1751
|
+
onchange={(e) => table.setPageSize(Number(e.currentTarget.value))}
|
|
1752
|
+
>{#each pageSizes as size (size)}<option value={size}
|
|
1753
|
+
>{size === 0 ? m.allRows : size}</option
|
|
1754
|
+
>{/each}</select
|
|
1755
|
+
><button
|
|
1756
|
+
type="button"
|
|
1757
|
+
role="combobox"
|
|
1758
|
+
aria-haspopup="listbox"
|
|
1759
|
+
aria-expanded="false"
|
|
1760
|
+
aria-controls="{uid}-page-sizes"
|
|
1761
|
+
aria-labelledby="{uid}-page-size"
|
|
1762
|
+
data-slean-part="trigger"
|
|
1763
|
+
><span data-slean-part="value">{s.pageSize === 0 ? m.allRows : s.pageSize}</span
|
|
1764
|
+
></button
|
|
1765
|
+
><span data-slean-part="toggle" aria-hidden="true"></span>
|
|
1766
|
+
<div popover="manual" data-slean-part="popup">
|
|
1767
|
+
<ul id="{uid}-page-sizes" role="listbox" aria-labelledby="{uid}-page-size"></ul>
|
|
1768
|
+
</div>
|
|
1769
|
+
</div></span
|
|
1770
|
+
>{:else}<label class="slean-table-page-size"
|
|
1771
|
+
>{m.pageSize}<select
|
|
1772
|
+
class="slean-table-input"
|
|
1773
|
+
value={s.pageSize}
|
|
1774
|
+
onchange={(e) => table.setPageSize(Number(e.currentTarget.value))}
|
|
1775
|
+
>{#each pageSizes as size (size)}<option value={size}
|
|
1776
|
+
>{size === 0 ? m.allRows : size}</option
|
|
1777
|
+
>{/each}</select
|
|
1778
|
+
></label
|
|
1779
|
+
>{/if}<span class="slean-table-pager"
|
|
1730
1780
|
><button
|
|
1731
1781
|
type="button"
|
|
1732
1782
|
class="slean-table-button"
|
package/dist/types.d.ts
CHANGED
|
@@ -299,6 +299,14 @@ export interface TableProps<T> {
|
|
|
299
299
|
pagination?: boolean;
|
|
300
300
|
/** Page sizes offered by the pager; the current size is always included. */
|
|
301
301
|
pageSizeOptions?: number[];
|
|
302
|
+
/**
|
|
303
|
+
* The page-size control. `native` (default): a native `<select>`. `custom`: the Select primitive
|
|
304
|
+
* of `@svelte-lean/primitives` (a trigger button and a listbox popup drawn the same in every
|
|
305
|
+
* engine), around the same native `<select>`, which keeps the value and works without scripts.
|
|
306
|
+
* `custom` needs the select behavior (`import '@svelte-lean/primitives/select/register'`) and
|
|
307
|
+
* its styles (`@svelte-lean/styles/select.css`) in the application.
|
|
308
|
+
*/
|
|
309
|
+
pageSizeSelect?: 'native' | 'custom';
|
|
302
310
|
/** Text of an empty value (`null`, `undefined`, `''`, or `format` returning `null`/`''`). */
|
|
303
311
|
placeholder?: string;
|
|
304
312
|
rowHoverable?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svelte-lean/table",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "A Svelte-native table and data-grid engine that ships only the features you use.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ömer Say",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"svelte": "^5.
|
|
61
|
+
"svelte": "^5.20.0"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "yarn run -T svelte-kit sync && yarn run -T svelte-package && node scripts/types.mjs && yarn run -T publint && yarn run -T attw --pack . --profile esm-only --exclude-entrypoints ./style.css --format table-flipped --no-emoji",
|