Skip to content

Commit

Permalink
refactor: extract grid utility columns logic to separate mixins (#6610)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomivirkki authored Oct 6, 2023
1 parent 91ea11e commit 589c5d7
Show file tree
Hide file tree
Showing 14 changed files with 515 additions and 420 deletions.
22 changes: 22 additions & 0 deletions packages/grid/src/vaadin-grid-filter-column-mixin.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license
* Copyright (c) 2016 - 2023 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import type { Constructor } from '@open-wc/dedupe-mixin';

export declare function GridFilterColumnMixin<T extends Constructor<HTMLElement>>(
superclass: T,
): Constructor<GridFilterColumnMixinClass> & T;

export declare class GridFilterColumnMixinClass {
/**
* Text to display as the label of the column filter text-field.
*/
header: string | null | undefined;

/**
* JS Path of the property in the item used for filtering the data.
*/
path: string | null | undefined;
}
100 changes: 100 additions & 0 deletions packages/grid/src/vaadin-grid-filter-column-mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @license
* Copyright (c) 2016 - 2023 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/

/**
* @polymerMixin
*/
export const GridFilterColumnMixin = (superClass) =>
class extends superClass {
static get properties() {
return {
/**
* JS Path of the property in the item used for filtering the data.
*/
path: String,

/**
* Text to display as the label of the column filter text-field.
*/
header: String,
};
}

static get observers() {
return ['_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header, _filterValue)'];
}

constructor() {
super();

this.__boundOnFilterValueChanged = this.__onFilterValueChanged.bind(this);
}

/**
* Renders the grid filter with the custom text field to the header cell.
*
* @override
*/
_defaultHeaderRenderer(root, _column) {
let filter = root.firstElementChild;
let textField = filter ? filter.firstElementChild : undefined;

if (!filter) {
filter = document.createElement('vaadin-grid-filter');
textField = document.createElement('vaadin-text-field');
textField.setAttribute('theme', 'small');
textField.setAttribute('style', 'max-width: 100%;');
textField.setAttribute('focus-target', '');
textField.addEventListener('value-changed', this.__boundOnFilterValueChanged);
filter.appendChild(textField);
root.appendChild(filter);
}

filter.path = this.path;
filter.value = this._filterValue;

textField.__rendererValue = this._filterValue;
textField.value = this._filterValue;
textField.label = this.__getHeader(this.header, this.path);
}

/**
* The filter column doesn't allow to use a custom header renderer
* to override the header cell content.
* It always renders the grid filter to the header cell.
*
* @override
*/
_computeHeaderRenderer() {
return this._defaultHeaderRenderer;
}

/**
* Updates the internal filter value once the filter text field is changed.
* The listener handles only user-fired events.
*
* @private
*/
__onFilterValueChanged(e) {
// Skip if the value is changed by the renderer.
if (e.detail.value === e.target.__rendererValue) {
return;
}

this._filterValue = e.detail.value;
}

/** @private */
__getHeader(header, path) {
if (header) {
return header;
}

if (path) {
return this._generateHeader(path);
}
}
};
20 changes: 9 additions & 11 deletions packages/grid/src/vaadin-grid-filter-column.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import type { GridDefaultItem } from './vaadin-grid.js';
import { GridColumn } from './vaadin-grid-column.js';
import type { GridColumn, GridColumnMixin } from './vaadin-grid-column.js';
import type { GridFilterColumnMixinClass } from './vaadin-grid-filter-column-mixin.js';

export * from './vaadin-grid-filter-column-mixin.js';

/**
* `<vaadin-grid-filter-column>` is a helper element for the `<vaadin-grid>`
Expand All @@ -19,17 +22,12 @@ import { GridColumn } from './vaadin-grid-column.js';
* ...
* ```
*/
declare class GridFilterColumn<TItem = GridDefaultItem> extends GridColumn<TItem> {
/**
* Text to display as the label of the column filter text-field.
*/
header: string | null | undefined;
declare class GridFilterColumn<TItem = GridDefaultItem> extends HTMLElement {}

/**
* JS Path of the property in the item used for filtering the data.
*/
path: string | null | undefined;
}
interface GridFilterColumn<TItem = GridDefaultItem>
extends GridFilterColumnMixinClass,
GridColumnMixin<TItem, GridColumn<TItem>>,
GridColumn<TItem> {}

declare global {
interface HTMLElementTagNameMap {
Expand Down
93 changes: 3 additions & 90 deletions packages/grid/src/vaadin-grid-filter-column.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import './vaadin-grid-filter.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { GridColumn } from './vaadin-grid-column.js';
import { GridFilterColumnMixin } from './vaadin-grid-filter-column-mixin.js';

/**
* `<vaadin-grid-filter-column>` is a helper element for the `<vaadin-grid>`
Expand All @@ -22,100 +23,12 @@ import { GridColumn } from './vaadin-grid-column.js';
*
* @customElement
* @extends GridColumn
* @mixes GridFilterColumnMixin
*/
class GridFilterColumn extends GridColumn {
class GridFilterColumn extends GridFilterColumnMixin(GridColumn) {
static get is() {
return 'vaadin-grid-filter-column';
}

static get properties() {
return {
/**
* JS Path of the property in the item used for filtering the data.
*/
path: String,

/**
* Text to display as the label of the column filter text-field.
*/
header: String,
};
}

static get observers() {
return ['_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header, _filterValue)'];
}

constructor() {
super();

this.__boundOnFilterValueChanged = this.__onFilterValueChanged.bind(this);
}

/**
* Renders the grid filter with the custom text field to the header cell.
*
* @override
*/
_defaultHeaderRenderer(root, _column) {
let filter = root.firstElementChild;
let textField = filter ? filter.firstElementChild : undefined;

if (!filter) {
filter = document.createElement('vaadin-grid-filter');
textField = document.createElement('vaadin-text-field');
textField.setAttribute('theme', 'small');
textField.setAttribute('style', 'max-width: 100%;');
textField.setAttribute('focus-target', '');
textField.addEventListener('value-changed', this.__boundOnFilterValueChanged);
filter.appendChild(textField);
root.appendChild(filter);
}

filter.path = this.path;
filter.value = this._filterValue;

textField.__rendererValue = this._filterValue;
textField.value = this._filterValue;
textField.label = this.__getHeader(this.header, this.path);
}

/**
* The filter column doesn't allow to use a custom header renderer
* to override the header cell content.
* It always renders the grid filter to the header cell.
*
* @override
*/
_computeHeaderRenderer() {
return this._defaultHeaderRenderer;
}

/**
* Updates the internal filter value once the filter text field is changed.
* The listener handles only user-fired events.
*
* @private
*/
__onFilterValueChanged(e) {
// Skip if the value is changed by the renderer.
if (e.detail.value === e.target.__rendererValue) {
return;
}

this._filterValue = e.detail.value;
}

/** @private */
__getHeader(header, path) {
if (header) {
return header;
}

if (path) {
return this._generateHeader(path);
}
}
}

defineCustomElement(GridFilterColumn);
Expand Down
24 changes: 24 additions & 0 deletions packages/grid/src/vaadin-grid-selection-column-mixin.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @license
* Copyright (c) 2016 - 2023 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import type { Constructor } from '@open-wc/dedupe-mixin';
import { GridSelectionColumnBaseMixinClass } from './vaadin-grid-selection-column-base-mixin.js';

/**
* Fired when the `selectAll` property changes.
*/
export type GridSelectionColumnSelectAllChangedEvent = CustomEvent<{ value: boolean }>;

export interface GridSelectionColumnCustomEventMap {
'select-all-changed': GridSelectionColumnSelectAllChangedEvent;
}

export interface GridSelectionColumnEventMap extends HTMLElementEventMap, GridSelectionColumnCustomEventMap {}

export declare function GridSelectionColumnMixin<TItem, T extends Constructor<HTMLElement>>(
superclass: T,
): Constructor<GridSelectionColumnMixinClass<TItem>> & T;

export declare class GridSelectionColumnMixinClass<TItem> extends GridSelectionColumnBaseMixinClass<TItem> {}
Loading

0 comments on commit 589c5d7

Please sign in to comment.