mirror of
https://github.com/hazemKrimi/react-weather-app.git
synced 2026-05-01 18:30:25 +00:00
Replace framer motion with elastic carousel for animation
This commit is contained in:
+1
-1
@@ -8,9 +8,9 @@
|
||||
"@types/react-dom": "^16.9.0",
|
||||
"@types/react-router-dom": "^5.1.6",
|
||||
"@types/styled-components": "^5.1.4",
|
||||
"framer-motion": "^2.9.1",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.14.0",
|
||||
"react-elastic-carousel": "^0.11.5",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "3.4.3",
|
||||
"styled-components": "^5.2.0",
|
||||
|
||||
@@ -9,7 +9,7 @@ export const Wrapper = styled.div`
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
width: 200px;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0rem;
|
||||
word-wrap: break-word;
|
||||
|
||||
+58
-87
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
// @ts-ignore
|
||||
import Carousel, { consts } from 'react-elastic-carousel';
|
||||
import { Wrapper } from './styles';
|
||||
import { Weather, WeatherResponse } from '../../types/weather';
|
||||
import { Forecast, ForecastResponse } from '../../types/forecast';
|
||||
@@ -13,8 +14,36 @@ const Home: React.FC = () => {
|
||||
const [forecast, setForecast] = useState<Forecast | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string>('');
|
||||
const [dailyForecastGrid, setDailyForecastGrid] = useState<number>(0);
|
||||
const [hourlyForecastGrid, setHourlyForecastGrid] = useState<number>(0);
|
||||
|
||||
const carouselSettings = {
|
||||
pagination: false,
|
||||
itemsToShow: 1,
|
||||
enableSwipe: true,
|
||||
isRTL: false,
|
||||
disableArrowsOnEnd: true,
|
||||
enableTilt: false,
|
||||
renderArrow: ({
|
||||
type,
|
||||
onClick,
|
||||
isEdge
|
||||
}: {
|
||||
type: string;
|
||||
onClick: () => void;
|
||||
isEdge: boolean;
|
||||
}) => (
|
||||
<>
|
||||
{type !== consts.PREV ? (
|
||||
<button onClick={onClick} disabled={isEdge} type='button' className='carousel-arrow'>
|
||||
<img src={RightArrow} alt='Left slider arrow' />
|
||||
</button>
|
||||
) : (
|
||||
<button onClick={onClick} disabled={isEdge} type='button' className='carousel-arrow'>
|
||||
<img src={LeftArrow} alt='Right slider arrow' />
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!navigator.geolocation)
|
||||
@@ -82,93 +111,35 @@ const Home: React.FC = () => {
|
||||
</div>
|
||||
<div className='daily-forecast'>
|
||||
<h2>Daily Forecast</h2>
|
||||
<div className='slider'>
|
||||
<motion.img
|
||||
src={LeftArrow}
|
||||
alt='Left slider arrow'
|
||||
onTap={() => {
|
||||
if (dailyForecastGrid <= forecast.daily.length / 2 - 1)
|
||||
setDailyForecastGrid(dailyForecastGrid + 1);
|
||||
}}
|
||||
onMouseDown={() => {
|
||||
if (dailyForecastGrid <= forecast.daily.length / 2 - 1)
|
||||
setDailyForecastGrid(dailyForecastGrid + 1);
|
||||
}}
|
||||
/>
|
||||
<div className='slider-background'>
|
||||
<motion.div
|
||||
initial={false}
|
||||
animate={{ transform: `translateX(${dailyForecastGrid * 10}rem)` }}
|
||||
transition={{ duration: 0.25 }}
|
||||
className='forecast-grid'
|
||||
>
|
||||
{forecast.daily.map(day => (
|
||||
<Card
|
||||
key={day.dt}
|
||||
date={new Date(day.dt * 1000)}
|
||||
time={false}
|
||||
data={day.temp.min + '°C/' + day.temp.max + '°C'}
|
||||
temp={day.temp.max > 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null}
|
||||
icon={day.weather[0].id}
|
||||
description={day.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
<motion.img
|
||||
src={RightArrow}
|
||||
alt='Right slider arrow'
|
||||
onTap={() => {
|
||||
if (dailyForecastGrid >= -forecast.daily.length / 2 + 1)
|
||||
setDailyForecastGrid(dailyForecastGrid - 1);
|
||||
}}
|
||||
onMouseDown={() => {
|
||||
if (dailyForecastGrid >= -forecast.daily.length / 2 + 1)
|
||||
setDailyForecastGrid(dailyForecastGrid - 1);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Carousel {...carouselSettings}>
|
||||
{forecast.daily.map(day => (
|
||||
<Card
|
||||
key={day.dt}
|
||||
date={new Date(day.dt * 1000)}
|
||||
time={false}
|
||||
data={day.temp.min + '°C/' + day.temp.max + '°C'}
|
||||
temp={day.temp.max > 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null}
|
||||
icon={day.weather[0].id}
|
||||
description={day.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
<div className='hourly-forecast'>
|
||||
<h2>Hourly Forecast</h2>
|
||||
<div className='slider'>
|
||||
<motion.img
|
||||
src={LeftArrow}
|
||||
alt='Left slider arrow'
|
||||
onTap={() => {
|
||||
if (hourlyForecastGrid <= forecast.hourly.length / 2 - 1)
|
||||
setHourlyForecastGrid(hourlyForecastGrid + 1);
|
||||
}}
|
||||
/>
|
||||
<div className='slider-background'>
|
||||
<motion.div
|
||||
initial={false}
|
||||
animate={{ transform: `translateX(${hourlyForecastGrid * 10}rem)` }}
|
||||
transition={{ duration: 0.25 }}
|
||||
className='forecast-grid'
|
||||
>
|
||||
{forecast.hourly.map(hour => (
|
||||
<Card
|
||||
key={hour.dt}
|
||||
date={new Date(hour.dt * 1000)}
|
||||
time={true}
|
||||
data={hour.temp + '°C'}
|
||||
temp={hour.temp > 25 ? 'hot' : hour.temp < 20 ? 'cold' : null}
|
||||
icon={hour.weather[0].id}
|
||||
description={hour.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
<motion.img
|
||||
src={RightArrow}
|
||||
alt='Right slider arrow'
|
||||
onTap={() => {
|
||||
if (hourlyForecastGrid >= -forecast.hourly.length / 2 + 1)
|
||||
setHourlyForecastGrid(hourlyForecastGrid - 1);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Carousel {...carouselSettings}>
|
||||
{forecast.hourly.map(hour => (
|
||||
<Card
|
||||
key={hour.dt}
|
||||
date={new Date(hour.dt * 1000)}
|
||||
time={true}
|
||||
data={hour.temp + '°C'}
|
||||
temp={hour.temp > 25 ? 'hot' : hour.temp < 20 ? 'cold' : null}
|
||||
icon={hour.weather[0].id}
|
||||
description={hour.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
<div className='wind'>
|
||||
<h2>Wind</h2>
|
||||
|
||||
@@ -17,32 +17,19 @@ export const Wrapper = styled.div`
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.slider {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.slider-background {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.carousel-arrow {
|
||||
background: none;
|
||||
border: none;
|
||||
align-self: center;
|
||||
cursor: pointer;
|
||||
padding: 0 !important;
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.forecast-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, 10rem);
|
||||
grid-auto-flow: column;
|
||||
column-gap: 2rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.error {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
|
||||
+58
-79
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
// @ts-ignore
|
||||
import Carousel, { consts } from 'react-elastic-carousel';
|
||||
import { Wrapper } from './styles';
|
||||
import { Weather, WeatherSearchResponse } from '../../types/weather';
|
||||
import { Forecast, ForecastResponse } from '../../types/forecast';
|
||||
@@ -15,8 +16,36 @@ const Search: React.FC = () => {
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string>('');
|
||||
const { query } = useParams<{ query: string }>();
|
||||
const [dailyForecastGrid, setDailyForecastGrid] = useState<number>(0);
|
||||
const [hourlyForecastGrid, setHourlyForecastGrid] = useState<number>(0);
|
||||
|
||||
const carouselSettings = {
|
||||
pagination: false,
|
||||
itemsToShow: 1,
|
||||
enableSwipe: true,
|
||||
isRTL: false,
|
||||
disableArrowsOnEnd: true,
|
||||
enableTilt: false,
|
||||
renderArrow: ({
|
||||
type,
|
||||
onClick,
|
||||
isEdge
|
||||
}: {
|
||||
type: string;
|
||||
onClick: () => void;
|
||||
isEdge: boolean;
|
||||
}) => (
|
||||
<>
|
||||
{type !== consts.PREV ? (
|
||||
<button onClick={onClick} disabled={isEdge} type='button' className='carousel-arrow'>
|
||||
<img src={RightArrow} alt='Left slider arrow' />
|
||||
</button>
|
||||
) : (
|
||||
<button onClick={onClick} disabled={isEdge} type='button' className='carousel-arrow'>
|
||||
<img src={LeftArrow} alt='Right slider arrow' />
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
@@ -75,85 +104,35 @@ const Search: React.FC = () => {
|
||||
</div>
|
||||
<div className='daily-forecast'>
|
||||
<h2>Daily Forecast</h2>
|
||||
<div className='slider'>
|
||||
<motion.img
|
||||
src={LeftArrow}
|
||||
alt='Left slider arrow'
|
||||
onTap={() => {
|
||||
if (dailyForecastGrid <= forecast.daily.length / 2 - 1)
|
||||
setDailyForecastGrid(dailyForecastGrid + 1);
|
||||
}}
|
||||
/>
|
||||
<div className='slider-background'>
|
||||
<motion.div
|
||||
initial={false}
|
||||
animate={{ transform: `translateX(${dailyForecastGrid * 10}rem)` }}
|
||||
transition={{ duration: 0.25 }}
|
||||
className='forecast-grid'
|
||||
>
|
||||
{forecast.daily.map(day => (
|
||||
<Card
|
||||
key={day.dt}
|
||||
date={new Date(day.dt * 1000)}
|
||||
time={false}
|
||||
data={day.temp.min + '°C/' + day.temp.max + '°C'}
|
||||
temp={day.temp.max > 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null}
|
||||
icon={day.weather[0].id}
|
||||
description={day.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
<motion.img
|
||||
src={RightArrow}
|
||||
alt='Right slider arrow'
|
||||
onTap={() => {
|
||||
if (dailyForecastGrid >= -forecast.daily.length / 2 + 1)
|
||||
setDailyForecastGrid(dailyForecastGrid - 1);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Carousel {...carouselSettings}>
|
||||
{forecast.daily.map(day => (
|
||||
<Card
|
||||
key={day.dt}
|
||||
date={new Date(day.dt * 1000)}
|
||||
time={false}
|
||||
data={day.temp.min + '°C/' + day.temp.max + '°C'}
|
||||
temp={day.temp.max > 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null}
|
||||
icon={day.weather[0].id}
|
||||
description={day.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
<div className='hourly-forecast'>
|
||||
<h2>Hourly Forecast</h2>
|
||||
<div className='slider'>
|
||||
<motion.img
|
||||
src={LeftArrow}
|
||||
alt='Left slider arrow'
|
||||
onTap={() => {
|
||||
if (hourlyForecastGrid <= forecast.hourly.length / 2 - 1)
|
||||
setHourlyForecastGrid(hourlyForecastGrid + 1);
|
||||
}}
|
||||
/>
|
||||
<div className='slider-background'>
|
||||
<motion.div
|
||||
initial={false}
|
||||
animate={{ transform: `translateX(${hourlyForecastGrid * 10}rem)` }}
|
||||
transition={{ duration: 0.25 }}
|
||||
className='forecast-grid'
|
||||
>
|
||||
{forecast.hourly.map(hour => (
|
||||
<Card
|
||||
key={hour.dt}
|
||||
date={new Date(hour.dt * 1000)}
|
||||
time={true}
|
||||
data={hour.temp + '°C'}
|
||||
temp={hour.temp > 25 ? 'hot' : hour.temp < 20 ? 'cold' : null}
|
||||
icon={hour.weather[0].id}
|
||||
description={hour.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
<motion.img
|
||||
src={RightArrow}
|
||||
alt='Right slider arrow'
|
||||
onTap={() => {
|
||||
if (hourlyForecastGrid >= -forecast.hourly.length / 2 + 1)
|
||||
setHourlyForecastGrid(hourlyForecastGrid - 1);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Carousel {...carouselSettings}>
|
||||
{forecast.hourly.map(hour => (
|
||||
<Card
|
||||
key={hour.dt}
|
||||
date={new Date(hour.dt * 1000)}
|
||||
time={true}
|
||||
data={hour.temp + '°C'}
|
||||
temp={hour.temp > 25 ? 'hot' : hour.temp < 20 ? 'cold' : null}
|
||||
icon={hour.weather[0].id}
|
||||
description={hour.weather[0].description}
|
||||
/>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
<div className='wind'>
|
||||
<h2>Wind</h2>
|
||||
|
||||
@@ -17,32 +17,19 @@ export const Wrapper = styled.div`
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.slider {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.slider-background {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.carousel-arrow {
|
||||
background: none;
|
||||
border: none;
|
||||
align-self: center;
|
||||
cursor: pointer;
|
||||
padding: 0 !important;
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.forecast-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, 10rem);
|
||||
grid-auto-flow: column;
|
||||
column-gap: 2rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.error {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
|
||||
@@ -1100,7 +1100,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
||||
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
||||
|
||||
"@emotion/is-prop-valid@^0.8.2", "@emotion/is-prop-valid@^0.8.8":
|
||||
"@emotion/is-prop-valid@^0.8.8":
|
||||
version "0.8.8"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||
@@ -2880,6 +2880,11 @@ class-utils@^0.3.5:
|
||||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
classnames@^2.2.6:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||
|
||||
clean-css@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
|
||||
@@ -4671,26 +4676,6 @@ fragment-cache@^0.2.1:
|
||||
dependencies:
|
||||
map-cache "^0.2.2"
|
||||
|
||||
framer-motion@^2.9.1:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-2.9.1.tgz#86713730e9503922eedcf5e1bb91a5acc30076f5"
|
||||
integrity sha512-NjEF5u1FkCTS+zRsDWOPPCxWBUWk255WXy4d1FDCC3j6ETJzDXx0V/NUPvwhzyATHbahfX5JdsHWdRe1whNHJg==
|
||||
dependencies:
|
||||
framesync "^4.1.0"
|
||||
hey-listen "^1.0.8"
|
||||
popmotion "9.0.0-rc.20"
|
||||
style-value-types "^3.1.9"
|
||||
tslib "^1.10.0"
|
||||
optionalDependencies:
|
||||
"@emotion/is-prop-valid" "^0.8.2"
|
||||
|
||||
framesync@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.1.0.tgz#69a8db3ca432dc70d6a76ba882684a1497ef068a"
|
||||
integrity sha512-MmgZ4wCoeVxNbx2xp5hN/zPDCbLSKiDt4BbbslK7j/pM2lg5S0vhTNv1v8BCVb99JPIo6hXBFdwzU7Q4qcAaoQ==
|
||||
dependencies:
|
||||
hey-listen "^1.0.5"
|
||||
|
||||
fresh@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
@@ -5034,11 +5019,6 @@ hex-color-regex@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
||||
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
|
||||
|
||||
hey-listen@^1.0.5, hey-listen@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
|
||||
integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
|
||||
|
||||
history@^4.9.0:
|
||||
version "4.10.1"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
|
||||
@@ -7690,16 +7670,6 @@ pnp-webpack-plugin@1.6.4:
|
||||
dependencies:
|
||||
ts-pnp "^1.1.6"
|
||||
|
||||
popmotion@9.0.0-rc.20:
|
||||
version "9.0.0-rc.20"
|
||||
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.0.0-rc.20.tgz#f3550042ae31957b5416793ae8723200951ad39d"
|
||||
integrity sha512-f98sny03WuA+c8ckBjNNXotJD4G2utG/I3Q23NU69OEafrXtxxSukAaJBxzbtxwDvz3vtZK69pu9ojdkMoBNTg==
|
||||
dependencies:
|
||||
framesync "^4.1.0"
|
||||
hey-listen "^1.0.8"
|
||||
style-value-types "^3.1.9"
|
||||
tslib "^1.10.0"
|
||||
|
||||
portfinder@^1.0.26:
|
||||
version "1.0.28"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
||||
@@ -8654,6 +8624,16 @@ react-dom@^16.14.0:
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.1"
|
||||
|
||||
react-elastic-carousel@^0.11.5:
|
||||
version "0.11.5"
|
||||
resolved "https://registry.yarnpkg.com/react-elastic-carousel/-/react-elastic-carousel-0.11.5.tgz#4be027ea047c4f7678273caa844e83d91f3784dc"
|
||||
integrity sha512-//k1IWUiUNXXNE8LHw4bLdP+8YCXLQHbeSOPiZo/+sTkUBp/YB/hjGKWH4RqSJ59AjF8PoxB+SUbqhdPTcwAuw==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
react-only-when "^1.0.2"
|
||||
react-swipeable "^5.5.1"
|
||||
resize-observer-polyfill "1.5.0"
|
||||
|
||||
react-error-overlay@^6.0.7:
|
||||
version "6.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
|
||||
@@ -8664,6 +8644,11 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react-only-when@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-only-when/-/react-only-when-1.0.2.tgz#a8a79b48dd6cfbd91ddc710674a94153e88039d3"
|
||||
integrity sha512-agE6l3L6bqaVuwNtjihTQ36M+VBfPS63KOzcNL4ZTmlwSxQPvhzIqmBWfiol0/wLYmKxCcBqgXkEJpvj5Kob8Q==
|
||||
|
||||
react-router-dom@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
|
||||
@@ -8753,6 +8738,13 @@ react-scripts@3.4.3:
|
||||
optionalDependencies:
|
||||
fsevents "2.1.2"
|
||||
|
||||
react-swipeable@^5.5.1:
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/react-swipeable/-/react-swipeable-5.5.1.tgz#48ae6182deaf62f21d4b87469b60281dbd7c4a76"
|
||||
integrity sha512-EQObuU3Qg3JdX3WxOn5reZvOSCpU4fwpUAs+NlXSN3y+qtsO2r8VGkVnOQzmByt3BSYj9EWYdUOUfi7vaMdZZw==
|
||||
dependencies:
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react@^16.14.0:
|
||||
version "16.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
|
||||
@@ -9021,6 +9013,11 @@ requires-port@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
resize-observer-polyfill@1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69"
|
||||
integrity sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||
@@ -9904,14 +9901,6 @@ style-loader@0.23.1:
|
||||
loader-utils "^1.1.0"
|
||||
schema-utils "^1.0.0"
|
||||
|
||||
style-value-types@^3.1.9:
|
||||
version "3.1.9"
|
||||
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.1.9.tgz#faf7da660d3f284ed695cff61ea197d85b9122cc"
|
||||
integrity sha512-050uqgB7WdvtgacoQKm+4EgKzJExVq0sieKBQQtJiU3Muh6MYcCp4T3M8+dfl6VOF2LR0NNwXBP1QYEed8DfIw==
|
||||
dependencies:
|
||||
hey-listen "^1.0.8"
|
||||
tslib "^1.10.0"
|
||||
|
||||
styled-components@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.2.0.tgz#6dcb5aa8a629c84b8d5ab34b7167e3e0c6f7ed74"
|
||||
|
||||
Reference in New Issue
Block a user