Add royal-table components

This commit is contained in:
Stanislav Romanov 2022-04-26 12:41:33 +03:00
parent 4da33d6dfc
commit 86a1572b0c
7 changed files with 176 additions and 0 deletions

View file

@ -0,0 +1,25 @@
<table class="royal-table" ...attributes>
{{#if @caption}}
<caption>
{{@caption}}
</caption>
{{/if}}
<thead>
{{yield
(component
'royal-table/row'
place='head'
onClickHead=@onClickHead
onSort=@onSort
sortingProp=@sortingProp
sortingIconComponent=@sortingIconComponent
parent=this
)
}}
</thead>
<tbody>
{{#each @data as |item index|}}
{{yield (component 'royal-table/row' place='body' data=item parent=this) item index}}
{{/each}}
</tbody>
</table>

View file

@ -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);
}
}
}

View file

@ -0,0 +1,46 @@
{{#if this.isHead}}
{{! template-lint-disable no-invalid-interactive }}
<th
role={{if @sortable 'button'}}
align={{@align}}
...attributes
{{on 'click' this.handleClickHead}}
{{on 'click' this.handleSort}}
{{! DOTO: align is depricated, use styles align instead }}
>
{{#if @sortable}}
{{! TODO: add ensure-safe-component }}
{{#let
(if
@sortingIconComponent
(component @sortingIconComponent)
(component 'royal-table/column/sorting-icon')
) as |SortingIcon|
}}
<SortingIcon
@sortable={{@sortable}}
@isSorted={{this.isSorted}}
@isAscSorted={{this.isAscSorted}}
@isDescSorted={{this.isDescSorted}}
/>
{{/let}}
{{/if}}
{{#if (has-block 'name')}}
{{yield to='name'}}
{{else}}
{{@name}}
{{/if}}
</th>
{{else if this.isBody}}
<td align={{@align}} ...attributes>
{{#if (has-block)}}
{{yield}}
{{else if @bodyComponent}}
{{#let (component @bodyComponent) as |BodyComponent|}}
<BodyComponent @data={{@data}} />
{{/let}}
{{else}}
{{get @data @prop}}
{{/if}}
</td>
{{/if}}

View file

@ -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);
}
}
}

View file

@ -0,0 +1,11 @@
<span ...attributes>
{{#if @sortable}}
{{#if @isAscSorted}}
🠗
{{else if @isDescSorted}}
🠕
{{else}}
⬍
{{/if}}
{{/if}}
</span>

View file

@ -0,0 +1,23 @@
<tr ...attributes>
{{yield
(component
'royal-table/column'
place=@place
prop=@prop
sortable=@sortable
onClickHead=@onClickHead
onSort=@onSort
sortingProp=@sortingProp
sortingIconComponent=@sortingIconComponent
data=@data
parent=@parent
)
}}
</tr>
{{#if (has-block 'expandedView')}}
{{#if @data.expanded}}
<tr>
<td colspan={{@parent.columns.length}}>{{yield to="expandedView"}}</td>
</tr>
{{/if}}
{{/if}}

View file

@ -0,0 +1,3 @@
import Component from '@glimmer/component';
export default class RoyalTableRowComponent extends Component {}