Guest User

Untitled

a guest
Jan 23rd, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.20 KB | None | 0 0
  1. import React, {
  2. createContext,
  3. // $FlowFixMe
  4. useReducer,
  5. } from 'react'
  6. import { ThemeProvider, createGlobalStyle } from 'styled-components'
  7. import { type, path, compose } from 'ramda'
  8. import type { Element } from 'react'
  9.  
  10. // --------- For Styles --------------//
  11. // ----------------------------------//
  12. const themeTypes = {
  13. LIGHT: 'THEME_LIGHT',
  14. DARK: 'THEME_DARK',
  15. }
  16.  
  17. // Construct theme
  18. type Theme = {
  19. elements: {
  20. appWrapper: string,
  21. text: string,
  22. },
  23. colors: Object,
  24. mixins: Object,
  25. }
  26. const colors = {
  27. black: '#191818',
  28. white: '#ffffff',
  29. }
  30. const mixins = {
  31. /** Define here the mixins... */
  32. }
  33.  
  34. // All the themes
  35. const themes = {
  36. [themeTypes.DARK]: {
  37. appWrapper: colors.black,
  38. text: colors.white,
  39. },
  40. [themeTypes.LIGHT]: {
  41. appWrapper: '#fbfbfb',
  42. text: colors.black,
  43. },
  44. }
  45.  
  46. function getTheme(themeType: string, addedColors?: Object): Theme {
  47. return {
  48. elements: themes[themeType],
  49. colors: {
  50. ...colors, // Add the default colors.
  51. ...addedColors, // Merge the added colors.
  52. },
  53. mixins,
  54. }
  55. }
  56.  
  57. // App theme Reducer - use for switching the theme.
  58. type Action = {
  59. type: string,
  60. }
  61. const initAppTheme = {
  62. elements: themes[themeTypes.DARK],
  63. colors,
  64. mixins,
  65. }
  66. function appThemeReducer(state: Theme, action: Action): Theme {
  67. const { type } = action
  68. switch (type) {
  69. case themeTypes.LIGHT: {
  70. const addedColors = {
  71. accent: '#d23669',
  72. }
  73. return getTheme(themeTypes.LIGHT, addedColors)
  74. }
  75. default: {
  76. const addedColors = {
  77. accent: '#ffa7c4',
  78. }
  79. return getTheme(themeTypes.DARK, addedColors)
  80. }
  81. }
  82. }
  83.  
  84. const AppThemeContext = createContext()
  85.  
  86. function AppThemeProvider({ children }: { children: Element<any> }) {
  87. const [theme, dispatch] = useReducer(appThemeReducer, initAppTheme)
  88. return (
  89. <AppThemeContext.Provider value={dispatch}>
  90. <ThemeProvider theme={theme}>{children}</ThemeProvider>
  91. </AppThemeContext.Provider>
  92. )
  93. }
  94.  
  95. // Add global styles.
  96. const GlobalStyle = createGlobalStyle`
  97. body {
  98. margin: 0;
  99. padding: 0;
  100. }
  101. body, h1,h2,h3,h4,h5,h6,p,span,div {
  102. font-family: sans-serif;
  103. }
  104. `
  105.  
  106. // Style helpers.
  107. // Creating css attribute with specified attr and value.
  108. const createAttr = attr => value => `${attr}: ${value}`
  109.  
  110. /**
  111. * getStyle :: (Array | String, String?) => Object => String
  112. *
  113. * A function for getting the value from the theme prop based on the keys. Keys could
  114. * either be String or Array. Attribute is optional. If given, we gonna create
  115. * css attribute with value.
  116. */
  117. function getStyle(keys: Array<string> | string, attr?: string) {
  118. return function getProps({ theme }: { theme: Theme }) {
  119. // If there is specificed attr.
  120. if (attr) {
  121. const addAttr = createAttr(attr)
  122. // Handle if the keys is string
  123. if (type(keys) === 'String') {
  124. return addAttr(theme[keys])
  125. }
  126. // Handle if the keys is array.
  127. return compose(
  128. addAttr,
  129. path(keys),
  130. )(theme)
  131. }
  132. // Handle if no attr.
  133. if (type(keys) === 'String') {
  134. return theme[keys]
  135. }
  136. // Handle if the keys is array.
  137. return path(keys, theme)
  138. }
  139. }
  140.  
  141. export {
  142. AppThemeProvider as default,
  143. AppThemeContext,
  144. GlobalStyle,
  145. themeTypes,
  146. getStyle,
  147. }
Add Comment
Please, Sign In to add comment