折叠面板Collapse、CollapseItem两个组件实现,Collapse用于接收一些折叠面板全局配置,如手风琴、懒加载等;CollapseItem用于对单个折叠栏进行配置,如禁用、排列、图标,因此核心部分使用useContext将父组件的props的部分子组件所需要的值传递给所有子组件。

组件库文档如下:

组件提供的API能力如下:

组件源码如下:
Collapse.tsx:

import React, { FC, memo, useState, createContext } from 'react';
import { CollapseProps } from './interfase';
import './style/index.module.less';export const ctx = createContext<any>({} as any); //顶层通信装置const Collapse: FC<CollapseProps> = (props) => {const {children,defaultActive,accordion,noBorder,headerAlign = 'left',lazyLoad = false,toggleCallback,} = props;const [activeKeyList, setActiveKeyList] = useState<Array<number | string>>(defaultActive || []); //父组件管理选中列表const providerList = {//父组件状态管理storeactiveKeyList,setActiveKeyList,accordion,headerAlign,lazyLoad,toggleCallback,};return (<ctx.Provider value={providerList}><divclassName="collapse-box"style={noBorder ? {} : { border: '1px solid rgba(229, 230, 235, 1)' }}>{children}</div></ctx.Provider>);
};export default memo(Collapse);

CollapseItem.tsx:

import React, { FC, memo, useMemo, useEffect, useContext } from 'react';
import { CollapseItemProps } from './interfase';
import { CaretDownOutlined, CaretRightOutlined, CaretLeftOutlined } from '@ant-design/icons';
import './style/item.module.less';
import useStateCallback from '../_util/hooks/useStateCallback';
import { ctx } from './index';const CollapseItem: FC<CollapseItemProps> = (props) => {const { children, header, disabled = false, listKey, extra } = props;const [contentDomHeight, setContentDomHeight] = useStateCallback(0);const [hasOpen, setHasOpen] = useStateCallback(false);const { activeKeyList, setActiveKeyList, accordion, headerAlign, lazyLoad, toggleCallback } =useContext(ctx); //父组件共享状态useEffect(() => {//根据默认值展开或收起if (activeKeyList.indexOf(Number(listKey)) == -1) {setContentDomHeight(0);} else {setContentDomHeight((document.querySelector('.collapse-item-content') as HTMLElement).scrollHeight + 30,);}}, [activeKeyList]);const toggleContent = () => {if (disabled) return; //禁用let newHeight = contentDomHeight;if (newHeight == 0) {//展开if (lazyLoad && !hasOpen) {//首次展开懒加载setHasOpen(true, (state: boolean) => {newHeight =(document.querySelector('.collapse-item-content') as HTMLElement).scrollHeight + 30;if (accordion) {//手风琴,全部清除再加入setActiveKeyList([Number(listKey)]);toggleCallback && toggleCallback([Number(listKey)]);} else {setActiveKeyList((oldAList: Array<string | number>) => {toggleCallback && toggleCallback([...[...oldAList, Number(listKey)].sort()]);return [...[...oldAList, Number(listKey)].sort()];});}setContentDomHeight(newHeight);});} else {newHeight =(document.querySelector('.collapse-item-content') as HTMLElement).scrollHeight + 30;if (accordion) {//手风琴,全部清除再加入setActiveKeyList([Number(listKey)]);toggleCallback && toggleCallback([Number(listKey)]);} else {setActiveKeyList((oldAList: Array<string | number>) => {toggleCallback && toggleCallback([...[...oldAList, Number(listKey)].sort()]);return [...[...oldAList, Number(listKey)].sort()];});}setContentDomHeight(newHeight);}} else {//收起newHeight = 0;setActiveKeyList((oldAList: Array<string | number>) => {oldAList.splice(oldAList.findIndex((item: number | string, i: number | string) => Number(i) + 1 == listKey,),1,);return [...oldAList.sort()];});setContentDomHeight(newHeight);}};const headerHeight = useMemo(() => {//展开高度return {maxHeight: `${contentDomHeight}px`,};}, [contentDomHeight]);const renderHeader = useMemo(() => {if (headerAlign == 'left') {return (<divclassName="collapse-item-header"onClick={toggleContent}style={disabled ? { color: '#c9cdd4', cursor: 'not-allowed' } : {}}><div className="left"><div className="header-icon">{headerHeight.maxHeight == '0px' ? <CaretRightOutlined /> : <CaretDownOutlined />}</div><div className="header-text">{header}</div></div>{extra && <div className="right">{extra}</div>}</div>);} else if (headerAlign == 'right') {return (<divclassName="collapse-item-header"onClick={toggleContent}style={disabled ? { color: '#c9cdd4', cursor: 'not-allowed' } : {}}><div className="left"><div className="header-text">{header}</div></div><div className="right">{extra}<div className="header-icon">{headerHeight.maxHeight == '0px' ? <CaretLeftOutlined /> : <CaretDownOutlined />}</div></div></div>);} else if (headerAlign == 'hide') {return (<divclassName="collapse-item-header"onClick={toggleContent}style={disabled ? { color: '#c9cdd4', cursor: 'not-allowed' } : {}}><div className="left"><div className="header-text">{header}</div></div><div className="right">{extra}</div></div>);}}, [headerAlign, headerHeight, disabled]);return (<div className="collapse-item">{renderHeader}<div className="collapse-item-content" style={headerHeight}>{lazyLoad ? hasOpen && children : children}</div></div>);
};export default memo(CollapseItem);

Concis组件库线上链接:http://react-view-ui.com:92
github:https://github.com/fengxinhhh/Concis
npm:https://www.npmjs.com/package/concis

开源不易,欢迎学习和体验,喜欢请多多支持,有问题请留言。

Concis组件库封装——Collapse折叠面板相关推荐

  1. Concis组件库封装——Badge徽标

    徽标其实和上文的Avatar头像是配套的,通常徽标的需求都是在头像的基础上提供的,因此本文将介绍徽标组件的封装,徽标其实是一个展示类组件,并没有什么交互,因此这个组件实现起来比较简单~ 先看一下组件库 ...

  2. Concis组件库封装——LazyLoad懒加载

    懒加载组件,支持任意元素进行延迟加载,可以在SPA单页应用首页渲染时减少非可视区的DOM渲染,加快首屏渲染效率,大致用法: <LazyLoad><div><span> ...

  3. Concis组件库封装——Rate评分

    Rate评分组件官方文档如下: 源码如下: import React, { FC, useState, useEffect, memo, useCallback } from 'react'; imp ...

  4. element-plus 组件解析 - Collapse 折叠面板

    element-plus 组件解析 - Collapse 折叠面板 1, 组件介绍 2,组件组成 3,组件实现 3.1,el-collapse 1,v-model="activeNames& ...

  5. 基于lerna重构Concis组件库

    lerna重构Concis项目 前言 重构过程 发包 Concis的地址 前言 博主最近在开发React组件库--Concis,目前针对PC端已经开发了30+组件,未来是期望可以转换出一套轻量的Mob ...

  6. 用timeline 时间线 和 Collapse 折叠面板做一个简单的时间轴

    项目上有个时间轴功能,我看了一下element上有时间轴功能,不过有点太简单,我想改造一下这个时间轴,记录一下,用Timeline 时间线 和 Collapse 折叠面板,两个加起来做了一时间轴,当是 ...

  7. 浅尝 | 从 0 到 1 Vue 组件库封装

    写在前面 对于目前框架为王的时代,前端可能很大一部分时间,都是在开发相关的页面组件,而有句话说得好,没有哪个前端不想拥有一个属于自己的,为自己量身定制的组件库,那么本文就为大家整理一下: 如何从 0 ...

  8. Vant组件库封装可翻页日历组件

    前言 我们在进行VUE开发的时候有的时候会使用到VantUI组件库: https://vant-contrib.gitee.io/vant/v2/#/zh-CN/home#jie-shao Vant ...

  9. collapse 微信小程序_微信小程序之有赞组件Collapse折叠面板的使用

    1. 使用指南 在 app.json 或 index.json 中引入组件 es6 "usingComponents": { "van-collapse": & ...

  10. ElementPlus的Collapse 折叠面板问题

    我也不明白为什么会报这个错误,把关于ts的代码改成js的就可以了.. ERROR in ./src/views/Home.vue?vue&type=script&lang=ts& ...

最新文章

  1. 在Linux上进行内核参数调整
  2. iphone无线服务器未响应,iPhone无线充电断断续续或无法充电是什么原因?
  3. 她因重仓马斯克和比特币封神!现在分享了十大2021技术趋势
  4. 支付宝的kill-ie
  5. 《程序员代码面试指南第二版》Python实现(个人读书笔记)
  6. spring 中 Hibernate 事务和JDBC事务嵌套问题
  7. MyBatis 源码解读-reflectorFactoryElement()
  8. DRDoS分布反射式拒绝服务攻击(什么是DRDoS)
  9. 容器编排技术 -- Windows Server 容器
  10. Oracle数据库学习(四)
  11. wps怎么图片透明_Tips:设置图片透明背景
  12. 倒立摆小车matlab仿真,倒立摆系统的建模及Matlab仿真分析
  13. pxe装机原理_pxe网络安装操作系统 原理与详细过程
  14. HTML标签关系——双标签和单标签,标签的嵌套与并列
  15. spring 事物(一)—— 事物详解
  16. PMP-项目采购管理
  17. FreeRTOS个人笔记-初谈CM3内核
  18. R可视乎|创建乐高版马赛克图
  19. Xss漏洞原理分析及简单的讲解
  20. 艾美捷RPMI-1640培养基含L-谷氨酰胺的功能和研究

热门文章

  1. 中国工程院院士倪光南:大数据产业安全和发展需同步
  2. JAVA设计模式详解(四)----------适配器模式
  3. 数据库原理 第四章作业
  4. 2021中国机器人操作系统(ROS)暑期学校-转载
  5. 不做自了汉,大家好才是真的好
  6. 算法篇-----粒子群算法
  7. RuntimeError: Error(s) in loading state_dict for BNInception:size mismatch for
  8. 什么是天使轮、A轮、B轮、C轮、D轮融资
  9. UEFI/GPT分区
  10. Java开源文件病毒扫描_使用多种反病毒引擎扫描文件