@mmlogic/components 0.5.9 → 0.5.11
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/cjs/mrd-boolean-field_25.cjs.entry.js +87 -28
- package/dist/collection/components/table/mrd-table/mrd-table.js +87 -28
- package/dist/components/mrd-table2.js +1 -1
- package/dist/esm/mrd-boolean-field_25.entry.js +87 -28
- package/dist/mosterdcomponents/cell-renderer-B8u5BCK-.js.map +1 -0
- package/dist/mosterdcomponents/client-layout-Bc42CfJB.js.map +1 -0
- package/dist/mosterdcomponents/document-attachments-BufPmMRv.js.map +1 -0
- package/dist/mosterdcomponents/field-helpers-CUJsHr1V.js.map +1 -0
- package/dist/mosterdcomponents/file-upload-common-DdTDuxEU.js.map +1 -0
- package/dist/mosterdcomponents/format-gcecItcD.js.map +1 -0
- package/dist/mosterdcomponents/i18n-Ba7_jO9I.js.map +1 -0
- package/dist/mosterdcomponents/index-1ayBojyN.js.map +1 -0
- package/dist/mosterdcomponents/index-DhffneUF.js.map +1 -0
- package/dist/mosterdcomponents/index.esm.js.map +1 -0
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js.map +1 -0
- package/dist/mosterdcomponents/{p-986a68d6.entry.js → p-eee4be8b.entry.js} +2 -2
- package/dist/mosterdcomponents/purify.es-_duHfPgC.js.map +1 -0
- package/dist/mosterdcomponents/query-params-BZbQoeYF.js.map +1 -0
- package/dist/mosterdcomponents/quill-C9pgw_k-.js.map +1 -0
- package/dist/mosterdcomponents/validation-CjjTt66G.js.map +1 -0
- package/dist/types/components/table/mrd-table/mrd-table.d.ts +26 -0
- package/package.json +1 -1
|
@@ -6641,6 +6641,8 @@ const MrdTable = class {
|
|
|
6641
6641
|
this.keydownHandler = null;
|
|
6642
6642
|
this.createPickerClickHandler = null;
|
|
6643
6643
|
this.viewPopoverClickHandler = null;
|
|
6644
|
+
/** Watches the host for gaining a box (e.g. its tab pane being shown) — see componentDidLoad. */
|
|
6645
|
+
this.resizeObserver = null;
|
|
6644
6646
|
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
6645
6647
|
this.colWidthMeasureScheduled = false;
|
|
6646
6648
|
/** Drag origin of the running column resize (null = no drag in progress). */
|
|
@@ -6745,6 +6747,14 @@ const MrdTable = class {
|
|
|
6745
6747
|
}
|
|
6746
6748
|
componentDidLoad() {
|
|
6747
6749
|
this.staleCheckTimer = setInterval(() => this.checkStalePages(), STALE_CHECK_INTERVAL_MS);
|
|
6750
|
+
// A table inside a hidden tab pane renders and loads page 0 without ever having a box, so
|
|
6751
|
+
// the width freeze cannot measure anything. ResizeObserver fires the moment the pane is
|
|
6752
|
+
// shown (the host gains a box) — that is when the freeze gets its chance. componentDidRender
|
|
6753
|
+
// is no help there: showing a sibling tab does not re-render this component.
|
|
6754
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
6755
|
+
this.resizeObserver = new ResizeObserver(() => this.freezeColWidths());
|
|
6756
|
+
this.resizeObserver.observe(this.el);
|
|
6757
|
+
}
|
|
6748
6758
|
}
|
|
6749
6759
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
6750
6760
|
applyDefaultSort(defaultSort) {
|
|
@@ -6848,6 +6858,10 @@ const MrdTable = class {
|
|
|
6848
6858
|
}
|
|
6849
6859
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
6850
6860
|
disconnectedCallback() {
|
|
6861
|
+
if (this.resizeObserver) {
|
|
6862
|
+
this.resizeObserver.disconnect();
|
|
6863
|
+
this.resizeObserver = null;
|
|
6864
|
+
}
|
|
6851
6865
|
if (this.staleCheckTimer !== null) {
|
|
6852
6866
|
clearInterval(this.staleCheckTimer);
|
|
6853
6867
|
this.staleCheckTimer = null;
|
|
@@ -6870,28 +6884,35 @@ const MrdTable = class {
|
|
|
6870
6884
|
}
|
|
6871
6885
|
}
|
|
6872
6886
|
componentDidRender() {
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6887
|
+
this.freezeColWidths();
|
|
6888
|
+
}
|
|
6889
|
+
/** Freeze the column widths once the first data page has rendered.
|
|
6890
|
+
*
|
|
6891
|
+
* The measurement reads layout and writes the colWidths @State, which would trigger a
|
|
6892
|
+
* re-render *during* the render cycle if done synchronously from componentDidRender. It is
|
|
6893
|
+
* deferred to a writeTask so the state mutation happens outside the render pass (avoids the
|
|
6894
|
+
* Stencil "state/prop changed during rendering" warning and potential loops).
|
|
6895
|
+
*
|
|
6896
|
+
* NB: the freeze must not depend on the totalElements prop — hosts may omit it and rely on
|
|
6897
|
+
* minKnownTotal, in which case the widths would never be locked and every incoming page
|
|
6898
|
+
* would re-flow all columns. */
|
|
6899
|
+
freezeColWidths() {
|
|
6900
|
+
if (this.colWidths.length !== 0 || this.colWidthMeasureScheduled || this.loadedPages.size === 0)
|
|
6901
|
+
return;
|
|
6902
|
+
this.colWidthMeasureScheduled = true;
|
|
6903
|
+
index.writeTask(() => {
|
|
6904
|
+
var _a;
|
|
6905
|
+
this.colWidthMeasureScheduled = false;
|
|
6906
|
+
// Re-check: state may have changed (e.g. a reset) between scheduling and running.
|
|
6907
|
+
if (this.colWidths.length !== 0)
|
|
6908
|
+
return;
|
|
6909
|
+
const measured = (_a = this.measureContentWidths()) !== null && _a !== void 0 ? _a : this.measureColWidths();
|
|
6910
|
+
// A table inside a hidden tab pane (a tab page that is loaded but not shown) has no
|
|
6911
|
+
// layout at all, so every measurement comes back 0. Locking those would pin every
|
|
6912
|
+
// column at MIN_COL_WIDTH for good; wait for the ResizeObserver to report a real box.
|
|
6913
|
+
if (measured && measured.some(w => w > 0))
|
|
6914
|
+
this.colWidths = measured;
|
|
6915
|
+
});
|
|
6895
6916
|
}
|
|
6896
6917
|
// ── Column resizing (drag the header border, Excel-style) ──────────────────
|
|
6897
6918
|
/** Current rendered header widths, or null when they can't be trusted (header not laid out yet). */
|
|
@@ -6901,6 +6922,49 @@ const MrdTable = class {
|
|
|
6901
6922
|
return null;
|
|
6902
6923
|
return Array.from(ths).map(th => Math.round(th.getBoundingClientRect().width));
|
|
6903
6924
|
}
|
|
6925
|
+
/** Width one cell needs to show its content in full, borders included.
|
|
6926
|
+
* Read from scrollWidth rather than the laid-out box: cells clip with `overflow: hidden`,
|
|
6927
|
+
* so a squeezed cell reports the width it *was given*, not the width it needs. */
|
|
6928
|
+
neededWidth(cell) {
|
|
6929
|
+
// The layout metrics are absent in the mock DOM the specs run on; treat them as 0
|
|
6930
|
+
// rather than letting a NaN poison the Math.max chain the callers build.
|
|
6931
|
+
const px = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
|
|
6932
|
+
const clientWidth = px(cell.clientWidth);
|
|
6933
|
+
const scrollWidth = px(cell.scrollWidth);
|
|
6934
|
+
const paddingRight = px(parseFloat(getComputedStyle(cell).paddingRight || '0'));
|
|
6935
|
+
const borders = Math.max(0, px(cell.offsetWidth) - clientWidth);
|
|
6936
|
+
// scrollWidth drops the right padding once the content overflows the clipped box;
|
|
6937
|
+
// when it fits, clientWidth is already the full padded box.
|
|
6938
|
+
const content = scrollWidth > clientWidth ? scrollWidth + paddingRight : clientWidth;
|
|
6939
|
+
return Math.ceil(content + borders);
|
|
6940
|
+
}
|
|
6941
|
+
/** Width each column needs for its header and its rendered page-0 cells — what the columns
|
|
6942
|
+
* are locked to, so they never end up narrower than their content.
|
|
6943
|
+
*
|
|
6944
|
+
* Deliberately not the laid-out widths: with many columns the browser squeezes them to fit
|
|
6945
|
+
* the container instead of overflowing (the cells clip, so they no longer resist), which
|
|
6946
|
+
* cost the horizontal scrollbar. Locking the needed widths makes the summed table width
|
|
6947
|
+
* exceed the container again, and `.mrd-table__scroll` scrolls. Capped per column at
|
|
6948
|
+
* MAX_AUTOFIT_WIDTH so one outlier value can't blow up the layout — same cap as auto-fit. */
|
|
6949
|
+
measureContentWidths() {
|
|
6950
|
+
const ths = this.el.querySelectorAll('.mrd-table__header');
|
|
6951
|
+
if (ths.length === 0 || ths.length !== this.columns.length)
|
|
6952
|
+
return null;
|
|
6953
|
+
const needed = Array.from(ths).map((th, idx) => {
|
|
6954
|
+
let widest = this.neededWidth(th);
|
|
6955
|
+
// .mrd-table__cell only matches real data cells — the shimmer/retry rows render a single
|
|
6956
|
+
// colSpan cell (without that class) which would measure as the full table width.
|
|
6957
|
+
this.el
|
|
6958
|
+
.querySelectorAll(`.mrd-table__cell:nth-child(${idx + 1})`)
|
|
6959
|
+
.forEach(cell => { widest = Math.max(widest, this.neededWidth(cell)); });
|
|
6960
|
+
return widest;
|
|
6961
|
+
});
|
|
6962
|
+
// Nothing has a box: the table is in a hidden tab pane. Report "cannot measure" rather
|
|
6963
|
+
// than clamping a row of zeroes up to MIN_COL_WIDTH, which would look like a real result.
|
|
6964
|
+
if (needed.every(w => w <= 0))
|
|
6965
|
+
return null;
|
|
6966
|
+
return needed.map(w => Math.min(Math.max(w, MIN_COL_WIDTH), MAX_AUTOFIT_WIDTH));
|
|
6967
|
+
}
|
|
6904
6968
|
/** Re-reads the rendered header widths into colWidths so a drag starts from what is
|
|
6905
6969
|
* actually on screen — and locks the columns if they weren't locked yet.
|
|
6906
6970
|
*
|
|
@@ -6961,12 +7025,7 @@ const MrdTable = class {
|
|
|
6961
7025
|
// colSpan cell (without that class) which would otherwise measure as the full table width.
|
|
6962
7026
|
const cells = this.el.querySelectorAll(`.mrd-table__header:nth-child(${idx + 1}), .mrd-table__cell:nth-child(${idx + 1})`);
|
|
6963
7027
|
let widest = 0;
|
|
6964
|
-
cells.forEach(cell => {
|
|
6965
|
-
// scrollWidth is the untruncated content width; cells clip with overflow: hidden.
|
|
6966
|
-
const style = getComputedStyle(cell);
|
|
6967
|
-
const padding = parseFloat(style.paddingLeft || '0') + parseFloat(style.paddingRight || '0');
|
|
6968
|
-
widest = Math.max(widest, cell.scrollWidth + padding);
|
|
6969
|
-
});
|
|
7028
|
+
cells.forEach(cell => { widest = Math.max(widest, this.neededWidth(cell)); });
|
|
6970
7029
|
if (widest > 0)
|
|
6971
7030
|
this.setColWidth(idx, Math.min(widest, MAX_AUTOFIT_WIDTH));
|
|
6972
7031
|
}
|
|
@@ -27,6 +27,8 @@ export class MrdTable {
|
|
|
27
27
|
this.keydownHandler = null;
|
|
28
28
|
this.createPickerClickHandler = null;
|
|
29
29
|
this.viewPopoverClickHandler = null;
|
|
30
|
+
/** Watches the host for gaining a box (e.g. its tab pane being shown) — see componentDidLoad. */
|
|
31
|
+
this.resizeObserver = null;
|
|
30
32
|
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
31
33
|
this.colWidthMeasureScheduled = false;
|
|
32
34
|
/** Drag origin of the running column resize (null = no drag in progress). */
|
|
@@ -131,6 +133,14 @@ export class MrdTable {
|
|
|
131
133
|
}
|
|
132
134
|
componentDidLoad() {
|
|
133
135
|
this.staleCheckTimer = setInterval(() => this.checkStalePages(), STALE_CHECK_INTERVAL_MS);
|
|
136
|
+
// A table inside a hidden tab pane renders and loads page 0 without ever having a box, so
|
|
137
|
+
// the width freeze cannot measure anything. ResizeObserver fires the moment the pane is
|
|
138
|
+
// shown (the host gains a box) — that is when the freeze gets its chance. componentDidRender
|
|
139
|
+
// is no help there: showing a sibling tab does not re-render this component.
|
|
140
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
141
|
+
this.resizeObserver = new ResizeObserver(() => this.freezeColWidths());
|
|
142
|
+
this.resizeObserver.observe(this.el);
|
|
143
|
+
}
|
|
134
144
|
}
|
|
135
145
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
136
146
|
applyDefaultSort(defaultSort) {
|
|
@@ -234,6 +244,10 @@ export class MrdTable {
|
|
|
234
244
|
}
|
|
235
245
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
236
246
|
disconnectedCallback() {
|
|
247
|
+
if (this.resizeObserver) {
|
|
248
|
+
this.resizeObserver.disconnect();
|
|
249
|
+
this.resizeObserver = null;
|
|
250
|
+
}
|
|
237
251
|
if (this.staleCheckTimer !== null) {
|
|
238
252
|
clearInterval(this.staleCheckTimer);
|
|
239
253
|
this.staleCheckTimer = null;
|
|
@@ -256,28 +270,35 @@ export class MrdTable {
|
|
|
256
270
|
}
|
|
257
271
|
}
|
|
258
272
|
componentDidRender() {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
273
|
+
this.freezeColWidths();
|
|
274
|
+
}
|
|
275
|
+
/** Freeze the column widths once the first data page has rendered.
|
|
276
|
+
*
|
|
277
|
+
* The measurement reads layout and writes the colWidths @State, which would trigger a
|
|
278
|
+
* re-render *during* the render cycle if done synchronously from componentDidRender. It is
|
|
279
|
+
* deferred to a writeTask so the state mutation happens outside the render pass (avoids the
|
|
280
|
+
* Stencil "state/prop changed during rendering" warning and potential loops).
|
|
281
|
+
*
|
|
282
|
+
* NB: the freeze must not depend on the totalElements prop — hosts may omit it and rely on
|
|
283
|
+
* minKnownTotal, in which case the widths would never be locked and every incoming page
|
|
284
|
+
* would re-flow all columns. */
|
|
285
|
+
freezeColWidths() {
|
|
286
|
+
if (this.colWidths.length !== 0 || this.colWidthMeasureScheduled || this.loadedPages.size === 0)
|
|
287
|
+
return;
|
|
288
|
+
this.colWidthMeasureScheduled = true;
|
|
289
|
+
writeTask(() => {
|
|
290
|
+
var _a;
|
|
291
|
+
this.colWidthMeasureScheduled = false;
|
|
292
|
+
// Re-check: state may have changed (e.g. a reset) between scheduling and running.
|
|
293
|
+
if (this.colWidths.length !== 0)
|
|
294
|
+
return;
|
|
295
|
+
const measured = (_a = this.measureContentWidths()) !== null && _a !== void 0 ? _a : this.measureColWidths();
|
|
296
|
+
// A table inside a hidden tab pane (a tab page that is loaded but not shown) has no
|
|
297
|
+
// layout at all, so every measurement comes back 0. Locking those would pin every
|
|
298
|
+
// column at MIN_COL_WIDTH for good; wait for the ResizeObserver to report a real box.
|
|
299
|
+
if (measured && measured.some(w => w > 0))
|
|
300
|
+
this.colWidths = measured;
|
|
301
|
+
});
|
|
281
302
|
}
|
|
282
303
|
// ── Column resizing (drag the header border, Excel-style) ──────────────────
|
|
283
304
|
/** Current rendered header widths, or null when they can't be trusted (header not laid out yet). */
|
|
@@ -287,6 +308,49 @@ export class MrdTable {
|
|
|
287
308
|
return null;
|
|
288
309
|
return Array.from(ths).map(th => Math.round(th.getBoundingClientRect().width));
|
|
289
310
|
}
|
|
311
|
+
/** Width one cell needs to show its content in full, borders included.
|
|
312
|
+
* Read from scrollWidth rather than the laid-out box: cells clip with `overflow: hidden`,
|
|
313
|
+
* so a squeezed cell reports the width it *was given*, not the width it needs. */
|
|
314
|
+
neededWidth(cell) {
|
|
315
|
+
// The layout metrics are absent in the mock DOM the specs run on; treat them as 0
|
|
316
|
+
// rather than letting a NaN poison the Math.max chain the callers build.
|
|
317
|
+
const px = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
|
|
318
|
+
const clientWidth = px(cell.clientWidth);
|
|
319
|
+
const scrollWidth = px(cell.scrollWidth);
|
|
320
|
+
const paddingRight = px(parseFloat(getComputedStyle(cell).paddingRight || '0'));
|
|
321
|
+
const borders = Math.max(0, px(cell.offsetWidth) - clientWidth);
|
|
322
|
+
// scrollWidth drops the right padding once the content overflows the clipped box;
|
|
323
|
+
// when it fits, clientWidth is already the full padded box.
|
|
324
|
+
const content = scrollWidth > clientWidth ? scrollWidth + paddingRight : clientWidth;
|
|
325
|
+
return Math.ceil(content + borders);
|
|
326
|
+
}
|
|
327
|
+
/** Width each column needs for its header and its rendered page-0 cells — what the columns
|
|
328
|
+
* are locked to, so they never end up narrower than their content.
|
|
329
|
+
*
|
|
330
|
+
* Deliberately not the laid-out widths: with many columns the browser squeezes them to fit
|
|
331
|
+
* the container instead of overflowing (the cells clip, so they no longer resist), which
|
|
332
|
+
* cost the horizontal scrollbar. Locking the needed widths makes the summed table width
|
|
333
|
+
* exceed the container again, and `.mrd-table__scroll` scrolls. Capped per column at
|
|
334
|
+
* MAX_AUTOFIT_WIDTH so one outlier value can't blow up the layout — same cap as auto-fit. */
|
|
335
|
+
measureContentWidths() {
|
|
336
|
+
const ths = this.el.querySelectorAll('.mrd-table__header');
|
|
337
|
+
if (ths.length === 0 || ths.length !== this.columns.length)
|
|
338
|
+
return null;
|
|
339
|
+
const needed = Array.from(ths).map((th, idx) => {
|
|
340
|
+
let widest = this.neededWidth(th);
|
|
341
|
+
// .mrd-table__cell only matches real data cells — the shimmer/retry rows render a single
|
|
342
|
+
// colSpan cell (without that class) which would measure as the full table width.
|
|
343
|
+
this.el
|
|
344
|
+
.querySelectorAll(`.mrd-table__cell:nth-child(${idx + 1})`)
|
|
345
|
+
.forEach(cell => { widest = Math.max(widest, this.neededWidth(cell)); });
|
|
346
|
+
return widest;
|
|
347
|
+
});
|
|
348
|
+
// Nothing has a box: the table is in a hidden tab pane. Report "cannot measure" rather
|
|
349
|
+
// than clamping a row of zeroes up to MIN_COL_WIDTH, which would look like a real result.
|
|
350
|
+
if (needed.every(w => w <= 0))
|
|
351
|
+
return null;
|
|
352
|
+
return needed.map(w => Math.min(Math.max(w, MIN_COL_WIDTH), MAX_AUTOFIT_WIDTH));
|
|
353
|
+
}
|
|
290
354
|
/** Re-reads the rendered header widths into colWidths so a drag starts from what is
|
|
291
355
|
* actually on screen — and locks the columns if they weren't locked yet.
|
|
292
356
|
*
|
|
@@ -347,12 +411,7 @@ export class MrdTable {
|
|
|
347
411
|
// colSpan cell (without that class) which would otherwise measure as the full table width.
|
|
348
412
|
const cells = this.el.querySelectorAll(`.mrd-table__header:nth-child(${idx + 1}), .mrd-table__cell:nth-child(${idx + 1})`);
|
|
349
413
|
let widest = 0;
|
|
350
|
-
cells.forEach(cell => {
|
|
351
|
-
// scrollWidth is the untruncated content width; cells clip with overflow: hidden.
|
|
352
|
-
const style = getComputedStyle(cell);
|
|
353
|
-
const padding = parseFloat(style.paddingLeft || '0') + parseFloat(style.paddingRight || '0');
|
|
354
|
-
widest = Math.max(widest, cell.scrollWidth + padding);
|
|
355
|
-
});
|
|
414
|
+
cells.forEach(cell => { widest = Math.max(widest, this.neededWidth(cell)); });
|
|
356
415
|
if (widest > 0)
|
|
357
416
|
this.setColWidth(idx, Math.min(widest, MAX_AUTOFIT_WIDTH));
|
|
358
417
|
}
|