@arcblock/ux 1.16.0 → 1.16.4

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 (90) hide show
  1. package/lib/CodeBlock/index.js +3 -1
  2. package/package.json +6 -5
  3. package/src/ActionButton/index.js +65 -0
  4. package/src/ActivityIndicator/index.js +186 -0
  5. package/src/Alert/index.js +104 -0
  6. package/src/Async/index.js +39 -0
  7. package/src/Badge/index.js +71 -0
  8. package/src/Blocklet/index.js +335 -0
  9. package/src/Button/index.js +4 -0
  10. package/src/Button/wrap.js +88 -0
  11. package/src/ButtonGroup/index.js +19 -0
  12. package/src/Center/index.js +17 -0
  13. package/src/ClickToCopy/index.js +90 -0
  14. package/src/CodeBlock/index.js +160 -0
  15. package/src/Colors/index.js +1 -0
  16. package/src/Colors/themes/default.js +53 -0
  17. package/src/ContactForm/index.js +240 -0
  18. package/src/CookieConsent/index.js +90 -0
  19. package/src/CountDown/index.js +151 -0
  20. package/src/Dialog/confirm.js +76 -0
  21. package/src/Dialog/dialog.js +162 -0
  22. package/src/Dialog/index.js +2 -0
  23. package/src/DriftBot/index.js +81 -0
  24. package/src/Earth/countries.json +8057 -0
  25. package/src/Earth/index.js +511 -0
  26. package/src/Earth/util.js +69 -0
  27. package/src/Empty/index.js +41 -0
  28. package/src/Footer/index.js +84 -0
  29. package/src/Icon/image.js +55 -0
  30. package/src/Icon/index.js +69 -0
  31. package/src/Img/index.js +172 -0
  32. package/src/InfoRow/index.js +83 -0
  33. package/src/Layout/dashboard/header.js +145 -0
  34. package/src/Layout/dashboard/index.js +140 -0
  35. package/src/Layout/dashboard/sidebar.js +120 -0
  36. package/src/Layout/index.js +318 -0
  37. package/src/Locale/browser-lang.js +63 -0
  38. package/src/Locale/context.js +88 -0
  39. package/src/Locale/images/globe-dark.png +0 -0
  40. package/src/Locale/images/globe-light.png +0 -0
  41. package/src/Locale/selector.js +138 -0
  42. package/src/Logo/images/logo-dark-text.svg +3 -0
  43. package/src/Logo/images/logo-dark-top.svg +6 -0
  44. package/src/Logo/images/logo-light-text.svg +3 -0
  45. package/src/Logo/images/logo-light-top.svg +6 -0
  46. package/src/Logo/index.js +47 -0
  47. package/src/Metric/index.js +115 -0
  48. package/src/NFTDisplay/README.md +59 -0
  49. package/src/NFTDisplay/aspect-ratio-container.js +34 -0
  50. package/src/NFTDisplay/broken.js +18 -0
  51. package/src/NFTDisplay/index.js +230 -0
  52. package/src/NFTDisplay/loading.js +17 -0
  53. package/src/NFTDisplay/svg-embedder/img.js +36 -0
  54. package/src/NFTDisplay/svg-embedder/inline-svg.js +37 -0
  55. package/src/PageScroller/index.js +342 -0
  56. package/src/PageScroller/usePrevValue.js +12 -0
  57. package/src/PricingTable/PricingPlan.js +112 -0
  58. package/src/PricingTable/index.js +43 -0
  59. package/src/Screenshot/devices.css +1366 -0
  60. package/src/Screenshot/index.js +181 -0
  61. package/src/Spinner/index.js +33 -0
  62. package/src/Switch/index.js +78 -0
  63. package/src/Tabs/index.js +46 -0
  64. package/src/Tag/index.js +73 -0
  65. package/src/Terminal/Player.js +364 -0
  66. package/src/Terminal/index.js +150 -0
  67. package/src/Terminal/player.css +378 -0
  68. package/src/Terminal/util.js +167 -0
  69. package/src/Terminal/xterm.css +171 -0
  70. package/src/TextCollapse/index.js +92 -0
  71. package/src/Theme/index.js +169 -0
  72. package/src/Theme/responsiveFontSizes.js +94 -0
  73. package/src/Toast/index.js +118 -0
  74. package/src/Util/index.js +264 -0
  75. package/src/Video/index.js +72 -0
  76. package/src/Wallet/Action.js +105 -0
  77. package/src/Wallet/Download.js +130 -0
  78. package/src/Wallet/Open.js +50 -0
  79. package/src/Wallet/images/abtwallet.png +0 -0
  80. package/src/Wallet/images/android_download.svg +23 -0
  81. package/src/Wallet/images/app-store.svg +20 -0
  82. package/src/Wallet/images/google-play.svg +70 -0
  83. package/src/WechatPrompt/images/android.png +0 -0
  84. package/src/WechatPrompt/images/ios.png +0 -0
  85. package/src/WechatPrompt/index.js +81 -0
  86. package/src/index.js +63 -0
  87. package/src/withTheme/index.js +72 -0
  88. package/src/withTracker/README.md +34 -0
  89. package/src/withTracker/error_boundary.js +34 -0
  90. package/src/withTracker/index.js +70 -0
@@ -0,0 +1,364 @@
1
+ /* eslint-disable react/no-unused-prop-types */
2
+ import React, { useReducer, useState, useRef, useEffect } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import useInterval from '@arcblock/react-hooks/lib/useInterval';
5
+ import useWindowSize from 'react-use/lib/useWindowSize';
6
+
7
+ import Terminal from './index';
8
+
9
+ import './player.css';
10
+
11
+ import {
12
+ formatFrames,
13
+ formatTime,
14
+ findFrameAt,
15
+ isFrameAt,
16
+ getFrameClass,
17
+ getPlayerClass,
18
+ defaultOptions,
19
+ defaultState,
20
+ } from './util';
21
+
22
+ export default function Player(props) {
23
+ const options = Object.assign({}, defaultOptions, props.options);
24
+ const { frames, totalDuration } = formatFrames(props.frames, options);
25
+
26
+ const terminalOptions = {
27
+ cols: options.cols,
28
+ rows: options.rows,
29
+ cursorStyle: options.cursorStyle,
30
+ fontFamily: options.fontFamily,
31
+ fontSize: options.fontSize,
32
+ lineHeight: options.lineHeight,
33
+ letterSpacing: options.letterSpacing,
34
+ allowTransparency: true,
35
+ scrollback: 0,
36
+ // theme: options.theme,
37
+ };
38
+
39
+ const stateReducer = (state, action) => {
40
+ // console.log(`dispatch.${action.type}`, action.payload);
41
+ switch (action.type) {
42
+ case 'jump':
43
+ return { ...state, isPlaying: false, ...action.payload };
44
+ case 'start':
45
+ return { ...state, isStarted: true, lastTickTime: Date.now() };
46
+ case 'play':
47
+ return {
48
+ ...state,
49
+ isPlaying: true,
50
+ lastTickTime: Date.now(),
51
+ ...action.payload,
52
+ };
53
+ case 'pause':
54
+ return { ...state, isPlaying: false, ...action.payload };
55
+ case 'tickStart':
56
+ return {
57
+ ...state,
58
+ isRendering: true,
59
+ lastTickTime: Date.now(),
60
+ ...action.payload,
61
+ };
62
+ case 'tickEnd':
63
+ return {
64
+ ...state,
65
+ isRendering: false,
66
+ lastTickTime: Date.now(),
67
+ ...action.payload,
68
+ };
69
+ case 'reset':
70
+ return {
71
+ ...state,
72
+ currentFrame: 0,
73
+ currentTime: 0,
74
+ ...action.payload,
75
+ };
76
+ default:
77
+ return { ...state, lastTickTime: Date.now(), ...action.payload };
78
+ }
79
+ };
80
+
81
+ const terminal = useRef(null);
82
+ const progress = useRef(null);
83
+ const container = useRef(null);
84
+ const [maxWidth, setMaxWidth] = useState(0);
85
+ const { width } = useWindowSize();
86
+ const [state, dispatch] = useReducer(stateReducer, defaultState);
87
+
88
+ useEffect(() => {
89
+ if (!terminal.current) {
90
+ return;
91
+ }
92
+
93
+ try {
94
+ const COLUMN_WIDTH = 972 / 121;
95
+ const child = container.current.getBoundingClientRect();
96
+ let containerWidth = child.x < 0 ? child.width + child.x : child.width;
97
+ if (container.current.parentNode) {
98
+ const parent = container.current.parentNode.getBoundingClientRect();
99
+ if (child.width > parent.width) {
100
+ containerWidth = parent.width;
101
+ }
102
+ }
103
+
104
+ if (options.controls) {
105
+ containerWidth -= 12;
106
+ }
107
+ const colContainer = Math.ceil(containerWidth / COLUMN_WIDTH);
108
+ const cols = Math.min(Math.max(colContainer, 40), options.cols);
109
+
110
+ terminal.current.resize(cols, options.rows);
111
+ } catch (err) {
112
+ // Do nothing
113
+ }
114
+ }, [width, maxWidth]);
115
+
116
+ // console.log('main.render', state, { totalFrame: frames.length, totalDuration });
117
+ // Render a frame
118
+ const renderFrame = (frameIndex, done) => {
119
+ const frame = frames[frameIndex];
120
+ if (frame.content) {
121
+ if (state.requireReset) {
122
+ terminal.current.reset();
123
+ }
124
+
125
+ terminal.current.write(frame.content, () => {
126
+ if (typeof done === 'function') {
127
+ done();
128
+ }
129
+ });
130
+ }
131
+ };
132
+
133
+ // Emit a event
134
+ const emitEvent = name => {
135
+ if (typeof props[name] === 'function') {
136
+ props[name]({ state, frames, options });
137
+ }
138
+ };
139
+
140
+ // Render thumbnailTime
141
+ useEffect(() => {
142
+ if (!terminal.current) {
143
+ return;
144
+ }
145
+ if (container.current) {
146
+ try {
147
+ setMaxWidth(container.current.getBoundingClientRect().width);
148
+ } catch (e) {
149
+ // Do nothing
150
+ }
151
+ }
152
+ if (options.autoplay) {
153
+ onStart();
154
+ } else {
155
+ doJump(Math.min(Math.abs(options.thumbnailTime), totalDuration));
156
+ }
157
+ }, []);
158
+
159
+ // Tick intervals
160
+ useInterval(
161
+ async () => {
162
+ if (state.isRendering) {
163
+ return false;
164
+ }
165
+
166
+ const tickDelay = Date.now() - state.lastTickTime;
167
+ const newState = {};
168
+
169
+ if (state.currentTime < totalDuration) {
170
+ newState.currentTime = state.currentTime + tickDelay;
171
+ }
172
+ if (state.currentTime > totalDuration) {
173
+ newState.currentTime = totalDuration;
174
+ }
175
+
176
+ const alreadyRendered = isFrameAt(frames, newState.currentTime, state.currentFrame);
177
+ if (state.currentFrame !== -1 && alreadyRendered) {
178
+ return dispatch({ type: 'tick', payload: newState });
179
+ }
180
+
181
+ // Reached the end
182
+ if (state.currentFrame === frames.length - 1) {
183
+ emitEvent('onComplete');
184
+
185
+ if (options.repeat) {
186
+ // console.log('tick.restart', newState, state);
187
+ return dispatch({ type: 'reset', payload: newState });
188
+ }
189
+
190
+ // console.log('tick.end', newState, state);
191
+ newState.currentTime = 0;
192
+ newState.currentFrame = 0;
193
+ newState.requireReset = true;
194
+ newState.isStarted = false;
195
+ return dispatch({ type: 'pause', payload: newState });
196
+ }
197
+
198
+ // Check if current time belongs to the next frame's duration
199
+ if (isFrameAt(newState.currentTime, state.currentFrame + 1)) {
200
+ newState.currentFrame = state.currentFrame + 1;
201
+ } else {
202
+ newState.currentFrame = findFrameAt(frames, newState.currentTime);
203
+ }
204
+
205
+ // console.log('tick.tick', newState, state);
206
+ dispatch({ type: 'tickStart', payload: newState });
207
+ return renderFrame(newState.currentFrame, () => {
208
+ if (state.requireReset) {
209
+ newState.requireReset = false;
210
+ }
211
+ dispatch({ type: 'tickEnd', payload: newState });
212
+ return emitEvent('onTick');
213
+ });
214
+ },
215
+ state.isPlaying ? 8 : null
216
+ );
217
+
218
+ // If controls are enabled, we need to disable frameBox
219
+ if (options.controls) {
220
+ options.frameBox.title = null;
221
+ options.frameBox.type = null;
222
+ options.frameBox.style = {};
223
+
224
+ if (options.theme.background === 'transparent') {
225
+ options.frameBox.style.background = 'black';
226
+ } else {
227
+ options.frameBox.style.background = options.theme.background;
228
+ }
229
+
230
+ options.frameBox.style.padding = '10px';
231
+ options.frameBox.style.paddingBottom = '40px';
232
+ }
233
+
234
+ const doJump = time => {
235
+ terminal.current.reset();
236
+
237
+ const toFrameIndex = findFrameAt(frames, time);
238
+ for (let i = 0; i < toFrameIndex; i++) {
239
+ renderFrame(i);
240
+ }
241
+ };
242
+
243
+ const onJump = e => {
244
+ if (!progress.current || !terminal.current || !state.isStarted) {
245
+ return false;
246
+ }
247
+
248
+ const length = progress.current.getBoundingClientRect().width;
249
+ const position = e.nativeEvent.offsetX;
250
+ // console.log('onJump', { length, position, e });
251
+
252
+ const currentTime = Math.floor((totalDuration * position) / length);
253
+ dispatch({ type: 'jump', payload: { currentTime } });
254
+ doJump(currentTime);
255
+ emitEvent('onJump');
256
+
257
+ return false;
258
+ };
259
+
260
+ const onStart = () => {
261
+ if (state.isStarted === false) {
262
+ dispatch({ type: 'start' });
263
+ terminal.current.reset();
264
+ }
265
+
266
+ dispatch({ type: 'play' });
267
+ emitEvent('onStart');
268
+
269
+ return false;
270
+ };
271
+
272
+ const onPause = () => {
273
+ dispatch({ type: 'pause' });
274
+ emitEvent('onPause');
275
+ return false;
276
+ };
277
+
278
+ const onPlay = async () => {
279
+ if (state.currentFrame === frames.length - 1 && state.currentTime === totalDuration) {
280
+ dispatch({ type: 'reset' });
281
+ terminal.current.reset();
282
+ }
283
+
284
+ emitEvent('onPlay');
285
+ return onStart();
286
+ };
287
+
288
+ return (
289
+ <div className={getPlayerClass(options, state)} ref={container}>
290
+ <div className="cover" onClick={onStart} />
291
+ <div className="start" onClick={onStart}>
292
+ <svg style={{ enableBackground: 'new 0 0 30 30' }} viewBox="0 0 30 30">
293
+ <polygon points="6.583,3.186 5,4.004 5,15 26,15 26.483,14.128 " />
294
+ <polygon points="6.583,26.814 5,25.996 5,15 26,15 26.483,15.872 " />
295
+ <circle cx="26" cy="15" r="1" />
296
+ <circle cx="6" cy="4" r="1" />
297
+ <circle cx="6" cy="26" r="1" />
298
+ </svg>
299
+ </div>
300
+ <div className="terminal">
301
+ <div className={getFrameClass(options)} style={options.frameBox.style || {}}>
302
+ <div className="terminal-titlebar">
303
+ <div className="buttons">
304
+ <div className="close-button" />
305
+ <div className="minimize-button" />
306
+ <div className="maximize-button" />
307
+ </div>
308
+ <div className="title">{options.frameBox.title || ''}</div>
309
+ </div>
310
+ <div className="terminal-body">
311
+ <Terminal ref={terminal} options={terminalOptions} />
312
+ </div>
313
+ </div>
314
+ </div>
315
+ <div className="controller">
316
+ {state.isPlaying && (
317
+ <div className="pause" onClick={onPause} title="Pause">
318
+ <span className="icon" />
319
+ </div>
320
+ )}
321
+ {!state.isPlaying && state.isStarted && (
322
+ <div className="play" onClick={onPlay} title="Play">
323
+ <span className="icon" />
324
+ </div>
325
+ )}
326
+ {!state.isPlaying && !state.isStarted && (
327
+ <div className="play" onClick={onStart} title="Start">
328
+ <span className="icon" />
329
+ </div>
330
+ )}
331
+ <div className="timer">{formatTime(state.currentTime)}</div>
332
+ <div className="progressbar-wrapper">
333
+ <div className="progressbar" ref={progress} onClick={onJump}>
334
+ <div
335
+ className="progress"
336
+ style={{ width: `${(state.currentTime / totalDuration) * 100}%` }}
337
+ />
338
+ </div>
339
+ </div>
340
+ </div>
341
+ </div>
342
+ );
343
+ }
344
+
345
+ Player.propTypes = {
346
+ frames: PropTypes.array.isRequired,
347
+ options: PropTypes.object.isRequired,
348
+ onComplete: PropTypes.func,
349
+ onStart: PropTypes.func,
350
+ onStop: PropTypes.func,
351
+ onPause: PropTypes.func,
352
+ onTick: PropTypes.func,
353
+ onJump: PropTypes.func,
354
+ };
355
+
356
+ const noop = () => {};
357
+ Player.defaultProps = {
358
+ onComplete: noop,
359
+ onStart: noop,
360
+ onStop: noop,
361
+ onPause: noop,
362
+ onTick: noop,
363
+ onJump: noop,
364
+ };
@@ -0,0 +1,150 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Terminal as XTerm } from 'xterm';
4
+ import { WebLinksAddon } from 'xterm-addon-web-links';
5
+ import { FitAddon } from 'xterm-addon-fit';
6
+ import { debounce } from 'lodash';
7
+
8
+ import './xterm.css';
9
+
10
+ export default class Terminal extends React.Component {
11
+ xterm = null;
12
+
13
+ container = null;
14
+
15
+ componentDidMount() {
16
+ const { value, options } = this.props;
17
+ this.fitAddon = new FitAddon();
18
+
19
+ this.xterm = new XTerm(options);
20
+ this.xterm.loadAddon(new WebLinksAddon());
21
+ this.xterm.loadAddon(this.fitAddon);
22
+
23
+ this.xterm.open(this.container);
24
+
25
+ this.xterm.onData(this.onData.bind(this));
26
+ this.xterm.onRender(this.onRender.bind(this));
27
+
28
+ if (value) {
29
+ this.xterm.write(value);
30
+ }
31
+
32
+ setTimeout(() => {
33
+ if (this.xterm) {
34
+ this.fitAddon.fit();
35
+ }
36
+ }, 0);
37
+
38
+ this.debounceFit = debounce(() => {
39
+ this.fitAddon.fit();
40
+ }, 600);
41
+
42
+ window.addEventListener('resize', this.debounceFit);
43
+ }
44
+
45
+ componentWillUnmount() {
46
+ if (this.xterm) {
47
+ this.xterm.dispose();
48
+ this.xterm = null;
49
+ }
50
+ window.removeEventListener('resize', this.debounceFit);
51
+ }
52
+
53
+ shouldComponentUpdate(nextProps) {
54
+ // eslint-disable-next-line no-prototype-builtins
55
+ if (nextProps.hasOwnProperty('value') && nextProps.value !== this.props.value) {
56
+ if (this.xterm) {
57
+ this.xterm.clear();
58
+ setTimeout(() => {
59
+ this.xterm.write(nextProps.value);
60
+ }, 0);
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+
66
+ getXTerm() {
67
+ return this.xterm;
68
+ }
69
+
70
+ write(data, cb) {
71
+ if (this.xterm) {
72
+ this.xterm.write(data, cb);
73
+ }
74
+ }
75
+
76
+ focus() {
77
+ if (this.xterm) {
78
+ this.xterm.focus();
79
+ }
80
+ }
81
+
82
+ reset() {
83
+ if (this.xterm) {
84
+ this.xterm.reset();
85
+ }
86
+ }
87
+
88
+ onData = data => {
89
+ if (this.props.onData) {
90
+ this.props.onData(data);
91
+ }
92
+ };
93
+
94
+ onRender = data => {
95
+ if (this.props.onRender) {
96
+ this.props.onRender(data);
97
+ }
98
+ };
99
+
100
+ resize(cols, rows) {
101
+ if (this.xterm) {
102
+ this.xterm.resize(Math.round(cols), Math.round(rows));
103
+ }
104
+ }
105
+
106
+ setOption(key, value) {
107
+ if (this.xterm) {
108
+ this.xterm.setOption(key, value);
109
+ }
110
+ }
111
+
112
+ getOption(key) {
113
+ if (this.xterm) {
114
+ this.xterm.setOption(key);
115
+ }
116
+ }
117
+
118
+ refresh() {
119
+ if (this.xterm) {
120
+ this.xterm.refresh(0, this.xterm.rows - 1);
121
+ }
122
+ }
123
+
124
+ render() {
125
+ const className = ['react-xterm', this.props.className].filter(Boolean).join(' ');
126
+ return (
127
+ // eslint-disable-next-line no-return-assign
128
+ <div ref={ref => (this.container = ref)} className={className} style={this.props.style} />
129
+ );
130
+ }
131
+ }
132
+
133
+ Terminal.propTypes = {
134
+ onData: PropTypes.func,
135
+ onRender: PropTypes.func,
136
+ options: PropTypes.object,
137
+ value: PropTypes.string,
138
+ className: PropTypes.string,
139
+ style: PropTypes.object,
140
+ };
141
+
142
+ const noop = () => {};
143
+ Terminal.defaultProps = {
144
+ onData: noop,
145
+ onRender: noop,
146
+ options: {},
147
+ value: '',
148
+ className: '',
149
+ style: {},
150
+ };