您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Slider.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // @flow
  2. import { makeStyles } from '@material-ui/core/styles';
  3. import clsx from 'clsx';
  4. import React from 'react';
  5. import { commonClassName } from '../../base/ui/constants';
  6. type Props = {
  7. /**
  8. * The 'aria-label' text.
  9. */
  10. ariaLabel: string,
  11. /**
  12. * The maximum value for slider value.
  13. */
  14. max: number,
  15. /**
  16. * The minimum value for slider value.
  17. */
  18. min: number,
  19. /**
  20. * Callback invoked on change.
  21. */
  22. onChange: Function,
  23. /**
  24. * The granularity that the value must adhere to.
  25. */
  26. step: number,
  27. /**
  28. * The current value where the knob is positioned.
  29. */
  30. value: number
  31. }
  32. const useStyles = makeStyles(theme => {
  33. // keep the same hight for all elements:
  34. // input, input track & fake track(div)
  35. const height = 6;
  36. const inputTrack = {
  37. background: 'transparent',
  38. height
  39. };
  40. const inputThumb = {
  41. background: theme.palette.text01,
  42. border: 0,
  43. borderRadius: '50%',
  44. height: 24,
  45. width: 24
  46. };
  47. const focused = {
  48. outline: `1px solid ${theme.palette.action03Focus}`
  49. };
  50. return {
  51. sliderContainer: {
  52. cursor: 'pointer',
  53. width: '100%',
  54. position: 'relative',
  55. textAlign: 'center'
  56. },
  57. knobContainer: {
  58. display: 'flex',
  59. justifyContent: 'space-between',
  60. marginLeft: 2,
  61. marginRight: 2,
  62. position: 'absolute',
  63. width: '100%'
  64. },
  65. knob: {
  66. background: theme.palette.text01,
  67. borderRadius: '50%',
  68. display: 'inline-block',
  69. height,
  70. width: 6
  71. },
  72. track: {
  73. background: theme.palette.ui02,
  74. borderRadius: theme.shape.borderRadius / 2,
  75. height
  76. },
  77. slider: {
  78. // Use an additional class here to override global CSS specificity
  79. '&.custom-slider': {
  80. '-webkit-appearance': 'none',
  81. background: 'transparent',
  82. left: 0,
  83. position: 'absolute',
  84. top: 0,
  85. width: '100%',
  86. '&:focus': {
  87. // override global styles in order to use our own color
  88. outline: 'none !important',
  89. '&::-webkit-slider-runnable-track': focused,
  90. '&::ms-track': focused,
  91. '&::-moz-range-track': focused
  92. },
  93. '&::-webkit-slider-runnable-track': {
  94. '-webkit-appearance': 'none',
  95. ...inputTrack
  96. },
  97. '&::-webkit-slider-thumb': {
  98. '-webkit-appearance': 'none',
  99. position: 'relative',
  100. top: -6,
  101. ...inputThumb
  102. },
  103. '&::ms-track': {
  104. ...inputTrack
  105. },
  106. '&::-ms-thumb': {
  107. ...inputThumb
  108. },
  109. '&::-moz-range-track': {
  110. ...inputTrack
  111. },
  112. '&::-moz-range-thumb': {
  113. ...inputThumb
  114. }
  115. }
  116. }
  117. };
  118. });
  119. /**
  120. * Custom slider.
  121. *
  122. * @returns {ReactElement}
  123. */
  124. function Slider({ ariaLabel, max, min, onChange, step, value }: Props) {
  125. const classes = useStyles();
  126. const knobs = [ ...Array(Math.floor((max - min) / step) + 1) ];
  127. return (
  128. <div className = { classes.sliderContainer }>
  129. <ul className = { clsx(commonClassName.emptyList, classes.knobContainer) }>
  130. {knobs.map((_, i) => (
  131. <li
  132. className = { classes.knob }
  133. key = { `knob-${i}` } />))}
  134. </ul>
  135. <div className = { classes.track } />
  136. <input
  137. aria-label = { ariaLabel }
  138. className = { clsx(classes.slider, 'custom-slider') }
  139. max = { max }
  140. min = { min }
  141. onChange = { onChange }
  142. step = { step }
  143. type = 'range'
  144. value = { value } />
  145. </div>
  146. );
  147. }
  148. export default Slider;