@arcblock/ux 1.16.60 → 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.
@@ -0,0 +1,254 @@
1
+ import React, { useRef } from 'react';
2
+ import styled from 'styled-components';
3
+ import PropTypes from 'prop-types';
4
+ import Typography from '@material-ui/core/Typography';
5
+ import CircularProgress from '@material-ui/core/CircularProgress';
6
+ import Avatar from '@arcblock/did-connect/lib/Avatar';
7
+
8
+ import Button from '../Button';
9
+ import Img from '../Img';
10
+
11
+ const Div = styled.div`
12
+ .arcblock-blocklet__content {
13
+ padding: 24px 16px 0 16px;
14
+ display: flex;
15
+ align-items: center;
16
+ cursor: pointer;
17
+ }
18
+ .arcblock-blocklet__content--body {
19
+ overflow: hidden;
20
+ flex: 1;
21
+ display: flex;
22
+ align-items: flex-start;
23
+ }
24
+ .arcblock-blocklet__cover {
25
+ width: 64px;
26
+ height: 64px;
27
+ margin-right: 12px;
28
+ overflow: hidden;
29
+ border-radius: 12px;
30
+ /* see: https://stackoverflow.com/questions/49066011/overflow-hidden-with-border-radius-not-working-on-safari */
31
+ transform: translateZ(0);
32
+ }
33
+ .arcblock-blocklet__button--hover {
34
+ &:not(.Mui-disabled) {
35
+ position: relative;
36
+ z-index: 1;
37
+ &::before {
38
+ content: '';
39
+ position: absolute;
40
+ height: 100%;
41
+ width: 100%;
42
+ left: 0;
43
+ top: 0;
44
+ transition: opacity 0.3s;
45
+ }
46
+ &:hover::before {
47
+ opacity: 0;
48
+ }
49
+ &::after {
50
+ content: '';
51
+ position: absolute;
52
+ height: 100%;
53
+ width: 100%;
54
+ background-color: ${props => props.theme.palette.primary.main};
55
+ transform: scale(0.1);
56
+ opacity: 0;
57
+ z-index: -1;
58
+ transition: transform 0.3s, opacity 0.3s, background-color 0.3s;
59
+ }
60
+ &:hover::after {
61
+ opacity: 1;
62
+ transform-origin: center;
63
+ transform: scale(1);
64
+ }
65
+ }
66
+
67
+ &:not(.Mui-disabled) {
68
+ background-color: transparent !important;
69
+ color: ${props => props.theme.palette.primary.main};
70
+ }
71
+ &:not(.Mui-disabled) {
72
+ &:hover {
73
+ color: ${props => props.theme.palette.common.white};
74
+ }
75
+ }
76
+ }
77
+ .arcblock-blocklet__info {
78
+ flex: 1;
79
+ overflow: hidden;
80
+ border-bottom: 1px solid ${props => props.theme.palette.divider};
81
+ padding-bottom: 24px;
82
+ }
83
+ .arcblock-blocklet__text {
84
+ height: 65px;
85
+ overflow: hidden;
86
+ }
87
+ /* 设置多行文本溢出显示省略号 兼容fireFox、safari */
88
+ .arcblock-blocklet__title {
89
+ margin: 0;
90
+ font-size: 18px;
91
+ font-weight: 500;
92
+ line-height: 22px;
93
+ overflow: hidden;
94
+ text-overflow: ellipsis;
95
+ display: -webkit-box;
96
+ -webkit-line-clamp: 2;
97
+ -webkit-box-orient: vertical;
98
+ max-height: 44px;
99
+ word-break: break-all;
100
+ }
101
+ .arcblock-blocklet__describe {
102
+ margin: 0;
103
+ color: ${props => props.theme.palette.grey[600]};
104
+ font-size: 14px;
105
+ font-weight: 500;
106
+ line-height: 17px;
107
+ max-height: 17px;
108
+ overflow: hidden;
109
+ text-overflow: ellipsis;
110
+ white-space: nowrap;
111
+ }
112
+ .arcblock-blocklet__version {
113
+ color: ${props => props.theme.palette.grey[600]};
114
+ }
115
+ `;
116
+ export default function BlockletStore({
117
+ title,
118
+ did,
119
+ description,
120
+ cover,
121
+ version,
122
+ button,
123
+ buttonText,
124
+ buttonDisabled,
125
+ buttonLoading,
126
+ onButtonClick,
127
+ onMainClick,
128
+ className,
129
+ ...rest
130
+ }) {
131
+ const wrapHandler =
132
+ (handler, stopFn = () => false) =>
133
+ (e, ...args) => {
134
+ if (stopFn()) {
135
+ e.preventDefault();
136
+ e.stopPropagation();
137
+ } else if (handler instanceof Function) {
138
+ e.preventDefault();
139
+ e.stopPropagation();
140
+ handler(...args);
141
+ }
142
+ };
143
+ const _onButtonClick = wrapHandler(onButtonClick, () => {
144
+ // stop click while custom button or buttonDisabled or buttondLoading
145
+ if (button || buttonDisabled || buttonLoading) {
146
+ return true;
147
+ }
148
+ return false;
149
+ });
150
+ const _onMainClick = wrapHandler(onMainClick);
151
+ const container = useRef(null);
152
+
153
+ return (
154
+ <Div {...rest}>
155
+ <div
156
+ className={`${className} arcblock-blocklet__content`}
157
+ onClick={_onMainClick}
158
+ ref={container}>
159
+ <div className="arcblock-blocklet__content--body">
160
+ {cover ? (
161
+ <div className="arcblock-blocklet__cover">
162
+ <Img src={cover} />
163
+ </div>
164
+ ) : (
165
+ did && (
166
+ <div className="arcblock-blocklet__cover">
167
+ <Avatar did={did} size={64} />
168
+ </div>
169
+ )
170
+ )}
171
+ <div className="arcblock-blocklet__info">
172
+ <div className="arcblock-blocklet__text">
173
+ <Typography
174
+ component="h3"
175
+ variant="h3"
176
+ className="arcblock-blocklet__title"
177
+ title={title}>
178
+ {title}
179
+ </Typography>
180
+ {description && (
181
+ <Typography
182
+ component="div"
183
+ variant="body2"
184
+ className="arcblock-blocklet__describe"
185
+ title={description}>
186
+ {description}
187
+ </Typography>
188
+ )}
189
+ </div>
190
+ <div
191
+ style={{
192
+ display: 'flex',
193
+ alignItems: 'center',
194
+ marginTop: '12px',
195
+ flexFlow: 'wrap',
196
+ }}>
197
+ <div onClick={_onButtonClick} style={{ marginRight: '12px' }}>
198
+ {button ||
199
+ (onButtonClick && (
200
+ <Button
201
+ className="arcblock-blocklet__button--hover"
202
+ variant="outlined"
203
+ color="primary"
204
+ size="small"
205
+ disabled={buttonDisabled || buttonLoading}
206
+ style={{
207
+ padding: '3px 6px',
208
+ fontSize: '14px',
209
+ minWidth: '92px',
210
+ textAlign: 'center',
211
+ }}>
212
+ {buttonLoading && (
213
+ <CircularProgress size={15} style={{ marginRight: 3, color: 'inherit' }} />
214
+ )}
215
+ {buttonText}
216
+ </Button>
217
+ ))}
218
+ </div>
219
+ <div className="arcblock-blocklet__version">{version && `v${version}`}</div>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </Div>
225
+ );
226
+ }
227
+ BlockletStore.propTypes = {
228
+ title: PropTypes.string.isRequired,
229
+ did: PropTypes.string,
230
+ description: PropTypes.string,
231
+ cover: PropTypes.string,
232
+ buttonText: PropTypes.string,
233
+ buttonDisabled: PropTypes.bool,
234
+ buttonLoading: PropTypes.bool,
235
+ button: PropTypes.element,
236
+ version: PropTypes.string,
237
+ onButtonClick: PropTypes.func,
238
+ onMainClick: PropTypes.func,
239
+ className: PropTypes.string,
240
+ };
241
+
242
+ BlockletStore.defaultProps = {
243
+ description: null,
244
+ cover: null,
245
+ did: null,
246
+ buttonText: 'Install',
247
+ buttonDisabled: false,
248
+ buttonLoading: false,
249
+ button: null,
250
+ version: null,
251
+ onButtonClick: null,
252
+ onMainClick: null,
253
+ className: null,
254
+ };
@@ -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;