Initial commit
This commit is contained in:
		
							
								
								
									
										21
									
								
								src/components/AnimatedSection.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/components/AnimatedSection.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import { useRef } from 'react'
 | 
			
		||||
import { motion, useInView } from 'framer-motion'
 | 
			
		||||
 | 
			
		||||
export function AnimatedSection({ children }: { children: React.ReactNode }) {
 | 
			
		||||
  const ref = useRef(null)
 | 
			
		||||
  const isInView = useInView(ref, { once: true, margin: '-20% 0px -20% 0px' })
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <motion.section
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      initial={{ opacity: 0, y: 50 }}
 | 
			
		||||
      animate={{
 | 
			
		||||
        opacity: isInView ? 1 : 0,
 | 
			
		||||
        y: isInView ? 0 : 50,
 | 
			
		||||
      }}
 | 
			
		||||
      transition={{ duration: 0.5 }}
 | 
			
		||||
    >
 | 
			
		||||
      {children}
 | 
			
		||||
    </motion.section>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								src/components/Button.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/components/Button.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
import { Link } from 'react-router-dom'
 | 
			
		||||
import clsx from 'clsx'
 | 
			
		||||
 | 
			
		||||
const baseStyles = {
 | 
			
		||||
  solid:
 | 
			
		||||
    'inline-flex justify-center rounded-lg py-2 px-3 text-sm font-semibold transition-colors',
 | 
			
		||||
  outline:
 | 
			
		||||
    'inline-flex justify-center rounded-lg border py-[calc(--spacing(2)-1px)] px-[calc(--spacing(3)-1px)] text-sm transition-colors',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const variantStyles = {
 | 
			
		||||
  solid: {
 | 
			
		||||
    cyan: 'relative overflow-hidden bg-cyan-500 text-white before:absolute before:inset-0 active:before:bg-transparent hover:before:bg-white/10 active:bg-cyan-600 active:text-white/80 before:transition-colors',
 | 
			
		||||
    white:
 | 
			
		||||
      'bg-white text-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70',
 | 
			
		||||
    gray: 'bg-gray-800 text-white hover:bg-gray-900 active:bg-gray-800 active:text-white/80',
 | 
			
		||||
    green: 'bg-green-500 text-white hover:bg-green-600',
 | 
			
		||||
  },
 | 
			
		||||
  outline: {
 | 
			
		||||
    gray: 'border-gray-300 text-gray-700 hover:border-cyan-500 active:border-cyan-500',
 | 
			
		||||
    white: 'border-gray-300 text-white hover:border-cyan-500 active:border-cyan-500',
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ButtonProps = (
 | 
			
		||||
  | {
 | 
			
		||||
      variant?: 'solid'
 | 
			
		||||
      color?: keyof typeof variantStyles.solid
 | 
			
		||||
    }
 | 
			
		||||
  | {
 | 
			
		||||
      variant: 'outline'
 | 
			
		||||
      color?: keyof typeof variantStyles.outline
 | 
			
		||||
    }
 | 
			
		||||
) &
 | 
			
		||||
  (
 | 
			
		||||
    | (Omit<React.ComponentPropsWithoutRef<typeof Link>, 'color'> & { to: string; as?: 'link' })
 | 
			
		||||
    | (Omit<React.ComponentPropsWithoutRef<'a'>, 'color'> & { to: string; as: 'a' })
 | 
			
		||||
    | (Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> & {
 | 
			
		||||
        to?: undefined
 | 
			
		||||
        as?: undefined
 | 
			
		||||
      })
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
export function Button({ className, as, ...props }: ButtonProps) {
 | 
			
		||||
  props.variant ??= 'solid'
 | 
			
		||||
  props.color ??= 'gray'
 | 
			
		||||
 | 
			
		||||
  className = clsx(
 | 
			
		||||
    baseStyles[props.variant],
 | 
			
		||||
    props.variant === 'outline'
 | 
			
		||||
      ? variantStyles.outline[props.color]
 | 
			
		||||
      : props.variant === 'solid'
 | 
			
		||||
        ? variantStyles.solid[props.color]
 | 
			
		||||
        : undefined,
 | 
			
		||||
    className,
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  if (typeof props.to === 'undefined') {
 | 
			
		||||
    return <button className={className} {...props} />
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (as === 'a') {
 | 
			
		||||
    const { to, variant, color, ...rest } = props as any
 | 
			
		||||
    return <a className={className} href={to} {...rest} />
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return <Link className={className} {...props} />
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/components/CircleBackground.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/components/CircleBackground.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { useId } from 'react'
 | 
			
		||||
 | 
			
		||||
export function CircleBackground({
 | 
			
		||||
  color,
 | 
			
		||||
  ...props
 | 
			
		||||
}: React.ComponentPropsWithoutRef<'svg'> & {
 | 
			
		||||
  color: string
 | 
			
		||||
}) {
 | 
			
		||||
  let id = useId()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <svg
 | 
			
		||||
      viewBox="0 0 558 558"
 | 
			
		||||
      width="558"
 | 
			
		||||
      height="558"
 | 
			
		||||
      fill="none"
 | 
			
		||||
      aria-hidden="true"
 | 
			
		||||
      {...props}
 | 
			
		||||
    >
 | 
			
		||||
      <defs>
 | 
			
		||||
        <linearGradient
 | 
			
		||||
          id={id}
 | 
			
		||||
          x1="79"
 | 
			
		||||
          y1="16"
 | 
			
		||||
          x2="105"
 | 
			
		||||
          y2="237"
 | 
			
		||||
          gradientUnits="userSpaceOnUse"
 | 
			
		||||
        >
 | 
			
		||||
          <stop stopColor={color} />
 | 
			
		||||
          <stop offset="1" stopColor={color} stopOpacity="0" />
 | 
			
		||||
        </linearGradient>
 | 
			
		||||
      </defs>
 | 
			
		||||
      <path
 | 
			
		||||
        opacity=".2"
 | 
			
		||||
        d="M1 279C1 125.465 125.465 1 279 1s278 124.465 278 278-124.465 278-278 278S1 432.535 1 279Z"
 | 
			
		||||
        stroke={color}
 | 
			
		||||
      />
 | 
			
		||||
      <path
 | 
			
		||||
        d="M1 279C1 125.465 125.465 1 279 1"
 | 
			
		||||
        stroke={`url(#${id})`}
 | 
			
		||||
        strokeLinecap="round"
 | 
			
		||||
      />
 | 
			
		||||
    </svg>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/components/Container.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/components/Container.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
import clsx from 'clsx'
 | 
			
		||||
 | 
			
		||||
export function Container({
 | 
			
		||||
  className,
 | 
			
		||||
  ...props
 | 
			
		||||
}: React.ComponentPropsWithoutRef<'div'>) {
 | 
			
		||||
  return (
 | 
			
		||||
    <div
 | 
			
		||||
      className={clsx('mx-auto max-w-7xl px-6 lg:px-8', className)}
 | 
			
		||||
      {...props}
 | 
			
		||||
    />
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/components/CountUpNumber.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/components/CountUpNumber.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
import CountUp from 'react-countup'
 | 
			
		||||
 | 
			
		||||
interface CountUpNumberProps {
 | 
			
		||||
  end: number
 | 
			
		||||
  className?: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function CountUpNumber({ end, className }: CountUpNumberProps) {
 | 
			
		||||
  return (
 | 
			
		||||
    <CountUp
 | 
			
		||||
      end={end}
 | 
			
		||||
      duration={2.5}
 | 
			
		||||
      separator=","
 | 
			
		||||
      className={className}
 | 
			
		||||
    />
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/components/Footer.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/components/Footer.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
import { Link } from 'react-router-dom'
 | 
			
		||||
import { Container } from './Container'
 | 
			
		||||
 | 
			
		||||
export function Footer() {
 | 
			
		||||
  return (
 | 
			
		||||
    <footer className="border-t border-gray-200">
 | 
			
		||||
      <Container>
 | 
			
		||||
        <div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-8">
 | 
			
		||||
          <div>
 | 
			
		||||
            <div className="flex items-center text-gray-900">
 | 
			
		||||
              <img src="/src/images/logomark.svg" alt="Mycelium Logomark" className="h-20 w-20 flex-none" />
 | 
			
		||||
              <div className="ml-4">
 | 
			
		||||
                <p className="text-base font-semibold">Mycelium</p>
 | 
			
		||||
                <p className="mt-1 text-sm">Unleash the Power of Decentralized Networks</p>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <nav className="mt-10 flex gap-8">
 | 
			
		||||
              <Link to="/" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
 | 
			
		||||
                Home
 | 
			
		||||
              </Link>
 | 
			
		||||
              <Link to="/cloud" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
 | 
			
		||||
                Cloud
 | 
			
		||||
              </Link>
 | 
			
		||||
              <Link to="/network" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
 | 
			
		||||
                Network
 | 
			
		||||
              </Link>
 | 
			
		||||
              <Link to="/agents" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
 | 
			
		||||
                Agents
 | 
			
		||||
              </Link>
 | 
			
		||||
            </nav>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
 | 
			
		||||
            <div className="relative flex h-16 w-16 flex-none items-center justify-center">
 | 
			
		||||
              <img src="/src/images/github.svg" alt="GitHub" className="h-16 w-16" />
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className="ml-4 lg:w-72">
 | 
			
		||||
              <p className="text-base font-semibold text-gray-900">
 | 
			
		||||
                <a href="https://github.com/threefoldtech/mycelium/releases/" target="_blank" rel="noopener noreferrer">
 | 
			
		||||
                  <span className="absolute inset-0 sm:rounded-2xl" />
 | 
			
		||||
                  Download Mycelium
 | 
			
		||||
                </a>
 | 
			
		||||
              </p>
 | 
			
		||||
              <p className="mt-1 text-sm text-gray-700">
 | 
			
		||||
                Head to the GitHub to access the latest Mycelium builds for your devices.
 | 
			
		||||
              </p>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="flex flex-col items-center border-t border-gray-200 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
 | 
			
		||||
          <p className="mt-6 text-sm text-gray-500 md:mt-0">
 | 
			
		||||
            © Copyright{' '}
 | 
			
		||||
            <a href="https://www.threefold.io" target="_blank" rel="noopener noreferrer" className="hover:text-cyan-500 transition-colors">
 | 
			
		||||
              ThreeFold
 | 
			
		||||
            </a>{' '}
 | 
			
		||||
            {new Date().getFullYear()}. All rights reserved.
 | 
			
		||||
          </p>
 | 
			
		||||
        </div>
 | 
			
		||||
      </Container>
 | 
			
		||||
    </footer>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/components/Header.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/components/Header.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
import { Link } from 'react-router-dom'
 | 
			
		||||
import { Container } from './Container'
 | 
			
		||||
import { Button } from './Button'
 | 
			
		||||
 | 
			
		||||
export function Header() {
 | 
			
		||||
  return (
 | 
			
		||||
    <header>
 | 
			
		||||
      <nav>
 | 
			
		||||
        <Container className="relative z-50 flex justify-between py-8">
 | 
			
		||||
          <div className="relative z-10 flex items-center gap-16">
 | 
			
		||||
            <Link to="/" aria-label="Home">
 | 
			
		||||
              <img src="/src/images/logomark.svg" alt="Mycelium" className="h-10 w-auto" />
 | 
			
		||||
            </Link>
 | 
			
		||||
            <div className="hidden lg:flex lg:gap-10">
 | 
			
		||||
              <Link
 | 
			
		||||
                to="/"
 | 
			
		||||
                className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
 | 
			
		||||
              >
 | 
			
		||||
                Home
 | 
			
		||||
              </Link>
 | 
			
		||||
              <Link
 | 
			
		||||
                to="/cloud"
 | 
			
		||||
                className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
 | 
			
		||||
              >
 | 
			
		||||
                Cloud
 | 
			
		||||
              </Link>
 | 
			
		||||
              <Link
 | 
			
		||||
                to="/network"
 | 
			
		||||
                className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
 | 
			
		||||
              >
 | 
			
		||||
                Network
 | 
			
		||||
              </Link>
 | 
			
		||||
              <Link
 | 
			
		||||
                to="/agents"
 | 
			
		||||
                className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
 | 
			
		||||
              >
 | 
			
		||||
                Agents
 | 
			
		||||
              </Link>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div className="flex items-center gap-6">
 | 
			
		||||
            <div className="flex items-center gap-6 max-lg:hidden">
 | 
			
		||||
              <Button
 | 
			
		||||
                to="https://threefold.info/mycelium_network/docs/"
 | 
			
		||||
                variant="outline"
 | 
			
		||||
                as="a"
 | 
			
		||||
                target="_blank"
 | 
			
		||||
                rel="noopener noreferrer"
 | 
			
		||||
              >
 | 
			
		||||
                Docs
 | 
			
		||||
              </Button>
 | 
			
		||||
              <Button to="/download" variant="solid" color="cyan">
 | 
			
		||||
                Get Mycelium
 | 
			
		||||
              </Button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </Container>
 | 
			
		||||
      </nav>
 | 
			
		||||
    </header>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/components/Layout.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/components/Layout.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
import { Outlet } from 'react-router-dom'
 | 
			
		||||
import { Header } from './Header'
 | 
			
		||||
import { Footer } from './Footer'
 | 
			
		||||
 | 
			
		||||
export function Layout() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="bg-gray-50 antialiased" style={{ fontFamily: 'var(--font-inter)' }}>
 | 
			
		||||
      <Header />
 | 
			
		||||
      <main>
 | 
			
		||||
        <Outlet />
 | 
			
		||||
      </main>
 | 
			
		||||
      <Footer />
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								src/components/Logo.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/components/Logo.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
export function Logomark(props: React.ComponentPropsWithoutRef<'svg'>) {
 | 
			
		||||
  return (
 | 
			
		||||
    <svg
 | 
			
		||||
      xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
      xmlnsXlink="http://www.w3.org/1999/xlink"
 | 
			
		||||
      width="81"
 | 
			
		||||
      height="50"
 | 
			
		||||
      version="1"
 | 
			
		||||
      viewBox="0 0 60.75 37.5"
 | 
			
		||||
      {...props}
 | 
			
		||||
    >
 | 
			
		||||
      <defs>
 | 
			
		||||
        <filter id="a" width="100%" height="100%" x="0%" y="0%">
 | 
			
		||||
          <feColorMatrix
 | 
			
		||||
            colorInterpolationFilters="sRGB"
 | 
			
		||||
            values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
 | 
			
		||||
          />
 | 
			
		||||
        </filter>
 | 
			
		||||
        <filter id="b" width="100%" height="100%" x="0%" y="0%">
 | 
			
		||||
          <feColorMatrix
 | 
			
		||||
            colorInterpolationFilters="sRGB"
 | 
			
		||||
            values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.2126 0.7152 0.0722 0 0"
 | 
			
		||||
          />
 | 
			
		||||
        </filter>
 | 
			
		||||
        <clipPath id="c">
 | 
			
		||||
          <path d="M.277.309H60V37H.277Zm0 0" />
 | 
			
		||||
        </clipPath>
 | 
			
		||||
        <mask id="d">
 | 
			
		||||
          <g filter="url(#a)">
 | 
			
		||||
            <g filter="url(#b)" transform="matrix(.08765 0 0 .08811 .276 .26)">
 | 
			
		||||
              <image
 | 
			
		||||
                xlinkHref="/src/images/logomark.svg"
 | 
			
		||||
                width="684"
 | 
			
		||||
                height="420"
 | 
			
		||||
              />
 | 
			
		||||
            </g>
 | 
			
		||||
          </g>
 | 
			
		||||
        </mask>
 | 
			
		||||
      </defs>
 | 
			
		||||
      <g clipPath="url(#c)" mask="url(#d)">
 | 
			
		||||
        <image
 | 
			
		||||
          xlinkHref="/src/images/logomark.svg"
 | 
			
		||||
          width="684"
 | 
			
		||||
          height="420"
 | 
			
		||||
          transform="matrix(.08765 0 0 .08811 .276 .26)"
 | 
			
		||||
        />
 | 
			
		||||
      </g>
 | 
			
		||||
    </svg>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function Logo(props: React.ComponentPropsWithoutRef<'svg'>) {
 | 
			
		||||
  return (
 | 
			
		||||
    <svg
 | 
			
		||||
      xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
      width="160"
 | 
			
		||||
      height="40"
 | 
			
		||||
      viewBox="0 0 120 30"
 | 
			
		||||
      {...props}
 | 
			
		||||
    >
 | 
			
		||||
      <image xlinkHref="/src/images/mycelium.svg" width="120" height="30" />
 | 
			
		||||
    </svg>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/components/ui/Globe.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/components/ui/Globe.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
import { useEffect, useRef } from 'react'
 | 
			
		||||
import createGlobe from 'cobe'
 | 
			
		||||
 | 
			
		||||
export function Globe({ className }: { className?: string }) {
 | 
			
		||||
  const canvasRef = useRef<HTMLCanvasElement>(null)
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    let phi = 0
 | 
			
		||||
 | 
			
		||||
    if (!canvasRef.current) return
 | 
			
		||||
 | 
			
		||||
    const globe = createGlobe(canvasRef.current, {
 | 
			
		||||
      devicePixelRatio: 2,
 | 
			
		||||
      width: 600 * 2,
 | 
			
		||||
      height: 600 * 2,
 | 
			
		||||
      phi: 0,
 | 
			
		||||
      theta: 0,
 | 
			
		||||
      dark: 0,
 | 
			
		||||
      diffuse: 1.2,
 | 
			
		||||
      mapSamples: 16000,
 | 
			
		||||
      mapBrightness: 6,
 | 
			
		||||
      baseColor: [0.3, 0.3, 0.3],
 | 
			
		||||
      markerColor: [0.1, 0.8, 1],
 | 
			
		||||
      glowColor: [1, 1, 1],
 | 
			
		||||
      markers: [
 | 
			
		||||
        { location: [37.7595, -122.4367], size: 0.03 },
 | 
			
		||||
        { location: [40.7128, -74.006], size: 0.1 },
 | 
			
		||||
      ],
 | 
			
		||||
      onRender: (state) => {
 | 
			
		||||
        state.phi = phi
 | 
			
		||||
        phi += 0.01
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    return () => {
 | 
			
		||||
      globe.destroy()
 | 
			
		||||
    }
 | 
			
		||||
  }, [])
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <canvas
 | 
			
		||||
      ref={canvasRef}
 | 
			
		||||
      className={className}
 | 
			
		||||
      style={{ width: '100%', height: '100%', maxWidth: '100%', aspectRatio: 1 }}
 | 
			
		||||
    />
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user