@@ -12,6 +12,7 @@ import RawModal from '../../atoms/modal/RawModal';
|
|||||||
function Dialog({
|
function Dialog({
|
||||||
className, isOpen, title, onAfterOpen, onAfterClose,
|
className, isOpen, title, onAfterOpen, onAfterClose,
|
||||||
contentOptions, onRequestClose, closeFromOutside, children,
|
contentOptions, onRequestClose, closeFromOutside, children,
|
||||||
|
invisibleScroll,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<RawModal
|
<RawModal
|
||||||
@@ -36,7 +37,7 @@ function Dialog({
|
|||||||
{contentOptions}
|
{contentOptions}
|
||||||
</Header>
|
</Header>
|
||||||
<div className="dialog__content__wrapper">
|
<div className="dialog__content__wrapper">
|
||||||
<ScrollView autoHide>
|
<ScrollView autoHide invisible={invisibleScroll}>
|
||||||
<div className="dialog__content-container">
|
<div className="dialog__content-container">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
@@ -55,6 +56,7 @@ Dialog.defaultProps = {
|
|||||||
onAfterClose: null,
|
onAfterClose: null,
|
||||||
onRequestClose: null,
|
onRequestClose: null,
|
||||||
closeFromOutside: true,
|
closeFromOutside: true,
|
||||||
|
invisibleScroll: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
Dialog.propTypes = {
|
Dialog.propTypes = {
|
||||||
@@ -67,6 +69,7 @@ Dialog.propTypes = {
|
|||||||
onRequestClose: PropTypes.func,
|
onRequestClose: PropTypes.func,
|
||||||
closeFromOutside: PropTypes.bool,
|
closeFromOutside: PropTypes.bool,
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
|
invisibleScroll: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Dialog;
|
export default Dialog;
|
||||||
|
|||||||
@@ -21,8 +21,3 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog__content-container {
|
|
||||||
padding-top: var(--sp-extra-tight);
|
|
||||||
padding-bottom: var(--sp-extra-loose);
|
|
||||||
}
|
|
||||||
49
src/app/molecules/dialog/ReusableDialog.jsx
Normal file
49
src/app/molecules/dialog/ReusableDialog.jsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import cons from '../../../client/state/cons';
|
||||||
|
|
||||||
|
import navigation from '../../../client/state/navigation';
|
||||||
|
import IconButton from '../../atoms/button/IconButton';
|
||||||
|
import Dialog from './Dialog';
|
||||||
|
|
||||||
|
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
|
||||||
|
|
||||||
|
function ReusableDialog() {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [data, setData] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleOpen = (title, render, afterClose) => {
|
||||||
|
setIsOpen(true);
|
||||||
|
setData({ title, render, afterClose });
|
||||||
|
};
|
||||||
|
navigation.on(cons.events.navigation.REUSABLE_DIALOG_OPENED, handleOpen);
|
||||||
|
return () => {
|
||||||
|
navigation.removeListener(cons.events.navigation.REUSABLE_DIALOG_OPENED, handleOpen);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleAfterClose = () => {
|
||||||
|
data.afterClose();
|
||||||
|
setData(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRequestClose = () => {
|
||||||
|
setIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
isOpen={isOpen}
|
||||||
|
title={data?.title || ''}
|
||||||
|
onAfterClose={handleAfterClose}
|
||||||
|
onRequestClose={handleRequestClose}
|
||||||
|
contentOptions={<IconButton src={CrossIC} onClick={handleRequestClose} tooltip="Close" />}
|
||||||
|
invisibleScroll
|
||||||
|
>
|
||||||
|
{data?.render(handleRequestClose) || <div />}
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReusableDialog;
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
@use '../../partials/dir';
|
@use '../../partials/dir';
|
||||||
|
|
||||||
.create-room {
|
.create-room {
|
||||||
|
margin: var(--sp-normal);
|
||||||
@include dir.side(margin, var(--sp-normal), var(--sp-extra-tight));
|
@include dir.side(margin, var(--sp-normal), var(--sp-extra-tight));
|
||||||
|
|
||||||
&__form > * {
|
&__form > * {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import Search from '../search/Search';
|
|||||||
import ViewSource from '../view-source/ViewSource';
|
import ViewSource from '../view-source/ViewSource';
|
||||||
import CreateRoom from '../create-room/CreateRoom';
|
import CreateRoom from '../create-room/CreateRoom';
|
||||||
|
|
||||||
|
import ReusableDialog from '../../molecules/dialog/ReusableDialog';
|
||||||
|
|
||||||
function Dialogs() {
|
function Dialogs() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -18,6 +20,8 @@ function Dialogs() {
|
|||||||
<CreateRoom />
|
<CreateRoom />
|
||||||
<SpaceAddExisting />
|
<SpaceAddExisting />
|
||||||
<Search />
|
<Search />
|
||||||
|
|
||||||
|
<ReusableDialog />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,9 +64,11 @@ function ReadReceipts() {
|
|||||||
onRequestClose={() => setIsOpen(false)}
|
onRequestClose={() => setIsOpen(false)}
|
||||||
contentOptions={<IconButton src={CrossIC} onClick={() => setIsOpen(false)} tooltip="Close" />}
|
contentOptions={<IconButton src={CrossIC} onClick={() => setIsOpen(false)} tooltip="Close" />}
|
||||||
>
|
>
|
||||||
|
<div style={{ marginTop: 'var(--sp-tight)', marginBottom: 'var(--sp-extra-loose)' }}>
|
||||||
{
|
{
|
||||||
readers.map(renderPeople)
|
readers.map(renderPeople)
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,3 +150,12 @@ export function openReusableContextMenu(placement, cords, render, afterClose) {
|
|||||||
afterClose,
|
afterClose,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function openReusableDialog(title, render, afterClose) {
|
||||||
|
appDispatcher.dispatch({
|
||||||
|
type: cons.actions.navigation.OPEN_REUSABLE_DIALOG,
|
||||||
|
title,
|
||||||
|
render,
|
||||||
|
afterClose,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ const cons = {
|
|||||||
CLICK_REPLY_TO: 'CLICK_REPLY_TO',
|
CLICK_REPLY_TO: 'CLICK_REPLY_TO',
|
||||||
OPEN_SEARCH: 'OPEN_SEARCH',
|
OPEN_SEARCH: 'OPEN_SEARCH',
|
||||||
OPEN_REUSABLE_CONTEXT_MENU: 'OPEN_REUSABLE_CONTEXT_MENU',
|
OPEN_REUSABLE_CONTEXT_MENU: 'OPEN_REUSABLE_CONTEXT_MENU',
|
||||||
|
OPEN_REUSABLE_DIALOG: 'OPEN_REUSABLE_DIALOG',
|
||||||
},
|
},
|
||||||
room: {
|
room: {
|
||||||
JOIN: 'JOIN',
|
JOIN: 'JOIN',
|
||||||
@@ -92,6 +93,7 @@ const cons = {
|
|||||||
REPLY_TO_CLICKED: 'REPLY_TO_CLICKED',
|
REPLY_TO_CLICKED: 'REPLY_TO_CLICKED',
|
||||||
SEARCH_OPENED: 'SEARCH_OPENED',
|
SEARCH_OPENED: 'SEARCH_OPENED',
|
||||||
REUSABLE_CONTEXT_MENU_OPENED: 'REUSABLE_CONTEXT_MENU_OPENED',
|
REUSABLE_CONTEXT_MENU_OPENED: 'REUSABLE_CONTEXT_MENU_OPENED',
|
||||||
|
REUSABLE_DIALOG_OPENED: 'REUSABLE_DIALOG_OPENED',
|
||||||
},
|
},
|
||||||
roomList: {
|
roomList: {
|
||||||
ROOMLIST_UPDATED: 'ROOMLIST_UPDATED',
|
ROOMLIST_UPDATED: 'ROOMLIST_UPDATED',
|
||||||
|
|||||||
@@ -174,6 +174,14 @@ class Navigation extends EventEmitter {
|
|||||||
action.afterClose,
|
action.afterClose,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
[cons.actions.navigation.OPEN_REUSABLE_DIALOG]: () => {
|
||||||
|
this.emit(
|
||||||
|
cons.events.navigation.REUSABLE_DIALOG_OPENED,
|
||||||
|
action.title,
|
||||||
|
action.render,
|
||||||
|
action.afterClose,
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
actions[action.type]?.();
|
actions[action.type]?.();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user