Skip to content

Commit a82d00a

Browse files
chore: clamp slider to 25% min
1 parent fe5a8c1 commit a82d00a

2 files changed

Lines changed: 39 additions & 15 deletions

File tree

app/components/UI/Bridge/Views/BatchSellReview/BatchSellPercentageSlider.test.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ jest.mock('react-native-gesture-handler', () => {
3535

3636
describe('BatchSellPercentageSlider', () => {
3737
it.each([
38-
[-10, 0],
39-
[0, 0],
40-
[12, 0],
38+
[-10, 25],
39+
[0, 25],
40+
[12, 25],
4141
[13, 25],
4242
[37, 25],
4343
[38, 50],
@@ -86,6 +86,23 @@ describe('BatchSellPercentageSlider', () => {
8686
expect(onValueChange).toHaveBeenCalledWith(25);
8787
});
8888

89+
it('does not decrement below the minimum snap point', () => {
90+
const onValueChange = jest.fn();
91+
const { getByTestId } = render(
92+
<BatchSellPercentageSlider
93+
value={25}
94+
onValueChange={onValueChange}
95+
testID={SLIDER_TEST_ID}
96+
/>,
97+
);
98+
99+
fireEvent(getByTestId(SLIDER_TEST_ID), 'accessibilityAction', {
100+
nativeEvent: { actionName: 'decrement' },
101+
});
102+
103+
expect(onValueChange).toHaveBeenCalledWith(25);
104+
});
105+
89106
it('renders muted marker dots for each snap point', () => {
90107
const { getByTestId } = render(
91108
<BatchSellPercentageSlider

app/components/UI/Bridge/Views/BatchSellReview/BatchSellPercentageSlider.tsx

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ import { useTailwind } from '@metamask/design-system-twrnc-preset';
1515
const HANDLE_SIZE = 24;
1616
const MARKER_SIZE = 4;
1717
const PERCENTAGE_STEP = 25;
18-
export const SNAP_POINTS = [0, 25, 50, 75, 100];
18+
export const SNAP_POINTS = [25, 50, 75, 100];
19+
const MIN_PERCENTAGE = SNAP_POINTS[0];
1920

2021
export function snapToPercentageStep(value: number): number {
2122
const snappedValue = Math.round(value / PERCENTAGE_STEP) * PERCENTAGE_STEP;
22-
return Math.max(0, Math.min(100, snappedValue));
23+
return Math.max(MIN_PERCENTAGE, Math.min(100, snappedValue));
2324
}
2425

2526
interface BatchSellPercentageSliderProps {
@@ -34,14 +35,15 @@ export function BatchSellPercentageSlider({
3435
testID,
3536
}: BatchSellPercentageSliderProps) {
3637
const tw = useTailwind();
38+
const snappedValue = snapToPercentageStep(value);
3739
const sliderWidth = useSharedValue(0);
3840
const translateX = useSharedValue(0);
3941
const widthRef = useRef(0);
4042

4143
const updatePosition = useCallback(
4244
(nextValue: number, width = widthRef.current) => {
43-
const snappedValue = snapToPercentageStep(nextValue);
44-
translateX.value = (snappedValue / 100) * width;
45+
const nextSnappedValue = snapToPercentageStep(nextValue);
46+
translateX.value = (nextSnappedValue / 100) * width;
4547
},
4648
[translateX],
4749
);
@@ -66,14 +68,14 @@ export function BatchSellPercentageSlider({
6668
const { width } = event.nativeEvent.layout;
6769
widthRef.current = width;
6870
sliderWidth.value = width;
69-
updatePosition(value, width);
71+
updatePosition(snappedValue, width);
7072
},
71-
[sliderWidth, updatePosition, value],
73+
[sliderWidth, snappedValue, updatePosition],
7274
);
7375

7476
useEffect(() => {
75-
updatePosition(value);
76-
}, [updatePosition, value]);
77+
updatePosition(snappedValue);
78+
}, [snappedValue, updatePosition]);
7779

7880
const progressStyle = useAnimatedStyle(() => ({
7981
width: translateX.value,
@@ -106,19 +108,24 @@ export function BatchSellPercentageSlider({
106108
(event: AccessibilityActionEvent) => {
107109
const nextValue =
108110
event.nativeEvent.actionName === 'increment'
109-
? snapToPercentageStep(value + PERCENTAGE_STEP)
110-
: snapToPercentageStep(value - PERCENTAGE_STEP);
111+
? snapToPercentageStep(snappedValue + PERCENTAGE_STEP)
112+
: snapToPercentageStep(snappedValue - PERCENTAGE_STEP);
111113

112114
onValueChange(nextValue);
113115
},
114-
[onValueChange, value],
116+
[onValueChange, snappedValue],
115117
);
116118

117119
return (
118120
<GestureHandlerRootView
119121
testID={testID}
120122
accessibilityRole="adjustable"
121-
accessibilityValue={{ min: 0, max: 100, now: value, text: `${value}%` }}
123+
accessibilityValue={{
124+
min: MIN_PERCENTAGE,
125+
max: 100,
126+
now: snappedValue,
127+
text: `${snappedValue}%`,
128+
}}
122129
accessibilityActions={[{ name: 'increment' }, { name: 'decrement' }]}
123130
onAccessibilityAction={handleAccessibilityAction}
124131
style={tw.style('h-6 w-full')}

0 commit comments

Comments
 (0)