refactor: collapse
							parent
							
								
									740ba04c02
								
							
						
					
					
						commit
						af182533c1
					
				|  | @ -0,0 +1,143 @@ | |||
| import { isEmptyElement, initDefaultProps, flattenChildren } from '../_util/props-util'; | ||||
| import { cloneElement } from '../_util/vnode'; | ||||
| import openAnimationFactory from './openAnimationFactory'; | ||||
| import { collapseProps, CollapsibleType } from './commonProps'; | ||||
| import { getDataAndAriaProps } from '../_util/util'; | ||||
| import { computed, defineComponent, ref, watch } from 'vue'; | ||||
| import firstNotUndefined from '../_util/firstNotUndefined'; | ||||
| import classNames from '../_util/classNames'; | ||||
| 
 | ||||
| type Key = number | string; | ||||
| 
 | ||||
| function getActiveKeysArray(activeKey: Key | Key[]) { | ||||
|   let currentActiveKey = activeKey; | ||||
|   if (!Array.isArray(currentActiveKey)) { | ||||
|     const activeKeyType = typeof currentActiveKey; | ||||
|     currentActiveKey = | ||||
|       activeKeyType === 'number' || activeKeyType === 'string' ? [currentActiveKey] : []; | ||||
|   } | ||||
|   return currentActiveKey.map(key => String(key)); | ||||
| } | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'Collapse', | ||||
|   inheritAttrs: false, | ||||
|   props: initDefaultProps(collapseProps(), { | ||||
|     prefixCls: 'rc-collapse', | ||||
|     accordion: false, | ||||
|     destroyInactivePanel: false, | ||||
|   }), | ||||
|   slots: ['expandIcon'], | ||||
|   emits: ['change'], | ||||
|   setup(props, { attrs, slots, emit }) { | ||||
|     const stateActiveKey = ref<Key[]>( | ||||
|       getActiveKeysArray(firstNotUndefined([props.activeKey, props.defaultActiveKey])), | ||||
|     ); | ||||
| 
 | ||||
|     watch( | ||||
|       () => props.activeKey, | ||||
|       () => { | ||||
|         stateActiveKey.value = getActiveKeysArray(props.activeKey); | ||||
|       }, | ||||
|     ); | ||||
|     const currentOpenAnimations = computed( | ||||
|       () => props.openAnimation || openAnimationFactory(props.prefixCls), | ||||
|     ); | ||||
| 
 | ||||
|     const setActiveKey = (activeKey: Key[]) => { | ||||
|       if (props.activeKey === undefined) { | ||||
|         stateActiveKey.value = activeKey; | ||||
|       } | ||||
|       emit('change', props.accordion ? activeKey[0] : activeKey); | ||||
|     }; | ||||
|     const onClickItem = (key: Key) => { | ||||
|       let activeKey = stateActiveKey.value; | ||||
|       if (props.accordion) { | ||||
|         activeKey = activeKey[0] === key ? [] : [key]; | ||||
|       } else { | ||||
|         activeKey = [...activeKey]; | ||||
|         const index = activeKey.indexOf(key); | ||||
|         const isActive = index > -1; | ||||
|         if (isActive) { | ||||
|           // remove active state | ||||
|           activeKey.splice(index, 1); | ||||
|         } else { | ||||
|           activeKey.push(key); | ||||
|         } | ||||
|       } | ||||
|       setActiveKey(activeKey); | ||||
|     }; | ||||
| 
 | ||||
|     const getNewChild = (child, index) => { | ||||
|       if (isEmptyElement(child)) return; | ||||
|       const activeKey = stateActiveKey.value; | ||||
|       const { | ||||
|         prefixCls, | ||||
|         accordion, | ||||
|         destroyInactivePanel, | ||||
|         expandIcon = slots.expandIcon, | ||||
|         collapsible, | ||||
|       } = props; | ||||
| 
 | ||||
|       // If there is no key provide, use the panel order as default key | ||||
|       const key = String(child.key ?? index); | ||||
|       const { | ||||
|         header = child.children?.header?.(), | ||||
|         headerClass, | ||||
|         collapsible: childCollapsible, | ||||
|         disabled, | ||||
|       } = child.props || {}; | ||||
|       let isActive = false; | ||||
| 
 | ||||
|       if (accordion) { | ||||
|         isActive = activeKey[0] === key; | ||||
|       } else { | ||||
|         isActive = activeKey.indexOf(key) > -1; | ||||
|       } | ||||
| 
 | ||||
|       let mergeCollapsible: CollapsibleType = childCollapsible ?? collapsible; | ||||
|       // legacy 2.x | ||||
|       if (disabled || disabled === '') { | ||||
|         mergeCollapsible = 'disabled'; | ||||
|       } | ||||
|       const newProps = { | ||||
|         key, | ||||
|         panelKey: key, | ||||
|         header, | ||||
|         headerClass, | ||||
|         isActive, | ||||
|         prefixCls, | ||||
|         destroyInactivePanel, | ||||
|         openAnimation: currentOpenAnimations.value, | ||||
|         accordion, | ||||
|         onItemClick: mergeCollapsible === 'disabled' ? null : onClickItem, | ||||
|         expandIcon, | ||||
|         collapsible: mergeCollapsible, | ||||
|       }; | ||||
| 
 | ||||
|       return cloneElement(child, newProps); | ||||
|     }; | ||||
| 
 | ||||
|     const getItems = () => { | ||||
|       return flattenChildren(slots.default?.()).map(getNewChild); | ||||
|     }; | ||||
| 
 | ||||
|     return () => { | ||||
|       const { prefixCls, accordion } = props; | ||||
|       const collapseClassName = classNames({ | ||||
|         [prefixCls]: true, | ||||
|         [attrs.class as string]: !!attrs.class, | ||||
|       }); | ||||
|       return ( | ||||
|         <div | ||||
|           class={collapseClassName} | ||||
|           {...getDataAndAriaProps(attrs)} | ||||
|           style={attrs.style} | ||||
|           role={accordion ? 'tablist' : null} | ||||
|         > | ||||
|           {getItems()} | ||||
|         </div> | ||||
|       ); | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|  | @ -0,0 +1,109 @@ | |||
| import PanelContent from './PanelContent'; | ||||
| import { initDefaultProps } from '../_util/props-util'; | ||||
| import { panelProps } from './commonProps'; | ||||
| import { defineComponent } from 'vue'; | ||||
| import Transition from '../_util/transition'; | ||||
| import classNames from '../_util/classNames'; | ||||
| import devWarning from '../vc-util/devWarning'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'Panel', | ||||
|   props: initDefaultProps(panelProps(), { | ||||
|     showArrow: true, | ||||
|     isActive: false, | ||||
|     onItemClick() {}, | ||||
|     headerClass: '', | ||||
|     forceRender: false, | ||||
|   }), | ||||
|   slots: ['expandIcon', 'extra', 'header'], | ||||
|   emits: ['itemClick'], | ||||
|   setup(props, { slots, emit }) { | ||||
|     devWarning( | ||||
|       !('disabled' in props), | ||||
|       'Collapse.Panel', | ||||
|       '`disabled` is deprecated. Please use `collapsible="disabled"` instead.', | ||||
|     ); | ||||
|     const handleItemClick = () => { | ||||
|       emit('itemClick', props.panelKey); | ||||
|     }; | ||||
|     const handleKeyPress = (e: KeyboardEvent) => { | ||||
|       if (e.key === 'Enter' || e.keyCode === 13 || e.which === 13) { | ||||
|         handleItemClick(); | ||||
|       } | ||||
|     }; | ||||
|     return () => { | ||||
|       const { | ||||
|         prefixCls, | ||||
|         header = slots.header?.(), | ||||
|         headerClass, | ||||
|         isActive, | ||||
|         showArrow, | ||||
|         destroyInactivePanel, | ||||
|         accordion, | ||||
|         forceRender, | ||||
|         openAnimation, | ||||
|         expandIcon = slots.expandIcon, | ||||
|         extra = slots.extra?.(), | ||||
|         collapsible, | ||||
|       } = props; | ||||
|       const disabled = collapsible === 'disabled'; | ||||
| 
 | ||||
|       const headerCls = classNames(`${prefixCls}-header`, { | ||||
|         [headerClass]: headerClass, | ||||
|         [`${prefixCls}-header-collapsible-only`]: collapsible === 'header', | ||||
|       }); | ||||
|       const itemCls = classNames({ | ||||
|         [`${prefixCls}-item`]: true, | ||||
|         [`${prefixCls}-item-active`]: isActive, | ||||
|         [`${prefixCls}-item-disabled`]: disabled, | ||||
|       }); | ||||
| 
 | ||||
|       let icon = <i class="arrow" />; | ||||
|       if (showArrow && typeof expandIcon === 'function') { | ||||
|         icon = expandIcon(props); | ||||
|       } | ||||
| 
 | ||||
|       const panelContent = ( | ||||
|         <PanelContent | ||||
|           v-show={isActive} | ||||
|           prefixCls={prefixCls} | ||||
|           isActive={isActive} | ||||
|           forceRender={forceRender} | ||||
|           role={accordion ? 'tabpanel' : null} | ||||
|           v-slots={{ default: slots.default }} | ||||
|         ></PanelContent> | ||||
|       ); | ||||
|       const transitionProps = { | ||||
|         appear: true, | ||||
|         css: false, | ||||
|         ...openAnimation, | ||||
|       }; | ||||
| 
 | ||||
|       return ( | ||||
|         <div class={itemCls}> | ||||
|           <div | ||||
|             class={headerCls} | ||||
|             onClick={() => collapsible !== 'header' && handleItemClick()} | ||||
|             role={accordion ? 'tab' : 'button'} | ||||
|             tabindex={disabled ? -1 : 0} | ||||
|             aria-expanded={isActive} | ||||
|             onKeypress={handleKeyPress} | ||||
|           > | ||||
|             {showArrow && icon} | ||||
|             {collapsible === 'header' ? ( | ||||
|               <span onClick={handleItemClick} class={`${prefixCls}-header-text`}> | ||||
|                 {header} | ||||
|               </span> | ||||
|             ) : ( | ||||
|               header | ||||
|             )} | ||||
|             {extra && <div class={`${prefixCls}-extra`}>{extra}</div>} | ||||
|           </div> | ||||
|           <Transition {...transitionProps}> | ||||
|             {!destroyInactivePanel || isActive ? panelContent : null} | ||||
|           </Transition> | ||||
|         </div> | ||||
|       ); | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|  | @ -0,0 +1,34 @@ | |||
| import { defineComponent, ref, watchEffect } from 'vue'; | ||||
| import { panelProps } from './commonProps'; | ||||
| import classNames from '../_util/classNames'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'PanelContent', | ||||
|   props: panelProps(), | ||||
|   setup(props, { slots }) { | ||||
|     const rendered = ref(false); | ||||
| 
 | ||||
|     watchEffect(() => { | ||||
|       if (props.isActive || props.forceRender) { | ||||
|         rendered.value = true; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     return () => { | ||||
|       if (!rendered.value) return null; | ||||
|       const { prefixCls, isActive, role } = props; | ||||
|       return ( | ||||
|         <div | ||||
|           ref={ref} | ||||
|           class={classNames(`${prefixCls}-content`, { | ||||
|             [`${prefixCls}-content-active`]: isActive, | ||||
|             [`${prefixCls}-content-inactive`]: !isActive, | ||||
|           })} | ||||
|           role={role} | ||||
|         > | ||||
|           <div class={`${prefixCls}-content-box`}>{slots.default?.()}</div> | ||||
|         </div> | ||||
|       ); | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|  | @ -1,100 +0,0 @@ | |||
| @prefixCls: rc-collapse; | ||||
| @text-color: #666; | ||||
| @borderStyle: 1px solid #d9d9d9; | ||||
| 
 | ||||
| #arrow { | ||||
|   .common() { | ||||
|     width: 0; | ||||
|     height: 0; | ||||
|     font-size: 0; | ||||
|     line-height: 0; | ||||
|   } | ||||
|   .right(@w, @h, @color) { | ||||
|     border-top: @w solid transparent; | ||||
|     border-bottom: @w solid transparent; | ||||
|     border-left: @h solid @color; | ||||
|   } | ||||
| 
 | ||||
|   .bottom(@w, @h, @color) { | ||||
|     border-left: @w solid transparent; | ||||
|     border-right: @w solid transparent; | ||||
|     border-top: @h solid @color; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .@{prefixCls} { | ||||
|   background-color: #f7f7f7; | ||||
|   border-radius: 3px; | ||||
|   border: @borderStyle; | ||||
| 
 | ||||
|   &-anim-active { | ||||
|     transition: height 0.2s ease-out; | ||||
|   } | ||||
| 
 | ||||
|   & > &-item { | ||||
|     border-top: @borderStyle; | ||||
|     &:first-child { | ||||
|       border-top: none; | ||||
|     } | ||||
| 
 | ||||
|     > .@{prefixCls}-header { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       line-height: 22px; | ||||
|       padding: 10px 16px; | ||||
|       color: #666; | ||||
|       cursor: pointer; | ||||
|       .arrow { | ||||
|         display: inline-block; | ||||
|         content: '\20'; | ||||
|         #arrow > .common(); | ||||
|         #arrow > .right(3px, 4px, #666); | ||||
|         vertical-align: middle; | ||||
|         margin-right: 8px; | ||||
|       } | ||||
| 
 | ||||
|       .@{prefixCls}-extra { | ||||
|         margin: 0 16px 0 auto; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   & > &-item-disabled > .@{prefixCls}-header { | ||||
|     cursor: not-allowed; | ||||
|     color: #999; | ||||
|     background-color: #f3f3f3; | ||||
|   } | ||||
| 
 | ||||
|   &-content { | ||||
|     overflow: hidden; | ||||
|     color: @text-color; | ||||
|     padding: 0 16px; | ||||
|     background-color: #fff; | ||||
| 
 | ||||
|     & > &-box { | ||||
|       margin-top: 16px; | ||||
|       margin-bottom: 16px; | ||||
|     } | ||||
| 
 | ||||
|     &-inactive { | ||||
|       display: none; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-item:last-child { | ||||
|     > .@{prefixCls}-content { | ||||
|       border-radius: 0 0 3px 3px; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   & > &-item-active { | ||||
|     > .@{prefixCls}-header { | ||||
|       .arrow { | ||||
|         position: relative; | ||||
|         top: 2px; | ||||
|         #arrow > .bottom(3px, 4px, #666); | ||||
|         margin-right: 6px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -1,4 +1,7 @@ | |||
| import PropTypes from '../../_util/vue-types'; | ||||
| import type { PropType } from 'vue'; | ||||
| import PropTypes from '../_util/vue-types'; | ||||
| 
 | ||||
| export type CollapsibleType = 'header' | 'disabled'; | ||||
| 
 | ||||
| const collapseProps = () => ({ | ||||
|   prefixCls: PropTypes.string, | ||||
|  | @ -19,6 +22,7 @@ const collapseProps = () => ({ | |||
|   openAnimation: PropTypes.object, | ||||
|   expandIconPosition: PropTypes.oneOf(['left', 'right']), | ||||
|   onChange: PropTypes.func, | ||||
|   collapsible: { type: String as PropType<CollapsibleType> }, | ||||
| }); | ||||
| 
 | ||||
| const panelProps = () => ({ | ||||
|  | @ -34,7 +38,10 @@ const panelProps = () => ({ | |||
|   forceRender: PropTypes.looseBool, | ||||
|   expandIcon: PropTypes.func, | ||||
|   extra: PropTypes.any, | ||||
|   panelKey: PropTypes.any, | ||||
|   panelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||||
|   collapsible: { type: String as PropType<CollapsibleType> }, | ||||
|   role: String, | ||||
|   onItemClick: { type: Function as PropType<(panelKey: string | number) => void> }, | ||||
| }); | ||||
| 
 | ||||
| export { collapseProps, panelProps }; | ||||
|  | @ -1,9 +0,0 @@ | |||
| // based on rc-collapse 1.11.8
 | ||||
| import CollapsePanel from './src/Panel'; | ||||
| import Collapse from './src/Collapse'; | ||||
| import { collapseProps, panelProps } from './src/commonProps'; | ||||
| 
 | ||||
| Collapse.Panel = CollapsePanel; | ||||
| 
 | ||||
| export { collapseProps, panelProps }; | ||||
| export default Collapse; | ||||
|  | @ -0,0 +1,9 @@ | |||
| // based on rc-collapse 3.1.1
 | ||||
| import CollapsePanel from './Panel'; | ||||
| import Collapse from './Collapse'; | ||||
| import { collapseProps, panelProps } from './commonProps'; | ||||
| 
 | ||||
| Collapse.Panel = CollapsePanel; | ||||
| 
 | ||||
| export { collapseProps, panelProps }; | ||||
| export default Collapse; | ||||
|  | @ -1,14 +1,14 @@ | |||
| import cssAnimation from '../../_util/css-animation'; | ||||
| import cssAnimation from '../_util/css-animation'; | ||||
| 
 | ||||
| function animate(node, show, transitionName, done) { | ||||
|   let height; | ||||
| function animate(node: HTMLElement, show: boolean, transitionName: string, done: () => void) { | ||||
|   let height: number; | ||||
|   return cssAnimation(node, transitionName, { | ||||
|     start() { | ||||
|       if (!show) { | ||||
|         node.style.height = `${node.offsetHeight}px`; | ||||
|       } else { | ||||
|         height = node.offsetHeight; | ||||
|         node.style.height = 0; | ||||
|         node.style.height = '0px'; | ||||
|       } | ||||
|     }, | ||||
|     active() { | ||||
|  | @ -21,12 +21,12 @@ function animate(node, show, transitionName, done) { | |||
|   }); | ||||
| } | ||||
| 
 | ||||
| function animation(prefixCls) { | ||||
| function animation(prefixCls: string) { | ||||
|   return { | ||||
|     onEnter(node, done) { | ||||
|     onEnter(node: HTMLElement, done: () => void) { | ||||
|       return animate(node, true, `${prefixCls}-anim`, done); | ||||
|     }, | ||||
|     onLeave(node, done) { | ||||
|     onLeave(node: HTMLElement, done: () => void) { | ||||
|       return animate(node, false, `${prefixCls}-anim`, done); | ||||
|     }, | ||||
|   }; | ||||
|  | @ -1,148 +0,0 @@ | |||
| import BaseMixin from '../../_util/BaseMixin'; | ||||
| import { | ||||
|   hasProp, | ||||
|   getPropsData, | ||||
|   isEmptyElement, | ||||
|   initDefaultProps, | ||||
|   getSlot, | ||||
| } from '../../_util/props-util'; | ||||
| import { cloneElement } from '../../_util/vnode'; | ||||
| import openAnimationFactory from './openAnimationFactory'; | ||||
| import { collapseProps } from './commonProps'; | ||||
| import { getDataAndAriaProps } from '../../_util/util'; | ||||
| import { defineComponent } from 'vue'; | ||||
| 
 | ||||
| function _toArray(activeKey) { | ||||
|   let currentActiveKey = activeKey; | ||||
|   if (!Array.isArray(currentActiveKey)) { | ||||
|     const activeKeyType = typeof currentActiveKey; | ||||
|     currentActiveKey = | ||||
|       activeKeyType === 'number' || activeKeyType === 'string' ? [currentActiveKey] : []; | ||||
|   } | ||||
|   return currentActiveKey.map(key => String(key)); | ||||
| } | ||||
| export default defineComponent({ | ||||
|   name: 'Collapse', | ||||
|   mixins: [BaseMixin], | ||||
|   inheritAttrs: false, | ||||
|   props: initDefaultProps(collapseProps(), { | ||||
|     prefixCls: 'rc-collapse', | ||||
|     accordion: false, | ||||
|     destroyInactivePanel: false, | ||||
|   }), | ||||
|   data() { | ||||
|     const { activeKey, defaultActiveKey, openAnimation, prefixCls } = this.$props; | ||||
|     let currentActiveKey = defaultActiveKey; | ||||
|     if (hasProp(this, 'activeKey')) { | ||||
|       currentActiveKey = activeKey; | ||||
|     } | ||||
|     const currentOpenAnimations = openAnimation || openAnimationFactory(prefixCls); | ||||
|     return { | ||||
|       currentOpenAnimations, | ||||
|       stateActiveKey: _toArray(currentActiveKey), | ||||
|     }; | ||||
|   }, | ||||
|   watch: { | ||||
|     activeKey(val) { | ||||
|       this.setState({ | ||||
|         stateActiveKey: _toArray(val), | ||||
|       }); | ||||
|     }, | ||||
|     openAnimation(val) { | ||||
|       this.setState({ | ||||
|         currentOpenAnimations: val, | ||||
|       }); | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|     onClickItem(key) { | ||||
|       let activeKey = this.stateActiveKey; | ||||
|       if (this.accordion) { | ||||
|         activeKey = activeKey[0] === key ? [] : [key]; | ||||
|       } else { | ||||
|         activeKey = [...activeKey]; | ||||
|         const index = activeKey.indexOf(key); | ||||
|         const isActive = index > -1; | ||||
|         if (isActive) { | ||||
|           // remove active state | ||||
|           activeKey.splice(index, 1); | ||||
|         } else { | ||||
|           activeKey.push(key); | ||||
|         } | ||||
|       } | ||||
|       this.setActiveKey(activeKey); | ||||
|     }, | ||||
|     getNewChild(child, index) { | ||||
|       if (isEmptyElement(child)) return; | ||||
|       const activeKey = this.stateActiveKey; | ||||
|       const { prefixCls, accordion, destroyInactivePanel, expandIcon } = this.$props; | ||||
| 
 | ||||
|       // If there is no key provide, use the panel order as default key | ||||
|       const key = String(child.key ?? index); | ||||
|       const { header, headerClass, disabled } = getPropsData(child); | ||||
|       let isActive = false; | ||||
| 
 | ||||
|       if (accordion) { | ||||
|         isActive = activeKey[0] === key; | ||||
|       } else { | ||||
|         isActive = activeKey.indexOf(key) > -1; | ||||
|       } | ||||
| 
 | ||||
|       let panelEvents = {}; | ||||
|       if (!disabled && disabled !== '') { | ||||
|         panelEvents = { | ||||
|           onItemClick: this.onClickItem, | ||||
|         }; | ||||
|       } | ||||
| 
 | ||||
|       const props = { | ||||
|         key, | ||||
|         panelKey: key, | ||||
|         header, | ||||
|         headerClass, | ||||
|         isActive, | ||||
|         prefixCls, | ||||
|         destroyInactivePanel, | ||||
|         openAnimation: this.currentOpenAnimations, | ||||
|         accordion, | ||||
|         expandIcon, | ||||
|         ...panelEvents, | ||||
|       }; | ||||
| 
 | ||||
|       return cloneElement(child, props); | ||||
|     }, | ||||
|     getItems() { | ||||
|       const newChildren = []; | ||||
|       const children = getSlot(this); | ||||
|       children && | ||||
|         children.forEach((child, index) => { | ||||
|           newChildren.push(this.getNewChild(child, index)); | ||||
|         }); | ||||
|       return newChildren; | ||||
|     }, | ||||
|     setActiveKey(activeKey) { | ||||
|       if (!hasProp(this, 'activeKey')) { | ||||
|         this.setState({ stateActiveKey: activeKey }); | ||||
|       } | ||||
|       this.__emit('change', this.accordion ? activeKey[0] : activeKey); | ||||
|     }, | ||||
|   }, | ||||
|   render() { | ||||
|     const { prefixCls, accordion } = this.$props; | ||||
|     const { class: className, style } = this.$attrs; | ||||
|     const collapseClassName = { | ||||
|       [prefixCls]: true, | ||||
|       [className]: className, | ||||
|     }; | ||||
|     return ( | ||||
|       <div | ||||
|         class={collapseClassName} | ||||
|         {...getDataAndAriaProps(this.$attrs)} | ||||
|         style={style} | ||||
|         role={accordion ? 'tablist' : null} | ||||
|       > | ||||
|         {this.getItems()} | ||||
|       </div> | ||||
|     ); | ||||
|   }, | ||||
| }); | ||||
|  | @ -1,94 +0,0 @@ | |||
| import PanelContent from './PanelContent'; | ||||
| import { initDefaultProps, getComponent, getSlot } from '../../_util/props-util'; | ||||
| import { panelProps } from './commonProps'; | ||||
| import { defineComponent } from 'vue'; | ||||
| import BaseMixin from '../../_util/BaseMixin'; | ||||
| import Transition from '../../_util/transition'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'Panel', | ||||
|   mixins: [BaseMixin], | ||||
|   props: initDefaultProps(panelProps(), { | ||||
|     showArrow: true, | ||||
|     isActive: false, | ||||
|     destroyInactivePanel: false, | ||||
|     headerClass: '', | ||||
|     forceRender: false, | ||||
|   }), | ||||
|   methods: { | ||||
|     handleItemClick() { | ||||
|       this.__emit('itemClick', this.panelKey); | ||||
|     }, | ||||
|     handleKeyPress(e) { | ||||
|       if (e.key === 'Enter' || e.keyCode === 13 || e.which === 13) { | ||||
|         this.handleItemClick(); | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   render() { | ||||
|     const { | ||||
|       prefixCls, | ||||
|       headerClass, | ||||
|       isActive, | ||||
|       showArrow, | ||||
|       destroyInactivePanel, | ||||
|       disabled, | ||||
|       openAnimation, | ||||
|       accordion, | ||||
|       forceRender, | ||||
|       expandIcon, | ||||
|       extra, | ||||
|     } = this.$props; | ||||
| 
 | ||||
|     const transitionProps = { | ||||
|       appear: true, | ||||
|       css: false, | ||||
|       ...openAnimation, | ||||
|     }; | ||||
|     const headerCls = { | ||||
|       [`${prefixCls}-header`]: true, | ||||
|       [headerClass]: headerClass, | ||||
|     }; | ||||
| 
 | ||||
|     const header = getComponent(this, 'header'); | ||||
|     const itemCls = { | ||||
|       [`${prefixCls}-item`]: true, | ||||
|       [`${prefixCls}-item-active`]: isActive, | ||||
|       [`${prefixCls}-item-disabled`]: disabled, | ||||
|     }; | ||||
|     let icon = <i class="arrow" />; | ||||
|     if (showArrow && typeof expandIcon === 'function') { | ||||
|       icon = expandIcon(this.$props); | ||||
|     } | ||||
| 
 | ||||
|     const panelContent = ( | ||||
|       <PanelContent | ||||
|         v-show={isActive} | ||||
|         prefixCls={prefixCls} | ||||
|         isActive={isActive} | ||||
|         destroyInactivePanel={destroyInactivePanel} | ||||
|         forceRender={forceRender} | ||||
|         role={accordion ? 'tabpanel' : null} | ||||
|       > | ||||
|         {getSlot(this)} | ||||
|       </PanelContent> | ||||
|     ); | ||||
|     return ( | ||||
|       <div class={itemCls} role="tablist"> | ||||
|         <div | ||||
|           class={headerCls} | ||||
|           onClick={this.handleItemClick} | ||||
|           onKeypress={this.handleKeyPress} | ||||
|           role={accordion ? 'tab' : 'button'} | ||||
|           tabindex={disabled ? -1 : 0} | ||||
|           aria-expanded={isActive} | ||||
|         > | ||||
|           {showArrow && icon} | ||||
|           {header} | ||||
|           {extra && <div class={`${prefixCls}-extra`}>{extra}</div>} | ||||
|         </div> | ||||
|         <Transition {...transitionProps}>{panelContent}</Transition> | ||||
|       </div> | ||||
|     ); | ||||
|   }, | ||||
| }); | ||||
|  | @ -1,39 +0,0 @@ | |||
| import PropTypes from '../../_util/vue-types'; | ||||
| import { getSlot } from '../../_util/props-util'; | ||||
| import { defineComponent } from 'vue'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'PanelContent', | ||||
|   props: { | ||||
|     prefixCls: PropTypes.string, | ||||
|     isActive: PropTypes.looseBool, | ||||
|     destroyInactivePanel: PropTypes.looseBool, | ||||
|     forceRender: PropTypes.looseBool, | ||||
|     role: PropTypes.any, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       _isActive: undefined, | ||||
|     }; | ||||
|   }, | ||||
|   render() { | ||||
|     this._isActive = this.forceRender || this._isActive || this.isActive; | ||||
|     if (!this._isActive) { | ||||
|       return null; | ||||
|     } | ||||
|     const { prefixCls, isActive, destroyInactivePanel, forceRender, role } = this.$props; | ||||
|     const contentCls = { | ||||
|       [`${prefixCls}-content`]: true, | ||||
|       [`${prefixCls}-content-active`]: isActive, | ||||
|     }; | ||||
|     const child = | ||||
|       !forceRender && !isActive && destroyInactivePanel ? null : ( | ||||
|         <div class={`${prefixCls}-content-box`}>{getSlot(this)}</div> | ||||
|       ); | ||||
|     return ( | ||||
|       <div class={contentCls} role={role}> | ||||
|         {child} | ||||
|       </div> | ||||
|     ); | ||||
|   }, | ||||
| }); | ||||
|  | @ -1,4 +1,4 @@ | |||
| // base rc-steps 3.5.0
 | ||||
| // base rc-steps 4.1.3
 | ||||
| import Steps from './Steps'; | ||||
| import Step from './Step'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ | |||
| </template> | ||||
| <script> | ||||
| import { defineComponent } from 'vue'; | ||||
| import demo from '../v2-doc/src/docs/timeline/demo/index.vue'; | ||||
| import demo from '../v2-doc/src/docs/collapse/demo/index.vue'; | ||||
| // import Affix from '../components/affix'; | ||||
| export default defineComponent({ | ||||
|   components: { | ||||
|  |  | |||
							
								
								
									
										2
									
								
								v2-doc
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								v2-doc
								
								
								
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 3a14ef175850d1fcb3ccd002c3afd1f871dc3257 | ||||
| Subproject commit c703df2dd803ee5097b414e2a32482b8fc2225d7 | ||||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou