Created
October 2, 2020 10:56
-
-
Save thinkawitch/b382da09bff116c9de47cfad9eaf9fe2 to your computer and use it in GitHub Desktop.
vertical resize for css grid in react hooks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* css vars names must be unique */ | |
:root { | |
--ezc-color-gray-100: #f8f9fa; | |
--ezc-color-gray-200: #e9ecef; | |
--ezc-color-gray-300: #dee2e6; | |
--ezc-color-gray-400: #ced4da; | |
--ezc-color-gray-500: #adb5bd; | |
--ezc-color-gray-600: #6c757d; | |
--ezc-color-gray-700: #495057; | |
--ezc-color-gray-800: #343a40; | |
--ezc-color-gray-900: #212529; | |
--ezc-color-body: #fefefe; | |
--ezc-color-black: #000000; | |
--ezc-messages-width-min: 250px; | |
--ezc-messages-width: auto; | |
--ezc-vresize-width: 10px; | |
--ezc-users-width-min: 150px; | |
--ezc-users-width-max: 300px; | |
--ezc-users-width: 200px; | |
--ezc-send-message-height: 40px; | |
--ezc-header-tabs-height: 26px; | |
--ezc-header-tabs-border-radius: 3px; | |
} | |
@function css_var($var-name) { | |
@return var(--#{$var-name}); | |
} | |
// scss variables | |
$ez-ml-panel-padding: 4px; // inner padding of main panel with active tab |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Fragment, useEffect } from 'react'; | |
import { updateCssVar, getCssVarPx } from '../utils/css'; | |
import MessagesContainer from './messages-container'; | |
import UsersContainer from './users-container'; | |
function MainContainer(props) { | |
useEffect(effectToResizeUsersColumn); | |
return ( | |
<Fragment> | |
<div className="ezchat-main-layout"> | |
<div className="ez-ml-messages"> | |
<MessagesContainer /> | |
</div> | |
<div className="ez-ml-send-message">[send message]</div> | |
<div className="ez-ml-vresize for-users"> | |
<div className="v-resize-bar" /> | |
</div> | |
<div className="ez-ml-users"> | |
<UsersContainer /> | |
</div> | |
<div className="ez-ml-vresize for-actions"> | |
<div className="v-resize-bar" /> | |
</div> | |
<div className="ez-ml-actions">actions</div> | |
</div> | |
</Fragment> | |
); | |
} | |
export default MainContainer; | |
// layout resizers | |
function effectToResizeUsersColumn() { | |
const messagesMinWidth = getCssVarPx('--ezc-messages-width-min'); | |
const vresizeWidth = getCssVarPx('--ezc-vresize-width'); | |
const usersMinWidth = getCssVarPx('--ezc-users-width-min'); | |
const usersMaxWidth = getCssVarPx('--ezc-users-width-max'); | |
//console.log('usersMinWidth', usersMinWidth, 'usersMaxWidth', usersMaxWidth) | |
let pageWidth = window.innerWidth; | |
//let resizedByUser = false; | |
let origX = null; | |
let origWidth = null; | |
function resize(e) { | |
if (origX === null) { | |
origX = e.pageX; | |
origWidth = document.querySelector('.ez-ml-users').getBoundingClientRect().width; | |
} | |
var newWidth = origX - e.pageX + origWidth; | |
if (newWidth < usersMinWidth) newWidth = usersMinWidth; | |
if (newWidth > usersMaxWidth) newWidth = usersMaxWidth; | |
window.requestAnimationFrame(() => { | |
updateCssVar('--ezc-users-width', newWidth+'px'); | |
}); | |
} | |
function stopResize() { | |
el.classList.remove('resizing'); | |
window.removeEventListener('mousemove', resize); | |
origX = null; | |
document.body.style.cursor = 'default'; | |
} | |
function onMouseDown(e) { | |
e.preventDefault(); | |
document.body.style.cursor = 'ew-resize'; | |
//resizedByUser = true; | |
el.classList.add('resizing'); | |
window.addEventListener('mousemove', resize); | |
window.addEventListener('mouseup', stopResize); | |
} | |
const el = document.querySelector('.ez-ml-vresize.for-users'); | |
el.addEventListener('mousedown', onMouseDown); | |
function onWindowResize() { | |
if (/*resizedByUser &&*/ window.innerWidth < pageWidth) { | |
const diff = (pageWidth - window.innerWidth); | |
let fullWidth = document.querySelector('.ezchat-main-layout').getBoundingClientRect().width - diff; | |
const messagesWidth = document.querySelector('.ez-ml-messages').getBoundingClientRect().width - diff; | |
const usersWidth = document.querySelector('.ez-ml-users').getBoundingClientRect().width; | |
//console.log('fullWidth', fullWidth, 'messagesWidth', messagesWidth, 'usersWidth', usersWidth); | |
let newWidth = usersWidth; | |
if (messagesWidth <= messagesMinWidth) { | |
newWidth = fullWidth - messagesMinWidth - vresizeWidth; | |
if (newWidth < usersMinWidth) newWidth = usersMinWidth; | |
} | |
window.requestAnimationFrame(function() { | |
updateCssVar('--ezc-users-width', newWidth+'px'); | |
}); | |
} | |
pageWidth = window.innerWidth; | |
} | |
window.addEventListener('resize', onWindowResize); | |
return () => { | |
// undo effect | |
window.removeEventListener('mousemove', resize); | |
window.removeEventListener('mouseup', stopResize); | |
window.removeEventListener('resize', onWindowResize); | |
el.removeEventListener('mousedown', onMouseDown); | |
} | |
} | |
function effectToResizeMessagesColumn() { | |
const messagesMinWidth = 580; | |
let messagesMaxWidth = getMessagesMaxWidth(); | |
let pageWidth = window.innerWidth; | |
let resizedByUser = false; | |
function getMessagesMaxWidth() { | |
return document.querySelector('.ezchat-main-layout').getBoundingClientRect().width - 250; | |
} | |
let origX = null; | |
let origWidth = null; | |
function resize(e) { | |
if (origX === null) { | |
origX = e.pageX; | |
origWidth = document.querySelector('.ez-ml-messages').getBoundingClientRect().width; | |
} | |
var newWidth = origX + e.pageX - origWidth; | |
if (newWidth < messagesMinWidth) newWidth = messagesMinWidth; | |
if (newWidth > messagesMaxWidth) newWidth = messagesMaxWidth; | |
window.requestAnimationFrame(() => { | |
updateCssVar('--ezc-messages-width', newWidth+'px'); | |
}); | |
} | |
function stopResize() { | |
el.classList.remove('resizing'); | |
window.removeEventListener('mousemove', resize); | |
origX = null; | |
document.body.style.cursor = 'default'; | |
} | |
function onMouseDown(e) { | |
e.preventDefault(); | |
document.body.style.cursor = 'ew-resize'; | |
resizedByUser = true; | |
el.classList.add('resizing'); | |
window.addEventListener('mousemove', resize); | |
window.addEventListener('mouseup', stopResize); | |
} | |
const el = document.querySelector('.ez-ml-vresize.for-messages'); | |
el.addEventListener('mousedown', onMouseDown); | |
function onWindowResize() { | |
messagesMaxWidth = getMessagesMaxWidth(); | |
if (resizedByUser && window.innerWidth < pageWidth) { | |
var newWidth = document.querySelector('.ez-ml-messages').getBoundingClientRect().width - (pageWidth - window.innerWidth); | |
if (newWidth < messagesMinWidth) newWidth = messagesMinWidth; | |
window.requestAnimationFrame(function() { | |
updateCssVar('--ezc-messages-width', newWidth+'px'); | |
}); | |
} | |
pageWidth = window.innerWidth; | |
} | |
window.addEventListener('resize', onWindowResize); | |
return () => { | |
// undo effect | |
window.removeEventListener('mousemove', resize); | |
window.removeEventListener('mouseup', stopResize); | |
window.removeEventListener('resize', onWindowResize); | |
el.removeEventListener('mousedown', onMouseDown); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.ezchat-main-layout { | |
display: grid; | |
height: 100%; | |
grid-template-areas: | |
"messages vresize users" | |
"send-message vresize users"; | |
grid-template-rows: auto var(--ezc-send-message-height); | |
grid-template-columns: minmax(var(--ezc-messages-width-min),auto) 10px var(--ezc-users-width); | |
.ez-ml-vresize.for-actions { display: none; } | |
.ez-ml-actions { display: none; } | |
&.with-moderation { | |
grid-template-areas: | |
"messages vresize users vresize actions" | |
"send-message vresize users vresize actions"; | |
.ez-ml-vresize.for-actions { display: none; } | |
.ez-ml-actions { display: block; } | |
} | |
} | |
.ez-ml-messages { | |
grid-area: messages; | |
background-color: lightgoldenrodyellow; | |
} | |
.ez-ml-send-message { | |
grid-area: send-message; | |
background-color: lightcyan; | |
} | |
.ez-ml-vresize { | |
grid-area: vresize; | |
background-color: seashell; | |
} | |
.ez-ml-users { | |
grid-area: users; | |
background-color: honeydew; | |
} | |
.ez-ml-actions { | |
grid-area: actions; | |
} | |
/* vertical resize panel */ | |
.ez-ml-vresize { | |
width: var(--ezc-vresize-width); | |
padding: 3px 0; | |
cursor: ew-resize; | |
.v-resize-bar { | |
width: 1px; | |
background-color: var(--ezc-color-gray-300); | |
margin: 0 auto; | |
height: 100%; | |
} | |
&.resizing { | |
background-color: var(--ezc-color-gray-500); | |
.v-resize-bar { | |
background-color: var(--color-dark); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment