Skip to content

Commit 7f12f05

Browse files
committed
chore(row-selection): WIP implement row plugin
1 parent 907b9bc commit 7f12f05

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

ember-headless-table/src/plugins/-private/base.ts

+27-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Table } from '../../-private/table';
77
import type { ColumnReordering } from '../column-reordering';
88
import type { ColumnVisibility } from '../column-visibility';
99
import type { Class, Constructor } from '[private-types]';
10-
import type { Column } from '[public-types]';
10+
import type { Column, Row } from '[public-types]';
1111
import type {
1212
ColumnMetaFor,
1313
ColumnOptionsFor,
@@ -19,6 +19,7 @@ import type {
1919

2020
const TABLE_META = new Map<string, Map<Class<unknown>, any>>();
2121
const COLUMN_META = new WeakMap<Column, Map<Class<unknown>, any>>();
22+
const ROW_META = new WeakMap<Row, Map<Class<unknown>, any>>();
2223

2324
type InstanceOf<T> = T extends Class<infer Instance> ? Instance : T;
2425

@@ -250,6 +251,29 @@ export const meta = {
250251
});
251252
},
252253

254+
/**
255+
* @public
256+
*
257+
* For a given row and plugin, return the meta / state bucket for the
258+
* plugin<->row instance pair.
259+
*
260+
* Note that this requires the row instance to exist on the table.
261+
*/
262+
forRow<P extends BasePlugin<any>, Data = unknown>(
263+
row: Row<Data>,
264+
klass: Class<P>,
265+
): RowMetaFor<SignatureFrom<P>> {
266+
return getPluginInstance(ROW_META, row, klass, () => {
267+
let plugin = row.table.pluginOf(klass);
268+
269+
assert(`[${klass.name}] cannot get plugin instance of unregistered plugin class`, plugin);
270+
assert(`<#${plugin.name}> plugin does not have meta specified`, plugin.meta);
271+
assert(`<#${plugin.name}> plugin does not specify row meta`, plugin.meta.row);
272+
273+
return new plugin.meta.row(row);
274+
});
275+
},
276+
253277
/**
254278
* @public
255279
*
@@ -413,10 +437,10 @@ export const options = {
413437
/**
414438
* @private
415439
*/
416-
function getPluginInstance<RootKey extends string | Column<any>, Instance>(
440+
function getPluginInstance<RootKey extends string | Column<any> | Row<any>, Instance>(
417441
map: RootKey extends string
418442
? Map<string, Map<Class<Instance>, Instance>>
419-
: WeakMap<Column, Map<Class<Instance>, Instance>>,
443+
: WeakMap<Column | Row, Map<Class<Instance>, Instance>>,
420444
rootKey: RootKey,
421445
mapKey: Class<Instance>,
422446
factory: () => Instance
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { meta } from '../-private/base';
2+
import { RowSelection } from './plugin';
3+
4+
import type { Row } from '../../-private/row';
5+
6+
export const isSelected = (row: Row) => meta.forRow(row, RowSelection).isSelected;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Public API
2+
export * from './helpers';
3+
export { RowSelection as Plugin } from './plugin';
4+
export { RowSelection } from './plugin';
5+
6+
// Public types
7+
export type { Signature } from './plugin';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { tracked } from '@glimmer/tracking';
2+
3+
import { BasePlugin } from '../-private/base';
4+
5+
import type { Row, Table } from '[public-types]';
6+
import type { PluginSignature } from '#interfaces';
7+
8+
type Identifier = string | number | symbol;
9+
10+
export interface Signature<DataType> extends PluginSignature {
11+
Meta: {
12+
Row: RowMeta;
13+
};
14+
Options: {
15+
Plugin: {
16+
/**
17+
* For a given row's data, how should the key be determined?
18+
* this could be a remote id from a database, or some other attribute
19+
*/
20+
key: (data: DataType) => Identifier;
21+
22+
onSelect: (row: Row) => void;
23+
selected: Identifier;
24+
};
25+
};
26+
}
27+
28+
/**
29+
* This plugin provides a means of managing selection of a single row in a table.
30+
*
31+
* The state of what is actually selected is managed by you, but this plugin
32+
* will wire up the click listeners as well as let you know which *data* is clicked.
33+
*/
34+
export class RowSelection<DataType> extends BasePlugin<Signature<DataType>> {
35+
name = 'row-selection';
36+
37+
meta = {
38+
row: RowMeta,
39+
};
40+
41+
rowModifier = (element: HTMLElement, []: RowApi<Table<DataType>>) => {};
42+
}
43+
44+
class RowMeta {
45+
@tracked isSelected = false;
46+
47+
toggle = () => (this.isSelected = !this.isSelected);
48+
select = () => (this.isSelected = true);
49+
deselect = () => (this.isSelected = false);
50+
}

0 commit comments

Comments
 (0)