Skip to content

Commit 16b1fdb

Browse files
committed
fix(ui): fix onChange not work
1 parent d9b5efb commit 16b1fdb

4 files changed

Lines changed: 21 additions & 24 deletions

File tree

packages/ui/src/components/checkbox/Checkbox.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ const Checkbox: React.ForwardRefRenderFunction<DCheckboxRef, DCheckboxProps> = (
5151

5252
const inGroup = checkboxGroupContext !== null;
5353

54-
const [checked, changeChecked, { validateClassName, ariaAttribute, controlDisabled }] = useTwoWayBinding(
54+
const [checked, changeChecked, { validateClassName, ariaAttribute, controlDisabled }] = useTwoWayBinding<boolean | undefined, boolean>(
5555
false,
56-
inGroup ? [checkboxGroupValue?.includes(dValue) ?? false] : dModel,
56+
dModel ?? (dIndeterminate ? [undefined] : inGroup ? [checkboxGroupValue?.includes(dValue) ?? false] : undefined),
5757
onModelChange,
5858
dFormControlName ? { formControlName: dFormControlName, id: _id } : undefined
5959
);
@@ -66,14 +66,13 @@ const Checkbox: React.ForwardRefRenderFunction<DCheckboxRef, DCheckboxProps> = (
6666
onChange?.(e);
6767

6868
if (!disabled) {
69+
changeChecked(dIndeterminate ? true : !checked);
6970
if (inGroup) {
70-
onCheckedChange?.(dValue, !checked);
71-
} else {
72-
changeChecked(!checked);
71+
onCheckedChange?.(dValue, dIndeterminate ? true : !checked);
7372
}
7473
}
7574
},
76-
[onChange, disabled, inGroup, onCheckedChange, dValue, checked, changeChecked]
75+
[onChange, disabled, changeChecked, dIndeterminate, checked, inGroup, onCheckedChange, dValue]
7776
);
7877

7978
return (

packages/ui/src/components/menu/Menu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export function DMenu(props: DMenuProps) {
6666
const [focusId, setFocusId] = useImmer<DMenuContextData['menuFocusId']>(null);
6767
const [activedescendant, setActiveDescendant] = useState<string | undefined>(undefined);
6868

69-
const [activeId, changeActiveId] = useTwoWayBinding<string | null>(null, dActive, onActiveChange);
69+
const [activeId, changeActiveId] = useTwoWayBinding<string | null, string>(null, dActive, onActiveChange);
7070
const [expandIds, changeExpandIds] = useTwoWayBinding(new Set<string>(), dExpands, onExpandsChange);
7171

7272
const expandTrigger = isUndefined(dExpandTrigger) ? (dMode === 'vertical' ? 'click' : 'hover') : dExpandTrigger;

packages/ui/src/components/radio/Radio.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const Radio: React.ForwardRefRenderFunction<DRadioRef, DRadioProps> = (props, re
6060

6161
const [checked, changeChecked, { validateClassName, ariaAttribute, controlDisabled }] = useTwoWayBinding(
6262
false,
63-
inGroup ? [radioGroupValue === dValue] : dModel,
63+
dModel ?? [radioGroupValue === dValue],
6464
onModelChange,
6565
dFormControlName ? { formControlName: dFormControlName, id: _id } : undefined
6666
);
@@ -73,10 +73,9 @@ const Radio: React.ForwardRefRenderFunction<DRadioRef, DRadioProps> = (props, re
7373
onChange?.(e);
7474

7575
if (!disabled) {
76+
changeChecked(true);
7677
if (inGroup) {
7778
onCheckedChange?.(dValue);
78-
} else {
79-
changeChecked(true);
8079
}
8180
if (radioEl && (radioGroupType === 'fill' || radioGroupType === 'outline')) {
8281
wave(radioEl, `var(--${dPrefix}color-primary)`);
@@ -104,6 +103,7 @@ const Radio: React.ForwardRefRenderFunction<DRadioRef, DRadioProps> = (props, re
104103
className={getClassName(`${dPrefix}radio__input`, validateClassName)}
105104
type="radio"
106105
name={radioGroupName}
106+
checked={checked}
107107
disabled={disabled}
108108
aria-labelledby={`${dPrefix}radio-label-${uniqueId}`}
109109
aria-checked={checked}

packages/ui/src/hooks/two-way-binding.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
32
import type { Updater as IUpdater } from './immer';
43

54
import { freeze, produce } from 'immer';
@@ -12,10 +11,10 @@ import { useStateBackflow } from './state-backflow';
1211

1312
export type Updater<S> = (value: S) => void;
1413

15-
export function useTwoWayBinding<T>(
14+
export function useTwoWayBinding<T, S = T>(
1615
initialValue: T | (() => T),
17-
input?: [T, Updater<T>?],
18-
onValueChange?: (value: any) => void,
16+
input?: [T, Updater<S>?],
17+
onValueChange?: (value: S) => void,
1918
opt?: {
2019
id: string;
2120
formControlName: string;
@@ -57,24 +56,23 @@ export function useTwoWayBinding<T>(
5756

5857
const setValue = input?.[1];
5958
const [autoValue, setAutoValue] = useState<T>(initialValue);
60-
const value = isUndefined(input?.[0]) ? autoValue : input![0];
59+
const value = isUndefined(input) ? autoValue : input[0];
6160

6261
const currentValue = formControl ? formControl.value : value;
6362

6463
const changeValue = useCallback(
6564
(updater: any) => {
6665
const val = isFunction(updater) ? produce(currentValue, updater) : freeze(updater);
6766

68-
if (formControl) {
69-
if (!Object.is(val, currentValue)) {
67+
if (!Object.is(val, currentValue)) {
68+
if (formControl) {
7069
formControl.markAsDirty(true);
7170
formControl.setValue(val);
72-
formInstance!.updateForm();
73-
}
74-
} else {
75-
setValue?.(val);
76-
setAutoValue(val);
77-
if (!Object.is(val, currentValue)) {
71+
onValueChange?.(val);
72+
formInstance?.updateForm();
73+
} else {
74+
setValue?.(val);
75+
setAutoValue(val);
7876
onValueChange?.(val);
7977
}
8078
}
@@ -85,7 +83,7 @@ export function useTwoWayBinding<T>(
8583
const res = useMemo<
8684
[
8785
T,
88-
IUpdater<T>,
86+
IUpdater<S>,
8987
{
9088
validateClassName?: string;
9189
ariaAttribute?: React.HTMLAttributes<HTMLElement>;

0 commit comments

Comments
 (0)