尽管我对 Tailwind CSS的热爱超过了其他框架,但我一直对缺乏类似于我们通过 Bootstrap 和 Materialize 等更全面的框架获得的组件感到失望,最近我发现了这个问题的完美解决方案: Chakra UI。
Chakra UI 遵循与 Tailwind CSS 相同的简洁和模块化的方法,因此您不需要浪费时间来取消和超越默认配置。
在本文中,我们将开始探索这个框架为我们所能做的最好的事情,以及为什么它是独一无二的。
安装
安装有点尴尬,因为有一些同行依赖,我认为它应该是默认的,但这就是为什么 ̄(ツ)_/ ̄。
我們只需要Chakra UI本身和一些東西從 Emotion,因為Chakra UI依賴於 👩 emotion, CSS-in-JS圖書館。
我们将使用npx
和Create React App来初始化我们的React应用程序:
1$ npx create-react-app chakra-app
2$ npm install @chakra-ui/core @emotion/core @emotion/styled emotion-theming
设置
在我们可以做任何事情之前,我们需要将整个应用程序包装成一个主题提供商
,该应用程序为我们的组件设置了所有默认风格。
1[label index.js]
2import { ThemeProvider } from "@chakra-ui/core";
3
4const ThemedApp = () => <ThemeProvider> <App /> </ThemeProvider>;
5
6ReactDOM.render(<ThemedApp />, document.getElementById('root'));
布局
除了我们正常的用户界面组件,如滑板和下载,Chakra UI为我们提供了几个元组件
(不是官方术语),以便轻松添加多组件的响应式布局。
Stack
- 将一组组合组合分为具有相同间隔的组件,默认情况下是垂直的,但可以用isInline
Flex
- 将一切都包装在一个 Flexbox 容器。Grid
- 包装在一个 CSS 网格容器。
1[label App.js]
2import { Stack, Flex, Box, Grid } from "@chakra-ui/core";
3
4const App = () => {
5 const flexSettings = {
6 flex: "1",
7 minW: "300px",
8 textAlign: "center",
9 color: "white",
10 mx: "6",
11 mb: "6"
12 };
13
14 const gridSettings = {
15 w: "100%",
16 textAlign: "center",
17 color: "white",
18 };
19
20 return (
21 <div>
22 <Flex w="100%" justify="space-between" flexWrap="wrap">
23 <Box {...flexSettings} bg={"red.500"}>I'm a box</Box>
24 <Box {...flexSettings} bg={"blue.500"}>I'm a box</Box>
25 <Box {...flexSettings} bg={"green.500"}>I'm a box</Box>
26 <Box {...flexSettings} bg={"purple.500"}>I'm a box</Box>
27 </Flex>
28
29 <Grid w="100%" templateColumns="repeat(auto-fit, minmax(300px, 1fr))" gap={6}>
30 <Box {...gridSettings} bg={"red.500"}>I'm a box</Box>
31 <Box {...gridSettings} bg={"blue.500"}>I'm a box</Box>
32 <Box {...gridSettings} bg={"green.500"}>I'm a box</Box>
33 <Box {...gridSettings} bg={"purple.500"}>I'm a box</Box>
34 </Grid>
35 </div>
36 );
37};
风格
由于Chakra UI基于Emotion来设计,允许使用CSS-in-JS,并添加了与Tailwind CSS相同的共同特性,这就是为什么我们能够使用w
和templateColumns
而不是width
和gridTemplateColumns
。
如果你不熟悉这种方法,它是写你的CSS的方式,这样你就可以得到所有JavaScript的好处,即使是Sass也不会带来,比如将一个风格连接到一个组件的状态。
在本示例中,我们将一个框的风格从组件的状态中划分出来,并使用一个小型的UI来操纵它。
1[label App.js]
2const BoxController = () => {
3 let [boxHeight, editHeight] = useState(20);
4 let [boxColor, editColor] = useState('red');
5 let [colorIntensity, editIntensity] = useState(500);
6
7 const boxSettings = {
8 flex: "1",
9 textAlign: "center",
10 color: "white",
11 h: `${boxHeight}px`,
12 bg: `${boxColor}.${colorIntensity}`
13 };
14
15 return (
16 <div>
17 <Box {...boxSettings}>I'm a Box</Box>
18 <Flex justifyContent="space-around">
19 <Stack>
20 <Heading size="md">Size</Heading>
21 <Button variantColor="red" onClick={() => editHeight(boxHeight -= 10)} border="none">Shrink</Button>
22 <Button variantColor="green" onClick={() => editHeight(boxHeight += 10)} border="none">Grow</Button>
23 </Stack>
24
25 <Stack>
26 <Heading size="md">Color</Heading>
27
28 <Flex w="200px" justifyContent="space-between">
29
30 <Stack>
31 <Button variantColor="green" onClick={() => editColor('green')} border="none">Green</Button>
32 <Button variantColor="blue" onClick={() => editColor('blue')} border="none">Blue</Button>
33 <Button variantColor="red" onClick={() => editColor('red')} border="none">Red</Button>
34 </Stack>
35
36 <Stack>
37 <Button variantColor="gray" variant="outline" onClick={() => editIntensity(colorIntensity -= 100)} border="none">Lighter</Button>
38 <Button variantColor="gray" variant="outline" onClick={() => editIntensity(colorIntensity += 100)} border="none">Darker</Button>
39 </Stack>
40
41 </Flex>
42 </Stack>
43 </Flex>
44 </div>
45 );
46};
组件
显然,我们不能超过每个组件,所以让我们专注于几个独特的Chakra UI。
龙头
盒子组件是一个干净的小滑出机制,这对任何侧面导航板来说都是完美的。 请注意,它使用了Chakra的自定义useDisclosure
链接,它为我们提供isOpen
,onOpen
和onClose
,以控制我们的盒子和任何类似的组件的状态,例如模式。
1[label App.js]
2import {
3 Drawer,
4 DrawerBody,
5 DrawerFooter,
6 DrawerHeader,
7 DrawerOverlay,
8 DrawerContent,
9 DrawerCloseButton,
10 Input,
11 Button,
12 useDisclosure,
13 Stack,
14 Textarea
15} from "@chakra-ui/core"
16
17const SignUpForm = () => {
18 const { isOpen, onOpen, onClose } = useDisclosure();
19 const btnRef = useRef();
20
21 return (
22 <div>
23 <Button ref={btnRef} variantColor="teal" border="none" onClick={onOpen}>
24 Sign Up
25 </Button>
26 <Drawer
27 isOpen={isOpen} placement="bottom"
28 onClose={onClose} finalFocusRef={btnRef}
29 >
30 <DrawerOverlay />
31 <DrawerContent>
32
33 <DrawerCloseButton border="none" />
34 <DrawerHeader>Sign up Now</DrawerHeader>
35
36 {/* Form */}
37 <DrawerBody >
38 <Stack height="30vh">
39 <Input w="98%" placeholder="Name" />
40 <Input w="98%" placeholder="Email" />
41 <Textarea w="98%" h="100%" placeholder="Message" />
42 </Stack>
43 </DrawerBody>
44
45 <DrawerFooter>
46 <Button variantColor="red" border="none" mr={3} onClick={onClose}>
47 Cancel
48 </Button>
49 <Button variantColor="blue" border="none">Save</Button>
50 </DrawerFooter>
51
52 </DrawerContent>
53 </Drawer>
54 </div>
55 );
56}
载人
Chakra UI为我们提供了一系列动画加载器,这些加载器很容易自定义,在这个例子中,我添加了一个循环来看到我们的加载器在行动中,但它们不需要基于任何外部的东西,它们也可以完全静态。
1[label App.js]
2import {
3 Stack,
4 CircularProgress,
5 CircularProgressLabel,
6 Progress,
7 Spinner
8} from "@chakra-ui/core"
9
10const Spinners = () => {
11 let [progress, update] = useState(0)
12
13 const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)
14
15 useEffect(() => setInterval(() => {
16 // Reset to 0 when reaches 100
17 update(progress < 100 ? progress += randomNum(0, 4) : 0)
18 }, 500), [])
19
20 return (
21 <div>
22 <Stack>
23 <CircularProgress color="green" isIndeterminate>
24 <CircularProgressLabel>{progress}%</CircularProgressLabel>
25 </CircularProgress>
26 <CircularProgress value={progress} size="100px" thickness={0.1} color="purple" />
27 <Progress value={progress} w="90%" />
28 <Progress value={progress + 10} w="90%" hasStripe isAnimated />
29 <Spinner
30 thickness="3px"
31 speed="1s"
32 emptyColor="gray.200"
33 color="blue.500"
34 size="2xl"
35 />
36 </Stack>
37 </div>
38 );
39}
主题
我还没有从任何其他框架中看到的东西是能够在整个应用程序中设置主题,无论是黑暗主题还是冬季主题,我们可以在一个地方轻松地定制整个网站 / 应用程序的风格。
在这个例子中,我添加了几个框,其设计和文本将基于假期。我个人喜欢当网站给你选择你最喜欢的设计时,就像Alligator.io一样。
1[label index.js]
2import { useTheme, ThemeProvider } from "@chakra-ui/core"
3
4const ThemedApp = () => {
5 const theme = useTheme()
6 const customTheme = {
7 ...theme,
8 colors: { ...theme.colors },
9 holidays: {
10 text: {
11 none: "Welcome to the site!",
12 stPatricksDay: "Happy St.Patty's Day!",
13 valentinesDay: "Happy Valentines Day!",
14 halloween: "Good luck trick-or-treating!",
15 christmas: "Merry Christmas!"
16 },
17 colors: {
18 none: {
19 "one": "#808080",
20 "two": "#808080",
21 "three": "#808080"
22 },
23 stPatricksDay: {
24 "one": "#224D17",
25 "two": "#60A830",
26 "three": "#099441"
27 },
28 valentinesDay: {
29 "one": "#b11d4d",
30 "two": "#fd6fa0",
31 "three": "#e986a3"
32 },
33 halloween: {
34 "one": "#810806",
35 "two": "#BF200E",
36 "three": "#FA4113"
37 },
38 christmas: {
39 "one": "#44b09e",
40 "two": "#e0d2c7",
41 "three": "#e01c34"
42 },
43 }
44 }
45 };
46 return (
47 <div>
48 <ThemeProvider theme={customTheme}><App /></ThemeProvider>
49 </div>
50 )
51}
1[label App.js]
2import {
3 Flex,
4 Button,
5 useTheme,
6 Box
7} from "@chakra-ui/core"
8
9const HolidayPicker = () => {
10 const [holiday, updateHoliday] = useState("none")
11 const theme = useTheme()
12
13 const holidayText = theme.holidays.text[holiday]
14 const holidayColor = theme.holidays.colors[holiday]
15
16 const btnStyles = {
17 border: 'none',
18 h: '25px',
19 borderRadius: '20px',
20 color: 'white',
21 fontWeight: 'bold',
22 cursor: 'pointer'
23 }
24 return (
25 <div>
26 <Flex justifyContent="space-around">
27 <Box bg={holidayColor.one} w="100%" h="400px" color="white">{holidayText}</Box>
28 <Box bg={holidayColor.two} w="100%" h="400px" color="white">{holidayText}</Box>
29 <Box bg={holidayColor.three} w="100%" h="400px" color="white">{holidayText}</Box>
30 </Flex>
31
32 <Flex justifyContent="space-around" mt="20px">
33 <Button bg={theme.holidays.colors.none} {...btnStyles}
34 onClick={() => updateHoliday('none')}>None</Button>
35 <Button bg={theme.holidays.colors.stPatricksDay} {...btnStyles}
36 onClick={() => updateHoliday('stPatricksDay')}
37 >St.Patrick's Day</Button>
38 <Button bg={theme.holidays.colors.valentinesDay} {...btnStyles}
39 onClick={() => updateHoliday('valentinesDay')}
40 >Valentine's Day</Button>
41 <Button bg={theme.holidays.colors.halloween} {...btnStyles}
42 onClick={() => updateHoliday('halloween')}
43 >Halloween</Button>
44 <Button bg={theme.holidays.colors.christmas} {...btnStyles}
45 onClick={() => updateHoliday('christmas')}
46 >Christmas</Button>
47 </Flex>
48 </div>
49 );
50}
关闭思想
与TailwindCSS一起,Chakra UI很容易成为我所有的项目中必不可少的工具之一,它不断改进,甚至现在也有几个拉动请求,如appBar和轮盘组件,可能会很快被添加。