react-ui-basics 0.0.219 → 0.0.221
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/Animated.js +1 -0
- package/Animated.js.map +1 -1
- package/Button.d.ts +24 -0
- package/Button.js +45 -75
- package/Button.js.map +1 -1
- package/DNDContainer.js +10 -5
- package/DNDContainer.js.map +1 -1
- package/DNDDraggable.d.ts +29 -0
- package/DNDDraggable.js +27 -44
- package/DNDDraggable.js.map +1 -1
- package/DNDDroppable.d.ts +28 -0
- package/DNDDroppable.js +32 -46
- package/DNDDroppable.js.map +1 -1
- package/Dialog.d.ts +29 -0
- package/Dialog.js +84 -143
- package/Dialog.js.map +1 -1
- package/DroppableHorizontalList.js +28 -27
- package/DroppableHorizontalList.js.map +1 -1
- package/DroppableList.js +29 -34
- package/DroppableList.js.map +1 -1
- package/Dropzone.js.map +1 -1
- package/FilteredList.d.ts +62 -0
- package/FilteredList.js +128 -232
- package/FilteredList.js.map +1 -1
- package/FormUploadProgress.d.ts +19 -0
- package/FormUploadProgress.js +14 -39
- package/FormUploadProgress.js.map +1 -1
- package/Modal.d.ts +31 -0
- package/Modal.js +102 -134
- package/Modal.js.map +1 -1
- package/ReactConstants.d.ts +6 -2
- package/ReactConstants.js +1 -1
- package/ReactConstants.js.map +1 -1
- package/ReactCreateElement.d.ts +3 -0
- package/ReactCreateElement.js.map +1 -1
- package/ReadyListener.d.ts +34 -0
- package/ReadyListener.js +34 -56
- package/ReadyListener.js.map +1 -1
- package/Scrollable.css +0 -1
- package/Scrollable.d.ts +33 -0
- package/Scrollable.js +308 -325
- package/Scrollable.js.map +1 -1
- package/ScrollableTable.d.ts +4 -2
- package/ScrollableTable.js +5 -6
- package/ScrollableTable.js.map +1 -1
- package/Table.js +1 -1
- package/Table.js.map +1 -1
- package/TextField.d.ts +36 -0
- package/TextField.js +73 -134
- package/TextField.js.map +1 -1
- package/Tools.d.ts +1 -1
- package/Tools.js +1 -1
- package/Tools.js.map +1 -1
- package/_virtual/_rollupPluginBabelHelpers.js +0 -15
- package/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
- package/bundle.css +903 -904
- package/package.json +1 -1
- package/router/Route.js +1 -0
- package/router/Route.js.map +1 -1
- package/src/Button.tsx +96 -0
- package/src/DNDContainer.tsx +19 -10
- package/src/{DNDDraggable.js → DNDDraggable.tsx} +35 -9
- package/src/{DNDDroppable.js → DNDDroppable.tsx} +35 -8
- package/src/{Dialog.js → Dialog.tsx} +63 -44
- package/src/DroppableHorizontalList.js +33 -32
- package/src/DroppableList.js +34 -41
- package/src/Dropzone.tsx +1 -1
- package/src/{FilteredList.js → FilteredList.tsx} +95 -45
- package/src/{FormUploadProgress.js → FormUploadProgress.tsx} +13 -22
- package/src/{Modal.js → Modal.tsx} +48 -33
- package/src/ReactConstants.ts +14 -6
- package/src/ReactCreateElement.tsx +3 -0
- package/src/ReadyListener.tsx +58 -0
- package/src/Scrollable.css +0 -1
- package/src/Scrollable.scss +0 -1
- package/src/{Scrollable.js → Scrollable.tsx} +72 -60
- package/src/ScrollableTable.tsx +7 -7
- package/src/Table.tsx +3 -3
- package/src/{TextField.js → TextField.tsx} +42 -44
- package/src/Tools.ts +2 -2
- package/src/store/Store.test.js +1 -1
- package/src/store/Store.ts +3 -1
- package/store/Store.js +1 -0
- package/store/Store.js.map +1 -1
- package/src/Button.js +0 -98
- package/src/ReactCreateElement.js +0 -3
- package/src/ReadyListener.js +0 -48
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React, {ReactElement, ReactNode} from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import ReactCreateElement from './ReactCreateElement';
|
|
4
4
|
import './Modal.css'
|
|
@@ -6,7 +6,6 @@ import Button from "./Button";
|
|
|
6
6
|
import {classNames, orNoop, setTimeout, DOCUMENT, addEventListener, removeEventListener, createRef, UNDEFINED, stopPropagation} from "./Tools";
|
|
7
7
|
import {PureComponent, componentDidMount, render, propsGetter, stateGSs, componentDidUpdate} from "./ReactConstants";
|
|
8
8
|
import MaterialIcon from "./MaterialIcon";
|
|
9
|
-
import PropTypes from "prop-types";
|
|
10
9
|
|
|
11
10
|
let listenerRef;
|
|
12
11
|
let zIndex = 100;
|
|
@@ -26,7 +25,32 @@ const addListener = (modal, listener) => {
|
|
|
26
25
|
addEventListener(DOCUMENT, EVENT_TYPE, listenerRef = listener);
|
|
27
26
|
};
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
type VoidFunction = () => void;
|
|
29
|
+
|
|
30
|
+
export interface ModalProps {
|
|
31
|
+
className?: string
|
|
32
|
+
top?: number
|
|
33
|
+
container?: Element | DocumentFragment
|
|
34
|
+
children?: ReactNode
|
|
35
|
+
closeIcon?: string | ReactElement
|
|
36
|
+
beforeClose?: (close: VoidFunction) => void
|
|
37
|
+
onOpen?: VoidFunction
|
|
38
|
+
onClose?: VoidFunction
|
|
39
|
+
open?: (open: VoidFunction) => void
|
|
40
|
+
close?: (open: VoidFunction) => void
|
|
41
|
+
show?: boolean
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
abstract class AbstractModal extends PureComponent<ModalProps> {
|
|
45
|
+
close: VoidFunction
|
|
46
|
+
open: VoidFunction
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class Modal extends AbstractModal {
|
|
50
|
+
|
|
51
|
+
static defaultContainer = UNDEFINED
|
|
52
|
+
static pollListener = pollListener
|
|
53
|
+
static addListener = addListener
|
|
30
54
|
|
|
31
55
|
static defaultProps = {
|
|
32
56
|
closeIcon: <MaterialIcon icon="close"/>,
|
|
@@ -41,22 +65,22 @@ class Modal extends PureComponent {
|
|
|
41
65
|
isShow,
|
|
42
66
|
getMenu,
|
|
43
67
|
getBeforeClose,
|
|
44
|
-
] = stateGSs(that, 3);
|
|
45
|
-
const overlay = createRef();
|
|
46
|
-
const el = createRef();
|
|
47
|
-
const content = createRef();
|
|
68
|
+
] = stateGSs<[boolean, any, (close: VoidFunction) => void]>(that, 3);
|
|
69
|
+
const overlay = createRef<HTMLDivElement>();
|
|
70
|
+
const el = createRef<HTMLDivElement>();
|
|
71
|
+
const content = createRef<HTMLDivElement>();
|
|
48
72
|
const props = propsGetter(that);
|
|
49
73
|
|
|
50
74
|
const beforeClose = (e) => {
|
|
51
75
|
stopPropagation(e);
|
|
52
76
|
const bc = getBeforeClose() || props().beforeClose;
|
|
53
77
|
if (!bc || bc(that.close))
|
|
54
|
-
that.close(
|
|
78
|
+
that.close();
|
|
55
79
|
};
|
|
56
80
|
|
|
57
81
|
const shouldClose = (e) => {
|
|
58
|
-
const isSameModal =
|
|
59
|
-
!(e && content().contains(
|
|
82
|
+
const isSameModal = el().style.zIndex == (zIndex - 1) + '';
|
|
83
|
+
!(e && content().contains(e.target)) && isSameModal && beforeClose(e);
|
|
60
84
|
};
|
|
61
85
|
|
|
62
86
|
const addTransitionListener = () => {
|
|
@@ -64,11 +88,11 @@ class Modal extends PureComponent {
|
|
|
64
88
|
let listener = () => {
|
|
65
89
|
removeEventListener(overlay(), transitionend, listener);
|
|
66
90
|
orNoop(isShow() ? props().onOpen : orNoop(props().onClose))();
|
|
67
|
-
el() && (
|
|
91
|
+
el() && (el().style.paddingBottom = isShow() ? '1px' : '0px'); // force invalidate scroll
|
|
68
92
|
};
|
|
69
93
|
addEventListener(overlay(), transitionend, listener);
|
|
70
94
|
};
|
|
71
|
-
that[
|
|
95
|
+
that[render] = () => {
|
|
72
96
|
const {className, top, container = Modal.defaultContainer, children, closeIcon} = props();
|
|
73
97
|
const menu = getMenu();
|
|
74
98
|
const show = isShow();
|
|
@@ -79,10 +103,13 @@ class Modal extends PureComponent {
|
|
|
79
103
|
style={top && {top: top + 'px'}}
|
|
80
104
|
ref={content}
|
|
81
105
|
>
|
|
82
|
-
{React.Children.map(children, child =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
106
|
+
{React.Children.map(children, child => {
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
return React.cloneElement(child, {
|
|
109
|
+
modalMenuConsumer: getMenu,
|
|
110
|
+
modalBeforeCloseConsumer: getBeforeClose
|
|
111
|
+
});
|
|
112
|
+
})}
|
|
86
113
|
{menu}
|
|
87
114
|
<Button className="close" flat={true} round={true} onClick={beforeClose}>
|
|
88
115
|
{closeIcon}
|
|
@@ -107,20 +134,20 @@ class Modal extends PureComponent {
|
|
|
107
134
|
if (isShow())
|
|
108
135
|
return;
|
|
109
136
|
|
|
110
|
-
el() && (
|
|
137
|
+
el() && (el().style.zIndex = '' + (zIndex++));
|
|
111
138
|
addTransitionListener();
|
|
112
139
|
isShow(true);
|
|
113
140
|
|
|
114
141
|
let listener = event => {
|
|
115
142
|
if (!event.defaultPrevented && event.keyCode === 27/*escape*/)
|
|
116
|
-
beforeClose();
|
|
143
|
+
beforeClose(event);
|
|
117
144
|
return true;
|
|
118
145
|
};
|
|
119
146
|
|
|
120
147
|
addListener(that, listener)
|
|
121
148
|
};
|
|
122
149
|
|
|
123
|
-
that[
|
|
150
|
+
that[componentDidMount] = () => {
|
|
124
151
|
const _props = props();
|
|
125
152
|
orNoop(_props.open)(() => {
|
|
126
153
|
setTimeout(open, 0);
|
|
@@ -130,7 +157,7 @@ class Modal extends PureComponent {
|
|
|
130
157
|
});
|
|
131
158
|
_props.show && setTimeout(open, 0)
|
|
132
159
|
};
|
|
133
|
-
that[
|
|
160
|
+
that[componentDidUpdate] = (prevProps) => {
|
|
134
161
|
const show = props().show;
|
|
135
162
|
if (show !== prevProps.show) {
|
|
136
163
|
show ? open() : close();
|
|
@@ -139,16 +166,4 @@ class Modal extends PureComponent {
|
|
|
139
166
|
}
|
|
140
167
|
}
|
|
141
168
|
|
|
142
|
-
|
|
143
|
-
Modal.pollListener = pollListener;
|
|
144
|
-
Modal.addListener = addListener;
|
|
145
|
-
|
|
146
|
-
export default Modal;
|
|
147
|
-
|
|
148
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
149
|
-
Modal.propTypes = {
|
|
150
|
-
[ReactConstants[5]]: PropTypes.string,
|
|
151
|
-
top: PropTypes.number,
|
|
152
|
-
container: PropTypes.node,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
169
|
+
export default Modal;
|
package/src/ReactConstants.ts
CHANGED
|
@@ -11,7 +11,9 @@ export const setState = (that: React.Component, data, cb?) => {
|
|
|
11
11
|
export const stateFieldSetter = (that, key, cb?: () => void) => (value, cb2?) => {
|
|
12
12
|
setState(that, {[key]: value}, cb2 || cb);
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
type GetterSetter<T> = (v?: T, cb?: () => void) => T;
|
|
16
|
+
export const stateGS: (<T>(that: React.Component) => GetterSetter<T>) = (that) => {
|
|
15
17
|
!that['sfc'] && (that['sfc'] = 0);
|
|
16
18
|
const key = '_' + (that['sfc']++);
|
|
17
19
|
const setter = stateFieldSetter(that, key);
|
|
@@ -21,17 +23,23 @@ export const stateGS: (<T>(that: React.Component) => (v?: T, cb?: () => void) =>
|
|
|
21
23
|
result.toString = () => key;
|
|
22
24
|
return result;
|
|
23
25
|
};
|
|
24
|
-
|
|
26
|
+
|
|
27
|
+
type TupleToGetterSetter<T extends any[]> = {
|
|
28
|
+
[K in keyof T]: GetterSetter<T[K]>;
|
|
29
|
+
};
|
|
30
|
+
export const stateGSs = <T extends any[]>(that, num): TupleToGetterSetter<T> => {
|
|
25
31
|
const result = [];
|
|
26
32
|
for (let i = 0; i < num; i++) {
|
|
27
33
|
result.push(stateGS(that));
|
|
28
34
|
}
|
|
29
|
-
return result
|
|
35
|
+
return result as TupleToGetterSetter<T>;
|
|
30
36
|
};
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
type GetSnapshot<T> = () => T;
|
|
39
|
+
type Subscribe = (onStoreChange: () => void) => () => void;
|
|
40
|
+
const useSyncExternalStoreShim = <T>(subscribe: Subscribe, getSnapshot: GetSnapshot<T>) => {
|
|
33
41
|
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
|
34
|
-
const cb = useRef();
|
|
42
|
+
const cb = useRef<GetSnapshot<T>>();
|
|
35
43
|
cb.current = getSnapshot;
|
|
36
44
|
let value = getSnapshot()
|
|
37
45
|
|
|
@@ -45,7 +53,7 @@ const useSyncExternalStoreShim = (subscribe, getSnapshot) => {
|
|
|
45
53
|
return value
|
|
46
54
|
}
|
|
47
55
|
|
|
48
|
-
export const useSyncExternalStore = React
|
|
56
|
+
export const useSyncExternalStore = React['useSyncExternalStore'] || useSyncExternalStoreShim
|
|
49
57
|
|
|
50
58
|
export const componentDidMount = 'componentDidMount';
|
|
51
59
|
export const componentWillUnmount = 'componentWillUnmount';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, {ReactNode} from 'react';
|
|
2
|
+
import ReactCreateElement from './ReactCreateElement';
|
|
3
|
+
import {componentDidMount, render, componentWillUnmount, setState, props, state, componentDidUpdate, children, PureComponent} from "./ReactConstants";
|
|
4
|
+
import {orNoop} from "./Tools";
|
|
5
|
+
|
|
6
|
+
export interface NotReadyIndicatorProps {
|
|
7
|
+
onChange?: (ready: boolean) => void
|
|
8
|
+
render?: (ready: boolean) => JSX.Element | ReactNode
|
|
9
|
+
children?: ReactNode
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface NotReadyIndicatorState {
|
|
13
|
+
r: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const createReadyListener = () => {
|
|
17
|
+
let indicator,
|
|
18
|
+
count = 0;
|
|
19
|
+
|
|
20
|
+
class NotReadyIndicator extends PureComponent<NotReadyIndicatorProps, NotReadyIndicatorState> {
|
|
21
|
+
constructor(properties) {
|
|
22
|
+
super(properties);
|
|
23
|
+
const that = this;
|
|
24
|
+
that.state = {r: true};
|
|
25
|
+
indicator = that;
|
|
26
|
+
that[render] = () => {
|
|
27
|
+
const _props = props(that),
|
|
28
|
+
renderer = _props[render],
|
|
29
|
+
ready = state(that).r;
|
|
30
|
+
|
|
31
|
+
if (renderer)
|
|
32
|
+
return renderer(ready);
|
|
33
|
+
else
|
|
34
|
+
return (!ready && _props[children]) || null;
|
|
35
|
+
};
|
|
36
|
+
that[componentDidMount] = that[componentDidUpdate] = () => {
|
|
37
|
+
orNoop(props(that).onChange)(state(that).r);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class NotReady extends PureComponent {
|
|
43
|
+
constructor(props) {
|
|
44
|
+
super(props);
|
|
45
|
+
const that = this;
|
|
46
|
+
that[componentDidMount] = () => {
|
|
47
|
+
count++;
|
|
48
|
+
setState(indicator, {r: false});
|
|
49
|
+
};
|
|
50
|
+
that[componentWillUnmount] = () => {
|
|
51
|
+
setState(indicator, {r: --count === 0});
|
|
52
|
+
};
|
|
53
|
+
that[render] = () => null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return [NotReadyIndicator, NotReady]
|
|
58
|
+
};
|
package/src/Scrollable.css
CHANGED
package/src/Scrollable.scss
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React, {CSSProperties, ReactNode} from 'react';
|
|
2
2
|
import ReactCreateElement from './ReactCreateElement';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import './Scrollable.css'
|
|
@@ -40,7 +40,32 @@ const scrollBarModeOf = createFieldGetter('scrollBarMode');
|
|
|
40
40
|
const onScroll = createFieldGetter('onScroll');
|
|
41
41
|
const horizontalScrollBarModeOf = createFieldGetter('horizontalScrollBarMode');
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
type ScrollbarMode = typeof SCROLLBAR_MODE_HIDDEN | typeof SCROLLBAR_MODE_VISIBLE | typeof SCROLLBAR_MODE_AUTO | typeof SCROLLBAR_RESIZE_DISABLED;
|
|
44
|
+
|
|
45
|
+
export interface ScrollableProps {
|
|
46
|
+
scrollBarMode?: ScrollbarMode
|
|
47
|
+
horizontalScrollBarMode?: ScrollbarMode
|
|
48
|
+
className?: string
|
|
49
|
+
style?: CSSProperties
|
|
50
|
+
onScrolledToBottom?: () => void
|
|
51
|
+
onScrolledToTop?: () => void
|
|
52
|
+
autoScrollTop?: boolean
|
|
53
|
+
children?: ReactNode
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
abstract class AbstractScrollable extends PureComponent<ScrollableProps> {
|
|
57
|
+
el: HTMLDivElement
|
|
58
|
+
setScroll: (y) => void
|
|
59
|
+
getScroll: () => number
|
|
60
|
+
getScrollHeight: () => number
|
|
61
|
+
getHeight: () => number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class Scrollable extends AbstractScrollable {
|
|
65
|
+
static defaultProps = {
|
|
66
|
+
autoScrollTop: true,
|
|
67
|
+
horizontalScrollBarMode: SCROLLBAR_MODE_HIDDEN
|
|
68
|
+
}
|
|
44
69
|
|
|
45
70
|
constructor(properties) {
|
|
46
71
|
super(properties);
|
|
@@ -48,14 +73,14 @@ class Scrollable extends PureComponent {
|
|
|
48
73
|
that.state = {};
|
|
49
74
|
|
|
50
75
|
const props = propsGetter(that);
|
|
51
|
-
const status = stateGS(that);
|
|
52
|
-
const statusH = stateGS(that);
|
|
76
|
+
const status = stateGS<typeof WITHOUT_SCROLL | typeof WITH_SCROLL>(that);
|
|
77
|
+
const statusH = stateGS<typeof WITHOUT_SCROLL | typeof WITH_SCROLL>(that);
|
|
53
78
|
|
|
54
|
-
const viewportRef = createRef();
|
|
55
|
-
const scrollbarRef = createRef();
|
|
56
|
-
const horizontalScrollbarRef = createRef();
|
|
57
|
-
const thumbRef = createRef();
|
|
58
|
-
const horizontalThumbRef = createRef();
|
|
79
|
+
const viewportRef = createRef<HTMLDivElement>();
|
|
80
|
+
const scrollbarRef = createRef<HTMLDivElement>();
|
|
81
|
+
const horizontalScrollbarRef = createRef<HTMLDivElement>();
|
|
82
|
+
const thumbRef = createRef<HTMLDivElement>();
|
|
83
|
+
const horizontalThumbRef = createRef<HTMLDivElement>();
|
|
59
84
|
|
|
60
85
|
let resizeInterval;
|
|
61
86
|
let initTimeout;
|
|
@@ -81,7 +106,7 @@ class Scrollable extends PureComponent {
|
|
|
81
106
|
const thumb = thumbRef();
|
|
82
107
|
const thumbH = horizontalThumbRef();
|
|
83
108
|
|
|
84
|
-
let scrolling =
|
|
109
|
+
let scrolling = '';
|
|
85
110
|
let scrolledToBottom = false;
|
|
86
111
|
let scrolledToTop = false;
|
|
87
112
|
let adjustedScrollWidth = false;
|
|
@@ -98,8 +123,8 @@ class Scrollable extends PureComponent {
|
|
|
98
123
|
const offsetWidth = offsetWidthOf(viewport);
|
|
99
124
|
const scrollbarHeight = offsetHeightOf(scrollbar);
|
|
100
125
|
const scrollbarWidth = offsetWidthOf(scrollbarH);
|
|
101
|
-
let position =
|
|
102
|
-
const positionH =
|
|
126
|
+
let position = viewport.scrollTop / (scrollHeight - offsetHeight);
|
|
127
|
+
const positionH = viewport.scrollLeft / (scrollWidth - offsetWidth);
|
|
103
128
|
|
|
104
129
|
if (position > 1) {
|
|
105
130
|
viewport.scrollTop = scrollHeight - offsetHeight;
|
|
@@ -128,8 +153,8 @@ class Scrollable extends PureComponent {
|
|
|
128
153
|
const reset = () => {
|
|
129
154
|
removeEventListener(WINDOW, 'mouseup', reset);
|
|
130
155
|
removeEventListener(WINDOW, 'mousemove', moveListener);
|
|
131
|
-
|
|
132
|
-
scrolling =
|
|
156
|
+
viewport.style.scrollBehavior = ''
|
|
157
|
+
scrolling = '';
|
|
133
158
|
};
|
|
134
159
|
const moveListener = (e) => {
|
|
135
160
|
if (!scrolling)
|
|
@@ -147,7 +172,7 @@ class Scrollable extends PureComponent {
|
|
|
147
172
|
lastY = e.clientY;
|
|
148
173
|
scrolling = 'v';
|
|
149
174
|
ratio = scrollHeightOf(viewport) / offsetHeightOf(viewport);
|
|
150
|
-
|
|
175
|
+
viewport.style.scrollBehavior = 'unset'
|
|
151
176
|
|
|
152
177
|
addEventListener(WINDOW, 'mouseup', reset);
|
|
153
178
|
addEventListener(WINDOW, 'mousemove', moveListener);
|
|
@@ -159,7 +184,7 @@ class Scrollable extends PureComponent {
|
|
|
159
184
|
lastX = e.clientX;
|
|
160
185
|
scrolling = 'h';
|
|
161
186
|
ratioH = scrollWidthOf(viewport) / offsetWidthOf(viewport);
|
|
162
|
-
|
|
187
|
+
viewport.style.scrollBehavior = 'unset'
|
|
163
188
|
|
|
164
189
|
addEventListener(WINDOW, 'mouseup', reset);
|
|
165
190
|
addEventListener(WINDOW, 'mousemove', moveListener);
|
|
@@ -168,27 +193,27 @@ class Scrollable extends PureComponent {
|
|
|
168
193
|
thumbH.onmouseup = reset;
|
|
169
194
|
|
|
170
195
|
scrollbar.onclick = (e) => {
|
|
171
|
-
if (
|
|
172
|
-
let thumbPosition = parseInt(
|
|
196
|
+
if (e.target === scrollbar) {
|
|
197
|
+
let thumbPosition = parseInt(styleOf(thumb).top);
|
|
173
198
|
viewport.scrollTop += offsetHeightOf(viewport) * 0.9 * (e.offsetY < thumbPosition ? -1 : 1);
|
|
174
199
|
}
|
|
175
200
|
};
|
|
176
201
|
scrollbarH.onclick = (e) => {
|
|
177
|
-
if (
|
|
178
|
-
let thumbPosition = parseInt(
|
|
202
|
+
if (e.target === scrollbarH) {
|
|
203
|
+
let thumbPosition = parseInt(styleOf(thumbH).left);
|
|
179
204
|
viewport.scrollLeft += offsetWidthOf(viewport) * 0.9 * (e.offsetX < thumbPosition ? -1 : 1);
|
|
180
205
|
}
|
|
181
206
|
};
|
|
182
207
|
|
|
183
208
|
const adjustScrollWidth = () => {
|
|
184
209
|
if (NATIVE_SCROLL_WIDTH < 0) {
|
|
185
|
-
NATIVE_SCROLL_WIDTH = viewport.offsetWidth -
|
|
210
|
+
NATIVE_SCROLL_WIDTH = viewport.offsetWidth - viewport.clientWidth;
|
|
186
211
|
if (NATIVE_SCROLL_WIDTH === 0 && scrollHeightOf(viewport) !== offsetHeightOf(viewport)) {
|
|
187
212
|
NATIVE_SCROLL_WIDTH = -1;
|
|
188
213
|
}
|
|
189
214
|
}
|
|
190
215
|
if (NATIVE_SCROLL_HEIGHT < 0) {
|
|
191
|
-
NATIVE_SCROLL_HEIGHT = viewport.offsetHeight -
|
|
216
|
+
NATIVE_SCROLL_HEIGHT = viewport.offsetHeight - viewport.clientHeight;
|
|
192
217
|
if (NATIVE_SCROLL_HEIGHT === 0 && scrollWidthOf(viewport) !== offsetWidthOf(viewport)) {
|
|
193
218
|
NATIVE_SCROLL_HEIGHT = -1;
|
|
194
219
|
}
|
|
@@ -196,12 +221,12 @@ class Scrollable extends PureComponent {
|
|
|
196
221
|
|
|
197
222
|
if (!adjustedScrollWidth) {
|
|
198
223
|
if (NATIVE_SCROLL_WIDTH >= 0 && status() !== WITHOUT_SCROLL) {
|
|
199
|
-
styleOf(viewport).paddingRight = (NATIVE_SCROLL_WIDTH) +
|
|
200
|
-
styleOf(viewport).marginRight = -(NATIVE_SCROLL_WIDTH) -
|
|
224
|
+
styleOf(viewport).paddingRight = (NATIVE_SCROLL_WIDTH) + scrollbar.clientWidth + 'px';
|
|
225
|
+
styleOf(viewport).marginRight = -(NATIVE_SCROLL_WIDTH) - scrollbar.clientWidth + 'px';
|
|
201
226
|
}
|
|
202
227
|
if (NATIVE_SCROLL_HEIGHT >= 0 && statusH() !== WITHOUT_SCROLL) {
|
|
203
|
-
styleOf(viewport).paddingBottom = (NATIVE_SCROLL_HEIGHT) +
|
|
204
|
-
styleOf(viewport).marginBottom = -(NATIVE_SCROLL_HEIGHT) -
|
|
228
|
+
styleOf(viewport).paddingBottom = (NATIVE_SCROLL_HEIGHT) + scrollbarH.clientHeight + 'px';
|
|
229
|
+
styleOf(viewport).marginBottom = -(NATIVE_SCROLL_HEIGHT) - scrollbarH.clientHeight + 'px';
|
|
205
230
|
}
|
|
206
231
|
adjustedScrollWidth = true;
|
|
207
232
|
}
|
|
@@ -252,13 +277,13 @@ class Scrollable extends PureComponent {
|
|
|
252
277
|
if (!containerHeight || (ratio === newRatio && Number.isFinite(newRatio)) || Number.isNaN(newRatio)) return;
|
|
253
278
|
|
|
254
279
|
const offsetHeight = offsetHeightOf(viewport);
|
|
255
|
-
const horizontalScrollBarOffset = statusH() !== WITHOUT_SCROLL ?
|
|
280
|
+
const horizontalScrollBarOffset = statusH() !== WITHOUT_SCROLL ? scrollbarH.clientHeight + Math.max(NATIVE_SCROLL_HEIGHT, 0) : 0;
|
|
256
281
|
|
|
257
282
|
let containerOffsetHeight = containerHeight + horizontalScrollBarOffset;
|
|
258
|
-
if (containerOffsetHeight
|
|
283
|
+
if (containerOffsetHeight === scrollHeight && status() === WITHOUT_SCROLL)
|
|
259
284
|
return;
|
|
260
285
|
|
|
261
|
-
if (props().autoScrollTop && scrollHeight - offsetHeight -
|
|
286
|
+
if (props().autoScrollTop && scrollHeight - offsetHeight - viewport.scrollTop <= 20 && newRatio < ratio && Number.isFinite(newRatio) && Number.isFinite(ratio)) {
|
|
262
287
|
viewport.scrollTop = 0; // scroll to top if scrollbar gets smaller
|
|
263
288
|
}
|
|
264
289
|
|
|
@@ -276,7 +301,7 @@ class Scrollable extends PureComponent {
|
|
|
276
301
|
return
|
|
277
302
|
}
|
|
278
303
|
|
|
279
|
-
if (containerOffsetHeight
|
|
304
|
+
if (containerOffsetHeight < scrollHeight) {
|
|
280
305
|
adjustedScrollWidth = false;
|
|
281
306
|
showScrollbar(scrollbar, viewport, adjustScrollWidth);
|
|
282
307
|
} else {
|
|
@@ -286,7 +311,7 @@ class Scrollable extends PureComponent {
|
|
|
286
311
|
scrolledToBottom = false;
|
|
287
312
|
scrolledToTop = false;
|
|
288
313
|
|
|
289
|
-
const position =
|
|
314
|
+
const position = viewport.scrollTop / (scrollHeight - offsetHeight);
|
|
290
315
|
styleOf(thumb).top = (position * (scrollbarHeight - offsetHeightOf(thumb))) + 'px';
|
|
291
316
|
};
|
|
292
317
|
|
|
@@ -301,10 +326,10 @@ class Scrollable extends PureComponent {
|
|
|
301
326
|
if (!containerWidth || (ratioH === newRatio && Number.isFinite(newRatio)) || Number.isNaN(newRatio)) return;
|
|
302
327
|
|
|
303
328
|
const offsetWidth = offsetWidthOf(viewport);
|
|
304
|
-
const verticalScrollBarOffset = status() !== WITHOUT_SCROLL ?
|
|
329
|
+
const verticalScrollBarOffset = status() !== WITHOUT_SCROLL ? scrollbar.clientWidth + Math.max(NATIVE_SCROLL_WIDTH, 0) : 0;
|
|
305
330
|
|
|
306
331
|
let containerOffsetWidth = containerWidth + verticalScrollBarOffset;
|
|
307
|
-
if (containerOffsetWidth
|
|
332
|
+
if (containerOffsetWidth === scrollWidth && statusH() === WITHOUT_SCROLL)
|
|
308
333
|
return;
|
|
309
334
|
|
|
310
335
|
ratioH = newRatio;
|
|
@@ -322,21 +347,21 @@ class Scrollable extends PureComponent {
|
|
|
322
347
|
styleOf(container).width = (scrollWidth - verticalScrollBarOffset) + 'px';
|
|
323
348
|
containerOffsetWidth = containerWidth + verticalScrollBarOffset;
|
|
324
349
|
|
|
325
|
-
if (containerOffsetWidth
|
|
350
|
+
if (containerOffsetWidth < scrollWidth) {
|
|
326
351
|
adjustedScrollWidth = false;
|
|
327
352
|
showHorizontalScrollbar(scrollbarH, viewport, adjustScrollWidth);
|
|
328
353
|
} else {
|
|
329
354
|
hideHorizontalScrollbar(scrollbarH, viewport);
|
|
330
355
|
}
|
|
331
356
|
|
|
332
|
-
const position =
|
|
357
|
+
const position = viewport.scrollLeft / (scrollWidth - offsetWidth);
|
|
333
358
|
styleOf(thumbH).left = (position * (scrollbarWidth - offsetWidthOf(thumbH))) + 'px';
|
|
334
359
|
};
|
|
335
360
|
|
|
336
361
|
let update;
|
|
337
362
|
let sbm = scrollBarModeOf(props());
|
|
338
363
|
let hsbm = horizontalScrollBarModeOf(props());
|
|
339
|
-
if (sbm !== SCROLLBAR_RESIZE_DISABLED &&
|
|
364
|
+
if (sbm !== SCROLLBAR_RESIZE_DISABLED && hsbm !== SCROLLBAR_RESIZE_DISABLED) {
|
|
340
365
|
update = () => {
|
|
341
366
|
updateVerticalScrollbar();
|
|
342
367
|
updateHorizontalScrollbar();
|
|
@@ -353,10 +378,10 @@ class Scrollable extends PureComponent {
|
|
|
353
378
|
}
|
|
354
379
|
};
|
|
355
380
|
|
|
356
|
-
that[
|
|
357
|
-
that[
|
|
381
|
+
that[componentDidMount] = init;
|
|
382
|
+
that[componentWillUnmount] = clear;
|
|
358
383
|
|
|
359
|
-
that[
|
|
384
|
+
that[componentDidUpdate] = (prevProps) => {
|
|
360
385
|
if (scrollBarModeOf(props()) !== scrollBarModeOf(prevProps))
|
|
361
386
|
init();
|
|
362
387
|
else if (onScroll(props()) !== onScroll(prevProps))
|
|
@@ -366,15 +391,19 @@ class Scrollable extends PureComponent {
|
|
|
366
391
|
that.setScroll = (y) => {
|
|
367
392
|
viewportRef().scrollTop = y
|
|
368
393
|
};
|
|
369
|
-
that.getScroll = () =>
|
|
394
|
+
that.getScroll = () => viewportRef().scrollTop;
|
|
370
395
|
that.getScrollHeight = () => scrollHeightOf(viewportRef());
|
|
371
396
|
that.getHeight = () => that.el.clientHeight;
|
|
372
397
|
|
|
373
|
-
that[
|
|
398
|
+
that[render] = () => {
|
|
374
399
|
const _props = props();
|
|
375
400
|
const {className, children} = _props;
|
|
401
|
+
|
|
376
402
|
return (
|
|
377
|
-
<div className={classNames('Scrollable', className, status() || WITH_SCROLL, statusH() + '-horizontal')}
|
|
403
|
+
<div className={classNames('Scrollable', className, status() || WITH_SCROLL, statusH() + '-horizontal')}
|
|
404
|
+
style={styleOf(_props)}
|
|
405
|
+
ref={ref('el', this)}
|
|
406
|
+
>
|
|
378
407
|
<div className="viewport" ref={viewportRef}>
|
|
379
408
|
{children}
|
|
380
409
|
</div>
|
|
@@ -390,21 +419,4 @@ class Scrollable extends PureComponent {
|
|
|
390
419
|
}
|
|
391
420
|
}
|
|
392
421
|
|
|
393
|
-
export default Scrollable
|
|
394
|
-
|
|
395
|
-
Scrollable.defaultProps = {
|
|
396
|
-
autoScrollTop: true,
|
|
397
|
-
horizontalScrollBarMode: SCROLLBAR_MODE_HIDDEN
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
401
|
-
Scrollable.propTypes = {
|
|
402
|
-
scrollBarMode: PropTypes.oneOf([SCROLLBAR_MODE_AUTO, SCROLLBAR_MODE_HIDDEN, SCROLLBAR_MODE_VISIBLE, SCROLLBAR_RESIZE_DISABLED]),
|
|
403
|
-
horizontalScrollBarMode: PropTypes.oneOf([SCROLLBAR_MODE_AUTO, SCROLLBAR_MODE_HIDDEN, SCROLLBAR_MODE_VISIBLE, SCROLLBAR_RESIZE_DISABLED]),
|
|
404
|
-
[ReactConstants[5]]: PropTypes.string,
|
|
405
|
-
style: PropTypes.object,
|
|
406
|
-
onScrolledToBottom: PropTypes.func,
|
|
407
|
-
onScrolledToTop: PropTypes.func,
|
|
408
|
-
autoScrollTop: PropTypes.bool,
|
|
409
|
-
}
|
|
410
|
-
}
|
|
422
|
+
export default Scrollable
|
package/src/ScrollableTable.tsx
CHANGED
|
@@ -13,13 +13,17 @@ export interface ScrollableTableProps<T> extends TableProps<T> {
|
|
|
13
13
|
scrollableProps?: any
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
class
|
|
16
|
+
abstract class AbstractScrollableTable<T> extends PureComponent<ScrollableTableProps<T>, TableState<T>> {
|
|
17
|
+
getScrollable: () => Scrollable
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class ScrollableTable<T> extends AbstractScrollableTable<T> implements WithScrollable {
|
|
17
21
|
|
|
18
22
|
constructor(properties) {
|
|
19
23
|
super(properties);
|
|
20
24
|
const that = this;
|
|
21
25
|
|
|
22
|
-
const scrollableRef = createRef();
|
|
26
|
+
const scrollableRef = createRef<Scrollable>();
|
|
23
27
|
|
|
24
28
|
that[render] = () => {
|
|
25
29
|
return <div className={`ScrollableTable`}>
|
|
@@ -28,11 +32,7 @@ class ScrollableTable<T> extends PureComponent<ScrollableTableProps<T>, TableSta
|
|
|
28
32
|
</Scrollable>
|
|
29
33
|
</div>;
|
|
30
34
|
}
|
|
31
|
-
that.getScrollable =
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getScrollable(): Scrollable {
|
|
35
|
-
return undefined;
|
|
35
|
+
that.getScrollable = scrollableRef
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
package/src/Table.tsx
CHANGED
|
@@ -123,14 +123,14 @@ class Table<T> extends Component<TableProps<T>, TableState<T>> {
|
|
|
123
123
|
super(properties);
|
|
124
124
|
const props = propsGetter(this);
|
|
125
125
|
|
|
126
|
-
const headers = createRef();
|
|
126
|
+
const headers = createRef<HTMLTableRowElement>();
|
|
127
127
|
let updateHeadersInterval = 0;
|
|
128
128
|
|
|
129
129
|
const updateHeaders = () => {
|
|
130
130
|
const hidden = headers().querySelectorAll('.hidden');
|
|
131
131
|
const fixed = headers().querySelectorAll('.fixed');
|
|
132
132
|
for (let i = 0; i < hidden.length; i++) {
|
|
133
|
-
fixed[i].style.width = hidden[i].offsetWidth + 'px'
|
|
133
|
+
(fixed[i] as HTMLElement).style.width = (hidden[i] as HTMLElement).offsetWidth + 'px'
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
136
|
|
|
@@ -339,7 +339,7 @@ class Row<T> extends PureComponent<RowProps<T>> {
|
|
|
339
339
|
onClick={onClick}>
|
|
340
340
|
{displayEditor && !column.editor && (
|
|
341
341
|
<TextField
|
|
342
|
-
value={value}
|
|
342
|
+
value={String(value)}
|
|
343
343
|
focused={editing.focused}
|
|
344
344
|
onFocus={() => {
|
|
345
345
|
setEditing(item, i, j, value, true)
|