mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-16 22:46:04 +01:00
feat: add social links
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
"@stitches/react": "^1.2.6",
|
||||
"next": "12.0.7",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2"
|
||||
"react-dom": "17.0.2",
|
||||
"react-icons": "^4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "15.0.0",
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { VariantProps } from '@stitches/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> & {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { styled, theme } from '../../styles/stitches.config'
|
||||
|
||||
type Color = keyof typeof theme.colors
|
||||
import { ColorsType, styled, theme, VariantProps } from '../../styles/stitches.config'
|
||||
|
||||
const colorVariantFn = (
|
||||
lightColor: Color,
|
||||
regularColor: Color,
|
||||
darkColor: Color,
|
||||
darkerColor: Color
|
||||
lightColor: ColorsType,
|
||||
regularColor: ColorsType,
|
||||
darkColor: ColorsType,
|
||||
darkerColor: ColorsType
|
||||
) => ({
|
||||
background: 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],
|
||||
|
||||
'&:hover': {
|
||||
@@ -216,3 +218,5 @@ export const Wrapper = styled('button', {
|
||||
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 { Button } from '../components/Button'
|
||||
import { SocialLinks } from '../components/SocialLinks'
|
||||
|
||||
export default function Home() {
|
||||
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 (
|
||||
<div
|
||||
style={{
|
||||
@@ -28,6 +56,7 @@ export default function Home() {
|
||||
}}
|
||||
>
|
||||
<Avatar src="/avatar.jpeg" />
|
||||
<SocialLinks socialLinks={socialLinks} color="rose" />
|
||||
{links.map(link => (
|
||||
<Button color="sky" schema="rounded" outline key={link.href}>
|
||||
{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({
|
||||
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"
|
||||
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:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
|
||||
Reference in New Issue
Block a user