-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add sliderBase * work in progress for range filter * update yarn lock * styling fixes * slider * slider * fix types * v0.13.1-1 * Fix more types * options icon * v0.13.1-2 * Fix styles * v0.13.1-3 * WIP * v0.13.1-4 * v0.13.1
- Loading branch information
1 parent
189859c
commit 5a830d9
Showing
16 changed files
with
1,145 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { FocusableRef } from '@react-types/shared'; | ||
import React from 'react'; | ||
import { | ||
SliderBase, | ||
SliderBaseChildArguments, | ||
SliderBaseProps, | ||
} from './SliderBase'; | ||
import { SliderThumb } from './SliderThumb'; | ||
import { RangeSliderProps } from '../types/slider'; | ||
import { useLocale } from '@react-aria/i18n'; | ||
|
||
function RangeSlider( | ||
props: RangeSliderProps, | ||
ref: FocusableRef<HTMLDivElement> | ||
) { | ||
let { | ||
onChange, | ||
onChangeEnd, | ||
value, | ||
defaultValue, | ||
getValueLabel, | ||
...otherProps | ||
} = props; | ||
|
||
let baseProps: Omit<SliderBaseProps<number[]>, 'children'> = { | ||
...otherProps, | ||
value: value != null ? [value.start, value.end] : undefined, | ||
defaultValue: | ||
defaultValue != null | ||
? [defaultValue.start, defaultValue.end] | ||
: // make sure that useSliderState knows we have two handles | ||
[props.minValue ?? 0, props.maxValue ?? 100], | ||
onChange(v) { | ||
onChange?.({ start: v[0], end: v[1] }); | ||
}, | ||
onChangeEnd(v) { | ||
onChangeEnd?.({ start: v[0], end: v[1] }); | ||
}, | ||
getValueLabel: getValueLabel | ||
? // @ts-expect-error update typescript version | ||
([start, end]) => getValueLabel({ start, end }) | ||
: undefined, | ||
}; | ||
|
||
let { direction } = useLocale(); | ||
|
||
return ( | ||
<SliderBase {...baseProps} classes={'ac-slider--range'} ref={ref}> | ||
{({ trackRef, inputRef, state }: SliderBaseChildArguments) => { | ||
let cssDirection = direction === 'rtl' ? 'right' : 'left'; | ||
return ( | ||
<> | ||
<div | ||
className={'ac-slider-track'} | ||
style={{ width: `${state.getThumbPercent(0) * 100}%` }} | ||
/> | ||
<SliderThumb | ||
index={0} | ||
aria-label={'minimum'} | ||
isDisabled={props.isDisabled} | ||
trackRef={trackRef} | ||
inputRef={inputRef} | ||
state={state} | ||
/> | ||
<div | ||
className={'ac-slider-track'} | ||
style={{ | ||
[cssDirection]: `${state.getThumbPercent(0) * 100}%`, | ||
width: `${Math.abs( | ||
state.getThumbPercent(0) - state.getThumbPercent(1) | ||
) * 100}%`, | ||
}} | ||
/> | ||
<SliderThumb | ||
index={1} | ||
aria-label={'maximum'} | ||
isDisabled={props.isDisabled} | ||
trackRef={trackRef} | ||
state={state} | ||
/> | ||
<div | ||
className={'ac-slider-track'} | ||
style={{ | ||
width: `${(1 - state.getThumbPercent(1)) * 100}%`, | ||
}} | ||
/> | ||
</> | ||
); | ||
}} | ||
</SliderBase> | ||
); | ||
} | ||
|
||
/** | ||
* RangeSliders allow users to quickly select a subset range. They should be used when the upper and lower bounds to the range are invariable. | ||
*/ | ||
const _RangeSlider = React.forwardRef(RangeSlider); | ||
export { _RangeSlider as RangeSlider }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { clamp } from '@react-aria/utils'; | ||
import { classNames } from '../utils'; | ||
import { FocusableRef } from '../types'; | ||
import React, { ReactNode } from 'react'; | ||
import { | ||
SliderBase, | ||
SliderBaseChildArguments, | ||
SliderBaseProps, | ||
} from './SliderBase'; | ||
import { SliderThumb } from './SliderThumb'; | ||
import { ACSliderProps } from '../types/slider'; | ||
|
||
function Slider(props: ACSliderProps, ref: FocusableRef<HTMLDivElement>) { | ||
let { | ||
onChange, | ||
onChangeEnd, | ||
value, | ||
defaultValue, | ||
isFilled, | ||
fillOffset, | ||
trackGradient, | ||
getValueLabel, | ||
...otherProps | ||
} = props; | ||
|
||
let baseProps: Omit<SliderBaseProps, 'children'> = { | ||
...otherProps, | ||
// Normalize `value: number[]` to `value: number` | ||
value: value != null ? [value] : undefined, | ||
defaultValue: defaultValue != null ? [defaultValue] : undefined, | ||
onChange: (v: number[]): void => { | ||
onChange?.(v[0]); | ||
}, | ||
onChangeEnd: (v: number[]): void => { | ||
onChangeEnd?.(v[0]); | ||
}, | ||
|
||
getValueLabel: | ||
typeof getValueLabel === 'function' | ||
? // @ts-ignore | ||
([v]) => getValueLabel(v) | ||
: undefined, | ||
}; | ||
|
||
return ( | ||
<SliderBase {...baseProps} ref={ref}> | ||
{({ trackRef, inputRef, state }: SliderBaseChildArguments) => { | ||
fillOffset = | ||
fillOffset != null | ||
? clamp( | ||
fillOffset, | ||
state.getThumbMinValue(0), | ||
state.getThumbMaxValue(0) | ||
) | ||
: fillOffset; | ||
|
||
let lowerTrack = ( | ||
<div | ||
className={classNames('ac-slider-track')} | ||
style={{ | ||
width: `${state.getThumbPercent(0) * 100}%`, | ||
// TODO not sure if it has advantages, but this could also be implemented as CSS calc(): | ||
// .track::before { | ||
// background-size: calc((1/ (var(--width)/100)) * 100%); | ||
// width: calc(var(--width) * 1%)M | ||
// } | ||
// @ts-ignore | ||
'--ac-track-background-size': `${(1 / state.getThumbPercent(0)) * | ||
100}%`, | ||
}} | ||
/> | ||
); | ||
let upperTrack = ( | ||
<div | ||
className="ac-slider-track" | ||
style={{ | ||
width: `${(1 - state.getThumbPercent(0)) * 100}%`, | ||
// @ts-ignore | ||
'--ac-track-background-size': `${(1 / | ||
(1 - state.getThumbPercent(0))) * | ||
100}%`, | ||
'--ac-track-background-position': '100%', | ||
}} | ||
/> | ||
); | ||
|
||
let filledTrack: ReactNode = null; | ||
if (isFilled && fillOffset != null) { | ||
let width = | ||
state.getThumbPercent(0) - state.getValuePercent(fillOffset); | ||
let isRightOfOffset = width > 0; | ||
let offset = isRightOfOffset | ||
? state.getValuePercent(fillOffset) | ||
: state.getThumbPercent(0); | ||
filledTrack = ( | ||
<div | ||
className="ac-slider-fill" | ||
style={{ | ||
left: `${offset * 100}%`, | ||
width: `${Math.abs(width) * 100}%`, | ||
}} | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
{lowerTrack} | ||
<SliderThumb | ||
index={0} | ||
isDisabled={props.isDisabled} | ||
trackRef={trackRef} | ||
inputRef={inputRef} | ||
state={state} | ||
name={props.name} | ||
/> | ||
{filledTrack} | ||
{upperTrack} | ||
</> | ||
); | ||
}} | ||
</SliderBase> | ||
); | ||
} | ||
|
||
/** | ||
* Sliders allow users to quickly select a value within a range. They should be used when the upper and lower bounds to the range are invariable. | ||
*/ | ||
const _Slider = React.forwardRef(Slider); | ||
export { _Slider as Slider }; |
Oops, something went wrong.