|
|
@@ -0,0 +1,116 @@
|
|
|
+import React, { useState, useContext, useEffect, useCallback } from 'react';
|
|
|
+import { View } from '@tarojs/components';
|
|
|
+import { CategorySidebarContext } from '../CategorySidebar';
|
|
|
+import './CategorySidebarItem.css';
|
|
|
+
|
|
|
+export interface CategorySidebarItemProps {
|
|
|
+ /** 标题 */
|
|
|
+ title?: string;
|
|
|
+ /** 是否禁用 */
|
|
|
+ disabled?: boolean;
|
|
|
+ /** 自定义类名 */
|
|
|
+ className?: string;
|
|
|
+ /** 点击事件回调 */
|
|
|
+ onClick?: (index: number) => void;
|
|
|
+ /** 子组件 */
|
|
|
+ children?: React.ReactNode;
|
|
|
+}
|
|
|
+
|
|
|
+const CategorySidebarItem: React.FC<CategorySidebarItemProps> = (props) => {
|
|
|
+ const { title, disabled = false, className = '', onClick, children } = props;
|
|
|
+
|
|
|
+ const [selected, setSelected] = useState<boolean>(false);
|
|
|
+ const [topRightRadius, setTopRightRadius] = useState<boolean>(false);
|
|
|
+ const [bottomRightRadius, setBottomRightRadius] = useState<boolean>(false);
|
|
|
+
|
|
|
+ const context = useContext(CategorySidebarContext);
|
|
|
+ const itemRef = React.useRef<any>(null);
|
|
|
+
|
|
|
+ // 注册到父组件
|
|
|
+ useEffect(() => {
|
|
|
+ if (context) {
|
|
|
+ context.registerItem(itemRef.current);
|
|
|
+ return () => {
|
|
|
+ context.unregisterItem(itemRef.current);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }, [context]);
|
|
|
+
|
|
|
+ // 设置选中状态
|
|
|
+ const setActive = useCallback((isActive: boolean) => {
|
|
|
+ return new Promise<void>((resolve) => {
|
|
|
+ setSelected(isActive);
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 设置顶部圆角
|
|
|
+ const setTopRightRadiusMethod = useCallback((val: boolean) => {
|
|
|
+ return new Promise<void>((resolve) => {
|
|
|
+ setTopRightRadius(val);
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 设置底部圆角
|
|
|
+ const setBottomRightRadiusMethod = useCallback((val: boolean) => {
|
|
|
+ return new Promise<void>((resolve) => {
|
|
|
+ setBottomRightRadius(val);
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 暴露方法给父组件
|
|
|
+ useEffect(() => {
|
|
|
+ itemRef.current = {
|
|
|
+ setActive,
|
|
|
+ setTopRightRadius: setTopRightRadiusMethod,
|
|
|
+ setBottomRightRadius: setBottomRightRadiusMethod,
|
|
|
+ };
|
|
|
+ }, [setActive, setTopRightRadiusMethod, setBottomRightRadiusMethod]);
|
|
|
+
|
|
|
+ // 点击事件处理
|
|
|
+ const handleClick = useCallback(() => {
|
|
|
+ if (!context || disabled) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前项在父组件中的索引
|
|
|
+ const index = context.activeKey;
|
|
|
+
|
|
|
+ // 设置选中状态
|
|
|
+ context.setActive(index).then(() => {
|
|
|
+ // 触发点击事件
|
|
|
+ if (onClick) {
|
|
|
+ onClick(index);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, [context, disabled, onClick]);
|
|
|
+
|
|
|
+ // 构建类名
|
|
|
+ const itemClassNames = [
|
|
|
+ 'category-sidebar-item',
|
|
|
+ selected ? 'active' : '',
|
|
|
+ disabled ? 'disabled' : '',
|
|
|
+ topRightRadius ? 'top-right-radius' : '',
|
|
|
+ bottomRightRadius ? 'bottom-right-radius' : '',
|
|
|
+ className,
|
|
|
+ ].filter(Boolean).join(' ');
|
|
|
+
|
|
|
+ return (
|
|
|
+ <View className="category-sidebar-item-container">
|
|
|
+ <View
|
|
|
+ className={itemClassNames}
|
|
|
+ hoverClass="category-sidebar-item--hover"
|
|
|
+ hoverStayTime={70}
|
|
|
+ onClick={handleClick}
|
|
|
+ >
|
|
|
+ <View className="category-sidebar-item__text text-overflow">
|
|
|
+ {title || children}
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default CategorySidebarItem;
|