@lavalogic/scoria 0.37.11 → 0.37.13
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/dist/Components/Table/Body/QuickSearchCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +4 -3
- package/dist/Components/Table/Body/Rows/TableRow.svelte +16 -2
- package/dist/Components/Table/ColumnFactory.svelte.js +21 -1
- package/dist/Components/Table/Table.svelte +22 -13
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +19 -0
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.js +19 -0
- package/dist/Components/Table/Types/Public/BaseColumnOptions.d.ts +12 -0
- package/dist/Components/Table/Types/Public/CreateTableOptions.d.ts +11 -0
- package/dist/Components/Table/Types/Public/RowSource.d.ts +9 -0
- package/dist/Components/Table/createTable.svelte.js +9 -1
- package/dist/scss/_mixins.scss +12 -3
- package/package.json +1 -1
|
@@ -687,8 +687,8 @@
|
|
|
687
687
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
688
688
|
--input-border: none;
|
|
689
689
|
--input-height: var(--height);
|
|
690
|
-
white-space: nowrap;
|
|
691
|
-
overflow-x: clip;
|
|
690
|
+
white-space: var(--cell-white-space, nowrap);
|
|
691
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
692
692
|
text-overflow: ellipsis;
|
|
693
693
|
position: relative;
|
|
694
694
|
padding-left: 0.75rem;
|
|
@@ -697,7 +697,8 @@
|
|
|
697
697
|
border-bottom: solid 1px #cbd4da;
|
|
698
698
|
box-sizing: border-box;
|
|
699
699
|
width: 100%;
|
|
700
|
-
height: var(--height);
|
|
700
|
+
height: var(--cell-height, var(--height));
|
|
701
|
+
min-height: var(--cell-min-height, var(--height));
|
|
701
702
|
}
|
|
702
703
|
|
|
703
704
|
.input-cell {
|
|
@@ -56,8 +56,8 @@ which reads either "Highlight row N" or "Unhighlight row N" depending on state.
|
|
|
56
56
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
57
57
|
--input-border: none;
|
|
58
58
|
--input-height: var(--height);
|
|
59
|
-
white-space: nowrap;
|
|
60
|
-
overflow-x: clip;
|
|
59
|
+
white-space: var(--cell-white-space, nowrap);
|
|
60
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
61
61
|
text-overflow: ellipsis;
|
|
62
62
|
position: relative;
|
|
63
63
|
padding-left: 0.75rem;
|
|
@@ -66,7 +66,8 @@ which reads either "Highlight row N" or "Unhighlight row N" depending on state.
|
|
|
66
66
|
border-bottom: solid 1px #cbd4da;
|
|
67
67
|
box-sizing: border-box;
|
|
68
68
|
width: 100%;
|
|
69
|
-
height: var(--height);
|
|
69
|
+
height: var(--cell-height, var(--height));
|
|
70
|
+
min-height: var(--cell-min-height, var(--height));
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
.highlight-content {
|
|
@@ -172,8 +172,8 @@
|
|
|
172
172
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
173
173
|
--input-border: none;
|
|
174
174
|
--input-height: var(--height);
|
|
175
|
-
white-space: nowrap;
|
|
176
|
-
overflow-x: clip;
|
|
175
|
+
white-space: var(--cell-white-space, nowrap);
|
|
176
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
177
177
|
text-overflow: ellipsis;
|
|
178
178
|
position: relative;
|
|
179
179
|
padding-left: 0.75rem;
|
|
@@ -182,7 +182,8 @@
|
|
|
182
182
|
border-bottom: solid 1px #cbd4da;
|
|
183
183
|
box-sizing: border-box;
|
|
184
184
|
width: 100%;
|
|
185
|
-
height: var(--height);
|
|
185
|
+
height: var(--cell-height, var(--height));
|
|
186
|
+
min-height: var(--cell-min-height, var(--height));
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
.focusable.multifocus,
|
|
@@ -117,8 +117,8 @@
|
|
|
117
117
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
118
118
|
--input-border: none;
|
|
119
119
|
--input-height: var(--height);
|
|
120
|
-
white-space: nowrap;
|
|
121
|
-
overflow-x: clip;
|
|
120
|
+
white-space: var(--cell-white-space, nowrap);
|
|
121
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
122
122
|
text-overflow: ellipsis;
|
|
123
123
|
position: relative;
|
|
124
124
|
padding-left: 0.75rem;
|
|
@@ -127,7 +127,8 @@
|
|
|
127
127
|
border-bottom: solid 1px #cbd4da;
|
|
128
128
|
box-sizing: border-box;
|
|
129
129
|
width: 100%;
|
|
130
|
-
height: var(--height);
|
|
130
|
+
height: var(--cell-height, var(--height));
|
|
131
|
+
min-height: var(--cell-min-height, var(--height));
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
.focusable.multifocus,
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
126
126
|
--input-border: none;
|
|
127
127
|
--input-height: var(--height);
|
|
128
|
-
white-space: nowrap;
|
|
129
|
-
overflow-x: clip;
|
|
128
|
+
white-space: var(--cell-white-space, nowrap);
|
|
129
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
130
130
|
text-overflow: ellipsis;
|
|
131
131
|
position: relative;
|
|
132
132
|
padding-left: 0.75rem;
|
|
@@ -135,7 +135,8 @@
|
|
|
135
135
|
border-bottom: solid 1px #cbd4da;
|
|
136
136
|
box-sizing: border-box;
|
|
137
137
|
width: 100%;
|
|
138
|
-
height: var(--height);
|
|
138
|
+
height: var(--cell-height, var(--height));
|
|
139
|
+
min-height: var(--cell-min-height, var(--height));
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
.focusable {
|
|
@@ -201,8 +201,8 @@
|
|
|
201
201
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
202
202
|
--input-border: none;
|
|
203
203
|
--input-height: var(--height);
|
|
204
|
-
white-space: nowrap;
|
|
205
|
-
overflow-x: clip;
|
|
204
|
+
white-space: var(--cell-white-space, nowrap);
|
|
205
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
206
206
|
text-overflow: ellipsis;
|
|
207
207
|
position: relative;
|
|
208
208
|
padding-left: 0.75rem;
|
|
@@ -211,7 +211,8 @@
|
|
|
211
211
|
border-bottom: solid 1px #cbd4da;
|
|
212
212
|
box-sizing: border-box;
|
|
213
213
|
width: 100%;
|
|
214
|
-
height: var(--height);
|
|
214
|
+
height: var(--cell-height, var(--height));
|
|
215
|
+
min-height: var(--cell-min-height, var(--height));
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
.focusable.multifocus,
|
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
111
111
|
--input-border: none;
|
|
112
112
|
--input-height: var(--height);
|
|
113
|
-
white-space: nowrap;
|
|
114
|
-
overflow-x: clip;
|
|
113
|
+
white-space: var(--cell-white-space, nowrap);
|
|
114
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
115
115
|
text-overflow: ellipsis;
|
|
116
116
|
position: relative;
|
|
117
117
|
padding-left: 0.75rem;
|
|
@@ -120,7 +120,8 @@
|
|
|
120
120
|
border-bottom: solid 1px #cbd4da;
|
|
121
121
|
box-sizing: border-box;
|
|
122
122
|
width: 100%;
|
|
123
|
-
height: var(--height);
|
|
123
|
+
height: var(--cell-height, var(--height));
|
|
124
|
+
min-height: var(--cell-min-height, var(--height));
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
.focusable.multifocus,
|
|
@@ -131,8 +131,8 @@
|
|
|
131
131
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
132
132
|
--input-border: none;
|
|
133
133
|
--input-height: var(--height);
|
|
134
|
-
white-space: nowrap;
|
|
135
|
-
overflow-x: clip;
|
|
134
|
+
white-space: var(--cell-white-space, nowrap);
|
|
135
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
136
136
|
text-overflow: ellipsis;
|
|
137
137
|
position: relative;
|
|
138
138
|
padding-left: 0.75rem;
|
|
@@ -141,7 +141,8 @@
|
|
|
141
141
|
border-bottom: solid 1px #cbd4da;
|
|
142
142
|
box-sizing: border-box;
|
|
143
143
|
width: 100%;
|
|
144
|
-
height: var(--height);
|
|
144
|
+
height: var(--cell-height, var(--height));
|
|
145
|
+
min-height: var(--cell-min-height, var(--height));
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
input[type=checkbox] {
|
|
@@ -251,8 +251,8 @@
|
|
|
251
251
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
252
252
|
--input-border: none;
|
|
253
253
|
--input-height: var(--height);
|
|
254
|
-
white-space: nowrap;
|
|
255
|
-
overflow-x: clip;
|
|
254
|
+
white-space: var(--cell-white-space, nowrap);
|
|
255
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
256
256
|
text-overflow: ellipsis;
|
|
257
257
|
position: relative;
|
|
258
258
|
padding-left: 0.75rem;
|
|
@@ -261,7 +261,8 @@
|
|
|
261
261
|
border-bottom: solid 1px #cbd4da;
|
|
262
262
|
box-sizing: border-box;
|
|
263
263
|
width: 100%;
|
|
264
|
-
height: var(--height);
|
|
264
|
+
height: var(--cell-height, var(--height));
|
|
265
|
+
min-height: var(--cell-min-height, var(--height));
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
.focusable.multifocus,
|
|
@@ -221,8 +221,8 @@
|
|
|
221
221
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
222
222
|
--input-border: none;
|
|
223
223
|
--input-height: var(--height);
|
|
224
|
-
white-space: nowrap;
|
|
225
|
-
overflow-x: clip;
|
|
224
|
+
white-space: var(--cell-white-space, nowrap);
|
|
225
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
226
226
|
text-overflow: ellipsis;
|
|
227
227
|
position: relative;
|
|
228
228
|
padding-left: 0.75rem;
|
|
@@ -231,7 +231,8 @@
|
|
|
231
231
|
border-bottom: solid 1px #cbd4da;
|
|
232
232
|
box-sizing: border-box;
|
|
233
233
|
width: 100%;
|
|
234
|
-
height: var(--height);
|
|
234
|
+
height: var(--cell-height, var(--height));
|
|
235
|
+
min-height: var(--cell-min-height, var(--height));
|
|
235
236
|
}
|
|
236
237
|
|
|
237
238
|
.focusable.multifocus,
|
|
@@ -262,8 +262,8 @@
|
|
|
262
262
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
263
263
|
--input-border: none;
|
|
264
264
|
--input-height: var(--height);
|
|
265
|
-
white-space: nowrap;
|
|
266
|
-
overflow-x: clip;
|
|
265
|
+
white-space: var(--cell-white-space, nowrap);
|
|
266
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
267
267
|
text-overflow: ellipsis;
|
|
268
268
|
position: relative;
|
|
269
269
|
padding-left: 0.75rem;
|
|
@@ -272,7 +272,8 @@
|
|
|
272
272
|
border-bottom: solid 1px #cbd4da;
|
|
273
273
|
box-sizing: border-box;
|
|
274
274
|
width: 100%;
|
|
275
|
-
height: var(--height);
|
|
275
|
+
height: var(--cell-height, var(--height));
|
|
276
|
+
min-height: var(--cell-min-height, var(--height));
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
.focusable.multifocus,
|
|
@@ -184,8 +184,8 @@
|
|
|
184
184
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
185
185
|
--input-border: none;
|
|
186
186
|
--input-height: var(--height);
|
|
187
|
-
white-space: nowrap;
|
|
188
|
-
overflow-x: clip;
|
|
187
|
+
white-space: var(--cell-white-space, nowrap);
|
|
188
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
189
189
|
text-overflow: ellipsis;
|
|
190
190
|
position: relative;
|
|
191
191
|
padding-left: 0.75rem;
|
|
@@ -194,7 +194,8 @@
|
|
|
194
194
|
border-bottom: solid 1px #cbd4da;
|
|
195
195
|
box-sizing: border-box;
|
|
196
196
|
width: 100%;
|
|
197
|
-
height: var(--height);
|
|
197
|
+
height: var(--cell-height, var(--height));
|
|
198
|
+
min-height: var(--cell-min-height, var(--height));
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
input[type=checkbox] {
|
|
@@ -234,8 +234,8 @@
|
|
|
234
234
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
235
235
|
--input-border: none;
|
|
236
236
|
--input-height: var(--height);
|
|
237
|
-
white-space: nowrap;
|
|
238
|
-
overflow-x: clip;
|
|
237
|
+
white-space: var(--cell-white-space, nowrap);
|
|
238
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
239
239
|
text-overflow: ellipsis;
|
|
240
240
|
position: relative;
|
|
241
241
|
padding-left: 0.75rem;
|
|
@@ -244,7 +244,8 @@
|
|
|
244
244
|
border-bottom: solid 1px #cbd4da;
|
|
245
245
|
box-sizing: border-box;
|
|
246
246
|
width: 100%;
|
|
247
|
-
height: var(--height);
|
|
247
|
+
height: var(--cell-height, var(--height));
|
|
248
|
+
min-height: var(--cell-min-height, var(--height));
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
.focusable.multifocus,
|
|
@@ -202,8 +202,8 @@
|
|
|
202
202
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
203
203
|
--input-border: none;
|
|
204
204
|
--input-height: var(--height);
|
|
205
|
-
white-space: nowrap;
|
|
206
|
-
overflow-x: clip;
|
|
205
|
+
white-space: var(--cell-white-space, nowrap);
|
|
206
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
207
207
|
text-overflow: ellipsis;
|
|
208
208
|
position: relative;
|
|
209
209
|
padding-left: 0.75rem;
|
|
@@ -212,7 +212,8 @@
|
|
|
212
212
|
border-bottom: solid 1px #cbd4da;
|
|
213
213
|
box-sizing: border-box;
|
|
214
214
|
width: 100%;
|
|
215
|
-
height: var(--height);
|
|
215
|
+
height: var(--cell-height, var(--height));
|
|
216
|
+
min-height: var(--cell-min-height, var(--height));
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
.focusable.multifocus,
|
|
@@ -188,8 +188,8 @@
|
|
|
188
188
|
transition: line-height 0.2s ease, height 0.2s ease;
|
|
189
189
|
--input-border: none;
|
|
190
190
|
--input-height: var(--height);
|
|
191
|
-
white-space: nowrap;
|
|
192
|
-
overflow-x: clip;
|
|
191
|
+
white-space: var(--cell-white-space, nowrap);
|
|
192
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
193
193
|
text-overflow: ellipsis;
|
|
194
194
|
position: relative;
|
|
195
195
|
padding-left: 0.75rem;
|
|
@@ -198,7 +198,8 @@
|
|
|
198
198
|
border-bottom: solid 1px #cbd4da;
|
|
199
199
|
box-sizing: border-box;
|
|
200
200
|
width: 100%;
|
|
201
|
-
height: var(--height);
|
|
201
|
+
height: var(--cell-height, var(--height));
|
|
202
|
+
min-height: var(--cell-min-height, var(--height));
|
|
202
203
|
}
|
|
203
204
|
|
|
204
205
|
.focusable {
|
|
@@ -153,6 +153,19 @@
|
|
|
153
153
|
// `innerTableName`. Generating this once per row prevents localStorage
|
|
154
154
|
// preset keys from accumulating UUID-keyed garbage every expand toggle.
|
|
155
155
|
const fallbackInnerTableName = generateWeakId<ScoriaStorageKey>();
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Inline style appended to a cell's `style="..."` when its column opts
|
|
159
|
+
* into `wrapValue`. The hooks switch the leaf cell's `white-space`,
|
|
160
|
+
* `overflow-x`, and `height` to wrap-friendly values. Implemented as
|
|
161
|
+
* CSS-variable overrides so the table-cell-basic mixin in
|
|
162
|
+
* `_mixins.scss` consumes them via `var(--cell-* , fallback)`.
|
|
163
|
+
*/
|
|
164
|
+
function cellWrapStyle(cell: TableCell<T>): string {
|
|
165
|
+
return cell.column.columnDef.wrapValue
|
|
166
|
+
? '--cell-white-space: normal; --cell-overflow-x: visible; --cell-height: auto; --cell-min-height: var(--height);'
|
|
167
|
+
: '';
|
|
168
|
+
}
|
|
156
169
|
</script>
|
|
157
170
|
|
|
158
171
|
<div
|
|
@@ -187,7 +200,7 @@
|
|
|
187
200
|
<div
|
|
188
201
|
role="cell"
|
|
189
202
|
class="cell pinned-left"
|
|
190
|
-
style="left: {leftOffsets[index]}px"
|
|
203
|
+
style="left: {leftOffsets[index]}px; {cellWrapStyle(cell)}"
|
|
191
204
|
>
|
|
192
205
|
<TableColumn
|
|
193
206
|
{cell}
|
|
@@ -200,6 +213,7 @@
|
|
|
200
213
|
<div
|
|
201
214
|
role="cell"
|
|
202
215
|
class="cell"
|
|
216
|
+
style={cellWrapStyle(cell)}
|
|
203
217
|
>
|
|
204
218
|
<TableColumn
|
|
205
219
|
{cell}
|
|
@@ -212,7 +226,7 @@
|
|
|
212
226
|
<div
|
|
213
227
|
role="cell"
|
|
214
228
|
class="cell pinned-right"
|
|
215
|
-
style="right: {rightOffsets[index]}px"
|
|
229
|
+
style="right: {rightOffsets[index]}px; {cellWrapStyle(cell)}"
|
|
216
230
|
>
|
|
217
231
|
<TableColumn
|
|
218
232
|
{cell}
|
|
@@ -109,6 +109,8 @@ function commonProps(opts, kind) {
|
|
|
109
109
|
// per-kind differentiation the factory just put in place.
|
|
110
110
|
minSize: opts.minWidth ?? defaultWidth,
|
|
111
111
|
width: opts.width ?? defaultWidth,
|
|
112
|
+
maxWidth: opts.maxWidth,
|
|
113
|
+
wrapValue: opts.wrapValue,
|
|
112
114
|
allowSorting: opts.allowSorting,
|
|
113
115
|
allowFiltering: opts.allowFiltering,
|
|
114
116
|
defaultHidden: opts.defaultHidden,
|
|
@@ -256,9 +258,27 @@ export function createColumnFactory() {
|
|
|
256
258
|
const normalisedOptions = opts.getOptions
|
|
257
259
|
? normaliseOptionsLoader(opts.getOptions)
|
|
258
260
|
: undefined;
|
|
261
|
+
// Display columns have no intrinsic kind (the value comes from an
|
|
262
|
+
// arbitrary `value: (row) => ...` thunk) so the generic 'display'
|
|
263
|
+
// default (150px) is the fallback. When the consumer DOES pass a
|
|
264
|
+
// `filterValueType`, treat it as a hint about the rendered shape
|
|
265
|
+
// of the column and pick the matching per-kind default so a table
|
|
266
|
+
// full of `col.display` columns ends up visually differentiated
|
|
267
|
+
// instead of every column collapsing to the same 150px floor.
|
|
268
|
+
const inferredKind = opts.filterValueType === 'Number'
|
|
269
|
+
? 'number'
|
|
270
|
+
: opts.filterValueType === 'Date'
|
|
271
|
+
? 'date'
|
|
272
|
+
: opts.filterValueType === 'Bool'
|
|
273
|
+
? 'checkbox'
|
|
274
|
+
: opts.filterValueType === 'Select'
|
|
275
|
+
? 'select'
|
|
276
|
+
: opts.filterValueType === 'String'
|
|
277
|
+
? 'text'
|
|
278
|
+
: 'display';
|
|
259
279
|
const def = new DisplayDef({
|
|
260
280
|
id,
|
|
261
|
-
...commonProps(opts,
|
|
281
|
+
...commonProps(opts, inferredKind),
|
|
262
282
|
accessorFn: opts.value,
|
|
263
283
|
modal: opts.modal,
|
|
264
284
|
// Display columns have no implicit filter type (unlike the
|
|
@@ -356,17 +356,20 @@
|
|
|
356
356
|
// 20px to match the existing visual).
|
|
357
357
|
// - Each other track uses one of two strategies based on the
|
|
358
358
|
// column's `userResized` flag:
|
|
359
|
-
// - `userResized = false` (default): `minmax(width, 1fr)`.
|
|
360
|
-
// column
|
|
361
|
-
//
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
//
|
|
359
|
+
// - `userResized = false` (default): `minmax(width, maxWidth ?? 1fr)`.
|
|
360
|
+
// The column is at least `width` wide and grows to share any
|
|
361
|
+
// leftover horizontal space with its sibling tracks. If the
|
|
362
|
+
// column has a `maxWidth`, that pixel value is the upper bound
|
|
363
|
+
// instead - the column never grows past `maxWidth`, and cells
|
|
364
|
+
// whose content exceeds the track ellipsise (or wrap, when the
|
|
365
|
+
// column opts in to `wrapValue`). The `1fr` upper bound was
|
|
366
|
+
// chosen over `max-content` because `max-content` is unstable
|
|
367
|
+
// under row virtualisation: tracks resize as rows scroll in
|
|
368
|
+
// and out of the rendered window because the auto-min/max
|
|
369
|
+
// consults only the currently-rendered cells.
|
|
365
370
|
// - `userResized = true`: `${width}px` (fixed). The column sits
|
|
366
371
|
// at exactly the size the user dragged it to, and dragging the
|
|
367
|
-
// handle again only changes this column
|
|
368
|
-
// columns keep their explicit widths and non-resized columns
|
|
369
|
-
// just adjust their flex share.
|
|
372
|
+
// handle again only changes this column.
|
|
370
373
|
// - Pinned and centre columns use the same per-column rule so
|
|
371
374
|
// toggling a column's pin state does not change its width.
|
|
372
375
|
// - Sticky-cell offsets are read from `_columnRenderedWidths`
|
|
@@ -374,10 +377,16 @@
|
|
|
374
377
|
// accurate sticky positions in both states.
|
|
375
378
|
const colsTemplate = $derived.by(() => {
|
|
376
379
|
void tableContext.columnSizing;
|
|
377
|
-
const track = (col: {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
380
|
+
const track = (col: {
|
|
381
|
+
columnDef: { width: number; maxWidth?: number; userResized: boolean };
|
|
382
|
+
}) => {
|
|
383
|
+
if (col.columnDef.userResized) {
|
|
384
|
+
return `${col.columnDef.width}px`;
|
|
385
|
+
}
|
|
386
|
+
const upper =
|
|
387
|
+
col.columnDef.maxWidth != null ? `${col.columnDef.maxWidth}px` : '1fr';
|
|
388
|
+
return `minmax(${col.columnDef.width}px, ${upper})`;
|
|
389
|
+
};
|
|
381
390
|
const tracks: Array<string> = ['20px'];
|
|
382
391
|
for (const col of leftColumns) {
|
|
383
392
|
tracks.push(track(col));
|
|
@@ -48,6 +48,16 @@ export interface ColumnDefProps<T extends object, in FilterFnType, out OptionsTy
|
|
|
48
48
|
minSize?: Pixels;
|
|
49
49
|
/** Initial width in pixels. Defaults to `minSize`. */
|
|
50
50
|
width?: Pixels;
|
|
51
|
+
/** Maximum width in pixels. When set, caps the grid track at this
|
|
52
|
+
* value (replacing the default `1fr` upper bound on the track).
|
|
53
|
+
* Cell content beyond the track is ellipsised, or wraps when
|
|
54
|
+
* `wrapValue` is also set. */
|
|
55
|
+
maxWidth?: Pixels;
|
|
56
|
+
/** When true, cell content that does not fit wraps onto new lines
|
|
57
|
+
* and the row's height grows to fit. When false (default) overflow
|
|
58
|
+
* is clipped with ellipsis. Surfaces as the `--wrap-value` CSS
|
|
59
|
+
* variable on the column track so cell SCSS picks it up. */
|
|
60
|
+
wrapValue?: boolean;
|
|
51
61
|
/** Async-flag predicate for whether a given cell is currently editable. */
|
|
52
62
|
isEditable?: (item: T, index: number) => boolean | Promise<boolean>;
|
|
53
63
|
/** Whether the column may be resized by the user. Defaults to `true`. */
|
|
@@ -129,6 +139,15 @@ export declare abstract class ColumnDef<T extends object, in FilterFnType = neve
|
|
|
129
139
|
/** Current width in pixels. Mutated by the resize handle. */
|
|
130
140
|
get width(): Pixels;
|
|
131
141
|
set width(v: Pixels);
|
|
142
|
+
private _maxWidth;
|
|
143
|
+
/** Maximum width in pixels. Undefined = no cap (track flexes under `1fr`). */
|
|
144
|
+
get maxWidth(): Pixels | undefined;
|
|
145
|
+
set maxWidth(v: Pixels | undefined);
|
|
146
|
+
private _wrapValue;
|
|
147
|
+
/** Whether oversized cell content wraps onto new lines (true) or is
|
|
148
|
+
* clipped with ellipsis (false). */
|
|
149
|
+
get wrapValue(): boolean;
|
|
150
|
+
set wrapValue(v: boolean);
|
|
132
151
|
private _isResizing;
|
|
133
152
|
/** Whether the resize handle is currently active. */
|
|
134
153
|
get isResizing(): boolean;
|
|
@@ -36,6 +36,8 @@ export class ColumnDef {
|
|
|
36
36
|
this.accessorFn = $derived(props.accessorFn);
|
|
37
37
|
this._minSize = $state(props.minSize ?? 48);
|
|
38
38
|
this._width = $state(props.width ?? props.minSize ?? 48);
|
|
39
|
+
this._maxWidth = $state(props.maxWidth);
|
|
40
|
+
this._wrapValue = $state(props.wrapValue ?? false);
|
|
39
41
|
this.isEditable = $derived(props.isEditable ?? (() => Promise.resolve(false)));
|
|
40
42
|
this.resizable = $derived(props.resizable ?? true);
|
|
41
43
|
this.header = $derived(props.header);
|
|
@@ -89,6 +91,23 @@ export class ColumnDef {
|
|
|
89
91
|
set width(v) {
|
|
90
92
|
this._width = v;
|
|
91
93
|
}
|
|
94
|
+
_maxWidth;
|
|
95
|
+
/** Maximum width in pixels. Undefined = no cap (track flexes under `1fr`). */
|
|
96
|
+
get maxWidth() {
|
|
97
|
+
return this._maxWidth;
|
|
98
|
+
}
|
|
99
|
+
set maxWidth(v) {
|
|
100
|
+
this._maxWidth = v;
|
|
101
|
+
}
|
|
102
|
+
_wrapValue;
|
|
103
|
+
/** Whether oversized cell content wraps onto new lines (true) or is
|
|
104
|
+
* clipped with ellipsis (false). */
|
|
105
|
+
get wrapValue() {
|
|
106
|
+
return this._wrapValue;
|
|
107
|
+
}
|
|
108
|
+
set wrapValue(v) {
|
|
109
|
+
this._wrapValue = v;
|
|
110
|
+
}
|
|
92
111
|
_isResizing = $state(false);
|
|
93
112
|
/** Whether the resize handle is currently active. */
|
|
94
113
|
get isResizing() {
|
|
@@ -21,6 +21,18 @@ export interface BaseColumnOptions {
|
|
|
21
21
|
minWidth?: number;
|
|
22
22
|
/** Initial width in pixels. Defaults to `minWidth`. */
|
|
23
23
|
width?: number;
|
|
24
|
+
/** Maximum width in pixels. When set, the column's grid track is
|
|
25
|
+
* capped at this value (instead of flexing freely under `1fr`).
|
|
26
|
+
* Cell content longer than the track is ellipsised by default;
|
|
27
|
+
* set `wrapValue: true` to make the row grow vertically and the
|
|
28
|
+
* content wrap onto multiple lines instead. */
|
|
29
|
+
maxWidth?: number;
|
|
30
|
+
/** When true, cell content that does not fit horizontally wraps
|
|
31
|
+
* onto a new line and the row's height expands to fit. When false
|
|
32
|
+
* (the default) overflow is clipped with `text-overflow: ellipsis`.
|
|
33
|
+
* Most useful when combined with `maxWidth` to clamp the track
|
|
34
|
+
* width and force wrapping to kick in. */
|
|
35
|
+
wrapValue?: boolean;
|
|
24
36
|
/** Whether this column may be sorted. Defaults to true. */
|
|
25
37
|
allowSorting?: boolean;
|
|
26
38
|
/** Whether this column may be filtered. Defaults to true. */
|
|
@@ -3,6 +3,7 @@ import type { AnyEditEvent } from './AnyEditEvent.js';
|
|
|
3
3
|
import type { ColumnFactory } from './ColumnFactory.js';
|
|
4
4
|
import type { ColumnSpec } from './ColumnSpec.js';
|
|
5
5
|
import type { LiteralRowIdKey } from './KeyConstraints.js';
|
|
6
|
+
import type { CustomRemoteFilters } from '../Filtering/CustomRemoteFilters.js';
|
|
6
7
|
import type { RowSource } from './RowSource.js';
|
|
7
8
|
import type { SelectionOptions } from './SelectionOptions.js';
|
|
8
9
|
import type { TableInitialState } from './TableInitialState.js';
|
|
@@ -35,6 +36,16 @@ export interface CreateTableOptions<TRow extends object, TRowId extends Primitiv
|
|
|
35
36
|
/** Column declarations. The closure receives a typed `ColumnFactory<TRow>`;
|
|
36
37
|
* return the column specs in memory order. */
|
|
37
38
|
columns: (col: ColumnFactory<TRow>) => ReadonlyArray<ColumnSpec<TRow>>;
|
|
39
|
+
/** Optional registry of custom server-driven filters, keyed by column id.
|
|
40
|
+
* Each entry provides the metadata the advanced filter panel needs to
|
|
41
|
+
* render an input for a column that does not have a built-in `filterFn`
|
|
42
|
+
* (such as `col.filterOnly(...)` chips or nested-path display columns).
|
|
43
|
+
*
|
|
44
|
+
* Passed as a thunk so the caller can return a `SvelteMap` whose
|
|
45
|
+
* reactive identity is preserved across re-renders. The same map is
|
|
46
|
+
* typically also handed to `createRemoteRowSource({ remoteFilters })`
|
|
47
|
+
* so the server query and the filter UI agree on the available keys. */
|
|
48
|
+
remoteFilters?: () => CustomRemoteFilters<unknown> | undefined;
|
|
38
49
|
/** Selection. Defaults to `{ mode: 'multiple' }` with internal map ownership. */
|
|
39
50
|
selection?: SelectionOptions<TRow, TRowId>;
|
|
40
51
|
/** Persistence. Defaults to all layers enabled. Pass `false` to disable
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RefWrapper } from '../../../../Types/Internal/RefWrapper.js';
|
|
2
2
|
import type { ColumnFiltersState } from '../Filtering/ColumnFiltersState.js';
|
|
3
3
|
import type { SortingState } from '../DataRepository/SortingState.js';
|
|
4
|
+
import type { CustomRemoteFilters } from '../Filtering/CustomRemoteFilters.js';
|
|
4
5
|
/**
|
|
5
6
|
* Data source for a Table. One of three variants:
|
|
6
7
|
*
|
|
@@ -71,6 +72,14 @@ export interface CustomRowSource<TRow extends object> {
|
|
|
71
72
|
* `AbortSignal` so consumers can cancel an in-flight request when its
|
|
72
73
|
* result is superseded. */
|
|
73
74
|
fetch: (request: RowFetchRequest) => Promise<RowFetchResponse<TRow>>;
|
|
75
|
+
/** Optional registry of server-driven filters keyed by column id. When
|
|
76
|
+
* set, the table's advanced filter panel will render a chip for each
|
|
77
|
+
* entry alongside the standard column-derived chips. Typically the
|
|
78
|
+
* custom-rows factory (e.g. `createRemoteRowSource`) populates this
|
|
79
|
+
* from the same map it uses to build the request URL, so the UI and
|
|
80
|
+
* the server query stay in sync without the caller having to wire the
|
|
81
|
+
* map twice. */
|
|
82
|
+
remoteFilters?: CustomRemoteFilters<unknown>;
|
|
74
83
|
}
|
|
75
84
|
/** Argument passed to `CustomRowSource.fetch`. */
|
|
76
85
|
export interface RowFetchRequest {
|
|
@@ -69,7 +69,15 @@ export function createTable(options) {
|
|
|
69
69
|
}
|
|
70
70
|
return internal.def;
|
|
71
71
|
});
|
|
72
|
-
|
|
72
|
+
// remoteFilters resolution order:
|
|
73
|
+
// 1. Explicit `options.remoteFilters` thunk on createTable.
|
|
74
|
+
// 2. `kind: 'custom'` row source's `remoteFilters` field (set by
|
|
75
|
+
// `createRemoteRowSource` from its own option of the same name).
|
|
76
|
+
// This means a caller can hand the same `SvelteMap` to the custom
|
|
77
|
+
// row-source factory once and the filter panel picks it up for free.
|
|
78
|
+
const remoteFilters = options.remoteFilters?.() ??
|
|
79
|
+
(options.rows.kind === 'custom' ? options.rows.remoteFilters : undefined);
|
|
80
|
+
const defsWrapper = remoteFilters ? { defs, remoteFilters } : { defs };
|
|
73
81
|
// ── 3. Construct the repository for the chosen row source ──────
|
|
74
82
|
const repository = makeRepository(options.name, options.rows, options.getUserId);
|
|
75
83
|
// ── 4. Build the `onEditCell` wrapper ──────────────────────────
|
package/dist/scss/_mixins.scss
CHANGED
|
@@ -1605,8 +1605,13 @@
|
|
|
1605
1605
|
@include table-height-transition;
|
|
1606
1606
|
--input-border: none;
|
|
1607
1607
|
--input-height: var(--height);
|
|
1608
|
-
|
|
1609
|
-
overflow-x
|
|
1608
|
+
// Layout hooks driven by per-column `wrapValue` (set as
|
|
1609
|
+
// `--cell-white-space`, `--cell-overflow-x`, `--cell-height` on
|
|
1610
|
+
// the cell wrapper by TableRow / TableHead when the column opts
|
|
1611
|
+
// in). Defaults preserve the historical single-line-with-ellipsis
|
|
1612
|
+
// rendering.
|
|
1613
|
+
white-space: var(--cell-white-space, nowrap);
|
|
1614
|
+
overflow-x: var(--cell-overflow-x, clip);
|
|
1610
1615
|
text-overflow: ellipsis;
|
|
1611
1616
|
position: relative;
|
|
1612
1617
|
padding-left: 0.75rem;
|
|
@@ -1626,7 +1631,11 @@
|
|
|
1626
1631
|
// BubbleCell, etc.) - the visible symptom was the display
|
|
1627
1632
|
// cells' bottom borders sitting 1px above the row's actual
|
|
1628
1633
|
// bottom edge.
|
|
1629
|
-
|
|
1634
|
+
//
|
|
1635
|
+
// `--cell-height` lets `wrapValue` columns override the floor to
|
|
1636
|
+
// `auto`, allowing the row to grow vertically to fit wrapped text.
|
|
1637
|
+
height: var(--cell-height, var(--height));
|
|
1638
|
+
min-height: var(--cell-min-height, var(--height));
|
|
1630
1639
|
}
|
|
1631
1640
|
}
|
|
1632
1641
|
|