VideoPreviewBase.styles.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import styled from '@emotion/styled'
  2. import { css, keyframes } from '@emotion/core'
  3. import { breakpoints, colors, spacing } from '@/shared/theme'
  4. import { CoverHoverOverlay, CoverIcon, ProgressOverlay } from './VideoPreview.styles'
  5. export const HOVER_BORDER_SIZE = '2px'
  6. type MainProps = {
  7. main: boolean
  8. }
  9. type ContainerProps = {
  10. clickable: boolean
  11. } & MainProps
  12. type ScalesWithCoverProps = {
  13. scalingFactor: number
  14. }
  15. const fadeIn = keyframes`
  16. 0% {
  17. opacity: 0
  18. }
  19. 100% {
  20. opacity: 1
  21. }
  22. `
  23. export const CoverWrapper = styled.div`
  24. max-width: 650px;
  25. width: 100%;
  26. `
  27. export const CoverContainer = styled.div`
  28. position: relative;
  29. width: 100%;
  30. height: 0;
  31. padding-top: 56.25%;
  32. transition-property: box-shadow, transform;
  33. transition-duration: 0.4s;
  34. transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
  35. animation: ${fadeIn} 0.5s ease-in;
  36. `
  37. const mainContainerCss = css`
  38. @media screen and (min-width: ${breakpoints.medium}) {
  39. flex-direction: row;
  40. }
  41. `
  42. export const Container = styled.article<ContainerProps>`
  43. width: 100%;
  44. color: ${colors.gray[300]};
  45. cursor: ${({ clickable }) => (clickable ? 'pointer' : 'auto')};
  46. display: inline-flex;
  47. flex-direction: column;
  48. ${({ main }) => main && mainContainerCss}
  49. ${({ clickable }) =>
  50. clickable &&
  51. `
  52. &:hover {
  53. ${CoverContainer} {
  54. transform: translate(-${spacing.xs}, -${spacing.xs});
  55. box-shadow: ${spacing.xs} ${spacing.xs} 0 ${colors.blue['500']};
  56. }
  57. ${CoverHoverOverlay} {
  58. opacity: 1;
  59. }
  60. ${CoverIcon} {
  61. transform: translateY(0);
  62. }
  63. ${ProgressOverlay} {
  64. bottom: ${HOVER_BORDER_SIZE};
  65. }
  66. }
  67. `};
  68. `
  69. const mainInfoContainerCss = css`
  70. @media screen and (min-width: ${breakpoints.medium}) {
  71. margin: ${spacing.xxl} 0 0 ${spacing.xl};
  72. }
  73. `
  74. export const InfoContainer = styled.div<MainProps>`
  75. width: 100%;
  76. display: flex;
  77. margin-top: ${({ main }) => (main ? spacing.m : spacing.s)};
  78. ${({ main }) => main && mainInfoContainerCss};
  79. `
  80. export const AvatarContainer = styled.div<ScalesWithCoverProps>`
  81. width: calc(40px * ${(props) => props.scalingFactor});
  82. min-width: calc(40px * ${(props) => props.scalingFactor});
  83. height: calc(40px * ${(props) => props.scalingFactor});
  84. margin-right: ${spacing.xs};
  85. `
  86. export const TextContainer = styled.div`
  87. display: flex;
  88. flex-direction: column;
  89. align-items: start;
  90. width: 100%;
  91. `
  92. export const MetaContainer = styled.div<MainProps>`
  93. margin-top: ${({ main }) => (main ? spacing.s : spacing.xs)};
  94. width: 100%;
  95. `