1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

example dialog

This commit is contained in:
muerwre 2019-08-02 17:49:53 +07:00
parent 06e72538d3
commit 80fc6523b7
5 changed files with 233 additions and 2 deletions

View file

@ -0,0 +1,16 @@
import React, { FC } from "react";
import { ScrollDialog } from "../ScrollDialog";
interface IProps {}
const ExampleDialog: FC<IProps> = ({}) => {
const title = <div>title</div>;
const buttons = <div>buttons</div>;
return (
<ScrollDialog buttons={buttons} width={720}>
<div style={{ height: 1400 }}>test</div>
</ScrollDialog>
);
};
export { ExampleDialog };

View file

@ -0,0 +1,117 @@
import React, { FC, MouseEventHandler, ReactChild, useCallback, useEffect, useState } from "react";
// import { DialogPanel } from '~/components/panels/DialogPanel';
import { Scroll } from "~/components/containers/Scroll";
import * as styles from "./styles.scss";
import classNames from "classnames";
interface IProps {
children: React.ReactChild;
title?: JSX.Element;
buttons?: JSX.Element;
size?: "medium" | "big";
width?: number;
onOverlayClick?: MouseEventHandler<HTMLDivElement>;
onRefCapture?: (ref: any) => void;
top_sticky?: ReactChild;
top_sticky_offset?: number;
}
const ScrollDialog: FC<IProps> = ({
children,
title,
buttons,
size = "medium",
width = 800,
top_sticky,
top_sticky_offset,
onOverlayClick,
onRefCapture
}) => {
const [height, setHeight] = useState(window.innerHeight - 240);
const [show_top_sticky, setShowTopSticky] = useState(false);
const [ref, setRef] = useState(null);
const onResize = useCallback(() => setHeight(window.innerHeight - 240), []);
useEffect(() => {
window.addEventListener("resize", onResize);
return () => window.removeEventListener("resize", onResize);
}, []);
const onScroll = useCallback(
({ target: { scrollTop = 0 } = {} } = {}) => {
if (!top_sticky || (!top_sticky_offset && top_sticky_offset !== 0)) return;
const is_shown = scrollTop >= top_sticky_offset + 20;
if (show_top_sticky !== is_shown) setShowTopSticky(is_shown);
},
[top_sticky, top_sticky_offset, show_top_sticky, setShowTopSticky]
);
useEffect(() => onScroll(), []);
useEffect(() => {
if (ref && onRefCapture) onRefCapture(ref);
}, [ref, onRefCapture]);
return (
<div className={styles.container}>
<div
className={classNames(styles.content, {
has_buttons: !!buttons,
has_title: !!title
})}
style={{ flexBasis: width }}
>
<div
className={styles.overlay}
onClick={onOverlayClick}
style={{ cursor: onOverlayClick ? "pointer" : "" }}
/>
{!!title && (
<div className={styles.top}>
<div className={styles.wrap} style={{ flexBasis: width }}>
<div className={styles.pan}>
{title}
{show_top_sticky && top_sticky && (
<div className={styles.top_sticky}>{top_sticky}</div>
)}
</div>
</div>
</div>
)}
{!!buttons && (
<div className={styles.bottom}>
<div className={styles.wrap} style={{ flexBasis: width }}>
<div className={styles.pan}>{buttons}</div>
</div>
</div>
)}
<div
className={styles.scroll_wrap}
style={{ flexBasis: width + 40 }}
// style={{ flexBasis: width }}
>
<Scroll
className="dialog_scroll"
autoHeightMax={height}
autoHeight
onScroll={onScroll}
onRef={setRef}
>
<div className={styles.content_wrap}>
<div className={styles.children}>{children}</div>
</div>
</Scroll>
</div>
</div>
</div>
);
};
export { ScrollDialog };

View file

@ -0,0 +1,97 @@
.container {
height: 100vh;
width: 100%;
align-items: center;
justify-content: center;
display: flex;
position: relative;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.content {
display: flex;
align-items: center;
justify-content: center;
position: relative;
padding: 0;
box-sizing: border-box;
flex: 1 1 800px;
z-index: 1;
&:global(.has_title) {
padding-top: 64px + 15px; // +15px
}
&:global(.has_buttons) {
padding-bottom: 64px + 15px; // +15px
}
}
.top,
.bottom {
width: 100%;
height: 64px;
position: absolute;
top: 20px;
bottom: auto;
left: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 0 $gap;
box-sizing: border-box;
z-index: 2;
}
.bottom {
bottom: 20px;
top: auto;
.pan {
border-radius: 0 0 $radius $radius;
}
}
.wrap {
flex: 0 1 800px;
height: 100%;
}
.scroll_wrap {
flex: 0 1 840px;
height: 100%;
}
.content_wrap {
padding: 0 20px;
}
.top_sticky {
position: absolute;
top: 100%;
left: 0;
width: 100%;
padding-top: $gap * 2;
margin-top: -$gap;
z-index: -1;
background: transparentize(white, 0.1);
border-radius: $radius;
box-shadow: transparentize(black, 0.9) 0 15px 15px;
}
.pan {
background: darken($content_bg, 4%);
height: 64px;
}
.children {
background: $content_bg;
radius: $radius;
}

View file

@ -1,5 +1,6 @@
import { ValueOf } from "~/redux/types"; import { ValueOf } from "~/redux/types";
import { HorizontalExample } from "~/containers/examples/HorizontalExample"; import { HorizontalExample } from "~/containers/examples/HorizontalExample";
import { ExampleDialog } from "~/containers/dialogs/ExampleDialog";
export const MODAL_ACTIONS = { export const MODAL_ACTIONS = {
SET_SHOWN: "MODAL.SET_SHOWN", SET_SHOWN: "MODAL.SET_SHOWN",
@ -12,7 +13,7 @@ export const DIALOGS = {
}; };
export const DIALOG_CONTENT = { export const DIALOG_CONTENT = {
[DIALOGS.TEST]: HorizontalExample [DIALOGS.TEST]: ExampleDialog
}; };
export interface IDialogProps { export interface IDialogProps {

View file

@ -9,7 +9,7 @@ export interface IModalState {
} }
const INITIAL_STATE: IModalState = { const INITIAL_STATE: IModalState = {
is_shown: false, is_shown: true,
dialog: DIALOGS.TEST dialog: DIALOGS.TEST
}; };