Skip to content

Commit 63a7065

Browse files
refactor(header): use signals for inputs and outputs
1 parent babdc44 commit 63a7065

File tree

4 files changed

+119
-148
lines changed

4 files changed

+119
-148
lines changed

projects/ngx-datatable/src/lib/components/datatable.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ export class DatatableComponent<TRow extends Row = any>
963963

964964
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
965965
if (this.headerComponent && this.headerComponent._columnGroupWidths.total !== width) {
966-
this.headerComponent.columns = [...this._internalColumns];
966+
this._internalColumns = [...this._internalColumns];
967967
}
968968

969969
return columns;

projects/ngx-datatable/src/lib/components/header/header-cell.component.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
TemplateRef,
1111
input,
1212
output,
13-
numberAttribute,
1413
computed,
1514
booleanAttribute
1615
} from '@angular/core';
@@ -87,7 +86,7 @@ import { nextSortDir } from '../../utils/sort';
8786
'[attr.title]': 'name()',
8887
'[attr.tabindex]': 'column().sortable ? 0 : -1',
8988
'[class]': 'columnCssClasses()',
90-
'[style.height.px]': 'headerHeight()',
89+
'[style.height]': 'headerHeight() === "auto" ? "auto" : headerHeight() + "px"',
9190
'[style.minWidth.px]': 'column().minWidth',
9291
'[style.maxWidth.px]': 'column().maxWidth',
9392
'[style.width.px]': 'column().width'
@@ -108,9 +107,7 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy {
108107
readonly allRowsSelected = input(false, { transform: booleanAttribute });
109108
readonly selectionType = input<SelectionType>();
110109
readonly column = input.required<TableColumnInternal>();
111-
readonly headerHeight = input.required<number, number>({
112-
transform: numberAttribute
113-
});
110+
readonly headerHeight = input.required<'auto' | number>();
114111
readonly sorts = input<SortPropDir[]>([]);
115112

116113
readonly sort = output<InnerSortEvent>();

projects/ngx-datatable/src/lib/components/header/header.component.spec.ts

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ describe('DataTableHeaderComponent', () => {
1414

1515
beforeEach(async () => {
1616
fixture = TestBed.createComponent(DataTableHeaderComponent);
17+
fixture.componentRef.setInput('columns', []);
18+
fixture.componentRef.setInput('innerWidth', 200);
19+
fixture.componentRef.setInput('sorts', []);
20+
fixture.componentRef.setInput('sortType', 'single');
21+
fixture.componentRef.setInput('headerHeight', 50);
22+
fixture.componentRef.setInput('ariaHeaderCheckboxMessage', 'Select all rows');
23+
1724
harness = await TestbedHarnessEnvironment.harnessForFixture(fixture, HeaderHarness);
1825
componentRef = fixture.componentRef;
1926
});
@@ -76,7 +83,7 @@ describe('DataTableHeaderComponent', () => {
7683
componentRef.instance.resizing.subscribe(event => {
7784
const { column, newValue } = event;
7885
column.width = newValue;
79-
componentRef.setInput('columns', [...componentRef.instance.columns]);
86+
componentRef.setInput('columns', [...componentRef.instance.columns()]);
8087
});
8188

8289
const initialWidth = await harness.getColumnWidth(0);
@@ -175,51 +182,64 @@ describe('DataTableHeaderComponent', () => {
175182

176183
componentRef.instance.reorder.subscribe(event => {
177184
const { newValue, prevValue } = event;
178-
const columns = componentRef.instance.columns;
185+
186+
// Get fresh reference to columns
187+
const currentColumns = [...componentRef.instance.columns()];
179188
const columnIndex = prevValue;
180-
const movedColumn = columns.splice(columnIndex, 1)[0];
181-
columns.splice(newValue, 0, movedColumn);
182-
componentRef.setInput('columns', columns);
183-
// TODO remove this once we migrate to signal inputs
184-
componentRef.instance.columns = columns;
189+
const movedColumn = currentColumns.splice(columnIndex, 1)[0];
190+
currentColumns.splice(newValue, 0, movedColumn);
191+
192+
// Update columns
193+
componentRef.setInput('columns', currentColumns);
194+
tick();
185195
});
186196

197+
fixture.detectChanges();
187198
tick();
188-
const headerCells = fixture.debugElement.queryAll(By.css('.draggable'));
199+
const headerCells = fixture.debugElement.queryAll(By.css('datatable-header-cell.draggable'));
189200

201+
// Get the first cell (Column 1) that we want to drag
190202
const firstCell = headerCells[0].nativeElement;
191-
const clientRect = (firstCell as HTMLElement).getBoundingClientRect();
203+
const secondCell = headerCells[1].nativeElement;
204+
205+
// Get positions
206+
const firstRect = firstCell.getBoundingClientRect();
207+
const secondRect = secondCell.getBoundingClientRect();
192208

209+
// Start drag on first cell
193210
const mouseDownEvent = new MouseEvent('mousedown', {
194-
clientX: clientRect.x,
195-
screenX: clientRect.x,
196-
clientY: clientRect.y,
197-
screenY: clientRect.y,
211+
clientX: firstRect.left + firstRect.width / 2,
212+
clientY: firstRect.top + firstRect.height / 2,
198213
bubbles: true
199214
});
200215
firstCell.dispatchEvent(mouseDownEvent);
216+
fixture.detectChanges();
201217

202-
// Wait 500ms after mousedown to consider it as long press
203-
await new Promise(resolve => setTimeout(resolve, 500));
204-
218+
// Wait for drag start delay
219+
tick(500);
205220
fixture.detectChanges();
206221

222+
// Move to the second cell position
207223
const mouseMoveEvent = new MouseEvent('mousemove', {
208-
clientX: clientRect.x + 200,
209-
screenX: clientRect.x + 200,
210-
clientY: clientRect.y,
211-
screenY: clientRect.y
224+
clientX: secondRect.left + secondRect.width / 2,
225+
clientY: secondRect.top + secondRect.height / 2,
226+
bubbles: true
212227
});
213228
document.dispatchEvent(mouseMoveEvent);
229+
fixture.detectChanges();
230+
tick();
214231

232+
// End drag
215233
const mouseUpEvent = new MouseEvent('mouseup', {
216-
clientX: clientRect.x + 200,
217-
screenX: clientRect.x + 200,
218-
clientY: clientRect.y,
219-
screenY: clientRect.y
234+
clientX: secondRect.left + secondRect.width / 2,
235+
clientY: secondRect.top + secondRect.height / 2,
236+
bubbles: true
220237
});
221238
document.dispatchEvent(mouseUpEvent);
222239

240+
// Allow time for any async operations
241+
tick(200);
242+
223243
expect(await harness.getColumnName(0)).toBe('Column 2');
224244
expect(await harness.getColumnName(1)).toBe('Column 1');
225245
expect(await harness.getColumnName(2)).toBe('Column 3');
@@ -236,14 +256,14 @@ describe('DataTableHeaderComponent', () => {
236256
])
237257
);
238258
const leftGroupStyle = await harness.getTransformStyle('left');
239-
expect(leftGroupStyle).toBe('');
259+
expect(leftGroupStyle).toBe('width: 100px;');
240260
componentRef.setInput('offsetX', 100);
241261

242262
expect(await harness.getTransformStyle('left')).toBe(leftGroupStyle);
243263

244264
const centerGroupStyle = await harness.getTransformStyle('center');
245265
expect(centerGroupStyle).toContain('translateX(-100px)');
246266

247-
expect(await harness.getTransformStyle('right')).toBe('');
267+
expect(await harness.getTransformStyle('right')).toBe('width: 200px;');
248268
});
249269
});

0 commit comments

Comments
 (0)