From 86a1572b0c2f0ed97ca093fa1c77ab2fabe9e58b Mon Sep 17 00:00:00 2001 From: Stanislav Romanov Date: Tue, 26 Apr 2022 12:41:33 +0300 Subject: [PATCH] Add royal-table components --- app/components/royal-table.hbs | 25 +++++++++ app/components/royal-table.js | 17 +++++++ app/components/royal-table/column.hbs | 46 +++++++++++++++++ app/components/royal-table/column.js | 51 +++++++++++++++++++ .../royal-table/column/sorting-icon.hbs | 11 ++++ app/components/royal-table/row.hbs | 23 +++++++++ app/components/royal-table/row.js | 3 ++ 7 files changed, 176 insertions(+) create mode 100644 app/components/royal-table.hbs create mode 100644 app/components/royal-table.js create mode 100644 app/components/royal-table/column.hbs create mode 100644 app/components/royal-table/column.js create mode 100644 app/components/royal-table/column/sorting-icon.hbs create mode 100644 app/components/royal-table/row.hbs create mode 100644 app/components/royal-table/row.js diff --git a/app/components/royal-table.hbs b/app/components/royal-table.hbs new file mode 100644 index 0000000..e35b5d4 --- /dev/null +++ b/app/components/royal-table.hbs @@ -0,0 +1,25 @@ + + {{#if @caption}} + + {{/if}} + + {{yield + (component + 'royal-table/row' + place='head' + onClickHead=@onClickHead + onSort=@onSort + sortingProp=@sortingProp + sortingIconComponent=@sortingIconComponent + parent=this + ) + }} + + + {{#each @data as |item index|}} + {{yield (component 'royal-table/row' place='body' data=item parent=this) item index}} + {{/each}} + +
+ {{@caption}} +
diff --git a/app/components/royal-table.js b/app/components/royal-table.js new file mode 100644 index 0000000..c495a4d --- /dev/null +++ b/app/components/royal-table.js @@ -0,0 +1,17 @@ +import Component from '@glimmer/component'; + +export default class RoyalTableComponent extends Component { + columns = []; + + registerColumn(column) { + if (!this.columns.includes(column)) { + this.columns.push(column); + } + } + + unregisterColumn(column) { + if (this.columns.includes(column)) { + this.columns = this.columns.filter((c) => c !== column); + } + } +} diff --git a/app/components/royal-table/column.hbs b/app/components/royal-table/column.hbs new file mode 100644 index 0000000..b9650b3 --- /dev/null +++ b/app/components/royal-table/column.hbs @@ -0,0 +1,46 @@ +{{#if this.isHead}} + {{! template-lint-disable no-invalid-interactive }} + + {{#if @sortable}} + {{! TODO: add ensure-safe-component }} + {{#let + (if + @sortingIconComponent + (component @sortingIconComponent) + (component 'royal-table/column/sorting-icon') + ) as |SortingIcon| + }} + + {{/let}} + {{/if}} + {{#if (has-block 'name')}} + {{yield to='name'}} + {{else}} + {{@name}} + {{/if}} + +{{else if this.isBody}} + + {{#if (has-block)}} + {{yield}} + {{else if @bodyComponent}} + {{#let (component @bodyComponent) as |BodyComponent|}} + + {{/let}} + {{else}} + {{get @data @prop}} + {{/if}} + +{{/if}} diff --git a/app/components/royal-table/column.js b/app/components/royal-table/column.js new file mode 100644 index 0000000..4b83ae6 --- /dev/null +++ b/app/components/royal-table/column.js @@ -0,0 +1,51 @@ +import Component from '@glimmer/component'; +import { action } from '@ember/object'; + +export default class RoyalTableColumnComponent extends Component { + constructor() { + super(...arguments); + + if (this.isHead) { + this.args?.parent?.registerColumn(this); + } + } + + willDestroy() { + super.willDestroy(...arguments); + this.args?.parent?.unregisterColumn(this); + } + + get isHead() { + return this.args.place === 'head'; + } + + get isBody() { + return this.args.place === 'body'; + } + + get isSorted() { + return this.args.sortingProp && (this.isAscSorted || this.isDescSorted); + } + + get isAscSorted() { + return this.args.sortingProp === `${this.args.prop}:asc`; + } + + get isDescSorted() { + return this.args.sortingProp === `${this.args.prop}:desc`; + } + + @action + handleClickHead(e) { + if (typeof this.args.onClickHead === 'function') { + this.args.onClickHead(this.args.prop, this, e); + } + } + + @action + handleSort(e) { + if (this.args.sortable && typeof this.args.onSort === 'function') { + this.args.onSort(this.args.prop, this, e); + } + } +} diff --git a/app/components/royal-table/column/sorting-icon.hbs b/app/components/royal-table/column/sorting-icon.hbs new file mode 100644 index 0000000..8a56eb0 --- /dev/null +++ b/app/components/royal-table/column/sorting-icon.hbs @@ -0,0 +1,11 @@ + + {{#if @sortable}} + {{#if @isAscSorted}} + 🠗 + {{else if @isDescSorted}} + 🠕 + {{else}} + ⬍ + {{/if}} + {{/if}} + diff --git a/app/components/royal-table/row.hbs b/app/components/royal-table/row.hbs new file mode 100644 index 0000000..09f098c --- /dev/null +++ b/app/components/royal-table/row.hbs @@ -0,0 +1,23 @@ + + {{yield + (component + 'royal-table/column' + place=@place + prop=@prop + sortable=@sortable + onClickHead=@onClickHead + onSort=@onSort + sortingProp=@sortingProp + sortingIconComponent=@sortingIconComponent + data=@data + parent=@parent + ) + }} + +{{#if (has-block 'expandedView')}} + {{#if @data.expanded}} + + {{yield to="expandedView"}} + + {{/if}} +{{/if}} diff --git a/app/components/royal-table/row.js b/app/components/royal-table/row.js new file mode 100644 index 0000000..5bf02c7 --- /dev/null +++ b/app/components/royal-table/row.js @@ -0,0 +1,3 @@ +import Component from '@glimmer/component'; + +export default class RoyalTableRowComponent extends Component {}