Skip to content

Commit 20a2e3c

Browse files
authored
Rkaraivanov/pre release fixes (#18)
* feat: Pre-release refactoring and fixes - Refactored auto-generation - Refactored filter events and behaviors - Fixed horizontal keyboard navigation - Updated custom-elements manifest - Include manifest and meta - Various bug fixes
1 parent 9eb125d commit 20a2e3c

24 files changed

+1876
-1111
lines changed

custom-elements.json

Lines changed: 1037 additions & 899 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 550 additions & 82 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@
1919
"files": [
2020
"/dist/",
2121
"/dist/bundle.*",
22-
"!/dist/test/"
22+
"!/dist/test/",
23+
"LICENSE",
24+
"README.md",
25+
"custom-elements.json"
2326
],
27+
"engines": {
28+
"node": "^14.21.0 || >= 16.19.0"
29+
},
2430
"scripts": {
2531
"analyze": "cem analyze --litelement --globs \"src/**/*.{js,ts}\" --exclude \"src/styles/**/*\"",
2632
"build": "npm run build:tsc && npm run dev:vite && npm run typedoc",
@@ -59,36 +65,36 @@
5965
"dependencies": {
6066
"@lit-labs/context": "^0.2.0",
6167
"@lit-labs/virtualizer": "^1.0.1",
62-
"igniteui-theming": "^1.2.0",
63-
"igniteui-webcomponents": "^4.1.1",
68+
"igniteui-theming": "^1.3.0",
69+
"igniteui-webcomponents": "^4.2.1",
6470
"lit": "^2.6.1"
6571
},
6672
"devDependencies": {
6773
"@blockquote/rollup-plugin-total-bundlesize": "^1.0.0",
6874
"@blockquote/sass-style-template": "3.0.0",
6975
"@blockquote/test-runner-mocha-style-reporter": "^1.4.1",
7076
"@custom-elements-manifest/analyzer": "^0.6.8",
71-
"@open-wc/eslint-config": "^9.2.0",
77+
"@open-wc/eslint-config": "^9.2.2",
7278
"@open-wc/testing": "^3.1.7",
73-
"@typescript-eslint/eslint-plugin": "^5.48.1",
74-
"@typescript-eslint/parser": "^5.48.1",
79+
"@typescript-eslint/eslint-plugin": "^5.51.0",
80+
"@typescript-eslint/parser": "^5.51.0",
7581
"@web/dev-server": "^0.1.35",
7682
"@web/test-runner": "^0.15.0",
7783
"@web/test-runner-playwright": "^0.9.0",
7884
"concurrently": "^7.6.0",
79-
"eslint": "^8.32.0",
85+
"eslint": "^8.33.0",
8086
"eslint-config-prettier": "^8.6.0",
8187
"eslint-plugin-log-filenames": "^1.0.6",
8288
"husky": "^8.0.3",
83-
"lint-staged": "^13.1.0",
84-
"prettier": "^2.8.3",
89+
"lint-staged": "^13.1.1",
90+
"prettier": "^2.8.4",
8591
"sinon": "^15.0.1",
8692
"stylelint": "^14.16.1",
8793
"stylelint-config-standard-scss": "^6.1.0",
88-
"tslib": "^2.4.1",
94+
"tslib": "^2.5.0",
8995
"typedoc": "^0.23.24",
90-
"typescript": "^4.9.4",
91-
"vite": "^4.0.4"
96+
"typescript": "^4.9.5",
97+
"vite": "^4.1.1"
9298
},
9399
"customElements": "custom-elements.json"
94100
}

src/components/cell.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import type { ApexCellContext, ColumnConfiguration, PropertyType } from '../inte
66
import { styles } from '../styles/body-cell/body-cell-styles.css.js';
77
import type ApexGridRow from './row.js';
88

9+
/**
10+
* Component representing a DOM cell of the Apex grid.
11+
*/
912
export default class ApexGridCell<T extends object> extends LitElement {
1013
public static get is() {
1114
return GRID_CELL_TAG;
@@ -17,15 +20,28 @@ export default class ApexGridCell<T extends object> extends LitElement {
1720
registerComponent(this);
1821
}
1922

23+
/**
24+
* The value which will be rendered by the component.
25+
*/
2026
@property({ attribute: false })
2127
public value!: PropertyType<T>;
2228

29+
/**
30+
* A reference to the column configuration object.
31+
*/
2332
@property({ attribute: false })
2433
public column!: ColumnConfiguration<T>;
2534

35+
/**
36+
* Indicates whether this is the active cell in the grid.
37+
*
38+
*/
2639
@property({ type: Boolean, reflect: true })
2740
public active = false;
2841

42+
/**
43+
* The parent row component holding this cell.
44+
*/
2945
public row!: ApexGridRow<T>;
3046

3147
protected get context(): ApexCellContext<T> {

src/components/filter-row.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { property, query } from 'lit/decorators.js';
44
import { ifDefined } from 'lit/directives/if-defined.js';
55

66
import { StateController, gridStateContext } from '../controllers/state.js';
7-
import { PIPELINE, DEFAULT_COLUMN_CONFIG } from '../internal/constants.js';
7+
import { DEFAULT_COLUMN_CONFIG } from '../internal/constants.js';
88
import { GRID_FILTER_ROW_TAG } from '../internal/tags.js';
99
import { getFilterOperandsFor } from '../internal/utils.js';
1010
import { registerComponent } from '../internal/register.js';
@@ -94,7 +94,7 @@ export default class ApexFilterRow<T extends object> extends LitElement {
9494
this.active = true;
9595

9696
await this.updateComplete;
97-
this.input.select();
97+
this.input?.select();
9898
}
9999

100100
#handleConditionChanged(event: CustomEvent<IgcDropdownItemComponent>) {
@@ -107,7 +107,7 @@ export default class ApexFilterRow<T extends object> extends LitElement {
107107
>;
108108

109109
if (this.input.value || this.expression.condition.unary) {
110-
this.filterController.filterWithEvent(this.expression);
110+
this.filterController.filterWithEvent(this.expression, 'modify');
111111
}
112112

113113
this.requestUpdate();
@@ -118,14 +118,18 @@ export default class ApexFilterRow<T extends object> extends LitElement {
118118

119119
const value = this.isNumeric ? parseFloat(event.detail) : event.detail;
120120
const shouldUpdate = this.isNumeric ? !isNaN(value as number) : !!value;
121+
const type = this.filterController.get(this.expression.key)?.has(this.expression)
122+
? 'modify'
123+
: 'add';
121124

122125
if (shouldUpdate) {
123126
this.expression.searchTerm = value as any;
124-
this.filterController.filterWithEvent(this.expression);
127+
128+
this.filterController.filterWithEvent(this.expression, type);
125129
} else {
126130
this.#removeExpression(this.expression);
127-
this.state.host.requestUpdate(PIPELINE);
128131
}
132+
129133
this.requestUpdate();
130134
}
131135

@@ -146,8 +150,7 @@ export default class ApexFilterRow<T extends object> extends LitElement {
146150
}
147151

148152
#handleResetClick() {
149-
this.filterController.reset(this.column.key);
150-
this.state.host.requestUpdate(PIPELINE);
153+
this.filterController.removeAllExpressions(this.column.key);
151154
this.requestUpdate();
152155
}
153156

@@ -171,7 +174,7 @@ export default class ApexFilterRow<T extends object> extends LitElement {
171174
e.stopPropagation();
172175

173176
expression.criteria = expression.criteria === 'and' ? 'or' : 'and';
174-
this.filterController.filterWithEvent(expression);
177+
this.filterController.filterWithEvent(expression, 'modify');
175178
this.requestUpdate();
176179
};
177180
}
@@ -181,7 +184,7 @@ export default class ApexFilterRow<T extends object> extends LitElement {
181184
e.stopPropagation();
182185
this.expression = expression;
183186
await this.updateComplete;
184-
this.input.select();
187+
this.input?.select();
185188
};
186189
}
187190

@@ -196,7 +199,6 @@ export default class ApexFilterRow<T extends object> extends LitElement {
196199
this.input.focus();
197200
}
198201

199-
this.state.host.requestUpdate(PIPELINE);
200202
this.requestUpdate();
201203
};
202204
}

src/components/grid.ts

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ import { GridDOMController } from '../controllers/dom.js';
1010
import { EventEmitterBase } from '../internal/mixins/event-emitter.js';
1111
import { watch } from '../internal/watch.js';
1212
import { DEFAULT_COLUMN_CONFIG, PIPELINE } from '../internal/constants.js';
13-
import { asArray, getFilterOperandsFor } from '../internal/utils.js';
13+
import { asArray, autoGenerateColumns, getFilterOperandsFor } from '../internal/utils.js';
1414

1515
import type {
1616
ColumnConfiguration,
17-
GridRemoteConfig,
17+
DataPipelineConfiguration,
1818
GridSortConfiguration,
1919
Keys,
2020
} from '../internal/types.js';
21-
import type { FilterExpressionTree } from '../operations/filter/tree.js';
2221
import type { FilterExpression } from '../operations/filter/types.js';
2322
import type { SortExpression } from '../operations/sort/types.js';
2423

@@ -50,16 +49,42 @@ import {
5049
*/
5150
export interface ApexFilteringEvent<T extends object> {
5251
/**
53-
* The filter expression to apply.
52+
* The target column for the filter operation.
5453
*/
55-
// expression: FilterExpression<T>;
54+
key: Keys<T>;
55+
56+
/**
57+
* The filter expression(s) to apply.
58+
*/
59+
expressions: FilterExpression<T>[];
60+
61+
/**
62+
* The type of modification which will be applied to the filter
63+
* state of the column.
64+
*
65+
* @remarks
66+
* `add` - a new filter expression will be added to the state of the column.
67+
* `modify` - an existing filter expression will be modified.
68+
* `remove` - the expression(s) will be removed from the state of the column.
69+
*/
70+
type: 'add' | 'modify' | 'remove';
71+
}
72+
73+
/**
74+
* Event object for the filtered event of the grid.
75+
*/
76+
export interface ApexFilteredEvent<T extends object> {
5677
/**
57-
* The filter state of the column.
78+
* The target column for the filter operation.
5879
*/
59-
state: FilterExpressionTree<T>;
80+
key: Keys<T>;
81+
82+
/**
83+
* The filter state of the column after the operation.
84+
*/
85+
state: FilterExpression<T>[];
6086
}
6187

62-
// TODO: Subject to change as these are way too generic names
6388
/**
6489
* Events for the apex-grid.
6590
*/
@@ -98,7 +123,7 @@ export interface ApexGridEventMap<T extends object> {
98123
*
99124
* @event
100125
*/
101-
filtered: CustomEvent<FilterExpressionTree<T>>;
126+
filtered: CustomEvent<ApexFilteredEvent<T>>;
102127
}
103128

104129
/**
@@ -121,7 +146,7 @@ export interface ApexGridEventMap<T extends object> {
121146
indigo,
122147
material,
123148
})
124-
export default class ApexGrid<T extends object> extends EventEmitterBase<ApexGridEventMap<T>> {
149+
export class ApexGrid<T extends object> extends EventEmitterBase<ApexGridEventMap<T>> {
125150
public static get is() {
126151
return GRID_TAG;
127152
}
@@ -173,12 +198,23 @@ export default class ApexGrid<T extends object> extends EventEmitterBase<ApexGri
173198
* data source.
174199
*
175200
* @remarks
176-
* This is a one-time operation which is executed when the grid is initially added to the DOM.
201+
* This is usually executed on initial rendering in the DOM. It depends on having an existing data source
202+
* to infer the column configuration for the grid.
177203
* Passing an empty data source or having a late bound data source (such as a HTTP request) will usually
178204
* result in empty column configuration for the grid.
179205
*
180206
* This property is ignored if any existing column configuration already exists in the grid.
181207
*
208+
* In a scenario where you want to bind a new data source and still keep the auto-generation behavior,
209+
* make sure to reset the column collection of the grid before passing in the new data source.
210+
*
211+
* @example
212+
* ```typescript
213+
* // assuming autoGenerate is set to true
214+
* grid.columns = [];
215+
* grid.data = [...];
216+
* ```
217+
*
182218
* @attr auto-generate
183219
*/
184220
@property({ type: Boolean, attribute: 'auto-generate' })
@@ -195,7 +231,7 @@ export default class ApexGrid<T extends object> extends EventEmitterBase<ApexGri
195231
* Configuration object which controls remote data operations for the grid.
196232
*/
197233
@property({ attribute: false })
198-
public remoteConfiguration?: GridRemoteConfig<T>;
234+
public dataPipelineConfiguration!: DataPipelineConfiguration<T>;
199235

200236
/**
201237
* Set the sort state for the grid.
@@ -268,6 +304,8 @@ export default class ApexGrid<T extends object> extends EventEmitterBase<ApexGri
268304
@watch('data')
269305
protected dataChanged() {
270306
this.dataState = structuredClone(this.data);
307+
autoGenerateColumns(this);
308+
271309
if (this.hasUpdated) {
272310
this.pipeline();
273311
}

src/components/row.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import type { ActiveNode, ColumnConfiguration } from '../internal/types.js';
77
import ApexGridCell from './cell.js';
88
import { styles } from '../styles/body-row/body-row-styles.css.js';
99

10+
/**
11+
* Component representing the DOM row in the Apex grid.
12+
*/
1013
export default class ApexGridRow<T extends object> extends LitElement {
1114
public static get is() {
1215
return GRID_ROW_TAG;

src/controllers/data-operation.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,31 @@ export class DataOperationsController<T extends object> implements ReactiveContr
1515

1616
public hostConnected() {}
1717

18-
protected get hasRemoteSort() {
19-
return isDefined(this.host.remoteConfiguration?.sort);
18+
protected get hasCustomSort() {
19+
return isDefined(this.host.dataPipelineConfiguration?.sort);
2020
}
2121

22-
protected get hasRemoteFilter() {
23-
return isDefined(this.host.remoteConfiguration?.filter);
22+
protected get hasCustomFilter() {
23+
return isDefined(this.host.dataPipelineConfiguration?.filter);
2424
}
2525

26-
protected get remoteFilter() {
27-
return this.host.remoteConfiguration!.filter!;
26+
protected get customFilter() {
27+
return this.host.dataPipelineConfiguration!.filter!;
2828
}
2929

30-
protected get remoteSort() {
31-
return this.host.remoteConfiguration!.sort!;
30+
protected get customSort() {
31+
return this.host.dataPipelineConfiguration!.sort!;
3232
}
3333

3434
public async apply(data: T[], state: StateController<T>) {
3535
const { filtering, sorting } = state;
3636

37-
data = this.hasRemoteFilter
38-
? await this.remoteFilter(data, filtering.state)
37+
data = this.hasCustomFilter
38+
? await this.customFilter({ data, grid: this.host, type: 'filter' })
3939
: this.filtering.apply(data, filtering.state);
4040

41-
data = this.hasRemoteSort
42-
? await this.remoteSort(data, sorting.state)
41+
data = this.hasCustomSort
42+
? await this.customSort({ data, grid: this.host, type: 'sort' })
4343
: this.sorting.apply(data, sorting.state);
4444

4545
return data;

0 commit comments

Comments
 (0)