mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-08 02:52:39 -05:00
Portal notifications basic structure (#99)
* Added basic files for notifications * Added basic notification styles
This commit is contained in:
parent
0a030b59cd
commit
d4b4d869b8
6 changed files with 266 additions and 116 deletions
|
@ -1,4 +1,5 @@
|
|||
import TriggerButton from './components/TriggerButton';
|
||||
import Notification from './components/Notification';
|
||||
import PopupModal from './components/PopupModal';
|
||||
import setupGhostApi from './utils/api';
|
||||
import AppContext from './AppContext';
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* We can create separate variables to keep styles grouped logically, and export them as one appeneded string
|
||||
*/
|
||||
|
||||
import {GlobalStyles} from './Global.styles';
|
||||
import {ActionButtonStyles} from './common/ActionButton';
|
||||
import {BackButtonStyles} from './common/BackButton';
|
||||
import {SwitchStyles} from './common/Switch';
|
||||
|
@ -16,96 +17,7 @@ import {MagicLinkStyles} from './pages/MagicLinkPage';
|
|||
import {LinkPageStyles} from './pages/LinkPage';
|
||||
|
||||
// Global styles
|
||||
const GlobalStyles = `
|
||||
|
||||
/* Colors
|
||||
/* ----------------------------------------------------- */
|
||||
:root {
|
||||
--black: #000;
|
||||
--grey0: #1d1d1d;
|
||||
--grey1: #333;
|
||||
--grey2: #3d3d3d;
|
||||
--grey3: #474747;
|
||||
--grey4: #515151;
|
||||
--grey5: #686868;
|
||||
--grey6: #7f7f7f;
|
||||
--grey7: #979797;
|
||||
--grey8: #aeaeae;
|
||||
--grey9: #c5c5c5;
|
||||
--grey10: #dcdcdc;
|
||||
--grey11: #e1e1e1;
|
||||
--grey12: #eaeaea;
|
||||
--grey13: #f9f9f9;
|
||||
--white: #fff;
|
||||
--red: #f02525;
|
||||
}
|
||||
|
||||
/* Globals
|
||||
/* ----------------------------------------------------- */
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 1.6rem;
|
||||
height: 100%;
|
||||
line-height: 1.6em;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
color: var(--grey4);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, ::after, ::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p {
|
||||
line-height: 1.15em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 31px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 23px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 15px;
|
||||
line-height: 1.55em;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a,
|
||||
.gh-portal-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
svg {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
const FrameStyles = `
|
||||
.gh-portal-main-title {
|
||||
text-align: center;
|
||||
color: var(--grey1);
|
||||
|
@ -736,6 +648,7 @@ const MobileStyles = `
|
|||
// Append all styles as string which we want to pass to iframe
|
||||
const FrameStyle =
|
||||
GlobalStyles +
|
||||
FrameStyles +
|
||||
AccountHomePageStyles +
|
||||
AccountPlanPageStyles +
|
||||
InputFieldStyles +
|
||||
|
|
93
ghost/portal/src/components/Global.styles.js
Normal file
93
ghost/portal/src/components/Global.styles.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
export const GlobalStyles = `
|
||||
/* Colors
|
||||
/* ----------------------------------------------------- */
|
||||
:root {
|
||||
--black: #000;
|
||||
--grey0: #1d1d1d;
|
||||
--grey1: #333;
|
||||
--grey2: #3d3d3d;
|
||||
--grey3: #474747;
|
||||
--grey4: #515151;
|
||||
--grey5: #686868;
|
||||
--grey6: #7f7f7f;
|
||||
--grey7: #979797;
|
||||
--grey8: #aeaeae;
|
||||
--grey9: #c5c5c5;
|
||||
--grey10: #dcdcdc;
|
||||
--grey11: #e1e1e1;
|
||||
--grey12: #eaeaea;
|
||||
--grey13: #f9f9f9;
|
||||
--white: #fff;
|
||||
--red: #f02525;
|
||||
--yellow: #FFDC15;
|
||||
--green: #7FC724;
|
||||
}
|
||||
|
||||
/* Globals
|
||||
/* ----------------------------------------------------- */
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 1.6rem;
|
||||
height: 100%;
|
||||
line-height: 1.6em;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
color: var(--grey4);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, ::after, ::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p {
|
||||
line-height: 1.15em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 31px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 23px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 15px;
|
||||
line-height: 1.55em;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a,
|
||||
.gh-portal-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
svg {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
`;
|
||||
|
||||
export default GlobalStyles;
|
68
ghost/portal/src/components/Notification.js
Normal file
68
ghost/portal/src/components/Notification.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
import Frame from './Frame';
|
||||
import AppContext from '../AppContext';
|
||||
import NotificationStyle from './Notification.styles';
|
||||
import {ReactComponent as CloseIcon} from '../images/icons/close.svg';
|
||||
|
||||
const React = require('react');
|
||||
|
||||
const Styles = ({brandColor, hasText}) => {
|
||||
const frame = {
|
||||
// ...(!hasText ? {width: '60px'} : {})
|
||||
};
|
||||
return {
|
||||
frame: {
|
||||
zIndex: '4000000',
|
||||
position: 'fixed',
|
||||
top: '0px',
|
||||
right: '0',
|
||||
left: '0',
|
||||
width: '100%',
|
||||
height: '80px',
|
||||
animation: '250ms ease 0s 1 normal none running animation-bhegco',
|
||||
transition: 'opacity 0.3s ease 0s',
|
||||
overflow: 'hidden',
|
||||
...frame
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class NotificationContent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className='gh-portal-notification-wrapper'>
|
||||
<div className='gh-portal-notification'>
|
||||
<p>Hey, this is a neutral notification. I hope you feel well today, here's a <a href='http://ghost.org' target='_blank' rel='noopener noreferrer'>link</a> for you.</p>
|
||||
<CloseIcon className='gh-portal-notification-closeicon' alt='Close' />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default class Notification extends React.Component {
|
||||
static contextType = AppContext;
|
||||
|
||||
renderFrameStyles() {
|
||||
const styles = `
|
||||
:root {
|
||||
--brandcolor: ${this.context.brandColor}
|
||||
}
|
||||
` + NotificationStyle;
|
||||
return (
|
||||
<style dangerouslySetInnerHTML={{__html: styles}} />
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const Style = Styles({brandColor: this.context.brandColor});
|
||||
const frameStyle = {
|
||||
...Style.frame
|
||||
};
|
||||
|
||||
return (
|
||||
<Frame style={frameStyle} title="membersjs-notification" head={this.renderFrameStyles()}>
|
||||
<NotificationContent updateWidth={width => this.onWidthChange(width)} />
|
||||
</Frame>
|
||||
);
|
||||
}
|
||||
}
|
97
ghost/portal/src/components/Notification.styles.js
Normal file
97
ghost/portal/src/components/Notification.styles.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
import {GlobalStyles} from './Global.styles';
|
||||
|
||||
const NotificationStyles = `
|
||||
.gh-portal-notification-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.gh-portal-notification {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 12px 44px;
|
||||
max-width: 100%;
|
||||
font-size: 1.4rem;
|
||||
letter-spacing: 0.2px;
|
||||
background: var(--grey1);
|
||||
color: var(--white);
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 3.2px 3.6px rgba(0, 0, 0, 0.024), 0 8.8px 10px -5px rgba(0, 0, 0, 0.12);
|
||||
animation: notification-slidein 0.6s ease-in-out;
|
||||
}
|
||||
|
||||
.gh-portal-notification p {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.gh-portal-notification a {
|
||||
color: var(--white);
|
||||
text-decoration: underline;
|
||||
transition: all 0.2s ease-in-out;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.gh-portal-notification a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.gh-portal-notification-closeicon {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
bottom: 0;
|
||||
right: 5px;
|
||||
color: var(--white);
|
||||
cursor: pointer;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 12px;
|
||||
transition: all 0.2s ease-in-out forwards;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.gh-portal-notification-closeicon:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.gh-portal-notification.success {
|
||||
background: var(--green);
|
||||
}
|
||||
|
||||
.gh-portal-notification.warning {
|
||||
background: var(--yellow);
|
||||
color: var(--grey1);
|
||||
}
|
||||
|
||||
.gh-portal-notification.warning a {
|
||||
color: var(--grey1);
|
||||
}
|
||||
|
||||
.gh-portal-notification.warning .gh-portal-notification-closeicon {
|
||||
color: var(--grey1);
|
||||
}
|
||||
|
||||
.gh-portal-notification.error {
|
||||
background: var(--red);
|
||||
}
|
||||
|
||||
.gh-portal-notification.branded {
|
||||
background: var(--brandcolor);
|
||||
}
|
||||
|
||||
@keyframes notification-slidein {
|
||||
0% { transform: translateY(-100px); }
|
||||
60% { transform: translateY(8px); }
|
||||
100% { transform: translateY(0); }
|
||||
}
|
||||
`;
|
||||
|
||||
const NotificationStyle =
|
||||
GlobalStyles +
|
||||
NotificationStyles;
|
||||
|
||||
export default NotificationStyle;
|
|
@ -1,30 +1,7 @@
|
|||
import {GlobalStyles} from './Global.styles';
|
||||
import {AvatarStyles} from './common/MemberGravatar';
|
||||
|
||||
const GlobalStyle = `
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 1.6rem;
|
||||
height: 100%;
|
||||
line-height: 1.6em;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
color: var(--grey4);
|
||||
}
|
||||
|
||||
*, ::after, ::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
svg {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
const TriggerButtonStyles = `
|
||||
.gh-portal-triggerbtn-wrapper {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
|
@ -63,7 +40,8 @@ const GlobalStyle = `
|
|||
`;
|
||||
|
||||
const TriggerButtonStyle =
|
||||
GlobalStyle +
|
||||
GlobalStyles +
|
||||
TriggerButtonStyles +
|
||||
AvatarStyles;
|
||||
|
||||
export default TriggerButtonStyle;
|
Loading…
Add table
Reference in a new issue