diff --git a/dist/react-input-range-beyondadmin.css b/dist/react-input-range-beyondadmin.css
new file mode 100644
index 0000000..2e9afec
--- /dev/null
+++ b/dist/react-input-range-beyondadmin.css
@@ -0,0 +1,112 @@
+.InputRange {
+ height: 16px;
+ border: 1px solid #6c6c6c;
+ background-color: #ffffff;
+}
+
+.InputRange-track--container {
+ top: 3px;
+ left: 1px;
+ background-color: #ffffff;
+}
+
+.InputRange-track {
+ height: 14px;
+}
+
+.InputRange-track--active {
+ background-color: #57b5e3;
+ border-radius: 0;
+}
+
+.InputRange-label {
+ font-size: 13px;
+ color: #3f3f3f;
+}
+
+.InputRange-slider {
+ top: 7px;
+ margin-top: 0;
+ height: 20px;
+ background-color: #F55F51;
+ border: 0;
+ border-radius: 0;
+ width: 40px;
+ margin-left: -20px;
+}
+
+.InputRange-label--value {
+ top: -1px;
+ margin-left: -8px;
+ position: absolute;
+ display: block;
+ border-left: 8px solid transparent;
+ border-right: 8px solid transparent;
+ border-bottom: 8px solid #fb6e52;
+}
+
+.InputRange-label--value .InputRange-labelContainer {
+ padding-top: 2px;
+ top: 8px;
+ z-index: 50;
+ left: -20px;
+ color: #ffffff;
+ width: 40px;
+ height: 18px;
+ position: absolute;
+ text-align: center;
+ background-color: #fb6e52;
+}
+
+.InputRange-sliderContainer a {
+ z-index: 100;
+ background-color: transparent;
+}
+
+/*
+* vertical styles
+*/
+
+.InputRange.vertical {
+ width: 16px;
+}
+
+.vertical .InputRange-track--container {
+ margin-bottom: 1px;
+ margin-left: 0;
+ left: 1px;
+ width: 14px;
+}
+
+.vertical .InputRange-label--value {
+ top: -6px;
+ margin-left: -18px;
+ position: absolute;
+ display: block;
+ z-index: 50;
+ border-right: 6px solid #fb6e52;
+ border-top: 6px solid transparent;
+ border-bottom: 6px solid transparent;
+}
+
+.vertical .InputRange-label--value .InputRange-labelContainer {
+ top: -10px;
+ left: 6px;
+ padding: 2px 5px 0 5px;
+ width: auto;
+}
+
+.vertical .InputRange-slider {
+ top: -10px;
+ left: 24px;
+}
+
+.vertical .InputRange-label--max {
+ right: -14px;
+ top: -10px;
+}
+
+.vertical .InputRange-label--min {
+ left: 28px;
+ bottom: -10px;
+}
\ No newline at end of file
diff --git a/dist/react-input-range.css b/dist/react-input-range.css
index 6efc526..b7361be 100644
--- a/dist/react-input-range.css
+++ b/dist/react-input-range.css
@@ -83,3 +83,40 @@
height: 1rem;
position: relative;
width: 100%; }
+
+/*
+ styles for vertical slider
+*/
+.InputRange.vertical {
+ height: 100%;
+ width: 1rem;
+ min-height: 200px;
+}
+
+.vertical .InputRange-track--container {
+ margin-top: 0;
+ top: 0;
+ bottom: 0;
+ left: 50%;
+ margin-left: -0.15rem;
+ height: 100%;
+}
+
+.vertical .InputRange-slider {
+ margin-left: -0.25rem;
+}
+
+.vertical .InputRange-label--min {
+ bottom: 0;
+ left: 1.75rem;
+}
+
+.vertical .InputRange-label--max {
+ right: -0.5rem;
+ top: 0;
+}
+
+.vertical .InputRange-label--value {
+ left: 1.5rem;
+ top: -0.5rem;
+}
diff --git a/dist/react-input-range.min.css b/dist/react-input-range.min.css
index 6933731..56b88f1 100644
--- a/dist/react-input-range.min.css
+++ b/dist/react-input-range.min.css
@@ -1 +1 @@
-.InputRange-slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#3f51b5;border:1px solid #3f51b5;border-radius:100%;cursor:pointer;display:block;height:1rem;margin-left:-.5rem;margin-top:-.65rem;outline:0;position:absolute;top:50%;transition:-webkit-transform .3s ease-out,box-shadow .3s ease-out;transition:transform .3s ease-out,box-shadow .3s ease-out;width:1rem}.InputRange-slider:active{-webkit-transform:scale(1.3);transform:scale(1.3)}.InputRange-slider:focus{box-shadow:0 0 0 5px rgba(63,81,181,.2)}.InputRange.is-disabled .InputRange-slider{background:#ccc;border:1px solid #ccc;box-shadow:none;-webkit-transform:none;transform:none}.InputRange-sliderContainer{transition:left .3s ease-out}.InputRange-label{color:#aaa;font-family:"Helvetica Neue",san-serif;font-size:.8rem;white-space:nowrap}.InputRange-label--max,.InputRange-label--min{bottom:-1.4rem;position:absolute}.InputRange-label--min{left:0}.InputRange-label--max{right:0}.InputRange-label--value{position:absolute;top:-1.8rem}.InputRange-labelContainer{left:-50%;position:relative}.InputRange-label--max .InputRange-labelContainer{left:50%}.InputRange-track{background:#eee;border-radius:.3rem;display:block;height:.3rem;position:relative;transition:left .3s ease-out,width .3s ease-out}.InputRange.is-disabled .InputRange-track{background:#eee}.InputRange-track--container{left:0;margin-top:-.15rem;position:absolute;right:0;top:50%}.InputRange-track--active{background:#3f51b5}.InputRange{cursor:pointer;height:1rem;position:relative;width:100%}
\ No newline at end of file
+.InputRange-slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#3f51b5;border:1px solid #3f51b5;border-radius:100%;cursor:pointer;display:block;height:1rem;margin-left:-.5rem;margin-top:-.65rem;outline:0;position:absolute;top:50%;transition:-webkit-transform .3s ease-out,box-shadow .3s ease-out;transition:transform .3s ease-out,box-shadow .3s ease-out;width:1rem}.InputRange-slider:active{-webkit-transform:scale(1.3);transform:scale(1.3)}.InputRange-slider:focus{box-shadow:0 0 0 5px rgba(63,81,181,.2)}.InputRange.is-disabled .InputRange-slider{background:#ccc;border:1px solid #ccc;box-shadow:none;-webkit-transform:none;transform:none}.InputRange-sliderContainer{transition:left .3s ease-out}.InputRange-label{color:#aaa;font-family:"Helvetica Neue",san-serif;font-size:.8rem;white-space:nowrap}.InputRange-label--max,.InputRange-label--min{bottom:-1.4rem;position:absolute}.InputRange-label--min{left:0}.InputRange-label--max{right:0}.InputRange-label--value{position:absolute;top:-1.8rem}.InputRange-labelContainer{left:-50%;position:relative}.InputRange-label--max .InputRange-labelContainer{left:50%}.InputRange-track{background:#eee;border-radius:.3rem;display:block;height:.3rem;position:relative;transition:left .3s ease-out,width .3s ease-out}.InputRange.is-disabled .InputRange-track{background:#eee}.InputRange-track--container{left:0;margin-top:-.15rem;position:absolute;right:0;top:50%}.InputRange-track--active{background:#3f51b5}.InputRange{cursor:pointer;height:1rem;position:relative;width:100%}.InputRange.vertical{height:100%;width:1rem;min-height:200px}.vertical .InputRange-track--container{margin-top:0;top:0;bottom:0;left:50%;margin-left:-.15rem;height:100%}.vertical .InputRange-slider{margin-left:-.25rem}.vertical .InputRange-label--min{bottom:0;left:1.75rem}.vertical .InputRange-label--max{right:-.5rem;top:0}.vertical .InputRange-label--value{left:1.5rem;top:-.5rem}
\ No newline at end of file
diff --git a/scss/InputRange.scss b/scss/InputRange.scss
index fd5b0c4..c7f3882 100644
--- a/scss/InputRange.scss
+++ b/scss/InputRange.scss
@@ -10,3 +10,9 @@
position: relative;
width: 100%;
}
+
+.InputRange.vertical {
+ height: 100%;
+ width: $InputRange-slider-height;
+ min-height: 200px;
+}
\ No newline at end of file
diff --git a/scss/_InputRangeLabel.scss b/scss/_InputRangeLabel.scss
index 9882416..9069630 100644
--- a/scss/_InputRangeLabel.scss
+++ b/scss/_InputRangeLabel.scss
@@ -23,3 +23,18 @@
position: absolute;
top: -1.8rem;
}
+
+.vertical .InputRange-label--min {
+ bottom: 0;
+ left: 1.75rem;
+}
+
+.vertical .InputRange-label--max {
+ right: -0.5rem;
+ top: 0;
+}
+
+.vertical .InputRange-label--value {
+ left: 1.5rem;
+ top: -0.5rem;
+}
\ No newline at end of file
diff --git a/scss/_InputRangeSlider.scss b/scss/_InputRangeSlider.scss
index fefc15d..a7a031e 100644
--- a/scss/_InputRangeSlider.scss
+++ b/scss/_InputRangeSlider.scss
@@ -33,3 +33,7 @@
.InputRange-sliderContainer {
transition: $InputRange-sliderContainer-transition;
}
+
+.vertical .InputRange-slider {
+ margin-left: $InputRange-slider-width / -4;
+}
\ No newline at end of file
diff --git a/scss/_InputRangeTrack.scss b/scss/_InputRangeTrack.scss
index 568ccd1..84dde84 100644
--- a/scss/_InputRangeTrack.scss
+++ b/scss/_InputRangeTrack.scss
@@ -22,3 +22,12 @@
.InputRange-track--active {
background: $InputRange-track--active-background;
}
+
+.vertical .InputRange-track--container {
+ margin-top: 0;
+ top: 0;
+ bottom: 0;
+ left: 50%;
+ margin-left: -0.5 * $InputRange-track-height;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/src/InputRange/InputRange.js b/src/InputRange/InputRange.js
index 0171d0f..00d28e1 100644
--- a/src/InputRange/InputRange.js
+++ b/src/InputRange/InputRange.js
@@ -97,11 +97,16 @@ function getDocument(inputRange) {
function getComponentClassName(inputRange) {
const { props } = inputRange;
+ let verticalClass = '';
+ if (props.orientation === 'vertical') {
+ verticalClass = ' vertical';
+ }
+
if (!props.disabled) {
- return props.classNames.component;
+ return props.classNames.component + verticalClass;
}
- return `${props.classNames.component} is-disabled`;
+ return `${props.classNames.component} is-disabled ${verticalClass}`;
}
/**
@@ -196,7 +201,8 @@ function renderSliders(inputRange) {
percentage={ percentage }
ref={ ref }
type={ key }
- value={ value } />
+ value={ value }
+ orientation={ inputRange.props.orientation }/>
);
sliders.push(slider);
@@ -444,7 +450,6 @@ export default class InputRange extends React.Component {
event.preventDefault();
const key = getKeyByPosition(this, position);
-
this.updatePosition(key, position);
}
@@ -566,7 +571,8 @@ export default class InputRange extends React.Component {
@@ -574,7 +580,8 @@ export default class InputRange extends React.Component {
classNames={ classNames }
ref="track"
percentages={ percentages }
- onTrackMouseDown={ this.handleTrackMouseDown }>
+ onTrackMouseDown={ this.handleTrackMouseDown }
+ orientation={this.props.orientation}>
{ renderSliders(this) }
@@ -582,7 +589,8 @@ export default class InputRange extends React.Component {
@@ -610,6 +618,7 @@ export default class InputRange extends React.Component {
* @property {Function} onChangeComplete
* @property {Function} step
* @property {Function} value
+ * @property {Function} orientation
*/
InputRange.propTypes = {
ariaLabelledby: React.PropTypes.string,
@@ -627,6 +636,7 @@ InputRange.propTypes = {
onChangeComplete: React.PropTypes.func,
step: React.PropTypes.number,
value: maxMinValuePropType,
+ orientation: React.PropTypes.string,
};
/**
@@ -641,6 +651,7 @@ InputRange.propTypes = {
* @property {number} minValue
* @property {number} step
* @property {Range|number} value
+ * @property {string} orientation
*/
InputRange.defaultProps = {
classNames: defaultClassNames,
@@ -652,4 +663,5 @@ InputRange.defaultProps = {
minValue: 0,
step: 1,
value: null,
+ orientation: 'horizontal',
};
diff --git a/src/InputRange/Slider.js b/src/InputRange/Slider.js
index 86d2c75..9ff5abb 100644
--- a/src/InputRange/Slider.js
+++ b/src/InputRange/Slider.js
@@ -26,6 +26,16 @@ function getDocument(slider) {
*/
function getStyle(slider) {
const perc = (slider.props.percentage || 0) * 100;
+
+ if (slider.props.orientation === 'vertical') {
+ const style = {
+ position: 'absolute',
+ bottom: `${perc}%`,
+ };
+
+ return style;
+ }
+
const style = {
position: 'absolute',
left: `${perc}%`,
@@ -193,6 +203,7 @@ export default class Slider extends React.Component {
* @property {Function} percentage
* @property {Function} type
* @property {Function} value
+ * @property {Function} orientation
*/
Slider.propTypes = {
ariaLabelledby: React.PropTypes.string,
@@ -206,4 +217,5 @@ Slider.propTypes = {
percentage: React.PropTypes.number.isRequired,
type: React.PropTypes.string.isRequired,
value: React.PropTypes.number.isRequired,
+ orientation: React.PropTypes.string,
};
diff --git a/src/InputRange/Track.js b/src/InputRange/Track.js
index 80e565a..9f752c2 100644
--- a/src/InputRange/Track.js
+++ b/src/InputRange/Track.js
@@ -13,6 +13,19 @@ import { autobind } from './util';
*/
function getActiveTrackStyle(track) {
const { props } = track;
+
+ if ( props.orientation === 'vertical' ) {
+ const height = `${(props.percentages.max - props.percentages.min) * 100}%`;
+ const top = `${100 - (props.percentages.max * 100)}%`;
+
+ const activeTrackStyle = {
+ top,
+ height,
+ };
+
+ return activeTrackStyle;
+ }
+
const width = `${(props.percentages.max - props.percentages.min) * 100}%`;
const left = `${props.percentages.min * 100}%`;
@@ -57,13 +70,24 @@ export default class Track extends React.Component {
* @param {SyntheticEvent} event - User event
*/
handleMouseDown(event) {
- const trackClientRect = this.clientRect;
+ let trackClientRect = this.clientRect;
const { clientX } = event.touches ? event.touches[0] : event;
- const position = {
+
+ let position = {
x: clientX - trackClientRect.left,
y: 0,
};
+ if (this.props.orientation === 'vertical') {
+ trackClientRect = this.clientRect;
+ const { clientY } = event.touches ? event.touches[0] : event;
+
+ position = {
+ x: 0,
+ y: trackClientRect.bottom - clientY,
+ };
+ }
+
this.props.onTrackMouseDown(event, this, position);
}
@@ -108,10 +132,12 @@ export default class Track extends React.Component {
* @property {Function} classNames
* @property {Function} onTrackMouseDown
* @property {Function} percentages
+ * @property {Function} orientation
*/
Track.propTypes = {
children: React.PropTypes.node,
classNames: React.PropTypes.objectOf(React.PropTypes.string),
onTrackMouseDown: React.PropTypes.func.isRequired,
percentages: React.PropTypes.objectOf(React.PropTypes.number).isRequired,
+ orientation: React.PropTypes.string,
};
diff --git a/src/InputRange/valueTransformer.js b/src/InputRange/valueTransformer.js
index 487baf9..a79b15c 100644
--- a/src/InputRange/valueTransformer.js
+++ b/src/InputRange/valueTransformer.js
@@ -12,6 +12,13 @@ import { clamp, isEmpty, isNumber, objectOf } from './util';
* @return {number} Percentage value
*/
function percentageFromPosition(inputRange, position) {
+ if (inputRange.props.orientation === 'vertical') {
+ const length = inputRange.trackClientRect.height;
+ const sizePerc = position.y / length;
+
+ return sizePerc || 0;
+ }
+
const length = inputRange.trackClientRect.width;
const sizePerc = position.x / length;
@@ -98,6 +105,17 @@ function percentagesFromValues(inputRange, values) {
* @return {Point} Position
*/
function positionFromValue(inputRange, value) {
+ if (inputRange.props.orientation === 'vertical') {
+ const length = inputRange.trackClientRect.height;
+ const valuePerc = percentageFromValue(inputRange, value);
+ const positionValue = valuePerc * length;
+
+ return {
+ x: 0,
+ y: positionValue,
+ };
+ }
+
const length = inputRange.trackClientRect.width;
const valuePerc = percentageFromValue(inputRange, value);
const positionValue = valuePerc * length;
@@ -132,6 +150,19 @@ function positionsFromValues(inputRange, values) {
* @return {Point}
*/
function positionFromEvent(inputRange, event) {
+ if (inputRange.props.orientation === 'vertical') {
+ const trackClientRect = inputRange.trackClientRect;
+ const length = trackClientRect.height;
+ const { clientY } = event.touches ? event.touches[0] : event;
+
+ const position = {
+ x: 0,
+ y: clamp(trackClientRect.bottom - clientY, 0, length),
+ };
+
+ return position;
+ }
+
const trackClientRect = inputRange.trackClientRect;
const length = trackClientRect.width;
const { clientX } = event.touches ? event.touches[0] : event;