mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-18 23:46:04 +01:00
feat: add social links
This commit is contained in:
@@ -17,7 +17,8 @@
|
|||||||
"@stitches/react": "^1.2.6",
|
"@stitches/react": "^1.2.6",
|
||||||
"next": "12.0.7",
|
"next": "12.0.7",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2"
|
"react-dom": "17.0.2",
|
||||||
|
"react-icons": "^4.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "15.0.0",
|
"@commitlint/cli": "15.0.0",
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { VariantProps } from '@stitches/react'
|
|
||||||
import { ButtonHTMLAttributes, ReactNode } from 'react'
|
import { ButtonHTMLAttributes, ReactNode } from 'react'
|
||||||
|
|
||||||
import { Wrapper } from './styles'
|
import { ButtonVariantProps, Wrapper } from './styles'
|
||||||
|
|
||||||
type ButtonProps = VariantProps<typeof Wrapper> &
|
type ButtonProps = ButtonVariantProps &
|
||||||
ButtonHTMLAttributes<HTMLButtonElement> & {
|
ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { styled, theme } from '../../styles/stitches.config'
|
import { ColorsType, styled, theme, VariantProps } from '../../styles/stitches.config'
|
||||||
|
|
||||||
type Color = keyof typeof theme.colors
|
|
||||||
|
|
||||||
const colorVariantFn = (
|
const colorVariantFn = (
|
||||||
lightColor: Color,
|
lightColor: ColorsType,
|
||||||
regularColor: Color,
|
regularColor: ColorsType,
|
||||||
darkColor: Color,
|
darkColor: ColorsType,
|
||||||
darkerColor: Color
|
darkerColor: ColorsType
|
||||||
) => ({
|
) => ({
|
||||||
background: theme.colors[regularColor],
|
background: theme.colors[regularColor],
|
||||||
borderColor: theme.colors[regularColor],
|
borderColor: theme.colors[regularColor],
|
||||||
@@ -23,7 +21,11 @@ const colorVariantFn = (
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const outlineVariantFn = (lightColor: Color, regularColor: Color, darkColor: Color) => ({
|
const outlineVariantFn = (
|
||||||
|
lightColor: ColorsType,
|
||||||
|
regularColor: ColorsType,
|
||||||
|
darkColor: ColorsType
|
||||||
|
) => ({
|
||||||
color: theme.colors[darkColor],
|
color: theme.colors[darkColor],
|
||||||
|
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
@@ -216,3 +218,5 @@ export const Wrapper = styled('button', {
|
|||||||
outline: false
|
outline: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export type ButtonVariantProps = VariantProps<typeof Wrapper>
|
||||||
|
|||||||
17
src/components/Link/index.tsx
Normal file
17
src/components/Link/index.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import NextLink from 'next/link'
|
||||||
|
import { AnchorHTMLAttributes } from 'react'
|
||||||
|
|
||||||
|
import { LinkVariantProps, Wrapper } from './styles'
|
||||||
|
|
||||||
|
export type LinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
||||||
|
href: string
|
||||||
|
color?: LinkVariantProps['color']
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Link({ href, ...rest }: LinkProps) {
|
||||||
|
return (
|
||||||
|
<NextLink href={href} passHref>
|
||||||
|
<Wrapper {...rest} />
|
||||||
|
</NextLink>
|
||||||
|
)
|
||||||
|
}
|
||||||
57
src/components/Link/styles.ts
Normal file
57
src/components/Link/styles.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { ColorsType, styled, theme, VariantProps } from '../../styles/stitches.config'
|
||||||
|
|
||||||
|
const colorVariantFn = (
|
||||||
|
regularColor: ColorsType,
|
||||||
|
darkColor: ColorsType,
|
||||||
|
darkerColor: ColorsType
|
||||||
|
) => ({
|
||||||
|
color: theme.colors[regularColor],
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
color: theme.colors[darkColor]
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:active': {
|
||||||
|
color: theme.colors[darkerColor]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const Wrapper = styled('a', {
|
||||||
|
fontWeight: 'medium',
|
||||||
|
textDecoration: 'none',
|
||||||
|
transition: 'color 0.25s ease',
|
||||||
|
cursor: 'pointer',
|
||||||
|
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
slate: colorVariantFn('slate600', 'slate700', 'slate800'),
|
||||||
|
gray: colorVariantFn('gray600', 'gray700', 'gray800'),
|
||||||
|
zinc: colorVariantFn('zinc600', 'zinc700', 'zinc800'),
|
||||||
|
neutral: colorVariantFn('neutral600', 'neutral700', 'neutral800'),
|
||||||
|
stone: colorVariantFn('stone600', 'stone700', 'stone800'),
|
||||||
|
red: colorVariantFn('red600', 'red700', 'red800'),
|
||||||
|
orange: colorVariantFn('orange600', 'orange700', 'orange800'),
|
||||||
|
amber: colorVariantFn('amber600', 'amber700', 'amber800'),
|
||||||
|
yellow: colorVariantFn('yellow600', 'yellow700', 'yellow800'),
|
||||||
|
lime: colorVariantFn('lime600', 'lime700', 'lime800'),
|
||||||
|
green: colorVariantFn('green600', 'green700', 'green800'),
|
||||||
|
emerald: colorVariantFn('emerald600', 'emerald700', 'emerald800'),
|
||||||
|
teal: colorVariantFn('teal600', 'teal700', 'teal800'),
|
||||||
|
cyan: colorVariantFn('cyan600', 'cyan700', 'cyan800'),
|
||||||
|
sky: colorVariantFn('sky600', 'sky700', 'sky800'),
|
||||||
|
blue: colorVariantFn('blue600', 'blue700', 'blue800'),
|
||||||
|
indigo: colorVariantFn('indigo600', 'indigo700', 'indigo800'),
|
||||||
|
violet: colorVariantFn('violet600', 'violet700', 'violet800'),
|
||||||
|
purple: colorVariantFn('purple600', 'purple700', 'purple800'),
|
||||||
|
fuchsia: colorVariantFn('fuchsia600', 'fuchsia700', 'fuchsia800'),
|
||||||
|
pink: colorVariantFn('pink600', 'pink700', 'pink800'),
|
||||||
|
rose: colorVariantFn('rose600', 'rose700', 'rose800')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultVariants: {
|
||||||
|
color: 'teal'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export type LinkVariantProps = VariantProps<typeof Wrapper>
|
||||||
54
src/components/SocialLinks/index.tsx
Normal file
54
src/components/SocialLinks/index.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import {
|
||||||
|
AiFillGithub as GitHub,
|
||||||
|
AiOutlineInstagram as Instagram,
|
||||||
|
AiOutlineWhatsApp as WhatsApp
|
||||||
|
} from 'react-icons/ai'
|
||||||
|
import { BsEnvelope as Email } from 'react-icons/bs'
|
||||||
|
import { FaDev as Dev, FaLinkedinIn as LinkedIn } from 'react-icons/fa'
|
||||||
|
import { IconType } from 'react-icons/lib'
|
||||||
|
|
||||||
|
import { Link } from '../Link'
|
||||||
|
import { LinkVariantProps } from '../Link/styles'
|
||||||
|
import { SocialItem, Wrapper } from './styles'
|
||||||
|
|
||||||
|
type SocialLink = {
|
||||||
|
label: string
|
||||||
|
href: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SocialLinksProps = LinkVariantProps & {
|
||||||
|
socialLinks: SocialLink[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const Icons = {
|
||||||
|
Email,
|
||||||
|
GitHub,
|
||||||
|
LinkedIn,
|
||||||
|
Dev,
|
||||||
|
Instagram,
|
||||||
|
WhatsApp
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SocialLinks({ socialLinks, color }: SocialLinksProps) {
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
{socialLinks.map(({ label, href }) => {
|
||||||
|
const Icon: IconType = Icons[label as keyof typeof Icons]
|
||||||
|
return (
|
||||||
|
<SocialItem key={href}>
|
||||||
|
<Link
|
||||||
|
href={href}
|
||||||
|
aria-label={label}
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
// @ts-ignore
|
||||||
|
color={color}
|
||||||
|
>
|
||||||
|
<Icon size={22} />
|
||||||
|
</Link>
|
||||||
|
</SocialItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Wrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
24
src/components/SocialLinks/styles.ts
Normal file
24
src/components/SocialLinks/styles.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { styled } from '../../styles/stitches.config'
|
||||||
|
|
||||||
|
export const Wrapper = styled('ul', {
|
||||||
|
display: 'inline-flex',
|
||||||
|
listStyle: 'none',
|
||||||
|
margin: 0,
|
||||||
|
padding: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
export const SocialItem = styled('li', {
|
||||||
|
transition: 'transform 0.2s ease-in-out',
|
||||||
|
|
||||||
|
'&:not(:last-child)': {
|
||||||
|
marginRight: '1rem'
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
transform: 'scale(1.1)'
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:active': {
|
||||||
|
transform: 'scale(0.95)'
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Avatar } from '../components/Avatar'
|
import { Avatar } from '../components/Avatar'
|
||||||
import { Button } from '../components/Button'
|
import { Button } from '../components/Button'
|
||||||
|
import { SocialLinks } from '../components/SocialLinks'
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const links = [
|
const links = [
|
||||||
@@ -17,6 +18,33 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const socialLinks = [
|
||||||
|
{
|
||||||
|
label: 'Email',
|
||||||
|
href: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'GitHub',
|
||||||
|
href: '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'LinkedIn',
|
||||||
|
href: '3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Dev',
|
||||||
|
href: '4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Instagram',
|
||||||
|
href: '5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'WhatsApp',
|
||||||
|
href: '6'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -28,6 +56,7 @@ export default function Home() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Avatar src="/avatar.jpeg" />
|
<Avatar src="/avatar.jpeg" />
|
||||||
|
<SocialLinks socialLinks={socialLinks} color="rose" />
|
||||||
{links.map(link => (
|
{links.map(link => (
|
||||||
<Button color="sky" schema="rounded" outline key={link.href}>
|
<Button color="sky" schema="rounded" outline key={link.href}>
|
||||||
{link.label}
|
{link.label}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { createStitches } from '@stitches/react'
|
import { createStitches, VariantProps } from '@stitches/react'
|
||||||
|
|
||||||
export const { css, styled, globalCss, theme, keyframes, getCssText } = createStitches({
|
export const { css, styled, globalCss, theme, keyframes, getCssText } = createStitches({
|
||||||
theme: {
|
theme: {
|
||||||
@@ -247,3 +247,7 @@ export const { css, styled, globalCss, theme, keyframes, getCssText } = createSt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type ColorsType = keyof typeof theme.colors
|
||||||
|
|
||||||
|
export type { ColorsType, VariantProps }
|
||||||
|
|||||||
@@ -3211,6 +3211,11 @@ react-dom@17.0.2:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
scheduler "^0.20.2"
|
scheduler "^0.20.2"
|
||||||
|
|
||||||
|
react-icons@^4.3.1:
|
||||||
|
version "4.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
|
||||||
|
integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
|
||||||
|
|
||||||
react-is@17.0.2:
|
react-is@17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||||
|
|||||||
Reference in New Issue
Block a user