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
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>
|
|
);
|
|
};
|