useColorSlider
Provides the behavior and accessibility implementation for a color slider component. Color sliders allow users to adjust an individual channel of a color value.
| install | yarn add @react-aria/color |
|---|---|
| version | 3.0.0-alpha.1 |
| usage | import {useColorSlider} from '@react-aria/color' |
API#
useColorSlider(
(props: ColorSliderAriaOptions,
, state: ColorSliderState
)): ColorSliderAriaExample#
import {useColorSliderState} from '@react-stately/color';
import {VisuallyHidden} from '@react-aria/visually-hidden';
import {useNumberFormatter} from '@react-aria/i18n';
import {useFocusRing} from '@react-aria/focus';
const TRACK_THICKNESS = 28;
const THUMB_SIZE = 20;
function ColorSlider(props) {
let numberFormatter = useNumberFormatter({
style: propschannel === 'alpha' ? 'percent' : 'decimal'
});
let state = useColorSliderState({...props numberFormatter});
let trackRef = ReactuseRef();
let inputRef = ReactuseRef();
let {
groupProps
trackProps
thumbProps
inputProps
labelProps
outputProps
} = useColorSlider(
{
...props
trackRef
inputRef
}
state
);
let {focusProps isFocusVisible} = useFocusRing();
return (
<div
...groupProps
style={
position: 'relative'
display: 'flex'
flexDirection: 'column'
alignItems: 'center'
width: 300
touchAction: 'none'
}>
/* Create a flex container for the label and output element. */
<div style={display: 'flex' alignSelf: 'stretch'}>
propslabel && <label ...labelProps>propslabel</label>
<output ...outputProps style={flex: '1 0 auto' textAlign: 'end'}>
stategetThumbValueLabel(0)
</output>
</div>
/* The track element holds the visible track line and the thumb. */
<div
...trackProps
ref=trackRef
style={
...trackPropsstyle
position: 'relative'
height: TRACK_THICKNESS
width: '100%'
borderRadius: 4
}>
<div
...thumbProps
style={
...thumbPropsstyle
position: 'absolute'
transform: 'translate(-50%, -50%)'
left: `%`
top: TRACK_THICKNESS / 2
border: '2px solid white'
boxShadow: '0 0 0 1px black, inset 0 0 0 1px black'
width: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE
height: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE
borderRadius: '50%'
boxSizing: 'border-box'
background: stategetDisplayColor()toString('css')
}>
<VisuallyHidden>
<input ref=inputRef ...inputProps ...focusProps />
</VisuallyHidden>
</div>
</div>
</div>
);
}
<ColorSlider channel="hue" label="Hue" defaultValue="hsl(0, 100%, 50%)" />import {useColorSliderState} from '@react-stately/color';
import {VisuallyHidden} from '@react-aria/visually-hidden';
import {useNumberFormatter} from '@react-aria/i18n';
import {useFocusRing} from '@react-aria/focus';
const TRACK_THICKNESS = 28;
const THUMB_SIZE = 20;
function ColorSlider(props) {
let numberFormatter = useNumberFormatter({
style: propschannel === 'alpha' ? 'percent' : 'decimal'
});
let state = useColorSliderState({
...props
numberFormatter
});
let trackRef = ReactuseRef();
let inputRef = ReactuseRef();
let {
groupProps
trackProps
thumbProps
inputProps
labelProps
outputProps
} = useColorSlider(
{
...props
trackRef
inputRef
}
state
);
let {focusProps isFocusVisible} = useFocusRing();
return (
<div
...groupProps
style={
position: 'relative'
display: 'flex'
flexDirection: 'column'
alignItems: 'center'
width: 300
touchAction: 'none'
}>
/* Create a flex container for the label and output element. */
<div style={display: 'flex' alignSelf: 'stretch'}>
propslabel && (
<label ...labelProps>propslabel</label>
)
<output
...outputProps
style={flex: '1 0 auto' textAlign: 'end'}>
stategetThumbValueLabel(0)
</output>
</div>
/* The track element holds the visible track line and the thumb. */
<div
...trackProps
ref=trackRef
style={
...trackPropsstyle
position: 'relative'
height: TRACK_THICKNESS
width: '100%'
borderRadius: 4
}>
<div
...thumbProps
style={
...thumbPropsstyle
position: 'absolute'
transform: 'translate(-50%, -50%)'
left: `%`
top: TRACK_THICKNESS / 2
border: '2px solid white'
boxShadow:
'0 0 0 1px black, inset 0 0 0 1px black'
width: isFocusVisible
? TRACK_THICKNESS + 4
: THUMB_SIZE
height: isFocusVisible
? TRACK_THICKNESS + 4
: THUMB_SIZE
borderRadius: '50%'
boxSizing: 'border-box'
background: state
getDisplayColor()
toString('css')
}>
<VisuallyHidden>
<input
ref=inputRef
...inputProps
...focusProps
/>
</VisuallyHidden>
</div>
</div>
</div>
);
}
<ColorSlider
channel="hue"
label="Hue"
defaultValue="hsl(0, 100%, 50%)"
/>import {useColorSliderState} from '@react-stately/color';
import {VisuallyHidden} from '@react-aria/visually-hidden';
import {useNumberFormatter} from '@react-aria/i18n';
import {useFocusRing} from '@react-aria/focus';
const TRACK_THICKNESS = 28;
const THUMB_SIZE = 20;
function ColorSlider(
props
) {
let numberFormatter = useNumberFormatter(
{
style:
propschannel ===
'alpha'
? 'percent'
: 'decimal'
}
);
let state = useColorSliderState(
{
...props
numberFormatter
}
);
let trackRef = ReactuseRef();
let inputRef = ReactuseRef();
let {
groupProps
trackProps
thumbProps
inputProps
labelProps
outputProps
} = useColorSlider(
{
...props
trackRef
inputRef
}
state
);
let {
focusProps
isFocusVisible
} = useFocusRing();
return (
<div
...groupProps
style={
position:
'relative'
display: 'flex'
flexDirection:
'column'
alignItems:
'center'
width: 300
touchAction:
'none'
}>
/* Create a flex container for the label and output element. */
<div
style={
display:
'flex'
alignSelf:
'stretch'
}>
propslabel && (
<label
...labelProps>
propslabel
</label>
)
<output
...outputProps
style={
flex:
'1 0 auto'
textAlign:
'end'
}>
stategetThumbValueLabel(
0
)
</output>
</div>
/* The track element holds the visible track line and the thumb. */
<div
...trackProps
ref=trackRef
style={
...trackPropsstyle
position:
'relative'
height: TRACK_THICKNESS
width: '100%'
borderRadius: 4
}>
<div
...thumbProps
style={
...thumbPropsstyle
position:
'absolute'
transform:
'translate(-50%, -50%)'
left: `%`
top:
TRACK_THICKNESS /
2
border:
'2px solid white'
boxShadow:
'0 0 0 1px black, inset 0 0 0 1px black'
width: isFocusVisible
? TRACK_THICKNESS +
4
: THUMB_SIZE
height: isFocusVisible
? TRACK_THICKNESS +
4
: THUMB_SIZE
borderRadius:
'50%'
boxSizing:
'border-box'
background: state
getDisplayColor()
toString(
'css'
)
}>
<VisuallyHidden>
<input
ref=
inputRef
...inputProps
...focusProps
/>
</VisuallyHidden>
</div>
</div>
</div>
);
}
<ColorSlider
channel="hue"
label="Hue"
defaultValue="hsl(0, 100%, 50%)"
/>Vertical#
function ColorSlider(props) {
let numberFormatter = useNumberFormatter({
style: propschannel === 'alpha' ? 'percent' : 'decimal'
});
let state = useColorSliderState({...props numberFormatter});
let trackRef = ReactuseRef();
let inputRef = ReactuseRef();
let {
groupProps
trackProps
thumbProps
inputProps
labelProps
outputProps
} = useColorSlider(
{
...props
orientation: 'vertical'
trackRef
inputRef
}
state
);
let {focusProps isFocusVisible} = useFocusRing();
return (
<div
...groupProps
style={
height: 200
touchAction: 'none'
}>
<div
...trackProps
ref=trackRef
style={
...trackPropsstyle
position: 'relative'
width: TRACK_THICKNESS
height: '100%'
borderRadius: 4
}>
<div
...thumbProps
style={
...thumbPropsstyle
position: 'absolute'
transform: 'translate(-50%, -50%)'
top: `%`
left: TRACK_THICKNESS / 2
border: '2px solid white'
boxShadow: '0 0 0 1px black, inset 0 0 0 1px black'
width: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE
height: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE
borderRadius: '50%'
boxSizing: 'border-box'
background: stategetDisplayColor()toString('css')
}>
<VisuallyHidden>
<input ref=inputRef ...inputProps ...focusProps />
</VisuallyHidden>
</div>
</div>
</div>
);
}
<ColorSlider
channel="hue"
aria-label="Hue"
defaultValue="hsl(0, 100%, 50%)"
/>function ColorSlider(props) {
let numberFormatter = useNumberFormatter({
style: propschannel === 'alpha' ? 'percent' : 'decimal'
});
let state = useColorSliderState({
...props
numberFormatter
});
let trackRef = ReactuseRef();
let inputRef = ReactuseRef();
let {
groupProps
trackProps
thumbProps
inputProps
labelProps
outputProps
} = useColorSlider(
{
...props
orientation: 'vertical'
trackRef
inputRef
}
state
);
let {focusProps isFocusVisible} = useFocusRing();
return (
<div
...groupProps
style={
height: 200
touchAction: 'none'
}>
<div
...trackProps
ref=trackRef
style={
...trackPropsstyle
position: 'relative'
width: TRACK_THICKNESS
height: '100%'
borderRadius: 4
}>
<div
...thumbProps
style={
...thumbPropsstyle
position: 'absolute'
transform: 'translate(-50%, -50%)'
top: `%`
left: TRACK_THICKNESS / 2
border: '2px solid white'
boxShadow:
'0 0 0 1px black, inset 0 0 0 1px black'
width: isFocusVisible
? TRACK_THICKNESS + 4
: THUMB_SIZE
height: isFocusVisible
? TRACK_THICKNESS + 4
: THUMB_SIZE
borderRadius: '50%'
boxSizing: 'border-box'
background: state
getDisplayColor()
toString('css')
}>
<VisuallyHidden>
<input
ref=inputRef
...inputProps
...focusProps
/>
</VisuallyHidden>
</div>
</div>
</div>
);
}
<ColorSlider
channel="hue"
aria-label="Hue"
defaultValue="hsl(0, 100%, 50%)"
/>function ColorSlider(
props
) {
let numberFormatter = useNumberFormatter(
{
style:
propschannel ===
'alpha'
? 'percent'
: 'decimal'
}
);
let state = useColorSliderState(
{
...props
numberFormatter
}
);
let trackRef = ReactuseRef();
let inputRef = ReactuseRef();
let {
groupProps
trackProps
thumbProps
inputProps
labelProps
outputProps
} = useColorSlider(
{
...props
orientation:
'vertical'
trackRef
inputRef
}
state
);
let {
focusProps
isFocusVisible
} = useFocusRing();
return (
<div
...groupProps
style={
height: 200
touchAction:
'none'
}>
<div
...trackProps
ref=trackRef
style={
...trackPropsstyle
position:
'relative'
width: TRACK_THICKNESS
height: '100%'
borderRadius: 4
}>
<div
...thumbProps
style={
...thumbPropsstyle
position:
'absolute'
transform:
'translate(-50%, -50%)'
top: `%`
left:
TRACK_THICKNESS /
2
border:
'2px solid white'
boxShadow:
'0 0 0 1px black, inset 0 0 0 1px black'
width: isFocusVisible
? TRACK_THICKNESS +
4
: THUMB_SIZE
height: isFocusVisible
? TRACK_THICKNESS +
4
: THUMB_SIZE
borderRadius:
'50%'
boxSizing:
'border-box'
background: state
getDisplayColor()
toString(
'css'
)
}>
<VisuallyHidden>
<input
ref=
inputRef
...inputProps
...focusProps
/>
</VisuallyHidden>
</div>
</div>
</div>
);
}
<ColorSlider
channel="hue"
aria-label="Hue"
defaultValue="hsl(0, 100%, 50%)"
/>Usage#
RGBA#
import {parseColor} from '@react-stately/color';
function Example() {
let [color setColor] = ReactuseState(parseColor('#7f007f'));
return (
<>
<ColorSlider
channel="red"
label="Red"
value=color
onChange=setColor
/>
<ColorSlider
channel="green"
label="Green"
value=color
onChange=setColor
/>
<ColorSlider
channel="blue"
label="Blue"
value=color
onChange=setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=setColor
/>
</>
);
}
import {parseColor} from '@react-stately/color';
function Example() {
let [color setColor] = ReactuseState(
parseColor('#7f007f')
);
return (
<>
<ColorSlider
channel="red"
label="Red"
value=color
onChange=setColor
/>
<ColorSlider
channel="green"
label="Green"
value=color
onChange=setColor
/>
<ColorSlider
channel="blue"
label="Blue"
value=color
onChange=setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=setColor
/>
</>
);
}
import {parseColor} from '@react-stately/color';
function Example() {
let [
color
setColor
] = ReactuseState(
parseColor('#7f007f')
);
return (
<>
<ColorSlider
channel="red"
label="Red"
value=color
onChange=
setColor
/>
<ColorSlider
channel="green"
label="Green"
value=color
onChange=
setColor
/>
<ColorSlider
channel="blue"
label="Blue"
value=color
onChange=
setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=
setColor
/>
</>
);
}
HSLA#
function Example() {
let [color setColor] = ReactuseState(parseColor('hsl(0, 100%, 50%)'));
return (
<>
<ColorSlider
channel="hue"
label="Hue"
value=color
onChange=setColor
/>
<ColorSlider
channel="saturation"
label="Saturation"
value=color
onChange=setColor
/>
<ColorSlider
channel="lightness"
label="Lightness"
value=color
onChange=setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=setColor
/>
</>
);
}
function Example() {
let [color setColor] = ReactuseState(
parseColor('hsl(0, 100%, 50%)')
);
return (
<>
<ColorSlider
channel="hue"
label="Hue"
value=color
onChange=setColor
/>
<ColorSlider
channel="saturation"
label="Saturation"
value=color
onChange=setColor
/>
<ColorSlider
channel="lightness"
label="Lightness"
value=color
onChange=setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=setColor
/>
</>
);
}
function Example() {
let [
color
setColor
] = ReactuseState(
parseColor(
'hsl(0, 100%, 50%)'
)
);
return (
<>
<ColorSlider
channel="hue"
label="Hue"
value=color
onChange=
setColor
/>
<ColorSlider
channel="saturation"
label="Saturation"
value=color
onChange=
setColor
/>
<ColorSlider
channel="lightness"
label="Lightness"
value=color
onChange=
setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=
setColor
/>
</>
);
}
HSBA#
function Example() {
let [color setColor] = ReactuseState(parseColor('hsb(0, 100%, 50%)'));
return (
<>
<ColorSlider
channel="hue"
label="Hue"
value=color
onChange=setColor
/>
<ColorSlider
channel="saturation"
label="Saturation"
value=color
onChange=setColor
/>
<ColorSlider
channel="brightness"
label="Brightness"
value=color
onChange=setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=setColor
/>
</>
);
}
function Example() {
let [color setColor] = ReactuseState(
parseColor('hsb(0, 100%, 50%)')
);
return (
<>
<ColorSlider
channel="hue"
label="Hue"
value=color
onChange=setColor
/>
<ColorSlider
channel="saturation"
label="Saturation"
value=color
onChange=setColor
/>
<ColorSlider
channel="brightness"
label="Brightness"
value=color
onChange=setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=setColor
/>
</>
);
}
function Example() {
let [
color
setColor
] = ReactuseState(
parseColor(
'hsb(0, 100%, 50%)'
)
);
return (
<>
<ColorSlider
channel="hue"
label="Hue"
value=color
onChange=
setColor
/>
<ColorSlider
channel="saturation"
label="Saturation"
value=color
onChange=
setColor
/>
<ColorSlider
channel="brightness"
label="Brightness"
value=color
onChange=
setColor
/>
<ColorSlider
channel="alpha"
label="Alpha"
value=color
onChange=
setColor
/>
</>
);
}