diff --git a/docs/src/components-spec.json b/docs/src/components-spec.json index eb7556a966..af5fe9039c 100644 --- a/docs/src/components-spec.json +++ b/docs/src/components-spec.json @@ -336,7 +336,9 @@ "object-table": "checkbox", "epmty-message": "text" }, - "events": {} + "events": { + "selectionChanged": "Fired when table row was selected/unselected" + } }, "typography": {}, "color": {} diff --git a/src/components/beta/gux-table/example.html b/src/components/beta/gux-table/example.html index 48731a7434..c4f5222889 100644 --- a/src/components/beta/gux-table/example.html +++ b/src/components/beta/gux-table/example.html @@ -244,4 +244,49 @@

Data table with scroll

+ + +

Object table with rows selection

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First nameLast nameAgeAction
JohnDoe25Delete
JaneDoe23Delete
JaneDoe21Delete
JaneDoe23Delete
\ No newline at end of file diff --git a/src/components/beta/gux-table/gux-row-select/gux-row-select.tsx b/src/components/beta/gux-table/gux-row-select/gux-row-select.tsx new file mode 100644 index 0000000000..6e3579a120 --- /dev/null +++ b/src/components/beta/gux-table/gux-row-select/gux-row-select.tsx @@ -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 ; + } +} diff --git a/src/components/beta/gux-table/gux-row-select/readme.md b/src/components/beta/gux-table/gux-row-select/readme.md new file mode 100644 index 0000000000..721b8e1421 --- /dev/null +++ b/src/components/beta/gux-table/gux-row-select/readme.md @@ -0,0 +1,30 @@ +# gux-row-select + + + + + + +## Events + +| Event | Description | Type | +| ----------- | ----------- | ------------------ | +| `selectRow` | | `CustomEvent` | + + +## 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/)* diff --git a/src/components/beta/gux-table/gux-table.less b/src/components/beta/gux-table/gux-table.less index e94e2de185..9329d33cff 100644 --- a/src/components/beta/gux-table/gux-table.less +++ b/src/components/beta/gux-table/gux-table.less @@ -9,6 +9,7 @@ @gux-table-row-hover: rgba(117, 168, 255, .24); @gux-table-scroll-divider: rgba(34, 37, 41, 0.1); @gux-table-scroll-thumb: #B5B6B7; +@gux-table-row-hover-selection: fade(@gux-blue, 24%); gux-table-beta { display: block; @@ -43,6 +44,13 @@ gux-table-beta { text-align: right; } + tr[data-row-id] th:first-child, + tr[data-row-id] td:first-child { + padding-left: 12px; + padding-right: 8px; + width: 16px; + } + th:last-child, td:last-child { border-right-width: 0px; } @@ -124,7 +132,13 @@ gux-table-beta { } tr:hover { - background: @gux-table-row-hover; + background: @gux-table-row-hover-selection; + } + + tr[data-selected-row] { + td { + background: @gux-table-row-hover-selection; + } } } } diff --git a/src/components/beta/gux-table/gux-table.tsx b/src/components/beta/gux-table/gux-table.tsx index 6657498a29..31865cc785 100644 --- a/src/components/beta/gux-table/gux-table.tsx +++ b/src/components/beta/gux-table/gux-table.tsx @@ -5,7 +5,9 @@ import { Listen, Prop, readTask, - State + State, + Event, + EventEmitter } from '@stencil/core'; import { buildI18nForComponent, GetI18nValue } from '../../../i18n'; import tableResources from './i18n/en.json'; @@ -64,6 +66,11 @@ export class GuxTable { @Prop() emptyMessage: string; + /** + * Triggers when table row was selected/unselected + */ + @Event() selectionChanged: EventEmitter; + @Listen('scroll', { capture: true }) onScroll(): void { const scrollLeft = this.tableContainer.querySelector('.gux-table-container') @@ -79,6 +86,11 @@ export class GuxTable { } } + @Listen('selectRow') + onSelectRow(event): void { + this.prepareSelectableRows(event.target); + } + private get tableContainer(): HTMLElement { return this.root.children[0] as HTMLElement; } @@ -254,6 +266,69 @@ export class GuxTable { } } + private rowSelection(checkbox: HTMLGuxCheckboxElement): void { + const currentRow: HTMLElement = + checkbox.parentElement.parentElement.parentElement; + if (checkbox.checked) { + currentRow.setAttribute('data-selected-row', ''); + this.selectionChanged.emit({ + rowsIds: [currentRow.getAttribute('data-row-id')], + actionType: 'selected' + }); + } else { + currentRow.removeAttribute('data-selected-row'); + this.selectionChanged.emit({ + rowsIds: [currentRow.getAttribute('data-row-id')], + actionType: 'unselected' + }); + } + } + + private allRowsSelection(mainCheckbox: HTMLGuxCheckboxElement): void { + mainCheckbox.checked = mainCheckbox.checked ? false : true; + const rowsSelectionCheckboxes: NodeList = this.tableContainer.querySelectorAll( + 'tbody gux-checkbox' + ); + 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({ + rowsIds: allAttributes, + actionType: mainCheckbox.checked ? 'selected' : 'unselected' + }); + } + + private prepareSelectableRows(rowSelect): void { + const bodyCheckboxes: HTMLGuxCheckboxElement[] = Array.from( + this.tableContainer.querySelectorAll('tbody gux-checkbox') + ); + const isNotAllCheckboxesSelected: boolean = !!bodyCheckboxes.find( + (checkbox: HTMLGuxCheckboxElement) => { + return !checkbox.checked; + } + ); + const currentCheckbox: HTMLGuxCheckboxElement = rowSelect.children[0]; + const mainCheckbox: HTMLGuxCheckboxElement = this.tableContainer.querySelector( + 'thead gux-checkbox' + ); + mainCheckbox.checked = !isNotAllCheckboxesSelected; + if (currentCheckbox === mainCheckbox) { + this.allRowsSelection(currentCheckbox); + } else { + this.rowSelection(currentCheckbox); + } + } + render() { return (
diff --git a/src/components/beta/gux-table/readme.md b/src/components/beta/gux-table/readme.md index 9e1f847e74..81cb727119 100644 --- a/src/components/beta/gux-table/readme.md +++ b/src/components/beta/gux-table/readme.md @@ -14,6 +14,13 @@ | `objectTable` | `object-table` | Indicates that object table specific styles should be applied | `boolean` | `false` | +## Events + +| Event | Description | Type | +| ------------------ | ----------------------------------------------- | ------------------ | +| `selectionChanged` | Triggers when table row was selected/unselected | `CustomEvent` | + + ## Dependencies ### Depends on diff --git a/src/components/stable/gux-checkbox/readme.md b/src/components/stable/gux-checkbox/readme.md index 013d124efa..c54382295f 100644 --- a/src/components/stable/gux-checkbox/readme.md +++ b/src/components/stable/gux-checkbox/readme.md @@ -42,6 +42,19 @@ This component represents a checkbox with three possible states: `unchecked`, `c | `check` | Emits when the checked state changes. | `CustomEvent` | +## Dependencies + +### Used by + + - [gux-row-select](../../beta/gux-table/gux-row-select) + +### Graph +```mermaid +graph TD; + gux-row-select --> gux-checkbox + style gux-checkbox fill:#f9f,stroke:#333,stroke-width:4px +``` + ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)*