Add royal-table components
This commit is contained in:
parent
4da33d6dfc
commit
86a1572b0c
7 changed files with 176 additions and 0 deletions
25
app/components/royal-table.hbs
Normal file
25
app/components/royal-table.hbs
Normal 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>
|
||||
17
app/components/royal-table.js
Normal file
17
app/components/royal-table.js
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
46
app/components/royal-table/column.hbs
Normal file
46
app/components/royal-table/column.hbs
Normal 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}}
|
||||
51
app/components/royal-table/column.js
Normal file
51
app/components/royal-table/column.js
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
app/components/royal-table/column/sorting-icon.hbs
Normal file
11
app/components/royal-table/column/sorting-icon.hbs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<span ...attributes>
|
||||
{{#if @sortable}}
|
||||
{{#if @isAscSorted}}
|
||||
🠗
|
||||
{{else if @isDescSorted}}
|
||||
🠕
|
||||
{{else}}
|
||||
⬍
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
23
app/components/royal-table/row.hbs
Normal file
23
app/components/royal-table/row.hbs
Normal 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}}
|
||||
3
app/components/royal-table/row.js
Normal file
3
app/components/royal-table/row.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export default class RoyalTableRowComponent extends Component {}
|
||||
Loading…
Reference in a new issue