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

86 lines
2.1 KiB
JavaScript

import React from 'react'
import { DEFAULT_WIDTHS, COLORS } from '../lib/constants'
const { minWidth, maxWidth } = DEFAULT_WIDTHS
function clamp(value, min, max) {
if (value < min) {
return min
}
if (value > max) {
return max
}
return value
}
function WidthHandler({
innerRef,
onChange,
onChangeComplete,
paddingHorizontal,
paddingVertical,
}) {
const startX = React.useRef(null)
const startWidth = React.useRef(null)
React.useEffect(() => {
function handleMouseMove(e) {
if (!startX.current) return
const delta = e.pageX - startX.current // leftOrRight === 'left' ? startX - e.pageX : (startX - e.pageX) * -1
const calculated = startWidth.current + delta * window.devicePixelRatio
const newWidth = clamp(calculated, minWidth, maxWidth)
onChange(newWidth)
}
window.addEventListener('mousemove', handleMouseMove)
return () => window.removeEventListener('mousemove', handleMouseMove)
}, [innerRef, onChange])
React.useEffect(() => {
function handleMouseUp() {
startX.current = null
onChangeComplete()
}
window.addEventListener('mouseup', handleMouseUp)
return () => window.removeEventListener('mouseup', handleMouseUp)
}, [onChangeComplete])
return (
// eslint-disable-next-line
<div
className="handler"
onMouseDown={e => {
startX.current = e.pageX
startWidth.current = innerRef.current.clientWidth
}}
role="separator"
aria-orientation="vertical"
aria-valuemin={minWidth}
aria-valuemax={maxWidth}
>
<style jsx>
{`
.handler {
z-index: 2;
position: absolute;
background-color: ${COLORS.BLUE};
top: ${paddingVertical};
bottom: ${paddingVertical};
right: ${paddingHorizontal};
width: 8px;
cursor: ew-resize;
opacity: 0;
}
.handler:hover {
opacity: 0.4;
}
`}
</style>
</div>
)
}
export default React.memo(WidthHandler)