Layout scaffolding for Web apps.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

122 wiersze
2.4 KiB

  1. import * as React from 'react'
  2. import styled, {createGlobalStyle} from 'styled-components';
  3. import TopBar from '../../widgets/TopBar'
  4. import {minWidthFactor} from '../../utilities/mixins';
  5. import {configVar, loadConfig} from '../../utilities/helpers'
  6. const Config = createGlobalStyle({
  7. ...loadConfig(),
  8. })
  9. const ContentBase = styled('main')({
  10. boxSizing: 'border-box',
  11. [minWidthFactor(3)]: {
  12. paddingRight: `calc(50% - ${configVar('base-width')} * 0.5)`,
  13. },
  14. })
  15. const SidebarBase = styled('div')({
  16. boxSizing: 'border-box',
  17. // prevent collapse of margin
  18. '::after': {
  19. content: "''",
  20. display: 'block',
  21. paddingBottom: 1,
  22. marginTop: -1,
  23. boxSizing: 'border-box',
  24. },
  25. '> *': {
  26. display: 'block',
  27. width: '100%',
  28. height: '100%',
  29. backgroundColor: 'white',
  30. },
  31. [minWidthFactor(3)]: {
  32. position: 'absolute',
  33. top: 0,
  34. right: 0,
  35. width: `calc(50% - ${configVar('base-width')} * 0.5)`,
  36. height: '100%',
  37. },
  38. })
  39. const SidebarMainContent = styled('div')({
  40. position: 'relative',
  41. zIndex: 1,
  42. })
  43. export const SidebarMainContainer = styled('div')({
  44. padding: '0 1rem',
  45. boxSizing: 'border-box',
  46. width: '100%',
  47. maxWidth: `calc(${configVar('base-width')} * 2)`,
  48. margin: '0 auto',
  49. [minWidthFactor(3)]: {
  50. width: `${configVar('base-width')}`,
  51. marginLeft: 0,
  52. },
  53. })
  54. export const ContentContainer = styled('div')({
  55. padding: '0 1rem',
  56. boxSizing: 'border-box',
  57. width: '100%',
  58. maxWidth: `calc(${configVar('base-width')} * 2)`,
  59. margin: '0 auto',
  60. [minWidthFactor(3)]: {
  61. marginRight: 0,
  62. },
  63. })
  64. type Props = {
  65. brand?: React.ReactNode,
  66. sidebarMain: React.ReactChild,
  67. userLink?: React.ReactNode,
  68. topBarCenter?: React.ReactChild,
  69. topBarComponent?: React.ElementType,
  70. sidebarMainComponent?: React.ElementType,
  71. }
  72. export const Layout: React.FC<Props> = ({
  73. brand,
  74. sidebarMain,
  75. userLink,
  76. topBarCenter,
  77. children,
  78. topBarComponent: TopBarComponent = 'div',
  79. sidebarMainComponent: SidebarMainComponent = 'div',
  80. }) => {
  81. return (
  82. <>
  83. <Config />
  84. {
  85. (
  86. brand
  87. || userLink
  88. || topBarCenter
  89. )
  90. && (
  91. <TopBar
  92. span="wide"
  93. brand={brand}
  94. userLink={userLink}
  95. baseComponent={TopBarComponent}
  96. >
  97. {topBarCenter}
  98. </TopBar>
  99. )
  100. }
  101. <ContentBase>
  102. {children}
  103. </ContentBase>
  104. <SidebarBase>
  105. <SidebarMainComponent>
  106. <SidebarMainContent>
  107. {sidebarMain}
  108. </SidebarMainContent>
  109. </SidebarMainComponent>
  110. </SidebarBase>
  111. </>
  112. )
  113. }