Chakra-UI

Chakra UI 是一个简单的,模块化的易于理解的 UI 组件库,提供了丰富的构建 React 应用所需的 UI 组件。

文档:https://next.chakra-ui.com/docs/getting-started

  • Chakra UI 内置 Emotion,是 CSS-IN-JS 解决方案的集大成者
  • 基于 Styled-Systems https://styled-system.com/
  • 支持开箱即用的主题功能
  • 默认支持白天和黑夜两种模式
  • 拥有大量功能丰富且有用的组件
  • 使响应式设计变的轻而易举
  • 文档清晰且全面,查找 API 更加容易
  • 适用于构建用于展示的给用户的界面
  • 框架正在变得越来越完善

快速开始

npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4

index.js

import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { theme, ChakraProvider, CSSReset } from '@chakra-ui/react'; ReactDOM.render( <ChakraProvider> <CSSReset /> <App theme={ theme } /> </ChakraProvider>, document.getElementById('root') );

App.js

import React from 'react'; import { Button } from '@chakra-ui/react'; function App () { return ( <div> <Button>按钮</Button> </div> ); } export default App;

样式属性

Style Props 是用来更改组件样式的,通过为组件传递属性的方式实现。通过传递简化的样式属性以达到提升开发效率的目的。

也可以查看文档:https://chakra-ui.com/docs/features/style-props。

样式属性 css属性 主题
m,margin margin space
mx margin-left & margin-right space
p,padding padding space
py padding-top & padding-bottom space
bg background colors
bgColor background-color colors
color color colors
border border borders
textAlign text-aligin none
w,width width sizes
boxSize width & height sizes
d,display display none
pos,position postion none
left left space
shadow,boxShadow box-shdow shadows
import React from 'react'; import { Button, Box } from '@chakra-ui/react'; function App () { return ( <Box w={ 200 } h={ 100 } bgColor="orange"> <Button>按钮</Button> </Box> ); } export default App;

颜色模式(color mode)

chakra-ui 提供的组件都支持两种颜色模式,浅色模式(light)和暗色模式(dark),可以通过 useColorMode 进行颜色模式的更改。

Chakra 将颜色模式存储在 localStorage 中,并使用类名策略来确保颜色模式是持久的。

import React from 'react'; import { Button, Box, Text, useColorMode } from '@chakra-ui/react'; function App () { const { colorMode, toggleColorMode } = useColorMode(); console.log(colorMode); return ( <Box w={ 200 } h={ 100 } bgColor={ colorMode === 'light' ? 'tomato' : 'skyblue' }> <Text>{ colorMode }</Text> <Button onClick={ toggleColorMode }>按钮</Button> </Box> ); } export default App;

useColorModelValue

根据颜色模式设置样式。

chakra 允许在为元素设置样式时根据颜色模式产生不同值,通过 useColorModeValue 钩子函数实现。

import React from 'react'; import { Button, Box, Text, useColorMode, useColorModeValue } from '@chakra-ui/react'; function App () { const { colorMode, toggleColorMode } = useColorMode(); const bgColor = useColorModeValue('tomato', 'skyblue'); return ( <Box w={ 200 } h={ 100 } bgColor={ bgColor }> <Text>{ colorMode }</Text> <Button onClick={ toggleColorMode }>按钮</Button> </Box> ); } export default App;

强制组件的颜色模式

使组件不受颜色模式的影响,始终保持在某个颜色模式下的样式。

import React from 'react'; import { Button, Box, Text, useColorMode, useColorModeValue, LightMode } from '@chakra-ui/react'; function App () { const { colorMode, toggleColorMode } = useColorMode(); const bgColor = useColorModeValue('tomato', 'skyblue'); return ( <Box w={ 200 } h={ 100 } bgColor={ bgColor }> <Text>{ colorMode }</Text> <Button onClick={ toggleColorMode }>按钮</Button> <br /> <LightMode> <Button onClick={ toggleColorMode }>按钮</Button> </LightMode> </Box> ); } export default App;

颜色模式通用设置

设置默认颜色模式

通过 theme.config.initialColorMode 可以设置应用使用的默认主题

import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { theme, ChakraProvider, CSSReset } from '@chakra-ui/react'; theme.config.initialColorMode = 'dark'; ReactDOM.render( <ChakraProvider> <CSSReset /> <App theme={ theme } /> </ChakraProvider>, document.getElementById('root') );

使用操作系统所使用的颜色模式

通过 theme.config.useSystemColorMode 可以设置将应用的颜色模式设置为操作系统所使用的颜色模式

import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { theme, ChakraProvider, CSSReset } from '@chakra-ui/react'; theme.config.useSystemColorMode = true; ReactDOM.render( <ChakraProvider> <CSSReset /> <App theme={ theme } /> </ChakraProvider>, document.getElementById('root') );

主题对象

颜色

设置颜色时,可以但不限于取主题中提供的颜色值。

console.log(theme.colors);
console.log(JSON.stringify(theme.colors.red)); //{"50":"#FFF5F5","100":"#FED7D7","200":"#FEB2B2","300":"#FC8181","400":"#F56565","500":"#E53E3E","600":"#C53030","700":"#9B2C2C","800":"#822727","900":"#63171B"}
import React from 'react'; import { Box, Text } from '@chakra-ui/react'; function App () { return ( <Box w={ 200 } h={ 100 } bgColor="orange.200"> <Text>Test</Text> </Box> ); } export default App;

间距和大小

Space

使用 Space 可以自定义项目间距,这些间距值可以由 padding、margin 和 top、left、right、bottom 样式引用。

console.log(theme.space); //{"1":"0.25rem","2":"0.5rem","3":"0.75rem","4":"1rem","5":"1.25rem","6":"1.5rem","7":"1.75rem","8":"2rem","9":"2.25rem","10":"2.5rem","12":"3rem","14":"3.5rem","16":"4rem","20":"5rem","24":"6rem","28":"7rem","32":"8rem","36":"9rem","40":"10rem","44":"11rem","48":"12rem","52":"13rem","56":"14rem","60":"15rem","64":"16rem","72":"18rem","80":"20rem","96":"24rem","px":"1px","0.5":"0.125rem","1.5":"0.375rem","2.5":"0.625rem","3.5":"0.875rem"}
import React from 'react'; import { Box, Text } from '@chakra-ui/react'; function App () { return ( <Box mt="6" w="2xs" h="10" bgColor="orange.200"> <Text>Test</Text> </Box> ); } export default App;

Sizes

使用 Sizes 可以自定义元素大小,这些值可以由 width、height 和 maxWidth、minWidth 等样式引用。

console.log(theme.sizes); //{"1":"0.25rem","2":"0.5rem","3":"0.75rem","4":"1rem","5":"1.25rem","6":"1.5rem","7":"1.75rem","8":"2rem","9":"2.25rem","10":"2.5rem","12":"3rem","14":"3.5rem","16":"4rem","20":"5rem","24":"6rem","28":"7rem","32":"8rem","36":"9rem","40":"10rem","44":"11rem","48":"12rem","52":"13rem","56":"14rem","60":"15rem","64":"16rem","72":"18rem","80":"20rem","96":"24rem","px":"1px","0.5":"0.125rem","1.5":"0.375rem","2.5":"0.625rem","3.5":"0.875rem","max":"max-content","min":"min-content","full":"100%","3xs":"14rem","2xs":"16rem","xs":"20rem","sm":"24rem","md":"28rem","lg":"32rem","xl":"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem","8xl":"90rem","container":{"sm":"640px","md":"768px","lg":"1024px","xl":"1280px"}}

响应式断点

Breakpoints。配置响应数组值中使用的默认断点,这些值将用于生成移动优先(即最小宽度)的媒体查询。

import React from 'react'; import { Box, Text } from '@chakra-ui/react'; function App () { return ( <Box mt="6" w={["100px", "300px", "500px", "700px", "1000px"]} h="10" bgColor="orange.200"> <Text>Test</Text> </Box> ); } export default App;

标准 chakra-ui 组件

import React from 'react'; import { chakra } from '@chakra-ui/react'; const MyButton = chakra('button', { baseStyle: { borderRadius: 'lg', px: 4, py: 2, fontSize: '12px', bgColor: 'blue.500', color: 'white' } }); function App () { return ( <div> <MyButton>按钮</MyButton> </div> ); } export default App;

全局化 chakra-ui 组件样式

  • src 文件夹中创建 component-styles 文件夹用于放置自定义 Chakra-UI 组件
  • 在 component-styles 文件夹中创建 button.js 文件并将组件样式放置于当前文件并进行默认导出
const ButtonStyle = { baseStyle: { borderRadius: 'lg' }, sizes: { sm: { px: 3, py: 1, fontSize: '12px' }, md: { px: 4, py: 2, fontSize: '14px' } }, variants: { primary: { bgColor: 'blue.500', color: 'white' }, danger: { bgColor: 'red.500', color: 'white' } }, defaultProps: { size: 'sm', variant: 'primary' } } export default ButtonStyle;
  • 在 component-styles 文件夹中创建 index.js 文件用于导入导出所有的自定义组件
import Button from './button'; export { Button }
  • 在 src 文件夹中的 index.js 文件中导入自定义 Chakra-UI 组件并和 components 属性进行合并
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { ChakraProvider, CSSReset, extendTheme } from '@chakra-ui/react'; import { Button } from './component-styles/index'; const theme = extendTheme({ components: { Button } }); ReactDOM.render( <ChakraProvider theme={ theme } > <CSSReset /> <App /> </ChakraProvider>, document.getElementById('root') );
  • 在组件中使用样式化组件
import React from 'react'; import { Button } from '@chakra-ui/react'; function App () { return ( <div> <Button variant="danger" size="md">按钮</Button> </div> ); } export default App;

构建注册表单

npm install react-icons --save

index.js

import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { ChakraProvider, CSSReset, theme } from '@chakra-ui/react'; ReactDOM.render( <ChakraProvider theme={ theme } > <CSSReset /> <App /> </ChakraProvider>, document.getElementById('root') );

App.js

import React from 'react'; import { Box } from '@chakra-ui/react'; import Form from './components/form'; function App () { return ( <Box w={ 500 } h={ 500 } margin="30px auto"> <Form /> </Box> ); } export default App;

components/form.js

import React from "react"; import { Input, InputGroup, InputLeftAddon, InputRightAddon, Stack, FormControl, FormHelperText, RadioGroup, Radio, Select, Switch, FormLabel, Flex, Button } from "@chakra-ui/react"; import { FaUserAlt, FaLock, FaCheck } from 'react-icons/fa'; export default function Form () { return ( <form> <Stack spacing="6"> <FormControl isDisabled isInvalid> <InputGroup> <InputLeftAddon children={ <FaUserAlt /> } /> <Input placeholder="请输入用户名" /> </InputGroup> <FormHelperText fontSize="xs">用户名是必填项</FormHelperText> </FormControl> <InputGroup> <InputLeftAddon children={ <FaLock /> } /> <Input type="password" placeholder="请输入密码" /> <InputRightAddon children={ <FaCheck /> } /> </InputGroup> <RadioGroup defaultValue="0"> <Stack direction="row" spacing="4"> <Radio value="0">男</Radio> <Radio value="1">女</Radio> </Stack> </RadioGroup> <Select placeholder="请选择学科"> <option value="Java">Java</option> <option value="大前端">大前端</option> </Select> <Flex> <Switch id="deal" mr="3" /> <FormLabel htmlFor="deal">是否同意协议</FormLabel> </Flex> <Button _hover={{ bgColor: 'tomato' }} colorScheme="teal">注册</Button> </Stack> </form> ) }

选项卡组件的使用

components/Form.js

import React from "react"; import { Box, Tabs, Tab, TabList, TabPanels, TabPanel, Image } from "@chakra-ui/react"; import SignUp from "./SignUp"; import SignIn from "./SignIn"; import chakraUILight from '../assets/images/chakra-ui-light.png'; export default function Form () { return ( <Box bgColor="gray.200" p={3} boxShadow="lg" borderRadius="lg"> <Image w={ 250 } mx="auto" mt="2" mb="6" src={ chakraUILight } /> <Tabs isFitted> <TabList> <Tab _focus={{ boxShadow: 'none' }}>注册</Tab> <Tab _focus={{ boxShadow: 'none' }}>登录</Tab> </TabList> <TabPanels> <TabPanel> <SignUp /> </TabPanel> <TabPanel> <SignIn /> </TabPanel> </TabPanels> </Tabs> </Box> ) }

components/SignIn.js

import React from "react"; import { Input, InputGroup, InputLeftAddon, InputRightAddon, Stack, FormControl, FormHelperText, Button } from "@chakra-ui/react"; import { FaUserAlt, FaLock, FaCheck } from 'react-icons/fa'; export default function SignIn () { return ( <form> <Stack spacing="6"> <FormControl isDisabled isInvalid> <InputGroup> <InputLeftAddon children={ <FaUserAlt /> } /> <Input bgColor="white" placeholder="请输入用户名" /> </InputGroup> <FormHelperText fontSize="xs">用户名是必填项</FormHelperText> </FormControl> <InputGroup> <InputLeftAddon children={ <FaLock /> } /> <Input bgColor="white" type="password" placeholder="请输入密码" /> <InputRightAddon children={ <FaCheck /> } /> </InputGroup> <Button _hover={{ bgColor: 'tomato' }} colorScheme="teal">登录</Button> </Stack> </form> ) }

components/SignUp.js

import React from "react"; import { Input, InputGroup, InputLeftAddon, InputRightAddon, Stack, FormControl, FormHelperText, RadioGroup, Radio, Select, Switch, FormLabel, Flex, Button } from "@chakra-ui/react"; import { FaUserAlt, FaLock, FaCheck } from 'react-icons/fa'; export default function SignUp () { return ( <form> <Stack spacing="6"> <FormControl isDisabled isInvalid> <InputGroup> <InputLeftAddon children={ <FaUserAlt /> } /> <Input bgColor="white" placeholder="请输入用户名" /> </InputGroup> <FormHelperText fontSize="xs">用户名是必填项</FormHelperText> </FormControl> <InputGroup> <InputLeftAddon children={ <FaLock /> } /> <Input bgColor="white" type="password" placeholder="请输入密码" /> <InputRightAddon children={ <FaCheck /> } /> </InputGroup> <RadioGroup defaultValue="0"> <Stack direction="row" spacing="4"> <Radio bgColor="white" value="0">男</Radio> <Radio bgColor="white" value="1">女</Radio> </Stack> </RadioGroup> <Select bgColor="white" placeholder="请选择学科"> <option value="Java">Java</option> <option value="大前端">大前端</option> </Select> <Flex> <Switch id="deal" mr="3" /> <FormLabel htmlFor="deal">是否同意协议</FormLabel> </Flex> <Button _hover={{ bgColor: 'tomato' }} colorScheme="teal">注册</Button> </Stack> </form> ) }

布局组件的使用

components/Card.js

import React from 'react'; import { Box, Image, Badge, Text, Stack, Flex, Button } from '@chakra-ui/react'; import ChakraUI from '../assets/images/chakra-ui.png'; import { AiFillStar } from 'react-icons/ai'; export default function Card () { return ( <Box w={ 400 } margin="0 auto" borderRadius="lg" boxShadow="lg" bgColor="gray.200" overflow="hidden" > <Image src={ ChakraUI } /> <Box p={ 3 } > <Stack direction="row" align="center"> <Badge variant="solid" colorScheme="teal" borderRadius="full" px="2">New</Badge> <Badge variant="solid" colorScheme="teal" borderRadius="full" px="2">React</Badge> <Badge variant="solid" colorScheme="teal" borderRadius="full" px="2">Chakra-UI</Badge> <Text>月落</Text> </Stack> <Text as="h3" pt={ 3 } pb={ 2 } color="gray.500" fontSize="xl" fontWeight="semibold">Chakra-UI 框架专题课程</Text> <Text fontWeight="light" fontSize="sm" lineHeight="tall"> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx </Text> <Flex align="center" mt={ 2 }> <Flex color="teal.500"> <AiFillStar /> <AiFillStar /> <AiFillStar /> <AiFillStar /> </Flex> <AiFillStar /> <Text ml={ 1 }>100 评论</Text> </Flex> </Box> <Button w="100%" colorScheme="teal"> 登录</Button> </Box> ) }

App.js

import React from 'react'; import { Box } from '@chakra-ui/react'; import Card from './components/Card'; function App () { return ( <Box w={ 500 } h={ 500 } margin="30px auto"> <Card /> </Box> ); } export default App;

表单和卡片的颜色兼容

App.js

import React from 'react'; import { Box, Button, useColorMode, Flex } from '@chakra-ui/react'; import Form from './components/Form'; import Card from './components/Card'; function App () { const { toggleColorMode } = useColorMode(); return ( <Box> <Button colorScheme="teal" mt="10px" ml="10px" mb="30px" onClick={toggleColorMode} > 切换模式 </Button> <Flex width="100%"> <Box width={ 400 }> <Form /> </Box> <Box width={ 400 } ml="30px"> <Card /> </Box> </Flex> </Box> ); } export default App;

components/Card.js

import React from 'react'; import { Box, Image, Badge, Text, Stack, Flex, Button, useColorModeValue } from '@chakra-ui/react'; import ChakraUI from '../assets/images/chakra-ui.png'; import { AiFillStar } from 'react-icons/ai'; export default function Card () { const bgColor = useColorModeValue('gray.200', 'gray.700'); const textColor = useColorModeValue('gray.700', 'gray.100'); return ( <Box w={ 400 } borderRadius="lg" boxShadow="lg" bgColor={ bgColor } overflow="hidden" > <Image src={ ChakraUI } /> <Box p={ 3 } > <Stack direction="row" align="center"> <Badge variant="solid" colorScheme="teal" borderRadius="full" px="2">New</Badge> <Badge variant="solid" colorScheme="teal" borderRadius="full" px="2">React</Badge> <Badge variant="solid" colorScheme="teal" borderRadius="full" px="2">Chakra-UI</Badge> <Text color={ textColor }>月落</Text> </Stack> <Text as="h3" pt={ 3 } pb={ 2 } color={ textColor } fontSize="xl" fontWeight="semibold">Chakra-UI 框架专题课程</Text> <Text fontWeight="light" fontSize="sm" color={ textColor } lineHeight="tall"> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx </Text> <Flex align="center" mt={ 2 }> <Flex color="teal.500"> <AiFillStar /> <AiFillStar /> <AiFillStar /> <AiFillStar /> </Flex> <AiFillStar /> <Text color={ textColor } ml={ 1 }>100 评论</Text> </Flex> </Box> <Button w="100%" colorScheme="teal"> 登录</Button> </Box> ) }

components/Form.js

import React from "react"; import { Box, Tabs, Tab, TabList, TabPanels, TabPanel, Image, useColorModeValue } from "@chakra-ui/react"; import SignUp from "./SignUp"; import SignIn from "./SignIn"; import chakraUILight from '../assets/images/chakra-ui-light.png'; import chakraUIDark from '../assets/images/chakra-ui-dark.png'; export default function Form () { const bgColor = useColorModeValue('gray.200', 'gray.700'); const chakraUI = useColorModeValue(chakraUILight, chakraUIDark); return ( <Box bgColor={ bgColor } p={3} boxShadow="lg" borderRadius="lg"> <Image w={ 250 } mx="auto" mt="2" mb="6" src={ chakraUI } /> <Tabs isFitted> <TabList> <Tab _focus={{ boxShadow: 'none' }}>注册</Tab> <Tab _focus={{ boxShadow: 'none' }}>登录</Tab> </TabList> <TabPanels> <TabPanel> <SignUp /> </TabPanel> <TabPanel> <SignIn /> </TabPanel> </TabPanels> </Tabs> </Box> ) }