react-ui-basics 0.0.175 → 0.0.176

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.
Files changed (137) hide show
  1. package/Animated.js.map +1 -1
  2. package/AutocompleteSelect.js.map +1 -1
  3. package/Button.js.map +1 -1
  4. package/Checkbox.js.map +1 -1
  5. package/CircleProgress.js.map +1 -1
  6. package/CommonFields.js.map +1 -1
  7. package/DNDContainer.js.map +1 -1
  8. package/DNDDraggable.js.map +1 -1
  9. package/DNDDroppable.js.map +1 -1
  10. package/Dialog.js.map +1 -1
  11. package/DropFileInput.js.map +1 -1
  12. package/DroppableHorizontalList.js.map +1 -1
  13. package/DroppableList.js.map +1 -1
  14. package/Dropzone.js.map +1 -1
  15. package/FilteredList.js.map +1 -1
  16. package/FloatingActionButton.js.map +1 -1
  17. package/FormUploadProgress.js.map +1 -1
  18. package/ImageGallery.js.map +1 -1
  19. package/MaterialIcon.js.map +1 -1
  20. package/Modal.js.map +1 -1
  21. package/ModalMenu.js.map +1 -1
  22. package/ReactConstants.js.map +1 -1
  23. package/ReactCreateElement.js.map +1 -1
  24. package/ReadyListener.js.map +1 -1
  25. package/Scrollable.js.map +1 -1
  26. package/ScrollableTable.js.map +1 -1
  27. package/Size.js.map +1 -1
  28. package/Snackbar.js.map +1 -1
  29. package/SpinningProgress.js.map +1 -1
  30. package/Switch.js.map +1 -1
  31. package/Table.js.map +1 -1
  32. package/TextField.js.map +1 -1
  33. package/Tools.d.ts +2 -2
  34. package/Tools.js.map +1 -1
  35. package/bundle.css +596 -596
  36. package/package.json +1 -1
  37. package/router/HistoryTools.js.map +1 -1
  38. package/router/Link.js.map +1 -1
  39. package/router/NavLink.js.map +1 -1
  40. package/router/Route.js.map +1 -1
  41. package/router/index.js.map +1 -1
  42. package/src/Animated.css +7 -0
  43. package/src/Animated.js +219 -0
  44. package/src/Animated.scss +8 -0
  45. package/src/AutocompleteSelect.css +256 -0
  46. package/src/AutocompleteSelect.js +473 -0
  47. package/src/AutocompleteSelect.scss +322 -0
  48. package/src/Button.css +138 -0
  49. package/src/Button.js +104 -0
  50. package/src/Button.scss +177 -0
  51. package/src/Checkbox.css +56 -0
  52. package/src/Checkbox.js +52 -0
  53. package/src/Checkbox.scss +87 -0
  54. package/src/CircleProgress.css +11 -0
  55. package/src/CircleProgress.js +38 -0
  56. package/src/CircleProgress.scss +13 -0
  57. package/src/CommonFields.js +21 -0
  58. package/src/DNDContainer.css +26 -0
  59. package/src/DNDContainer.js +263 -0
  60. package/src/DNDContainer.scss +33 -0
  61. package/src/DNDDraggable.js +55 -0
  62. package/src/DNDDroppable.js +58 -0
  63. package/src/Dialog.css +36 -0
  64. package/src/Dialog.js +160 -0
  65. package/src/Dialog.scss +42 -0
  66. package/src/DropFileInput.css +24 -0
  67. package/src/DropFileInput.js +45 -0
  68. package/src/DropFileInput.scss +28 -0
  69. package/src/DroppableHorizontalList.js +190 -0
  70. package/src/DroppableList.css +14 -0
  71. package/src/DroppableList.js +201 -0
  72. package/src/DroppableList.scss +27 -0
  73. package/src/Dropzone.css +54 -0
  74. package/src/Dropzone.js +140 -0
  75. package/src/Dropzone.scss +66 -0
  76. package/src/FilteredList.css +68 -0
  77. package/src/FilteredList.js +196 -0
  78. package/src/FilteredList.scss +86 -0
  79. package/src/FloatingActionButton.css +20 -0
  80. package/src/FloatingActionButton.js +35 -0
  81. package/src/FloatingActionButton.scss +25 -0
  82. package/src/FormUploadProgress.css +61 -0
  83. package/src/FormUploadProgress.js +87 -0
  84. package/src/FormUploadProgress.scss +78 -0
  85. package/src/ImageGallery.css +196 -0
  86. package/src/ImageGallery.js +935 -0
  87. package/src/ImageGallery.scss +256 -0
  88. package/src/MaterialIcon.js +1837 -0
  89. package/src/Modal.css +61 -0
  90. package/src/Modal.js +160 -0
  91. package/src/Modal.scss +73 -0
  92. package/src/ModalMenu.css +30 -0
  93. package/src/ModalMenu.js +59 -0
  94. package/src/ModalMenu.scss +36 -0
  95. package/src/ReactConstants.ts +42 -0
  96. package/src/ReactCreateElement.js +5 -0
  97. package/src/ReadyListener.js +53 -0
  98. package/src/ResizeObserver.ts +50 -0
  99. package/src/Scrollable.css +80 -0
  100. package/src/Scrollable.js +388 -0
  101. package/src/Scrollable.scss +100 -0
  102. package/src/ScrollableTable.css +6 -0
  103. package/src/ScrollableTable.scss +12 -0
  104. package/src/ScrollableTable.tsx +39 -0
  105. package/src/Size.js +56 -0
  106. package/src/Snackbar.css +40 -0
  107. package/src/Snackbar.js +71 -0
  108. package/src/Snackbar.scss +47 -0
  109. package/src/SpinningProgress.css +49 -0
  110. package/src/SpinningProgress.js +19 -0
  111. package/src/SpinningProgress.scss +57 -0
  112. package/src/Switch.css +69 -0
  113. package/src/Switch.js +54 -0
  114. package/src/Switch.scss +73 -0
  115. package/src/Table.css +94 -0
  116. package/src/Table.scss +121 -0
  117. package/src/Table.tsx +360 -0
  118. package/src/TextField.css +122 -0
  119. package/src/TextField.js +162 -0
  120. package/src/TextField.scss +160 -0
  121. package/src/Tools.test.js +105 -0
  122. package/src/Tools.ts +231 -0
  123. package/src/global.css +1 -0
  124. package/src/global.scss +6 -0
  125. package/src/index.js +78 -0
  126. package/src/router/HistoryTools.js +32 -0
  127. package/src/router/Link.js +27 -0
  128. package/src/router/NavLink.js +25 -0
  129. package/src/router/README.md +55 -0
  130. package/src/router/Route.js +209 -0
  131. package/src/router/Route.test.js +139 -0
  132. package/src/router/index.js +14 -0
  133. package/src/store/ProxyTools.js +91 -0
  134. package/src/store/ProxyTools.test.js +97 -0
  135. package/src/store/Store.ts +91 -0
  136. package/store/ProxyTools.js.map +1 -1
  137. package/store/Store.js.map +1 -1
package/src/Table.tsx ADDED
@@ -0,0 +1,360 @@
1
+ import React, {ChangeEvent, Component, ReactElement, SyntheticEvent} from 'react';
2
+ import './Table.css'
3
+ import TextField from "./TextField";
4
+ import AutocompleteSelect, {MODE_DEFAULT, MODE_MULTIPLE_MINI} from "./AutocompleteSelect";
5
+ import Switch from "./Switch";
6
+ import {Comparators, NOOP, classNames, preventDefault, stopPropagation, isFunction, isString, orNoop, createRef, setInterval, createAccessor, UNDEFINED} from "./Tools";
7
+ import MaterialIcon from "./MaterialIcon";
8
+ import {componentDidUpdate, componentWillUnmount, render, PureComponent, propsGetter, componentDidMount, stateGSs} from "./ReactConstants";
9
+
10
+ export const SORT_ASC = Comparators.SORT_ASC;
11
+ export const SORT_DESC = Comparators.SORT_DESC;
12
+
13
+ const getId = item => item.id;
14
+
15
+ type SortOrder = typeof SORT_ASC | typeof SORT_DESC;
16
+ type Comparator = <T>(a: T, b: T) => number;
17
+
18
+ const editorSelect = 'Select'
19
+ const editorSwitch = 'Switch'
20
+
21
+ export interface RowProps<T> {
22
+ i: number,
23
+ item: T,
24
+ disabled?: (t: T) => boolean,
25
+ editing,
26
+ onClick?: (t: T, e: SyntheticEvent) => void,
27
+ className?: string | ((e: T) => string),
28
+ columns: TableColumn<T>[],
29
+ cancelEditing: () => void,
30
+ onFinishEditing: () => void,
31
+ handleInputChange: (e: ChangeEvent) => void,
32
+ setValue: (v: any) => void,
33
+ setEditing: (t: T, i: number, value?: any) => void,
34
+ onMouseDown?: (e: SyntheticEvent, row: number, column: number) => void,
35
+ onMouseUp?: (e: SyntheticEvent, row: number, column: number) => void,
36
+ onMouseEnter?: (e: SyntheticEvent, row: number, column: number) => void,
37
+ onMouseLeave?: (e: SyntheticEvent, row: number, column: number) => void,
38
+ }
39
+
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);
44
+
45
+ export type CellClassName<T> = (item: T, field: string, row: number, column: number) => string;
46
+ export type ColumnClassName<T> = string | CellClassName<T>
47
+
48
+ export interface TableColumn<T> {
49
+ field?: string,
50
+ className?: ColumnClassName<T>,
51
+ onClick?: (e: SyntheticEvent, startEditing: () => void, item: T, field: string, row: number, column: number) => void,
52
+ comparator?: Comparator,
53
+ header?: string | ReactElement,
54
+ sortable?: boolean,
55
+ displayEditor?: boolean,
56
+ formatter?: Formatter<T, any>,
57
+ format?: string,
58
+ editable?: boolean | ((t: T) => boolean),
59
+ editor?: typeof editorSelect | typeof editorSwitch | ((t: T, cancel: () => void, isEditing: boolean) => ReactElement),
60
+ preEditor?: (a: any) => any,
61
+ }
62
+
63
+ export interface TableProps<T> {
64
+ columns: TableColumn<T>[],
65
+ data: T[],
66
+ className?: string,
67
+ sortOrder?: SortOrder
68
+ sortBy?: string,
69
+ onSortChange?: (sortBy: string, sortOrder: SortOrder) => void,
70
+ onRowClick?: (t: T, e: SyntheticEvent) => void,
71
+ disabled?: (t: T) => boolean,
72
+ toKey?: (t: T) => number | string,
73
+ onChange?: (t: T, cancel: () => void) => void,
74
+ rowClassName?: string | ((t: T) => string),
75
+ onMouseDown?: (e: SyntheticEvent, row: number, column: number) => void,
76
+ onMouseUp?: (e: SyntheticEvent, row: number, column: number) => void,
77
+ onMouseEnter?: (e: SyntheticEvent, row: number, column: number) => void,
78
+ onMouseLeave?: (e: SyntheticEvent, row: number, column: number) => void,
79
+ }
80
+
81
+
82
+ export interface TableState<T> {
83
+ sortOrder?: SortOrder
84
+ sortBy?: string,
85
+ comparator?: Comparator,
86
+ data?: T[],
87
+ }
88
+
89
+ class Table<T> extends Component<TableProps<T>, TableState<T>> {
90
+ startEditing: (item, columnIndex, value?) => void;
91
+ finishEditing: () => void;
92
+ isEditing: () => boolean;
93
+
94
+ constructor(properties) {
95
+ super(properties);
96
+ const props = propsGetter(this);
97
+
98
+ const headers = createRef();
99
+ let updateHeadersInterval = 0;
100
+
101
+ const updateHeaders = () => {
102
+ const hidden = headers().querySelectorAll('.hidden');
103
+ const fixed = headers().querySelectorAll('.fixed');
104
+ for (let i = 0; i < hidden.length; i++) {
105
+ fixed[i].style.width = hidden[i].offsetWidth + 'px'
106
+ }
107
+ };
108
+
109
+ const [editingState, dataState, sortByState, sortOrderState, comparatorState] = stateGSs(this, 5);
110
+ const comparatorGetter = createAccessor('comparator');
111
+
112
+ const cancelEditing = () => {
113
+ editingState(false)
114
+ };
115
+
116
+ const setEditing = (item, columnIndex, value) => {
117
+ const {columns} = props()
118
+ const field = columns[columnIndex].field
119
+ editingState({id: item.id, value: (value != null ? value : item[field]), columnIndex, item, field})
120
+ };
121
+ this.startEditing = setEditing
122
+ this.isEditing = () => !!editingState()
123
+
124
+ const handleInputChange = (event) => {
125
+ const target = event.target;
126
+ const value = target.type === 'checkbox' ? target.checked : target.value;
127
+ editingState({...editingState(), value});
128
+ };
129
+
130
+ const onFinishEditing = () => {
131
+ const editing = editingState();
132
+ if (!editing || editing.value === null)
133
+ return;
134
+
135
+ let value = editing.value;
136
+ if (isString(value))
137
+ value = value.trim();
138
+
139
+ if (value === editing.item[editing.field])
140
+ return cancelEditing();
141
+
142
+ let updated = {
143
+ ...editing.item,
144
+ [editing.field]: value
145
+ };
146
+ props().onChange(updated, cancelEditing)
147
+ };
148
+ this.finishEditing = onFinishEditing
149
+
150
+ const setValue = (value) => {
151
+ editingState({...editingState(), value}, onFinishEditing)
152
+ };
153
+
154
+
155
+ const setData = (data, sortBy?, sortOrder?, comparator?) => {
156
+ data = data ? [...data] : [];
157
+ sortBy = sortBy || sortByState()
158
+ sortOrder = sortOrder || sortOrderState()
159
+ comparator = comparator || comparatorState()
160
+ if (sortBy) {
161
+ let c = comparator
162
+ if (c && sortOrder === SORT_DESC)
163
+ c = Comparators.inverse(c)
164
+
165
+ data.sort(c || Comparators.of(sortBy, sortOrder, data));
166
+ }
167
+ sortOrderState(sortOrder)
168
+ comparatorState(comparator)
169
+ sortByState(sortBy)
170
+ dataState(data, () => {
171
+ orNoop(props().onSortChange)(sortBy, sortOrder)
172
+ })
173
+ };
174
+
175
+ const sort = (e, sortBy, comparator) => {
176
+ preventDefault(e);
177
+ const sortOrder = sortByState() === sortBy && sortOrderState() === SORT_ASC ? SORT_DESC : SORT_ASC;
178
+ setData(dataState(), sortBy, sortOrder, comparator)
179
+ }
180
+
181
+ this[componentDidMount] = () => {
182
+ const {sortBy, sortOrder = SORT_ASC, columns, data} = props();
183
+ setData(data, sortBy, sortOrder, comparatorGetter(columns.find(it => it.field === sortBy)))
184
+ updateHeaders();
185
+ updateHeadersInterval = setInterval(updateHeaders, 1000)
186
+ };
187
+
188
+ this[componentDidUpdate] = (prevProps, prevState, snapshot) => {
189
+ const {sortBy, sortOrder, columns, data} = props();
190
+ if (sortBy !== prevProps.sortBy || sortOrder !== prevProps.sortOrder) {
191
+ setData(dataState(), sortBy, sortOrder || SORT_ASC, comparatorGetter(columns.find(it => it.field === sortBy)))
192
+ } else if (data !== prevProps.data) {
193
+ setData(data)
194
+ }
195
+ updateHeaders();
196
+ };
197
+
198
+ this[render] = () => {
199
+ const {columns = [], onRowClick = NOOP, disabled, className, rowClassName, toKey = getId, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave} = props();
200
+ const sortBy = sortByState()
201
+ const sortOrder = sortOrderState()
202
+ const editing = editingState();
203
+ const data = dataState() || [];
204
+ return (
205
+ <table className={classNames(`Table`, className)}>
206
+ <thead>
207
+ <tr ref={headers}>
208
+ {columns.filter(it => !!it).map((column, i) => {
209
+ const sortable = column.sortable || column.sortable == null;
210
+ return (
211
+ <th key={i} onClick={e => sortable && sort(e, column.field, comparatorGetter(column))}>
212
+ <div className={classNames('hidden', sortable && 'sortable', sortBy === column.field && 'active')}>
213
+ {column.header}
214
+ {column.header && sortBy === column.field && sortOrder === SORT_ASC && (<MaterialIcon icon={'keyboard_arrow_up'}/>)}
215
+ {column.header && sortBy === column.field && sortOrder === SORT_DESC && (<MaterialIcon icon={'keyboard_arrow_down'}/>)}
216
+ </div>
217
+ <div className={classNames('fixed', sortable && 'sortable', sortBy === column.field && 'active')}>
218
+ {column.header}
219
+ {column.header && sortBy === column.field && sortOrder === SORT_ASC && (<MaterialIcon icon={'keyboard_arrow_up'}/>)}
220
+ {column.header && sortBy === column.field && sortOrder === SORT_DESC && (<MaterialIcon icon={'keyboard_arrow_down'}/>)}
221
+ </div>
222
+ </th>
223
+ );
224
+ })}
225
+ </tr>
226
+ </thead>
227
+ <tbody>
228
+ {data.map((item, i) => (<Row
229
+ key={toKey(item)}
230
+ i={i}
231
+ item={item}
232
+ disabled={disabled}
233
+ editing={editing && editing.id === toKey(item) ? editing : null}
234
+ onClick={onRowClick}
235
+ className={rowClassName}
236
+ columns={columns}
237
+ setEditing={setEditing}
238
+ cancelEditing={cancelEditing}
239
+ onFinishEditing={onFinishEditing}
240
+ handleInputChange={handleInputChange}
241
+ setValue={setValue}
242
+ onMouseDown={onMouseDown}
243
+ onMouseUp={onMouseUp}
244
+ onMouseEnter={onMouseEnter}
245
+ onMouseLeave={onMouseLeave}
246
+ />
247
+ ))}
248
+ </tbody>
249
+ </table>
250
+ );
251
+ };
252
+
253
+ this[componentWillUnmount] = () => {
254
+ clearInterval(updateHeadersInterval)
255
+ };
256
+ }
257
+ }
258
+
259
+ const formatValue: (<T>(item: T, column: TableColumn<T>) => string | ReactElement) = (item, column) => {
260
+ const value = item[column.field];
261
+ const formatter = column.formatter;
262
+ return formatter ? (formatter as ((value?: any, item?: any, format?: string) => ReactElement))(value, item, column.format) : '' + value;
263
+ };
264
+
265
+ export interface TableColumnSelect extends TableColumn<any> {
266
+ editorData?: any,
267
+ multiSelect?: any,
268
+ onSelect?: any,
269
+ editorSelectedComponent?: any,
270
+ editorChildCompononent?: any,
271
+ prefilter?: any,
272
+ }
273
+
274
+ class Row<T> extends PureComponent<RowProps<T>> {
275
+ render() {
276
+ let {item, i, disabled, editing, onClick, className, columns, setEditing, cancelEditing, onFinishEditing, handleInputChange, setValue, onMouseDown, onMouseEnter, onMouseUp, onMouseLeave} = this.props;
277
+ return <tr onClick={e => onClick(item, e)}
278
+ className={classNames(
279
+ disabled && disabled(item) && 'disabled',
280
+ className && (isFunction(className) ? (className as (t: T) => string)(item) : className as string))
281
+ }>
282
+ {columns.filter(it => !!it).map((column, j) => {
283
+ const isEditing = editing && editing.columnIndex === j;
284
+ const editable = isFunction(column.editable) ? (column.editable as ((t: T) => boolean))(item) : !!column.editable;
285
+ const startEditing = !isEditing && editable ? () => setEditing(item, j) : NOOP;
286
+ const onClick = (!!column.onClick ? (e) => column.onClick(e, startEditing, item, column.field, i, j) : startEditing)
287
+
288
+ let displayEditor = isEditing || column.displayEditor;
289
+ let value = item[column.field];
290
+ if(editing) {
291
+ value = editing.value != null ? editing.value : value;
292
+ value = column.preEditor ? column.preEditor(value) : value
293
+ }
294
+ return (
295
+ <td key={j}
296
+ onMouseDown={onMouseDown ? (e) => onMouseDown(e, i, j) : UNDEFINED}
297
+ onMouseUp={onMouseUp ? (e) => onMouseUp(e, i, j) : UNDEFINED}
298
+ onMouseEnter={onMouseEnter ? (e) => onMouseEnter(e, i, j) : UNDEFINED}
299
+ onMouseLeave={onMouseLeave ? (e) => onMouseLeave(e, i, j) : UNDEFINED}
300
+ className={classNames(
301
+ editable ? 'editable' : 'ro',
302
+ isEditing && 'editing',
303
+ isString(column.className) && (column.className as string),
304
+ isFunction(column.className) && (column.className as CellClassName<T>)(item, column.field, i, j),
305
+ )}
306
+ onClick={onClick}>
307
+ {displayEditor && !column.editor && (
308
+ <TextField
309
+ value={value}
310
+ focused={true}
311
+ onBlur={cancelEditing}
312
+ onChange={handleInputChange}
313
+ onKeyDown={e => {
314
+ if (e.keyCode === 27/*escape*/) {
315
+ preventDefault(e);
316
+ cancelEditing();
317
+ }
318
+ if (e.keyCode === 13/*enter*/) {
319
+ preventDefault(e);
320
+ onFinishEditing();
321
+ }
322
+ }}
323
+ />
324
+ )}
325
+ {displayEditor && column.editor === editorSelect && (
326
+ <AutocompleteSelect
327
+ value={value}
328
+ data={(column as TableColumnSelect).editorData}
329
+ focused={true}
330
+ withArrow={false}
331
+ withFilter={false}
332
+ 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 => setValue((column as TableColumnSelect).onSelect(value))) : setValue)}
336
+ onSelect={!(column as TableColumnSelect).multiSelect && ((column as TableColumnSelect).onSelect ? (value => setValue((column as TableColumnSelect).onSelect(value))) : setValue)}
337
+ childComponent={(column as TableColumnSelect).editorChildCompononent}
338
+ onCancel={cancelEditing}
339
+ prefilter={(column as TableColumnSelect).prefilter}
340
+ />
341
+ )}
342
+ {displayEditor && column.editor === editorSwitch && (
343
+ <Switch onClick={e => {
344
+ stopPropagation(e);
345
+ preventDefault(e);
346
+ setValue(!value)
347
+ }} value={value}/>
348
+ )}
349
+ {displayEditor && isFunction(column.editor)
350
+ && (column.editor as ((t: T, cancel: () => void, isEditing: boolean) => ReactElement))(item, cancelEditing, isEditing)}
351
+ {!isEditing && !column.displayEditor && formatValue(item, column)}
352
+ </td>
353
+ );
354
+ })}
355
+ </tr>
356
+ }
357
+ }
358
+
359
+
360
+ export default Table;
@@ -0,0 +1,122 @@
1
+ .TextField {
2
+ position: relative;
3
+ width: 100%;
4
+ }
5
+ .TextField > label {
6
+ font-family: Roboto, sans-serif;
7
+ color: rgba(0, 0, 0, 0.3);
8
+ font-size: 16px;
9
+ position: absolute;
10
+ left: 0px;
11
+ top: 16px;
12
+ margin-top: -16px;
13
+ transition: all 0.2s ease;
14
+ user-select: none;
15
+ cursor: text;
16
+ }
17
+ .TextField > input {
18
+ font-family: Roboto, sans-serif;
19
+ color: #1e252d;
20
+ height: 19px;
21
+ font-size: 16px;
22
+ width: 100%;
23
+ border: 0px;
24
+ padding-bottom: 4px;
25
+ padding-top: 0;
26
+ outline-color: rgba(0, 0, 0, 0);
27
+ }
28
+ .TextField > input:focus {
29
+ outline: none;
30
+ }
31
+ .TextField > input:disabled {
32
+ color: gray;
33
+ background-color: white;
34
+ }
35
+ .TextField > input:disabled + .border {
36
+ height: 0px;
37
+ border-bottom: 2px dotted #e0e0e0;
38
+ }
39
+ .TextField > input::placeholder {
40
+ font-family: Roboto, sans-serif;
41
+ color: rgba(0, 0, 0, 0.3);
42
+ opacity: 1;
43
+ }
44
+ .TextField > .border {
45
+ border-bottom: 1px solid #e0e0e0;
46
+ height: 1px;
47
+ position: relative;
48
+ }
49
+ .TextField > .border .line {
50
+ left: 50%;
51
+ width: 0;
52
+ height: 2px;
53
+ min-height: 2px;
54
+ background-color: #00bcd4;
55
+ transition: all 0.2s ease;
56
+ position: absolute;
57
+ }
58
+ .TextField > .error {
59
+ text-align: left;
60
+ font-size: 10px;
61
+ min-height: 0;
62
+ line-height: 14px;
63
+ color: #f44336;
64
+ visibility: hidden;
65
+ opacity: 0;
66
+ transition: all 0.2s ease;
67
+ }
68
+ .TextField.focused > label, .TextField.withValue > label {
69
+ top: 4px;
70
+ font-size: 12px;
71
+ line-height: 14px;
72
+ }
73
+ .TextField.errored > .error {
74
+ visibility: visible;
75
+ opacity: 1;
76
+ }
77
+ .TextField.errored > .border {
78
+ border-bottom-color: #f44336;
79
+ }
80
+ .TextField.errored > label {
81
+ color: #f44336;
82
+ }
83
+ .TextField.focused > label {
84
+ color: #00bcd4;
85
+ }
86
+ .TextField.focused > .border .line {
87
+ left: 0;
88
+ width: 100%;
89
+ }
90
+ .TextField.disabled label, .TextField.disabled input {
91
+ cursor: not-allowed;
92
+ }
93
+ .TextField.withLabel {
94
+ margin-top: 15px;
95
+ }
96
+ .TextField input::-webkit-contacts-auto-fill-button {
97
+ visibility: hidden;
98
+ display: none !important;
99
+ pointer-events: none;
100
+ position: absolute;
101
+ right: 0;
102
+ }
103
+ .TextField input:-webkit-autofill {
104
+ -webkit-box-shadow: inset 0 0 0px 9999px white;
105
+ }
106
+ @keyframes shake {
107
+ 0%, 100% {
108
+ transform: translateX(0);
109
+ }
110
+ 20%, 60% {
111
+ transform: translateX(-5px);
112
+ }
113
+ 40%, 80% {
114
+ transform: translateX(5px);
115
+ }
116
+ }
117
+ .TextField .shake {
118
+ animation-duration: 0.5s;
119
+ animation-fill-mode: both;
120
+ animation-timing-function: ease-in-out;
121
+ animation-name: shake;
122
+ }
@@ -0,0 +1,162 @@
1
+ import ReactConstants from "./../ReactConstants";
2
+ import {clientHeight as __clientHeight, clientWidth as __clientWidth, createAccessor as __createAccessor, data as __data, height as __height, left as __left, length as __length, pageX as __pageX, pageY as __pageY, props as __props, scrollLeft as __scrollLeft, scrollTop as __scrollTop, state as __state, style as __style, target as __target, top as __top, value as __value, width as __width} from "./../CommonFields";
3
+ import React from 'react';
4
+ import {toConsumableArray as __toConsumableArray} from "./../_virtual/_rollupPluginBabelHelpers";
5
+ import {extends as __extends} from "./../_virtual/_rollupPluginBabelHelpers";
6
+ import {inherits as __inherits} from "./../_virtual/_rollupPluginBabelHelpers";
7
+ import './TextField.css';
8
+ import ReactCreateElement from './ReactCreateElement';
9
+ import './TextField.css'
10
+ import {classNames, getRandomId, isUndefined, orNoop, addEventListener, createRef, setTimeout} from "./Tools";
11
+ import {PureComponent, render, componentDidMount, propsGetter, stateGSs, componentDidUpdate} from "./ReactConstants";
12
+ import PropTypes from "prop-types";
13
+
14
+ class TextField extends PureComponent {
15
+
16
+ constructor(properties) {
17
+ super(properties);
18
+ const that = this;
19
+ that.state = {};
20
+
21
+ const randomId = getRandomId('tf-');
22
+ const [
23
+ isFocused,
24
+ errorState,
25
+ isWithValue,
26
+ ] = stateGSs(that, 3);
27
+ const props = propsGetter(that);
28
+
29
+ const inputRef = createRef();
30
+ const check = () => {
31
+ const {required, check} = props();
32
+ const value = __value(inputRef());
33
+ const error = (required && value === '') || (check && check(value));
34
+ errorState() !== error && setTimeout(errorState, 0, error);
35
+ return error;
36
+ };
37
+
38
+ const onChange = (e) => {
39
+ orNoop(props()[ReactConstants[7]])(e);
40
+ isWithValue(!!__value(inputRef()));
41
+ check()
42
+ };
43
+
44
+ const onFocus = () => {
45
+ isFocused(true);
46
+ orNoop(props().onFocus)();
47
+ };
48
+ const onBlur = () => {
49
+ isFocused(false);
50
+ check();
51
+ orNoop(props().onBlur)();
52
+ };
53
+
54
+ that[ReactConstants[3]] = () => {
55
+ const _props = props();
56
+ const {value, name, type, label, check, disabled, required, min, max, onClick, onKeyDown, onKeyUp, onMouseUp, autoComplete, placeholder, className} = _props;
57
+ const id = _props.id || randomId;
58
+ const error = errorState();
59
+ return (
60
+ <div
61
+ className={classNames('TextField',
62
+ isFocused() && 'focused',
63
+ (value || placeholder || (isWithValue() && isUndefined(value))) && 'withValue',
64
+ error && (required || check) && 'errored',
65
+ disabled && 'disabled',
66
+ label && 'withLabel',
67
+ className)}
68
+ onClick={() => {
69
+ inputRef().focus();
70
+ }}
71
+ >
72
+ {label && (<label className={classNames(error && !isFocused() && 'shake')} htmlFor={id}>{label}{required && ' *'}</label>)}
73
+ <input type={type || 'text'} id={id} name={name} value={value} disabled={disabled}
74
+ min={min}
75
+ max={max}
76
+ ref={inputRef}
77
+ onChange={onChange}
78
+ onFocus={onFocus}
79
+ onBlur={onBlur}
80
+ onClick={onClick}
81
+ onKeyDown={onKeyDown}
82
+ onKeyUp={onKeyUp}
83
+ onMouseUp={onMouseUp}
84
+ autoComplete={autoComplete || 'on'}
85
+ placeholder={placeholder}
86
+ />
87
+ <div className="border">
88
+ <div className="line"/>
89
+ </div>
90
+ {error && <div className="error">{error}</div>}
91
+ </div>
92
+ )
93
+ };
94
+
95
+ that[ReactConstants[0]] = () => {
96
+ const {focused, input} = props(),
97
+ i = inputRef();
98
+ let hasValue = !!__value(i);
99
+ isWithValue(hasValue);
100
+
101
+ !hasValue && setTimeout(() => {
102
+ try {
103
+ let matches = i.matches(':-internal-autofill-selected');
104
+ matches && isWithValue(matches)
105
+ } catch (ignored) {
106
+ }
107
+ }, 100)
108
+
109
+ focused && i.focus();
110
+ orNoop(input)(i);
111
+ };
112
+ that[ReactConstants[2]] = () => {
113
+ if (__value(props()) !== __value(inputRef()))
114
+ check();
115
+ const {focused} = props(),
116
+ i = inputRef();
117
+ focused && i.focus();
118
+ };
119
+ that.check = check;
120
+ that.getInput = inputRef;
121
+
122
+ that.withAutofillAnimationCallback = () => {
123
+ addEventListener(inputRef(), 'animationstart', () => {
124
+ isWithValue(true);
125
+ }, false);
126
+ };
127
+ }
128
+ }
129
+
130
+ if (process.env.NODE_ENV !== 'production') {
131
+ TextField.propTypes = {
132
+ id: PropTypes.string,
133
+ [ReactConstants[5]]: PropTypes.string,
134
+ value: PropTypes.string,
135
+ name: PropTypes.string,
136
+ type: PropTypes.string,
137
+ autoComplete: PropTypes.string,
138
+ placeholder: PropTypes.string,
139
+ label: PropTypes.oneOfType([
140
+ PropTypes.string,
141
+ PropTypes.element
142
+ ]),
143
+ check: PropTypes.func,
144
+ [ReactConstants[6]]: PropTypes.func,
145
+ onKeyDown: PropTypes.func,
146
+ onFocus: PropTypes.func,
147
+ onBlur: PropTypes.func,
148
+ [ReactConstants[7]]: PropTypes.func,
149
+ required: PropTypes.bool,
150
+ disabled: PropTypes.bool,
151
+ min: PropTypes.oneOfType([
152
+ PropTypes.string,
153
+ PropTypes.number
154
+ ]),
155
+ max: PropTypes.oneOfType([
156
+ PropTypes.string,
157
+ PropTypes.number
158
+ ]),
159
+ };
160
+ }
161
+
162
+ export default TextField