mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-04 02:01:58 -05:00
Cleaned up Frame components
refs https://github.com/TryGhost/Team/issues/1858
This commit is contained in:
parent
02a514f17c
commit
bcb23bc9dc
3 changed files with 67 additions and 60 deletions
|
@ -1,4 +1,4 @@
|
|||
import Frame from './components/Frame';
|
||||
import {CommentsFrame} from './components/Frame';
|
||||
import React from 'react';
|
||||
import {isSyncAction, ActionHandler, SyncActionHandler} from './actions';
|
||||
import {createPopupNotification} from './utils/helpers';
|
||||
|
@ -18,14 +18,6 @@ function AuthFrame({adminUrl, onLoad}) {
|
|||
);
|
||||
}
|
||||
|
||||
function CommentsBoxContainer({done, appVersion}) {
|
||||
return (
|
||||
<Frame title="comments-box">
|
||||
<CommentsBox done={done} />
|
||||
</Frame>
|
||||
);
|
||||
}
|
||||
|
||||
function SentryErrorBoundary({dsn, children}) {
|
||||
// todo: add Sentry.ErrorBoundary wrapper if Sentry is enabled
|
||||
return (
|
||||
|
@ -309,7 +301,9 @@ export default class App extends React.Component {
|
|||
return (
|
||||
<SentryErrorBoundary dsn={this.props.sentryDsn}>
|
||||
<AppContext.Provider value={this.getContextFromState()}>
|
||||
<CommentsBoxContainer done={done} />
|
||||
<CommentsFrame>
|
||||
<CommentsBox done={done} />
|
||||
</CommentsFrame>
|
||||
<AuthFrame adminUrl={this.props.adminUrl} onLoad={this.initAdminAuth.bind(this)}/>
|
||||
<PopupModal />
|
||||
</AppContext.Provider>
|
||||
|
|
|
@ -2,32 +2,73 @@ import React, {useContext, useState} from 'react';
|
|||
import AppContext from '../AppContext';
|
||||
import IFrame from './IFrame';
|
||||
|
||||
const Frame = ({
|
||||
children,
|
||||
type,
|
||||
...props
|
||||
}) => {
|
||||
/**
|
||||
* Loads all the CSS styles inside an iFrame. Only shows the visible content as soon as the CSS file with the tailwind classes has loaded.
|
||||
*/
|
||||
const TailwindFrame = ({children, onResize, style, title}) => {
|
||||
const {stylesUrl} = useContext(AppContext);
|
||||
const [cssLoaded, setCssLoaded] = useState(!stylesUrl);
|
||||
|
||||
const styles = `
|
||||
const initialStyles = `
|
||||
body, html {
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
|
||||
// We have two types of frames:
|
||||
// - A full width + content fitted height one
|
||||
// - A fixed positioned one for modals
|
||||
/**
|
||||
* @type {'dynamic'|'fixed'}
|
||||
*/
|
||||
type = type ?? 'dynamic';
|
||||
const onLoadCSS = () => {
|
||||
setCssLoaded(true);
|
||||
};
|
||||
|
||||
// For now we don't listen for type changes, we could consider adding useEffect, but that won't be used
|
||||
const defaultStyle = type === 'dynamic' ? {
|
||||
const head = (
|
||||
<>
|
||||
{stylesUrl ? <link rel="stylesheet" href={stylesUrl} onLoad={onLoadCSS} /> : null}
|
||||
<style dangerouslySetInnerHTML={{__html: initialStyles}} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
</>
|
||||
);
|
||||
|
||||
// For now we're using <NewFrame> because using a functional component with portal caused some weird issues with modals
|
||||
return (
|
||||
<IFrame head={head} style={style} onResize={onResize} title={title}>
|
||||
{cssLoaded && children}
|
||||
</IFrame>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* This iframe has the same height as it contents and mimics a shadow DOM component
|
||||
*/
|
||||
const ResizableFrame = ({children, style, title}) => {
|
||||
const [iframeStyle, setIframeStyle] = useState(style);
|
||||
const onResize = (iframeRoot) => {
|
||||
setIframeStyle((current) => {
|
||||
return {
|
||||
...current,
|
||||
height: `${iframeRoot.scrollHeight}px`
|
||||
};
|
||||
});
|
||||
};
|
||||
return (
|
||||
<TailwindFrame style={iframeStyle} onResize={onResize} title={title}>
|
||||
{children}
|
||||
</TailwindFrame>
|
||||
);
|
||||
};
|
||||
|
||||
export const CommentsFrame = ({children}) => {
|
||||
const style = {
|
||||
width: '100%',
|
||||
height: '400px'
|
||||
} : {
|
||||
};
|
||||
return (
|
||||
<ResizableFrame style={style} title="comments-frame">
|
||||
{children}
|
||||
</ResizableFrame>
|
||||
);
|
||||
};
|
||||
|
||||
export const PopupFrame = ({children}) => {
|
||||
const style = {
|
||||
zIndex: '3999999',
|
||||
position: 'fixed',
|
||||
left: '0',
|
||||
|
@ -37,37 +78,9 @@ const Frame = ({
|
|||
overflow: 'hidden'
|
||||
};
|
||||
|
||||
const [iframeStyle, setIframeStyle] = useState(defaultStyle);
|
||||
|
||||
const onResize = (iframeRoot) => {
|
||||
setIframeStyle((current) => {
|
||||
return {
|
||||
...current,
|
||||
height: `${iframeRoot.scrollHeight}px`
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const [cssLoaded, setCssLoaded] = useState(!stylesUrl);
|
||||
|
||||
const onLoadCSS = () => {
|
||||
setCssLoaded(true);
|
||||
};
|
||||
|
||||
const head = (
|
||||
<>
|
||||
{stylesUrl ? <link rel="stylesheet" href={stylesUrl} onLoad={onLoadCSS} /> : null}
|
||||
<style dangerouslySetInnerHTML={{__html: styles}} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
</>
|
||||
);
|
||||
|
||||
// For now we're using <NewFrame> because using a functional component with portal caused some weird issues with modals
|
||||
return (
|
||||
<IFrame {...props} head={head} style={iframeStyle} onResize={type === 'dynamic' ? onResize : null}>
|
||||
{cssLoaded && children}
|
||||
</IFrame>
|
||||
<TailwindFrame style={style} title="popup-frame">
|
||||
{children}
|
||||
</TailwindFrame>
|
||||
);
|
||||
};
|
||||
|
||||
export default Frame;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, {useContext, useEffect} from 'react';
|
||||
import {Transition} from '@headlessui/react';
|
||||
import Frame from '../Frame';
|
||||
import {PopupFrame} from '../Frame';
|
||||
import AppContext from '../../AppContext';
|
||||
|
||||
const GenericDialog = (props) => {
|
||||
|
@ -29,7 +29,7 @@ const GenericDialog = (props) => {
|
|||
|
||||
return (
|
||||
<Transition show={props.show} appear={true}>
|
||||
<Frame type="fixed">
|
||||
<PopupFrame>
|
||||
<div>
|
||||
<Transition.Child
|
||||
enter="transition duration-200 linear"
|
||||
|
@ -53,7 +53,7 @@ const GenericDialog = (props) => {
|
|||
</div>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</Frame>
|
||||
</PopupFrame>
|
||||
</Transition>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue