Browse Source

feat: clean up, spacing, search

fix/enable-imgix
Thomas Osmonson 4 years ago
parent
commit
059a21c9ff
  1. 2
      package.json
  2. 2
      src/common/constants.ts
  3. 4
      src/common/navigation.yaml
  4. 114
      src/common/routes/all-routes.json
  5. 8
      src/common/routes/get-routes.js
  6. 8
      src/common/utils/index.ts
  7. 2
      src/components/clarity-ref.tsx
  8. 21
      src/components/color-modes/styles.tsx
  9. 15
      src/components/custom-blocks/page-reference.tsx
  10. 18
      src/components/feedback.tsx
  11. 3
      src/components/footer.tsx
  12. 118
      src/components/header.tsx
  13. 1
      src/components/home/common.tsx
  14. 48
      src/components/layouts/base-layout.tsx
  15. 3
      src/components/layouts/markdown-wrapper.tsx
  16. 4
      src/components/mdx/components/heading.tsx
  17. 4
      src/components/mdx/components/link.tsx
  18. 9
      src/components/mdx/components/typography.tsx
  19. 14
      src/components/mdx/md-contents.tsx
  20. 14
      src/components/mdx/styles.tsx
  21. 8
      src/components/mdx/typography.ts
  22. 8
      src/components/pagination.tsx
  23. 94
      src/components/search.tsx
  24. 44
      src/components/side-nav.tsx
  25. 28
      yarn.lock

2
package.json

@ -34,7 +34,7 @@
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"mdi-react": "7.3.0", "mdi-react": "7.3.0",
"micro-memoize": "^4.0.9", "micro-memoize": "^4.0.9",
"next": "^9.5.2-canary.4", "next": "^9.5.2-canary.5",
"next-fonts": "^1.4.0", "next-fonts": "^1.4.0",
"next-google-fonts": "^1.1.0", "next-google-fonts": "^1.1.0",
"next-mdx-remote": "^0.6.0", "next-mdx-remote": "^0.6.0",

2
src/common/constants.ts

@ -1,7 +1,7 @@
export const SIDEBAR_WIDTH = 208; export const SIDEBAR_WIDTH = 208;
export const TOC_WIDTH = 208; export const TOC_WIDTH = 208;
export const CONTENT_MAX_WIDTH = 1104; export const CONTENT_MAX_WIDTH = 1104;
export const PAGE_WIDTH = 1216; export const PAGE_WIDTH = 1104;
export const SHIKI_THEME = 'Material-Theme-Default'; export const SHIKI_THEME = 'Material-Theme-Default';
export const THEME_STORAGE_KEY = 'theme'; export const THEME_STORAGE_KEY = 'theme';

4
src/common/navigation.yaml

@ -99,7 +99,9 @@ sections:
- path: /blockstack-cli - path: /blockstack-cli
- path: /stacks-blockchain - path: /stacks-blockchain
- path: /stacks-rpc-api - path: /stacks-rpc-api
- path: /faqs - external:
href: 'https://blockstack.zendesk.com/hc/en-us'
title: FAQs
- path: /glossary - path: /glossary
- path: /deploy-tips - path: /deploy-tips
- title: Ecosystem - title: Ecosystem

114
src/common/routes/all-routes.json

@ -1,114 +0,0 @@
[
{
"title": "Authentication",
"routes": [
{ "path": "browser/todo-list" },
{ "path": "develop/connect/overview" },
{ "path": "develop/profiles" }
]
},
{
"title": "Data Storage",
"routes": [
{ "path": "storage/overview" },
{ "path": "develop/storage" },
{ "path": "storage/authentication" },
{ "path": "storage/write-to-read" }
]
},
{
"title": "Data Indexing",
"routes": [
{ "path": "develop/radiks-intro" },
{ "path": "develop/radiks-setup" },
{ "path": "develop/radiks-models" },
{ "path": "develop/radiks-collaborate" },
{ "path": "develop/radiks-server-extras" }
]
},
{
"title": "Smart Contracts",
"routes": [
{ "path": "core/smart/overview" },
{ "path": "core/smart/tutorial" },
{ "path": "core/smart/tutorial-counter" },
{ "path": "core/smart/tutorial-test" },
{ "path": "develop/connect/use-with-clarity" },
{ "path": "core/smart/principals" },
{ "path": "core/smart/testnet-node" },
{ "path": "core/smart/cli-wallet-quickstart" }
]
},
{
"title": "Naming Services",
"routes": [
{ "path": "core/naming/introduction" },
{ "path": "core/naming/architecture" },
{ "path": "core/naming/namespaces" },
{ "path": "core/naming/comparison" },
{ "path": "core/naming/tutorial_subdomains" },
{ "path": "core/naming/search" },
{ "path": "core/faq_technical" },
{ "path": "core/naming/pickname" },
{ "path": "core/naming/creationhowto" },
{ "path": "core/naming/resolving" },
{ "path": "core/naming/register" },
{ "path": "core/naming/manage" },
{ "path": "core/naming/subdomains" },
{ "path": "core/naming/forks" }
]
},
{
"title": "Data Portability (Preview)",
"routes": [{ "path": "develop/collections" }, { "path": "develop/collection-type" }]
},
{
"title": "Host a Storage Hub",
"routes": [
{ "path": "storage/hub-operation" },
{ "path": "storage/amazon-s3-deploy" },
{ "path": "storage/digital-ocean-deploy" },
{ "path": "storage/hello-hub-choice" },
{ "path": "storage/gaia-admin" }
]
},
{
"title": "Atlas",
"routes": [
{ "path": "core/atlas/overview" },
{ "path": "core/atlas/howitworks" },
{ "path": "core/atlas/howtouse" }
]
},
{
"title": "Blockstack and Stacks Tokens",
"routes": [
{ "path": "org/overview" },
{ "path": "faqs/allFAQS" },
{ "path": "org/token" },
{ "path": "org/whitepaper-blockchain" },
{ "path": "org/wallet-intro" },
{ "path": "org/wallet-install" },
{ "path": "org/wallet-use" },
{ "path": "org/wallet-troubleshoot" },
{ "path": "org/tokenholders" }
]
},
{
"title": "References",
"routes": [
{ "path": "core/cmdLineRef" },
{ "path": "core/smart/clarityRef" },
{ "path": "core/smart/rpc-api" },
{ "path": "common/javascript_ref" },
{ "path": "common/android_ref" },
{ "path": "common/ios_ref" },
{ "path": "common/core_ref" },
{ "path": "core/wire-format" },
{ "path": "storage/config-schema" },
{ "path": "org/secureref" },
{ "path": "develop/overview_auth" },
{ "path": "org/terms" }
]
}
]

8
src/common/routes/get-routes.js

@ -31,14 +31,16 @@ const getFlatMap = navigation => {
let sectionPages = []; let sectionPages = [];
if (page.sections) { if (page.sections) {
sectionPages = page.sections.flatMap(_section => sectionPages = page.sections.flatMap(_section =>
_section.pages.flatMap(sectionPage => `${page.path}${sectionPage.path}`) _section.pages.flatMap(
sectionPage => sectionPage && sectionPage.path && `${page.path}${sectionPage.path}`
)
); );
} }
const pages = page.pages.flatMap(_page => { const pages = page.pages.flatMap(_page => {
if (_page.pages) { if (_page.pages) {
return _page.pages.flatMap(p => `${page.path}${_page.path}${p.path}`); return _page.pages.flatMap(p => `${page.path}${_page.path}${p.path}`);
} else { } else {
return `${page.path}${_page.path}`; return _page.path && `${page.path}${_page.path}`;
} }
}); });
return [...pages, ...sectionPages]; return [...pages, ...sectionPages];
@ -49,7 +51,7 @@ const getFlatMap = navigation => {
); );
}; };
const allRoutes = getFlatMap(navigation); const allRoutes = getFlatMap(navigation).filter(route => route);
const getHeadings = mdContent => { const getHeadings = mdContent => {
const regex = /(#+)(.*)/gm; const regex = /(#+)(.*)/gm;

8
src/common/utils/index.ts

@ -72,3 +72,11 @@ export const getTitle = ({ title, headings }): string => title || getTitleFromHe
export const transition = (timing = '0.2s', properties = 'all') => export const transition = (timing = '0.2s', properties = 'all') =>
`${properties} ${timing} cubic-bezier(0.23, 1, 0.32, 1)`; `${properties} ${timing} cubic-bezier(0.23, 1, 0.32, 1)`;
export const getCategory = (pathname: string) => {
const arr = pathname.split('/');
if (arr.length > 1) {
return arr[1];
}
return undefined;
};

2
src/components/clarity-ref.tsx

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { MDXComponents } from '@components/mdx/mdx-components'; import { MDXComponents } from '@components/mdx/mdx-components';
import { TableOfContents } from '@components/toc'; import { TableOfContents } from '@components/toc';
import { hydrate } from '@common/data/hydrate-mdx'; import hydrate from 'next-mdx-remote/hydrate';
import { space } from '@blockstack/ui'; import { space } from '@blockstack/ui';
export const ClarityKeywordReference = ({ content, headings }) => { export const ClarityKeywordReference = ({ content, headings }) => {

21
src/components/color-modes/styles.tsx

@ -6,12 +6,21 @@ export const ColorModes = createGlobalStyle`
${generateCssVariables('light')}; ${generateCssVariables('light')};
--colors-highlight-line-bg: rgba(255,255,255,0.08); --colors-highlight-line-bg: rgba(255,255,255,0.08);
} }
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
:root { :root {
${generateCssVariables('dark')}; ${generateCssVariables('dark')};
--colors-highlight-line-bg: rgba(255,255,255,0.04); --colors-highlight-line-bg: rgba(255,255,255,0.04);
} }
* {
-webkit-font-smoothing: subpixel-antialiased;
-moz-osx-font-smoothing: auto;
}
} }
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
@ -19,6 +28,10 @@ export const ColorModes = createGlobalStyle`
${generateCssVariables('light')}; ${generateCssVariables('light')};
--colors-highlight-line-bg: rgba(255,255,255,0.08); --colors-highlight-line-bg: rgba(255,255,255,0.08);
} }
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
} }
html, body, #__next { html, body, #__next {
@ -28,10 +41,18 @@ export const ColorModes = createGlobalStyle`
&.light { &.light {
${generateCssVariables('light')}; ${generateCssVariables('light')};
--colors-highlight-line-bg: rgba(255,255,255,0.08); --colors-highlight-line-bg: rgba(255,255,255,0.08);
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
} }
&.dark { &.dark {
${generateCssVariables('dark')}; ${generateCssVariables('dark')};
--colors-highlight-line-bg: rgba(255,255,255,0.04); --colors-highlight-line-bg: rgba(255,255,255,0.04);
* {
-webkit-font-smoothing: subpixel-antialiased;
-moz-osx-font-smoothing: auto;
}
} }
} }

15
src/components/custom-blocks/page-reference.tsx

@ -59,7 +59,7 @@ const InlineCard = ({ page }) => {
return ( return (
<Flex <Flex
border={border()} border={border()}
flexDirection={['column', 'column', 'row']} flexDirection={['column', 'row', 'row', 'row']}
p={space('base-loose')} p={space('base-loose')}
borderRadius="12px" borderRadius="12px"
align="center" align="center"
@ -79,13 +79,13 @@ const InlineCard = ({ page }) => {
</Box> </Box>
<Flex <Flex
flexDirection="column" flexDirection="column"
ml={space(['none', 'none', 'base'])} ml={space(['none', 'base', 'base', 'base'])}
mt={space(['base', 'base', 'none'])} mt={space(['base', 'none', 'none', 'none'])}
textAlign={['center', 'center', 'left']} textAlign={['center', 'left', 'left', 'left']}
> >
<Flex align="baseline"> <Flex align="baseline">
<Title <Title
width={['100%', '100%', 'unset']} width={['100%', 'unset', 'unset', 'unset']}
color={hover ? color('accent') : color('text-title')} color={hover ? color('accent') : color('text-title')}
mb={space('extra-tight')} mb={space('extra-tight')}
> >
@ -93,11 +93,11 @@ const InlineCard = ({ page }) => {
</Title> </Title>
{page.tags?.length ? ( {page.tags?.length ? (
<Flex <Flex
position={['absolute', 'absolute', 'static']} position={['absolute', 'static', 'static', 'static']}
top={space('base-loose')} top={space('base-loose')}
right={space('base-loose')} right={space('base-loose')}
> >
{page.tags.map(tag => ( {page.tags.map((tag, key) => (
<Flex <Flex
ml={space('tight')} ml={space('tight')}
borderRadius="18px" borderRadius="18px"
@ -110,6 +110,7 @@ const InlineCard = ({ page }) => {
textTransform="capitalize" textTransform="capitalize"
color={color('invert')} color={color('invert')}
transition={transition()} transition={transition()}
key={key}
> >
{tag} {tag}
</Flex> </Flex>

18
src/components/feedback.tsx

@ -11,11 +11,13 @@ import {
SlideFade, SlideFade,
} from '@blockstack/ui'; } from '@blockstack/ui';
import { Text } from '@components/typography'; import { Text } from '@components/typography';
import { MDXComponents, Link } from '@components/mdx'; import { Link } from '@components/mdx';
import { SadIcon, NeutralIcon, HappyIcon } from '@components/icons/feedback'; import { SadIcon, NeutralIcon, HappyIcon } from '@components/icons/feedback';
import { useTouchable } from '@common/hooks/use-touchable'; import { useTouchable } from '@common/hooks/use-touchable';
import { border } from '@common/utils'; import { border } from '@common/utils';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { getHeadingStyles } from '@components/mdx/typography';
import { css } from '@styled-system/css';
const Icon: React.FC<BoxProps & { icon: React.FC<any> }> = ({ icon: IconComponent, ...props }) => { const Icon: React.FC<BoxProps & { icon: React.FC<any> }> = ({ icon: IconComponent, ...props }) => {
const { bind, hover, active } = useTouchable(); const { bind, hover, active } = useTouchable();
@ -24,11 +26,11 @@ const Icon: React.FC<BoxProps & { icon: React.FC<any> }> = ({ icon: IconComponen
<Box <Box
color={color('text-caption')} color={color('text-caption')}
_hover={{ color: color('bg'), cursor: 'pointer' }} _hover={{ color: color('bg'), cursor: 'pointer' }}
size="42px" size="28px"
{...props} {...props}
{...bind} {...bind}
> >
<IconComponent bg={isHovered ? color('accent') : color('bg-light')} /> <IconComponent bg={isHovered ? color('accent') : color('bg-alt')} />
</Box> </Box>
); );
}; };
@ -99,8 +101,14 @@ export const FeedbackSection: React.FC<BoxProps> = props => {
mt={space('extra-loose')} mt={space('extra-loose')}
> >
<Flex> <Flex>
<Box position="relative"> <Box mt={space('extra-loose')} position="relative">
<MDXComponents.h4>Was this page helpful?</MDXComponents.h4> <Text
css={css({
...getHeadingStyles('h5'),
})}
>
Was this page helpful?
</Text>
<Stack isInline spacing={space('base-loose')} mt={space('base-loose')}> <Stack isInline spacing={space('base-loose')} mt={space('base-loose')}>
<Icon onClick={() => handleShow()} icon={SadIcon} /> <Icon onClick={() => handleShow()} icon={SadIcon} />
<Icon onClick={() => handleShow()} icon={NeutralIcon} /> <Icon onClick={() => handleShow()} icon={NeutralIcon} />

3
src/components/footer.tsx

@ -1,11 +1,12 @@
import React from 'react'; import React from 'react';
import { space } from '@blockstack/ui';
import { Pagination } from '@components/pagination'; import { Pagination } from '@components/pagination';
import { Section, SectionWrapper } from '@components/home/common'; import { Section, SectionWrapper } from '@components/home/common';
import { FeedbackSection } from '@components/feedback'; import { FeedbackSection } from '@components/feedback';
const Footer = ({ hidePagination, ...rest }: any) => { const Footer = ({ hidePagination, ...rest }: any) => {
return ( return (
<Section> <Section px={space(['extra-loose', 'extra-loose', 'none', 'none'])}>
<SectionWrapper> <SectionWrapper>
<Pagination /> <Pagination />
<FeedbackSection /> <FeedbackSection />

118
src/components/header.tsx

@ -11,7 +11,7 @@ import {
FlexProps, FlexProps,
Fade, Fade,
} from '@blockstack/ui'; } from '@blockstack/ui';
import { Link, Text } from '@components/typography'; import { Link, LinkProps, Text } from '@components/typography';
import MenuIcon from 'mdi-react/MenuIcon'; import MenuIcon from 'mdi-react/MenuIcon';
import CloseIcon from 'mdi-react/CloseIcon'; import CloseIcon from 'mdi-react/CloseIcon';
import { useMobileMenuState } from '@common/hooks/use-mobile-menu'; import { useMobileMenuState } from '@common/hooks/use-mobile-menu';
@ -23,6 +23,7 @@ import { PAGE_WIDTH } from '@common/constants';
import { border, transition } from '@common/utils'; import { border, transition } from '@common/utils';
import { getCapsizeStyles } from '@components/mdx/typography'; import { getCapsizeStyles } from '@components/mdx/typography';
import { useTouchable } from '@common/hooks/use-touchable'; import { useTouchable } from '@common/hooks/use-touchable';
import { useRouter } from 'next/router';
const MenuButton = ({ ...rest }: any) => { const MenuButton = ({ ...rest }: any) => {
const { isOpen, handleOpen, handleClose } = useMobileMenuState(); const { isOpen, handleOpen, handleClose } = useMobileMenuState();
@ -50,31 +51,44 @@ const nav = [
children: [ children: [
{ {
label: 'Documentation', label: 'Documentation',
href: 'https://docs.blockstack.org/',
}, },
{ {
label: 'GitHub', label: 'GitHub',
href: 'https://github.com/blockstack',
}, },
{ {
label: 'Papers', label: 'Papers',
href: 'https://www.blockstack.org/papers',
}, },
{ {
label: 'Discord', label: 'Discord',
href: 'https://discord.com/invite/6PcCMU',
}, },
], ],
}, },
{ label: 'Testnet' }, { label: 'Testnet', href: 'https://www.blockstack.org/testnet' },
{ label: 'Discover apps' }, { label: 'Discover apps', href: 'https://app.co/' },
]; ];
export const HEADER_HEIGHT = 132; export const HEADER_HEIGHT = 132;
const HeaderTextItem: React.FC<BoxProps> = ({ children, ...rest }) => ( const HeaderTextItem: React.FC<BoxProps & LinkProps> = ({ children, href, as, ...rest }) => (
<Text <Text
color={color('invert')} color={color('invert')}
css={css({ css={css({
...getCapsizeStyles(16, 26), ...getCapsizeStyles(16, 26),
...rest, ...rest,
color: 'currentColor',
':hover': {
cursor: 'pointer',
textDecoration: href ? 'underline' : 'none',
color: href ? color('accent') : 'currentColor',
},
})} })}
as={as}
// @ts-ignore
href={href}
> >
{children} {children}
</Text> </Text>
@ -86,11 +100,12 @@ const NavItem: React.FC<FlexProps & { item: any }> = ({ item, ...props }) => {
}); });
return ( return (
<Flex justifyContent="center" position="relative" {...props} {...bind}> <Flex justifyContent="center" position="relative" {...props} {...bind}>
<Link as="a"> <HeaderTextItem as={item.href ? 'a' : 'span'} href={item.href}>
<HeaderTextItem>{item.label}</HeaderTextItem> {item.label}
</Link> </HeaderTextItem>
{item.children ? ( {item.children ? (
<Box ml={space('extra-tight')}> <Box color={color('text-caption')} ml={space('extra-tight')}>
<ChevronIcon direction="down" /> <ChevronIcon direction="down" />
</Box> </Box>
) : null} ) : null}
@ -125,6 +140,11 @@ const NavItem: React.FC<FlexProps & { item: any }> = ({ item, ...props }) => {
borderBottom={_key < item.children.length - 1 && border()} borderBottom={_key < item.children.length - 1 && border()}
px={space('base')} px={space('base')}
py={space('base-loose')} py={space('base-loose')}
as="a"
display="block"
// @ts-ignore
href={child.href}
target="_blank"
> >
<HeaderTextItem color="currentColor">{child.label}</HeaderTextItem> <HeaderTextItem color="currentColor">{child.label}</HeaderTextItem>
</Box> </Box>
@ -157,41 +177,63 @@ const Navigation: React.FC<BoxProps> = props => {
); );
}; };
const LogoLink = () => {
const { hover, active, bind } = useTouchable();
const router = useRouter();
return (
<NextLink href="/" passHref>
<Link
as="a"
style={{
textDecoration: 'none',
pointerEvents: router.pathname === '/' ? 'none' : 'unset',
}}
{...bind}
>
<Flex as="span" align="center">
<Box
as="span"
// opacity={hover || active ? 0.75 : 1}
color={hover || active ? color('accent') : color('invert')}
mr={space('tight')}
>
<BlockstackIcon size="20px" />
</Box>
<Box as="span" transform="translateY(1px)">
<HeaderTextItem>Blockstack</HeaderTextItem>
</Box>
</Flex>
</Link>
</NextLink>
);
};
const Header = ({ hideSubBar, ...rest }: any) => { const Header = ({ hideSubBar, ...rest }: any) => {
return ( return (
<> <>
<HeaderWrapper> <HeaderWrapper>
<Flex <Box mx="auto" px="extra-loose">
justifyContent="space-between" <Flex
align="center" justifyContent="space-between"
bg={color('bg')} align="center"
style={{ bg={color('bg')}
backdropFilter: 'blur(5px)', style={{
}} backdropFilter: 'blur(5px)',
height="72px" }}
maxWidth={`${PAGE_WIDTH}px`} height="72px"
mx="auto" maxWidth={`${PAGE_WIDTH}px`}
px={space(['extra-loose', 'extra-loose', 'base', 'base'])} mx="auto"
{...rest} color={color('text-title')}
> {...rest}
<NextLink href="/" passHref> >
<Link as="a"> <LogoLink />
<Flex align="center"> <Flex align="center">
<Box color={color('invert')} mr={space('tight')}> <Navigation />
<BlockstackIcon size="20px" /> <ColorModeButton />
</Box> <MenuButton />
<Box transform="translateY(1px)"> </Flex>
<HeaderTextItem>Blockstack</HeaderTextItem>
</Box>
</Flex>
</Link>
</NextLink>
<Flex align="center">
<Navigation />
<ColorModeButton />
<MenuButton />
</Flex> </Flex>
</Flex> </Box>
</HeaderWrapper> </HeaderWrapper>
</> </>
); );

1
src/components/home/common.tsx

@ -33,7 +33,6 @@ export const SectionWrapper: React.FC<BoxProps> = props => (
width="100%" width="100%"
maxWidth={`${CONTENT_MAX_WIDTH}px`} maxWidth={`${CONTENT_MAX_WIDTH}px`}
overflow="hidden" overflow="hidden"
px={space('extra-loose')}
pt={space('extra-loose')} pt={space('extra-loose')}
{...props} {...props}
/> />

48
src/components/layouts/base-layout.tsx

@ -144,29 +144,31 @@ const BaseLayout: React.FC<{ isHome?: boolean }> = ({ children }) => {
<Flex minHeight="100vh" flexDirection="column"> <Flex minHeight="100vh" flexDirection="column">
<MobileMenu /> <MobileMenu />
<Header /> <Header />
<Flex width="100%" flexGrow={1} maxWidth={`${PAGE_WIDTH}px`} mx="auto"> <Flex flexGrow={1} width="100%" mx="auto" px={['0', '0', 'extra-loose', 'extra-loose']}>
<SideNav display={['none', 'none', 'block']} /> <Flex width="100%" flexGrow={1} maxWidth={`${PAGE_WIDTH}px`} mx="auto">
<Flex <SideNav display={['none', 'none', 'block']} />
flexGrow={1} <Flex
maxWidth={[ flexGrow={1}
'100%', maxWidth={[
'100%', '100%',
`calc(100% - ${isHome ? 0 : SIDEBAR_WIDTH}px)`, '100%',
`calc(100% - ${isHome ? 0 : SIDEBAR_WIDTH}px)`, `calc(100% - ${isHome ? 0 : SIDEBAR_WIDTH}px)`,
]} `calc(100% - ${isHome ? 0 : SIDEBAR_WIDTH}px)`,
flexDirection="column" ]}
> flexDirection="column"
<Main mx="unset" width={'100%'}> >
<Flex <Main mx="unset" width={'100%'}>
flexDirection={['column', 'column', 'row', 'row']} <Flex
maxWidth="108ch" flexDirection={['column', 'column', 'row', 'row']}
mx="auto" maxWidth="108ch"
flexGrow={1} mx="auto"
> flexGrow={1}
{children} >
</Flex> {children}
</Main> </Flex>
{isErrorPage ? null : <Footer justifySelf="flex-end" />} </Main>
{isErrorPage ? null : <Footer justifySelf="flex-end" />}
</Flex>
</Flex> </Flex>
</Flex> </Flex>
</Flex> </Flex>

3
src/components/layouts/markdown-wrapper.tsx

@ -16,9 +16,8 @@ const PageTop = props => {
const isHome = router.pathname === '/'; const isHome = router.pathname === '/';
return ( return (
<Box <Box
pl={space('extra-loose')}
pr={['extra-loose', 'extra-loose', 'unset']}
mb={['extra-loose', 'extra-loose', '64px']} mb={['extra-loose', 'extra-loose', '64px']}
px={space(['extra-loose', 'extra-loose', 'none', 'none'])}
> >
<Flex> <Flex>
<H1 mb="0 !important">{getTitle(props)}</H1> <H1 mb="0 !important">{getTitle(props)}</H1>

4
src/components/mdx/components/heading.tsx

@ -66,8 +66,8 @@ const Hashtag = () => (
position="absolute" position="absolute"
as="span" as="span"
align="center" align="center"
size="1rem" size="20px"
left="10px" left={['12px', '12px', '-20px', '-20px']}
color={color('text-caption')} color={color('text-caption')}
> >
<HashtagIcon size="1rem" /> <HashtagIcon size="1rem" />

4
src/components/mdx/components/link.tsx

@ -3,7 +3,7 @@ import NextLink from 'next/link';
import React, { forwardRef, Ref } from 'react'; import React, { forwardRef, Ref } from 'react';
export const SmartLink = ({ href, ...rest }: { href: string }) => { export const SmartLink = ({ href, ...rest }: { href: string }) => {
const isExternal = href.includes('http') || href.includes('mailto'); const isExternal = !href || href?.includes('http') || href?.includes('mailto');
const link = <Link href={href} {...rest} />; const link = <Link href={href} {...rest} />;
return isExternal ? ( return isExternal ? (
@ -21,7 +21,7 @@ export const Link = forwardRef(
ref: Ref<HTMLDivElement> ref: Ref<HTMLDivElement>
) => ( ) => (
<Box <Box
as="a" as={props.href ? 'a' : 'span'}
ref={ref} ref={ref}
color="var(--colors-accent)" color="var(--colors-accent)"
cursor="pointer" cursor="pointer"

9
src/components/mdx/components/typography.tsx

@ -12,14 +12,7 @@ export const H6: React.FC<BoxProps> = props => <BaseHeading as="h6" {...props} /
export const Br: React.FC<BoxProps> = props => <Box height="24px" {...props} />; export const Br: React.FC<BoxProps> = props => <Box height="24px" {...props} />;
export const Hr: React.FC<BoxProps> = props => ( export const Hr: React.FC<BoxProps> = props => (
<Box <Box as="hr" borderTopWidth="1px" borderColor={color('border')} my={'64px'} {...props} />
as="hr"
borderTopWidth="1px"
borderColor={color('border')}
my={space('extra-loose')}
mx={space('extra-loose')}
{...props}
/>
); );
export const P: React.FC<BoxProps> = props => <Text as="p" {...props} />; export const P: React.FC<BoxProps> = props => <Text as="p" {...props} />;

14
src/components/mdx/md-contents.tsx

@ -17,31 +17,29 @@ export const MDContents: React.FC<any> = React.memo(
({ pageTop: PageTop = null, headings, children }) => { ({ pageTop: PageTop = null, headings, children }) => {
const router = useRouter(); const router = useRouter();
const isHome = router.pathname === '/'; const isHome = router.pathname === '/';
const TOCShowing = !isHome && headings?.length > 1;
return ( return (
<> <>
<ContentWrapper <ContentWrapper
pl={space(['none', 'none', 'extra-loose', 'extra-loose'])} width={['100%', '100%', '100%', `calc(100% - ${!TOCShowing ? 0 : TOC_WIDTH}px)`]}
pr={
isHome ? ['0px', '0px', 'base-loose'] : space(['0', '0', 'extra-loose', 'extra-loose'])
}
width={['100%', '100%', '100%', `calc(100% - ${isHome ? 0 : TOC_WIDTH + 20}px)`]}
mx="unset" mx="unset"
pt="unset" pt="unset"
css={css(styleOverwrites as any)} css={css(styleOverwrites as any)}
pr={TOCShowing && ['0', '0', '0', 'extra-loose']}
> >
{PageTop && <PageTop />} {PageTop && <PageTop />}
{children} {children}
</ContentWrapper> </ContentWrapper>
{!isHome ? ( {!isHome ? (
<Box <Box
maxWidth={['100%', `${TOC_WIDTH + 20}px`, `${TOC_WIDTH + 20}px`]} maxWidth={['100%', `${TOC_WIDTH}px`, `${TOC_WIDTH}px`]}
width="100%" width="100%"
display={['none', 'none', 'none', 'block']} display={['none', 'none', 'none', 'block']}
pr="base-loose"
> >
<Box position="sticky" top={0} pt="64px"> <Box position="sticky" top={0} pt="64px">
<Search mb={space('extra-loose')} /> <Search mb={space('extra-loose')} />
{headings?.length > 1 ? ( {TOCShowing ? (
<TableOfContents <TableOfContents
pl={space('base')} pl={space('base')}
borderLeft={border()} borderLeft={border()}

14
src/components/mdx/styles.tsx

@ -8,9 +8,6 @@ import { getCapsizeStyles } from '@components/mdx/typography';
export const MdxOverrides = createGlobalStyle` export const MdxOverrides = createGlobalStyle`
* { * {
font-feature-settings: 'ss01' on; font-feature-settings: 'ss01' on;
backface-visibility: hidden;
-webkit-font-smoothing: antialiased;
-webkit-font-smoothing: subpixel-antialiased;
} }
html, body { html, body {
font-family: 'Soehne', Inter, sans-serif; font-family: 'Soehne', Inter, sans-serif;
@ -125,12 +122,13 @@ export const styleOverwrites = {
'&:first-child > h2:first-child': { '&:first-child > h2:first-child': {
mt: 0, mt: 0,
}, },
'& > *:not(pre):not(ul):not(ol):not(img):not([data-reach-accordion]):not(section)': { '& > *:not(pre):not(ul):not(ol):not(img):not([data-reach-accordion]):not(section):not(hr)': {
px: space('extra-loose'), px: space(['extra-loose', 'extra-loose', 'none', 'none']),
}, },
'ul, ol': { 'ul, ol': {
pr: space('extra-loose'), // pr: space('extra-loose'),
pl: '64px', px: space(['64px', '64px', 'extra-loose', 'extra-loose']),
// pl: '64px',
'ul, ol': { 'ul, ol': {
pl: space('extra-loose'), pl: space('extra-loose'),
}, },
@ -140,7 +138,7 @@ export const styleOverwrites = {
textDecoration: 'inherit', textDecoration: 'inherit',
}, },
pre: { pre: {
px: space(['none', 'none', 'extra-loose', 'extra-loose']), // px: space(['none', 'none', 'extra-loose', 'extra-loose']),
}, },
img: { img: {
mx: 'auto', mx: 'auto',

8
src/components/mdx/typography.ts

@ -23,22 +23,22 @@ export const getCapsizeStyles = (fontSize, leading) =>
const h1 = { const h1 = {
fontWeight: 600, fontWeight: 600,
...getCapsizeStyles(36, 52), ...getCapsizeStyles(36, 42),
}; };
const h2 = { const h2 = {
fontWeight: 500, fontWeight: 500,
...getCapsizeStyles(24, 40), ...getCapsizeStyles(24, 32),
}; };
const h3 = { const h3 = {
fontWeight: 500, fontWeight: 500,
...getCapsizeStyles(18, 32), ...getCapsizeStyles(18, 28),
}; };
const h4 = { const h4 = {
fontWeight: 400, fontWeight: 400,
...getCapsizeStyles(20, 36), ...getCapsizeStyles(20, 32),
}; };
const h5 = { const h5 = {

8
src/components/pagination.tsx

@ -98,7 +98,7 @@ const Title: React.FC<BoxProps & { isHovered?: boolean }> = ({ isHovered, ...pro
color={isHovered ? color('accent') : color('text-title')} color={isHovered ? color('accent') : color('text-title')}
mb={space('tight')} mb={space('tight')}
css={css({ css={css({
...getHeadingStyles('h3'), ...getHeadingStyles('h4'),
})} })}
{...props} {...props}
/> />
@ -108,7 +108,7 @@ const PrevCard: React.FC<any> = React.memo(props => {
const { prev } = usePaginateRoutes(); const { prev } = usePaginateRoutes();
return prev ? ( return prev ? (
<Card> <Card py="loose">
{({ hover, active }) => ( {({ hover, active }) => (
<> <>
<FloatingLink href={prev.path} /> <FloatingLink href={prev.path} />
@ -126,7 +126,7 @@ const NextCard: React.FC<any> = React.memo(props => {
const { next } = usePaginateRoutes(); const { next } = usePaginateRoutes();
return next ? ( return next ? (
<Card textAlign="right" align="flex-end"> <Card py="loose" textAlign="right" align="flex-end">
{({ hover, active }) => ( {({ hover, active }) => (
<> <>
<FloatingLink href={next.path} /> <FloatingLink href={next.path} />
@ -143,7 +143,7 @@ const NextCard: React.FC<any> = React.memo(props => {
export const Pagination: React.FC<any> = React.memo(({ hidePagination, ...rest }: any) => ( export const Pagination: React.FC<any> = React.memo(({ hidePagination, ...rest }: any) => (
<Grid <Grid
gridColumnGap={space('base-loose')} gridColumnGap={space('extra-loose')}
gridRowGap={space('extra-loose')} gridRowGap={space('extra-loose')}
gridTemplateColumns={['repeat(1, 1fr)', 'repeat(1, 1fr)', 'repeat(2, 1fr)', 'repeat(2, 1fr)']} gridTemplateColumns={['repeat(1, 1fr)', 'repeat(1, 1fr)', 'repeat(2, 1fr)', 'repeat(2, 1fr)']}
> >

94
src/components/search.tsx

@ -1,11 +1,24 @@
import React from 'react'; import React from 'react';
import { Box, Flex, Portal, space, Fade, themeColor, color, BoxProps } from '@blockstack/ui'; import {
Box,
Flex,
Portal,
space,
Fade,
themeColor,
color,
BoxProps,
Grid,
Stack,
} from '@blockstack/ui';
import { useDocSearchKeyboardEvents } from '@docsearch/react'; import { useDocSearchKeyboardEvents } from '@docsearch/react';
import { Text } from '@components/typography'; import { Text } from '@components/typography';
import { SearchIcon } from '@components/icons/search'; import { SearchIcon } from '@components/icons/search';
import Router from 'next/router'; import Router from 'next/router';
import Link from 'next/link'; import Link from 'next/link';
import { getCapsizeStyles } from '@components/mdx/typography';
import { css } from '@styled-system/css';
import { border } from '@common/utils';
const getLocalUrl = href => { const getLocalUrl = href => {
const _url = new URL(href); const _url = new URL(href);
@ -33,6 +46,32 @@ const navigator = {
}, },
}; };
const Key: React.FC<BoxProps> = ({ children, ...rest }) => (
<Grid
style={{
placeItems: 'center',
}}
size="18px"
bg={color('bg')}
border={border()}
borderRadius="3px"
boxShadow="low"
opacity={0.75}
{...rest}
>
<Text
css={css({
color: color('text-caption'),
display: 'block',
transform: 'translateY(1px)',
...getCapsizeStyles(12, 12),
})}
>
{children}
</Text>
</Grid>
);
const searchOptions = { const searchOptions = {
apiKey: '9040ba6d60f5ecb36eafc26396288875', apiKey: '9040ba6d60f5ecb36eafc26396288875',
indexName: 'blockstack', indexName: 'blockstack',
@ -96,7 +135,7 @@ export const SearchBox: React.FC<BoxProps> = React.memo(props => {
borderRadius="12px" borderRadius="12px"
display={['none', 'none', 'block', 'block']} display={['none', 'none', 'block', 'block']}
border="1px solid" border="1px solid"
borderColor={isOpen ? 'rgba(170, 179, 255, 0.8)' : color('bg-alt')} borderColor={isOpen ? 'rgba(170, 179, 255, 0.8)' : color('border')}
boxShadow={ boxShadow={
isOpen ? '0 0 0 3px rgba(170, 179, 255, 0.25)' : '0 0 0 3px rgba(170, 179, 255, 0)' isOpen ? '0 0 0 3px rgba(170, 179, 255, 0.25)' : '0 0 0 3px rgba(170, 179, 255, 0)'
} }
@ -104,23 +143,44 @@ export const SearchBox: React.FC<BoxProps> = React.memo(props => {
_hover={{ _hover={{
borderColor: 'rgba(170, 179, 255, 0.8)', borderColor: 'rgba(170, 179, 255, 0.8)',
boxShadow: '0 0 0 3px rgba(170, 179, 255, 0.25)', boxShadow: '0 0 0 3px rgba(170, 179, 255, 0.25)',
cursor: 'pointer',
}}
style={{
userSelect: 'none',
}} }}
{...props} {...props}
> >
<Flex <Flex align="center" justifyContent="space-between">
ref={searchButtonRef} <Flex
onClick={onOpen} ref={searchButtonRef}
px={space('base-tight')} onClick={onOpen}
py={space('tight')} px={space('base-tight')}
align="center" py={space('tight')}
_hover={{ borderColor: themeColor('blue.400'), cursor: 'pointer' }} align="center"
> _hover={{ borderColor: themeColor('blue.400') }}
<Box transform="scaleX(-1)" mr={space('tight')} color={color('text-caption')}> >
<SearchIcon size="18px" /> <Box
</Box> transform="scaleX(-1)"
<Text fontSize={'14px'} color={color('text-caption')}> mr={space('tight')}
Search docs opacity={0.6}
</Text> color={color('text-caption')}
>
<SearchIcon size="18px" />
</Box>
<Text
opacity={0.8}
css={css({
color: color('text-caption'),
...getCapsizeStyles(14, 28),
})}
>
Search docs
</Text>
</Flex>
<Stack isInline spacing="3px" pr="base">
<Key></Key>
<Key>K</Key>
</Stack>
</Flex> </Flex>
</Box> </Box>
</> </>

44
src/components/side-nav.tsx

@ -6,11 +6,12 @@ import { SIDEBAR_WIDTH } from '@common/constants';
// @ts-ignore // @ts-ignore
import nav from '@common/navigation.yaml'; import nav from '@common/navigation.yaml';
import ArrowLeftIcon from 'mdi-react/ArrowLeftIcon'; import ArrowLeftIcon from 'mdi-react/ArrowLeftIcon';
import { getTitle, slugify } from '@common/utils'; import { getCategory, getTitle, slugify } from '@common/utils';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { getCapsizeStyles } from '@components/mdx/typography'; import { getCapsizeStyles } from '@components/mdx/typography';
import { Text } from '@components/typography'; import { Text } from '@components/typography';
import { css } from '@styled-system/css'; import { css } from '@styled-system/css';
import { SmartLink } from '@components/mdx';
const Wrapper: React.FC<BoxProps & { containerProps?: BoxProps }> = ({ const Wrapper: React.FC<BoxProps & { containerProps?: BoxProps }> = ({
width = `${SIDEBAR_WIDTH}px`, width = `${SIDEBAR_WIDTH}px`,
containerProps, containerProps,
@ -24,7 +25,6 @@ const Wrapper: React.FC<BoxProps & { containerProps?: BoxProps }> = ({
width={width} width={width}
maxHeight={`calc(100vh - 60px)`} maxHeight={`calc(100vh - 60px)`}
overflow="auto" overflow="auto"
px={space('base')}
top={0} top={0}
pt="64px" pt="64px"
{...containerProps} {...containerProps}
@ -57,21 +57,22 @@ const PageItem = React.forwardRef(
) => { ) => {
const typeStyles = isTopLevel ? getCapsizeStyles(16, 26) : getCapsizeStyles(14, 20); const typeStyles = isTopLevel ? getCapsizeStyles(16, 26) : getCapsizeStyles(14, 20);
return ( return (
<Text <SmartLink
ref={ref} ref={ref}
css={css({ css={css({
display: 'block', display: 'block',
...typeStyles, ...typeStyles,
color: isActive ? color('accent') : isTopLevel ? color('text-title') : _color, color: isActive ? color('accent') : isTopLevel ? color('text-title') : _color,
mb, mb: isTopLevel ? space('base-loose') : mb,
':hover': { ':hover': {
color: isTopLevel ? color('accent') : color('text-title'), color: isTopLevel ? color('accent') : color('text-title'),
}, },
textDecoration: 'none',
})} })}
{...props} {...props}
> >
{children} {children}
</Text> </SmartLink>
); );
} }
); );
@ -94,6 +95,16 @@ const getRoutePath = path => routes.find(route => route.path.endsWith(path));
const ChildPages = ({ items, handleClick }: any) => const ChildPages = ({ items, handleClick }: any) =>
items?.pages items?.pages
? items?.pages?.map(page => { ? items?.pages?.map(page => {
if (page.external) {
return (
<Box mb={space('extra-tight')}>
<PageItem as="a" href={page.external.href} target="_blank">
{page.external.title}
</PageItem>
</Box>
);
}
const path = page.pages const path = page.pages
? `${page.path}${page.pages[0].path}` ? `${page.path}${page.pages[0].path}`
: items.path : items.path
@ -153,7 +164,7 @@ const BackItem = props => (
<Box mr={space('extra-tight')}> <Box mr={space('extra-tight')}>
<ArrowLeftIcon size="16px" /> <ArrowLeftIcon size="16px" />
</Box> </Box>
<PageItem mb={'0px'} color={'currentColor'}> <PageItem textDecoration="none" mb={'0px'} color={'currentColor'}>
Back Back
</PageItem> </PageItem>
</Flex> </Flex>
@ -170,6 +181,7 @@ const Navigation = () => {
React.useEffect(() => { React.useEffect(() => {
let currentSection = selected.items; let currentSection = selected.items;
nav.sections.forEach(section => { nav.sections.forEach(section => {
section.pages.forEach(page => { section.pages.forEach(page => {
if (page.pages) { if (page.pages) {
@ -234,6 +246,7 @@ const Navigation = () => {
} }
if (selected.type === 'default') { if (selected.type === 'default') {
const urlCategory = getCategory(router.pathname);
return selected.items.map((section, i) => { return selected.items.map((section, i) => {
return ( return (
<Box mb="40px"> <Box mb="40px">
@ -256,17 +269,14 @@ const Navigation = () => {
return ( return (
<Box mb={space('extra-tight')}> <Box mb={space('extra-tight')}>
<Link href={path}> <PageItem
<PageItem href={!urlCategory ? path : !path.includes(urlCategory) && path}
as="a" isTopLevel={i === 0}
href={path} isActive={router.pathname.endsWith(path)}
isTopLevel={i === 0} onClick={() => handleClick(page)}
isActive={router.pathname.endsWith(path)} >
onClick={() => handleClick(page)} {section.usePageTitles ? getTitle(route) : convertToTitle(page.path)}
> </PageItem>
{section.usePageTitles ? getTitle(route) : convertToTitle(page.path)}
</PageItem>
</Link>
</Box> </Box>
); );
})} })}

28
yarn.lock

@ -1526,10 +1526,10 @@
resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-9.5.1.tgz#c7e2fd457810b34e8ce598f57075b799ca48751b" resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-9.5.1.tgz#c7e2fd457810b34e8ce598f57075b799ca48751b"
integrity sha512-jmNKqEMWkCPQWWeoq6CiOShngGv99Cs+rQSLlU7BZMVCZzbcTVEkAsUqR4WfLA97K2ihjtNidY5jwbKFu4h83Q== integrity sha512-jmNKqEMWkCPQWWeoq6CiOShngGv99Cs+rQSLlU7BZMVCZzbcTVEkAsUqR4WfLA97K2ihjtNidY5jwbKFu4h83Q==
"@next/react-dev-overlay@9.5.2-canary.4": "@next/react-dev-overlay@9.5.2-canary.5":
version "9.5.2-canary.4" version "9.5.2-canary.5"
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.2-canary.4.tgz#d9fea4dd68a6a6cffd21b29b9f102617babfde58" resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.2-canary.5.tgz#b04f84a4df8d4a49239b8264b5156487c2a6f393"
integrity sha512-6NB8pcm6TikrwWwFK5Xmf0PEspN5X+i9sxTHknt6z0SaUKn+KBemdtGEbgkkQS0mNUOyBnrcs6K6nJ0+qAm1Sg== integrity sha512-YaO0gIHC6/VrrbN/2FeN96pCcrsJAVGmxa1TUHEq2djzzv2NCh0MXnGzqWfbeQGYshjLzHNksDpfZgdHujncqg==
dependencies: dependencies:
"@babel/code-frame" "7.8.3" "@babel/code-frame" "7.8.3"
ally.js "1.4.1" ally.js "1.4.1"
@ -1542,10 +1542,10 @@
stacktrace-parser "0.1.10" stacktrace-parser "0.1.10"
strip-ansi "6.0.0" strip-ansi "6.0.0"
"@next/react-refresh-utils@9.5.2-canary.4": "@next/react-refresh-utils@9.5.2-canary.5":
version "9.5.2-canary.4" version "9.5.2-canary.5"
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.2-canary.4.tgz#a612f5da712f74218bf8d7929433da68f39145e3" resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.2-canary.5.tgz#314c04d281018157eda010c351548cbf3cc8ca48"
integrity sha512-w/st+aJ3EGbvMgGW/dInkTeLE8MquorvpJ8wKd/wXyKm1nboJnxCSqtIsZBJcsznCsltm8P9V6mCZUTuzcXkCA== integrity sha512-mYT+8yMHlLQ5jSwibwKOCnsMY2qnlZ/caNI5qwTRH+ugKdyTNyFONm9d54KT9umdXei3azlkWJc0CI/Ceuo8mw==
"@popperjs/core@^2.4.0": "@popperjs/core@^2.4.0":
version "2.4.4" version "2.4.4"
@ -6324,10 +6324,10 @@ next-transpile-modules@^4.0.2:
micromatch "^4.0.2" micromatch "^4.0.2"
slash "^3.0.0" slash "^3.0.0"
next@^9.5.2-canary.4: next@^9.5.2-canary.5:
version "9.5.2-canary.4" version "9.5.2-canary.5"
resolved "https://registry.yarnpkg.com/next/-/next-9.5.2-canary.4.tgz#8023fc2c59eec015f5dbd4a0a287f41a96e6b613" resolved "https://registry.yarnpkg.com/next/-/next-9.5.2-canary.5.tgz#3743800daa0271fd97d4f037ba9ef74688f3b849"
integrity sha512-LCoQVcT8u+cLmAQClpl2UdYUcVMKu0GVL3eqfTiNZI08JONhGAuX2OrWMsj6KeKVpDdGZ0T47z5VO4q8/QFNIw== integrity sha512-a5XTn8T5D88seubihcclRnf0ZKD0lz2cvYVH+aSi9pbUSyzKrG0yHNi1dauXXtba+CUFxvLn8BTWjmFXPy0W+g==
dependencies: dependencies:
"@ampproject/toolbox-optimizer" "2.5.14" "@ampproject/toolbox-optimizer" "2.5.14"
"@babel/code-frame" "7.8.3" "@babel/code-frame" "7.8.3"
@ -6348,8 +6348,8 @@ next@^9.5.2-canary.4:
"@babel/preset-typescript" "7.9.0" "@babel/preset-typescript" "7.9.0"
"@babel/runtime" "7.9.6" "@babel/runtime" "7.9.6"
"@babel/types" "7.9.6" "@babel/types" "7.9.6"
"@next/react-dev-overlay" "9.5.2-canary.4" "@next/react-dev-overlay" "9.5.2-canary.5"
"@next/react-refresh-utils" "9.5.2-canary.4" "@next/react-refresh-utils" "9.5.2-canary.5"
ast-types "0.13.2" ast-types "0.13.2"
babel-plugin-syntax-jsx "6.18.0" babel-plugin-syntax-jsx "6.18.0"
babel-plugin-transform-define "2.0.0" babel-plugin-transform-define "2.0.0"

Loading…
Cancel
Save