Skip to content

Commit

Permalink
type: React.Key => SafeKey
Browse files Browse the repository at this point in the history
  • Loading branch information
afc163 committed Oct 14, 2024
1 parent b01e960 commit f3806bd
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 110 deletions.
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lint-staged
37 changes: 21 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,49 +34,54 @@
"compile": "father build",
"lint": "eslint src/ examples/ --ext .tsx,.ts,.jsx,.js",
"now-build": "npm run build",
"prepare": "dumi setup",
"prepare": "husky",
"prepublishOnly": "npm run compile && np --yolo --no-publish --any-branch",
"prettier": "prettier '{src,tests}/**/*.{ts,tsx}' 'tests/**/*.js' --write",
"start": "dumi dev",
"test": "rc-test"
},
"lint-staged": {
"*": "prettier --write --ignore-unknown"
},
"dependencies": {
"@babel/runtime": "^7.25.7",
"classnames": "2.x",
"rc-select": "~14.15.0",
"rc-tree": "~5.9.0",
"classnames": "^2.5.1",
"rc-select": "~14.15.2",
"rc-tree": "~5.10.0",
"rc-util": "^5.43.0"
},
"devDependencies": {
"@rc-component/father-plugin": "^1.0.0",
"@rc-component/trigger": "^1.5.0",
"@testing-library/react": "^12.0.0",
"@types/jest": "^29.5.12",
"@rc-component/father-plugin": "^1.1.0",
"@rc-component/trigger": "^1.18.3",
"@testing-library/react": "^12.1.5",
"@types/jest": "^29.5.13",
"@types/node": "^22.7.5",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.2.19",
"@types/warning": "^3.0.0",
"@types/react-dom": "^18.3.1",
"@types/warning": "^3.0.3",
"@umijs/fabric": "^4.0.1",
"cheerio": "1.0.0-rc.12",
"cross-env": "^7.0.3",
"dumi": "^2.4.12",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.8",
"enzyme-to-json": "^3.6.2",
"eslint": "^8.56.0",
"eslint-plugin-jest": "^27.6.0",
"eslint": "^8.57.1",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-unicorn": "^56.0.0",
"father": "^4.5.0",
"glob": "^11.0.0",
"husky": "^9.1.6",
"lint-staged": "^15.2.10",
"np": "^10.0.7",
"prettier": "^3.3.3",
"rc-dialog": "^9.6.0",
"rc-field-form": "^2.4.0",
"rc-test": "^7.1.0",
"rc-virtual-list": "^3.14.8",
"react": "16.x",
"react-dom": "16.x",
"typescript": "^5.6.3",
"cheerio": "1.0.0-rc.12"
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.6.3"
},
"peerDependencies": {
"react": "*",
Expand Down
18 changes: 9 additions & 9 deletions src/LegacyContext.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import * as React from 'react';
import type { DataEntity, IconType } from 'rc-tree/lib/interface';
import type { Key, LegacyDataNode, RawValueType } from './interface';
import type { LegacyDataNode, SafeKey } from './interface';

interface LegacyContextProps {
checkable: boolean | React.ReactNode;
checkedKeys: Key[];
halfCheckedKeys: Key[];
treeExpandedKeys: Key[];
treeDefaultExpandedKeys: Key[];
onTreeExpand: (keys: Key[]) => void;
checkedKeys: SafeKey[];
halfCheckedKeys: SafeKey[];
treeExpandedKeys: SafeKey[];
treeDefaultExpandedKeys: SafeKey[];
onTreeExpand: (keys: SafeKey[]) => void;
treeDefaultExpandAll: boolean;
treeIcon: IconType;
showTreeIcon: boolean;
switcherIcon: IconType;
treeLine: boolean;
treeNodeFilterProp: string;
treeLoadedKeys: Key[];
treeLoadedKeys: SafeKey[];
treeMotion: any;
loadData: (treeNode: LegacyDataNode) => Promise<unknown>;
onTreeLoad: (loadedKeys: Key[]) => void;
onTreeLoad: (loadedKeys: SafeKey[]) => void;

keyEntities: Record<RawValueType, DataEntity<any>>;
keyEntities: Record<SafeKey, DataEntity<any>>;
}

const LegacySelectContext = React.createContext<LegacyContextProps>(null);
Expand Down
14 changes: 7 additions & 7 deletions src/OptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import useMemo from 'rc-util/lib/hooks/useMemo';
import * as React from 'react';
import LegacyContext from './LegacyContext';
import TreeSelectContext from './TreeSelectContext';
import type { Key, TreeDataNode } from './interface';
import type { SafeKey, TreeDataNode } from './interface';
import { getAllKeys, isCheckDisabled } from './utils/valueUtil';

const HIDDEN_STYLE = {
Expand All @@ -23,7 +23,7 @@ const HIDDEN_STYLE = {
};

interface TreeEventInfo {
node: { key: Key };
node: { key: SafeKey };
selected?: boolean;
checked?: boolean;
}
Expand Down Expand Up @@ -77,7 +77,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
);

// ========================== Active ==========================
const [activeKey, setActiveKey] = React.useState<Key>(null);
const [activeKey, setActiveKey] = React.useState<SafeKey>(null);
const activeEntity = keyEntities[activeKey];

// ========================== Values ==========================
Expand Down Expand Up @@ -112,8 +112,8 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
};

// =========================== Keys ===========================
const [expandedKeys, setExpandedKeys] = React.useState<Key[]>(treeDefaultExpandedKeys);
const [searchExpandedKeys, setSearchExpandedKeys] = React.useState<Key[]>(null);
const [expandedKeys, setExpandedKeys] = React.useState<SafeKey[]>(treeDefaultExpandedKeys);
const [searchExpandedKeys, setSearchExpandedKeys] = React.useState<SafeKey[]>(null);

const mergedExpandedKeys = React.useMemo(() => {
if (treeExpandedKeys) {
Expand All @@ -129,7 +129,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchValue]);

const onInternalExpand = (keys: Key[]) => {
const onInternalExpand = (keys: SafeKey[]) => {
setExpandedKeys(keys);
setSearchExpandedKeys(keys);

Expand All @@ -143,7 +143,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
event.preventDefault();
};

const onInternalSelect = (__: React.Key[], info: TreeEventInfo) => {
const onInternalSelect = (__: SafeKey[], info: TreeEventInfo) => {
const { node } = info;

if (checkable && isCheckDisabled(node)) {
Expand Down
4 changes: 2 additions & 2 deletions src/TreeNode.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* istanbul ignore file */
import type * as React from 'react';
import type { DataNode, Key } from './interface';
import type { DataNode, SafeKey } from './interface';

export interface TreeNodeProps extends Omit<DataNode, 'children'> {
value: Key;
value: SafeKey;
children?: React.ReactNode;
}

Expand Down
63 changes: 26 additions & 37 deletions src/TreeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,9 @@ import type { CheckedStrategy } from './utils/strategyUtil';
import { formatStrategyValues, SHOW_ALL, SHOW_CHILD, SHOW_PARENT } from './utils/strategyUtil';
import { fillFieldNames, isNil, toArray } from './utils/valueUtil';
import warningProps from './utils/warningPropsUtil';
import type { LabeledValueType, SafeKey, SelectSource, DefaultValueType } from './interface';

export type OnInternalSelect = (value: RawValueType, info: { selected: boolean }) => void;

export type RawValueType = string | number;

export interface LabeledValueType {
key?: React.Key;
value?: RawValueType;
label?: React.ReactNode;
/** Only works on `treeCheckStrictly` */
halfChecked?: boolean;
}

export type SelectSource = 'option' | 'selection' | 'input' | 'clear';

export type DraftValueType = RawValueType | LabeledValueType | (RawValueType | LabeledValueType)[];
export type OnInternalSelect = (value: SafeKey, info: { selected: boolean }) => void;

/** @deprecated This is only used for legacy compatible. Not works on new code. */
export interface LegacyCheckedNode {
Expand All @@ -55,7 +42,7 @@ export interface LegacyCheckedNode {
export interface ChangeEventExtra {
/** @deprecated Please save prev value by control logic instead */
preValue: LabeledValueType[];
triggerValue: RawValueType;
triggerValue: SafeKey;
/** @deprecated Use `onSelect` or `onDeselect` instead. */
selected?: boolean;
/** @deprecated Use `onSelect` or `onDeselect` instead. */
Expand All @@ -79,9 +66,9 @@ export interface InternalFieldName extends Omit<FieldNames, 'label'> {
}

export interface SimpleModeConfig {
id?: React.Key;
pId?: React.Key;
rootPId?: React.Key;
id?: SafeKey;
pId?: SafeKey;
rootPId?: SafeKey;
}

export interface BaseOptionType {
Expand All @@ -93,10 +80,10 @@ export interface BaseOptionType {
}

export interface DefaultOptionType extends BaseOptionType {
value?: RawValueType;
value?: SafeKey;
title?: React.ReactNode;
label?: React.ReactNode;
key?: React.Key;
key?: SafeKey;
children?: DefaultOptionType[];
}

Expand Down Expand Up @@ -145,14 +132,14 @@ export interface TreeSelectProps<
treeData?: OptionType[];
treeDataSimpleMode?: boolean | SimpleModeConfig;
loadData?: (dataNode: LegacyDataNode) => Promise<unknown>;
treeLoadedKeys?: React.Key[];
onTreeLoad?: (loadedKeys: React.Key[]) => void;
treeLoadedKeys?: SafeKey[];
onTreeLoad?: (loadedKeys: SafeKey[]) => void;

// >>> Expanded
treeDefaultExpandAll?: boolean;
treeExpandedKeys?: React.Key[];
treeDefaultExpandedKeys?: React.Key[];
onTreeExpand?: (expandedKeys: React.Key[]) => void;
treeExpandedKeys?: SafeKey[];
treeDefaultExpandedKeys?: SafeKey[];
onTreeExpand?: (expandedKeys: SafeKey[]) => void;
treeExpandAction?: ExpandAction;

// >>> Options
Expand All @@ -171,7 +158,7 @@ export interface TreeSelectProps<
treeMotion?: any;
}

function isRawValue(value: RawValueType | LabeledValueType): value is RawValueType {
function isRawValue(value: SafeKey | LabeledValueType): value is SafeKey {
return !value || typeof value !== 'object';
}

Expand Down Expand Up @@ -295,7 +282,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)

/** Get `missingRawValues` which not exist in the tree yet */
const splitRawValues = React.useCallback(
(newRawValues: RawValueType[]) => {
(newRawValues: SafeKey[]) => {
const missingRawValues = [];
const existRawValues = [];

Expand Down Expand Up @@ -343,7 +330,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
);

// ========================= Wrap Value =========================
const toLabeledValues = React.useCallback((draftValues: DraftValueType) => {
const toLabeledValues = React.useCallback((draftValues: DefaultValueType) => {
const values = toArray(draftValues);

return values.map(val => {
Expand All @@ -355,7 +342,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
}, []);

const convert2LabelValues = React.useCallback(
(draftValues: DraftValueType) => {
(draftValues: DefaultValueType) => {
const values = toLabeledValues(draftValues);

return values.map(item => {
Expand All @@ -368,7 +355,9 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)

// Fill missing label & status
if (entity) {
rawLabel = treeTitleRender ? treeTitleRender(entity.node) : rawLabel ?? getLabel(entity.node);
rawLabel = treeTitleRender
? treeTitleRender(entity.node)
: (rawLabel ?? getLabel(entity.node));
rawDisabled = entity.node.disabled;
} else if (rawLabel === undefined) {
// We try to find in current `labelInValue` value
Expand Down Expand Up @@ -475,8 +464,8 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
// =========================== Change ===========================
const triggerChange = useRefFunc(
(
newRawValues: RawValueType[],
extra: { triggerValue?: RawValueType; selected?: boolean },
newRawValues: SafeKey[],
extra: { triggerValue?: SafeKey; selected?: boolean },
source: SelectSource,
) => {
const labeledValues = convert2LabelValues(newRawValues);
Expand All @@ -489,7 +478,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)

// Generate rest parameters is costly, so only do it when necessary
if (onChange) {
let eventValues: RawValueType[] = newRawValues;
let eventValues: SafeKey[] = newRawValues;
if (treeConduction) {
const formattedKeyList = formatStrategyValues(
newRawValues,
Expand All @@ -508,7 +497,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
selected: undefined,
};

let returnRawValues: (LabeledValueType | RawValueType)[] = eventValues;
let returnRawValues: (LabeledValueType | SafeKey)[] = eventValues;

// We need fill half check back
if (treeCheckStrictly) {
Expand Down Expand Up @@ -563,7 +552,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
// ========================== Options ===========================
/** Trigger by option list */
const onOptionSelect = React.useCallback(
(selectedKey: React.Key, { selected, source }: { selected: boolean; source: SelectSource }) => {
(selectedKey: SafeKey, { selected, source }: { selected: boolean; source: SelectSource }) => {
const entity = keyEntities[selectedKey];
const node = entity?.node;
const selectedValue = node?.[mergedFieldNames.value] ?? selectedKey;
Expand All @@ -584,7 +573,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
const keyList = existRawValues.map(val => valueEntities.get(val).key);

// Conduction by selected or not
let checkedKeys: React.Key[];
let checkedKeys: SafeKey[];
if (selected) {
({ checkedKeys } = conductCheck(keyList, true, keyEntities));
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/useCache.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import * as React from 'react';
import type { LabeledValueType, RawValueType } from '../TreeSelect';
import type { LabeledValueType, SafeKey } from '../interface';

/**
* This function will try to call requestIdleCallback if available to save performance.
* No need `getLabel` here since already fetch on `rawLabeledValue`.
*/
export default (values: LabeledValueType[]): [LabeledValueType[]] => {
const cacheRef = React.useRef({
valueLabels: new Map<RawValueType, React.ReactNode>(),
valueLabels: new Map<SafeKey, React.ReactNode>(),
});

return React.useMemo(() => {
const { valueLabels } = cacheRef.current;
const valueLabelsCache = new Map<RawValueType, React.ReactNode>();
const valueLabelsCache = new Map<SafeKey, React.ReactNode>();

const filledValues = values.map(item => {
const { value } = item;
Expand Down
Loading

0 comments on commit f3806bd

Please sign in to comment.