score:19
you can use indicator dragger with mousedown
on it.
here for example
// styles
dragger: {
width: '5px',
cursor: 'ew-resize',
padding: '4px 0 0',
bordertop: '1px solid #ddd',
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
zindex: '100',
backgroundcolor: '#f4f7f9'
}
...
state = {
isresizing: false,
lastdownx: 0,
newwidth: {}
};
handlemousedown = e => {
this.setstate({ isresizing: true, lastdownx: e.clientx });
};
handlemousemove = e => {
// we don't want to do anything if we aren't resizing.
if (!this.state.isresizing) {
return;
}
let offsetright =
document.body.offsetwidth - (e.clientx - document.body.offsetleft);
let minwidth = 50;
let maxwidth = 600;
if (offsetright > minwidth && offsetright < maxwidth) {
this.setstate({ newwidth: { width: offsetright } });
}
};
handlemouseup = e => {
this.setstate({ isresizing: false });
};
componentdidmount() {
document.addeventlistener('mousemove', e => this.handlemousemove(e));
document.addeventlistener('mouseup', e => this.handlemouseup(e));
}
...
<drawer
variant="permanent"
open
anchor={'right'}
classes={{
paper: classes.drawerpaper
}}
paperprops={{ style: this.state.newwidth }}
>
<div
id="dragger"
onmousedown={event => {
this.handlemousedown(event);
}}
classname={classes.dragger}
/>
{drawer}
</drawer>
the idea is, when click the dragger, it will resize width drawer
followed mouse move.
play demo.
score:2
just use a synthetic event on your handle element. that way, you can avoid the messiness/performance costs of having a universal event listener. something like the following:
render() {
return (
<div onmousedown={this.yourresizefunc}>
</div>
);
}
score:2
you can do that with css only, if that fits your need. it's the simplest solution. look mom, no javascript.
.resizable {
height: 150px;
width: 150px;
border: 1px solid #333;
resize: horizontal;
overflow: auto;
}
<div class="resizable"></div>
score:4
it might be a useresize
hook with api to enable resizing and providing current width.
import { usecallback, useeffect, usestate } from 'react'
type useresizeprops = {
minwidth: number
}
type useresizereturn = {
width: number
enableresize: () => void
}
const useresize = ({
minwidth,
}: useresizeprops): useresizereturn => {
const [isresizing, setisresizing] = usestate(false)
const [width, setwidth] = usestate(minwidth)
const enableresize = usecallback(() => {
setisresizing(true)
}, [setisresizing])
const disableresize = usecallback(() => {
setisresizing(false)
}, [setisresizing])
const resize = usecallback(
(e: mouseevent) => {
if (isresizing) {
const newwidth = e.clientx // you may want to add some offset here from props
if (newwidth >= minwidth) {
setwidth(newwidth)
}
}
},
[minwidth, isresizing, setwidth],
)
useeffect(() => {
document.addeventlistener('mousemove', resize)
document.addeventlistener('mouseup', disableresize)
return () => {
document.removeeventlistener('mousemove', resize)
document.removeeventlistener('mouseup', disableresize)
}
}, [disableresize, resize])
return { width, enableresize }
}
export default useresize
then you could decouple resizing logic from your layout component like this:
const layout = () => {
const { width, enableresize } = useresize(200);
return (
<drawer
variant="permanent"
open
paperprops={{ style: { width } }}
>
{drawer}
<div
style={{
position: absolute,
width: '2px',
top: '0',
right: '-1px',
bottom: '0',
cursor: 'col-resize'
}}
onmousedown={enableresize}
/>
</drawer>
)
score:5
i would like to add an answer that is more up to date using react hooks.
you can do it like this, then:
css:
sidebar-dragger: {
width: '5px',
cursor: 'ew-resize',
padding: '4px 0 0',
bordertop: '1px solid #ddd',
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
zindex: '100',
backgroundcolor: '#f4f7f9'
}
react (using hooks with refs and states)
let isresizing = null;
function resizeablesidebar (props) {
const sidebarpanel = react.useref('sidebarpanel');
const cbhandlemousemove = react.usecallback(handlemousemove, []);
const cbhandlemouseup = react.usecallback(handlemouseup, []);
function handlemousedown (e) {
e.stoppropagation();
e.preventdefault();
// we will only add listeners when needed, and remove them afterward
document.addeventlistener('mousemove', cbhandlemousemove);
document.addeventlistener('mouseup', cbhandlemouseup);
isresizing = true;
};
function handlemousemove (e) {
if (!isresizing) {
return;
}
let offsetright =
document.body.offsetwidth - (e.clientx - document.body.offsetleft);
let minwidth = 50;
if (offsetright > minwidth) {
let cursize = offsetright - 60;
// using a ref instead of state will be way faster
sidebarpanel.current.style.width = cursize + 'px';
}
};
function handlemouseup (e) {
if (!isresizing) {
return;
}
isresizing = false;
document.removeeventlistener('mousemove', cbhandlemousemove);
document.removeeventlistener('mouseup', cbhandlemouseup);
};
return <div classname="sidebar-container">
<div
classname="sidebar-dragger"
onmousedown={handlemousedown}
/>
<div>
your stuff goes here
</div>
</div>;
}
Source: stackoverflow.com
Related Query
- Recommended way to have drawer resizable?
- Is there a recommended way to run setup in a React component but only after several conditions have been met?
- Recommended way of making React component/div draggable
- What is the best way to have variable attributes in JSX?
- What is the best way to have a fallback image in NextJS?
- Why React's PureComponent is recommended to have all its children "pure"
- How is the correct way to have multiple dataProviders in react-admin?
- Recommended way to use GraphQL in Next.js app
- Recommended way to share components between nextjs zones?
- Is there a way to show a Material-UI Drawer nested inside a Grid component?
- Is there a way to have `react-scripts` include extra files in the root of the build?
- I have built a global state redux like pattern with context and hooks. Is there a way to combine reducers?
- Whats the proper way to have a form submit data in a stateless react component?
- Is there a way to have line breaks in text without using dangerouslySetInnerHTML?
- Is there a way to have "onPress" and "onLongPress" on same "Button/TouchableOpacity"
- Recommended way of using React + Picturefill
- React Material UI Drawer - Warning Each child in a list should have a unique "key" prop
- any way to have multiple tabs(screens) in react native with a preview like in a browsers do for example?
- Material-UI React.js, Is there a way to have an onClick event for both a ListItem, and the ListItem's Avatar?
- Creating a survey using React but stuck finding a way to have questions dependent on certain responses
- Most "react" way to have multiple different renderings
- Best way to have absolute imports with Webpack 2?
- is there a way to have mui v5 render the classnames without the css-yyy prefix?
- Is there a way to have custom breakpoints in React-Bootstrap
- What is recommended way to determine if a Redux state empty array is the initial state or the result of an API call that returns an empty array?
- Is there a way to have a React child component displayed as a string, with indentations, returns, and with jsx syntactic sugar?
- Is there a way with React Slick to have a Carousel inside a Carousel?
- Is there a way to have evenly sized ticks for recharts axis while keeping my max value?
- How can we send/flash notitication/alert in a functional way in React ? Need to have a common function which can be used everywhere
- What is the best way to understand that all redux-forms have been successfully submitted?
More Query from same tag
- React Redux - Pass data from state to another component to display list of results
- testing library jest - test style upon table cell click
- How can I push value to url in react js?
- Css - achieving 360 deg icon rotate in 2 clicks
- Not able to access Gitlab env variables either in node.js or react
- Download files from GridFS Stream NodeJS Backend / React Front End
- React form not filling out with fetched data
- How to forwardRef selected value from React-Select to react-hook-form
- array is undefined in component being rendered with enzyme?
- How to display only the data from a detail component using nested routes in React?
- Testing a custom UseInterval hook with jest
- MenuIcon not found in material-ui/icons
- tab of object undefined in Js
- Rerendering component and useReducer initialization
- Simple Webpack + React + ES6 + babel example doesn't work. Unexpected token error
- Static react website on S3 request URL to API rewritten to own URL
- how to get the caret position in react js?
- clip-path-polyfill react import not working
- Typescript compiler giving " 'type aliases' can only be used in a .ts file." in a js file
- Redirecting User after Stripe Payment Node js
- TypeError: Cannot read property '_id' of undefined error
- ReactJS: Filter rendering of a list by whole names only?
- How can I use react navigation props in class component?
- 'TypeError: NetworkError when attempting to fetch resource' on form submit ReactJS
- React: Passing props to parent returns <empy string>
- React 16.2 <Fragment> gives Uncaught error: Element type is invalid
- Filtering, Grouping and Aggregating data using Underscore js
- Pause video when changing slide in react js?
- Heroku Google OAuth Error
- How do you make the ListHeaderComponent of a React Native FlatList sticky?