diff --git a/components/lazy-image/index.module.scss b/components/lazy-image/index.module.scss new file mode 100644 index 0000000..9388e59 --- /dev/null +++ b/components/lazy-image/index.module.scss @@ -0,0 +1,29 @@ +@import '../../styles/variables.scss'; + +.root { + position: relative; + width: 100%; +} + +.image { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + font-family: 'object-fit: cover; object-position: center;', sans-serif; + object-fit: cover; + object-position: center; +} + +.placeholder { + composes: image; + transition: opacity 0.2s linear 0.2s; +} + +.normal { + composes: image; + transition: opacity 0.2s linear; +} diff --git a/components/lazy-image/index.tsx b/components/lazy-image/index.tsx new file mode 100644 index 0000000..3e302ca --- /dev/null +++ b/components/lazy-image/index.tsx @@ -0,0 +1,54 @@ +import React, { useRef, useEffect } from 'react' +import { LazyImageFull, ImageState } from 'react-lazy-images' +import objectFitImages from 'object-fit-images' + +import styles from './index.module.scss' + +type LazyImageProps = { + src: string + srcRetina: string + srcPlaceholder: string + alt: string + aspectRatio: string +} + +const LazyImage = ({ src, srcRetina, srcPlaceholder, alt, aspectRatio }: LazyImageProps) => { + const [widthString, heightString] = aspectRatio.split('/') + const width = parseInt(widthString) + const height = parseInt(heightString) + + const imgRef = useRef(null) + + useEffect(() => { + if (imgRef.current) { + objectFitImages(imgRef.current) + } + }, [imgRef]) + + return ( + + {({ imageProps, imageState, ref }) => { + const loaded = imageState === ImageState.LoadSuccess + return ( +
+ {imageProps.alt} + {imageProps.alt} +
+ ) + }} +
+ ) +} + +export { LazyImage } diff --git a/components/typography/index.module.scss b/components/typography/index.module.scss index aea2879..5753995 100644 --- a/components/typography/index.module.scss +++ b/components/typography/index.module.scss @@ -28,6 +28,16 @@ .footer { font-size: $font-size-footer; line-height: $line-height-footer; + + a { + color: inherit; + + &:focus, + &:active, + &:hover { + color: inherit; + } + } } .superscript { diff --git a/package.json b/package.json index 57d8938..4d7d178 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "classnames": "2.2.6", "multer": "1.4.2", "next": "9.3.4", + "object-fit-images": "3.2.4", "preact": "10.4.0", "preact-render-to-string": "5.1.6", "preact-ssr-prepass": "1.0.1", @@ -50,6 +51,7 @@ "react": "16.13.1", "react-dom": "16.13.1", "react-dropzone": "10.2.2", + "react-lazy-images": "1.1.0", "sharp": "0.25.2", "use-dark-mode": "2.3.1" }, @@ -71,6 +73,7 @@ "@types/classnames": "2.2.10", "@types/multer": "1.4.2", "@types/node": "13.11.1", + "@types/object-fit-images": "3.2.0", "@types/react": "16.9.34", "@types/sharp": "0.24.0", "@typescript-eslint/eslint-plugin": "2.27.0", diff --git a/pages/appycon.tsx b/pages/appycon.tsx deleted file mode 100644 index 2051cf3..0000000 --- a/pages/appycon.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' -import { NextPage } from 'next' -import { BaseLayout } from 'components/base-layout' -import { Typography } from 'components/typography' -import { SEO } from 'components/seo' -import { ToolTitle } from 'components/tool-title' - -const Appycon: NextPage = () => ( - - -
- Appycon - - A small online tool to help you generate your favicon in all the sizes and formats you need.
-
- Just drag & drop an image and you will then get a downloadable file alongside some documentation on how to - add the favicons. -
-
- - Created by 4 people on their 2020’s worldwide quarantine. Background image from Unsplash. - -
-
-) - -export default Appycon diff --git a/pages/favycon.tsx b/pages/favycon.tsx deleted file mode 100644 index 9d8307c..0000000 --- a/pages/favycon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' -import { NextPage } from 'next' -import { BaseLayout } from 'components/base-layout' -import { Typography } from 'components/typography' -import { SEO } from 'components/seo' -import { ToolTitle } from 'components/tool-title' - -const Favycon: NextPage = () => ( - - -
- Favycon - - A small online tool to help you generate your favicon in all the sizes and formats you need.
-
- Just drag & drop an image and you will then get a downloadable file alongside some documentation on how to - add the favicons. -
-
- - Created by 4 people on their 2020’s worldwide quarantine. Background image from Unsplash. - -
-
-) - -export default Favycon diff --git a/pages/index.module.scss b/pages/index.module.scss new file mode 100644 index 0000000..4a432df --- /dev/null +++ b/pages/index.module.scss @@ -0,0 +1,56 @@ +@import '../styles/variables.scss'; + +.container { + display: flex; + align-items: flex-start; + justify-content: space-between; + width: 100%; + max-width: 960px; + padding: 52px 20px; + margin: 0 auto; +} + +.info { + width: 100%; + max-width: 350px; +} + +.firstParagraph { + margin-top: 8px; +} + +.secondParagraph { + margin-top: 16px; + margin-bottom: 60px; +} + +.dragAndDrop { + position: relative; + display: flex; + align-items: flex-start; + justify-content: center; + width: 100%; + max-width: 540px; + padding: 41px 0 38px; +} + +.background { + position: absolute; + top: 10px; + right: 0; + left: 0; + z-index: -1; + width: 100%; + overflow: hidden; + border-radius: 8px; + transform: rotate(2deg); +} + +.image { + position: absolute; + top: 57px; + right: 15px; + width: 184px; + height: 108px; + transform: translate(100%, -100%); +} diff --git a/pages/index.tsx b/pages/index.tsx index fe08eb9..2c0d365 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,17 +1,79 @@ import React from 'react' import { NextPage } from 'next' +import useDarkMode from 'use-dark-mode' +import { LazyImage } from 'components/lazy-image' import { BaseLayout } from 'components/base-layout' +import { Typography } from 'components/typography' import { SEO } from 'components/seo' import { ToolTitle } from 'components/tool-title' +import { DragAndDrop } from 'components/drag-and-drop' -const Home: NextPage = () => ( - - -
- Favycon - Appycon -
-
-) +import styles from './index.module.scss' + +const getRandomNumber = (min = 1, max = 3) => Math.floor(Math.random() * max) + min + +const unsplashImagesUrls = [ + 'https://unsplash.com/photos/F573ZRbKOEw', + 'https://unsplash.com/photos/k0JNJRbrJAs', + 'https://unsplash.com/photos/f9oQZOk9vnk', +] + +const Home: NextPage = () => { + const { value: isDark } = useDarkMode(false) + const backgroundId = getRandomNumber() + const onDrop = (acceptedFiles: File[]) => { + console.log('acceptedFiles[0]', acceptedFiles[0]) + } + + return ( + + +
+
+ Favycon + + A small online tool to help you generate your favicon in all the sizes and formats you need. + + + Just drag & drop an image and you will then get a downloadable file alongside some documentation on how + to add the favicons. + +
+ + Created by 4 people on their 2020’s worldwide quarantine. Background image from{' '} + + Unsplash + + . + +
+
+
+ +
+ +
+ +
+
+
+
+ ) +} export default Home diff --git a/public/images/dnd-dark@1x.png b/public/images/dnd-dark@1x.png new file mode 100644 index 0000000..36d9402 Binary files /dev/null and b/public/images/dnd-dark@1x.png differ diff --git a/public/images/dnd-dark@2x.png b/public/images/dnd-dark@2x.png new file mode 100644 index 0000000..b5ca27e Binary files /dev/null and b/public/images/dnd-dark@2x.png differ diff --git a/public/images/dnd-light@1x.png b/public/images/dnd-light@1x.png new file mode 100644 index 0000000..89934ec Binary files /dev/null and b/public/images/dnd-light@1x.png differ diff --git a/public/images/dnd-light@2x.png b/public/images/dnd-light@2x.png new file mode 100644 index 0000000..3dc4b02 Binary files /dev/null and b/public/images/dnd-light@2x.png differ diff --git a/public/images/unsplash-1@1x.jpg b/public/images/unsplash-1@1x.jpg new file mode 100644 index 0000000..06e870b Binary files /dev/null and b/public/images/unsplash-1@1x.jpg differ diff --git a/public/images/unsplash-1@2x.jpg b/public/images/unsplash-1@2x.jpg new file mode 100644 index 0000000..fad1fb1 Binary files /dev/null and b/public/images/unsplash-1@2x.jpg differ diff --git a/public/images/unsplash-1@placeholder.jpg b/public/images/unsplash-1@placeholder.jpg new file mode 100644 index 0000000..600cc90 Binary files /dev/null and b/public/images/unsplash-1@placeholder.jpg differ diff --git a/public/images/unsplash-2@1x.jpg b/public/images/unsplash-2@1x.jpg new file mode 100644 index 0000000..b8b30d2 Binary files /dev/null and b/public/images/unsplash-2@1x.jpg differ diff --git a/public/images/unsplash-2@2x.jpg b/public/images/unsplash-2@2x.jpg new file mode 100644 index 0000000..7efbfd2 Binary files /dev/null and b/public/images/unsplash-2@2x.jpg differ diff --git a/public/images/unsplash-2@placeholder.jpg b/public/images/unsplash-2@placeholder.jpg new file mode 100644 index 0000000..3fb9efe Binary files /dev/null and b/public/images/unsplash-2@placeholder.jpg differ diff --git a/public/images/unsplash-3@1x.jpg b/public/images/unsplash-3@1x.jpg new file mode 100644 index 0000000..d62d949 Binary files /dev/null and b/public/images/unsplash-3@1x.jpg differ diff --git a/public/images/unsplash-3@2x.jpg b/public/images/unsplash-3@2x.jpg new file mode 100644 index 0000000..c5a5b20 Binary files /dev/null and b/public/images/unsplash-3@2x.jpg differ diff --git a/public/images/unsplash-3@placeholder.jpg b/public/images/unsplash-3@placeholder.jpg new file mode 100644 index 0000000..ef90d59 Binary files /dev/null and b/public/images/unsplash-3@placeholder.jpg differ diff --git a/yarn.lock b/yarn.lock index fe8487c..51ce2f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1203,7 +1203,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.9.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== @@ -2444,6 +2444,11 @@ resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.2.tgz#d070fe6a6b78755d1092a3dc492d34c3d8f871c4" integrity sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA== +"@types/object-fit-images@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/object-fit-images/-/object-fit-images-3.2.0.tgz#ffa0b3243ade3b89a2b12a08e92dbbea75b825f4" + integrity sha512-ordonpqL1HiYEHDIGxDo/MvyDvGZiNmPpw9bYxys7TXPcCN5WBejOR1Mj/KPCPyjMeaXyLQu7JP5tVi4GBRoWA== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -10321,6 +10326,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-fit-images@3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/object-fit-images/-/object-fit-images-3.2.4.tgz#6c299d38fdf207746e5d2d46c2877f6f25d15b52" + integrity sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg== + object-inspect@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" @@ -11682,6 +11692,14 @@ react-inspector@^4.0.0: is-dom "^1.0.9" prop-types "^15.6.1" +react-intersection-observer@^6.1.0: + version "6.4.2" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-6.4.2.tgz#a061add707c37ea14e1308c77c2e286719347928" + integrity sha512-gL6YrkhniA0tIbyDbUterzBwKh61vHR520rsKULel5T37gG4YP07wnWI3WoqOcKK5bKAu0PZB2FHD7/OjawN+w== + dependencies: + "@babel/runtime" "^7.2.0" + invariant "^2.2.4" + react-is@16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" @@ -11692,6 +11710,14 @@ react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-lazy-images@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-lazy-images/-/react-lazy-images-1.1.0.tgz#c865445c96e568a6249db03a2bb2dccd49cb6f50" + integrity sha512-h5DHFhkMJyh2qsDl3hXWu6d+On10FsgHtRJ+BH7xjgsFOvsqaii9CEwEESqPJrrAiHo1qrN1LgzrV8X3zctHKA== + dependencies: + react-intersection-observer "^6.1.0" + unionize "^2.1.2" + react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" @@ -14150,6 +14176,11 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +unionize@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/unionize/-/unionize-2.2.0.tgz#ce88635aa0793f28ab617abeac36172ba0aeb7bc" + integrity sha512-lHXiL6LPVuRYBGCLOdUd4GMHoAGqM0HtYHAZcA6pUEiwN1nk+LEYlh8bud7saeL0bkFntJzCPEPVVJeFm3Cqsg== + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"