Skip to content

Commit

Permalink
♻️ chore: remove keyManager
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmclin2 committed Aug 27, 2023
1 parent 358876e commit 48f8d80
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 316 deletions.
17 changes: 6 additions & 11 deletions src/SortableList/container/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useSensor,
useSensors,
} from '@dnd-kit/core';
import isEqual from 'lodash.isequal';
import { createPortal } from 'react-dom';

import { restrictToVerticalAxis, restrictToWindowEdges } from '@dnd-kit/modifiers';
Expand All @@ -16,7 +17,6 @@ import {
sortableKeyboardCoordinates,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import isEqual from 'lodash.isequal';
import type { CSSProperties, FC } from 'react';
import { useMemo } from 'react';
import { Flexbox } from 'react-layout-kit';
Expand All @@ -38,6 +38,8 @@ const selector = (s: Store) => ({
renderHeader: s.renderHeader,
});

const dataSelector = (s: Store) => s.value;

export interface AppProps {
/**
* 类名
Expand All @@ -59,7 +61,8 @@ const App: FC<AppProps> = ({ className, style, prefixCls: customPrefixCls }) =>
shallow,
);

const keyManager = useStore((s) => s.keyManager, isEqual);
const items = useStore(dataSelector, isEqual);

const prefixCls = getPrefixCls('sortable-list', customPrefixCls);

const sensors = useSensors(
Expand All @@ -86,15 +89,7 @@ const App: FC<AppProps> = ({ className, style, prefixCls: customPrefixCls }) =>
onDragCancel={handleDragCancel}
modifiers={[restrictToVerticalAxis, restrictToWindowEdges]}
>
<SortableContext
// dndkit 的 bug ,必须要用 object 的 id 获取,否则 transform 一直为空。
items={keyManager.keys.map((key) => {
return {
id: key,
};
})}
strategy={verticalListSortingStrategy}
>
<SortableContext items={items} strategy={verticalListSortingStrategy}>
{renderHeader?.()}
<SortList prefixCls={prefixCls} />
{overlay}
Expand Down
100 changes: 4 additions & 96 deletions src/SortableList/container/StoreUpdater.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,8 @@
import { produce } from 'immer';
import { ForwardedRef, forwardRef, useImperativeHandle } from 'react';
import { forwardRef, useImperativeHandle } from 'react';
import { createStoreUpdater } from 'zustand-utils';
import { useSortableList } from '..';
import { useStoreApi } from '../store';

import type {
CreatorButtonProps,
GetItemStyles,
OnChange,
RenderActionProps,
RenderItemProps,
} from '../type';

/**
* 供外部使用的 ref 方法
*/
export interface SortableListRef<T> {
addItem: (item?: T, index?: number) => void;
removeItem: (index: number) => void;
updateItem: (item: T, index: number) => void;
}

export interface StoreUpdaterProps<T = any> {
/**
* 值
*/
value?: T[];
/**
* 初始值
*/
initialValues?: T[];
/**
* 值变化
*/
onChange?: OnChange;
/**
* 渲染内容区域
*/
renderContent?: RenderItemProps<T>;
/**
* 除列表自带操作之外的其他操作自渲染
*/
actions?: RenderActionProps<T>;
/**
* 渲染头部区域
*/
renderHeader?: () => React.ReactNode;
/**
* 对外部暴露方法
*/
ref?: ForwardedRef<SortableListRef<T>>;
/**
* 新建对象相关属性
*/
creatorButtonProps?: CreatorButtonProps;
/**
* 如果为 true,则会在 devtools 中显示 SortableTree 内部的数据结构
* @internal
*/
SHOW_STORE_IN_DEVTOOLS?: boolean;
/**
* 紧凑模式, 默认为 false
*/
compact?: boolean;
/**
* 是否隐藏删除按钮,默认为 false
*/
hideRemove?: boolean;
/**
* 自定义排序容器样式
*/
getItemStyles?: GetItemStyles;
}
import type { StoreUpdaterProps } from '../type';

const StoreUpdater = forwardRef(
(
Expand All @@ -92,26 +23,9 @@ const StoreUpdater = forwardRef(
const storeApi = useStoreApi();
const useStoreUpdater = createStoreUpdater<StoreUpdaterProps>(storeApi);

// KeyManager 和 value & initialValues 同步。
const KeyManagerUpdater = (state, key) => {
const { keyManager } = storeApi.getState();
// value 为空处理
const value = state[key] || [];
const manager = produce(keyManager, (draft) => {
value.forEach((__, index) => {
const key = draft.keys[index];
if (key === undefined) {
draft.keys[index] = draft.id;
draft.id += 1;
}
});
return draft;
});

storeApi.setState({ keyManager: manager, [key]: value });
};

useStoreUpdater('value', initialValues, []);
useStoreUpdater('initialValues', initialValues);
useStoreUpdater('value', value);
useStoreUpdater('onChange', onChange);
useStoreUpdater('creatorButtonProps', creatorButtonProps);
useStoreUpdater('renderContent', renderContent);
Expand All @@ -121,12 +35,6 @@ const StoreUpdater = forwardRef(
useStoreUpdater('compact', compact);
useStoreUpdater('hideRemove', hideRemove);

// KeyManager 状态受控
useStoreUpdater('initialValues', initialValues, [initialValues], (state) => {
KeyManagerUpdater(state, 'initialValues');
});
useStoreUpdater('value', value, [value], (state) => KeyManagerUpdater(state, 'value'));

// 将 store 传递到外部
const instance = useSortableList();
useImperativeHandle(ref, () => instance);
Expand Down
2 changes: 1 addition & 1 deletion src/SortableList/container/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { forwardRef, memo, ReactNode } from 'react';
import { ConfigProvider } from '../../ConfigProvider';
import type { StoreUpdaterProps } from '../type';
import type { AppProps } from './App';
import App from './App';
import { SortableListProvider } from './Provider';
import type { StoreUpdaterProps } from './StoreUpdater';
import StoreUpdater from './StoreUpdater';

export { SortableListProvider } from './Provider';
Expand Down
6 changes: 3 additions & 3 deletions src/SortableList/features/DragOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@ import { defaultDropAnimationSideEffects } from '@dnd-kit/core';
import isEqual from 'lodash.isequal';
import { useStore } from '../store';
import type { Store } from '../store/store';
import { getIndexOfActiveItem } from '../utils';

const selector = (s: Store) => ({
activeId: s.activeId,
compact: s.compact,
hideRemove: s.hideRemove,
renderContent: s.renderContent,
getItemStyles: s.getItemStyles,
getActiveIndex: s.getActiveIndex,
});

interface OverlayProps {
prefixCls: string;
}

const Overlay: FC<OverlayProps> = ({ prefixCls }) => {
const { activeId, compact, renderContent, getActiveIndex, hideRemove, getItemStyles } = useStore(
const { activeId, compact, renderContent, hideRemove, getItemStyles } = useStore(
selector,
shallow,
);
const value = useStore((s) => s.value, isEqual);
const activeIndex = getActiveIndex();
const activeIndex = getIndexOfActiveItem(value, activeId);

return (
<DragOverlay
Expand Down
24 changes: 11 additions & 13 deletions src/SortableList/features/SortList.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { PlusOutlined } from '@ant-design/icons';
import { Button, Empty } from 'antd';
import isEqual from 'lodash.isequal';
import type { FC } from 'react';
import { memo } from 'react';
import { shallow } from 'zustand/shallow';

import { List, SortableItem } from '../components';
import { useStore } from '../store';

import { PlusOutlined } from '@ant-design/icons';
import { Button, Empty } from 'antd';
import isEqual from 'lodash.isequal';
import type { Store } from '../store';
import { useStore } from '../store';
import { useStyle } from '../style';

const selector = (s: Store) => ({
Expand All @@ -30,8 +28,8 @@ const SortableList: FC<SortableListProps> = ({ prefixCls }) => {
shallow,
);

const [value, keyManager, creatorButtonProps, actions] = useStore(
(s) => [s.value, s.keyManager, s.creatorButtonProps, s.actions],
const [items, creatorButtonProps, actions] = useStore(
(s) => [s.value, s.creatorButtonProps, s.actions],
isEqual,
);

Expand All @@ -52,7 +50,7 @@ const SortableList: FC<SortableListProps> = ({ prefixCls }) => {
className={styles.btnAdd}
onClick={() => {
const intialValue = {
...(record && typeof record === 'function' ? record(value.length) : record),
...(record && typeof record === 'function' ? record(items.length) : record),
};
dispatchListData({
type: 'addItem',
Expand All @@ -68,7 +66,7 @@ const SortableList: FC<SortableListProps> = ({ prefixCls }) => {

return (
<>
{Array.isArray(value) && value.length === 0 ? (
{Array.isArray(items) && items.length === 0 ? (
<>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}>
{showInEmpty === false ? null : <CreateButton empty />}
Expand All @@ -77,11 +75,11 @@ const SortableList: FC<SortableListProps> = ({ prefixCls }) => {
) : (
<>
<List prefixCls={prefixCls}>
{value.map((item, index) => {
{items.map((item, index) => {
return (
<SortableItem
key={keyManager.keys[index]}
id={keyManager.keys[index]}
key={item.id}
id={item.id}
index={index}
compact={compact}
hideRemove={hideRemove}
Expand Down
4 changes: 0 additions & 4 deletions src/SortableList/store/initialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import { SortableListState } from '../type';
export const initialState: SortableListState = {
activeId: null,
value: [],
keyManager: {
keys: [],
id: 1, // 自增
},
compact: false,
hideRemove: false,
onChange: undefined,
Expand Down
Loading

0 comments on commit 48f8d80

Please sign in to comment.