Skip to content

Commit 0f255bb

Browse files
Removing pageSize from sliderProps (#2917)
* removing pageSize from sliderProps also forcing pageSize to be a multiple of step * adding test for page size clamping * using snap value to step for page size calc * fixing logic to account for if step is less or greater than min/max * fixing comment * making math simpler for calculating page size * exposing pageSize and step from useColorSliderState memoizing step calc in useSliderState as well. Exposing pageSize and step from useColorSliderState allows us to remove extraneous useKeyboard from useColorSlider that was previously needed for pageUp/Down handling Co-authored-by: Robert Snow <[email protected]>
1 parent 4ea2db6 commit 0f255bb

File tree

7 files changed

+53
-43
lines changed

7 files changed

+53
-43
lines changed

packages/@react-aria/slider/stories/Slider.stories.tsx

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ storiesOf('Slider (hooks)', module)
2828
'single with aria label',
2929
() => <StorySlider aria-label="Size" onChange={action('onChange')} onChangeEnd={action('onChangeEnd')} showTip />
3030
)
31-
.add(
32-
'single with pageSize',
33-
() => <StorySlider label="Degrees" onChange={action('onChange')} onChangeEnd={action('onChangeEnd')} minValue={0} maxValue={360} pageSize={15} formatOptions={{style: 'unit', unit: 'degree', unitDisplay: 'narrow'}} showTip />
34-
)
3531
.add(
3632
'range',
3733
() => (<StoryRangeSlider
@@ -60,23 +56,6 @@ storiesOf('Slider (hooks)', module)
6056
unitDisplay: 'narrow'
6157
} as any} />)
6258
)
63-
.add(
64-
'range with pageSize',
65-
() => (<StoryRangeSlider
66-
label="Arc"
67-
defaultValue={[45, 135]}
68-
minValue={0}
69-
maxValue={360}
70-
pageSize={15}
71-
onChange={action('onChange')}
72-
onChangeEnd={action('onChangeEnd')}
73-
showTip
74-
formatOptions={{
75-
style: 'unit',
76-
unit: 'degree',
77-
unitDisplay: 'narrow'
78-
} as any} />)
79-
)
8059
.add(
8160
'3 thumbs',
8261
() => (

packages/@react-spectrum/slider/stories/RangeSlider.stories.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ storiesOf('Slider/RangeSlider', module)
7171
.add(
7272
'min/max',
7373
() => render({label: 'Label', minValue: 30, maxValue: 70})
74-
)
75-
.add(
76-
'pageSize',
77-
() => render({label: 'Label', minValue: 0, maxValue: 360, pageSize: 15, formatOptions: {style: 'unit', unit: 'degree', unitDisplay: 'narrow'}})
7874
);
7975

8076
function render(props: SpectrumRangeSliderProps = {}) {

packages/@react-spectrum/slider/stories/Slider.stories.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ storiesOf('Slider', module)
9696
'step',
9797
() => render({label: 'Label', minValue: 0, maxValue: 100, step: 5})
9898
)
99-
.add(
100-
'pageSize',
101-
() => render({label: 'Label', minValue: 0, maxValue: 360, pageSize: 15, formatOptions: {style: 'unit', unit: 'degree', unitDisplay: 'narrow'}})
102-
)
10399
.add(
104100
'isFilled: true',
105101
() => render({label: 'Label', isFilled: true})

packages/@react-spectrum/slider/test/Slider.test.tsx

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,16 +267,51 @@ describe('Slider', function () {
267267

268268
it.each`
269269
Name | props | commands
270-
${'(left/right arrows, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.ArrowRight, result: +1}, {left: press.ArrowLeft, result: -1}]}
271-
${'(left/right arrows, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.ArrowRight, result: -1}, {left: press.ArrowLeft, result: +1}]}
270+
${'(left/right arrows, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.ArrowRight, result: +10}, {left: press.ArrowLeft, result: -10}]}
271+
${'(left/right arrows, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.ArrowRight, result: -10}, {left: press.ArrowLeft, result: +10}]}
272272
${'(page up/down, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.PageUp, result: +20}, {left: press.PageDown, result: -20}]}
273273
${'(page up/down, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.PageUp, result: +20}, {left: press.PageDown, result: -20}]}
274-
`('$Name respects the page size', function ({props, commands}) {
274+
`('$Name sets page size to a multiple of step', function ({props, commands}) {
275275
let tree = render(
276276
<Provider theme={theme} {...props}>
277-
<Slider label="Label" pageSize={20} defaultValue={50} />
277+
<Slider label="Label" minValue={0} maxValue={230} defaultValue={50} step={10} />
278278
</Provider>
279279
);
280+
// The slider page size should be initially calulated as 230/10 = 23 and then snapped to 20 so it is a multiple of the step
281+
let slider = tree.getByRole('slider');
282+
testKeypresses([slider, slider], commands);
283+
});
284+
285+
it.each`
286+
Name | props | commands
287+
${'(left/right arrows, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.ArrowRight, result: +2}, {left: press.ArrowLeft, result: -2}]}
288+
${'(left/right arrows, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.ArrowRight, result: -2}, {left: press.ArrowLeft, result: +2}]}
289+
${'(page up/down, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.PageUp, result: +2}, {left: press.PageDown, result: -2}]}
290+
${'(page up/down, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.PageUp, result: +2}, {left: press.PageDown, result: -2}]}
291+
`('$Name sets page size to a multiple of step (scenario: step is less than min)', function ({props, commands}) {
292+
let tree = render(
293+
<Provider theme={theme} {...props}>
294+
<Slider label="Label" minValue={50} maxValue={75} defaultValue={60} step={2} />
295+
</Provider>
296+
);
297+
// The slider page size should be initially calulated as 25/10 = 2.5, snaps to 2
298+
let slider = tree.getByRole('slider');
299+
testKeypresses([slider, slider], commands);
300+
});
301+
302+
it.each`
303+
Name | props | commands
304+
${'(left/right arrows, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.ArrowRight, result: +2}, {left: press.ArrowLeft, result: -2}]}
305+
${'(left/right arrows, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.ArrowRight, result: -2}, {left: press.ArrowLeft, result: +2}]}
306+
${'(page up/down, ltr)'} | ${{locale: 'de-DE'}} | ${[{left: press.PageUp, result: +4}, {left: press.PageDown, result: -4}]}
307+
${'(page up/down, rtl)'} | ${{locale: 'ar-AE'}} | ${[{left: press.PageUp, result: +4}, {left: press.PageDown, result: -4}]}
308+
`('$Name sets page size to a multiple of step (scenario: step is greater than max)', function ({props, commands}) {
309+
let tree = render(
310+
<Provider theme={theme} {...props}>
311+
<Slider label="Label" minValue={-50} maxValue={-15} defaultValue={-40} step={2} />
312+
</Provider>
313+
);
314+
// The slider page size should be initially calulated as 35/10 = 3.5, snaps to 4
280315
let slider = tree.getByRole('slider');
281316
testKeypresses([slider, slider], commands);
282317
});

packages/@react-stately/color/src/useColorSliderState.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export function useColorSliderState(props: ColorSliderStateOptions): ColorSlider
5858
}
5959
});
6060

61+
let {step, pageSize} = color.getChannelRange(channel);
6162
return {
6263
...sliderState,
6364
value: color,
@@ -84,6 +85,8 @@ export function useColorSliderState(props: ColorSliderStateOptions): ColorSlider
8485
},
8586
getThumbValueLabel() {
8687
return color.formatChannelValue(channel, locale);
87-
}
88+
},
89+
step,
90+
pageSize
8891
};
8992
}

packages/@react-stately/slider/src/useSliderState.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import {clamp, snapValueToStep} from '@react-aria/utils';
1414
import {SliderProps} from '@react-types/slider';
1515
import {useControlledState} from '@react-stately/utils';
16-
import {useRef, useState} from 'react';
16+
import {useMemo, useRef, useState} from 'react';
1717

1818
export interface SliderState {
1919
/**
@@ -159,10 +159,16 @@ export function useSliderState(props: SliderStateOptions): SliderState {
159159
minValue = DEFAULT_MIN_VALUE,
160160
maxValue = DEFAULT_MAX_VALUE,
161161
numberFormatter: formatter,
162-
step = DEFAULT_STEP_VALUE,
163-
pageSize = Math.max((maxValue - minValue) / 10, step)
162+
step = DEFAULT_STEP_VALUE
164163
} = props;
165164

165+
// Page step should be at least equal to step and always a multiple of the step.
166+
let pageSize = useMemo(() => {
167+
let calcPageSize = (maxValue - minValue) / 10;
168+
calcPageSize = snapValueToStep(calcPageSize, 0, calcPageSize + step, step);
169+
return Math.max(calcPageSize, step);
170+
}, [step, maxValue, minValue]);
171+
166172
const [values, setValues] = useControlledState<number[]>(
167173
props.value as any,
168174
props.defaultValue ?? [minValue] as any,

packages/@react-types/slider/src/index.d.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,7 @@ export interface SliderProps<T = number[]> extends RangeInputBase<number>, Value
3939
* The slider's step value.
4040
* @default 1
4141
*/
42-
step?: number,
43-
/**
44-
* The slider's page step value, used when incrementing and decrementing.
45-
* @default 1
46-
*/
47-
pageSize?: number
42+
step?: number
4843
}
4944

5045
export interface SliderThumbProps extends FocusableProps, Validation, LabelableProps {

0 commit comments

Comments
 (0)