react-ui-basics 0.0.186 → 0.0.187

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-ui-basics",
3
- "version": "0.0.186",
3
+ "version": "0.0.187",
4
4
  "description": "",
5
5
  "module": "index.js",
6
6
  "_main": "index.cjs.js",
@@ -5,13 +5,13 @@ export const props: <P>(that: React.Component<P>) => P = that => that.props;
5
5
  export const propsGetter: <P>(that: React.Component<P>) => (() => P) = that => () => props(that);
6
6
  // @ts-ignore //ignore incompatible casting EMPTY to S
7
7
  export const state: <P, S>(that: React.Component<P, S>) => S = that => that.state || EMPTY;
8
- export const setState = (that, data, cb?) => {
8
+ export const setState = (that: React.Component, data, cb?) => {
9
9
  that.setState(data, cb);
10
10
  };
11
- export const stateFieldSetter = (that, key, cb?) => (value, cb2?) => {
11
+ export const stateFieldSetter = (that, key, cb?: () => void) => (value, cb2?) => {
12
12
  setState(that, {[key]: value}, cb2 || cb);
13
13
  };
14
- export const stateGS: ((that: React.Component) => (v?, cb?) => any) = (that) => {
14
+ export const stateGS: (<T>(that: React.Component) => (v?: T, cb?: () => void) => T) = (that) => {
15
15
  !that['sfc'] && (that['sfc'] = 0);
16
16
  const key = '_' + (that['sfc']++);
17
17
  const setter = stateFieldSetter(that, key);
package/src/Table.tsx CHANGED
@@ -3,9 +3,22 @@ import './Table.css'
3
3
  import TextField from "./TextField";
4
4
  import AutocompleteSelect, {MODE_DEFAULT, MODE_MULTIPLE_MINI} from "./AutocompleteSelect";
5
5
  import Switch from "./Switch";
6
- import {Comparators, NOOP, classNames, preventDefault, stopPropagation, isFunction, isString, orNoop, createRef, setInterval, createAccessor, UNDEFINED} from "./Tools";
6
+ import {
7
+ Comparators,
8
+ NOOP,
9
+ classNames,
10
+ preventDefault,
11
+ stopPropagation,
12
+ isFunction,
13
+ isString,
14
+ orNoop,
15
+ createRef,
16
+ setInterval,
17
+ createAccessor,
18
+ UNDEFINED
19
+ } from "./Tools";
7
20
  import MaterialIcon from "./MaterialIcon";
8
- import {componentDidUpdate, componentWillUnmount, render, PureComponent, propsGetter, componentDidMount, stateGSs} from "./ReactConstants";
21
+ import {componentDidUpdate, componentWillUnmount, render, PureComponent, propsGetter, componentDidMount, stateGSs, stateGS} from "./ReactConstants";
9
22
 
10
23
  export const SORT_ASC = Comparators.SORT_ASC;
11
24
  export const SORT_DESC = Comparators.SORT_DESC;
@@ -29,35 +42,39 @@ export interface RowProps<T> {
29
42
  cancelEditing: () => void,
30
43
  onFinishEditing: () => void,
31
44
  handleInputChange: (e: ChangeEvent) => void,
32
- setValue: (v: any, t: T, field: String) => void,
33
- setEditing: (t: T, i: number, value?: any) => void,
45
+ setValue: (v: any, t: T, field: keyof T) => void,
46
+ setEditing: (t: T, i: number, value?: any, focused?: boolean) => void,
34
47
  onMouseDown?: (e: SyntheticEvent, row: number, column: number) => void,
35
48
  onMouseUp?: (e: SyntheticEvent, row: number, column: number) => void,
36
49
  onMouseEnter?: (e: SyntheticEvent, row: number, column: number) => void,
37
50
  onMouseLeave?: (e: SyntheticEvent, row: number, column: number) => void,
38
51
  }
39
52
 
40
- export type Formatter<T, V> =
41
- ((value?: V, item?: T, format?: string) => ReactElement | string)
42
- | ((value: V, item: T) => ReactElement | string)
43
- | ((value: V) => ReactElement | string);
53
+ export type Formatter<T, V> = ((value: V, item?: T, format?: string) => ReactElement | string);
44
54
 
45
- export type CellClassName<T> = (item: T, field: string, row: number, column: number) => string;
55
+ export type CellClassName<T> = (item: T, field: keyof T, row: number, column: number) => string;
46
56
  export type ColumnClassName<T> = string | CellClassName<T>
47
57
 
48
58
  export interface TableColumn<T> {
49
- field?: string,
59
+ field?: keyof T,
50
60
  className?: ColumnClassName<T>,
51
- onClick?: (e: SyntheticEvent, startEditing: () => void, item: T, field: string, row: number, column: number) => void,
61
+ onClick?: (e: SyntheticEvent, startEditing: () => void, item: T, field: keyof T, row: number, column: number) => void,
52
62
  comparator?: Comparator,
53
63
  header?: string | ReactElement,
54
64
  sortable?: boolean,
55
65
  displayEditor?: boolean,
56
- formatter?: Formatter<T, any>,
66
+ formatter?: Formatter<T, T[keyof T]>,
57
67
  format?: string,
58
68
  editable?: boolean | ((t: T) => boolean),
59
69
  editor?: typeof editorSelect | typeof editorSwitch | ((t: T, cancel: () => void, isEditing: boolean) => ReactElement),
60
- preEditor?: (a: any) => any,
70
+ preEditor?: (a: T[keyof T]) => any,
71
+ }
72
+
73
+ export interface TableColumnTyped<T, F extends keyof T> extends TableColumn<T>{
74
+ field?: F,
75
+ onClick?: (e: SyntheticEvent, startEditing: () => void, item: T, field: F, row: number, column: number) => void,
76
+ formatter?: Formatter<T, T[F]>,
77
+ preEditor?: (a: T[F]) => any,
61
78
  }
62
79
 
63
80
  export interface TableProps<T> {
@@ -86,10 +103,19 @@ export interface TableState<T> {
86
103
  data?: T[],
87
104
  }
88
105
 
106
+ export interface EditingState<T> {
107
+ id: number | string
108
+ value: any
109
+ columnIndex: number
110
+ item: T
111
+ field: keyof T
112
+ focused: boolean
113
+ }
114
+
89
115
  class Table<T> extends Component<TableProps<T>, TableState<T>> {
90
- startEditing: (item, columnIndex, value?) => void;
116
+ startEditing: (item: T, columnIndex: number, value?, focused?: boolean) => void;
91
117
  finishEditing: () => void;
92
- isEditing: () => boolean;
118
+ getEditingState: () => EditingState<T>;
93
119
 
94
120
  constructor(properties) {
95
121
  super(properties);
@@ -106,20 +132,21 @@ class Table<T> extends Component<TableProps<T>, TableState<T>> {
106
132
  }
107
133
  };
108
134
 
109
- const [editingState, dataState, sortByState, sortOrderState, comparatorState] = stateGSs(this, 5);
135
+ const editingState = stateGS<EditingState<T>>(this)
136
+ const [dataState, sortByState, sortOrderState, comparatorState] = stateGSs(this, 4);
110
137
  const comparatorGetter = createAccessor('comparator');
111
138
 
112
139
  const cancelEditing = () => {
113
- editingState(false)
140
+ editingState(null)
114
141
  };
115
142
 
116
- const setEditing = (item, columnIndex, value) => {
143
+ const setEditing = (item, columnIndex, value, focused = true) => {
117
144
  const {columns} = props()
118
145
  const field = columns[columnIndex].field
119
- editingState({id: item.id, value: (value != null ? value : item[field]), columnIndex, item, field})
146
+ editingState({id: item.id, value: (value != null ? value : item[field]), columnIndex, item, field, focused: !!focused})
120
147
  };
121
148
  this.startEditing = setEditing
122
- this.isEditing = () => !!editingState()
149
+ this.getEditingState = () => editingState()
123
150
 
124
151
  const handleInputChange = (event) => {
125
152
  const target = event.target;
@@ -148,7 +175,7 @@ class Table<T> extends Component<TableProps<T>, TableState<T>> {
148
175
  this.finishEditing = onFinishEditing
149
176
 
150
177
  const setValue = (value, item, field) => {
151
- editingState({item, field, value}, onFinishEditing)
178
+ editingState({...editingState(), item, field, value}, onFinishEditing)
152
179
  };
153
180
 
154
181
 
@@ -163,6 +190,7 @@ class Table<T> extends Component<TableProps<T>, TableState<T>> {
163
190
  c = Comparators.inverse(c)
164
191
 
165
192
  data.sort(c || Comparators.of(sortBy, sortOrder, data));
193
+ [].sort()
166
194
  }
167
195
  sortOrderState(sortOrder)
168
196
  comparatorState(comparator)
@@ -262,12 +290,12 @@ const formatValue: (<T>(item: T, column: TableColumn<T>) => string | ReactElemen
262
290
  return formatter ? (formatter as ((value?: any, item?: any, format?: string) => ReactElement))(value, item, column.format) : '' + value;
263
291
  };
264
292
 
265
- export interface TableColumnSelect extends TableColumn<any> {
293
+ export interface TableColumnSelect<T> extends TableColumn<T> {
266
294
  editorData?: any,
267
295
  multiSelect?: any,
268
296
  onSelect?: any,
269
297
  editorSelectedComponent?: any,
270
- editorChildCompononent?: any,
298
+ editorChildComponent?: any,
271
299
  prefilter?: any,
272
300
  }
273
301
 
@@ -307,10 +335,10 @@ class Row<T> extends PureComponent<RowProps<T>> {
307
335
  {displayEditor && !column.editor && (
308
336
  <TextField
309
337
  value={value}
310
- focused={true}
338
+ focused={editing.focused}
311
339
  onBlur={cancelEditing}
312
340
  onChange={handleInputChange}
313
- onKeyDown={e => {
341
+ onKeyUp={e => {
314
342
  if (e.keyCode === 27/*escape*/) {
315
343
  preventDefault(e);
316
344
  cancelEditing();
@@ -325,22 +353,22 @@ class Row<T> extends PureComponent<RowProps<T>> {
325
353
  {displayEditor && column.editor === editorSelect && (
326
354
  <AutocompleteSelect
327
355
  value={value}
328
- data={(column as TableColumnSelect).editorData}
356
+ data={(column as TableColumnSelect<T>).editorData}
329
357
  focused={true}
330
358
  withArrow={false}
331
359
  withFilter={false}
332
360
  selectedMode={'inline'}
333
- selectedComponent={(column as TableColumnSelect).editorSelectedComponent}
334
- mode={(column as TableColumnSelect).multiSelect ? MODE_MULTIPLE_MINI : MODE_DEFAULT}
335
- onChange={(column as TableColumnSelect).multiSelect && ((column as TableColumnSelect).onSelect ? (value => {
336
- setValue((column as TableColumnSelect).onSelect(value), item, column.field);
361
+ selectedComponent={(column as TableColumnSelect<T>).editorSelectedComponent}
362
+ mode={(column as TableColumnSelect<T>).multiSelect ? MODE_MULTIPLE_MINI : MODE_DEFAULT}
363
+ onChange={(column as TableColumnSelect<T>).multiSelect && ((column as TableColumnSelect<T>).onSelect ? (value => {
364
+ setValue((column as TableColumnSelect<T>).onSelect(value), item, column.field);
337
365
  }) : value => setValue(value, item, column.field))}
338
- onSelect={!(column as TableColumnSelect).multiSelect && ((column as TableColumnSelect).onSelect ? (value => {
339
- setValue((column as TableColumnSelect).onSelect(value), item, column.field);
366
+ onSelect={!(column as TableColumnSelect<T>).multiSelect && ((column as TableColumnSelect<T>).onSelect ? (value => {
367
+ setValue((column as TableColumnSelect<T>).onSelect(value), item, column.field);
340
368
  }) : value => setValue(value, item, column.field))}
341
- childComponent={(column as TableColumnSelect).editorChildCompononent}
369
+ childComponent={(column as TableColumnSelect<T>).editorChildComponent}
342
370
  onCancel={cancelEditing}
343
- prefilter={(column as TableColumnSelect).prefilter}
371
+ prefilter={(column as TableColumnSelect<T>).prefilter}
344
372
  />
345
373
  )}
346
374
  {displayEditor && column.editor === editorSwitch && (
package/src/Tools.ts CHANGED
@@ -169,30 +169,40 @@ export const removeEventListener = (el, type, listener, options?) => {
169
169
  export const UNDEFINED = undefined;
170
170
  export const isUndefined = a => a === UNDEFINED;
171
171
 
172
+ export type ComparatorFunction<T> = (a: T, b: T) => number;
173
+ export interface Comparator<T> extends ComparatorFunction<T>{
174
+ inverse : <T>() => Comparator<T>
175
+ and : <T>(comparator: Comparator<T>) => Comparator<T>
176
+ }
177
+
178
+ type SortOrder = 'ASC' | 'DESC';
179
+ type FieldGetter<T> = (t: T) => any;
180
+ type SortField<T> = keyof T | FieldGetter<T>;
172
181
 
173
182
  export class Comparators {
174
- static SORT_ASC = 'ASC';
175
- static SORT_DESC = 'DESC';
183
+ static SORT_ASC: SortOrder = 'ASC';
184
+ static SORT_DESC: SortOrder = 'DESC';
176
185
 
177
- static of = (field, order, data) => {
186
+ static of = <T>(field: SortField<T> | SortField<T>[], order: SortOrder | SortOrder[], data?: T[]): Comparator<T> => {
178
187
  let comparator;
179
188
  if (Array.isArray(field)) {
180
189
  const isOrderArray = Array.isArray(order);
181
190
  comparator = Comparators.chain(field.map((it, i) => Comparators.of(it, (isOrderArray && order[i]) || Comparators.SORT_ASC, data)));
182
191
  } else if (isFunction(field)) {
183
- if (data && data[0] && isString(field(data[0]))) {
192
+ const getter: FieldGetter<T> = field as FieldGetter<T>
193
+ if (data && data[0] && isString(getter(data[0]))) {
184
194
  const collator = new Intl.Collator('default', {sensitivity: 'base'});
185
195
  comparator = (a, b) => {
186
- return collator.compare(field(a), field(b));
196
+ return collator.compare(getter(a), getter(b));
187
197
  }
188
198
  } else
189
199
  comparator = (a, b) => {
190
- const A = field(a);
191
- const B = field(b);
200
+ const A = getter(a);
201
+ const B = getter(b);
192
202
  return (A < B ? -1 : (A > B ? 1 : 0));
193
203
  };
194
204
  } else if (isString(field))
195
- comparator = Comparators.of(it => it[field], Comparators.SORT_ASC, data);
205
+ comparator = Comparators.of(it => it[field as string], Comparators.SORT_ASC, data);
196
206
  else
197
207
  comparator = Comparators.of(it => it, Comparators.SORT_ASC, data);
198
208
 
@@ -202,7 +212,7 @@ export class Comparators {
202
212
 
203
213
  return addComparatorMethods(comparator);
204
214
  };
205
- static chain = (comparators) => addComparatorMethods((a, b) => {
215
+ static chain = <T>(comparators: Comparator<T>[]) => addComparatorMethods((a: T, b: T) => {
206
216
  let result;
207
217
  for (let i = 0; i < comparators.length; i++) {
208
218
  result = comparators[i](a, b);
@@ -213,11 +223,14 @@ export class Comparators {
213
223
  }
214
224
  );
215
225
 
216
- static inverse = (comparator) => addComparatorMethods((a, b) => -comparator(a, b));
226
+ static inverse = <T>(comparator: Comparator<T>) => addComparatorMethods((a: T, b: T) => -comparator(a, b));
217
227
  }
218
228
 
219
- const addComparatorMethods = function (comparator) {
229
+ const addComparatorMethods = <T>(cf: ComparatorFunction<T>): Comparator<T> => {
230
+ const comparator = cf as Comparator<T>
231
+ // @ts-ignore
220
232
  comparator.inverse = () => Comparators.inverse(comparator);
233
+ // @ts-ignore
221
234
  comparator.and = (another) => Comparators.chain([comparator, another]);
222
235
  return comparator;
223
236
  };