Skip to content

Commit

Permalink
feat: add universal chakra link component (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
tundera committed Jan 10, 2022
1 parent dbe5380 commit 4265bfa
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 57 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p align="center" style="text-align:center">
<img alt="Bison Logo" src="https://user-images.githubusercontent.com/14339/89243835-f47e7c80-d5d2-11ea-8d8d-36202227d0ec.png" />
<h1 align="center">The Full Stack Jamstack in-a-box.</h1>
<h1 align="center">The Full Stack Jamstack in-a-box</h1>
</p>

Bison is a starter repository created out of real-world apps at [Echobind](https://echobind.com). It represents our team's "Greenfield Web Stack" that we use when creating web apps for clients.
Expand Down
3 changes: 2 additions & 1 deletion packages/create-bison-app/template/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Center, Flex, Text, Link } from '@chakra-ui/layout';
import { Center, Flex, Text } from '@chakra-ui/layout';

import { Logo } from './Logo';
import { Link } from './Link';

export function Footer() {
const year = new Date().getFullYear();
Expand Down
109 changes: 109 additions & 0 deletions packages/create-bison-app/template/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type { PropsWithChildren } from 'react';
import type { LinkProps as NextLinkProps } from 'next/link';
import React from 'react';
import NextLink from 'next/link';
import {
Button as ChakraButton,
ButtonProps as ChakraButtonProps,
BreadcrumbLink as ChakraBreadcrumbLink,
BreadcrumbLinkProps as ChakraBreadcrumbLinkProps,
Link as ChakraLink,
LinkProps as ChakraLinkProps,
} from '@chakra-ui/react';

export type NextLinkAs = NextLinkProps['as'];

export type LinkProps<T> =
| PropsWithChildren<NextLinkProps & Omit<T, 'as'>>
| PropsWithChildren<Omit<NextLinkProps, 'as'> & T>;

type ChakraLinkAs = ChakraLinkProps['as'];

// Has to be a new component because both chakra and next share the `as` keyword
export const Link = ({
href,
as,
replace,
scroll,
shallow,
prefetch,
locale,
isExternal,
children,
...chakraProps
}: LinkProps<ChakraLinkProps>) => {
return isExternal ? (
<ChakraLink href={href} as={as as ChakraLinkAs} isExternal {...chakraProps}>
{children}
</ChakraLink>
) : (
<NextLink
passHref={true}
href={href}
as={as as NextLinkAs}
replace={replace}
scroll={scroll}
shallow={shallow}
prefetch={prefetch}
locale={locale}
>
<ChakraLink {...chakraProps}>{children}</ChakraLink>
</NextLink>
);
};

export const ButtonLink = ({
href,
as,
replace,
scroll,
shallow,
prefetch,
locale,
children,
...chakraProps
}: LinkProps<ChakraButtonProps>) => {
return (
<NextLink
passHref={true}
href={href}
as={as as NextLinkAs}
replace={replace}
scroll={scroll}
shallow={shallow}
prefetch={prefetch}
locale={locale}
>
<ChakraButton as="a" {...chakraProps}>
{children}
</ChakraButton>
</NextLink>
);
};

export const BreadcrumbLink = ({
href,
as,
replace,
scroll,
shallow,
prefetch,
locale,
children,
...chakraProps
}: LinkProps<ChakraBreadcrumbLinkProps>) => {
return (
<NextLink
passHref={true}
href={href}
as={as as NextLinkAs}
replace={replace}
scroll={scroll}
shallow={shallow}
prefetch={prefetch}
locale={locale}
>
<ChakraBreadcrumbLink {...chakraProps}>{children}</ChakraBreadcrumbLink>
</NextLink>
);
};
22 changes: 5 additions & 17 deletions packages/create-bison-app/template/components/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import React, { useState } from 'react';
import { useRouter } from 'next/router';
import NextLink from 'next/link';
import {
Link,
Flex,
Text,
FormControl,
FormLabel,
Input,
Stack,
Button,
Circle,
} from '@chakra-ui/react';
import { Flex, Text, FormControl, FormLabel, Input, Stack, Button, Circle } from '@chakra-ui/react';
import { useForm } from 'react-hook-form';
import { gql } from '@apollo/client';

import { EMAIL_REGEX } from '../constants';
import { useAuth } from '../context/auth';
import { ErrorText } from '../components/ErrorText';
import { Link } from './Link';
import { setErrorsFromGraphQLErrors } from '../utils/setErrors';
import { LoginMutationVariables, useLoginMutation } from '../types';

Expand Down Expand Up @@ -116,11 +106,9 @@ export function LoginForm() {
<Flex marginTop={8} justifyContent="center">
<Text color="gray.500">
New User?{' '}
<NextLink href="/signup" passHref>
<Link href="#" color="gray.900">
Sign Up
</Link>
</NextLink>
<Link href="/signup" color="gray.900">
Sign Up
</Link>
</Text>
</Flex>
</form>
Expand Down
11 changes: 5 additions & 6 deletions packages/create-bison-app/template/components/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from 'react';
import { Heading } from '@chakra-ui/react';
import NextLink from 'next/link';

import { Link } from './Link';

export function Logo() {
return (
<NextLink href="/" passHref>
<Heading as="a" size="md">
MyApp
</Heading>
</NextLink>
<Heading as={Link} href="/" size="md">
MyApp
</Heading>
);
}
12 changes: 4 additions & 8 deletions packages/create-bison-app/template/components/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import {
Link,
Stack,
useBreakpoint,
Button,
Expand All @@ -9,7 +8,8 @@ import {
MenuList,
MenuItem,
} from '@chakra-ui/react';
import NextLink from 'next/link';

import { Link } from './Link';

export function Nav() {
const breakpoint = useBreakpoint();
Expand All @@ -23,9 +23,7 @@ export function Nav() {

<MenuList width="full">
<MenuItem>
<NextLink href="/">
<Link href="">Link 1</Link>
</NextLink>
<Link href="/">Link 1</Link>
</MenuItem>

<MenuItem>
Expand All @@ -45,9 +43,7 @@ export function Nav() {
</Menu>
) : (
<Stack as="nav" direction="row" ml="auto" alignItems="center" fontSize="md" spacing={8}>
<NextLink href="/">
<Link href="">Link 1</Link>
</NextLink>
<Link href="/">Link 1</Link>

<Link href="/#features">Link 2</Link>
<Link href="/#tech">Link 3</Link>
Expand Down
22 changes: 5 additions & 17 deletions packages/create-bison-app/template/components/SignupForm.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
import React, { useState } from 'react';
import NextLink from 'next/link';
import {
Link,
Flex,
Text,
FormControl,
FormLabel,
Input,
Stack,
Button,
Circle,
} from '@chakra-ui/react';
import { Flex, Text, FormControl, FormLabel, Input, Stack, Button, Circle } from '@chakra-ui/react';
import { gql } from '@apollo/client';
import { useForm } from 'react-hook-form';
import { useRouter } from 'next/router';
Expand All @@ -20,6 +9,7 @@ import { setErrorsFromGraphQLErrors } from '../utils/setErrors';
import { SignupMutationVariables, useSignupMutation } from '../types';
import { EMAIL_REGEX } from '../constants';

import { Link } from './Link';
import { ErrorText } from './ErrorText';

export const SIGNUP_MUTATION = gql`
Expand Down Expand Up @@ -140,11 +130,9 @@ export function SignupForm() {
<Flex marginTop={8} justifyContent="center">
<Text color="gray.500">
Have an account?{' '}
<NextLink href="/login" passHref>
<Link href="#" color="gray.900">
Sign In
</Link>
</NextLink>
<Link href="/login" color="gray.900">
Sign In
</Link>
</Text>
</Flex>
</form>
Expand Down
12 changes: 5 additions & 7 deletions packages/create-bison-app/template/layouts/LoggedOut.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Box, Flex, Button } from '@chakra-ui/react';
import NextLink from 'next/link';
import { Box, Flex } from '@chakra-ui/react';

import { ButtonLink } from '../components/Link';
import { Logo } from '../components/Logo';
import { Footer } from '../components/Footer';

Expand All @@ -16,11 +16,9 @@ export function LoggedOutLayout({ children }: Props) {
<Flex p={4}>
<Logo />

<NextLink href="/login" passHref>
<Button as="a" ml="auto" display={{ base: 'none', lg: 'inline-flex' }}>
Login
</Button>
</NextLink>
<ButtonLink href="/login" ml="auto" display={{ base: 'none', lg: 'inline-flex' }}>
Login
</ButtonLink>
</Flex>
</>

Expand Down

0 comments on commit 4265bfa

Please sign in to comment.