-
Notifications
You must be signed in to change notification settings - Fork 25
/
bodyCells.ts
156 lines (135 loc) · 3.93 KB
/
bodyCells.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { derived, type Readable } from 'svelte/store';
import type { BodyRow } from './bodyRows';
import type { DataColumn, DisplayColumn, FlatColumn } from './columns';
import { TableComponent } from './tableComponent';
import type { DataLabel, DisplayLabel } from './types/Label';
import type { AnyPlugins } from './types/TablePlugin';
import type { RenderConfig } from 'svelte-render';
export type BodyCellInit<Item, Plugins extends AnyPlugins = AnyPlugins> = {
id: string;
row: BodyRow<Item, Plugins>;
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export type BodyCellAttributes<Item, Plugins extends AnyPlugins = AnyPlugins> = {
role: 'cell';
};
export abstract class BodyCell<
Item,
Plugins extends AnyPlugins = AnyPlugins
> extends TableComponent<Item, Plugins, 'tbody.tr.td'> {
abstract column: FlatColumn<Item, Plugins>;
row: BodyRow<Item, Plugins>;
constructor({ id, row }: BodyCellInit<Item, Plugins>) {
super({ id });
this.row = row;
}
abstract render(): RenderConfig;
attrs(): Readable<BodyCellAttributes<Item, Plugins>> {
return derived(super.attrs(), ($baseAttrs) => {
return {
...$baseAttrs,
role: 'cell' as const,
};
});
}
abstract clone(): BodyCell<Item, Plugins>;
rowColId(): string {
return `${this.row.id}:${this.column.id}`;
}
dataRowColId(): string | undefined {
if (!this.row.isData()) {
return undefined;
}
return `${this.row.dataId}:${this.column.id}`;
}
// TODO Workaround for https://github.com/vitejs/vite/issues/9528
isData(): this is DataBodyCell<Item, Plugins> {
return '__data' in this;
}
// TODO Workaround for https://github.com/vitejs/vite/issues/9528
isDisplay(): this is DisplayBodyCell<Item, Plugins> {
return '__display' in this;
}
}
export type DataBodyCellInit<Item, Plugins extends AnyPlugins = AnyPlugins, Value = unknown> = Omit<
BodyCellInit<Item, Plugins>,
'id'
> & {
column: DataColumn<Item, Plugins>;
label?: DataLabel<Item, Plugins, Value>;
value: Value;
};
export type DataBodyCellAttributes<
Item,
Plugins extends AnyPlugins = AnyPlugins
> = BodyCellAttributes<Item, Plugins>;
export class DataBodyCell<
Item,
Plugins extends AnyPlugins = AnyPlugins,
Value = unknown
> extends BodyCell<Item, Plugins> {
// TODO Workaround for https://github.com/vitejs/vite/issues/9528
__data = true;
column: DataColumn<Item, Plugins>;
label?: DataLabel<Item, Plugins, Value>;
value: Value;
constructor({ row, column, label, value }: DataBodyCellInit<Item, Plugins, Value>) {
super({ id: column.id, row });
this.column = column;
this.label = label;
this.value = value;
}
render(): RenderConfig {
if (this.label === undefined) {
return `${this.value}`;
}
if (this.state === undefined) {
throw new Error('Missing `state` reference');
}
return this.label(this, this.state);
}
clone(): DataBodyCell<Item, Plugins> {
const clonedCell = new DataBodyCell({
row: this.row,
column: this.column,
label: this.label,
value: this.value,
});
return clonedCell;
}
}
export type DisplayBodyCellInit<Item, Plugins extends AnyPlugins = AnyPlugins> = Omit<
BodyCellInit<Item, Plugins>,
'id'
> & {
column: DisplayColumn<Item, Plugins>;
label: DisplayLabel<Item, Plugins>;
};
export class DisplayBodyCell<Item, Plugins extends AnyPlugins = AnyPlugins> extends BodyCell<
Item,
Plugins
> {
// TODO Workaround for https://github.com/vitejs/vite/issues/9528
__display = true;
column: DisplayColumn<Item, Plugins>;
label: DisplayLabel<Item, Plugins>;
constructor({ row, column, label }: DisplayBodyCellInit<Item, Plugins>) {
super({ id: column.id, row });
this.column = column;
this.label = label;
}
render(): RenderConfig {
if (this.state === undefined) {
throw new Error('Missing `state` reference');
}
return this.label(this, this.state);
}
clone(): DisplayBodyCell<Item, Plugins> {
const clonedCell = new DisplayBodyCell({
row: this.row,
column: this.column,
label: this.label,
});
return clonedCell;
}
}