Zeichen's app for both server and client.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

113 rivejä
2.1 KiB

  1. import * as React from 'react'
  2. import * as PropTypes from 'prop-types'
  3. import Link from 'next/link'
  4. import styled from 'styled-components'
  5. import Icon from '../Icon/Icon'
  6. const Base = styled('div')({
  7. width: 0,
  8. height: '4rem',
  9. flex: 'auto',
  10. padding: '0.25rem',
  11. boxSizing: 'border-box',
  12. position: 'relative',
  13. '@media (min-width: 1080px)': {
  14. width: '4rem',
  15. height: '4rem',
  16. },
  17. })
  18. const ClickArea = styled('a')({
  19. display: 'grid',
  20. color: 'inherit',
  21. placeContent: 'center',
  22. width: '100%',
  23. height: '100%',
  24. position: 'absolute',
  25. top: 0,
  26. left: 0,
  27. textDecoration: 'none',
  28. })
  29. const ClickAreaContent = styled('span')({
  30. display: 'block',
  31. textAlign: 'center',
  32. lineHeight: 1,
  33. })
  34. const Highlight = styled('div')({
  35. width: '100%',
  36. height: '100%',
  37. backgroundColor: 'var(--color-primary)',
  38. opacity: 0.5,
  39. borderRadius: '0.25rem',
  40. [`+ ${ClickArea}`]: {
  41. opacity: 0.75,
  42. },
  43. })
  44. const Title = styled('small')({
  45. display: 'block',
  46. fontWeight: 'bolder',
  47. position: 'absolute',
  48. left: -999999,
  49. })
  50. const MobileBase = styled(Base)({
  51. '@media (min-width: 1080px)': {
  52. display: 'none',
  53. },
  54. })
  55. const propTypes = {
  56. href: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired,
  57. iconName: PropTypes.string.isRequired,
  58. title: PropTypes.string,
  59. mobileOnly: PropTypes.bool,
  60. active: PropTypes.bool,
  61. }
  62. type Props = PropTypes.InferProps<typeof propTypes>
  63. const PrimaryNavItem: React.FC<Props> = ({
  64. href,
  65. iconName,
  66. title,
  67. mobileOnly = false,
  68. active = false,
  69. }) => {
  70. const BaseComponent = mobileOnly ? MobileBase : Base
  71. return (
  72. <BaseComponent>
  73. {
  74. active
  75. && (
  76. <Highlight />
  77. )
  78. }
  79. <Link
  80. href={href}
  81. passHref
  82. shallow
  83. >
  84. <ClickArea
  85. title={title}
  86. >
  87. <ClickAreaContent>
  88. <Icon
  89. name={iconName}
  90. />
  91. <Title>
  92. {title}
  93. </Title>
  94. </ClickAreaContent>
  95. </ClickArea>
  96. </Link>
  97. </BaseComponent>
  98. )
  99. }
  100. PrimaryNavItem.propTypes = propTypes
  101. export default PrimaryNavItem