DEV Community

Cover image for Build a modern user interface with ChakraUI
notHanii
notHanii

Posted on

Build a modern user interface with ChakraUI

Install and Setup Chakra UI in a React Project

npx create-next-app --ts
# or
yarn create next-app --typescript
Enter fullscreen mode Exit fullscreen mode
yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4
Enter fullscreen mode Exit fullscreen mode

AppProps is a type that is given to us by Next.js and Typescript.

import { AppProps } from 'next/app';

const App = () => {

};

export default App;
Enter fullscreen mode Exit fullscreen mode
const App = ({ Component, pageProps }: AppProps) => {
  return <Component {...pageProps} />
};
Enter fullscreen mode Exit fullscreen mode
import { ChakraProvider } from '@chakra-ui/react';

const App = ({ Component, pageProps }: AppProps) => {
  return 
    <ChakraProvider>
      <Component {...pageProps} />
    </ChakraProvider>
};
Enter fullscreen mode Exit fullscreen mode

Build a Layout with the Container, Flex and VStack Component in Chakra UI

Figma is a vector graphics editor and prototyping tool which is primarily web-based, with additional offline features enabled by desktop applications for macOS and Windows.

Containers are used to constrain a content's width to the current breakpoint while keeping it fluid.


import { Container } from '@chakra-ui/react';
Enter fullscreen mode Exit fullscreen mode
const IndexPage = () => (
  <Container>

  </Container>
)
Enter fullscreen mode Exit fullscreen mode

Style props are a way to alter the style of a component by simply passing props to it.

The sizes key allows you to customize the global sizing of components you build for your project.

const IndexPage = () => (
  <Container maxWidth="container.xl" padding={0}>

  </Container>
)
Enter fullscreen mode Exit fullscreen mode

Flex is Box with display: flex and comes with helpful style shorthand. It renders a div element.

import { Container, Flex } from '@chakra-ui/react'; 

const IndexPage = () => (
  <Container maxWidth="container.xl" padding={0}>
    <Flex h="100vh" py={20}>

    </Flex>
  </Container>
)
Enter fullscreen mode Exit fullscreen mode

VStack is used to add spacing between elements in vertical direction only, and centers them.

import { Container, Flex, VStack } from '@chakra-ui/react'; 

const IndexPage = () => (
  <Container maxWidth="container.xl" padding={0}>
    <Flex h="100vh" py={20}>
      <VStack
        w="full"
        h="full"
        p={10}
        spacing={10}
        alignItems="flex-start"
      ></VStack>
    </Flex>
  </Container>
)
Enter fullscreen mode Exit fullscreen mode
const IndexPage = () => (
  <Container maxWidth="container.xl" padding={0}>
    <Flex h="100vh" py={20}>
      <VStack
        w="full"
        h="full"
        p={10}
        spacing={10}
        alignItems="flex-start"
      ></VStack>
      <VStack
        w="full"
        h="full"
        p={10}
        spacing={10}
        alignItems="flex-start"
        bg="gray.50"
      ></VStack>
    </Flex>
  </Container>
)
Enter fullscreen mode Exit fullscreen mode

Build a 2-Column Form with the SimpleGrid, FormControl, and Input Component in Chakra UI

Headings are used for rendering headlines.

import { VStack, Heading } from '@chakra-ui/react';

const Details = () => {
  return (
    <VStack w="full" h="full" p={10} spacing={10} alignItems="flex-start">
      <Heading size="2xl">Your details</Heading>
    </VStack>
  )
}
Enter fullscreen mode Exit fullscreen mode

Text component is the used to render text and paragraphs within an interface.

import { VStack, Heading, Text } from '@chakra-ui/react';

<Heading size="2xl">Your details</Heading>
<Text>If you already have an account, click here to log in.</Text>
Enter fullscreen mode Exit fullscreen mode

Overriding a parent's styling is quite easy in Chakra UI. To override the parent's spacing, we can wrap our Heading and our Text in another VStack and set spacing={3}. In existing react components, trying to override them may force you to restyle your parent components along with their internals.

Create a Dark Mode Switcher in Chakra UI

useColorMode is a React hook that gives you access to the current color mode, and a function to toggle the color mode.

const Cart = () => {
  const { toggleColorMode } = useColorMode();
  ...
  <Button onClick={toggleColorMode} variant="link" colorScheme="black">
    try changing the theme.
  </Button>
}
Enter fullscreen mode Exit fullscreen mode

useColorModeValue is a React hook used to change any value or style based on the color mode. It takes 2 arguments: the value in light mode, and the value in dark mode.

const bgColor = useColorModeValue("gray.50", "whiteAlpha.50")

<VStack
  w="full"
  h="full"
  p={10}
  spacing={6}
  align="Flex-start"
  bg={bgColor}
>
Enter fullscreen mode Exit fullscreen mode
const secondaryTextColor = useColorModeValue("gray.600", "gray.400")

<Text color="gray.600"> 
// turns into
<Text color={secondaryTextColor}>
Enter fullscreen mode Exit fullscreen mode
<VStack spacing={3} alignItems="flex-start">
  <Heading size="2xl">Your details</Heading>
  <Text>If you already have an account, click here to log in.</Text>
</VStack>
Enter fullscreen mode Exit fullscreen mode

Grid is a primitive useful for grid layouts. Grid is Box with display: grid and it comes with helpful style shorthand. It renders a div element.

import { VStack, Heading, Text, SimpleGrid, GridItem } from '@chakra-ui/react';

<SimpleGrid columns={2} columnGap={3} rowGap={6} w="full">

</SimpleGrid>
Enter fullscreen mode Exit fullscreen mode

FormControl provides context such as isInvalid, isDisabled, and isRequired to form elements. Since our SimpleGrid is two columns, we can make one of our inputs only take up one of those columns using colSpan={1}.

import { ..., FormControl, FormLabel, Input } from '@chakra-ui/react';

<SimpleGrid columns={2} columnGap={3} rowGap={6} w="full">
  <GridItem colSpan={1}>
    <FormControl>
      <FormLabel>First Name</FormLabel>
      <Input placeholder="John"/>
    </FormControl>
  </GridItem>
</SimpleGrid>
Enter fullscreen mode Exit fullscreen mode
<GridItem colSpan={1}>
  <FormControl>
    <FormLabel>Last Name</FormLabel>
    <Input placeholder="Doe"/>
  </FormControl>
</GridItem>
Enter fullscreen mode Exit fullscreen mode
<GridItem colSpan={2}>
  <FormControl>
    <FormLabel>Address</FormLabel>
    <Input placeholder="Blvd. Broken Dreams 21"/>
  </FormControl>
</GridItem>
Enter fullscreen mode Exit fullscreen mode
<GridItem colSpan={1}>
  <FormControl>
    <FormLabel>City</FormLabel>
    <Input placeholder="San Francisco"/>
  </FormControl>
</GridItem>
Enter fullscreen mode Exit fullscreen mode

Select component is a component that allows users pick a value from predefined options. Ideally, it should be used when there are more than 5 options, otherwise you might consider using a radio group instead.

import { ..., Select } from '@chakra-ui/react';

<GridItem colSpan={1}>
  <FormControl>
    <FormLabel>City</FormLabel>
    <Select>
      <option value="usa">United States of America</option>
      <option value="uae">United Arab Emirates</option>
      <option value="nmk">North Macedonia</option>
      <option value="de">Germany</option>
    </Select>
  </FormControl>
</GridItem>
Enter fullscreen mode Exit fullscreen mode

The Checkbox component is used in forms when a user needs to select multiple values from several options.

import { ..., Checkbox, Button } from '@chakra-ui/react';

<GridItem colSpan={2}>
  <CheckBox defaultChecked>Ship to billing address.</CheckBox>
</GridItem>
Enter fullscreen mode Exit fullscreen mode
<GridItem colSpan={2}>
  <Button size="lb" w="full">
    Place Order
  </Button>
</GridItem>
Enter fullscreen mode Exit fullscreen mode

Implement Responsive Design in Chakra UI

All style props accept arrays as values for mobile-first responsive styles. This is known as The Array syntax.

This means that in our array, we get 0 from 0 to 479 pixels, 10 from 480 pixels until 767 pixels, and then 20 from 768 pixels and up.

<Flex h="100vh" py={[0, 10, 20]}>
  <Details />
  <Cart />
</Flex>
Enter fullscreen mode Exit fullscreen mode

By using Responsive Direction, we can pass responsive values to our Flex component to change the stack direction and/or the spacing between our elements.

<Flex 
  h="100vh" 
  py={[0, 10, 20]}
  direction={{ base: 'column-reverse', md: 'row' }}
>
  <Details />
  <Cart />
</Flex>
Enter fullscreen mode Exit fullscreen mode
<Flex 
  h={{ base: 'auto', md: '100vh' }} 
  py={[0, 10, 20]}
  direction={{ base: 'column-reverse', md: 'row' }}
>
  <Details />
  <Cart />
</Flex>
Enter fullscreen mode Exit fullscreen mode

The useBreakpointValue is a custom hook which returns the value for the current breakpoint from the provided responsive values object. This hook also responds to the window resizing and returning the appropriate value for the new window size.

import { ..., useBreakpointValue } from '@chakra-ui/react';

const colSpan = useBreakpointValue({ base: 2, md: 1 });
Enter fullscreen mode Exit fullscreen mode
<GridItem colSpan={1}>
// All of them will now be....
<GridItem colSpan={colSpan}>
Enter fullscreen mode Exit fullscreen mode

Define Custom Colors and Fonts in Chakra UI

By default, all Chakra components inherit values from the default theme. In some scenarios, you might need to customize the theme tokens to match your design requirements. This is where extendTheme comes in to play.

import { extendTheme} from '@chakra-ui/rect';

const theme = extendTheme({});

export default theme;
Enter fullscreen mode Exit fullscreen mode
import theme from '../src/theme';

const App = ({ Component, pageProps }: AppProps) => {
  return ( 
    <ChakraProvider theme={theme}>
      <Component {...pageProps}>
    </ChakraProvider>
  )
}
Enter fullscreen mode Exit fullscreen mode
const theme = extendTheme({
  fonts: {
    heading: 'Montserrat',
    body: 'Inter',
  }
});
Enter fullscreen mode Exit fullscreen mode
import { ..., theme as base } from '@chakra-ui/rect';

const theme = extendTheme({
  fonts: {
    heading: `Montserrat, ${base.fonts?.heading}`,
    body: `Inter, ${base.fonts?.body}`,
  }
});
Enter fullscreen mode Exit fullscreen mode
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Montserrat:wght@700&display=swap');
Enter fullscreen mode Exit fullscreen mode
colors: {
  brand: {
    50: '#f5fee5',
    100: '#e1fbb2',
    200: '#cdf781',
    300: '#b8ee56',
    400: '#a2e032',
    500: '#8ac919',
    600: '#71ab09',
    700: '#578602',
    800: '#3c5e00',
    900: '#203300',
  },
},
Enter fullscreen mode Exit fullscreen mode
<Button colorScheme="brand" size="lg" w="full">
  Place Order
</Button>
Enter fullscreen mode Exit fullscreen mode

Use Theme Extensions in Chakra UI

withDefaultColorScheme does exactly what is in the name, sets a default color scheme to all of your components. It takes an object where you can set your colorScheme to a color, and you can set it to specifically focus on certain components such as Button or Badge.

Most components in Chakra UI have default styling. Variants are one way we can override those default settings and set certain components to have a different visual styles. withDefaultVariant is how we handle our variants.

withDefaultColorScheme({
  colorScheme: 'brand',
  components: ['Checkbox'],
})
withDefaultVariant({
  variant: 'filled',
  components: ['Input', 'Select'],
})
Enter fullscreen mode Exit fullscreen mode

Override the Built-in Component's Styles in Chakra UI

Continuing on how we override the default styling of our components, without using any theme extensions, we are going to use the basic API for this.

export default {
  // Styles for the base style
  baseStyle: {},
  // Styles for the size variations
  sizes: {},
  // Styles for the visual style variations
  variants: {},
  // The default `size` or `variant` values
  defaultProps: {},
}
Enter fullscreen mode Exit fullscreen mode
components: {
  Input: {
    sizes: {
      md: {
        field: {
          borderRadius: 'none',
        }
      }
    }
  },
},
Enter fullscreen mode Exit fullscreen mode
variants: {
  filled: {
    field: {
      _focus: {
        borderColor: 'brand.500',
      },
    },
  },
},
Enter fullscreen mode Exit fullscreen mode
Checkbox: {
  baseStyle: {
    control: {
      borderRadius: 'none',
      _focus: {
        ring: 2, 
        ringColor: 'brand.500',
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Create Custom Variants in Chakra UI

Just like we edited the styling of our components in the last two lessons, we are going to do the same to our variants to create our own custom variants. Just make sure to use the variant prop on your components in your details.tsx file and set it to what you named your variant, in our case primary.

Button: {
  variants: {
    primary: {
      rounded: 'none',
    },
  },
},
Enter fullscreen mode Exit fullscreen mode
Button: {
  variants: {
    primary: (props) => ({
      rounded: 'none',
      ...brandRing,
      backgroundColor: mode('brand.500', 'brand.200')(props),
    }),
  },
},
Enter fullscreen mode Exit fullscreen mode
Button: {
  variants: {
    primary: (props) => ({
      rounded: 'none',
      ...brandRing,
      backgroundColor: mode('brand.500', 'brand.200')(props),

      _hover: {
        backgroundColor: mode('brand.600', 'brand.300')(props),
      },

      _active: {
        backgroundColor: mode('brand.700', 'brand.400')(props),
      },
    }),
  },
},
Enter fullscreen mode Exit fullscreen mode
Button: {
  variants: {
    primary: (props) => ({
      rounded: 'none',
      ...brandRing,
      color: mode('white', 'gray.800')(props),
      backgroundColor: mode('brand.500', 'brand.200')(props),

      _hover: {
        backgroundColor: mode('brand.600', 'brand.300')(props),
      },

      _active: {
        backgroundColor: mode('brand.700', 'brand.400')(props),
      },
    }),
  },
},
Enter fullscreen mode Exit fullscreen mode

Top comments (0)