Skip to content

Commit fbb2822

Browse files
刘欢claude
andcommitted
refactor: extract useDisabled hook to unify disabled handling
- Extract disabled logic into useDisabled hook - Add type annotations for TypeScript inference - Extract gap variable in useOffset to avoid duplication Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cf5819c commit fbb2822

3 files changed

Lines changed: 50 additions & 30 deletions

File tree

src/Slider.tsx

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Steps from './Steps';
1212
import Tracks from './Tracks';
1313
import type { SliderContextProps } from './context';
1414
import SliderContext from './context';
15+
import useDisabled from './hooks/useDisabled';
1516
import useDrag from './hooks/useDrag';
1617
import useOffset from './hooks/useOffset';
1718
import useRange from './hooks/useRange';
@@ -189,27 +190,8 @@ const Slider = React.forwardRef<SliderRef, SliderProps<number | number[]>>((prop
189190
const [mergedValue, setValue] = useControlledState(defaultValue, value);
190191

191192
// ============================ Disabled ============================
192-
const disabled = React.useMemo(() => {
193-
if (typeof rawDisabled === 'boolean') {
194-
return rawDisabled;
195-
}
196-
if (Array.isArray(rawDisabled)) {
197-
const values = Array.isArray(mergedValue) ? mergedValue : [mergedValue];
198-
return values.every((_, index) => rawDisabled[index]);
199-
}
200-
return false;
201-
}, [rawDisabled, mergedValue]);
202193

203-
const isHandleDisabled = React.useCallback(
204-
(index: number) => {
205-
if (typeof rawDisabled === 'boolean') {
206-
return rawDisabled;
207-
}
208-
// Return individual disabled state if defined, otherwise fallback to global disabled
209-
return rawDisabled[index] ?? disabled;
210-
},
211-
[rawDisabled, disabled],
212-
);
194+
const [disabled, isHandleDisabled, hasDisabledHandle] = useDisabled(rawDisabled, mergedValue);
213195

214196
const direction = React.useMemo<Direction>(() => {
215197
if (vertical) {
@@ -221,14 +203,6 @@ const Slider = React.forwardRef<SliderRef, SliderProps<number | number[]>>((prop
221203
// ============================ Range =============================
222204
const [rangeEnabled, rangeEditable, rangeDraggableTrack, minCount, maxCount] = useRange(range);
223205

224-
// Check if any handle is disabled - if so, disable all editable operations
225-
const hasDisabledHandle = React.useMemo(() => {
226-
if (typeof rawDisabled === 'boolean') {
227-
return rawDisabled;
228-
}
229-
return rawDisabled.some((d) => d);
230-
}, [rawDisabled]);
231-
232206
// Disable editable when any handle is disabled
233207
const effectiveRangeEditable = rangeEditable && !hasDisabledHandle;
234208

src/hooks/useDisabled.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from 'react';
2+
3+
const useDisabled = (
4+
rawDisabled: boolean | boolean[],
5+
mergedValue?: number | number[],
6+
): [boolean, (index: number) => boolean, boolean] => {
7+
8+
const disabledIsArray = Array.isArray(rawDisabled);
9+
const disabledIsBoolean = typeof rawDisabled === 'boolean';
10+
const values = React.useMemo(
11+
() => (Array.isArray(mergedValue) ? mergedValue : [mergedValue]),
12+
[mergedValue],
13+
);
14+
15+
const disabled = React.useMemo(() => {
16+
if (disabledIsBoolean) {
17+
return rawDisabled;
18+
}
19+
return disabledIsArray ? values.every((_, index) => rawDisabled[index]) : false;
20+
}, [rawDisabled, mergedValue]);
21+
22+
const isHandleDisabled = React.useCallback(
23+
(index: number): boolean => {
24+
if (disabledIsBoolean) {
25+
return rawDisabled;
26+
}
27+
return rawDisabled[index] ?? disabled;
28+
},
29+
[rawDisabled, disabled],
30+
);
31+
32+
const hasDisabledHandle = React.useMemo(() => {
33+
if (disabledIsBoolean) {
34+
return rawDisabled;
35+
}
36+
return rawDisabled.some((d) => d);
37+
}, [rawDisabled]);
38+
39+
return [
40+
disabled,
41+
isHandleDisabled,
42+
hasDisabledHandle,
43+
];
44+
};
45+
46+
export default useDisabled;

src/hooks/useOffset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ export default function useOffset(
190190
return (pushable === null && dist === 0) || (typeof pushable === 'number' && dist < pushable);
191191
};
192192

193+
const gap = typeof pushable === 'number' ? pushable : 0;
194+
193195
// Get the minimum boundary for a handle considering disabled handles as fixed anchors
194196
const getHandleMinBound = (values: number[], handleIndex: number): number => {
195-
const gap = typeof pushable === 'number' ? pushable : 0;
196197
// Collect min and all left-side disabled handle positions as candidates
197198
const candidates = [min];
198199
for (let i = handleIndex - 1; i >= 0; i -= 1) {
@@ -206,7 +207,6 @@ export default function useOffset(
206207

207208
// Get the maximum boundary for a handle considering disabled handles as fixed anchors
208209
const getHandleMaxBound = (values: number[], handleIndex: number): number => {
209-
const gap = typeof pushable === 'number' ? pushable : 0;
210210
// Collect max and all right-side disabled handle positions as candidates
211211
const candidates = [max];
212212
for (let i = handleIndex + 1; i < values.length; i += 1) {

0 commit comments

Comments
 (0)