React组件 - 折叠展开组件之@kunukn/react-collapse

3,795 阅读2分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

前言:

最近的项目,UI 设计使用jQuery做了展开折叠展开的动画效果,需要设置折叠展开的动画时长。
找了一堆 React 的组件后,终于找到一个符合要求的。
就是这个 @kunukn/react-collapse。

效果如下:

kunukn-react-collapse.gif

上述效果的代码地址:

helloreact/kunukn-react-collapse at main · bettersun/helloreact (github.com)

React折叠展开组件 @kunukn/react-collapse

npm 地址:

@kunukn/react-collapse - npm (npmjs.com)

github 地址:

[kunukn/react-collapse: Component-wrapper for collapse animation with CSS for elements with variable and dynamic height (github.com)](github.com/nkbt/react-…)


下面的内容为文档的翻译(人肉翻译,理解或翻译若有不当,还请指正,部分内容未翻译)

必要的CSS

⚠️ ️你需要在 CSS 样式文件里添加样式 (transition)用来添加动画。

例:

<style>
  .collapse-css-transition {
    transition: height 280ms cubic-bezier(0.4, 0, 0.2, 1);
  }
</style>

也可以把样式的内容加到 transition 属性里。

  <Collapse
    transition={`height ${duration} cubic-bezier(.4, 0, .2, 1)`}
    isOpen={isOpen}
  >

不指定此样式则无动画效果。

React 16.8+版本的安装

npm i @kunukn/react-collapse
# or 
# yarn add @kunukn/react-collapse 

React 16.3+版本的安装

npm i @kunukn/react-collapse@^1
# or 
# yarn add @kunukn/react-collapse@^1 

import Collapse from "@kunukn/react-collapse";
// or with require syntax
// const Collapse = require("@kunukn/react-collapse");
 
const MyComponent = () => (
  <Collapse isOpen={true || false}>
    <div>Your content</div>
  </Collapse>
);

属性

属性类型默认值
isOpenbooleanfalse
childrennode | function
renderfunction
classNamestringcollapse-css-transition
transitionstring
elementTypestringdiv
collapseHeightstring0px
onChangefunction
onInitfunction
addStatebooleanfalse
noAnimbooleanfalse
overflowOnExpandedbooleanfalse
  • isOpen

    true: 展开,false:折叠。

  • children : 子组件或子组件函数。

    渲染:

    const MyComponent = ({ isOpen }) => (
      <Collapse isOpen={isOpen}>
        <p>Paragraph of text.</p>
        <p>Another paragraph is also OK.</p>
        <p>Images and any other content are ok too.</p>
        <img src="cutecat.gif" />
      </Collapse>
    );
    

    使用属性模式渲染:

    const MyComponent = ({ isOpen }) => (
      <Collapse isOpen={isOpen}>
        {state => (
          <div className={`using-collapse-state-to-add-css-class ${state}`}>
            <p>I know the collapse state: {state}</p>
          </div>
        )}
      </Collapse>
    );
    
  • render : 渲染函数

    const MyComponent = ({ isOpen }) => {
      const render = state => (
        <div className={`using-collapse-state-to-add-css-class ${state}`}>
          <p>I know the collapse state: {state}</p>
        </div>
      );
      return <Collapse isOpen={isOpen} render={render} />;
    };
    

    有四个可用的折叠状态:collapsed, collapsing, expanded, expanding.

  • className : 子组件的CSS 类名

    可以指定一个自定义的 CSS 类名。默认值是 collapse-css-transition

    指定子组件的 CSS 类名时,记得要添加 CSS 的 transition。

  • transition : 变换动画参数

    也可以使用 transition 属性来在指定CSS的 transition。

    const MyComponent = ({ isOpen, duration = "290ms" }) => (
      <Collapse
        transition={`height ${duration} cubic-bezier(.4, 0, .2, 1)`}
        isOpen={isOpen}
      >
        <p>Paragraph of text</p>
      </Collapse>
    );
    
  • elementType : 生成的子组件的HTML元素类型,默认是 div。

    const MyComponent = ({ isOpen }) => (
      <Collapse elementType="article" isOpen={isOpen}>
        <p>Paragraph of text inside an article element</p>
      </Collapse>
    );
    
  • collapseHeight : 折叠时高度

    可指定折叠时的高度用于显示部分内容。

    const MyComponent = ({ isOpen }) => (
      <Collapse collapseHeight="40px" isOpen={isOpen}>
        <p>A long paragraph of text inside an article element</p>
      </Collapse>
    );
    
  • onChange : 切换时的回调函数,有state 和 style 两个参数,可用来设置状态和样式。

    const MyComponent = ({ isOpen }) => {
      const onChange = ({ state, style }) => {
        /*
        state: string = the state of the collapse component.
        style: object = styles that are applied to the component.
      */
      };
     
      return (
        <Collapse onChange={onChange} isOpen={isOpen}>
          <p>A long paragraph of text inside an article element</p>
        </Collapse>
      );
    };
    
  • onInit : 和 onChange 类似,但只在 DOM 加载时调用。

    下面是开始为折叠状态,加载时展开的例子。

    const MyComponent = () => {
     
      const [isOpen, setIsOpen] = React.useState(false);
     
      const onInit = ({ state, style, node }) => {
        /*
           node: HTMLElement = the DOM node of the component.
        */
      
        setIsOpen(true);
      };
     
      return (
        <div>
          <button onClick={() => setIsOpen(state => !state)}> Toggle </button>
          <Collapse onInit={onInit} isOpen={isOpen}>
            <p>A long paragraph of text inside an article element</p>
          </Collapse>
        </div>
      );
    };
    
  • addState

    如果添加此属性 ,则下面的属性会根据状态来决定是否添加到组件。

    --c-collapsed
    --c-collapsing
    --c-expanded
    --c-expanding
    
  • noAnim

    如果添加此属性,则不会有折叠展开时的动画。

    只会在折叠后和展开后的两种状态切换。

  • overflowOnExpanded

    如果添加此属性,则展开时不会加上 overflow: hidden 样式。

  • 自定义属性,Collapse 支持向渲染的DOM 元素上应用例如 aria- 和 data- 的自定义属性。

    比如用来设定aria-hidden属性

    const MyComponent = ({ isOpen }) => (
      <Collapse aria-hidden={isOpen ? "false" : "true"} isOpen={isOpen}>
        <p>Paragraph of text</p>
      </Collapse>
    );
    

    比如指定动画时长,可使用下面的自定义属性。

    const collapseStyles = { transitionDuration: "270ms" };
     
    const MyComponent = ({ isOpen }) => (
      <Collapse style={collapseStyles} isOpen={isOpen}>
        <p>Paragraph of text</p>
      </Collapse>
    );
    

支持的浏览器

IE11以上的现代浏览器

支持的 React 版本

  • React version 16.3+ : 使用 Collapse 版本 1
  • React version 16.8+ : 使用 Collapse 版本 2+

使用的 React16.3的生命周期

  • render (使用折叠状态来调用 CSS transition)
  • componentDidMount (初始为展开或折叠状态)
  • getDerivedStateFromProps (检测isOpen,如果isOpen 属性被改变,则应用一个新的折叠状态)
  • componentDidUpdate (从四个折叠状态中更新样式状态)

使用的React16.8钩子

  • useState
  • useEffect
  • useRef
  • useCallback
  • useReducer