/config/$1"
47 | }
48 | },
49 | "dependencies": {
50 | "@babel/polyfill": "^7.8.3",
51 | "@material-ui/core": "^4.9.3",
52 | "@material-ui/styles": "^4.9.0",
53 | "@zeit/next-typescript": "^1.1.1",
54 | "lodash": "^4.17.15",
55 | "next": "^9.2.2",
56 | "normalize.css": "^8.0.1",
57 | "react": "^16.12.0",
58 | "react-dom": "^16.12.0",
59 | "react-redux": "^7.2.0",
60 | "redux": "^4.0.5",
61 | "redux-actions": "^2.6.5",
62 | "redux-batched-actions": "^0.4.1",
63 | "redux-control": "^0.4.0",
64 | "redux-thunk": "^2.3.0",
65 | "styled-components": "^5.0.1",
66 | "url-parse": "^1.4.7"
67 | },
68 | "devDependencies": {
69 | "@babel/cli": "^7.8.4",
70 | "@babel/core": "^7.8.4",
71 | "@babel/plugin-proposal-class-properties": "^7.8.3",
72 | "@babel/preset-env": "^7.8.4",
73 | "@types/jest": "^25.1.3",
74 | "@types/lodash": "^4.14.149",
75 | "@types/react": "^16.9.22",
76 | "@types/react-redux": "^7.1.7",
77 | "@types/redux-actions": "^2.6.1",
78 | "@types/redux-logger": "^3.0.7",
79 | "@types/styled-components": "^5.0.0",
80 | "@types/styled-jsx": "^2.2.8",
81 | "@types/url-parse": "^1.4.3",
82 | "@typescript-eslint/eslint-plugin": "^2.20.0",
83 | "@typescript-eslint/parser": "^2.20.0",
84 | "babel-eslint": "^10.0.2",
85 | "babel-plugin-styled-components": "^1.10.7",
86 | "eslint": "^6.8.0",
87 | "eslint-config-prettier": "^6.10.0",
88 | "eslint-config-standard": "^14.1.0",
89 | "eslint-plugin-import": "^2.20.1",
90 | "eslint-plugin-node": "^11.0.0",
91 | "eslint-plugin-prettier": "^3.1.2",
92 | "eslint-plugin-promise": "^4.2.1",
93 | "eslint-plugin-react": "^7.18.3",
94 | "eslint-plugin-standard": "^4.0.1",
95 | "file-loader": "^5.1.0",
96 | "imagemin-webpack-plugin": "^2.4.2",
97 | "jest": "^25.1.0",
98 | "next-compose-plugins": "^2.2.0",
99 | "oss-cdn-helper": "^0.1.0",
100 | "prettier": "^1.19.1",
101 | "prettier-eslint": "^9.0.1",
102 | "raw-loader": "^4.0.0",
103 | "redux-logger": "^3.0.6",
104 | "sqip-loader": "^1.0.0",
105 | "stylelint": "^13.2.0",
106 | "stylelint-config-standard": "^20.0.0",
107 | "stylelint-config-styled-components": "^0.1.1",
108 | "stylelint-processor-styled-components": "^1.10.0",
109 | "svg-sprite-loader": "4.1.3",
110 | "svgo": "^1.3.2",
111 | "svgo-loader": "^2.2.1",
112 | "typescript": "^3.8.2",
113 | "url-loader": "^3.0.0"
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/utils/theme.ts:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 | import { css } from 'styled-components'
3 |
4 | import { createMuiTheme } from '@material-ui/core/styles'
5 | import { ThemeOptions } from '@material-ui/core/styles/createMuiTheme'
6 |
7 | const myTypographyFontFamily = {
8 | 100: '"PingFangSC-Ultralight", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;',
9 | 200: '"PingFangSC-Thin", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;',
10 | 300: '"PingFangSC-Light", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;',
11 | 400: '"PingFangSC", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;',
12 | 500: '"PingFangSC-Medium", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;',
13 | 900: '"PingFangSC-Semibold", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;'
14 | }
15 |
16 | const defaultTheme: ThemeOptions = {
17 | palette: {
18 | type: 'light',
19 | primary: {
20 | main: '#58C1B6',
21 | light: '#79D8CE',
22 | contrastText: '#fff'
23 | },
24 | secondary: {
25 | main: '#5a8dbe',
26 | light: '#5cb1b7',
27 | contrastText: '#fff'
28 | },
29 | text: {
30 | primary: '#272E3E',
31 | secondary: '#545A69',
32 | disabled: '#797F8F'
33 | },
34 | error: {
35 | main: '#D94F43'
36 | },
37 | tonalOffset: 0.05,
38 | action: {
39 | active: 'rgba(0, 0, 0, 0.54)',
40 | hover: 'rgba(0, 0, 0, 0.1)',
41 | hoverOpacity: 0.05,
42 | selected: 'rgba(0, 0, 0, 0.14)',
43 | disabled: 'rgba(0, 0, 0, 0.26)',
44 | disabledBackground: 'rgba(0, 0, 0, 0.12)'
45 | }
46 | },
47 | mixins: {
48 | toolbar: {
49 | minHeight: 56,
50 | '@media (min-width:0px) and (orientation: landscape)': {
51 | minHeight: 56
52 | },
53 | '@media (min-width:600px)': {
54 | minHeight: 56
55 | }
56 | }
57 | },
58 | typography: {
59 | fontFamily:
60 | '"PingFangSC", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;',
61 | h1: {
62 | fontSize: '2.375rem', // 38px
63 | lineHeight: 1.3 // 37.33333px
64 | },
65 | h2: {
66 | fontSize: '2.25rem', // 36px
67 | lineHeight: 1.3 // 34.66667px
68 | },
69 | h3: {
70 | fontSize: '1.5rem', // 24px
71 | lineHeight: 1 // 32px
72 | },
73 | h4: {
74 | fontSize: '1.375rem', // 22px
75 | lineHeight: 18 / 11 // 29.3333333px
76 | },
77 | h5: {
78 | fontSize: '1.25rem', // 20px
79 | lineHeight: 1 // 26.666667px
80 | },
81 | h6: {
82 | fontSize: '1.125rem', // 18px
83 | lineHeight: 1.3 // 24px
84 | },
85 | subtitle1: {
86 | fontSize: '1rem',
87 | lineHeight: 12 / 7
88 | },
89 | body2: {
90 | fontSize: '0.875rem', // 14px
91 | fontWeight: 400,
92 | lineHeight: 12 / 7 // 20px
93 | },
94 | button: {
95 | fontSize: '0.875rem',
96 | fontWeight: 500,
97 | fontFamily: myTypographyFontFamily[500],
98 | lineHeight: '1'
99 | }
100 | },
101 | breakpoints: {
102 | values: {
103 | xs: 0,
104 | sm: 600,
105 | md: 960,
106 | lg: 1200,
107 | xl: 1920
108 | }
109 | }
110 | }
111 |
112 | export const getTheme = (newTheme?: ThemeOptions) =>
113 | createMuiTheme(_.merge(defaultTheme, newTheme))
114 |
115 | // https://material-ui.com/customization/default-theme/
116 | const theme = getTheme()
117 |
118 | export const scrollbar = css`
119 | -webkit-overflow-scrolling: touch;
120 |
121 | ::-webkit-scrollbar {
122 | width: 4px;
123 | height: 4px;
124 | }
125 |
126 | ::-webkit-scrollbar-track {
127 | border-radius: 2px;
128 | transition: all 0.3s;
129 | background: rgba(0, 0, 0, 0);
130 | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0);
131 | }
132 |
133 | ::-webkit-scrollbar-thumb {
134 | border-radius: 2px;
135 | transition: all 0.3s;
136 | background: rgba(0, 0, 0, 0);
137 | box-shadow: inset 0 0 10px rgba(0, 0, 0, 0);
138 | }
139 |
140 | &:hover {
141 | ::-webkit-scrollbar-thumb {
142 | background: rgba(0, 0, 0, 0.12);
143 | box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.12);
144 | }
145 | }
146 | `
147 |
148 | export const getMyTypographyFontFamily = (fontWeight: string) => {
149 | const keys = Object.keys(myTypographyFontFamily)
150 | for (const key of keys) {
151 | const parsedKey = parseInt(key, 10)
152 | const parsedFontWeight = parseInt(fontWeight, 10)
153 | if (parsedFontWeight <= parsedKey) {
154 | // @ts-ignore
155 | return myTypographyFontFamily[key]
156 | }
157 | }
158 | return myTypographyFontFamily['400']
159 | }
160 |
161 | export const palettePrimaryMain = () => theme.palette.primary.main
162 | export const palettePrimaryLight = () => theme.palette.primary.light
163 | export const palettePrimaryDark = () => theme.palette.primary.dark
164 |
165 | export const paletteSecondaryMain = () => theme.palette.secondary.main
166 | export const paletteSecondaryLight = () => theme.palette.secondary.light
167 |
168 | export const paletteBackgroundDefault = () => theme.palette.background.default
169 | export const paletteTextPrimary = () => theme.palette.text.primary
170 | export const paletteTextSecondary = () => theme.palette.text.secondary
171 | export const paletteTextDisabled = () => theme.palette.text.disabled
172 | export const paletteErrorMain = () => theme.palette.error.main
173 | export const paletteErrorLight = () => theme.palette.error.light
174 |
175 | export const paletteActionBackgroundColor = () =>
176 | theme.palette.action.disabledBackground
177 | export const paletteDividerColor = () => theme.palette.divider
178 |
179 | export const breakpointsDown = theme.breakpoints.down
180 | export const breakpointsValues = theme.breakpoints.values
181 |
182 | export const transitionsCreate = () => theme.transitions.create
183 |
184 | export const spacingUnit = theme.spacing
185 | export const typographyFontSize = () => theme.typography.fontSize
186 | export const typographyH6FontSize = () => theme.typography.h6.fontSize
187 | export const typographyH6LineHeight = () => theme.typography.h6.lineHeight
188 | export const typographyButtonFontSize = () => theme.typography.button.fontSize
189 | export const typographyBody2LineHeight = () => theme.typography.body2.lineHeight
190 | export const typographyButtonLineHeight = () =>
191 | theme.typography.button.lineHeight
192 | export const shapeBorderRadius = () => theme.shape.borderRadius
193 |
194 | export const not = (...keys: K[]) => (
195 | value: ((props: P) => string) | string
196 | ) => (props: P) => {
197 | for (const key of keys) {
198 | if (props[key]) {
199 | return ''
200 | }
201 | }
202 | return typeof value === 'function' ? value(props) : value
203 | }
204 |
205 | export const check =
(...keys: K[]) => (
206 | value: ((props: P) => string) | string
207 | ) => (props: P) => {
208 | for (const key of keys) {
209 | if (props[key]) {
210 | return typeof value === 'function' ? value(props) : value
211 | }
212 | }
213 | return ''
214 | }
215 |
216 | // TODO: Fix ts-ignore
217 | export const checkBy = (property: string, mapping: {}) => (props: {}) => {
218 | // @ts-ignore
219 | const value = mapping[props[property]]
220 | return typeof value === 'function' ? value(props) : value
221 | }
222 |
223 | export const fp = (props: O, keys: K[]) => {
224 | const { ...newProps } = props
225 |
226 | for (const key of keys) {
227 | delete newProps[key]
228 | }
229 |
230 | return newProps as {
231 | [key in Exclude]: O[key]
232 | }
233 | }
234 |
235 | export const filterProps = fp
236 |
237 | export default theme
238 |
--------------------------------------------------------------------------------