nextjs based first commit

pull/49/head
sunface 4 years ago
parent 8f55735e4d
commit da00413171

@ -0,0 +1,7 @@
{
"extends": "../eslintrc.json",
"parserOptions": {
"project": "tsconfig.json"
}
}

3
.gitignore vendored

@ -1 +1,4 @@
node_modules
yarn-error.log
.next/
.DS_Store

@ -0,0 +1,63 @@
const baseUrl = "https://github.com/imdotdev/im.dev"
const siteConfig = {
copyright: `Copyright © ${new Date().getFullYear()} Segun Adebayo. All Rights Reserved.`,
algolia: {
apiKey: "df1dcc41f7b8e5d68e73dd56d1e19701",
indexName: "chakra-ui",
inputSelector: "#algolia-search",
},
author: {
name: "Segun Adebayo",
github: "https://github.com/segunadebayo",
twitter: "https://twitter.com/thesegunadebayo",
linkedin: "https://linkedin.com/in/thesegunadebayo",
email: "sage@adebayosegun.com",
},
repo: {
url: baseUrl,
editUrl: `${baseUrl}/edit/develop/website`,
blobUrl: `${baseUrl}/blob/develop`,
},
openCollective: {
url: "https://opencollective.com/chakra-ui",
},
discord: {
url: "https://discord.gg/dQHfcWF",
},
seo: {
title: "im.dev",
titleTemplate: "%s - im.dev",
description:
"千挑万选,只为把高质量的内容呈现给你。我是开发,我为技术代言",
siteUrl: "https://im.dev",
openGraph: {
type: "website",
locale: "en_US",
url: "https://chakra-ui.com",
title: "Chakra UI",
description:
"Simple, Modular and Accessible UI Components for your React Applications.",
site_name:
"Chakra UI: Simple, Modular and Accessible UI Components for your React Applications.",
images: [
{
url: "/og-image.png",
width: 1240,
height: 480,
alt:
"Chakra UI: Simple, Modular and Accessible UI Components for your React Applications.",
},
{
url: "/twitter-og-image.png",
width: 1012,
height: 506,
alt:
"Chakra UI: Simple, Modular and Accessible UI Components for your React Applications.",
},
],
},
},
}
export default siteConfig

@ -0,0 +1,48 @@
import React from "react"
import { Box, Icon, Text, Stack, Link, chakra } from "@chakra-ui/react"
import { IoLogoTwitter, IoLogoLinkedin } from "react-icons/io"
import { MdEmail } from "react-icons/md"
import { DiGithubBadge } from "react-icons/di"
type FooterLinkProps = {
icon?: React.ElementType
href?: string
label?: string
}
const FooterLink: React.FC<FooterLinkProps> = ({ icon, href, label }) => (
<Link display="inline-block" href={href} aria-label={label} isExternal>
<Icon as={icon} fontSize="xl" color="gray.400" />
</Link>
)
const links = [
{
icon: DiGithubBadge,
label: "GitHub",
href: "https://github.com/imdotdev/imdev",
},
{
icon: MdEmail,
label: "Email",
href: "mailto:cto@188.com",
},
]
export const Footer = () => (
<Box as="footer" mt={12} textAlign="center">
<Text fontSize="sm" display="flex" alignItems="center" justifyContent="center">
<span>Proudly made in </span>
<chakra.span fontSize="24px" ml="2">🇨🇳</chakra.span>
<chakra.span ml="2">by codecc.com</chakra.span>
</Text>
<Stack mt={4} direction="row" spacing="12px" justify="center">
{links.map((link) => (
<FooterLink key={link.href} {...link} />
))}
</Stack>
</Box>
)
export default Footer

@ -0,0 +1,184 @@
import {
Box,
BoxProps,
Center,
CloseButton,
Flex,
HStack,
IconButton,
IconButtonProps,
useBreakpointValue,
useColorModeValue,
useUpdateEffect,
} from "@chakra-ui/react"
import { AnimatePresence, motion, useElementScroll } from "framer-motion"
import useRouteChanged from "src/hooks/use-route-changed"
import NextLink from "next/link"
import { useRouter } from "next/router"
import * as React from "react"
import { AiOutlineMenu } from "react-icons/ai"
import { RemoveScroll } from "react-remove-scroll"
import Logo from "src/components/logo"
function NavLink({ href, children }) {
const { pathname } = useRouter()
const [, group] = href.split("/")
const isActive = pathname.includes(group)
return (
<NextLink href={href}>
<Center
flex="1"
minH="40px"
as="button"
rounded="md"
transition="0.2s all"
fontWeight={isActive ? "semibold" : "medium"}
bg={isActive ? "teal.400" : undefined}
borderWidth={isActive ? undefined : "1px"}
color={isActive ? "white" : undefined}
_hover={{
bg: isActive
? "teal.500"
: useColorModeValue("gray.100", "whiteAlpha.100"),
}}
>
{children}
</Center>
</NextLink>
)
}
interface MobileNavContentProps {
isOpen?: boolean
onClose?: () => void
}
export function MobileNavContent(props: MobileNavContentProps) {
const { isOpen, onClose } = props
const closeBtnRef = React.useRef<HTMLButtonElement>()
const { pathname } = useRouter()
useRouteChanged(onClose)
/**
* Scenario: Menu is open on mobile, and user resizes to desktop/tablet viewport.
* Result: We'll close the menu
*/
const showOnBreakpoint = useBreakpointValue({ base: true, lg: false })
React.useEffect(() => {
if (showOnBreakpoint == false) {
onClose()
}
}, [showOnBreakpoint])
useUpdateEffect(() => {
if (isOpen) {
requestAnimationFrame(() => {
closeBtnRef.current?.focus()
})
}
}, [isOpen])
const [shadow, setShadow] = React.useState<string>()
return (
<AnimatePresence>
{isOpen && (
<RemoveScroll forwardProps>
<motion.div
transition={{ duration: 0.08 }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Flex
direction="column"
w="100%"
bg={useColorModeValue("white", "gray.800")}
h="100vh"
overflow="auto"
pos="absolute"
top="0"
left="0"
zIndex={20}
pb="8"
>
<Box>
<Flex justify="space-between" px="6" pt="5" pb="4">
<Logo />
<HStack spacing="5">
<CloseButton ref={closeBtnRef} onClick={onClose} />
</HStack>
</Flex>
<Box px="6" pb="6" pt="2" shadow={shadow}>
<HStack>
<NavLink href="/docs/getting-started">Docs</NavLink>
<NavLink href="/guides/integrations/with-cra">
Guides
</NavLink>
<NavLink href="/team">Team</NavLink>
</HStack>
</Box>
</Box>
<ScrollView
onScroll={(scrolled) => {
setShadow(scrolled ? "md" : undefined)
}}
>
</ScrollView>
</Flex>
</motion.div>
</RemoveScroll>
)}
</AnimatePresence>
)
}
const ScrollView = (props: BoxProps & { onScroll?: any }) => {
const { onScroll, ...rest } = props
const [y, setY] = React.useState(0)
const elRef = React.useRef<any>()
const { scrollY } = useElementScroll(elRef)
React.useEffect(() => {
return scrollY.onChange(() => setY(scrollY.get()))
}, [scrollY])
useUpdateEffect(() => {
onScroll?.(y > 5 ? true : false)
}, [y])
return (
<Box
ref={elRef}
flex="1"
id="routes"
overflow="auto"
px="6"
pb="6"
{...rest}
/>
)
}
export const MobileNavButton = React.forwardRef(
(props: IconButtonProps, ref: React.Ref<any>) => {
return (
<IconButton
ref={ref}
display={{ base: "flex", md: "none" }}
aria-label="Open menu"
fontSize="20px"
color={useColorModeValue("gray.800", "inherit")}
variant="ghost"
icon={<AiOutlineMenu />}
{...props}
/>
)
},
)

@ -0,0 +1,186 @@
import {
chakra,
Flex,
Box,
HStack,
Icon,
IconButton,
Link,
useColorMode,
useColorModeValue,
useDisclosure,
useUpdateEffect,
Menu,
MenuButton,
MenuList,
MenuItem,
MenuDivider,
Image
} from "@chakra-ui/react"
import siteConfig from "configs/site-config"
import { useViewportScroll } from "framer-motion"
import NextLink from "next/link"
import React from "react"
import { FaMoon, FaSun, FaUserAlt, FaRegSun, FaSignOutAlt, FaRegBookmark, FaChartBar, FaHome } from "react-icons/fa"
import Logo, { LogoIcon } from "src/components/logo"
import { MobileNavButton, MobileNavContent } from "./mobile-nav"
import AlgoliaSearch from "src/components/search/algolia-search"
const DiscordIcon = (props) => (
<svg viewBox="0 0 146 146" {...props}>
<path
fill="currentColor"
d="M107.75 125.001s-4.5-5.375-8.25-10.125c16.375-4.625 22.625-14.875 22.625-14.875-5.125 3.375-10 5.75-14.375 7.375-6.25 2.625-12.25 4.375-18.125 5.375-12 2.25-23 1.625-32.375-.125-7.125-1.375-13.25-3.375-18.375-5.375-2.875-1.125-6-2.5-9.125-4.25-.375-.25-.75-.375-1.125-.625-.25-.125-.375-.25-.5-.375-2.25-1.25-3.5-2.125-3.5-2.125s6 10 21.875 14.75c-3.75 4.75-8.375 10.375-8.375 10.375-27.625-.875-38.125-19-38.125-19 0-40.25 18-72.875 18-72.875 18-13.5 35.125-13.125 35.125-13.125l1.25 1.5c-22.5 6.5-32.875 16.375-32.875 16.375s2.75-1.5 7.375-3.625c13.375-5.875 24-7.5 28.375-7.875.75-.125 1.375-.25 2.125-.25 7.625-1 16.25-1.25 25.25-.25 11.875 1.375 24.625 4.875 37.625 12 0 0-9.875-9.375-31.125-15.875l1.75-2S110 19.626 128 33.126c0 0 18 32.625 18 72.875 0 0-10.625 18.125-38.25 19zM49.625 66.626c-7.125 0-12.75 6.25-12.75 13.875s5.75 13.875 12.75 13.875c7.125 0 12.75-6.25 12.75-13.875.125-7.625-5.625-13.875-12.75-13.875zm45.625 0c-7.125 0-12.75 6.25-12.75 13.875s5.75 13.875 12.75 13.875c7.125 0 12.75-6.25 12.75-13.875s-5.625-13.875-12.75-13.875z"
fillRule="nonzero"
/>
</svg>
)
const GithubIcon = (props) => (
<svg viewBox="0 0 20 20" {...props}>
<path
fill="currentColor"
d="M10 0a10 10 0 0 0-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.46-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.52 2.34 1.08 2.91.83.1-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.1.39-1.99 1.03-2.69a3.6 3.6 0 0 1 .1-2.64s.84-.27 2.75 1.02a9.58 9.58 0 0 1 5 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.4.1 2.64.64.7 1.03 1.6 1.03 2.69 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.75c0 .26.18.58.69.48A10 10 0 0 0 10 0"
/>
</svg>
)
function HeaderContent() {
const mobileNav = useDisclosure()
const { toggleColorMode: toggleMode } = useColorMode()
const text = useColorModeValue("dark", "light")
const SwitchIcon = useColorModeValue(FaMoon, FaSun)
const mobileNavBtnRef = React.useRef<HTMLButtonElement>()
useUpdateEffect(() => {
mobileNavBtnRef.current?.focus()
}, [mobileNav.isOpen])
return (
<>
<Flex w="100%" h="100%" align="center" justify="space-between" px={{ base: "4", md: "6" }}>
<Flex align="center">
<NextLink href="/" passHref>
<chakra.a display="block" aria-label="Chakra UI, Back to homepage">
<Logo display={{ base: "none", md: "block" }} />
<Box minW="3rem" display={{ base: "block", md: "none" }}>
<LogoIcon />
</Box>
</chakra.a>
</NextLink>
<HStack spacing="5" display={{ base: "none", md: "flex" }} ml="16" fontSize="17px">
<Link>Home</Link>
<Link>Tags</Link>
</HStack>
</Flex>
<Flex
w="100%"
maxW="724px"
align="center"
color="gray.400"
>
<AlgoliaSearch />
<HStack spacing="5" display={{ base: "none", md: "flex" }}>
<Link
isExternal
aria-label="Go to Chakra UI GitHub page"
href={siteConfig.repo.url}
>
<Icon
as={GithubIcon}
display="block"
transition="color 0.2s"
w="5"
h="5"
_hover={{ color: "gray.600" }}
/>
</Link>
</HStack>
<IconButton
size="md"
fontSize="lg"
aria-label={`Switch to ${text} mode`}
variant="ghost"
color="current"
ml={{ base: "0", md: "3" }}
onClick={toggleMode}
icon={<SwitchIcon />}
/>
<Menu>
<MenuButton
as={IconButton}
bg="transparent"
icon={<FaUserAlt />}
aria-label="Options"
ml={{ base: "0", md: "2" }}
/>
<MenuList>
<MenuItem>
<Image
boxSize="2rem"
borderRadius="full"
src="https://placekitten.com/100/100"
alt="Fluffybuns the destroyer"
mr="12px"
/>
<span>Sunface</span>
</MenuItem>
<MenuDivider />
<MenuItem icon={<FaChartBar fontSize="16" />}>Dashboard</MenuItem>
<MenuItem icon={<FaRegBookmark fontSize="16" />}>Bookmarks</MenuItem>
<MenuDivider />
<MenuItem icon={<FaRegSun fontSize="16" />}>Account Settings</MenuItem>
<MenuItem icon={<FaSignOutAlt fontSize="16" />}>Log out</MenuItem>
</MenuList>
</Menu>
<MobileNavButton
ref={mobileNavBtnRef}
aria-label="Open Menu"
onClick={mobileNav.onOpen}
/>
</Flex>
</Flex>
<MobileNavContent isOpen={mobileNav.isOpen} onClose={mobileNav.onClose} />
</>
)
}
function Header(props) {
const bg = useColorModeValue("white", "gray.800")
const ref = React.useRef<HTMLHeadingElement>()
const [y, setY] = React.useState(0)
const { height = 0 } = ref.current?.getBoundingClientRect() ?? {}
const { scrollY } = useViewportScroll()
React.useEffect(() => {
return scrollY.onChange(() => setY(scrollY.get()))
}, [scrollY])
return (
<chakra.header
ref={ref}
shadow={y > height ? "sm" : undefined}
transition="box-shadow 0.2s"
pos="fixed"
top="0"
zIndex="3"
bg={bg}
left="0"
right="0"
borderTop="4px solid"
borderTopColor="teal.400"
width="full"
{...props}
>
<chakra.div height="4.5rem" mx="auto" maxW="1200px">
<HeaderContent />
</chakra.div>
</chakra.header>
)
}
export default Header

@ -0,0 +1,66 @@
import { Badge, Box, chakra } from "@chakra-ui/react"
import { SkipNavContent, SkipNavLink } from "@chakra-ui/skip-nav"
import Container from "components/container"
import Footer from "./footer"
import Nav from "./nav"
import SEO from "components/seo"
import { useRouter } from "next/router"
import * as React from "react"
import PageTransition from "src/components/page-transition"
import siteConfig from "configs/site-config"
function useHeadingFocusOnRouteChange() {
const router = useRouter()
React.useEffect(() => {
const onRouteChange = () => {
const [heading] = Array.from(document.getElementsByTagName("h1"))
heading?.focus()
}
router.events.on("routeChangeComplete", onRouteChange)
return () => {
router.events.off("routeChangeComplete", onRouteChange)
}
}, [])
}
interface PageContainerProps {
children: React.ReactNode
}
function PageContainer(props: PageContainerProps) {
const { children } = props
useHeadingFocusOnRouteChange()
return (
<>
<SEO
title={siteConfig.seo.title}
description={siteConfig.seo.description}
/>
<SkipNavLink zIndex={20}>Skip to Content</SkipNavLink>
<Nav />
<Container as="main" className="main-content">
<Box display={{ base: "block", md: "flex" }}>
<div style={{ flex: 1 }}>
<SkipNavContent />
<Box
id="content"
pt={3}
px={5}
mt="4.5rem"
mx="auto"
>
<PageTransition>
{children}
</PageTransition>
</Box>
<Footer />
</div>
</Box>
</Container>
</>
)
}
export default PageContainer

2
next-env.d.ts vendored

@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

@ -0,0 +1,18 @@
async function redirect() {
return [
{
source: "/discord",
destination: "https://discord.gg/dQHfcWF",
permanent: true,
},
// GENERAL
{
source: "/getting-started",
destination: "/docs/getting-started",
permanent: true,
}
]
}
module.exports = redirect

@ -0,0 +1,23 @@
const withPlugins = require("next-compose-plugins")
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
})
const defaultConfig = {
target: "serverless",
webpack: (config) => ({
...config,
externals: [...config.externals],
}),
experimental: {
optimizeFonts: true,
modern: true,
},
redirects: require("./next-redirect"),
}
module.exports = withPlugins(
[withBundleAnalyzer],
defaultConfig,
)

@ -0,0 +1,42 @@
{
"name": "im.dev",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev -p 4004",
"build": "next build",
"start": "next start",
"test": "jest",
"clean": "rm -rf .next",
"analyze": "ANALYZE=true next build"
},
"dependencies": {
"@chakra-ui/icons": "^1.0.4",
"@chakra-ui/props-docs": "1.0.13",
"@chakra-ui/react": "1.2.1",
"@chakra-ui/skip-nav": "^1.1.0",
"@chakra-ui/theme-tools": "1.0.3",
"@chakra-ui/utils": "1.1.0",
"@emotion/react": "^11.1.4",
"@emotion/styled": "^11.0.0",
"@octokit/rest": "^18.0.12",
"date-fns": "^2.16.1",
"framer-motion": "^3.1.1",
"next": "^10.0.4",
"next-seo": "^4.17.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-icons": "^4.1.0",
"docsearch.js": "^2.6.3",
"@docsearch/react": "^1.0.0-alpha.27"
},
"devDependencies": {
"@next/bundle-analyzer": "^10.0.4",
"@types/node": "^14.14.19",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"next-compose-plugins": "^2.2.1",
"typescript": "^4.1.3"
}
}

@ -0,0 +1,37 @@
import { trackPageview } from "analytics/track-event"
import { DefaultSeo } from "next-seo"
import Head from "next/head"
import Router from "next/router"
import React from "react"
import { ChakraProvider } from "@chakra-ui/react"
import theme from "theme"
import FontFace from "src/components/font-face"
import { getSeo } from "utils/seo"
Router.events.on("routeChangeComplete", (url) => {
trackPageview(url)
})
const App = ({ Component, pageProps }) => {
const seo = getSeo({ omitOpenGraphImage: false })
return (
<>
<Head>
<meta content="IE=edge" httpEquiv="X-UA-Compatible" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://static.cloudflareinsights.com" />
<meta name="theme-color" content="#319795" />
</Head>
<DefaultSeo {...seo} />
<ChakraProvider theme={theme}>
<Component {...pageProps} />
</ChakraProvider>
<FontFace />
</>
)
}
export default App

@ -0,0 +1,23 @@
import { chakra } from "@chakra-ui/react"
import Container from "components/container"
import SEO from "components/seo"
import siteConfig from "configs/site-config"
import Nav from "layouts/nav"
import PageContainer from "layouts/page-container"
import React from "react"
const HomePage = () => (
<>
<SEO
title={siteConfig.seo.title}
description={siteConfig.seo.description}
/>
<Nav />
<PageContainer>
<chakra.h1>NOT FOUND</chakra.h1>
<p>You just hit a route that doesn&#39;t exist... the sadness.</p>
</PageContainer>
</>
)
export default HomePage

Binary file not shown.

Binary file not shown.

@ -0,0 +1,22 @@
import React from "react"
const GAScript = () => (
<>
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GA_TRACKING_ID}`}
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${process.env.GA_TRACKING_ID}');
`,
}}
/>
</>
)
export default GAScript

@ -0,0 +1,33 @@
export function trackPageview(url: string) {
const _window = window as typeof window & { gtag: any }
try {
_window.gtag("config", process.env.GA_TRACKING_ID, {
page_location: url,
page_title: document.title,
})
} catch (err) {
console.error("Failed sending metrics", err)
}
}
type TrackEventOptions = {
action: any
category: string
label: string
value: string
}
export function trackEvent(options: TrackEventOptions) {
const { action, category, label, value } = options
const _window = window as typeof window & { gtag: any }
try {
_window.gtag("event", action, {
event_category: category,
event_label: label,
value,
})
} catch (err) {
console.error("Failed sending metrics", err)
}
}

@ -0,0 +1,16 @@
import React from "react"
import { Box, BoxProps } from "@chakra-ui/react"
export const Container = (props: BoxProps) => (
<Box
w="full"
pb="12"
pt="3"
maxW="1200px"
mx="auto"
px={{ base: "4", md: "8" }}
{...props}
/>
)
export default Container

@ -0,0 +1,80 @@
const FontFace = () => (
<style jsx global>
{`
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 100;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 200;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 300;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 400;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 500;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 600;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 700;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 800;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 900;
font-display: block;
src: url(/fonts/Inter.woff2) format("woff2");
}
`}
</style>
)
export default FontFace

@ -0,0 +1,74 @@
import { chakra, HTMLChakraProps, useColorModeValue } from "@chakra-ui/react"
import React from "react"
export const Logo = (props: HTMLChakraProps<"svg">) => {
const fill = useColorModeValue("#2D3748", "#fff")
return (
<chakra.svg
height="8"
width="auto"
viewBox="0 0 998 257"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M388.5 115.302c17.612 0 25.466 11.424 28.084 21.658l24.752-9.044c-4.76-18.564-21.896-38.08-53.074-38.08-33.32 0-59.262 25.704-59.262 61.404 0 35.224 25.942 61.642 59.976 61.642 30.464 0 47.838-19.754 53.312-37.842l-24.276-8.806c-2.618 8.806-10.948 21.42-29.036 21.42-17.374 0-32.368-13.09-32.368-36.414s14.994-35.938 31.892-35.938zM484.894 141.244c.476-14.756 8.806-26.18 24.038-26.18 17.374 0 23.8 11.424 23.8 25.704v68.544h27.608v-73.304c0-25.466-13.804-45.934-42.364-45.934-12.138 0-25.228 4.284-33.082 14.518V37h-27.608v172.312h27.608v-68.068zM577.29 177.896c0 18.326 14.994 34.986 39.27 34.986 18.802 0 30.226-9.52 35.7-18.326 0 9.282.952 14.042 1.19 14.756h25.704c-.238-1.19-1.428-8.092-1.428-18.564v-57.596c0-23.086-13.566-43.316-49.266-43.316-28.56 0-46.648 17.85-48.79 37.842l25.228 5.712c1.19-11.662 9.282-20.944 23.8-20.944 15.232 0 21.896 7.854 21.896 17.612 0 4.046-1.904 7.378-8.568 8.33l-29.75 4.522c-19.754 2.856-34.986 14.28-34.986 34.986zm44.506 13.328c-10.948 0-16.898-7.14-16.898-14.994 0-9.52 6.902-14.28 15.47-15.708L650.594 156v5.236c0 22.61-13.328 29.988-28.798 29.988zM810.108 93.406h-36.652l-44.506 46.886V37h-27.37v172.312h27.37v-32.368l14.28-14.994 34.034 47.362h33.796l-48.552-66.878 47.6-49.028zM889.349 92.692c-1.19-.238-4.046-.714-7.378-.714-15.232 0-28.084 7.378-33.558 19.992V93.406h-26.894v115.906h27.608v-55.216c0-21.658 9.758-34.034 31.178-34.034 2.856 0 5.95.238 9.044.714V92.692zM895.968 177.896c0 18.326 14.994 34.986 39.27 34.986 18.802 0 30.226-9.52 35.7-18.326 0 9.282.952 14.042 1.19 14.756h25.704c-.238-1.19-1.428-8.092-1.428-18.564v-57.596c0-23.086-13.566-43.316-49.266-43.316-28.56 0-46.648 17.85-48.79 37.842l25.228 5.712c1.19-11.662 9.282-20.944 23.8-20.944 15.232 0 21.896 7.854 21.896 17.612 0 4.046-1.904 7.378-8.568 8.33l-29.75 4.522c-19.754 2.856-34.986 14.28-34.986 34.986zm44.506 13.328c-10.948 0-16.898-7.14-16.898-14.994 0-9.52 6.902-14.28 15.47-15.708L969.272 156v5.236c0 22.61-13.328 29.988-28.798 29.988z"
fill={fill}
/>
<rect width="257" height="257" rx="128.5" fill="url(#logo)" />
<path
d="M69.558 133.985l87.592-86.9891c1.636-1.6251 4.27.3525 3.165 2.377l-32.601 59.7521c-.728 1.332.237 2.958 1.755 2.958h56.34c1.815 0 2.691 2.223 1.364 3.462l-98.7278 92.142c-1.7702 1.652-4.4051-.676-2.9839-2.636l46.7357-64.473c.958-1.322.014-3.174-1.619-3.174H70.9673c-1.7851 0-2.6759-2.161-1.4093-3.419z"
fill="#fff"
/>
<defs>
<linearGradient
id="logo"
x1="128.5"
x2="128.5"
y2="257"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#7BCBD4" />
<stop offset="1" stopColor="#29C6B7" />
</linearGradient>
</defs>
</chakra.svg>
)
}
export const LogoIcon = (props: HTMLChakraProps<"svg">) => {
const fill = useColorModeValue("#2D3748", "#fff")
return (
<chakra.svg
height="8"
width="auto"
viewBox="0 0 257 257"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<rect width="257" height="257" rx="128.5" fill="url(#mark)" />
<path
d="M69.558 133.985l87.592-86.9891c1.636-1.6251 4.27.3525 3.165 2.377l-32.601 59.7521c-.728 1.332.237 2.958 1.755 2.958h56.34c1.815 0 2.691 2.223 1.364 3.462l-98.7278 92.142c-1.7702 1.652-4.4051-.676-2.9839-2.636l46.7357-64.473c.958-1.322.014-3.174-1.619-3.174H70.9673c-1.7851 0-2.6759-2.161-1.4093-3.419z"
fill="#fff"
/>
<defs>
<linearGradient
id="mark"
x1="128.5"
x2="128.5"
y2="257"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#7BCBD4" />
<stop offset="1" stopColor="#29C6B7" />
</linearGradient>
</defs>
</chakra.svg>
)
}
export default Logo

@ -0,0 +1,12 @@
import * as React from "react"
import { HTMLMotionProps, motion } from "framer-motion"
const PageTransition = (props: HTMLMotionProps<"div">) => (
<motion.div
initial={{ y: -16, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
{...props}
/>
)
export default PageTransition

@ -0,0 +1,168 @@
import { SearchIcon } from "@chakra-ui/icons"
import {
chakra,
HStack,
HTMLChakraProps,
Kbd,
Portal,
Text,
useColorModeValue,
VisuallyHidden,
} from "@chakra-ui/react"
import { DocSearchModal, useDocSearchKeyboardEvents } from "@docsearch/react"
import Head from "next/head"
import Link from "next/link"
import { useRouter } from "next/router"
import * as React from "react"
import SearchStyle from "./search.styles"
const ACTION_KEY_DEFAULT = ["Ctrl", "Control"]
const ACTION_KEY_APPLE = ["⌘", "Command"]
function Hit(props: any) {
const { hit, children } = props
return (
<Link href={hit.url} passHref>
<a>{children}</a>
</Link>
)
}
export const SearchButton = React.forwardRef(function SearchButton(
props: HTMLChakraProps<"button">,
ref: React.Ref<HTMLButtonElement>,
) {
const [actionKey, setActionKey] = React.useState<string[]>(ACTION_KEY_APPLE)
React.useEffect(() => {
if (typeof navigator === "undefined") return
const isMac = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)
if (!isMac) {
setActionKey(ACTION_KEY_DEFAULT)
}
}, [])
return (
<chakra.button
flex="1"
type="button"
role="search"
mr="6"
ref={ref}
lineHeight="1.2"
w="100%"
bg={useColorModeValue("white", "gray.700")}
whiteSpace="nowrap"
display={{ base: "none", sm: "flex" }}
alignItems="center"
color="gray.400"
py="3"
px="4"
outline="0"
_focus={{ shadow: "outline" }}
shadow="base"
rounded="md"
{...props}
>
<SearchIcon />
<HStack w="full" ml="3" spacing="4px">
<Text textAlign="left" flex="1">
Search the docs
</Text>
<HStack spacing="4px">
<VisuallyHidden>Press </VisuallyHidden>
<Kbd color="gray.500" rounded="2px">
<chakra.div
as="abbr"
title={actionKey[1]}
textDecoration="none !important"
>
{ACTION_KEY_APPLE[0]}
</chakra.div>
</Kbd>
<VisuallyHidden> and </VisuallyHidden>
<Kbd color="gray.500" rounded="2px">
K
</Kbd>
<VisuallyHidden> to search</VisuallyHidden>
</HStack>
</HStack>
</chakra.button>
)
})
function AlgoliaSearch() {
const router = useRouter()
const [isOpen, setIsOpen] = React.useState(false)
const searchButtonRef = React.useRef()
const [initialQuery, setInitialQuery] = React.useState(null)
const onOpen = React.useCallback(() => {
setIsOpen(true)
}, [setIsOpen])
const onClose = React.useCallback(() => {
setIsOpen(false)
}, [setIsOpen])
const onInput = React.useCallback(
(e) => {
setIsOpen(true)
setInitialQuery(e.key)
},
[setIsOpen, setInitialQuery],
)
useDocSearchKeyboardEvents({
isOpen,
onOpen,
onClose,
onInput,
searchButtonRef,
})
return (
<>
<Head>
<link
rel="preconnect"
href="https://BH4D9OD16A-dsn.algolia.net"
crossOrigin="true"
/>
</Head>
<SearchStyle />
<SearchButton onClick={onOpen} ref={searchButtonRef} />
{isOpen && (
<Portal>
<DocSearchModal
placeholder="Search the docs"
initialQuery={initialQuery}
initialScrollY={window.scrollY}
onClose={onClose}
indexName="chakra-ui"
apiKey="df1dcc41f7b8e5d68e73dd56d1e19701"
appId="BH4D9OD16A"
//@ts-expect-error
navigator={{
navigate({ suggestionUrl }) {
setIsOpen(false)
router.push(suggestionUrl)
},
}}
hitComponent={Hit}
transformItems={(items) => {
return items.map((item) => {
const a = document.createElement("a")
a.href = item.url
const hash = a.hash === "#content-wrapper" ? "" : a.hash
item.url = `${a.pathname}${hash}`
return item
})
}}
/>
</Portal>
)}
</>
)
}
export default AlgoliaSearch

@ -0,0 +1,467 @@
import { Global, css } from "@emotion/react"
const SearchStyle = () => (
<Global
styles={(theme: any) => css`
.DocSearch--active {
overflow: hidden !important;
}
.DocSearch-Container {
height: 100vh;
left: 0;
position: fixed;
top: 0;
width: 100vw;
z-index: 200;
display: flex;
flex-direction: column;
background: rgba(0, 0, 0, 0.25);
padding: 1rem;
@media (min-width: 640px) {
padding: 1.5rem;
}
@media (min-width: 768px) {
padding: 10vh;
}
@media (min-width: 1024px) {
padding: 12vh;
}
}
.DocSearch-LoadingIndicator svg {
display: none;
}
.DocSearch-LoadingIndicator {
display: none;
width: 1.5rem;
height: 1.5rem;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='9' stroke-width='2' stroke='%23#319795' /%3E%3Cpath d='M3,12a9,9 0 1,0 18,0a9,9 0 1,0 -18,0' stroke-width='2' stroke='%2306b6d4' stroke-dasharray='56.5486677646' stroke-dashoffset='37.6991118431' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-size: 100% 100%;
}
.DocSearch-Container--Stalled .DocSearch-LoadingIndicator {
display: block;
}
.DocSearch-Modal {
margin: 0 auto;
width: 100%;
max-width: 47.375rem;
display: flex;
flex-direction: column;
min-height: 0;
border-radius: 0.75rem;
box-shadow: ${theme.shadows.lg};
background: white;
.chakra-ui-dark & {
background: ${theme.colors.gray["700"]};
}
}
.DocSearch-SearchBar {
flex: none;
border-bottom: 1px solid ${theme.colors.gray["200"]};
position: relative;
z-index: 1;
display: flex;
align-items: center;
margin: 0 1.5rem;
.chakra-ui-dark & {
border-bottom-color: ${theme.colors.gray["600"]};
}
}
.DocSearch-Form {
flex: auto;
display: flex;
align-items: center;
min-width: 0;
}
.DocSearch-Dropdown {
flex: auto;
border-bottom-left-radius: 1rem;
border-bottom-right-radius: 1rem;
padding: 0 1.5rem 1.5rem;
overflow: auto;
}
.DocSearch-MagnifierLabel {
flex: none;
width: 1.5rem;
height: 1.5rem;
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z' stroke='%23319795' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
}
.DocSearch-MagnifierLabel svg {
display: none;
}
.DocSearch-Container--Stalled .DocSearch-MagnifierLabel {
display: none;
}
.DocSearch-Input {
appearance: none;
background: transparent;
height: 4.5rem;
font-size: 1rem;
font-weight: 500;
color: black;
margin-left: 1rem;
margin-right: 1rem;
flex: auto;
min-width: 0;
.chakra-ui-dark & {
color: white;
}
}
.DocSearch-Input:focus {
outline: 2px dotted transparent;
}
.DocSearch-Input::-webkit-search-cancel-button,
.DocSearch-Input::-webkit-search-decoration,
.DocSearch-Input::-webkit-search-results-button,
.DocSearch-Input::-webkit-search-results-decoration {
display: none;
}
.DocSearch-Reset {
display: none;
}
.DocSearch-Reset::before {
content: "esc";
}
.DocSearch-Cancel {
flex: none;
font-size: 0;
border-radius: 0.375rem;
background-color: ${theme.colors.gray["50"]};
border: 1px solid ${theme.colors.gray["300"]};
padding: 0.125rem 0.375rem;
.chakra-ui-dark & {
background-color: ${theme.colors.gray["700"]};
border-color: ${theme.colors.gray["600"]};
}
}
.DocSearch-Cancel::before {
content: "esc";
color: ${theme.colors.gray["400"]};
font-size: 0.875rem;
line-height: 1.25rem;
}
.DocSearch-Reset svg {
display: none;
}
.DocSearch-Hit-source {
line-height: 1.5rem;
font-weight: 600;
color: ${theme.colors.gray["600"]};
margin-top: 1.5rem;
margin-bottom: 1rem;
.chakra-ui-dark & {
color: ${theme.colors.gray["400"]};
}
}
.DocSearch-Hit-Container {
display: flex;
align-items: center;
height: 4rem;
}
.DocSearch-Hit-Tree {
display: none;
}
.DocSearch-Hit-icon {
flex: none;
margin-right: 0.875rem;
}
.DocSearch-Hit-icon path {
stroke-width: 2px;
stroke: #71717a;
}
.DocSearch-Hit[aria-selected="true"] .DocSearch-Hit-icon path {
stroke: white;
}
.DocSearch-Hit-content-wrapper {
flex: auto;
display: flex;
flex-direction: column-reverse;
min-width: 0;
}
.DocSearch-Hit-path {
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: ${theme.colors.gray["500"]};
}
.DocSearch-Hit[aria-selected="true"] .DocSearch-Hit-path {
color: ${theme.colors.teal["200"]};
}
.DocSearch-Dropdown ul {
list-style-type: none;
}
.DocSearch-Hit-title {
color: black;
line-height: 1.5rem;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.DocSearch-Hit[aria-selected="true"] .DocSearch-Hit-title {
color: white;
}
.DocSearch-Hit-title + .DocSearch-Hit-path {
margin-bottom: 0.125rem;
}
.DocSearch-Hit-action {
flex: none;
margin-left: 0.875rem;
}
.DocSearch-Hit-action-button {
display: flex;
}
.DocSearch-Hit-action + .DocSearch-Hit-action {
margin-left: 0.5rem;
}
.DocSearch-Hit-action path {
stroke-width: 2px;
stroke: #71717a;
}
.DocSearch-Hit[aria-selected="true"] .DocSearch-Hit-action path {
stroke: white;
}
.DocSearch-Hit > a {
display: block;
background: ${theme.colors.gray["50"]};
border-radius: 0.5rem;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
padding: 0 1.25rem 0 1rem;
.chakra-ui-dark & {
background: ${theme.colors.gray["600"]};
* {
color: white !important;
}
}
}
.DocSearch-Hit[aria-selected="true"] > a {
background: ${theme.colors.teal["500"]};
}
.DocSearch-Hit + .DocSearch-Hit {
margin-top: 0.5rem;
}
.DocSearch-Hit {
position: relative;
}
.DocSearch-Hit--Child {
padding-left: 1.75rem;
}
.DocSearch-Hit--Child::before,
.DocSearch-Hit--Child
+ .DocSearch-Hit:not(.DocSearch-Hit--Child)::before {
content: "";
position: absolute;
top: -0.25rem;
bottom: -0.25rem;
left: 0.5rem;
width: 1.25rem;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='200' viewBox='0 0 12 200' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 1 0 V 200 M 1 100 H 12' stroke='%23a1a1aa' stroke-width='2'/%3E%3C/svg%3E%0A");
background-repeat: no-repeat;
background-position: center left;
}
.DocSearch-Hit--Child:last-child::before,
.DocSearch-Hit--Child
+ .DocSearch-Hit:not(.DocSearch-Hit--Child)::before {
background-image: url("data:image/svg+xml,%3Csvg width='12' height='200' viewBox='0 0 12 200' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 1 0 V 89 Q 1 100 12 100' stroke='%23a1a1aa' stroke-width='2'/%3E%3C/svg%3E%0A");
}
.DocSearch-Hit:not(.DocSearch-Hit--Child) + .DocSearch-Hit--Child::after {
content: "";
position: absolute;
top: -0.25rem;
left: 0;
width: 1.25rem;
height: 0.25rem;
background: inherit;
}
.DocSearch-Hit--Child
+ .DocSearch-Hit:not(.DocSearch-Hit--Child)::before {
top: auto;
bottom: calc(100% + 0.25rem);
height: calc(100% + 0.25rem);
background-color: #fff;
.chakra-ui-dark & {
background-color: ${theme.colors.gray["700"]};
}
}
.DocSearch-Hits mark {
background: none;
color: ${theme.colors.teal["500"]};
}
.DocSearch-Hit[aria-selected="true"] mark {
color: inherit;
text-decoration: underline;
}
.DocSearch-Footer {
flex: none;
display: flex;
justify-content: flex-end;
margin: 0 1.5rem;
border-top: 1px solid ${theme.colors.gray["200"]};
padding: 1.25rem 0;
.chakra-ui-dark & {
border-top-color: ${theme.colors.gray["600"]};
}
}
.DocSearch-Commands {
display: none;
}
.DocSearch-Logo a {
display: flex;
align-items: center;
color: #5d6494;
font-size: 0.75rem;
font-weight: 500;
}
.DocSearch-Logo svg {
color: ${theme.colors.teal["500"]};
margin-left: 0.5rem;
}
.DocSearch-Label {
.chakra-ui-dark & {
opacity: 0.5;
color: white;
}
}
.DocSearch-Hit--deleting,
.DocSearch-Hit--favoriting {
opacity: 0;
transition: all 250ms linear;
}
.DocSearch-NoResults .DocSearch-Screen-Icon {
display: none;
}
.DocSearch-Title {
font-size: ${theme.fontSizes.lg};
line-height: 1.2rem;
margin-bottom: 2.5rem;
}
.DocSearch-Title strong {
color: inherit;
font-weight: 500;
}
.DocSearch-StartScreen,
.DocSearch-NoResults {
padding-top: 2.5rem;
padding-bottom: 1rem;
}
.DocSearch-StartScreen .DocSearch-Help {
font-size: ${theme.fontSizes.md};
line-height: 1.5rem;
}
.DocSearch-NoResults-Prefill-List .DocSearch-Help {
font-size: ${theme.fontSizes.xs};
line-height: 1rem;
letter-spacing: ${theme.letterSpacings.wide};
text-transform: uppercase;
font-weight: 600;
padding-bottom: 0.5rem;
border-bottom: 1px solid ${theme.colors.gray["200"]};
.chakra-ui-dark & {
border-bottom: 1px solid ${theme.colors.gray["600"]};
}
}
.DocSearch-NoResults-Prefill-List li {
padding: 0.5rem 0;
border-bottom: 1px solid ${theme.colors.gray["200"]};
.chakra-ui-dark & {
border-bottom: 1px solid ${theme.colors.gray["600"]};
}
}
.DocSearch-NoResults-Prefill-List button {
font-weight: 500;
color: ${theme.colors.teal["600"]};
.chakra-ui-dark & {
color: ${theme.colors.teal["400"]};
}
}
.DocSearch-NoResults-Prefill-List + .DocSearch-Help {
font-size: ${theme.fontSizes.sm};
line-height: 1.25rem;
margin-top: 1rem;
}
.DocSearch-NoResults-Prefill-List + .DocSearch-Help a {
color: ${theme.colors.teal["600"]};
font-weight: 500;
.chakra-ui-dark & {
color: ${theme.colors.teal["300"]};
}
}
`}
/>
)
export default SearchStyle

@ -0,0 +1,16 @@
import React from "react"
import { NextSeo, NextSeoProps } from "next-seo"
import siteConfig from "configs/site-config"
export interface SEOProps extends Pick<NextSeoProps, "title" | "description"> {}
const SEO = ({ title, description }: SEOProps) => (
<NextSeo
title={title}
description={description}
openGraph={{ title, description }}
titleTemplate={siteConfig.seo.titleTemplate}
/>
)
export default SEO

@ -0,0 +1,20 @@
import { useRouter } from "next/router"
import { useEffect } from "react"
const useRouteChanged = (fn: () => void) => {
const router = useRouter()
useEffect(() => {
const handleRouteChange = (url: string) => {
fn()
console.log("App is changing to: ", url)
}
router.events.on("routeChangeComplete", handleRouteChange)
return () => {
router.events.off("routeChangeComplete", handleRouteChange)
}
}, [router.events, fn])
}
export default useRouteChanged

@ -0,0 +1,18 @@
import siteConfig from "configs/site-config"
export function getSeo({
omitOpenGraphImage,
}: {
omitOpenGraphImage: boolean
}) {
const { seo } = siteConfig
const { images, ...openGraph } = seo.openGraph
return {
...seo,
openGraph: {
...openGraph,
images: omitOpenGraphImage ? undefined : images,
},
}
}

@ -0,0 +1,133 @@
import { extendTheme } from "@chakra-ui/react"
import { mode } from "@chakra-ui/theme-tools"
const customTheme = extendTheme({
fonts: {
heading: "Inter, sans-serif",
body: "Inter, sans-serif",
},
shadows: {
search:
"0 0 0 1px rgba(16,22,26,.1), 0 4px 8px rgba(16,22,26,.2), 0 18px 46px 6px rgba(16,22,26,.2)",
},
styles: {
global: (props) => ({
body: {
color: mode("gray.700", "whiteAlpha.900")(props),
".deleted": {
color: "#ff8383 !important",
fontStyle: "normal !important",
},
".inserted": {
color: "#b5f4a5 !important",
fontStyle: "normal !important",
},
},
}),
},
textStyles: {
heading: {
fontFamily: "heading",
textAlign: "center",
fontWeight: "bold",
letterSpacing: "-0.015em",
lineHeight: "1.24",
fontSize: { base: "2rem", md: "3.5rem" },
},
"heading-2": {
fontFamily: "heading",
textAlign: "center",
fontWeight: "bold",
letterSpacing: "-0.015em",
lineHeight: "1.24",
fontSize: { base: "1.75rem", md: "2.75rem" },
},
caps: {
textTransform: "uppercase",
fontSize: "sm",
letterSpacing: "widest",
fontWeight: "bold",
},
},
mdx: {
h1: {
mt: "2rem",
mb: ".25rem",
lineHeight: 1.2,
fontWeight: "bold",
fontSize: "1.875rem",
letterSpacing: "-.025em",
},
h2: {
mt: "4rem",
mb: "0.5rem",
lineHeight: 1.3,
fontWeight: "semibold",
fontSize: "1.5rem",
letterSpacing: "-.025em",
"& + h3": {
mt: "1.5rem",
},
},
h3: {
mt: "3rem",
// mb: "0.5rem",
lineHeight: 1.25,
fontWeight: "semibold",
fontSize: "1.25rem",
letterSpacing: "-.025em",
},
h4: {
mt: "3rem",
lineHeight: 1.375,
fontWeight: "semibold",
fontSize: "1.125rem",
},
a: {
color: "teal.500",
fontWeight: "semibold",
transition: "color 0.15s",
transitionTimingFunction: "ease-out",
_hover: {
color: "teal.600",
},
},
p: {
mt: "1.25rem",
lineHeight: 1.7,
"blockquote &": {
mt: 0,
},
},
hr: {
my: "4rem",
},
blockquote: {
bg: "orange.100",
borderWidth: "1px",
borderColor: "orange.200",
rounded: "lg",
px: "1.25rem",
py: "1rem",
my: "1.5rem",
},
ul: {
mt: "1.5rem",
ml: "1.25rem",
"blockquote &": { mt: 0 },
"& > * + *": {
mt: "0.25rem",
},
},
code: {
rounded: "sm",
px: "1",
fontSize: "0.875em",
py: "2px",
whiteSpace: "nowrap",
lineHeight: "normal",
},
},
})
export default customTheme

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"hooks/*": ["src/hooks/*"],
"components/*": ["src/components/*"],
"utils/*": ["src/utils/*"],
"analytics/*": ["src/analytics/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save