Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

> **Note:** This project is currently in initial development (0.0.x versions). Until version 1.0.0 is released, the public API is not considered stable and breaking changes may occur in any release without following semantic versioning conventions.

## [0.3.0] - 2025-12-11

### Changed

- **BREAKING:** Column properties have been renamed:
- `key` → `field` - The field from the data that the column references
- `type` → `dataType` - The data type of the column's values
- `headerText` → `header` - The header text of the column

## [0.2.0] - 2025-12-10

### Changed
Expand Down
40 changes: 20 additions & 20 deletions demo/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,30 +107,30 @@ const themeChoose = html`

const columns: ColumnConfiguration<User>[] = [
{
key: 'id',
headerText: 'User ID',
field: 'id',
header: 'User ID',
resizable: true,
type: 'number',
dataType: 'number',
filterable: true,
sortable: true,
},
{
key: 'name',
field: 'name',
cellTemplate: (params) => html`<igc-input .value=${params.value}></igc-input>`,
filterable: true,
sortable: true,
},
{
key: 'avatar',
field: 'avatar',
cellTemplate: (params) =>
html`<igc-avatar
shape="circle"
.src=${params.value}
></igc-avatar>`,
},
{
key: 'satisfaction',
type: 'number',
field: 'satisfaction',
dataType: 'number',
sortable: true,
filterable: true,
cellTemplate: (params) =>
Expand All @@ -141,7 +141,7 @@ const columns: ColumnConfiguration<User>[] = [
></igc-rating>`,
},
{
key: 'priority',
field: 'priority',
cellTemplate: (params) =>
html`<igc-select
outlined
Expand All @@ -157,14 +157,14 @@ const columns: ColumnConfiguration<User>[] = [
},
},
{
key: 'age',
field: 'age',
},
{
key: 'email',
field: 'email',
},
{
key: 'subscribed',
type: 'boolean',
field: 'subscribed',
dataType: 'boolean',
sortable: true,
filterable: true,
cellTemplate: (params) =>
Expand All @@ -179,11 +179,11 @@ const data = generateData(1e3);
IgcGridLite.register();

const column = document.createElement(IgcGridLiteColumn.tagName) as IgcGridLiteColumn<User>;
column.key = 'email';
column.headerText = 'Toggle Me';
column.field = 'email';
column.header = 'Toggle Me';

const column2 = document.createElement(IgcGridLiteColumn.tagName) as IgcGridLiteColumn<User>;
column2.headerText = 'Non-existent';
column2.header = 'Non-existent';

const toggleColumn = () => {
const grid = getElement<IgcGridLite<User>>(IgcGridLite.tagName);
Expand All @@ -194,7 +194,7 @@ const toggleColumn = () => {
const toggleFiltering = () => {
const grid = getElement<IgcGridLite<User>>(IgcGridLite.tagName);
const column = Array.from(grid.querySelectorAll(IgcGridLiteColumn.tagName)).find(
(col) => col.key === 'name',
(col) => col.field === 'name',
)!;

column.filterable = !column.filterable;
Expand All @@ -217,16 +217,16 @@ render(
${columns.map(
(col) =>
html`<igc-grid-lite-column
.key=${col.key}
.type=${col.type}
.headerText=${col.headerText}
.field=${col.field}
.dataType=${col.dataType}
.header=${col.header}
?hidden=${col.hidden}
?resizable=${col.resizable}
?sortable=${col.sortable}
.sortConfiguration=${col.sortConfiguration}
?filterable=${col.filterable}
.cellTemplate=${col.cellTemplate}
.headerTemplate=${col.headerTemplate as any}
.headerTemplate=${col.headerTemplate}
></igc-grid-lite-column>`,
)}
</igc-grid-lite>
Expand Down
8 changes: 4 additions & 4 deletions src/components/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ export class IgcGridLiteColumn<T extends object>
@consume({ context: COLUMN_UPDATE_CONTEXT })
protected _setConfig?: (config: BaseColumnConfiguration<T>) => void;

/** The key of the column, used to identify the data field. */
/** The field from the data for this column. */
@property()
public key!: keyof T;
public field!: keyof T;

/** The data type of the column's values. */
@property()
public type?: 'number' | 'string' | 'boolean' = 'string';
public dataType?: 'number' | 'string' | 'boolean' = 'string';

/** The header text of the column. */
@property()
public headerText?: string;
public header?: string;

/** The width of the column. */
@property()
Expand Down
12 changes: 6 additions & 6 deletions src/components/filter-row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class IgcFilterRow<T extends object> extends LitElement {
public state!: StateController<T>;

protected get isNumeric() {
return this.column.type === 'number';
return this.column.dataType === 'number';
}

protected get filterController() {
Expand Down Expand Up @@ -99,7 +99,7 @@ export default class IgcFilterRow<T extends object> extends LitElement {

#handleConditionChanged(event: CustomEvent<IgcDropdownItemComponent>) {
event.stopPropagation();
const key = event.detail.value as OperandKeys<T[typeof this.column.key]>;
const key = event.detail.value as OperandKeys<T[typeof this.column.field]>;

// XXX: Types
this.expression.condition = (getFilterOperandsFor(this.column) as any)[key] as FilterOperation<
Expand Down Expand Up @@ -150,7 +150,7 @@ export default class IgcFilterRow<T extends object> extends LitElement {
}

#handleResetClick() {
this.filterController.removeAllExpressions(this.column.key);
this.filterController.removeAllExpressions(this.column.field);
this.requestUpdate();
}

Expand Down Expand Up @@ -236,7 +236,7 @@ export default class IgcFilterRow<T extends object> extends LitElement {
}

protected renderActiveChips() {
const state = this.filterController.get(this.column.key);
const state = this.filterController.get(this.column.field);

return !state
? nothing
Expand Down Expand Up @@ -350,7 +350,7 @@ export default class IgcFilterRow<T extends object> extends LitElement {
}

protected renderFilterState(column: ColumnConfiguration<T>) {
const state = this.filterController.get(column.key);
const state = this.filterController.get(column.field);

const partial = state && state.length < 3;
const hidden = state && state.length >= 3;
Expand All @@ -363,7 +363,7 @@ export default class IgcFilterRow<T extends object> extends LitElement {

const count = hidden ? html`<span slot="suffix">${state.length}</span>` : nothing;
const chip = html`<igc-chip
data-column=${column.key}
data-column=${column.field}
@click=${open}
>${prefixedIcon('filter')}Filter${count}</igc-chip
>`;
Expand Down
4 changes: 2 additions & 2 deletions src/components/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ export class IgcGridLite<T extends object> extends EventEmitterBase<IgcGridLiteE
*/
public getColumn(id: Keys<T> | number): ColumnConfiguration<T> | undefined {
return this._stateController.columns.find((column, index) =>
isNumber(id) ? index === id : column.key === id
isNumber(id) ? index === id : column.field === id
);
}

Expand All @@ -422,7 +422,7 @@ export class IgcGridLite<T extends object> extends EventEmitterBase<IgcGridLiteE
const target = getElementFromEventPath<IgcGridLiteCell<T>>(IgcGridLiteCell.tagName, event);

if (target) {
this._stateController.active = { column: target.column.key, row: target.row.index };
this._stateController.active = { column: target.column.field, row: target.row.index };
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/header-row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default class IgcGridLiteHeaderRow<T extends object> extends LitElement {
? nothing
: html`
<igc-grid-lite-header
part=${partMap({ filtered: column.key === filterRow?.column?.key })}
part=${partMap({ filtered: column.field === filterRow?.column?.field })}
.column=${column}
></igc-grid-lite-header>
`
Expand Down
4 changes: 2 additions & 2 deletions src/components/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default class IgcGridLiteHeader<T extends object> extends LitElement {
#handleAutosize = () => this.resizeController.autosize(this.column, this);

protected renderSortPart() {
const state = this.state.sorting.state.get(this.column.key);
const state = this.state.sorting.state.get(this.column.field);
const idx = Array.from(this.state.sorting.state.values()).indexOf(state!);
const attr =
this.state.host.sortingOptions.mode === 'multiple' ? (idx > -1 ? idx + 1 : nothing) : nothing;
Expand All @@ -129,7 +129,7 @@ export default class IgcGridLiteHeader<T extends object> extends LitElement {
}

protected renderContentPart() {
const defaultContent = this.column.headerText ?? this.column.key;
const defaultContent = this.column.header ?? this.column.field;
const template = this.column.headerTemplate;

return html`
Expand Down
4 changes: 2 additions & 2 deletions src/components/row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ export default class IgcGridLiteRow<T extends object> extends LitElement {
? nothing
: html`<igc-grid-lite-cell
part="cell"
.active=${key === column.key && index === this.index}
.active=${key === column.field && index === this.index}
.column=${column}
.row=${this as IgcGridLiteRow<T>}
.value=${data[column.key]}
.value=${data[column.field]}
></igc-grid-lite-cell>`
)}
`;
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class FilterController<T extends object> implements ReactiveController {

// XXX: Types
return {
key: column.key,
key: column.field,
condition: operands[keys[0]],
caseSensitive,
} as unknown as FilterExpression<T>;
Expand Down
8 changes: 4 additions & 4 deletions src/controllers/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ export class NavigationController<T extends object> implements ReactiveControlle
}

protected get _firstColumn() {
return this._state.host.getColumn(0)!.key ?? '';
return this._state.host.getColumn(0)!.field ?? '';
}

protected getPreviousColumn(key: Keys<T>) {
return this._columns[Math.max(this._columns.indexOf(this._state.host.getColumn(key)!) - 1, 0)]
.key;
.field;
}

protected getNextColumn(key: Keys<T>) {
Expand All @@ -50,7 +50,7 @@ export class NavigationController<T extends object> implements ReactiveControlle
this._columns.indexOf(this._state.host.getColumn(key)!) + 1,
this._columns.length - 1
)
].key;
].field;
}

protected scrollToCell(node: ActiveNode<T>) {
Expand All @@ -60,7 +60,7 @@ export class NavigationController<T extends object> implements ReactiveControlle

if (row) {
row.cells
.find((cell) => cell.column.key === node.column)
.find((cell) => cell.column.field === node.column)
?.scrollIntoView({ block: 'nearest' });
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/resize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class ResizeController<T extends object> implements ReactiveController {

#maxSize(key: Keys<T>, headerWidth: number) {
const max = this.host.rows
.map((row) => row.cells.find((cell) => cell.column.key === key)!)
.map((row) => row.cells.find((cell) => cell.column.field === key)!)
.reduce((prev, current) => (current.offsetWidth > prev ? current.offsetWidth : prev), 0);

return Math.max(...[MIN_COL_RESIZE_WIDTH, max, headerWidth]);
Expand Down Expand Up @@ -54,7 +54,7 @@ export class ResizeController<T extends object> implements ReactiveController {
this.host.requestUpdate();
await this.host.updateComplete;

column.width = `${this.#maxSize(column.key, header.offsetWidth)}px`;
column.width = `${this.#maxSize(column.field, header.offsetWidth)}px`;
this.host.requestUpdate();
}

Expand Down
6 changes: 3 additions & 3 deletions src/controllers/sort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export class SortController<T extends object> implements ReactiveController {
}

public prepareExpression(column: ColumnConfiguration<T>): SortingExpression<T> {
if (this.state.has(column.key)) {
const expr = this.state.get(column.key)!;
if (this.state.has(column.field)) {
const expr = this.state.get(column.field)!;

return Object.assign(expr, {
direction: this.#orderBy(expr.direction),
Expand All @@ -99,7 +99,7 @@ export class SortController<T extends object> implements ReactiveController {
}

// Initial state
return this.#createDefaultExpression(column.key);
return this.#createDefaultExpression(column.field);
}

public reset(key?: Keys<T>) {
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class StateController<T extends object> implements ReactiveController {

public updateColumnsConfiguration(config: ColumnConfiguration<T>[]): void {
for (const columnConfig of config) {
const existing = this._columns.findIndex((column) => column.key === columnConfig.key);
const existing = this._columns.findIndex((column) => column.field === columnConfig.field);
if (existing !== -1) {
this._columns[existing] = {
...this._columns[existing],
Expand Down
4 changes: 2 additions & 2 deletions src/internal/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export const SENTINEL_NODE: Readonly<ActiveNode<any>> = Object.freeze({
row: -1,
});
export const DEFAULT_COLUMN_CONFIG = Object.freeze<ColumnConfiguration<any>>({
key: columnKey,
type: 'string',
field: columnKey,
dataType: 'string',
resizable: false,
hidden: false,
sortable: false,
Expand Down
10 changes: 5 additions & 5 deletions src/internal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ export type ColumnSortConfiguration<T, K extends Keys<T> = Keys<T>> = K extends
/** Configuration object for grid columns. */
export interface BaseColumnConfiguration<T extends object, K extends Keys<T> = Keys<T>> {
/**
* The field for from the data the this column will reference.
* The field from the data for this column.
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected grammar from 'The field from the data for this column' to 'The field from the data that this column references'.

Suggested change
* The field from the data for this column.
* The field from the data that this column references.

Copilot uses AI. Check for mistakes.
*/
key: K;
field: K;
/**
* The type of data this column will reference.
*
Expand All @@ -70,12 +70,12 @@ export interface BaseColumnConfiguration<T extends object, K extends Keys<T> = K
* If not passed, `string` is assumed to be the default type.
*
*/
type?: DataType;
dataType?: DataType;
/**
* Optional text to display in the column header. By default, the column key is used
* Optional text to display in the column header. By default, the column field is used
* to render the header text.
*/
headerText?: string;
header?: string;
/**
* Width for the current column.
*
Expand Down
Loading