UNPKG

3.91 kBJavaScriptView Raw
1import React from 'react'
2import styled, { withTheme } from 'styled-components'
3
4import {
5 P,
6 FlexRow,
7 FlexCol,
8 Chevron
9} from 'SRC'
10
11import defaultProps from './defaultProps.js'
12import { CSSTransitionGroup } from 'react-transition-group'
13
14class BaseTextCarousel extends React.Component {
15 constructor (props) {
16 super(props)
17 this.state = {
18 index: 0
19 }
20 }
21
22 onClickChevronLeft = () => {
23 const { quotes } = this.props
24 const { index } = this.state
25 if (index === 0) {
26 this.setState({index: (quotes.length - 1) })
27 clearInterval(this.timer)
28 this.quoteTimer((quotes.length - 1))
29 } else {
30 this.setState({index: index - 1 })
31 clearInterval(this.timer)
32 this.quoteTimer()
33 }
34 }
35
36 onClickChevronRight = () => {
37 const { index } = this.state
38 const { quotes } = this.props
39
40 if (index === (quotes.length - 1)) {
41 this.setState({index: 0})
42 clearInterval(this.timer)
43 this.quoteTimer()
44 } else {
45 this.setState({index: index + 1})
46 clearInterval(this.timer)
47 this.quoteTimer()
48 }
49 }
50
51 updateIndex = () => {
52 const { quotes } = this.props
53 const { index } = this.state
54
55 if (index === quotes.length - 1) {
56 this.setState({index: 0})
57 } else {
58 this.setState({index: index + 1})
59 }
60 }
61
62 quoteTimer = () => {
63 this.timer = setInterval(this.updateIndex, 5000)
64 }
65
66 componentWillUnmount () {
67 clearInterval(this.timer)
68 }
69
70 componentWillMount () {
71 this.setState({index: 0})
72 this.quoteTimer()
73 }
74
75 render () {
76 const { className, quotes } = this.props
77
78 const { index } = this.state
79 return (
80 <FlexRow
81 constrained
82 element='section'
83 className={className}>
84 <FlexCol
85 className="quote_controller"
86 mobile={{width: 4}}
87 desktop={{span: 1, width: 10}}>
88 <Chevron left onClick={this.onClickChevronLeft} />
89 <CSSTransitionGroup
90 aria-hidden
91 transitionName="quote"
92 transitionEnterTimeout={500}
93 transitionLeaveTimeout={1}>
94 <P key={index}>{quotes[index].quote}</P>
95 </CSSTransitionGroup>
96 <Chevron right onClick={this.onClickChevronRight} />
97 </FlexCol>
98 </FlexRow>
99 )
100 }
101}
102
103const TextCarousel = styled(BaseTextCarousel)`
104 ${props => props.theme.media.tablet`
105 margin-top: 6rem;
106 `}
107 ${P} {
108 text-align: center;
109 margin: 0 0 1rem 0;
110 }
111 ${P} {
112 color: ${props => props.theme.colors.navy};
113 display: flex;
114 justify-content: center;
115 align-items: center;
116 height: 100%;
117 margin-top: 0;
118 margin-bottom: 0;
119 min-height: 12rem;
120 max-height: 45rem;
121 font-style: italic;
122 font-weight: normal;
123 letter-spacing: normal;
124 font-stretch: normal;
125 font-size: ${props => props.fontSizes.mobile};
126 ${props => props.theme.breakpointsVerbose.aboveTablet`
127 font-size: ${props => props.fontSizes.desktop};
128 `}
129 }
130 ${Chevron} {
131 flex-basis: 2.4rem;
132 min-width: 2.4rem;
133 height: 2.4rem;
134 stroke-width: .7rem;
135 }
136 .quote_controller {
137 display: flex;
138 justify-content: space-between;
139 align-items: center;
140 min-height: 14rem;
141 max-height: 45rem;
142 position: relative
143 width: 100%;
144 }
145 .quote_controller span {
146 display: flex;
147 justify-content: space-between;
148 align-items: center;
149 min-height: 12rem;
150 max-height: 45rem;
151 }
152 .quote-enter {
153 opacity: 0.01;
154 }
155 .quote-enter.quote-enter-active {
156 opacity: 1;
157 transition: opacity 500ms ease-in;
158 }
159 .quote-leave {
160 opacity: 0;
161 }
162 .quote-leave.quote-leave-active {
163 opacity: 0;
164 }
165`
166
167TextCarousel.defaultProps = {
168 ...defaultProps,
169 fontSizes: {
170 desktop: '2.0rem',
171 mobile: '1.6rem'
172 },
173 padding: true,
174 constrained: true
175}
176
177/** @component */
178export default withTheme(TextCarousel)