Skip to content

Commit

Permalink
chore(components/patterns): add Cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jun 22, 2021
1 parent 87d5040 commit 68538c9
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 18 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@microlink/mql": "~0.9.5",
"@microlink/react": "~5.5.6",
"@microlink/recipes": "~1.0.0",
"@radix-ui/react-popper": "0.0.17",
"@stripe/react-stripe-js": "~1.4.1",
"@stripe/stripe-js": "~1.15.0",
"@styled-system/prop-types": "~5.1.5",
Expand Down
43 changes: 25 additions & 18 deletions src/components/pages/home/hero.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Link, Flex, Subhead, Container, Heading } from 'components/elements'
import { Caption, ArrowLink } from 'components/patterns'
import { Cursor, Caption, ArrowLink } from 'components/patterns'
import React, { useEffect, useState } from 'react'
import { fadeIn } from 'components/keyframes'
import { layout } from 'theme'

const SENTENCES = [
{ href: '/recipes/get-html', text: 'Get HTML markup', color: '#850BA7' },
{ href: '/screenshot', text: 'Take a screenshot', color: '#FD494A' },
{ href: '/pdf', text: 'Generate a PDF', color: '#e000ac' },
{ href: '/meta', text: 'Normalize metadata', color: '#3e55ff' },
{ href: '/insights', text: 'Run Lighthouse', color: '#B500ED' },
{ href: '/recipes', text: 'Get HTML markup', color: '#850BA7' },
{ href: '/screenshot', text: 'Take a screenshot', color: '#FD494A' },
{ href: '/insights', text: 'Identify tech stack', color: '#A31B90' },
{ href: '/recipes', text: 'Automate scrapping', color: '#DF3A61' }
{ href: '/pdf', text: 'Generate a PDF', color: '#e000ac' },
{ href: '/recipes', text: 'Automate scrapping', color: '#DF3A61' },
{ href: '/insights', text: 'Run Lighthouse', color: '#B500ED' }
]

const SENTENCES_INTERVAL = 3500
Expand All @@ -29,30 +29,37 @@ const Hero = props => {

const { color, text, href } = SENTENCES[index]

const cursor = `url("data:image/svg+xml,%3Csvg shape-rendering='geometricPrecision' xmlns='http://www.w3.org/2000/svg' width='32' height='32' fill='none'%3E%3Cg filter='url(%23filter0_d)'%3E%3Cpath fill='%23${color.slice(
1
)}' d='M9.63 6.9a1 1 0 011.27-1.27l11.25 3.75a1 1 0 010 1.9l-4.68 1.56a1 1 0 00-.63.63l-1.56 4.68a1 1 0 01-1.9 0L9.63 6.9z'/%3E%3Cpath stroke='%23fff' stroke-width='1.5' d='M11.13 4.92a1.75 1.75 0 00-2.2 2.21l3.74 11.26a1.75 1.75 0 003.32 0l1.56-4.68a.25.25 0 01.16-.16L22.4 12a1.75 1.75 0 000-3.32L11.13 4.92z'/%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' width='32.26' height='32.26' x='.08' y='.08' filterUnits='userSpaceOnUse'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dy='4'/%3E%3CfeGaussianBlur stdDeviation='4'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0'/%3E%3CfeBlend in2='BackgroundImageFix' mode='normal' result='effect1_dropShadow'/%3E%3CfeBlend in='SourceGraphic' in2='effect1_dropShadow' mode='normal' result='shape'/%3E%3C/filter%3E%3C/defs%3E%3C/svg%3E") 6 2, default`

return (
<Flex
data-debug
px={3}
flexDirection='column'
alignItems='center'
justifyContent='center'
style={{ cursor }}
{...props}
>
<Heading fontSize={['48px', 6, 7, 7]} titleize={false}>
Browser as API
</Heading>
<Link pt={[2, 2, 3, 3]} href={href} linkProps={{ title: text }}>
<Subhead color='black80' titleize={false} key={text} css={fadeIn}>
{text}
</Subhead>
</Link>
<Cursor bg={color} text={href}>
<Link
href={href}
style={{ cursor: 'inherit' }}
linkProps={{ style: { cursor: 'inherit' } }}
>
<Subhead
pt={[2, 2, 3, 3]}
pb={[4, 4, 5, 5]}
color='black80'
titleize={false}
key={text}
css={fadeIn}
>
{text}
</Subhead>
</Link>
</Cursor>
<Caption
py={[4, 4, 5, 5]}
pb={[4, 4, 5, 5]}
px={[4, 4, 0, 0]}
maxWidth={[layout.small, layout.small, layout.normal, layout.normal]}
>
Expand Down
66 changes: 66 additions & 0 deletions src/components/patterns/Cursor/Cursor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Popper, PopperAnchor, PopperContent } from '@radix-ui/react-popper'
import React, { useState, useRef, useEffect } from 'react'
import { Box, Text } from 'components/elements'
import styled from 'styled-components'
import { shadows } from 'theme'

const CursorContent = styled(Text)`
border-radius: 9999px;
border: ${props => `1.8px solid ${props.color}`};
box-shadow: ${shadows[0]};
`

const Cursor = ({ color = 'white', style: innerStyle, bg, text, children }) => {
const [isActive, setIsActive] = useState(false)
const mousePosRef = useRef({ x: 0, y: 0 })

const handleMouseMove = event =>
(mousePosRef.current = { x: event.pageX, y: event.pageY })

const virtualRef = useRef({
getBoundingClientRect: () =>
window.DOMRect.fromRect({ width: 0, height: 0, ...mousePosRef.current })
})

useEffect(() => {
document.addEventListener('mousemove', handleMouseMove)
return () => document.removeEventListener('mousemove', handleMouseMove)
}, [])

const onMouseEnter = () => setIsActive(true)
const onMouseLeave = () => setIsActive(false)

const cursor = `url("data:image/svg+xml,%3Csvg shape-rendering='geometricPrecision' xmlns='http://www.w3.org/2000/svg' width='32' height='32' fill='none'%3E%3Cg filter='url(%23filter0_d)'%3E%3Cpath fill='%23${bg.slice(
1
)}' d='M9.63 6.9a1 1 0 011.27-1.27l11.25 3.75a1 1 0 010 1.9l-4.68 1.56a1 1 0 00-.63.63l-1.56 4.68a1 1 0 01-1.9 0L9.63 6.9z'/%3E%3Cpath stroke='%23fff' stroke-width='1.5' d='M11.13 4.92a1.75 1.75 0 00-2.2 2.21l3.74 11.26a1.75 1.75 0 003.32 0l1.56-4.68a.25.25 0 01.16-.16L22.4 12a1.75 1.75 0 000-3.32L11.13 4.92z'/%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' width='32.26' height='32.26' x='.08' y='.08' filterUnits='userSpaceOnUse'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dy='4'/%3E%3CfeGaussianBlur stdDeviation='4'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0'/%3E%3CfeBlend in2='BackgroundImageFix' mode='normal' result='effect1_dropShadow'/%3E%3CfeBlend in='SourceGraphic' in2='effect1_dropShadow' mode='normal' result='shape'/%3E%3C/filter%3E%3C/defs%3E%3C/svg%3E") 6 2, default`

return (
<>
<Box
style={isActive ? { cursor, ...innerStyle } : innerStyle}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
{children}
</Box>
{isActive && (
<Popper>
<PopperAnchor virtualRef={virtualRef} />
<PopperContent align='start' sideOffset={15} alignOffset={15}>
<CursorContent
py='5px'
px='10px'
fontSize='12px'
color={color}
bg={bg}
>
{text}
</CursorContent>
</PopperContent>
</Popper>
)}
</>
)
}

export default Cursor
33 changes: 33 additions & 0 deletions src/components/patterns/Cursor/Cursor.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Subhead } from 'components/elements'
import { Cursor } from 'components/patterns'
import { storiesOf } from '@storybook/react'
import { Story } from 'story'
import React from 'react'

const storyName = 'Cursor'

const code = `
import { Subhead } from 'components/elements'
import { Cursor } from 'components/patterns'
export default () => (
<Fragment>
<Cursor color='white' bg='#3e55ff' text='/screenshots'>
<Subhead>Hover on me</Subhead>
</Cursor>
</Fragment>
)`

const CursorStory = () => {
return (
<Story name={storyName} code={code}>
<Cursor color='white' bg='#3e55ff' text='/screenshots'>
<Subhead px={5} border='1px solid black'>
Hover on me
</Subhead>
</Cursor>
</Story>
)
}

storiesOf('Patterns', module).add(storyName, () => <CursorStory />)
2 changes: 2 additions & 0 deletions src/components/patterns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Footer from './Footer/Footer'
import Grid from './Grid'
import Layout from './Layout'
import Legend from './Legend/Legend'
import Cursor from './Cursor/Cursor'
import List from './List/List'
import Average from './Average/Average'
import Microlink from './Microlink/Microlink'
Expand All @@ -37,6 +38,7 @@ export {
ClusterMonitor,
CookiesPolicy,
CubeBackground,
Cursor,
DemoLinks,
DotsBackground,
Faq,
Expand Down

1 comment on commit 68538c9

@vercel
Copy link

@vercel vercel bot commented on 68538c9 Jun 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.