Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Range slider component #793

Closed
wants to merge 25 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

styling improvements

  • Loading branch information...
mikejolley committed Aug 1, 2019
commit 88beed1b143087ff5a3b21cce2437841cf793352
@@ -40,55 +40,67 @@ class PriceSlider extends Component {
onChangeMin() {
const { step, max } = this.state;

let value = this.minRange.current.value;

if ( max <= value ) {
value = max - step;
}

this.setState( {
currentMin: this.minRange.current.value,
currentMax: Math.min( max, Math.max( parseInt( this.minRange.current.value, 10 ) + step, this.maxRange.current.value ) ),
currentMin: value,
currentMax: Math.min( max, Math.max( this.maxRange.current.value, parseInt( value, 10 ) + step ) ),
} );
}

onChangeMax() {
const { step, min } = this.state;

let value = this.maxRange.current.value;

if ( min >= value ) {
value = min + step;
}

this.setState( {
currentMin: Math.max( min, Math.min( this.minRange.current.value, parseInt( this.maxRange.current.value, 10 ) - step ) ),
currentMax: this.maxRange.current.value,
currentMin: Math.max( min, Math.min( this.minRange.current.value, parseInt( value, 10 ) - step ) ),
currentMax: value,
} );
}

onInputMin() {
const { min, max } = this.state;
const { min, max, step } = this.state;

let value = this.minInput.current.value.replace( /[^0-9.-]+/g, '' );

if ( min > value ) {
value = min;
}

if ( max < value ) {
value = max;
if ( max <= value ) {
value = max - step;
}

this.setState( {
currentMin: value ? parseInt( value, 10 ) : '',
currentMax: Math.min( max, Math.max( parseInt( value, 10 ) || 0, this.maxRange.current.value ) ),
currentMax: Math.min( max, Math.max( ( parseInt( value, 10 ) || 0 ) + step, this.maxRange.current.value ) ),
} );
}

onInputMax() {
const { min, max } = this.state;
const { min, max, step } = this.state;

let value = this.maxInput.current.value.replace( /[^0-9.-]+/g, '' );

if ( min > value ) {
value = min;
if ( min >= value ) {
value = min + step;
}

if ( max < value ) {
value = max;
}

this.setState( {
currentMin: Math.max( min, Math.min( this.minRange.current.value, parseInt( value, 10 ) || 0 ) ),
currentMin: Math.max( min, Math.min( ( parseInt( value, 10 ) || 0 ) - step ), this.minRange.current.value ),
currentMax: value ? parseInt( value, 10 ) : '',
} );
}
@@ -114,22 +126,41 @@ class PriceSlider extends Component {
render() {
const { min, max, step, currentMin, currentMax } = this.state;

const minProgress = ( ( currentMin / max ) * 100 );
// eslint-disable-next-line no-mixed-operators
const maxProgress = ( max - ( currentMax / max ) * 100 );
const low = Math.round( 100 * ( ( currentMin - min ) / ( max - min ) ) ) + 0.5;
const high = Math.round( 100 * ( ( currentMax - min ) / ( max - min ) ) ) + 0.5;

return (
<div className="wc-block-price-filter">
<input type="text" onInput={ this.onInputMin } ref={ this.minInput } className="wc-block-price-filter__amount wc-block-price-filter__amount--min" value={ this.formatCurrencyForInput( currentMin ) } size="5" />
<input type="text" onInput={ this.onInputMax } ref={ this.maxInput } className="wc-block-price-filter__amount wc-block-price-filter__amount--max" value={ this.formatCurrencyForInput( currentMax ) } size="5" />
<div className="wc-block-price-filter__range-input-wrapper">
<input type="range" ref={ this.minRange } onChange={ this.onChangeMin } className="wc-block-price-filter__range-input wc-block-price-filter__range-input--min" value={ currentMin ? currentMin : 0 } step={ step } min={ min } max={ max } />
<input type="range" ref={ this.maxRange } onChange={ this.onChangeMax } className="wc-block-price-filter__range-input wc-block-price-filter__range-input--max" value={ currentMax ? currentMax : max } step={ step } min={ min } max={ max } />
<div className="wc-block-price-filter__progress wc-block-price-filter__progress--lower" style={ {
width: 'calc(' + minProgress + '% - 7px ',
} } />
<div className="wc-block-price-filter__progress wc-block-price-filter__progress--upper" style={ {
width: 'calc(' + maxProgress + '% - 7px ',
} } />
<div className="wc-block-price-filter__range-input-progress" style={
{
'--low': low + '%',
'--high': high + '%',
}
} />
<input
type="range"
className="wc-block-price-filter__range-input wc-block-price-filter__range-input--min"
ref={ this.minRange }
onChange={ this.onChangeMin }
value={ currentMin ? currentMin : 0 }
step={ step }
min={ min }
max={ max }
/>
<input
type="range"
className="wc-block-price-filter__range-input wc-block-price-filter__range-input--max"
ref={ this.maxRange }
onMouseDown={ this.onMouseOver }
onChange={ this.onChangeMax }
value={ currentMax ? currentMax : max }
step={ step }
min={ min }
max={ max }
/>
</div>
</div>
);
@@ -1,8 +1,6 @@
/* stylelint-disable */
@mixin thumb {
background-color: transparent;
/* stylelint-disable */
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='52' height='42'%3E%3Cdefs%3E%3Cpath id='a' d='M23.3176 7.9423l-8.4163-6.1432C13.1953.5706 11.2618-.0997 9.2146.0121h-.1137C4.2103.347.1159 4.368.0022 9.2827-.1115 14.644 4.2102 19 9.6696 19h.1137c1.8197 0 3.6395-.6702 5.118-1.787l8.4163-6.255c.9099-.8935.9099-2.2338 0-3.0157z'/%3E%3Cpath id='b' d='M23.3176 7.9423l-8.4163-6.1432C13.1953.5706 11.2618-.0997 9.2146.0121h-.1137C4.2103.347.1159 4.368.0022 9.2827-.1115 14.644 4.2102 19 9.6696 19h.1137c1.8197 0 3.6395-.6702 5.118-1.787l8.4163-6.255c.9099-.8935.9099-2.2338 0-3.0157z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%23FFF' fill-rule='nonzero' stroke='%2395588A' d='M24.3176 8.9423l-8.4163-6.1432c-1.706-1.2285-3.6395-1.8988-5.6867-1.787h-.1137c-4.8906.335-8.985 4.356-9.0987 9.2706C.8885 15.644 5.2102 20 10.6696 20h.1137c1.8197 0 3.6395-.6702 5.118-1.787l8.4163-6.255c.9099-.8935.9099-2.2338 0-3.0157z'/%3E%3Cpath stroke='%23B8B8B8' d='M9 6v9m3-9v9'/%3E%3Cg fill-rule='nonzero' transform='translate(1 22)'%3E%3Cuse fill='%23F8F3F7' stroke='%23FFF' stroke-opacity='.75' stroke-width='3' xlink:href='%23a'/%3E%3Cuse stroke='%2395588A' xlink:href='%23a'/%3E%3C/g%3E%3Cpath stroke='%2395588A' d='M9 27v9m3-9v9'/%3E%3Cg%3E%3Cpath fill='%23FFF' fill-rule='nonzero' stroke='%2395588A' d='M27.6824 8.9423l8.4163-6.1432c1.706-1.2285 3.6395-1.8988 5.6867-1.787h.1137c4.8906.335 8.985 4.356 9.0987 9.2706C51.1115 15.644 46.7898 20 41.3304 20h-.1137c-1.8197 0-3.6395-.6702-5.118-1.787l-8.4163-6.255c-.9099-.8935-.9099-2.2338 0-3.0157z'/%3E%3Cpath stroke='%23B8B8B8' d='M43 6v9m-3-9v9'/%3E%3C/g%3E%3Cg%3E%3Cg fill-rule='nonzero' transform='matrix(-1 0 0 1 51 22)'%3E%3Cuse fill='%23F8F3F7' stroke='%23FFF' stroke-opacity='.75' stroke-width='3' xlink:href='%23b'/%3E%3Cuse stroke='%2395588A' xlink:href='%23b'/%3E%3C/g%3E%3Cpath stroke='%2395588A' d='M43 27v9m-3-9v9'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
/* stylelint-enable */
background-position: 0 0;
width: 26px;
height: 21px;
@@ -13,18 +11,36 @@
cursor: pointer;
z-index: 20;
pointer-events: auto;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='52' height='42'%3E%3Cdefs%3E%3Cpath id='a' d='M23.3176 7.9423l-8.4163-6.1432C13.1953.5706 11.2618-.0997 9.2146.0121h-.1137C4.2103.347.1159 4.368.0022 9.2827-.1115 14.644 4.2102 19 9.6696 19h.1137c1.8197 0 3.6395-.6702 5.118-1.787l8.4163-6.255c.9099-.8935.9099-2.2338 0-3.0157z'/%3E%3Cpath id='b' d='M23.3176 7.9423l-8.4163-6.1432C13.1953.5706 11.2618-.0997 9.2146.0121h-.1137C4.2103.347.1159 4.368.0022 9.2827-.1115 14.644 4.2102 19 9.6696 19h.1137c1.8197 0 3.6395-.6702 5.118-1.787l8.4163-6.255c.9099-.8935.9099-2.2338 0-3.0157z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%23FFF' fill-rule='nonzero' stroke='%2395588A' d='M24.3176 8.9423l-8.4163-6.1432c-1.706-1.2285-3.6395-1.8988-5.6867-1.787h-.1137c-4.8906.335-8.985 4.356-9.0987 9.2706C.8885 15.644 5.2102 20 10.6696 20h.1137c1.8197 0 3.6395-.6702 5.118-1.787l8.4163-6.255c.9099-.8935.9099-2.2338 0-3.0157z'/%3E%3Cpath stroke='%23B8B8B8' d='M9 6v9m3-9v9'/%3E%3Cg fill-rule='nonzero' transform='translate(1 22)'%3E%3Cuse fill='%23F8F3F7' stroke='%23FFF' stroke-opacity='.75' stroke-width='3' xlink:href='%23a'/%3E%3Cuse stroke='%2395588A' xlink:href='%23a'/%3E%3C/g%3E%3Cpath stroke='%2395588A' d='M9 27v9m3-9v9'/%3E%3Cg%3E%3Cpath fill='%23FFF' fill-rule='nonzero' stroke='%2395588A' d='M27.6824 8.9423l8.4163-6.1432c1.706-1.2285 3.6395-1.8988 5.6867-1.787h.1137c4.8906.335 8.985 4.356 9.0987 9.2706C51.1115 15.644 46.7898 20 41.3304 20h-.1137c-1.8197 0-3.6395-.6702-5.118-1.787l-8.4163-6.255c-.9099-.8935-.9099-2.2338 0-3.0157z'/%3E%3Cpath stroke='%23B8B8B8' d='M43 6v9m-3-9v9'/%3E%3C/g%3E%3Cg%3E%3Cg fill-rule='nonzero' transform='matrix(-1 0 0 1 51 22)'%3E%3Cuse fill='%23F8F3F7' stroke='%23FFF' stroke-opacity='.75' stroke-width='3' xlink:href='%23b'/%3E%3Cuse stroke='%2395588A' xlink:href='%23b'/%3E%3C/g%3E%3Cpath stroke='%2395588A' d='M43 27v9m-3-9v9'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
transition: transform .2s ease-in-out;

&:hover,
&:active {
background-position-y: -21px;
filter: drop-shadow( 3px 0 0 rgba( 255, 255, 255, .75 ) ) drop-shadow( -3px 0 0 rgba( 255, 255, 255, .75 ) );
&:hover {
@include thumbFocus;
transform: scale(1.1);
}
}

@mixin thumbFocus {
background-position-y: -21px;
filter: drop-shadow(3px 0 0 rgba(255, 255, 255, .75)) drop-shadow(-3px 0 0 rgba(255, 255, 255, .75));
}
/* stylelint-enable */
@mixin track {
cursor: default;
height: 0;
outline: 0;
-webkit-appearance: none;
-moz-appearance: none;
}
@mixin reset {
margin: 0;
padding: 0;
border: 0;
outline: none;
background: transparent;
-webkit-appearance: none;
-moz-appearance: none;
}

.wc-block-price-filter {
@@ -41,49 +57,36 @@
}
}
.wc-block-price-filter__range-input-wrapper {
background: #a8739d;
box-shadow: 0 0 0 1px inset #95588a;
@include reset;
height: 9px;
padding: 0;
clear: both;
position: relative;
}
.wc-block-price-filter__progress {
box-shadow: 0 0 0 1px inset rgba(0, 0, 0, 0.1);
background: #e1e1e1;
box-shadow: 0 0 0 1px inset #b8b8b8;
border-radius: 2px;
height: 9px;
padding: 0;
position: absolute;
z-index: 5;

&.wc-block-price-filter__progress--lower {
.wc-block-price-filter__range-input-progress {
height: 9px;
width: 100%;
position: absolute;
left: 0;
}
&.wc-block-price-filter__progress--upper {
right: 0;
top: 0;
--track-background: linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0) no-repeat 0 100% / 100% 100%;
--range-color: #a8739d;
background: var(--track-background);
}
}
.wc-block-price-filter__range-input {
@include reset;
width: 100%;
height: 0;
border: 0;
margin: 0;
padding: 0;
background: transparent;
-webkit-appearance: none;
-moz-appearance: none;
display: block;
outline: none !important;
position: relative;
pointer-events: none;
outline: none !important;

&::-webkit-slider-runnable-track {
-webkit-appearance: none;
@include track;
}
&::-webkit-slider-thumb {
-webkit-appearance: none;
@include thumb;
margin: -6px 0 0 0;
}
@@ -96,26 +99,39 @@
border: 0;
}
&::-moz-range-track {
-moz-appearance: none;
@include track;
}
&::-moz-range-progress {
-moz-appearance: none;
background: transparent;
@include reset;
}
&::-moz-range-thumb {
-moz-appearance: none;
@include thumb;
}

&::-ms-thumb {
@include thumb;
}

&:focus {
&::-webkit-slider-thumb {
@include thumbFocus;
}
&::-moz-range-thumb {
@include thumbFocus;
}
&::-ms-thumb {
@include thumbFocus;
}
}

&.wc-block-price-filter__range-input--min {
z-index: 15;

&::-webkit-slider-thumb {
margin-left: -7px;
margin-left: -2px;
}
&::-moz-range-thumb {
transform: translate( -7px, 4px );
transform: translate(-2px, 4px);
}
}

@@ -124,30 +140,35 @@

&::-webkit-slider-thumb {
background-position-x: 26px;
margin-left: 7px;
margin-left: 2px;
}
&::-moz-range-thumb {
background-position-x: 26px;
transform: translate( 7px, 4px );
transform: translate(2px, 4px);
}
&::-ms-thumb {
background-position-x: 26px;
}
}
}
}

/* IE 11 will not support multi-range slider due to poor pointer-events support on the thumb. Reverts to 2 sliders. */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
@mixin ie {
.wc-block-price-filter {
.wc-block-price-filter__progress {
display: none;
}
.wc-block-price-filter__range-input-wrapper {
background: transparent;
box-shadow: none;
height: 48px;
height: 24px;
.wc-block-price-filter__range-input-progress {
display: none;
}
}
.wc-block-price-filter__range-input {
height: 24px;
pointer-events: auto;
position: absolute;
left: 0;
top: 0;

&::-ms-track {
/*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
@@ -165,16 +186,15 @@
box-shadow: 0 0 0 1px inset #b8b8b8;
}
&::-ms-fill-upper {
background: #a8739d;
box-shadow: 0 0 0 1px inset #95588a;
}
&::-ms-thumb {
@include thumb;
pointer-events: auto;
background: transparent;
}
&::-ms-tooltip {
display: none;
}
&::-ms-thumb {
transform: translate(1px, 0);
pointer-events: auto;
}
}
.wc-block-price-filter__range-input--max {
&::-ms-fill-upper {
@@ -185,9 +205,14 @@
background: #a8739d;
box-shadow: 0 0 0 1px inset #95588a;
}
&::-ms-thumb {
background-position-x: 26px;
}
}
}
}

/* IE 11 will not support multi-range slider due to poor pointer-events support on the thumb. Reverts to 2 sliders. */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
@include ie;
}
@supports (-ms-ime-align:auto) {
@include ie;
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.