Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

VolumeSlider.tsx 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React, { useCallback, useState } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { makeStyles } from 'tss-react/mui';
  4. import Icon from '../../../base/icons/components/Icon';
  5. import { IconVolumeUp } from '../../../base/icons/svg';
  6. import { VOLUME_SLIDER_SCALE } from '../../constants';
  7. /**
  8. * The type of the React {@code Component} props of {@link VolumeSlider}.
  9. */
  10. interface IProps {
  11. /**
  12. * The value of the audio slider should display at when the component first
  13. * mounts. Changes will be stored in state. The value should be a number
  14. * between 0 and 1.
  15. */
  16. initialValue: number;
  17. /**
  18. * The callback to invoke when the audio slider value changes.
  19. */
  20. onChange: Function;
  21. }
  22. const useStyles = makeStyles()(theme => {
  23. return {
  24. container: {
  25. minHeight: '40px',
  26. minWidth: '180px',
  27. width: '100%',
  28. boxSizing: 'border-box',
  29. cursor: 'pointer',
  30. display: 'flex',
  31. alignItems: 'center',
  32. padding: '10px 16px',
  33. '&:hover': {
  34. backgroundColor: theme.palette.ui02
  35. }
  36. },
  37. icon: {
  38. minWidth: '20px',
  39. marginRight: '16px',
  40. position: 'relative'
  41. },
  42. sliderContainer: {
  43. position: 'relative',
  44. width: '100%'
  45. },
  46. slider: {
  47. position: 'absolute',
  48. width: '100%',
  49. top: '50%',
  50. transform: 'translate(0, -50%)'
  51. }
  52. };
  53. });
  54. const _onClick = (e: React.MouseEvent) => {
  55. e.stopPropagation();
  56. };
  57. const VolumeSlider = ({
  58. initialValue,
  59. onChange
  60. }: IProps) => {
  61. const { classes, cx } = useStyles();
  62. const { t } = useTranslation();
  63. const [ volumeLevel, setVolumeLevel ] = useState((initialValue || 0) * VOLUME_SLIDER_SCALE);
  64. const _onVolumeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
  65. const newVolumeLevel = Number(event.currentTarget.value);
  66. onChange(newVolumeLevel / VOLUME_SLIDER_SCALE);
  67. setVolumeLevel(newVolumeLevel);
  68. }, [ onChange ]);
  69. return (
  70. <div
  71. aria-label = { t('volumeSlider') }
  72. className = { cx('popupmenu__contents', classes.container) }
  73. onClick = { _onClick }>
  74. <span className = { classes.icon }>
  75. <Icon
  76. size = { 22 }
  77. src = { IconVolumeUp } />
  78. </span>
  79. <div className = { classes.sliderContainer }>
  80. <input
  81. aria-valuemax = { VOLUME_SLIDER_SCALE }
  82. aria-valuemin = { 0 }
  83. aria-valuenow = { volumeLevel }
  84. className = { cx('popupmenu__volume-slider', classes.slider) }
  85. max = { VOLUME_SLIDER_SCALE }
  86. min = { 0 }
  87. onChange = { _onVolumeChange }
  88. tabIndex = { 0 }
  89. type = 'range'
  90. value = { volumeLevel } />
  91. </div>
  92. </div>
  93. );
  94. };
  95. export default VolumeSlider;