UNPKG

@3mo/data-grid

Version:
208 lines (199 loc) 6.72 kB
import { __decorate } from "tslib"; import { component, Component, css, html, property, event, style, live, queryAll } from '@a11d/lit'; import { observeResize } from '@3mo/resize-observer'; import { Localizer } from '@3mo/localization'; import { DataGridSelectability, DataGridSidePanelTab } from './index.js'; Localizer.dictionaries.add('en', { 'Actions for ${count:pluralityNumber} selected entries': [ 'Actions for the selected entry', 'Actions for ${count} selected entries', ], }); Localizer.dictionaries.add('de', { 'Actions for ${count:pluralityNumber} selected entries': [ 'Optionen für den ausgewählten Eintrag', 'Optionen für ${count} ausgewählte Einträge', ], }); let DataGridHeader = class DataGridHeader extends Component { constructor() { super(...arguments); this.overlayOpen = false; this.handleDataGridDataChange = () => { this.requestUpdate(); }; this.handleSelectionChange = (e) => { const previousSelection = this.selection; const selection = e.detail; if (previousSelection === 'indeterminate' || selection === false) { this.dataGrid.deselectAll(); } else { this.dataGrid.selectAll(); } }; } connected() { this.dataGrid.dataChange.subscribe(this.handleDataGridDataChange); } disconnected() { this.dataGrid.dataChange.unsubscribe(this.handleDataGridDataChange); } updated(...parameters) { super.updated(...parameters); this.columnHeaders.forEach(h => h.requestUpdate()); } static get styles() { return css ` :host { --mo-data-grid-header-separator-height: 15px; --mo-data-grid-header-separator-width: 2px; display: grid; grid-template-columns: subgrid; position: sticky; grid-column: -1 / 1; background: var(--mo-data-grid-header-background, var(--mo-data-grid-sticky-part-color)); top: 0; z-index: 4; font-size: small; border-block: var(--mo-data-grid-border); height: var(--mo-data-grid-header-height); } .details, .selection, .actions, .context-menu { position: sticky; background: var(--mo-data-grid-sticky-part-color); z-index: 5; } .details { inset-inline-start: 0px; } .selection { inset-inline-start: 0px; } .actions, .context-menu { cursor: pointer; inset-inline-end: 0px; } .actions { mo-icon-button { color: var(--mo-color-accent); font-size: large; } } .context-menu { background-color: var(--mo-color-accent); mo-icon-button { color: var(--mo-color-on-accent); font-size: 20px; } } `; } get template() { return html ` ${this.detailsExpanderTemplate} ${this.selectionTemplate} ${this.contentTemplate} ${this.fillerTemplate} ${this.actionsTemplate} `; } get detailsExpanderTemplate() { return this.dataGrid.hasDetails === false ? html.nothing : html ` <mo-flex class='details' justifyContent='center' alignItems='center' ${style({ insetInlineStart: '0px' })} ${this.getResizeObserver('detailsColumnWidthInPixels')} > ${!this.dataGrid.hasDetails || !this.dataGrid.multipleDetails ? html.nothing : html ` <mo-icon-button dense icon=${this.dataGrid.allRowDetailsOpen ? 'unfold_less' : 'unfold_more'} @click=${() => this.toggleAllDetails()} ></mo-icon-button> `} </mo-flex> `; } get selectionTemplate() { return !this.dataGrid.hasSelection ? html.nothing : html ` <mo-flex class='selection' justifyContent='center' alignItems='center' ${style({ insetInlineStart: this.dataGrid.hasDetails ? '20px' : '0px' })} ${this.getResizeObserver('selectionColumnWidthInPixels')} > ${this.dataGrid.selectability !== DataGridSelectability.Multiple ? html.nothing : html ` <mo-checkbox .selected=${live(this.selection)} @change=${this.handleSelectionChange}></mo-checkbox> `} </mo-flex> `; } get selection() { switch (this.dataGrid.selectedData.length) { case 0: return false; case this.dataGrid.dataLength: return true; default: return 'indeterminate'; } } get contentTemplate() { return html ` ${this.dataGrid.visibleColumns.map(column => html ` <mo-data-grid-column-header .column=${column}></mo-data-grid-column-header> `)} `; } get fillerTemplate() { return html `<span></span>`; } get actionsTemplate() { if (this.dataGrid.hasContextMenu && this.dataGrid.selectedData.length > 1) { return html ` <mo-flex class='context-menu' alignItems='end' justifyContent='center' ${this.getResizeObserver('actionsColumnWidthInPixels')}> <mo-popover-container> <mo-icon-button dense icon='more_vert' title=${t('Actions for ${count:pluralityNumber} selected entries', { count: this.dataGrid.selectedData.length })}></mo-icon-button> <mo-menu slot='popover'> ${this.dataGrid.contextMenuController.getMenuContentTemplate()} </mo-menu> </mo-popover-container> </mo-flex> `; } if (!this.dataGrid.hasToolbar && !this.dataGrid.sidePanelHidden) { return html ` <mo-flex class='actions' alignItems='end' justifyContent='center' ${this.getResizeObserver('actionsColumnWidthInPixels')}> <mo-icon-button dense icon='settings' @click=${() => this.dataGrid.navigateToSidePanelTab(this.dataGrid.sidePanelTab ? undefined : DataGridSidePanelTab.Settings)} ></mo-icon-button> </mo-flex> `; } return html.nothing; } getResizeObserver(property) { // @ts-expect-error Readonly property set here return observeResize(([entry]) => this.dataGrid.columnsController[property] = entry?.contentRect.width ?? 0); } toggleAllDetails() { this.dataGrid.toggleRowDetails(); this.requestUpdate(); } }; __decorate([ event() ], DataGridHeader.prototype, "pageChange", void 0); __decorate([ event() ], DataGridHeader.prototype, "modeSelectionChange", void 0); __decorate([ property({ type: Object }) ], DataGridHeader.prototype, "dataGrid", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], DataGridHeader.prototype, "overlayOpen", void 0); __decorate([ queryAll('mo-data-grid-column-header') ], DataGridHeader.prototype, "columnHeaders", void 0); DataGridHeader = __decorate([ component('mo-data-grid-header') ], DataGridHeader); export { DataGridHeader };