Layout scaffolding for Web apps.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

138 lignes
2.4 KiB

  1. import * as React from 'react'
  2. import styled from 'styled-components'
  3. import {applyBackgroundColor, minWidthFactor} from '../../utilities/mixins'
  4. import {configVar} from '../../utilities/helpers'
  5. const Base = styled('div')({
  6. position: 'fixed',
  7. top: 0,
  8. left: 0,
  9. width: '100%',
  10. height: 'var(--height-topbar, 4rem)',
  11. zIndex: 2,
  12. ...applyBackgroundColor(),
  13. '~ *': {
  14. paddingTop: 'var(--height-topbar, 4rem)',
  15. },
  16. '~ main ~ *': {
  17. paddingTop: 0,
  18. },
  19. ...minWidthFactor(3)({
  20. '~ main ~ *': {
  21. paddingTop: 'var(--height-topbar, 4rem)',
  22. },
  23. }),
  24. })
  25. const Container = styled('div')({
  26. padding: '0 1rem',
  27. boxSizing: 'border-box',
  28. margin: '0 auto',
  29. maxWidth: `calc(${configVar('base-width')} * 2)`,
  30. width: '100%',
  31. height: '100%',
  32. display: 'flex',
  33. alignItems: 'center',
  34. })
  35. const WideContainer = styled(Container)({
  36. ...minWidthFactor(3)({
  37. maxWidth: `calc(${configVar('base-width')} * 3)`,
  38. }),
  39. })
  40. const BrandContainer = styled('div')({
  41. })
  42. const CenterContainer = styled('div')({
  43. flex: 'auto',
  44. padding: '0 1rem',
  45. boxSizing: 'border-box',
  46. ':first-child': {
  47. paddingLeft: 0,
  48. },
  49. })
  50. const ActionContainer = styled('div')({
  51. display: 'flex',
  52. alignItems: 'center',
  53. justifyContent: 'flex-end',
  54. height: '100%',
  55. whiteSpace: 'nowrap',
  56. ...minWidthFactor(2)({
  57. minWidth: '8rem',
  58. }),
  59. })
  60. const LinkContainer = styled('div')({
  61. width: 'var(--height-topbar, 4rem)',
  62. height: '100%',
  63. '> *': {
  64. width: '100%',
  65. height: '100%',
  66. display: 'inline-grid',
  67. placeContent: 'center',
  68. },
  69. })
  70. const MenuLinkContainer = styled(LinkContainer)({
  71. ...minWidthFactor(3)({
  72. position: 'absolute',
  73. left: -999999,
  74. }),
  75. })
  76. type Props = {
  77. wide?: boolean,
  78. brand?: React.ReactNode,
  79. menuLink?: React.ReactNode,
  80. userLink?: React.ReactNode,
  81. }
  82. const TopBar: React.FC<Props> = ({
  83. wide,
  84. brand,
  85. menuLink,
  86. userLink,
  87. children,
  88. }) => {
  89. const ContainerComponent = wide ? WideContainer : Container
  90. return (
  91. <Base>
  92. <ContainerComponent>
  93. {
  94. Boolean(brand as unknown)
  95. && (
  96. <BrandContainer>
  97. {brand}
  98. </BrandContainer>
  99. )
  100. }
  101. <CenterContainer>
  102. {children}
  103. </CenterContainer>
  104. <ActionContainer>
  105. {
  106. Boolean(menuLink as unknown)
  107. && (
  108. <MenuLinkContainer>
  109. {menuLink}
  110. </MenuLinkContainer>
  111. )
  112. }
  113. {
  114. Boolean(userLink as unknown)
  115. && (
  116. <LinkContainer>
  117. {userLink}
  118. </LinkContainer>
  119. )
  120. }
  121. </ActionContainer>
  122. </ContainerComponent>
  123. </Base>
  124. )
  125. }
  126. export default TopBar