1 | import React from 'react'
|
2 | import styled, { withTheme } from 'styled-components'
|
3 |
|
4 | import {
|
5 | H1,
|
6 | H2,
|
7 | FlexRow,
|
8 | FlexCol,
|
9 | Chevron
|
10 | } from 'SRC'
|
11 |
|
12 | import PressIcon from 'SRC/core/icons/press/PressIcon'
|
13 | import IconRow from './IconRow'
|
14 | import defaultProps from './defaultProps.js'
|
15 |
|
16 | import MediaQuery from 'react-responsive';
|
17 | import { CSSTransitionGroup } from 'react-transition-group'
|
18 |
|
19 | class BasePressQuotes extends React.Component {
|
20 | constructor (props) {
|
21 | super(props)
|
22 | this.state = {
|
23 | index: 0
|
24 | }
|
25 | }
|
26 |
|
27 | onClick = (index) => {
|
28 | return (() => {
|
29 | this.setState({index: index})
|
30 | clearInterval(this.timer)
|
31 | this.quoteTimer()
|
32 | })
|
33 | }
|
34 |
|
35 | onClickChevronLeft = () => {
|
36 | const { quotes } = this.props
|
37 | const { index } = this.state
|
38 | if (index === 0) {
|
39 | this.setState({index: (quotes.length - 1) })
|
40 | clearInterval(this.timer)
|
41 | this.quoteTimer((quotes.length - 1))
|
42 | } else {
|
43 | this.setState({index: index - 1 })
|
44 | clearInterval(this.timer)
|
45 | this.quoteTimer()
|
46 | }
|
47 | }
|
48 |
|
49 | onClickChevronRight = () => {
|
50 | const { index } = this.state
|
51 | const { quotes } = this.props
|
52 |
|
53 | if (index === (quotes.length - 1)) {
|
54 | this.setState({index: 0})
|
55 | clearInterval(this.timer)
|
56 | this.quoteTimer()
|
57 | } else {
|
58 | this.setState({index: index + 1})
|
59 | clearInterval(this.timer)
|
60 | this.quoteTimer()
|
61 | }
|
62 | }
|
63 |
|
64 | updateIndex = () => {
|
65 | const { quotes } = this.props
|
66 | const { index } = this.state
|
67 |
|
68 | if (index === quotes.length - 1) {
|
69 | this.setState({index: 0})
|
70 | } else {
|
71 | this.setState({index: index + 1})
|
72 | }
|
73 | }
|
74 |
|
75 | quoteTimer = () => {
|
76 | this.timer = setInterval(this.updateIndex, 5000)
|
77 | }
|
78 |
|
79 | componentWillUnmount () {
|
80 | clearInterval(this.timer)
|
81 | }
|
82 |
|
83 | componentWillMount () {
|
84 | this.setState({index: 0})
|
85 | this.quoteTimer()
|
86 | }
|
87 |
|
88 | render () {
|
89 | const { className, header, headerLabel, theme, quotes} = this.props
|
90 | const { index } = this.state
|
91 | return (
|
92 | <FlexRow
|
93 | constrained
|
94 | element='section'
|
95 | className={className}>
|
96 | <FlexCol mobile={{width: 4}} desktop={{width: 12}}>
|
97 | <H1 aria-label={headerLabel}>{header}</H1>
|
98 | </FlexCol>
|
99 | <FlexCol
|
100 | className="quote_controller"
|
101 | mobile={{width: 4}}
|
102 | desktop={{span: 1, width: 10}}>
|
103 | <Chevron left onClick={this.onClickChevronLeft} />
|
104 | <CSSTransitionGroup
|
105 | aria-hidden
|
106 | transitionName="quote"
|
107 | transitionEnterTimeout={500}
|
108 | transitionLeaveTimeout={1}>
|
109 | <H2 lowercase key={index}>{quotes[index].quote}</H2>
|
110 | </CSSTransitionGroup>
|
111 | <Chevron right onClick={this.onClickChevronRight} />
|
112 | </FlexCol>
|
113 | <FlexCol mobile={{width: 4}} desktop={{span: 1, width: 10}}>
|
114 | <MediaQuery query={theme.breakpoints.aboveTabletMax}>
|
115 | <IconRow
|
116 | quotes={quotes}
|
117 | onClick={this.onClick}
|
118 | selected={index} />
|
119 | </MediaQuery>
|
120 | </FlexCol>
|
121 | <FlexCol mobile={{width: 4}} desktop={{span: 1, width: 10}}>
|
122 | <MediaQuery query="(max-device-width: 959px)">
|
123 | <PressIcon
|
124 | key={index}
|
125 | brand={quotes[index].id}
|
126 | selected={true} />
|
127 | </MediaQuery>
|
128 | </FlexCol>
|
129 | {quotes.map(({quote, name}, index) => {
|
130 | return (
|
131 | <blockquote key={index}>
|
132 | {quote}
|
133 | <cite>{name}</cite>
|
134 | </blockquote>
|
135 | )
|
136 | })}
|
137 | </FlexRow>
|
138 | )
|
139 | }
|
140 | }
|
141 |
|
142 | const PressQuotes = styled(BasePressQuotes)`
|
143 | margin-top: 4rem;
|
144 | margin-bottom: 2rem;
|
145 | ${props => props.theme.media.tablet`
|
146 | margin-top: 6rem;
|
147 | `}
|
148 | ${H1}, ${H2} {
|
149 | text-align: center;
|
150 | margin: 0 0 1rem 0;
|
151 | }
|
152 | ${H1} {
|
153 | @media (max-width: 958px) { font-size: 3.4rem; }
|
154 | }
|
155 | ${H2} {
|
156 | color: ${props => props.theme.colors.rocketBlue};
|
157 | display: flex;
|
158 | justify-content: center;
|
159 | align-items: center;
|
160 | height: 100%;
|
161 | margin-top: 0;
|
162 | margin-bottom: 0;
|
163 | min-height: 12rem;
|
164 | max-height: 45rem;
|
165 | font-style: italic;
|
166 | }
|
167 | ${Chevron} {
|
168 | flex-basis: 2.4rem;
|
169 | min-width: 2.4rem;
|
170 | height: 2.4rem;
|
171 | stroke-width: .7rem;
|
172 | }
|
173 | ${PressIcon} {
|
174 | max-height: 4.5rem;
|
175 | box-sizing: border-box;
|
176 | &: hover {
|
177 | fill: ${props => props.theme.colors.rocketBlue};
|
178 | }
|
179 | }
|
180 | .quote_controller {
|
181 | display: flex;
|
182 | justify-content: space-between;
|
183 | align-items: center;
|
184 | min-height: 14rem;
|
185 | max-height: 45rem;
|
186 | position: relative
|
187 | width: 100%;
|
188 | }
|
189 | .press_icons {
|
190 | display: flex;
|
191 | flex-wrap: wrap;
|
192 | max-height: 12rem;
|
193 | justify-content: center;
|
194 | @media (max-width: 958px) { margin-top: 0.5em; }
|
195 | > * {
|
196 | width: 30rem;
|
197 | @media (min-width: 959px) { width: 25%; }
|
198 | }
|
199 | }
|
200 | .quote_controller span {
|
201 | display: flex;
|
202 | justify-content: space-between;
|
203 | align-items: center;
|
204 | min-height: 12rem;
|
205 | max-height: 45rem;
|
206 | }
|
207 | .quote-enter {
|
208 | opacity: 0.01;
|
209 | }
|
210 | .quote-enter.quote-enter-active {
|
211 | opacity: 1;
|
212 | transition: opacity 500ms ease-in;
|
213 | }
|
214 | .quote-leave {
|
215 | opacity: 0;
|
216 | }
|
217 | .quote-leave.quote-leave-active {
|
218 | opacity: 0;
|
219 | }
|
220 | blockquote {
|
221 | border: 0;
|
222 | clip: rect(0 0 0 0);
|
223 | height: 1px;
|
224 | margin: -1px;
|
225 | overflow: hidden;
|
226 | padding: 0;
|
227 | position: absolute;
|
228 | width: 1px;
|
229 | }
|
230 | `
|
231 |
|
232 | PressQuotes.defaultProps = {
|
233 | ...defaultProps,
|
234 | padding: true,
|
235 | constrained: true
|
236 | }
|
237 |
|
238 |
|
239 | export default withTheme(PressQuotes)
|