@arcblock/ux 1.16.62 → 1.16.63

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.
@@ -1,424 +1,5 @@
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';
1
+ import ActionButton from './utils';
2
+ import Blocklet from './blocklet';
10
3
 
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
4
  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
- };
5
+ export default Blocklet;
@@ -0,0 +1,49 @@
1
+ import styled from 'styled-components';
2
+
3
+ const ActionButton = styled.div`
4
+ background-color: transparent !important;
5
+ & > :not(.Mui-disabled) {
6
+ position: relative;
7
+ z-index: 1;
8
+ &::before {
9
+ content: '';
10
+ position: absolute;
11
+ height: 100%;
12
+ width: 100%;
13
+ left: 0;
14
+ top: 0;
15
+ transition: opacity 0.3s;
16
+ }
17
+ &:hover::before {
18
+ opacity: 0;
19
+ }
20
+ &::after {
21
+ content: '';
22
+ position: absolute;
23
+ height: 100%;
24
+ width: 100%;
25
+ border-radius: 2px;
26
+ background-color: ${props => props.theme.palette.primary.main};
27
+ transform: scale(0.1);
28
+ opacity: 0;
29
+ z-index: -1;
30
+ transition: transform 0.3s, opacity 0.3s, background-color 0.3s;
31
+ }
32
+ &:hover::after {
33
+ opacity: 1;
34
+ transform-origin: center;
35
+ transform: scale(1);
36
+ }
37
+ }
38
+ & > :not(.Mui-disabled) {
39
+ background-color: transparent !important;
40
+ color: ${props => props.theme.palette.primary.main}!important;
41
+ }
42
+ & > :not(.Mui-disabled) {
43
+ &:hover {
44
+ color: ${props => props.theme.palette.common.white}!important;
45
+ }
46
+ }
47
+ `;
48
+
49
+ export default ActionButton;