Skip to content
This repository was archived by the owner on Nov 10, 2020. It is now read-only.

Commit

Permalink
feat(table row selection): create gux-row-select component
Browse files Browse the repository at this point in the history
re #6
  • Loading branch information
Klimonov committed Sep 23, 2020
1 parent a8094f9 commit 7b7508a
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 101 deletions.
15 changes: 10 additions & 5 deletions src/components/beta/gux-table/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -370,33 +370,38 @@ <h1>Object table with rows selection</h1>
<gux-table object-table selectable-rows>
<table slot="data">
<thead>
<tr>
<tr data-row-id="head">
<th><gux-row-select></gux-row-select></th>
<th data-column-name="first-name">First name</th>
<th data-column-name="last-name">Last name</th>
<th data-column-name="age" data-cell-numeric>Age</th>
<th data-column-name="action" data-cell-action>Action</th>
</tr>
</thead>
<tbody>
<tr>
<tr data-row-id="1id">
<td><gux-row-select></gux-row-select></td>
<td>John</td>
<td>Doe</td>
<td data-cell-numeric>25</td>
<td data-cell-action>Delete</td>
</tr>
<tr>
<tr data-row-id="2id">
<td><gux-row-select></gux-row-select></td>
<td>Jane</td>
<td>Doe</td>
<td data-cell-numeric>23</td>
<td data-cell-action>Delete</td>
</tr>
<tr>
<tr data-row-id="3id">
<td><gux-row-select></gux-row-select></td>
<td>Jane</td>
<td>Doe</td>
<td data-cell-numeric>21</td>
<td data-cell-action>Delete</td>
</tr>
<tr>
<tr data-row-id="3id">
<td><gux-row-select></gux-row-select></td>
<td>Jane</td>
<td>Doe</td>
<td data-cell-numeric>23</td>
Expand Down
17 changes: 17 additions & 0 deletions src/components/beta/gux-table/gux-row-select/gux-row-select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Component, h, Event, EventEmitter } from '@stencil/core';

@Component({
tag: 'gux-row-select'
})
export class GuxRowSelect {
@Event()
selectRow: EventEmitter;

private handlerCheck(): void {
this.selectRow.emit();
}

render() {
return <gux-checkbox onCheck={this.handlerCheck.bind(this)}></gux-checkbox>;
}
}
30 changes: 30 additions & 0 deletions src/components/beta/gux-table/gux-row-select/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# gux-row-select



<!-- Auto Generated Below -->


## Events

| Event | Description | Type |
| ----------- | ----------- | ------------------ |
| `selectRow` | | `CustomEvent<any>` |


## Dependencies

### Depends on

- [gux-checkbox](../../../stable/gux-checkbox)

### Graph
```mermaid
graph TD;
gux-row-select --> gux-checkbox
style gux-row-select fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
6 changes: 3 additions & 3 deletions src/components/beta/gux-table/gux-table.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@gux-table-scroll-divider: rgba(34, 37, 41, 0.1);
@gux-table-scroll-thumb: #B5B6B7;
@gux-table-scroll-thumb-hover: #555d66;
@gux-table-row-hover-selection: fade(@gux-genesys-blue, 24%);
@gux-table-row-hover-selection: fade(@gux-blue, 24%);
@gux-table-background-secondary: #f8f8f8;
@gux-table-column-sort-hover: #98a7b8;
@gux-table-empty-message: #9baab8;
Expand Down Expand Up @@ -46,8 +46,8 @@ gux-table {
text-align: right;
}

th[data-cell-row-selection],
td[data-cell-row-selection] {
tr[data-row-id] th:first-child,
tr[data-row-id] td:first-child {
padding-left: 12px;
padding-right: 8px;
width: 16px;
Expand Down
133 changes: 44 additions & 89 deletions src/components/beta/gux-table/gux-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ export class GuxTable {
}
}

@Listen('selectRow')
onSelectRow(event): void {
this.prepareSelectableRows(event.target);
}

private get tableContainer(): HTMLElement {
return this.root.children[0] as HTMLElement;
}
Expand Down Expand Up @@ -419,115 +424,69 @@ export class GuxTable {
tableContainerElement.scrollHeight > tableContainerElement.clientHeight;
}

private handleRowSelection(event: CustomEvent): void {
const checkboxElement = event.target as HTMLElement;
const currentRow = checkboxElement.parentElement
.parentElement as HTMLTableRowElement;

if (event.detail) {
private rowSelection(checkbox: HTMLGuxCheckboxElement): void {
const currentRow: HTMLElement =
checkbox.parentElement.parentElement.parentElement;
if (checkbox.checked) {
currentRow.setAttribute('data-selected-row', '');

this.selectionChanged.emit({
rowsIndices: [currentRow.rowIndex - 1],
rowsIndices: [currentRow.getAttribute('data-row-id')],
actionType: 'selected'
});
} else {
currentRow.removeAttribute('data-selected-row');

this.selectionChanged.emit({
rowsIndices: [currentRow.rowIndex - 1],
rowsIndices: [currentRow.getAttribute('data-row-id')],
actionType: 'unselected'
});
}
}

const rowsSelectionCheckboxes = Array.from(
this.tableContainer.querySelectorAll('tbody gux-checkbox')
private allRowsSelection(mainCheckbox: HTMLGuxCheckboxElement): void {
mainCheckbox.checked = mainCheckbox.checked ? false : true;
const rowsSelectionCheckboxes: NodeList = this.tableContainer.querySelectorAll(
'tbody gux-checkbox'
);
const isAllCheckboxesSelected = rowsSelectionCheckboxes.every(
(checkbox: HTMLGuxCheckboxElement) => {
return checkbox.checked;
const allAttributes: string[] = [];
rowsSelectionCheckboxes.forEach((checkbox: HTMLGuxCheckboxElement) => {
const parentTrElement: HTMLElement =
checkbox.parentElement.parentElement.parentElement;
allAttributes.push(parentTrElement.getAttribute('data-row-id'));
if (mainCheckbox.checked) {
checkbox.checked = true;
parentTrElement.setAttribute('data-selected-row', '');
} else {
checkbox.checked = false;
parentTrElement.removeAttribute('data-selected-row');
}
});
this.selectionChanged.emit({
rowsIndices: allAttributes,
actionType: mainCheckbox.checked ? 'selected' : 'unselected'
});
}

private prepareSelectableRows(rowSelect): void {
const bodyCheckboxes: HTMLGuxCheckboxElement[] = Array.from(
this.tableContainer.querySelectorAll('tbody gux-checkbox')
);
const isSomeCheckboxUnselected = rowsSelectionCheckboxes.some(
const isNotAllCheckboxesSelected: boolean = !!bodyCheckboxes.find(
(checkbox: HTMLGuxCheckboxElement) => {
return !checkbox.checked;
}
);

const allRowsSelectionCheckbox = this.tableContainer.querySelector(
const currentCheckbox: HTMLGuxCheckboxElement = rowSelect.children[0];
const mainCheckbox: HTMLGuxCheckboxElement = this.tableContainer.querySelector(
'thead gux-checkbox'
) as HTMLGuxCheckboxElement;
if (isAllCheckboxesSelected) {
allRowsSelectionCheckbox.checked = true;
} else if (allRowsSelectionCheckbox.checked && isSomeCheckboxUnselected) {
allRowsSelectionCheckbox.checked = false;
}
}

private handleAllRowsSelection(event: CustomEvent): void {
const rowSelectionCells = Array.from(
this.tableContainer.querySelectorAll('td[data-cell-row-selection]')
);
const tableRows = Array.from(
this.tableContainer.querySelectorAll('tbody tr')
);

if (event.detail) {
rowSelectionCells.forEach((cell: HTMLElement) => {
cell.children[0].setAttribute('checked', '');
});
tableRows.forEach((row: HTMLElement) => {
row.setAttribute('data-selected-row', '');
});

this.selectionChanged.emit({
rowsIndices: [...Array(rowSelectionCells.length).keys()],
actionType: 'selected'
});
mainCheckbox.checked = !isNotAllCheckboxesSelected;
if (currentCheckbox === mainCheckbox) {
this.allRowsSelection(currentCheckbox);
} else {
rowSelectionCells.forEach((cell: HTMLElement) => {
cell.children[0].removeAttribute('checked');
});
tableRows.forEach((row: HTMLElement) => {
row.removeAttribute('data-selected-row');
});

this.selectionChanged.emit({
rowsIndices: [...Array(rowSelectionCells.length).keys()],
actionType: 'unselected'
});
this.rowSelection(currentCheckbox);
}
}

private prepareSelectableRows(): void {
const tableHead = this.tableContainer.querySelector('thead tr');
const tableBody = this.tableContainer.querySelectorAll('tbody tr');
const rowsSelectionCheckbox = document.createElement('gux-checkbox');
const rowsSelectionColumn = document.createElement('th');

rowsSelectionColumn.setAttribute('data-cell-row-selection', '');
rowsSelectionColumn.appendChild(rowsSelectionCheckbox);
tableHead.prepend(rowsSelectionColumn);

rowsSelectionCheckbox.addEventListener(
'check',
this.handleAllRowsSelection.bind(this)
);

tableBody.forEach((row: HTMLElement) => {
const rowSelectionCell = document.createElement('td');
const rowSelectionCheckbox = document.createElement('gux-checkbox');
rowSelectionCell.setAttribute('data-cell-row-selection', '');
rowSelectionCell.appendChild(rowSelectionCheckbox);
row.prepend(rowSelectionCell);

rowSelectionCheckbox.addEventListener(
'check',
this.handleRowSelection.bind(this)
);
});
}

async componentWillLoad(): Promise<void> {
this.i18n = await buildI18nForComponent(this.root, tableResources);
if (!this.emptyMessage) {
Expand All @@ -540,10 +499,6 @@ export class GuxTable {
this.reorderColumns();
}

if (this.selectableRows && this.objectTable) {
this.prepareSelectableRows();
}

this.prepareSortableColumns();

if (this.resizableColumns) {
Expand Down
2 changes: 0 additions & 2 deletions src/components/beta/gux-table/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@
### Depends on

- [gux-icon](../../stable/gux-icon)
- [gux-checkbox](../../stable/gux-checkbox)

### Graph
```mermaid
graph TD;
gux-table --> gux-icon
gux-table --> gux-checkbox
style gux-table fill:#f9f,stroke:#333,stroke-width:4px
```

Expand Down
4 changes: 2 additions & 2 deletions src/components/stable/gux-checkbox/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ This component represents a checkbox with three possible states: `unchecked`, `c

### Used by

- [gux-table](../../beta/gux-table)
- [gux-row-select](../../beta/gux-table/gux-row-select)

### Graph
```mermaid
graph TD;
gux-table --> gux-checkbox
gux-row-select --> gux-checkbox
style gux-checkbox fill:#f9f,stroke:#333,stroke-width:4px
```

Expand Down

0 comments on commit 7b7508a

Please sign in to comment.