Skip to content

Commit

Permalink
feat(comparison-table): popular cell for mobile view (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
snoopy-cat authored and GitHub Enterprise committed Sep 28, 2020
1 parent 8d42e7f commit 4e84871
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export abstract class NxComparisonTableBase implements OnDestroy {
/** How many product columns the table has. */
abstract _infoColumnCount();

/** Get the popular cell of the table. */
abstract _getPopularCell();

/** Add a column to the list of disabled columns. */
abstract _addDisabledColumn(disabledColumn: number);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,45 +94,89 @@

<!-- row for every product -->
<!-- intersection cells have to be placed in first row -->
<tr [class.is-disabled]="_isMobileRowDisabled(headerIndex)" *ngFor="let headerCell of _getHeaderCells(); let headerIndex = index">
<ng-container *ngTemplateOutlet="headerCell._content"></ng-container>
<ng-container *ngFor="let element of elements; let infoIndex = index">
<ng-container *ngIf="_isRow(element) && !element._isPartOfToggleSection()">
<!-- we need the extra ng-container or VE will fail because of the _isRow method -->
<ng-container *ngIf="infoIndex > 0 && infoIndex < _getMobileColumnCount()">
<!-- placeholder cell if this is a new block of info rows -->
<ng-container *ngIf="_isFirstInfoOfBlock(infoIndex)">
<td class="nx-comparison-table__placeholder-cell" aria-hidden="true"></td>
</ng-container>
<ng-container *ngFor="let headerCell of _getHeaderCells(); let headerIndex = index">
<tr *ngIf="_getPopularCell() && _getPopularCell().forColumn === headerIndex + 1" class="nx-comparison-table__popular-row">
<ng-container *ngTemplateOutlet="_getPopularCell()._content"></ng-container>

<!-- if first mobile row: show intersection cells -->
<ng-container *ngIf="headerIndex === 0 && element.intersectionCell">
<ng-container *ngTemplateOutlet="element?.intersectionCell?._content"></ng-container>
<ng-container *ngFor="let element of elements; let infoIndex = index">
<ng-container *ngIf="_isRow(element) && !element._isPartOfToggleSection()">
<!-- we need the extra ng-container or VE will fail because of the _isRow method -->
<ng-container *ngIf="infoIndex > 0 && infoIndex < _getMobileColumnCount()">
<!-- placeholder cell if this is a new block of info rows -->
<ng-container *ngIf="_isFirstInfoOfBlock(infoIndex)">
<td class="nx-comparison-table__placeholder-cell" aria-hidden="true"></td>
</ng-container>
<!-- if there is an intersection cell, we need a marker so that we know we have to place a left border to the next cell -->
<ng-container *ngIf="element.intersectionCell">
<div class="nx-comparison-table__intersection-cell-marker"></div>
</ng-container>
<!-- placeholder cell for every cell of the row, except intersection cells -->
<ng-container *ngIf="element.cells.length > 0">
<td class="nx-comparison-table__placeholder-with-border-cell" aria-hidden="true"></td>
</ng-container>
</ng-container>
<ng-container *ngIf="element.cells.length > 0">
<ng-container *ngTemplateOutlet="element.cells.toArray()[headerIndex]?._content"></ng-container>
</ng-container>

<ng-container *ngIf="_isToggleSection(element)">
<td class="nx-comparison-table__placeholder-cell" aria-hidden="true"></td>
<ng-container *ngFor="let row of element.rows">
<ng-container *ngIf="_isRow(row)">
<!-- if there is an intersection cell, we need a marker so that we know we have to place a left border to the next cell -->
<ng-container *ngIf="row.intersectionCell">
<div class="nx-comparison-table__intersection-cell-marker"></div>
</ng-container>
<!-- placeholder cell for every cell of the row, except intersection cells -->
<ng-container *ngIf="row.cells.length > 0">
<td class="nx-comparison-table__placeholder-with-border-cell" aria-hidden="true"></td>
</ng-container>
</ng-container>
</ng-container>
</ng-container>

</ng-container>
</tr>

<tr [class.is-disabled]="_isMobileRowDisabled(headerIndex)">
<ng-container *ngTemplateOutlet="headerCell._content"></ng-container>
<ng-container *ngFor="let element of elements; let infoIndex = index">
<ng-container *ngIf="_isRow(element) && !element._isPartOfToggleSection()">
<!-- we need the extra ng-container or VE will fail because of the _isRow method -->
<ng-container *ngIf="infoIndex > 0 && infoIndex < _getMobileColumnCount()">
<!-- placeholder cell if this is a new block of info rows -->
<ng-container *ngIf="_isFirstInfoOfBlock(infoIndex)">
<td class="nx-comparison-table__placeholder-cell" aria-hidden="true"></td>
</ng-container>

<ng-container *ngIf="_isToggleSection(element)">
<td class="nx-comparison-table__placeholder-cell" aria-hidden="true"></td>
<ng-container *ngFor="let row of element.rows">
<ng-container *ngIf="_isRow(row)">
<!-- if first mobile row: show intersection cells -->
<ng-container *ngIf="headerIndex === 0 && row.intersectionCell">
<ng-container *ngTemplateOutlet="row.intersectionCell._content">
</ng-container>
<ng-container *ngIf="headerIndex === 0 && element.intersectionCell">
<ng-container *ngTemplateOutlet="element?.intersectionCell?._content"></ng-container>
</ng-container>
<ng-container *ngIf="element.cells.length > 0">
<ng-container *ngTemplateOutlet="element.cells.toArray()[headerIndex]?._content"></ng-container>
</ng-container>
</ng-container>
</ng-container>

<ng-container *ngIf="row.cells.length > 0">
<ng-container *ngTemplateOutlet="row.cells.toArray()[headerIndex]._content"></ng-container>
<ng-container *ngIf="_isToggleSection(element)">
<td class="nx-comparison-table__placeholder-cell" aria-hidden="true"></td>
<ng-container *ngFor="let row of element.rows">
<ng-container *ngIf="_isRow(row)">
<!-- if first mobile row: show intersection cells -->
<ng-container *ngIf="headerIndex === 0 && row.intersectionCell">
<ng-container *ngTemplateOutlet="row.intersectionCell._content">
</ng-container>
</ng-container>

<ng-container *ngIf="row.cells.length > 0">
<ng-container *ngTemplateOutlet="row.cells.toArray()[headerIndex]._content"></ng-container>
</ng-container>
</ng-container>
</ng-container>
</ng-container>

</ng-container>
</tr>
</ng-container>

</ng-container>
</tr>
</table>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,13 @@
@include var(background-color, comparison-table-cell-background-color);
}

.nx-comparison-table__mobile-popular-cell {
@include type-style(comparison-table-popular-cell);
@include var(background-color, comparison-table-popular-cell-background-color);
@include var(color, comparison-table-popular-cell-text-color);
padding: 4px;
}

.nx-comparison-table__mobile-header-cell {
padding: 8px 4px;

Expand All @@ -314,6 +321,25 @@
}
}

.nx-comparison-table__mobile-popular-cell,
.nx-comparison-table__placeholder-with-border-cell {
border-top: nx-border-size(xs) solid v(comparison-table-border-color);
}

.nx-comparison-table__intersection-cell-marker {
display: none;
}

.nx-comparison-table__intersection-cell-marker + .nx-comparison-table__placeholder-with-border-cell {
@include break-out(&, 'ltr') {
border-left: nx-border-size(xs) solid v(comparison-table-border-color);
}

@include break-out(&, 'rtl') {
border-right: nx-border-size(xs) solid v(comparison-table-border-color);
}
}

tr:last-child {

.nx-comparison-table__cell,
Expand All @@ -338,7 +364,7 @@
}

tr th:last-child,
tr td:last-child {
tr td:last-child:not(.nx-comparison-table__placeholder-with-border-cell) {
@include break-out(&, 'ltr') {
border-right: nx-border-size(xs) solid v(comparison-table-border-color);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { NxComparisonTableBase } from './comparison-table-base';
import { NxToggleSectionAnimations } from './toggle-section/toggle-section-animations';
import { NxComparisonTableRowGroupDirective } from './comparison-table-row-group.directive';
import { NxViewportService } from '@aposin/ng-aquila/utils';
import { NxComparisonTablePopularCell } from './popular-cell/popular-cell.component';

@Component({
selector: 'nx-comparison-table',
Expand Down Expand Up @@ -168,6 +169,13 @@ export class NxComparisonTableComponent extends NxComparisonTableBase implements
return (row as NxComparisonTableRowDirective).cells.toArray();
}

_getPopularCell(): NxComparisonTablePopularCell {
const row = this.elements.find(element =>
this._isRow(element) && (element as NxComparisonTableRowDirective).type === 'header'
);
return (row as NxComparisonTableRowDirective).popularCell;
}

_getFooterCells(): NxComparisonTableCell[] {
const row = this.elements.find(element =>
this._isRow(element) && (element as NxComparisonTableRowDirective).type === 'footer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</ng-container>
<ng-container *ngIf="_table.viewType === 'mobile'">
<td class="nx-comparison-table__intersection-cell"
[attr.rowspan]="_table._infoColumnCount()"
[attr.rowspan]="_getMobileRowspan()"
[attr.headers]="_getHeaderIds()">
<ng-container *ngTemplateOutlet="ngContent"></ng-container>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@ export class NxComparisonTableIntersectionCell {
return headers;
}

_getMobileRowspan() {
return this._table._getPopularCell() ? this._table._infoColumnCount() + 1 : this._table._infoColumnCount();
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
<ng-template #content>
<div class="nx-comparison-table__popular-cell" role="cell" [attr.id]="id">
<div class="nx-comparison-table__cell-content">
<ng-content></ng-content>
<ng-container *ngIf="_table.viewType === 'desktop' || _table.viewType === 'tablet'">
<div class="nx-comparison-table__popular-cell" role="cell" [attr.id]="id">
<div class="nx-comparison-table__cell-content">
<ng-container *ngTemplateOutlet="ngContent"></ng-container>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="_table.viewType === 'mobile'">
<td class="nx-comparison-table__mobile-popular-cell" [attr.id]="id">
<ng-container *ngTemplateOutlet="ngContent"></ng-container>
</td>
</ng-container>
</ng-template>


<ng-template #ngContent>
<ng-content></ng-content>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,32 @@ describe('NxComparisonTablePopularCell', () => {
expect(placeholderCells.length).toBe(2);
}));

it('should not display on mobile', fakeAsync(() => {
it('should display cell on mobile', fakeAsync(() => {
createTestComponent(PopularCellComponent);
viewport.set('mobile');
window.dispatchEvent(new Event('resize'));
tick(THROTTLE_TIME);
fixture.detectChanges();

const popularCell = fixture.debugElement.query(By.css('.nx-comparison-table__popular-cell'));
expect(popularCell).toBe(null);
const popularCell = fixture.debugElement.query(By.css('.nx-comparison-table__mobile-popular-cell'));
expect(popularCell).toBeDefined();
expect(popularCell.nativeElement.textContent).toBe('Popular cell');
}));

it('should have the correct number of placeholder cells in the popular cell row (mobile)', fakeAsync(() => {
createTestComponent(PopularCellComponent);
viewport.set('mobile');
window.dispatchEvent(new Event('resize'));
tick(THROTTLE_TIME);
fixture.detectChanges();

const popularRow = fixture.debugElement.query(By.css('.nx-comparison-table__popular-row'));
expect(popularRow).toBeDefined();

const placeholderCells = popularRow.nativeElement.querySelectorAll('.nx-comparison-table__placeholder-cell');
expect(placeholderCells.length).toBe(1);
const emptyCells = popularRow.nativeElement.querySelectorAll('.nx-comparison-table__placeholder-with-border-cell');
expect(emptyCells.length).toBe(1);
}));

afterEach(() => viewport.reset());
Expand Down

0 comments on commit 4e84871

Please sign in to comment.