xv-webcomponents 2.0.0-beta.2 → 2.0.0-beta.28
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/README.md +3 -2
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +3 -4
- package/dist/angular/proxies.d.ts +60 -34
- package/dist/angular/proxies.js +51 -67
- package/dist/angular/web-components.module.d.ts +1 -1
- package/dist/angular/web-components.module.js +10 -13
- package/dist/cjs/{index-Cfa6bBQW.js → index-DaTpiyaU.js} +1 -1
- package/dist/cjs/{index-Cixkr3sz.js → index-Dwhgrew8.js} +15 -10
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/{xv-accordion-v2_50.cjs.entry.js → xv-accordion-v2_49.cjs.entry.js} +1529 -147
- package/dist/cjs/xv-header-next.cjs.entry.js +2 -2
- package/dist/cjs/xv-mega-menu-next.cjs.entry.js +2 -2
- package/dist/cjs/xv-webcomponents.cjs.js +3 -3
- package/dist/collection/collection-manifest.json +1 -2
- package/dist/collection/components/xv-overflow-menu/xv-overflow-menu.js +9 -8
- package/dist/collection/components/xv-table/xv-table-cell/xv-table-cell.css +129 -61
- package/dist/collection/components/xv-table/xv-table-cell/xv-table-cell.js +277 -78
- package/dist/collection/components/xv-table/xv-table-row/xv-table-row.css +138 -24
- package/dist/collection/components/xv-table/xv-table-row/xv-table-row.js +334 -168
- package/dist/collection/components/xv-table/xv-table.css +240 -99
- package/dist/collection/components/xv-table/xv-table.js +2056 -63
- package/dist/collection/components/xv-table/xv-table.model.js +10 -0
- package/dist/collection/components/xv-table/xv-table.utils.js +243 -0
- package/dist/collection/components/xv-tabs/xv-tab/xv-tab.js +1 -1
- package/dist/collection/components/xv-tag/xv-tag.js +1 -1
- package/dist/collection/components/xv-tag-combobox/xv-tag-combobox.js +2 -2
- package/dist/collection/components/xv-text-input/xv-text-input.js +2 -2
- package/dist/collection/components/xv-textarea/xv-textarea.js +2 -2
- package/dist/collection/components/xv-tile/xv-tile.js +2 -2
- package/dist/collection/components/xv-toggle/xv-toggle.js +1 -1
- package/dist/collection/components/xv-toggle-tip/xv-toggle-tip.js +1 -1
- package/dist/collection/components/xv-tooltip/xv-tooltip.js +2 -2
- package/dist/collection/utils/table-layout.js +130 -0
- package/dist/components/index.js +1 -1
- package/dist/components/p-B0kwaJ8n.js +1 -0
- package/dist/components/{p-CbVZCn2p.js → p-BEoh0dZI.js} +1 -1
- package/dist/components/{p-ZYJfCCwX.js → p-BaZ-srfu.js} +1 -1
- package/dist/components/{p-DyGMZIub.js → p-Bej2l-wN.js} +1 -1
- package/dist/components/{p-Ddx5DwV5.js → p-BfhvpeQh.js} +1 -1
- package/dist/components/{p-kQVUwJXZ.js → p-CSYnNMKb.js} +1 -1
- package/dist/components/{p-BNP2Lw34.js → p-CspyoLL9.js} +1 -1
- package/dist/components/p-CvgDDcjp.js +1 -0
- package/dist/components/{p-COoj5JkZ.js → p-D4FwGeDJ.js} +1 -1
- package/dist/components/p-DCvH_Br_.js +1 -0
- package/dist/components/{p-CEjlxnKY.js → p-DFe9Mtw_.js} +1 -1
- package/dist/components/{p-BRZwUlfE.js → p-DFtMwE-h.js} +1 -1
- package/dist/components/p-DIvi4fI3.js +1 -0
- package/dist/components/{p-DTwz9Fsh.js → p-DNRISLNf.js} +1 -1
- package/dist/components/p-DPnvoOYj.js +1 -0
- package/dist/components/{p-Dzz9jxLm.js → p-Dwbe941A.js} +1 -1
- package/dist/components/{p-CMAJWZsP.js → p-JClekcEh.js} +1 -1
- package/dist/components/{p-DtUNYh73.js → p-NoM9oIJn.js} +1 -1
- package/dist/components/{p-DlLBjhuH.js → p-XEk4dHG3.js} +1 -1
- package/dist/components/p-i7_81si-.js +1 -0
- package/dist/components/{p-BRYrLHiz.js → p-i82EFiq6.js} +1 -1
- package/dist/components/{p-BXB4D7j4.js → p-jD7nSJaM.js} +1 -1
- package/dist/components/xv-accordion-v2-item.js +1 -1
- package/dist/components/xv-accordion-v2.js +1 -1
- package/dist/components/xv-breadcrumbs-v2.js +1 -1
- package/dist/components/xv-button-group-v2.js +1 -1
- package/dist/components/xv-button-v2.js +1 -1
- package/dist/components/xv-card-v2.js +1 -1
- package/dist/components/xv-checkbox-v2.js +1 -1
- package/dist/components/xv-content-switcher-item-v2.js +1 -1
- package/dist/components/xv-content-switcher-v2.js +1 -1
- package/dist/components/xv-data-table-cell.js +1 -1
- package/dist/components/xv-data-table-collapse.js +1 -1
- package/dist/components/xv-data-table-row.js +1 -1
- package/dist/components/xv-data-table.js +2 -2
- package/dist/components/xv-date-picker.js +1 -1
- package/dist/components/xv-datepicker.js +1 -1
- package/dist/components/xv-dropdown-v2-item.js +1 -1
- package/dist/components/xv-dropdown-v2.js +1 -1
- package/dist/components/xv-file-uploader.js +1 -1
- package/dist/components/xv-footer.js +1 -1
- package/dist/components/xv-geo-map-v2.js +1 -1
- package/dist/components/xv-header-next.js +1 -1
- package/dist/components/xv-header.js +1 -1
- package/dist/components/xv-image-viewer.js +1 -1
- package/dist/components/xv-link-v2.js +1 -1
- package/dist/components/xv-loader-v2.js +1 -1
- package/dist/components/xv-login-modal.js +1 -1
- package/dist/components/xv-mega-menu-next.js +1 -1
- package/dist/components/xv-mega-menu.js +1 -1
- package/dist/components/xv-modal-v2.js +1 -1
- package/dist/components/xv-notification-v2.js +1 -1
- package/dist/components/xv-number-input-v2.js +1 -1
- package/dist/components/xv-overflow-menu-v2-item.js +1 -1
- package/dist/components/xv-overflow-menu-v2.js +1 -1
- package/dist/components/xv-pagination.js +1 -1
- package/dist/components/xv-progress-indicator-v2-item.js +1 -1
- package/dist/components/xv-progress-indicator-v2.js +1 -1
- package/dist/components/xv-radio-v2.js +1 -1
- package/dist/components/xv-slider-v2.js +1 -1
- package/dist/components/xv-tab-v2.js +1 -1
- package/dist/components/{xv-table-v2-row.d.ts → xv-table-cell.d.ts} +4 -4
- package/dist/components/xv-table-cell.js +1 -0
- package/dist/components/{xv-table-v2-cell.d.ts → xv-table-row.d.ts} +4 -4
- package/dist/components/xv-table-row.js +1 -0
- package/dist/components/{xv-table-v2.d.ts → xv-table.d.ts} +4 -4
- package/dist/components/xv-table.js +1 -0
- package/dist/components/xv-tabs-v2.js +1 -1
- package/dist/components/xv-tag-combobox.js +1 -1
- package/dist/components/xv-tag-v2.js +1 -1
- package/dist/components/xv-text-input-v2.js +1 -1
- package/dist/components/xv-textarea.js +1 -1
- package/dist/components/xv-tile.js +1 -1
- package/dist/components/xv-toggle-tip.js +1 -1
- package/dist/components/xv-toggle.js +1 -1
- package/dist/components/xv-tooltip-v2.js +1 -1
- package/dist/custom-elements.json +1765 -294
- package/dist/docs.json +2749 -443
- package/dist/esm/{index-B6cY-_U1.js → index-ClusqSO5.js} +1 -1
- package/dist/esm/{index-Bu8SrOeR.js → index-DJC3-dS3.js} +15 -10
- package/dist/esm/index.js +2 -2
- package/dist/esm/loader.js +3 -3
- package/dist/esm/{xv-accordion-v2_50.entry.js → xv-accordion-v2_49.entry.js} +1527 -144
- package/dist/esm/xv-header-next.entry.js +2 -2
- package/dist/esm/xv-mega-menu-next.entry.js +2 -2
- package/dist/esm/xv-webcomponents.js +4 -4
- package/dist/react/components.d.ts +3 -4
- package/dist/react/components.js +3 -4
- package/dist/react/{xv-table-v2-expand.d.ts → xv-table-cell.d.ts} +3 -3
- package/dist/react/xv-table-cell.js +14 -0
- package/dist/react/{xv-table-v2.d.ts → xv-table-row.d.ts} +3 -3
- package/dist/react/{xv-table-v2.js → xv-table-row.js} +5 -5
- package/dist/react/xv-table.d.ts +18 -0
- package/dist/react/xv-table.js +22 -0
- package/dist/types/components/xv-table/xv-table-cell/xv-table-cell.d.ts +43 -8
- package/dist/types/components/xv-table/xv-table-row/xv-table-row.d.ts +57 -18
- package/dist/types/components/xv-table/xv-table.d.ts +298 -9
- package/dist/types/components/xv-table/xv-table.model.d.ts +78 -0
- package/dist/types/components/xv-table/xv-table.utils.d.ts +47 -0
- package/dist/types/components.d.ts +899 -118
- package/dist/types/stencil-public-runtime.d.ts +61 -55
- package/dist/types/utils/table-layout.d.ts +7 -0
- package/dist/vscode-data.json +347 -56
- package/dist/xv-webcomponents/index.esm.js +1 -1
- package/dist/xv-webcomponents/{p-1ffb0b4f.entry.js → p-0c30d09f.entry.js} +1 -1
- package/dist/xv-webcomponents/{p-eb9d7750.entry.js → p-6b58979e.entry.js} +2 -2
- package/dist/xv-webcomponents/{p-Bu8SrOeR.js → p-DJC3-dS3.js} +2 -2
- package/dist/xv-webcomponents/{p-DB4KqDJz.js → p-DSFVdw3w.js} +1 -1
- package/dist/xv-webcomponents/{p-d4d26ff2.entry.js → p-c4173686.entry.js} +1 -1
- package/dist/xv-webcomponents/xv-webcomponents.esm.js +1 -1
- package/package.json +139 -139
- package/dist/collection/components/xv-table/_vars.js +0 -2
- package/dist/collection/components/xv-table/xv-table-expand/xv-table-expand.css +0 -58
- package/dist/collection/components/xv-table/xv-table-expand/xv-table-expand.js +0 -75
- package/dist/components/p-CHtssNO9.js +0 -1
- package/dist/components/p-CILNPUHH.js +0 -1
- package/dist/components/p-DVZ2BlIP.js +0 -1
- package/dist/components/p-bdaoJ1tx.js +0 -1
- package/dist/components/xv-table-v2-cell.js +0 -1
- package/dist/components/xv-table-v2-expand.d.ts +0 -11
- package/dist/components/xv-table-v2-expand.js +0 -1
- package/dist/components/xv-table-v2-row.js +0 -1
- package/dist/components/xv-table-v2.js +0 -1
- package/dist/react/xv-table-v2-cell.d.ts +0 -12
- package/dist/react/xv-table-v2-cell.js +0 -14
- package/dist/react/xv-table-v2-expand.js +0 -14
- package/dist/react/xv-table-v2-row.d.ts +0 -13
- package/dist/react/xv-table-v2-row.js +0 -17
- package/dist/types/components/xv-table/_vars.d.ts +0 -15
- package/dist/types/components/xv-table/xv-table-expand/xv-table-expand.d.ts +0 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement, F as Fragment } from './index-
|
|
2
|
-
import { u as uidGenerator, f as forEach, r as resolveFieldMessage, s as setAttr, c as resolveWhitelabel, a as api, g as getMetaNav, b as getBaseUrl, d as debounce$1 } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement, F as Fragment } from './index-DJC3-dS3.js';
|
|
2
|
+
import { u as uidGenerator, f as forEach, r as resolveFieldMessage, s as setAttr, c as resolveWhitelabel, a as api, g as getMetaNav, b as getBaseUrl, d as debounce$1 } from './index-ClusqSO5.js';
|
|
3
3
|
import { S as SIZE_VAR, X as XV_SORT_DIR, O as OverflowMenuVariant, a as OverflowMenuItemSelector } from './_vars-CDEU4jkD.js';
|
|
4
4
|
|
|
5
5
|
const xvAccordionCss = () => `:host{display:block}`;
|
|
@@ -83210,20 +83210,21 @@ const XvOverflowMenu = class {
|
|
|
83210
83210
|
document.removeEventListener('click', this.handleClickOutside, { capture: true });
|
|
83211
83211
|
};
|
|
83212
83212
|
this.handleClickOutside = (ev) => {
|
|
83213
|
-
var _a, _b
|
|
83213
|
+
var _a, _b;
|
|
83214
83214
|
if (!this.open)
|
|
83215
83215
|
return;
|
|
83216
|
-
//
|
|
83217
|
-
//
|
|
83218
|
-
const
|
|
83219
|
-
|
|
83216
|
+
// composedPath is the only check that survives shadow-DOM retargeting: a click inside a menu
|
|
83217
|
+
// that lives in another component's shadow root arrives here retargeted to that outer host.
|
|
83218
|
+
const path = (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)) !== null && _b !== void 0 ? _b : [];
|
|
83219
|
+
const inside = (node) => !!node && (path.includes(node) || (path.length === 0 && node.contains(ev.target)));
|
|
83220
|
+
if (inside(this.el))
|
|
83220
83221
|
return;
|
|
83221
|
-
if ((
|
|
83222
|
+
if (inside(this.triggerButtonEl))
|
|
83222
83223
|
return;
|
|
83223
|
-
if ((
|
|
83224
|
+
if (inside(this.listEl))
|
|
83224
83225
|
return;
|
|
83225
83226
|
// A click on the anchor is handled by its own listener (toggle) — don't treat it as "outside".
|
|
83226
|
-
if ((
|
|
83227
|
+
if (inside(this.anchorEl))
|
|
83227
83228
|
return;
|
|
83228
83229
|
this.open = false;
|
|
83229
83230
|
};
|
|
@@ -83869,174 +83870,1556 @@ const XvTab = class {
|
|
|
83869
83870
|
this.loading = false;
|
|
83870
83871
|
}
|
|
83871
83872
|
render() {
|
|
83872
|
-
return (h(Host, { key: '
|
|
83873
|
+
return (h(Host, { key: '7147f87058327e099ad257d3821447dac8e3affb', disabled: this.disabled, name: this.name }, this.loading ? h("xv-loader-v2", { size: SIZE_VAR.LG }) : h("slot", null)));
|
|
83873
83874
|
}
|
|
83874
83875
|
};
|
|
83875
83876
|
XvTab.style = xvTabCss();
|
|
83876
83877
|
|
|
83877
|
-
const
|
|
83878
|
+
const DB_NAME = 'xv-webcomponents';
|
|
83879
|
+
const DB_VERSION = 1;
|
|
83880
|
+
const STORE = 'table-layouts';
|
|
83881
|
+
const MAX_AGE_MS = 180 * 24 * 60 * 60 * 1000;
|
|
83882
|
+
const READ_TIMEOUT_MS = 1500;
|
|
83883
|
+
let connection = null;
|
|
83884
|
+
let pruned = false;
|
|
83885
|
+
const layoutId = (owner, storageKey) => `${owner || 'anonymous'}:${storageKey}`;
|
|
83886
|
+
const request = (req) => new Promise((resolve, reject) => {
|
|
83887
|
+
req.onsuccess = () => resolve(req.result);
|
|
83888
|
+
req.onerror = () => reject(req.error);
|
|
83889
|
+
});
|
|
83890
|
+
/**
|
|
83891
|
+
* Our own database on purpose. XvMarketplaceNG's origin already carries a Dexie database, and Dexie
|
|
83892
|
+
* multiplies its version by ten — sharing a name loses the version race and kills the feature (MAR-15943).
|
|
83893
|
+
*/
|
|
83894
|
+
const openDb = () => {
|
|
83895
|
+
if (connection)
|
|
83896
|
+
return connection;
|
|
83897
|
+
connection = new Promise(resolve => {
|
|
83898
|
+
if (typeof indexedDB === 'undefined')
|
|
83899
|
+
return resolve(null);
|
|
83900
|
+
let req;
|
|
83901
|
+
try {
|
|
83902
|
+
req = indexedDB.open(DB_NAME, DB_VERSION);
|
|
83903
|
+
}
|
|
83904
|
+
catch (_a) {
|
|
83905
|
+
return resolve(null);
|
|
83906
|
+
}
|
|
83907
|
+
req.onupgradeneeded = () => {
|
|
83908
|
+
const db = req.result;
|
|
83909
|
+
if (db.objectStoreNames.contains(STORE))
|
|
83910
|
+
return;
|
|
83911
|
+
const store = db.createObjectStore(STORE, { keyPath: 'id' });
|
|
83912
|
+
store.createIndex('owner', 'owner');
|
|
83913
|
+
store.createIndex('updatedAt', 'updatedAt');
|
|
83914
|
+
};
|
|
83915
|
+
req.onsuccess = () => resolve(req.result);
|
|
83916
|
+
req.onerror = () => resolve(null);
|
|
83917
|
+
req.onblocked = () => resolve(null);
|
|
83918
|
+
});
|
|
83919
|
+
return connection;
|
|
83920
|
+
};
|
|
83921
|
+
const store = async (mode) => {
|
|
83922
|
+
const db = await openDb();
|
|
83923
|
+
if (!db)
|
|
83924
|
+
return null;
|
|
83925
|
+
try {
|
|
83926
|
+
return db.transaction(STORE, mode).objectStore(STORE);
|
|
83927
|
+
}
|
|
83928
|
+
catch (_a) {
|
|
83929
|
+
return null;
|
|
83930
|
+
}
|
|
83931
|
+
};
|
|
83932
|
+
/** A cold database must not hold the first paint hostage — past this, the declared columns win. */
|
|
83933
|
+
const withTimeout = (promise, fallback, ms = READ_TIMEOUT_MS) => Promise.race([promise, new Promise(resolve => setTimeout(() => resolve(fallback), ms))]);
|
|
83934
|
+
const readLayout = async (owner, storageKey) => {
|
|
83935
|
+
if (!storageKey)
|
|
83936
|
+
return null;
|
|
83937
|
+
const read = (async () => {
|
|
83938
|
+
var _a;
|
|
83939
|
+
try {
|
|
83940
|
+
const objectStore = await store('readonly');
|
|
83941
|
+
if (!objectStore)
|
|
83942
|
+
return null;
|
|
83943
|
+
const record = await request(objectStore.get(layoutId(owner, storageKey)));
|
|
83944
|
+
return (_a = record === null || record === void 0 ? void 0 : record.layout) !== null && _a !== void 0 ? _a : null;
|
|
83945
|
+
}
|
|
83946
|
+
catch (_b) {
|
|
83947
|
+
return null;
|
|
83948
|
+
}
|
|
83949
|
+
})();
|
|
83950
|
+
const layout = await withTimeout(read, null);
|
|
83951
|
+
void pruneLayouts();
|
|
83952
|
+
return layout;
|
|
83953
|
+
};
|
|
83954
|
+
const writeLayout = async (owner, storageKey, layout) => {
|
|
83955
|
+
if (!storageKey)
|
|
83956
|
+
return;
|
|
83957
|
+
try {
|
|
83958
|
+
const objectStore = await store('readwrite');
|
|
83959
|
+
if (!objectStore)
|
|
83960
|
+
return;
|
|
83961
|
+
const record = {
|
|
83962
|
+
id: layoutId(owner, storageKey),
|
|
83963
|
+
owner: owner || 'anonymous',
|
|
83964
|
+
storageKey,
|
|
83965
|
+
layout,
|
|
83966
|
+
updatedAt: Date.now(),
|
|
83967
|
+
};
|
|
83968
|
+
await request(objectStore.put(record));
|
|
83969
|
+
}
|
|
83970
|
+
catch (_a) {
|
|
83971
|
+
// Private mode and a full quota both degrade to "this table does not remember".
|
|
83972
|
+
}
|
|
83973
|
+
};
|
|
83974
|
+
const deleteLayout = async (owner, storageKey) => {
|
|
83975
|
+
if (!storageKey)
|
|
83976
|
+
return;
|
|
83977
|
+
try {
|
|
83978
|
+
const objectStore = await store('readwrite');
|
|
83979
|
+
if (!objectStore)
|
|
83980
|
+
return;
|
|
83981
|
+
await request(objectStore.delete(layoutId(owner, storageKey)));
|
|
83982
|
+
}
|
|
83983
|
+
catch (_a) {
|
|
83984
|
+
// See writeLayout.
|
|
83985
|
+
}
|
|
83986
|
+
};
|
|
83987
|
+
const pruneLayouts = async () => {
|
|
83988
|
+
if (pruned)
|
|
83989
|
+
return;
|
|
83990
|
+
pruned = true;
|
|
83991
|
+
try {
|
|
83992
|
+
const objectStore = await store('readwrite');
|
|
83993
|
+
if (!objectStore)
|
|
83994
|
+
return;
|
|
83995
|
+
const range = IDBKeyRange.upperBound(Date.now() - MAX_AGE_MS);
|
|
83996
|
+
const stale = await request(objectStore.index('updatedAt').getAll(range));
|
|
83997
|
+
stale.forEach(record => objectStore.delete(record.id));
|
|
83998
|
+
}
|
|
83999
|
+
catch (_a) {
|
|
84000
|
+
// See writeLayout.
|
|
84001
|
+
}
|
|
84002
|
+
};
|
|
84003
|
+
|
|
84004
|
+
const XV_TABLE_ROW_TAG = 'xv-table-row';
|
|
84005
|
+
const XV_TABLE_CELL_TAG = 'xv-table-cell';
|
|
84006
|
+
const XV_TABLE_LAYOUT_VERSION = 1;
|
|
84007
|
+
/** The floor a resize drag may not cross, when the column names no minWidth. */
|
|
84008
|
+
const XV_TABLE_MIN_COLUMN_WIDTH = 64;
|
|
84009
|
+
/** Per visible column, the width below which the table scrolls instead of squeezing. */
|
|
84010
|
+
const XV_TABLE_SCROLL_COLUMN_WIDTH = 120;
|
|
84011
|
+
const XV_TABLE_CONTROL_WIDTH = 48;
|
|
84012
|
+
const XV_TABLE_DEFAULT_PAGE_SIZES = [10, 20, 30, 40, 50, 100];
|
|
84013
|
+
|
|
84014
|
+
const ORDER_BY = /^(asc|desc)\((.+)\)$/;
|
|
84015
|
+
/** Array and object props accept their JSON string form so they stay settable from plain markup. */
|
|
84016
|
+
const parseProp = (value, fallback) => {
|
|
84017
|
+
if (typeof value !== 'string')
|
|
84018
|
+
return value !== null && value !== void 0 ? value : fallback;
|
|
84019
|
+
if (!value.trim())
|
|
84020
|
+
return fallback;
|
|
84021
|
+
try {
|
|
84022
|
+
return JSON.parse(value);
|
|
84023
|
+
}
|
|
84024
|
+
catch (_a) {
|
|
84025
|
+
return fallback;
|
|
84026
|
+
}
|
|
84027
|
+
};
|
|
84028
|
+
const parsePageSizes = (value) => {
|
|
84029
|
+
const parsed = typeof value === 'string' && value.includes(',')
|
|
84030
|
+
? value.split(',').map(part => Number(part.trim()))
|
|
84031
|
+
: parseProp(value, XV_TABLE_DEFAULT_PAGE_SIZES);
|
|
84032
|
+
const sizes = (parsed || []).filter(size => Number.isFinite(size) && size > 0);
|
|
84033
|
+
return sizes.length ? sizes : XV_TABLE_DEFAULT_PAGE_SIZES;
|
|
84034
|
+
};
|
|
84035
|
+
const parseSortBy = (value) => {
|
|
84036
|
+
if (!value)
|
|
84037
|
+
return null;
|
|
84038
|
+
if (typeof value !== 'string') {
|
|
84039
|
+
return value.name ? { name: value.name, direction: value.direction || XV_SORT_DIR.ASC } : null;
|
|
84040
|
+
}
|
|
84041
|
+
const match = ORDER_BY.exec(value.trim());
|
|
84042
|
+
if (!match)
|
|
84043
|
+
return null;
|
|
84044
|
+
return { name: match[2], direction: match[1] };
|
|
84045
|
+
};
|
|
84046
|
+
const nextSortDirection = (current) => current === XV_SORT_DIR.ASC ? XV_SORT_DIR.DESC : XV_SORT_DIR.ASC;
|
|
84047
|
+
const sortName = (column) => column.sortName || column.id;
|
|
84048
|
+
const cellValue = (row, column) => {
|
|
84049
|
+
if (typeof column.value === 'function')
|
|
84050
|
+
return column.value(row);
|
|
84051
|
+
const key = column.value || column.id;
|
|
84052
|
+
return row === null || row === void 0 ? void 0 : row[key];
|
|
84053
|
+
};
|
|
84054
|
+
const isEmpty = (value) => value === null || value === undefined || value === '';
|
|
84055
|
+
// Only a date-shaped string is read as a date: an article number must not sort as a year.
|
|
84056
|
+
const DATE_LIKE = /^\d{4}-\d{2}-\d{2}([T ]|$)|^\d{1,2}[./-]\d{1,2}[./-]\d{2,4}$/;
|
|
84057
|
+
const toComparable = (value) => {
|
|
84058
|
+
if (value instanceof Date)
|
|
84059
|
+
return value.getTime();
|
|
84060
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
84061
|
+
return value;
|
|
84062
|
+
const text = String(value);
|
|
84063
|
+
const asDate = DATE_LIKE.test(text.trim()) ? Date.parse(text) : NaN;
|
|
84064
|
+
return Number.isNaN(asDate) ? text : asDate;
|
|
84065
|
+
};
|
|
84066
|
+
/** Empty values sort last in both directions — a blank cell is not "smallest", it is missing. */
|
|
84067
|
+
const compareValues = (a, b, locale) => {
|
|
84068
|
+
if (isEmpty(a) && isEmpty(b))
|
|
84069
|
+
return 0;
|
|
84070
|
+
if (isEmpty(a))
|
|
84071
|
+
return 1;
|
|
84072
|
+
if (isEmpty(b))
|
|
84073
|
+
return -1;
|
|
84074
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
84075
|
+
return a - b;
|
|
84076
|
+
const left = toComparable(a);
|
|
84077
|
+
const right = toComparable(b);
|
|
84078
|
+
if (typeof left === 'string' || typeof right === 'string') {
|
|
84079
|
+
return String(left).localeCompare(String(right), locale, { numeric: true, sensitivity: 'base' });
|
|
84080
|
+
}
|
|
84081
|
+
return Number(left) - Number(right);
|
|
84082
|
+
};
|
|
84083
|
+
const sortRows = (rows, column, direction, locale) => {
|
|
84084
|
+
if (!column || direction === XV_SORT_DIR.NONE)
|
|
84085
|
+
return rows;
|
|
84086
|
+
const factor = direction === XV_SORT_DIR.DESC ? -1 : 1;
|
|
84087
|
+
// Read each cell once rather than four times per comparison.
|
|
84088
|
+
const decorated = rows.map(row => ({ row, key: cellValue(row, column) }));
|
|
84089
|
+
decorated.sort((a, b) => {
|
|
84090
|
+
const result = compareValues(a.key, b.key, locale);
|
|
84091
|
+
// Empty always trails, so it must not be flipped by a descending sort.
|
|
84092
|
+
if (isEmpty(a.key) !== isEmpty(b.key))
|
|
84093
|
+
return result;
|
|
84094
|
+
return result * factor;
|
|
84095
|
+
});
|
|
84096
|
+
return decorated.map(item => item.row);
|
|
84097
|
+
};
|
|
84098
|
+
const totalPages = (total, pageSize) => Math.ceil((total || 0) / (pageSize || 10)) || 1;
|
|
84099
|
+
const clampPage = (page, pages) => Math.min(Math.max(page || 1, 1), Math.max(pages, 1));
|
|
84100
|
+
const pageSlice = (rows, page, pageSize) => {
|
|
84101
|
+
const size = pageSize || 10;
|
|
84102
|
+
const start = (clampPage(page, totalPages(rows.length, size)) - 1) * size;
|
|
84103
|
+
return rows.slice(start, start + size);
|
|
84104
|
+
};
|
|
84105
|
+
const visibleColumns = (columns) => columns.filter(column => !column.hidden);
|
|
84106
|
+
const hideableColumns = (columns) => columns.filter(column => column.hideable);
|
|
84107
|
+
/** A column may narrow a table-level switch, never widen it. */
|
|
84108
|
+
const columnAllows = (column, table, key) => { var _a; return table && ((_a = column[key]) !== null && _a !== void 0 ? _a : true); };
|
|
84109
|
+
const clampWidth = (width, column) => {
|
|
84110
|
+
const min = column.minWidth || XV_TABLE_MIN_COLUMN_WIDTH;
|
|
84111
|
+
const max = column.maxWidth || Number.MAX_SAFE_INTEGER;
|
|
84112
|
+
return Math.round(Math.min(Math.max(width, min), max));
|
|
84113
|
+
};
|
|
84114
|
+
/**
|
|
84115
|
+
* What the rigid parts of the table actually need. A pixel column needs its width; a percentage
|
|
84116
|
+
* column squeezes by definition and asks for nothing; a column that named no width gets the
|
|
84117
|
+
* scroll-width guess. Guessing for all of them made a table of narrow columns scroll for nothing.
|
|
84118
|
+
*/
|
|
84119
|
+
const tableMinWidth = (columns, minWidth, controls = 0) => {
|
|
84120
|
+
if (minWidth)
|
|
84121
|
+
return minWidth + controls;
|
|
84122
|
+
const declared = visibleColumns(columns).reduce((total, column) => {
|
|
84123
|
+
if (typeof column.width === 'number')
|
|
84124
|
+
return total + column.width;
|
|
84125
|
+
return column.width ? total : total + XV_TABLE_SCROLL_COLUMN_WIDTH;
|
|
84126
|
+
}, 0);
|
|
84127
|
+
return declared + controls;
|
|
84128
|
+
};
|
|
84129
|
+
/**
|
|
84130
|
+
* The grid track list. Resize rewrites this one string on the host, which is a single DOM write
|
|
84131
|
+
* per pointermove — a colgroup would need one per `<col>`. One track per control column: a grip
|
|
84132
|
+
* and a checkbox are separate cells, so they need separate tracks.
|
|
84133
|
+
*/
|
|
84134
|
+
const buildColumnTracks = (columns, leading = [], trailing = []) => {
|
|
84135
|
+
const shown = visibleColumns(columns);
|
|
84136
|
+
// `table-layout: fixed`, which is what these tables were written against: while some column left
|
|
84137
|
+
// its width open, a declared width is exact and the open ones take what is left. Once every
|
|
84138
|
+
// column has named a width, the widths also become proportions and the table scales up to fit —
|
|
84139
|
+
// but never below what was declared, so a narrow column keeps the room its content needs.
|
|
84140
|
+
const proportional = shown.length > 0 && shown.every(column => !!column.width);
|
|
84141
|
+
return [
|
|
84142
|
+
...leading.map(width => `${width}px`),
|
|
84143
|
+
// No space inside minmax(): the track list is indexed as an array during a resize drag.
|
|
84144
|
+
...shown.map(column => {
|
|
84145
|
+
if (!column.width)
|
|
84146
|
+
return `minmax(${column.minWidth || XV_TABLE_MIN_COLUMN_WIDTH}px,1fr)`;
|
|
84147
|
+
if (typeof column.width === 'number') {
|
|
84148
|
+
return proportional
|
|
84149
|
+
? `minmax(${column.width}px,${column.width}fr)`
|
|
84150
|
+
: `${column.width}px`;
|
|
84151
|
+
}
|
|
84152
|
+
// A percentage keeps its exact share of the table and squeezes with it, never forcing a scroll.
|
|
84153
|
+
const percent = /^([0-9.]+)%$/.test(column.width);
|
|
84154
|
+
return percent ? `minmax(0,${column.width})` : column.width;
|
|
84155
|
+
}),
|
|
84156
|
+
...trailing.map(width => `${width}px`),
|
|
84157
|
+
];
|
|
84158
|
+
};
|
|
84159
|
+
const buildColumnTemplate = (columns, leading = [], trailing = []) => buildColumnTracks(columns, leading, trailing).join(' ');
|
|
84160
|
+
const moveItem = (items, from, to) => {
|
|
84161
|
+
const next = [...items];
|
|
84162
|
+
next.splice(to, 0, next.splice(from, 1)[0]);
|
|
84163
|
+
return next;
|
|
84164
|
+
};
|
|
84165
|
+
/** Hidden columns keep their absolute slot while the visible ones move around them. */
|
|
84166
|
+
const mergeVisibleOrder = (columns, ordered) => {
|
|
84167
|
+
const queue = [...ordered];
|
|
84168
|
+
return columns.map(column => (column.hidden ? column : queue.shift() || column));
|
|
84169
|
+
};
|
|
84170
|
+
/**
|
|
84171
|
+
* Only the deviations from the declared columns are stored. An untouched column follows the code,
|
|
84172
|
+
* so a later default still reaches everyone who once dragged a column edge.
|
|
84173
|
+
*/
|
|
84174
|
+
const diffLayout = (columns, declared) => {
|
|
84175
|
+
const defaults = new Map(declared.map(column => [column.id, column]));
|
|
84176
|
+
const order = columns.map(column => column.id);
|
|
84177
|
+
const widths = {};
|
|
84178
|
+
const hidden = {};
|
|
84179
|
+
columns.forEach(column => {
|
|
84180
|
+
const base = defaults.get(column.id);
|
|
84181
|
+
// Only a resize writes a width, and a resize always writes pixels: a declared `25%` is not a
|
|
84182
|
+
// deviation, and storing it would freeze the layout the next time the code changes.
|
|
84183
|
+
if (typeof column.width === 'number' && column.width !== (base === null || base === void 0 ? void 0 : base.width)) {
|
|
84184
|
+
widths[column.id] = column.width;
|
|
84185
|
+
}
|
|
84186
|
+
if (!!column.hidden !== !!(base === null || base === void 0 ? void 0 : base.hidden))
|
|
84187
|
+
hidden[column.id] = !!column.hidden;
|
|
84188
|
+
});
|
|
84189
|
+
return {
|
|
84190
|
+
v: XV_TABLE_LAYOUT_VERSION,
|
|
84191
|
+
order: order.join() === declared.map(column => column.id).join() ? [] : order,
|
|
84192
|
+
widths,
|
|
84193
|
+
hidden,
|
|
84194
|
+
};
|
|
84195
|
+
};
|
|
84196
|
+
const isLayoutChanged = (layout) => !!layout && (!!layout.order.length || !!Object.keys(layout.widths).length || !!Object.keys(layout.hidden).length);
|
|
84197
|
+
/** Merges onto clones, so a stored width never writes back into the page's declared preset. */
|
|
84198
|
+
const applyLayout = (declared, layout) => {
|
|
84199
|
+
const clones = declared.map(column => (Object.assign({}, column)));
|
|
84200
|
+
if (!layout || layout.v !== XV_TABLE_LAYOUT_VERSION)
|
|
84201
|
+
return clones;
|
|
84202
|
+
const byId = new Map(clones.map(column => [column.id, column]));
|
|
84203
|
+
const ordered = layout.order.map(id => byId.get(id)).filter(Boolean);
|
|
84204
|
+
clones.forEach((column, index) => {
|
|
84205
|
+
if (!ordered.includes(column))
|
|
84206
|
+
ordered.splice(Math.min(index, ordered.length), 0, column);
|
|
84207
|
+
});
|
|
84208
|
+
ordered.forEach(column => {
|
|
84209
|
+
const width = layout.widths[column.id];
|
|
84210
|
+
if (width)
|
|
84211
|
+
column.width = width;
|
|
84212
|
+
const hidden = layout.hidden[column.id];
|
|
84213
|
+
if (hidden !== undefined && column.hideable)
|
|
84214
|
+
column.hidden = hidden;
|
|
84215
|
+
});
|
|
84216
|
+
return ordered;
|
|
84217
|
+
};
|
|
84218
|
+
const formatCell = (value, column, locale) => {
|
|
84219
|
+
if (isEmpty(value))
|
|
84220
|
+
return '';
|
|
84221
|
+
switch (column.format) {
|
|
84222
|
+
case 'number':
|
|
84223
|
+
return new Intl.NumberFormat(locale).format(Number(value));
|
|
84224
|
+
case 'currency':
|
|
84225
|
+
return new Intl.NumberFormat(locale, {
|
|
84226
|
+
style: 'currency',
|
|
84227
|
+
currency: column.formatArg || 'EUR',
|
|
84228
|
+
}).format(Number(value));
|
|
84229
|
+
case 'date': {
|
|
84230
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
84231
|
+
return Number.isNaN(date.getTime()) ? String(value) : new Intl.DateTimeFormat(locale).format(date);
|
|
84232
|
+
}
|
|
84233
|
+
case 'period': {
|
|
84234
|
+
const [start, end] = Array.isArray(value) ? value : [];
|
|
84235
|
+
const part = (input, options) => {
|
|
84236
|
+
if (isEmpty(input))
|
|
84237
|
+
return '';
|
|
84238
|
+
const date = input instanceof Date ? input : new Date(String(input));
|
|
84239
|
+
return Number.isNaN(date.getTime()) ? '' : new Intl.DateTimeFormat(locale, options).format(date);
|
|
84240
|
+
};
|
|
84241
|
+
// A missing end leaves no dangling separator, and the year is only spelled once.
|
|
84242
|
+
return [
|
|
84243
|
+
part(start, { day: '2-digit', month: '2-digit' }),
|
|
84244
|
+
part(end, { day: '2-digit', month: '2-digit', year: '2-digit' }),
|
|
84245
|
+
].filter(Boolean).join(' - ');
|
|
84246
|
+
}
|
|
84247
|
+
case 'list':
|
|
84248
|
+
return Array.isArray(value) ? value.join(column.formatArg || ', ') : String(value);
|
|
84249
|
+
default:
|
|
84250
|
+
return String(value);
|
|
84251
|
+
}
|
|
84252
|
+
};
|
|
84253
|
+
|
|
84254
|
+
const xvTableCss = () => `@charset "UTF-8";:host{--xv-table-columns:1fr;--xv-table-height:40px;--xv-table-padding-x:var(--spacing-05);--xv-table-padding-y:var(--spacing-03);--xv-table-border-color:var(--border-subtle-01);--xv-table-header-bg:var(--layer-accent-01);--xv-table-loading-bg:var(--layer-02);--xv-table-loading-opacity:0.8;--xv-table-max-height:none;--xv-table-scroll-width:1180px;display:block;position:relative;color:var(--text-primary);font-family:var(--ff-body);font-size:var(--fz-md)}:host([block]){width:100%}:host([size=xs]){--xv-table-height:24px;--xv-table-padding-x:var(--spacing-03);--xv-table-padding-y:var(--spacing-01)}:host([size=sm]){--xv-table-height:32px;--xv-table-padding-x:var(--spacing-04);--xv-table-padding-y:var(--spacing-02)}:host([size=md]){--xv-table-height:40px;--xv-table-padding-x:var(--spacing-05);--xv-table-padding-y:var(--spacing-03)}:host([size=lg]){--xv-table-height:48px;--xv-table-padding-x:var(--spacing-05);--xv-table-padding-y:var(--spacing-04)}:host([size=xl]){--xv-table-height:64px;--xv-table-padding-x:var(--spacing-06);--xv-table-padding-y:var(--spacing-05)}:host(.is-dragging){cursor:grabbing;user-select:none}.heading{padding:var(--spacing-05) var(--spacing-05) var(--spacing-06)}.heading_title{margin:0;font-family:var(--ff-heading);font-size:var(--fz-xl);font-weight:400;line-height:28px}.heading_description{margin:var(--spacing-02) 0 0;color:var(--text-secondary);line-height:18px}.bar{position:sticky;left:0;z-index:10}.bar_toolbar{display:flex;align-items:center;gap:var(--spacing-03);min-height:var(--xv-table-height)}.bar_toolbar ::slotted(*){flex:1 1 auto;min-width:0}.bar_batch{position:absolute;inset:0;z-index:2;display:flex;align-items:center;gap:var(--spacing-03);padding:0 var(--spacing-05);border-radius:3px 3px 0 0;background:var(--interactive-01);color:var(--text-on-color)}.bar_count{margin-left:auto;font-weight:600}.scroll{position:relative}@media screen and (max-width: 1180px){.scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:var(--layer-accent-03) transparent}.grid{min-width:max(var(--xv-table-min-width), var(--xv-table-scroll-width))}}.scroll--overflowing{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:var(--layer-accent-03) transparent}:host([min-width]:not([min-width="0"])) .scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:var(--layer-accent-03) transparent}:host([min-width]:not([min-width="0"])) .grid{min-width:var(--xv-table-min-width)}:host([sticky-header]) .scroll{min-height:0;max-height:var(--xv-table-max-height);overflow-y:auto}.grid{display:grid;grid-template-columns:var(--xv-table-columns);box-sizing:border-box;border:1px solid var(--xv-table-border-color);border-bottom:0}:host([sticky-header]) ::slotted(xv-table-row[header]),:host([sticky-header]) xv-table-row[header]{position:sticky;top:0;z-index:5}.body{grid-column:1/-1;display:grid;grid-template-columns:subgrid}.body[hidden]{display:none}.skeleton_row{grid-column:1/-1;display:grid;grid-template-columns:subgrid;min-height:var(--xv-table-height);box-shadow:inset 0 -1px 0 0 var(--border-subtle-00)}.skeleton_cell{display:flex;align-items:center;padding:var(--xv-table-padding-y) var(--xv-table-padding-x)}.skeleton_bar{width:100%;height:12px;border-radius:2px;background:var(--layer-accent-01);animation:xv-table-pulse 1.4s ease-in-out infinite}@keyframes xv-table-pulse{0%,100%{opacity:1}50%{opacity:0.4}}.empty{display:flex;align-items:center;justify-content:center;min-height:calc(var(--xv-table-height) * 2);border:1px solid var(--xv-table-border-color);border-top:0;color:var(--text-secondary)}.loading{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.loading::before{content:"";position:absolute;inset:0;background:var(--xv-table-loading-bg);opacity:var(--xv-table-loading-opacity)}.picker{margin-left:auto}.picker_list{display:flex;flex-direction:column;gap:var(--spacing-02);max-height:320px;overflow-y:auto;padding:var(--spacing-03)}.picker_trigger{position:relative;display:inline-flex;color:var(--icon-primary)}.picker_marker{position:absolute;top:-2px;right:-4px;width:6px;height:6px;border-radius:50%;background:var(--background-brand)}.pagination{border:1px solid var(--xv-table-border-color);border-top:0}`;
|
|
83878
84255
|
|
|
84256
|
+
const CHECKBOX_EVENT = 'eventChange';
|
|
84257
|
+
const INTERACTIVE = 'a,button,input,select,textarea,[role="button"],xv-button-v2,xv-link-v2,xv-checkbox-v2,xv-radio-v2,xv-overflow-menu-v2,xv-tooltip-v2';
|
|
83879
84258
|
const XvTable = class {
|
|
83880
84259
|
constructor(hostRef) {
|
|
83881
84260
|
registerInstance(this, hostRef);
|
|
84261
|
+
this.sortChange = createEvent(this, "sortChange", 7);
|
|
84262
|
+
this.selectedChange = createEvent(this, "selectedChange", 7);
|
|
84263
|
+
this.expandedChange = createEvent(this, "expandedChange", 7);
|
|
84264
|
+
this.pageChange = createEvent(this, "pageChange", 7);
|
|
84265
|
+
this.layoutChange = createEvent(this, "layoutChange", 7);
|
|
84266
|
+
this.rowClick = createEvent(this, "rowClick", 7);
|
|
84267
|
+
this.rowOrderChange = createEvent(this, "rowOrderChange", 7);
|
|
84268
|
+
/** Column definitions. Accepts its JSON string form so it is settable from plain markup. */
|
|
84269
|
+
this.columns = [];
|
|
84270
|
+
/** Row data. Ignored when `xv-table-row` children are slotted. */
|
|
84271
|
+
this.rows = [];
|
|
84272
|
+
/** Property of a row object that identifies it in selection and expansion payloads. */
|
|
84273
|
+
this.rowKey = 'id';
|
|
84274
|
+
/** Row height ladder. */
|
|
83882
84275
|
this.size = SIZE_VAR.MD;
|
|
83883
|
-
|
|
83884
|
-
this.
|
|
84276
|
+
/** Stretches the table to the full width of its container. */
|
|
84277
|
+
this.block = false;
|
|
84278
|
+
/** Covers the body with a loading state. */
|
|
84279
|
+
this.loading = false;
|
|
84280
|
+
/** Placeholder rows drawn while `loading`. Zero draws a spinner instead. */
|
|
84281
|
+
this.skeletonRows = 0;
|
|
84282
|
+
/** Highlights a row on pointer hover. */
|
|
84283
|
+
this.hover = false;
|
|
84284
|
+
/** Emits `rowClick` when a row is clicked outside an interactive element. */
|
|
84285
|
+
this.rowClickable = false;
|
|
84286
|
+
/** Title above the table. */
|
|
84287
|
+
this.label = '';
|
|
84288
|
+
/** Supporting text under the title. */
|
|
84289
|
+
this.description = '';
|
|
84290
|
+
/** Shown when there are no rows. */
|
|
84291
|
+
this.emptyLabel = '';
|
|
84292
|
+
/** Text of the batch bar counter. `{count}` is replaced with the number of selected rows. */
|
|
84293
|
+
this.selectedLabel = '';
|
|
84294
|
+
/** Tooltip on the column picker trigger. */
|
|
84295
|
+
this.columnsLabel = 'Columns';
|
|
84296
|
+
/** Text of the button that restores the declared column layout. */
|
|
84297
|
+
this.resetLabel = 'Reset';
|
|
84298
|
+
/** Accessible name of a row's expand toggle. */
|
|
84299
|
+
this.expandLabel = 'Toggle row';
|
|
84300
|
+
/** Accessible name of a row's drag grip. */
|
|
84301
|
+
this.reorderLabel = 'Drag to reorder';
|
|
84302
|
+
/**
|
|
84303
|
+
* `none` makes headers inert whatever the column says; `client` sorts the `rows` prop itself;
|
|
84304
|
+
* `server` offers the affordance and only emits `sortChange` for the consumer to reload.
|
|
84305
|
+
*/
|
|
84306
|
+
this.sortMode = 'none';
|
|
84307
|
+
/** Active sort, as `asc(field)` / `desc(field)` or an object. */
|
|
84308
|
+
this.sortBy = '';
|
|
84309
|
+
/** `multiple` renders checkboxes, `single` renders radios. */
|
|
84310
|
+
this.selection = 'none';
|
|
84311
|
+
/** Values of the selected rows. */
|
|
84312
|
+
this.selected = [];
|
|
84313
|
+
/** Whether rows expand, and whether more than one may be open. */
|
|
84314
|
+
this.expandMode = 'none';
|
|
84315
|
+
/** Values of the expanded rows. */
|
|
84316
|
+
this.expanded = [];
|
|
84317
|
+
/** `client` slices the `rows` prop; `server` only emits `pageChange`. */
|
|
84318
|
+
this.paginationMode = 'none';
|
|
84319
|
+
/** Current page, 1-based. */
|
|
84320
|
+
this.page = 1;
|
|
84321
|
+
/** Rows per page. */
|
|
84322
|
+
this.pageSize = 10;
|
|
84323
|
+
/** Total row count, for `server` pagination. */
|
|
84324
|
+
this.total = 0;
|
|
84325
|
+
/** Page size choices. Accepts a comma-separated attribute. */
|
|
84326
|
+
this.pageSizeOptions = [10, 20, 30, 40, 50, 100];
|
|
84327
|
+
/**
|
|
84328
|
+
* Allows dragging column edges. Off by default: no handle is rendered and nothing is bound
|
|
84329
|
+
* until it is switched on. A column may switch itself off, never on.
|
|
84330
|
+
*/
|
|
84331
|
+
this.resizable = false;
|
|
84332
|
+
/** Allows dragging column headers into a new order. Off by default, like `resizable`. */
|
|
84333
|
+
this.reorderable = false;
|
|
84334
|
+
/**
|
|
84335
|
+
* Allows dragging rows into a new order. Off by default: nothing is bound and no handle is
|
|
84336
|
+
* rendered until it is switched on.
|
|
84337
|
+
*/
|
|
84338
|
+
this.rowReorderable = false;
|
|
84339
|
+
/** Whether the whole row drags, or only a grip in a leading control cell. */
|
|
84340
|
+
this.rowReorderHandle = 'icon';
|
|
84341
|
+
/** Keeps the header visible while the body scrolls. */
|
|
84342
|
+
this.stickyHeader = false;
|
|
84343
|
+
/**
|
|
84344
|
+
* Width below which the table scrolls instead of squeezing, at any viewport. Left unset, a table
|
|
84345
|
+
* only stops squeezing below 1180px, where it scrolls at the width its columns declared.
|
|
84346
|
+
*/
|
|
84347
|
+
this.minWidth = 0;
|
|
84348
|
+
/** Persists the column layout under this key. Empty means the layout is not remembered. */
|
|
84349
|
+
this.storageKey = '';
|
|
84350
|
+
/** Scopes the stored layout to a user. */
|
|
84351
|
+
this.storageOwner = 'anonymous';
|
|
84352
|
+
/** Controlled column layout. Overrides whatever is stored. */
|
|
84353
|
+
this.layout = null;
|
|
84354
|
+
/** Locale used for sorting and cell formatting. Falls back to the nearest `[lang]` ancestor. */
|
|
84355
|
+
this.locale = '';
|
|
84356
|
+
this.columnState = [];
|
|
84357
|
+
this.sortState = null;
|
|
84358
|
+
this.selectedValues = [];
|
|
84359
|
+
this.expandedValues = [];
|
|
84360
|
+
this.layoutPending = false;
|
|
84361
|
+
this.columnDragging = false;
|
|
84362
|
+
this.dragOverId = '';
|
|
84363
|
+
this.dropRowIndex = -1;
|
|
84364
|
+
this.slottedRowCount = 0;
|
|
84365
|
+
this.derivedTracks = [];
|
|
84366
|
+
this.hasSlottedHeader = false;
|
|
84367
|
+
this.hasSlottedHeading = false;
|
|
84368
|
+
this.hasSlottedEmpty = false;
|
|
84369
|
+
this.overflowing = false;
|
|
84370
|
+
this.declared = [];
|
|
84371
|
+
this.declaredSignature = '';
|
|
84372
|
+
/** Whether the columns came from a slotted header rather than the `columns` prop. */
|
|
84373
|
+
this.fromMarkup = false;
|
|
84374
|
+
this.rowData = [];
|
|
84375
|
+
this.seededExpanded = false;
|
|
84376
|
+
// Only rows this table collapsed are re-shown, so a consumer's own [hidden] is left alone.
|
|
84377
|
+
this.collapsed = new WeakSet();
|
|
84378
|
+
this.dragRowIndex = -1;
|
|
84379
|
+
this.layoutToken = 0;
|
|
84380
|
+
this.dragColumnId = '';
|
|
84381
|
+
/**
|
|
84382
|
+
* A declared width is a floor, so columns that cannot fit overflow rather than squeeze. The table
|
|
84383
|
+
* scrolls them into reach instead of letting them hang outside the block they were given.
|
|
84384
|
+
*/
|
|
84385
|
+
this.measureOverflow = () => {
|
|
84386
|
+
if (!this.scrollEl)
|
|
84387
|
+
return;
|
|
84388
|
+
const overflowing = this.scrollEl.scrollWidth - this.scrollEl.clientWidth > 1;
|
|
84389
|
+
if (overflowing !== this.overflowing)
|
|
84390
|
+
this.overflowing = overflowing;
|
|
84391
|
+
};
|
|
84392
|
+
this.toggleSort = (column) => {
|
|
84393
|
+
var _a;
|
|
84394
|
+
// A finished column drag still fires a click on the header — that must not sort it.
|
|
84395
|
+
if (!this.isSortable(column) || this.columnDragging)
|
|
84396
|
+
return;
|
|
84397
|
+
const name = sortName(column);
|
|
84398
|
+
const direction = nextSortDirection(((_a = this.sortState) === null || _a === void 0 ? void 0 : _a.name) === name ? this.sortState.direction : null);
|
|
84399
|
+
this.sortState = { name, direction };
|
|
84400
|
+
this.sortChange.emit(this.sortState);
|
|
84401
|
+
};
|
|
84402
|
+
this.resizeStart = (event, column, handle) => {
|
|
84403
|
+
if (event.button !== 0)
|
|
84404
|
+
return;
|
|
84405
|
+
event.preventDefault();
|
|
84406
|
+
event.stopPropagation();
|
|
84407
|
+
const shown = this.visible;
|
|
84408
|
+
const index = shown.indexOf(column);
|
|
84409
|
+
// Trading with a neighbour keeps the total, so the table never stops filling its container.
|
|
84410
|
+
const pairIndex = index + 1 < shown.length ? index + 1 : index - 1;
|
|
84411
|
+
const pair = shown[pairIndex];
|
|
84412
|
+
const cells = this.headerCells();
|
|
84413
|
+
const startWidth = cells[index].getBoundingClientRect().width;
|
|
84414
|
+
const pairStart = pair ? cells[pairIndex].getBoundingClientRect().width : 0;
|
|
84415
|
+
const startX = event.clientX;
|
|
84416
|
+
const offset = this.leadingTracks.length;
|
|
84417
|
+
let width = startWidth;
|
|
84418
|
+
let pairWidth = pairStart;
|
|
84419
|
+
handle.setPointerCapture(event.pointerId);
|
|
84420
|
+
// Written straight onto the grid: a re-render per pointermove stutters on a full page.
|
|
84421
|
+
const move = (moveEvent) => {
|
|
84422
|
+
var _a;
|
|
84423
|
+
width = clampWidth(startWidth + moveEvent.clientX - startX, column);
|
|
84424
|
+
if (pair) {
|
|
84425
|
+
// The neighbour's own floor caps the drag, so neither column is squeezed past its minimum.
|
|
84426
|
+
pairWidth = clampWidth(pairStart - (width - startWidth), pair);
|
|
84427
|
+
width = clampWidth(startWidth + (pairStart - pairWidth), column);
|
|
84428
|
+
}
|
|
84429
|
+
const tracks = buildColumnTracks(this.columnState, this.leadingTracks, this.trailingTracks);
|
|
84430
|
+
tracks[index + offset] = `${width}px`;
|
|
84431
|
+
if (pair)
|
|
84432
|
+
tracks[pairIndex + offset] = `${pairWidth}px`;
|
|
84433
|
+
(_a = this.gridEl) === null || _a === void 0 ? void 0 : _a.style.setProperty('--xv-table-columns', tracks.join(' '));
|
|
84434
|
+
};
|
|
84435
|
+
const stop = () => {
|
|
84436
|
+
handle.removeEventListener('pointermove', move);
|
|
84437
|
+
handle.removeEventListener('pointerup', stop);
|
|
84438
|
+
handle.removeEventListener('pointercancel', stop);
|
|
84439
|
+
this.columnState = this.columnState.map(item => {
|
|
84440
|
+
if (item.id === column.id)
|
|
84441
|
+
return Object.assign(Object.assign({}, item), { width });
|
|
84442
|
+
if (pair && item.id === pair.id)
|
|
84443
|
+
return Object.assign(Object.assign({}, item), { width: pairWidth });
|
|
84444
|
+
return item;
|
|
84445
|
+
});
|
|
84446
|
+
this.commitLayout();
|
|
84447
|
+
};
|
|
84448
|
+
handle.addEventListener('pointermove', move);
|
|
84449
|
+
handle.addEventListener('pointerup', stop);
|
|
84450
|
+
handle.addEventListener('pointercancel', stop);
|
|
84451
|
+
};
|
|
84452
|
+
this.resizeReset = (column) => {
|
|
84453
|
+
var _a;
|
|
84454
|
+
const width = (_a = this.declared.find(item => item.id === column.id)) === null || _a === void 0 ? void 0 : _a.width;
|
|
84455
|
+
this.columnState = this.columnState.map(item => (item.id === column.id ? Object.assign(Object.assign({}, item), { width }) : item));
|
|
84456
|
+
this.commitLayout();
|
|
84457
|
+
};
|
|
84458
|
+
this.headPointerDown = (event) => {
|
|
84459
|
+
const hit = this.headerCellFrom(event);
|
|
84460
|
+
if (!hit)
|
|
84461
|
+
return;
|
|
84462
|
+
const path = event.composedPath();
|
|
84463
|
+
if (!path.some(node => { var _a; return (_a = node === null || node === void 0 ? void 0 : node.classList) === null || _a === void 0 ? void 0 : _a.contains('resize'); }))
|
|
84464
|
+
return;
|
|
84465
|
+
this.resizeStart(event, hit.column, event.composedPath()[0]);
|
|
84466
|
+
};
|
|
84467
|
+
this.headKeyDown = (event) => {
|
|
84468
|
+
if (event.key !== 'Enter' && event.key !== ' ')
|
|
84469
|
+
return;
|
|
84470
|
+
const hit = this.headerCellFrom(event);
|
|
84471
|
+
if (!hit)
|
|
84472
|
+
return;
|
|
84473
|
+
event.preventDefault();
|
|
84474
|
+
this.toggleSort(hit.column);
|
|
84475
|
+
};
|
|
84476
|
+
this.headDblClick = (event) => {
|
|
84477
|
+
const path = event.composedPath();
|
|
84478
|
+
if (!path.some(node => { var _a; return (_a = node === null || node === void 0 ? void 0 : node.classList) === null || _a === void 0 ? void 0 : _a.contains('resize'); }))
|
|
84479
|
+
return;
|
|
84480
|
+
const hit = this.headerCellFrom(event);
|
|
84481
|
+
if (hit)
|
|
84482
|
+
this.resizeReset(hit.column);
|
|
84483
|
+
};
|
|
84484
|
+
this.headDragStart = (event) => {
|
|
84485
|
+
const hit = this.headerCellFrom(event);
|
|
84486
|
+
if (hit)
|
|
84487
|
+
this.dragStart(event, hit.column);
|
|
84488
|
+
};
|
|
84489
|
+
this.headDragOver = (event) => {
|
|
84490
|
+
const hit = this.headerCellFrom(event);
|
|
84491
|
+
if (hit)
|
|
84492
|
+
this.dragOver(event, hit.column, hit.cell);
|
|
84493
|
+
};
|
|
84494
|
+
this.headDrop = (event) => {
|
|
84495
|
+
const hit = this.headerCellFrom(event);
|
|
84496
|
+
if (hit)
|
|
84497
|
+
this.drop(event, hit.column);
|
|
84498
|
+
};
|
|
84499
|
+
this.dragStart = (event, column) => {
|
|
84500
|
+
var _a;
|
|
84501
|
+
this.dragColumnId = column.id;
|
|
84502
|
+
this.columnDragging = true;
|
|
84503
|
+
(_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.setData('text/plain', column.id);
|
|
84504
|
+
if (event.dataTransfer)
|
|
84505
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
84506
|
+
};
|
|
84507
|
+
this.dragOver = (event, column, cell) => {
|
|
84508
|
+
if (!this.dragColumnId || column.id === this.dragColumnId)
|
|
84509
|
+
return;
|
|
84510
|
+
if (!columnAllows(column, this.reorderable, 'reorderable'))
|
|
84511
|
+
return;
|
|
84512
|
+
event.preventDefault();
|
|
84513
|
+
if (this.dragOverId === column.id)
|
|
84514
|
+
return;
|
|
84515
|
+
this.dragOverId = column.id;
|
|
84516
|
+
this.headerCells().forEach(item => item.classList.toggle('drag-over', item === cell));
|
|
84517
|
+
};
|
|
84518
|
+
this.drop = (event, column) => {
|
|
84519
|
+
event.preventDefault();
|
|
84520
|
+
this.clearDragOver();
|
|
84521
|
+
if (!this.dragColumnId || column.id === this.dragColumnId)
|
|
84522
|
+
return;
|
|
84523
|
+
if (!columnAllows(column, this.reorderable, 'reorderable'))
|
|
84524
|
+
return;
|
|
84525
|
+
const shown = this.visible;
|
|
84526
|
+
const from = shown.findIndex(item => item.id === this.dragColumnId);
|
|
84527
|
+
const to = shown.findIndex(item => item.id === column.id);
|
|
84528
|
+
if (from < 0 || to < 0)
|
|
84529
|
+
return;
|
|
84530
|
+
this.columnState = mergeVisibleOrder(this.columnState, moveItem(shown, from, to));
|
|
84531
|
+
this.commitLayout();
|
|
84532
|
+
};
|
|
84533
|
+
this.dragEnd = () => {
|
|
84534
|
+
this.dragColumnId = '';
|
|
84535
|
+
this.clearDragOver();
|
|
84536
|
+
// The trailing click lands after dragend, so the sort guard has to outlive the gesture.
|
|
84537
|
+
setTimeout(() => (this.columnDragging = false), 0);
|
|
84538
|
+
};
|
|
84539
|
+
this.toggleSelectAll = () => {
|
|
84540
|
+
// Tri-state: a partial box clears what is picked rather than completing the set.
|
|
84541
|
+
this.setSelection(this.selectedValues.length ? [] : this.rowValues());
|
|
84542
|
+
};
|
|
84543
|
+
this.toggleColumn = (column) => {
|
|
84544
|
+
this.columnState = this.columnState.map(item => item.id === column.id ? Object.assign(Object.assign({}, item), { hidden: !item.hidden }) : item);
|
|
84545
|
+
this.commitLayout();
|
|
84546
|
+
};
|
|
84547
|
+
this.rowDragStart = (event) => {
|
|
84548
|
+
const row = this.rowFrom(event);
|
|
84549
|
+
if (!row || row.group || row.disabled)
|
|
84550
|
+
return;
|
|
84551
|
+
this.dragRowIndex = this.bodyRows().indexOf(row);
|
|
84552
|
+
if (this.dragRowIndex < 0)
|
|
84553
|
+
return;
|
|
84554
|
+
row.classList.add('is-dragging');
|
|
84555
|
+
if (event.dataTransfer)
|
|
84556
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
84557
|
+
};
|
|
84558
|
+
this.rowDragOver = (event) => {
|
|
84559
|
+
if (this.dragRowIndex < 0)
|
|
84560
|
+
return;
|
|
84561
|
+
const row = this.rowFrom(event);
|
|
84562
|
+
if (!row || row.group)
|
|
84563
|
+
return;
|
|
84564
|
+
const index = this.bodyRows().indexOf(row);
|
|
84565
|
+
if (index < 0 || index === this.dragRowIndex)
|
|
84566
|
+
return;
|
|
84567
|
+
event.preventDefault();
|
|
84568
|
+
if (index === this.dropRowIndex)
|
|
84569
|
+
return;
|
|
84570
|
+
this.dropRowIndex = index;
|
|
84571
|
+
// The line marks the edge the row will land against, so its side follows the drag direction.
|
|
84572
|
+
this.bodyRows().forEach((item, i) => {
|
|
84573
|
+
item.classList.toggle('drop-above', i === index && index < this.dragRowIndex);
|
|
84574
|
+
item.classList.toggle('drop-below', i === index && index > this.dragRowIndex);
|
|
84575
|
+
});
|
|
84576
|
+
};
|
|
84577
|
+
this.rowDrop = (event) => {
|
|
84578
|
+
if (this.dragRowIndex < 0)
|
|
84579
|
+
return;
|
|
84580
|
+
event.preventDefault();
|
|
84581
|
+
const to = this.dropRowIndex;
|
|
84582
|
+
const from = this.dragRowIndex;
|
|
84583
|
+
this.rowDragEnd();
|
|
84584
|
+
if (to < 0 || from === to)
|
|
84585
|
+
return;
|
|
84586
|
+
this.rowOrderChange.emit({ from, to });
|
|
84587
|
+
};
|
|
84588
|
+
this.rowDragEnd = () => {
|
|
84589
|
+
this.bodyRows().forEach(row => row.classList.remove('is-dragging', 'drop-above', 'drop-below'));
|
|
84590
|
+
this.dragRowIndex = -1;
|
|
84591
|
+
this.dropRowIndex = -1;
|
|
84592
|
+
};
|
|
84593
|
+
/** One listener for the whole body instead of a child event per row. */
|
|
84594
|
+
this.bodyChange = (event) => {
|
|
84595
|
+
var _a;
|
|
84596
|
+
const path = event.composedPath();
|
|
84597
|
+
const row = path.find(node => { var _a; return ((_a = node === null || node === void 0 ? void 0 : node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === XV_TABLE_ROW_TAG; });
|
|
84598
|
+
if (!row || row.disabled)
|
|
84599
|
+
return;
|
|
84600
|
+
// A checkbox the consumer put in a cell is its own; only the row's own control selects a row.
|
|
84601
|
+
const control = path.find(node => { var _a; return (_a = node === null || node === void 0 ? void 0 : node.classList) === null || _a === void 0 ? void 0 : _a.contains('control_input'); });
|
|
84602
|
+
if (!control || !((_a = row.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(control)))
|
|
84603
|
+
return;
|
|
84604
|
+
event.stopPropagation();
|
|
84605
|
+
if (row.hasAttribute('header'))
|
|
84606
|
+
return this.toggleSelectAll();
|
|
84607
|
+
this.toggleRowSelection(row.value);
|
|
84608
|
+
};
|
|
84609
|
+
this.gridClick = (event) => {
|
|
84610
|
+
const path = event.composedPath();
|
|
84611
|
+
if (path.some(node => { var _a; return (_a = node === null || node === void 0 ? void 0 : node.classList) === null || _a === void 0 ? void 0 : _a.contains('resize'); }))
|
|
84612
|
+
return;
|
|
84613
|
+
const header = this.headerCellFrom(event);
|
|
84614
|
+
if (header)
|
|
84615
|
+
return this.toggleSort(header.column);
|
|
84616
|
+
this.bodyClick(event);
|
|
84617
|
+
};
|
|
84618
|
+
this.bodyClick = (event) => {
|
|
84619
|
+
const path = event.composedPath();
|
|
84620
|
+
const row = path.find(node => { var _a; return ((_a = node === null || node === void 0 ? void 0 : node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === XV_TABLE_ROW_TAG; });
|
|
84621
|
+
if (!row || row.disabled)
|
|
84622
|
+
return;
|
|
84623
|
+
if (path.some(node => { var _a; return ((_a = node === null || node === void 0 ? void 0 : node.getAttribute) === null || _a === void 0 ? void 0 : _a.call(node, 'part')) === 'expand-button'; })) {
|
|
84624
|
+
this.toggleExpanded(row.value);
|
|
84625
|
+
return;
|
|
84626
|
+
}
|
|
84627
|
+
if (!this.rowClickable)
|
|
84628
|
+
return;
|
|
84629
|
+
// event.target is retargeted to the row at this boundary, so the path is the only honest check.
|
|
84630
|
+
if (path.some(node => { var _a; return node !== row && ((_a = node === null || node === void 0 ? void 0 : node.matches) === null || _a === void 0 ? void 0 : _a.call(node, INTERACTIVE)); }))
|
|
84631
|
+
return;
|
|
84632
|
+
this.rowClick.emit({ value: row.value, index: this.renderedRows().indexOf(row) });
|
|
84633
|
+
};
|
|
84634
|
+
this.paginationChanged = (event) => {
|
|
84635
|
+
event.stopPropagation();
|
|
84636
|
+
this.page = event.detail.page || this.page;
|
|
84637
|
+
this.pageSize = event.detail.itemsPerPage || this.pageSize;
|
|
84638
|
+
this.pageChange.emit({ page: this.page, pageSize: this.pageSize });
|
|
84639
|
+
};
|
|
84640
|
+
}
|
|
84641
|
+
componentWillLoad() {
|
|
84642
|
+
this.declared = parseProp(this.columns, []);
|
|
84643
|
+
this.rowData = parseProp(this.rows, []);
|
|
84644
|
+
this.columnState = this.declared.map(column => (Object.assign({}, column)));
|
|
84645
|
+
this.sortState = parseSortBy(this.sortBy);
|
|
84646
|
+
this.selectedValues = parseProp(this.selected, []);
|
|
84647
|
+
this.expandedValues = parseProp(this.expanded, []);
|
|
84648
|
+
this.slottedRowCount = this.slottedRows().length;
|
|
84649
|
+
if (this.storageKey || this.layout)
|
|
84650
|
+
this.restoreLayout();
|
|
84651
|
+
}
|
|
84652
|
+
componentDidLoad() {
|
|
84653
|
+
// Bound imperatively: a custom event has no typed JSX handler on a plain element.
|
|
84654
|
+
this.el.addEventListener(CHECKBOX_EVENT, this.bodyChange);
|
|
84655
|
+
// Absent in mock-doc and in hydrate builds; componentDidRender still keeps the rows in sync.
|
|
84656
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
84657
|
+
this.rowObserver = new MutationObserver(records => {
|
|
84658
|
+
// A framework re-rendering its own markup inside a cell must not trigger a full resync.
|
|
84659
|
+
if (!records.some(record => this.touchesStructure(record)))
|
|
84660
|
+
return;
|
|
84661
|
+
this.syncStructure();
|
|
84662
|
+
this.syncRows();
|
|
84663
|
+
});
|
|
84664
|
+
this.rowObserver.observe(this.el, {
|
|
84665
|
+
childList: true,
|
|
84666
|
+
subtree: true,
|
|
84667
|
+
// A framework can reflect these after the table has already read the header once.
|
|
84668
|
+
attributes: true,
|
|
84669
|
+
attributeFilter: ['column-id', 'width', 'sortable', 'hideable', 'parent'],
|
|
84670
|
+
});
|
|
84671
|
+
}
|
|
84672
|
+
// Fires after layout, so reading the two widths costs no extra reflow.
|
|
84673
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
84674
|
+
this.sizeObserver = new ResizeObserver(() => this.measureOverflow());
|
|
84675
|
+
if (this.scrollEl)
|
|
84676
|
+
this.sizeObserver.observe(this.scrollEl);
|
|
84677
|
+
if (this.gridEl)
|
|
84678
|
+
this.sizeObserver.observe(this.gridEl);
|
|
84679
|
+
}
|
|
84680
|
+
this.syncStructure();
|
|
84681
|
+
this.syncRows();
|
|
84682
|
+
}
|
|
84683
|
+
componentDidRender() {
|
|
84684
|
+
this.syncRows();
|
|
84685
|
+
}
|
|
84686
|
+
disconnectedCallback() {
|
|
84687
|
+
var _a, _b;
|
|
84688
|
+
this.el.removeEventListener(CHECKBOX_EVENT, this.bodyChange);
|
|
84689
|
+
(_a = this.rowObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
84690
|
+
this.rowObserver = undefined;
|
|
84691
|
+
(_b = this.sizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
84692
|
+
this.sizeObserver = undefined;
|
|
84693
|
+
}
|
|
84694
|
+
columnsChanged() {
|
|
84695
|
+
this.declared = parseProp(this.columns, []);
|
|
84696
|
+
this.restoreLayout();
|
|
83885
84697
|
}
|
|
83886
|
-
|
|
83887
|
-
|
|
84698
|
+
layoutInputChanged() {
|
|
84699
|
+
this.restoreLayout();
|
|
84700
|
+
}
|
|
84701
|
+
sortByChanged() {
|
|
84702
|
+
this.sortState = parseSortBy(this.sortBy);
|
|
84703
|
+
}
|
|
84704
|
+
selectedChanged() {
|
|
84705
|
+
this.selectedValues = parseProp(this.selected, []);
|
|
84706
|
+
}
|
|
84707
|
+
expandedChanged() {
|
|
84708
|
+
this.expandedValues = parseProp(this.expanded, []);
|
|
84709
|
+
}
|
|
84710
|
+
rowsChanged() {
|
|
84711
|
+
this.rowData = parseProp(this.rows, []);
|
|
84712
|
+
}
|
|
84713
|
+
/** Selects every selectable row. */
|
|
84714
|
+
async selectAll() {
|
|
84715
|
+
this.setSelection(this.rowValues());
|
|
84716
|
+
}
|
|
84717
|
+
/** Clears the selection. */
|
|
84718
|
+
async clearSelection() {
|
|
84719
|
+
this.setSelection([]);
|
|
84720
|
+
}
|
|
84721
|
+
/** Drops the stored layout and returns to the declared columns. */
|
|
84722
|
+
async resetLayout() {
|
|
84723
|
+
this.columnState = this.declared.map(column => (Object.assign({}, column)));
|
|
84724
|
+
await deleteLayout(this.storageOwner, this.storageKey);
|
|
84725
|
+
this.layoutChange.emit(diffLayout(this.columnState, this.declared));
|
|
84726
|
+
}
|
|
84727
|
+
/** The layout as it would be stored: only the deviations from the declared columns. */
|
|
84728
|
+
async getLayout() {
|
|
84729
|
+
return diffLayout(this.columnState, this.declared);
|
|
84730
|
+
}
|
|
84731
|
+
async restoreLayout() {
|
|
84732
|
+
const token = ++this.layoutToken;
|
|
84733
|
+
const controlled = parseProp(this.layout, null);
|
|
84734
|
+
if (controlled) {
|
|
84735
|
+
this.columnState = applyLayout(this.declared, controlled);
|
|
83888
84736
|
return;
|
|
83889
|
-
if (detail.checked) {
|
|
83890
|
-
this.selected.set(detail.name, detail);
|
|
83891
84737
|
}
|
|
83892
|
-
|
|
83893
|
-
this.
|
|
84738
|
+
if (!this.storageKey) {
|
|
84739
|
+
this.columnState = this.declared.map(column => (Object.assign({}, column)));
|
|
84740
|
+
return;
|
|
83894
84741
|
}
|
|
83895
|
-
|
|
84742
|
+
// Painting declared widths and correcting them afterwards is visible, so the body waits.
|
|
84743
|
+
this.layoutPending = true;
|
|
84744
|
+
const stored = await readLayout(this.storageOwner, this.storageKey);
|
|
84745
|
+
if (token !== this.layoutToken)
|
|
84746
|
+
return;
|
|
84747
|
+
this.columnState = applyLayout(this.declared, stored);
|
|
84748
|
+
this.layoutPending = false;
|
|
84749
|
+
}
|
|
84750
|
+
commitLayout() {
|
|
84751
|
+
const next = diffLayout(this.columnState, this.declared);
|
|
84752
|
+
void writeLayout(this.storageOwner, this.storageKey, next);
|
|
84753
|
+
this.layoutChange.emit(next);
|
|
84754
|
+
}
|
|
84755
|
+
get localeTag() {
|
|
84756
|
+
var _a;
|
|
84757
|
+
return this.locale || ((_a = this.el.closest('[lang]')) === null || _a === void 0 ? void 0 : _a.getAttribute('lang')) || 'de';
|
|
84758
|
+
}
|
|
84759
|
+
get visible() {
|
|
84760
|
+
return visibleColumns(this.columnState);
|
|
84761
|
+
}
|
|
84762
|
+
get hasSelection() {
|
|
84763
|
+
return this.selection !== 'none';
|
|
84764
|
+
}
|
|
84765
|
+
get hasExpand() {
|
|
84766
|
+
return this.expandMode !== 'none';
|
|
84767
|
+
}
|
|
84768
|
+
get template() {
|
|
84769
|
+
if (this.columnState.length) {
|
|
84770
|
+
return buildColumnTemplate(this.columnState, this.leadingTracks, this.trailingTracks);
|
|
84771
|
+
}
|
|
84772
|
+
// No columns declared: a plain table takes its structure from the markup itself.
|
|
84773
|
+
return [...this.leadingTracks.map(w => `${w}px`), ...this.derivedTracks, ...this.trailingTracks.map(w => `${w}px`)].join(' ');
|
|
84774
|
+
}
|
|
84775
|
+
/** Grip, then the expand toggle, then selection — one track each, in render order. */
|
|
84776
|
+
get leadingTracks() {
|
|
84777
|
+
return [
|
|
84778
|
+
...(this.rowReorderable ? [XV_TABLE_CONTROL_WIDTH] : []),
|
|
84779
|
+
...(this.hasExpand ? [XV_TABLE_CONTROL_WIDTH] : []),
|
|
84780
|
+
...(this.hasSelection ? [XV_TABLE_CONTROL_WIDTH] : []),
|
|
84781
|
+
];
|
|
84782
|
+
}
|
|
84783
|
+
get trailingTracks() {
|
|
84784
|
+
return [];
|
|
83896
84785
|
}
|
|
83897
|
-
|
|
84786
|
+
get dataRows() {
|
|
84787
|
+
const all = this.rowData;
|
|
84788
|
+
const sorted = this.sortMode === 'client' && this.sortState
|
|
84789
|
+
? sortRows(all, this.columnBySortName(this.sortState.name), this.sortState.direction, this.localeTag)
|
|
84790
|
+
: all;
|
|
84791
|
+
return this.paginationMode === 'client' ? pageSlice(sorted, this.page, this.pageSize) : sorted;
|
|
84792
|
+
}
|
|
84793
|
+
get rowTotal() {
|
|
84794
|
+
if (this.paginationMode === 'server')
|
|
84795
|
+
return this.total;
|
|
84796
|
+
const slotted = this.topRows(this.slottedRows()).length;
|
|
84797
|
+
return slotted || this.rowData.length;
|
|
84798
|
+
}
|
|
84799
|
+
// Nothing to show is not the same as something to say: a consumer that draws its own empty state
|
|
84800
|
+
// next to the table would otherwise get an empty frame above it.
|
|
84801
|
+
get isEmpty() {
|
|
84802
|
+
return !this.loading && !this.rowTotal && (!!this.emptyLabel || this.hasSlottedEmpty);
|
|
84803
|
+
}
|
|
84804
|
+
columnBySortName(name) {
|
|
84805
|
+
return this.columnState.find(column => sortName(column) === name) || null;
|
|
84806
|
+
}
|
|
84807
|
+
touchesStructure(record) {
|
|
84808
|
+
// The filter already narrows attributes to the ones that shape a column.
|
|
84809
|
+
if (record.type === 'attributes')
|
|
84810
|
+
return true;
|
|
84811
|
+
const structural = (node) => {
|
|
84812
|
+
var _a;
|
|
84813
|
+
const tag = (_a = node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
84814
|
+
// Anything that fills a slot shapes the table; markup inside a cell does not.
|
|
84815
|
+
return tag === XV_TABLE_ROW_TAG || tag === XV_TABLE_CELL_TAG || !!node.slot;
|
|
84816
|
+
};
|
|
84817
|
+
return (Array.from(record.addedNodes).some(structural) || Array.from(record.removedNodes).some(structural));
|
|
84818
|
+
}
|
|
84819
|
+
isBodyRow(row) {
|
|
84820
|
+
return !row.hasAttribute('header') && row.getAttribute('slot') !== 'footer';
|
|
84821
|
+
}
|
|
84822
|
+
/** Body rows only — these are the ones selection and expansion count. */
|
|
84823
|
+
slottedRows() {
|
|
84824
|
+
return this.slottedRowsAll().filter(row => this.isBodyRow(row));
|
|
84825
|
+
}
|
|
84826
|
+
/** A page is counted in top-level rows: a group and its children travel together. */
|
|
84827
|
+
topRows(rows) {
|
|
84828
|
+
return rows.filter(row => this.isBodyRow(row) && !this.parentOf(row));
|
|
84829
|
+
}
|
|
84830
|
+
/** Every slotted row, footer included: they all need the column tracks lined up. */
|
|
84831
|
+
slottedRowsAll() {
|
|
84832
|
+
return Array.from(this.el.children).filter(child => child.tagName.toLowerCase() === XV_TABLE_ROW_TAG);
|
|
84833
|
+
}
|
|
84834
|
+
/** Every row on screen, whichever mode produced it. */
|
|
84835
|
+
renderedRows() {
|
|
83898
84836
|
var _a;
|
|
83899
|
-
|
|
84837
|
+
const slotted = this.slottedRows();
|
|
84838
|
+
if (slotted.length)
|
|
84839
|
+
return slotted;
|
|
84840
|
+
return Array.from(((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${XV_TABLE_ROW_TAG}:not([header])`)) || []);
|
|
84841
|
+
}
|
|
84842
|
+
rowValues() {
|
|
84843
|
+
const slotted = this.slottedRows();
|
|
84844
|
+
if (slotted.length) {
|
|
84845
|
+
const parents = this.parentValues(slotted);
|
|
84846
|
+
return slotted
|
|
84847
|
+
.filter(row => !this.isDisabled(row))
|
|
84848
|
+
.map(row => row.value)
|
|
84849
|
+
.filter(value => !parents.has(String(value)));
|
|
84850
|
+
}
|
|
84851
|
+
return this.dataRows.map(row => row === null || row === void 0 ? void 0 : row[this.rowKey]);
|
|
84852
|
+
}
|
|
84853
|
+
/** A disabled row is not selectable, so it stays out of every selection set. */
|
|
84854
|
+
isDisabled(row) {
|
|
84855
|
+
return !!row.disabled || row.hasAttribute('disabled');
|
|
84856
|
+
}
|
|
84857
|
+
/** `parent` may arrive as an attribute or as a property, depending on the consumer. */
|
|
84858
|
+
parentOf(row) {
|
|
84859
|
+
return String(row.parent || row.getAttribute('parent') || '');
|
|
84860
|
+
}
|
|
84861
|
+
parentValues(rows) {
|
|
84862
|
+
return new Set(rows.map(row => this.parentOf(row)).filter(Boolean));
|
|
84863
|
+
}
|
|
84864
|
+
childValuesOf(value) {
|
|
84865
|
+
return this.buildTree(this.slottedRows()).get(String(value)) || [];
|
|
84866
|
+
}
|
|
84867
|
+
/** One walk of the rows answers every parent/child question asked during a sync. */
|
|
84868
|
+
buildTree(rows) {
|
|
84869
|
+
const children = new Map();
|
|
84870
|
+
rows.forEach(row => {
|
|
84871
|
+
const parent = this.parentOf(row);
|
|
84872
|
+
if (!parent)
|
|
84873
|
+
return;
|
|
84874
|
+
const values = children.get(parent) || [];
|
|
84875
|
+
if (!this.isDisabled(row))
|
|
84876
|
+
values.push(row.value);
|
|
84877
|
+
children.set(parent, values);
|
|
84878
|
+
});
|
|
84879
|
+
return children;
|
|
84880
|
+
}
|
|
84881
|
+
/**
|
|
84882
|
+
* Child rows declare their parent by value. They stay siblings in the grid — that is what keeps
|
|
84883
|
+
* them in the table's columns, rather than a nested table inside a panel.
|
|
84884
|
+
*/
|
|
84885
|
+
syncRowTree(rows, children, expanded) {
|
|
84886
|
+
const page = this.pageWindow(rows);
|
|
84887
|
+
const groups = new Map();
|
|
84888
|
+
rows.forEach(row => {
|
|
84889
|
+
var _a;
|
|
84890
|
+
const value = String((_a = row.value) !== null && _a !== void 0 ? _a : '');
|
|
84891
|
+
if (value && !this.parentOf(row))
|
|
84892
|
+
groups.set(value, row);
|
|
84893
|
+
});
|
|
84894
|
+
rows.forEach(row => {
|
|
84895
|
+
var _a;
|
|
84896
|
+
const props = row;
|
|
84897
|
+
const parent = this.parentOf(row);
|
|
84898
|
+
const value = String((_a = props.value) !== null && _a !== void 0 ? _a : '');
|
|
84899
|
+
if (parent) {
|
|
84900
|
+
const group = groups.get(parent);
|
|
84901
|
+
// A child follows its group: it shows when the group is open and on the current page.
|
|
84902
|
+
const show = expanded.has(parent) && (!page || (!!group && page.has(group)));
|
|
84903
|
+
this.showRow(row, show);
|
|
84904
|
+
props.expandable = false;
|
|
84905
|
+
return;
|
|
84906
|
+
}
|
|
84907
|
+
const hasChildren = children.has(value);
|
|
84908
|
+
const panel = !!row.querySelector('[slot="expand"]');
|
|
84909
|
+
// a row is expandable when it has children, or content for the panel
|
|
84910
|
+
props.expandable = hasChildren || panel;
|
|
84911
|
+
props.hasPanel = panel;
|
|
84912
|
+
row.classList.toggle('has-children', hasChildren);
|
|
84913
|
+
this.showRow(row, !page || !this.isBodyRow(row) || page.has(row));
|
|
84914
|
+
});
|
|
84915
|
+
}
|
|
84916
|
+
/** Only rows this table hid are shown again, so a consumer's own `hidden` survives a sync. */
|
|
84917
|
+
showRow(row, show) {
|
|
84918
|
+
if (!show) {
|
|
84919
|
+
this.collapsed.add(row);
|
|
84920
|
+
row.hidden = true;
|
|
83900
84921
|
return;
|
|
83901
|
-
|
|
83902
|
-
|
|
83903
|
-
|
|
83904
|
-
return 'minmax(0, 1fr)';
|
|
83905
|
-
if (v === 'auto')
|
|
83906
|
-
return 'minmax(0, auto)';
|
|
83907
|
-
return `calc(${v} - ${50 / this.colsSize.length}px)`;
|
|
83908
|
-
})
|
|
83909
|
-
.join(' ') + ' repeat(auto-fit, minmax(0, 1fr))');
|
|
84922
|
+
}
|
|
84923
|
+
if (this.collapsed.delete(row))
|
|
84924
|
+
row.hidden = false;
|
|
83910
84925
|
}
|
|
83911
|
-
|
|
83912
|
-
|
|
84926
|
+
/** The rows of the current page, or null while the table is not the one paging. */
|
|
84927
|
+
pageWindow(rows) {
|
|
84928
|
+
if (this.paginationMode !== 'client')
|
|
84929
|
+
return null;
|
|
84930
|
+
const top = this.topRows(rows);
|
|
84931
|
+
if (!top.length)
|
|
84932
|
+
return null;
|
|
84933
|
+
const size = this.pageSize || 10;
|
|
84934
|
+
const start = (clampPage(this.page, totalPages(top.length, size)) - 1) * size;
|
|
84935
|
+
return new Set(top.slice(start, start + size));
|
|
83913
84936
|
}
|
|
83914
|
-
|
|
83915
|
-
|
|
84937
|
+
/** Cells are written in declared order; hiding and reordering only move them visually. */
|
|
84938
|
+
syncCells(row, order) {
|
|
84939
|
+
const cells = Array.from(row.children).filter(cell => cell.getAttribute('slot') !== 'expand');
|
|
84940
|
+
cells.forEach((cell, index) => {
|
|
84941
|
+
var _a;
|
|
84942
|
+
const column = this.declared[index];
|
|
84943
|
+
if (!column)
|
|
84944
|
+
return;
|
|
84945
|
+
const current = this.columnState.find(item => item.id === column.id);
|
|
84946
|
+
const props = cell;
|
|
84947
|
+
props.columnId = column.id;
|
|
84948
|
+
if (column.align)
|
|
84949
|
+
props.align = column.align;
|
|
84950
|
+
if (column.overflow)
|
|
84951
|
+
props.overflow = column.overflow;
|
|
84952
|
+
if (column.clampLines)
|
|
84953
|
+
props.clampLines = column.clampLines;
|
|
84954
|
+
cell.style.order = String((_a = order.get(column.id)) !== null && _a !== void 0 ? _a : index);
|
|
84955
|
+
cell.hidden = !!(current === null || current === void 0 ? void 0 : current.hidden);
|
|
84956
|
+
});
|
|
83916
84957
|
}
|
|
83917
|
-
|
|
83918
|
-
|
|
83919
|
-
|
|
83920
|
-
|
|
83921
|
-
|
|
83922
|
-
|
|
83923
|
-
|
|
83924
|
-
|
|
83925
|
-
|
|
83926
|
-
const
|
|
83927
|
-
|
|
83928
|
-
|
|
83929
|
-
|
|
83930
|
-
|
|
83931
|
-
this.sortChange = createEvent(this, "sortChange", 7);
|
|
84958
|
+
/** Structure writes @State, so it runs outside the render cycle: on load and on childList. */
|
|
84959
|
+
syncStructure() {
|
|
84960
|
+
const rows = this.slottedRowsAll();
|
|
84961
|
+
this.slottedRowCount = this.slottedRows().length;
|
|
84962
|
+
// The heading block is not rendered at all unless something fills it, and a slotted title is
|
|
84963
|
+
// just as much a title as the prop.
|
|
84964
|
+
const heading = Array.from(this.el.children).some(child => child.slot === 'label' || child.slot === 'description');
|
|
84965
|
+
if (this.hasSlottedHeading !== heading)
|
|
84966
|
+
this.hasSlottedHeading = heading;
|
|
84967
|
+
const empty = Array.from(this.el.children).some(child => child.slot === 'empty');
|
|
84968
|
+
if (this.hasSlottedEmpty !== empty)
|
|
84969
|
+
this.hasSlottedEmpty = empty;
|
|
84970
|
+
this.seedExpanded(rows);
|
|
84971
|
+
this.syncDerivedTracks(rows);
|
|
83932
84972
|
}
|
|
83933
|
-
|
|
83934
|
-
|
|
84973
|
+
/**
|
|
84974
|
+
* A row may declare itself open in markup. Read once, before the table starts writing the
|
|
84975
|
+
* attribute itself — after that there is no telling a declared value from a toggled one.
|
|
84976
|
+
*/
|
|
84977
|
+
seedExpanded(rows) {
|
|
84978
|
+
// Rows that arrive from an HTTP call are not there on the first pass, so seeding waits for them.
|
|
84979
|
+
if (this.seededExpanded || !rows.length)
|
|
83935
84980
|
return;
|
|
83936
|
-
|
|
83937
|
-
|
|
83938
|
-
|
|
83939
|
-
|
|
83940
|
-
|
|
83941
|
-
|
|
83942
|
-
|
|
83943
|
-
|
|
83944
|
-
|
|
84981
|
+
this.seededExpanded = true;
|
|
84982
|
+
const open = rows
|
|
84983
|
+
.filter(row => row.hasAttribute('expanded'))
|
|
84984
|
+
.map(row => row.value)
|
|
84985
|
+
.filter(value => value !== '' && value !== undefined);
|
|
84986
|
+
const merged = [...this.expandedValues, ...open.filter(v => !this.expandedValues.includes(v))];
|
|
84987
|
+
if (merged.length !== this.expandedValues.length)
|
|
84988
|
+
this.expandedValues = merged;
|
|
84989
|
+
}
|
|
84990
|
+
/** Pushing props onto children is safe during render; nothing here touches @State. */
|
|
84991
|
+
syncRows() {
|
|
84992
|
+
const rows = this.slottedRowsAll();
|
|
84993
|
+
const tree = this.buildTree(rows);
|
|
84994
|
+
// A value may reach the table as a number and come back from an attribute as a string.
|
|
84995
|
+
const expanded = new Set(this.expandedValues.map(String));
|
|
84996
|
+
const selected = new Set(this.selectedValues.map(String));
|
|
84997
|
+
const order = new Map(this.columnState.map((column, index) => [column.id, index]));
|
|
84998
|
+
this.syncRowTree(rows, tree, expanded);
|
|
84999
|
+
this.syncHeaderCells(rows.find(row => row.hasAttribute('header')));
|
|
85000
|
+
rows.forEach(row => {
|
|
85001
|
+
const value = row.value;
|
|
85002
|
+
const props = row;
|
|
85003
|
+
props.selectionMode = this.selection;
|
|
85004
|
+
props.expandMode = this.expandMode;
|
|
85005
|
+
props.size = this.size;
|
|
85006
|
+
props.hover = this.hover;
|
|
85007
|
+
props.rowReorderable = this.rowReorderable;
|
|
85008
|
+
props.rowReorderHandle = this.rowReorderHandle;
|
|
85009
|
+
props.expandLabel = this.expandLabel;
|
|
85010
|
+
props.reorderLabel = this.reorderLabel;
|
|
85011
|
+
if (row.hasAttribute('header')) {
|
|
85012
|
+
// A slotted header carries select-all too, so it reflects the whole table.
|
|
85013
|
+
const all = this.rowValues();
|
|
85014
|
+
const picked = this.selectedValues.length;
|
|
85015
|
+
props.selected = !!picked && picked === all.length;
|
|
85016
|
+
props.partial = !!picked && picked < all.length;
|
|
85017
|
+
props.selectable = all.length > 0;
|
|
85018
|
+
this.syncCells(row, order);
|
|
85019
|
+
return;
|
|
83945
85020
|
}
|
|
85021
|
+
const children = tree.get(String(value)) || [];
|
|
85022
|
+
if (children.length) {
|
|
85023
|
+
const picked = children.filter(child => selected.has(String(child)));
|
|
85024
|
+
props.selected = picked.length === children.length;
|
|
85025
|
+
props.partial = !!picked.length && picked.length < children.length;
|
|
85026
|
+
}
|
|
85027
|
+
else {
|
|
85028
|
+
props.selected = selected.has(String(value));
|
|
85029
|
+
props.partial = false;
|
|
85030
|
+
}
|
|
85031
|
+
props.expanded = expanded.has(String(value));
|
|
85032
|
+
this.syncCells(row, order);
|
|
83946
85033
|
});
|
|
83947
|
-
if (!this.name)
|
|
83948
|
-
this.name = uidGenerator();
|
|
83949
|
-
this.sortChange.emit({ name: this.name, value: this.sort });
|
|
83950
85034
|
}
|
|
83951
|
-
|
|
85035
|
+
/** Sorting is offered only when a mode asks for it, so `none` and `server` cannot look alike. */
|
|
85036
|
+
isSortable(column) {
|
|
85037
|
+
return !!column.sortable && this.sortMode !== 'none';
|
|
85038
|
+
}
|
|
85039
|
+
/**
|
|
85040
|
+
* A slotted header is the consumer's markup, so the table pushes the column state onto its cells
|
|
85041
|
+
* rather than rendering a second header of its own.
|
|
85042
|
+
*/
|
|
85043
|
+
syncHeaderCells(header) {
|
|
85044
|
+
if (!header)
|
|
85045
|
+
return;
|
|
85046
|
+
const cells = Array.from(header.children).filter(child => child.tagName.toLowerCase() === XV_TABLE_CELL_TAG);
|
|
85047
|
+
cells.forEach((cell, index) => {
|
|
85048
|
+
var _a;
|
|
85049
|
+
const declared = cell.columnId || cell.getAttribute('column-id');
|
|
85050
|
+
const column = declared
|
|
85051
|
+
? this.columnState.find(item => item.id === declared)
|
|
85052
|
+
: this.visible[index];
|
|
85053
|
+
const props = cell;
|
|
85054
|
+
props.header = true;
|
|
85055
|
+
props.reorderLabel = this.reorderLabel;
|
|
85056
|
+
if (!column) {
|
|
85057
|
+
props.resizable = false;
|
|
85058
|
+
props.reorderable = false;
|
|
85059
|
+
return;
|
|
85060
|
+
}
|
|
85061
|
+
const sortable = this.isSortable(column);
|
|
85062
|
+
props.columnId = column.id;
|
|
85063
|
+
// A markup header declares `sortable` itself. Writing the table's own idea of it back would
|
|
85064
|
+
// overwrite what the consumer just bound, and the table would then read its own answer.
|
|
85065
|
+
if (!this.fromMarkup)
|
|
85066
|
+
props.sortable = sortable;
|
|
85067
|
+
props.sortDirection =
|
|
85068
|
+
sortable && ((_a = this.sortState) === null || _a === void 0 ? void 0 : _a.name) === sortName(column) ? this.sortState.direction : '';
|
|
85069
|
+
props.resizable = columnAllows(column, this.resizable, 'resizable');
|
|
85070
|
+
props.reorderable = columnAllows(column, this.reorderable, 'reorderable');
|
|
85071
|
+
if (column.headerAlign)
|
|
85072
|
+
props.align = column.headerAlign;
|
|
85073
|
+
cell.draggable = props.reorderable;
|
|
85074
|
+
});
|
|
85075
|
+
}
|
|
85076
|
+
/** Reads the column shape out of the markup when no `columns` prop was given. */
|
|
85077
|
+
syncDerivedTracks(rows) {
|
|
85078
|
+
const header = rows.find(row => row.hasAttribute('header')) || null;
|
|
85079
|
+
if (this.hasSlottedHeader !== !!header)
|
|
85080
|
+
this.hasSlottedHeader = !!header;
|
|
85081
|
+
// Re-read the header while it is the declaration: a framework sets `sortable`, `hideable` or a
|
|
85082
|
+
// width as properties, and those can land after the first read. `columns` wins when it is given.
|
|
85083
|
+
if (header && (this.fromMarkup || !this.declared.length))
|
|
85084
|
+
this.deriveColumns(header);
|
|
85085
|
+
if (this.columnState.length)
|
|
85086
|
+
return;
|
|
85087
|
+
const source = header || rows[0];
|
|
85088
|
+
if (!source)
|
|
85089
|
+
return;
|
|
85090
|
+
const cells = Array.from(source.children).filter(cell => cell.getAttribute('slot') !== 'expand');
|
|
85091
|
+
const widths = cells.map(cell => String(cell.width || cell.getAttribute('width') || ''));
|
|
85092
|
+
// Every width fixed leaves nothing to absorb the slack, so they share it by weight.
|
|
85093
|
+
const share = widths.length > 0 && widths.every(width => /^[0-9.]+$/.test(width));
|
|
85094
|
+
const tracks = widths.map(width => {
|
|
85095
|
+
if (!width)
|
|
85096
|
+
return `minmax(${XV_TABLE_MIN_COLUMN_WIDTH}px,1fr)`;
|
|
85097
|
+
if (!/^[0-9.]+$/.test(width))
|
|
85098
|
+
return width;
|
|
85099
|
+
return share ? `minmax(${width}px,${width}fr)` : `${width}px`;
|
|
85100
|
+
});
|
|
85101
|
+
if (tracks.join(' ') !== this.derivedTracks.join(' '))
|
|
85102
|
+
this.derivedTracks = tracks;
|
|
85103
|
+
}
|
|
85104
|
+
/**
|
|
85105
|
+
* With no `columns` prop the header cells are the declaration: their attributes carry the id,
|
|
85106
|
+
* width and switches, so a markup-only table still resizes, reorders and remembers its layout.
|
|
85107
|
+
*/
|
|
85108
|
+
deriveColumns(header) {
|
|
85109
|
+
const cells = Array.from(header.children).filter(child => child.tagName.toLowerCase() === XV_TABLE_CELL_TAG);
|
|
85110
|
+
if (!cells.length)
|
|
85111
|
+
return;
|
|
85112
|
+
const taken = new Set();
|
|
85113
|
+
const derived = cells.map((cell, index) => {
|
|
85114
|
+
var _a;
|
|
85115
|
+
// The property wins over the attribute: a framework binds properties, and it may have done so
|
|
85116
|
+
// before the cell upgraded. The attribute is the fallback for plain markup.
|
|
85117
|
+
const props = cell;
|
|
85118
|
+
const flag = (name, value) => (value !== null && value !== void 0 ? value : cell.hasAttribute(name));
|
|
85119
|
+
// `240` and `240px` are both pixels; `25%`, `auto` or `12rem` land in the track as written.
|
|
85120
|
+
const width = String(props.width || cell.getAttribute('width') || '');
|
|
85121
|
+
const pixels = /^([0-9.]+)(px)?$/.exec(width);
|
|
85122
|
+
// Two columns may honestly carry the same name — a details and a delete cell both keyed by
|
|
85123
|
+
// `id`. Ids address a column, so a repeat is made unique here rather than silently sharing
|
|
85124
|
+
// a track with the column it collides with.
|
|
85125
|
+
let id = props.columnId || cell.getAttribute('column-id') || `col-${index}`;
|
|
85126
|
+
while (taken.has(id))
|
|
85127
|
+
id = `${id}-${index}`;
|
|
85128
|
+
taken.add(id);
|
|
85129
|
+
return {
|
|
85130
|
+
id,
|
|
85131
|
+
label: ((_a = cell.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '',
|
|
85132
|
+
sortable: flag('sortable', props.sortable),
|
|
85133
|
+
hideable: flag('hideable', props.hideable),
|
|
85134
|
+
width: !width ? undefined : pixels ? Number(pixels[1]) : width,
|
|
85135
|
+
};
|
|
85136
|
+
});
|
|
85137
|
+
// Compared on everything the header declares, not only the ids: a framework sets `sortable` as
|
|
85138
|
+
// a property, and it may land after the table first read the markup. Ids alone would freeze
|
|
85139
|
+
// that first reading and quietly drop the sort affordance the consumer asked for.
|
|
85140
|
+
const signature = derived.map(c => `${c.id}|${c.sortable}|${c.hideable}|${c.width}`).join();
|
|
85141
|
+
if (signature === this.declaredSignature)
|
|
85142
|
+
return;
|
|
85143
|
+
this.declaredSignature = signature;
|
|
85144
|
+
this.fromMarkup = true;
|
|
85145
|
+
this.declared = derived;
|
|
85146
|
+
this.columnState = derived.map(column => (Object.assign({}, column)));
|
|
85147
|
+
if (this.storageKey)
|
|
85148
|
+
this.restoreLayout();
|
|
85149
|
+
}
|
|
85150
|
+
/** Every header cell on screen, whether the table rendered it or the consumer slotted it. */
|
|
85151
|
+
headerCells() {
|
|
85152
|
+
var _a;
|
|
85153
|
+
const row = this.slottedRowsAll().find(item => item.hasAttribute('header')) ||
|
|
85154
|
+
((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${XV_TABLE_ROW_TAG}[header]`));
|
|
85155
|
+
if (!row)
|
|
85156
|
+
return [];
|
|
85157
|
+
return Array.from(row.children).filter(
|
|
85158
|
+
// Hidden cells are left out: these are indexed against the visible columns.
|
|
85159
|
+
child => child.tagName.toLowerCase() === XV_TABLE_CELL_TAG && !child.hidden);
|
|
85160
|
+
}
|
|
85161
|
+
/** A header cell knows its column by id, or failing that by its position in the row. */
|
|
85162
|
+
columnOf(cell) {
|
|
85163
|
+
const id = cell.columnId || cell.getAttribute('column-id');
|
|
85164
|
+
if (id)
|
|
85165
|
+
return this.columnState.find(column => column.id === id) || null;
|
|
85166
|
+
const index = this.headerCells().indexOf(cell);
|
|
85167
|
+
return this.visible[index] || null;
|
|
85168
|
+
}
|
|
85169
|
+
headerCellFrom(event) {
|
|
85170
|
+
const path = event.composedPath();
|
|
85171
|
+
const cell = path.find(node => { var _a; return ((_a = node === null || node === void 0 ? void 0 : node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === XV_TABLE_CELL_TAG && node.hasAttribute('header'); });
|
|
85172
|
+
if (!cell)
|
|
85173
|
+
return null;
|
|
85174
|
+
const column = this.columnOf(cell);
|
|
85175
|
+
return column ? { cell, column } : null;
|
|
85176
|
+
}
|
|
85177
|
+
clearDragOver() {
|
|
85178
|
+
this.dragOverId = '';
|
|
85179
|
+
this.headerCells().forEach(item => item.classList.remove('drag-over'));
|
|
85180
|
+
}
|
|
85181
|
+
setSelection(values) {
|
|
85182
|
+
this.selectedValues = values;
|
|
85183
|
+
const all = !!values.length && values.length === this.rowValues().length;
|
|
85184
|
+
this.selectedChange.emit({ values, all, partial: !!values.length && !all });
|
|
85185
|
+
}
|
|
85186
|
+
toggleRowSelection(value) {
|
|
85187
|
+
const children = this.childValuesOf(value);
|
|
85188
|
+
if (children.length) {
|
|
85189
|
+
const picked = children.some(child => this.selectedValues.includes(child));
|
|
85190
|
+
this.setSelection(picked
|
|
85191
|
+
? this.selectedValues.filter(item => !children.includes(item))
|
|
85192
|
+
: [...this.selectedValues, ...children]);
|
|
85193
|
+
return;
|
|
85194
|
+
}
|
|
85195
|
+
if (this.selection === 'single') {
|
|
85196
|
+
this.setSelection(this.selectedValues.includes(value) ? [] : [value]);
|
|
85197
|
+
return;
|
|
85198
|
+
}
|
|
85199
|
+
const next = this.selectedValues.includes(value)
|
|
85200
|
+
? this.selectedValues.filter(item => item !== value)
|
|
85201
|
+
: [...this.selectedValues, value];
|
|
85202
|
+
this.setSelection(next);
|
|
85203
|
+
}
|
|
85204
|
+
toggleExpanded(value) {
|
|
85205
|
+
const open = this.expandedValues.includes(value);
|
|
85206
|
+
const next = open
|
|
85207
|
+
? this.expandedValues.filter(item => item !== value)
|
|
85208
|
+
: this.expandMode === 'single'
|
|
85209
|
+
? [value]
|
|
85210
|
+
: [...this.expandedValues, value];
|
|
85211
|
+
this.expandedValues = next;
|
|
85212
|
+
this.expandedChange.emit({ values: next });
|
|
85213
|
+
}
|
|
85214
|
+
bodyRows() {
|
|
85215
|
+
// A collapsed child is not on screen, so it must not take an index in `rowOrderChange`.
|
|
85216
|
+
return this.renderedRows().filter(row => row.getAttribute('slot') !== 'footer' && !row.hidden);
|
|
85217
|
+
}
|
|
85218
|
+
rowFrom(event) {
|
|
85219
|
+
if (!this.rowReorderable)
|
|
85220
|
+
return null;
|
|
85221
|
+
const path = event.composedPath();
|
|
85222
|
+
return path.find(node => { var _a; return ((_a = node === null || node === void 0 ? void 0 : node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === XV_TABLE_ROW_TAG; }) || null;
|
|
85223
|
+
}
|
|
85224
|
+
/** The same row and cell components the consumer would write by hand. */
|
|
85225
|
+
renderHead() {
|
|
85226
|
+
const values = this.rowValues();
|
|
85227
|
+
const count = this.selectedValues.length;
|
|
85228
|
+
return (h("xv-table-row", { header: true, part: "head", size: this.size, selectionMode: this.selection, expandMode: this.expandMode, expandable: this.expandMode !== 'none', rowReorderable: this.rowReorderable, rowReorderHandle: this.rowReorderHandle, selected: !!count && count === values.length, partial: !!count && count < values.length, selectable: values.length > 0 }, this.visible.map(column => {
|
|
85229
|
+
var _a;
|
|
85230
|
+
const sortable = this.isSortable(column);
|
|
85231
|
+
const active = sortable && ((_a = this.sortState) === null || _a === void 0 ? void 0 : _a.name) === sortName(column);
|
|
85232
|
+
return (h("xv-table-cell", { key: column.id, header: true, part: "header-cell", columnId: column.id, align: column.headerAlign || 'start', tooltip: column.headerTooltip || '', sortable: sortable, sortDirection: active ? this.sortState.direction : '', resizable: columnAllows(column, this.resizable, 'resizable'), reorderable: columnAllows(column, this.reorderable, 'reorderable'), reorderLabel: this.reorderLabel, ref: element => element && (element.draggable = columnAllows(column, this.reorderable, 'reorderable')) }, column.label));
|
|
85233
|
+
})));
|
|
85234
|
+
}
|
|
85235
|
+
renderDataRow(row, index) {
|
|
85236
|
+
const value = row === null || row === void 0 ? void 0 : row[this.rowKey];
|
|
85237
|
+
return (h("xv-table-row", { key: value !== null && value !== void 0 ? value : index, value: value, size: this.size, hover: this.hover, selectionMode: this.selection, expandMode: this.expandMode, expandable: this.expandMode !== 'none', rowReorderable: this.rowReorderable, rowReorderHandle: this.rowReorderHandle, expandLabel: this.expandLabel, reorderLabel: this.reorderLabel, selected: this.selectedValues.includes(value), expanded: this.expandedValues.includes(value) }, this.visible.map(column => (h("xv-table-cell", { key: column.id, columnId: column.id, align: column.align || 'start', overflow: column.overflow || 'ellipsis', clampLines: column.clampLines || 2 }, formatCell(cellValue(row, column), column, this.localeTag))))));
|
|
85238
|
+
}
|
|
85239
|
+
renderSkeleton() {
|
|
85240
|
+
return Array.from({ length: this.skeletonRows }).map((_, index) => (h("div", { class: "skeleton_row", key: `skeleton-${index}`, "aria-hidden": "true" }, this.visible.map(column => (h("div", { class: "skeleton_cell", key: column.id }, h("span", { class: "skeleton_bar" })))))));
|
|
85241
|
+
}
|
|
85242
|
+
renderColumnPicker() {
|
|
85243
|
+
const hideable = hideableColumns(this.columnState);
|
|
85244
|
+
if (!hideable.length)
|
|
85245
|
+
return null;
|
|
85246
|
+
const changed = isLayoutChanged(diffLayout(this.columnState, this.declared));
|
|
85247
|
+
return (
|
|
85248
|
+
// The picker sits at the right edge, so it opens inward or a container with overflow clips it.
|
|
85249
|
+
h("xv-overflow-menu-v2", { class: "picker", part: "column-picker", position: "right", tooltip: this.columnsLabel }, h("span", { slot: "trigger", class: "picker_trigger" }, h("svg", { viewBox: "0 0 640 512", width: "16", height: "16", role: "img", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M448 80l0 352 128 0c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16L448 80zm-48 0L240 80l0 352 160 0 0-352zM192 432l0-352L64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l128 0zM0 96C0 60.7 28.7 32 64 32l512 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96z" })), changed && h("span", { class: "picker_marker" })), h("div", { class: "picker_list" }, hideable.map(column => (h("xv-checkbox-v2", { key: column.id, class: "picker_item", checked: !column.hidden, label: column.label || column.id, size: this.size, onEventChange: () => this.toggleColumn(column) }))), changed && (h("xv-button-v2", { variant: "tertiary", size: "sm", onClick: () => this.resetLayout() }, this.resetLabel)))));
|
|
85250
|
+
}
|
|
83952
85251
|
render() {
|
|
83953
|
-
|
|
85252
|
+
const hasHeading = !!this.label || !!this.description || this.hasSlottedHeading;
|
|
85253
|
+
const count = this.selectedValues.length;
|
|
85254
|
+
const composed = !!this.slottedRowCount;
|
|
85255
|
+
const pages = totalPages(this.rowTotal, this.pageSize);
|
|
85256
|
+
return (h(Host, { key: 'c2f1eeb31477c009112ea67964859a06f32fb0be', class: { 'is-dragging': this.columnDragging } }, hasHeading && (h("div", { key: 'b16d5ed6a0ec41e1e93938c136720a9b3f076718', class: "heading", part: "heading" }, h("slot", { key: 'b5597ee8f3e1b43c8a003bf51f0dd1fdea307584', name: "label" }, this.label && h("h3", { key: '7b5c70866bbea7f38bd9ed3f12f5f79abdec9b5b', class: "heading_title", part: "title" }, this.label)), h("slot", { key: 'e3fc65553d7d8afa5617116ef03c0e71c4083092', name: "description" }, this.description && h("p", { key: 'f3545d3da1697eadb58b081db1f63dbc758446a2', class: "heading_description", part: "description" }, this.description)))), h("div", { key: 'b2363cd4706ef813a7986a46e634c7a17c2887e7', class: "bar", part: "bar" }, h("div", { key: 'b4ed99838d302c23e539d3f0aed986d6597cfa97', class: "bar_toolbar", part: "toolbar" }, h("slot", { key: '7dfe5fe111ac94245b57d9b16db98e86df96e14d', name: "toolbar" }), this.renderColumnPicker()), !!count && (h("div", { key: '00e6baa9e59099c688f398f98552e96accfcfdbd', class: "bar_batch", part: "batch" }, h("slot", { key: '719ccca8dc2d5728ceec0fa5953ec45148fbfca7', name: "batch" }), !!this.selectedLabel && (h("span", { key: 'ae71c3c543d5faef29145a32c0cee9f2d9c5441e', class: "bar_count" }, this.selectedLabel.replace('{count}', String(count))))))), h("div", { key: '0739869a681a870c611b50b8cec858bf8c60b2fb', class: { scroll: true, 'scroll--overflowing': this.overflowing }, part: "scroll", ref: element => (this.scrollEl = element) }, h("div", { key: '978390fa1eed594533ac9911eae893cdbcb48f01', class: "grid", part: "grid", role: "table", onPointerDown: this.headPointerDown, onDblClick: this.headDblClick, onKeyDown: this.headKeyDown, onDragStart: this.headDragStart, onDragOver: this.headDragOver, onDrop: this.headDrop, onDragEnd: this.dragEnd, ref: element => (this.gridEl = element), style: {
|
|
85257
|
+
'--xv-table-columns': this.template,
|
|
85258
|
+
// Handed to CSS rather than applied here: a wide table squeezes like a real one, and
|
|
85259
|
+
// only a narrow viewport turns this into the width it scrolls at.
|
|
85260
|
+
'--xv-table-min-width': `${tableMinWidth(this.columnState, this.minWidth, [...this.leadingTracks, ...this.trailingTracks].reduce((a, b) => a + b, 0))}px`,
|
|
85261
|
+
}, onClick: this.gridClick }, !this.hasSlottedHeader && this.renderHead(), h("div", { key: '22295be916a60272a46fe01cf3399b345e274948', class: "body", part: "body", role: "rowgroup", hidden: this.layoutPending, onDragStart: this.rowReorderable ? this.rowDragStart : undefined, onDragOver: this.rowReorderable ? this.rowDragOver : undefined, onDrop: this.rowReorderable ? this.rowDrop : undefined, onDragEnd: this.rowReorderable ? this.rowDragEnd : undefined }, this.loading && this.skeletonRows > 0
|
|
85262
|
+
? this.renderSkeleton()
|
|
85263
|
+
: composed
|
|
85264
|
+
? null
|
|
85265
|
+
: this.dataRows.map((row, index) => this.renderDataRow(row, index)), h("slot", { key: '05441531d73c716d3846794bea921eafa2b61533' })), h("slot", { key: 'e9f573271b2a6b19f212b598cd4471ee0070e340', name: "footer" }))), this.isEmpty && (h("div", { key: '4ceb6586322442b2fe48c3191641ce7857ef8f4b', class: "empty", part: "empty" }, h("slot", { key: '6213459f9c9657174edbb8b41daa48672b8f0a51', name: "empty" }, this.emptyLabel))), this.loading && !this.skeletonRows && (h("div", { key: 'edd362ca185dcd335b76b6c1c1369b886a97864c', class: "loading", part: "loading" }, h("xv-loader-v2", { key: '8d73899654faa6bb8b403f1aad2a426ad595bfa9', size: SIZE_VAR.LG }))), this.paginationMode !== 'none' && !!this.rowTotal && (h("xv-pagination", { key: '64f7884cf9dd446c5cad790f5bca97fbe33522b9', class: "pagination", part: "pagination", size: this.size, variant: "full", block: true, total: pages, page: this.page, totalItems: this.rowTotal, itemsPerPage: this.pageSize, itemsPerPageOptions: parsePageSizes(this.pageSizeOptions), responsiveVariant: { compact: [0, 768] }, onPageChange: this.paginationChanged }))));
|
|
83954
85266
|
}
|
|
83955
85267
|
get el() { return getElement(this); }
|
|
85268
|
+
static get watchers() { return {
|
|
85269
|
+
"columns": [{
|
|
85270
|
+
"columnsChanged": 0
|
|
85271
|
+
}],
|
|
85272
|
+
"layout": [{
|
|
85273
|
+
"layoutInputChanged": 0
|
|
85274
|
+
}],
|
|
85275
|
+
"storageKey": [{
|
|
85276
|
+
"layoutInputChanged": 0
|
|
85277
|
+
}],
|
|
85278
|
+
"storageOwner": [{
|
|
85279
|
+
"layoutInputChanged": 0
|
|
85280
|
+
}],
|
|
85281
|
+
"sortBy": [{
|
|
85282
|
+
"sortByChanged": 0
|
|
85283
|
+
}],
|
|
85284
|
+
"selected": [{
|
|
85285
|
+
"selectedChanged": 0
|
|
85286
|
+
}],
|
|
85287
|
+
"expanded": [{
|
|
85288
|
+
"expandedChanged": 0
|
|
85289
|
+
}],
|
|
85290
|
+
"rows": [{
|
|
85291
|
+
"rowsChanged": 0
|
|
85292
|
+
}]
|
|
85293
|
+
}; }
|
|
83956
85294
|
};
|
|
83957
|
-
|
|
83958
|
-
|
|
83959
|
-
const XV_EXPANDABLE_KEY = 'expandable';
|
|
83960
|
-
const XV_TABLE_TAG = 'xv-table-v2';
|
|
85295
|
+
XvTable.style = xvTableCss();
|
|
83961
85296
|
|
|
83962
|
-
const
|
|
85297
|
+
const xvTableCellCss = () => `:host{--xv-table-cell-padding-x:var(--xv-table-padding-x, var(--spacing-05));--xv-table-cell-padding-y:var(--xv-table-padding-y, var(--spacing-03));--xv-table-cell-clamp:2;display:flex;align-items:center;box-sizing:border-box;min-width:0;padding-block:var(--xv-table-cell-padding-y);padding-inline:min(var(--xv-table-cell-padding-x), 25%);color:var(--text-primary);font-family:var(--ff-body);font-size:var(--fz-md);line-height:18px;letter-spacing:0.16px}:host([align=center]){justify-content:center;text-align:center}:host([align=end]){justify-content:flex-end;text-align:right}.content{min-width:0;max-width:100%}[part=tooltip]{min-width:0;max-width:100%}:host([overflow=ellipsis]) .content{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host([overflow=ellipsis]) .content ::slotted(*){min-width:0;max-width:100%}:host([overflow=clamp]) .content{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--xv-table-cell-clamp);overflow:hidden}:host([overflow=clamp]) .content ::slotted(*){display:inline}:host([overflow=wrap]) .content{overflow:visible;white-space:normal}:host([header]){position:relative;gap:var(--spacing-02);font-weight:600}:host([header]) .content{flex:1}:host([header][align=end]) .sort{order:-1}:host([header][sortable]){cursor:pointer}:host([header][sortable]):hover{background:var(--layer-accent-hover-01)}:host([header][sortable]):focus-visible{outline:2px solid var(--focus);outline-offset:0}:host([header][sortable]):focus-visible{outline-offset:-2px}:host([header][sort-direction=asc]),:host([header][sort-direction=desc]){background:var(--layer-accent-active-01)}.sort{flex:none;width:8px;height:8px;border-right:1px solid currentColor;border-bottom:1px solid currentColor;opacity:0;transform:rotate(45deg) translate(-2px, -2px)}:host([header][sortable]:hover) .sort{opacity:0.5}:host([header][sort-direction=asc]) .sort,:host([header][sort-direction=desc]) .sort{opacity:1}:host([header][sort-direction=asc]) .sort{transform:rotate(-135deg) translate(-2px, -2px)}.grip{position:absolute;top:50%;left:4px;transform:translateY(-50%);width:8px;height:14px;opacity:0;cursor:grab;background-image:radial-gradient(currentColor 1px, transparent 1px);background-size:4px 4px}:host([header]:hover) .grip{opacity:0.5}:host(.drag-over){box-shadow:inset 2px 0 0 0 var(--interactive-01)}.resize{position:absolute;top:0;right:0;z-index:1;width:6px;height:100%;cursor:col-resize;touch-action:none}.resize:hover,.resize:active{background:var(--interactive-01)}:host([hidden]){display:none}`;
|
|
83963
85298
|
|
|
83964
|
-
const
|
|
85299
|
+
const XvTableCell = class {
|
|
83965
85300
|
constructor(hostRef) {
|
|
83966
85301
|
registerInstance(this, hostRef);
|
|
83967
|
-
this.
|
|
83968
|
-
this.
|
|
83969
|
-
|
|
83970
|
-
|
|
83971
|
-
|
|
85302
|
+
/** Column this cell belongs to. Identifies it for sorting, resizing and the stored layout. */
|
|
85303
|
+
this.columnId = '';
|
|
85304
|
+
/** Horizontal alignment of the content. */
|
|
85305
|
+
this.align = 'start';
|
|
85306
|
+
/** How content wider than the column behaves. */
|
|
85307
|
+
this.overflow = 'ellipsis';
|
|
85308
|
+
/** Lines kept before clamping, when `overflow` is `clamp`. */
|
|
85309
|
+
this.clampLines = 2;
|
|
85310
|
+
/** Tooltip shown on hover. Only a cell that sets it pays for the tooltip component. */
|
|
85311
|
+
this.tooltip = '';
|
|
85312
|
+
/** Column width. Read off the header row when the table has no `columns`. Any CSS length. */
|
|
85313
|
+
this.width = '';
|
|
85314
|
+
/** Renders the cell as a column header. Set by the table from the row it sits in. */
|
|
85315
|
+
this.header = false;
|
|
85316
|
+
/** Offers the sort affordance. A header cell only. */
|
|
85317
|
+
this.sortable = false;
|
|
85318
|
+
/** Direction currently sorted by; empty when this column is not the active one. */
|
|
85319
|
+
this.sortDirection = '';
|
|
85320
|
+
/** Lets the column picker hide this column. A header cell only. */
|
|
85321
|
+
this.hideable = false;
|
|
85322
|
+
/** Offers the resize handle. A header cell only. */
|
|
85323
|
+
this.resizable = false;
|
|
85324
|
+
/** Offers the drag grip. A header cell only. */
|
|
85325
|
+
this.reorderable = false;
|
|
85326
|
+
/** Accessible name of the drag grip. */
|
|
85327
|
+
this.reorderLabel = 'Drag to reorder';
|
|
83972
85328
|
}
|
|
83973
|
-
|
|
83974
|
-
|
|
85329
|
+
get ariaSort() {
|
|
85330
|
+
if (!this.header || !this.sortable)
|
|
85331
|
+
return null;
|
|
85332
|
+
if (this.sortDirection === XV_SORT_DIR.ASC)
|
|
85333
|
+
return 'ascending';
|
|
85334
|
+
if (this.sortDirection === XV_SORT_DIR.DESC)
|
|
85335
|
+
return 'descending';
|
|
85336
|
+
return 'none';
|
|
83975
85337
|
}
|
|
83976
|
-
|
|
83977
|
-
|
|
85338
|
+
render() {
|
|
85339
|
+
const content = (h("div", { key: 'eefd1609b456cdcc9e802c27e524613b64a9ce39', class: "content", part: "content", style: this.overflow === 'clamp' ? { '--xv-table-cell-clamp': `${this.clampLines}` } : undefined }, h("slot", { key: 'a00460b7e2fbf775c7607af68b078a4fcff70c11' })));
|
|
85340
|
+
return (h(Host, { key: '54976b9c9740d576bb4a81a15af65aa79a2f0888', role: this.header ? 'columnheader' : 'cell', part: "cell", "aria-sort": this.ariaSort, tabindex: this.header && this.sortable ? 0 : null }, this.header && this.reorderable && h("span", { key: 'f443393d1ea62a0c94bfa59b77c377bf5fc04a66', class: "grip", part: "grip", "aria-label": this.reorderLabel }), this.tooltip ? (
|
|
85341
|
+
// Popper puts the panel on document.body, so the scroll container cannot clip it.
|
|
85342
|
+
h("xv-tooltip-v2", { part: "tooltip", dashed: true, position: "top-start", message: this.tooltip }, content)) : (content), this.header && this.sortable && h("span", { key: 'c26fa895c0a9a17cbe6c33c68f9e14b05781554e', class: "sort", "aria-hidden": "true" }), this.header && this.resizable && h("span", { key: '37fa59799c363ed83f2dd0052b3203aa3bf01a6c', class: "resize", part: "resize", "aria-hidden": "true" })));
|
|
83978
85343
|
}
|
|
83979
85344
|
get el() { return getElement(this); }
|
|
83980
85345
|
};
|
|
83981
|
-
|
|
85346
|
+
XvTableCell.style = xvTableCellCss();
|
|
83982
85347
|
|
|
83983
|
-
const xvTableRowCss = () => `:host{
|
|
85348
|
+
const xvTableRowCss = () => `:host{--xv-table-row-bg:var(--layer-02);--xv-table-row-height:var(--xv-table-height, 40px);--xv-table-row-disabled-opacity:0.5;grid-column:1/-1;display:grid;grid-template-columns:subgrid;align-items:stretch;min-height:var(--xv-table-row-height);background:var(--xv-table-row-bg);box-shadow:inset 0 -1px 0 0 var(--border-subtle-00)}@supports not (grid-template-columns: subgrid){:host{display:contents}}:host([hover]:not([disabled]):hover){--xv-table-row-bg:var(--layer-hover-01)}:host([selected]){--xv-table-row-bg:var(--layer-selected-01)}:host([selected][hover]:hover){--xv-table-row-bg:var(--layer-selected-hover-01)}:host([row-reorderable][draggable=true]){cursor:grab}:host(.is-dragging){opacity:0.4}:host(.drop-above){box-shadow:inset 0 2px 0 0 var(--interactive-01)}:host(.drop-below){box-shadow:inset 0 -2px 0 0 var(--interactive-01)}:host([group]){--xv-table-row-bg:var(--layer-accent-01);font-weight:600}:host(.has-children){--xv-table-row-bg:var(--layer-accent-01)}:host(.has-children[hover]:hover){--xv-table-row-bg:var(--layer-accent-hover-01)}:host([header]){--xv-table-row-bg:var(--xv-table-header-bg, var(--layer-accent-01));box-shadow:inset 0 -1px 0 0 var(--border-subtle-01);font-weight:600}:host([disabled]:not([header])){cursor:not-allowed;color:var(--text-disabled);pointer-events:none;opacity:var(--xv-table-row-disabled-opacity)}.control{display:flex;align-items:center;justify-content:center;padding:0 var(--spacing-03)}.control--grip{order:-3}.control--expand{order:-2}.control--lead{order:-1}.control_grip{width:8px;height:14px;opacity:0.4;cursor:grab;background-image:radial-gradient(currentColor 1px, transparent 1px);background-size:4px 4px}.control_grip:active{cursor:grabbing}.control_expand{width:24px;height:24px;padding:0;border:0;background:none;color:var(--icon-primary);cursor:pointer}.control_expand::before{content:"";display:block;width:8px;height:8px;margin:0 auto;border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:rotate(45deg) translate(-2px, -2px);transition:transform 0.15s ease}.control_expand.open::before{transform:rotate(-135deg) translate(-2px, -2px)}.control_expand:disabled{color:var(--icon-disabled);cursor:not-allowed}.control_expand:focus-visible{outline:2px solid var(--focus);outline-offset:0}.control_expand:focus-visible{outline-offset:-2px}.expand{order:10000;grid-column:1/-1;padding:var(--spacing-05);background:var(--layer-01);box-shadow:inset 0 1px 0 0 var(--border-subtle-00)}.expand[hidden]{display:none}:host([hidden]){display:none}`;
|
|
83984
85349
|
|
|
83985
85350
|
const XvTableRow = class {
|
|
83986
85351
|
constructor(hostRef) {
|
|
83987
85352
|
registerInstance(this, hostRef);
|
|
83988
|
-
|
|
83989
|
-
this.
|
|
83990
|
-
|
|
83991
|
-
|
|
83992
|
-
|
|
83993
|
-
|
|
83994
|
-
|
|
83995
|
-
|
|
83996
|
-
|
|
83997
|
-
|
|
83998
|
-
|
|
83999
|
-
|
|
84000
|
-
|
|
84001
|
-
|
|
84002
|
-
|
|
84003
|
-
|
|
85353
|
+
/** Identifies the row in selection and expansion payloads. */
|
|
85354
|
+
this.value = '';
|
|
85355
|
+
/** Selection control rendered in the leading cell. Set by the table. */
|
|
85356
|
+
this.selectionMode = 'none';
|
|
85357
|
+
/** Whether the row can be expanded. Set by the table. */
|
|
85358
|
+
this.expandMode = 'none';
|
|
85359
|
+
/** Whether the row offers its selection control. A header with no rows under it has nothing to pick. */
|
|
85360
|
+
this.selectable = true;
|
|
85361
|
+
/** Row height ladder. Set by the table. */
|
|
85362
|
+
this.size = SIZE_VAR.MD;
|
|
85363
|
+
/** Whether the row is selected. */
|
|
85364
|
+
this.selected = false;
|
|
85365
|
+
/** Indeterminate state of the header row's select-all checkbox. */
|
|
85366
|
+
this.partial = false;
|
|
85367
|
+
/** Whether the row's expand panel is open. */
|
|
85368
|
+
this.expanded = false;
|
|
85369
|
+
/**
|
|
85370
|
+
* Value of the row this one belongs to. Child rows are siblings in the same grid, so they keep
|
|
85371
|
+
* the table's columns instead of living in a panel of their own.
|
|
85372
|
+
*/
|
|
85373
|
+
// Not reflected: an empty default would put parent="" on every row and break [parent] selectors.
|
|
85374
|
+
this.parent = '';
|
|
85375
|
+
/** Whether this row has anything to expand. Set by the table. */
|
|
85376
|
+
this.expandable = false;
|
|
85377
|
+
/** Whether the row carries `slot="expand"` content. Set by the table. */
|
|
85378
|
+
this.hasPanel = false;
|
|
85379
|
+
/** Renders the row as a subtotal or grouping row: no controls, accented background. */
|
|
85380
|
+
this.group = false;
|
|
85381
|
+
/** Marks the row as the table's header. Its cells supply the column labels. */
|
|
85382
|
+
this.header = false;
|
|
85383
|
+
/** Highlights the row on pointer hover. Set by the table. */
|
|
85384
|
+
this.hover = false;
|
|
85385
|
+
/** Blocks selection and expansion. */
|
|
85386
|
+
this.disabled = false;
|
|
85387
|
+
/** Whether this row can be dragged into a new position. Set by the table. */
|
|
85388
|
+
this.rowReorderable = false;
|
|
85389
|
+
/** Whether the whole row drags, or only its grip. Set by the table. */
|
|
85390
|
+
this.rowReorderHandle = 'icon';
|
|
85391
|
+
/** Accessible name of the expand toggle. Set by the table. */
|
|
85392
|
+
this.expandLabel = 'Toggle row';
|
|
85393
|
+
/** Accessible name of the drag grip. Set by the table. */
|
|
85394
|
+
this.reorderLabel = 'Drag to reorder';
|
|
84004
85395
|
}
|
|
84005
|
-
|
|
84006
|
-
|
|
84007
|
-
|
|
84008
|
-
this.
|
|
84009
|
-
name: this.name,
|
|
84010
|
-
value: this.value,
|
|
84011
|
-
checked: this.checked,
|
|
84012
|
-
partial: this.partial,
|
|
84013
|
-
header: this.header,
|
|
84014
|
-
expandable: this.el.getAttribute('slot') === XV_EXPANDABLE_KEY,
|
|
84015
|
-
});
|
|
85396
|
+
// `draggable` is an enumerated attribute, not a boolean one: rendered as `draggable=""` it reads
|
|
85397
|
+
// as `auto`, which never drags. The property reflects the string the browser expects.
|
|
85398
|
+
componentDidRender() {
|
|
85399
|
+
this.el.draggable = this.dragsWholeRow;
|
|
84016
85400
|
}
|
|
84017
|
-
|
|
84018
|
-
|
|
84019
|
-
|
|
84020
|
-
|
|
84021
|
-
|
|
84022
|
-
|
|
84023
|
-
|
|
84024
|
-
setAttr(this.el.closest(XV_TABLE_TAG), `variant-${this.variant}`, !!this.variant);
|
|
84025
|
-
}
|
|
84026
|
-
}
|
|
85401
|
+
get dragsWholeRow() {
|
|
85402
|
+
return (this.rowReorderable &&
|
|
85403
|
+
this.rowReorderHandle === 'row' &&
|
|
85404
|
+
!this.group &&
|
|
85405
|
+
!this.header &&
|
|
85406
|
+
!this.disabled &&
|
|
85407
|
+
this.el.slot !== 'footer');
|
|
84027
85408
|
}
|
|
84028
85409
|
render() {
|
|
84029
|
-
|
|
84030
|
-
|
|
84031
|
-
|
|
84032
|
-
|
|
85410
|
+
// Empty spacers, or a group row's cells slide into the control tracks.
|
|
85411
|
+
const hasSelect = this.selectionMode !== 'none';
|
|
85412
|
+
const hasExpand = this.expandMode !== 'none';
|
|
85413
|
+
// A header keeps the control cells as spacers, like a group row: it has nothing to expand or drag.
|
|
85414
|
+
const expandable = hasExpand && !this.group && !this.header && this.expandable;
|
|
85415
|
+
const draggable = this.rowReorderable && !this.group && !this.header && !this.disabled && this.el.slot !== 'footer';
|
|
85416
|
+
// An empty panel would still paint its padding and background, so it is not rendered at all.
|
|
85417
|
+
const panel = expandable && this.hasPanel;
|
|
85418
|
+
return (h(Host, { key: 'ff2940779a1781b9a953629e4c8bf9a7431105fb', role: "row", part: "row" }, this.rowReorderable && (h("div", { key: 'd37b95aa6e56d073f1a9183be0475835b991f9d9', class: "control control--grip", part: "control", role: "cell" }, draggable && this.rowReorderHandle === 'icon' && (h("span", { key: '806316bd3cfb4340069418b3a43791073800d8fd', class: "control_grip", part: "grip", ref: element => element && (element.draggable = true), "aria-label": this.reorderLabel })))), hasExpand && (h("div", { key: 'e8455932d6147a965a27fbe2543ceeece4a65be8', class: "control control--expand", part: "control", role: "cell" }, expandable && (h("button", { key: 'eff064a985e9e6e44f122a42658f36ebd4f8d443', type: "button", class: { control_expand: true, open: this.expanded }, part: "expand-button", disabled: this.disabled, "aria-expanded": String(this.expanded), "aria-label": this.expandLabel })))), hasSelect && (h("div", { key: '97ffdebfe4ef650aa45020ff54449db83f252f68', class: "control control--lead", part: "control", role: "cell" }, !this.group &&
|
|
85419
|
+
this.selectable &&
|
|
85420
|
+
(this.selectionMode === 'multiple' ? (h("xv-checkbox-v2", { class: "control_input", checked: this.selected || this.partial, partial: this.partial, disabled: this.disabled, size: this.size })) : (h("xv-radio-v2", { class: "control_input", checked: this.selected, disabled: this.disabled, size: this.size }))))), h("slot", { key: '77414059aab52c6b11fe4b3571742eb9f4781fa8' }), panel && (h("div", { key: 'df45265616deac76f9bdb571def33be0a917bb01', class: "expand", part: "expand-panel", role: "cell", hidden: !this.expanded }, h("slot", { key: '986cbf15abb19462e98b4650ac707d0c79be54f4', name: "expand" })))));
|
|
84033
85421
|
}
|
|
84034
85422
|
get el() { return getElement(this); }
|
|
84035
|
-
static get watchers() { return {
|
|
84036
|
-
"checked": [{
|
|
84037
|
-
"checkedChangeHandle": 0
|
|
84038
|
-
}]
|
|
84039
|
-
}; }
|
|
84040
85423
|
};
|
|
84041
85424
|
XvTableRow.style = xvTableRowCss();
|
|
84042
85425
|
|
|
@@ -84393,12 +85776,12 @@ const XvTagCombobox = class {
|
|
|
84393
85776
|
const ariaOwns = suggestionsVisible ? `${this.uid}-listbox` : undefined;
|
|
84394
85777
|
const activedesc = this.highlighted >= 0 ? this.optionId(this.highlighted) : undefined;
|
|
84395
85778
|
const message = resolveFieldMessage({ error: this.error, warning: this.warning, helper: this.helper });
|
|
84396
|
-
return (h(Host, { key: '
|
|
85779
|
+
return (h(Host, { key: '5351ddba9ec53411d14582d3e4c013000f560540', class: "xv-combobox", part: "root", size: this.size }, this.label && h("label", { key: '9072c85cbd926b16e08827dacccd4d7f0a86d411', class: "label" }, this.label), h("div", { key: 'd63f9438b385fc05b53f29be87d5e1cf77a02f88', class: {
|
|
84397
85780
|
'control': true,
|
|
84398
85781
|
'control--disabled': this.disabled,
|
|
84399
85782
|
'control--error': !!this.error,
|
|
84400
85783
|
'control--readonly': !!this.readonly,
|
|
84401
|
-
}, onClick: () => this.blockClick() }, h("div", { key: '
|
|
85784
|
+
}, onClick: () => this.blockClick() }, h("div", { key: 'e303fef8789d9f1df8a9febe667f8fa0d72f4aaa', class: "control-chips", role: "list" }, this.selected.map((s, i) => (h("xv-tag-v2", { role: "listitem", part: "chip", "data-value": s.value, size: this.COMPARE_TAG_SIZE[this.size], disabled: this.disabled, bg: (s === null || s === void 0 ? void 0 : s.bg) || 'var(--layer-accent-01, #F7F7F7)', color: (s === null || s === void 0 ? void 0 : s.color) || 'var(--text-primary, #333)', closeable: !this.readonly, onCloseClick: ({ detail }) => this.removeTag(i, detail) }, s.label))), h("input", { key: '08ec28c65696a36238aa4f2c7f9ba2a89c34e31c', ref: (el) => (this.inputEl = el), class: "control-input", readonly: this.readonly, placeholder: this.selected.length ? '' : this.placeholder, value: this.inputValue, onInput: (e) => this.onInput(e), onKeyDown: (e) => this.onKeyDown(e), onFocus: () => { this.onOpen(); this.recomputeFiltered(); }, "aria-autocomplete": "list", "aria-expanded": this.open ? 'true' : 'false', "aria-controls": ariaOwns, "aria-activedescendant": activedesc, disabled: this.disabled })), this.loading && (h("span", { key: '434666b2391399635cfe9c18320e4e10c0b67abf', class: "control-loader", part: "loader", "aria-hidden": "true" }, h("xv-loader-v2", { key: '66ffdb3f446ee255495d05c9a456a868b208c52a', size: "sm", variant: "horizontal" })))), message && (h("p", { key: '47f10c7a1e7a0eb5f9cfef0a303a667278833673', class: { message: true, [message.level]: true } }, message.text)), suggestionsVisible && (h("ul", { key: 'cba3064999cd0fa1159bb1a5b0967633de6d2e6f', id: `${this.uid}-listbox`, class: "suggestions", role: "listbox", part: "listbox" }, this.filtered.map((opt, idx) => (h("li", { id: this.optionId(idx), class: { 'suggestions-opt': true, 'suggestions-opt--highlight': idx === this.highlighted }, role: "option", "aria-selected": idx === this.highlighted, onMouseEnter: () => this.onOptionMouseEnter(idx), onMouseDown: (ev) => ev.preventDefault(), onClick: () => this.selectOption(opt) }, h("div", { class: "suggestions-opt-content" }, opt.bg ? h("span", { class: "suggestions-opt-content--color", style: { background: opt.bg } }) : null, h("span", { class: "suggestions-opt-content--label" }, this.highlightLabel(opt.label).map((seg, i) => typeof seg === 'string' ? h("span", { key: i }, seg) : h("strong", { key: i }, seg.match)))))))))));
|
|
84402
85785
|
}
|
|
84403
85786
|
get host() { return getElement(this); }
|
|
84404
85787
|
static get watchers() { return {
|
|
@@ -84430,7 +85813,7 @@ const XvTag = class {
|
|
|
84430
85813
|
this.closeClick.emit(e);
|
|
84431
85814
|
}
|
|
84432
85815
|
render() {
|
|
84433
|
-
return (h(Host, { key: '
|
|
85816
|
+
return (h(Host, { key: '138d2cd5c76589ffd98054c7af17905921725aab', style: { color: this.color, background: this.bg }, class: `xv-tag ${this.disabled ? 'disabled' : ''} ${this.size}` }, h("div", { key: 'd3fe0db007cf464d64a63ed907c60dc0fd61c19c', class: "xv-tag_content", part: "details-content" }, h("slot", { key: 'caaebab8bce651040ac5c3291ffa2668b04cac56' })), this.closeable && (h("button", { key: 'ab6790f6b80906dcf28aee7fc739e375ae774df4', onClick: this.closeHandler.bind(this), class: "xv-tag_close" }))));
|
|
84434
85817
|
}
|
|
84435
85818
|
};
|
|
84436
85819
|
XvTag.style = xvTagCss();
|
|
@@ -84470,13 +85853,13 @@ const XvTextInput = class {
|
|
|
84470
85853
|
}
|
|
84471
85854
|
render() {
|
|
84472
85855
|
const message = resolveFieldMessage({ error: this.error, warning: this.warning, helper: this.helper });
|
|
84473
|
-
return (h(Host, { key: '
|
|
85856
|
+
return (h(Host, { key: '9aec75a885d16f416708047095897ac987b9e1ec', class: { disabled: !!this.disabled } }, h("label", { key: '4d6934a4208df6e858277366e7a74da9ec7c0ed3', class: "control" }, this.label && h("span", { key: '57c1974e09512b744aecc18dacfe7cae0bac6921', class: "control_label" }, this.label), h("div", { key: '5b0dd4d878da6e8bfc05a0f704954081e9b8058d', class: {
|
|
84474
85857
|
'control_input': true,
|
|
84475
85858
|
readonly: !!this.readonly,
|
|
84476
85859
|
[this.size]: true,
|
|
84477
85860
|
error: !!this.error,
|
|
84478
85861
|
warning: !!this.warning,
|
|
84479
|
-
} }, h("input", { key: '
|
|
85862
|
+
} }, h("input", { key: '0a5d8923bbcf54a551618557037a96b2e3c2166f', autocomplete: this.autocomplete, type: (this.type === 'password' && this.isPasswordVisible && 'text') || this.type, placeholder: this.placeholder, disabled: this.disabled, readonly: this.readonly, onInput: this.handleInput, name: this.name, value: this.value }), h("div", { key: 'a627fa606172a1e8d198b8dc8daadc280d39cfa2', class: "control_input__icons" }, this.loading && h("xv-loader-v2", { key: 'e2e9bb121daf4aedc173909545b80961db442002', size: SIZE_VAR.XS }), this.clearable && this.value && !this.loading && !this.disabled && !this.readonly && (h("button", { key: '45e514e856569d54bb4c98a8ac78a0aedc70ce37', type: "button", class: "status-icon clear", "aria-label": "Clear", onClick: this.handleClear }, "\u00D7")), !!this.error ? (h("span", { class: "status-icon error", "aria-hidden": "true" }, "!")) : !!this.warning ? (h("span", { class: "status-icon warning", "aria-hidden": "true" }, "\u26A0")) : null, this.type === 'password' && (h("button", { key: 'f7ae4b875d4a515e79fa1699d0fe3d4aa8b27586', onClick: this.togglePassword, disabled: this.disabled, class: "status-icon" }, h("svg", { key: '08bf622486f686fba2309004145c4c340faf8cd0', xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 512", width: 16, height: 16 }, this.isPasswordVisible ? (h("path", { fill: "currentColor", d: "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zm151 118.3C226 97.7 269.5 80 320 80c65.2 0 118.8 29.6 159.9 67.7C518.4 183.5 545 226 558.6 256c-12.6 28-36.6 66.8-70.9 100.9l-53.8-42.2c9.1-17.6 14.2-37.5 14.2-58.7c0-70.7-57.3-128-128-128c-32.2 0-61.7 11.9-84.2 31.5l-46.1-36.1zM394.9 284.2l-81.5-63.9c4.2-8.5 6.6-18.2 6.6-28.3c0-5.5-.7-10.9-2-16c.7 0 1.3 0 2 0c44.2 0 80 35.8 80 80c0 9.9-1.8 19.4-5.1 28.2zm9.4 130.3C378.8 425.4 350.7 432 320 432c-65.2 0-118.8-29.6-159.9-67.7C121.6 328.5 95 286 81.4 256c8.3-18.4 21.5-41.5 39.4-64.8L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5l-41.9-33zM192 256c0 70.7 57.3 128 128 128c13.3 0 26.1-2 38.2-5.8L302 334c-23.5-5.4-43.1-21.2-53.7-42.3l-56.1-44.2c-.2 2.8-.3 5.6-.3 8.5z" })) : (h("path", { fill: "currentColor", d: "M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256c13.6 30 40.2 72.5 78.6 108.3C169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6zM288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80c-.7 0-1.3 0-2 0c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2c0 .7 0 1.3 0 2c0 44.2 35.8 80 80 80zm0-208a128 128 0 1 1 0 256 128 128 0 1 1 0-256z" })))))))), message && (h("p", { key: '2c1d43925fd56c86e47dfd88c4644b030639f81e', class: { message: true, [message.level]: true } }, message.text))));
|
|
84480
85863
|
}
|
|
84481
85864
|
static get formAssociated() { return true; }
|
|
84482
85865
|
};
|
|
@@ -84514,12 +85897,12 @@ const XvTextarea = class {
|
|
|
84514
85897
|
}
|
|
84515
85898
|
render() {
|
|
84516
85899
|
const message = resolveFieldMessage({ error: this.error, warning: this.warning, helper: this.helper });
|
|
84517
|
-
return (h(Host, { key: '
|
|
85900
|
+
return (h(Host, { key: '8f8a6e5f1886e21e52ffc3e006c4d43b1de420eb', class: { disabled: !!this.disabled } }, h("label", { key: '2097cfb9d893772a0aa1e2aa3aeadd5484ebb48e', class: "control" }, (this.label || this.max) && (h("p", { key: '4a5ce1d5ad1d62ba1ab1249b2f15504eafc727af', class: "control_label" }, h("span", { key: 'f8344446dcf38978181473292c6a748d394538f6' }, this.label, this.info && h("xv-tooltip-v2", { key: 'bf23e43f1b7f0ea94ba9cb376c4893ea413ec5df', message: this.info })), this.max !== undefined && !this.counterHide && (h("span", { key: '7b377f47c6b426428fbaee01746415032b75d0b5', class: "control_label__count" }, this.value.length || 0, "/", this.max)))), h("div", { key: 'b7e1937e704f7493544443d159e7b3c1783a1e45', class: {
|
|
84518
85901
|
'control_input': true,
|
|
84519
85902
|
readonly: !!this.readonly,
|
|
84520
85903
|
error: !!this.error,
|
|
84521
85904
|
warning: this.warning !== undefined,
|
|
84522
|
-
} }, h("textarea", { key: '
|
|
85905
|
+
} }, h("textarea", { key: '4c09ca41ec313fca1f2df3e4e941d342d6121b6a', class: { 'no-resize': !!this.noResize }, name: this.name, rows: this.rows, value: this.value, maxLength: this.max, disabled: this.disabled, readOnly: this.readonly, placeholder: this.placeholder, onInput: this.onInput }), h("div", { key: '68dcba186158bf977193f908cf2a129452ba904e', class: "control_input__icons" }, this._renderIcon()))), message && (h("p", { key: '150534971f182c93c131fee2b00eae5cc78e7c30', class: { message: true, [message.level]: true } }, message.text))));
|
|
84523
85906
|
}
|
|
84524
85907
|
_renderIcon() {
|
|
84525
85908
|
if (this.loading)
|
|
@@ -84570,7 +85953,7 @@ const XvTile = class {
|
|
|
84570
85953
|
this.checked = !this.checked;
|
|
84571
85954
|
}
|
|
84572
85955
|
render() {
|
|
84573
|
-
return (h(Host, { key: '
|
|
85956
|
+
return (h(Host, { key: '7a4262c881da376efbba73e6ecdeef845caefa0e', class: "xv-tile--host" }, h("label", { key: '9e3fcc2f59463c39d61352e84f89c6905b8b6754', class: {
|
|
84574
85957
|
[this.el.className]: !!this.el.className,
|
|
84575
85958
|
'xv-tile': true,
|
|
84576
85959
|
[`xv-tile--variant-${this.variant}`]: !!this.variant,
|
|
@@ -84578,7 +85961,7 @@ const XvTile = class {
|
|
|
84578
85961
|
'xv-tile--disabled': !!this.disabled,
|
|
84579
85962
|
'selected': !!this.checked,
|
|
84580
85963
|
'xv-tile--error': !!this.error,
|
|
84581
|
-
} }, h("div", { key: '
|
|
85964
|
+
} }, h("div", { key: 'aacc76f7706cef6b3f7dc642e07f0aa0ed641368', class: "xv-tile_content" }, this.label && h("p", { key: 'c52856112766b1047581570dadd3ca3daa09e191', class: "xv-tile_content__title" }, this.label), h("slot", { key: 'c23faffc735f62a7007ad6ab25caad10278543d8' })), this.variant === 'selectable' && (h("div", { key: 'c9005b66ccb8feea162b43079762f7e2f8a7c5cf', class: "xv-tile_control" }, this.multiple ? (h("input", { type: "checkbox", disabled: this.disabled || this.readonly, readonly: this.readonly, onChange: this.handleChange, name: this.name, value: this.value, checked: this.checked })) : (h("input", { type: "radio", disabled: this.disabled || this.readonly, readonly: this.readonly, onChange: this.handleChange, name: this.name, value: this.value, checked: this.checked })))), (this.variant === 'clickable' || this.variant === 'expandable') && (h("div", { key: '08d6633d4a19ea03c761d18b20f164ae23002479', class: "xv-tile_footer" }, h("button", { key: 'ff242c00e2dadf564d146a02ac944d1bee7c7ec7', class: { 'xv-tile_footer__icon': true, [`icon--${this.variant}`]: true, open: this.checked } }))), h("div", { key: '27350c54f82cf8c78e49c04fc2b2b4fb0e4bbb96', class: { 'xv-tile_expandable': true, open: this.checked } }, h("slot", { key: '85f9a007a422ca5e7c06239d771cc8ede86a4e21', name: "expandable" })))));
|
|
84582
85965
|
}
|
|
84583
85966
|
get el() { return getElement(this); }
|
|
84584
85967
|
};
|
|
@@ -84610,7 +85993,7 @@ const XvToggle = class {
|
|
|
84610
85993
|
};
|
|
84611
85994
|
}
|
|
84612
85995
|
render() {
|
|
84613
|
-
return (h(Host, { key: '
|
|
85996
|
+
return (h(Host, { key: '752b686c9e361b4ca0a0ad48d61072a2c819373c', class: { 'xv-toggle': true, disabled: this.disabled, readonly: !!this.readonly, block: !!this.block } }, this.label && h("span", { key: 'c99e7d648d7886db04fbfaf16bedf40b982f6b72', class: "label" }, this.label), h("label", { key: 'ff15e59d5b7ace403030f997d8b1ddf3640f0bf6', class: "control" }, h("slot", { key: 'bea4d7593d2c7caca6b69e5cc219c1b8dbb55d09', name: "before" }), h("div", { key: '7ad81dc90a00339c8653605cfeb5468377be366b', class: "control_input" }, h("input", { key: 'ffbcaac266859de781476ba06e9e56069fd11ad4', type: "checkbox", readonly: this.readonly, name: this.name, value: this.value, checked: this.checked, disabled: this.disabled || this.readonly, onChange: this.onChange }), h("span", { key: 'd0b1915cd7ab776eb3b573802f5ee73ec417edde', class: "toggle" })), h("slot", { key: '4de504f5a68a747e097fed0260fe55b4dd93de57', name: "after" }))));
|
|
84614
85997
|
}
|
|
84615
85998
|
static get formAssociated() { return true; }
|
|
84616
85999
|
};
|
|
@@ -84687,7 +86070,7 @@ const XvToggleTip = class {
|
|
|
84687
86070
|
}
|
|
84688
86071
|
;
|
|
84689
86072
|
render() {
|
|
84690
|
-
return (h(Host, { key: '
|
|
86073
|
+
return (h(Host, { key: '355065995790b620e5ed8b5d561b2898f787ac15', class: "xv-toggle-tip" }, h("div", { key: 'ff20f44061ee280105d53176e5c508e0845df871', class: { 'trigger': true, 'trigger--block': this.block }, role: "button", tabindex: "0", "aria-expanded": this.open ? 'true' : 'false', "aria-controls": "popover", onClick: () => this.setPopover(!this.open), ref: (el) => (this.triggerEl = el) }, h("slot", { key: 'd407db9a0df2a9f90b628ed79d6c648eed2c2c70', name: "trigger" }, h("svg", { key: 'f82ed966ca4436d8dde8bf5c2b992466f541224f', class: "trigger_icon", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", width: 16, height: 16 }, h("path", { key: '6f5187fbf1560ebd7a3f2e529d3fdd15fa80fea0', fill: "currentColor", d: "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336c-13.3 0-24 10.7-24 24s10.7 24 24 24l80 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-8 0 0-88c0-13.3-10.7-24-24-24l-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l24 0 0 64-24 0zm40-144a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" })))), h("div", { key: '76fc29909a52ce4701d71e3509c4ebe8d1d32ee2', class: { popover: true, autoSize: !!this.autoSize }, role: "tooltip", tabindex: "-1", ref: (el) => (this.popoverEl = el) }, h("div", { key: 'afabe0c85104f8c5e204677b53f5815f314a5039', class: "popover-tip", part: "tip", "data-popper-arrow": "" }), h("div", { key: 'f274e790046bcf6edc8123b2b0bcda895931772c', class: "popover-content" }, h("slot", { key: '8f28653ab605ae2eee5c7027532b024e914a8c13', name: "header" }), h("slot", { key: '1c26b3cb17db7fc9256fd42f7dcddb51eb182db5', name: "body" }), h("slot", { key: '3b537a669336579f2285784f469d4425d0f1cc31', name: "footer" })))));
|
|
84691
86074
|
}
|
|
84692
86075
|
disconnectedCallback() {
|
|
84693
86076
|
this.destroyPopper();
|
|
@@ -84742,14 +86125,14 @@ const XvTooltip = class {
|
|
|
84742
86125
|
this.destroyTooltip();
|
|
84743
86126
|
}
|
|
84744
86127
|
render() {
|
|
84745
|
-
return (h(Host, { key: '
|
|
86128
|
+
return (h(Host, { key: 'a6853dc450f6d063a702a1791297963f1530c003', role: "tooltip", class: {
|
|
84746
86129
|
'xv-tooltip-wrapper': true,
|
|
84747
86130
|
[`xv-tooltip-wrapper__block`]: !!this.block,
|
|
84748
86131
|
[`xv-tooltip-wrapper__dashed`]: !!this.dashed,
|
|
84749
|
-
} }, h("slot", { key: '
|
|
86132
|
+
} }, h("slot", { key: 'db5ea6da812b85930e8c74dc2ceaf59f8e6197b1' }, h("svg", { key: '7ac24beb22b912f77ec3535309019833f28fd375', xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", width: 16, height: 16 }, h("path", { key: 'b86e5339a9af99e6011fceea6d8b77e89dcd0e19', fill: "currentColor", d: "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336c-13.3 0-24 10.7-24 24s10.7 24 24 24l80 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-8 0 0-88c0-13.3-10.7-24-24-24l-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l24 0 0 64-24 0zm40-144a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" })))));
|
|
84750
86133
|
}
|
|
84751
86134
|
get el() { return getElement(this); }
|
|
84752
86135
|
};
|
|
84753
86136
|
XvTooltip.style = xvTooltipCss();
|
|
84754
86137
|
|
|
84755
|
-
export { XvAccordion as xv_accordion_v2, XvAccordionItem as xv_accordion_v2_item, XvBreadcrumbs as xv_breadcrumbs_v2, XvButtonGroup as xv_button_group_v2, XvButton as xv_button_v2, XvCard as xv_card_v2, XvCheckbox as xv_checkbox_v2, XvContentSwitcherItem as xv_content_switcher_item_v2, XvContentSwitcher as xv_content_switcher_v2, XvDataTable as xv_data_table, XvDataTableCell as xv_data_table_cell, XvDataTableCollapse as xv_data_table_collapse, XvDataTableRow as xv_data_table_row, XvDatePicker as xv_date_picker, XvDatepicker as xv_datepicker, XvDropdown as xv_dropdown_v2, XvDropdownItem as xv_dropdown_v2_item, XvFileUploader as xv_file_uploader, Xvfooter as xv_footer, XvGeoMap as xv_geo_map_v2, XvHeader as xv_header, XvImageViewer as xv_image_viewer, XvLink as xv_link_v2, XvLoader as xv_loader_v2, XvLoginModal as xv_login_modal, XvMegaMenu as xv_mega_menu, XvModal as xv_modal_v2, XvNotification as xv_notification_v2, XvNumberInput as xv_number_input_v2, XvOverflowMenu as xv_overflow_menu_v2, XvOverflowMenuItem as xv_overflow_menu_v2_item, XvPagination as xv_pagination, XvProgressIndicator as xv_progress_indicator_v2, XvProgressIndicatorItem as xv_progress_indicator_v2_item, XvRadio as xv_radio_v2, XvSlider as xv_slider_v2, XvTab as xv_tab_v2, XvTable as
|
|
86138
|
+
export { XvAccordion as xv_accordion_v2, XvAccordionItem as xv_accordion_v2_item, XvBreadcrumbs as xv_breadcrumbs_v2, XvButtonGroup as xv_button_group_v2, XvButton as xv_button_v2, XvCard as xv_card_v2, XvCheckbox as xv_checkbox_v2, XvContentSwitcherItem as xv_content_switcher_item_v2, XvContentSwitcher as xv_content_switcher_v2, XvDataTable as xv_data_table, XvDataTableCell as xv_data_table_cell, XvDataTableCollapse as xv_data_table_collapse, XvDataTableRow as xv_data_table_row, XvDatePicker as xv_date_picker, XvDatepicker as xv_datepicker, XvDropdown as xv_dropdown_v2, XvDropdownItem as xv_dropdown_v2_item, XvFileUploader as xv_file_uploader, Xvfooter as xv_footer, XvGeoMap as xv_geo_map_v2, XvHeader as xv_header, XvImageViewer as xv_image_viewer, XvLink as xv_link_v2, XvLoader as xv_loader_v2, XvLoginModal as xv_login_modal, XvMegaMenu as xv_mega_menu, XvModal as xv_modal_v2, XvNotification as xv_notification_v2, XvNumberInput as xv_number_input_v2, XvOverflowMenu as xv_overflow_menu_v2, XvOverflowMenuItem as xv_overflow_menu_v2_item, XvPagination as xv_pagination, XvProgressIndicator as xv_progress_indicator_v2, XvProgressIndicatorItem as xv_progress_indicator_v2_item, XvRadio as xv_radio_v2, XvSlider as xv_slider_v2, XvTab as xv_tab_v2, XvTable as xv_table, XvTableCell as xv_table_cell, XvTableRow as xv_table_row, XvTabs as xv_tabs_v2, XvTagCombobox as xv_tag_combobox, XvTag as xv_tag_v2, XvTextInput as xv_text_input_v2, XvTextarea as xv_textarea, XvTile as xv_tile, XvToggle as xv_toggle, XvToggleTip as xv_toggle_tip, XvTooltip as xv_tooltip_v2 };
|