mirror of https://github.com/sgoudham/carbon.git
add 'width' option for Carbon container (#949)
* feat: add 'width' option for Carbon container * feat: draggable width adjustment * chore: auto disable widthAdjustment when edge starts dragging * remove label width default; tweak settings style * use only right width handler * use react effects, add a11y role and props * clean up code * use clamp fn * move max and min widths out of state * give WidthHandler a display name * tweak variable names Co-authored-by: Mike Fix <mrfix84@gmail.com> Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>main
parent
249f94851d
commit
41722923d5
@ -0,0 +1,73 @@
|
||||
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
|
||||
}
|
||||
|
||||
export default function WidthHandler(props) {
|
||||
const { onChange, innerRef, paddingHorizontal } = props
|
||||
|
||||
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])
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line
|
||||
<div
|
||||
className="handler"
|
||||
onMouseDown={e => {
|
||||
startX.current = e.pageX
|
||||
startWidth.current = innerRef.current.clientWidth
|
||||
}}
|
||||
onMouseUp={() => {
|
||||
startX.current = null
|
||||
}}
|
||||
role="separator"
|
||||
aria-orientation="vertical"
|
||||
aria-valuemin={minWidth}
|
||||
aria-valuemax={maxWidth}
|
||||
>
|
||||
<style jsx>
|
||||
{`
|
||||
.handler {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
background-color: ${COLORS.BLUE};
|
||||
top: ${paddingHorizontal};
|
||||
bottom: ${paddingHorizontal};
|
||||
right: ${paddingHorizontal};
|
||||
width: 8px;
|
||||
cursor: ew-resize;
|
||||
opacity: 0;
|
||||
}
|
||||
.handler:hover {
|
||||
opacity: 0.4;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</div>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue