antd-mobile-taro-ui
Version:
以antd-mobile为设计标准,基于taro框架的微信小程序组件库
162 lines (147 loc) • 5.34 kB
JavaScript
import React, { useState, useRef } from 'react';
import { withNativeProps } from 'antd-mobile/es/utils/native-props';
import { UnfoldIcon } from 'antd-mobile-taro-icons';
import classNames from 'classnames';
import { usePropsValue } from 'antd-mobile/es/utils/use-props-value';
import { useShouldRender } from 'antd-mobile/es/utils/should-render';
import { useIsomorphicUpdateLayoutEffect } from 'antd-mobile/es/utils/use-isomorphic-update-layout-effect';
import { traverseReactNode } from 'antd-mobile/es/utils/traverse-react-node';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { useMount } from 'ahooks';
import { isWeapp } from '../../utils/client';
import List from '../list';
const classPrefix = `adm-collapse`;
export const CollapsePanel = () => {
return null;
};
const CollapsePanelContent = props => {
const {
visible
} = props;
const innerRef = useRef(null);
const shouldRender = useShouldRender(visible, props.forceRender, props.destroyOnClose);
const [height, setHeight] = useState(0);
const nodeRef = useRef(null);
useMount(() => {
if (isWeapp) {
setTimeout(() => {
const inner = innerRef.current;
if (!inner) return;
if (inner === null || inner === void 0 ? void 0 : inner.sid) {
nodeRef.current = Taro.createSelectorQuery().select(`#${inner === null || inner === void 0 ? void 0 : inner.sid}`);
} else {
console.error(`HTMLDivElement: Taro node can no find sid`);
}
if (!visible) return;
if (!nodeRef.current) return;
nodeRef.current.boundingClientRect(rect => setHeight(rect.height)).exec();
}, 0);
}
});
useIsomorphicUpdateLayoutEffect(() => {
if (isWeapp) {
if (!nodeRef.current) return;
if (visible) {
if (!nodeRef.current) return;
Taro.nextTick(() => {
if (!nodeRef.current) return;
nodeRef.current.boundingClientRect(rect => {
setHeight(rect.height);
}).exec();
});
setTimeout(() => {
setHeight('auto');
}, 200);
} else {
nodeRef.current.boundingClientRect(rect => {
setHeight(rect.height);
}).exec();
setTimeout(() => {
setHeight(0);
}, 200);
}
}
}, [visible]);
return React.createElement(View, {
className: `${classPrefix}-panel-content`,
style: {
height: isWeapp ? height : visible ? 'auto' : 0
}
}, React.createElement(View, {
className: `${classPrefix}-panel-content-inner`,
ref: innerRef
}, React.createElement(List.Item, null, shouldRender && props.children)));
};
export const Collapse = props => {
var _a;
const panels = [];
traverseReactNode(props.children, child => {
if (!React.isValidElement(child)) return;
const {
key
} = child;
if (typeof key !== 'string') return;
panels.push(child);
});
const [activeKey, setActiveKey] = usePropsValue(props.accordion ? {
value: props.activeKey === undefined ? undefined : props.activeKey === null ? [] : [props.activeKey],
defaultValue: props.defaultActiveKey === undefined || props.defaultActiveKey === null ? [] : [props.defaultActiveKey],
onChange: v => {
var _a, _b;
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, (_b = v[0]) !== null && _b !== void 0 ? _b : null);
}
} : {
value: props.activeKey,
defaultValue: (_a = props.defaultActiveKey) !== null && _a !== void 0 ? _a : [],
onChange: props.onChange
});
const activeKeyList = activeKey === null ? [] : Array.isArray(activeKey) ? activeKey : [activeKey];
return withNativeProps(props, React.createElement(View, {
className: classPrefix
}, React.createElement(List, null, panels.map(panel => {
const key = panel.key;
const active = activeKeyList.includes(key);
const handleClick = event => {
var _a, _b;
if (props.accordion) {
if (active) {
setActiveKey([]);
} else {
setActiveKey([key]);
}
} else if (active) {
setActiveKey(activeKeyList.filter(v => v !== key));
} else {
setActiveKey([...activeKeyList, key]);
}
(_b = (_a = panel.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
};
const renderArrow = () => {
let arrow = React.createElement(UnfoldIcon, null);
if (props.arrow !== undefined) {
arrow = props.arrow;
}
if (panel.props.arrow !== undefined) {
arrow = panel.props.arrow;
}
return typeof arrow === 'function' ? arrow(active) : React.createElement(View, {
className: classNames(`${classPrefix}-arrow`, {
[`${classPrefix}-arrow-active`]: active
})
}, arrow);
};
return React.createElement(React.Fragment, {
key: key
}, withNativeProps(panel.props, React.createElement(List.Item, {
className: `${classPrefix}-panel-header`,
onClick: handleClick,
disabled: panel.props.disabled,
arrow: renderArrow()
}, panel.props.title)), React.createElement(CollapsePanelContent, {
visible: active,
forceRender: !!panel.props.forceRender,
destroyOnClose: !!panel.props.destroyOnClose
}, panel.props.children));
}))));
};