@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
144 lines • 4.84 kB
JavaScript
import _noop from "lodash/noop";
import React from 'react';
import cls from 'classnames';
import '@douyinfe/semi-foundation/lib/es/audioPlayer/audioPlayer.css';
import { cssClasses } from '@douyinfe/semi-foundation/lib/es/audioPlayer/constants';
import Tooltip from '../tooltip';
import { formatTime } from './utils';
const prefixCls = cssClasses.PREFIX;
export default class AudioSlider extends React.Component {
constructor(props) {
var _this;
super(props);
_this = this;
this.handleMouseEnter = e => {
this.setState({
isHovering: true
});
this.handleMouseEvent(e, false);
};
this.handleMouseDown = e => {
this.setState({
isDragging: true
});
this.handleMouseEvent(e, true);
};
this.handleMouseUp = () => {
if (this.state.isDragging) {
this.setState({
isDragging: false
});
}
};
this.handleMouseEvent = function (e) {
let shouldSetValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (!_this.sliderRef.current || _this.props.disabled) return;
const rect = _this.sliderRef.current.getBoundingClientRect();
const offset = _this.props.vertical ? rect.bottom - e.clientY : e.clientX - rect.left;
const total = _this.props.vertical ? rect.height : rect.width;
const percentage = Math.min(Math.max(offset / total, 0), 1);
const value = percentage * _this.props.max;
if (shouldSetValue && (_this.state.isDragging || e.type === 'mousedown')) {
_this.props.onChange(value);
}
_this.setState({
movingInfo: {
progress: percentage,
offset: _this.props.vertical ? offset - rect.height / 2 : offset - rect.width / 2
}
});
};
this.handleMouseMove = e => {
this.handleMouseEvent(e, true);
};
this.handleMouseLeave = () => {
this.setState({
isHovering: false,
isDragging: false
});
};
this.state = {
isDragging: false,
isHovering: false,
movingInfo: null
};
this.sliderRef = /*#__PURE__*/React.createRef();
this.handleRef = /*#__PURE__*/React.createRef();
}
render() {
const {
vertical,
width,
height,
showTooltip,
max,
value: currentValue,
theme
} = this.props;
const {
movingInfo,
isHovering
} = this.state;
const sliderContent = /*#__PURE__*/React.createElement("div", {
onMouseDown: this.handleMouseDown,
onMouseUp: this.handleMouseUp,
onMouseEnter: this.handleMouseEnter,
onMouseLeave: this.handleMouseLeave,
onMouseMove: this.handleMouseMove,
className: cls(`${prefixCls}-slider-wrapper`, {
[`${prefixCls}-slider-wrapper-vertical`]: vertical,
[`${prefixCls}-slider-wrapper-horizontal`]: !vertical
})
}, /*#__PURE__*/React.createElement("div", {
ref: this.sliderRef,
className: cls(`${prefixCls}-slider`, `${prefixCls}-slider-${theme}`, {
[`${prefixCls}-slider-vertical`]: vertical,
[`${prefixCls}-slider-horizontal`]: !vertical
}),
style: {
width: vertical ? isHovering ? 8 : 4 : width,
height: vertical ? height : isHovering ? 8 : 4
}
}, /*#__PURE__*/React.createElement("div", {
className: cls(`${prefixCls}-slider-progress`, {
[`${prefixCls}-slider-progress-vertical`]: vertical,
[`${prefixCls}-slider-progress-horizontal`]: !vertical
}),
style: {
height: vertical ? `${currentValue / max * 100}%` : '100%',
width: vertical ? '100%' : `${currentValue / max * 100}%`
}
}), /*#__PURE__*/React.createElement("div", {
ref: this.handleRef,
className: cls(`${prefixCls}-slider-dot`),
style: {
left: vertical ? '50%' : `calc(${currentValue / max * 100}% - 8px)`,
bottom: vertical ? `calc(${currentValue / max * 100}% - 8px)` : undefined,
top: vertical ? undefined : '50%',
transform: vertical ? 'translateX(-50%)' : 'translateY(-50%)',
opacity: isHovering ? 1 : 0,
transition: 'opacity 0.2s',
pointerEvents: 'none'
}
})));
return showTooltip ? (/*#__PURE__*/React.createElement(Tooltip, {
position: vertical ? 'right' : 'top',
autoAdjustOverflow: true,
content: formatTime((movingInfo === null || movingInfo === void 0 ? void 0 : movingInfo.progress) * max),
style: {
[vertical ? 'top' : 'left']: movingInfo === null || movingInfo === void 0 ? void 0 : movingInfo.offset
}
}, sliderContent)) : sliderContent;
}
}
AudioSlider.defaultProps = {
value: 0,
onChange: _noop,
max: 100,
vertical: false,
width: '100%',
height: 4,
showTooltip: true,
disabled: false,
theme: 'dark'
};