mirror of https://github.com/lukechilds/docs.git
Thomas Osmonson
5 years ago
16 changed files with 1025 additions and 290 deletions
@ -1,54 +0,0 @@ |
|||||
name: Deploy preview |
|
||||
on: pull_request |
|
||||
|
|
||||
jobs: |
|
||||
vercel-deployment: |
|
||||
runs-on: ubuntu-latest |
|
||||
steps: |
|
||||
- uses: actions/checkout@v2 |
|
||||
- name: Vercel action |
|
||||
uses: amondnet/vercel-action@master |
|
||||
id: vercel-deployment-preview |
|
||||
with: |
|
||||
vercel-token: ${{ secrets.VERCEL_TOKEN }} |
|
||||
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} |
|
||||
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} |
|
||||
scope: ${{ secrets.VERCEL_SCOPE }} |
|
||||
- name: Comment on PR |
|
||||
uses: actions/github-script@v2 |
|
||||
id: comment |
|
||||
with: |
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }} |
|
||||
script: | |
|
||||
const firstLine = `The Blockstack docs have been deployed with Vercel using the code from this PR!`; |
|
||||
const { data } = await github.issues.listComments({ |
|
||||
...context.repo, |
|
||||
issue_number: context.issue.number, |
|
||||
}); |
|
||||
const vercelPreviewURLComment = data.find((comment) => |
|
||||
comment.body.includes(firstLine) |
|
||||
); |
|
||||
const commentId = vercelPreviewURLComment && vercelPreviewURLComment.id || undefined; |
|
||||
const commentBody = ` |
|
||||
#### Deploy previews |
|
||||
${firstLine} |
|
||||
|
|
||||
- [Blockstack docs](${{ steps.vercel-deployment-preview.outputs.preview-url }}) |
|
||||
|
|
||||
Built with commit ${context.sha}. |
|
||||
`; |
|
||||
if(context.issue.number){ |
|
||||
if (commentId) { |
|
||||
await github.issues.updateComment({ |
|
||||
...context.repo, |
|
||||
comment_id: commentId, |
|
||||
body: commentBody, |
|
||||
}); |
|
||||
} else { |
|
||||
await github.issues.createComment({ |
|
||||
...context.repo, |
|
||||
issue_number: context.issue.number, |
|
||||
body: commentBody, |
|
||||
}); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,37 @@ |
|||||
|
name: Code quality |
||||
|
on: [push] |
||||
|
|
||||
|
jobs: |
||||
|
code_quality: |
||||
|
runs-on: ubuntu-latest |
||||
|
steps: |
||||
|
- name: Checkout |
||||
|
uses: actions/checkout@v2 |
||||
|
|
||||
|
- name: Set Node Version |
||||
|
uses: actions/setup-node@v1.4.2 |
||||
|
with: |
||||
|
node-version: 14 |
||||
|
|
||||
|
- name: Get yarn cache directory path |
||||
|
id: yarn-cache-dir-path |
||||
|
run: echo "::set-output name=dir::$(yarn cache dir)" |
||||
|
|
||||
|
- name: Check Cache |
||||
|
uses: actions/cache@v2 |
||||
|
id: yarn-cache |
||||
|
with: |
||||
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} |
||||
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} |
||||
|
restore-keys: | |
||||
|
${{ runner.os }}-yarn- |
||||
|
|
||||
|
- name: Install deps |
||||
|
run: yarn --frozen-lockfile |
||||
|
if: steps.yarn-cache.outputs.cache-hit != 'true' |
||||
|
|
||||
|
- name: Lint |
||||
|
run: yarn lint |
||||
|
|
||||
|
- name: Typecheck |
||||
|
run: yarn typecheck |
@ -0,0 +1,28 @@ |
|||||
|
import React from 'react'; |
||||
|
import { Box, BoxProps, color, Flex, space, Stack, themeColor } from '@blockstack/ui'; |
||||
|
import { MDXComponents } from '@components/mdx'; |
||||
|
import { SadIcon, NeutralIcon, HappyIcon } from '@components/icons/feedback'; |
||||
|
import { useHover } from 'use-events'; |
||||
|
import { border } from '@common/utils'; |
||||
|
|
||||
|
const Icon: React.FC<BoxProps & { icon: React.FC<any> }> = ({ icon: IconComponent, ...props }) => { |
||||
|
const [isHovered, bind] = useHover(); |
||||
|
return ( |
||||
|
<Box _hover={{ color: color('accent'), cursor: 'pointer' }} size="42px" {...props} {...bind}> |
||||
|
<IconComponent bg={isHovered ? themeColor('blue.200') : themeColor('ink.200')} /> |
||||
|
</Box> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export const FeedbackSection: React.FC<BoxProps> = props => { |
||||
|
return ( |
||||
|
<Box borderTop={border()} py={space('extra-loose')} mt={space('extra-loose')}> |
||||
|
<MDXComponents.h3>Was this page helpful?</MDXComponents.h3> |
||||
|
<Stack isInline spacing={space('base-loose')} mt={space('base-loose')}> |
||||
|
<Icon icon={SadIcon} /> |
||||
|
<Icon icon={NeutralIcon} /> |
||||
|
<Icon icon={HappyIcon} /> |
||||
|
</Stack> |
||||
|
</Box> |
||||
|
); |
||||
|
}; |
@ -0,0 +1,120 @@ |
|||||
|
import React from 'react'; |
||||
|
import { Box, BoxProps, transition } from '@blockstack/ui'; |
||||
|
import { SVGProps } from 'react'; |
||||
|
|
||||
|
export type SvgProps = React.FC<BoxProps & SVGProps<any>>; |
||||
|
|
||||
|
export const SadIcon: SvgProps = ({ bg = '#E1E3E8', ...props }) => ( |
||||
|
<Box |
||||
|
as="svg" |
||||
|
width="28" |
||||
|
height="28" |
||||
|
viewBox="0 0 28 28" |
||||
|
fill="none" |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
{...props} |
||||
|
> |
||||
|
<Box |
||||
|
as="circle" |
||||
|
transition={transition} |
||||
|
// @ts-ignore
|
||||
|
cx="14" |
||||
|
cy="14" |
||||
|
r="14" |
||||
|
fill={bg as string} |
||||
|
/> |
||||
|
<path |
||||
|
d="M5.83334 8.75V8.75C6.94335 10.415 9.39 10.415 10.5 8.75V8.75" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
<path |
||||
|
d="M17.5 8.75V8.75C18.61 10.415 21.0567 10.415 22.1667 8.75V8.75" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
<path |
||||
|
d="M7 17.5001V17.5001C11.055 14.1209 16.945 14.1209 21 17.5001V17.5001" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
</Box> |
||||
|
); |
||||
|
|
||||
|
export const NeutralIcon: SvgProps = ({ bg = '#E1E3E8', ...props }) => ( |
||||
|
<Box |
||||
|
as="svg" |
||||
|
width="28" |
||||
|
height="28" |
||||
|
viewBox="0 0 28 28" |
||||
|
fill="none" |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
{...props} |
||||
|
> |
||||
|
<Box |
||||
|
as="circle" |
||||
|
transition={transition} |
||||
|
// @ts-ignore
|
||||
|
cx="14" |
||||
|
cy="14" |
||||
|
r="14" |
||||
|
fill={bg as string} |
||||
|
/> |
||||
|
<path |
||||
|
d="M5.83331 9.91659V9.91659C7.38689 10.0276 8.9464 10.0276 10.5 9.91659V9.91659" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
<path |
||||
|
d="M17.5 9.91659V9.91659C19.0536 10.0276 20.6131 10.0276 22.1667 9.91659V9.91659" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
<path d="M7 17.5H14H21" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" /> |
||||
|
</Box> |
||||
|
); |
||||
|
|
||||
|
export const HappyIcon: SvgProps = ({ bg = '#E1E3E8', ...props }) => ( |
||||
|
<Box |
||||
|
as="svg" |
||||
|
width="28" |
||||
|
height="28" |
||||
|
viewBox="0 0 28 28" |
||||
|
fill="none" |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
{...props} |
||||
|
> |
||||
|
<Box |
||||
|
as="circle" |
||||
|
transition={transition} // @ts-ignore
|
||||
|
cx="14" |
||||
|
cy="14" |
||||
|
r="14" |
||||
|
fill={bg as string} |
||||
|
/> |
||||
|
<path |
||||
|
d="M5.83331 10.5V10.5C6.94332 8.83498 9.38997 8.83498 10.5 10.5V10.5" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
<path |
||||
|
d="M17.5 10.5V10.5C18.61 8.83498 21.0567 8.83498 22.1667 10.5V10.5" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="1.5" |
||||
|
strokeLinecap="round" |
||||
|
/> |
||||
|
<path |
||||
|
d="M21 14C21 15.8565 20.2625 17.637 18.9497 18.9497C17.637 20.2625 15.8565 21 14 21C12.1435 21 10.363 20.2625 9.05025 18.9497C7.7375 17.637 7 15.8565 7 14L14 14H21Z" |
||||
|
fill="currentColor" |
||||
|
/> |
||||
|
</Box> |
||||
|
); |
@ -1,167 +1,113 @@ |
|||||
import { Box, Flex, FlexProps, color, space, BoxProps } from '@blockstack/ui'; |
|
||||
import { Caption, Text } from '@components/typography'; |
|
||||
import { useRouter } from 'next/router'; |
|
||||
import React from 'react'; |
import React from 'react'; |
||||
import { slugify } from '@common/utils'; |
import { Box, BoxProps, Flex, Grid, color, space } from '@blockstack/ui'; |
||||
import Link from 'next/link'; |
import routes from '@common/routes'; |
||||
import { useHover } from 'use-events'; |
import { useRouter } from 'next/router'; |
||||
import { ContentWrapper } from '@components/content-wrapper'; |
import { MDXComponents } from '@components/mdx'; |
||||
|
import { border } from '@common/utils'; |
||||
|
import NextLink from 'next/link'; |
||||
|
import { Link } from '@components/typography'; |
||||
|
const usePaginateRoutes = () => { |
||||
|
const router = useRouter(); |
||||
|
|
||||
|
const getRoute = route => router.pathname.includes(route.path); |
||||
|
const getSection = _section => _section.routes.find(getRoute); |
||||
|
const findSectionByTitle = item => item.title === section.title; |
||||
|
|
||||
|
const section = routes.find(getSection); |
||||
|
|
||||
|
if (!section) |
||||
|
return { |
||||
|
next: undefined, |
||||
|
prev: undefined, |
||||
|
}; |
||||
|
|
||||
|
const { routes: sectionRoutes } = section; |
||||
|
const sectionIndex: number = routes.findIndex(findSectionByTitle); |
||||
|
|
||||
|
const nextSection = routes[sectionIndex + 1]; |
||||
|
const prevSection = routes[sectionIndex - 1]; |
||||
|
|
||||
|
const isFirstSection = sectionIndex === 0; |
||||
|
const isLastSection = sectionIndex === routes.length - 1; |
||||
|
|
||||
|
const route = sectionRoutes.find(getRoute); |
||||
|
const routeIndex: number = sectionRoutes.findIndex(getRoute); |
||||
|
|
||||
|
const isFirstRouteInSection = routeIndex === 0; |
||||
|
const isLastRouteInSection = routeIndex === sectionRoutes.length - 1; |
||||
|
|
||||
|
let next; |
||||
|
let prev; |
||||
|
|
||||
|
if (!isLastRouteInSection) { |
||||
|
next = sectionRoutes[routeIndex + 1]; |
||||
|
} |
||||
|
if (isLastRouteInSection && !isLastSection) { |
||||
|
next = nextSection?.routes?.length && nextSection?.routes[0]; |
||||
|
} |
||||
|
if (!isFirstRouteInSection) { |
||||
|
prev = sectionRoutes[routeIndex - 1]; |
||||
|
} |
||||
|
if (isFirstRouteInSection && !isFirstSection) { |
||||
|
prev = prevSection?.routes?.length && prevSection?.routes[0]; |
||||
|
} |
||||
|
|
||||
|
return { next, prev }; |
||||
|
}; |
||||
|
|
||||
// const transition = 'all 0.2s cubic-bezier(0.23, 1, 0.32, 1)';
|
const Description: React.FC<BoxProps> = props => ( |
||||
//
|
<Box maxWidth="32ch" mt={space('extra-tight')}> |
||||
// const Previous = ({ isHovered }: { isHovered: boolean }) => {
|
<MDXComponents.p {...props} /> |
||||
// return (
|
</Box> |
||||
// <Flex>
|
); |
||||
// <Box
|
|
||||
// mr="extra-tight"
|
|
||||
// transition={transition}
|
|
||||
// transform={isHovered ? 'translateX(-2px)' : 'none'}
|
|
||||
// >
|
|
||||
// ←
|
|
||||
// </Box>
|
|
||||
// <Box>
|
|
||||
// <Caption>Previous</Caption>
|
|
||||
// </Box>
|
|
||||
// </Flex>
|
|
||||
// );
|
|
||||
// };
|
|
||||
// const Next = ({ isHovered }: { isHovered: boolean }) => {
|
|
||||
// return (
|
|
||||
// <Flex justifyContent="flex-end">
|
|
||||
// <Box>
|
|
||||
// <Caption>Next</Caption>
|
|
||||
// </Box>
|
|
||||
// <Box
|
|
||||
// ml="extra-tight"
|
|
||||
// transition={transition}
|
|
||||
// transform={isHovered ? 'translateX(2px)' : 'none'}
|
|
||||
// >
|
|
||||
// →
|
|
||||
// </Box>
|
|
||||
// </Flex>
|
|
||||
// );
|
|
||||
// };
|
|
||||
//
|
|
||||
// interface PaginationLinkProps extends BoxProps {
|
|
||||
// slug: string;
|
|
||||
// label: string;
|
|
||||
// prev?: boolean;
|
|
||||
// }
|
|
||||
//
|
|
||||
// const PaginationLink = ({ slug, label, prev, ...rest }: PaginationLinkProps) => {
|
|
||||
// const [isHovered, bindHover] = useHover();
|
|
||||
// return (
|
|
||||
// <Link href={`/${slug}`} passHref>
|
|
||||
// <Box
|
|
||||
// color="var(--colors-text-body)"
|
|
||||
// _hover={{
|
|
||||
// color: 'var(--colors-accent)',
|
|
||||
// }}
|
|
||||
// as="a"
|
|
||||
// py={space('extra-loose')}
|
|
||||
// display="block"
|
|
||||
// flexGrow={1}
|
|
||||
// {...bindHover}
|
|
||||
// {...rest}
|
|
||||
// >
|
|
||||
// <Caption textAlign={prev ? 'left' : 'right'} display="block">
|
|
||||
// {prev ? <Previous isHovered={isHovered} /> : <Next isHovered={isHovered} />}
|
|
||||
// </Caption>
|
|
||||
// <Text
|
|
||||
// textAlign={prev ? 'left' : 'right'}
|
|
||||
// display="block"
|
|
||||
// textStyle="display.large"
|
|
||||
// color="currentColor"
|
|
||||
// >
|
|
||||
// {label}
|
|
||||
// </Text>
|
|
||||
// </Box>
|
|
||||
// </Link>
|
|
||||
// );
|
|
||||
// };
|
|
||||
//
|
|
||||
// const getRouteWithSection = (route: string) => {
|
|
||||
// let section = '';
|
|
||||
// const keys = Object.keys(paginationRoutes);
|
|
||||
// keys.forEach(key => {
|
|
||||
// const routes = paginationRoutes[key].map(r => slugify(r));
|
|
||||
// if (routes.length && routes.find(r => r === route) && key !== 'top' && key !== 'bottom') {
|
|
||||
// section = key + '/';
|
|
||||
// }
|
|
||||
// });
|
|
||||
// return section + route;
|
|
||||
// };
|
|
||||
//
|
|
||||
// const usePagination = () => {
|
|
||||
// const router = useRouter();
|
|
||||
// const [state, setState] = React.useState({
|
|
||||
// previous: undefined,
|
|
||||
// previousSlug: undefined,
|
|
||||
// next: undefined,
|
|
||||
// nextSlug: undefined,
|
|
||||
// });
|
|
||||
// React.useEffect(() => {
|
|
||||
// const routesAsSlugs = routes.map(r => slugify(r));
|
|
||||
// const _route = router.asPath.replace('/', '');
|
|
||||
// const __route = _route.includes('/') ? _route.split('/')[1] : _route;
|
|
||||
// const route = __route === '' ? 'getting-started' : __route;
|
|
||||
// const index = routesAsSlugs.indexOf(route);
|
|
||||
// const previous = routes[index - 1];
|
|
||||
// const previousSlug = getRouteWithSection(routesAsSlugs[index - 1]);
|
|
||||
// const next = routes[index + 1];
|
|
||||
// const nextSlug = getRouteWithSection(routesAsSlugs[index + 1]);
|
|
||||
//
|
|
||||
// setState({
|
|
||||
// previous,
|
|
||||
// previousSlug,
|
|
||||
// next,
|
|
||||
// nextSlug,
|
|
||||
// });
|
|
||||
// }, [router.asPath]);
|
|
||||
//
|
|
||||
// const { previous, previousSlug, next, nextSlug } = state;
|
|
||||
//
|
|
||||
// return [
|
|
||||
// { label: previous, path: previousSlug, condition: !!previous },
|
|
||||
// {
|
|
||||
// label: next,
|
|
||||
// path: nextSlug,
|
|
||||
// condition: !!next,
|
|
||||
// },
|
|
||||
// ];
|
|
||||
// };
|
|
||||
//
|
|
||||
// export const Pagination: React.FC<FlexProps> = props => {
|
|
||||
// const buttons = usePagination();
|
|
||||
// return (
|
|
||||
// <Box maxWidth="100%" {...props}>
|
|
||||
// <ContentWrapper
|
|
||||
// borderTop="1px solid"
|
|
||||
// borderColor={color('border')}
|
|
||||
// flexDirection="row"
|
|
||||
// alignItems="baseline"
|
|
||||
// justify="space-between"
|
|
||||
// pt="unset"
|
|
||||
// pb="unset"
|
|
||||
// width="100%"
|
|
||||
// maxWidth="98ch"
|
|
||||
// mx="auto"
|
|
||||
// px={space('extra-loose')}
|
|
||||
// >
|
|
||||
// {buttons.map((button, index) =>
|
|
||||
// button.condition ? (
|
|
||||
// <PaginationLink
|
|
||||
// textAlign={index === 0 ? 'left' : 'right'}
|
|
||||
// slug={button.path}
|
|
||||
// label={button.label}
|
|
||||
// prev={index === 0}
|
|
||||
// key={index}
|
|
||||
// />
|
|
||||
// ) : null
|
|
||||
// )}
|
|
||||
// </ContentWrapper>
|
|
||||
// </Box>
|
|
||||
// );
|
|
||||
// };
|
|
||||
|
|
||||
export const Pagination: React.FC<FlexProps> = props => <></>; |
export const Pagination = ({ hidePagination, ...rest }: any) => { |
||||
|
const { next, prev } = usePaginateRoutes(); |
||||
|
return ( |
||||
|
<Grid |
||||
|
pt={space('extra-loose')} |
||||
|
borderTop={border()} |
||||
|
gridColumnGap={space('base-loose')} |
||||
|
gridRowGap={space('extra-loose')} |
||||
|
gridTemplateColumns={['repeat(1, 1fr)', 'repeat(1, 1fr)', 'repeat(2, 1fr)', 'repeat(2, 1fr)']} |
||||
|
> |
||||
|
{prev ? ( |
||||
|
<Box _hover={{ cursor: 'pointer' }} width="100%" position="relative"> |
||||
|
<NextLink href={`/${prev.path}`} passHref> |
||||
|
<Link position="absolute" size="100%" zIndex={2} as="a" /> |
||||
|
</NextLink> |
||||
|
<MDXComponents.h5 color={color('text-caption')}>Previous</MDXComponents.h5> |
||||
|
<Box maxWidth="38ch"> |
||||
|
<MDXComponents.h3 my={0}>{prev.title || prev.headings[0]}</MDXComponents.h3> |
||||
|
</Box> |
||||
|
{prev.description && <Description>{prev.description}</Description>} |
||||
|
</Box> |
||||
|
) : ( |
||||
|
<Box /> |
||||
|
)} |
||||
|
{next ? ( |
||||
|
<Flex |
||||
|
_hover={{ cursor: 'pointer' }} |
||||
|
width="100%" |
||||
|
textAlign="right" |
||||
|
direction="column" |
||||
|
align="flex-end" |
||||
|
position="relative" |
||||
|
> |
||||
|
<NextLink href={`/${next.path}`} passHref> |
||||
|
<Link position="absolute" size="100%" zIndex={2} as="a" /> |
||||
|
</NextLink> |
||||
|
<MDXComponents.h5 color={color('text-caption')} width="100%" display="block"> |
||||
|
Next |
||||
|
</MDXComponents.h5> |
||||
|
<Box maxWidth="38ch"> |
||||
|
<MDXComponents.h3 my={0}>{next.title || next.headings[0]}</MDXComponents.h3> |
||||
|
</Box> |
||||
|
{next.description && <Description>{next.description}</Description>} |
||||
|
</Flex> |
||||
|
) : ( |
||||
|
<Box /> |
||||
|
)} |
||||
|
</Grid> |
||||
|
); |
||||
|
}; |
||||
|
File diff suppressed because it is too large
Loading…
Reference in new issue