@rpcbase/client 0.180.0 → 0.181.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.
@@ -0,0 +1,81 @@
1
+ /* @flow */
2
+ import PropTypes from "prop-types"
3
+ import invariant from "invariant"
4
+
5
+ import {KEYCODE} from "../utils"
6
+ import defaultGetHelperDimensions from "./defaultGetHelperDimensions"
7
+ import defaultShouldCancelStart from "./defaultShouldCancelStart"
8
+
9
+ export const propTypes = {
10
+ axis: PropTypes.oneOf(["x", "y", "xy"]),
11
+ contentWindow: PropTypes.any,
12
+ disableAutoscroll: PropTypes.bool,
13
+ distance: PropTypes.number,
14
+ getContainer: PropTypes.func,
15
+ getHelperDimensions: PropTypes.func,
16
+ helperClass: PropTypes.string,
17
+ helperContainer: PropTypes.oneOfType([
18
+ PropTypes.func,
19
+ typeof HTMLElement === "undefined" ? PropTypes.any : PropTypes.instanceOf(HTMLElement),
20
+ ]),
21
+ hideSortableGhost: PropTypes.bool,
22
+ keyboardSortingTransitionDuration: PropTypes.number,
23
+ lockAxis: PropTypes.string,
24
+ lockOffset: PropTypes.oneOfType([
25
+ PropTypes.number,
26
+ PropTypes.string,
27
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
28
+ ]),
29
+ lockToContainerEdges: PropTypes.bool,
30
+ onSortEnd: PropTypes.func,
31
+ onSortMove: PropTypes.func,
32
+ onSortOver: PropTypes.func,
33
+ onSortStart: PropTypes.func,
34
+ pressDelay: PropTypes.number,
35
+ pressThreshold: PropTypes.number,
36
+ keyCodes: PropTypes.shape({
37
+ lift: PropTypes.arrayOf(PropTypes.number),
38
+ drop: PropTypes.arrayOf(PropTypes.number),
39
+ cancel: PropTypes.arrayOf(PropTypes.number),
40
+ up: PropTypes.arrayOf(PropTypes.number),
41
+ down: PropTypes.arrayOf(PropTypes.number),
42
+ }),
43
+ shouldCancelStart: PropTypes.func,
44
+ transitionDuration: PropTypes.number,
45
+ updateBeforeSortStart: PropTypes.func,
46
+ useDragHandle: PropTypes.bool,
47
+ useWindowAsScrollContainer: PropTypes.bool,
48
+ }
49
+
50
+ export const defaultKeyCodes = {
51
+ lift: [KEYCODE.SPACE],
52
+ drop: [KEYCODE.SPACE],
53
+ cancel: [KEYCODE.ESC],
54
+ up: [KEYCODE.UP, KEYCODE.LEFT],
55
+ down: [KEYCODE.DOWN, KEYCODE.RIGHT],
56
+ }
57
+
58
+ export const defaultProps = {
59
+ axis: "y",
60
+ disableAutoscroll: false,
61
+ distance: 0,
62
+ getHelperDimensions: defaultGetHelperDimensions,
63
+ hideSortableGhost: true,
64
+ lockOffset: "50%",
65
+ lockToContainerEdges: false,
66
+ pressDelay: 0,
67
+ pressThreshold: 5,
68
+ keyCodes: defaultKeyCodes,
69
+ shouldCancelStart: defaultShouldCancelStart,
70
+ transitionDuration: 300,
71
+ useWindowAsScrollContainer: false,
72
+ }
73
+
74
+ export const omittedProps = Object.keys(propTypes)
75
+
76
+ export function validateProps(props) {
77
+ invariant(
78
+ !(props.distance && props.pressDelay),
79
+ "Attempted to set both `pressDelay` and `distance` on SortableContainer, you may only use one or the other, not both at the same time.",
80
+ )
81
+ }
@@ -0,0 +1,111 @@
1
+ /* @flow */
2
+ import * as React from "react"
3
+ import PropTypes from "prop-types"
4
+ import invariant from "invariant"
5
+ import {SortableContext} from "./SortableContainer"
6
+
7
+ import {provideDisplayName, omit} from "./utils"
8
+
9
+ const propTypes = {
10
+ index: PropTypes.number.isRequired,
11
+ collection: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
12
+ disabled: PropTypes.bool,
13
+ }
14
+
15
+ const omittedProps = Object.keys(propTypes)
16
+
17
+ export default function sortableElement(WrappedComponent, config = {withRef: false}) {
18
+ return class WithSortableElement extends React.Component {
19
+ static displayName = provideDisplayName("sortableElement", WrappedComponent)
20
+
21
+ static contextType = SortableContext
22
+
23
+ static propTypes = propTypes
24
+
25
+ static defaultProps = {
26
+ collection: 0,
27
+ }
28
+
29
+ nodeRef = React.createRef()
30
+ wrappedInstance = React.createRef()
31
+
32
+ componentDidMount() {
33
+ this.register()
34
+ }
35
+
36
+ componentDidUpdate(prevProps) {
37
+ const node = this.nodeRef.current
38
+
39
+ if (node) {
40
+ if (prevProps.index !== this.props.index) {
41
+ node.sortableInfo.index = this.props.index
42
+ }
43
+
44
+ if (prevProps.disabled !== this.props.disabled) {
45
+ node.sortableInfo.disabled = this.props.disabled
46
+ }
47
+ }
48
+
49
+ if (prevProps.collection !== this.props.collection) {
50
+ this.unregister(prevProps.collection)
51
+ this.register()
52
+ }
53
+ }
54
+
55
+ componentWillUnmount() {
56
+ this.unregister()
57
+ }
58
+
59
+ register() {
60
+ const {collection, disabled, index} = this.props
61
+ const node = this.nodeRef.current
62
+
63
+ if (node) {
64
+ node.sortableInfo = {
65
+ collection,
66
+ disabled,
67
+ index,
68
+ manager: this.context.manager,
69
+ }
70
+ }
71
+
72
+ this.node = node
73
+ this.ref = {node}
74
+
75
+ this.context.manager.add(collection, this.ref)
76
+ }
77
+
78
+ unregister(collection = this.props.collection) {
79
+ this.context.manager.remove(collection, this.ref)
80
+ }
81
+
82
+ getWrappedInstance() {
83
+ invariant(
84
+ config.withRef,
85
+ "To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableElement() call",
86
+ )
87
+ return this.wrappedInstance.current
88
+ }
89
+
90
+ render() {
91
+ const ref = config.withRef ? this.wrappedInstance : null
92
+
93
+ return (
94
+ <WrappedComponent
95
+ ref={node => {
96
+ if (node) {
97
+ this.nodeRef.current = node
98
+ node.sortableInfo = {
99
+ collection: this.props.collection,
100
+ disabled: this.props.disabled,
101
+ index: this.props.index,
102
+ manager: this.context.manager,
103
+ }
104
+ }
105
+ if (ref) ref.current = node
106
+ }}
107
+ {...omit(this.props, omittedProps)} index={this.props.index} />
108
+ )
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,45 @@
1
+ /* @flow */
2
+ import * as React from "react"
3
+ import invariant from "invariant"
4
+
5
+ import {provideDisplayName} from "./utils"
6
+
7
+ export default function sortableHandle(WrappedComponent, config = {withRef: false}) {
8
+ return class WithSortableHandle extends React.Component {
9
+ static displayName = provideDisplayName("sortableHandle", WrappedComponent)
10
+
11
+ wrappedInstance = React.createRef()
12
+ nodeRef = React.createRef()
13
+
14
+ componentDidMount() {
15
+ const node = this.nodeRef.current
16
+ if (node) {
17
+ node.sortableHandle = true
18
+ }
19
+ }
20
+
21
+ getWrappedInstance() {
22
+ invariant(
23
+ config.withRef,
24
+ "To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableHandle() call",
25
+ )
26
+ return this.wrappedInstance.current
27
+ }
28
+
29
+ render() {
30
+ const ref = config.withRef ? this.wrappedInstance : null
31
+
32
+ return <WrappedComponent ref={node => {
33
+ if (node) {
34
+ this.nodeRef.current = node
35
+ node.sortableHandle = true
36
+ }
37
+ if (ref) ref.current = node
38
+ }} {...this.props} />
39
+ }
40
+ }
41
+ }
42
+
43
+ export function isSortableHandle(node) {
44
+ return node.sortableHandle != null
45
+ }
@@ -0,0 +1,14 @@
1
+ @import "helpers";
2
+
3
+ .sortable-drag-handle {
4
+ cursor: move;
5
+ color: $gray-500;
6
+
7
+ &:hover {
8
+ color: $gray-700;
9
+ }
10
+
11
+ &:active {
12
+ color: $gray-900;
13
+ }
14
+ }
@@ -0,0 +1,9 @@
1
+ /* @flow */
2
+ export {default as SortableContainer} from "./SortableContainer"
3
+ export {default as SortableElement} from "./SortableElement"
4
+ export {default as SortableHandle} from "./SortableHandle"
5
+ export {default as DragHandle} from "./DragHandle"
6
+
7
+ export {default as sortableContainer} from "./SortableContainer"
8
+ export {default as sortableElement} from "./SortableElement"
9
+ export {default as sortableHandle} from "./SortableHandle"
@@ -0,0 +1,292 @@
1
+ /* @flow */
2
+ import invariant from "invariant"
3
+
4
+ export function omit(obj, keysToOmit) {
5
+ return Object.keys(obj).reduce((acc, key) => {
6
+ if (keysToOmit.indexOf(key) === -1) {
7
+ acc[key] = obj[key]
8
+ }
9
+
10
+ return acc
11
+ }, {})
12
+ }
13
+
14
+ export const events = {
15
+ end: ["touchend", "touchcancel", "mouseup"],
16
+ move: ["touchmove", "mousemove"],
17
+ start: ["touchstart", "mousedown"],
18
+ }
19
+
20
+ export const vendorPrefix = (function () {
21
+ if (typeof window === "undefined" || typeof document === "undefined") {
22
+ // Server environment
23
+ return ""
24
+ }
25
+
26
+ // fix for: https://bugzilla.mozilla.org/show_bug.cgi?id=548397
27
+ // window.getComputedStyle() returns null inside an iframe with display: none
28
+ // in this case return an array with a fake mozilla style in it.
29
+ const styles = window.getComputedStyle(document.documentElement, "") || ["-moz-hidden-iframe"]
30
+ const pre = (Array.prototype.slice
31
+ .call(styles)
32
+ .join("")
33
+ .match(/-(moz|webkit|ms)-/) ||
34
+ (styles.OLink === "" && ["", "o"]))[1]
35
+
36
+ switch (pre) {
37
+ case "ms":
38
+ return "ms"
39
+ default:
40
+ return pre && pre.length ? pre[0].toUpperCase() + pre.substr(1) : ""
41
+ }
42
+ })()
43
+
44
+ export function setInlineStyles(node, styles) {
45
+ Object.keys(styles).forEach((key) => {
46
+ node.style[key] = styles[key]
47
+ })
48
+ }
49
+
50
+ export function setTranslate3d(node, translate) {
51
+ node.style[`${vendorPrefix}Transform`] =
52
+ translate == null ? "" : `translate3d(${translate.x}px,${translate.y}px,0)`
53
+ }
54
+
55
+ export function setTransitionDuration(node, duration) {
56
+ node.style[`${vendorPrefix}TransitionDuration`] = duration == null ? "" : `${duration}ms`
57
+ }
58
+
59
+ export function closest(el, fn) {
60
+ while (el) {
61
+ if (fn(el)) {
62
+ return el
63
+ }
64
+
65
+ el = el.parentNode
66
+ }
67
+
68
+ return null
69
+ }
70
+
71
+ export function limit(min, max, value) {
72
+ return Math.max(min, Math.min(value, max))
73
+ }
74
+
75
+ function getPixelValue(stringValue) {
76
+ if (stringValue.substr(-2) === "px") {
77
+ return parseFloat(stringValue)
78
+ }
79
+
80
+ return 0
81
+ }
82
+
83
+ export function getElementMargin(element) {
84
+ const style = window.getComputedStyle(element)
85
+
86
+ return {
87
+ bottom: getPixelValue(style.marginBottom),
88
+ left: getPixelValue(style.marginLeft),
89
+ right: getPixelValue(style.marginRight),
90
+ top: getPixelValue(style.marginTop),
91
+ }
92
+ }
93
+
94
+ export function provideDisplayName(prefix, Component) {
95
+ const componentName = Component.displayName || Component.name
96
+
97
+ return componentName ? `${prefix}(${componentName})` : prefix
98
+ }
99
+
100
+ export function getScrollAdjustedBoundingClientRect(node, scrollDelta) {
101
+ const boundingClientRect = node.getBoundingClientRect()
102
+
103
+ return {
104
+ top: boundingClientRect.top + scrollDelta.top,
105
+ left: boundingClientRect.left + scrollDelta.left,
106
+ }
107
+ }
108
+
109
+ export function getPosition(event) {
110
+ if (event.touches && event.touches.length) {
111
+ return {
112
+ x: event.touches[0].pageX,
113
+ y: event.touches[0].pageY,
114
+ }
115
+ } else if (event.changedTouches && event.changedTouches.length) {
116
+ return {
117
+ x: event.changedTouches[0].pageX,
118
+ y: event.changedTouches[0].pageY,
119
+ }
120
+ } else {
121
+ return {
122
+ x: event.pageX,
123
+ y: event.pageY,
124
+ }
125
+ }
126
+ }
127
+
128
+ export function isTouchEvent(event) {
129
+ return (
130
+ (event.touches && event.touches.length) || (event.changedTouches && event.changedTouches.length)
131
+ )
132
+ }
133
+
134
+ export function getEdgeOffset(node, parent, offset = {left: 0, top: 0}) {
135
+ if (!node) {
136
+ return undefined
137
+ }
138
+
139
+ // Get the actual offsetTop / offsetLeft value, no matter how deep the node is nested
140
+ const nodeOffset = {
141
+ left: offset.left + node.offsetLeft,
142
+ top: offset.top + node.offsetTop,
143
+ }
144
+
145
+ if (node.parentNode === parent) {
146
+ return nodeOffset
147
+ }
148
+
149
+ return getEdgeOffset(node.parentNode, parent, nodeOffset)
150
+ }
151
+
152
+ export function getTargetIndex(newIndex, prevIndex, oldIndex) {
153
+ if (newIndex < oldIndex && newIndex > prevIndex) {
154
+ return newIndex - 1
155
+ } else if (newIndex > oldIndex && newIndex < prevIndex) {
156
+ return newIndex + 1
157
+ } else {
158
+ return newIndex
159
+ }
160
+ }
161
+
162
+ export function getLockPixelOffset({lockOffset, width, height}) {
163
+ let offsetX = lockOffset
164
+ let offsetY = lockOffset
165
+ let unit = "px"
166
+
167
+ if (typeof lockOffset === "string") {
168
+ const match = /^[+-]?\d*(?:\.\d*)?(px|%)$/.exec(lockOffset)
169
+
170
+ invariant(
171
+ match !== null,
172
+ "lockOffset value should be a number or a string of a " +
173
+ 'number followed by "px" or "%". Given %s',
174
+ lockOffset,
175
+ )
176
+
177
+ offsetX = parseFloat(lockOffset)
178
+ offsetY = parseFloat(lockOffset)
179
+ unit = match[1]
180
+ }
181
+
182
+ invariant(
183
+ isFinite(offsetX) && isFinite(offsetY),
184
+ "lockOffset value should be a finite. Given %s",
185
+ lockOffset,
186
+ )
187
+
188
+ if (unit === "%") {
189
+ offsetX = (offsetX * width) / 100
190
+ offsetY = (offsetY * height) / 100
191
+ }
192
+
193
+ return {
194
+ x: offsetX,
195
+ y: offsetY,
196
+ }
197
+ }
198
+
199
+ export function getLockPixelOffsets({height, width, lockOffset}) {
200
+ const offsets = Array.isArray(lockOffset) ? lockOffset : [lockOffset, lockOffset]
201
+
202
+ invariant(
203
+ offsets.length === 2,
204
+ "lockOffset prop of SortableContainer should be a single " +
205
+ "value or an array of exactly two values. Given %s",
206
+ lockOffset,
207
+ )
208
+
209
+ const [minLockOffset, maxLockOffset] = offsets
210
+
211
+ return [
212
+ getLockPixelOffset({height, lockOffset: minLockOffset, width}),
213
+ getLockPixelOffset({height, lockOffset: maxLockOffset, width}),
214
+ ]
215
+ }
216
+
217
+ function isScrollable(el) {
218
+ const computedStyle = window.getComputedStyle(el)
219
+ const overflowRegex = /(auto|scroll)/
220
+ const properties = ["overflow", "overflowX", "overflowY"]
221
+
222
+ return properties.find((property) => overflowRegex.test(computedStyle[property]))
223
+ }
224
+
225
+ export function getScrollingParent(el) {
226
+ if (!(el instanceof HTMLElement)) {
227
+ return null
228
+ } else if (isScrollable(el)) {
229
+ return el
230
+ } else {
231
+ return getScrollingParent(el.parentNode)
232
+ }
233
+ }
234
+
235
+ export function getContainerGridGap(element) {
236
+ const style = window.getComputedStyle(element)
237
+
238
+ if (style.display === "grid") {
239
+ return {
240
+ x: getPixelValue(style.gridColumnGap),
241
+ y: getPixelValue(style.gridRowGap),
242
+ }
243
+ }
244
+
245
+ return {x: 0, y: 0}
246
+ }
247
+
248
+ export const KEYCODE = {
249
+ TAB: 9,
250
+ ESC: 27,
251
+ SPACE: 32,
252
+ LEFT: 37,
253
+ UP: 38,
254
+ RIGHT: 39,
255
+ DOWN: 40,
256
+ }
257
+
258
+ export const NodeType = {
259
+ Anchor: "A",
260
+ Button: "BUTTON",
261
+ Canvas: "CANVAS",
262
+ Input: "INPUT",
263
+ Option: "OPTION",
264
+ Textarea: "TEXTAREA",
265
+ Select: "SELECT",
266
+ }
267
+
268
+ export function cloneNode(node) {
269
+ const selector = "input, textarea, select, canvas, [contenteditable]"
270
+ const fields = node.querySelectorAll(selector)
271
+ const clonedNode = node.cloneNode(true)
272
+ const clonedFields = [...clonedNode.querySelectorAll(selector)]
273
+
274
+ clonedFields.forEach((field, i) => {
275
+ if (field.type !== "file") {
276
+ field.value = fields[i].value
277
+ }
278
+
279
+ // Fixes an issue with original radio buttons losing their value once the
280
+ // clone is inserted in the DOM, as radio button `name` attributes must be unique
281
+ if (field.type === "radio" && field.name) {
282
+ field.name = `__sortableClone__${field.name}`
283
+ }
284
+
285
+ if (field.tagName === NodeType.Canvas && fields[i].width > 0 && fields[i].height > 0) {
286
+ const destCtx = field.getContext("2d")
287
+ destCtx.drawImage(fields[i], 0, 0)
288
+ }
289
+ })
290
+
291
+ return clonedNode
292
+ }