mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-30 22:34:01 -05:00
Updated Portal notification styles (#20538)
closes https://linear.app/ghost/issue/DES-548/update-portal-notification-style Portal popup notification styles look outdated and harsh. Also in-popup notifications have several visual design issues such as positioning, alignment, typography and so on. This PR fixes these issues by applying a much more standard design to Portal notifications.
This commit is contained in:
parent
65bec88187
commit
58ac19ada6
6 changed files with 39 additions and 124 deletions
|
@ -23,6 +23,7 @@ import EmailReceivingFAQ from './pages/EmailReceivingFAQ.css';
|
|||
import {TipsAndDonationsSuccessStyle} from './pages/SupportSuccess';
|
||||
import {TipsAndDonationsErrorStyle} from './pages/SupportError';
|
||||
import {RecommendationsPageStyles} from './pages/RecommendationsPage';
|
||||
import NotificationStyle from './Notification.styles';
|
||||
|
||||
// Global styles
|
||||
const FrameStyles = `
|
||||
|
@ -1275,6 +1276,7 @@ export function getFrameStyles({site}) {
|
|||
MagicLinkStyles +
|
||||
SignupPageStyles +
|
||||
OfferPageStyles({site}) +
|
||||
NotificationStyle +
|
||||
PopupNotificationStyles +
|
||||
MobileStyles +
|
||||
MultipleProductsGlobalStyles +
|
||||
|
|
|
@ -26,7 +26,7 @@ export const GlobalStyles = `
|
|||
--red: #f02525;
|
||||
--darkerRed: #C50202;
|
||||
--yellow: #FFDC15;
|
||||
--green: #7FC724;
|
||||
--green: #30CF43;
|
||||
}
|
||||
|
||||
/* Globals
|
||||
|
|
|
@ -15,9 +15,9 @@ const Styles = () => {
|
|||
position: 'fixed',
|
||||
top: '0',
|
||||
right: '0',
|
||||
maxWidth: '415px',
|
||||
maxWidth: '481px',
|
||||
width: '100%',
|
||||
height: '120px',
|
||||
height: '220px',
|
||||
animation: '250ms ease 0s 1 normal none running animation-bhegco',
|
||||
transition: 'opacity 0.3s ease 0s',
|
||||
overflow: 'hidden'
|
||||
|
@ -34,13 +34,13 @@ const NotificationText = ({type, status, context}) => {
|
|||
const firstname = context.member.firstname || '';
|
||||
return (
|
||||
<p>
|
||||
{firstname ? t('Welcome back, {{name}}!', {name: firstname}) : t('Welcome back!')}<br />{t('You\'ve successfully signed in.')}
|
||||
<strong>{firstname ? t('Welcome back, {{name}}!', {name: firstname}) : t('Welcome back!')}</strong><br />{t('You\'ve successfully signed in.')}
|
||||
</p>
|
||||
);
|
||||
} else if (type === 'signin' && status === 'error') {
|
||||
return (
|
||||
<p>
|
||||
{t('Could not sign in. Login link expired.')} <a href={signinPortalLink} target="_parent">{t('Click here to retry')}</a>
|
||||
{t('Could not sign in. Login link expired.')} <br /><a href={signinPortalLink} target="_parent">{t('Click here to retry')}</a>
|
||||
</p>
|
||||
);
|
||||
} else if (type === 'signup' && status === 'success') {
|
||||
|
|
|
@ -11,21 +11,22 @@ const NotificationStyles = `
|
|||
.gh-portal-notification {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
width: 100%;
|
||||
padding: 14px 44px 18px 20px;
|
||||
padding: 16px;
|
||||
max-width: 380px;
|
||||
min-height: 66px;
|
||||
font-size: 1.3rem;
|
||||
letter-spacing: 0.2px;
|
||||
background: rgba(var(--grey1rgb),0.95);
|
||||
background: var(--white);
|
||||
backdrop-filter: blur(8px);
|
||||
color: var(--white);
|
||||
color: var(--grey0);
|
||||
border-radius: 7px;
|
||||
box-shadow: 0 3.2px 3.6px rgba(var(--black), 0.024), 0 8.8px 10px -5px rgba(var(--black), 0.08);
|
||||
box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.30), 0px 51px 40px 0px rgba(0, 0, 0, 0.05), 0px 15.375px 12.059px 0px rgba(0, 0, 0, 0.03), 0px 6.386px 5.009px 0px rgba(0, 0, 0, 0.03), 0px 2.31px 1.812px 0px rgba(0, 0, 0, 0.02);
|
||||
animation: notification-slidein 0.55s cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .gh-portal-notification {
|
||||
|
@ -49,16 +50,15 @@ const NotificationStyles = `
|
|||
text-align: start;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--grey13);
|
||||
padding-inline-start: 40px;
|
||||
color: var(--grey0);
|
||||
}
|
||||
|
||||
.gh-portal-notification p strong {
|
||||
color: var(--white);
|
||||
color: var(--grey0);
|
||||
}
|
||||
|
||||
.gh-portal-notification a {
|
||||
color: var(--white);
|
||||
color: var(--grey0);
|
||||
text-decoration: underline;
|
||||
transition: all 0.2s ease-in-out;
|
||||
outline: none;
|
||||
|
@ -69,11 +69,10 @@ const NotificationStyles = `
|
|||
}
|
||||
|
||||
.gh-portal-notification-icon {
|
||||
position: absolute;
|
||||
top: calc(50% - 14px);
|
||||
left: 17px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
min-width: 18px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
html[dir="rtl"] .gh-portal-notification-icon {
|
||||
right: 17px;
|
||||
|
@ -89,22 +88,22 @@ const NotificationStyles = `
|
|||
}
|
||||
|
||||
.gh-portal-notification-closeicon {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
bottom: 0;
|
||||
right: 5px;
|
||||
color: var(--white);
|
||||
color: var(--grey8);
|
||||
cursor: pointer;
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
height: 12px;
|
||||
padding: 10px;
|
||||
margin-top: -6px;
|
||||
margin-right: -6px;
|
||||
margin-bottom: -6px;
|
||||
transition: all 0.2s ease-in-out forwards;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.gh-portal-notification-closeicon:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes notification-slidein {
|
||||
0% { transform: translateX(380px); }
|
||||
|
@ -130,7 +129,7 @@ const NotificationStyles = `
|
|||
100% { transform: translateY(-150px); }
|
||||
}
|
||||
|
||||
@media (max-width: 414px) {
|
||||
@media (max-width: 480px) {
|
||||
.gh-portal-notification {
|
||||
left: 12px;
|
||||
max-width: calc(100% - 24px);
|
||||
|
|
|
@ -215,9 +215,9 @@ class PopupContent extends React.Component {
|
|||
return (
|
||||
<>
|
||||
<div className={'gh-portal-popup-wrapper ' + pageClass} onClick={e => this.handlePopupClose(e)}>
|
||||
{this.renderPopupNotification()}
|
||||
<div className={containerClassName} style={pageStyle} ref={node => (this.node = node)} tabIndex={-1}>
|
||||
<CookieDisabledBanner message={cookieBannerText} />
|
||||
{this.renderPopupNotification()}
|
||||
{this.renderActivePage()}
|
||||
{(popupSize === 'full' ?
|
||||
<div className={'gh-portal-powered inside ' + (hasMode(['preview']) ? 'hidden ' : '') + pageClass}>
|
||||
|
|
|
@ -10,103 +10,17 @@ import {SYNTAX_I18NEXT} from '@doist/react-interpolate';
|
|||
|
||||
export const PopupNotificationStyles = `
|
||||
.gh-portal-popupnotification {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
left: 16px;
|
||||
padding: 12px;
|
||||
background: var(--grey2);
|
||||
z-index: 11000;
|
||||
border-radius: 5px;
|
||||
font-size: 1.5rem;
|
||||
box-shadow: 0px 0.8151839971542358px 0.8151839971542358px 0px rgba(var(--blackrgb),0.01),
|
||||
0px 2.2538793087005615px 2.2538793087005615px 0px rgba(var(--blackrgb),0.02),
|
||||
0px 5.426473140716553px 5.426473140716553px 0px rgba(var(--blackrgb),0.03),
|
||||
0px 18px 18px 0px rgba(var(--blackrgb),0.04);
|
||||
animation: popupnotification-slidein 0.3s ease-in-out;
|
||||
right: 42px;
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification.slideout {
|
||||
animation: popupnotification-slideout 0.48s ease-in;
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification p {
|
||||
color: var(--white);
|
||||
margin: 0 0 0 8px;
|
||||
padding: 0 20px;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.5em;
|
||||
letter-spacing: 0.2px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification a {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification-icon {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
html[dir="rtl"] .gh-portal-popupnotification-icon {
|
||||
left: unset;
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification-icon.success {
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification-icon.error {
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification .closeicon {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
bottom: 0;
|
||||
right: 3px;
|
||||
color: var(--white);
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 12px;
|
||||
transition: all 0.15s ease-in-out forwards;
|
||||
opacity: 0.8;
|
||||
}
|
||||
html[dir="rtl"] .gh-portal-popupnotification .closeicon {
|
||||
html[dir="rtl"] .gh-portal-notification {
|
||||
right: unset;
|
||||
left: 3px;
|
||||
left: 42px;
|
||||
}
|
||||
|
||||
.gh-portal-popupnotification .closeicon:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
@keyframes popupnotification-slidein {
|
||||
0% {
|
||||
transform: translateY(-10px);
|
||||
opacity: 0;
|
||||
}
|
||||
60% { transform: translateY(2px); }
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes popupnotification-slideout {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
opacity: 1.0;
|
||||
}
|
||||
40% { transform: translateY(2px); }
|
||||
100% {
|
||||
transform: translateY(-10px);
|
||||
opacity: 0;
|
||||
@media (max-width: 480px) {
|
||||
.gh-portal-notification {
|
||||
max-width: calc(100% - 54px);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@ -116,7 +30,7 @@ const CloseButton = ({hide = false, onClose}) => {
|
|||
return null;
|
||||
}
|
||||
return (
|
||||
<CloseIcon className='closeicon' alt='Close' onClick={onClose} />
|
||||
<CloseIcon className='gh-portal-notification-closeicon' alt='Close' onClick={onClose} />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -155,7 +69,7 @@ export default class PopupNotification extends React.Component {
|
|||
onAnimationEnd(e) {
|
||||
const {popupNotification} = this.context;
|
||||
const {type} = popupNotification || {};
|
||||
if (e.animationName === 'popupnotification-slideout') {
|
||||
if (e.animationName === 'notification-slideout' || e.animationName === 'notification-slideout-mobile') {
|
||||
if (type === 'stripe:billing-update') {
|
||||
clearURLParams(['stripe']);
|
||||
}
|
||||
|
@ -212,8 +126,8 @@ export default class PopupNotification extends React.Component {
|
|||
const slideClass = className ? ` ${className}` : '';
|
||||
|
||||
return (
|
||||
<div className={`gh-portal-popupnotification${statusClass}${slideClass}`} onAnimationEnd={e => this.onAnimationEnd(e)}>
|
||||
{(status === 'error' ? <WarningIcon className='gh-portal-popupnotification-icon error' alt=''/> : <CheckmarkIcon className='gh-portal-popupnotification-icon success' alt=''/>)}
|
||||
<div className={`gh-portal-notification gh-portal-popupnotification ${statusClass}${slideClass}`} onAnimationEnd={e => this.onAnimationEnd(e)}>
|
||||
{(status === 'error' ? <WarningIcon className='gh-portal-notification-icon error' alt=''/> : <CheckmarkIcon className='gh-portal-notification-icon success' alt=''/>)}
|
||||
<NotificationText type={type} status={status} message={message} site={site} t={t} />
|
||||
<CloseButton hide={!closeable} onClose={e => this.closeNotification(e)}/>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue