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.

85 lines
2.6 KiB
JavaScript

"use strict";
const React = require("react");
const { ResizableBox } = require("react-resizable");
const defaultValue = require("default-value");
const useDisableSelection = require("../../util/use-disable-selection");
const useTheme = require("../../util/themeable");
const defaultStyle = require("./style.css");
function Handle({ ... props }) {
let { withTheme } = useTheme({ control: "pane", defaultStyle });
// NOTE: We need to forward all props to make the mouse events work, which react-resizable internally adds to the component
return (
<div className={withTheme("handleHitbox")} {... props}>
<div className={withTheme("handle")} />
</div>
);
}
// TODO: Only exact pixel values currently supported for initialSize, add some sort of percentage support in the future?
// FIXME: Increase handle hitbox size
// FIXME: `Resizable` wrapper element
// NOTE: onResized and direction are internal, handleSide too but it can be overwritten
module.exports = function Pane({ onResized, resizable, initialSize, minimumSize, maximumSize, direction, handleSide, children }) {
let { withTheme } = useTheme({ control: "pane", defaultStyle });
let { disableGlobalSelection, enableGlobalSelection } = useDisableSelection();
// FIXME: Validate inputs
let sizeProps = (direction === "vertical")
? {
height: initialSize,
minConstraints: [ 0, defaultValue(minimumSize, 0) ],
maxConstraints: [ Infinity, defaultValue(maximumSize, Infinity) ],
}
: {
width: initialSize,
minConstraints: [ defaultValue(minimumSize, 0), 0 ],
maxConstraints: [ defaultValue(maximumSize, Infinity), Infinity ],
};
let axisProp = (direction === "vertical")
? "y"
: "x";
function handleOnResizeStop(node, event) {
let newSize = (direction === "vertical")
? event.size.height
: event.size.width;
onResized(newSize);
enableGlobalSelection();
}
function handleOnResizeStart() {
disableGlobalSelection();
}
// NOTE: Needed to prevent react-resizable from somehow breaking hooks inside of Handle
function handleFunction() {
return <Handle />;
}
// FIXME: Do we still need the contentWrapper, without the bounds-measuring logic?
let content = (
<div className={withTheme("contentWrapper")}>
{children}
</div>
);
return (
<div className={withTheme("uilibComponent", "pane", `handleSide-${handleSide}`)}>
{(resizable === true)
? <ResizableBox handle={handleFunction} resizeHandles={[ handleSide ]} axis={axisProp} onResizeStop={handleOnResizeStop} onResizeStart={handleOnResizeStart} {... sizeProps}>
{content}
</ResizableBox>
: content
}
</div>
);
};