Skip to content

Instantly share code, notes, and snippets.

@julianwachholz
Created October 20, 2021 16:12
Show Gist options
  • Save julianwachholz/79b3f1c4c0e1215de6cb9697538850b7 to your computer and use it in GitHub Desktop.
Save julianwachholz/79b3f1c4c0e1215de6cb9697538850b7 to your computer and use it in GitHub Desktop.
Simple resizable element in React (with Tailwind classes)
import React, { useCallback, useRef, useState } from "react";
function clampHeight(height) {
const minHeight = 200;
const maxHeight = document.body.clientHeight - 300;
return Math.min(Math.max(height, minHeight), maxHeight);
}
export default function Element() {
const [height, setHeight] = useState(null);
const ref = useRef();
const resizeHeight = useCallback(() => {
function onMouseMove(e) {
setHeight((currentHeight) => {
if (currentHeight === null) {
return clampHeight(ref.current.clientHeight - e.movementY);
}
return clampHeight(currentHeight - e.movementY);
});
}
function onMouseUp() {
document.body.classList.remove("select-none");
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}
document.body.classList.add("select-none");
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
}, []);
return (
<section
className="relative border-t border-gray-200 bg-gray-100"
style={{
height: height === null ? "50%" : height,
}}
ref={ref}
>
<div
className="absolute inset-x-0 top-0 border-t-4 border-transparent hover:border-gray-300 active:border-gray-400 cursor-[ns-resize]"
onMouseDown={resizeHeight}
/>
<div>
Content here
</div>
</section>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment