@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,110 @@
1
+ /* eslint-disable react/no-unused-prop-types */
2
+ import React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import styled from 'styled-components';
5
+ import Typography from '@material-ui/core/Typography';
6
+
7
+ import { mergeProps } from '../Util';
8
+ import Logo from '../Logo';
9
+
10
+ export default function Footer(props) {
11
+ const newProps = mergeProps(props, Footer, ['dark', 'style']);
12
+ const { className, copyStart, style, brand, dark } = newProps;
13
+
14
+ const endYear = new Date().getFullYear();
15
+ const copyYear = endYear === copyStart ? endYear : `${copyStart}-${endYear}`;
16
+
17
+ return (
18
+ <Container className={className} style={style} dark={dark}>
19
+ <Typography component="div" className="footer">
20
+ <Typography component="p" className="footer-item">
21
+ <span className="footer-copy">&copy; Copyright {copyYear} </span>
22
+ <span className="footer-brand">{brand}</span>
23
+ </Typography>
24
+ <Typography
25
+ component="p"
26
+ className="footer-item"
27
+ style={{ justifyContent: 'flex-end', flexShrink: 0 }}>
28
+ Powered by
29
+ <Logo mode={dark ? 'light' : 'dark'} layout="horizontal" className="logo-container" />
30
+ </Typography>
31
+ </Typography>
32
+ </Container>
33
+ );
34
+ }
35
+
36
+ Footer.propTypes = {
37
+ dark: PropTypes.bool,
38
+ className: PropTypes.string,
39
+ copyStart: PropTypes.string,
40
+ brand: PropTypes.string,
41
+ style: PropTypes.object,
42
+ };
43
+
44
+ Footer.defaultProps = {
45
+ dark: false,
46
+ brand: 'ArcBlock Inc.',
47
+ copyStart: '2017',
48
+ className: '',
49
+ style: {},
50
+ };
51
+
52
+ const Container = styled.div`
53
+ margin-top: 64px;
54
+ padding: 24px 0 32px;
55
+ border-top: 1px solid ${props => (props.dark ? props.theme.palette.grey[900] : '#dee2e7')};
56
+ box-sizing: border-box;
57
+ width: 100%;
58
+
59
+ @media (max-width: 540px) {
60
+ padding: 8px 0;
61
+ }
62
+
63
+ .footer {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+
68
+ .footer-item {
69
+ color: ${props => props.theme.palette.grey[900]};
70
+ display: flex;
71
+ align-items: center;
72
+ flex-wrap: wrap;
73
+ font-size: 0.9rem;
74
+ }
75
+
76
+ .footer-brand {
77
+ margin-left: 8px;
78
+ margin-right: 8px;
79
+ }
80
+
81
+ .logo-container {
82
+ margin: 0 24px;
83
+ width: 90px;
84
+ opacity: 0.5;
85
+ }
86
+
87
+ @media (max-width: 540px) {
88
+ .footer-item {
89
+ font-size: 0.7rem;
90
+ }
91
+
92
+ .logo-container {
93
+ margin: 0 0 0 16px;
94
+ width: 70px;
95
+ height: 40px;
96
+ }
97
+ }
98
+
99
+ @media (max-width: 380px) {
100
+ .footer-item {
101
+ font-size: 0.65rem;
102
+ }
103
+
104
+ .logo-container {
105
+ margin: 0 0 0 8px;
106
+ height: 24px;
107
+ }
108
+ }
109
+ }
110
+ `;
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled from 'styled-components';
4
+
5
+ import Img from '../Img';
6
+
7
+ export default function ImageIcon({ name, size, alt, color, style, prefix, showBadge, ...rest }) {
8
+ const src = `${prefix}/${name}-${color.replace(/^#/, '')}.png`;
9
+ return (
10
+ <Div style={{ width: size, height: size }}>
11
+ <Img
12
+ width={size}
13
+ height={size}
14
+ alt={alt || name}
15
+ src={src}
16
+ style={Object.assign({ width: size }, style)}
17
+ {...rest}
18
+ />
19
+ {showBadge && <i className="badge-point" />}
20
+ </Div>
21
+ );
22
+ }
23
+
24
+ ImageIcon.propTypes = {
25
+ name: PropTypes.string.isRequired,
26
+ size: PropTypes.number,
27
+ color: PropTypes.string,
28
+ alt: PropTypes.string,
29
+ style: PropTypes.object,
30
+ prefix: PropTypes.string,
31
+ showBadge: PropTypes.bool,
32
+ };
33
+
34
+ ImageIcon.defaultProps = {
35
+ size: 36,
36
+ color: '#000000',
37
+ alt: '',
38
+ style: {},
39
+ prefix: '/images',
40
+ showBadge: false,
41
+ };
42
+
43
+ const Div = styled.div`
44
+ position: relative;
45
+ .badge-point {
46
+ position: absolute;
47
+ width: 10px;
48
+ height: 10px;
49
+ border-radius: 10px;
50
+ background-color: #fe4e44;
51
+ right: -2px;
52
+ top: 0;
53
+ box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3), 0px 0px 20px rgba(0, 0, 0, 0.1);
54
+ }
55
+ `;
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled from 'styled-components';
4
+
5
+ import colors from '../Colors';
6
+
7
+ const variants = {
8
+ light: 'fal',
9
+ regular: 'far',
10
+ solid: 'fas',
11
+ };
12
+
13
+ const Icon = ({ name, color, size, variant, rounded, style, className, forwardedRef, ...rest }) => {
14
+ const content = (
15
+ <i
16
+ ref={forwardedRef}
17
+ className={`${variants[variant]} fa-${name} ${rounded ? '' : className}`}
18
+ style={Object.assign({ color, fontSize: `${size}px` }, style || {})}
19
+ />
20
+ );
21
+
22
+ if (rounded) {
23
+ return (
24
+ <Span ref={forwardedRef} size={size} color={color} className={className} {...rest}>
25
+ {content}
26
+ </Span>
27
+ );
28
+ }
29
+
30
+ return content;
31
+ };
32
+
33
+ Icon.propTypes = {
34
+ name: PropTypes.string.isRequired,
35
+ className: PropTypes.string,
36
+ color: PropTypes.string,
37
+ rounded: PropTypes.bool,
38
+ variant: PropTypes.string,
39
+ size: PropTypes.number,
40
+ style: PropTypes.object,
41
+ };
42
+
43
+ Icon.defaultProps = {
44
+ rounded: false,
45
+ variant: 'light',
46
+ color: colors.grey[900],
47
+ className: '',
48
+ size: 24,
49
+ style: {},
50
+ };
51
+
52
+ const Span = styled.span`
53
+ width: ${props => props.size * 2}px;
54
+ height: ${props => props.size * 2}px;
55
+ border-radius: 50%;
56
+ border: 1px solid ${props => props.color};
57
+ display: flex;
58
+ justify-content: center;
59
+ align-items: center;
60
+
61
+ .fa,
62
+ .fas,
63
+ .fal,
64
+ .far {
65
+ line-height: ${props => props.size}px;
66
+ }
67
+ `;
68
+
69
+ export default React.forwardRef((props, ref) => <Icon {...props} forwardedRef={ref} />);
@@ -0,0 +1,172 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { makeStyles, SvgIcon } from '@material-ui/core';
4
+ import { useInView } from 'react-intersection-observer';
5
+ import Alert from 'mdi-material-ui/Alert';
6
+ import ImageIcon from 'mdi-material-ui/Image';
7
+
8
+ const useStyles = makeStyles(() => ({
9
+ root: {
10
+ position: 'relative',
11
+ overflow: 'hidden',
12
+ '& .image--state, & .image--img': {
13
+ minWidth: '100%',
14
+ minHeight: '100%',
15
+ position: 'absolute',
16
+ top: 0,
17
+ left: '50%',
18
+ transform: 'translateX(-50%)',
19
+ },
20
+ '& .image--state': {
21
+ display: 'flex',
22
+ flexDirection: 'column',
23
+ justifyContent: 'center',
24
+ alignItems: 'center',
25
+ color: '#999',
26
+ background: '#eee',
27
+ width: '100%',
28
+ height: '100%',
29
+ },
30
+ '& .image--img': {
31
+ opacity: 0,
32
+ },
33
+ '& .image--icon': {
34
+ fontSize: 30,
35
+ maxWidth: '80%',
36
+ maxHeight: '80%',
37
+ },
38
+ },
39
+ }));
40
+
41
+ function Img({
42
+ lazy,
43
+ width,
44
+ height,
45
+ repeat,
46
+ ratio,
47
+ alt,
48
+ size,
49
+ position,
50
+ src,
51
+ placeholder,
52
+ fallback,
53
+ style,
54
+ className,
55
+ onError,
56
+ onSuccess,
57
+ ...rest
58
+ }) {
59
+ const classes = useStyles();
60
+ const [ref, inView] = lazy ? useInView({ threshold: 0, triggerOnce: true }) : [null, true];
61
+
62
+ const [imgState, setImgState] = useState('init');
63
+
64
+ const actualSrc = useMemo(() => {
65
+ switch (imgState) {
66
+ case 'init':
67
+ case 'loading':
68
+ return placeholder;
69
+ case 'error':
70
+ return fallback;
71
+ case 'loaded':
72
+ return src;
73
+ default:
74
+ return null;
75
+ }
76
+ }, [placeholder, fallback, src, imgState]);
77
+
78
+ const actualRatio = useMemo(() => {
79
+ if (width && height) return (100 * height) / width;
80
+ return ratio * 100;
81
+ });
82
+
83
+ const mergedStyle = useMemo(
84
+ () => ({
85
+ backgroundImage: actualSrc ? `url(${actualSrc})` : '',
86
+ backgroundPosition: position,
87
+ backgroundSize: size,
88
+ backgroundRepeat: repeat,
89
+ paddingTop: `${actualRatio}%`,
90
+ }),
91
+ [actualSrc, position, size, imgState]
92
+ );
93
+
94
+ const outerStyle = {
95
+ ...style,
96
+ display: 'inline-block',
97
+ width: width ? `${width}px` : '100%',
98
+ };
99
+
100
+ function loadImg() {
101
+ const img = new Image();
102
+ img.src = src;
103
+ setImgState('loading');
104
+ img.onload = () => {
105
+ setImgState('loaded');
106
+ onSuccess();
107
+ };
108
+ img.onerror = err => {
109
+ setImgState('error');
110
+ onError(err);
111
+ };
112
+ }
113
+
114
+ useEffect(() => {
115
+ if (inView) loadImg();
116
+ }, [inView]);
117
+
118
+ return (
119
+ // paddingTop 要求元素本身的宽度为 100%,所以只能加一个外层元素去限制宽度
120
+ <div ref={ref} style={outerStyle} {...rest}>
121
+ <div className={`image ${className} ${classes.root}`} style={mergedStyle}>
122
+ {!fallback && imgState === 'error' && (
123
+ <div className="image--state" title="loading image">
124
+ <SvgIcon component={Alert} className="image--icon" />
125
+ </div>
126
+ )}
127
+ {!placeholder && imgState === 'loading' && (
128
+ <div className="image--state" title="Image load error">
129
+ <SvgIcon component={ImageIcon} className="image--icon" />
130
+ </div>
131
+ )}
132
+ {imgState === 'loaded' && <img className="image--img" src={src} alt={alt} />}
133
+ </div>
134
+ </div>
135
+ );
136
+ }
137
+
138
+ Img.propTypes = {
139
+ src: PropTypes.string.isRequired,
140
+ alt: PropTypes.string,
141
+ size: PropTypes.string,
142
+ position: PropTypes.string,
143
+ style: PropTypes.object,
144
+ ratio: PropTypes.number,
145
+ repeat: PropTypes.string,
146
+ width: PropTypes.number,
147
+ height: PropTypes.number,
148
+ lazy: PropTypes.bool,
149
+ placeholder: PropTypes.string,
150
+ fallback: PropTypes.string,
151
+ className: PropTypes.string,
152
+ onError: PropTypes.func,
153
+ onSuccess: PropTypes.func,
154
+ };
155
+ Img.defaultProps = {
156
+ alt: null,
157
+ size: 'cover',
158
+ position: 'top center',
159
+ repeat: 'no-repeat',
160
+ style: null,
161
+ ratio: 1,
162
+ width: null,
163
+ height: null,
164
+ lazy: true,
165
+ placeholder: null,
166
+ fallback: null,
167
+ className: '',
168
+ onError: () => {},
169
+ onSuccess: () => {},
170
+ };
171
+
172
+ export default Img;
@@ -0,0 +1,83 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import camelCase from 'lodash/camelCase';
4
+ import upperFirst from 'lodash/upperFirst';
5
+ import styled from 'styled-components';
6
+ import Typography from '@material-ui/core/Typography';
7
+
8
+ const InfoRow = ({ name, nameFormatter, layout, children, valueComponent, nameWidth, ...rest }) => (
9
+ <Container layout={layout} width={nameWidth} {...rest}>
10
+ <Typography color="textSecondary" className="info-row__name">
11
+ {nameFormatter(name)}
12
+ </Typography>
13
+
14
+ {children && (
15
+ <Typography color="textPrimary" component={valueComponent} className="info-row__value">
16
+ {children}
17
+ </Typography>
18
+ )}
19
+ </Container>
20
+ );
21
+
22
+ InfoRow.propTypes = {
23
+ name: PropTypes.any.isRequired,
24
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
25
+ children: PropTypes.any,
26
+ nameFormatter: PropTypes.func,
27
+ valueComponent: PropTypes.string,
28
+ nameWidth: PropTypes.number,
29
+ };
30
+
31
+ InfoRow.defaultProps = {
32
+ children: null,
33
+ nameWidth: 90,
34
+ nameFormatter: name => {
35
+ const resetName = name
36
+ .split(' ')
37
+ .map(x => upperFirst(camelCase(x)))
38
+ .join(' ');
39
+
40
+ return typeof name === 'string' ? resetName : name;
41
+ },
42
+ valueComponent: 'p',
43
+ layout: 'horizontal',
44
+ };
45
+
46
+ const Container = styled.div`
47
+ display: flex;
48
+ flex-direction: ${props => (props.layout === 'vertical' ? 'column' : 'row')};
49
+ justify-content: flex-start;
50
+ align-items: ${props => (props.layout === 'vertical' ? 'flex-start' : 'center')};
51
+ margin-bottom: 16px;
52
+
53
+ .info-row__name {
54
+ width: ${props => props.width}px;
55
+ margin-right: ${props => (props.layout === 'vertical' ? '0' : '8px')};
56
+ margin-bottom: ${props => (props.layout === 'vertical' ? '8px' : '0')};
57
+ text-transform: capitalize;
58
+ }
59
+
60
+ .info-row__value {
61
+ flex: 1;
62
+ overflow: auto;
63
+ word-wrap: break-word;
64
+ font-weight: 500;
65
+ }
66
+
67
+ @media (max-width: ${props => props.theme.breakpoints.values.md}px) {
68
+ flex-direction: column;
69
+ justify-content: flex-start;
70
+ align-items: flex-start;
71
+ .info-row__name {
72
+ font-weight: bold;
73
+ }
74
+
75
+ .info-row__value {
76
+ width: 100%;
77
+ font-size: 12px;
78
+ margin-top: 8px;
79
+ }
80
+ }
81
+ `;
82
+
83
+ export default InfoRow;
@@ -0,0 +1,157 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled from 'styled-components';
4
+ import Button from '@material-ui/core/IconButton';
5
+ import AppBar from '@material-ui/core/AppBar';
6
+ import Toolbar from '@material-ui/core/Toolbar';
7
+ import Box from '@material-ui/core/Box';
8
+ import Typography from '@material-ui/core/Typography';
9
+ import MenuIcon from '@material-ui/icons/Menu';
10
+ import { Link } from 'react-router-dom';
11
+
12
+ import Logo from '../../Logo';
13
+
14
+ const StyledAppBar = styled(AppBar)`
15
+ && {
16
+ z-index: ${props => props.theme.zIndex.drawer + 1};
17
+ background: ${props => props.theme.palette.background.default};
18
+ box-shadow: none;
19
+ top: 0;
20
+ height: auto;
21
+ }
22
+ .header-toolbar {
23
+ background: ${props => props.theme.palette.background.default};
24
+ color: ${props => props.theme.palette.text.primary};
25
+ margin: ${props => props.theme.spacing(1)}px 0;
26
+ }
27
+ .header-link {
28
+ display: flex;
29
+ text-decoration: none;
30
+ flex-shrink: 1;
31
+ overflow: hidden;
32
+ }
33
+ .header-logo {
34
+ margin-right: 20px;
35
+ }
36
+ .header-title {
37
+ display: flex;
38
+ flex-direction: column;
39
+ justify-content: center;
40
+ align-items: flex-start;
41
+ }
42
+ .header-title__primary {
43
+ font-size: 24px;
44
+ font-weight: 800;
45
+ color: ${props => props.theme.typography.color.main};
46
+ text-transform: uppercase;
47
+ display: flex;
48
+ align-items: center;
49
+ }
50
+ .header-title__secondary {
51
+ font-size: 14px;
52
+ line-height: 1.71;
53
+ color: ${props => props.theme.typography.color.gray};
54
+ }
55
+
56
+ .header-addons {
57
+ display: flex;
58
+ justify-content: center;
59
+ align-items: center;
60
+ flex-shrink: 9999999;
61
+
62
+ .user-addon {
63
+ .header-avatar {
64
+ width: 32px;
65
+ border-radius: 16px;
66
+ height: auto;
67
+ }
68
+ }
69
+ }
70
+ .header-menu {
71
+ display: none;
72
+ }
73
+ @media (max-width: ${props => props.theme.breakpoints.values.md}px) {
74
+ /*
75
+ 以下样式用来替代 display:none, 如果为 logo prop 传入一个自定义的 svg, 并且 svg 中的元素通过 id 引用了 defs 中的元素 (比如 linearGradient),
76
+ 这种情况下因为 header 和 sidebar 中会各有一个相同的 svg, defs 中元素的 id 会出现冲突,
77
+ 当屏幕很窄的情况, header 会通过设置 display:none 将 svg logo 隐藏,
78
+ 这会导致 svg defs 中的元素不能被正常引用 (比如 fill 引用的 color 失效), 这会进一步导致 sidebar 中的 logo 不能正常显示
79
+ */
80
+ .header-logo {
81
+ position: absolute;
82
+ width: 0;
83
+ height: 0;
84
+ overflow: hidden;
85
+ }
86
+ .header-title {
87
+ display: none;
88
+ }
89
+ .header-title__primary {
90
+ font-size: 20px;
91
+ }
92
+ .header-menu {
93
+ display: block;
94
+ }
95
+ }
96
+ `;
97
+
98
+ export default function Header({
99
+ children,
100
+ brand,
101
+ brandAddon,
102
+ description,
103
+ addons,
104
+ onToggleMenu,
105
+ homeUrl,
106
+ logo,
107
+ ...rest
108
+ }) {
109
+ return (
110
+ <StyledAppBar position="sticky" className="header" {...rest}>
111
+ <Toolbar disableGutters={false} className="header-toolbar">
112
+ <Button
113
+ color="inherit"
114
+ aria-label="open drawer"
115
+ edge="start"
116
+ className="header-menu"
117
+ onClick={onToggleMenu}>
118
+ <MenuIcon />
119
+ </Button>
120
+ <Link to={homeUrl} className="header-link">
121
+ <div className="header-logo">{logo || <Logo showText={false} />}</div>
122
+ <div className="header-title">
123
+ <Typography component="h2" noWrap className="header-title__primary">
124
+ {brand}
125
+ {brandAddon}
126
+ </Typography>
127
+ <Typography component="p" noWrap className="header-title__secondary">
128
+ {description}
129
+ </Typography>
130
+ </div>
131
+ </Link>
132
+ <Box flexGrow={1} />
133
+ {!!children && <div className="header-children">{children}</div>}
134
+ <div className="header-addons">{addons}</div>
135
+ </Toolbar>
136
+ </StyledAppBar>
137
+ );
138
+ }
139
+
140
+ Header.propTypes = {
141
+ onToggleMenu: PropTypes.func.isRequired,
142
+ brand: PropTypes.string.isRequired,
143
+ brandAddon: PropTypes.object,
144
+ description: PropTypes.string.isRequired,
145
+ children: PropTypes.any,
146
+ addons: PropTypes.any,
147
+ homeUrl: PropTypes.string,
148
+ logo: PropTypes.any,
149
+ };
150
+
151
+ Header.defaultProps = {
152
+ children: null,
153
+ addons: null,
154
+ brandAddon: null,
155
+ homeUrl: '/',
156
+ logo: null,
157
+ };