diff --git a/package.json b/package.json index 137b9a0..20b2bf3 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/Card/styles.ts b/src/components/Card/styles.ts index acf24c9..a7e2395 100644 --- a/src/components/Card/styles.ts +++ b/src/components/Card/styles.ts @@ -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; diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index dc0adf4..f34e7c2 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -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(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); - const [dailyForecastGrid, setDailyForecastGrid] = useState(0); - const [hourlyForecastGrid, setHourlyForecastGrid] = useState(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 ? ( + + ) : ( + + )} + + ) + }; useEffect(() => { if (!navigator.geolocation) @@ -82,93 +111,35 @@ const Home: React.FC = () => {

Daily Forecast

-
- { - if (dailyForecastGrid <= forecast.daily.length / 2 - 1) - setDailyForecastGrid(dailyForecastGrid + 1); - }} - onMouseDown={() => { - if (dailyForecastGrid <= forecast.daily.length / 2 - 1) - setDailyForecastGrid(dailyForecastGrid + 1); - }} - /> -
- - {forecast.daily.map(day => ( - 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null} - icon={day.weather[0].id} - description={day.weather[0].description} - /> - ))} - -
- { - if (dailyForecastGrid >= -forecast.daily.length / 2 + 1) - setDailyForecastGrid(dailyForecastGrid - 1); - }} - onMouseDown={() => { - if (dailyForecastGrid >= -forecast.daily.length / 2 + 1) - setDailyForecastGrid(dailyForecastGrid - 1); - }} - /> -
+ + {forecast.daily.map(day => ( + 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null} + icon={day.weather[0].id} + description={day.weather[0].description} + /> + ))} +

Hourly Forecast

-
- { - if (hourlyForecastGrid <= forecast.hourly.length / 2 - 1) - setHourlyForecastGrid(hourlyForecastGrid + 1); - }} - /> -
- - {forecast.hourly.map(hour => ( - 25 ? 'hot' : hour.temp < 20 ? 'cold' : null} - icon={hour.weather[0].id} - description={hour.weather[0].description} - /> - ))} - -
- { - if (hourlyForecastGrid >= -forecast.hourly.length / 2 + 1) - setHourlyForecastGrid(hourlyForecastGrid - 1); - }} - /> -
+ + {forecast.hourly.map(hour => ( + 25 ? 'hot' : hour.temp < 20 ? 'cold' : null} + icon={hour.weather[0].id} + description={hour.weather[0].description} + /> + ))} +

Wind

diff --git a/src/pages/Home/styles.ts b/src/pages/Home/styles.ts index f4849cd..c13c3ca 100644 --- a/src/pages/Home/styles.ts +++ b/src/pages/Home/styles.ts @@ -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; diff --git a/src/pages/Search/index.tsx b/src/pages/Search/index.tsx index aa6d52c..3ff159b 100644 --- a/src/pages/Search/index.tsx +++ b/src/pages/Search/index.tsx @@ -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(true); const [error, setError] = useState(''); const { query } = useParams<{ query: string }>(); - const [dailyForecastGrid, setDailyForecastGrid] = useState(0); - const [hourlyForecastGrid, setHourlyForecastGrid] = useState(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 ? ( + + ) : ( + + )} + + ) + }; useEffect(() => { (async () => { @@ -75,85 +104,35 @@ const Search: React.FC = () => {

Daily Forecast

-
- { - if (dailyForecastGrid <= forecast.daily.length / 2 - 1) - setDailyForecastGrid(dailyForecastGrid + 1); - }} - /> -
- - {forecast.daily.map(day => ( - 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null} - icon={day.weather[0].id} - description={day.weather[0].description} - /> - ))} - -
- { - if (dailyForecastGrid >= -forecast.daily.length / 2 + 1) - setDailyForecastGrid(dailyForecastGrid - 1); - }} - /> -
+ + {forecast.daily.map(day => ( + 25 ? 'hot' : day.temp.max < 20 ? 'cold' : null} + icon={day.weather[0].id} + description={day.weather[0].description} + /> + ))} +

Hourly Forecast

-
- { - if (hourlyForecastGrid <= forecast.hourly.length / 2 - 1) - setHourlyForecastGrid(hourlyForecastGrid + 1); - }} - /> -
- - {forecast.hourly.map(hour => ( - 25 ? 'hot' : hour.temp < 20 ? 'cold' : null} - icon={hour.weather[0].id} - description={hour.weather[0].description} - /> - ))} - -
- { - if (hourlyForecastGrid >= -forecast.hourly.length / 2 + 1) - setHourlyForecastGrid(hourlyForecastGrid - 1); - }} - /> -
+ + {forecast.hourly.map(hour => ( + 25 ? 'hot' : hour.temp < 20 ? 'cold' : null} + icon={hour.weather[0].id} + description={hour.weather[0].description} + /> + ))} +

Wind

diff --git a/src/pages/Search/styles.ts b/src/pages/Search/styles.ts index f4849cd..c13c3ca 100644 --- a/src/pages/Search/styles.ts +++ b/src/pages/Search/styles.ts @@ -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; diff --git a/yarn.lock b/yarn.lock index 9188c80..1c47cab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"