mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Updated trigger button design
no refs. - added separate trigger button styles file - restructured and updated styles
This commit is contained in:
parent
f47cacd299
commit
e877dd5e37
7 changed files with 82 additions and 69 deletions
|
@ -143,7 +143,7 @@ export default class App extends React.Component {
|
||||||
showPopup: true,
|
showPopup: true,
|
||||||
site: Fixtures.site,
|
site: Fixtures.site,
|
||||||
member: Fixtures.member.paid,
|
member: Fixtures.member.paid,
|
||||||
page: 'signup'
|
page: 'accountHome'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {AvatarStyles} from './common/MemberGravatar';
|
||||||
import {MagicLinkStyles} from './pages/MagicLinkPage';
|
import {MagicLinkStyles} from './pages/MagicLinkPage';
|
||||||
|
|
||||||
// Global styles
|
// Global styles
|
||||||
export const GlobalStyles = `
|
const GlobalStyles = `
|
||||||
|
|
||||||
/* Colors
|
/* Colors
|
||||||
/* ----------------------------------------------------- */
|
/* ----------------------------------------------------- */
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {ReactComponent as ButtonIcon3} from '../images/icons/button-icon-3.svg';
|
||||||
import {ReactComponent as ButtonIcon4} from '../images/icons/button-icon-4.svg';
|
import {ReactComponent as ButtonIcon4} from '../images/icons/button-icon-4.svg';
|
||||||
import {ReactComponent as ButtonIcon5} from '../images/icons/button-icon-5.svg';
|
import {ReactComponent as ButtonIcon5} from '../images/icons/button-icon-5.svg';
|
||||||
import getContrastColor from '../utils/contrast-color';
|
import getContrastColor from '../utils/contrast-color';
|
||||||
|
import TriggerButtonStyle from './TriggerButton.styles';
|
||||||
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
const ICON_MAPPING = {
|
const ICON_MAPPING = {
|
||||||
|
@ -33,45 +35,16 @@ const Styles = ({brandColor, hasText}) => {
|
||||||
width: '500px',
|
width: '500px',
|
||||||
maxWidth: '500px',
|
maxWidth: '500px',
|
||||||
height: '60px',
|
height: '60px',
|
||||||
boxShadow: 'rgba(0, 0, 0, 0.06) 0px 1px 6px 0px, rgba(0, 0, 0, 0.16) 0px 2px 32px 0px',
|
boxShadow: '0 3.2px 3.6px rgba(0, 0, 0, 0.024), 0 8.8px 10px rgba(0, 0, 0, 0.035), 0 21.1px 24.1px rgba(0, 0, 0, 0.046), 0 70px 80px rgba(0, 0, 0, 0.07)',
|
||||||
borderRadius: '999px',
|
borderRadius: '999px',
|
||||||
backgroundColor: brandColor,
|
|
||||||
animation: '250ms ease 0s 1 normal none running animation-bhegco',
|
animation: '250ms ease 0s 1 normal none running animation-bhegco',
|
||||||
transition: 'opacity 0.3s ease 0s',
|
transition: 'opacity 0.3s ease 0s',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
...frame
|
...frame
|
||||||
},
|
},
|
||||||
launcher: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '0px',
|
|
||||||
left: '0px',
|
|
||||||
width: '60px',
|
|
||||||
height: '60px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
transformOrigin: 'center center',
|
|
||||||
backfaceVisibility: 'hidden',
|
|
||||||
WebkitFontSmoothing: 'antialiased',
|
|
||||||
borderRadius: '999px',
|
|
||||||
overflow: 'hidden'
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
userSelect: 'none',
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'flex',
|
|
||||||
WebkitBoxAlign: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
WebkitBoxPack: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
width: '100%',
|
|
||||||
opacity: '1',
|
|
||||||
transform: 'rotate(0deg) scale(1)',
|
|
||||||
height: '100%',
|
|
||||||
transition: 'transform 0.16s linear 0s, opacity 0.08s linear 0s',
|
|
||||||
overflow: 'hidden'
|
|
||||||
},
|
|
||||||
userIcon: {
|
userIcon: {
|
||||||
width: '26px',
|
width: '34px',
|
||||||
height: '26px',
|
height: '34px',
|
||||||
color: invertColor
|
color: invertColor
|
||||||
},
|
},
|
||||||
closeIcon: {
|
closeIcon: {
|
||||||
|
@ -141,19 +114,25 @@ class TriggerButtonContent extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(ICON_MAPPING).includes(buttonIcon)) {
|
if (this.context.member) {
|
||||||
const ButtonIcon = ICON_MAPPING[buttonIcon];
|
|
||||||
return (
|
|
||||||
<ButtonIcon style={Style.userIcon} />
|
|
||||||
);
|
|
||||||
} else if (buttonIcon) {
|
|
||||||
return (
|
|
||||||
<img style={{width: '26px', height: '26px'}} src={buttonIcon} alt="Icon" />
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
return (
|
||||||
<UserIcon style={Style.userIcon} />
|
<UserIcon style={Style.userIcon} />
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
if (Object.keys(ICON_MAPPING).includes(buttonIcon)) {
|
||||||
|
const ButtonIcon = ICON_MAPPING[buttonIcon];
|
||||||
|
return (
|
||||||
|
<ButtonIcon style={Style.userIcon} />
|
||||||
|
);
|
||||||
|
} else if (buttonIcon) {
|
||||||
|
return (
|
||||||
|
<img style={{width: '26px', height: '26px'}} src={buttonIcon} alt="Icon" />
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<UserIcon style={Style.userIcon} />
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,11 +164,10 @@ class TriggerButtonContent extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const hasText = this.hasText();
|
const hasText = this.hasText();
|
||||||
const Style = Styles({brandColor: this.context.brandColor});
|
|
||||||
if (hasText) {
|
if (hasText) {
|
||||||
return (
|
return (
|
||||||
<div style={Style.button} onClick={e => this.onToggle(e)}>
|
<div className='gh-portal-triggerbtn-wrapper' onClick={e => this.onToggle(e)}>
|
||||||
<div style={{padding: '0 16px 0 20px', display: 'flex', alignItems: 'center'}} ref={this.container}>
|
<div className='gh-portal-triggerbtn-container' ref={this.container}>
|
||||||
{this.renderTriggerIcon()}
|
{this.renderTriggerIcon()}
|
||||||
{this.renderText()}
|
{this.renderText()}
|
||||||
</div>
|
</div>
|
||||||
|
@ -197,8 +175,8 @@ class TriggerButtonContent extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div style={Style.button} onClick={e => this.onToggle(e)}>
|
<div className='gh-portal-triggerbtn-wrapper' onClick={e => this.onToggle(e)}>
|
||||||
<div style={{padding: '0 24px', display: 'flex'}}>
|
<div className='gh-portal-triggerbtn-container'>
|
||||||
{this.renderTriggerIcon()}
|
{this.renderTriggerIcon()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -228,6 +206,17 @@ export default class TriggerButton extends React.Component {
|
||||||
return ['icon-and-text', 'text-only'].includes(buttonStyle) && !this.context.member && buttonText;
|
return ['icon-and-text', 'text-only'].includes(buttonStyle) && !this.context.member && buttonText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderFrameStyles() {
|
||||||
|
const styles = `
|
||||||
|
:root {
|
||||||
|
--brandcolor: ${this.context.brandColor}
|
||||||
|
}
|
||||||
|
` + TriggerButtonStyle;
|
||||||
|
return (
|
||||||
|
<style dangerouslySetInnerHTML={{__html: styles}} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {portal_button: portalButton} = this.context.site;
|
const {portal_button: portalButton} = this.context.site;
|
||||||
const {showPopup} = this.context;
|
const {showPopup} = this.context;
|
||||||
|
@ -248,7 +237,7 @@ export default class TriggerButton extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Frame style={frameStyle} title="membersjs-trigger">
|
<Frame style={frameStyle} title="membersjs-trigger" head={this.renderFrameStyles()}>
|
||||||
<TriggerButtonContent isPopupOpen={showPopup} updateWidth={width => this.onWidthChange(width)} />
|
<TriggerButtonContent isPopupOpen={showPopup} updateWidth={width => this.onWidthChange(width)} />
|
||||||
</Frame>
|
</Frame>
|
||||||
);
|
);
|
||||||
|
|
40
ghost/portal/src/components/TriggerButton.styles.js
Normal file
40
ghost/portal/src/components/TriggerButton.styles.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import {AvatarStyles} from './common/MemberGravatar';
|
||||||
|
|
||||||
|
const GlobalStyle = `
|
||||||
|
.gh-portal-triggerbtn-wrapper {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(0deg) scale(1);
|
||||||
|
height: 100%;
|
||||||
|
transition: transform 0.16s linear 0s; opacity 0.08s linear 0s;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
background: var(--brandcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-portal-triggerbtn-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-portal-triggerbtn-container.with-label {
|
||||||
|
padding: 0 16px 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-portal-avatar {
|
||||||
|
margin-bottom: 16px !important;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TriggerButtonStyle =
|
||||||
|
GlobalStyle +
|
||||||
|
AvatarStyles;
|
||||||
|
|
||||||
|
export default TriggerButtonStyle;
|
|
@ -29,25 +29,9 @@ export const AvatarStyles = `
|
||||||
const Styles = ({style = {}}) => {
|
const Styles = ({style = {}}) => {
|
||||||
return {
|
return {
|
||||||
avatarContainer: {
|
avatarContainer: {
|
||||||
position: 'relative',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
overflow: 'hidden',
|
|
||||||
borderRadius: '999px',
|
|
||||||
...(style.avatarContainer || {}) // Override any custom style
|
...(style.avatarContainer || {}) // Override any custom style
|
||||||
},
|
},
|
||||||
gravatar: {
|
gravatar: {
|
||||||
position: 'absolute',
|
|
||||||
display: 'block',
|
|
||||||
top: '-1px',
|
|
||||||
right: '-1px',
|
|
||||||
bottom: '-1px',
|
|
||||||
left: '-1px',
|
|
||||||
width: 'calc(100% + 2px)',
|
|
||||||
height: 'calc(100% + 2px)',
|
|
||||||
opacity: '1',
|
|
||||||
maxWidth: 'unset',
|
|
||||||
...(style.avatarContainer || {}) // Override any custom style
|
...(style.avatarContainer || {}) // Override any custom style
|
||||||
},
|
},
|
||||||
userIcon: {
|
userIcon: {
|
||||||
|
@ -64,7 +48,7 @@ function MemberGravatar({gravatar, style}) {
|
||||||
return (
|
return (
|
||||||
<figure className='gh-portal-avatar' style={Style.avatarContainer}>
|
<figure className='gh-portal-avatar' style={Style.avatarContainer}>
|
||||||
<UserIcon style={Style.userIcon} />
|
<UserIcon style={Style.userIcon} />
|
||||||
{gravatar ? <img style={Style.gravatar} src={gravatar} alt="Gravatar" /> : null}
|
{gravatar ? <img style={Style.gravatar} src={gravatar} alt="" /> : null}
|
||||||
</figure>
|
</figure>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ export const AccountHomePageStyles = `
|
||||||
const UserAvatar = ({avatar, brandColor}) => {
|
const UserAvatar = ({avatar, brandColor}) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<MemberAvatar gravatar={avatar} style={{userIcon: {color: brandColor, width: '56px', height: '56px'}}} />
|
<MemberAvatar gravatar={avatar} style={{userIcon: {color: brandColor, width: '56px', height: '56px', padding: '2px'}}} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,7 @@ export const member = {
|
||||||
email: 'paidmember+@example.com',
|
email: 'paidmember+@example.com',
|
||||||
name: 'Paid Member',
|
name: 'Paid Member',
|
||||||
firstname: 'Member',
|
firstname: 'Member',
|
||||||
avatar_image: 'https://gravatar.com/avatar/eb0ef27b5faa9528c900170cba4c11dc?s=250&d=blank',
|
avatar_image: 'https://gravatar.com/avatar/eb0ef27b5faa9528c900170cba4c11dc?s=250&',
|
||||||
subscriptions: [{
|
subscriptions: [{
|
||||||
id: 'sub_HCLyRzHcGciDWJ',
|
id: 'sub_HCLyRzHcGciDWJ',
|
||||||
customer: {
|
customer: {
|
||||||
|
|
Loading…
Add table
Reference in a new issue