Open 981377660LMT opened 8 months ago
这一版的动态版本挂载属性可读性太差,换一个实现。
想清楚,对外暴露Context方便还是暴露Context.Provider方便
import { createContext, useContext, useState } from 'react';
/**
* 用于控制多个组件的显示隐藏状态.
* 一个group内部最多存在一个显示的组件.
*/
interface IVisibilityController<Id extends PropertyKey> {
get: (id: Id) => boolean;
set: (id: Id, visible: boolean) => void;
toggle: (id: Id) => boolean;
clear: () => void;
}
const useVisibilityController = <Id extends PropertyKey>(initVisibleId?: Id): IVisibilityController<Id> => {
const NULL_ID = Symbol('NULL_ID');
const [visibleId, setVisibleId] = useState<Id | Symbol>(initVisibleId ?? NULL_ID); // TODO, ref
return {
get (id) {
return id === visibleId;
},
set (id, visible) {
if (visible) {
setVisibleId(id);
} else if (id === visibleId) {
setVisibleId(NULL_ID);
}
},
toggle (id) {
if (id === visibleId) {
setVisibleId(NULL_ID);
return false;
} else {
setVisibleId(id);
return true;
}
},
clear () {
setVisibleId(NULL_ID);
}
};
};
type FilterDropdownId = `conjuctionDropdownVisible-${string | number}` | `columnDropdownVisible-${string | number}` | `operatorDropdownVisible-${string | number}` | `targetValueDropdownVisible-${string | number}` | 'addFilterDropdownVisible';
type GroupDropdownId = `columnDropdownVisible-${string | number}` | 'addGroupDropdownVisible';
type SortDropdownId = `columnDropdownVisible-${string | number}` | 'addSortDropdownVisible';
const FilterDropdownVisibilityControllerContext = createContext<IVisibilityController<FilterDropdownId> | null>(null);
const GroupDropdownVisibilityControllerContext = createContext<IVisibilityController<GroupDropdownId> | null>(null);
const SortDropdownVisibilityControllerContext = createContext<IVisibilityController<SortDropdownId> | null>(null);
export const FilterDropdownVisibilityControllerProvider = (props: React.PropsWithChildren<{}>) => {
const controller = useVisibilityController();
return <FilterDropdownVisibilityControllerContext.Provider value={controller} {...props} />;
};
export const GroupDropdownVisibilityControllerProvider = (props: React.PropsWithChildren<{}>) => {
const controller = useVisibilityController();
return <GroupDropdownVisibilityControllerContext.Provider value={controller} {...props} />;
};
export const useSortDropdownVisibilityControllerProvider = (props: React.PropsWithChildren<{}>) => {
const controller = useVisibilityController();
return <SortDropdownVisibilityControllerContext.Provider value={controller} {...props} />;
};
export const useFilterDropdownVisibilityController = () => useContext(FilterDropdownVisibilityControllerContext);
export const useGroupDropdownVisibilityController = () => useContext(GroupDropdownVisibilityControllerContext);
export const useSortDropdownVisibilityController = () => useContext(SortDropdownVisibilityControllerContext);