You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Slider.js 29 KiB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _extends2 = require('babel-runtime/helpers/extends');
  6. var _extends3 = _interopRequireDefault(_extends2);
  7. var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
  8. var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
  9. var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
  10. var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
  11. var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
  12. var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
  13. var _createClass2 = require('babel-runtime/helpers/createClass');
  14. var _createClass3 = _interopRequireDefault(_createClass2);
  15. var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
  16. var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
  17. var _inherits2 = require('babel-runtime/helpers/inherits');
  18. var _inherits3 = _interopRequireDefault(_inherits2);
  19. var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
  20. var _defineProperty3 = _interopRequireDefault(_defineProperty2);
  21. var _simpleAssign = require('simple-assign');
  22. var _simpleAssign2 = _interopRequireDefault(_simpleAssign);
  23. var _react = require('react');
  24. var _react2 = _interopRequireDefault(_react);
  25. var _propTypes = require('prop-types');
  26. var _propTypes2 = _interopRequireDefault(_propTypes);
  27. var _keycode = require('keycode');
  28. var _keycode2 = _interopRequireDefault(_keycode);
  29. var _warning = require('warning');
  30. var _warning2 = _interopRequireDefault(_warning);
  31. var _transitions = require('../styles/transitions');
  32. var _transitions2 = _interopRequireDefault(_transitions);
  33. var _FocusRipple = require('../internal/FocusRipple');
  34. var _FocusRipple2 = _interopRequireDefault(_FocusRipple);
  35. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  36. /**
  37. * Verifies min/max range.
  38. * @param {Object} props Properties of the React component.
  39. * @param {String} propName Name of the property to validate.
  40. * @param {String} componentName Name of the component whose property is being validated.
  41. * @returns {Object} Returns an Error if min >= max otherwise null.
  42. */
  43. var minMaxPropType = function minMaxPropType(props, propName, componentName) {
  44. for (var _len = arguments.length, rest = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
  45. rest[_key - 3] = arguments[_key];
  46. }
  47. var error = _propTypes2.default.number.apply(_propTypes2.default, [props, propName, componentName].concat(rest));
  48. if (error !== null) {
  49. return error;
  50. }
  51. if (props.min >= props.max) {
  52. var errorMsg = propName === 'min' ? 'min should be less than max' : 'max should be greater than min';
  53. return new Error(errorMsg);
  54. }
  55. };
  56. /**
  57. * Verifies value is within the min/max range.
  58. * @param {Object} props Properties of the React component.
  59. * @param {String} propName Name of the property to validate.
  60. * @param {String} componentName Name of the component whose property is being validated.
  61. * @returns {Object} Returns an Error if the value is not within the range otherwise null.
  62. */
  63. var valueInRangePropType = function valueInRangePropType(props, propName, componentName) {
  64. for (var _len2 = arguments.length, rest = Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
  65. rest[_key2 - 3] = arguments[_key2];
  66. }
  67. var error = _propTypes2.default.number.apply(_propTypes2.default, [props, propName, componentName].concat(rest));
  68. if (error !== null) {
  69. return error;
  70. }
  71. var value = props[propName];
  72. if (value < props.min || props.max < value) {
  73. return new Error(propName + ' should be within the range specified by min and max');
  74. }
  75. };
  76. var crossAxisProperty = {
  77. x: 'height',
  78. 'x-reverse': 'height',
  79. y: 'width',
  80. 'y-reverse': 'width'
  81. };
  82. var crossAxisOffsetProperty = {
  83. x: 'top',
  84. 'x-reverse': 'top',
  85. y: 'left',
  86. 'y-reverse': 'left'
  87. };
  88. var mainAxisProperty = {
  89. x: 'width',
  90. 'x-reverse': 'width',
  91. y: 'height',
  92. 'y-reverse': 'height'
  93. };
  94. var mainAxisMarginFromEnd = {
  95. x: 'marginRight',
  96. 'x-reverse': 'marginLeft',
  97. y: 'marginTop',
  98. 'y-reverse': 'marginBottom'
  99. };
  100. var mainAxisMarginFromStart = {
  101. x: 'marginLeft',
  102. 'x-reverse': 'marginRight',
  103. y: 'marginBottom',
  104. 'y-reverse': 'marginTop'
  105. };
  106. var mainAxisOffsetProperty = {
  107. x: 'left',
  108. 'x-reverse': 'right',
  109. y: 'bottom',
  110. 'y-reverse': 'top'
  111. };
  112. var mainAxisClientProperty = {
  113. x: 'clientWidth',
  114. 'x-reverse': 'clientWidth',
  115. y: 'clientHeight',
  116. 'y-reverse': 'clientHeight'
  117. };
  118. var mainAxisClientOffsetProperty = {
  119. x: 'clientX',
  120. 'x-reverse': 'clientX',
  121. y: 'clientY',
  122. 'y-reverse': 'clientY'
  123. };
  124. var reverseMainAxisOffsetProperty = {
  125. x: 'right',
  126. 'x-reverse': 'left',
  127. y: 'top',
  128. 'y-reverse': 'bottom'
  129. };
  130. var isMouseControlInverted = function isMouseControlInverted(axis) {
  131. return axis === 'x-reverse' || axis === 'y';
  132. };
  133. var calculateAxis = function calculateAxis(axis, isRtl) {
  134. if (isRtl) {
  135. switch (axis) {
  136. case 'x':
  137. return 'x-reverse';
  138. case 'x-reverse':
  139. return 'x';
  140. }
  141. }
  142. return axis;
  143. };
  144. function getPercent(value, min, max) {
  145. var percent = (value - min) / (max - min);
  146. if (isNaN(percent)) {
  147. percent = 0;
  148. }
  149. return percent;
  150. }
  151. var getStyles = function getStyles(props, context, state) {
  152. var _slider, _track, _filledAndRemaining, _handle, _objectAssign2, _objectAssign3;
  153. var axis = props.axis,
  154. disabled = props.disabled,
  155. max = props.max,
  156. min = props.min;
  157. var _context$muiTheme = context.muiTheme,
  158. isRtl = _context$muiTheme.isRtl,
  159. _context$muiTheme$sli = _context$muiTheme.slider,
  160. handleColorZero = _context$muiTheme$sli.handleColorZero,
  161. handleFillColor = _context$muiTheme$sli.handleFillColor,
  162. handleSize = _context$muiTheme$sli.handleSize,
  163. handleSizeDisabled = _context$muiTheme$sli.handleSizeDisabled,
  164. handleSizeActive = _context$muiTheme$sli.handleSizeActive,
  165. trackSize = _context$muiTheme$sli.trackSize,
  166. trackColor = _context$muiTheme$sli.trackColor,
  167. trackColorSelected = _context$muiTheme$sli.trackColorSelected,
  168. rippleColor = _context$muiTheme$sli.rippleColor,
  169. selectionColor = _context$muiTheme$sli.selectionColor;
  170. var fillGutter = handleSize / 2;
  171. var disabledGutter = trackSize + handleSizeDisabled / 2;
  172. var calcDisabledSpacing = disabled ? ' - ' + disabledGutter + 'px' : '';
  173. var percent = getPercent(state.value, min, max);
  174. var calculatedAxis = calculateAxis(axis, isRtl);
  175. var styles = {
  176. slider: (_slider = {
  177. touchCallout: 'none',
  178. userSelect: 'none',
  179. cursor: 'default'
  180. }, (0, _defineProperty3.default)(_slider, crossAxisProperty[calculatedAxis], handleSizeActive), (0, _defineProperty3.default)(_slider, mainAxisProperty[calculatedAxis], '100%'), (0, _defineProperty3.default)(_slider, 'position', 'relative'), (0, _defineProperty3.default)(_slider, 'marginTop', 24), (0, _defineProperty3.default)(_slider, 'marginBottom', 48), _slider),
  181. track: (_track = {
  182. position: 'absolute'
  183. }, (0, _defineProperty3.default)(_track, crossAxisOffsetProperty[calculatedAxis], (handleSizeActive - trackSize) / 2), (0, _defineProperty3.default)(_track, mainAxisOffsetProperty[calculatedAxis], 0), (0, _defineProperty3.default)(_track, mainAxisProperty[calculatedAxis], '100%'), (0, _defineProperty3.default)(_track, crossAxisProperty[calculatedAxis], trackSize), _track),
  184. filledAndRemaining: (_filledAndRemaining = {
  185. directionInvariant: true,
  186. position: 'absolute'
  187. }, (0, _defineProperty3.default)(_filledAndRemaining, crossAxisOffsetProperty, 0), (0, _defineProperty3.default)(_filledAndRemaining, crossAxisProperty[calculatedAxis], '100%'), (0, _defineProperty3.default)(_filledAndRemaining, 'transition', _transitions2.default.easeOut(null, 'margin')), _filledAndRemaining),
  188. handle: (_handle = {
  189. directionInvariant: true,
  190. boxSizing: 'border-box',
  191. position: 'absolute',
  192. cursor: 'pointer',
  193. pointerEvents: 'inherit'
  194. }, (0, _defineProperty3.default)(_handle, crossAxisOffsetProperty[calculatedAxis], 0), (0, _defineProperty3.default)(_handle, mainAxisOffsetProperty[calculatedAxis], percent === 0 ? '0%' : percent * 100 + '%'), (0, _defineProperty3.default)(_handle, 'zIndex', 1), (0, _defineProperty3.default)(_handle, 'margin', {
  195. x: trackSize / 2 + 'px 0 0 0',
  196. 'x-reverse': trackSize / 2 + 'px 0 0 0',
  197. y: '0 0 0 ' + trackSize / 2 + 'px',
  198. 'y-reverse': '0 0 0 ' + trackSize / 2 + 'px'
  199. }[calculatedAxis]), (0, _defineProperty3.default)(_handle, 'width', handleSize), (0, _defineProperty3.default)(_handle, 'height', handleSize), (0, _defineProperty3.default)(_handle, 'backgroundColor', selectionColor), (0, _defineProperty3.default)(_handle, 'backgroundClip', 'padding-box'), (0, _defineProperty3.default)(_handle, 'border', '0px solid transparent'), (0, _defineProperty3.default)(_handle, 'borderRadius', '50%'), (0, _defineProperty3.default)(_handle, 'transform', {
  200. x: 'translate(-50%, -50%)',
  201. 'x-reverse': 'translate(50%, -50%)',
  202. y: 'translate(-50%, 50%)',
  203. 'y-reverse': 'translate(-50%, -50%)'
  204. }[calculatedAxis]), (0, _defineProperty3.default)(_handle, 'transition', _transitions2.default.easeOut('450ms', 'background') + ', ' + _transitions2.default.easeOut('450ms', 'border-color') + ', ' + _transitions2.default.easeOut('450ms', 'width') + ', ' + _transitions2.default.easeOut('450ms', 'height')), (0, _defineProperty3.default)(_handle, 'overflow', 'visible'), (0, _defineProperty3.default)(_handle, 'outline', 'none'), _handle),
  205. handleWhenDisabled: {
  206. boxSizing: 'content-box',
  207. cursor: 'not-allowed',
  208. backgroundColor: trackColor,
  209. width: handleSizeDisabled,
  210. height: handleSizeDisabled,
  211. border: 'none'
  212. },
  213. handleWhenPercentZero: {
  214. border: trackSize + 'px solid ' + handleColorZero,
  215. backgroundColor: handleFillColor,
  216. boxShadow: 'none'
  217. },
  218. handleWhenPercentZeroAndDisabled: {
  219. cursor: 'not-allowed',
  220. width: handleSizeDisabled,
  221. height: handleSizeDisabled
  222. },
  223. handleWhenPercentZeroAndFocused: {
  224. border: trackSize + 'px solid ' + trackColorSelected
  225. },
  226. handleWhenActive: {
  227. width: handleSizeActive,
  228. height: handleSizeActive
  229. },
  230. ripple: {
  231. height: handleSize,
  232. width: handleSize,
  233. overflow: 'visible'
  234. },
  235. rippleWhenPercentZero: {
  236. top: -trackSize,
  237. left: -trackSize
  238. },
  239. rippleInner: {
  240. height: '300%',
  241. width: '300%',
  242. top: -handleSize,
  243. left: -handleSize
  244. },
  245. rippleColor: {
  246. fill: percent === 0 ? handleColorZero : rippleColor
  247. }
  248. };
  249. styles.filled = (0, _simpleAssign2.default)({}, styles.filledAndRemaining, (_objectAssign2 = {}, (0, _defineProperty3.default)(_objectAssign2, mainAxisOffsetProperty[calculatedAxis], 0), (0, _defineProperty3.default)(_objectAssign2, 'backgroundColor', disabled ? trackColor : selectionColor), (0, _defineProperty3.default)(_objectAssign2, mainAxisMarginFromEnd[calculatedAxis], fillGutter), (0, _defineProperty3.default)(_objectAssign2, mainAxisProperty[calculatedAxis], 'calc(' + percent * 100 + '%' + calcDisabledSpacing + ')'), _objectAssign2));
  250. styles.remaining = (0, _simpleAssign2.default)({}, styles.filledAndRemaining, (_objectAssign3 = {}, (0, _defineProperty3.default)(_objectAssign3, reverseMainAxisOffsetProperty[calculatedAxis], 0), (0, _defineProperty3.default)(_objectAssign3, 'backgroundColor', (state.hovered || state.focused) && !disabled ? trackColorSelected : trackColor), (0, _defineProperty3.default)(_objectAssign3, mainAxisMarginFromStart[calculatedAxis], fillGutter), (0, _defineProperty3.default)(_objectAssign3, mainAxisProperty[calculatedAxis], 'calc(' + (1 - percent) * 100 + '%' + calcDisabledSpacing + ')'), _objectAssign3));
  251. return styles;
  252. };
  253. var Slider = function (_Component) {
  254. (0, _inherits3.default)(Slider, _Component);
  255. function Slider() {
  256. var _ref;
  257. var _temp, _this, _ret;
  258. (0, _classCallCheck3.default)(this, Slider);
  259. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  260. args[_key3] = arguments[_key3];
  261. }
  262. return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = Slider.__proto__ || (0, _getPrototypeOf2.default)(Slider)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
  263. active: false,
  264. dragging: false,
  265. focused: false,
  266. hovered: false,
  267. value: 0
  268. }, _this.track = null, _this.handle = null, _this.resolveValue = function (value, min, max) {
  269. if (value > max) {
  270. return max;
  271. }
  272. if (value < min) {
  273. return min;
  274. }
  275. return value;
  276. }, _this.handleKeyDown = function (event) {
  277. var _this$props = _this.props,
  278. axis = _this$props.axis,
  279. min = _this$props.min,
  280. max = _this$props.max,
  281. step = _this$props.step;
  282. var isRtl = _this.context.muiTheme.isRtl;
  283. var calculatedAxis = calculateAxis(axis, isRtl);
  284. var action = void 0;
  285. switch ((0, _keycode2.default)(event)) {
  286. case 'page down':
  287. case 'down':
  288. if (calculatedAxis === 'y-reverse') {
  289. action = 'increase';
  290. } else {
  291. action = 'decrease';
  292. }
  293. break;
  294. case 'left':
  295. if (calculatedAxis === 'x-reverse') {
  296. action = 'increase';
  297. } else {
  298. action = 'decrease';
  299. }
  300. break;
  301. case 'page up':
  302. case 'up':
  303. if (calculatedAxis === 'y-reverse') {
  304. action = 'decrease';
  305. } else {
  306. action = 'increase';
  307. }
  308. break;
  309. case 'right':
  310. if (calculatedAxis === 'x-reverse') {
  311. action = 'decrease';
  312. } else {
  313. action = 'increase';
  314. }
  315. break;
  316. case 'home':
  317. action = 'min';
  318. break;
  319. case 'end':
  320. action = 'max';
  321. break;
  322. }
  323. if (action) {
  324. var newValue = void 0;
  325. // Cancel scroll
  326. event.preventDefault();
  327. switch (action) {
  328. case 'decrease':
  329. newValue = _this.state.value - step;
  330. break;
  331. case 'increase':
  332. newValue = _this.state.value + step;
  333. break;
  334. case 'min':
  335. newValue = min;
  336. break;
  337. case 'max':
  338. newValue = max;
  339. break;
  340. }
  341. // We need to use toFixed() because of float point errors.
  342. // For example, 0.01 + 0.06 = 0.06999999999999999
  343. newValue = _this.resolveValue(parseFloat(newValue.toFixed(5)), min, max);
  344. if (_this.state.value !== newValue) {
  345. _this.setState({
  346. value: newValue
  347. });
  348. if (_this.props.onChange) {
  349. _this.props.onChange(event, newValue);
  350. }
  351. }
  352. }
  353. }, _this.handleDragMouseMove = function (event) {
  354. _this.onDragUpdate(event, 'mouse');
  355. }, _this.handleTouchMove = function (event) {
  356. _this.onDragUpdate(event, 'touch');
  357. }, _this.handleMouseEnd = function (event) {
  358. document.removeEventListener('mousemove', _this.handleDragMouseMove);
  359. document.removeEventListener('mouseup', _this.handleMouseEnd);
  360. _this.onDragStop(event);
  361. }, _this.handleTouchEnd = function (event) {
  362. document.removeEventListener('touchmove', _this.handleTouchMove);
  363. document.removeEventListener('touchup', _this.handleTouchEnd);
  364. document.removeEventListener('touchend', _this.handleTouchEnd);
  365. document.removeEventListener('touchcancel', _this.handleTouchEnd);
  366. _this.onDragStop(event);
  367. }, _this.handleTouchStart = function (event) {
  368. var _this$props2 = _this.props,
  369. axis = _this$props2.axis,
  370. disabled = _this$props2.disabled;
  371. var isRtl = _this.context.muiTheme.isRtl;
  372. if (disabled) {
  373. return;
  374. }
  375. var calculatedAxis = calculateAxis(axis, isRtl);
  376. var position = void 0;
  377. if (isMouseControlInverted(calculatedAxis)) {
  378. position = _this.getTrackOffset() - event.touches[0][mainAxisClientOffsetProperty[calculatedAxis]];
  379. } else {
  380. position = event.touches[0][mainAxisClientOffsetProperty[calculatedAxis]] - _this.getTrackOffset();
  381. }
  382. _this.setValueFromPosition(event, position);
  383. document.addEventListener('touchmove', _this.handleTouchMove);
  384. document.addEventListener('touchup', _this.handleTouchEnd);
  385. document.addEventListener('touchend', _this.handleTouchEnd);
  386. document.addEventListener('touchcancel', _this.handleTouchEnd);
  387. _this.onDragStart(event);
  388. // Cancel scroll and context menu
  389. event.preventDefault();
  390. }, _this.handleFocus = function (event) {
  391. _this.setState({
  392. focused: true
  393. });
  394. if (_this.props.onFocus) {
  395. _this.props.onFocus(event);
  396. }
  397. }, _this.handleBlur = function (event) {
  398. _this.setState({
  399. focused: false,
  400. active: false
  401. });
  402. if (_this.props.onBlur) {
  403. _this.props.onBlur(event);
  404. }
  405. }, _this.handleMouseDown = function (event) {
  406. var _this$props3 = _this.props,
  407. axis = _this$props3.axis,
  408. disabled = _this$props3.disabled;
  409. var isRtl = _this.context.muiTheme.isRtl;
  410. if (disabled) {
  411. return;
  412. }
  413. var calculatedAxis = calculateAxis(axis, isRtl);
  414. var position = void 0;
  415. if (isMouseControlInverted(calculatedAxis)) {
  416. position = _this.getTrackOffset() - event[mainAxisClientOffsetProperty[calculatedAxis]];
  417. } else {
  418. position = event[mainAxisClientOffsetProperty[calculatedAxis]] - _this.getTrackOffset();
  419. }
  420. _this.setValueFromPosition(event, position);
  421. document.addEventListener('mousemove', _this.handleDragMouseMove);
  422. document.addEventListener('mouseup', _this.handleMouseEnd);
  423. // Cancel text selection
  424. event.preventDefault();
  425. // Set focus manually since we called preventDefault()
  426. _this.handle.focus();
  427. _this.onDragStart(event);
  428. }, _this.handleMouseUp = function () {
  429. if (!_this.props.disabled) {
  430. _this.setState({
  431. active: false
  432. });
  433. }
  434. }, _this.handleMouseEnter = function () {
  435. _this.setState({
  436. hovered: true
  437. });
  438. }, _this.handleMouseLeave = function () {
  439. _this.setState({
  440. hovered: false
  441. });
  442. }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
  443. }
  444. (0, _createClass3.default)(Slider, [{
  445. key: 'componentWillMount',
  446. value: function componentWillMount() {
  447. var _props = this.props,
  448. defaultValue = _props.defaultValue,
  449. min = _props.min,
  450. max = _props.max;
  451. var value = this.props.value;
  452. if (value === undefined) {
  453. value = defaultValue !== undefined ? defaultValue : min;
  454. }
  455. this.setState({
  456. value: this.resolveValue(value, min, max)
  457. });
  458. }
  459. }, {
  460. key: 'componentWillReceiveProps',
  461. value: function componentWillReceiveProps(nextProps) {
  462. if (nextProps.value !== undefined && !this.state.dragging) {
  463. var _nextProps$min = nextProps.min,
  464. min = _nextProps$min === undefined ? this.props.min : _nextProps$min,
  465. _nextProps$max = nextProps.max,
  466. max = _nextProps$max === undefined ? this.props.max : _nextProps$max;
  467. this.setState({
  468. value: this.resolveValue(nextProps.value, min, max)
  469. });
  470. }
  471. }
  472. }, {
  473. key: 'getValue',
  474. value: function getValue() {
  475. process.env.NODE_ENV !== "production" ? (0, _warning2.default)(false, 'Material-UI Slider: getValue() method is deprecated.\n Use the onChange callbacks instead.\n It will be removed with v0.17.0.') : void 0;
  476. return this.state.value;
  477. }
  478. }, {
  479. key: 'clearValue',
  480. value: function clearValue() {
  481. process.env.NODE_ENV !== "production" ? (0, _warning2.default)(false, 'Material-UI Slider: clearValue() method is deprecated.\n Use the value property to control the component instead.\n It will be removed with v0.17.0.') : void 0;
  482. this.setState({
  483. value: this.props.min
  484. });
  485. }
  486. }, {
  487. key: 'getTrackOffset',
  488. value: function getTrackOffset() {
  489. var axis = this.props.axis;
  490. var isRtl = this.context.muiTheme.isRtl;
  491. var calculatedAxis = calculateAxis(axis, isRtl);
  492. if (!this.track) return 0;
  493. return this.track.getBoundingClientRect()[mainAxisOffsetProperty[calculatedAxis]];
  494. }
  495. }, {
  496. key: 'onDragStart',
  497. value: function onDragStart(event) {
  498. this.setState({
  499. dragging: true,
  500. active: true
  501. });
  502. if (this.props.onDragStart) {
  503. this.props.onDragStart(event);
  504. }
  505. }
  506. }, {
  507. key: 'onDragUpdate',
  508. value: function onDragUpdate(event, type) {
  509. var _this2 = this;
  510. var _props2 = this.props,
  511. axis = _props2.axis,
  512. disabled = _props2.disabled;
  513. var isRtl = this.context.muiTheme.isRtl;
  514. if (this.dragRunning) {
  515. return;
  516. }
  517. this.dragRunning = true;
  518. requestAnimationFrame(function () {
  519. _this2.dragRunning = false;
  520. var calculatedAxis = calculateAxis(axis, isRtl);
  521. var source = type === 'touch' ? event.touches[0] : event;
  522. var position = void 0;
  523. if (isMouseControlInverted(calculatedAxis)) {
  524. position = _this2.getTrackOffset() - source[mainAxisClientOffsetProperty[calculatedAxis]];
  525. } else {
  526. position = source[mainAxisClientOffsetProperty[calculatedAxis]] - _this2.getTrackOffset();
  527. }
  528. if (!disabled) {
  529. _this2.setValueFromPosition(event, position);
  530. }
  531. });
  532. }
  533. }, {
  534. key: 'onDragStop',
  535. value: function onDragStop(event) {
  536. this.setState({
  537. dragging: false,
  538. active: false
  539. });
  540. if (this.props.onDragStop) {
  541. this.props.onDragStop(event);
  542. }
  543. }
  544. }, {
  545. key: 'setValueFromPosition',
  546. value: function setValueFromPosition(event, position) {
  547. var _props3 = this.props,
  548. axis = _props3.axis,
  549. step = _props3.step,
  550. min = _props3.min,
  551. max = _props3.max;
  552. var isRtl = this.context.muiTheme.isRtl;
  553. var calculatedAxis = calculateAxis(axis, isRtl);
  554. var positionMax = this.track[mainAxisClientProperty[calculatedAxis]];
  555. var value = void 0;
  556. if (position <= 0) {
  557. value = min;
  558. } else if (position >= positionMax) {
  559. value = max;
  560. } else {
  561. value = position / positionMax * (max - min);
  562. value = Math.round(value / step) * step + min;
  563. value = parseFloat(value.toFixed(5));
  564. }
  565. value = this.resolveValue(value, min, max);
  566. if (this.state.value !== value) {
  567. this.setState({
  568. value: value
  569. });
  570. if (this.props.onChange) {
  571. this.props.onChange(event, value);
  572. }
  573. }
  574. }
  575. }, {
  576. key: 'render',
  577. value: function render() {
  578. var _this3 = this;
  579. var _props4 = this.props,
  580. axis = _props4.axis,
  581. disabled = _props4.disabled,
  582. disableFocusRipple = _props4.disableFocusRipple,
  583. max = _props4.max,
  584. min = _props4.min,
  585. name = _props4.name,
  586. onBlur = _props4.onBlur,
  587. onChange = _props4.onChange,
  588. onDragStart = _props4.onDragStart,
  589. onDragStop = _props4.onDragStop,
  590. onFocus = _props4.onFocus,
  591. required = _props4.required,
  592. sliderStyle = _props4.sliderStyle,
  593. step = _props4.step,
  594. style = _props4.style,
  595. propValue = _props4.value,
  596. other = (0, _objectWithoutProperties3.default)(_props4, ['axis', 'disabled', 'disableFocusRipple', 'max', 'min', 'name', 'onBlur', 'onChange', 'onDragStart', 'onDragStop', 'onFocus', 'required', 'sliderStyle', 'step', 'style', 'value']);
  597. var _state = this.state,
  598. active = _state.active,
  599. focused = _state.focused,
  600. hovered = _state.hovered,
  601. value = _state.value;
  602. var prepareStyles = this.context.muiTheme.prepareStyles;
  603. var styles = getStyles(this.props, this.context, this.state);
  604. var percent = getPercent(value, min, max);
  605. var handleStyles = {};
  606. if (percent === 0) {
  607. handleStyles = (0, _simpleAssign2.default)({}, styles.handle, styles.handleWhenPercentZero, active && styles.handleWhenActive, (hovered || focused) && !disabled && styles.handleWhenPercentZeroAndFocused, disabled && styles.handleWhenPercentZeroAndDisabled);
  608. } else {
  609. handleStyles = (0, _simpleAssign2.default)({}, styles.handle, active && styles.handleWhenActive, disabled && styles.handleWhenDisabled);
  610. }
  611. var rippleStyle = (0, _simpleAssign2.default)({}, styles.ripple, percent === 0 && styles.rippleWhenPercentZero);
  612. return _react2.default.createElement(
  613. 'div',
  614. (0, _extends3.default)({}, other, { style: prepareStyles((0, _simpleAssign2.default)({}, style)) }),
  615. _react2.default.createElement(
  616. 'div',
  617. {
  618. style: prepareStyles((0, _simpleAssign2.default)({}, styles.slider, sliderStyle)),
  619. onFocus: this.handleFocus,
  620. onBlur: this.handleBlur,
  621. onMouseDown: this.handleMouseDown,
  622. onMouseEnter: this.handleMouseEnter,
  623. onMouseLeave: this.handleMouseLeave,
  624. onMouseUp: this.handleMouseUp,
  625. onTouchStart: this.handleTouchStart,
  626. onKeyDown: !disabled ? this.handleKeyDown : undefined
  627. },
  628. _react2.default.createElement(
  629. 'div',
  630. { ref: function ref(node) {
  631. return _this3.track = node;
  632. }, style: prepareStyles(styles.track) },
  633. _react2.default.createElement('div', { style: prepareStyles(styles.filled) }),
  634. _react2.default.createElement('div', { style: prepareStyles(styles.remaining) }),
  635. _react2.default.createElement(
  636. 'div',
  637. {
  638. ref: function ref(node) {
  639. return _this3.handle = node;
  640. },
  641. style: prepareStyles(handleStyles),
  642. tabIndex: 0
  643. },
  644. !disabled && !disableFocusRipple && _react2.default.createElement(_FocusRipple2.default, {
  645. style: rippleStyle,
  646. innerStyle: styles.rippleInner,
  647. show: (hovered || focused) && !active,
  648. color: styles.rippleColor.fill
  649. })
  650. )
  651. )
  652. ),
  653. _react2.default.createElement('input', {
  654. type: 'hidden',
  655. name: name,
  656. value: value,
  657. required: required,
  658. min: min,
  659. max: max,
  660. step: step
  661. })
  662. );
  663. }
  664. }]);
  665. return Slider;
  666. }(_react.Component);
  667. Slider.defaultProps = {
  668. axis: 'x',
  669. disabled: false,
  670. disableFocusRipple: false,
  671. max: 1,
  672. min: 0,
  673. required: true,
  674. step: 0.01,
  675. style: {}
  676. };
  677. Slider.contextTypes = {
  678. muiTheme: _propTypes2.default.object.isRequired
  679. };
  680. Slider.propTypes = process.env.NODE_ENV !== "production" ? {
  681. /**
  682. * The axis on which the slider will slide.
  683. */
  684. axis: _propTypes2.default.oneOf(['x', 'x-reverse', 'y', 'y-reverse']),
  685. /**
  686. * The default value of the slider.
  687. */
  688. defaultValue: valueInRangePropType,
  689. /**
  690. * Disables focus ripple if set to true.
  691. */
  692. disableFocusRipple: _propTypes2.default.bool,
  693. /**
  694. * If true, the slider will not be interactable.
  695. */
  696. disabled: _propTypes2.default.bool,
  697. /**
  698. * The maximum value the slider can slide to on
  699. * a scale from 0 to 1 inclusive. Cannot be equal to min.
  700. */
  701. max: minMaxPropType,
  702. /**
  703. * The minimum value the slider can slide to on a scale
  704. * from 0 to 1 inclusive. Cannot be equal to max.
  705. */
  706. min: minMaxPropType,
  707. /**
  708. * The name of the slider. Behaves like the name attribute
  709. * of an input element.
  710. */
  711. name: _propTypes2.default.string,
  712. /** @ignore */
  713. onBlur: _propTypes2.default.func,
  714. /**
  715. * Callback function that is fired when the slider's value changed.
  716. *
  717. * @param {object} event KeyDown event targeting the slider.
  718. * @param {number} newValue The new value of the slider.
  719. */
  720. onChange: _propTypes2.default.func,
  721. /**
  722. * Callback function that is fired when the slider has begun to move.
  723. *
  724. * @param {object} event MouseDown or TouchStart event targeting the slider.
  725. */
  726. onDragStart: _propTypes2.default.func,
  727. /**
  728. * Callback function that is fired when the slide has stopped moving.
  729. *
  730. * @param {object} event MouseEnd or TouchEnd event targeting the slider.
  731. */
  732. onDragStop: _propTypes2.default.func,
  733. /** @ignore */
  734. onFocus: _propTypes2.default.func,
  735. /**
  736. * Whether or not the slider is required in a form.
  737. */
  738. required: _propTypes2.default.bool,
  739. /**
  740. * Override the inline-styles of the inner slider element.
  741. */
  742. sliderStyle: _propTypes2.default.object,
  743. /**
  744. * The granularity the slider can step through values.
  745. */
  746. step: _propTypes2.default.number,
  747. /**
  748. * Override the inline-styles of the root element.
  749. */
  750. style: _propTypes2.default.object,
  751. /**
  752. * The value of the slider.
  753. */
  754. value: valueInRangePropType
  755. } : {};
  756. exports.default = Slider;