@triptyk/ember-yeti-table 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +9 -115
- package/declarations/components/yeti-table/body.d.ts +32 -0
- package/declarations/components/yeti-table/body.d.ts.map +1 -0
- package/declarations/components/yeti-table/header.d.ts +33 -0
- package/declarations/components/yeti-table/header.d.ts.map +1 -0
- package/declarations/components/yeti-table/pagination.d.ts +40 -0
- package/declarations/components/yeti-table/pagination.d.ts.map +1 -0
- package/declarations/components/yeti-table/table.d.ts +21 -0
- package/declarations/components/yeti-table/table.d.ts.map +1 -0
- package/declarations/components/yeti-table/tbody/row/cell.d.ts +44 -0
- package/declarations/components/yeti-table/tbody/row/cell.d.ts.map +1 -0
- package/declarations/components/yeti-table/tbody/row.d.ts +37 -0
- package/declarations/components/yeti-table/tbody/row.d.ts.map +1 -0
- package/declarations/components/yeti-table/tbody.d.ts +29 -0
- package/declarations/components/yeti-table/tbody.d.ts.map +1 -0
- package/declarations/components/yeti-table/tfoot/row/cell.d.ts +40 -0
- package/declarations/components/yeti-table/tfoot/row/cell.d.ts.map +1 -0
- package/declarations/components/yeti-table/tfoot/row.d.ts +37 -0
- package/declarations/components/yeti-table/tfoot/row.d.ts.map +1 -0
- package/declarations/components/yeti-table/tfoot.d.ts +27 -0
- package/declarations/components/yeti-table/tfoot.d.ts.map +1 -0
- package/declarations/components/yeti-table/thead/row/cell.d.ts +54 -0
- package/declarations/components/yeti-table/thead/row/cell.d.ts.map +1 -0
- package/declarations/components/yeti-table/thead/row/column.d.ts +69 -0
- package/declarations/components/yeti-table/thead/row/column.d.ts.map +1 -0
- package/declarations/components/yeti-table/thead/row.d.ts +55 -0
- package/declarations/components/yeti-table/thead/row.d.ts.map +1 -0
- package/declarations/components/yeti-table/thead.d.ts +34 -0
- package/declarations/components/yeti-table/thead.d.ts.map +1 -0
- package/declarations/components/yeti-table.d.ts +107 -0
- package/declarations/components/yeti-table.d.ts.map +1 -0
- package/declarations/index.d.ts +1 -0
- package/declarations/index.d.ts.map +1 -0
- package/declarations/template-registry.d.ts +1 -0
- package/declarations/template-registry.d.ts.map +1 -0
- package/declarations/themes/default-theme.d.ts +3 -27
- package/declarations/themes/default-theme.d.ts.map +1 -1
- package/declarations/types.d.ts +82 -0
- package/declarations/types.d.ts.map +1 -0
- package/declarations/utils/create-regex.d.ts +1 -1
- package/declarations/utils/create-regex.d.ts.map +1 -1
- package/declarations/utils/filtering-utils.d.ts +2 -4
- package/declarations/utils/filtering-utils.d.ts.map +1 -1
- package/declarations/utils/sorting-utils.d.ts +6 -15
- package/declarations/utils/sorting-utils.d.ts.map +1 -1
- package/dist/components/yeti-table/body.js +19 -14
- package/dist/components/yeti-table/body.js.map +1 -1
- package/dist/components/yeti-table/header.js +10 -10
- package/dist/components/yeti-table/header.js.map +1 -1
- package/dist/components/yeti-table/pagination.js +14 -44
- package/dist/components/yeti-table/pagination.js.map +1 -1
- package/dist/components/yeti-table/table.js +1 -23
- package/dist/components/yeti-table/table.js.map +1 -1
- package/dist/components/yeti-table/tbody/row/cell.js +12 -12
- package/dist/components/yeti-table/tbody/row/cell.js.map +1 -1
- package/dist/components/yeti-table/tbody/row.js +15 -21
- package/dist/components/yeti-table/tbody/row.js.map +1 -1
- package/dist/components/yeti-table/tbody.js +1 -0
- package/dist/components/yeti-table/tbody.js.map +1 -1
- package/dist/components/yeti-table/tfoot/row/cell.js +9 -9
- package/dist/components/yeti-table/tfoot/row/cell.js.map +1 -1
- package/dist/components/yeti-table/tfoot/row.js +11 -11
- package/dist/components/yeti-table/tfoot/row.js.map +1 -1
- package/dist/components/yeti-table/tfoot.js +1 -0
- package/dist/components/yeti-table/tfoot.js.map +1 -1
- package/dist/components/yeti-table/thead/row/cell.js +11 -8
- package/dist/components/yeti-table/thead/row/cell.js.map +1 -1
- package/dist/components/yeti-table/thead/row/column.js +27 -128
- package/dist/components/yeti-table/thead/row/column.js.map +1 -1
- package/dist/components/yeti-table/thead/row.js +15 -15
- package/dist/components/yeti-table/thead/row.js.map +1 -1
- package/dist/components/yeti-table/thead.js +3 -22
- package/dist/components/yeti-table/thead.js.map +1 -1
- package/dist/components/yeti-table.js +99 -303
- package/dist/components/yeti-table.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/template-registry.js +2 -0
- package/dist/template-registry.js.map +1 -0
- package/dist/themes/default-theme.js +3 -2
- package/dist/themes/default-theme.js.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/create-regex.js +6 -6
- package/dist/utils/create-regex.js.map +1 -1
- package/dist/utils/filtering-utils.js +20 -8
- package/dist/utils/filtering-utils.js.map +1 -1
- package/dist/utils/sorting-utils.js +13 -18
- package/dist/utils/sorting-utils.js.map +1 -1
- package/package.json +37 -16
- package/src/components/yeti-table/{body.gjs → body.gts} +49 -45
- package/src/components/yeti-table/header.gts +67 -0
- package/src/components/yeti-table/pagination.gts +118 -0
- package/src/components/yeti-table/table.gts +27 -0
- package/src/components/yeti-table/tbody/row/{cell.gjs → cell.gts} +38 -19
- package/src/components/yeti-table/tbody/row.gts +76 -0
- package/src/components/yeti-table/tbody.gts +53 -0
- package/src/components/yeti-table/tfoot/row/cell.gts +64 -0
- package/src/components/yeti-table/tfoot/row.gts +59 -0
- package/src/components/yeti-table/tfoot.gts +41 -0
- package/src/components/yeti-table/thead/row/{cell.gjs → cell.gts} +36 -13
- package/src/components/yeti-table/thead/row/column.gts +177 -0
- package/src/components/yeti-table/thead/row.gts +105 -0
- package/src/components/yeti-table/thead.gts +65 -0
- package/src/components/yeti-table.gts +629 -0
- package/src/template-registry.ts +10 -0
- package/src/themes/{default-theme.js → default-theme.ts} +5 -1
- package/src/types.ts +94 -0
- package/src/utils/{create-regex.js → create-regex.ts} +10 -10
- package/src/utils/filtering-utils.ts +91 -0
- package/src/utils/{sorting-utils.js → sorting-utils.ts} +35 -26
- package/dist/_app_/themes/default-theme.js +0 -1
- package/dist/_app_/utils/create-regex.js +0 -1
- package/dist/_app_/utils/filtering-utils.js +0 -1
- package/dist/_app_/utils/sorting-utils.js +0 -1
- package/src/components/yeti-table/header.gjs +0 -54
- package/src/components/yeti-table/pagination.gjs +0 -155
- package/src/components/yeti-table/table.gjs +0 -34
- package/src/components/yeti-table/tbody/row.gjs +0 -89
- package/src/components/yeti-table/tbody.gjs +0 -55
- package/src/components/yeti-table/tfoot/row/cell.gjs +0 -45
- package/src/components/yeti-table/tfoot/row.gjs +0 -44
- package/src/components/yeti-table/tfoot.gjs +0 -33
- package/src/components/yeti-table/thead/row/column.gjs +0 -260
- package/src/components/yeti-table/thead/row.gjs +0 -71
- package/src/components/yeti-table/thead.gjs +0 -45
- package/src/components/yeti-table.gjs +0 -780
- package/src/utils/filtering-utils.js +0 -75
- /package/src/{.gitkeep → index.ts} +0 -0
|
@@ -1,44 +1,60 @@
|
|
|
1
1
|
import { action } from '@ember/object';
|
|
2
|
-
|
|
3
2
|
import Component from '@glimmer/component';
|
|
4
3
|
|
|
4
|
+
import { fn, get, hash } from '@ember/helper';
|
|
5
|
+
|
|
6
|
+
import type { WithBoundArgs } from '@glint/template';
|
|
7
|
+
|
|
8
|
+
import TBodyRow from './tbody/row.gts';
|
|
9
|
+
import type {
|
|
10
|
+
ColumnDefinition,
|
|
11
|
+
Row,
|
|
12
|
+
RowClickHandler,
|
|
13
|
+
Theme,
|
|
14
|
+
} from '../../types.ts';
|
|
15
|
+
|
|
5
16
|
/**
|
|
6
17
|
Renders a `<tbody>` element and yields the row component, row data and index.
|
|
7
|
-
```hbs
|
|
8
|
-
<table.body as |body person index|>
|
|
9
|
-
<body.row as |row|>
|
|
10
|
-
<row.cell>
|
|
11
|
-
{{person.firstName}} #{{index}}
|
|
12
|
-
</row.cell>
|
|
13
|
-
<row.cell>
|
|
14
|
-
{{person.lastName}}
|
|
15
|
-
</row.cell>
|
|
16
|
-
<row.cell>
|
|
17
|
-
{{person.points}}
|
|
18
|
-
</row.cell>
|
|
19
|
-
</body.row>
|
|
20
|
-
</table.body>
|
|
21
|
-
```
|
|
22
|
-
It can also be used as a blockless component to let yeti table automatically
|
|
23
|
-
unroll thee rows for you, based on the `@prop` arguments you passed in to the
|
|
24
|
-
column definition components.
|
|
25
|
-
```hbs
|
|
26
|
-
<table.body/>
|
|
27
|
-
```
|
|
28
|
-
Remember that this component's block will be rendered once per each item in the `@data` array.
|
|
29
18
|
|
|
30
19
|
@class Body
|
|
31
|
-
@yield {object} body
|
|
32
|
-
@yield {Component} body.row - the row component
|
|
33
|
-
@yield {Object} rowData - one item in the data array
|
|
34
|
-
@yield {number} index
|
|
35
20
|
*/
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
export interface BodySignature {
|
|
23
|
+
Element: HTMLTableSectionElement;
|
|
24
|
+
Args: {
|
|
25
|
+
theme?: Theme;
|
|
26
|
+
data?: Row[];
|
|
27
|
+
columns?: ColumnDefinition[];
|
|
28
|
+
onRowClick?: RowClickHandler;
|
|
29
|
+
};
|
|
30
|
+
Blocks: {
|
|
31
|
+
default: [
|
|
32
|
+
{ row: WithBoundArgs<typeof TBodyRow, 'theme' | 'onClick' | 'columns'> },
|
|
33
|
+
Row,
|
|
34
|
+
number,
|
|
35
|
+
];
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default class Body extends Component<BodySignature> {
|
|
40
|
+
@action
|
|
41
|
+
handleRowClick(rowData: Row): void {
|
|
42
|
+
this.args.onRowClick?.(rowData);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
asContent = (value: unknown): string => {
|
|
46
|
+
if (value == null) return '';
|
|
47
|
+
if (typeof value === 'string') return value;
|
|
48
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
49
|
+
return String(value);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return JSON.stringify(value);
|
|
53
|
+
} catch {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
};
|
|
40
57
|
|
|
41
|
-
export default class Body extends Component {
|
|
42
58
|
<template>
|
|
43
59
|
<tbody class={{@theme.tbody}} ...attributes>
|
|
44
60
|
{{#if (has-block)}}
|
|
@@ -68,9 +84,9 @@ export default class Body extends Component {
|
|
|
68
84
|
{{#each @columns as |column|}}
|
|
69
85
|
<row.cell @class={{column.columnClass}}>
|
|
70
86
|
{{#if column.prop}}
|
|
71
|
-
{{get rowData column.prop}}
|
|
87
|
+
{{this.asContent (get rowData column.prop)}}
|
|
72
88
|
{{else}}
|
|
73
|
-
{{rowData}}
|
|
89
|
+
{{this.asContent rowData}}
|
|
74
90
|
{{/if}}
|
|
75
91
|
</row.cell>
|
|
76
92
|
{{/each}}
|
|
@@ -79,16 +95,4 @@ export default class Body extends Component {
|
|
|
79
95
|
{{/if}}
|
|
80
96
|
</tbody>
|
|
81
97
|
</template>
|
|
82
|
-
/**
|
|
83
|
-
* Adds a click action to each row, called with the clicked row's data as an argument.
|
|
84
|
-
* Can be used with both the blockless and block invocations.
|
|
85
|
-
*
|
|
86
|
-
* @argument onRowClick
|
|
87
|
-
* @type Function
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
@action
|
|
91
|
-
handleRowClick(rowData) {
|
|
92
|
-
this.args.onRowClick?.(rowData);
|
|
93
|
-
}
|
|
94
98
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { action } from '@ember/object';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
|
|
4
|
+
import { hash } from '@ember/helper';
|
|
5
|
+
|
|
6
|
+
import type { WithBoundArgs } from '@glint/template';
|
|
7
|
+
|
|
8
|
+
import Column from './thead/row/column.gts';
|
|
9
|
+
import type { ColumnParent } from './thead/row/column.gts';
|
|
10
|
+
import type { ColumnDefinition, SortDirection, Theme } from '../../types.ts';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
Renders a `<thead>` element and yields the column component.
|
|
14
|
+
|
|
15
|
+
@class Header
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export interface HeaderSignature {
|
|
19
|
+
Element: HTMLTableSectionElement;
|
|
20
|
+
Args: {
|
|
21
|
+
trClass?: string;
|
|
22
|
+
theme?: Theme;
|
|
23
|
+
sortable?: boolean;
|
|
24
|
+
sortSequence?: SortDirection[] | string;
|
|
25
|
+
columns?: ColumnDefinition[];
|
|
26
|
+
onColumnClick?: (column: Column, e: MouseEvent) => void;
|
|
27
|
+
parent?: ColumnParent;
|
|
28
|
+
};
|
|
29
|
+
Blocks: {
|
|
30
|
+
default: [
|
|
31
|
+
{
|
|
32
|
+
column: WithBoundArgs<
|
|
33
|
+
typeof Column,
|
|
34
|
+
'sortable' | 'sortSequence' | 'onClick' | 'parent' | 'theme'
|
|
35
|
+
>;
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default class Header extends Component<HeaderSignature> {
|
|
42
|
+
@action
|
|
43
|
+
onColumnClickHeader(column: Column, e: MouseEvent): void {
|
|
44
|
+
if (this.args.onColumnClick && column.sortable) {
|
|
45
|
+
this.args.onColumnClick(column, e);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<thead class={{@theme.thead}} ...attributes>
|
|
51
|
+
<tr class="{{@trClass}} {{@theme.theadRow}} {{@theme.row}}">
|
|
52
|
+
{{yield
|
|
53
|
+
(hash
|
|
54
|
+
column=(component
|
|
55
|
+
Column
|
|
56
|
+
sortable=@sortable
|
|
57
|
+
sortSequence=@sortSequence
|
|
58
|
+
onClick=this.onColumnClickHeader
|
|
59
|
+
parent=@parent
|
|
60
|
+
theme=@theme
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
}}
|
|
64
|
+
</tr>
|
|
65
|
+
</thead>
|
|
66
|
+
</template>
|
|
67
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { action } from '@ember/object';
|
|
2
|
+
import { helper } from '@ember/component/helper';
|
|
3
|
+
import Component from '@glimmer/component';
|
|
4
|
+
import { localCopy } from 'tracked-toolbox';
|
|
5
|
+
|
|
6
|
+
import { on } from '@ember/modifier';
|
|
7
|
+
|
|
8
|
+
import type { PaginationActions, PaginationData, Theme } from '../../types.ts';
|
|
9
|
+
import { uniqueId } from '@ember/helper';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
Simple pagination controls component that is included to help you get started quickly.
|
|
13
|
+
|
|
14
|
+
@class Pagination
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface PaginationSignature {
|
|
18
|
+
Element: HTMLDivElement;
|
|
19
|
+
Args: {
|
|
20
|
+
theme?: Theme;
|
|
21
|
+
paginationData: PaginationData;
|
|
22
|
+
paginationActions: PaginationActions;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
pageSizes?: number[];
|
|
25
|
+
showInfo?: boolean;
|
|
26
|
+
showPageSizeSelector?: boolean;
|
|
27
|
+
showButtons?: boolean;
|
|
28
|
+
};
|
|
29
|
+
Blocks: { default: [] };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default class Pagination extends Component<PaginationSignature> {
|
|
33
|
+
isPaginationNumberSelected = helper(([number]: [number]) => {
|
|
34
|
+
return number === this.args.paginationData.pageSize;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
get shouldDisablePrevious(): boolean {
|
|
38
|
+
return !!this.args.paginationData.isFirstPage || !!this.args.disabled;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get shouldDisableNext(): boolean {
|
|
42
|
+
return !!this.args.paginationData.isLastPage || !!this.args.disabled;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@localCopy('args.pageSizes', [10, 15, 20, 25])
|
|
46
|
+
pageSizes!: number[];
|
|
47
|
+
|
|
48
|
+
@localCopy('args.showInfo', true)
|
|
49
|
+
showInfo!: boolean;
|
|
50
|
+
|
|
51
|
+
@localCopy('args.showPageSizeSelector', true)
|
|
52
|
+
showPageSizeSelector!: boolean;
|
|
53
|
+
|
|
54
|
+
@localCopy('args.showButtons', true)
|
|
55
|
+
showButtons!: boolean;
|
|
56
|
+
|
|
57
|
+
@action
|
|
58
|
+
changePageSize(ev: Event): void {
|
|
59
|
+
const target = ev.target as HTMLSelectElement;
|
|
60
|
+
this.args.paginationActions.changePageSize(target.value);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<div class={{@theme.pagination.controls}} ...attributes>
|
|
65
|
+
{{#if this.showInfo}}
|
|
66
|
+
<div class={{@theme.pagination.info}}>
|
|
67
|
+
Showing
|
|
68
|
+
{{@paginationData.pageStart}}
|
|
69
|
+
to
|
|
70
|
+
{{@paginationData.pageEnd}}
|
|
71
|
+
of
|
|
72
|
+
{{@paginationData.totalRows}}
|
|
73
|
+
entries
|
|
74
|
+
</div>
|
|
75
|
+
{{/if}}
|
|
76
|
+
|
|
77
|
+
{{#if this.showPageSizeSelector}}
|
|
78
|
+
<div class={{@theme.pagination.pageSize}}>
|
|
79
|
+
{{#let (uniqueId) as |selectId|}}
|
|
80
|
+
<label for="page-size-select-{{selectId}}">Rows per page:</label>
|
|
81
|
+
<select
|
|
82
|
+
id="page-size-select-{{selectId}}"
|
|
83
|
+
disabled={{@disabled}}
|
|
84
|
+
{{on "change" this.changePageSize}}
|
|
85
|
+
>
|
|
86
|
+
{{#each this.pageSizes as |pageSize|}}
|
|
87
|
+
<option
|
|
88
|
+
value={{pageSize}}
|
|
89
|
+
selected={{this.isPaginationNumberSelected pageSize}}
|
|
90
|
+
>{{pageSize}}</option>
|
|
91
|
+
{{/each}}
|
|
92
|
+
</select>
|
|
93
|
+
{{/let}}
|
|
94
|
+
</div>
|
|
95
|
+
{{/if}}
|
|
96
|
+
|
|
97
|
+
{{#if this.showButtons}}
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
class={{@theme.pagination.previous}}
|
|
101
|
+
disabled={{this.shouldDisablePrevious}}
|
|
102
|
+
{{on "click" @paginationActions.previousPage}}
|
|
103
|
+
>
|
|
104
|
+
Previous
|
|
105
|
+
</button>
|
|
106
|
+
|
|
107
|
+
<button
|
|
108
|
+
type="button"
|
|
109
|
+
class={{@theme.pagination.next}}
|
|
110
|
+
disabled={{this.shouldDisableNext}}
|
|
111
|
+
{{on "click" @paginationActions.nextPage}}
|
|
112
|
+
>
|
|
113
|
+
Next
|
|
114
|
+
</button>
|
|
115
|
+
{{/if}}
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
118
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
2
|
+
|
|
3
|
+
import type { Theme } from '../../types.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
A simple component that just renders the `<table>` element with the correct
|
|
7
|
+
theme classes.
|
|
8
|
+
|
|
9
|
+
@class Table
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export interface TableSignature {
|
|
13
|
+
Element: HTMLTableElement;
|
|
14
|
+
Args: {
|
|
15
|
+
theme?: Theme;
|
|
16
|
+
parent?: unknown;
|
|
17
|
+
};
|
|
18
|
+
Blocks: { default: [] };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const Table: TemplateOnlyComponent<TableSignature> = <template>
|
|
22
|
+
<table class={{@theme.table}} ...attributes>
|
|
23
|
+
{{yield}}
|
|
24
|
+
</table>
|
|
25
|
+
</template>;
|
|
26
|
+
|
|
27
|
+
export default Table;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import type Owner from '@ember/owner';
|
|
4
|
+
|
|
5
|
+
import { hash } from '@ember/helper';
|
|
6
|
+
|
|
7
|
+
import type { ColumnDefinition, Theme } from '../../../../types.ts';
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
10
|
@class TBodyCell
|
|
@@ -18,34 +23,48 @@ import { tracked } from '@glimmer/tracking';
|
|
|
18
23
|
```
|
|
19
24
|
*/
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
export interface TBodyCellParent {
|
|
27
|
+
registerCell(cell: TBodyCell): number;
|
|
28
|
+
unregisterCell(cell: TBodyCell): void;
|
|
29
|
+
}
|
|
22
30
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</template>
|
|
31
|
+
export interface TBodyCellSignature {
|
|
32
|
+
Element: HTMLTableCellElement;
|
|
33
|
+
Args: {
|
|
34
|
+
class?: string;
|
|
35
|
+
theme?: Theme;
|
|
36
|
+
parent?: TBodyCellParent;
|
|
37
|
+
columns?: ColumnDefinition[];
|
|
38
|
+
};
|
|
39
|
+
Blocks: { default: [{ prop: string | undefined }] };
|
|
40
|
+
}
|
|
34
41
|
|
|
42
|
+
export default class TBodyCell extends Component<TBodyCellSignature> {
|
|
35
43
|
@tracked
|
|
36
|
-
index;
|
|
44
|
+
index: number | undefined;
|
|
37
45
|
|
|
38
|
-
get column() {
|
|
39
|
-
return this.args.columns[this.index]
|
|
46
|
+
get column(): ColumnDefinition {
|
|
47
|
+
return this.args.columns?.[this.index ?? -1] ?? {};
|
|
40
48
|
}
|
|
41
49
|
|
|
42
|
-
constructor() {
|
|
43
|
-
super(
|
|
50
|
+
constructor(owner: Owner, args: TBodyCellSignature['Args']) {
|
|
51
|
+
super(owner, args);
|
|
44
52
|
this.index = this.args.parent?.registerCell(this);
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
willDestroy() {
|
|
48
|
-
super.willDestroy(
|
|
55
|
+
willDestroy(): void {
|
|
56
|
+
super.willDestroy();
|
|
49
57
|
this.args.parent?.unregisterCell(this);
|
|
50
58
|
}
|
|
59
|
+
|
|
60
|
+
<template>
|
|
61
|
+
{{#if this.column.visible}}
|
|
62
|
+
<td
|
|
63
|
+
class="{{@class}} {{this.column.columnClass}} {{@theme.tbodyCell}}"
|
|
64
|
+
...attributes
|
|
65
|
+
>
|
|
66
|
+
{{yield (hash prop=this.column.prop)}}
|
|
67
|
+
</td>
|
|
68
|
+
{{/if}}
|
|
69
|
+
</template>
|
|
51
70
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { action } from '@ember/object';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
|
|
4
|
+
import { hash } from '@ember/helper';
|
|
5
|
+
import { on } from '@ember/modifier';
|
|
6
|
+
|
|
7
|
+
import type { WithBoundArgs } from '@glint/template';
|
|
8
|
+
|
|
9
|
+
import Cell from './row/cell.gts';
|
|
10
|
+
import type {
|
|
11
|
+
ColumnDefinition,
|
|
12
|
+
RowClickHandler,
|
|
13
|
+
Theme,
|
|
14
|
+
} from '../../../types.ts';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
Renders a `<tr>` element and yields the cell component.
|
|
18
|
+
|
|
19
|
+
@class TBodyRow
|
|
20
|
+
@yield {object} row
|
|
21
|
+
@yield {Component} row.cell - the cell component
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface TBodyCellLike {
|
|
25
|
+
index?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface TBodyRowSignature {
|
|
29
|
+
Element: HTMLTableRowElement;
|
|
30
|
+
Args: {
|
|
31
|
+
theme?: Theme;
|
|
32
|
+
columns?: ColumnDefinition[];
|
|
33
|
+
onClick?: RowClickHandler;
|
|
34
|
+
};
|
|
35
|
+
Blocks: {
|
|
36
|
+
default: [
|
|
37
|
+
{ cell: WithBoundArgs<typeof Cell, 'theme' | 'parent' | 'columns'> },
|
|
38
|
+
];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default class TBodyRow extends Component<TBodyRowSignature> {
|
|
43
|
+
cells: TBodyCellLike[] = [];
|
|
44
|
+
|
|
45
|
+
registerCell(cell: TBodyCellLike): number {
|
|
46
|
+
const index = this.cells.length;
|
|
47
|
+
this.cells.push(cell);
|
|
48
|
+
return index;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
unregisterCell(cell: TBodyCellLike): void {
|
|
52
|
+
const cells = this.cells;
|
|
53
|
+
const index = cells.indexOf(cell);
|
|
54
|
+
|
|
55
|
+
cells.splice(index, 1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@action
|
|
59
|
+
handleClick(event: MouseEvent): void {
|
|
60
|
+
this.args.onClick?.(event);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
{{! template-lint-disable no-invalid-interactive }}
|
|
65
|
+
<tr
|
|
66
|
+
class="{{@theme.tbodyRow}} {{@theme.row}}"
|
|
67
|
+
{{on "click" this.handleClick}}
|
|
68
|
+
role={{if @onClick "button"}}
|
|
69
|
+
...attributes
|
|
70
|
+
>
|
|
71
|
+
{{yield
|
|
72
|
+
(hash cell=(component Cell theme=@theme parent=this columns=@columns))
|
|
73
|
+
}}
|
|
74
|
+
</tr>
|
|
75
|
+
</template>
|
|
76
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
import { hash } from '@ember/helper';
|
|
4
|
+
|
|
5
|
+
import type { WithBoundArgs } from '@glint/template';
|
|
6
|
+
|
|
7
|
+
import TBodyRow from './tbody/row.gts';
|
|
8
|
+
import type {
|
|
9
|
+
ColumnDefinition,
|
|
10
|
+
Row,
|
|
11
|
+
RowClickHandler,
|
|
12
|
+
Theme,
|
|
13
|
+
} from '../../types.ts';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
Renders a `<tbody>` element and yields the row component and data. You must iterate each row.
|
|
17
|
+
|
|
18
|
+
@class TBody
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export interface TBodySignature {
|
|
22
|
+
Element: HTMLTableSectionElement;
|
|
23
|
+
Args: {
|
|
24
|
+
theme?: Theme;
|
|
25
|
+
data?: Row[];
|
|
26
|
+
columns?: ColumnDefinition[];
|
|
27
|
+
onRowClick?: RowClickHandler;
|
|
28
|
+
};
|
|
29
|
+
Blocks: {
|
|
30
|
+
default: [
|
|
31
|
+
{
|
|
32
|
+
row: WithBoundArgs<typeof TBodyRow, 'theme' | 'onClick' | 'columns'>;
|
|
33
|
+
},
|
|
34
|
+
Row[] | undefined,
|
|
35
|
+
];
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// eslint-disable-next-line ember/no-empty-glimmer-component-classes
|
|
40
|
+
export default class TBody extends Component<TBodySignature> {
|
|
41
|
+
<template>
|
|
42
|
+
<tbody class={{@theme.tbody}} ...attributes>
|
|
43
|
+
{{yield
|
|
44
|
+
(hash
|
|
45
|
+
row=(component
|
|
46
|
+
TBodyRow theme=@theme onClick=@onRowClick columns=@columns
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
@data
|
|
50
|
+
}}
|
|
51
|
+
</tbody>
|
|
52
|
+
</template>
|
|
53
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import type Owner from '@ember/owner';
|
|
4
|
+
|
|
5
|
+
import type { ColumnDefinition, Theme } from '../../../../types.ts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
Renders a `<td>` element and yields for the developer to supply content.
|
|
9
|
+
|
|
10
|
+
```hbs
|
|
11
|
+
<table.tfoot as |foot|>
|
|
12
|
+
<foot.row as |row|>
|
|
13
|
+
<row.cell>
|
|
14
|
+
Footer content
|
|
15
|
+
</row.cell>
|
|
16
|
+
</foot.row>
|
|
17
|
+
</table.tfoot>
|
|
18
|
+
```
|
|
19
|
+
@class TFootCell
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export interface TFootCellParent {
|
|
23
|
+
registerCell(cell: TFootCell): number;
|
|
24
|
+
unregisterCell(cell: TFootCell): void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface TFootCellSignature {
|
|
28
|
+
Element: HTMLTableCellElement;
|
|
29
|
+
Args: {
|
|
30
|
+
class?: string;
|
|
31
|
+
theme?: Theme;
|
|
32
|
+
parent?: TFootCellParent;
|
|
33
|
+
columns?: ColumnDefinition[];
|
|
34
|
+
};
|
|
35
|
+
Blocks: { default: [] };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default class TFootCell extends Component<TFootCellSignature> {
|
|
39
|
+
@tracked
|
|
40
|
+
index: number | undefined;
|
|
41
|
+
|
|
42
|
+
get column(): ColumnDefinition | undefined {
|
|
43
|
+
return this.args.columns?.[this.index ?? -1];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
constructor(owner: Owner, args: TFootCellSignature['Args']) {
|
|
47
|
+
super(owner, args);
|
|
48
|
+
|
|
49
|
+
this.index = this.args.parent?.registerCell(this);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
willDestroy(): void {
|
|
53
|
+
super.willDestroy();
|
|
54
|
+
this.args.parent?.unregisterCell(this);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
<template>
|
|
58
|
+
{{#if this.column.visible}}
|
|
59
|
+
<td class="{{@class}} {{@theme.tfootCell}}" ...attributes>
|
|
60
|
+
{{yield}}
|
|
61
|
+
</td>
|
|
62
|
+
{{/if}}
|
|
63
|
+
</template>
|
|
64
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
import { hash } from '@ember/helper';
|
|
4
|
+
|
|
5
|
+
import type { WithBoundArgs } from '@glint/template';
|
|
6
|
+
|
|
7
|
+
import Cell from './row/cell.gts';
|
|
8
|
+
import type { ColumnDefinition, Theme } from '../../../types.ts';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
Renders a `<tr>` element and yields cell component.
|
|
12
|
+
|
|
13
|
+
@class TFootRow
|
|
14
|
+
@yield {object} row
|
|
15
|
+
@yield {Component} row.cell
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
interface TFootCellLike {
|
|
19
|
+
index?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TFootRowSignature {
|
|
23
|
+
Element: HTMLTableRowElement;
|
|
24
|
+
Args: {
|
|
25
|
+
class?: string;
|
|
26
|
+
theme?: Theme;
|
|
27
|
+
columns?: ColumnDefinition[];
|
|
28
|
+
parent?: unknown;
|
|
29
|
+
};
|
|
30
|
+
Blocks: {
|
|
31
|
+
default: [
|
|
32
|
+
{ cell: WithBoundArgs<typeof Cell, 'theme' | 'parent' | 'columns'> },
|
|
33
|
+
];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default class TFootRow extends Component<TFootRowSignature> {
|
|
38
|
+
cells: TFootCellLike[] = [];
|
|
39
|
+
|
|
40
|
+
registerCell(cell: TFootCellLike): number {
|
|
41
|
+
const index = this.cells.length;
|
|
42
|
+
this.cells.push(cell);
|
|
43
|
+
return index;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
unregisterCell(cell: TFootCellLike): void {
|
|
47
|
+
const cells = this.cells;
|
|
48
|
+
const index = cells.indexOf(cell);
|
|
49
|
+
cells.splice(index, 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
<template>
|
|
53
|
+
<tr class="{{@class}} {{@theme.tfootRow}} {{@theme.row}}" ...attributes>
|
|
54
|
+
{{yield
|
|
55
|
+
(hash cell=(component Cell theme=@theme parent=this columns=@columns))
|
|
56
|
+
}}
|
|
57
|
+
</tr>
|
|
58
|
+
</template>
|
|
59
|
+
}
|