@arcblock/ux 0.78.25 → 1.6.59

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 (172) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +0 -56
  3. package/lib/ActionButton/index.js +6 -4
  4. package/lib/ActivityIndicator/index.js +75 -23
  5. package/lib/Alert/index.js +15 -11
  6. package/lib/Async/index.js +1 -1
  7. package/lib/Badge/index.js +17 -15
  8. package/lib/Blocklet/index.js +261 -0
  9. package/lib/Button/wrap.js +96 -43
  10. package/lib/ButtonGroup/index.js +3 -16
  11. package/lib/Center/index.js +30 -4
  12. package/lib/ClickToCopy/index.js +10 -8
  13. package/lib/CodeBlock/index.js +40 -13
  14. package/lib/Colors/index.js +15 -0
  15. package/lib/Colors/themes/default.js +85 -0
  16. package/lib/ContactForm/index.js +9 -10
  17. package/lib/CookieConsent/index.js +98 -0
  18. package/lib/CountDown/index.js +18 -14
  19. package/lib/Dialog/confirm.js +84 -0
  20. package/lib/Dialog/dialog.js +137 -0
  21. package/lib/Dialog/index.js +23 -0
  22. package/lib/Earth/index.js +33 -33
  23. package/lib/Empty/index.js +61 -0
  24. package/lib/Footer/index.js +16 -18
  25. package/lib/Icon/image.js +10 -13
  26. package/lib/Icon/index.js +10 -8
  27. package/lib/Img/index.js +212 -0
  28. package/lib/InfoRow/index.js +7 -6
  29. package/lib/Layout/dashboard/header.js +60 -42
  30. package/lib/Layout/dashboard/index.js +72 -60
  31. package/lib/Layout/dashboard/sidebar.js +41 -25
  32. package/lib/Layout/index.js +113 -51
  33. package/lib/Locale/browser-lang.js +0 -2
  34. package/lib/Locale/context.js +85 -61
  35. package/lib/Locale/selector.js +33 -20
  36. package/lib/Logo/index.js +15 -13
  37. package/lib/Metric/index.js +5 -6
  38. package/lib/NFTDisplay/README.md +59 -0
  39. package/lib/NFTDisplay/aspect-ratio-container.js +52 -0
  40. package/lib/NFTDisplay/broken.js +25 -0
  41. package/lib/NFTDisplay/index.js +317 -0
  42. package/lib/NFTDisplay/loading.js +23 -0
  43. package/lib/NFTDisplay/svg-embedder/img.js +68 -0
  44. package/lib/NFTDisplay/svg-embedder/inline-svg.js +54 -0
  45. package/lib/PageScroller/index.js +10 -11
  46. package/lib/PageScroller/usePrevValue.js +2 -2
  47. package/lib/PricingTable/PricingPlan.js +12 -15
  48. package/lib/PricingTable/index.js +5 -5
  49. package/lib/Result/common.js +176 -0
  50. package/lib/Result/index.js +61 -0
  51. package/lib/Result/result.js +69 -0
  52. package/lib/Result/translations.js +61 -0
  53. package/lib/Screenshot/index.js +14 -13
  54. package/lib/Spinner/index.js +37 -0
  55. package/lib/SplitButton/index.js +126 -0
  56. package/lib/Switch/index.js +107 -0
  57. package/lib/Tabs/index.js +24 -47
  58. package/lib/Tag/index.js +15 -13
  59. package/lib/Terminal/Player.js +43 -45
  60. package/lib/Terminal/index.js +3 -1
  61. package/lib/Terminal/util.js +2 -3
  62. package/lib/TextCollapse/index.js +21 -14
  63. package/lib/Theme/index.js +79 -63
  64. package/lib/Theme/responsiveFontSizes.js +8 -8
  65. package/lib/Toast/index.js +12 -11
  66. package/lib/Util/index.js +197 -26
  67. package/lib/Video/index.js +8 -11
  68. package/lib/Wallet/Action.js +15 -13
  69. package/lib/Wallet/Download.js +60 -58
  70. package/lib/Wallet/Open.js +2 -2
  71. package/lib/WechatPrompt/index.js +10 -10
  72. package/lib/index.js +6 -6
  73. package/lib/withTheme/index.js +5 -17
  74. package/lib/withTracker/error_boundary.js +3 -3
  75. package/lib/withTracker/index.js +6 -7
  76. package/package.json +22 -17
  77. package/src/ActionButton/index.js +65 -0
  78. package/src/ActivityIndicator/index.js +141 -0
  79. package/src/Alert/index.js +104 -0
  80. package/src/Async/index.js +39 -0
  81. package/src/Badge/index.js +71 -0
  82. package/src/Blocklet/index.js +424 -0
  83. package/src/Button/index.js +4 -0
  84. package/src/Button/wrap.js +101 -0
  85. package/src/ButtonGroup/index.js +6 -0
  86. package/src/Center/index.js +40 -0
  87. package/src/ClickToCopy/index.js +90 -0
  88. package/src/CodeBlock/index.js +160 -0
  89. package/src/Colors/index.js +1 -0
  90. package/src/Colors/themes/default.js +54 -0
  91. package/src/ContactForm/index.js +240 -0
  92. package/src/CookieConsent/index.js +90 -0
  93. package/src/CountDown/index.js +151 -0
  94. package/src/Dialog/confirm.js +76 -0
  95. package/src/Dialog/dialog.js +162 -0
  96. package/src/Dialog/index.js +2 -0
  97. package/src/DriftBot/index.js +81 -0
  98. package/src/Earth/countries.json +8057 -0
  99. package/src/Earth/index.js +511 -0
  100. package/src/Earth/util.js +69 -0
  101. package/src/Empty/index.js +41 -0
  102. package/src/Footer/index.js +110 -0
  103. package/src/Icon/image.js +55 -0
  104. package/src/Icon/index.js +69 -0
  105. package/src/Img/index.js +172 -0
  106. package/src/InfoRow/index.js +83 -0
  107. package/src/Layout/dashboard/header.js +157 -0
  108. package/src/Layout/dashboard/index.js +150 -0
  109. package/src/Layout/dashboard/sidebar.js +122 -0
  110. package/src/Layout/index.js +318 -0
  111. package/src/Locale/browser-lang.js +63 -0
  112. package/src/Locale/context.js +94 -0
  113. package/src/Locale/images/globe-dark.png +0 -0
  114. package/src/Locale/images/globe-light.png +0 -0
  115. package/src/Locale/selector.js +135 -0
  116. package/src/Logo/images/logo-dark-text.svg +3 -0
  117. package/src/Logo/images/logo-dark-top.svg +6 -0
  118. package/src/Logo/images/logo-light-text.svg +3 -0
  119. package/src/Logo/images/logo-light-top.svg +6 -0
  120. package/src/Logo/index.js +47 -0
  121. package/src/Metric/index.js +115 -0
  122. package/src/NFTDisplay/README.md +59 -0
  123. package/src/NFTDisplay/aspect-ratio-container.js +34 -0
  124. package/src/NFTDisplay/broken.js +18 -0
  125. package/src/NFTDisplay/index.js +257 -0
  126. package/src/NFTDisplay/loading.js +17 -0
  127. package/src/NFTDisplay/svg-embedder/img.js +36 -0
  128. package/src/NFTDisplay/svg-embedder/inline-svg.js +37 -0
  129. package/src/PageScroller/index.js +342 -0
  130. package/src/PageScroller/usePrevValue.js +12 -0
  131. package/src/PricingTable/PricingPlan.js +112 -0
  132. package/src/PricingTable/index.js +43 -0
  133. package/src/Result/common.js +116 -0
  134. package/src/Result/index.js +31 -0
  135. package/src/Result/result.js +57 -0
  136. package/src/Result/translations.js +56 -0
  137. package/src/Screenshot/devices.css +1366 -0
  138. package/src/Screenshot/index.js +181 -0
  139. package/src/Spinner/index.js +19 -0
  140. package/src/SplitButton/index.js +112 -0
  141. package/src/Switch/index.js +78 -0
  142. package/src/Tabs/index.js +46 -0
  143. package/src/Tag/index.js +73 -0
  144. package/src/Terminal/Player.js +364 -0
  145. package/src/Terminal/index.js +150 -0
  146. package/src/Terminal/player.css +378 -0
  147. package/src/Terminal/util.js +167 -0
  148. package/src/Terminal/xterm.css +171 -0
  149. package/src/TextCollapse/index.js +92 -0
  150. package/src/Theme/index.js +184 -0
  151. package/src/Theme/responsiveFontSizes.js +94 -0
  152. package/src/Toast/index.js +118 -0
  153. package/src/Util/index.js +281 -0
  154. package/src/Video/index.js +72 -0
  155. package/src/Wallet/Action.js +105 -0
  156. package/src/Wallet/Download.js +130 -0
  157. package/src/Wallet/Open.js +50 -0
  158. package/src/Wallet/images/abtwallet.png +0 -0
  159. package/src/Wallet/images/android_download.svg +23 -0
  160. package/src/Wallet/images/app-store.svg +20 -0
  161. package/src/Wallet/images/google-play.svg +70 -0
  162. package/src/WechatPrompt/images/android.png +0 -0
  163. package/src/WechatPrompt/images/ios.png +0 -0
  164. package/src/WechatPrompt/index.js +81 -0
  165. package/src/index.js +63 -0
  166. package/src/withTheme/index.js +72 -0
  167. package/src/withTracker/README.md +34 -0
  168. package/src/withTracker/error_boundary.js +34 -0
  169. package/src/withTracker/index.js +70 -0
  170. package/lib/GraphQLPlayground/graphiql.css +0 -1850
  171. package/lib/GraphQLPlayground/index.js +0 -302
  172. package/lib/GraphQLPlayground/util.js +0 -55
@@ -0,0 +1,424 @@
1
+ import React, { useRef } from 'react';
2
+ import styled from 'styled-components';
3
+ import PropTypes from 'prop-types';
4
+ import Portal from '@material-ui/core/Portal';
5
+ import Typography from '@material-ui/core/Typography';
6
+ import CircularProgress from '@material-ui/core/CircularProgress';
7
+ import useMediaQuery from '@material-ui/core/useMediaQuery';
8
+ import useTheme from '@material-ui/core/styles/useTheme';
9
+ import Avatar from '@arcblock/did-connect/lib/Avatar';
10
+
11
+ import Icon from '../Icon';
12
+ import Button from '../Button';
13
+ import Img from '../Img';
14
+
15
+ const Div = styled.div`
16
+ &.arcblock-blocklet {
17
+ padding: 0 16px;
18
+ background: ${props => props.theme.palette.common.white};
19
+ overflow: hidden;
20
+ box-shadow: 0px 0px 8px #f0f0f0;
21
+ &:hover {
22
+ box-shadow: 0px 2px 12px #f0f0f0;
23
+ }
24
+ }
25
+ .arcblock-blocklet__content {
26
+ padding: 16px 0 0 0;
27
+ }
28
+ .arcblock-blocklet__content--main {
29
+ display: flex;
30
+ align-items: center;
31
+ cursor: pointer;
32
+ }
33
+ .arcblock-blocklet__content--body {
34
+ overflow: hidden;
35
+ flex: 1;
36
+ display: flex;
37
+ align-items: flex-start;
38
+ }
39
+ .arcblock-blocklet__addons {
40
+ padding: 16px 0;
41
+ }
42
+ .arcblock-blocklet__cover {
43
+ width: 80px;
44
+ height: 80px;
45
+ margin-right: 12px;
46
+ overflow: hidden;
47
+ border-radius: 12px;
48
+ /* see: https://stackoverflow.com/questions/49066011/overflow-hidden-with-border-radius-not-working-on-safari */
49
+ transform: translateZ(0);
50
+ }
51
+
52
+ .arcblock-blocklet__info {
53
+ flex: 1;
54
+ overflow: hidden;
55
+ .arcblock-blocklet__button {
56
+ margin-top: 16px;
57
+ display: inline-block;
58
+ }
59
+ }
60
+ // 覆盖 mui-button 的样式 做成 blocklet 内部 button 的专有样式
61
+ .arcblock-blocklet__button--hover {
62
+ &:not(.Mui-disabled) {
63
+ position: relative;
64
+ z-index: 1;
65
+ &::before {
66
+ content: '';
67
+ position: absolute;
68
+ height: 100%;
69
+ width: 100%;
70
+ left: 0;
71
+ top: 0;
72
+ transition: opacity 0.3s;
73
+ }
74
+ &:hover::before {
75
+ opacity: 0;
76
+ }
77
+ &::after {
78
+ content: '';
79
+ position: absolute;
80
+ height: 100%;
81
+ width: 100%;
82
+ background-color: ${props => props.theme.palette.primary.main};
83
+ transform: scale(0.1);
84
+ opacity: 0;
85
+ z-index: -1;
86
+ transition: transform 0.3s, opacity 0.3s, background-color 0.3s;
87
+ }
88
+ &:hover::after {
89
+ opacity: 1;
90
+ transform-origin: center;
91
+ transform: scale(1);
92
+ }
93
+ }
94
+
95
+ &:not(.Mui-disabled) {
96
+ background-color: transparent !important;
97
+ color: ${props => props.theme.palette.primary.main};
98
+ }
99
+ &:not(.Mui-disabled) {
100
+ &:hover {
101
+ color: ${props => props.theme.palette.common.white};
102
+ }
103
+ }
104
+ }
105
+
106
+ .arcblock-blocklet__title {
107
+ margin: 0;
108
+ font-size: 18px;
109
+ font-weight: 600;
110
+ overflow: hidden;
111
+ text-overflow: ellipsis;
112
+ white-space: nowrap;
113
+ }
114
+ .arcblock-blocklet__describe {
115
+ margin: 0 0 2px 0;
116
+ color: #999;
117
+ font-size: 14px;
118
+ overflow: hidden;
119
+ text-overflow: ellipsis;
120
+ white-space: nowrap;
121
+ }
122
+
123
+ .arcblock-blocklet__addons {
124
+ display: flex;
125
+ justify-content: space-between;
126
+ color: #999;
127
+ font-size: 14px;
128
+ position: relative;
129
+ }
130
+ .arcblock-blocklet__addons--item {
131
+ white-space: nowrap;
132
+ }
133
+ &.arcblock-blocklet--size-md {
134
+ &:hover {
135
+ position: relative;
136
+ }
137
+ .arcblock-blocklet__title {
138
+ height: 2.3em;
139
+ margin-bottom: 3px;
140
+ display: -webkit-box;
141
+ -webkit-box-orient: vertical;
142
+ -webkit-line-clamp: 2;
143
+ overflow: hidden;
144
+ text-overflow: initial;
145
+ white-space: initial;
146
+ word-break: break-all;
147
+ }
148
+ .arcblock-blocklet__describe {
149
+ white-space: normal;
150
+ height: 2.86em;
151
+ }
152
+ .arcblock-blocklet__button {
153
+ margin-top: 5px;
154
+ }
155
+ }
156
+ &.arcblock-blocklet--size-sm,
157
+ &.arcblock-blocklet--size-xs {
158
+ .arcblock-blocklet__cover {
159
+ width: 40px;
160
+ height: 40px;
161
+ border-radius: 6px;
162
+ }
163
+ .arcblock-blocklet__content {
164
+ padding: 16px 0;
165
+ }
166
+ .arcblock-blocklet__addons {
167
+ padding: 8px 0;
168
+ .arcblock-blocklet__addons--item {
169
+ font-size: 12px;
170
+ }
171
+ }
172
+ }
173
+ &.arcblock-blocklet--size-xs {
174
+ .arcblock-blocklet__addons {
175
+ display: none !important;
176
+ }
177
+ }
178
+ `;
179
+ const ActionButton = styled.div`
180
+ background-color: transparent !important;
181
+ & > :not(.Mui-disabled) {
182
+ position: relative;
183
+ z-index: 1;
184
+ &::before {
185
+ content: '';
186
+ position: absolute;
187
+ height: 100%;
188
+ width: 100%;
189
+ left: 0;
190
+ top: 0;
191
+ transition: opacity 0.3s;
192
+ }
193
+ &:hover::before {
194
+ opacity: 0;
195
+ }
196
+ &::after {
197
+ content: '';
198
+ position: absolute;
199
+ height: 100%;
200
+ width: 100%;
201
+ background-color: ${props => props.theme.palette.primary.main};
202
+ transform: scale(0.1);
203
+ opacity: 0;
204
+ z-index: -1;
205
+ transition: transform 0.3s, opacity 0.3s, background-color 0.3s;
206
+ }
207
+ &:hover::after {
208
+ opacity: 1;
209
+ transform-origin: center;
210
+ transform: scale(1);
211
+ }
212
+ }
213
+ & > :not(.Mui-disabled) {
214
+ background-color: transparent !important;
215
+ color: ${props => props.theme.palette.primary.main}!important;
216
+ }
217
+ & > :not(.Mui-disabled) {
218
+ &:hover {
219
+ color: ${props => props.theme.palette.common.white}!important;
220
+ }
221
+ }
222
+ `;
223
+ function BlockletIcon({ name }) {
224
+ return <Icon name={name} color="inherit" size={15} style={{ marginRight: 8 }} />;
225
+ }
226
+ BlockletIcon.propTypes = {
227
+ name: PropTypes.string.isRequired,
228
+ };
229
+
230
+ function prettySize(_size) {
231
+ let size = _size;
232
+ const list = ['', 'k', 'm', 'b'];
233
+ let index = 0;
234
+ while (size > 1000 && index < list.length - 1) {
235
+ size = (size / 1000).toFixed(1);
236
+ index += 1;
237
+ }
238
+ return _size && `${size}${list[index]}`;
239
+ }
240
+
241
+ export default function Blocklet({
242
+ title,
243
+ did,
244
+ description,
245
+ cover,
246
+ type,
247
+ size,
248
+ addons,
249
+ button,
250
+ buttonText,
251
+ buttonDisabled,
252
+ buttonLoading,
253
+ isStickyButton,
254
+ onButtonClick,
255
+ onMainClick,
256
+ onTagClick,
257
+ className,
258
+ scaleClickZone,
259
+ ...rest
260
+ }) {
261
+ const wrapHandler =
262
+ (handler, stopFn = () => false) =>
263
+ (e, ...args) => {
264
+ if (stopFn()) {
265
+ e.preventDefault();
266
+ e.stopPropagation();
267
+ } else if (handler instanceof Function) {
268
+ e.preventDefault();
269
+ e.stopPropagation();
270
+ handler(...args);
271
+ }
272
+ };
273
+ const _onButtonClick = wrapHandler(onButtonClick, () => {
274
+ // stop click while custom button or buttonDisabled or buttondLoading
275
+ if (button || buttonDisabled || buttonLoading) {
276
+ return true;
277
+ }
278
+ return false;
279
+ });
280
+ const _onMainClick = wrapHandler(onMainClick);
281
+
282
+ const theme = useTheme();
283
+ const isDownSm = useMediaQuery(theme.breakpoints.down('sm'));
284
+ const isDownMd = useMediaQuery(theme.breakpoints.down('md'));
285
+ const isUPLg = useMediaQuery(theme.breakpoints.up('lg'));
286
+
287
+ // If size is auto, need calculate actual size according to screen size
288
+ // eslint-disable-next-line no-nested-ternary
289
+ const actualSize = size === 'auto' ? (isDownSm ? 'xs' : isDownMd ? 'sm' : 'md') : size;
290
+ // eslint-disable-next-line no-nested-ternary
291
+ const didAvatarSize = size === 'auto' ? (isUPLg ? 80 : 40) : size === 'md' ? 80 : 40;
292
+ const container = useRef(null);
293
+
294
+ return (
295
+ <Div
296
+ {...rest}
297
+ scaleClickZone={scaleClickZone}
298
+ className={`${className} arcblock-blocklet arcblock-blocklet--size-${actualSize}`}>
299
+ <div className="arcblock-blocklet__content">
300
+ <div className="arcblock-blocklet__content--main" onClick={_onMainClick} ref={container}>
301
+ <div className="arcblock-blocklet__content--body">
302
+ {cover ? (
303
+ <div className="arcblock-blocklet__cover">
304
+ <Img src={cover} />
305
+ </div>
306
+ ) : (
307
+ did && (
308
+ <div className="arcblock-blocklet__cover">
309
+ <Avatar did={did} size={didAvatarSize} />
310
+ </div>
311
+ )
312
+ )}
313
+ <div className="arcblock-blocklet__info">
314
+ <Typography
315
+ component="h3"
316
+ variant="h3"
317
+ className="arcblock-blocklet__title"
318
+ title={title}>
319
+ {title}
320
+ </Typography>
321
+ {description && (
322
+ <Typography
323
+ component="div"
324
+ variant="body2"
325
+ className="arcblock-blocklet__describe"
326
+ title={description}>
327
+ {description}
328
+ </Typography>
329
+ )}
330
+ {['md', 'sm', 'xs'].includes(actualSize) && (
331
+ <Portal container={container.current} disablePortal={actualSize === 'md'}>
332
+ <div
333
+ className="arcblock-blocklet__button"
334
+ onClick={_onButtonClick}
335
+ style={{ display: isStickyButton ? 'block' : '' }}>
336
+ {button ||
337
+ (onButtonClick && (
338
+ <Button
339
+ className="arcblock-blocklet__button--hover"
340
+ variant="outlined"
341
+ color="primary"
342
+ size="small"
343
+ disabled={buttonDisabled || buttonLoading}
344
+ style={
345
+ actualSize === 'md'
346
+ ? { padding: '3px 20px', fontSize: '14px' }
347
+ : { padding: '3px 15px', minWidth: '54px', fontSize: '13px' }
348
+ }>
349
+ {buttonLoading && (
350
+ <CircularProgress
351
+ size={actualSize === 'md' ? 15 : 13}
352
+ style={{ marginRight: 3, color: 'inherit' }}
353
+ />
354
+ )}
355
+ {buttonText}
356
+ </Button>
357
+ ))}
358
+ </div>
359
+ </Portal>
360
+ )}
361
+ </div>
362
+ </div>
363
+ </div>
364
+ </div>
365
+ <div className="arcblock-blocklet__addons">
366
+ {addons.map((item, index) => (
367
+ <Typography
368
+ component="span"
369
+ variant="caption"
370
+ className="arcblock-blocklet__addons--item"
371
+ // eslint-disable-next-line react/no-array-index-key
372
+ key={index}
373
+ title={item.title}>
374
+ {item.empty ? null : (
375
+ <>
376
+ <BlockletIcon name={item.icon} />
377
+ {item.pretty ? prettySize(item.value) : item.value}
378
+ </>
379
+ )}
380
+ </Typography>
381
+ ))}
382
+ </div>
383
+ </Div>
384
+ );
385
+ }
386
+ export { ActionButton };
387
+ Blocklet.propTypes = {
388
+ title: PropTypes.string.isRequired,
389
+ did: PropTypes.string,
390
+ isStickyButton: PropTypes.bool,
391
+ description: PropTypes.string,
392
+ cover: PropTypes.string,
393
+ buttonText: PropTypes.string,
394
+ buttonDisabled: PropTypes.bool,
395
+ buttonLoading: PropTypes.bool,
396
+ button: PropTypes.element,
397
+ type: PropTypes.string,
398
+ addons: PropTypes.arrayOf(PropTypes.object),
399
+ size: PropTypes.oneOf(['xs', 'sm', 'md', 'auto']),
400
+ onButtonClick: PropTypes.func,
401
+ onMainClick: PropTypes.func,
402
+ onTagClick: PropTypes.func,
403
+ className: PropTypes.string,
404
+ scaleClickZone: PropTypes.number,
405
+ };
406
+
407
+ Blocklet.defaultProps = {
408
+ description: null,
409
+ cover: null,
410
+ did: null,
411
+ isStickyButton: false,
412
+ buttonText: 'Install',
413
+ buttonDisabled: false,
414
+ buttonLoading: false,
415
+ button: null,
416
+ type: null,
417
+ size: 'auto',
418
+ addons: [],
419
+ onButtonClick: null,
420
+ onMainClick: null,
421
+ onTagClick: null,
422
+ className: null,
423
+ scaleClickZone: 1.5,
424
+ };
@@ -0,0 +1,4 @@
1
+ import Button from '@material-ui/core/Button';
2
+ import wrap from './wrap';
3
+
4
+ export default wrap(Button);
@@ -0,0 +1,101 @@
1
+ /* eslint-disable prefer-destructuring */
2
+ /* eslint-disable func-names */
3
+ import React from 'react';
4
+ import PropTypes from 'prop-types';
5
+
6
+ import Spinner from '../Spinner';
7
+ import colors from '../Colors';
8
+ import { mergeProps } from '../Util';
9
+
10
+ export default function (BaseComponent) {
11
+ function WrappedComponent(props) {
12
+ const newProps = mergeProps(props, WrappedComponent, ['style']);
13
+ const { children, rounded, loading, disabled, style, forwardedRef, color, ...rest } = newProps;
14
+
15
+ const isDisabled = disabled || loading;
16
+
17
+ let loadingSize = 16;
18
+ switch (rest.size) {
19
+ case 'small':
20
+ loadingSize = 14;
21
+ break;
22
+ case 'large':
23
+ loadingSize = 18;
24
+ break;
25
+ default:
26
+ }
27
+ const styles = Object.assign({}, style, {
28
+ boxShadow: 'none',
29
+ textTransform: 'capitalize',
30
+ });
31
+
32
+ // mui 只支持 4 种 color 值: default/inherit/primary/secondary (传入这 4 种之外的值会报 warning),
33
+ // 这里扩展 danger/warning/reverse 三种 color
34
+ let _rest = rest;
35
+ switch (color) {
36
+ case 'error':
37
+ case 'danger': {
38
+ if (rest.variant === 'contained') {
39
+ styles.backgroundColor = colors.error.main;
40
+ styles.color = colors.common.white;
41
+ } else {
42
+ styles.borderColor = colors.error.main;
43
+ styles.color = colors.error.main;
44
+ }
45
+ break;
46
+ }
47
+ case 'warning': {
48
+ if (rest.variant === 'contained') {
49
+ styles.backgroundColor = colors.warning.main;
50
+ styles.color = colors.common.white;
51
+ } else {
52
+ styles.borderColor = colors.warning.main;
53
+ styles.color = colors.warning.main;
54
+ }
55
+ break;
56
+ }
57
+ case 'reverse': {
58
+ if (rest.variant === 'contained') {
59
+ styles.backgroundColor = 'rgba(255, 255, 255, 0.9)';
60
+ styles.color = colors.grey[900];
61
+ } else {
62
+ styles.borderColor = colors.grey[900];
63
+ styles.color = colors.grey[900];
64
+ }
65
+ break;
66
+ }
67
+ // 除扩展的几种 color 外, 由 mui button 自己处理 color
68
+ default: {
69
+ _rest = { ..._rest, color };
70
+ }
71
+ }
72
+ if (rounded) {
73
+ // styles.borderRadius = { small: 16, medium: 18, large: 20 }[rest.size];
74
+ styles.borderRadius = '100vw';
75
+ }
76
+
77
+ return (
78
+ <BaseComponent style={styles} ref={forwardedRef} disabled={isDisabled} {..._rest}>
79
+ {loading && <Spinner size={loadingSize} style={{ marginRight: 5 }} />}
80
+ {children}
81
+ </BaseComponent>
82
+ );
83
+ }
84
+
85
+ WrappedComponent.propTypes = {
86
+ children: PropTypes.any.isRequired,
87
+ style: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
88
+ size: PropTypes.oneOf(['large', 'medium', 'small']),
89
+ forwardedRef: PropTypes.any,
90
+ rounded: PropTypes.bool,
91
+ };
92
+
93
+ WrappedComponent.defaultProps = {
94
+ rounded: false,
95
+ size: 'medium',
96
+ forwardedRef: null,
97
+ style: {},
98
+ };
99
+
100
+ return React.forwardRef((props, ref) => <WrappedComponent {...props} forwardedRef={ref} />);
101
+ }
@@ -0,0 +1,6 @@
1
+ import ButtonGroup from '@material-ui/core/ButtonGroup';
2
+ import wrap from '../Button/wrap';
3
+
4
+ // deprecated, ux ButtonGroup 组件废弃, 建议直接使用 @material-ui/core/ButtonGroup
5
+ // (该定制组件原本目的是调整 ButtonGroup 的圆角, 但最新设计规范已经不再使用较大的圆角, 改为使用 mui button 默认的圆角)
6
+ export default wrap(ButtonGroup);
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import PropTypes from 'prop-types';
4
+
5
+ /**
6
+ *
7
+ * @param {string} relative 容器相对尺寸,默认相对屏幕(screen),可设置为父容器(parent)
8
+ * @returns react component element
9
+ */
10
+ export default function Center({ children, relative }) {
11
+ let style = {};
12
+
13
+ if (relative === 'parent') {
14
+ style = {
15
+ width: '100%',
16
+ height: '100%',
17
+ };
18
+ }
19
+
20
+ return <Div style={style}>{children}</Div>;
21
+ }
22
+
23
+ const Div = styled.div`
24
+ flex: 1;
25
+ width: 100vw;
26
+ height: 100vh;
27
+
28
+ display: flex;
29
+ justify-content: center;
30
+ align-items: center;
31
+ `;
32
+
33
+ Center.propTypes = {
34
+ children: PropTypes.any.isRequired,
35
+ relative: PropTypes.string,
36
+ };
37
+
38
+ Center.defaultProps = {
39
+ relative: 'screen',
40
+ };
@@ -0,0 +1,90 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import Copy from 'copy-to-clipboard';
3
+ import PropTypes from 'prop-types';
4
+ import useWindowSize from 'react-use/lib/useWindowSize';
5
+
6
+ import Tooltip from '@material-ui/core/Tooltip';
7
+ import Typography from '@material-ui/core/Typography';
8
+ import styled from 'styled-components';
9
+
10
+ import Toast from '../Toast';
11
+ import { mergeProps } from '../Util';
12
+
13
+ export default function ClickToCopy(props) {
14
+ const newProps = mergeProps(props, ClickToCopy, ['style']);
15
+ const { children, content, tip, copiedTip, tipPlacement, style, ...rest } = newProps;
16
+
17
+ const [copied, setCopied] = useState(false);
18
+ const childrenRef = React.createRef();
19
+ const { width } = useWindowSize();
20
+
21
+ const onCopy = e => {
22
+ Copy(content || e.current.textContent);
23
+ setCopied(true);
24
+ };
25
+
26
+ useEffect(() => {
27
+ let timer = null;
28
+ if (copied) {
29
+ timer = setTimeout(() => {
30
+ setCopied(false);
31
+ }, 2000);
32
+ }
33
+
34
+ return () => {
35
+ if (timer) {
36
+ clearTimeout(timer);
37
+ }
38
+ };
39
+ });
40
+
41
+ return (
42
+ <Tooltip
43
+ title={copied ? copiedTip : tip}
44
+ {...rest}
45
+ placement={tipPlacement}
46
+ disableFocusListener>
47
+ <Container
48
+ ref={childrenRef}
49
+ component="span"
50
+ style={Object.assign(
51
+ { fontSize: 'inherit', color: 'inherit', fontWeight: 'inherit' },
52
+ style
53
+ )}
54
+ onClick={() => onCopy(childrenRef)}>
55
+ {children || content}
56
+ {copied && width < 600 && <Toast variant="success" message={copiedTip} />}
57
+ </Container>
58
+ </Tooltip>
59
+ );
60
+ }
61
+
62
+ ClickToCopy.propTypes = {
63
+ children: PropTypes.any.isRequired,
64
+ content: PropTypes.string,
65
+ tip: PropTypes.string,
66
+ tipPlacement: PropTypes.string,
67
+ copiedTip: PropTypes.string,
68
+ style: PropTypes.object,
69
+ };
70
+
71
+ ClickToCopy.defaultProps = {
72
+ content: '',
73
+ tip: 'Click To Copy',
74
+ copiedTip: 'Copied',
75
+ tipPlacement: 'right',
76
+ style: {},
77
+ };
78
+
79
+ const Container = styled(Typography)`
80
+ display: inline;
81
+ white-space: pre-wrap;
82
+ word-wrap: break-word;
83
+ overflow-wrap: break-word;
84
+ align-items: center;
85
+ justify-content: start;
86
+ border-radius: 15px;
87
+ padding: 1px 12px;
88
+ background-color: rgba(0, 0, 0, 0.08);
89
+ cursor: pointer;
90
+ `;