-
-
-
-
-
-
-
-
- Drag & drop a .png file or
-
- click here to upload it.
-
-
+
+ {!image && !zipData && (
+ <>
+
+
+
+
+
+
+
+
+ Drag & drop an image file or
+
+ click here to upload it.
+
+
+
+
+ We recommend a square PNG or SVG with at least 310px
+
+
+ No data or images are stored
+
+ >
+ )}
+ {image && !zipData && (
+ <>
+
+
+

+

+
+
+
+ {title}
+
+
+
+ {imageData.name}
+ {imageData.extension}
+
+
+ ({imageSizes.width}x{imageSizes.height})
+
+
+
+
+
+
+ {isSquare ? : }
+
+ Square image
+
+
+
+ {isPngOrSvg ? : }
+
+ PNG or SVG
+
+
+
+ {isSvg || is310px ? : }
+
+ 310px or higher
+
+
+
+
+
+ Advanced
+
+
+
+ setPwa(!pwa)}>
+
+ PWA compatible
+
+
+ 512px or higher{' '}
+
+
+
+
+
+ setDarkMode(!darkMode)}>
+
+ Dark Mode version
+
+
+ Available soon
+
+
+
+
+
+
+
+
+
+ >
+ )}
+ {zipData && (
+ <>
+
+
+
+ Your new favicon is ready!
+
+
+ We’ve prepared a zip file with all the sizes and a README with the code plus other resources.
+
+
+
+
+
+
+ {sizesCount} different sizes
+
+
+
+
+
+ Code generated
+
+
+
+
+
+
+
+
+
setIsModalOpen(false)}
+ className={styles.content}
+ overlayClassName={classnames(styles.overlay, { [styles.dark]: isDark })}
+ closeTimeoutMS={200}
+ contentLabel="Code generated">
+
+
+
+ Insert the following code in the <head> section of your pages:
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
-
- We recommend a square png image with at least 310px
-
-
- No data or images are stored
-
)
}
diff --git a/components/favycon-info/index.module.scss b/components/favycon-info/index.module.scss
new file mode 100644
index 0000000..45a9639
--- /dev/null
+++ b/components/favycon-info/index.module.scss
@@ -0,0 +1,15 @@
+@import '../../styles/variables.scss';
+
+.root {
+ width: 100%;
+ max-width: 350px;
+}
+
+.firstParagraph {
+ margin-top: 8px;
+}
+
+.secondParagraph {
+ margin-top: 16px;
+ margin-bottom: 60px;
+}
diff --git a/components/favycon-info/index.tsx b/components/favycon-info/index.tsx
new file mode 100644
index 0000000..f54f028
--- /dev/null
+++ b/components/favycon-info/index.tsx
@@ -0,0 +1,40 @@
+import React from 'react'
+import { Typography } from 'components/typography'
+import { ToolTitle } from 'components/tool-title'
+
+import styles from './index.module.scss'
+
+type FavyconInfoProps = {
+ imageIndex: number
+}
+
+const unsplashImagesUrls = [
+ 'https://unsplash.com/photos/zKnQnyARggY',
+ 'https://unsplash.com/photos/UQAQm_EpWR8',
+ 'https://unsplash.com/photos/IXUM4cJynP0',
+]
+
+const FavyconInfo = ({ imageIndex }: FavyconInfoProps) => {
+ 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 { FavyconInfo }
diff --git a/components/favycon-wizard/index.module.scss b/components/favycon-wizard/index.module.scss
new file mode 100644
index 0000000..510780f
--- /dev/null
+++ b/components/favycon-wizard/index.module.scss
@@ -0,0 +1,77 @@
+@import '../../styles/variables.scss';
+
+.root {
+ position: relative;
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+ width: 100%;
+ max-width: 540px;
+ padding: 41px 0 0;
+}
+
+.error {
+ position: absolute;
+ top: -5px;
+ left: 6px;
+ display: flex;
+ align-items: center;
+ padding: 6px 8px 6px 16px;
+ background: $red;
+ border-radius: 18px;
+ box-shadow: 0 2px 4px rgba($black, 0.12);
+ opacity: 1;
+ transition: opacity 0.2s ease-in-out;
+ transform: translateY(-100%) rotate(2deg);
+
+ &.hide {
+ pointer-events: none;
+ opacity: 0;
+ }
+}
+
+.errorIcon {
+ margin-left: 24px;
+ cursor: pointer;
+}
+
+.background {
+ position: absolute;
+ top: 10px;
+ right: 0;
+ left: 0;
+ z-index: -1;
+ width: 100%;
+ overflow: hidden;
+ border-radius: 8px;
+ transform: rotate(2deg);
+
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 0;
+ content: '';
+ background: rgba($black, 0.16);
+ border-radius: 8px;
+ }
+}
+
+.image {
+ position: absolute;
+ top: 57px;
+ right: 15px;
+ z-index: -1;
+ width: 184px;
+ height: 108px;
+ opacity: 1;
+ transition: opacity 0.2s ease-in-out;
+ transform: translate(100%, -100%);
+
+ &.hide {
+ pointer-events: none;
+ opacity: 0;
+ }
+}
diff --git a/components/favycon-wizard/index.tsx b/components/favycon-wizard/index.tsx
new file mode 100644
index 0000000..e9f995c
--- /dev/null
+++ b/components/favycon-wizard/index.tsx
@@ -0,0 +1,52 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import classnames from 'classnames'
+import useDarkMode from 'use-dark-mode'
+import { LazyImage } from 'components/lazy-image'
+
+import styles from './index.module.scss'
+import { Typography } from 'components/typography'
+import { SvgError } from 'components/svgs/svg-error'
+
+type FavyconWizardProps = {
+ children: PropTypes.ReactNodeLike
+ backgroundId: number
+ error: string
+ clearError: () => void
+ showDndImage: boolean
+}
+
+const FavyconWizardComponent = ({ children, backgroundId, error, clearError, showDndImage }: FavyconWizardProps) => {
+ const { value: isDark } = useDarkMode(false)
+ return (
+
+
+
+ {error}
+
+
+
+
+
+
+ {children}
+
+
+
+
+ )
+}
+
+export const FavyconWizard = React.memo(FavyconWizardComponent)
diff --git a/components/header/index.module.scss b/components/header/index.module.scss
index 26a3353..094e822 100644
--- a/components/header/index.module.scss
+++ b/components/header/index.module.scss
@@ -6,8 +6,9 @@
.container {
max-width: 1440px;
- height: 64px;
- padding: 0 20px;
+ height: 68px;
+ padding: 20px 20px 0 20px;
+ margin: 0 auto;
}
.header {
@@ -22,9 +23,15 @@
border-radius: 16px;
box-shadow: 0 0 10px rgba($off-white, 0.5);
transition: all 0.2s ease;
+
+ a {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
}
.dark {
- background: $dark-black;
- box-shadow: 0 0 10px rgba($dark-black, 0.5);
+ background: $darker-black;
+ box-shadow: 0 0 10px rgba($darker-black, 0.5);
}
diff --git a/components/header/index.tsx b/components/header/index.tsx
index 730f15b..da8c870 100644
--- a/components/header/index.tsx
+++ b/components/header/index.tsx
@@ -1,9 +1,10 @@
import React from 'react'
+import Link from 'next/link'
import useDarkMode from 'use-dark-mode'
import classnames from 'classnames'
import { DarkModeToggle } from 'components/dark-mode-toggle'
-import { Typography } from 'components/typography'
import { Sticky } from 'components/sticky'
+import { SvgFavycon } from 'components/svgs/svg-favycon'
import styles from './index.module.scss'
@@ -16,7 +17,11 @@ const Header = () => {
diff --git a/components/seo/index.tsx b/components/seo/index.tsx
index 9ed8096..6383457 100644
--- a/components/seo/index.tsx
+++ b/components/seo/index.tsx
@@ -10,16 +10,14 @@ const SEO = ({ title, description }: SEOProps) => (
{title}
-
-
-
+
+
+
-
-
-
+
diff --git a/components/svgs/svg-appycon.tsx b/components/svgs/svg-appycon.tsx
index 977551e..fcfa1aa 100644
--- a/components/svgs/svg-appycon.tsx
+++ b/components/svgs/svg-appycon.tsx
@@ -4,7 +4,7 @@ import { uniqueId } from 'utils/ids'
const SvgAppycon: React.FC
> = (props) => {
const idPrefix = uniqueId('svg-')
return (
-