探索ChakraUIReact组件库

来自菜鸟教程
跳转至:导航、​搜索

尽管我喜欢 Tailwind CSS 胜过其他框架,但我一直对缺少像 Bootstrap 和 Materialize 这样更成熟的框架所提供的组件感到失望。 我最近发现了这个问题的完美解决方案:Chakra UI

Chakra UI 遵循与 Tailwind CSS 相同的简约和模块化方法,因此您无需再浪费时间撤消和覆盖默认配置。

在本文中,我们将开始探索这个框架可以为我们做的最好的事情以及为什么它是独一无二的。

安装

安装有点尴尬,因为我认为默认情况下应该附带一些对等依赖项,但由于某种原因它就是这样¯\_(ツ)_/¯。

我们只需要 Chakra UI 本身和来自 Emotion 的一些东西,因为 Chakra UI 依赖于 👩‍🎤 EmotionCSS-in-JS 库。

我们将使用 npx 和 Create React App 来初始化我们的 React 应用程序:

$ npx create-react-app chakra-app
$ npm install @chakra-ui/core @emotion/core @emotion/styled emotion-theming

设置

在我们做任何事情之前,我们需要将整个应用程序包装在一个 ThemeProvider 中,它为我们的组件建立了所有默认样式。

index.js

import { ThemeProvider } from "@chakra-ui/core";

const ThemedApp = () => <ThemeProvider> <App /> </ThemeProvider>;

ReactDOM.render(<ThemedApp />, document.getElementById('root'));

布局

除了滑块和下拉菜单等常规 UI 组件外,Chakra UI 还为我们提供了一些“元组件”(不是官方术语),用于轻松添加多个组件的响应式布局。 使用所有它们,您可以传入您期望的属性,例如 CSS 中的 bgjustifyContent 作为道具。

  • Stack - 在组件上以相等的间距对一组进行分组,默认情况下是垂直的,但可以用 isInline 覆盖。
  • Flex - 将所有内容包装在 Flexbox 容器 中。
  • Grid - 将所有内容包装在 CSS 网格容器 中。
  • Box - 只是一个用于接收样式道具的 div。

应用程序.js

import { Stack, Flex, Box, Grid } from "@chakra-ui/core";

const App = () => {
  const flexSettings = {
    flex: "1",
    minW: "300px",
    textAlign: "center",
    color: "white",
    mx: "6",
    mb: "6"
  };

  const gridSettings = {
    w: "100%",
    textAlign: "center",
    color: "white",
  };

  return (
    <div>
      <Flex w="100%" justify="space-between" flexWrap="wrap">
        <Box {...flexSettings} bg={"red.500"}>I'm a box</Box>
        <Box {...flexSettings} bg={"blue.500"}>I'm a box</Box>
        <Box {...flexSettings} bg={"green.500"}>I'm a box</Box>
        <Box {...flexSettings} bg={"purple.500"}>I'm a box</Box>
      </Flex>

      <Grid w="100%" templateColumns="repeat(auto-fit, minmax(300px, 1fr))" gap={6}>
        <Box {...gridSettings} bg={"red.500"}>I'm a box</Box>
        <Box {...gridSettings} bg={"blue.500"}>I'm a box</Box>
        <Box {...gridSettings} bg={"green.500"}>I'm a box</Box>
        <Box {...gridSettings} bg={"purple.500"}>I'm a box</Box>
      </Grid>
    </div>
  );
};

造型

由于 Chakra UI 基于 Emotion 进行样式设置,因此允许使用 CSS-in-JS 并为与 Tailwind CSS 相同样式的常见属性添加自己的简写,这就是我们能够使用 w 和 [ X208X] 而不是 widthgridTemplateColumns

如果您不熟悉这种样式设置方法,那么它是一种编写 CSS 的方法,因此您可以获得所有即使 Sass 也没有的 JavaScript 好东西,例如将样式连接到组件的状态。

在这个例子中,我们根据组件的状态来创建一个盒子的样式,并使用一个小的 UI 来操作它。

应用程序.js

const BoxController = () => {
  let [boxHeight, editHeight] = useState(20);
  let [boxColor, editColor] = useState('red');
  let [colorIntensity, editIntensity] = useState(500);

  const boxSettings = {
    flex: "1",
    textAlign: "center",
    color: "white",
    h: `${boxHeight}px`,
    bg: `${boxColor}.${colorIntensity}`
  };

  return (
    <div>
      <Box {...boxSettings}>I'm a Box</Box>
      <Flex justifyContent="space-around">
        <Stack>
          <Heading size="md">Size</Heading>
          <Button variantColor="red" onClick={() => editHeight(boxHeight -= 10)} border="none">Shrink</Button>
          <Button variantColor="green" onClick={() => editHeight(boxHeight += 10)} border="none">Grow</Button>
        </Stack>

        <Stack>
          <Heading size="md">Color</Heading>

          <Flex w="200px" justifyContent="space-between">

            <Stack>
              <Button variantColor="green" onClick={() => editColor('green')} border="none">Green</Button>
              <Button variantColor="blue" onClick={() => editColor('blue')} border="none">Blue</Button>
              <Button variantColor="red" onClick={() => editColor('red')} border="none">Red</Button>
            </Stack>

            <Stack>
              <Button variantColor="gray" variant="outline" onClick={() => editIntensity(colorIntensity -= 100)} border="none">Lighter</Button>
              <Button variantColor="gray" variant="outline" onClick={() => editIntensity(colorIntensity += 100)} border="none">Darker</Button>
            </Stack>

          </Flex>
        </Stack>
      </Flex>
    </div>
  );
};

组件

我们显然不能遍历每个组件,所以让我们只关注 Chakra UI 独有的几个。

抽屉

抽屉组件是一个干净的小滑出机制,非常适合任何侧面导航栏。 请注意,它使用 Chakra 的自定义 useDisclosure 钩子,它为我们提供了 isOpenonOpenonClose 来控制抽屉和任何类似组件的状态,例如一个模态。

应用程序.js

import {
  Drawer,
  DrawerBody,
  DrawerFooter,
  DrawerHeader,
  DrawerOverlay,
  DrawerContent,
  DrawerCloseButton,
  Input,
  Button,
  useDisclosure,
  Stack,
  Textarea
} from "@chakra-ui/core"

const SignUpForm = () =>  {
  const { isOpen, onOpen, onClose } = useDisclosure();
  const btnRef = useRef();

  return (
    <div>
      <Button ref={btnRef} variantColor="teal" border="none" onClick={onOpen}>
        Sign Up
      </Button>
      <Drawer
        isOpen={isOpen} placement="bottom"
        onClose={onClose} finalFocusRef={btnRef}
      >
        <DrawerOverlay />
        <DrawerContent>

          <DrawerCloseButton border="none" />
          <DrawerHeader>Sign up Now</DrawerHeader>

          {/* Form */}
          <DrawerBody >
            <Stack height="30vh">
              <Input w="98%" placeholder="Name" />
              <Input w="98%" placeholder="Email" />
              <Textarea w="98%" h="100%" placeholder="Message" />
            </Stack>
          </DrawerBody>

          <DrawerFooter>
            <Button variantColor="red" border="none" mr={3} onClick={onClose}>
              Cancel
            </Button>
            <Button variantColor="blue" border="none">Save</Button>
          </DrawerFooter>

        </DrawerContent>
      </Drawer>
    </div>
  );
}

装载机

Chakra UI 为我们提供了一系列非常容易定制的动画加载器。 在这个例子中,我添加了一个循环来查看我们的加载器在运行,但它们不需要基于任何外部,它们也可以是完全静态的。

应用程序.js

import {
  Stack,
  CircularProgress,
  CircularProgressLabel,
  Progress,
  Spinner
} from "@chakra-ui/core"

const Spinners = () => {
  let [progress, update] = useState(0)

  const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)

  useEffect(() => setInterval(() => {
    // Reset to 0 when reaches 100
    update(progress < 100 ? progress += randomNum(0, 4) : 0)
  }, 500), [])

  return (
    <div>
      <Stack>
        <CircularProgress color="green" isIndeterminate>
          <CircularProgressLabel>{progress}%</CircularProgressLabel>
        </CircularProgress>
        <CircularProgress value={progress} size="100px" thickness={0.1} color="purple" />
        <Progress value={progress} w="90%" />
        <Progress value={progress + 10} w="90%" hasStripe isAnimated />
        <Spinner
          thickness="3px"
          speed="1s"
          emptyColor="gray.200"
          color="blue.500"
          size="2xl"
        />
      </Stack>
    </div>
  );
}

主题

我还没有从任何其他框架中看到的是能够在整个应用程序中设置主题。 无论是深色主题还是冬季主题,我们都可以在一个地方轻松自定义整个网站/应用程序的样式。

在此示例中,我添加了几个框,其设计和文本将基于假日季节。 我个人喜欢网站让您选择最喜欢的设计,就像 Alligator.io 所做的那样。 😉

index.js

import { useTheme, ThemeProvider } from "@chakra-ui/core"


const ThemedApp = () => {
  const theme = useTheme()
  const customTheme = {
    ...theme,
    colors: { ...theme.colors },
    holidays: {
        text: {
          none: "Welcome to the site!",
          stPatricksDay: "Happy St.Patty's Day!",
          valentinesDay: "Happy Valentines Day!",
          halloween: "Good luck trick-or-treating!",
          christmas: "Merry Christmas!"
        },
        colors: {
            none: {
              "one": "#808080",
              "two": "#808080",
              "three": "#808080"
            },
            stPatricksDay: {
              "one": "#224D17",
              "two": "#60A830",
              "three": "#099441"
            },
            valentinesDay: {
              "one": "#b11d4d",
              "two": "#fd6fa0",
              "three": "#e986a3"
            },
            halloween: {
              "one": "#810806",
              "two": "#BF200E",
              "three": "#FA4113"
            },
            christmas: {
              "one": "#44b09e",
              "two": "#e0d2c7",
              "three": "#e01c34"
            },
        }
      }
  };
  return (
    <div>
      <ThemeProvider theme={customTheme}><App /></ThemeProvider>
    </div>
  )
}

应用程序.js

import {
  Flex,
  Button,
  useTheme,
  Box
} from "@chakra-ui/core"

const HolidayPicker = () => {
  const [holiday, updateHoliday] = useState("none")
  const theme = useTheme()

  const holidayText = theme.holidays.text[holiday]
  const holidayColor = theme.holidays.colors[holiday]

  const btnStyles = {
    border: 'none',
    h: '25px',
    borderRadius: '20px',
    color: 'white',
    fontWeight: 'bold',
    cursor: 'pointer'
  }
  return (
    <div>
      <Flex justifyContent="space-around">
        <Box bg={holidayColor.one} w="100%" h="400px" color="white">{holidayText}</Box>
        <Box bg={holidayColor.two} w="100%" h="400px" color="white">{holidayText}</Box>
        <Box bg={holidayColor.three} w="100%" h="400px" color="white">{holidayText}</Box>
      </Flex>

      <Flex justifyContent="space-around" mt="20px">
        <Button bg={theme.holidays.colors.none} {...btnStyles}
          onClick={() => updateHoliday('none')}>None</Button>
        <Button bg={theme.holidays.colors.stPatricksDay} {...btnStyles}
          onClick={() => updateHoliday('stPatricksDay')}
        >St.Patrick's Day</Button>
        <Button bg={theme.holidays.colors.valentinesDay} {...btnStyles}
          onClick={() => updateHoliday('valentinesDay')}
        >Valentine's Day</Button>
        <Button bg={theme.holidays.colors.halloween} {...btnStyles}
          onClick={() => updateHoliday('halloween')}
        >Halloween</Button>
        <Button bg={theme.holidays.colors.christmas} {...btnStyles}
          onClick={() => updateHoliday('christmas')}
        >Christmas</Button>
      </Flex>
    </div>
  );
}

结束的想法

与 TailwindCSS 一起,Chakra UI 很容易成为我所有项目中必不可少的工具之一。 它在不断改进,甚至现在还有一些像 appBar 和轮播组件这样的拉取请求可能很快就会被添加。 我希望这足以帮助你决定 Chakra UI 是否应该出现在你的 React/UI 库中。