UNPKG

@3mo/data-grid

Version:
882 lines (855 loc) 32.9 kB
var DataGrid_1; import { __decorate } from "tslib"; import { property, component, Component, html, css, query, ifDefined, event, style, literal, staticHtml, cache, eventOptions, queryAll, repeat, eventListener } from '@a11d/lit'; import { LocalStorage } from '@a11d/local-storage'; import { InstanceofAttributeController } from '@3mo/instanceof-attribute-controller'; import { SlotController } from '@3mo/slot-controller'; import { tooltip } from '@3mo/tooltip'; import { ThemeController } from '@3mo/theme'; import { observeMutation } from '@3mo/mutation-observer'; import { MediaQueryController } from '@3mo/media-query-observer'; import { Localizer } from '@3mo/localization'; import { DataGridColumnsController } from './DataGridColumnsController.js'; import { DataGridSelectionBehaviorOnDataChange, DataGridSelectionController } from './DataGridSelectionController.js'; import { DataGridSortingController } from './DataGridSortingController.js'; import { DataGridDetailsController } from './DataGridDetailsController.js'; import { DataGridCsvController, DataGridSidePanelTab, DataGridContextMenuController } from './index.js'; import { DataRecord } from './DataRecord.js'; Localizer.dictionaries.add('de', { 'No results': 'Kein Ergebnis', 'More Filters': 'Weitere Filter', }); export var DataGridEditability; (function (DataGridEditability) { DataGridEditability["Never"] = "never"; DataGridEditability["Cell"] = "cell"; DataGridEditability["Always"] = "always"; })(DataGridEditability || (DataGridEditability = {})); /** * @element mo-data-grid * * @attr data - The data to be displayed in the DataGrid. It is an array of objects, where each object represents a row. * @attr columns - The columns to be displayed in the DataGrid. It is an array of objects, where each object represents a column. * @attr headerHidden - Whether the header should be hidden. * @attr preventVerticalContentScroll - Whether the content should be prevented from scrolling vertically. * @attr page - The current page. * @attr pagination - The pagination mode. It can be either `auto` or a number. * @attr sorting - The sorting mode. It is an object with `selector` and `strategy` properties. * @attr selectability - The selection mode. Default to 'single' if context menus available, 'undefined' otherwise. * @attr isDataSelectable - Whether data of a given row is selectable. * @attr selectedData - The selected data. * @attr selectOnClick - Whether the row should be selected on click. * @attr selectionBehaviorOnDataChange - The behavior of the selection when the data changes. * @attr multipleDetails - Whether multiple details can be opened at the same time. * @attr subDataGridDataSelector - The key path of the sub data grid data. * @attr hasDataDetail - Whether the data has a detail. * @attr detailsOnClick - Whether the details should be opened on click. * @attr primaryContextMenuItemOnDoubleClick - The primary context menu item on double click. * @attr editability - The editability mode. * @attr getRowDetailsTemplate - A function which returns a template for the details of a given row. * @attr getRowContextMenuTemplate - A function which returns a template for the context menu of a given row. * @attr sidePanelTab - The side panel tab. * @attr sidePanelHidden - Whether the side panel should be hidden. * @attr hasAlternatingBackground - Whether the rows should have alternating background. * @attr preventFabCollapse - Whether the FAB should be prevented from collapsing. * @attr cellFontSize - The font size of the cells relative to the default font size. Defaults @see DataGrid.cellFontSize 's value which defaults to 0.8. * @attr rowHeight - The height of the rows in pixels. Defaults to @see DataGrid.rowHeight 's value which defaults to 35. * @attr exportable - Whether the DataGrid is exportable. This will show an export button in the footer. * * @slot - Use this slot only for declarative DataGrid APIs e.g. setting ColumnDefinitions via `mo-data-grid-columns` tag. * @slot toolbar - The horizontal bar above DataGrid's contents. * @slot toolbar-action - A slot for action icon-buttons in the toolbar which are displayed on the end. * @slot filter - A vertical bar for elements which filter DataGrid's data. It is opened through an icon-button in the toolbar. * @slot sum - A horizontal bar in the DataGrid's footer for showing sums. Calculated sums are also placed here by default. * @slot settings - A vertical bar for elements which change DataGrid's settings. It is pre-filled with columns' settings and can be opened through an icon-button in the toolbar. * @slot fab - A wrapper at the bottom right edge, floating right above the footer, expecting Floating Action Button to be placed in. * @slot error-no-content - A slot for displaying an error message when no data is available. * * @cssprop --mo-data-grid-min-visible-rows - The minimum number of visible rows. Default to 2.5. * @cssprop --mo-data-grid-footer-background - The background of the footer. * @cssprop --mo-data-grid-cell-padding - The inline padding of the cells. Default to 10px. * @cssprop --mo-data-grid-column-sub-row-indentation - The indentation of the first column in the sub row. Default to 20px. * * @fires dataChange * @fires selectionChange * @fires pageChange * @fires paginationChange * @fires columnsChange * @fires sidePanelOpen * @fires sidePanelClose * @fires sortingChange * @fires rowDetailsOpen * @fires rowDetailsClose * @fires rowClick * @fires rowDoubleClick * @fires rowMiddleClick * @fires cellEdit */ let DataGrid = DataGrid_1 = class DataGrid extends Component { constructor() { super(...arguments); this.data = new Array(); this.columns = new Array(); this.headerHidden = false; this.preventVerticalContentScroll = false; this.page = 1; this.selectedData = new Array(); this.selectOnClick = false; this.selectionBehaviorOnDataChange = DataGridSelectionBehaviorOnDataChange.Reset; this.multipleDetails = false; this.detailsOnClick = false; this.primaryContextMenuItemOnDoubleClick = false; this.editability = DataGridEditability.Never; this.sidePanelHidden = false; this.hasAlternatingBackground = DataGrid_1.hasAlternatingBackground.value; this.preventFabCollapse = false; this.fabSlotCollapsed = false; this.exportable = false; this.cellFontSize = DataGrid_1.cellRelativeFontSize.value; this.rowHeight = DataGrid_1.rowHeight.value; this.slotController = new SlotController(this, async () => { this.hasSums; this.hasFabs; await new Promise(r => requestIdleCallback(r)); this.style.setProperty('--mo-data-grid-fab-slot-width', `${this.renderRoot?.querySelector('slot[name=fab]')?.getBoundingClientRect().width || 75}px`); }); this.instanceofAttributeController = new InstanceofAttributeController(this); this.smallScreenObserverController = new MediaQueryController(this, '(max-width: 768px)'); this.themeController = new ThemeController(this); this.columnsController = new DataGridColumnsController(this); this.selectionController = new DataGridSelectionController(this); this.sortingController = new DataGridSortingController(this); this.contextMenuController = new DataGridContextMenuController(this); this.detailsController = new DataGridDetailsController(this); this.csvController = new DataGridCsvController(this); this.splitterResizerTemplate = html ` <mo-splitter-resizer-line style='--mo-splitter-resizer-line-thickness: 1px; --mo-splitter-resizer-line-idle-background: var(--mo-color-transparent-gray-3); --mo-splitter-resizer-line-horizontal-transform: scaleX(5);'></mo-splitter-resizer-line> `; this.lastScrollElementTop = 0; } setPage(page) { this.page = page; this.pageChange.dispatch(page); } setPagination(pagination) { this.pagination = pagination; this.paginationChange.dispatch(pagination); } setData(data, selectionBehavior = this.selectionBehaviorOnDataChange) { this.data = data; this.selectionController.handleDataChange(selectionBehavior); this.dataChange.dispatch(data); } get hasSelection() { return this.selectionController.hasSelection; } selectAll(...parameters) { return this.selectionController.selectAll(...parameters); } deselectAll(...parameters) { return this.selectionController.deselectAll(...parameters); } select(...parameters) { return this.selectionController.select(...parameters); } isSelectable(...parameters) { return this.selectionController.isSelectable(...parameters); } get hasDetails() { return this.detailsController.hasDetails; } get allRowDetailsOpen() { return this.detailsController.areAllOpen; } openRowDetails(...parameters) { return this.detailsController.openAll(...parameters); } closeRowDetails(...parameters) { return this.detailsController.closeAll(...parameters); } toggleRowDetails(...parameters) { return this.detailsController.toggleAll(...parameters); } getSorting(...parameters) { return this.sortingController.get(...parameters); } sort(...parameters) { return this.sortingController.set(...parameters); } unsort(...parameters) { return this.sortingController.reset(...parameters); } setColumns(...parameters) { return this.columnsController.setColumns(...parameters); } extractColumns(...parameters) { return this.columnsController.extractColumns(...parameters); } generateCsv(...parameters) { return this.csvController.generateCsv(...parameters); } get extractedColumns() { return this.columnsController.extractedColumns; } extractedColumnsUpdated(extractedColumns) { this.setColumns(extractedColumns); } get visibleColumns() { return this.columnsController.visibleColumns; } getRow(data) { return this.rows.find(r => r.data === data); } getCell(data, column) { const row = this.getRow(data); return row?.getCell(column); } handleEdit(data, column, value) { const row = this.getRow(data); const cell = row?.getCell(column); if (row && cell && value !== undefined && column.dataSelector && cell.value !== value) { row.requestUpdate(); KeyPath.set(row.data, column.dataSelector, value); this.cellEdit.dispatch(cell); } } navigateToSidePanelTab(tab) { this.sidePanelTab = tab; !tab ? this.sidePanelClose.dispatch() : this.sidePanelOpen.dispatch(tab); } get hasContextMenu() { return this.contextMenuController.hasContextMenu; } get toolbarElements() { return this.slotController.getAssignedElements('toolbar'); } get hasToolbar() { return this.toolbarDefaultTemplate !== html.nothing || this.toolbarElements.length > 0; } get filterElements() { return this.slotController.getAssignedElements('filter'); } get hasFilters() { return this.filtersDefaultTemplate !== html.nothing || this.filterElements.length > 0; } get hasSums() { const hasSums = !!this.columns.find(c => c.sumHeading) || !!this.querySelector('* [slot="sum"]') || !!this.renderRoot?.querySelector('slot[name="sum"] > *'); this.toggleAttribute('hasSums', hasSums); return hasSums; } get hasFabs() { const hasFabs = !!this.querySelector('* [slot=fab]') || !!this.renderRoot?.querySelector('#fab *:not(slot[name=fab])'); this.toggleAttribute('hasFabs', hasFabs); return hasFabs; } get hasPagination() { return this.pagination !== undefined; } get supportsDynamicPageSize() { return this.hasPagination; } get pageSize() { const dynamicPageSize = (pageSize) => this.supportsDynamicPageSize ? pageSize : DataGrid_1.pageSize.value; if (!this.pagination) { return dynamicPageSize(this.data.length); } if (this.pagination === 'auto') { const rowsHeight = (this.scroller?.clientHeight ?? 0) - (this.header?.clientHeight ?? 0); const rowHeight = this.rowHeight; const pageSize = Math.floor(rowsHeight / rowHeight) || 1; return dynamicPageSize(pageSize); } return this.pagination; } get hasFooter() { const value = this.hasPagination || this.hasSums || this.exportable; this.toggleAttribute('hasFooter', value); return value; } get dataLength() { return this.dataRecords.length; } get maxPage() { return this.dataLength === undefined ? undefined : Math.max(Math.ceil(this.dataLength / this.pageSize), 1); } get hasNextPage() { return this.page !== this.maxPage; } updated(...parameters) { this.header?.requestUpdate(); this.sidePanel?.requestUpdate(); this.footer?.requestUpdate(); this.rows.forEach(row => row.requestUpdate()); // @ts-expect-error rowIntersectionObserver is initialized once here this.rowIntersectionObserver ?? (this.rowIntersectionObserver = new IntersectionObserver(entries => { entries.forEach(({ target, isIntersecting }) => { target.isIntersecting = isIntersecting; }); }, { root: this.scroller, rootMargin: '400px 0px' })); this.navigateToLastValidPageIfNeeded(); return super.updated(...parameters); } navigateToLastValidPageIfNeeded() { if (this.maxPage && this.page > this.maxPage) { this.setPage(this.maxPage); } } firstUpdated(props) { super.firstUpdated(props); this.cellEdit.subscribe(() => this.requestUpdate()); this.setPage(1); } static get styles() { return css ` :host { --mo-data-grid-column-details-width: 20px; --mo-data-grid-column-selection-width: 40px; --mo-data-grid-column-actions-width: 28px; --mo-data-grid-cell-padding: 10px; --mo-data-grid-header-height: 32px; --mo-data-grid-footer-min-height: 40px; --mo-data-grid-toolbar-padding: 0px 14px 14px 14px; --mo-data-grid-border: 1px solid var(--mo-color-transparent-gray-3); --mo-details-data-grid-start-margin: 26px; --mo-data-grid-sticky-part-color: var(--mo-color-surface); --mo-data-grid-alternating-background: color-mix(in srgb, black var(--mo-data-grid-alternating-background-transparency), transparent 0%); --mo-data-grid-selection-background: color-mix(in srgb, var(--mo-color-accent), transparent 50%); --_content-min-height-default: calc(var(--mo-data-grid-min-visible-rows, 2.5) * var(--mo-data-grid-row-height) + var(--mo-data-grid-header-height)); display: flex; flex-direction: column; height: 100%; overflow-x: hidden; } :not(:has([mo-data-grid-row])) { --_content-min-height-default: 150px; } :host([data-theme=light]) { --mo-data-grid-alternating-background-transparency : 5%; } :host([data-theme=dark]) { --mo-data-grid-alternating-background-transparency: 20%; } :host([preventVerticalContentScroll]) mo-scroller { overflow-y: hidden; &::part(container) { position: relative; } } #content { width: fit-content; min-width: 100%; height: min-content; min-height: 100%; } #toolbar { position: relative; padding: var(--mo-data-grid-toolbar-padding); #actions { margin-inline-start: auto; mo-icon-button, ::slotted(mo-icon-button[slot='toolbar-action']) { color: var(--mo-color-gray); &[data-selected] { color: var(--mo-color-accent); } } } } #fab { position: absolute; inset-inline-end: 16px; transition: var(--mo-data-grid-fab-transition, 250ms); z-index: 3; top: -64px; } :host([hasFooter]) #fab { top: -28px; } :host([fabSlotCollapsed][hasFabs]) #fab { transform: scale(0); opacity: 0; } mo-data-grid-footer { transition: var(--mo-data-grid-fab-transition, 250ms); } :host([hasSums][hasFabs]:not([fabSlotCollapsed])) mo-data-grid-footer { --mo-data-grid-footer-trailing-padding: calc(var(--mo-data-grid-fab-slot-width, 56px) + 16px); } slot[name=fab] { display: block; z-index: 1; } mo-empty-state, ::slotted(mo-empty-state) { height: calc(100% - var(--mo-data-grid-header-height) / 2); margin-block-start: calc(var(--mo-data-grid-header-height) / 2); position: absolute; inset: 0; } #overlayModeContainer { position: relative; height: 100%; width: 100%; mo-data-grid-side-panel { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 5; background-color: var(--mo-color-surface); } } `; } get template() { return html ` <slot name='column' hidden ${observeMutation(() => this.requestUpdate())}>${this.columnsTemplate}</slot> ${this.toolbarTemplate} ${this.smallScreenObserverController.matches ? this.overlayModeTemplate : this.splitterModeTemplate} `; } get splitterModeTemplate() { return html ` <mo-splitter direction='horizontal-reversed' ${style({ height: '100%' })} .resizerTemplate=${this.splitterResizerTemplate}> ${cache(this.sidePanelTab === undefined ? html.nothing : html ` <mo-splitter-item size='min(25%, 300px)' min='max(15%, 250px)' max='clamp(100px, 50%, 750px)'> ${this.sidePanelTemplate} </mo-splitter-item> `)} <mo-splitter-item min='0px' ${style({ position: 'relative' })}> ${this.dataGridTemplate} </mo-splitter-item> </mo-splitter> `; } get overlayModeTemplate() { return html ` <mo-flex id='overlayModeContainer'> ${this.dataGridTemplate} ${this.sidePanelTab === undefined ? html.nothing : this.sidePanelTemplate} </mo-flex> `; } get sidePanelTemplate() { return html ` <mo-data-grid-side-panel .dataGrid=${this} tab=${ifDefined(this.sidePanelTab)} > <slot slot='settings' name='settings'>${this.settingsDefaultTemplate}</slot> <slot slot='filter' name='filter'>${this.filtersDefaultTemplate}</slot> </mo-data-grid-side-panel> `; } get settingsDefaultTemplate() { return html.nothing; } get filtersDefaultTemplate() { return html.nothing; } get columnsTemplate() { return html.nothing; } get rowElementTag() { return DataGrid_1.defaultRowElementTag; } get hasDefaultRowElements() { return this.rowElementTag === DataGrid_1.defaultRowElementTag; } get fabTemplate() { // These also update the respective attributes for now this.hasSums; this.hasFabs; return html ` <slot name='fab' @slotchange=${() => { this.hasSums; this.hasFabs; }}></slot> `; } get contentTemplate() { return !this.data.length ? this.noContentTemplate : this.rowsTemplate; } get noContentTemplate() { return html ` <slot name='error-no-content'> <mo-empty-state icon='youtube_searched_for'>${t('No results')}</mo-empty-state> </slot> `; } get dataGridTemplate() { this.toggleAttribute('hasDetails', this.hasDetails); return html ` <mo-grid rows='* auto' ${style({ position: 'relative', height: '100%' })}> <mo-scroller ${style({ minHeight: 'var(--mo-data-grid-content-min-height, var(--_content-min-height-default))' })} @scroll=${this.handleScroll} > <mo-grid id='content' autoRows='min-content' columns='var(--mo-data-grid-columns)'> ${this.headerTemplate} ${this.contentTemplate} </mo-grid> </mo-scroller> ${this.footerTemplate} </mo-grid> `; } get headerTemplate() { return this.headerHidden ? html.nothing : html ` <mo-data-grid-header .dataGrid=${this}></mo-data-grid-header> `; } get rowsTemplate() { // Do not use the data-record or data as the key as it leads to UI flickering return html ` ${this.hiddenSizeAnchorRowTemplate} ${repeat(this.renderDataRecords, record => record.index, (record, index) => this.getRowTemplate(record, index))} `; } /** * The hidden size anchor row renders the longest content of each column in a hidden row. * This is used to mitigate the issue of using values with fluctuating lengths * with a automatic column width e.g. "max-content" or "fit-content" in combination with * row virtualization, which could lead to a lot of column resizing during scrolling. */ get hiddenSizeAnchorRowTemplate() { const getLength = (template) => [...template.values ?? [], ...template.strings ?? []] .map(v => { try { return `${v}`; } catch { return ''; } }) .reduce((acc, v) => acc + v.length, 0); const getLongestContent = (column) => { return this.dataRecords .map(dr => column.getContentTemplate?.(KeyPath.get(dr.data, column.dataSelector), dr.data) ?? html.nothing) .reduce((longest, current) => (getLength(current) > getLength(longest)) || false ? current : longest, html.nothing); }; return html ` <style> #size-anchor { display: grid; grid-template-columns: subgrid; grid-column: -1 / 1; font-size: var(--mo-data-grid-cell-font-size); height: 0; visibility: hidden; opacity: 0; div { user-select: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-inline: var(--mo-data-grid-cell-padding); margin-inline-start: calc(var(--_max-level, 0) * var(--mo-data-grid-column-sub-row-indentation, 20px)) } } </style> <div id='size-anchor'> ${!this.hasDetails ? html.nothing : html `<span></span>`} ${!this.hasSelection ? html.nothing : html `<span></span>`} ${this.visibleColumns.map(column => html ` <div style='--_max-level: ${Math.max(...this.dataRecords.map(dr => dr.level))}'> ${getLongestContent(column)} </div> `)} </div> `; } getRowTemplate(dataRecord, index = 0) { return staticHtml ` <${this.rowElementTag} part='row' .dataRecord=${dataRecord} ?data-has-alternating-background=${this.hasAlternatingBackground && index % 2 === 1} ></${this.rowElementTag}> `; } get footerTemplate() { return html ` <mo-flex ${style({ position: 'relative' })}> <mo-flex id='fab' direction='vertical-reversed' gap='0.5rem'> ${this.fabTemplate} </mo-flex> ${this.hasFooter === false ? html.nothing : html ` <mo-data-grid-footer .dataGrid=${this} page=${this.page}> <slot name='sum' slot='sum'>${this.sumDefaultTemplate}</slot> </mo-data-grid-footer> `} </mo-flex> `; } get sumsTemplate() { return html ` ${this.columns.map(c => c.sumTemplate)} `; } get toolbarTemplate() { return this.hasToolbar === false ? html.nothing : html ` <mo-flex id='toolbar' direction='horizontal' gap='8px' wrap='wrap' alignItems='center'> <slot name='toolbar'>${this.toolbarDefaultTemplate}</slot> <mo-flex id='actions' direction='horizontal' gap='8px' alignContent='center'> <slot name='toolbar-action'>${this.toolbarActionDefaultTemplate}</slot> ${this.toolbarActionsTemplate} </mo-flex> </mo-flex> `; } get toolbarDefaultTemplate() { return html.nothing; } get toolbarActionDefaultTemplate() { return html.nothing; } get sumDefaultTemplate() { return html.nothing; } get toolbarActionsTemplate() { return html ` ${!this.hasFilters ? html.nothing : html ` <mo-icon-button icon='filter_list' ${tooltip(t('More Filters'))} ?data-selected=${this.sidePanelTab === DataGridSidePanelTab.Filters} @click=${() => this.navigateToSidePanelTab(this.sidePanelTab === DataGridSidePanelTab.Filters ? undefined : DataGridSidePanelTab.Filters)} ></mo-icon-button> `} <mo-icon-button icon='settings' ${tooltip(t('Settings'))} ?data-selected=${this.sidePanelTab === DataGridSidePanelTab.Settings} @click=${() => this.navigateToSidePanelTab(this.sidePanelTab === DataGridSidePanelTab.Settings ? undefined : DataGridSidePanelTab.Settings)} ></mo-icon-button> `; } handleScroll(e) { if (this.preventFabCollapse === false) { if (!e.composed) { e.preventDefault(); e.target?.dispatchEvent(new Event('scroll', { composed: true, bubbles: true })); if (this.hasFabs) { const targetElement = e.composedPath()[0]; const scrollTop = targetElement.scrollTop; const isUpScrolling = scrollTop <= this.lastScrollElementTop; this.fabSlotCollapsed = !isUpScrolling; this.lastScrollElementTop = scrollTop <= 0 ? 0 : scrollTop; } } } } handlePointerDown(event) { this.rows.forEach(row => row.cells.forEach(cell => cell.handlePointerDown(event))); } *getFlattenedData(values = this.data) { if (!this.subDataGridDataSelector) { yield* this.sortingController.toSortedBy(values.map((data, index) => new DataRecord(this, { level: 0, index, data })), ({ data }) => data); return; } const flatten = (data, level = 0) => { const subData = KeyPath.get(data, this.subDataGridDataSelector); const subDataRecords = !Array.isArray(subData) ? undefined : this.sortingController .toSortedBy(subData.map(data => new DataRecord(this, { level, data })), ({ data }) => data) .flatMap(({ data }) => flatten(data, level + 1)); return [ new DataRecord(this, { data, level, subDataRecords }), ...(subDataRecords ?? []) ]; }; for (const data of this.sortingController.toSorted(values)) { yield* flatten(data); } return; } get dataRecords() { return [...this.getFlattenedData()] .map((record, index) => { // @ts-expect-error index is initialized here record.index = index; return record; }); } get renderDataRecords() { const rootRecords = this.dataRecords.filter(r => r.level === 0); if (this.hasPagination === false) { return rootRecords; } const from = this.dataSkip; const to = this.dataSkip + this.dataTake; return rootRecords.slice(from, to); } get dataSkip() { return (this.page - 1) * this.pageSize; } get dataTake() { return this.pageSize; } async *getCsvData() { yield 1; return this.dataRecords; } }; DataGrid.rowHeight = new LocalStorage('DataGrid.RowHeight', 35); DataGrid.cellRelativeFontSize = new LocalStorage('DataGrid.CellRelativeFontSize', 0.8); DataGrid.pageSize = new LocalStorage('DataGrid.PageSize', 25); DataGrid.hasAlternatingBackground = new LocalStorage('DataGrid.HasAlternatingBackground', true); DataGrid.defaultRowElementTag = literal `mo-data-grid-default-row`; __decorate([ event() ], DataGrid.prototype, "dataChange", void 0); __decorate([ event() ], DataGrid.prototype, "selectionChange", void 0); __decorate([ event() ], DataGrid.prototype, "pageChange", void 0); __decorate([ event() ], DataGrid.prototype, "paginationChange", void 0); __decorate([ event() ], DataGrid.prototype, "columnsChange", void 0); __decorate([ event() ], DataGrid.prototype, "sidePanelOpen", void 0); __decorate([ event() ], DataGrid.prototype, "sidePanelClose", void 0); __decorate([ event() ], DataGrid.prototype, "sortingChange", void 0); __decorate([ event() ], DataGrid.prototype, "rowDetailsOpen", void 0); __decorate([ event() ], DataGrid.prototype, "rowDetailsClose", void 0); __decorate([ event() ], DataGrid.prototype, "rowClick", void 0); __decorate([ event() ], DataGrid.prototype, "rowDoubleClick", void 0); __decorate([ event() ], DataGrid.prototype, "rowMiddleClick", void 0); __decorate([ event() ], DataGrid.prototype, "cellEdit", void 0); __decorate([ property({ type: Array }) ], DataGrid.prototype, "data", void 0); __decorate([ property({ type: Array }) ], DataGrid.prototype, "columns", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], DataGrid.prototype, "headerHidden", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], DataGrid.prototype, "preventVerticalContentScroll", void 0); __decorate([ property({ type: Number }) ], DataGrid.prototype, "page", void 0); __decorate([ property({ reflect: true, converter: (value) => value === null || value === undefined ? undefined : Number.isNaN(Number(value)) ? value : Number(value) }) ], DataGrid.prototype, "pagination", void 0); __decorate([ property({ type: Object }) ], DataGrid.prototype, "sorting", void 0); __decorate([ property({ reflect: true }) ], DataGrid.prototype, "selectability", void 0); __decorate([ property({ type: Object }) ], DataGrid.prototype, "isDataSelectable", void 0); __decorate([ property({ type: Array, event: 'selectionChange' }) ], DataGrid.prototype, "selectedData", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "selectOnClick", void 0); __decorate([ property() ], DataGrid.prototype, "selectionBehaviorOnDataChange", void 0); __decorate([ property({ type: Object }) ], DataGrid.prototype, "getRowDetailsTemplate", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "multipleDetails", void 0); __decorate([ property() ], DataGrid.prototype, "subDataGridDataSelector", void 0); __decorate([ property({ type: Object }) ], DataGrid.prototype, "hasDataDetail", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "detailsOnClick", void 0); __decorate([ property({ type: Object }) ], DataGrid.prototype, "getRowContextMenuTemplate", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "primaryContextMenuItemOnDoubleClick", void 0); __decorate([ property({ reflect: true }) ], DataGrid.prototype, "editability", void 0); __decorate([ property() ], DataGrid.prototype, "sidePanelTab", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "sidePanelHidden", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "hasAlternatingBackground", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "preventFabCollapse", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], DataGrid.prototype, "fabSlotCollapsed", void 0); __decorate([ property({ type: Boolean }) ], DataGrid.prototype, "exportable", void 0); __decorate([ property({ type: Number, updated() { const fontSize = Math.max(0.8, Math.min(1.2, this.cellFontSize)); this.style.setProperty('--mo-data-grid-cell-font-size', `${fontSize}rem`); } }) ], DataGrid.prototype, "cellFontSize", void 0); __decorate([ property({ type: Number, updated() { const rowHeight = Math.max(30, Math.min(60, this.rowHeight)); this.style.setProperty('--mo-data-grid-row-height', `${rowHeight}px`); } }) ], DataGrid.prototype, "rowHeight", void 0); __decorate([ query('mo-data-grid-header') ], DataGrid.prototype, "header", void 0); __decorate([ query('mo-scroller') ], DataGrid.prototype, "scroller", void 0); __decorate([ queryAll('[mo-data-grid-row]') ], DataGrid.prototype, "rows", void 0); __decorate([ query('mo-data-grid-footer') ], DataGrid.prototype, "footer", void 0); __decorate([ query('mo-data-grid-side-panel') ], DataGrid.prototype, "sidePanel", void 0); __decorate([ eventOptions({ passive: true }) ], DataGrid.prototype, "handleScroll", null); __decorate([ eventListener({ target: document, type: 'pointerdown' }) ], DataGrid.prototype, "handlePointerDown", null); DataGrid = DataGrid_1 = __decorate([ component('mo-data-grid') ], DataGrid); export { DataGrid };