@uwdata/mosaic-inputs 0.12.2 → 0.14.0

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/src/Table.js CHANGED
@@ -1,16 +1,77 @@
1
- import { MosaicClient, clausePoints, coordinator, isParam, toDataColumns } from '@uwdata/mosaic-core';
1
+ import { Selection, clausePoints, coordinator, isParam, isSelection, toDataColumns } from '@uwdata/mosaic-core';
2
2
  import { Query, desc } from '@uwdata/mosaic-sql';
3
3
  import { formatDate, formatLocaleAuto, formatLocaleNumber } from './util/format.js';
4
- import { input } from './input.js';
4
+ import { Input, input } from './input.js';
5
5
 
6
6
  let _id = -1;
7
7
 
8
+ /**
9
+ * Create a new table input instance.
10
+ * @param {object} options Options object
11
+ * @param {HTMLElement} [options.element] The parent DOM element in which to
12
+ * place the table element. If undefined, a new `div` element is created.
13
+ * @param {Selection} [options.filterBy] A selection to filter the database
14
+ * table indicated by the *from* option.
15
+ * @param {Selection} [options.as] The output selection. A selection
16
+ * clause is added for the currently selected table row.
17
+ * @param {{ [name: string]: 'left' | 'right' | 'center' }} [options.align]
18
+ * An object that maps column names to horiztonal text alignment values. If
19
+ * unspecified, alignment is determined based on the column data type.
20
+ * @param {{ [name: string]: (value: any) => string }} [options.format] An
21
+ * object that maps column names to format functions to use for that
22
+ * column's data. Each format function takes a value as input and generates
23
+ * formatted text to show in the table.
24
+ * @param {string} [options.from] The name of a database table to use as a data
25
+ * source for this widget. Used in conjunction with the *columns* option.
26
+ * @param {string[]} [options.columns] The name of database columns to include
27
+ * in the table component. If unspecified, all columns are included.
28
+ * Used in conjunction with the *from* option.
29
+ * @param {number | { [name: string]: number }} [options.width] If a number,
30
+ * sets the desired width of the table, in pixels. If an object, is used to
31
+ * set explicit pixel widts for each named column included in the object.
32
+ * @param {number} [options.maxWidth] The maximum width of the table, in pixels.
33
+ * @param {number} [options.height] The desired height of the table, in pixels.
34
+ * @param {number} [options.rowBatch] The number of rows to request per query
35
+ * batch. The batch size will be used to prefetch data beyond the currently
36
+ * visible range.
37
+ * @returns {HTMLElement} The container element for a table component.
38
+ */
8
39
  export const table = options => input(Table, options);
9
40
 
10
- export class Table extends MosaicClient {
41
+ /**
42
+ * A HTML table based table component.
43
+ * @extends {Input}
44
+ */
45
+ export class Table extends Input {
11
46
  /**
12
47
  * Create a new Table instance.
13
48
  * @param {object} options Options object
49
+ * @param {HTMLElement} [options.element] The parent DOM element in which to
50
+ * place the table element. If undefined, a new `div` element is created.
51
+ * @param {Selection} [options.filterBy] A selection to filter the database
52
+ * table indicated by the *from* option.
53
+ * @param {Selection} [options.as] The output selection. A selection
54
+ * clause is added for the currently selected table row.
55
+ * @param {{ [name: string]: 'left' | 'right' | 'center' }} [options.align]
56
+ * An object that maps column names to horiztonal text alignment values. If
57
+ * unspecified, alignment is determined based on the column data type.
58
+ * @param {{ [name: string]: (value: any) => string }} [options.format] An
59
+ * object that maps column names to format functions to use for that
60
+ * column's data. Each format function takes a value as input and generates
61
+ * formatted text to show in the table.
62
+ * @param {string} [options.from] The name of a database table to use as a data
63
+ * source for this widget. Used in conjunction with the *columns* option.
64
+ * @param {string[]} [options.columns] The name of database columns to include
65
+ * in the table component. If unspecified, all columns are included.
66
+ * Used in conjunction with the *from* option.
67
+ * @param {number | { [name: string]: number }} [options.width] If a number,
68
+ * sets the desired width of the table, in pixels. If an object, is used to
69
+ * set explicit pixel widts for each named column included in the object.
70
+ * @param {number} [options.maxWidth] The maximum width of the table, in pixels.
71
+ * @param {number} [options.height] The desired height of the table, in pixels.
72
+ * @param {number} [options.rowBatch] The number of rows to request per query
73
+ * batch. The batch size will be used to prefetch data beyond the currently
74
+ * visible range.
14
75
  */
15
76
  constructor({
16
77
  element,
@@ -25,8 +86,11 @@ export class Table extends MosaicClient {
25
86
  rowBatch = 100,
26
87
  as
27
88
  } = {}) {
28
- super(filterBy);
89
+ super(filterBy, element, null);
90
+
29
91
  this.id = `table-${++_id}`;
92
+ this.element.setAttribute('id', this.id);
93
+
30
94
  this.from = from;
31
95
  this.columns = columns;
32
96
  this.format = format;
@@ -40,7 +104,7 @@ export class Table extends MosaicClient {
40
104
 
41
105
  this.offset = 0;
42
106
  this.limit = +rowBatch;
43
- this.pending = false;
107
+ this.isPending = false;
44
108
 
45
109
  this.selection = as;
46
110
  this.currentRow = -1;
@@ -49,9 +113,6 @@ export class Table extends MosaicClient {
49
113
  this.sortColumn = null;
50
114
  this.sortDesc = false;
51
115
 
52
- this.element = element || document.createElement('div');
53
- this.element.setAttribute('id', this.id);
54
- Object.defineProperty(this.element, 'value', { value: this });
55
116
  if (typeof width === 'number') this.element.style.width = `${width}px`;
56
117
  if (maxWidth) this.element.style.maxWidth = `${maxWidth}px`;
57
118
  this.element.style.maxHeight = `${height}px`;
@@ -59,15 +120,16 @@ export class Table extends MosaicClient {
59
120
 
60
121
  let prevScrollTop = -1;
61
122
  this.element.addEventListener('scroll', evt => {
62
- const { pending, loaded } = this;
123
+ const { isPending, loaded } = this;
124
+ // @ts-ignore
63
125
  const { scrollHeight, scrollTop, clientHeight } = evt.target;
64
126
 
65
127
  const back = scrollTop < prevScrollTop;
66
128
  prevScrollTop = scrollTop;
67
- if (back || pending || loaded) return;
129
+ if (back || isPending || loaded) return;
68
130
 
69
131
  if (scrollHeight - scrollTop < 2 * clientHeight) {
70
- this.pending = true;
132
+ this.isPending = true;
71
133
  this.requestData(this.offset + this.limit);
72
134
  }
73
135
  });
@@ -168,7 +230,7 @@ export class Table extends MosaicClient {
168
230
  }
169
231
 
170
232
  queryResult(data) {
171
- if (!this.pending) {
233
+ if (!this.isPending) {
172
234
  // data is not from an internal request, so reset table
173
235
  this.loaded = false;
174
236
  this.data = [];
@@ -204,10 +266,16 @@ export class Table extends MosaicClient {
204
266
  this.loaded = true;
205
267
  }
206
268
 
207
- this.pending = false;
269
+ this.isPending = false;
208
270
  return this;
209
271
  }
210
272
 
273
+ activate() {
274
+ if (isSelection(this.selection)) {
275
+ this.selection.activate(this.clause([]));
276
+ }
277
+ }
278
+
211
279
  sort(event, column) {
212
280
  if (column === this.sortColumn) {
213
281
  this.sortDesc = !this.sortDesc;
package/src/input.js CHANGED
@@ -1,7 +1,40 @@
1
- import { coordinator } from '@uwdata/mosaic-core';
1
+ import { coordinator, MosaicClient } from '@uwdata/mosaic-core';
2
2
 
3
- export function input(InputClass, options) {
4
- const input = new InputClass(options);
3
+ /**
4
+ * Instantiate an input, register it with the coordinator, and
5
+ * return the corresponding HTML element.
6
+ * @template {new (...args: any) => Input} T
7
+ * @param {T} InputClass
8
+ * @param {ConstructorParameters<T>} params
9
+ * @returns {HTMLElement} The container element of the input.
10
+ */
11
+ export function input(InputClass, ...params) {
12
+ const input = new InputClass(...params);
5
13
  coordinator().connect(input);
6
14
  return input.element;
7
15
  }
16
+
17
+ /**
18
+ * Base class for input components.
19
+ * @import {Activatable} from '@uwdata/mosaic-core'
20
+ * @implements {Activatable}
21
+ */
22
+ export class Input extends MosaicClient {
23
+ /**
24
+ * Create a new input instance.
25
+ * @param {import('@uwdata/mosaic-core').Selection} [filterBy] A selection
26
+ * with which to filter backing data that parameterizes this input.
27
+ * @param {HTMLElement} [element] Optional container HTML element to use.
28
+ * @param {string} [className] A class name to set on the container element.
29
+ */
30
+ constructor(filterBy, element, className = 'input') {
31
+ super(filterBy);
32
+ this.element = element || document.createElement('div');
33
+ if (className) this.element.setAttribute('class', className);
34
+ Object.defineProperty(this.element, 'value', { value: this });
35
+ }
36
+
37
+ activate() {
38
+ // subclasses should override
39
+ }
40
+ }
@@ -0,0 +1,3 @@
1
+ import { defineConfig } from 'vite';
2
+
3
+ export default defineConfig({});